mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 06:10:06 -04:00
Slider: Add step parameter (#1225)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
@@ -71,6 +71,8 @@ pub struct Slider<'a> {
|
||||
suffix: String,
|
||||
text: String,
|
||||
text_color: Option<Color32>,
|
||||
/// Sets the minimal step of the widget value
|
||||
step: Option<f64>,
|
||||
min_decimals: usize,
|
||||
max_decimals: Option<usize>,
|
||||
}
|
||||
@@ -113,6 +115,7 @@ impl<'a> Slider<'a> {
|
||||
suffix: Default::default(),
|
||||
text: Default::default(),
|
||||
text_color: None,
|
||||
step: None,
|
||||
min_decimals: 0,
|
||||
max_decimals: None,
|
||||
}
|
||||
@@ -199,6 +202,16 @@ impl<'a> Slider<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// Default: `0.0` (disabled).
|
||||
pub fn step_by(mut self, step: f64) -> Self {
|
||||
self.step = if step != 0.0 { Some(step) } else { None };
|
||||
self
|
||||
}
|
||||
|
||||
// TODO: 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.
|
||||
@@ -255,6 +268,9 @@ impl<'a> Slider<'a> {
|
||||
if let Some(max_decimals) = self.max_decimals {
|
||||
value = emath::round_to_decimals(value, max_decimals);
|
||||
}
|
||||
if let Some(step) = self.step {
|
||||
value = (value / step).round() * step;
|
||||
}
|
||||
set(&mut self.get_set_value, value);
|
||||
}
|
||||
|
||||
@@ -330,14 +346,22 @@ impl<'a> Slider<'a> {
|
||||
let prev_value = self.get_value();
|
||||
let prev_position = self.position_from_value(prev_value, position_range.clone());
|
||||
let new_position = prev_position + kb_step;
|
||||
let new_value = if self.smart_aim {
|
||||
let aim_radius = ui.input().aim_radius();
|
||||
emath::smart_aim::best_in_range_f64(
|
||||
self.value_from_position(new_position - aim_radius, position_range.clone()),
|
||||
self.value_from_position(new_position + aim_radius, position_range.clone()),
|
||||
)
|
||||
} else {
|
||||
self.value_from_position(new_position, position_range.clone())
|
||||
let new_value = match self.step {
|
||||
Some(step) => prev_value + (kb_step as f64 * step),
|
||||
None if self.smart_aim => {
|
||||
let aim_radius = ui.input().aim_radius();
|
||||
emath::smart_aim::best_in_range_f64(
|
||||
self.value_from_position(
|
||||
new_position - aim_radius,
|
||||
position_range.clone(),
|
||||
),
|
||||
self.value_from_position(
|
||||
new_position + aim_radius,
|
||||
position_range.clone(),
|
||||
),
|
||||
)
|
||||
}
|
||||
_ => self.value_from_position(new_position, position_range.clone()),
|
||||
};
|
||||
self.set_value(new_value);
|
||||
}
|
||||
@@ -438,10 +462,19 @@ impl<'a> Slider<'a> {
|
||||
}
|
||||
|
||||
fn value_ui(&mut self, ui: &mut Ui, position_range: RangeInclusive<f32>) {
|
||||
// If `DragValue` is controlled from the keyboard and `step` is defined, set speed to `step`
|
||||
let change = ui.input().num_presses(Key::ArrowUp) as i32
|
||||
+ ui.input().num_presses(Key::ArrowRight) as i32
|
||||
- ui.input().num_presses(Key::ArrowDown) as i32
|
||||
- ui.input().num_presses(Key::ArrowLeft) as i32;
|
||||
let speed = match self.step {
|
||||
Some(step) if change != 0 => step,
|
||||
_ => self.current_gradient(&position_range),
|
||||
};
|
||||
let mut value = self.get_value();
|
||||
ui.add(
|
||||
DragValue::new(&mut value)
|
||||
.speed(self.current_gradient(&position_range))
|
||||
.speed(speed)
|
||||
.clamp_range(self.clamp_range())
|
||||
.min_decimals(self.min_decimals)
|
||||
.max_decimals_opt(self.max_decimals)
|
||||
|
||||
Reference in New Issue
Block a user