Skip to content

Commit

Permalink
WIP: Vizia updates
Browse files Browse the repository at this point in the history
Diopser, Spectral Compressor, and Crisp have not yet been looked at. The
things that to be fixed at the moment are:

- Text input
- Resize handles
- Window resizing
  • Loading branch information
robbert-vdh committed Nov 5, 2023
1 parent a2a62f6 commit 94f648f
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 113 deletions.
3 changes: 1 addition & 2 deletions nih_plug_vizia/src/widgets/generic_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ impl GenericUi {
Ps: Params + 'static,
{
// Basic styling is done in the `theme.css` style sheet
Self::new_custom(cx, params.clone(), move |cx, param_ptr| {
let params = params.clone();
Self::new_custom(cx, params, move |cx, param_ptr| {
HStack::new(cx, move |cx| {
// Align this on the right
Label::new(cx, unsafe { param_ptr.name() }).class("label");
Expand Down
18 changes: 11 additions & 7 deletions nih_plug_vizia/src/widgets/param_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,19 @@ where
FMap: Fn(&Params) -> &P + Copy + 'static,
{
fn clone(&self) -> Self {
Self {
param: self.param,
params: self.params.clone(),
params_to_param: self.params_to_param,
}
*self
}
}

impl<L, Params, P, FMap> Copy for ParamWidgetData<L, Params, P, FMap>
where
L: Lens<Target = Params> + Copy,
Params: 'static,
P: Param + 'static,
FMap: Fn(&Params) -> &P + Copy + 'static,
{
}

impl<L, Params, P, FMap> ParamWidgetData<L, Params, P, FMap>
where
L: Lens<Target = Params> + Clone,
Expand All @@ -72,7 +77,7 @@ where
{
let params_to_param = self.params_to_param;

self.params.clone().map(move |params| {
self.params.map(move |params| {
let param = params_to_param(params);
f(param)
})
Expand Down Expand Up @@ -136,7 +141,6 @@ impl ParamWidgetBase {
// outlive the editor
let param: &P = unsafe {
&*params
.clone()
.map(move |params| params_to_param(params) as *const P)
.get(cx)
};
Expand Down
4 changes: 2 additions & 2 deletions nih_plug_vizia/src/widgets/param_button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl ParamButton {
FMap: Fn(&Params) -> &P + Copy + 'static,
{
Self {
param_base: ParamWidgetBase::new(cx, params.clone(), params_to_param),
param_base: ParamWidgetBase::new(cx, params, params_to_param),

use_scroll_wheel: true,
label_override: None,
Expand All @@ -48,7 +48,7 @@ impl ParamButton {
}
.build(
cx,
ParamWidgetBase::build_view(params.clone(), params_to_param, move |cx, param_data| {
ParamWidgetBase::build_view(params, params_to_param, move |cx, param_data| {
Binding::new(cx, Self::label_override, move |cx, label_override| {
match label_override.get(cx) {
Some(label_override) => Label::new(cx, &label_override),
Expand Down
71 changes: 21 additions & 50 deletions nih_plug_vizia/src/widgets/param_slider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl ParamSlider {
// default value lies somewhere in the middle and the parameter is continuous. Otherwise
// this approach looks a bit jarring.
Self {
param_base: ParamWidgetBase::new(cx, params.clone(), params_to_param),
param_base: ParamWidgetBase::new(cx, params, params_to_param),

text_input_active: false,
drag_active: false,
Expand All @@ -117,9 +117,6 @@ impl ParamSlider {
Binding::new(cx, ParamSlider::style, move |cx, style| {
let style = style.get(cx);

// Needs to be moved into the below closures, and it can't be `Copy`
let param_data = param_data.clone();

// Can't use `.to_string()` here as that would include the modulation.
let unmodulated_normalized_value_lens =
param_data.make_lens(|param| param.unmodulated_normalized_value());
Expand All @@ -130,16 +127,14 @@ impl ParamSlider {
// The resulting tuple `(start_t, delta)` corresponds to the start and the
// signed width of the bar. `start_t` is in `[0, 1]`, and `delta` is in
// `[-1, 1]`.
let fill_start_delta_lens = {
let param_data = param_data.clone();
let fill_start_delta_lens =
unmodulated_normalized_value_lens.map(move |current_value| {
Self::compute_fill_start_delta(
style,
param_data.param(),
*current_value,
)
})
};
});

// If the parameter is being modulated by the host (this only works for CLAP
// plugins with hosts that support this), then this is the difference
Expand All @@ -150,13 +145,10 @@ impl ParamSlider {
});

// This is used to draw labels for `CurrentStepLabeled`
let make_preview_value_lens = {
let param_data = param_data.clone();
move |normalized_value| {
param_data.make_lens(move |param| {
param.normalized_value_to_string(normalized_value, true)
})
}
let make_preview_value_lens = move |normalized_value| {
param_data.make_lens(move |param| {
param.normalized_value_to_string(normalized_value, true)
})
};

// Only draw the text input widget when it gets focussed. Otherwise, overlay the
Expand All @@ -168,17 +160,8 @@ impl ParamSlider {
ParamSlider::text_input_active,
move |cx, text_input_active| {
if text_input_active.get(cx) {
Self::text_input_view(cx, display_value_lens.clone());
Self::text_input_view(cx, display_value_lens);
} else {
// All of this data needs to be moved into the `ZStack` closure, and
// the `Map` lens combinator isn't `Copy`
let param_data = param_data.clone();
let fill_start_delta_lens = fill_start_delta_lens.clone();
let modulation_start_delta_lens =
modulation_start_delta_lens.clone();
let display_value_lens = display_value_lens.clone();
let make_preview_value_lens = make_preview_value_lens.clone();

ZStack::new(cx, move |cx| {
Self::slider_fill_view(
cx,
Expand Down Expand Up @@ -237,11 +220,7 @@ impl ParamSlider {
Element::new(cx)
.class("fill")
.height(Stretch(1.0))
.left(
fill_start_delta_lens
.clone()
.map(|(start_t, _)| Percentage(start_t * 100.0)),
)
.left(fill_start_delta_lens.map(|(start_t, _)| Percentage(start_t * 100.0)))
.width(fill_start_delta_lens.map(|(_, delta)| Percentage(delta * 100.0)))
// Hovering is handled on the param slider as a whole, this
// should not affect that
Expand All @@ -254,18 +233,10 @@ impl ParamSlider {
.class("fill")
.class("fill--modulation")
.height(Stretch(1.0))
.visibility(
modulation_start_delta_lens
.clone()
.map(|(_, delta)| *delta != 0.0),
)
.visibility(modulation_start_delta_lens.map(|(_, delta)| *delta != 0.0))
// Widths cannot be negative, so we need to compensate the start
// position if the width does happen to be negative
.width(
modulation_start_delta_lens
.clone()
.map(|(_, delta)| Percentage(delta.abs() * 100.0)),
)
.width(modulation_start_delta_lens.map(|(_, delta)| Percentage(delta.abs() * 100.0)))
.left(modulation_start_delta_lens.map(|(start_t, delta)| {
if *delta < 0.0 {
Percentage((start_t + delta) * 100.0)
Expand Down Expand Up @@ -320,7 +291,7 @@ impl ParamSlider {
// current display value (before modulation) is used.
match label_override_lens.get(cx) {
Some(label_override) => Label::new(cx, &label_override),
None => Label::new(cx, display_value_lens.clone()),
None => Label::new(cx, display_value_lens),
}
.class("value")
.class("value--single")
Expand Down Expand Up @@ -464,11 +435,11 @@ impl View for ParamSlider {
// still won't work.
WindowEvent::MouseDown(MouseButton::Left)
| WindowEvent::MouseTripleClick(MouseButton::Left) => {
if cx.modifiers.alt() {
if cx.modifiers().alt() {
// ALt+Click brings up a text entry dialog
self.text_input_active = true;
cx.set_active(true);
} else if cx.modifiers.command() {
} else if cx.modifiers().command() {
// Ctrl+Click, double click, and right clicks should reset the parameter instead
// of initiating a drag operation
self.param_base.begin_set_parameter(cx);
Expand All @@ -485,16 +456,16 @@ impl View for ParamSlider {
// When holding down shift while clicking on a parameter we want to granuarly
// edit the parameter without jumping to a new value
self.param_base.begin_set_parameter(cx);
if cx.modifiers.shift() {
if cx.modifiers().shift() {
self.granular_drag_status = Some(GranularDragStatus {
starting_x_coordinate: cx.mouse.cursorx,
starting_x_coordinate: cx.mouse().cursorx,
starting_value: self.param_base.unmodulated_normalized_value(),
});
} else {
self.granular_drag_status = None;
self.set_normalized_value_drag(
cx,
util::remap_current_entity_x_coordinate(cx, cx.mouse.cursorx),
util::remap_current_entity_x_coordinate(cx, cx.mouse().cursorx),
);
}
}
Expand Down Expand Up @@ -529,7 +500,7 @@ impl View for ParamSlider {
if self.drag_active {
// If shift is being held then the drag should be more granular instead of
// absolute
if cx.modifiers.shift() {
if cx.modifiers().shift() {
let granular_drag_status =
*self
.granular_drag_status
Expand All @@ -544,7 +515,7 @@ impl View for ParamSlider {
util::remap_current_entity_x_t(cx, granular_drag_status.starting_value);
let delta_x = ((*x - granular_drag_status.starting_x_coordinate)
* GRANULAR_DRAG_MULTIPLIER)
* cx.style.dpi_factor as f32;
* cx.scale_factor();

self.set_normalized_value_drag(
cx,
Expand All @@ -567,7 +538,7 @@ impl View for ParamSlider {
self.granular_drag_status = None;
self.param_base.set_normalized_value(
cx,
util::remap_current_entity_x_coordinate(cx, cx.mouse.cursorx),
util::remap_current_entity_x_coordinate(cx, cx.mouse().cursorx),
);
}
}
Expand All @@ -577,7 +548,7 @@ impl View for ParamSlider {
self.scrolled_lines += scroll_y;

if self.scrolled_lines.abs() >= 1.0 {
let use_finer_steps = cx.modifiers.shift();
let use_finer_steps = cx.modifiers().shift();

// Scrolling while dragging needs to be taken into account here
if !self.drag_active {
Expand Down
26 changes: 10 additions & 16 deletions nih_plug_vizia/src/widgets/peak_meter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl PeakMeter {
// current moment in time by mutating some values captured into the mapping closure.
let held_peak_value_db = Cell::new(f32::MIN);
let last_held_peak_value: Cell<Option<Instant>> = Cell::new(None);
let peak_dbfs = level_dbfs.clone().map(move |level| -> f32 {
let peak_dbfs = level_dbfs.map(move |level| -> f32 {
match hold_time {
Some(hold_time) => {
let mut peak_level = held_peak_value_db.get();
Expand Down Expand Up @@ -97,9 +97,8 @@ impl PeakMeter {
}

let font_size = {
let current = cx.current();
let draw_cx = DrawContext::new(cx);
draw_cx.font_size(current) * draw_cx.style.dpi_factor as f32
let event_cx = EventContext::new(cx);
event_cx.font_size() * event_cx.scale_factor()
};
let label = if first_tick {
Label::new(cx, "-inf")
Expand Down Expand Up @@ -157,19 +156,14 @@ where

// TODO: It would be cool to allow the text color property to control the gradient here. For
// now we'll only support basic background colors and borders.
let background_color = cx.background_color().cloned().unwrap_or_default();
let border_color = cx.border_color().cloned().unwrap_or_default();
let background_color = cx.background_color();
let border_color = cx.border_color();
let opacity = cx.opacity();
let mut background_color: vg::Color = background_color.into();
background_color.set_alphaf(background_color.a * opacity);
let mut border_color: vg::Color = border_color.into();
border_color.set_alphaf(border_color.a * opacity);

let border_width = match cx.border_width().unwrap_or_default() {
Units::Pixels(val) => val,
Units::Percentage(val) => bounds.w.min(bounds.h) * (val / 100.0),
_ => 0.0,
};
let border_width = cx.border_width();

let mut path = vg::Path::new();
{
Expand All @@ -187,7 +181,7 @@ where

// Fill with background color
let paint = vg::Paint::color(background_color);
canvas.fill_path(&mut path, &paint);
canvas.fill_path(&path, &paint);

// And now for the fun stuff. We'll try to not overlap the border, but we'll draw that last
// just in case.
Expand Down Expand Up @@ -222,7 +216,7 @@ where
opacity,
));
paint.set_line_width(TICK_WIDTH * dpi_scale);
canvas.stroke_path(&mut path, &paint);
canvas.stroke_path(&path, &paint);
}

// Draw the hold peak value if the hold time option has been set
Expand All @@ -241,12 +235,12 @@ where

let mut paint = vg::Paint::color(vg::Color::rgbaf(0.3, 0.3, 0.3, opacity));
paint.set_line_width(TICK_WIDTH * dpi_scale);
canvas.stroke_path(&mut path, &paint);
canvas.stroke_path(&path, &paint);
}

// Draw border last
let mut paint = vg::Paint::color(border_color);
paint.set_line_width(border_width);
canvas.stroke_path(&mut path, &paint);
canvas.stroke_path(&path, &paint);
}
}
Loading

0 comments on commit 94f648f

Please sign in to comment.