Mema
Memory Matrix — multi-channel audio matrix monitor and router
Loading...
Searching...
No Matches
OutputControlComponent.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
20
23
24namespace Mema
25{
26
27//==============================================================================
30{
32
33 m_outputLevels = std::make_unique<MeterbridgeComponent>(MeterbridgeComponent::Direction::Vertical);
34 addAndMakeVisible(m_outputLevels.get());
35}
36
41
43{
44 auto bounds = getLocalBounds();
45
46 if (m_outputLevels)
47 m_outputLevels->setBounds(bounds
48 .removeFromRight(bounds.getWidth() - int(s_channelSize + s_channelGap))
49 .removeFromTop(int(m_outputMutes.size() * (s_channelSize + s_channelGap))));
50
51 if (!m_outputMutes.empty())
52 {
53 auto muteHeight = int(s_channelSize + s_channelGap);
54 for (auto const& outputMuteKV : m_outputMutes)
55 {
56 outputMuteKV.second->setBounds(bounds.removeFromTop(muteHeight).reduced(2));
57 }
58 }
59
61}
62
64{
65 // (Our component is opaque, so we must completely fill the background with a solid colour)
66 g.fillAll(getLookAndFeel().findColour(ResizableWindow::backgroundColourId));
67
68 // Paint whatever the base class does ontop of the solid fill
70}
71
72void OutputControlComponent::setOutputMute(std::uint16_t channel, bool muteState, int /*userId*/)
73{
74 if (m_outputMutes.count(channel) != 1)
75 return;
76
77 if (m_outputMutes.at(channel))
78 m_outputMutes.at(channel)->setToggleState(muteState, juce::dontSendNotification);
79}
80
82{
83 if(!data)
84 return;
85
86 switch(data->GetDataType())
87 {
89 m_levelData = *(dynamic_cast<ProcessorLevelData*>(data));
91 break;
95 default:
96 break;
97 }
98}
99
101{
102
103 if (m_outputLevels)
104 m_outputLevels->processingDataChanged(&m_levelData);
105
107}
108
109void OutputControlComponent::setChannelCount(std::uint16_t channelCount)
110{
111 if (m_channelCount != channelCount)
112 {
113 m_channelCount = channelCount;
114 DBG(__FUNCTION__ << " " << int(channelCount));
115
116 m_outputLevels->setChannelCount(channelCount);
117
118 auto channelsToRemove = std::vector<std::uint16_t>();
119 for (auto const& outputMuteKV : m_outputMutes)
120 {
121 if (outputMuteKV.first > channelCount)
122 channelsToRemove.push_back(outputMuteKV.first);
123 }
124 for (auto const& channel : channelsToRemove)
125 {
126 removeChildComponent(m_outputMutes.at(channel).get());
127 auto iter = std::find_if(m_outputMutes.begin(), m_outputMutes.end(), [=](const auto& outputMuteKV) { return outputMuteKV.first == channel; });
128 if (iter != m_outputMutes.end())
129 m_outputMutes.erase(iter);
130 }
131
132 for (std::uint16_t channel = 1; channel <= channelCount; channel++)
133 {
134 if (m_outputMutes.count(channel) == 0)
135 {
136 m_outputMutes[channel] =std::make_unique<juce::TextButton>("M", "Mute");
137 m_outputMutes.at(channel)->setClickingTogglesState(true);
138 m_outputMutes.at(channel)->addListener(this);
139 m_outputMutes.at(channel)->setColour(juce::TextButton::ColourIds::buttonOnColourId, juce::Colours::red);
140 addAndMakeVisible(m_outputMutes.at(channel).get());
141 }
142 }
143
146
147 resized();
148 }
149}
150
152{
153 auto iter = std::find_if(m_outputMutes.begin(), m_outputMutes.end(), [=](const auto& outputMuteKV) { return outputMuteKV.second.get() == button; });
154 if (iter != m_outputMutes.end() && nullptr != iter->second)
155 outputMuteChange(iter->first, iter->second->getToggleState(), this);
156}
157
159{
160 return { 60, m_channelCount * int(s_channelSize + s_channelGap) };
161}
162
163
164}
Base class for all audio-data visualisation components in the Mema processor editor.
void paint(Graphics &) override
Paints the visualiser background.
virtual void processChanges()
Called on the message thread to update cached data before repainting.
void notifyChanges()
Marks that new data is available and triggers a repaint on the next timer tick.
void setUsesValuesInDB(bool useValuesInDB)
void resized() override
Lays out child components.
Base class for all data objects exchanged between the audio processor and its analyzers/visualisers.
@ Invalid
Uninitialised or unknown data.
@ AudioSignal
Raw audio buffer data.
@ Level
Peak/RMS/hold level metering data.
@ Spectrum
FFT frequency-spectrum data.
Type GetDataType()
Returns the concrete type of this data object.
void outputMuteChange(std::uint16_t channel, bool muteState, MemaOutputCommander *sender)
@ Vertical
Bars grow bottom-to-top.
void setOutputMute(std::uint16_t channel, bool muteState, int userId=-1) override
virtual void processChanges() override
Called on the message thread to update cached data before repainting.
void setChannelCount(std::uint16_t channelCount) override
void buttonClicked(juce::Button *) override
std::function< void()> onBoundsRequirementChange
juce::Rectangle< int > getRequiredSize()
void processingDataChanged(AbstractProcessorData *data) override
Definition Mema.cpp:27