1//! Display interactive elements on top of other widgets.
2mod element;
3mod group;
45pub use element::Element;
6pub use group::Group;
78use crate::event::{self, Event};
9use crate::layout;
10use crate::mouse;
11use crate::renderer;
12use crate::widget::{Operation, Tree};
13use crate::{Clipboard, Layout, Point, Rectangle, Shell, Size, Vector};
1415/// An interactive component that can be displayed on top of other widgets.
16pub trait Overlay<Message, Theme, Renderer>
17where
18Renderer: crate::Renderer,
19{
20/// Returns the layout [`Node`] of the [`Overlay`].
21 ///
22 /// This [`Node`] is used by the runtime to compute the [`Layout`] of the
23 /// user interface.
24 ///
25 /// [`Node`]: layout::Node
26fn layout(&mut self, renderer: &Renderer, bounds: Size) -> layout::Node;
2728/// Draws the [`Overlay`] using the associated `Renderer`.
29fn draw(
30&self,
31 renderer: &mut Renderer,
32 theme: &Theme,
33 style: &renderer::Style,
34 layout: Layout<'_>,
35 cursor: mouse::Cursor,
36 );
3738/// Applies an [`crate::widget::Operation`] to the [`Overlay`].
39fn operate(
40&mut self,
41 _layout: Layout<'_>,
42 _renderer: &Renderer,
43 _operation: &mut dyn Operation,
44 ) {
45 }
4647/// Processes a runtime [`Event`].
48 ///
49 /// It receives:
50 /// * an [`Event`] describing user interaction
51 /// * the computed [`Layout`] of the [`Overlay`]
52 /// * the current cursor position
53 /// * a mutable `Message` list, allowing the [`Overlay`] to produce
54 /// new messages based on user interaction.
55 /// * the `Renderer`
56 /// * a [`Clipboard`], if available
57 ///
58 /// By default, it does nothing.
59fn on_event(
60&mut self,
61 _event: Event,
62 _layout: Layout<'_>,
63 _cursor: mouse::Cursor,
64 _renderer: &Renderer,
65 _clipboard: &mut dyn Clipboard,
66 _shell: &mut Shell<'_, Message>,
67 ) -> event::Status {
68 event::Status::Ignored
69 }
7071/// Returns the current [`mouse::Interaction`] of the [`Overlay`].
72 ///
73 /// By default, it returns [`mouse::Interaction::Idle`].
74fn mouse_interaction(
75&self,
76 _layout: Layout<'_>,
77 _cursor: mouse::Cursor,
78 _viewport: &Rectangle,
79 _renderer: &Renderer,
80 ) -> mouse::Interaction {
81 mouse::Interaction::None
82 }
8384/// Returns true if the cursor is over the [`Overlay`].
85 ///
86 /// By default, it returns true if the bounds of the `layout` contain
87 /// the `cursor_position`.
88fn is_over(
89&self,
90 layout: Layout<'_>,
91 _renderer: &Renderer,
92 cursor_position: Point,
93 ) -> bool {
94 layout.bounds().contains(cursor_position)
95 }
9697/// Returns the nested overlay of the [`Overlay`], if there is any.
98fn overlay<'a>(
99&'a mut self,
100 _layout: Layout<'_>,
101 _renderer: &Renderer,
102 ) -> Option<Element<'a, Message, Theme, Renderer>> {
103None
104}
105}
106107/// Returns a [`Group`] of overlay [`Element`] children.
108///
109/// This method will generally only be used by advanced users that are
110/// implementing the [`Widget`](crate::Widget) trait.
111pub fn from_children<'a, Message, Theme, Renderer>(
112 children: &'a mut [crate::Element<'_, Message, Theme, Renderer>],
113 tree: &'a mut Tree,
114 layout: Layout<'_>,
115 renderer: &Renderer,
116 translation: Vector,
117) -> Option<Element<'a, Message, Theme, Renderer>>
118where
119Renderer: crate::Renderer,
120{
121let children = children
122 .iter_mut()
123 .zip(&mut tree.children)
124 .zip(layout.children())
125 .filter_map(|((child, state), c_layout)| {
126 child.as_widget_mut().overlay(
127 state,
128 c_layout.with_virtual_offset(layout.virtual_offset()),
129 renderer,
130 translation,
131 )
132 })
133 .collect::<Vec<_>>();
134135 (!children.is_empty()).then(|| Group::with_children(children).overlay())
136}