Skip to main content

fui/node/
scroll_state.rs

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}