1
0
Fork 0

Add boilerplate for the analyzer widget

This commit is contained in:
Robbert van der Helm 2023-03-20 14:56:43 +01:00
parent 990fe33ff7
commit 7c4ae32ba4
4 changed files with 112 additions and 12 deletions

View file

@ -26,7 +26,7 @@ use crate::params;
use crate::spectrum::SpectrumOutput; use crate::spectrum::SpectrumOutput;
/// A very abstract spectrum analyzer. This draws the magnitude spectrum's bins as vertical lines /// 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 { pub struct SpectrumAnalyzer {
spectrum: Arc<Mutex<SpectrumOutput>>, spectrum: Arc<Mutex<SpectrumOutput>>,
sample_rate: Arc<AtomicF32>, sample_rate: Arc<AtomicF32>,

View file

@ -23,10 +23,12 @@ use nih_plug_vizia::{assets, create_vizia_editor, ViziaState, ViziaTheming};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use self::analyzer::Analyzer;
use self::mode_button::EditorModeButton; use self::mode_button::EditorModeButton;
use crate::analyzer::AnalyzerData; use crate::analyzer::AnalyzerData;
use crate::{SpectralCompressor, SpectralCompressorParams}; use crate::{SpectralCompressor, SpectralCompressorParams};
mod analyzer;
mod mode_button; mod mode_button;
/// The entire GUI's width, in logical pixels. /// The entire GUI's width, in logical pixels.
@ -81,6 +83,8 @@ pub(crate) fn create(editor_state: Arc<ViziaState>, editor_data: Data) -> Option
assets::register_noto_sans_light(cx); assets::register_noto_sans_light(cx);
assets::register_noto_sans_thin(cx); assets::register_noto_sans_thin(cx);
cx.add_theme(include_str!("editor/theme.css"));
editor_data.clone().build(cx); editor_data.clone().build(cx);
ResizeHandle::new(cx); ResizeHandle::new(cx);
@ -229,17 +233,12 @@ fn main_column(cx: &mut Context) {
} }
fn analyzer_column(cx: &mut Context) { fn analyzer_column(cx: &mut Context) {
HStack::new(cx, |cx| { Analyzer::new(cx, Data::analyzer_data, Data::sample_rate)
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))
// These arbitrary 12 pixels are to align with the analyzer toggle botton .bottom(Pixels(12.0))
.space(Pixels(12.0)) .left(Pixels(2.0))
.bottom(Pixels(12.0)) .top(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());
} }
fn make_column(cx: &mut Context, title: &str, contents: impl FnOnce(&mut Context)) { fn make_column(cx: &mut Context, title: &str, contents: impl FnOnce(&mut Context)) {

View file

@ -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 <https://www.gnu.org/licenses/>.
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<Mutex<triple_buffer::Output<AnalyzerData>>>,
sample_rate: Arc<AtomicF32>,
}
impl Analyzer {
/// Creates a new [`Analyzer`].
pub fn new<LAnalyzerData, LRate>(
cx: &mut Context,
analyzer_data: LAnalyzerData,
sample_rate: LRate,
) -> Handle<Self>
where
LAnalyzerData: Lens<Target = Arc<Mutex<triple_buffer::Output<AnalyzerData>>>>,
LRate: Lens<Target = Arc<AtomicF32>>,
{
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);
}
}

View file

@ -0,0 +1,5 @@
analyzer {
border-color: #0a0a0a;
border-width: 1px;
color: #0a0a0a;
}