Mema
Memory Matrix — multi-channel audio matrix monitor and router
Loading...
Searching...
No Matches
MemaProcessorEditor.cpp
Go to the documentation of this file.
1/* Copyright (c) 2024, Christian Ahrens
2 *
3 * This file is part of Mema <https://github.com/ChristianAhrens/Mema>
4 *
5 * This tool is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Lesser General Public License version 3.0 as published
7 * by the Free Software Foundation.
8 *
9 * This tool is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 * details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this tool; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include "MemaProcessorEditor.h"
20
21#include <JuceHeader.h>
22
23#include "../MemaProcessorEditor/PluginControlComponent.h"
24#include "../MemaProcessorEditor/InputControlComponent.h"
25#include "../MemaProcessorEditor/CrosspointsControlComponent.h"
26#include "../MemaProcessorEditor/OutputControlComponent.h"
27
28
29namespace Mema
30{
31
32//==============================================================================
33MemaProcessorEditor::MemaProcessorEditor(AudioProcessor& processor)
34 : juce::AudioProcessorEditor(processor)
35{
36 std::function<void()> boundsRequirementChange = [=]() {
37 if(m_crosspointCtrl && m_outputCtrl && m_inputCtrl)
38 {
39 auto requiredCrosspointsSize = m_crosspointCtrl->getRequiredSize();
40 auto requiredOutputCtrlSize = m_outputCtrl->getRequiredSize();
41 auto requiredInputCtrlSize = m_inputCtrl->getRequiredSize();
42
43 auto requiredSize = requiredCrosspointsSize;
44
45 // if the IO components require more than the central crosspoint component, take that into account here
46 if (requiredCrosspointsSize.getWidth() < requiredInputCtrlSize.getWidth())
47 requiredSize.setWidth(requiredInputCtrlSize.getWidth());
48 if (requiredCrosspointsSize.getHeight() < requiredOutputCtrlSize.getHeight())
49 requiredSize.setHeight(requiredOutputCtrlSize.getHeight());
50
51 // expand the required size with IO component 'framing' with
52 requiredSize.setWidth(requiredSize.getWidth() + requiredOutputCtrlSize.getWidth() + 1);
53 requiredSize.setHeight(requiredSize.getHeight() + requiredInputCtrlSize.getHeight() + 1 + sc_pluginControlHeight + 2);
54 DBG(__FUNCTION__);
55 if (onEditorSizeChangeRequested)
56 onEditorSizeChangeRequested(requiredSize);
57 }
58 };
59
60 m_pluginControl = std::make_unique<PluginControlComponent>();
61 m_pluginControl->onPluginSelected = [=](const juce::PluginDescription& pluginDescription) {
62 auto memaProc = dynamic_cast<MemaProcessor*>(getAudioProcessor());
63 if (memaProc)
64 {
65 auto success = memaProc->setPlugin(pluginDescription);
66 jassert(success);
67 }
68 };
69 m_pluginControl->onPluginEnabledChange = [=](bool enabled) {
70 auto memaProc = dynamic_cast<MemaProcessor*>(getAudioProcessor());
71 if (memaProc)
72 memaProc->setPluginEnabledState(enabled);
73 };
74 m_pluginControl->onPluginPrePostChange = [=](bool post) {
75 auto memaProc = dynamic_cast<MemaProcessor*>(getAudioProcessor());
76 if (memaProc)
77 memaProc->setPluginPrePostState(post);
78 };
79 m_pluginControl->onShowPluginEditor = [=]() {
80 auto memaProc = dynamic_cast<MemaProcessor*>(getAudioProcessor());
81 if (memaProc)
82 memaProc->openPluginEditor();
83 };
84 m_pluginControl->onClearPlugin = [=]() {
85 auto memaProc = dynamic_cast<MemaProcessor*>(getAudioProcessor());
86 if (memaProc)
87 memaProc->clearPlugin();
88 };
89 m_pluginControl->onPluginParametersStatusChanged = [=]() {
90 auto& paramInfos = m_pluginControl->getParameterInfos();
91 auto memaProc = dynamic_cast<MemaProcessor*>(getAudioProcessor());
92 if (memaProc)
93 {
94 for (auto& info : paramInfos)
95 memaProc->setPluginParameterRemoteControlInfos(info.second.index, info.second.isRemoteControllable, info.second.type, info.second.stepCount);
96 }
97 };
98 addAndMakeVisible(m_pluginControl.get());
99
100 m_ioLabel = std::make_unique<IOLabelComponent>(IOLabelComponent::Direction::OI);
101 addAndMakeVisible(m_ioLabel.get());
102
103 m_resetToUnityButton = std::make_unique<juce::DrawableButton>("UnityReset", juce::DrawableButton::ButtonStyle::ImageOnButtonBackground);
104 m_resetToUnityButton->setTooltip("Reset to unity patch and unmute all");
105 m_resetToUnityButton->onClick = [this] { if (onResetToUnity) onResetToUnity(); };
106 addAndMakeVisible(m_resetToUnityButton.get());
107
108 m_inputCtrl = std::make_unique<InputControlComponent>();
109 m_inputCtrl->onBoundsRequirementChange = boundsRequirementChange;
110 addAndMakeVisible(m_inputCtrl.get());
111
112 m_crosspointCtrl = std::make_unique<CrosspointsControlComponent>();
113 m_crosspointCtrl->onBoundsRequirementChange = boundsRequirementChange;
114 addAndMakeVisible(m_crosspointCtrl.get());
115
116 m_outputCtrl = std::make_unique<OutputControlComponent>();
117 m_outputCtrl->onBoundsRequirementChange = boundsRequirementChange;
118 addAndMakeVisible(m_outputCtrl.get());
119
120 auto memaProc = dynamic_cast<MemaProcessor*>(&processor);
121 if (memaProc)
122 {
123 memaProc->addInputListener(m_inputCtrl.get());
124 memaProc->addInputCommander(m_inputCtrl.get());
125
126 memaProc->addCrosspointCommander(m_crosspointCtrl.get());
127
128 memaProc->addOutputListener(m_outputCtrl.get());
129 memaProc->addOutputCommander(m_outputCtrl.get());
130
131 memaProc->onPluginSet = [=](const juce::PluginDescription& pluginDescription) { if (m_pluginControl) m_pluginControl->setSelectedPlugin(pluginDescription); };
132
133 m_pluginControl->setPluginEnabled(memaProc->isPluginEnabled());
134 m_pluginControl->setPluginPrePost(memaProc->isPluginPost());
135 m_pluginControl->setSelectedPlugin(memaProc->getPluginDescription());
136 m_pluginControl->setParameterInfos(memaProc->getPluginParameterInfos());
137 }
138
139 m_gridLayout.items = { juce::GridItem(*m_ioLabel), juce::GridItem(*m_inputCtrl), juce::GridItem(*m_outputCtrl), juce::GridItem(*m_crosspointCtrl) };
140 m_gridLayout.rowGap.pixels = 1.0;
141 m_gridLayout.columnGap.pixels = 1.0;
142
143 setSize(800, 800);
144}
145
146MemaProcessorEditor::MemaProcessorEditor(AudioProcessor* processor)
147 : MemaProcessorEditor(*processor)
148{
149}
150
151MemaProcessorEditor::~MemaProcessorEditor()
152{
153}
154
155void MemaProcessorEditor::paint (Graphics& g)
156{
157 // (Our component is opaque, so we must completely fill the background with a solid colour)
158 g.setColour(getLookAndFeel().findColour(juce::AlertWindow::backgroundColourId));
159}
160
161void MemaProcessorEditor::resized()
162{
163 auto bounds = getLocalBounds();
164 m_pluginControl->setBounds(bounds.removeFromTop(sc_pluginControlHeight + 1));
165 bounds.removeFromTop(1);
166
167 auto requiredInputsHeight = m_inputCtrl->getRequiredSize().getHeight();
168 auto requiredOutputsWidth = m_outputCtrl->getRequiredSize().getWidth();
169
170 m_gridLayout.templateRows = { juce::Grid::TrackInfo(juce::Grid::Px(requiredInputsHeight)), juce::Grid::TrackInfo(juce::Grid::Fr(1)) };
171 m_gridLayout.templateColumns = { juce::Grid::TrackInfo(juce::Grid::Px(requiredOutputsWidth)), juce::Grid::TrackInfo(juce::Grid::Fr(1)) };
172 m_gridLayout.performLayout(bounds);
173
174 // reset to unity button shall hover centered above iolabel
175 auto resetButtonBounds = m_ioLabel->getBounds();
176 auto wMargin = (resetButtonBounds.getWidth() - sc_resetButtonSize) / 2;
177 auto hMargin = (resetButtonBounds.getHeight() - sc_resetButtonSize) / 2;
178 resetButtonBounds.reduce(wMargin, hMargin);
179 m_resetToUnityButton->setBounds(resetButtonBounds);
180}
181
182void MemaProcessorEditor::lookAndFeelChanged()
183{
184 auto resetToUnityDrawable = juce::Drawable::createFromSVG(*juce::XmlDocument::parse(BinaryData::replay_24dp_svg).get());
185 resetToUnityDrawable->replaceColour(juce::Colours::black, getLookAndFeel().findColour(juce::TextButton::ColourIds::textColourOnId));
186 m_resetToUnityButton->setImages(resetToUnityDrawable.get());
187
188 if (m_pluginControl)
189 m_pluginControl->lookAndFeelChanged();
190
191 juce::AudioProcessorEditor::lookAndFeelChanged();
192}
193
194
195}
MemaProcessorEditor(juce::AudioProcessor &processor)
Definition Mema.cpp:27