iced_core/
overlay.rs

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