Move ParamSliderInternal variables to ParamSlider
This commit is contained in:
parent
269c2a51e1
commit
eb33a55fcc
|
@ -16,6 +16,7 @@ const GRANULAR_DRAG_MULTIPLIER: f32 = 0.1;
|
||||||
/// TODO: Handle scrolling for steps (and shift+scroll for smaller steps?)
|
/// TODO: Handle scrolling for steps (and shift+scroll for smaller steps?)
|
||||||
/// TODO: We may want to add a couple dedicated event handlers if it seems like those would be
|
/// TODO: We may want to add a couple dedicated event handlers if it seems like those would be
|
||||||
/// useful, having a completely self contained widget is perfectly fine for now though
|
/// useful, having a completely self contained widget is perfectly fine for now though
|
||||||
|
#[derive(Lens)]
|
||||||
pub struct ParamSlider {
|
pub struct ParamSlider {
|
||||||
// We're not allowed to store a reference to the parameter internally, at least not in the
|
// We're not allowed to store a reference to the parameter internally, at least not in the
|
||||||
// struct that implements [`View`]
|
// struct that implements [`View`]
|
||||||
|
@ -31,6 +32,14 @@ pub struct ParamSlider {
|
||||||
/// dragging for higher precision dragging. This is a `None` value when granular dragging is not
|
/// dragging for higher precision dragging. This is a `None` value when granular dragging is not
|
||||||
/// active.
|
/// active.
|
||||||
granular_drag_start_x_value: Option<(f32, f32)>,
|
granular_drag_start_x_value: Option<(f32, f32)>,
|
||||||
|
|
||||||
|
|
||||||
|
/// What style to use for the slider.
|
||||||
|
style: ParamSliderStyle,
|
||||||
|
/// Will be set to `true` when the field gets Alt+Click'ed which will replae the label with a
|
||||||
|
/// text box.
|
||||||
|
text_input_active: bool,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How the [`ParamSlider`] should display its values. Set this using
|
/// How the [`ParamSlider`] should display its values. Set this using
|
||||||
|
@ -57,42 +66,12 @@ pub enum ParamSliderStyle {
|
||||||
enum ParamSliderEvent {
|
enum ParamSliderEvent {
|
||||||
/// Text input has been cancelled without submitting a new value.
|
/// Text input has been cancelled without submitting a new value.
|
||||||
CancelTextInput,
|
CancelTextInput,
|
||||||
/// A new value has been sent by the text input dialog after pressint Enter.
|
/// A new value has been sent by the text input dialog after pressing Enter.
|
||||||
TextInput(String),
|
TextInput(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Internal param slider state the view needs to react to.
|
|
||||||
#[derive(Lens)]
|
|
||||||
struct ParamSliderInternal {
|
|
||||||
/// What style to use for the slider.
|
|
||||||
style: ParamSliderStyle,
|
|
||||||
/// Will be set to `true` when the field gets Alt+Click'ed which will replae the label with a
|
|
||||||
/// text box.
|
|
||||||
text_input_active: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ParamSliderInternalEvent {
|
|
||||||
SetStyle(ParamSliderStyle),
|
|
||||||
SetTextInputActive(bool),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Model for ParamSliderInternal {
|
|
||||||
fn event(&mut self, _cx: &mut Context, event: &mut Event) {
|
|
||||||
event.map(
|
|
||||||
|param_slider_internal_event, _| match param_slider_internal_event {
|
|
||||||
ParamSliderInternalEvent::SetStyle(style) => self.style = *style,
|
|
||||||
ParamSliderInternalEvent::SetTextInputActive(active) => {
|
|
||||||
// When this gets set to `true` the textbox widget will be created, and when it
|
|
||||||
// gets created we'll focus it and select all text
|
|
||||||
self.text_input_active = *active;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ParamSlider {
|
impl ParamSlider {
|
||||||
/// Creates a new [`ParamSlider`] for the given parameter. To accomdate VIZIA's mapping system,
|
/// Creates a new [`ParamSlider`] for the given parameter. To accommodate VIZIA's mapping system,
|
||||||
/// you'll need to provide a lens containing your `Params` implementation object (check out how
|
/// you'll need to provide a lens containing your `Params` implementation object (check out how
|
||||||
/// the `Data` struct is used in `gain_gui_vizia`) and a projection function that maps the
|
/// the `Data` struct is used in `gain_gui_vizia`) and a projection function that maps the
|
||||||
/// `Params` object to the parameter you want to display a widget for. Parameter changes are
|
/// `Params` object to the parameter you want to display a widget for. Parameter changes are
|
||||||
|
@ -109,7 +88,7 @@ impl ParamSlider {
|
||||||
{
|
{
|
||||||
// We'll visualize the difference between the current value and the default value if the
|
// We'll visualize the difference between the current value and the default value if the
|
||||||
// default value lies somewhere in the middle and the parameter is continuous. Otherwise
|
// default value lies somewhere in the middle and the parameter is continuous. Otherwise
|
||||||
// this appraoch looks a bit jarring.
|
// this approach looks a bit jarring.
|
||||||
// We need to do a bit of a nasty and erase the lifetime bound by going through the raw
|
// We need to do a bit of a nasty and erase the lifetime bound by going through the raw
|
||||||
// GuiContext and a ParamPtr.
|
// GuiContext and a ParamPtr.
|
||||||
let param_ptr = params
|
let param_ptr = params
|
||||||
|
@ -131,15 +110,13 @@ impl ParamSlider {
|
||||||
drag_active: false,
|
drag_active: false,
|
||||||
is_double_click: false,
|
is_double_click: false,
|
||||||
granular_drag_start_x_value: None,
|
granular_drag_start_x_value: None,
|
||||||
|
|
||||||
|
style: ParamSliderStyle::Centered,
|
||||||
|
text_input_active: false,
|
||||||
}
|
}
|
||||||
.build(cx, move |cx| {
|
.build(cx, move |cx| {
|
||||||
ParamSliderInternal {
|
|
||||||
style: ParamSliderStyle::Centered,
|
|
||||||
text_input_active: false,
|
|
||||||
}
|
|
||||||
.build(cx);
|
|
||||||
|
|
||||||
Binding::new(cx, ParamSliderInternal::style, move |cx, style| {
|
Binding::new(cx, ParamSlider::style, move |cx, style| {
|
||||||
let style = style.get(cx);
|
let style = style.get(cx);
|
||||||
let draw_fill_from_default = matches!(style, ParamSliderStyle::Centered)
|
let draw_fill_from_default = matches!(style, ParamSliderStyle::Centered)
|
||||||
&& step_count.is_none()
|
&& step_count.is_none()
|
||||||
|
@ -152,7 +129,7 @@ impl ParamSlider {
|
||||||
let params = params.clone();
|
let params = params.clone();
|
||||||
Binding::new(
|
Binding::new(
|
||||||
cx,
|
cx,
|
||||||
ParamSliderInternal::text_input_active,
|
ParamSlider::text_input_active,
|
||||||
move |cx, text_input_active| {
|
move |cx, text_input_active| {
|
||||||
// Can't use `.to_string()` here as that would include the modulation.
|
// Can't use `.to_string()` here as that would include the modulation.
|
||||||
let param_display_value_lens = params.clone().map(move |params| {
|
let param_display_value_lens = params.clone().map(move |params| {
|
||||||
|
@ -287,7 +264,7 @@ impl ParamSlider {
|
||||||
// should not affect that
|
// should not affect that
|
||||||
.hoverable(false);
|
.hoverable(false);
|
||||||
|
|
||||||
// If the parameter is being modulated, then we'll display anoter
|
// If the parameter is being modulated, then we'll display another
|
||||||
// filled bar showing the current modulation delta
|
// filled bar showing the current modulation delta
|
||||||
// VIZIA's bindings make this a bit, uh, difficult to read
|
// VIZIA's bindings make this a bit, uh, difficult to read
|
||||||
Element::new(cx)
|
Element::new(cx)
|
||||||
|
@ -394,14 +371,11 @@ impl ParamSlider {
|
||||||
/// slider styles from [`ParamSliderStyle`] this will remap the normalized range to match up
|
/// slider styles from [`ParamSliderStyle`] this will remap the normalized range to match up
|
||||||
/// with the fill value display.
|
/// with the fill value display.
|
||||||
fn set_normalized_value_drag(&self, cx: &mut Context, normalized_value: f32) {
|
fn set_normalized_value_drag(&self, cx: &mut Context, normalized_value: f32) {
|
||||||
let normalized_value = match (cx.data(), unsafe { self.param_ptr.step_count() }) {
|
let normalized_value = match (self.style, unsafe { self.param_ptr.step_count() }) {
|
||||||
(
|
(
|
||||||
Some(ParamSliderInternal {
|
|
||||||
style:
|
ParamSliderStyle::CurrentStep { even: true } | ParamSliderStyle::CurrentStepLabeled { even: true },
|
||||||
ParamSliderStyle::CurrentStep { even: true }
|
|
||||||
| ParamSliderStyle::CurrentStepLabeled { even: true },
|
|
||||||
..
|
|
||||||
}),
|
|
||||||
Some(step_count),
|
Some(step_count),
|
||||||
) => {
|
) => {
|
||||||
// We'll remap the value range to be the same as the displayed range, e.g. with each
|
// We'll remap the value range to be the same as the displayed range, e.g. with each
|
||||||
|
@ -426,7 +400,7 @@ impl View for ParamSlider {
|
||||||
fn event(&mut self, cx: &mut Context, event: &mut Event) {
|
fn event(&mut self, cx: &mut Context, event: &mut Event) {
|
||||||
event.map(|param_slider_event, _| match param_slider_event {
|
event.map(|param_slider_event, _| match param_slider_event {
|
||||||
ParamSliderEvent::CancelTextInput => {
|
ParamSliderEvent::CancelTextInput => {
|
||||||
cx.emit(ParamSliderInternalEvent::SetTextInputActive(false));
|
self.text_input_active = false;
|
||||||
cx.set_active(false);
|
cx.set_active(false);
|
||||||
}
|
}
|
||||||
ParamSliderEvent::TextInput(string) => {
|
ParamSliderEvent::TextInput(string) => {
|
||||||
|
@ -438,7 +412,7 @@ impl View for ParamSlider {
|
||||||
cx.emit(RawParamEvent::EndSetParameter(self.param_ptr));
|
cx.emit(RawParamEvent::EndSetParameter(self.param_ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.emit(ParamSliderInternalEvent::SetTextInputActive(false));
|
self.text_input_active = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -446,7 +420,7 @@ impl View for ParamSlider {
|
||||||
WindowEvent::MouseDown(MouseButton::Left) => {
|
WindowEvent::MouseDown(MouseButton::Left) => {
|
||||||
if cx.modifiers().alt() {
|
if cx.modifiers().alt() {
|
||||||
// ALt+Click brings up a text entry dialog
|
// ALt+Click brings up a text entry dialog
|
||||||
cx.emit(ParamSliderInternalEvent::SetTextInputActive(true));
|
self.text_input_active = true;
|
||||||
cx.set_active(true);
|
cx.set_active(true);
|
||||||
} else if cx.modifiers().command() || self.is_double_click {
|
} else if cx.modifiers().command() || self.is_double_click {
|
||||||
// Ctrl+Click and double click should reset the parameter instead of initiating
|
// Ctrl+Click and double click should reset the parameter instead of initiating
|
||||||
|
@ -552,13 +526,6 @@ pub trait ParamSliderExt {
|
||||||
|
|
||||||
impl ParamSliderExt for Handle<'_, ParamSlider> {
|
impl ParamSliderExt for Handle<'_, ParamSlider> {
|
||||||
fn set_style(self, style: ParamSliderStyle) -> Self {
|
fn set_style(self, style: ParamSliderStyle) -> Self {
|
||||||
self.cx.emit_custom(
|
self.modify(|param_slider: &mut ParamSlider| param_slider.style = style)
|
||||||
Event::new(ParamSliderInternalEvent::SetStyle(style))
|
|
||||||
.target(self.entity)
|
|
||||||
.origin(self.entity)
|
|
||||||
.propagate(Propagation::Subtree),
|
|
||||||
);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue