freya_components/scrollviews/
scrollthumb.rs

1use freya_core::prelude::*;
2use torin::size::Size;
3enum ScrollThumbState {
4    Idle,
5    Hovering,
6}
7
8use crate::{
9    get_theme,
10    scrollviews::shared::Axis,
11    theming::component_themes::ScrollBarThemePartial,
12};
13
14#[derive(Clone, PartialEq)]
15pub struct ScrollThumb {
16    pub(crate) theme: Option<ScrollBarThemePartial>,
17    pub clicking_scrollbar: State<Option<(Axis, f64)>>,
18    pub axis: Axis,
19    pub size: f32,
20}
21
22impl RenderOwned for ScrollThumb {
23    fn render(mut self) -> impl IntoElement {
24        let scrollbar_theme = get_theme!(&self.theme, scrollbar);
25        let mut state = use_state(|| ScrollThumbState::Idle);
26
27        let (width, height) = match self.axis {
28            Axis::X => (Size::px(self.size), Size::fill()),
29            Axis::Y => (Size::fill(), Size::px(self.size)),
30        };
31        let thumb_background = match *state.read() {
32            _ if self.clicking_scrollbar.read().is_some() => {
33                scrollbar_theme.active_thumb_background
34            }
35            ScrollThumbState::Idle => scrollbar_theme.thumb_background,
36            ScrollThumbState::Hovering => scrollbar_theme.hover_thumb_background,
37        };
38
39        let on_pointer_enter = move |_| state.set(ScrollThumbState::Hovering);
40        let on_pointer_leave = move |_| state.set(ScrollThumbState::Idle);
41
42        rect()
43            .width(width)
44            .height(height)
45            .padding(4.)
46            .on_pointer_enter(on_pointer_enter)
47            .on_pointer_leave(on_pointer_leave)
48            .on_pointer_down(move |e: Event<PointerEventData>| {
49                if self.axis == Axis::X {
50                    self.clicking_scrollbar
51                        .set(Some((self.axis, e.element_location().x)));
52                } else {
53                    self.clicking_scrollbar
54                        .set(Some((self.axis, e.element_location().y)));
55                }
56            })
57            .child(
58                rect()
59                    .width(Size::fill())
60                    .height(Size::fill())
61                    .background(thumb_background)
62                    .corner_radius(8.),
63            )
64    }
65}