From 2583fd2c5204c0828dd58bc46fd1e45f4b84de8d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sun, 10 Feb 2019 16:10:08 +0100 Subject: [PATCH] integer sliders --- emigui/src/emigui.rs | 22 ++++++++++---------- emigui/src/widgets.rs | 48 ++++++++++++++++++++++++++++++++++--------- example/src/app.rs | 43 +++++++++++++++++++++++++------------- 3 files changed, 78 insertions(+), 35 deletions(-) diff --git a/emigui/src/emigui.rs b/emigui/src/emigui.rs index 658f628a..bfabfc53 100644 --- a/emigui/src/emigui.rs +++ b/emigui/src/emigui.rs @@ -21,15 +21,15 @@ fn show_options(options: &mut LayoutOptions, gui: &mut Region) { if gui.add(Button::new("Reset LayoutOptions")).clicked { *options = Default::default(); } - gui.add(Slider::new(&mut options.item_spacing.x, 0.0, 10.0).text("item_spacing.x")); - gui.add(Slider::new(&mut options.item_spacing.y, 0.0, 10.0).text("item_spacing.y")); - gui.add(Slider::new(&mut options.window_padding.x, 0.0, 10.0).text("window_padding.x")); - gui.add(Slider::new(&mut options.window_padding.y, 0.0, 10.0).text("window_padding.y")); - gui.add(Slider::new(&mut options.indent, 0.0, 100.0).text("indent")); - gui.add(Slider::new(&mut options.button_padding.x, 0.0, 20.0).text("button_padding.x")); - gui.add(Slider::new(&mut options.button_padding.y, 0.0, 20.0).text("button_padding.y")); - gui.add(Slider::new(&mut options.clickable_diameter, 0.0, 60.0).text("clickable_diameter")); - gui.add(Slider::new(&mut options.start_icon_width, 0.0, 60.0).text("start_icon_width")); + gui.add(Slider::f32(&mut options.item_spacing.x, 0.0, 10.0).text("item_spacing.x")); + gui.add(Slider::f32(&mut options.item_spacing.y, 0.0, 10.0).text("item_spacing.y")); + gui.add(Slider::f32(&mut options.window_padding.x, 0.0, 10.0).text("window_padding.x")); + gui.add(Slider::f32(&mut options.window_padding.y, 0.0, 10.0).text("window_padding.y")); + gui.add(Slider::f32(&mut options.indent, 0.0, 100.0).text("indent")); + gui.add(Slider::f32(&mut options.button_padding.x, 0.0, 20.0).text("button_padding.x")); + gui.add(Slider::f32(&mut options.button_padding.y, 0.0, 20.0).text("button_padding.y")); + gui.add(Slider::f32(&mut options.clickable_diameter, 0.0, 60.0).text("clickable_diameter")); + gui.add(Slider::f32(&mut options.start_icon_width, 0.0, 60.0).text("start_icon_width")); } fn show_style(style: &mut style::Style, gui: &mut Region) { @@ -37,12 +37,12 @@ fn show_style(style: &mut style::Style, gui: &mut Region) { *style = Default::default(); } gui.add(Checkbox::new(&mut style.debug_rects, "debug_rects")); - gui.add(Slider::new(&mut style.line_width, 0.0, 10.0).text("line_width")); + gui.add(Slider::f32(&mut style.line_width, 0.0, 10.0).text("line_width")); } fn show_font_sizes(font_sizes: &mut FontSizes, gui: &mut Region) { for (text_style, mut size) in font_sizes { - gui.add(Slider::new(&mut size, 4.0, 40.0).text(format!("{:?}", text_style))); + gui.add(Slider::f32(&mut size, 4.0, 40.0).text(format!("{:?}", text_style))); } } diff --git a/emigui/src/widgets.rs b/emigui/src/widgets.rs index 397e4335..b718ae6f 100644 --- a/emigui/src/widgets.rs +++ b/emigui/src/widgets.rs @@ -204,25 +204,49 @@ impl Widget for RadioButton { // ---------------------------------------------------------------------------- -#[derive(Debug)] pub struct Slider<'a> { - value: &'a mut f32, + get_set_value: Box<'a + FnMut(Option) -> f32>, min: f32, max: f32, id: Option, text: Option, + precision: usize, text_color: Option, text_on_top: Option, } impl<'a> Slider<'a> { - pub fn new(value: &'a mut f32, min: f32, max: f32) -> Self { + pub fn f32(value: &'a mut f32, min: f32, max: f32) -> Self { Slider { - value, + get_set_value: Box::new(move |v: Option| { + if let Some(v) = v { + *value = v + } + *value + }), min, max, id: None, text: None, + precision: 3, + text_on_top: None, + text_color: None, + } + } + + pub fn i32(value: &'a mut i32, min: i32, max: i32) -> Self { + Slider { + get_set_value: Box::new(move |v: Option| { + if let Some(v) = v { + *value = v.round() as i32 + } + *value as f32 + }), + min: min as f32, + max: max as f32, + id: None, + text: None, + precision: 0, text_on_top: None, text_color: None, } @@ -245,14 +269,19 @@ impl<'a> Slider<'a> { } impl<'a> Widget for Slider<'a> { - fn add_to(self, region: &mut Region) -> GuiResponse { + fn add_to(mut self, region: &mut Region) -> GuiResponse { let text_style = TextStyle::Button; let font = ®ion.fonts()[text_style]; if let Some(text) = &self.text { let text_on_top = self.text_on_top.unwrap_or_default(); let text_color = self.text_color; - let full_text = format!("{}: {:.3}", text, self.value); + let full_text = format!( + "{}: {:.*}", + text, + self.precision, + (self.get_set_value)(None) + ); let id = Some(self.id.unwrap_or_else(|| make_id(text))); let mut naked = self; naked.id = id; @@ -278,7 +307,6 @@ impl<'a> Widget for Slider<'a> { } else { let height = font.line_spacing().max(region.options().clickable_diameter); - let value = self.value; let min = self.min; let max = self.max; debug_assert!(min <= max); @@ -293,13 +321,13 @@ impl<'a> Widget for Slider<'a> { if let Some(mouse_pos) = region.input().mouse_pos { if interact.active { - *value = remap_clamp( + (self.get_set_value)(Some(remap_clamp( mouse_pos.x, interact.rect.min().x, interact.rect.max().x, min, max, - ); + ))); } } @@ -307,7 +335,7 @@ impl<'a> Widget for Slider<'a> { interact, max, min, - value: *value, + value: (self.get_set_value)(None), }); region.response(interact) diff --git a/example/src/app.rs b/example/src/app.rs index 7aca8db2..28c181bd 100644 --- a/example/src/app.rs +++ b/example/src/app.rs @@ -8,6 +8,7 @@ pub struct App { size: Vec2, corner_radius: f32, stroke_width: f32, + num_boxes: i32, } impl Default for App { @@ -19,6 +20,7 @@ impl Default for App { size: vec2(100.0, 50.0), corner_radius: 5.0, stroke_width: 2.0, + num_boxes: 1, } } } @@ -68,21 +70,34 @@ impl App { }); gui.foldable("Test box rendering", |gui| { - gui.add(Slider::new(&mut self.size.x, 0.0, 500.0).text("width")); - gui.add(Slider::new(&mut self.size.y, 0.0, 500.0).text("height")); - gui.add(Slider::new(&mut self.corner_radius, 0.0, 50.0).text("corner_radius")); - gui.add(Slider::new(&mut self.stroke_width, 0.0, 10.0).text("stroke_width")); + gui.add(Slider::f32(&mut self.size.x, 0.0, 500.0).text("width")); + gui.add(Slider::f32(&mut self.size.y, 0.0, 500.0).text("height")); + gui.add(Slider::f32(&mut self.corner_radius, 0.0, 50.0).text("corner_radius")); + gui.add(Slider::f32(&mut self.stroke_width, 0.0, 10.0).text("stroke_width")); + gui.add(Slider::i32(&mut self.num_boxes, 0, 5).text("num_boxes")); - let pos = gui.reserve_space(self.size, None).rect.min(); - gui.add_graphic(GuiCmd::PaintCommands(vec![PaintCmd::Rect { - corner_radius: self.corner_radius, - fill_color: Some(srgba(136, 136, 136, 255)), - rect: Rect::from_min_size(pos, self.size), - outline: Some(Outline { - width: self.stroke_width, - color: srgba(255, 255, 255, 255), - }), - }])); + let pos = gui + .reserve_space( + vec2(self.size.x * (self.num_boxes as f32), self.size.y), + None, + ) + .rect + .min(); + + for i in 0..self.num_boxes { + gui.add_graphic(GuiCmd::PaintCommands(vec![PaintCmd::Rect { + corner_radius: self.corner_radius, + fill_color: Some(srgba(136, 136, 136, 255)), + rect: Rect::from_min_size( + vec2(pos.x + (i as f32) * self.size.x, pos.y), + self.size, + ), + outline: Some(Outline { + width: self.stroke_width, + color: srgba(255, 255, 255, 255), + }), + }])); + } }); } }