freya-components 0.5.0-beta.12

Components for Freya apps
Documentation
use freya_core::prelude::*;
use torin::{
    prelude::{
        Alignment,
        Gaps,
    },
    size::Size,
};

use crate::{
    get_theme,
    scrollviews::{
        Axis,
        ScrollBarThemePartial,
        ScrollBarThemePreference,
        ScrollBarThumbEvents,
    },
};

#[derive(PartialEq)]
enum ScrollThumbState {
    Idle,
    Hovering,
}

#[derive(Clone, PartialEq)]
pub struct ScrollThumb {
    pub theme: Option<ScrollBarThemePartial>,
    pub clicking_scrollbar: State<Option<(Axis, f64)>>,
    pub thumb_events: ScrollBarThumbEvents,
    pub axis: Axis,
    pub size: f32,
    pub cross_size: f32,
    pub cross_gap: f32,
}

impl ComponentOwned for ScrollThumb {
    fn render(self) -> impl IntoElement {
        let scrollbar_theme = get_theme!(&self.theme, ScrollBarThemePreference, "scrollbar");
        let mut state = use_state(|| ScrollThumbState::Idle);

        let (width, height, pill_width, pill_height, padding, main_align, cross_align) =
            match self.axis {
                Axis::X => (
                    Size::px(self.size),
                    Size::fill(),
                    Size::fill(),
                    Size::px(self.cross_size),
                    Gaps::new(0., 0., self.cross_gap, 0.),
                    Alignment::end(),
                    Alignment::start(),
                ),
                Axis::Y => (
                    Size::fill(),
                    Size::px(self.size),
                    Size::px(self.cross_size),
                    Size::fill(),
                    Gaps::new(0., self.cross_gap, 0., 0.),
                    Alignment::start(),
                    Alignment::end(),
                ),
            };

        let thumb_background = match *state.read() {
            _ if self.clicking_scrollbar.read().is_some() => {
                scrollbar_theme.active_thumb_background
            }
            ScrollThumbState::Hovering => scrollbar_theme.hover_thumb_background,
            ScrollThumbState::Idle => scrollbar_theme.thumb_background,
        };

        let on_pointer_over = move |_| state.set_if_modified(ScrollThumbState::Hovering);
        let on_pointer_out = move |_| state.set_if_modified(ScrollThumbState::Idle);

        rect()
            .width(width)
            .height(height)
            .padding(padding)
            .main_align(main_align)
            .cross_align(cross_align)
            .on_pointer_over(on_pointer_over)
            .on_pointer_out(on_pointer_out)
            .on_pointer_down(self.thumb_events.on_pointer_down)
            .on_pointer_press(self.thumb_events.on_pointer_press)
            .child(
                rect()
                    .width(pill_width)
                    .height(pill_height)
                    .background(thumb_background)
                    .corner_radius(8.),
            )
    }
}