use crate::{Recti, Vec2i};
#[derive(Copy, Clone, Debug)]
pub(crate) enum ScrollAxis {
Vertical,
Horizontal,
}
pub(crate) fn scrollbar_base(axis: ScrollAxis, body: Recti, scrollbar_size: i32) -> Recti {
let mut base = body;
match axis {
ScrollAxis::Vertical => {
base.x = body.x + body.width;
base.width = scrollbar_size;
}
ScrollAxis::Horizontal => {
base.y = body.y + body.height;
base.height = scrollbar_size;
}
}
base
}
pub(crate) fn scrollbar_max_scroll(content_len: i32, view_len: i32) -> i32 {
(content_len - view_len).max(0)
}
pub(crate) fn scrollbar_drag_delta(axis: ScrollAxis, delta: Vec2i, content_len: i32, base: Recti) -> i32 {
let base_len = match axis {
ScrollAxis::Vertical => base.height,
ScrollAxis::Horizontal => base.width,
};
if base_len <= 0 {
return 0;
}
let axis_delta = match axis {
ScrollAxis::Vertical => delta.y,
ScrollAxis::Horizontal => delta.x,
};
axis_delta.saturating_mul(content_len) / base_len
}
pub(crate) fn scrollbar_thumb(axis: ScrollAxis, base: Recti, view_len: i32, content_len: i32, scroll: i32, thumb_size: i32) -> Recti {
let mut thumb = base;
let base_len = match axis {
ScrollAxis::Vertical => base.height,
ScrollAxis::Horizontal => base.width,
};
if base_len <= 0 || content_len <= 0 || view_len <= 0 {
return thumb;
}
let mut thumb_len = base_len.saturating_mul(view_len) / content_len;
if thumb_len < thumb_size {
thumb_len = thumb_size;
}
if thumb_len > base_len {
thumb_len = base_len;
}
match axis {
ScrollAxis::Vertical => thumb.height = thumb_len,
ScrollAxis::Horizontal => thumb.width = thumb_len,
}
let max_scroll = scrollbar_max_scroll(content_len, view_len);
if max_scroll > 0 {
let track_len = base_len - thumb_len;
if track_len > 0 {
let offset = scroll.clamp(0, max_scroll) * track_len / max_scroll;
match axis {
ScrollAxis::Vertical => thumb.y += offset,
ScrollAxis::Horizontal => thumb.x += offset,
}
}
}
thumb
}