Add `clamp_to_range` option to DragValue, rename `clamp_range` to `range` (deprecating the former) (#4728)
Adds the ability to have `DragValue` not clamp values its presented with and instead apply clamping only once there's any user input. In action: https://github.com/emilk/egui/assets/1220815/af42fd67-86d0-4364-8ae6-48a2ec15646a Alternative name could be `only_clamp_on_change`, not entirely certain which one is better 🤔
This commit is contained in:
parent
3b9f964aed
commit
10f092d9d4
|
|
@ -155,7 +155,7 @@ impl Widget for &mut epaint::TessellationOptions {
|
||||||
.on_hover_text("Apply feathering to smooth out the edges of shapes. Turn off for small performance gain.");
|
.on_hover_text("Apply feathering to smooth out the edges of shapes. Turn off for small performance gain.");
|
||||||
|
|
||||||
if *feathering {
|
if *feathering {
|
||||||
ui.add(crate::DragValue::new(feathering_size_in_pixels).clamp_range(0.0..=10.0).speed(0.1).suffix(" px"));
|
ui.add(crate::DragValue::new(feathering_size_in_pixels).range(0.0..=10.0).speed(0.1).suffix(" px"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -165,7 +165,7 @@ impl Widget for &mut epaint::TessellationOptions {
|
||||||
ui.label("Spline tolerance");
|
ui.label("Spline tolerance");
|
||||||
let speed = 0.01 * *bezier_tolerance;
|
let speed = 0.01 * *bezier_tolerance;
|
||||||
ui.add(
|
ui.add(
|
||||||
crate::DragValue::new(bezier_tolerance).clamp_range(0.0001..=10.0)
|
crate::DragValue::new(bezier_tolerance).range(0.0001..=10.0)
|
||||||
.speed(speed)
|
.speed(speed)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -337,16 +337,16 @@ impl Options {
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Line scroll speed");
|
ui.label("Line scroll speed");
|
||||||
ui.add(
|
ui.add(crate::DragValue::new(line_scroll_speed).range(0.0..=f32::INFINITY))
|
||||||
crate::DragValue::new(line_scroll_speed).clamp_range(0.0..=f32::INFINITY),
|
.on_hover_text(
|
||||||
)
|
"How many lines to scroll with each tick of the mouse wheel",
|
||||||
.on_hover_text("How many lines to scroll with each tick of the mouse wheel");
|
);
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Scroll zoom speed");
|
ui.label("Scroll zoom speed");
|
||||||
ui.add(
|
ui.add(
|
||||||
crate::DragValue::new(scroll_zoom_speed)
|
crate::DragValue::new(scroll_zoom_speed)
|
||||||
.clamp_range(0.0..=f32::INFINITY)
|
.range(0.0..=f32::INFINITY)
|
||||||
.speed(0.001),
|
.speed(0.001),
|
||||||
)
|
)
|
||||||
.on_hover_text("How fast to zoom with ctrl/cmd + scroll");
|
.on_hover_text("How fast to zoom with ctrl/cmd + scroll");
|
||||||
|
|
|
||||||
|
|
@ -571,26 +571,26 @@ impl ScrollStyle {
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(DragValue::new(bar_width).clamp_range(0.0..=32.0));
|
ui.add(DragValue::new(bar_width).range(0.0..=32.0));
|
||||||
ui.label("Full bar width");
|
ui.label("Full bar width");
|
||||||
});
|
});
|
||||||
if *floating {
|
if *floating {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(DragValue::new(floating_width).clamp_range(0.0..=32.0));
|
ui.add(DragValue::new(floating_width).range(0.0..=32.0));
|
||||||
ui.label("Thin bar width");
|
ui.label("Thin bar width");
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(DragValue::new(floating_allocated_width).clamp_range(0.0..=32.0));
|
ui.add(DragValue::new(floating_allocated_width).range(0.0..=32.0));
|
||||||
ui.label("Allocated width");
|
ui.label("Allocated width");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(DragValue::new(handle_min_length).clamp_range(0.0..=32.0));
|
ui.add(DragValue::new(handle_min_length).range(0.0..=32.0));
|
||||||
ui.label("Minimum handle length");
|
ui.label("Minimum handle length");
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(DragValue::new(bar_outer_margin).clamp_range(0.0..=32.0));
|
ui.add(DragValue::new(bar_outer_margin).range(0.0..=32.0));
|
||||||
ui.label("Outer margin");
|
ui.label("Outer margin");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -603,7 +603,7 @@ impl ScrollStyle {
|
||||||
if *floating {
|
if *floating {
|
||||||
crate::Grid::new("opacity").show(ui, |ui| {
|
crate::Grid::new("opacity").show(ui, |ui| {
|
||||||
fn opacity_ui(ui: &mut Ui, opacity: &mut f32) {
|
fn opacity_ui(ui: &mut Ui, opacity: &mut f32) {
|
||||||
ui.add(DragValue::new(opacity).speed(0.01).clamp_range(0.0..=1.0));
|
ui.add(DragValue::new(opacity).speed(0.01).range(0.0..=1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.label("Opacity");
|
ui.label("Opacity");
|
||||||
|
|
@ -626,7 +626,7 @@ impl ScrollStyle {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(DragValue::new(bar_inner_margin).clamp_range(0.0..=32.0));
|
ui.add(DragValue::new(bar_inner_margin).range(0.0..=32.0));
|
||||||
ui.label("Inner margin");
|
ui.label("Inner margin");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1418,7 +1418,7 @@ impl Style {
|
||||||
ui.label("Animation duration");
|
ui.label("Animation duration");
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(animation_time)
|
DragValue::new(animation_time)
|
||||||
.clamp_range(0.0..=1.0)
|
.range(0.0..=1.0)
|
||||||
.speed(0.02)
|
.speed(0.02)
|
||||||
.suffix(" s"),
|
.suffix(" s"),
|
||||||
);
|
);
|
||||||
|
|
@ -1515,19 +1515,19 @@ impl Spacing {
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Indent");
|
ui.label("Indent");
|
||||||
ui.add(DragValue::new(indent).clamp_range(0.0..=100.0));
|
ui.add(DragValue::new(indent).range(0.0..=100.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Slider width");
|
ui.label("Slider width");
|
||||||
ui.add(DragValue::new(slider_width).clamp_range(0.0..=1000.0));
|
ui.add(DragValue::new(slider_width).range(0.0..=1000.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Slider rail height");
|
ui.label("Slider rail height");
|
||||||
ui.add(DragValue::new(slider_rail_height).clamp_range(0.0..=50.0));
|
ui.add(DragValue::new(slider_rail_height).range(0.0..=50.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("ComboBox width");
|
ui.label("ComboBox width");
|
||||||
ui.add(DragValue::new(combo_width).clamp_range(0.0..=1000.0));
|
ui.add(DragValue::new(combo_width).range(0.0..=1000.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Default area size");
|
ui.label("Default area size");
|
||||||
|
|
@ -1535,20 +1535,20 @@ impl Spacing {
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("TextEdit width");
|
ui.label("TextEdit width");
|
||||||
ui.add(DragValue::new(text_edit_width).clamp_range(0.0..=1000.0));
|
ui.add(DragValue::new(text_edit_width).range(0.0..=1000.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Tooltip wrap width");
|
ui.label("Tooltip wrap width");
|
||||||
ui.add(DragValue::new(tooltip_width).clamp_range(0.0..=1000.0));
|
ui.add(DragValue::new(tooltip_width).range(0.0..=1000.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Default menu width");
|
ui.label("Default menu width");
|
||||||
ui.add(DragValue::new(menu_width).clamp_range(0.0..=1000.0));
|
ui.add(DragValue::new(menu_width).range(0.0..=1000.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Menu spacing")
|
ui.label("Menu spacing")
|
||||||
.on_hover_text("Horizontal spacing between menus");
|
.on_hover_text("Horizontal spacing between menus");
|
||||||
ui.add(DragValue::new(menu_spacing).clamp_range(0.0..=10.0));
|
ui.add(DragValue::new(menu_spacing).range(0.0..=10.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Checkboxes etc");
|
ui.label("Checkboxes etc");
|
||||||
|
|
@ -1556,17 +1556,17 @@ impl Spacing {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(icon_width)
|
DragValue::new(icon_width)
|
||||||
.prefix("outer icon width:")
|
.prefix("outer icon width:")
|
||||||
.clamp_range(0.0..=60.0),
|
.range(0.0..=60.0),
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(icon_width_inner)
|
DragValue::new(icon_width_inner)
|
||||||
.prefix("inner icon width:")
|
.prefix("inner icon width:")
|
||||||
.clamp_range(0.0..=60.0),
|
.range(0.0..=60.0),
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(icon_spacing)
|
DragValue::new(icon_spacing)
|
||||||
.prefix("spacing:")
|
.prefix("spacing:")
|
||||||
.clamp_range(0.0..=10.0),
|
.range(0.0..=10.0),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
@ -1579,7 +1579,7 @@ impl Spacing {
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("Max height of a combo box");
|
ui.label("Max height of a combo box");
|
||||||
ui.add(DragValue::new(combo_height).clamp_range(0.0..=1000.0));
|
ui.add(DragValue::new(combo_height).range(0.0..=1000.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.collapsing("Scroll Area", |ui| {
|
ui.collapsing("Scroll Area", |ui| {
|
||||||
|
|
@ -1611,15 +1611,15 @@ impl Interaction {
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
ui.label("interact_radius")
|
ui.label("interact_radius")
|
||||||
.on_hover_text("Interact with the closest widget within this radius.");
|
.on_hover_text("Interact with the closest widget within this radius.");
|
||||||
ui.add(DragValue::new(interact_radius).clamp_range(0.0..=20.0));
|
ui.add(DragValue::new(interact_radius).range(0.0..=20.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("resize_grab_radius_side").on_hover_text("Radius of the interactive area of the side of a window during drag-to-resize");
|
ui.label("resize_grab_radius_side").on_hover_text("Radius of the interactive area of the side of a window during drag-to-resize");
|
||||||
ui.add(DragValue::new(resize_grab_radius_side).clamp_range(0.0..=20.0));
|
ui.add(DragValue::new(resize_grab_radius_side).range(0.0..=20.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("resize_grab_radius_corner").on_hover_text("Radius of the interactive area of the corner of a window during drag-to-resize.");
|
ui.label("resize_grab_radius_corner").on_hover_text("Radius of the interactive area of the corner of a window during drag-to-resize.");
|
||||||
ui.add(DragValue::new(resize_grab_radius_corner).clamp_range(0.0..=20.0));
|
ui.add(DragValue::new(resize_grab_radius_corner).range(0.0..=20.0));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("Tooltip delay").on_hover_text(
|
ui.label("Tooltip delay").on_hover_text(
|
||||||
|
|
@ -1627,7 +1627,7 @@ impl Interaction {
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(tooltip_delay)
|
DragValue::new(tooltip_delay)
|
||||||
.clamp_range(0.0..=1.0)
|
.range(0.0..=1.0)
|
||||||
.speed(0.05)
|
.speed(0.05)
|
||||||
.suffix(" s"),
|
.suffix(" s"),
|
||||||
);
|
);
|
||||||
|
|
@ -1638,7 +1638,7 @@ impl Interaction {
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(tooltip_grace_time)
|
DragValue::new(tooltip_grace_time)
|
||||||
.clamp_range(0.0..=1.0)
|
.range(0.0..=1.0)
|
||||||
.speed(0.05)
|
.speed(0.05)
|
||||||
.suffix(" s"),
|
.suffix(" s"),
|
||||||
);
|
);
|
||||||
|
|
@ -1996,7 +1996,7 @@ impl TextCursorStyle {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(on_duration)
|
DragValue::new(on_duration)
|
||||||
.speed(0.1)
|
.speed(0.1)
|
||||||
.clamp_range(0.0..=2.0)
|
.range(0.0..=2.0)
|
||||||
.suffix(" s"),
|
.suffix(" s"),
|
||||||
);
|
);
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
@ -2005,7 +2005,7 @@ impl TextCursorStyle {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(off_duration)
|
DragValue::new(off_duration)
|
||||||
.speed(0.1)
|
.speed(0.1)
|
||||||
.clamp_range(0.0..=2.0)
|
.range(0.0..=2.0)
|
||||||
.suffix(" s"),
|
.suffix(" s"),
|
||||||
);
|
);
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
@ -2065,12 +2065,12 @@ fn two_drag_values(value: &mut Vec2, range: std::ops::RangeInclusive<f32>) -> im
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(&mut value.x)
|
DragValue::new(&mut value.x)
|
||||||
.clamp_range(range.clone())
|
.range(range.clone())
|
||||||
.prefix("x: "),
|
.prefix("x: "),
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(&mut value.y)
|
DragValue::new(&mut value.y)
|
||||||
.clamp_range(range.clone())
|
.range(range.clone())
|
||||||
.prefix("y: "),
|
.prefix("y: "),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
@ -2212,7 +2212,7 @@ impl Widget for &mut Rounding {
|
||||||
ui.checkbox(&mut same, "same");
|
ui.checkbox(&mut same, "same");
|
||||||
|
|
||||||
let mut cr = self.nw;
|
let mut cr = self.nw;
|
||||||
ui.add(DragValue::new(&mut cr).clamp_range(0.0..=f32::INFINITY));
|
ui.add(DragValue::new(&mut cr).range(0.0..=f32::INFINITY));
|
||||||
*self = Rounding::same(cr);
|
*self = Rounding::same(cr);
|
||||||
})
|
})
|
||||||
.response
|
.response
|
||||||
|
|
@ -2222,19 +2222,19 @@ impl Widget for &mut Rounding {
|
||||||
|
|
||||||
crate::Grid::new("rounding").num_columns(2).show(ui, |ui| {
|
crate::Grid::new("rounding").num_columns(2).show(ui, |ui| {
|
||||||
ui.label("NW");
|
ui.label("NW");
|
||||||
ui.add(DragValue::new(&mut self.nw).clamp_range(0.0..=f32::INFINITY));
|
ui.add(DragValue::new(&mut self.nw).range(0.0..=f32::INFINITY));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("NE");
|
ui.label("NE");
|
||||||
ui.add(DragValue::new(&mut self.ne).clamp_range(0.0..=f32::INFINITY));
|
ui.add(DragValue::new(&mut self.ne).range(0.0..=f32::INFINITY));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("SW");
|
ui.label("SW");
|
||||||
ui.add(DragValue::new(&mut self.sw).clamp_range(0.0..=f32::INFINITY));
|
ui.add(DragValue::new(&mut self.sw).range(0.0..=f32::INFINITY));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
ui.label("SE");
|
ui.label("SE");
|
||||||
ui.add(DragValue::new(&mut self.se).clamp_range(0.0..=f32::INFINITY));
|
ui.add(DragValue::new(&mut self.se).range(0.0..=f32::INFINITY));
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
@ -2266,13 +2266,13 @@ impl Widget for &mut Shadow {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(&mut offset.x)
|
DragValue::new(&mut offset.x)
|
||||||
.speed(1.0)
|
.speed(1.0)
|
||||||
.clamp_range(-100.0..=100.0)
|
.range(-100.0..=100.0)
|
||||||
.prefix("x: "),
|
.prefix("x: "),
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(&mut offset.y)
|
DragValue::new(&mut offset.y)
|
||||||
.speed(1.0)
|
.speed(1.0)
|
||||||
.clamp_range(-100.0..=100.0)
|
.range(-100.0..=100.0)
|
||||||
.prefix("y: "),
|
.prefix("y: "),
|
||||||
);
|
);
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
@ -2280,14 +2280,14 @@ impl Widget for &mut Shadow {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(blur)
|
DragValue::new(blur)
|
||||||
.speed(1.0)
|
.speed(1.0)
|
||||||
.clamp_range(0.0..=100.0)
|
.range(0.0..=100.0)
|
||||||
.prefix("blur: "),
|
.prefix("blur: "),
|
||||||
);
|
);
|
||||||
|
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(spread)
|
DragValue::new(spread)
|
||||||
.speed(1.0)
|
.speed(1.0)
|
||||||
.clamp_range(0.0..=100.0)
|
.range(0.0..=100.0)
|
||||||
.prefix("spread: "),
|
.prefix("spread: "),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -2302,12 +2302,8 @@ impl Widget for &mut Stroke {
|
||||||
let Stroke { width, color } = self;
|
let Stroke { width, color } = self;
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(
|
ui.add(DragValue::new(width).speed(0.1).range(0.0..=f32::INFINITY))
|
||||||
DragValue::new(width)
|
.on_hover_text("Width");
|
||||||
.speed(0.1)
|
|
||||||
.clamp_range(0.0..=f32::INFINITY),
|
|
||||||
)
|
|
||||||
.on_hover_text("Width");
|
|
||||||
ui.color_edit_button_srgba(color);
|
ui.color_edit_button_srgba(color);
|
||||||
|
|
||||||
// stroke preview:
|
// stroke preview:
|
||||||
|
|
|
||||||
|
|
@ -410,7 +410,7 @@ fn rgba_edit_ui(ui: &mut Ui, [r, g, b, a]: &mut [f32; 4], alpha: Alpha) -> bool
|
||||||
DragValue::new(value)
|
DragValue::new(value)
|
||||||
.speed(0.003)
|
.speed(0.003)
|
||||||
.prefix(prefix)
|
.prefix(prefix)
|
||||||
.clamp_range(0.0..=1.0)
|
.range(0.0..=1.0)
|
||||||
.custom_formatter(|n, _| format!("{n:.03}"))
|
.custom_formatter(|n, _| format!("{n:.03}"))
|
||||||
.ui(ui)
|
.ui(ui)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,8 @@ pub struct DragValue<'a> {
|
||||||
speed: f64,
|
speed: f64,
|
||||||
prefix: String,
|
prefix: String,
|
||||||
suffix: String,
|
suffix: String,
|
||||||
clamp_range: RangeInclusive<f64>,
|
range: RangeInclusive<f64>,
|
||||||
|
clamp_to_range: bool,
|
||||||
min_decimals: usize,
|
min_decimals: usize,
|
||||||
max_decimals: Option<usize>,
|
max_decimals: Option<usize>,
|
||||||
custom_formatter: Option<NumFormatter<'a>>,
|
custom_formatter: Option<NumFormatter<'a>>,
|
||||||
|
|
@ -55,9 +56,7 @@ impl<'a> DragValue<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
if Num::INTEGRAL {
|
if Num::INTEGRAL {
|
||||||
slf.max_decimals(0)
|
slf.max_decimals(0).range(Num::MIN..=Num::MAX).speed(0.25)
|
||||||
.clamp_range(Num::MIN..=Num::MAX)
|
|
||||||
.speed(0.25)
|
|
||||||
} else {
|
} else {
|
||||||
slf
|
slf
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +68,8 @@ impl<'a> DragValue<'a> {
|
||||||
speed: 1.0,
|
speed: 1.0,
|
||||||
prefix: Default::default(),
|
prefix: Default::default(),
|
||||||
suffix: Default::default(),
|
suffix: Default::default(),
|
||||||
clamp_range: f64::NEG_INFINITY..=f64::INFINITY,
|
range: f64::NEG_INFINITY..=f64::INFINITY,
|
||||||
|
clamp_to_range: true,
|
||||||
min_decimals: 0,
|
min_decimals: 0,
|
||||||
max_decimals: None,
|
max_decimals: None,
|
||||||
custom_formatter: None,
|
custom_formatter: None,
|
||||||
|
|
@ -87,10 +87,35 @@ impl<'a> DragValue<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clamp incoming and outgoing values to this range.
|
/// Sets valid range for the value.
|
||||||
|
///
|
||||||
|
/// By default all values are clamped to this range, even when not interacted with.
|
||||||
|
/// You can change this behavior by passing `false` to [`Slider::clamp_to_range`].
|
||||||
|
#[deprecated = "Use `range` instead"]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn clamp_range<Num: emath::Numeric>(mut self, clamp_range: RangeInclusive<Num>) -> Self {
|
pub fn clamp_range<Num: emath::Numeric>(mut self, range: RangeInclusive<Num>) -> Self {
|
||||||
self.clamp_range = clamp_range.start().to_f64()..=clamp_range.end().to_f64();
|
self.range = range.start().to_f64()..=range.end().to_f64();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets valid range for dragging the value.
|
||||||
|
///
|
||||||
|
/// By default all values are clamped to this range, even when not interacted with.
|
||||||
|
/// You can change this behavior by passing `false` to [`Slider::clamp_to_range`].
|
||||||
|
#[inline]
|
||||||
|
pub fn range<Num: emath::Numeric>(mut self, range: RangeInclusive<Num>) -> Self {
|
||||||
|
self.range = range.start().to_f64()..=range.end().to_f64();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If set to `true`, all incoming and outgoing values will be clamped to the sliding [`Self::range`] (if any).
|
||||||
|
///
|
||||||
|
/// If set to `false`, a value outside of the range that is set programmatically or by user input will not be changed.
|
||||||
|
/// Dragging will be restricted to the range regardless of this setting.
|
||||||
|
/// Default: `true`.
|
||||||
|
#[inline]
|
||||||
|
pub fn clamp_to_range(mut self, clamp_to_range: bool) -> Self {
|
||||||
|
self.clamp_to_range = clamp_to_range;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +182,7 @@ impl<'a> DragValue<'a> {
|
||||||
/// # egui::__run_test_ui(|ui| {
|
/// # egui::__run_test_ui(|ui| {
|
||||||
/// # let mut my_i32: i32 = 0;
|
/// # let mut my_i32: i32 = 0;
|
||||||
/// ui.add(egui::DragValue::new(&mut my_i32)
|
/// ui.add(egui::DragValue::new(&mut my_i32)
|
||||||
/// .clamp_range(0..=((60 * 60 * 24) - 1))
|
/// .range(0..=((60 * 60 * 24) - 1))
|
||||||
/// .custom_formatter(|n, _| {
|
/// .custom_formatter(|n, _| {
|
||||||
/// let n = n as i32;
|
/// let n = n as i32;
|
||||||
/// let hours = n / (60 * 60);
|
/// let hours = n / (60 * 60);
|
||||||
|
|
@ -201,7 +226,7 @@ impl<'a> DragValue<'a> {
|
||||||
/// # egui::__run_test_ui(|ui| {
|
/// # egui::__run_test_ui(|ui| {
|
||||||
/// # let mut my_i32: i32 = 0;
|
/// # let mut my_i32: i32 = 0;
|
||||||
/// ui.add(egui::DragValue::new(&mut my_i32)
|
/// ui.add(egui::DragValue::new(&mut my_i32)
|
||||||
/// .clamp_range(0..=((60 * 60 * 24) - 1))
|
/// .range(0..=((60 * 60 * 24) - 1))
|
||||||
/// .custom_formatter(|n, _| {
|
/// .custom_formatter(|n, _| {
|
||||||
/// let n = n as i32;
|
/// let n = n as i32;
|
||||||
/// let hours = n / (60 * 60);
|
/// let hours = n / (60 * 60);
|
||||||
|
|
@ -361,7 +386,8 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
let Self {
|
let Self {
|
||||||
mut get_set_value,
|
mut get_set_value,
|
||||||
speed,
|
speed,
|
||||||
clamp_range,
|
range,
|
||||||
|
clamp_to_range,
|
||||||
prefix,
|
prefix,
|
||||||
suffix,
|
suffix,
|
||||||
min_decimals,
|
min_decimals,
|
||||||
|
|
@ -439,12 +465,15 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if clamp_to_range {
|
||||||
|
value = clamp_value_to_range(value, range.clone());
|
||||||
|
}
|
||||||
|
|
||||||
if change != 0.0 {
|
if change != 0.0 {
|
||||||
value += speed * change;
|
value += speed * change;
|
||||||
value = emath::round_to_decimals(value, auto_decimals);
|
value = emath::round_to_decimals(value, auto_decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = clamp_to_range(value, clamp_range.clone());
|
|
||||||
if old_value != value {
|
if old_value != value {
|
||||||
set(&mut get_set_value, value);
|
set(&mut get_set_value, value);
|
||||||
ui.data_mut(|data| data.remove::<String>(id));
|
ui.data_mut(|data| data.remove::<String>(id));
|
||||||
|
|
@ -466,8 +495,10 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
Some(parser) => parser(&value_text),
|
Some(parser) => parser(&value_text),
|
||||||
None => value_text.parse().ok(),
|
None => value_text.parse().ok(),
|
||||||
};
|
};
|
||||||
if let Some(parsed_value) = parsed_value {
|
if let Some(mut parsed_value) = parsed_value {
|
||||||
let parsed_value = clamp_to_range(parsed_value, clamp_range.clone());
|
if clamp_to_range {
|
||||||
|
parsed_value = clamp_value_to_range(parsed_value, range.clone());
|
||||||
|
}
|
||||||
set(&mut get_set_value, parsed_value);
|
set(&mut get_set_value, parsed_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -503,8 +534,10 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
Some(parser) => parser(&value_text),
|
Some(parser) => parser(&value_text),
|
||||||
None => value_text.parse().ok(),
|
None => value_text.parse().ok(),
|
||||||
};
|
};
|
||||||
if let Some(parsed_value) = parsed_value {
|
if let Some(mut parsed_value) = parsed_value {
|
||||||
let parsed_value = clamp_to_range(parsed_value, clamp_range.clone());
|
if clamp_to_range {
|
||||||
|
parsed_value = clamp_value_to_range(parsed_value, range.clone());
|
||||||
|
}
|
||||||
set(&mut get_set_value, parsed_value);
|
set(&mut get_set_value, parsed_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -519,9 +552,9 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
.sense(Sense::click_and_drag())
|
.sense(Sense::click_and_drag())
|
||||||
.min_size(ui.spacing().interact_size); // TODO(emilk): find some more generic solution to `min_size`
|
.min_size(ui.spacing().interact_size); // TODO(emilk): find some more generic solution to `min_size`
|
||||||
|
|
||||||
let cursor_icon = if value <= *clamp_range.start() {
|
let cursor_icon = if value <= *range.start() {
|
||||||
CursorIcon::ResizeEast
|
CursorIcon::ResizeEast
|
||||||
} else if value < *clamp_range.end() {
|
} else if value < *range.end() {
|
||||||
CursorIcon::ResizeHorizontal
|
CursorIcon::ResizeHorizontal
|
||||||
} else {
|
} else {
|
||||||
CursorIcon::ResizeWest
|
CursorIcon::ResizeWest
|
||||||
|
|
@ -576,7 +609,8 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
);
|
);
|
||||||
let rounded_new_value =
|
let rounded_new_value =
|
||||||
emath::round_to_decimals(rounded_new_value, auto_decimals);
|
emath::round_to_decimals(rounded_new_value, auto_decimals);
|
||||||
let rounded_new_value = clamp_to_range(rounded_new_value, clamp_range.clone());
|
// Dragging will always clamp the value to the range.
|
||||||
|
let rounded_new_value = clamp_value_to_range(rounded_new_value, range.clone());
|
||||||
set(&mut get_set_value, rounded_new_value);
|
set(&mut get_set_value, rounded_new_value);
|
||||||
|
|
||||||
ui.data_mut(|data| data.insert_temp::<f64>(id, precise_value));
|
ui.data_mut(|data| data.insert_temp::<f64>(id, precise_value));
|
||||||
|
|
@ -596,18 +630,18 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
// If either end of the range is unbounded, it's better
|
// If either end of the range is unbounded, it's better
|
||||||
// to leave the corresponding AccessKit field set to None,
|
// to leave the corresponding AccessKit field set to None,
|
||||||
// to allow for platform-specific default behavior.
|
// to allow for platform-specific default behavior.
|
||||||
if clamp_range.start().is_finite() {
|
if range.start().is_finite() {
|
||||||
builder.set_min_numeric_value(*clamp_range.start());
|
builder.set_min_numeric_value(*range.start());
|
||||||
}
|
}
|
||||||
if clamp_range.end().is_finite() {
|
if range.end().is_finite() {
|
||||||
builder.set_max_numeric_value(*clamp_range.end());
|
builder.set_max_numeric_value(*range.end());
|
||||||
}
|
}
|
||||||
builder.set_numeric_value_step(speed);
|
builder.set_numeric_value_step(speed);
|
||||||
builder.add_action(Action::SetValue);
|
builder.add_action(Action::SetValue);
|
||||||
if value < *clamp_range.end() {
|
if value < *range.end() {
|
||||||
builder.add_action(Action::Increment);
|
builder.add_action(Action::Increment);
|
||||||
}
|
}
|
||||||
if value > *clamp_range.start() {
|
if value > *range.start() {
|
||||||
builder.add_action(Action::Decrement);
|
builder.add_action(Action::Decrement);
|
||||||
}
|
}
|
||||||
// The name field is set to the current value by the button,
|
// The name field is set to the current value by the button,
|
||||||
|
|
@ -641,7 +675,7 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clamp_to_range(x: f64, range: RangeInclusive<f64>) -> f64 {
|
fn clamp_value_to_range(x: f64, range: RangeInclusive<f64>) -> f64 {
|
||||||
let (mut min, mut max) = (*range.start(), *range.end());
|
let (mut min, mut max) = (*range.start(), *range.end());
|
||||||
|
|
||||||
if min.total_cmp(&max) == Ordering::Greater {
|
if min.total_cmp(&max) == Ordering::Greater {
|
||||||
|
|
@ -659,7 +693,7 @@ fn clamp_to_range(x: f64, range: RangeInclusive<f64>) -> f64 {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::clamp_to_range;
|
use super::clamp_value_to_range;
|
||||||
|
|
||||||
macro_rules! total_assert_eq {
|
macro_rules! total_assert_eq {
|
||||||
($a:expr, $b:expr) => {
|
($a:expr, $b:expr) => {
|
||||||
|
|
@ -673,16 +707,16 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_total_cmp_clamp_to_range() {
|
fn test_total_cmp_clamp_value_to_range() {
|
||||||
total_assert_eq!(0.0_f64, clamp_to_range(-0.0, 0.0..=f64::MAX));
|
total_assert_eq!(0.0_f64, clamp_value_to_range(-0.0, 0.0..=f64::MAX));
|
||||||
total_assert_eq!(-0.0_f64, clamp_to_range(0.0, -1.0..=-0.0));
|
total_assert_eq!(-0.0_f64, clamp_value_to_range(0.0, -1.0..=-0.0));
|
||||||
total_assert_eq!(-1.0_f64, clamp_to_range(-25.0, -1.0..=1.0));
|
total_assert_eq!(-1.0_f64, clamp_value_to_range(-25.0, -1.0..=1.0));
|
||||||
total_assert_eq!(5.0_f64, clamp_to_range(5.0, -1.0..=10.0));
|
total_assert_eq!(5.0_f64, clamp_value_to_range(5.0, -1.0..=10.0));
|
||||||
total_assert_eq!(15.0_f64, clamp_to_range(25.0, -1.0..=15.0));
|
total_assert_eq!(15.0_f64, clamp_value_to_range(25.0, -1.0..=15.0));
|
||||||
total_assert_eq!(1.0_f64, clamp_to_range(1.0, 1.0..=10.0));
|
total_assert_eq!(1.0_f64, clamp_value_to_range(1.0, 1.0..=10.0));
|
||||||
total_assert_eq!(10.0_f64, clamp_to_range(10.0, 1.0..=10.0));
|
total_assert_eq!(10.0_f64, clamp_value_to_range(10.0, 1.0..=10.0));
|
||||||
total_assert_eq!(5.0_f64, clamp_to_range(5.0, 10.0..=1.0));
|
total_assert_eq!(5.0_f64, clamp_value_to_range(5.0, 10.0..=1.0));
|
||||||
total_assert_eq!(5.0_f64, clamp_to_range(15.0, 5.0..=1.0));
|
total_assert_eq!(5.0_f64, clamp_value_to_range(15.0, 5.0..=1.0));
|
||||||
total_assert_eq!(1.0_f64, clamp_to_range(-5.0, 5.0..=1.0));
|
total_assert_eq!(1.0_f64, clamp_value_to_range(-5.0, 5.0..=1.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,8 @@ pub enum SliderOrientation {
|
||||||
/// Control a number with a slider.
|
/// Control a number with a slider.
|
||||||
///
|
///
|
||||||
/// The slider range defines the values you get when pulling the slider to the far edges.
|
/// The slider range defines the values you get when pulling the slider to the far edges.
|
||||||
/// By default, the slider can still show values outside this range,
|
/// By default all values are clamped to this range, even when not interacted with.
|
||||||
/// and still allows users to enter values outside the range by clicking the slider value and editing it.
|
/// You can change this behavior by passing `false` to [`Slider::clamp_to_range`].
|
||||||
/// If you want to clamp incoming and outgoing values, use [`Slider::clamp_to_range`].
|
|
||||||
///
|
///
|
||||||
/// The range can include any numbers, and go from low-to-high or from high-to-low.
|
/// The range can include any numbers, and go from low-to-high or from high-to-low.
|
||||||
///
|
///
|
||||||
|
|
@ -545,14 +544,6 @@ impl<'a> Slider<'a> {
|
||||||
set(&mut self.get_set_value, value);
|
set(&mut self.get_set_value, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clamp_range(&self) -> RangeInclusive<f64> {
|
|
||||||
if self.clamp_to_range {
|
|
||||||
self.range()
|
|
||||||
} else {
|
|
||||||
f64::NEG_INFINITY..=f64::INFINITY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn range(&self) -> RangeInclusive<f64> {
|
fn range(&self) -> RangeInclusive<f64> {
|
||||||
self.range.clone()
|
self.range.clone()
|
||||||
}
|
}
|
||||||
|
|
@ -818,7 +809,8 @@ impl<'a> Slider<'a> {
|
||||||
let response = ui.add({
|
let response = ui.add({
|
||||||
let mut dv = DragValue::new(&mut value)
|
let mut dv = DragValue::new(&mut value)
|
||||||
.speed(speed)
|
.speed(speed)
|
||||||
.clamp_range(self.clamp_range())
|
.range(self.range.clone())
|
||||||
|
.clamp_to_range(self.clamp_to_range)
|
||||||
.min_decimals(self.min_decimals)
|
.min_decimals(self.min_decimals)
|
||||||
.max_decimals_opt(self.max_decimals)
|
.max_decimals_opt(self.max_decimals)
|
||||||
.suffix(self.suffix.clone())
|
.suffix(self.suffix.clone())
|
||||||
|
|
@ -870,7 +862,12 @@ impl<'a> Slider<'a> {
|
||||||
builder.set_numeric_value_step(step);
|
builder.set_numeric_value_step(step);
|
||||||
}
|
}
|
||||||
builder.add_action(Action::SetValue);
|
builder.add_action(Action::SetValue);
|
||||||
let clamp_range = self.clamp_range();
|
|
||||||
|
let clamp_range = if self.clamp_to_range {
|
||||||
|
self.range()
|
||||||
|
} else {
|
||||||
|
f64::NEG_INFINITY..=f64::INFINITY
|
||||||
|
};
|
||||||
if value < *clamp_range.end() {
|
if value < *clamp_range.end() {
|
||||||
builder.add_action(Action::Increment);
|
builder.add_action(Action::Increment);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,15 +43,11 @@ impl CodeExample {
|
||||||
r#"
|
r#"
|
||||||
ui.add(
|
ui.add(
|
||||||
egui::DragValue::new(age)
|
egui::DragValue::new(age)
|
||||||
.clamp_range(0..=120)
|
.range(0..=120)
|
||||||
.suffix(" years"),
|
.suffix(" years"),
|
||||||
);"#,
|
);"#,
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(egui::DragValue::new(age).range(0..=120).suffix(" years"));
|
||||||
egui::DragValue::new(age)
|
|
||||||
.clamp_range(0..=120)
|
|
||||||
.suffix(" years"),
|
|
||||||
);
|
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
|
|
||||||
show_code(
|
show_code(
|
||||||
|
|
|
||||||
|
|
@ -95,13 +95,13 @@ impl crate::View for ContextMenus {
|
||||||
egui::Grid::new("button_grid").show(ui, |ui| {
|
egui::Grid::new("button_grid").show(ui, |ui| {
|
||||||
ui.add(
|
ui.add(
|
||||||
egui::DragValue::new(&mut self.width)
|
egui::DragValue::new(&mut self.width)
|
||||||
.clamp_range(0.0..=f32::INFINITY)
|
.range(0.0..=f32::INFINITY)
|
||||||
.speed(1.0)
|
.speed(1.0)
|
||||||
.prefix("Width: "),
|
.prefix("Width: "),
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
egui::DragValue::new(&mut self.height)
|
egui::DragValue::new(&mut self.height)
|
||||||
.clamp_range(0.0..=f32::INFINITY)
|
.range(0.0..=f32::INFINITY)
|
||||||
.speed(1.0)
|
.speed(1.0)
|
||||||
.prefix("Height: "),
|
.prefix("Height: "),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ impl LineDemo {
|
||||||
ui.add(
|
ui.add(
|
||||||
egui::DragValue::new(circle_radius)
|
egui::DragValue::new(circle_radius)
|
||||||
.speed(0.1)
|
.speed(0.1)
|
||||||
.clamp_range(0.0..=f64::INFINITY)
|
.range(0.0..=f64::INFINITY)
|
||||||
.prefix("r: "),
|
.prefix("r: "),
|
||||||
);
|
);
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
|
@ -353,7 +353,7 @@ impl MarkerDemo {
|
||||||
ui.add(
|
ui.add(
|
||||||
egui::DragValue::new(&mut self.marker_radius)
|
egui::DragValue::new(&mut self.marker_radius)
|
||||||
.speed(0.1)
|
.speed(0.1)
|
||||||
.clamp_range(0.0..=f64::INFINITY)
|
.range(0.0..=f64::INFINITY)
|
||||||
.prefix("Radius: "),
|
.prefix("Radius: "),
|
||||||
);
|
);
|
||||||
ui.checkbox(&mut self.automatic_colors, "Automatic colors");
|
ui.checkbox(&mut self.automatic_colors, "Automatic colors");
|
||||||
|
|
@ -432,7 +432,7 @@ impl LegendDemo {
|
||||||
ui.add(
|
ui.add(
|
||||||
egui::DragValue::new(&mut config.background_alpha)
|
egui::DragValue::new(&mut config.background_alpha)
|
||||||
.speed(0.02)
|
.speed(0.02)
|
||||||
.clamp_range(0.0..=1.0),
|
.range(0.0..=1.0),
|
||||||
);
|
);
|
||||||
ui.end_row();
|
ui.end_row();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ impl crate::View for WidgetGallery {
|
||||||
(ui.add(
|
(ui.add(
|
||||||
egui::DragValue::new(&mut self.opacity)
|
egui::DragValue::new(&mut self.opacity)
|
||||||
.speed(0.01)
|
.speed(0.01)
|
||||||
.clamp_range(0.0..=1.0),
|
.range(0.0..=1.0),
|
||||||
) | ui.label("Opacity"))
|
) | ui.label("Opacity"))
|
||||||
.on_hover_text("Reduce this value to make widgets semi-transparent");
|
.on_hover_text("Reduce this value to make widgets semi-transparent");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ impl eframe::App for PlotExample {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(&mut self.zoom_speed)
|
DragValue::new(&mut self.zoom_speed)
|
||||||
.clamp_range(0.1..=2.0)
|
.range(0.1..=2.0)
|
||||||
.speed(0.1),
|
.speed(0.1),
|
||||||
);
|
);
|
||||||
ui.label("Zoom speed").on_hover_text("How fast to zoom in and out with the mouse wheel");
|
ui.label("Zoom speed").on_hover_text("How fast to zoom in and out with the mouse wheel");
|
||||||
|
|
@ -55,7 +55,7 @@ impl eframe::App for PlotExample {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(
|
ui.add(
|
||||||
DragValue::new(&mut self.scroll_speed)
|
DragValue::new(&mut self.scroll_speed)
|
||||||
.clamp_range(0.1..=100.0)
|
.range(0.1..=100.0)
|
||||||
.speed(0.1),
|
.speed(0.1),
|
||||||
);
|
);
|
||||||
ui.label("Scroll speed").on_hover_text("How fast to pan with the mouse wheel");
|
ui.label("Scroll speed").on_hover_text("How fast to pan with the mouse wheel");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue