28#include <CustomLookAndFeel.h>
29#include <WebUpdateDetector.h>
40 m_config = std::make_unique<MemaReAppConfiguration>(JUCEAppBasics::AppConfigurationBase::getDefaultConfigFilePath());
41 m_config->addDumper(
this);
44 if (!m_config->isValid())
46 m_config->ResetToDefault();
49 m_networkConnection = std::make_unique<InterprocessConnectionImpl>();
50 m_networkConnection->onConnectionMade = [=]() {
53 std::vector<Mema::SerializableMessage::SerializableMessageType> desiredTrafficTypes = {
59 m_networkConnection->sendMessage(std::make_unique<Mema::DataTrafficTypeSelectionMessage>(desiredTrafficTypes)->getSerializedMessage());
61 setStatus(Status::Monitoring);
63 m_networkConnection->onConnectionLost = [=]() {
66 if (m_remoteComponent)
67 m_remoteComponent->resetCtrl();
71 setStatus(Status::Connecting);
73 m_networkConnection->onMessageReceived = [=](
const juce::MemoryBlock& message) {
77 m_settingsHostLookAndFeelId = epm->getPaletteStyle();
78 jassert(m_settingsHostLookAndFeelId >= JUCEAppBasics::CustomLookAndFeel::PS_Dark && m_settingsHostLookAndFeelId <= JUCEAppBasics::CustomLookAndFeel::PS_Light);
80 if (onPaletteStyleChange && !m_settingsItems[2].second && !m_settingsItems[3].second)
82 m_settingsItems[1].second = 1;
83 onPaletteStyleChange(m_settingsHostLookAndFeelId,
false);
86 else if (m_remoteComponent &&
nullptr != knownMessage && Status::Monitoring == m_currentStatus)
88 m_remoteComponent->handleMessage(*knownMessage);
93 m_remoteComponent = std::make_unique<MemaReComponent>();
94 m_remoteComponent->onExitClick = [=]() {
95 setStatus(Status::Discovering);
97 m_remoteComponent->onMessageReadyToSend = [=](
const juce::MemoryBlock& message) {
98 if (m_networkConnection)
99 m_networkConnection->sendMessage(message);
101 addAndMakeVisible(m_remoteComponent.get());
103 m_discoverComponent = std::make_unique<MemaClientDiscoverComponent>();
105 m_discoverComponent->onServiceSelected = [=](
const JUCEAppBasics::SessionMasterAwareService& selectedService) {
106 m_selectedService = selectedService;
111 m_config->triggerConfigurationDump(
false);
113 addAndMakeVisible(m_discoverComponent.get());
115 m_connectingComponent = std::make_unique<MemaClientConnectingComponent>();
116 addAndMakeVisible(m_connectingComponent.get());
118 m_aboutComponent = std::make_unique<AboutComponent>(BinaryData::MemaReRect_png, BinaryData::MemaReRect_pngSize);
119 m_aboutButton = std::make_unique<juce::DrawableButton>(
"About", juce::DrawableButton::ButtonStyle::ImageFitted);
120 m_aboutButton->setTooltip(juce::String(
"About") + juce::JUCEApplication::getInstance()->getApplicationName());
121 m_aboutButton->onClick = [
this] {
122 juce::PopupMenu aboutMenu;
123 aboutMenu.addCustomItem(1, std::make_unique<CustomAboutItem>(m_aboutComponent.get(), juce::Rectangle<int>(250, 250)),
nullptr, juce::String(
"Info about") + juce::JUCEApplication::getInstance()->getApplicationName());
124 aboutMenu.showMenuAsync(juce::PopupMenu::Options());
126 m_aboutButton->setAlwaysOnTop(
true);
127 m_aboutButton->setColour(juce::DrawableButton::ColourIds::backgroundColourId, juce::Colours::transparentBlack);
128 m_aboutButton->setColour(juce::DrawableButton::ColourIds::backgroundOnColourId, juce::Colours::transparentBlack);
129 addAndMakeVisible(m_aboutButton.get());
133 auto fullscreenShortCutHint = std::string(
" (Ctrl+F11)");
135 auto fullscreenShortCutHint = std::string(
" (Cmd+Ctrl+F)");
139 m_settingsItems[MemaReSettingsOption::LookAndFeel_FollowHost] = std::make_pair(
"Follow Mema", 0);
140 m_settingsItems[MemaReSettingsOption::LookAndFeel_Dark] = std::make_pair(
"Dark", 1);
141 m_settingsItems[MemaReSettingsOption::LookAndFeel_Light] = std::make_pair(
"Light", 0);
143 m_settingsItems[MemaReSettingsOption::ControlFormat_RawChannels] = std::make_pair(
"Faderbank", 1);
144 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_LRS] = std::make_pair(juce::AudioChannelSet::createLRS().getDescription().toStdString(), 0);
145 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_LCRS] = std::make_pair(juce::AudioChannelSet::createLCRS().getDescription().toStdString(), 0);
146 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_5point0] = std::make_pair(juce::AudioChannelSet::create5point0().getDescription().toStdString(), 0);
147 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_5point1] = std::make_pair(juce::AudioChannelSet::create5point1().getDescription().toStdString(), 0);
148 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_5point1point2] = std::make_pair(juce::AudioChannelSet::create5point1point2().getDescription().toStdString(), 0);
149 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_7point0] = std::make_pair(juce::AudioChannelSet::create7point0().getDescription().toStdString(), 0);
150 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_7point1] = std::make_pair(juce::AudioChannelSet::create7point1().getDescription().toStdString(), 0);
151 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_7point1point4] = std::make_pair(juce::AudioChannelSet::create7point1point4().getDescription().toStdString(), 0);
152 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_9point1point6] = std::make_pair(juce::AudioChannelSet::create9point1point6().getDescription().toStdString(), 0);
153 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_Quadrophonic] = std::make_pair(juce::AudioChannelSet::quadraphonic().getDescription().toStdString(), 0);
154 m_settingsItems[MemaReSettingsOption::ControlFormat_PluginParameterControl] = std::make_pair(
"Plug-in parameter control", 1);
156 m_settingsItems[MemaReSettingsOption::ControlColour_Green] = std::make_pair(
"Green", 1);
157 m_settingsItems[MemaReSettingsOption::ControlColour_Red] = std::make_pair(
"Red", 0);
158 m_settingsItems[MemaReSettingsOption::ControlColour_Blue] = std::make_pair(
"Blue", 0);
159 m_settingsItems[MemaReSettingsOption::ControlColour_Pink] = std::make_pair(
"Anni Pink", 0);
160 m_settingsItems[MemaReSettingsOption::ControlColour_Laser] = std::make_pair(
"Laser", 0);
162 m_settingsItems[MemaReSettingsOption::ControlsSize_S] = std::make_pair(
"S", 1);
163 m_settingsItems[MemaReSettingsOption::ControlsSize_M] = std::make_pair(
"M", 0);
164 m_settingsItems[MemaReSettingsOption::ControlsSize_L] = std::make_pair(
"L", 0);
165#if JUCE_WINDOWS || JUCE_MAC
167 m_settingsItems[MemaReSettingsOption::FullscreenWindowMode] = std::make_pair(
"Toggle fullscreen mode" + fullscreenShortCutHint, 0);
170 m_settingsButton = std::make_unique<juce::DrawableButton>(
"Settings", juce::DrawableButton::ButtonStyle::ImageFitted);
171 m_settingsButton->setTooltip(juce::String(
"Settings for") + juce::JUCEApplication::getInstance()->getApplicationName());
172 m_settingsButton->onClick = [
this] {
173 juce::PopupMenu lookAndFeelSubMenu;
174 for (
int i = MemaReSettingsOption::LookAndFeel_First; i <= MemaReSettingsOption::LookAndFeel_Last; i++)
175 lookAndFeelSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
177 juce::PopupMenu controlFormatSubMenu;
178 for (
int i = MemaReSettingsOption::ControlFormat_First; i <= MemaReSettingsOption::ControlFormat_Last; i++)
179 controlFormatSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
181 juce::PopupMenu controlColourSubMenu;
182 for (
int i = MemaReSettingsOption::ControlColour_First; i <= MemaReSettingsOption::ControlColour_Last; i++)
183 controlColourSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
185 juce::PopupMenu constrolsSizeSubMenu;
186 for (
int i = MemaReSettingsOption::ControlsSize_First; i <= MemaReSettingsOption::ControlsSize_Last; i++)
187 constrolsSizeSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
189 juce::PopupMenu settingsMenu;
190 settingsMenu.addSubMenu(
"LookAndFeel", lookAndFeelSubMenu);
191 settingsMenu.addSubMenu(
"Control format", controlFormatSubMenu);
192 settingsMenu.addSubMenu(
"Control colour", controlColourSubMenu);
193 settingsMenu.addSubMenu(
"Controls size", constrolsSizeSubMenu);
194 settingsMenu.addSeparator();
195 settingsMenu.addItem(MemaReSettingsOption::ExternalControl,
"External control...",
true);
196#if JUCE_WINDOWS || JUCE_MAC
197 settingsMenu.addSeparator();
198 settingsMenu.addItem(MemaReSettingsOption::FullscreenWindowMode, m_settingsItems[MemaReSettingsOption::FullscreenWindowMode].first,
true,
false);
200 settingsMenu.showMenuAsync(juce::PopupMenu::Options(), [=](
int selectedId) {
201 handleSettingsMenuResult(selectedId);
203 m_config->triggerConfigurationDump();
206 m_settingsButton->setAlwaysOnTop(
true);
207 m_settingsButton->setColour(juce::DrawableButton::ColourIds::backgroundColourId, juce::Colours::transparentBlack);
208 m_settingsButton->setColour(juce::DrawableButton::ColourIds::backgroundOnColourId, juce::Colours::transparentBlack);
209 addAndMakeVisible(m_settingsButton.get());
211 m_disconnectButton = std::make_unique<juce::DrawableButton>(
"Disconnect", juce::DrawableButton::ButtonStyle::ImageFitted);
212 m_disconnectButton->setTooltip(juce::String(
"Disconnect ") + juce::JUCEApplication::getInstance()->getApplicationName() +
" from " + (m_selectedService.description.isNotEmpty() ? m_selectedService.description :
"Nothing :)"));
213 m_disconnectButton->onClick = [
this] {
214 if (m_networkConnection)
215 m_networkConnection->disconnect();
217 if (m_remoteComponent)
218 m_remoteComponent->resetCtrl();
220 m_selectedService = {};
221 if (m_discoverComponent)
222 m_discoverComponent->resetServices();
225 m_config->triggerConfigurationDump();
227 setStatus(Status::Discovering);
229 m_disconnectButton->setAlwaysOnTop(
true);
230 m_disconnectButton->setColour(juce::DrawableButton::ColourIds::backgroundColourId, juce::Colours::transparentBlack);
231 m_disconnectButton->setColour(juce::DrawableButton::ColourIds::backgroundOnColourId, juce::Colours::transparentBlack);
232 addAndMakeVisible(m_disconnectButton.get());
234#ifdef RUN_MESSAGE_TESTS
242#define IGNORE_UPDATES
243#elif defined JUCE_ANDROID
245#define IGNORE_UPDATES
248#if defined IGNORE_UPDATES
250 auto updater = JUCEAppBasics::WebUpdateDetector::getInstance();
251 updater->SetReferenceVersion(ProjectInfo::versionString);
252 updater->SetDownloadUpdateWebAddress(
"https://github.com/christianahrens/mema/releases/latest");
253 updater->CheckForNewVersion(
true,
"https://raw.githubusercontent.com/ChristianAhrens/Mema/refs/heads/main/");
258 m_config->addWatcher(
this);
261 setWantsKeyboardFocus(
true);
270 auto safety = JUCEAppBasics::iOS_utils::getDeviceSafetyMargins();
277 switch (m_currentStatus)
279 case Status::Monitoring:
280 m_connectingComponent->setVisible(
false);
281 m_discoverComponent->setVisible(
false);
282 m_remoteComponent->setVisible(
true);
285 case Status::Connecting:
286 m_remoteComponent->setVisible(
false);
287 m_discoverComponent->setVisible(
false);
288 m_connectingComponent->setVisible(
true);
291 case Status::Discovering:
293 m_connectingComponent->setVisible(
false);
294 m_remoteComponent->setVisible(
false);
295 m_discoverComponent->setVisible(
true);
302 m_aboutButton->setBounds(
leftButtons.removeFromTop(35).removeFromBottom(30));
303 m_settingsButton->setBounds(
leftButtons.removeFromTop(35).removeFromBottom(30));
304 m_disconnectButton->setBounds(
rightButtons.removeFromTop(35).removeFromBottom(30));
314 auto aboutButtonDrawable = juce::Drawable::createFromSVG(*juce::XmlDocument::parse(BinaryData::question_mark_24dp_svg).
get());
318 auto settingsDrawable = juce::Drawable::createFromSVG(*juce::XmlDocument::parse(BinaryData::settings_24dp_svg).
get());
322 auto disconnectDrawable = juce::Drawable::createFromSVG(*juce::XmlDocument::parse(BinaryData::link_off_24dp_svg).
get());
326 applyControlColour();
332 handleSettingsMenuResult(
option);
335void MainComponent::handleSettingsMenuResult(
int selectedId)
340 handleSettingsLookAndFeelMenuResult(
selectedId);
342 handleSettingsControlFormatMenuResult(
selectedId);
344 handleSettingsControlColourMenuResult(
selectedId);
346 handleSettingsControlsSizeMenuResult(
selectedId);
348 showExternalControlSettings();
350 handleSettingsFullscreenModeToggleResult();
355void MainComponent::handleSettingsLookAndFeelMenuResult(
int selectedId)
387void MainComponent::handleSettingsControlFormatMenuResult(
int selectedId)
390 std::function<
void(
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int,
int)>
setSettingsItemsCheckState = [=](
int a,
int b,
int c,
int d,
int e,
int f,
int g,
int h,
int i,
int j,
int k,
int l) {
408 setSettingsItemsCheckState(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
409 if (m_remoteComponent)
410 m_remoteComponent->setFaderbankCtrlActive();
413 setSettingsItemsCheckState(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
414 if (m_remoteComponent)
415 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::createLRS());
418 setSettingsItemsCheckState(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
419 if (m_remoteComponent)
420 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::createLCRS());
423 setSettingsItemsCheckState(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
424 if (m_remoteComponent)
425 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create5point0());
428 setSettingsItemsCheckState(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
429 if (m_remoteComponent)
430 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create5point1());
433 setSettingsItemsCheckState(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
434 if (m_remoteComponent)
435 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create5point1point2());
438 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
439 if (m_remoteComponent)
440 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create7point0());
443 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
444 if (m_remoteComponent)
445 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create7point1());
448 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
449 if (m_remoteComponent)
450 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create7point1point4());
453 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
454 if (m_remoteComponent)
455 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create9point1point6());
458 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
459 if (m_remoteComponent)
460 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::quadraphonic());
463 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
464 if (m_remoteComponent)
465 m_remoteComponent->setPluginCtrlActive();
475void MainComponent::handleSettingsControlColourMenuResult(
int selectedId)
490 setControlColour(juce::Colours::forestgreen);
494 setControlColour(juce::Colours::orangered);
498 setControlColour(juce::Colours::dodgerblue);
502 setControlColour(juce::Colours::deeppink);
506 setControlColour(juce::Colour(0xd1, 0xff, 0x4f));
514void MainComponent::handleSettingsControlsSizeMenuResult(
int selectedId)
543void MainComponent::handleSettingsFullscreenModeToggleResult()
545 toggleFullscreenMode();
548void MainComponent::toggleFullscreenMode()
555void MainComponent::showExternalControlSettings()
557 m_messageBox = std::make_unique<juce::AlertWindow>(
558 "External control setup",
559 "Enter remote control parameters to externally connect to " + juce::JUCEApplication::getInstance()->getApplicationName() +
" and control its parameters.\n" +
560 "Info: This machine uses IP " + juce::IPAddress::getLocalAddress().toString(),
561 juce::MessageBoxIconType::NoIcon);
563 m_messageBox->addTextBlock(
"\nADM-OSC connection parameters:");
564 if (m_remoteComponent)
566 auto admOscSettings = m_remoteComponent->getExternalAdmOscSettings();
567 m_messageBox->addTextEditor(
"ADM local port", juce::String(std::get<0>(
admOscSettings)),
"ADM-OSC port");
568 m_messageBox->addTextEditor(
"ADM remote IP", std::get<1>(
admOscSettings).toString(),
"Target IP");
569 m_messageBox->addTextEditor(
"ADM remote port", juce::String(std::get<2>(
admOscSettings)),
"Target port");
578 m_messageBox->addButton(
"Cancel", 0, juce::KeyPress(juce::KeyPress::escapeKey));
579 m_messageBox->addButton(
"Ok", 1, juce::KeyPress(juce::KeyPress::returnKey));
580 m_messageBox->enterModalState(
true, juce::ModalCallbackFunction::create([=](
int returnValue) {
584 auto ADMOSCremoteIP = juce::IPAddress(m_messageBox->getTextEditorContents(
"ADM remote IP"));
585 auto ADMOSCremotePort = m_messageBox->getTextEditorContents(
"ADM remote port").getIntValue();
586 if (m_remoteComponent)
591 m_config->triggerConfigurationDump();
595 m_messageBox.reset();
599void MainComponent::setControlColour(
const juce::Colour& controlColour)
603 applyControlColour();
605 if (m_connectingComponent)
606 m_connectingComponent->lookAndFeelChanged();
609void MainComponent::applyControlColour()
616 case JUCEAppBasics::CustomLookAndFeel::PS_Light:
617 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringPeakColourId, m_controlColour.brighter());
618 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringRmsColourId, m_controlColour);
620 case JUCEAppBasics::CustomLookAndFeel::PS_Dark:
622 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringPeakColourId, m_controlColour.darker());
623 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringRmsColourId, m_controlColour);
631 if (m_remoteComponent)
632 m_remoteComponent->setControlsSize(
ctrlsSize);
635void MainComponent::setStatus(
const Status& s)
638 juce::MessageManager::callAsync([
safeThis = juce::Component::SafePointer<MainComponent>(
this)]() {
646 return m_currentStatus;
649void MainComponent::connectToMema()
651 if (m_connectingComponent)
652 m_connectingComponent->setMasterServiceDescription(m_selectedService.description);
653 if (m_discoverComponent)
654 m_discoverComponent->setMasterServiceDescription(m_selectedService.description);
656 setStatus(Status::Connecting);
666 if (Status::Connecting == getStatus())
668 auto sl = m_discoverComponent->getAvailableServices();
669 auto const&
iter = std::find_if(
sl.begin(),
sl.end(), [=](
const auto&
service) { return service.description == m_selectedService.description; });
672 if ((m_selectedService.address !=
iter->address && m_selectedService.port !=
iter->port && m_selectedService.description !=
iter->description) || !m_networkConnection->isConnected())
674 m_selectedService = *
iter;
675 if (m_networkConnection)
676 m_networkConnection->ConnectToSocket(m_selectedService.address.toString(), m_selectedService.port);
678 else if (m_networkConnection && !m_networkConnection->isConnected())
679 m_networkConnection->RetryConnectToSocket();
689 if (
key == juce::KeyPress(juce::KeyPress::F11Key, juce::ModifierKeys::ctrlModifier, 0) ||
690 key == juce::KeyPress(
'f', juce::ModifierKeys::commandModifier | juce::ModifierKeys::ctrlModifier, 0))
692 toggleFullscreenMode();
717 if (m_settingsItems[
i].
second == 1)
725 if (m_settingsItems[
i].
second == 1)
733 if (m_settingsItems[
i].
second == 1)
741 if (m_settingsItems[
i].
second == 1)
752 if (m_remoteComponent)
757 if (m_remoteComponent)
779 if (m_networkConnection)
780 m_networkConnection->disconnect();
782 m_selectedService = {};
840 if (m_remoteComponent)
848 return juce::Desktop::getInstance().getKioskModeComponent() !=
nullptr;
852 return peer->isFullScreen();
void paint(juce::Graphics &g) override
Paints the background and any status overlay.
void performConfigurationDump() override
Serialises the current configuration to the XML file on disk.
std::function< void(int, bool)> onPaletteStyleChange
Called when the user changes the look-and-feel or metering colour.
void resized() override
Lays out the active child component to fill the window.
MemaReSettingsOption
Identifiers for all user-configurable settings exposed via the settings popup menu.
@ ControlsSize_M
Medium control elements.
@ ControlsSize_S
Small control elements.
@ ControlFormat_PanningType_5point0
2-D spatial panning — 5.0 surround.
@ LookAndFeel_Light
Force light look-and-feel.
@ ControlFormat_PanningType_7point1point4
2-D spatial panning — 7.1.4 Dolby Atmos.
@ ControlFormat_PanningType_9point1point6
2-D spatial panning — 9.1.6 ATMOS full-3D.
@ ControlColour_Blue
Blue accent colour.
@ LookAndFeel_FollowHost
Match the host OS appearance.
@ ControlFormat_PanningType_7point0
2-D spatial panning — 7.0 surround.
@ ControlColour_Laser
High-visibility laser-green accent colour.
@ ExternalControl
Opens the ADM-OSC external-control settings dialog.
@ LookAndFeel_Dark
Force dark look-and-feel.
@ ControlColour_Pink
Pink accent colour.
@ ControlFormat_PanningType_LCRS
2-D spatial panning — LCRS 4-channel.
@ ControlFormat_PanningType_LRS
2-D spatial panning — LRS 3-channel.
@ ControlFormat_PanningType_Quadrophonic
2-D spatial panning — classic 4-channel quad.
@ ControlsSize_L
Large control elements (good for touch screens).
@ ControlColour_Red
Red accent colour.
@ ControlColour_Green
Green accent colour (default).
@ ControlFormat_RawChannels
Faderbank crosspoint control (raw input × output).
@ ControlFormat_PanningType_5point1point2
2-D spatial panning — 5.1.2 with height.
@ ControlFormat_PluginParameterControl
Plugin-parameter control panel.
@ ControlFormat_PanningType_7point1
2-D spatial panning — 7.1 surround.
@ ControlFormat_PanningType_5point1
2-D spatial panning — 5.1 surround.
@ FullscreenWindowMode
Toggle between popup and fullscreen window mode.
Status
Connection/application phase driven by the TCP session lifecycle.
void lookAndFeelChanged() override
Propagates a look-and-feel change to all owned child components.
bool keyPressed(const juce::KeyPress &key) override
Handles keyboard shortcuts (e.g. Escape to disconnect).
void applySettingsOption(const MemaMoSettingsOption &option)
Applies a settings menu selection, updating look-and-feel, visualisation type, or colour.
void onConfigUpdated() override
Reacts to external configuration changes.
bool isFullscreenEnabled()
Returns whether the window is currently displayed in fullscreen mode.
void timerCallback() override
Periodic callback used to retry TCP connections and poll network status.
std::function< void(bool)> onSetFullscreenWindow
Called to request a fullscreen/windowed transition from the application shell.
~MainComponent() override
static juce::String getAttributeName(AttributeID ID)
@ CONTROLFORMAT
Active control mode (faderbank, 2-D panning layout, plugin parameters).
@ ADMOSCCLIENT
ADM-OSC client (remote IP and port for outgoing messages).
@ CONTROLSSIZE
Size category for control widgets (S / M / L).
@ VISUCONFIG
Root element for visualisation/control settings.
@ LOOKANDFEEL
Active look-and-feel (follow host / dark / light).
@ ADMOSCHOST
ADM-OSC host (local UDP listen port).
@ EXTCTRLCONFIG
Root element for external ADM-OSC controller settings.
@ CONNECTIONCONFIG
Root element for TCP connection settings.
@ SERVICEDESCRIPTION
Stored multicast service descriptor of the last connected Mema instance.
@ CONTROLCOLOUR
User-selected accent colour for control elements.
static juce::String getTagName(TagID ID)
@ PORT
UDP/TCP port number.
@ IP
IP address string (used for ADM-OSC remote client address).
Carries the active look-and-feel palette style from Mema to connected clients.
ControlsSize
Size category for rendered control elements.
@ S
Small — suited for desktop with many channels.
@ L
Large — suited for touch screens.
static void freeMessageData(SerializableMessage *message)
Type-correctly destroys a SerializableMessage* returned by initFromMemoryBlock().
static SerializableMessage * initFromMemoryBlock(const juce::MemoryBlock &blob)
Deserialises a raw TCP frame into the correct concrete SerializableMessage subclass.
@ PluginParameterValue
Single parameter value update sent from Mema.Re to Mema.
@ ReinitIOCount
New input/output channel count; clients must rebuild their UI accordingly.
@ ControlParameters
Full routing-matrix state snapshot; sent by Mema on connect and echoed by Mema.Re on change.
@ EnvironmentParameters
Look-and-feel palette sent by Mema to clients on connect.
@ PluginParameterInfos
Plugin name and full parameter descriptor list; sent by Mema when a plugin is loaded or changed.
static juce::String getRemoteServiceTypeUID()
Returns the UID for the Mema.Re remote-control service.
static juce::String getServiceTypeUIDBase()
Returns the base string for building service type UIDs.