1use crate::core::layout::{self, Layout};
2use crate::core::mouse;
3use crate::core::overlay;
4use crate::core::renderer;
5use crate::core::widget;
6use crate::core::widget::Tree;
7use crate::core::{self, Event, Length, Rectangle, Shell, Size, Vector, Widget};
8
9pub struct Responsive<'a, W> {
14 view: Box<dyn Fn(Size) -> W + 'a>,
15 width: Length,
16 height: Length,
17 content: Option<W>,
18}
19
20impl<'a, W> Responsive<'a, W> {
21 pub fn new(view: impl Fn(Size) -> W + 'a) -> Self {
28 Self {
29 view: Box::new(view),
30 width: Length::Fill,
31 height: Length::Fill,
32 content: None,
33 }
34 }
35
36 pub fn width(mut self, width: impl Into<Length>) -> Self {
38 self.width = width.into();
39 self
40 }
41
42 pub fn height(mut self, height: impl Into<Length>) -> Self {
44 self.height = height.into();
45 self
46 }
47}
48
49impl<W> widget::Meta for Responsive<'_, W> {}
50
51impl<W, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Responsive<'_, W>
52where
53 Renderer: core::Renderer,
54 W: Widget<Message, Theme, Renderer>,
55{
56 fn diff(&mut self, _tree: &mut Tree) {
57 }
59
60 fn size(&self) -> Size<Length> {
61 Size {
62 width: self.width,
63 height: self.height,
64 }
65 }
66
67 fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits) {
68 let limits = limits.width(self.width).height(self.height);
69 let size = limits.bounds();
70
71 self.content = Some((self.view)(size));
72 tree.diff_children(std::slice::from_mut(&mut self.content));
73
74 self.content
75 .layout(&mut tree.children[0], renderer, &limits.loose());
76
77 tree.size = limits.resolve(self.width, self.height, tree.children[0].size);
78 }
79
80 fn update(
81 &mut self,
82 tree: &mut Tree,
83 event: &Event,
84 layout: Layout,
85 cursor: mouse::Cursor,
86 renderer: &Renderer,
87 shell: &mut Shell<'_, Message>,
88 viewport: &Rectangle,
89 ) {
90 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
91
92 self.content
93 .update(tree, event, layout, cursor, renderer, shell, viewport);
94 }
95
96 fn draw(
97 &self,
98 tree: &Tree,
99 renderer: &mut Renderer,
100 theme: &Theme,
101 style: &renderer::Style,
102 layout: Layout,
103 cursor: mouse::Cursor,
104 viewport: &Rectangle,
105 ) {
106 let (layout, tree) = layout.iter(&tree.children).next().unwrap();
107
108 self.content
109 .draw(tree, renderer, theme, style, layout, cursor, viewport);
110 }
111
112 fn mouse_interaction(
113 &self,
114 tree: &Tree,
115 layout: Layout,
116 cursor: mouse::Cursor,
117 viewport: &Rectangle,
118 renderer: &Renderer,
119 ) -> mouse::Interaction {
120 let (layout, tree) = layout.iter(&tree.children).next().unwrap();
121
122 self.content
123 .mouse_interaction(tree, layout, cursor, viewport, renderer)
124 }
125
126 fn operate(
127 &mut self,
128 tree: &mut Tree,
129 layout: Layout,
130 viewport: &Rectangle,
131 renderer: &Renderer,
132 operation: &mut dyn widget::Operation,
133 ) {
134 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
135
136 self.content
137 .operate(tree, layout, viewport, renderer, operation);
138 }
139
140 fn overlay<'a>(
141 &'a mut self,
142 tree: &'a mut Tree,
143 layout: Layout,
144 renderer: &Renderer,
145 viewport: &Rectangle,
146 translation: Vector,
147 window: Size,
148 ) -> Vec<overlay::Element<'a, Message, Theme, Renderer>> {
149 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
150
151 self.content
152 .overlay(tree, layout, renderer, viewport, translation, window)
153 }
154}