From 50a56d41ee20c534ed4bface8058f99aebc5c2df Mon Sep 17 00:00:00 2001 From: Cristian Dinu Date: Thu, 8 Apr 2021 23:20:52 +0300 Subject: [PATCH] DragValue improvements (#274) * Display ResizeHorizontal cursor on hover * Adapt the URL open command to the platform With this new version we use $OSTYPE bash env var to query what OS are we running on. - On Linux, ex: Fedora, we use `xdg-open` - On Windows, ex: msys, we use `start` - For other other variants we try to use `open` We should update this script when we notice that `open` is not available on a particular platform. (cherry picked from commit b3aa4982f683d961c21fd18e9ffc1fdf5fba0783) * Add slow speed mode for `DragValue` The slow speed mode is disabled by default. It can be activated or deactivated using `DragValue::slow_speed()`. When active the `Shift` key can be used to have a better control over the value, `DragValue::speed` / 10.0 increments. * Display `ResizeHorizontal` cursor while dragging too * Apply review suggestion Shorter and in line with the rest of the code base Co-authored-by: Emil Ernerfeldt * Add `Modifiers::shift_only` for better code clarity * Make slow speed always enabled Co-authored-by: Emil Ernerfeldt --- egui/src/data/input.rs | 7 +++++++ egui/src/widgets/drag_value.rs | 26 ++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/egui/src/data/input.rs b/egui/src/data/input.rs index c524fcf6..d6d08eed 100644 --- a/egui/src/data/input.rs +++ b/egui/src/data/input.rs @@ -153,13 +153,20 @@ pub struct Modifiers { } impl Modifiers { + #[inline(always)] pub fn is_none(&self) -> bool { self == &Self::default() } + #[inline(always)] pub fn any(&self) -> bool { !self.is_none() } + + #[inline(always)] + pub fn shift_only(&self) -> bool { + self.shift && !(self.alt || self.command) + } } /// Keyboard keys. diff --git a/egui/src/widgets/drag_value.rs b/egui/src/widgets/drag_value.rs index cd0eb495..ffaceb3e 100644 --- a/egui/src/widgets/drag_value.rs +++ b/egui/src/widgets/drag_value.rs @@ -217,10 +217,15 @@ impl<'a> Widget for DragValue<'a> { max_decimals, } = self; + let is_slow_speed = ui.input().modifiers.shift_only(); + let value = get(&mut get_set_value); let value = clamp_to_range(value, clamp_range.clone()); let aim_rad = ui.input().aim_radius() as f64; + let auto_decimals = (aim_rad / speed.abs()).log10().ceil().clamp(0.0, 15.0) as usize; + let auto_decimals = auto_decimals + is_slow_speed as usize; + let max_decimals = max_decimals.unwrap_or(auto_decimals + 2); let auto_decimals = auto_decimals.clamp(min_decimals, max_decimals); let value_text = if value == 0.0 { @@ -262,21 +267,30 @@ impl<'a> Widget for DragValue<'a> { .sense(Sense::click_and_drag()) .text_style(TextStyle::Monospace) .wrap(false); + let response = ui.add_sized(ui.spacing().interact_size, button); - let response = response.on_hover_text(format!( - "{}{}{}\nDrag to edit or click to enter a value.", - prefix, - value as f32, // Show full precision value on-hover. TODO: figure out f64 vs f32 - suffix - )); + let response = response + .on_hover_cursor(CursorIcon::ResizeHorizontal) + .on_hover_text(format!( + "{}{}{}\nDrag to edit or click to enter a value.\nPress 'Shift' while dragging for better control.", + prefix, + value as f32, // Show full precision value on-hover. TODO: figure out f64 vs f32 + suffix + )); if response.clicked() { ui.memory().request_focus(kb_edit_id); ui.memory().drag_value.edit_string = None; // Filled in next frame } else if response.dragged() { + ui.output().cursor_icon = CursorIcon::ResizeHorizontal; + let mdelta = response.drag_delta(); let delta_points = mdelta.x - mdelta.y; // Increase to the right and up + + let speed = if is_slow_speed { speed / 10.0 } else { speed }; + let delta_value = delta_points as f64 * speed; + if delta_value != 0.0 { let mut drag_state = std::mem::take(&mut ui.memory().drag_value);