1//! Display interactive elements on top of other widgets.
2mod element;
3mod group;
45pub use element::Element;
6pub use group::Group;
78use crate::layout;
9use crate::mouse;
10use crate::renderer;
11use crate::widget;
12use crate::widget::Tree;
13use crate::{Clipboard, Event, 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 a [`widget::Operation`] to the [`Overlay`].
39fn operate(
40&mut self,
41 _layout: Layout<'_>,
42 _renderer: &Renderer,
43 _operation: &mut dyn widget::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 update(
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 ) {
68 }
6970/// Returns the current [`mouse::Interaction`] of the [`Overlay`].
71 ///
72 /// By default, it returns [`mouse::Interaction::Idle`].
73fn mouse_interaction(
74&self,
75 _layout: Layout<'_>,
76 _cursor: mouse::Cursor,
77 _viewport: &Rectangle,
78 _renderer: &Renderer,
79 ) -> mouse::Interaction {
80 mouse::Interaction::None
81 }
8283/// Returns true if the cursor is over the [`Overlay`].
84 ///
85 /// By default, it returns true if the bounds of the `layout` contain
86 /// the `cursor_position`.
87fn is_over(
88&self,
89 layout: Layout<'_>,
90 _renderer: &Renderer,
91 cursor_position: Point,
92 ) -> bool {
93 layout.bounds().contains(cursor_position)
94 }
9596/// Returns the nested overlay of the [`Overlay`], if there is any.
97fn overlay<'a>(
98&'a mut self,
99 _layout: Layout<'_>,
100 _renderer: &Renderer,
101 ) -> Option<Element<'a, Message, Theme, Renderer>> {
102None
103}
104}
105106/// Returns a [`Group`] of overlay [`Element`] children.
107///
108/// This method will generally only be used by advanced users that are
109/// implementing the [`Widget`](crate::Widget) trait.
110pub fn from_children<'a, Message, Theme, Renderer>(
111 children: &'a mut [crate::Element<'_, Message, Theme, Renderer>],
112 tree: &'a mut Tree,
113 layout: Layout<'_>,
114 renderer: &Renderer,
115 translation: Vector,
116) -> Option<Element<'a, Message, Theme, Renderer>>
117where
118Renderer: crate::Renderer,
119{
120let children = children
121 .iter_mut()
122 .zip(&mut tree.children)
123 .zip(layout.children())
124 .filter_map(|((child, state), layout)| {
125 child
126 .as_widget_mut()
127 .overlay(state, layout, renderer, translation)
128 })
129 .collect::<Vec<_>>();
130131 (!children.is_empty()).then(|| Group::with_children(children).overlay())
132}