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