From 806608740aa36fa6cdd3fcd21ebf1ae99afdceda Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 19 Sep 2020 14:54:03 +0300 Subject: [PATCH] Update slider API slightly --- CHANGELOG.markdown | 2 + imgui-examples/examples/test_window_impl.rs | 10 ++- src/widget/drag.rs | 1 + src/widget/slider.rs | 74 ++++++++++++++++----- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index e99d656..45d18c6 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -18,6 +18,8 @@ - Upgrade to cimgui / imgui 1.78 - Store per-texture sampler parameters in imgui-glium-renderer to support customizing them +- Slider widget constructors no longer require the range parameter. Call the + range function on the builder to set the range. ### Fixed diff --git a/imgui-examples/examples/test_window_impl.rs b/imgui-examples/examples/test_window_impl.rs index 4f21ad2..bdb845e 100644 --- a/imgui-examples/examples/test_window_impl.rs +++ b/imgui-examples/examples/test_window_impl.rs @@ -435,7 +435,7 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) { )); ui.spacing(); - Slider::new(im_str!("Wrap width"), -20.0 ..= 600.0) + Slider::new(im_str!("Wrap width")).range(-20.0 ..= 600.0) .display_format(im_str!("%.0f")) .build(ui, &mut state.wrap_width); @@ -852,7 +852,9 @@ fn show_example_menu_file<'a>(ui: &Ui<'a>, state: &mut FileMenuState) { ui.text(format!("Scrolling Text {}", i)); } }); - Slider::new(im_str!("Value"), 0.0..=1.0).build(ui, &mut state.f); + Slider::new(im_str!("Value")) + .range(0.0..=1.0) + .build(ui, &mut state.f); ui.input_float(im_str!("Input"), &mut state.f) .step(0.1) @@ -887,7 +889,9 @@ fn show_example_app_auto_resize(ui: &Ui, state: &mut AutoResizeState, opened: &m Note that you probably don't want to query the window size to output your content because that would create a feedback loop.", ); - Slider::new(im_str!("Number of lines"), 1..=20).build(ui, &mut state.lines); + Slider::new(im_str!("Number of lines")) + .range(1..=20) + .build(ui, &mut state.lines); for i in 0..state.lines { ui.text(format!("{:2$}This is line {}", "", i, i as usize * 4)); } diff --git a/src/widget/drag.rs b/src/widget/drag.rs index e36b0e5..32001c0 100644 --- a/src/widget/drag.rs +++ b/src/widget/drag.rs @@ -31,6 +31,7 @@ impl<'a, T: DataTypeKind> Drag<'a, T> { flags: SliderFlags::empty(), } } + /// Sets the range (inclusive) #[inline] pub fn range>(mut self, range: R) -> Self { self.min = range.start_bound().copied(); diff --git a/src/widget/slider.rs b/src/widget/slider.rs index caa4e9f..198dcaa 100644 --- a/src/widget/slider.rs +++ b/src/widget/slider.rs @@ -1,9 +1,8 @@ use bitflags::bitflags; -use std::ops::RangeInclusive; use std::os::raw::c_void; use std::ptr; -use crate::internal::DataTypeKind; +use crate::internal::{DataTypeKind, InclusiveRangeBounds}; use crate::string::ImStr; use crate::sys; use crate::Ui; @@ -30,23 +29,30 @@ bitflags!( #[must_use] pub struct Slider<'a, T: DataTypeKind> { label: &'a ImStr, - min: T, - max: T, + min: Option, + max: Option, display_format: Option<&'a ImStr>, flags: SliderFlags, } impl<'a, T: DataTypeKind> Slider<'a, T> { /// Constructs a new slider builder with the given range. - pub fn new(label: &ImStr, range: RangeInclusive) -> Slider { + pub fn new(label: &ImStr) -> Slider { Slider { label, - min: *range.start(), - max: *range.end(), + min: None, + max: None, display_format: None, flags: SliderFlags::empty(), } } + /// Sets the range (inclusive) + #[inline] + pub fn range>(mut self, range: R) -> Self { + self.min = range.start_bound().copied(); + self.max = range.end_bound().copied(); + self + } /// Sets the display format using *a C-style printf string* #[inline] pub fn display_format(mut self, display_format: &'a ImStr) -> Self { @@ -68,8 +74,14 @@ impl<'a, T: DataTypeKind> Slider<'a, T> { self.label.as_ptr(), T::KIND as i32, value as *mut T as *mut c_void, - &self.min as *const T as *const c_void, - &self.max as *const T as *const c_void, + self.min + .as_ref() + .map(|min| min as *const T) + .unwrap_or(ptr::null()) as *const c_void, + self.max + .as_ref() + .map(|max| max as *const T) + .unwrap_or(ptr::null()) as *const c_void, self.display_format .map(ImStr::as_ptr) .unwrap_or(ptr::null()), @@ -87,8 +99,14 @@ impl<'a, T: DataTypeKind> Slider<'a, T> { T::KIND as i32, values.as_mut_ptr() as *mut c_void, values.len() as i32, - &self.min as *const T as *const c_void, - &self.max as *const T as *const c_void, + self.min + .as_ref() + .map(|min| min as *const T) + .unwrap_or(ptr::null()) as *const c_void, + self.max + .as_ref() + .map(|max| max as *const T) + .unwrap_or(ptr::null()) as *const c_void, self.display_format .map(ImStr::as_ptr) .unwrap_or(ptr::null()), @@ -104,24 +122,31 @@ impl<'a, T: DataTypeKind> Slider<'a, T> { pub struct VerticalSlider<'a, T: DataTypeKind + Copy> { label: &'a ImStr, size: [f32; 2], - min: T, - max: T, + min: Option, + max: Option, display_format: Option<&'a ImStr>, flags: SliderFlags, } impl<'a, T: DataTypeKind> VerticalSlider<'a, T> { /// Constructs a new vertical slider builder with the given size and range. - pub fn new(label: &ImStr, size: [f32; 2], range: RangeInclusive) -> VerticalSlider { + pub fn new(label: &ImStr, size: [f32; 2]) -> VerticalSlider { VerticalSlider { label, size, - min: *range.start(), - max: *range.end(), + min: None, + max: None, display_format: None, flags: SliderFlags::empty(), } } + /// Sets the range (inclusive) + #[inline] + pub fn range>(mut self, range: R) -> Self { + self.min = range.start_bound().copied(); + self.max = range.end_bound().copied(); + self + } /// Sets the display format using *a C-style printf string* #[inline] pub fn display_format(mut self, display_format: &'a ImStr) -> Self { @@ -144,8 +169,14 @@ impl<'a, T: DataTypeKind> VerticalSlider<'a, T> { self.size.into(), T::KIND as i32, value as *mut T as *mut c_void, - &self.min as *const T as *const c_void, - &self.max as *const T as *const c_void, + self.min + .as_ref() + .map(|min| min as *const T) + .unwrap_or(ptr::null()) as *const c_void, + self.max + .as_ref() + .map(|max| max as *const T) + .unwrap_or(ptr::null()) as *const c_void, self.display_format .map(ImStr::as_ptr) .unwrap_or(ptr::null()), @@ -178,6 +209,13 @@ impl<'a> AngleSlider<'a> { flags: SliderFlags::empty(), } } + /// Sets the range (in degrees, inclusive) + #[inline] + pub fn range_degrees>(mut self, range: R) -> Self { + self.min_degrees = range.start_bound().copied().unwrap_or(-360.0); + self.max_degrees = range.end_bound().copied().unwrap_or(360.0); + self + } /// Sets the minimum value (in degrees) #[inline] pub fn min_degrees(mut self, min_degrees: f32) -> Self {