diff --git a/CHANGELOG.md b/CHANGELOG.md index 94d66d85..e36a149d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Add `Ui::hyperlink_to(label, url)`. * Sliders can now have a value prefix and suffix (e.g. the suffix `"°"` works like a unit). * `Context::set_pixels_per_point` to control the scale of the UI. +* Add support for all integers in `DragValue` and `Slider` (except 128-bit). ### Changed 🔧 diff --git a/egui/src/widgets/drag_value.rs b/egui/src/widgets/drag_value.rs index f0b23df3..796cddbb 100644 --- a/egui/src/widgets/drag_value.rs +++ b/egui/src/widgets/drag_value.rs @@ -51,6 +51,21 @@ pub struct DragValue<'a> { max_decimals: Option, } +macro_rules! impl_integer_constructor { + ($int:ident) => { + pub fn $int(value: &'a mut $int) -> Self { + Self::from_get_set(move |v: Option| { + if let Some(v) = v { + *value = v.round() as $int; + } + *value as f64 + }) + .max_decimals(0) + .clamp_range_f64(($int::MIN as f64)..=($int::MAX as f64)) + } + }; +} + impl<'a> DragValue<'a> { pub fn f32(value: &'a mut f32) -> Self { Self::from_get_set(move |v: Option| { @@ -70,25 +85,16 @@ impl<'a> DragValue<'a> { }) } - pub fn u8(value: &'a mut u8) -> Self { - Self::from_get_set(move |v: Option| { - if let Some(v) = v { - *value = v.round() as u8; - } - *value as f64 - }) - .max_decimals(0) - } - - pub fn i32(value: &'a mut i32) -> Self { - Self::from_get_set(move |v: Option| { - if let Some(v) = v { - *value = v.round() as i32; - } - *value as f64 - }) - .max_decimals(0) - } + impl_integer_constructor!(i8); + impl_integer_constructor!(u8); + impl_integer_constructor!(i16); + impl_integer_constructor!(u16); + impl_integer_constructor!(i32); + impl_integer_constructor!(u32); + impl_integer_constructor!(i64); + impl_integer_constructor!(u64); + impl_integer_constructor!(isize); + impl_integer_constructor!(usize); pub fn from_get_set(get_set_value: impl 'a + FnMut(Option) -> f64) -> Self { Self { diff --git a/egui/src/widgets/slider.rs b/egui/src/widgets/slider.rs index 03fca521..cf7a6067 100644 --- a/egui/src/widgets/slider.rs +++ b/egui/src/widgets/slider.rs @@ -18,13 +18,6 @@ fn set(get_set_value: &mut GetSetValue<'_>, value: f64) { (get_set_value)(Some(value)); } -fn to_f64_range(r: RangeInclusive) -> RangeInclusive -where - f64: From, -{ - f64::from(*r.start())..=f64::from(*r.end()) -} - // ---------------------------------------------------------------------------- #[derive(Clone)] @@ -72,7 +65,52 @@ pub struct Slider<'a> { max_decimals: Option, } +macro_rules! impl_integer_constructor { + ($int:ident) => { + pub fn $int(value: &'a mut $int, range: RangeInclusive<$int>) -> Self { + let range_f64 = (*range.start() as f64)..=(*range.end() as f64); + Self::from_get_set(range_f64, move |v: Option| { + if let Some(v) = v { + *value = v.round() as $int + } + *value as f64 + }) + .integer() + } + }; +} + impl<'a> Slider<'a> { + 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| { + if let Some(v) = v { + *value = v as f32 + } + *value as f64 + }) + } + + pub fn f64(value: &'a mut f64, range: RangeInclusive) -> Self { + Self::from_get_set(range, move |v: Option| { + if let Some(v) = v { + *value = v + } + *value + }) + } + + impl_integer_constructor!(i8); + impl_integer_constructor!(u8); + impl_integer_constructor!(i16); + impl_integer_constructor!(u16); + impl_integer_constructor!(i32); + impl_integer_constructor!(u32); + impl_integer_constructor!(i64); + impl_integer_constructor!(u64); + impl_integer_constructor!(isize); + impl_integer_constructor!(usize); + pub fn from_get_set( range: RangeInclusive, get_set_value: impl 'a + FnMut(Option) -> f64, @@ -97,65 +135,6 @@ impl<'a> Slider<'a> { } } - pub fn f32(value: &'a mut f32, range: RangeInclusive) -> Self { - Self::from_get_set(to_f64_range(range), move |v: Option| { - if let Some(v) = v { - *value = v as f32 - } - *value as f64 - }) - } - - pub fn f64(value: &'a mut f64, range: RangeInclusive) -> Self { - Self::from_get_set(to_f64_range(range), move |v: Option| { - if let Some(v) = v { - *value = v - } - *value - }) - } - - pub fn u8(value: &'a mut u8, range: RangeInclusive) -> Self { - Self::from_get_set(to_f64_range(range), move |v: Option| { - if let Some(v) = v { - *value = v.round() as u8 - } - *value as f64 - }) - .integer() - } - - pub fn i32(value: &'a mut i32, range: RangeInclusive) -> Self { - Self::from_get_set(to_f64_range(range), move |v: Option| { - if let Some(v) = v { - *value = v.round() as i32 - } - *value as f64 - }) - .integer() - } - - pub fn u32(value: &'a mut u32, range: RangeInclusive) -> Self { - Self::from_get_set(to_f64_range(range), move |v: Option| { - if let Some(v) = v { - *value = v.round() as u32 - } - *value as f64 - }) - .integer() - } - - pub fn usize(value: &'a mut usize, range: RangeInclusive) -> Self { - let range = (*range.start() as f64)..=(*range.end() as f64); - Self::from_get_set(range, move |v: Option| { - if let Some(v) = v { - *value = v.round() as usize - } - *value as f64 - }) - .integer() - } - /// Control wether or not the slider shows the current value. /// Default: `true`. pub fn show_value(mut self, show_value: bool) -> Self {