use dioxus::prelude::Key;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SplitUnit {
Percent,
Px,
}
impl SplitUnit {
#[must_use]
pub const fn suffix(self) -> &'static str {
match self {
Self::Percent => "%",
Self::Px => "px",
}
}
#[must_use]
pub const fn step(self) -> f64 {
match self {
Self::Percent => 5.0,
Self::Px => 16.0,
}
}
}
#[must_use]
pub fn settle(value: f64, min: f64, max: f64, unit: SplitUnit) -> f64 {
let clamped = value.clamp(min, max.max(min));
match unit {
SplitUnit::Percent => (clamped * 10.0).round() / 10.0,
SplitUnit::Px => clamped.round(),
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct KeyContext {
pub inline: bool,
pub rtl: bool,
pub growth: f64,
pub current: f64,
pub min: f64,
pub max: f64,
pub step: f64,
pub restore: Option<f64>,
}
#[must_use]
pub fn key_value(key: &Key, shift: bool, bar: KeyContext) -> Option<(f64, Option<f64>)> {
let step = bar.step * if shift { 10.0 } else { 1.0 };
let toward_end = match (bar.inline, key) {
(true, Key::ArrowRight) => {
if bar.rtl {
-1.0
} else {
1.0
}
}
(true, Key::ArrowLeft) => {
if bar.rtl {
1.0
} else {
-1.0
}
}
(false, Key::ArrowDown) => 1.0,
(false, Key::ArrowUp) => -1.0,
_ => 0.0,
};
if toward_end != 0.0 {
return Some((bar.current + toward_end * bar.growth * step, None));
}
match key {
Key::Home => Some((bar.min, None)),
Key::End => Some((bar.max, None)),
Key::Enter if bar.current > bar.min => Some((bar.min, Some(bar.current))),
Key::Enter => Some((bar.restore.unwrap_or(bar.max), None)),
_ => None,
}
}
#[must_use]
pub fn drag_value(start: f64, delta: f64, per_pixel: f64, growth: f64, rtl_inline: bool) -> f64 {
let sign = growth * if rtl_inline { -1.0 } else { 1.0 };
start + sign * delta * per_pixel
}