refactored Slider to match the new Ui based architecture

This commit is contained in:
Gabe Weiner 2022-01-28 11:36:22 -05:00 committed by Jonathan Spira
parent 18ded1a58a
commit d05827258f
3 changed files with 66 additions and 36 deletions

View File

@ -44,13 +44,11 @@ fn example_1(ui: &Ui, state: &mut State) {
ui.text("Floats: f32 f64");
// Full ranges can be specified with Rust's `::MIN/MAX` constants
Slider::new("u8 value", u8::MIN, u8::MAX)
.build(ui, &mut state.u8_value);
ui.slider("u8 value", u8::MIN, u8::MAX, &mut state.u8_value);
// However for larger data-types, it's usually best to specify
// a much smaller range. The following slider is hard to use.
Slider::new("Full range f32 value", f32::MIN/2.0, f32::MAX/2.0)
.build(ui, &mut state.f32_value);
ui.slider("Full range f32 value", f32::MIN/2.0, f32::MAX/2.0, &mut state.f32_value);
// Note the `... / 2.0` - anything larger is not supported by
// the upstream C++ library
ui.text("Note that for 32-bit/64-bit types, sliders are always limited to half of the natural type range!");
@ -58,24 +56,16 @@ fn example_1(ui: &Ui, state: &mut State) {
// Most of the time, it's best to specify the range
ui.separator();
ui.text("Slider range can be limited:");
Slider::new("i32 value with range", -999, 999)
.build(ui, &mut state.i32_value);
Slider::new("f32 value", -10.0, 10.0)
.build(ui, &mut state.f32_value);
ui.slider("i32 value with range", -999, 999, &mut state.i32_value);
ui.slider("f32 value", -10.0, 10.0, &mut state.f32_value);
ui.separator();
ui.text("Value formatting can be customized with a C-style printf string:");
Slider::new("f64 value with custom formatting", -999_999_999.0, 999_999_999.0)
.display_format("%09.0f")
.build(ui, &mut state.f64_formatted);
ui.slider_config("f64 value with custom formatting", -999_999_999.0, 999_999_999.0).display_format("%09.0f").build(&mut state.f64_formatted);
// The display format changes the increments the slider operates in:
Slider::new("f32 with %.01f", 0.0, 1.0)
.display_format("%.01f")
.build(ui, &mut state.f32_value);
Slider::new("Same f32 with %.05f", 0.0, 1.0)
.display_format("%.05f")
.build(ui, &mut state.f32_value);
ui.slider_config("f32 with %.01f", 0.0, 1.0).display_format("%.01f").build(&mut state.f32_value);
ui.slider_config("Same f32 with %.05f", 0.0, 1.0).display_format("%.05f").build(&mut state.f32_value);
ui.separator();
ui.text("Vertical sliders require a size parameter but otherwise work in a similar way:");
@ -91,11 +81,12 @@ fn example_2(ui: &Ui, state: &mut State) {
.position([20.0, 120.0], Condition::Appearing);
w.build(|| {
ui.text("You can easily build a slider group from an array of values:");
Slider::new("[u8; 4]", 0, u8::MAX).build_array(ui, &mut state.array);
ui.slider_config("[u8; 4]", 0, u8::MAX)
.build_array(&mut state.array);
ui.text("You don't need to use arrays with known length; arbitrary slices can be used:");
let slice: &mut [u8] = &mut state.array[1..=2];
Slider::new("subslice", 0, u8::MAX).build_array(ui, slice);
ui.slider_config("subslice", 0, u8::MAX).build_array(slice);
});
}

View File

@ -433,9 +433,9 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
);
ui.spacing();
Slider::new("Wrap width", -20.0, 600.0)
ui.slider_config("Wrap width", -20.0, 600.0)
.display_format("%.0f")
.build(ui, &mut state.wrap_width);
.build(&mut state.wrap_width);
ui.text("Test paragraph 1:");
// TODO
@ -877,7 +877,7 @@ fn show_example_menu_file(ui: &Ui, state: &mut FileMenuState) {
ui.text(format!("Scrolling Text {}", i));
}
});
Slider::new("Value", 0.0, 1.0).build(ui, &mut state.f);
ui.slider("Value", 0.0, 1.0, &mut state.f);
ui.input_float("Input", &mut state.f).step(0.1).build();
let items = ["Yes", "No", "Maybe"];
@ -904,7 +904,7 @@ 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("Number of lines", 1, 20).build(ui, &mut state.lines);
ui.slider("Number of lines", 1, 20, &mut state.lines);
for i in 0..state.lines {
ui.text(format!("{:2$}This is line {}", "", i, i as usize * 4));
}

View File

@ -23,32 +23,65 @@ bitflags!(
}
);
impl Ui {
/// Creates a new slider widget. Returns true if the value has been edited.
pub fn slider<T: AsRef<str>, K: DataTypeKind>(
&self,
label: T,
min: K,
max: K,
value: &mut K,
) -> bool {
self.slider_config(label, min, max).build(value)
}
/// Creates an new ubuilt Slider.
pub fn slider_config<T: AsRef<str>, K: DataTypeKind>(
&self,
label: T,
min: K,
max: K,
) -> Slider<'_, T, K> {
Slider {
label,
min,
max,
display_format: Option::<&'static str>::None,
flags: SliderFlags::empty(),
ui: self,
}
}
}
/// Builder for a slider widget.
#[derive(Copy, Clone, Debug)]
#[must_use]
pub struct Slider<Label, Data, Format = &'static str> {
pub struct Slider<'ui, Label, Data, Format = &'static str> {
label: Label,
min: Data,
max: Data,
display_format: Option<Format>,
flags: SliderFlags,
ui: &'ui Ui,
}
impl<T: AsRef<str>, K: DataTypeKind> Slider<T, K> {
impl<'ui, T: AsRef<str>, K: DataTypeKind> Slider<'ui, T, K> {
/// Constructs a new slider builder with the given range.
#[doc(alias = "SliderScalar", alias = "SliderScalarN")]
pub fn new(label: T, min: K, max: K) -> Self {
#[deprecated(note = "Use `Ui::slider` or `Ui::slider_config`.", since = "0.9.0")]
pub fn new(ui: &'ui Ui, label: T, min: K, max: K) -> Self {
Slider {
label,
min,
max,
display_format: None,
flags: SliderFlags::empty(),
ui,
}
}
}
impl<Label, Data, Format> Slider<Label, Data, Format>
impl<'ui, Label, Data, Format> Slider<'ui, Label, Data, Format>
where
Label: AsRef<str>,
Data: DataTypeKind,
@ -57,11 +90,12 @@ where
/// Sets the range inclusively, such that both values given
/// are valid values which the slider can be dragged to.
///
/// ```rust
/// # use imgui::im_str;
/// imgui::Slider::new(im_str!("Example"), i8::MIN, i8::MAX)
/// ```no_run
/// # let mut ctx = imgui::Context::create();
/// # let ui = ctx.frame();
/// ui.slider_config("Example", i8::MIN, i8::MAX)
/// .range(4, 8)
/// // Remember to call .build(&ui)
/// // Remember to call .build()
/// ;
/// ```
///
@ -83,13 +117,14 @@ where
pub fn display_format<Format2: AsRef<str>>(
self,
display_format: Format2,
) -> Slider<Label, Data, Format2> {
) -> Slider<'ui, Label, Data, Format2> {
Slider {
label: self.label,
min: self.min,
max: self.max,
display_format: Some(display_format),
flags: self.flags,
ui: self.ui,
}
}
/// Replaces all current settings with the given flags
@ -101,9 +136,11 @@ where
/// Builds a slider that is bound to the given value.
///
/// Returns true if the slider value was changed.
pub fn build(self, ui: &Ui, value: &mut Data) -> bool {
pub fn build(self, value: &mut Data) -> bool {
unsafe {
let (label, display_format) = ui.scratch_txt_with_opt(self.label, self.display_format);
let (label, display_format) = self
.ui
.scratch_txt_with_opt(self.label, self.display_format);
sys::igSliderScalar(
label,
@ -119,9 +156,11 @@ where
/// Builds a horizontal array of multiple sliders attached to the given slice.
///
/// Returns true if any slider value was changed.
pub fn build_array(self, ui: &Ui, values: &mut [Data]) -> bool {
pub fn build_array(self, values: &mut [Data]) -> bool {
unsafe {
let (label, display_format) = ui.scratch_txt_with_opt(self.label, self.display_format);
let (label, display_format) = self
.ui
.scratch_txt_with_opt(self.label, self.display_format);
sys::igSliderScalarN(
label,