Skip to content

Commit a596abf

Browse files
committed
Support overlays in tester devtool
1 parent baa7d2b commit a596abf

1 file changed

Lines changed: 156 additions & 30 deletions

File tree

devtools/src/tester/recorder.rs

Lines changed: 156 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::core::layout;
22
use crate::core::mouse;
3+
use crate::core::overlay;
34
use crate::core::renderer;
45
use crate::core::widget;
56
use crate::core::widget::tree;
67
use crate::core::{
78
self, Clipboard, Element, Event, Layout, Length, Point, Rectangle, Shell,
8-
Size, Widget,
9+
Size, Vector, Widget,
910
};
1011

1112
pub fn recorder<'a, Message, Theme, Renderer>(
@@ -64,35 +65,7 @@ where
6465
);
6566

6667
if let Some(on_event) = &self.on_event {
67-
match event {
68-
Event::Mouse(event) => {
69-
if !cursor.is_over(layout.bounds()) {
70-
return;
71-
}
72-
73-
match event {
74-
mouse::Event::ButtonPressed(_)
75-
| mouse::Event::ButtonReleased(_)
76-
| mouse::Event::WheelScrolled { .. } => {
77-
shell.publish(on_event(Event::Mouse(*event)));
78-
}
79-
mouse::Event::CursorMoved { position } => {
80-
shell.publish(on_event(Event::Mouse(
81-
mouse::Event::CursorMoved {
82-
position: *position
83-
- (layout.bounds().position()
84-
- Point::ORIGIN),
85-
},
86-
)));
87-
}
88-
_ => {}
89-
}
90-
}
91-
Event::Keyboard(event) => {
92-
shell.publish(on_event(Event::Keyboard(event.clone())));
93-
}
94-
_ => {}
95-
}
68+
record(event, cursor, shell, layout.bounds(), on_event);
9669
}
9770
}
9871

@@ -168,6 +141,26 @@ where
168141
.as_widget()
169142
.operate(state, layout, renderer, operation);
170143
}
144+
145+
fn overlay<'a>(
146+
&'a mut self,
147+
state: &'a mut widget::Tree,
148+
layout: Layout<'a>,
149+
renderer: &Renderer,
150+
_viewport: &Rectangle,
151+
translation: Vector,
152+
) -> Option<overlay::Element<'a, Message, Theme, Renderer>> {
153+
self.content
154+
.as_widget_mut()
155+
.overlay(state, layout, renderer, &layout.bounds(), translation)
156+
.map(|raw| {
157+
overlay::Element::new(Box::new(Overlay {
158+
raw,
159+
bounds: layout.bounds(),
160+
on_event: self.on_event.as_deref(),
161+
}))
162+
})
163+
}
171164
}
172165

173166
impl<'a, Message, Theme, Renderer> From<Recorder<'a, Message, Theme, Renderer>>
@@ -181,3 +174,136 @@ where
181174
Element::new(recorder)
182175
}
183176
}
177+
178+
struct Overlay<'a, Message, Theme, Renderer> {
179+
raw: overlay::Element<'a, Message, Theme, Renderer>,
180+
bounds: Rectangle,
181+
on_event: Option<&'a dyn Fn(Event) -> Message>,
182+
}
183+
184+
impl<'a, Message, Theme, Renderer> core::Overlay<Message, Theme, Renderer>
185+
for Overlay<'a, Message, Theme, Renderer>
186+
where
187+
Renderer: core::Renderer + 'a,
188+
{
189+
fn layout(&mut self, renderer: &Renderer, _bounds: Size) -> layout::Node {
190+
self.raw
191+
.as_overlay_mut()
192+
.layout(renderer, self.bounds.size())
193+
}
194+
195+
fn draw(
196+
&self,
197+
renderer: &mut Renderer,
198+
theme: &Theme,
199+
style: &renderer::Style,
200+
layout: Layout<'_>,
201+
cursor: mouse::Cursor,
202+
) {
203+
self.raw
204+
.as_overlay()
205+
.draw(renderer, theme, style, layout, cursor);
206+
}
207+
208+
fn operate(
209+
&mut self,
210+
layout: Layout<'_>,
211+
renderer: &Renderer,
212+
operation: &mut dyn widget::Operation,
213+
) {
214+
self.raw
215+
.as_overlay_mut()
216+
.operate(layout, renderer, operation);
217+
}
218+
219+
fn update(
220+
&mut self,
221+
event: &Event,
222+
layout: Layout<'_>,
223+
cursor: mouse::Cursor,
224+
renderer: &Renderer,
225+
clipboard: &mut dyn Clipboard,
226+
shell: &mut Shell<'_, Message>,
227+
) {
228+
if shell.is_event_captured() {
229+
return;
230+
}
231+
232+
self.raw
233+
.as_overlay_mut()
234+
.update(event, layout, cursor, renderer, clipboard, shell);
235+
236+
if let Some(on_event) = &self.on_event {
237+
record(event, cursor, shell, self.bounds, on_event);
238+
}
239+
}
240+
241+
fn mouse_interaction(
242+
&self,
243+
layout: Layout<'_>,
244+
cursor: mouse::Cursor,
245+
renderer: &Renderer,
246+
) -> mouse::Interaction {
247+
self.raw
248+
.as_overlay()
249+
.mouse_interaction(layout, cursor, renderer)
250+
}
251+
252+
fn overlay<'b>(
253+
&'b mut self,
254+
layout: Layout<'b>,
255+
renderer: &Renderer,
256+
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
257+
self.raw
258+
.as_overlay_mut()
259+
.overlay(layout, renderer)
260+
.map(|raw| {
261+
overlay::Element::new(Box::new(Overlay {
262+
raw,
263+
bounds: self.bounds,
264+
on_event: self.on_event,
265+
}))
266+
})
267+
}
268+
269+
fn index(&self) -> f32 {
270+
self.raw.as_overlay().index()
271+
}
272+
}
273+
274+
fn record<Message>(
275+
event: &Event,
276+
cursor: mouse::Cursor,
277+
shell: &mut Shell<'_, Message>,
278+
bounds: Rectangle,
279+
on_event: impl Fn(Event) -> Message,
280+
) {
281+
match event {
282+
Event::Mouse(event) => {
283+
if !cursor.is_over(bounds) {
284+
return;
285+
}
286+
287+
match event {
288+
mouse::Event::ButtonPressed(_)
289+
| mouse::Event::ButtonReleased(_)
290+
| mouse::Event::WheelScrolled { .. } => {
291+
shell.publish(on_event(Event::Mouse(*event)));
292+
}
293+
mouse::Event::CursorMoved { position } => {
294+
shell.publish(on_event(Event::Mouse(
295+
mouse::Event::CursorMoved {
296+
position: *position
297+
- (bounds.position() - Point::ORIGIN),
298+
},
299+
)));
300+
}
301+
_ => {}
302+
}
303+
}
304+
Event::Keyboard(event) => {
305+
shell.publish(on_event(Event::Keyboard(event.clone())));
306+
}
307+
_ => {}
308+
}
309+
}

0 commit comments

Comments
 (0)