iced_core/widget/operation/
scrollable.rs
1use crate::widget::{Id, Operation};
3use crate::{Rectangle, Vector};
4
5pub trait Scrollable {
7 fn snap_to(&mut self, offset: RelativeOffset);
9
10 fn scroll_to(&mut self, offset: AbsoluteOffset);
12
13 fn scroll_by(
15 &mut self,
16 offset: AbsoluteOffset,
17 bounds: Rectangle,
18 content_bounds: Rectangle,
19 );
20}
21
22pub fn snap_to<T>(target: Id, offset: RelativeOffset) -> impl Operation<T> {
25 struct SnapTo {
26 target: Id,
27 offset: RelativeOffset,
28 }
29
30 impl<T> Operation<T> for SnapTo {
31 fn container(
32 &mut self,
33 _id: Option<&Id>,
34 _bounds: Rectangle,
35 operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
36 ) {
37 operate_on_children(self);
38 }
39
40 fn scrollable(
41 &mut self,
42 id: Option<&Id>,
43 _bounds: Rectangle,
44 _content_bounds: Rectangle,
45 _translation: Vector,
46 state: &mut dyn Scrollable,
47 ) {
48 if Some(&self.target) == id {
49 state.snap_to(self.offset);
50 }
51 }
52 }
53
54 SnapTo { target, offset }
55}
56
57pub fn scroll_to<T>(target: Id, offset: AbsoluteOffset) -> impl Operation<T> {
60 struct ScrollTo {
61 target: Id,
62 offset: AbsoluteOffset,
63 }
64
65 impl<T> Operation<T> for ScrollTo {
66 fn container(
67 &mut self,
68 _id: Option<&Id>,
69 _bounds: Rectangle,
70 operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
71 ) {
72 operate_on_children(self);
73 }
74
75 fn scrollable(
76 &mut self,
77 id: Option<&Id>,
78 _bounds: Rectangle,
79 _content_bounds: Rectangle,
80 _translation: Vector,
81 state: &mut dyn Scrollable,
82 ) {
83 if Some(&self.target) == id {
84 state.scroll_to(self.offset);
85 }
86 }
87 }
88
89 ScrollTo { target, offset }
90}
91
92pub fn scroll_by<T>(target: Id, offset: AbsoluteOffset) -> impl Operation<T> {
95 struct ScrollBy {
96 target: Id,
97 offset: AbsoluteOffset,
98 }
99
100 impl<T> Operation<T> for ScrollBy {
101 fn container(
102 &mut self,
103 _id: Option<&Id>,
104 _bounds: Rectangle,
105 operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
106 ) {
107 operate_on_children(self);
108 }
109
110 fn scrollable(
111 &mut self,
112 id: Option<&Id>,
113 bounds: Rectangle,
114 content_bounds: Rectangle,
115 _translation: Vector,
116 state: &mut dyn Scrollable,
117 ) {
118 if Some(&self.target) == id {
119 state.scroll_by(self.offset, bounds, content_bounds);
120 }
121 }
122 }
123
124 ScrollBy { target, offset }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Default)]
129pub struct AbsoluteOffset {
130 pub x: f32,
132 pub y: f32,
134}
135
136#[derive(Debug, Clone, Copy, PartialEq, Default)]
140pub struct RelativeOffset {
141 pub x: f32,
143 pub y: f32,
145}
146
147impl RelativeOffset {
148 pub const START: Self = Self { x: 0.0, y: 0.0 };
150
151 pub const END: Self = Self { x: 1.0, y: 1.0 };
153}