iced_native/widget/operation/
scrollable.rs

1//! Operate on widgets that can be scrolled.
2use crate::widget::{Id, Operation};
3
4/// The internal state of a widget that can be scrolled.
5pub trait Scrollable {
6    /// Snaps the scroll of the widget to the given `percentage` along the horizontal & vertical axis.
7    fn snap_to(&mut self, offset: RelativeOffset);
8}
9
10/// Produces an [`Operation`] that snaps the widget with the given [`Id`] to
11/// the provided `percentage`.
12pub fn snap_to<T>(target: Id, offset: RelativeOffset) -> impl Operation<T> {
13    struct SnapTo {
14        target: Id,
15        offset: RelativeOffset,
16    }
17
18    impl<T> Operation<T> for SnapTo {
19        fn container(
20            &mut self,
21            _id: Option<&Id>,
22            operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
23        ) {
24            operate_on_children(self)
25        }
26
27        fn scrollable(&mut self, state: &mut dyn Scrollable, id: Option<&Id>) {
28            if Some(&self.target) == id {
29                state.snap_to(self.offset);
30            }
31        }
32    }
33
34    SnapTo { target, offset }
35}
36
37/// The amount of offset in each direction of a [`Scrollable`].
38///
39/// A value of `0.0` means start, while `1.0` means end.
40#[derive(Debug, Clone, Copy, PartialEq, Default)]
41pub struct RelativeOffset {
42    /// The amount of horizontal offset
43    pub x: f32,
44    /// The amount of vertical offset
45    pub y: f32,
46}
47
48impl RelativeOffset {
49    /// A relative offset that points to the top-left of a [`Scrollable`].
50    pub const START: Self = Self { x: 0.0, y: 0.0 };
51
52    /// A relative offset that points to the bottom-right of a [`Scrollable`].
53    pub const END: Self = Self { x: 1.0, y: 1.0 };
54}