1use crate::core::layout;
37use crate::core::mouse;
38use crate::core::overlay;
39use crate::core::renderer;
40use crate::core::widget::tree::{self, Tree};
41use crate::core::widget::{self, Operation, Widget};
42use crate::core::{Element, Event, Layout, Length, Rectangle, Shell, Size, Vector};
43
44pub struct Opaque<W> {
80 content: W,
81 capture_scroll: bool,
82}
83
84impl<W> Opaque<W> {
85 pub fn new(content: W) -> Self {
87 Opaque {
88 content,
89 capture_scroll: false,
90 }
91 }
92
93 pub fn capture_scroll(mut self, capture: bool) -> Self {
100 self.capture_scroll = capture;
101 self
102 }
103
104 pub fn into_inner(self) -> W {
106 self.content
107 }
108}
109
110impl<W> widget::Meta for Opaque<W> {}
111
112impl<W, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Opaque<W>
113where
114 W: Widget<Message, Theme, Renderer>,
115{
116 fn tag(&self) -> tree::Tag {
117 self.content.tag()
118 }
119
120 fn state(&self) -> tree::State {
121 self.content.state()
122 }
123
124 fn diff(&mut self, tree: &mut Tree) {
125 tree.diff_children(std::slice::from_mut(&mut self.content));
126 }
127
128 fn size(&self) -> Size<Length> {
129 self.content.size()
130 }
131
132 fn layout(&mut self, tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits) {
133 self.content.layout(&mut tree.children[0], renderer, limits);
134
135 tree.size = tree.children[0].size;
136 }
137
138 fn draw(
139 &self,
140 tree: &Tree,
141 renderer: &mut Renderer,
142 theme: &Theme,
143 style: &renderer::Style,
144 layout: Layout,
145 cursor: mouse::Cursor,
146 viewport: &Rectangle,
147 ) {
148 let (layout, tree) = layout.iter(&tree.children).next().unwrap();
149
150 self.content
151 .draw(tree, renderer, theme, style, layout, cursor, viewport);
152 }
153
154 fn operate(
155 &mut self,
156 tree: &mut Tree,
157 layout: Layout,
158 viewport: &Rectangle,
159 renderer: &Renderer,
160 operation: &mut dyn Operation,
161 ) {
162 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
163
164 self.content
165 .operate(tree, layout, viewport, renderer, operation);
166 }
167
168 fn update(
169 &mut self,
170 tree: &mut Tree,
171 event: &Event,
172 layout: Layout,
173 cursor: mouse::Cursor,
174 renderer: &Renderer,
175 shell: &mut Shell<'_, Message>,
176 viewport: &Rectangle,
177 ) {
178 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
179
180 let is_mouse_press = matches!(event, Event::Mouse(mouse::Event::ButtonPressed(_)));
181 let is_wheel_scroll = matches!(event, Event::Mouse(mouse::Event::WheelScrolled { .. }));
182
183 self.content
184 .update(tree, event, layout, cursor, renderer, shell, viewport);
185
186 if (is_mouse_press || (self.capture_scroll && is_wheel_scroll))
187 && cursor.is_over(layout.bounds())
188 {
189 shell.capture_event();
190 }
191 }
192
193 fn mouse_interaction(
194 &self,
195 tree: &Tree,
196 layout: Layout,
197 cursor: mouse::Cursor,
198 viewport: &Rectangle,
199 renderer: &Renderer,
200 ) -> mouse::Interaction {
201 let (layout, tree) = layout.iter(&tree.children).next().unwrap();
202
203 let interaction = self
204 .content
205 .mouse_interaction(tree, layout, cursor, viewport, renderer);
206
207 if interaction == mouse::Interaction::None && cursor.is_over(layout.bounds()) {
208 mouse::Interaction::Idle
209 } else {
210 interaction
211 }
212 }
213
214 fn overlay<'b>(
215 &'b mut self,
216 tree: &'b mut Tree,
217 layout: Layout,
218 renderer: &Renderer,
219 viewport: &Rectangle,
220 translation: Vector,
221 window: Size,
222 ) -> Vec<overlay::Element<'b, Message, Theme, Renderer>> {
223 let (layout, tree) = layout.iter_mut(&mut tree.children).next().unwrap();
224
225 self.content
226 .overlay(tree, layout, renderer, viewport, translation, window)
227 }
228}
229
230impl<'a, W, Message, Theme, Renderer> From<Opaque<W>> for Element<'a, Message, Theme, Renderer>
231where
232 Message: 'a,
233 Theme: 'a,
234 Renderer: 'a,
235 W: Widget<Message, Theme, Renderer> + 'a,
236{
237 fn from(opaque: Opaque<W>) -> Element<'a, Message, Theme, Renderer> {
238 opaque._boxed()
239 }
240}