1
0
Fork 0

Render the ParamSlider value

This commit is contained in:
Robbert van der Helm 2022-02-09 19:45:54 +01:00
parent b61d17fee9
commit e1f80e203a

View file

@ -20,16 +20,30 @@ lazy_static! {
/// TODO: Check below for more input methods that should be added /// TODO: Check below for more input methods that should be added
/// TODO: Decouple the logic from the drawing so we can also do things like nobs without having to /// TODO: Decouple the logic from the drawing so we can also do things like nobs without having to
/// repeat everything /// repeat everything
/// TODO: Add WidgetInfo annotations for accessibility
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct ParamSlider<'a, P: Param> { pub struct ParamSlider<'a, P: Param> {
param: &'a P, param: &'a P,
setter: &'a ParamSetter<'a>, setter: &'a ParamSetter<'a>,
draw_value: bool,
} }
impl<'a, P: Param> ParamSlider<'a, P> { impl<'a, P: Param> ParamSlider<'a, P> {
/// Create a new slider for a parameter. Use the other methods to modify the slider before /// Create a new slider for a parameter. Use the other methods to modify the slider before
/// passing it to [Ui::add()]. /// passing it to [Ui::add()].
pub fn for_param(param: &'a P, setter: &'a ParamSetter<'a>) -> Self { pub fn for_param(param: &'a P, setter: &'a ParamSetter<'a>) -> Self {
Self { param, setter } Self {
param,
setter,
draw_value: true,
}
}
/// Don't draw the text slider's current value after the slider.
pub fn without_value(mut self) -> Self {
self.draw_value = false;
self
} }
fn normalized_value(&self) -> f32 { fn normalized_value(&self) -> f32 {
@ -104,7 +118,7 @@ impl<'a, P: Param> ParamSlider<'a, P> {
ui.memory().data.insert_temp(*DRAG_AMOUNT_MEMORY_ID, amount); ui.memory().data.insert_temp(*DRAG_AMOUNT_MEMORY_ID, amount);
} }
fn slider_ui(&self, ui: &Ui, response: &Response) { fn slider_ui(&self, ui: &mut Ui, response: &Response) {
// Handle user input // Handle user input
// TODO: Optionally (since it can be annoying) add scrolling behind a builder option // TODO: Optionally (since it can be annoying) add scrolling behind a builder option
// TODO: Optionally add alt+click for value entry? // TODO: Optionally add alt+click for value entry?
@ -161,37 +175,75 @@ impl<'a, P: Param> ParamSlider<'a, P> {
); );
} }
} }
fn value_ui(&self, ui: &mut Ui) {
let visuals = ui.visuals().widgets.inactive;
let should_draw_frame = ui.visuals().button_frame;
let padding = ui.spacing().button_padding;
let text = ui.painter().layout(
format!("{}", self.param),
TextStyle::Button,
visuals.text_color(),
ui.available_width() - (padding.x * 2.0),
);
let (_, rect) = ui.allocate_space(text.size() + (padding * 2.0));
if ui.is_rect_visible(rect) {
if should_draw_frame {
let fill = visuals.bg_fill;
let stroke = visuals.bg_stroke;
ui.painter().rect(
rect.expand(visuals.expansion),
visuals.corner_radius,
fill,
stroke,
);
}
let text_pos = ui
.layout()
.align_size_within_rect(text.size(), rect.shrink2(padding))
.min;
ui.painter().galley(text_pos, text);
}
}
} }
impl<P: Param> Widget for ParamSlider<'_, P> { impl<P: Param> Widget for ParamSlider<'_, P> {
fn ui(self, ui: &mut Ui) -> Response { fn ui(self, ui: &mut Ui) -> Response {
// Allocate space, but add some padding on the top and bottom to make it look a bit slimmer. ui.horizontal(|ui| {
let height = ui // Allocate space, but add some padding on the top and bottom to make it look a bit slimmer.
.fonts() let height = ui
.row_height(TextStyle::Body) .fonts()
.max(ui.spacing().interact_size.y); .row_height(TextStyle::Body)
let slider_height = ui.painter().round_to_pixel(height * 0.65); .max(ui.spacing().interact_size.y);
let response = ui let slider_height = ui.painter().round_to_pixel(height * 0.65);
.vertical(|ui| { let response = ui
ui.allocate_space(vec2( .vertical(|ui| {
ui.spacing().slider_width, ui.allocate_space(vec2(
(height - slider_height) / 2.0, ui.spacing().slider_width,
)); (height - slider_height) / 2.0,
let response = ui.allocate_response( ));
vec2(ui.spacing().slider_width, slider_height), let response = ui.allocate_response(
Sense::click_and_drag(), vec2(ui.spacing().slider_width, slider_height),
); Sense::click_and_drag(),
ui.allocate_space(vec2( );
ui.spacing().slider_width, ui.allocate_space(vec2(
(height - slider_height) / 2.0, ui.spacing().slider_width,
)); (height - slider_height) / 2.0,
response ));
}) response
.inner; })
.inner;
// TODO: Render the text self.slider_ui(ui, &response);
self.slider_ui(ui, &response); if self.draw_value {
self.value_ui(ui);
}
response response
})
.inner
} }
} }