iced_core/widget/operation/
scrollable.rs1use crate::widget::{Id, Operation};
3use crate::{Rectangle, Vector};
4
5pub trait Scrollable {
7 fn snap_to(&mut self, offset: RelativeOffset<Option<f32>>);
9
10 fn scroll_to(&mut self, offset: AbsoluteOffset<Option<f32>>);
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>(
25 target: Id,
26 offset: RelativeOffset<Option<f32>>,
27) -> impl Operation<T> {
28 struct SnapTo {
29 target: Id,
30 offset: RelativeOffset<Option<f32>>,
31 }
32
33 impl<T> Operation<T> for SnapTo {
34 fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
35 operate(self);
36 }
37
38 fn scrollable(
39 &mut self,
40 id: Option<&Id>,
41 _bounds: Rectangle,
42 _content_bounds: Rectangle,
43 _translation: Vector,
44 state: &mut dyn Scrollable,
45 ) {
46 if Some(&self.target) == id {
47 state.snap_to(self.offset);
48 }
49 }
50 }
51
52 SnapTo { target, offset }
53}
54
55pub fn scroll_to<T>(
58 target: Id,
59 offset: AbsoluteOffset<Option<f32>>,
60) -> impl Operation<T> {
61 struct ScrollTo {
62 target: Id,
63 offset: AbsoluteOffset<Option<f32>>,
64 }
65
66 impl<T> Operation<T> for ScrollTo {
67 fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
68 operate(self);
69 }
70
71 fn scrollable(
72 &mut self,
73 id: Option<&Id>,
74 _bounds: Rectangle,
75 _content_bounds: Rectangle,
76 _translation: Vector,
77 state: &mut dyn Scrollable,
78 ) {
79 if Some(&self.target) == id {
80 state.scroll_to(self.offset);
81 }
82 }
83 }
84
85 ScrollTo { target, offset }
86}
87
88pub fn scroll_by<T>(target: Id, offset: AbsoluteOffset) -> impl Operation<T> {
91 struct ScrollBy {
92 target: Id,
93 offset: AbsoluteOffset,
94 }
95
96 impl<T> Operation<T> for ScrollBy {
97 fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
98 operate(self);
99 }
100
101 fn scrollable(
102 &mut self,
103 id: Option<&Id>,
104 bounds: Rectangle,
105 content_bounds: Rectangle,
106 _translation: Vector,
107 state: &mut dyn Scrollable,
108 ) {
109 if Some(&self.target) == id {
110 state.scroll_by(self.offset, bounds, content_bounds);
111 }
112 }
113 }
114
115 ScrollBy { target, offset }
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Default)]
120pub struct AbsoluteOffset<T = f32> {
121 pub x: T,
123 pub y: T,
125}
126
127impl From<AbsoluteOffset> for AbsoluteOffset<Option<f32>> {
128 fn from(offset: AbsoluteOffset) -> Self {
129 Self {
130 x: Some(offset.x),
131 y: Some(offset.y),
132 }
133 }
134}
135
136#[derive(Debug, Clone, Copy, PartialEq, Default)]
140pub struct RelativeOffset<T = f32> {
141 pub x: T,
143 pub y: T,
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}
154
155impl From<RelativeOffset> for RelativeOffset<Option<f32>> {
156 fn from(offset: RelativeOffset) -> Self {
157 Self {
158 x: Some(offset.x),
159 y: Some(offset.y),
160 }
161 }
162}