1use crate::signal::{Callback, Signal, Subscription};
2use std::cell::RefCell;
3use std::rc::Rc;
4
5fn set_signal(signal: &Rc<RefCell<Signal<f32>>>, next: f32) {
6 let callbacks = signal.borrow_mut().set(next);
7 if let Some(callbacks) = callbacks {
8 for callback in callbacks {
9 callback();
10 }
11 }
12}
13
14fn subscribe_signal(
15 signal: &Rc<RefCell<Signal<f32>>>,
16 handler: impl Fn() + 'static,
17) -> Subscription {
18 let callback: Callback = Rc::new(handler);
19 signal.borrow_mut().subscribe(callback)
20}
21
22#[derive(Clone)]
23pub struct ScrollState {
24 offset_x: Rc<RefCell<Signal<f32>>>,
25 offset_y: Rc<RefCell<Signal<f32>>>,
26 content_width: Rc<RefCell<Signal<f32>>>,
27 content_height: Rc<RefCell<Signal<f32>>>,
28 viewport_width: Rc<RefCell<Signal<f32>>>,
29 viewport_height: Rc<RefCell<Signal<f32>>>,
30}
31
32impl Default for ScrollState {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37
38impl ScrollState {
39 pub fn new() -> Self {
40 Self {
41 offset_x: Rc::new(RefCell::new(Signal::new(0.0))),
42 offset_y: Rc::new(RefCell::new(Signal::new(0.0))),
43 content_width: Rc::new(RefCell::new(Signal::new(0.0))),
44 content_height: Rc::new(RefCell::new(Signal::new(0.0))),
45 viewport_width: Rc::new(RefCell::new(Signal::new(0.0))),
46 viewport_height: Rc::new(RefCell::new(Signal::new(0.0))),
47 }
48 }
49
50 pub fn offset_x(&self) -> f32 {
51 self.offset_x.borrow().get()
52 }
53
54 pub fn offset_y(&self) -> f32 {
55 self.offset_y.borrow().get()
56 }
57
58 pub fn content_width(&self) -> f32 {
59 self.content_width.borrow().get()
60 }
61
62 pub fn content_height(&self) -> f32 {
63 self.content_height.borrow().get()
64 }
65
66 pub fn viewport_width(&self) -> f32 {
67 self.viewport_width.borrow().get()
68 }
69
70 pub fn viewport_height(&self) -> f32 {
71 self.viewport_height.borrow().get()
72 }
73
74 pub fn set_offset_x(&self, next: f32) {
75 set_signal(&self.offset_x, next);
76 }
77
78 pub fn set_offset_y(&self, next: f32) {
79 set_signal(&self.offset_y, next);
80 }
81
82 pub fn set_content_width(&self, next: f32) {
83 set_signal(&self.content_width, next);
84 }
85
86 pub fn set_content_height(&self, next: f32) {
87 set_signal(&self.content_height, next);
88 }
89
90 pub fn set_viewport_width(&self, next: f32) {
91 set_signal(&self.viewport_width, next);
92 }
93
94 pub fn set_viewport_height(&self, next: f32) {
95 set_signal(&self.viewport_height, next);
96 }
97
98 pub fn subscribe_offset_x(&self, handler: impl Fn() + 'static) -> Subscription {
99 subscribe_signal(&self.offset_x, handler)
100 }
101
102 pub fn subscribe_offset_y(&self, handler: impl Fn() + 'static) -> Subscription {
103 subscribe_signal(&self.offset_y, handler)
104 }
105
106 pub fn subscribe_content_width(&self, handler: impl Fn() + 'static) -> Subscription {
107 subscribe_signal(&self.content_width, handler)
108 }
109
110 pub fn subscribe_content_height(&self, handler: impl Fn() + 'static) -> Subscription {
111 subscribe_signal(&self.content_height, handler)
112 }
113
114 pub fn subscribe_viewport_width(&self, handler: impl Fn() + 'static) -> Subscription {
115 subscribe_signal(&self.viewport_width, handler)
116 }
117
118 pub fn subscribe_viewport_height(&self, handler: impl Fn() + 'static) -> Subscription {
119 subscribe_signal(&self.viewport_height, handler)
120 }
121}