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);