diff --git a/egui/src/widgets/drag_value.rs b/egui/src/widgets/drag_value.rs index 6f21fb785..559e1883f 100644 --- a/egui/src/widgets/drag_value.rs +++ b/egui/src/widgets/drag_value.rs @@ -67,13 +67,30 @@ macro_rules! impl_integer_constructor { *value as f64 }) .max_decimals(0) - .clamp_range_f64(($int::MIN as f64)..=($int::MAX as f64)) + .clamp_range($int::MIN..=$int::MAX) .speed(0.25) } }; } impl<'a> DragValue<'a> { + pub fn new(value: &'a mut Num) -> Self { + let slf = Self::from_get_set(move |v: Option| { + if let Some(v) = v { + *value = Num::from_f64(v) + } + value.to_f64() + }); + + if Num::INTEGRAL { + slf.max_decimals(0) + .clamp_range(Num::MIN..=Num::MAX) + .speed(0.25) + } else { + slf + } + } + pub fn f32(value: &'a mut f32) -> Self { Self::from_get_set(move |v: Option| { if let Some(v) = v { @@ -122,11 +139,12 @@ impl<'a> DragValue<'a> { } /// Clamp incoming and outgoing values to this range. - pub fn clamp_range(mut self, clamp_range: RangeInclusive) -> Self { - self.clamp_range = *clamp_range.start() as f64..=*clamp_range.end() as f64; + pub fn clamp_range(mut self, clamp_range: RangeInclusive) -> Self { + self.clamp_range = clamp_range.start().to_f64()..=clamp_range.end().to_f64(); self } + #[deprecated = "Use clamp_range"] pub fn clamp_range_f64(mut self, clamp_range: RangeInclusive) -> Self { self.clamp_range = clamp_range; self diff --git a/egui/src/widgets/slider.rs b/egui/src/widgets/slider.rs index 396ab4ac6..38c28ddb4 100644 --- a/egui/src/widgets/slider.rs +++ b/egui/src/widgets/slider.rs @@ -81,6 +81,22 @@ macro_rules! impl_integer_constructor { } impl<'a> Slider<'a> { + pub fn new(value: &'a mut Num, range: RangeInclusive) -> Self { + let range_f64 = range.start().to_f64()..=range.end().to_f64(); + let slf = Self::from_get_set(range_f64, move |v: Option| { + if let Some(v) = v { + *value = Num::from_f64(v) + } + value.to_f64() + }); + + if Num::INTEGRAL { + slf.integer() + } else { + slf + } + } + pub fn f32(value: &'a mut f32, range: RangeInclusive) -> Self { let range_f64 = (*range.start() as f64)..=(*range.end() as f64); Self::from_get_set(range_f64, move |v: Option| { @@ -396,7 +412,7 @@ impl<'a> Slider<'a> { ui.add( DragValue::f64(&mut value) .speed(self.current_gradient(&x_range)) - .clamp_range_f64(self.clamp_range()) + .clamp_range(self.clamp_range()) .min_decimals(self.min_decimals) .max_decimals_opt(self.max_decimals) .suffix(self.suffix.clone()) diff --git a/emath/src/lib.rs b/emath/src/lib.rs index 44737993a..a7bf9ed86 100644 --- a/emath/src/lib.rs +++ b/emath/src/lib.rs @@ -67,6 +67,7 @@ use std::ops::{Add, Div, Mul, RangeInclusive, Sub}; // ---------------------------------------------------------------------------- pub mod align; +mod numeric; mod pos2; mod rect; mod rect_transform; @@ -76,6 +77,7 @@ mod vec2; pub use { align::{Align, Align2}, + numeric::*, pos2::*, rect::*, rect_transform::*, diff --git a/emath/src/numeric.rs b/emath/src/numeric.rs new file mode 100644 index 000000000..cef1daab5 --- /dev/null +++ b/emath/src/numeric.rs @@ -0,0 +1,60 @@ +/// Implemented for all builtin numeric types +pub trait Numeric: Clone + Copy + PartialEq + PartialOrd + 'static { + /// Is this an integer type? + const INTEGRAL: bool; + + /// Smallest finite value + const MIN: Self; + + /// Largest finite value + const MAX: Self; + + fn to_f64(self) -> f64; + + fn from_f64(num: f64) -> Self; +} + +macro_rules! impl_numeric_float { + ($t:ident) => { + impl Numeric for $t { + const INTEGRAL: bool = false; + const MIN: Self = std::$t::MIN; + const MAX: Self = std::$t::MAX; + fn to_f64(self) -> f64 { + self as f64 + } + fn from_f64(num: f64) -> Self { + num as Self + } + } + }; +} + +macro_rules! impl_numeric_integer { + ($t:ident) => { + impl Numeric for $t { + const INTEGRAL: bool = true; + const MIN: Self = std::$t::MIN; + const MAX: Self = std::$t::MAX; + fn to_f64(self) -> f64 { + self as f64 + } + fn from_f64(num: f64) -> Self { + num as Self + } + } + }; +} + +impl_numeric_float!(f32); +impl_numeric_float!(f64); +impl_numeric_integer!(i8); +impl_numeric_integer!(u8); +impl_numeric_integer!(i16); +impl_numeric_integer!(u16); +impl_numeric_integer!(i32); +impl_numeric_integer!(u32); +impl_numeric_integer!(i64); +impl_numeric_integer!(u64); +impl_numeric_integer!(isize); +impl_numeric_integer!(usize);