canary-rs/scripts/sao-ui/src/widgets/slider.rs

113 lines
2.6 KiB
Rust

// Copyright (c) 2022 Marceline Crmaer
// SPDX-License-Identifier: AGPL-3.0-or-later
use super::prelude::*;
pub struct SliderStyle {
pub bg_color: Color,
pub bg_padding: f32,
pub bg_rounding: f32,
pub fg_color: Color,
}
impl Default for SliderStyle {
fn default() -> Self {
Self {
bg_color: THEME.palette.overlay,
bg_padding: 2.5,
bg_rounding: 2.5,
fg_color: THEME.palette.blue,
}
}
}
pub struct Slider {
style: SliderStyle,
bg_rect: Rect,
fg_rect: Rect,
position: f32,
dirty: bool,
updating: bool,
}
impl Slider {
pub fn new(style: SliderStyle, rect: Rect) -> Self {
Self {
style,
bg_rect: rect,
fg_rect: rect,
position: 0.5,
dirty: true,
updating: false,
}
}
pub fn set_position(&mut self, position: f32) {
if !self.updating {
self.position = position;
self.dirty = true;
}
}
pub fn has_update(&mut self) -> Option<f32> {
if self.updating {
Some(self.position)
} else {
None
}
}
pub fn set_rect(&mut self, rect: Rect) {
self.bg_rect = rect;
self.dirty = true;
}
fn undirty(&mut self) {
if !self.dirty {
return;
}
let mut fg_space = self.bg_rect.inset(self.style.bg_padding);
fg_space.br.x = (fg_space.width() * self.position) + fg_space.tl.x;
self.fg_rect = fg_space;
self.dirty = false;
}
pub fn get_position(&self) -> f32 {
self.position
}
}
impl Widget for Slider {
fn draw(&mut self, ctx: &DrawContext) {
self.undirty();
ctx.draw_rounded_rect(self.bg_rect, self.style.bg_rounding, self.style.bg_color);
ctx.draw_rect(self.fg_rect, self.style.fg_color);
}
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
if let CursorEventKind::Select = kind {
if self.bg_rect.contains_point(at) {
self.updating = true;
}
}
if !self.updating {
return;
}
match kind {
CursorEventKind::Hover => {}
CursorEventKind::Select | CursorEventKind::Drag => {
let offset = at.x - self.fg_rect.tl.x;
let range = self.bg_rect.inset(self.style.bg_padding).width();
self.position = (offset / range).clamp(0.0, 1.0);
self.dirty = true;
}
CursorEventKind::Deselect => {
self.updating = false;
}
}
}
}