Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

surge-fx: split ParameterPanel into its own component #7951

Merged
merged 13 commits into from
Feb 10, 2025
5 changes: 1 addition & 4 deletions src/surge-fx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -56,12 +56,9 @@ juce_add_plugin(${PROJECT_NAME}

target_sources(${PROJECT_NAME} PRIVATE
SurgeFXEditor.cpp
SurgeFXEditor.h
SurgeFXProcessor.cpp
SurgeFXProcessor.h
SurgeLookAndFeel.h
ParameterPanel.cpp
FXOpenSoundControl.cpp
FXOpenSoundControl.h
)

target_link_libraries(${PROJECT_NAME} PRIVATE
240 changes: 240 additions & 0 deletions src/surge-fx/ParameterPanel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
#include "ParameterPanel.h"

ParameterPanel::ParameterPanel(SurgefxAudioProcessor &p,
std::vector<juce::Component *> &accessibleOrder)
: processor(p), styleSheet(sst::jucegui::style::StyleSheet::getBuiltInStyleSheet(
sst::jucegui::style::StyleSheet::DARK)),
accessibleOrderWeakRefs(accessibleOrder)
{
sst::jucegui::style ::StyleSheet::initializeStyleSheets([]() {});

using knobStyle = sst::jucegui::components::Knob::Styles;

styleSheet->setColour(knobStyle::styleClass, knobStyle::handle, backgroundColour);
styleSheet->setColour(knobStyle::styleClass, knobStyle::knobbase, backgroundColour);
styleSheet->setColour(knobStyle::styleClass, knobStyle::value, surgeOrange);
styleSheet->setColour(knobStyle::styleClass, knobStyle::value_hover, surgeOrange);

for (int i = 0; i < n_fx_params; ++i)
{
auto knob = std::make_unique<sst::jucegui::components::Knob>();
auto knobSource = std::make_unique<KnobSource>(processor, fxParamDisplay[i], i);

knob->setStyle(styleSheet);
knob->setModulationDisplay(sst::jucegui::components::Knob::Modulatable::NONE);

auto paramName = processor.getParamName(i) + " " + processor.getParamGroup(i);
knobSource->setValueFromGUI(processor.getFXStorageValue01(i));
knobSource->setLabel(paramName + " Knob");

knob->setSource(knobSource.get());

addAndMakeVisibleRecordOrder(knob.get());
knobs.push_back(std::move(knob));
sources.push_back(std::move(knobSource));

fxTempoSync[i].setOnOffImage(BinaryData::TS_Act_svg, BinaryData::TS_Act_svgSize,
BinaryData::TS_Deact_svg, BinaryData::TS_Deact_svgSize);
fxTempoSync[i].setEnabled(processor.canTempoSync(i));
fxTempoSync[i].setToggleState(processor.getFXStorageTempoSync(i),
juce::NotificationType::dontSendNotification);
fxTempoSync[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamTempoSync(i, this->fxTempoSync[i].getToggleState());
this->processor.setFXStorageTempoSync(i, this->fxTempoSync[i].getToggleState());
fxParamDisplay[i].setDisplay(
processor.getParamValueFromFloat(i, processor.getFXStorageValue01(i)));
this->processor.setUserEditingParamFeature(i, false);
};

fxTempoSync[i].setTitle("Parameter " + std::to_string(i) + " TempoSync");
addAndMakeVisibleRecordOrder(&(fxTempoSync[i]));

fxDeactivated[i].setOnOffImage(BinaryData::DE_Act_svg, BinaryData::DE_Act_svgSize,
BinaryData::DE_Deact_svg, BinaryData::DE_Deact_svgSize);
fxDeactivated[i].setEnabled(processor.canDeactitvate(i));
fxDeactivated[i].setToggleState(processor.getFXStorageDeactivated(i),
juce::NotificationType::dontSendNotification);
fxDeactivated[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamDeactivated(i, this->fxDeactivated[i].getToggleState());
this->processor.setFXStorageDeactivated(i, this->fxDeactivated[i].getToggleState());
// Special case - coupled dectivation
this->reset();
this->processor.setUserEditingParamFeature(i, false);
};
fxDeactivated[i].setTitle("Parameter " + std::to_string(i) + " Deactivate");
addAndMakeVisibleRecordOrder(&(fxDeactivated[i]));

fxExtended[i].setOnOffImage(BinaryData::EX_Act_svg, BinaryData::EX_Act_svgSize,
BinaryData::EX_Deact_svg, BinaryData::EX_Deact_svgSize);
fxExtended[i].setEnabled(processor.canExtend(i));
fxExtended[i].setToggleState(processor.getFXStorageExtended(i),
juce::NotificationType::dontSendNotification);
fxExtended[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamExtended(i, this->fxExtended[i].getToggleState());
this->processor.setFXStorageExtended(i, this->fxExtended[i].getToggleState());
fxParamDisplay[i].setDisplay(
processor.getParamValueFromFloat(i, processor.getFXStorageValue01(i)));
this->processor.setUserEditingParamFeature(i, false);
};
fxExtended[i].setTitle("Parameter " + std::to_string(i) + " Extended");
addAndMakeVisibleRecordOrder(&(fxExtended[i]));

fxAbsoluted[i].setOnOffImage(BinaryData::AB_Act_svg, BinaryData::AB_Act_svgSize,
BinaryData::AB_Deact_svg, BinaryData::AB_Deact_svgSize);
fxAbsoluted[i].setEnabled(processor.canAbsolute(i));
fxAbsoluted[i].setToggleState(processor.getFXParamAbsolute(i),
juce::NotificationType::dontSendNotification);
fxAbsoluted[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamAbsolute(i, this->fxAbsoluted[i].getToggleState());
this->processor.setFXStorageAbsolute(i, this->fxAbsoluted[i].getToggleState());

fxParamDisplay[i].setDisplay(
processor.getParamValueFromFloat(i, processor.getFXStorageValue01(i)));
this->processor.setUserEditingParamFeature(i, false);
};

fxAbsoluted[i].setTitle("Parameter " + std::to_string(i) + " Absoluted");
addAndMakeVisibleRecordOrder(&(fxAbsoluted[i]));

processor.prepareParametersAbsentAudio();
fxParamDisplay[i].setGroup(processor.getParamGroup(i).c_str());
fxParamDisplay[i].setName(processor.getParamName(i).c_str());
fxParamDisplay[i].setDisplay(processor.getParamValue(i));
fxParamDisplay[i].setEnabled(processor.getParamEnabled(i));
fxParamDisplay[i].onOverlayEntered = [i, this](const std::string &s) {
processor.setParameterByString(i, s);
};

addAndMakeVisibleRecordOrder(&(fxParamDisplay[i]));
}
}

ParameterPanel::~ParameterPanel() {}

void ParameterPanel::paint(juce::Graphics &g) { g.fillAll(backgroundColour); }

void ParameterPanel::reset()
{
knobs.clear();
sources.clear();

auto st = [](auto &thing, const std::string &title) {
thing.setTitle(title);
if (auto *handler = thing.getAccessibilityHandler())
{
handler->notifyAccessibilityEvent(juce::AccessibilityEvent::titleChanged);
handler->notifyAccessibilityEvent(juce::AccessibilityEvent::valueChanged);
}
};

for (int i = 0; i < n_fx_params; ++i)
{
auto knob = std::make_unique<sst::jucegui::components::Knob>();
auto knobSource = std::make_unique<KnobSource>(processor, fxParamDisplay[i], i);

knob->setStyle(styleSheet);
knob->setModulationDisplay(sst::jucegui::components::Knob::Modulatable::NONE);

auto paramName = processor.getParamName(i) + " " + processor.getParamGroup(i);
knobSource->setValueFromGUI(processor.getFXStorageValue01(i));
auto name = paramName + " Knob";
knobSource->setLabel(name);

knob->setSource(knobSource.get());
knob->setEnabled(processor.getParamEnabled(i));

addAndMakeVisibleRecordOrder(knob.get());
knobs.push_back(std::move(knob));
sources.push_back(std::move(knobSource));

fxParamDisplay[i].setDisplay(processor.getParamValue(i).c_str());
fxParamDisplay[i].setGroup(processor.getParamGroup(i).c_str());
fxParamDisplay[i].setName(processor.getParamName(i).c_str());
fxParamDisplay[i].allowsTypein = processor.canSetParameterByString(i);

fxParamDisplay[i].setEnabled(processor.getParamEnabled(i));
fxParamDisplay[i].setAppearsDeactivated(processor.getFXStorageAppearsDeactivated(i));

fxTempoSync[i].setEnabled(processor.canTempoSync(i));
fxTempoSync[i].setAccessible(processor.canTempoSync(i));
fxTempoSync[i].setToggleState(processor.getFXStorageTempoSync(i),
juce::NotificationType::dontSendNotification);
st(fxTempoSync[i], name + " Tempo Synced");
fxDeactivated[i].setEnabled(false);

fxExtended[i].setEnabled(processor.canExtend(i));
fxExtended[i].setToggleState(processor.getFXStorageExtended(i),
juce::NotificationType::dontSendNotification);
fxExtended[i].setAccessible(processor.canExtend(i));
st(fxExtended[i], name + " Extended");
fxAbsoluted[i].setEnabled(processor.canAbsolute(i));
fxAbsoluted[i].setToggleState(processor.getFXStorageAbsolute(i),
juce::NotificationType::dontSendNotification);
fxAbsoluted[i].setAccessible(processor.canAbsolute(i));
st(fxAbsoluted[i], name + " Absolute");
fxDeactivated[i].setEnabled(processor.canDeactitvate(i));
fxDeactivated[i].setToggleState(processor.getFXStorageDeactivated(i),
juce::NotificationType::dontSendNotification);
fxDeactivated[i].setAccessible(processor.canDeactitvate(i));
st(fxDeactivated[i], name + " Deactivated");
}
resized();
}
void ParameterPanel::resized()
{
int ypos0 = 5;
int rowHeight = getHeight() / 6.0;
int byoff = 7;

int sliderOff = 5;
if (getWidth() < baseWidth)
sliderOff = 2;

for (int i = 0; i < n_fx_params; ++i)
{
juce::Rectangle<int> position{(i / 6) * getWidth() / 2 + sliderOff,
(i % 6) * rowHeight + ypos0, rowHeight - sliderOff,
rowHeight - sliderOff};

position = position.reduced(position.getWidth() * 0.10, position.getHeight() * 0.10);

knobs.at(i).get()->setBounds(position);

int buttonSize = 19;
if (getWidth() < baseWidth)
buttonSize = 17;
int buttonMargin = 1;
juce::Rectangle<int> tsPos{(i / 6) * getWidth() / 2 + 2 + rowHeight - 5,
(i % 6) * rowHeight + ypos0 + byoff + buttonMargin, buttonSize,
buttonSize};
fxTempoSync[i].setBounds(tsPos);

juce::Rectangle<int> daPos{(i / 6) * getWidth() / 2 + 2 + rowHeight - 5,
(i % 6) * rowHeight + ypos0 + byoff + 2 * buttonMargin +
buttonSize,
buttonSize, buttonSize};
fxDeactivated[i].setBounds(daPos);

juce::Rectangle<int> exPos{
(i / 6) * getWidth() / 2 + 2 + rowHeight - 5 + buttonMargin + buttonSize,
(i % 6) * rowHeight + ypos0 + byoff + 1 * buttonMargin + 0 * buttonSize, buttonSize,
buttonSize};
fxExtended[i].setBounds(exPos);

juce::Rectangle<int> abPos{
(i / 6) * getWidth() / 2 + 2 + rowHeight - 5 + buttonMargin + buttonSize,
(i % 6) * rowHeight + ypos0 + byoff + 2 * buttonMargin + 1 * buttonSize, buttonSize,
buttonSize};
fxAbsoluted[i].setBounds(abPos);

juce::Rectangle<int> dispPos{
(i / 6) * getWidth() / 2 + 4 + rowHeight - 5 + 2 * buttonMargin + 2 * buttonSize,
(i % 6) * rowHeight + ypos0,
getWidth() / 2 - rowHeight - 8 - 2 * buttonMargin - 2 * buttonSize, rowHeight - 5};
fxParamDisplay[i].setBounds(dispPos);
}
}
52 changes: 52 additions & 0 deletions src/surge-fx/ParameterPanel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef SURGE_SRC_SURGE_FX_PARAMETERPANEL_H
#define SURGE_SRC_SURGE_FX_PARAMETERPANEL_H

#include "SurgeFXProcessor.h"
#include "SurgeLookAndFeel.h"
#include "KnobSource.h"

#include <sst/jucegui/style/StyleSheet.h>
#include <sst/jucegui/components/Knob.h>

class ParameterPanel : public juce::Component
{
public:
ParameterPanel(SurgefxAudioProcessor &, std::vector<juce::Component *> &accessibleOrder);

~ParameterPanel() override;

void paint(juce::Graphics &) override;
void resized() override;
void reset();

SurgeFXParamDisplay fxParamDisplay[n_fx_params];
std::vector<std::unique_ptr<KnobSource>> sources;
std::shared_ptr<sst::jucegui::style::StyleSheet> styleSheet;

private:
static constexpr int topSection = 80;
static constexpr int baseWidth = 600;

SurgefxAudioProcessor &processor;

SurgeTempoSyncSwitch fxTempoSync[n_fx_params];
SurgeTempoSyncSwitch fxDeactivated[n_fx_params];
SurgeTempoSyncSwitch fxExtended[n_fx_params];
SurgeTempoSyncSwitch fxAbsoluted[n_fx_params];

std::vector<std::unique_ptr<sst::jucegui::components::Knob>> knobs;

juce::Colour backgroundColour = juce::Colour(205, 206, 212);
juce::Colour surgeOrange = juce::Colour(255, 144, 0);
std::vector<juce::Component *> &accessibleOrderWeakRefs; // Reference to the vector

void addAndMakeVisibleRecordOrder(juce::Component *c)
{
accessibleOrderWeakRefs.push_back(c);
addAndMakeVisible(c);
}

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ParameterPanel);
};

#endif // SURGE_SRC_SURGE_FX_PARAMETERPANEL_H
230 changes: 17 additions & 213 deletions src/surge-fx/SurgeFXEditor.cpp
Original file line number Diff line number Diff line change
@@ -119,13 +119,8 @@ struct Picker : public juce::Component

//==============================================================================
SurgefxAudioProcessorEditor::SurgefxAudioProcessorEditor(SurgefxAudioProcessor &p)
: AudioProcessorEditor(&p),
sst::jucegui::style::StyleConsumer(sst::jucegui::components::Knob::Styles::styleClass),
styleSheet(sst::jucegui::style::StyleSheet::getBuiltInStyleSheet(
sst::jucegui::style::StyleSheet::DARK)),
processor(p)
: AudioProcessorEditor(&p), processor(p)
{
sst::jucegui::style::StyleSheet::initializeStyleSheets([]() {});

processor.storage->addErrorListener(this);
setAccessible(true);
@@ -138,111 +133,8 @@ SurgefxAudioProcessorEditor::SurgefxAudioProcessorEditor(SurgefxAudioProcessor &
picker = std::make_unique<Picker>(this);
addAndMakeVisibleRecordOrder(picker.get());

auto backgroundColour = findColour(SurgeLookAndFeel::SurgeColourIds::componentBgStart);
auto surgeOrange = findColour(SurgeLookAndFeel::SurgeColourIds::orange);

using knobStyle = sst::jucegui::components::Knob::Styles;
styleSheet->setColour(knobStyle::styleClass, knobStyle::handle, backgroundColour);
styleSheet->setColour(knobStyle::styleClass, knobStyle::knobbase, backgroundColour);
styleSheet->setColour(knobStyle::styleClass, knobStyle::value, surgeOrange);
styleSheet->setColour(knobStyle::styleClass, knobStyle::value_hover, surgeOrange);

for (int i = 0; i < n_fx_params; ++i)
{
auto knob = std::make_unique<sst::jucegui::components::Knob>();
auto knobSource = std::make_unique<KnobSource>(processor, fxParamDisplay[i], i);

knob->setStyle(styleSheet);
knob->setModulationDisplay(sst::jucegui::components::Knob::Modulatable::NONE);

auto paramName = processor.getParamName(i) + " " + processor.getParamGroup(i);
knobSource->setValueFromGUI(processor.getFXStorageValue01(i));
knobSource->setLabel(paramName + " Knob");

knob->setSource(knobSource.get());

addAndMakeVisible(knob.get());
knobs.push_back(std::move(knob));
sources.push_back(std::move(knobSource));

fxTempoSync[i].setOnOffImage(BinaryData::TS_Act_svg, BinaryData::TS_Act_svgSize,
BinaryData::TS_Deact_svg, BinaryData::TS_Deact_svgSize);
fxTempoSync[i].setEnabled(processor.canTempoSync(i));
fxTempoSync[i].setToggleState(processor.getFXStorageTempoSync(i),
juce::NotificationType::dontSendNotification);
fxTempoSync[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamTempoSync(i, this->fxTempoSync[i].getToggleState());
this->processor.setFXStorageTempoSync(i, this->fxTempoSync[i].getToggleState());
fxParamDisplay[i].setDisplay(
processor.getParamValueFromFloat(i, processor.getFXStorageValue01(i)));
this->processor.setUserEditingParamFeature(i, false);
};

fxTempoSync[i].setTitle("Parameter " + std::to_string(i) + " TempoSync");
addAndMakeVisibleRecordOrder(&(fxTempoSync[i]));

fxDeactivated[i].setOnOffImage(BinaryData::DE_Act_svg, BinaryData::DE_Act_svgSize,
BinaryData::DE_Deact_svg, BinaryData::DE_Deact_svgSize);
fxDeactivated[i].setEnabled(processor.canDeactitvate(i));
fxDeactivated[i].setToggleState(processor.getFXStorageDeactivated(i),
juce::NotificationType::dontSendNotification);
fxDeactivated[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamDeactivated(i, this->fxDeactivated[i].getToggleState());
this->processor.setFXStorageDeactivated(i, this->fxDeactivated[i].getToggleState());
// Special case - coupled dectivation
this->resetLabels();
this->processor.setUserEditingParamFeature(i, false);
};
fxDeactivated[i].setTitle("Parameter " + std::to_string(i) + " Deactivate");
addAndMakeVisibleRecordOrder(&(fxDeactivated[i]));

fxExtended[i].setOnOffImage(BinaryData::EX_Act_svg, BinaryData::EX_Act_svgSize,
BinaryData::EX_Deact_svg, BinaryData::EX_Deact_svgSize);
fxExtended[i].setEnabled(processor.canExtend(i));
fxExtended[i].setToggleState(processor.getFXStorageExtended(i),
juce::NotificationType::dontSendNotification);
fxExtended[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamExtended(i, this->fxExtended[i].getToggleState());
this->processor.setFXStorageExtended(i, this->fxExtended[i].getToggleState());
fxParamDisplay[i].setDisplay(
processor.getParamValueFromFloat(i, processor.getFXStorageValue01(i)));
this->processor.setUserEditingParamFeature(i, false);
};
fxExtended[i].setTitle("Parameter " + std::to_string(i) + " Extended");
addAndMakeVisibleRecordOrder(&(fxExtended[i]));

fxAbsoluted[i].setOnOffImage(BinaryData::AB_Act_svg, BinaryData::AB_Act_svgSize,
BinaryData::AB_Deact_svg, BinaryData::AB_Deact_svgSize);
fxAbsoluted[i].setEnabled(processor.canAbsolute(i));
fxAbsoluted[i].setToggleState(processor.getFXParamAbsolute(i),
juce::NotificationType::dontSendNotification);
fxAbsoluted[i].onClick = [i, this]() {
this->processor.setUserEditingParamFeature(i, true);
this->processor.setFXParamAbsolute(i, this->fxAbsoluted[i].getToggleState());
this->processor.setFXStorageAbsolute(i, this->fxAbsoluted[i].getToggleState());

fxParamDisplay[i].setDisplay(
processor.getParamValueFromFloat(i, processor.getFXStorageValue01(i)));
this->processor.setUserEditingParamFeature(i, false);
};

fxAbsoluted[i].setTitle("Parameter " + std::to_string(i) + " Absoluted");
addAndMakeVisibleRecordOrder(&(fxAbsoluted[i]));

processor.prepareParametersAbsentAudio();
fxParamDisplay[i].setGroup(processor.getParamGroup(i).c_str());
fxParamDisplay[i].setName(processor.getParamName(i).c_str());
fxParamDisplay[i].setDisplay(processor.getParamValue(i));
fxParamDisplay[i].setEnabled(processor.getParamEnabled(i));
fxParamDisplay[i].onOverlayEntered = [i, this](const std::string &s) {
processor.setParameterByString(i, s);
};

addAndMakeVisibleRecordOrder(&(fxParamDisplay[i]));
}
deafultParameterPanel = std::make_unique<ParameterPanel>(p, accessibleOrderWeakRefs);
addAndMakeVisibleRecordOrder(deafultParameterPanel.get());

fxNameLabel = std::make_unique<juce::Label>("fxlabel", "Surge XT Effects");
fxNameLabel->setFont(juce::FontOptions(28));
@@ -269,7 +161,6 @@ SurgefxAudioProcessorEditor::SurgefxAudioProcessorEditor(SurgefxAudioProcessor &

idleTimer = std::make_unique<IdleTimer>(this);
idleTimer->startTimer(1000 / 5);
resized();
}

SurgefxAudioProcessorEditor::~SurgefxAudioProcessorEditor()
@@ -292,61 +183,7 @@ void SurgefxAudioProcessorEditor::resetLabels()
}
};

knobs.clear();
sources.clear();

for (int i = 0; i < n_fx_params; ++i)
{
auto knob = std::make_unique<sst::jucegui::components::Knob>();
auto knobSource = std::make_unique<KnobSource>(processor, fxParamDisplay[i], i);

knob->setStyle(styleSheet);
knob->setModulationDisplay(sst::jucegui::components::Knob::Modulatable::NONE);

auto paramName = processor.getParamName(i) + " " + processor.getParamGroup(i);
knobSource->setValueFromGUI(processor.getFXStorageValue01(i));
auto name = paramName + " Knob";
knobSource->setLabel(name);

knob->setSource(knobSource.get());
knob->setEnabled(processor.getParamEnabled(i));

addAndMakeVisible(*knob);
knobs.push_back(std::move(knob));
sources.push_back(std::move(knobSource));

fxParamDisplay[i].setDisplay(processor.getParamValue(i).c_str());
fxParamDisplay[i].setGroup(processor.getParamGroup(i).c_str());
fxParamDisplay[i].setName(processor.getParamName(i).c_str());
fxParamDisplay[i].allowsTypein = processor.canSetParameterByString(i);

fxParamDisplay[i].setEnabled(processor.getParamEnabled(i));
fxParamDisplay[i].setAppearsDeactivated(processor.getFXStorageAppearsDeactivated(i));

fxTempoSync[i].setEnabled(processor.canTempoSync(i));
fxTempoSync[i].setAccessible(processor.canTempoSync(i));
fxTempoSync[i].setToggleState(processor.getFXStorageTempoSync(i),
juce::NotificationType::dontSendNotification);
st(fxTempoSync[i], name + " Tempo Synced");
fxDeactivated[i].setEnabled(false);

fxExtended[i].setEnabled(processor.canExtend(i));
fxExtended[i].setToggleState(processor.getFXStorageExtended(i),
juce::NotificationType::dontSendNotification);
fxExtended[i].setAccessible(processor.canExtend(i));
st(fxExtended[i], name + " Extended");
fxAbsoluted[i].setEnabled(processor.canAbsolute(i));
fxAbsoluted[i].setToggleState(processor.getFXStorageAbsolute(i),
juce::NotificationType::dontSendNotification);
fxAbsoluted[i].setAccessible(processor.canAbsolute(i));
st(fxAbsoluted[i], name + " Absolute");
fxDeactivated[i].setEnabled(processor.canDeactitvate(i));
fxDeactivated[i].setToggleState(processor.getFXStorageDeactivated(i),
juce::NotificationType::dontSendNotification);
fxDeactivated[i].setAccessible(processor.canDeactitvate(i));
st(fxDeactivated[i], name + " Deactivated");
}

deafultParameterPanel->reset();
picker->repaint();

int row = 0, col = 0;
@@ -378,8 +215,9 @@ void SurgefxAudioProcessorEditor::paramsChangedCallback()
{
if (i < n_fx_params)
{
sources.at(i)->setValueFromModel(fv[i]);
fxParamDisplay[i].setDisplay(processor.getParamValueFor(i, fv[i]));
deafultParameterPanel->sources.at(i)->setValueFromModel(fv[i]);
deafultParameterPanel->fxParamDisplay[i].setDisplay(
processor.getParamValueFor(i, fv[i]));
}
else
{
@@ -401,60 +239,26 @@ void SurgefxAudioProcessorEditor::paint(juce::Graphics &g)
void SurgefxAudioProcessorEditor::resized()
{
picker->setBounds(100, 10, getWidth() - 200, topSection - 30);

int ypos0 = topSection - 5;
int rowHeight = (getHeight() - topSection - 40 - 10) / 6.0;
int byoff = 7;

int sliderOff = 5;
if (getWidth() < baseWidth)
sliderOff = 2;
for (int i = 0; i < n_fx_params; ++i)
{
juce::Rectangle<int> position{(i / 6) * getWidth() / 2 + sliderOff,
(i % 6) * rowHeight + ypos0, rowHeight - sliderOff,
rowHeight - sliderOff};

position = position.reduced(position.getWidth() * 0.10, position.getHeight() * 0.10);

knobs.at(i).get()->setBounds(position);

int buttonSize = 19;
if (getWidth() < baseWidth)
buttonSize = 17;
int buttonMargin = 1;
juce::Rectangle<int> tsPos{(i / 6) * getWidth() / 2 + 2 + rowHeight - 5,
(i % 6) * rowHeight + ypos0 + byoff + buttonMargin, buttonSize,
buttonSize};
fxTempoSync[i].setBounds(tsPos);

juce::Rectangle<int> daPos{(i / 6) * getWidth() / 2 + 2 + rowHeight - 5,
(i % 6) * rowHeight + ypos0 + byoff + 2 * buttonMargin +
buttonSize,
buttonSize, buttonSize};
fxDeactivated[i].setBounds(daPos);

juce::Rectangle<int> exPos{
(i / 6) * getWidth() / 2 + 2 + rowHeight - 5 + buttonMargin + buttonSize,
(i % 6) * rowHeight + ypos0 + byoff + 1 * buttonMargin + 0 * buttonSize, buttonSize,
buttonSize};
fxExtended[i].setBounds(exPos);

juce::Rectangle<int> abPos{
(i / 6) * getWidth() / 2 + 2 + rowHeight - 5 + buttonMargin + buttonSize,
(i % 6) * rowHeight + ypos0 + byoff + 2 * buttonMargin + 1 * buttonSize, buttonSize,
buttonSize};
fxAbsoluted[i].setBounds(abPos);

juce::Rectangle<int> dispPos{
(i / 6) * getWidth() / 2 + 4 + rowHeight - 5 + 2 * buttonMargin + 2 * buttonSize,
(i % 6) * rowHeight + ypos0,
getWidth() / 2 - rowHeight - 8 - 2 * buttonMargin - 2 * buttonSize, rowHeight - 5};
fxParamDisplay[i].setBounds(dispPos);
}

auto bounds = getLocalBounds();
int topAreaHeight =
static_cast<int>((static_cast<float>(topSection) / baseHeight) * getHeight());
int bottomAreaHeight = static_cast<int>((static_cast<float>(40) / baseHeight) * getHeight());

bounds.removeFromTop(topAreaHeight);
bounds.removeFromBottom(bottomAreaHeight);

fxNameLabel->setFont(juce::FontOptions(28));
fxNameLabel->setBounds(40, getHeight() - 40, 350, 38);

deafultParameterPanel->setBounds(bounds);
}

int SurgefxAudioProcessorEditor::findLargestFittingZoomBetween(
16 changes: 3 additions & 13 deletions src/surge-fx/SurgeFXEditor.h
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@
#define SURGE_SRC_SURGE_FX_SURGEFXEDITOR_H

#include "SurgeFXProcessor.h"
#include "ParameterPanel.h"
#include "SurgeLookAndFeel.h"
#include "KnobSource.h"

@@ -37,8 +38,7 @@
*/
class SurgefxAudioProcessorEditor : public juce::AudioProcessorEditor,
juce::AsyncUpdater,
SurgeStorage::ErrorListener,
sst::jucegui::style::StyleConsumer
SurgeStorage::ErrorListener
{
public:
SurgefxAudioProcessorEditor(SurgefxAudioProcessor &);
@@ -57,7 +57,7 @@ class SurgefxAudioProcessorEditor : public juce::AudioProcessorEditor,
};
std::vector<FxMenu> menu;
std::unique_ptr<juce::Component> picker;

std::unique_ptr<ParameterPanel> deafultParameterPanel;
static constexpr int topSection = 80;

void makeMenu();
@@ -110,16 +110,7 @@ class SurgefxAudioProcessorEditor : public juce::AudioProcessorEditor,

static constexpr int baseWidth = 600, baseHeight = 55 * 6 + 80 + topSection;

std::vector<std::unique_ptr<sst::jucegui::components::Knob>> knobs;
std::vector<std::unique_ptr<KnobSource>> sources;

private:
SurgeFXParamDisplay fxParamDisplay[n_fx_params];
SurgeTempoSyncSwitch fxTempoSync[n_fx_params];
SurgeTempoSyncSwitch fxDeactivated[n_fx_params];
SurgeTempoSyncSwitch fxExtended[n_fx_params];
SurgeTempoSyncSwitch fxAbsoluted[n_fx_params];

void blastToggleState(int i);
void resetLabels();

@@ -150,7 +141,6 @@ class SurgefxAudioProcessorEditor : public juce::AudioProcessorEditor,

public:
std::vector<juce::Component *> accessibleOrderWeakRefs;
std::shared_ptr<sst::jucegui::style::StyleSheet> styleSheet;

public:
std::unique_ptr<juce::ComponentTraverser> createFocusTraverser() override;
5 changes: 4 additions & 1 deletion src/surge-fx/SurgeLookAndFeel.h
Original file line number Diff line number Diff line change
@@ -20,6 +20,8 @@
* https://github.com/surge-synthesizer/surge
*/

#ifndef SURGE_SRC_SURGE_FX_SURGELOOKANDFEEL_H
#define SURGE_SRC_SURGE_FX_SURGELOOKANDFEEL_H
#include "version.h"

#include "juce_gui_basics/juce_gui_basics.h"
@@ -224,7 +226,7 @@ class SurgeLookAndFeel : public juce::LookAndFeel_V4
shouldDrawButtonAsDown);
}

void drawCornerResizer(juce::Graphics &g, int w, int h, bool, bool) override{};
void drawCornerResizer(juce::Graphics &g, int w, int h, bool, bool) override {}

void paintComponentBackground(juce::Graphics &g, int w, int h)
{
@@ -504,3 +506,4 @@ class SurgeTempoSyncSwitch : public juce::ToggleButton
g.fillRoundedRectangle(kbounds, controlRadius);
}
};
#endif // SURGE_SRC_SURGE_FX_SURGELOOKANDFEEL_H