Add `trailing_fill()` toggle to `Slider` (#2660)
* slider: add trailing_color toggle * slider/visuals: add global option in visuals with override toggle * slider: add to demos * use `.unwrap_or_else()` instead of match
This commit is contained in:
parent
212656f3fc
commit
628c84cbee
|
|
@ -8,6 +8,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG
|
||||||
* ⚠️ BREAKING: `egui::Context` now use closures for locking ([#2625](https://github.com/emilk/egui/pull/2625)):
|
* ⚠️ BREAKING: `egui::Context` now use closures for locking ([#2625](https://github.com/emilk/egui/pull/2625)):
|
||||||
* `ctx.input().key_pressed(Key::A)` -> `ctx.input(|i| i.key_pressed(Key::A))`
|
* `ctx.input().key_pressed(Key::A)` -> `ctx.input(|i| i.key_pressed(Key::A))`
|
||||||
* `ui.memory().toggle_popup(popup_id)` -> `ui.memory_mut(|mem| mem.toggle_popup(popup_id))`
|
* `ui.memory().toggle_popup(popup_id)` -> `ui.memory_mut(|mem| mem.toggle_popup(popup_id))`
|
||||||
|
* Add `Slider::trailing_fill` for trailing color behind the circle like a `ProgressBar` ([#2660](https://github.com/emilk/egui/pull/2660)).
|
||||||
|
|
||||||
### Added ⭐
|
### Added ⭐
|
||||||
* Add `Response::drag_started_by` and `Response::drag_released_by` for convenience, similar to `dragged` and `dragged_by` ([#2507](https://github.com/emilk/egui/pull/2507)).
|
* Add `Response::drag_started_by` and `Response::drag_released_by` for convenience, similar to `dragged` and `dragged_by` ([#2507](https://github.com/emilk/egui/pull/2507)).
|
||||||
|
|
|
||||||
|
|
@ -509,6 +509,11 @@ pub struct Visuals {
|
||||||
/// Wether or not Grids and Tables should be striped by default
|
/// Wether or not Grids and Tables should be striped by default
|
||||||
/// (have alternating rows differently colored).
|
/// (have alternating rows differently colored).
|
||||||
pub striped: bool,
|
pub striped: bool,
|
||||||
|
|
||||||
|
/// Show trailing color behind the circle of a [`Slider`]. Default is OFF.
|
||||||
|
///
|
||||||
|
/// Enabling this will affect ALL sliders, and can be enabled/disabled per slider with [`Slider::trailing_fill`].
|
||||||
|
pub slider_trailing_fill: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visuals {
|
impl Visuals {
|
||||||
|
|
@ -768,6 +773,8 @@ impl Visuals {
|
||||||
indent_has_left_vline: true,
|
indent_has_left_vline: true,
|
||||||
|
|
||||||
striped: false,
|
striped: false,
|
||||||
|
|
||||||
|
slider_trailing_fill: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1333,6 +1340,8 @@ impl Visuals {
|
||||||
indent_has_left_vline,
|
indent_has_left_vline,
|
||||||
|
|
||||||
striped,
|
striped,
|
||||||
|
|
||||||
|
slider_trailing_fill,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui.collapsing("Background Colors", |ui| {
|
ui.collapsing("Background Colors", |ui| {
|
||||||
|
|
@ -1395,6 +1404,8 @@ impl Visuals {
|
||||||
|
|
||||||
ui.checkbox(striped, "By default, add stripes to grids and tables?");
|
ui.checkbox(striped, "By default, add stripes to grids and tables?");
|
||||||
|
|
||||||
|
ui.checkbox(slider_trailing_fill, "Add trailing color to sliders");
|
||||||
|
|
||||||
ui.vertical_centered(|ui| reset_button(ui, self));
|
ui.vertical_centered(|ui| reset_button(ui, self));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ pub struct Slider<'a> {
|
||||||
max_decimals: Option<usize>,
|
max_decimals: Option<usize>,
|
||||||
custom_formatter: Option<NumFormatter<'a>>,
|
custom_formatter: Option<NumFormatter<'a>>,
|
||||||
custom_parser: Option<NumParser<'a>>,
|
custom_parser: Option<NumParser<'a>>,
|
||||||
|
trailing_fill: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Slider<'a> {
|
impl<'a> Slider<'a> {
|
||||||
|
|
@ -129,6 +130,7 @@ impl<'a> Slider<'a> {
|
||||||
max_decimals: None,
|
max_decimals: None,
|
||||||
custom_formatter: None,
|
custom_formatter: None,
|
||||||
custom_parser: None,
|
custom_parser: None,
|
||||||
|
trailing_fill: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,6 +271,17 @@ impl<'a> Slider<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Display trailing color behind the slider's circle. Default is OFF.
|
||||||
|
///
|
||||||
|
/// This setting can be enabled globally for all sliders with [`Visuals::slider_trailing_fill`].
|
||||||
|
/// Toggling it here will override the above setting ONLY for this individual slider.
|
||||||
|
///
|
||||||
|
/// The fill color will be taken from `selection.bg_fill` in your [`Visuals`], the same as a [`ProgressBar`].
|
||||||
|
pub fn trailing_fill(mut self, trailing_fill: bool) -> Self {
|
||||||
|
self.trailing_fill = Some(trailing_fill);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set custom formatter defining how numbers are converted into text.
|
/// Set custom formatter defining how numbers are converted into text.
|
||||||
///
|
///
|
||||||
/// A custom formatter takes a `f64` for the numeric value and a `RangeInclusive<usize>` representing
|
/// A custom formatter takes a `f64` for the numeric value and a `RangeInclusive<usize>` representing
|
||||||
|
|
@ -616,18 +629,40 @@ impl<'a> Slider<'a> {
|
||||||
let rail_radius = ui.painter().round_to_pixel(self.rail_radius_limit(rect));
|
let rail_radius = ui.painter().round_to_pixel(self.rail_radius_limit(rect));
|
||||||
let rail_rect = self.rail_rect(rect, rail_radius);
|
let rail_rect = self.rail_rect(rect, rail_radius);
|
||||||
|
|
||||||
let position_1d = self.position_from_value(value, position_range);
|
|
||||||
|
|
||||||
let visuals = ui.style().interact(response);
|
let visuals = ui.style().interact(response);
|
||||||
ui.painter().add(epaint::RectShape {
|
let widget_visuals = &ui.visuals().widgets;
|
||||||
rect: rail_rect,
|
|
||||||
rounding: ui.visuals().widgets.inactive.rounding,
|
|
||||||
fill: ui.visuals().widgets.inactive.bg_fill,
|
|
||||||
stroke: Default::default(),
|
|
||||||
});
|
|
||||||
|
|
||||||
|
ui.painter().rect_filled(
|
||||||
|
rail_rect,
|
||||||
|
widget_visuals.inactive.rounding,
|
||||||
|
widget_visuals.inactive.bg_fill,
|
||||||
|
);
|
||||||
|
|
||||||
|
let position_1d = self.position_from_value(value, position_range);
|
||||||
let center = self.marker_center(position_1d, &rail_rect);
|
let center = self.marker_center(position_1d, &rail_rect);
|
||||||
|
|
||||||
|
// Decide if we should add trailing fill.
|
||||||
|
let trailing_fill = self
|
||||||
|
.trailing_fill
|
||||||
|
.unwrap_or_else(|| ui.visuals().slider_trailing_fill);
|
||||||
|
|
||||||
|
// Paint trailing fill.
|
||||||
|
if trailing_fill {
|
||||||
|
let mut trailing_rail_rect = rail_rect;
|
||||||
|
|
||||||
|
// The trailing rect has to be drawn differently depending on the orientation.
|
||||||
|
match self.orientation {
|
||||||
|
SliderOrientation::Vertical => trailing_rail_rect.min.y = center.y,
|
||||||
|
SliderOrientation::Horizontal => trailing_rail_rect.max.x = center.x,
|
||||||
|
};
|
||||||
|
|
||||||
|
ui.painter().rect_filled(
|
||||||
|
trailing_rail_rect,
|
||||||
|
widget_visuals.inactive.rounding,
|
||||||
|
ui.visuals().selection.bg_fill,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
ui.painter().add(epaint::CircleShape {
|
ui.painter().add(epaint::CircleShape {
|
||||||
center,
|
center,
|
||||||
radius: self.handle_radius(rect) + visuals.expansion,
|
radius: self.handle_radius(rect) + visuals.expansion,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ pub struct Sliders {
|
||||||
pub integer: bool,
|
pub integer: bool,
|
||||||
pub vertical: bool,
|
pub vertical: bool,
|
||||||
pub value: f64,
|
pub value: f64,
|
||||||
|
pub trailing_fill: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Sliders {
|
impl Default for Sliders {
|
||||||
|
|
@ -31,6 +32,7 @@ impl Default for Sliders {
|
||||||
integer: false,
|
integer: false,
|
||||||
vertical: false,
|
vertical: false,
|
||||||
value: 10.0,
|
value: 10.0,
|
||||||
|
trailing_fill: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -64,6 +66,7 @@ impl super::View for Sliders {
|
||||||
integer,
|
integer,
|
||||||
vertical,
|
vertical,
|
||||||
value,
|
value,
|
||||||
|
trailing_fill,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
ui.label("You can click a slider value to edit it with the keyboard.");
|
ui.label("You can click a slider value to edit it with the keyboard.");
|
||||||
|
|
@ -95,7 +98,8 @@ impl super::View for Sliders {
|
||||||
.smart_aim(*smart_aim)
|
.smart_aim(*smart_aim)
|
||||||
.orientation(orientation)
|
.orientation(orientation)
|
||||||
.text("i32 demo slider")
|
.text("i32 demo slider")
|
||||||
.step_by(istep),
|
.step_by(istep)
|
||||||
|
.trailing_fill(*trailing_fill),
|
||||||
);
|
);
|
||||||
*value = value_i32 as f64;
|
*value = value_i32 as f64;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -106,7 +110,8 @@ impl super::View for Sliders {
|
||||||
.smart_aim(*smart_aim)
|
.smart_aim(*smart_aim)
|
||||||
.orientation(orientation)
|
.orientation(orientation)
|
||||||
.text("f64 demo slider")
|
.text("f64 demo slider")
|
||||||
.step_by(istep),
|
.step_by(istep)
|
||||||
|
.trailing_fill(*trailing_fill),
|
||||||
);
|
);
|
||||||
|
|
||||||
ui.label(
|
ui.label(
|
||||||
|
|
@ -126,17 +131,24 @@ impl super::View for Sliders {
|
||||||
Slider::new(min, type_min..=type_max)
|
Slider::new(min, type_min..=type_max)
|
||||||
.logarithmic(true)
|
.logarithmic(true)
|
||||||
.smart_aim(*smart_aim)
|
.smart_aim(*smart_aim)
|
||||||
.text("left"),
|
.text("left")
|
||||||
|
.trailing_fill(*trailing_fill),
|
||||||
);
|
);
|
||||||
ui.add(
|
ui.add(
|
||||||
Slider::new(max, type_min..=type_max)
|
Slider::new(max, type_min..=type_max)
|
||||||
.logarithmic(true)
|
.logarithmic(true)
|
||||||
.smart_aim(*smart_aim)
|
.smart_aim(*smart_aim)
|
||||||
.text("right"),
|
.text("right")
|
||||||
|
.trailing_fill(*trailing_fill),
|
||||||
);
|
);
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
|
ui.checkbox(trailing_fill, "Toggle trailing color");
|
||||||
|
ui.label("When enabled, trailing color will be painted up until the circle.");
|
||||||
|
|
||||||
|
ui.separator();
|
||||||
|
|
||||||
ui.checkbox(use_steps, "Use steps");
|
ui.checkbox(use_steps, "Use steps");
|
||||||
ui.label("When enabled, the minimal value change would be restricted to a given step.");
|
ui.label("When enabled, the minimal value change would be restricted to a given step.");
|
||||||
if *use_steps {
|
if *use_steps {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue