From 6ae4bc486b2608212f5fc8453f5aa7e5106853f8 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 15 Dec 2022 17:05:43 +0100 Subject: [PATCH] Add Slider::drag_value_speed --- CHANGELOG.md | 3 ++- crates/egui/src/widgets/slider.rs | 32 +++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d65ce7a7..5b2798c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG ## Unreleased ### Added ⭐ * `Event::Key` now has a `repeat` field that is set to `true` if the event was the result of a key-repeat ([#2435](https://github.com/emilk/egui/pull/2435)). +* Add `Slider::drag_value_speed`, which lets you ask for finer precision when dragging the slider value rather than the actual slider. ### Fixed 🐛 * Expose `TextEdit`'s multiline flag to AccessKit ([#2448](https://github.com/emilk/egui/pull/2448)). @@ -15,7 +16,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG ## 0.20.1 - 2022-12-11 - Fix key-repeat ### Changed 🔧 -* `InputState`: all press functions again include key repeates (like in egui 0.19) ([#2429](https://github.com/emilk/egui/pull/2429)). +* `InputState`: all press functions again include key repeats (like in egui 0.19) ([#2429](https://github.com/emilk/egui/pull/2429)). * Improve the look of thin white lines ([#2437](https://github.com/emilk/egui/pull/2437)). ### Fixed 🐛 diff --git a/crates/egui/src/widgets/slider.rs b/crates/egui/src/widgets/slider.rs index bb673afa..0142e2e3 100644 --- a/crates/egui/src/widgets/slider.rs +++ b/crates/egui/src/widgets/slider.rs @@ -79,6 +79,7 @@ pub struct Slider<'a> { text: WidgetText, /// Sets the minimal step of the widget value step: Option, + drag_value_speed: Option, min_decimals: usize, max_decimals: Option, custom_formatter: Option>, @@ -123,6 +124,7 @@ impl<'a> Slider<'a> { suffix: Default::default(), text: Default::default(), step: None, + drag_value_speed: None, min_decimals: 0, max_decimals: None, custom_formatter: None, @@ -212,6 +214,7 @@ impl<'a> Slider<'a> { } /// Sets the minimal change of the value. + /// /// Value `0.0` effectively disables the feature. If the new value is out of range /// and `clamp_to_range` is enabled, you would not have the ability to change the value. /// @@ -221,8 +224,22 @@ impl<'a> Slider<'a> { self } + /// When dragging the value, how fast does it move? + /// + /// Unit: values per point (logical pixel). + /// See also [`DragValue::speed`]. + /// + /// By default this is the same speed as when dragging the slider, + /// but you can change it here to for instance have a much finer control + /// by dragging the slider value rather than the slider itself. + pub fn drag_value_speed(mut self, drag_value_speed: f64) -> Self { + self.drag_value_speed = Some(drag_value_speed); + self + } + // TODO(emilk): we should also have a "min precision". /// Set a minimum number of decimals to display. + /// /// Normally you don't need to pick a precision, as the slider will intelligently pick a precision for you. /// Regardless of precision the slider will use "smart aim" to help the user select nice, round values. pub fn min_decimals(mut self, min_decimals: usize) -> Self { @@ -232,6 +249,7 @@ impl<'a> Slider<'a> { // TODO(emilk): we should also have a "max precision". /// Set a maximum number of decimals to display. + /// /// Values will also be rounded to this number of decimals. /// Normally you don't need to pick a precision, as the slider will intelligently pick a precision for you. /// Regardless of precision the slider will use "smart aim" to help the user select nice, round values. @@ -241,6 +259,7 @@ impl<'a> Slider<'a> { } /// Set an exact number of decimals to display. + /// /// Values will also be rounded to this number of decimals. /// Normally you don't need to pick a precision, as the slider will intelligently pick a precision for you. /// Regardless of precision the slider will use "smart aim" to help the user select nice, round values. @@ -678,7 +697,6 @@ impl<'a> Slider<'a> { } fn value_ui(&mut self, ui: &mut Ui, position_range: RangeInclusive) -> Response { - // If [`DragValue`] is controlled from the keyboard and `step` is defined, set speed to `step` let change = { // Hold one lock rather than 4 (see https://github.com/emilk/egui/pull/1380). let input = ui.input(); @@ -687,10 +705,16 @@ impl<'a> Slider<'a> { - input.num_presses(Key::ArrowDown) as i32 - input.num_presses(Key::ArrowLeft) as i32 }; - let speed = match self.step { - Some(step) if change != 0 => step, - _ => self.current_gradient(&position_range), + + let any_change = change != 0; + let speed = if let (Some(step), true) = (self.step, any_change) { + // If [`DragValue`] is controlled from the keyboard and `step` is defined, set speed to `step` + step + } else { + self.drag_value_speed + .unwrap_or_else(|| self.current_gradient(&position_range)) }; + let mut value = self.get_value(); let response = ui.add({ let mut dv = DragValue::new(&mut value)