1use crate::Theme;
2use cosmic_theme::LayeredTheme;
3use iced::widget::Container;
4use iced_core::event::{self, Event};
5use iced_core::layout;
6use iced_core::mouse;
7use iced_core::overlay;
8use iced_core::renderer;
9use iced_core::widget::Tree;
10use iced_core::{
11 Alignment, Clipboard, Element, Layout, Length, Padding, Rectangle, Shell, Vector, Widget,
12};
13pub use iced_widget::container::{Catalog, Style};
14
15pub fn layer_container<'a, Message: 'static, E>(
16 content: E,
17) -> LayerContainer<'a, Message, crate::Renderer>
18where
19 E: Into<Element<'a, Message, Theme, crate::Renderer>>,
20{
21 LayerContainer::new(content)
22}
23
24#[allow(missing_debug_implementations)]
28pub struct LayerContainer<'a, Message, Renderer>
29where
30 Renderer: iced_core::Renderer,
31{
32 layer: Option<cosmic_theme::Layer>,
33 container: Container<'a, Message, Theme, Renderer>,
34}
35
36impl<'a, Message, Renderer> LayerContainer<'a, Message, Renderer>
37where
38 Renderer: iced_core::Renderer,
39 {
41 pub(crate) fn new<T>(content: T) -> Self
43 where
44 T: Into<Element<'a, Message, Theme, Renderer>>,
45 {
46 LayerContainer {
47 layer: None,
48 container: Container::new(content),
49 }
50 }
51
52 #[must_use]
54 pub fn layer(mut self, layer: cosmic_theme::Layer) -> Self {
55 self.layer = Some(layer);
56 self.class(match layer {
57 cosmic_theme::Layer::Background => crate::theme::Container::Background,
58 cosmic_theme::Layer::Primary => crate::theme::Container::Primary,
59 cosmic_theme::Layer::Secondary => crate::theme::Container::Secondary,
60 })
61 }
62
63 #[must_use]
65 pub fn padding<P: Into<Padding>>(mut self, padding: P) -> Self {
66 self.container = self.container.padding(padding);
67 self
68 }
69
70 #[must_use]
72 #[inline]
73 pub fn width(mut self, width: Length) -> Self {
74 self.container = self.container.width(width);
75 self
76 }
77
78 #[must_use]
80 #[inline]
81 pub fn height(mut self, height: Length) -> Self {
82 self.container = self.container.height(height);
83 self
84 }
85
86 #[must_use]
88 #[inline]
89 pub fn max_width(mut self, max_width: f32) -> Self {
90 self.container = self.container.max_width(max_width);
91 self
92 }
93
94 #[must_use]
96 #[inline]
97 pub fn max_height(mut self, max_height: f32) -> Self {
98 self.container = self.container.max_height(max_height);
99 self
100 }
101
102 #[must_use]
104 #[inline]
105 pub fn align_x(mut self, alignment: Alignment) -> Self {
106 self.container = self.container.align_x(alignment);
107 self
108 }
109
110 #[must_use]
112 #[inline]
113 pub fn align_y(mut self, alignment: Alignment) -> Self {
114 self.container = self.container.align_y(alignment);
115 self
116 }
117
118 #[must_use]
120 #[inline]
121 pub fn center_x(mut self, width: Length) -> Self {
122 self.container = self.container.center_x(width);
123 self
124 }
125
126 #[must_use]
128 #[inline]
129 pub fn center_y(mut self, height: Length) -> Self {
130 self.container = self.container.center_y(height);
131 self
132 }
133
134 #[must_use]
136 #[inline]
137 pub fn center(mut self, length: Length) -> Self {
138 self.container = self.container.center(length);
139 self
140 }
141
142 #[must_use]
144 pub fn class(mut self, style: impl Into<crate::style::iced::Container<'a>>) -> Self {
145 self.container = self.container.class(style);
146 self
147 }
148}
149
150impl<Message, Renderer> Widget<Message, Theme, Renderer> for LayerContainer<'_, Message, Renderer>
151where
152 Renderer: iced_core::Renderer,
153{
154 fn children(&self) -> Vec<Tree> {
155 self.container.children()
156 }
157
158 fn tag(&self) -> iced_core::widget::tree::Tag {
159 self.container.tag()
160 }
161
162 fn diff(&mut self, tree: &mut Tree) {
163 self.container.diff(tree);
164 }
165
166 fn state(&self) -> iced_core::widget::tree::State {
167 self.container.state()
168 }
169
170 fn size(&self) -> iced_core::Size<Length> {
171 self.container.size()
172 }
173
174 fn layout(
175 &self,
176 tree: &mut Tree,
177 renderer: &Renderer,
178 limits: &layout::Limits,
179 ) -> layout::Node {
180 self.container.layout(tree, renderer, limits)
181 }
182
183 fn operate(
184 &self,
185 tree: &mut Tree,
186 layout: Layout<'_>,
187 renderer: &Renderer,
188 operation: &mut dyn iced_core::widget::Operation<()>,
189 ) {
190 self.container.operate(tree, layout, renderer, operation);
191 }
192
193 fn on_event(
194 &mut self,
195 tree: &mut Tree,
196 event: Event,
197 layout: Layout<'_>,
198 cursor_position: mouse::Cursor,
199 renderer: &Renderer,
200 clipboard: &mut dyn Clipboard,
201 shell: &mut Shell<'_, Message>,
202 viewport: &Rectangle,
203 ) -> event::Status {
204 self.container.on_event(
205 tree,
206 event,
207 layout,
208 cursor_position,
209 renderer,
210 clipboard,
211 shell,
212 viewport,
213 )
214 }
215
216 fn mouse_interaction(
217 &self,
218 tree: &Tree,
219 layout: Layout<'_>,
220 cursor_position: mouse::Cursor,
221 viewport: &Rectangle,
222 renderer: &Renderer,
223 ) -> mouse::Interaction {
224 self.container
225 .mouse_interaction(tree, layout, cursor_position, viewport, renderer)
226 }
227
228 fn draw(
229 &self,
230 tree: &Tree,
231 renderer: &mut Renderer,
232 theme: &Theme,
233 renderer_style: &renderer::Style,
234 layout: Layout<'_>,
235 cursor_position: mouse::Cursor,
236 viewport: &Rectangle,
237 ) {
238 let theme = if let Some(layer) = self.layer {
239 let mut theme = theme.clone();
240 theme.set_layer(layer);
241 theme
242 } else {
243 theme.clone()
244 };
245
246 self.container.draw(
247 tree,
248 renderer,
249 &theme,
250 renderer_style,
251 layout,
252 cursor_position,
253 viewport,
254 );
255 }
256
257 fn overlay<'b>(
258 &'b mut self,
259 tree: &'b mut Tree,
260 layout: Layout<'_>,
261 renderer: &Renderer,
262 translation: Vector,
263 ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
264 self.container.overlay(tree, layout, renderer, translation)
265 }
266
267 fn drag_destinations(
268 &self,
269 state: &Tree,
270 layout: Layout<'_>,
271 renderer: &Renderer,
272 dnd_rectangles: &mut iced_core::clipboard::DndDestinationRectangles,
273 ) {
274 self.container
275 .drag_destinations(state, layout, renderer, dnd_rectangles);
276 }
277
278 fn id(&self) -> Option<crate::widget::Id> {
279 Widget::id(&self.container)
280 }
281
282 fn set_id(&mut self, id: crate::widget::Id) {
283 self.container.set_id(id);
284 }
285
286 #[cfg(feature = "a11y")]
287 fn a11y_nodes(
289 &self,
290 layout: iced_core::Layout<'_>,
291 state: &Tree,
292 p: iced::mouse::Cursor,
293 ) -> iced_accessibility::A11yTree {
294 self.container.a11y_nodes(layout, state, p)
295 }
296}
297
298impl<'a, Message, Renderer> From<LayerContainer<'a, Message, Renderer>>
299 for Element<'a, Message, Theme, Renderer>
300where
301 Message: 'a,
302 Renderer: 'a + iced_core::Renderer,
303{
304 fn from(
305 column: LayerContainer<'a, Message, Renderer>,
306 ) -> Element<'a, Message, Theme, Renderer> {
307 Element::new(column)
308 }
309}