Mema
Memory Matrix — multi-channel audio matrix monitor and router
Loading...
Searching...
No Matches
InputControlComponent.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_inputLevels = std::make_unique<MeterbridgeComponent>(MeterbridgeComponent::Direction::Horizontal);
34 addAndMakeVisible(m_inputLevels.get());
35}
36
41
43{
44 auto bounds = getLocalBounds();
45
46 if (m_inputLevels)
47 m_inputLevels->setBounds(bounds
48 .removeFromTop(bounds.getHeight() - int(s_channelSize + s_channelGap))
49 .removeFromLeft(int(m_inputMutes.size() * (s_channelSize + s_channelGap))));
50
51 if (!m_inputMutes.empty())
52 {
53 auto muteWidth = int(s_channelSize + s_channelGap);
54 for (auto const& inputMuteKV : m_inputMutes)
55 {
56 inputMuteKV.second->setBounds(bounds.removeFromLeft(muteWidth).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 InputControlComponent::setInputMute(std::uint16_t channel, bool muteState, int /*userId*/)
73{
74 if (m_inputMutes.count(channel) != 1)
75 return;
76
77 if (m_inputMutes.at(channel))
78 m_inputMutes.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 if (m_inputLevels)
103 m_inputLevels->processingDataChanged(&m_levelData);
104
106}
107
108void InputControlComponent::setChannelCount(std::uint16_t channelCount)
109{
110 if (m_channelCount != channelCount)
111 {
112 m_channelCount = channelCount;
113 DBG(__FUNCTION__ << " " << int(channelCount));
114
115 m_inputLevels->setChannelCount(channelCount);
116
117 auto channelsToRemove = std::vector<std::uint16_t>();
118 for (auto const& inputMuteKV : m_inputMutes)
119 {
120 if (inputMuteKV.first > channelCount)
121 channelsToRemove.push_back(inputMuteKV.first);
122 }
123 for (auto const& channel : channelsToRemove)
124 {
125 removeChildComponent(m_inputMutes.at(channel).get());
126 auto iter = std::find_if(m_inputMutes.begin(), m_inputMutes.end(), [=](const auto& inputMuteKV) { return inputMuteKV.first == channel; });
127 if (iter != m_inputMutes.end())
128 m_inputMutes.erase(iter);
129 }
130
131 for (std::uint16_t channel = 1; channel <= channelCount; channel++)
132 {
133 if (m_inputMutes.count(channel) == 0)
134 {
135 m_inputMutes[channel] = std::make_unique<juce::TextButton>("M", "Mute");
136 m_inputMutes.at(channel)->setClickingTogglesState(true);
137 m_inputMutes.at(channel)->addListener(this);
138 m_inputMutes.at(channel)->setColour(juce::TextButton::ColourIds::buttonOnColourId, juce::Colours::red);
139 addAndMakeVisible(m_inputMutes.at(channel).get());
140 }
141 }
142
145
146 resized();
147 }
148}
149
150void InputControlComponent::buttonClicked(juce::Button* button)
151{
152 auto iter = std::find_if(m_inputMutes.begin(), m_inputMutes.end(), [=](const auto& inputMuteKV) { return inputMuteKV.second.get() == button; });
153 if (iter != m_inputMutes.end() && nullptr != iter->second)
154 inputMuteChange(iter->first, iter->second->getToggleState(), this);
155}
156
158{
159 return { m_channelCount * int(s_channelSize + s_channelGap), 60 };
160}
161
162
163}
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 processingDataChanged(AbstractProcessorData *data) override
void paint(Graphics &) override
void buttonClicked(juce::Button *) override
void setChannelCount(std::uint16_t channelCount) override
virtual void processChanges() override
Called on the message thread to update cached data before repainting.
void setInputMute(std::uint16_t channel, bool muteState, int userId=-1) override
std::function< void()> onBoundsRequirementChange
juce::Rectangle< int > getRequiredSize()
void inputMuteChange(std::uint16_t channel, bool muteState, MemaInputCommander *sender)
@ Horizontal
Bars grow left-to-right.
Definition Mema.cpp:27