many UI fixes and new screenshot

This commit is contained in:
Armin 2026-09-17 11:29:01 +02:00
commit 88ed77a0c6
8 changed files with 43 additions and 29 deletions

View file

@ -47,7 +47,7 @@ TerionProcessorEditor::TerionProcessorEditor(TerionProcessor& p)
// Freeze button
addAndMakeVisible(freezeButton);
freezeButton.setButtonText("FRZ");
freezeButton.setButtonText("Freeze");
freezeButton.setColour(juce::ToggleButton::textColourId, juce::Colour(0xff888899));
freezeButton.setColour(juce::ToggleButton::tickColourId, juce::Colour(0xff7ecfcf));
freezeAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ButtonAttachment>(
@ -55,7 +55,7 @@ TerionProcessorEditor::TerionProcessorEditor(TerionProcessor& p)
// Mono button
addAndMakeVisible(monoButton);
monoButton.setButtonText("MONO");
monoButton.setButtonText("Mono");
monoButton.setColour(juce::ToggleButton::textColourId, juce::Colour(0xff888899));
monoButton.setColour(juce::ToggleButton::tickColourId, juce::Colour(0xff7ecfcf));
monoAttachment = std::make_unique<juce::AudioProcessorValueTreeState::ButtonAttachment>(
@ -133,10 +133,10 @@ void TerionProcessorEditor::paint(juce::Graphics& g)
g.setColour(juce::Colour(0xff555566));
g.setFont(juce::Font(juce::FontOptions(9.0f * s)));
juce::String footerText = "Terion "
juce::String footerText = "Terion (Git: "
+ juce::String(TERION_GIT_HASH)
+ " | " + juce::String(TERION_BUILD_TIME)
+ " | " + juce::String(TERION_GIT_LOCAL_COMMITS) + " local";
+ ", " + juce::String(TERION_GIT_DIRTY)
+ ") | built: " + juce::String(TERION_BUILD_TIME);
g.drawFittedText(footerText, footer.reduced(static_cast<int>(10.0f * s), 0),
juce::Justification::centredLeft, 1);
@ -149,20 +149,18 @@ void TerionProcessorEditor::resized()
const int knobs = static_cast<int>(kKnobSize * s);
const int margin = static_cast<int>(kKnobMargin * s);
const int scaleW = static_cast<int>(76.0f * s);
const int monoW = static_cast<int>(72.0f * s);
const int gap = static_cast<int>(8.0f * s);
auto bounds = getLocalBounds();
auto footer = bounds.removeFromBottom(footerH);
// Footer: scale dropdown + mono toggle on the right
scaleBox.setBounds(footer.getWidth() - scaleW, 1, scaleW, footerH - 2);
monoButton.setBounds(footer.getWidth() - scaleW - monoW, 1, monoW, footerH - 2);
// Footer: scale dropdown with an 8px gap on the top and right
scaleBox.setBounds(footer.getWidth() - scaleW - gap, gap, scaleW, footerH - 2 - gap);
// Scope fills the remaining area
scope.setBounds(bounds);
// Controls layout: knob row sits 8px above the footer, FRZ stays top-right
const int gap = static_cast<int>(8.0f * s);
// Controls layout: knob row sits 8px above the footer, Freeze/Mono stay top-right
const int numKnobs = 5;
const int rowH = knobs + static_cast<int>(12.0f * s) - static_cast<int>(6.0f * s);
const int startX = bounds.getWidth() - (numKnobs * (knobs + margin) + knobs + margin);
@ -173,8 +171,11 @@ void TerionProcessorEditor::resized()
dotSizeKnob.setBounds(startX + 2 * (knobs + margin), startY, knobs, knobs);
smoothingKnob.setBounds(startX + 3 * (knobs + margin), startY, knobs, knobs);
afterglowKnob.setBounds(startX + 4 * (knobs + margin), startY, knobs, knobs);
freezeButton.setBounds(bounds.getWidth() - knobs - margin, static_cast<int>(20.0f * s),
knobs, knobs - static_cast<int>(20.0f * s));
const int freezeY = static_cast<int>(20.0f * s);
const int freezeH = knobs - static_cast<int>(20.0f * s);
freezeButton.setBounds(bounds.getWidth() - knobs - margin, freezeY, knobs, freezeH);
monoButton.setBounds(bounds.getWidth() - knobs - margin, freezeY + freezeH + gap,
knobs, freezeH);
const int labelY = startY + knobs - static_cast<int>(6.0f * s);
const int labelH = static_cast<int>(12.0f * s);

View file

@ -8,22 +8,22 @@ TerionProcessor::TerionProcessor()
apvts(*this, nullptr, "Parameters", {
std::make_unique<juce::AudioParameterFloat>(
juce::ParameterID{"fadeTime", 1},
"Fade Time",
"Fade",
juce::NormalisableRange<float>(0.1f, 10.0f, 0.01f, 0.4f),
2.0f),
std::make_unique<juce::AudioParameterFloat>(
juce::ParameterID{"sensitivity", 2},
"Sensitivity",
"Response",
juce::NormalisableRange<float>(-12.0f, 24.0f, 0.1f, 0.5f),
0.0f),
std::make_unique<juce::AudioParameterFloat>(
juce::ParameterID{"dotSize", 3},
"Dot Size",
"Size",
juce::NormalisableRange<float>(0.5f, 8.0f, 0.1f, 0.5f),
1.0f),
std::make_unique<juce::AudioParameterFloat>(
juce::ParameterID{"smoothing", 4},
"Smoothing",
"Smooth",
juce::NormalisableRange<float>(0.0f, 0.99f, 0.01f, 0.5f),
0.0f),
std::make_unique<juce::AudioParameterBool>(
@ -36,7 +36,7 @@ TerionProcessor::TerionProcessor()
false),
std::make_unique<juce::AudioParameterFloat>(
juce::ParameterID{"afterglow", 7},
"Afterglow",
"Glow",
juce::NormalisableRange<float>(0.0f, 5.0f, 0.01f, 0.5f),
0.5f)
})

View file

@ -13,6 +13,14 @@ VectorScope::~VectorScope()
void VectorScope::timerCallback()
{
// Refresh the numeric readouts at kMetricsRateHz while keeping the trail
// animation running at the full 30 Hz.
const float frozen = processor.apvts.getRawParameterValue("freeze")->load();
if (frozen < 0.5f && ++metricFrame >= 30 / kMetricsRateHz)
{
metricFrame = 0;
cachedMetrics = processor.getMetrics();
}
repaint();
}
@ -183,7 +191,7 @@ void VectorScope::drawLegends(juce::Graphics& g, float cx, float cy, float radiu
void VectorScope::drawMetricsOverlay(juce::Graphics& g, const juce::Rectangle<int>& bounds)
{
const auto& metrics = processor.getMetrics();
const auto& metrics = cachedMetrics;
const float s = currentScale;
const int margin = static_cast<int>(10.0f * s);
const int lineHeight = static_cast<int>(14.0f * s);
@ -217,6 +225,6 @@ void VectorScope::drawMetricsOverlay(juce::Graphics& g, const juce::Rectangle<in
drawMetric("Mid", metrics.midLevel, "dB", y); y += lineHeight;
drawMetric("Side", metrics.sideLevel, "dB", y); y += lineHeight;
drawMetric("Balance", metrics.balance, "dB", y); y += lineHeight;
drawMetric("Phase", metrics.phaseAngle, "\u00B0", y); y += lineHeight;
drawMetric("Phase", metrics.phaseAngle, "deg", y); y += lineHeight;
drawMetric("Crest", metrics.crestFactor, "dB", y); y += lineHeight;
}

View file

@ -20,6 +20,9 @@ private:
TerionProcessor& processor;
float currentScale = 1.0f;
juce::Image trail;
StereoMetrics cachedMetrics;
int metricFrame = 0;
static constexpr int kMetricsRateHz = 2;
void drawLegends(juce::Graphics& g, float cx, float cy, float radius);
void drawHairCross(juce::Graphics& g, float cx, float cy);

View file

@ -1,5 +1,5 @@
#pragma once
#define TERION_GIT_HASH "@GIT_HASH@"
#define TERION_GIT_DIRTY "@GIT_DIRTY@"
#define TERION_BUILD_TIME "@BUILD_TIME@"
#define TERION_GIT_LOCAL_COMMITS "@GIT_LOCAL_COMMITS@"