From 7c4ae32ba43a40194d01597aba98dcaeb785ccce Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 20 Mar 2023 14:56:43 +0100 Subject: [PATCH] Add boilerplate for the analyzer widget --- plugins/diopser/src/editor/analyzer.rs | 2 +- plugins/spectral_compressor/src/editor.rs | 21 ++-- .../src/editor/analyzer.rs | 96 +++++++++++++++++++ .../spectral_compressor/src/editor/theme.css | 5 + 4 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 plugins/spectral_compressor/src/editor/analyzer.rs create mode 100644 plugins/spectral_compressor/src/editor/theme.css diff --git a/plugins/diopser/src/editor/analyzer.rs b/plugins/diopser/src/editor/analyzer.rs index 8e36cc87..a884409c 100644 --- a/plugins/diopser/src/editor/analyzer.rs +++ b/plugins/diopser/src/editor/analyzer.rs @@ -26,7 +26,7 @@ use crate::params; use crate::spectrum::SpectrumOutput; /// A very abstract spectrum analyzer. This draws the magnitude spectrum's bins as vertical lines -/// with the same distirubtion as the filter frequency parameter.. +/// with the same distribution as the filter frequency parameter.. pub struct SpectrumAnalyzer { spectrum: Arc>, sample_rate: Arc, diff --git a/plugins/spectral_compressor/src/editor.rs b/plugins/spectral_compressor/src/editor.rs index 9f7a7457..1e1978f0 100644 --- a/plugins/spectral_compressor/src/editor.rs +++ b/plugins/spectral_compressor/src/editor.rs @@ -23,10 +23,12 @@ use nih_plug_vizia::{assets, create_vizia_editor, ViziaState, ViziaTheming}; use serde::{Deserialize, Serialize}; use std::sync::{Arc, Mutex}; +use self::analyzer::Analyzer; use self::mode_button::EditorModeButton; use crate::analyzer::AnalyzerData; use crate::{SpectralCompressor, SpectralCompressorParams}; +mod analyzer; mod mode_button; /// The entire GUI's width, in logical pixels. @@ -81,6 +83,8 @@ pub(crate) fn create(editor_state: Arc, editor_data: Data) -> Option assets::register_noto_sans_light(cx); assets::register_noto_sans_thin(cx); + cx.add_theme(include_str!("editor/theme.css")); + editor_data.clone().build(cx); ResizeHandle::new(cx); @@ -229,17 +233,12 @@ fn main_column(cx: &mut Context) { } fn analyzer_column(cx: &mut Context) { - HStack::new(cx, |cx| { - Label::new(cx, "When I grow up I want to be a spectrum analyzer!"); - }) - // These arbitrary 12 pixels are to align with the analyzer toggle botton - .space(Pixels(12.0)) - .bottom(Pixels(12.0)) - .left(Pixels(2.0)) - .top(Pixels(12.0)) - .child_space(Stretch(1.0)) - .border_width(Pixels(1.0)) - .border_color(Color::black()); + Analyzer::new(cx, Data::analyzer_data, Data::sample_rate) + // These arbitrary 12 pixels are to align with the analyzer toggle botton + .space(Pixels(12.0)) + .bottom(Pixels(12.0)) + .left(Pixels(2.0)) + .top(Pixels(12.0)); } fn make_column(cx: &mut Context, title: &str, contents: impl FnOnce(&mut Context)) { diff --git a/plugins/spectral_compressor/src/editor/analyzer.rs b/plugins/spectral_compressor/src/editor/analyzer.rs new file mode 100644 index 00000000..21f8b7d7 --- /dev/null +++ b/plugins/spectral_compressor/src/editor/analyzer.rs @@ -0,0 +1,96 @@ +// Spectral Compressor: an FFT based compressor +// Copyright (C) 2021-2023 Robbert van der Helm +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use atomic_float::AtomicF32; +use nih_plug_vizia::vizia::prelude::*; +use nih_plug_vizia::vizia::vg; +use std::sync::{Arc, Mutex}; + +use crate::analyzer::AnalyzerData; + +/// A very spectrum analyzer with an overlay for the gain reduction. +pub struct Analyzer { + analyzer_data: Arc>>, + sample_rate: Arc, +} + +impl Analyzer { + /// Creates a new [`Analyzer`]. + pub fn new( + cx: &mut Context, + analyzer_data: LAnalyzerData, + sample_rate: LRate, + ) -> Handle + where + LAnalyzerData: Lens>>>, + LRate: Lens>, + { + Self { + analyzer_data: analyzer_data.get(cx), + sample_rate: sample_rate.get(cx), + } + .build( + cx, + // This is an otherwise empty element only used for custom drawing + |_cx| (), + ) + } +} + +impl View for Analyzer { + fn element(&self) -> Option<&'static str> { + Some("analyzer") + } + + fn draw(&self, cx: &mut DrawContext, canvas: &mut Canvas) { + let bounds = cx.bounds(); + dbg!(bounds); + if bounds.w == 0.0 || bounds.h == 0.0 { + return; + } + + // This only covers the style rules we're actually setting + let opacity = cx.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 mut border_color: vg::Color = cx.border_color().cloned().unwrap_or_default().into(); + border_color.set_alphaf(border_color.a * opacity); + + // TODO: Draw the spectrum analyzer + + // Draw the border last + let mut path = vg::Path::new(); + { + let x = bounds.x + border_width / 2.0; + let y = bounds.y + border_width / 2.0; + let w = bounds.w - border_width; + let h = bounds.h - border_width; + path.move_to(x, y); + path.line_to(x, y + h); + path.line_to(x + w, y + h); + path.line_to(x + w, y); + path.line_to(x, y); + path.close(); + } + + let mut paint = vg::Paint::color(border_color); + paint.set_line_width(border_width); + canvas.stroke_path(&mut path, &paint); + } +} diff --git a/plugins/spectral_compressor/src/editor/theme.css b/plugins/spectral_compressor/src/editor/theme.css new file mode 100644 index 00000000..d84bbab5 --- /dev/null +++ b/plugins/spectral_compressor/src/editor/theme.css @@ -0,0 +1,5 @@ +analyzer { + border-color: #0a0a0a; + border-width: 1px; + color: #0a0a0a; +}