freya_components/scrollviews/
scrollthumb.rs1use freya_core::prelude::*;
2use torin::{
3 prelude::{
4 Alignment,
5 Gaps,
6 },
7 size::Size,
8};
9
10use crate::{
11 get_theme,
12 scrollviews::{
13 Axis,
14 ScrollBarThemePartial,
15 ScrollBarThemePreference,
16 ScrollBarThumbEvents,
17 },
18};
19
20#[derive(PartialEq)]
21enum ScrollThumbState {
22 Idle,
23 Hovering,
24}
25
26#[derive(Clone, PartialEq)]
27pub struct ScrollThumb {
28 pub theme: Option<ScrollBarThemePartial>,
29 pub clicking_scrollbar: State<Option<(Axis, f64)>>,
30 pub thumb_events: ScrollBarThumbEvents,
31 pub axis: Axis,
32 pub size: f32,
33 pub cross_size: f32,
34 pub cross_gap: f32,
35}
36
37impl ComponentOwned for ScrollThumb {
38 fn render(self) -> impl IntoElement {
39 let scrollbar_theme = get_theme!(&self.theme, ScrollBarThemePreference, "scrollbar");
40 let mut state = use_state(|| ScrollThumbState::Idle);
41
42 let (width, height, pill_width, pill_height, padding, main_align, cross_align) =
43 match self.axis {
44 Axis::X => (
45 Size::px(self.size),
46 Size::fill(),
47 Size::fill(),
48 Size::px(self.cross_size),
49 Gaps::new(0., 0., self.cross_gap, 0.),
50 Alignment::end(),
51 Alignment::start(),
52 ),
53 Axis::Y => (
54 Size::fill(),
55 Size::px(self.size),
56 Size::px(self.cross_size),
57 Size::fill(),
58 Gaps::new(0., self.cross_gap, 0., 0.),
59 Alignment::start(),
60 Alignment::end(),
61 ),
62 };
63
64 let thumb_background = match *state.read() {
65 _ if self.clicking_scrollbar.read().is_some() => {
66 scrollbar_theme.active_thumb_background
67 }
68 ScrollThumbState::Hovering => scrollbar_theme.hover_thumb_background,
69 ScrollThumbState::Idle => scrollbar_theme.thumb_background,
70 };
71
72 let on_pointer_over = move |_| state.set_if_modified(ScrollThumbState::Hovering);
73 let on_pointer_out = move |_| state.set_if_modified(ScrollThumbState::Idle);
74
75 rect()
76 .width(width)
77 .height(height)
78 .padding(padding)
79 .main_align(main_align)
80 .cross_align(cross_align)
81 .on_pointer_over(on_pointer_over)
82 .on_pointer_out(on_pointer_out)
83 .on_pointer_down(self.thumb_events.on_pointer_down)
84 .on_pointer_press(self.thumb_events.on_pointer_press)
85 .child(
86 rect()
87 .width(pill_width)
88 .height(pill_height)
89 .background(thumb_background)
90 .corner_radius(8.),
91 )
92 }
93}