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 = {
60 m_networkConnection->sendMessage(std::make_unique<Mema::DataTrafficTypeSelectionMessage>(desiredTrafficTypes)->getSerializedMessage());
62 setStatus(Status::Monitoring);
64 m_networkConnection->onConnectionLost = [=]() {
67 if (m_remoteComponent)
68 m_remoteComponent->resetCtrl();
72 setStatus(Status::Connecting);
74 m_networkConnection->onMessageReceived = [=](
const juce::MemoryBlock& message) {
78 m_settingsHostLookAndFeelId = epm->getPaletteStyle();
79 jassert(m_settingsHostLookAndFeelId >= JUCEAppBasics::CustomLookAndFeel::PS_Dark && m_settingsHostLookAndFeelId <= JUCEAppBasics::CustomLookAndFeel::PS_Light);
81 if (onPaletteStyleChange && !m_settingsItems[2].second && !m_settingsItems[3].second)
83 m_settingsItems[1].second = 1;
84 onPaletteStyleChange(m_settingsHostLookAndFeelId,
false);
87 else if (m_remoteComponent &&
nullptr != knownMessage && Status::Monitoring == m_currentStatus)
89 m_remoteComponent->handleMessage(*knownMessage);
94 m_remoteComponent = std::make_unique<MemaReComponent>();
95 m_remoteComponent->onExitClick = [=]() {
96 setStatus(Status::Discovering);
98 m_remoteComponent->onMessageReadyToSend = [=](
const juce::MemoryBlock& message) {
99 if (m_networkConnection)
100 m_networkConnection->sendMessage(message);
102 addAndMakeVisible(m_remoteComponent.get());
104 m_discoverComponent = std::make_unique<MemaClientDiscoverComponent>();
106 m_discoverComponent->onServiceSelected = [=](
const JUCEAppBasics::SessionMasterAwareService& selectedService) {
107 m_selectedService = selectedService;
112 m_config->triggerConfigurationDump(
false);
114 addAndMakeVisible(m_discoverComponent.get());
116 m_connectingComponent = std::make_unique<MemaClientConnectingComponent>();
117 addAndMakeVisible(m_connectingComponent.get());
119 m_aboutComponent = std::make_unique<AboutComponent>(BinaryData::MemaReRect_png, BinaryData::MemaReRect_pngSize);
120 m_aboutButton = std::make_unique<juce::DrawableButton>(
"About", juce::DrawableButton::ButtonStyle::ImageFitted);
121 m_aboutButton->setTooltip(juce::String(
"About") + juce::JUCEApplication::getInstance()->getApplicationName());
122 m_aboutButton->onClick = [
this] {
123 juce::PopupMenu aboutMenu;
124 aboutMenu.addCustomItem(1, std::make_unique<CustomAboutItem>(m_aboutComponent.get(), juce::Rectangle<int>(250, 250)),
nullptr, juce::String(
"Info about") + juce::JUCEApplication::getInstance()->getApplicationName());
125 aboutMenu.showMenuAsync(juce::PopupMenu::Options());
127 m_aboutButton->setAlwaysOnTop(
true);
128 m_aboutButton->setColour(juce::DrawableButton::ColourIds::backgroundColourId, juce::Colours::transparentBlack);
129 m_aboutButton->setColour(juce::DrawableButton::ColourIds::backgroundOnColourId, juce::Colours::transparentBlack);
130 addAndMakeVisible(m_aboutButton.get());
134 auto fullscreenShortCutHint = std::string(
" (Ctrl+F11)");
136 auto fullscreenShortCutHint = std::string(
" (Cmd+Ctrl+F)");
140 m_settingsItems[MemaReSettingsOption::LookAndFeel_FollowHost] = std::make_pair(
"Follow Mema", 0);
141 m_settingsItems[MemaReSettingsOption::LookAndFeel_Dark] = std::make_pair(
"Dark", 1);
142 m_settingsItems[MemaReSettingsOption::LookAndFeel_Light] = std::make_pair(
"Light", 0);
144 m_settingsItems[MemaReSettingsOption::ControlFormat_RawChannels] = std::make_pair(
"Faderbank", 1);
145 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_LRS] = std::make_pair(juce::AudioChannelSet::createLRS().getDescription().toStdString(), 0);
146 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_LCRS] = std::make_pair(juce::AudioChannelSet::createLCRS().getDescription().toStdString(), 0);
147 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_5point0] = std::make_pair(juce::AudioChannelSet::create5point0().getDescription().toStdString(), 0);
148 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_5point1] = std::make_pair(juce::AudioChannelSet::create5point1().getDescription().toStdString(), 0);
149 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_5point1point2] = std::make_pair(juce::AudioChannelSet::create5point1point2().getDescription().toStdString(), 0);
150 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_7point0] = std::make_pair(juce::AudioChannelSet::create7point0().getDescription().toStdString(), 0);
151 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_7point1] = std::make_pair(juce::AudioChannelSet::create7point1().getDescription().toStdString(), 0);
152 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_7point1point4] = std::make_pair(juce::AudioChannelSet::create7point1point4().getDescription().toStdString(), 0);
153 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_9point1point6] = std::make_pair(juce::AudioChannelSet::create9point1point6().getDescription().toStdString(), 0);
154 m_settingsItems[MemaReSettingsOption::ControlFormat_PanningType_Quadrophonic] = std::make_pair(juce::AudioChannelSet::quadraphonic().getDescription().toStdString(), 0);
155 m_settingsItems[MemaReSettingsOption::ControlFormat_PluginParameterControl] = std::make_pair(
"Plug-in parameter control", 1);
157 m_settingsItems[MemaReSettingsOption::ControlColour_Green] = std::make_pair(
"Green", 1);
158 m_settingsItems[MemaReSettingsOption::ControlColour_Red] = std::make_pair(
"Red", 0);
159 m_settingsItems[MemaReSettingsOption::ControlColour_Blue] = std::make_pair(
"Blue", 0);
160 m_settingsItems[MemaReSettingsOption::ControlColour_Pink] = std::make_pair(
"Anni Pink", 0);
161 m_settingsItems[MemaReSettingsOption::ControlColour_Laser] = std::make_pair(
"Laser", 0);
163 m_settingsItems[MemaReSettingsOption::ControlsSize_S] = std::make_pair(
"S", 1);
164 m_settingsItems[MemaReSettingsOption::ControlsSize_M] = std::make_pair(
"M", 0);
165 m_settingsItems[MemaReSettingsOption::ControlsSize_L] = std::make_pair(
"L", 0);
166#if JUCE_WINDOWS || JUCE_MAC
168 m_settingsItems[MemaReSettingsOption::FullscreenWindowMode] = std::make_pair(
"Toggle fullscreen mode" + fullscreenShortCutHint, 0);
171 m_settingsButton = std::make_unique<juce::DrawableButton>(
"Settings", juce::DrawableButton::ButtonStyle::ImageFitted);
172 m_settingsButton->setTooltip(juce::String(
"Settings for") + juce::JUCEApplication::getInstance()->getApplicationName());
173 m_settingsButton->onClick = [
this] {
174 juce::PopupMenu lookAndFeelSubMenu;
175 for (
int i = MemaReSettingsOption::LookAndFeel_First; i <= MemaReSettingsOption::LookAndFeel_Last; i++)
176 lookAndFeelSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
178 juce::PopupMenu controlFormatSubMenu;
179 for (
int i = MemaReSettingsOption::ControlFormat_First; i <= MemaReSettingsOption::ControlFormat_Last; i++)
180 controlFormatSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
182 juce::PopupMenu controlColourSubMenu;
183 for (
int i = MemaReSettingsOption::ControlColour_First; i <= MemaReSettingsOption::ControlColour_Last; i++)
184 controlColourSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
186 juce::PopupMenu constrolsSizeSubMenu;
187 for (
int i = MemaReSettingsOption::ControlsSize_First; i <= MemaReSettingsOption::ControlsSize_Last; i++)
188 constrolsSizeSubMenu.addItem(i, m_settingsItems[i].first,
true, m_settingsItems[i].second == 1);
190 juce::PopupMenu settingsMenu;
191 settingsMenu.addSubMenu(
"LookAndFeel", lookAndFeelSubMenu);
192 settingsMenu.addSubMenu(
"Control format", controlFormatSubMenu);
193 settingsMenu.addSubMenu(
"Control colour", controlColourSubMenu);
194 settingsMenu.addSubMenu(
"Controls size", constrolsSizeSubMenu);
195 settingsMenu.addSeparator();
196 settingsMenu.addItem(MemaReSettingsOption::ExternalControl,
"External control...",
true);
197#if JUCE_WINDOWS || JUCE_MAC
198 settingsMenu.addSeparator();
199 settingsMenu.addItem(MemaReSettingsOption::FullscreenWindowMode, m_settingsItems[MemaReSettingsOption::FullscreenWindowMode].first,
true,
false);
201 settingsMenu.showMenuAsync(juce::PopupMenu::Options(), [=](
int selectedId) {
202 handleSettingsMenuResult(selectedId);
204 m_config->triggerConfigurationDump();
207 m_settingsButton->setAlwaysOnTop(
true);
208 m_settingsButton->setColour(juce::DrawableButton::ColourIds::backgroundColourId, juce::Colours::transparentBlack);
209 m_settingsButton->setColour(juce::DrawableButton::ColourIds::backgroundOnColourId, juce::Colours::transparentBlack);
210 addAndMakeVisible(m_settingsButton.get());
212 m_disconnectButton = std::make_unique<juce::DrawableButton>(
"Disconnect", juce::DrawableButton::ButtonStyle::ImageFitted);
213 m_disconnectButton->setTooltip(juce::String(
"Disconnect ") + juce::JUCEApplication::getInstance()->getApplicationName() +
" from " + (m_selectedService.description.isNotEmpty() ? m_selectedService.description :
"Nothing :)"));
214 m_disconnectButton->onClick = [
this] {
215 if (m_networkConnection)
216 m_networkConnection->disconnect();
218 if (m_remoteComponent)
219 m_remoteComponent->resetCtrl();
221 m_selectedService = {};
222 if (m_discoverComponent)
223 m_discoverComponent->resetServices();
226 m_config->triggerConfigurationDump();
228 setStatus(Status::Discovering);
230 m_disconnectButton->setAlwaysOnTop(
true);
231 m_disconnectButton->setColour(juce::DrawableButton::ColourIds::backgroundColourId, juce::Colours::transparentBlack);
232 m_disconnectButton->setColour(juce::DrawableButton::ColourIds::backgroundOnColourId, juce::Colours::transparentBlack);
233 addAndMakeVisible(m_disconnectButton.get());
235 if (juce::JUCEApplication::getInstance()->getCommandLineParameters().contains(
"--noconfigui"))
237 m_aboutButton->setVisible(
false);
238 m_settingsButton->setVisible(
false);
239 m_disconnectButton->setVisible(
false);
242#ifdef RUN_MESSAGE_TESTS
250#define IGNORE_UPDATES
251#elif defined JUCE_ANDROID
253#define IGNORE_UPDATES
256#if defined IGNORE_UPDATES
258 auto noUpdates = juce::JUCEApplication::getInstance()->getCommandLineParameters().contains(
"--noupdates");
261 auto updater = JUCEAppBasics::WebUpdateDetector::getInstance();
262 updater->SetReferenceVersion(ProjectInfo::versionString);
263 updater->SetDownloadUpdateWebAddress(
"https://github.com/christianahrens/mema/releases/latest");
264 updater->CheckForNewVersion(
true,
"https://raw.githubusercontent.com/ChristianAhrens/Mema/refs/heads/main/");
270 m_config->addWatcher(
this);
273 setWantsKeyboardFocus(
true);
275 JUCEAppBasics::iOS_utils::initialise([
this] { resized(); });
280 JUCEAppBasics::iOS_utils::deinitialise();
285 auto safety = JUCEAppBasics::iOS_utils::getDeviceSafetyMargins();
292 switch (m_currentStatus)
294 case Status::Monitoring:
295 m_connectingComponent->setVisible(
false);
296 m_discoverComponent->setVisible(
false);
297 m_remoteComponent->setVisible(
true);
300 case Status::Connecting:
301 m_remoteComponent->setVisible(
false);
302 m_discoverComponent->setVisible(
false);
303 m_connectingComponent->setVisible(
true);
306 case Status::Discovering:
308 m_connectingComponent->setVisible(
false);
309 m_remoteComponent->setVisible(
false);
310 m_discoverComponent->setVisible(
true);
319 m_aboutButton->setBounds(
leftButtons.removeFromTop(35).removeFromBottom(30));
320 m_settingsButton->setBounds(
leftButtons.removeFromTop(35).removeFromBottom(30));
321 m_disconnectButton->setBounds(
rightButtons.removeFromTop(35).removeFromBottom(30));
332 auto aboutButtonDrawable = juce::Drawable::createFromSVG(*juce::XmlDocument::parse(BinaryData::question_mark_24dp_svg).
get());
336 auto settingsDrawable = juce::Drawable::createFromSVG(*juce::XmlDocument::parse(BinaryData::settings_24dp_svg).
get());
340 auto disconnectDrawable = juce::Drawable::createFromSVG(*juce::XmlDocument::parse(BinaryData::link_off_24dp_svg).
get());
344 applyControlColour();
350 handleSettingsMenuResult(
option);
353void MainComponent::handleSettingsMenuResult(
int selectedId)
358 handleSettingsLookAndFeelMenuResult(
selectedId);
360 handleSettingsControlFormatMenuResult(
selectedId);
362 handleSettingsControlColourMenuResult(
selectedId);
364 handleSettingsControlsSizeMenuResult(
selectedId);
366 showExternalControlSettings();
368 handleSettingsFullscreenModeToggleResult();
373void MainComponent::handleSettingsLookAndFeelMenuResult(
int selectedId)
405void MainComponent::handleSettingsControlFormatMenuResult(
int selectedId)
408 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) {
426 setSettingsItemsCheckState(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
427 if (m_remoteComponent)
428 m_remoteComponent->setFaderbankCtrlActive();
431 setSettingsItemsCheckState(0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
432 if (m_remoteComponent)
433 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::createLRS());
436 setSettingsItemsCheckState(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
437 if (m_remoteComponent)
438 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::createLCRS());
441 setSettingsItemsCheckState(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
442 if (m_remoteComponent)
443 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create5point0());
446 setSettingsItemsCheckState(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
447 if (m_remoteComponent)
448 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create5point1());
451 setSettingsItemsCheckState(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
452 if (m_remoteComponent)
453 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create5point1point2());
456 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
457 if (m_remoteComponent)
458 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create7point0());
461 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
462 if (m_remoteComponent)
463 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create7point1());
466 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);
467 if (m_remoteComponent)
468 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create7point1point4());
471 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0);
472 if (m_remoteComponent)
473 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::create9point1point6());
476 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
477 if (m_remoteComponent)
478 m_remoteComponent->setOutputPanningCtrlActive(juce::AudioChannelSet::quadraphonic());
481 setSettingsItemsCheckState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
482 if (m_remoteComponent)
483 m_remoteComponent->setPluginCtrlActive();
493void MainComponent::handleSettingsControlColourMenuResult(
int selectedId)
508 setControlColour(juce::Colours::forestgreen);
512 setControlColour(juce::Colours::orangered);
516 setControlColour(juce::Colours::dodgerblue);
520 setControlColour(juce::Colours::deeppink);
524 setControlColour(juce::Colour(0xd1, 0xff, 0x4f));
532void MainComponent::handleSettingsControlsSizeMenuResult(
int selectedId)
561void MainComponent::handleSettingsFullscreenModeToggleResult()
563 toggleFullscreenMode();
566void MainComponent::toggleFullscreenMode()
573void MainComponent::showExternalControlSettings()
575 m_messageBox = std::make_unique<juce::AlertWindow>(
576 "External control setup",
577 "Enter remote control parameters to externally connect to " + juce::JUCEApplication::getInstance()->getApplicationName() +
" and control its parameters.\n" +
578 "Info: This machine uses IP " + juce::IPAddress::getLocalAddress().toString(),
579 juce::MessageBoxIconType::NoIcon);
581 m_messageBox->addTextBlock(
"\nADM-OSC connection parameters:");
582 if (m_remoteComponent)
584 auto admOscSettings = m_remoteComponent->getExternalAdmOscSettings();
585 m_messageBox->addTextEditor(
"ADM local port", juce::String(std::get<0>(
admOscSettings)),
"ADM-OSC port");
586 m_messageBox->addTextEditor(
"ADM remote IP", std::get<1>(
admOscSettings).toString(),
"Target IP");
587 m_messageBox->addTextEditor(
"ADM remote port", juce::String(std::get<2>(
admOscSettings)),
"Target port");
596 m_messageBox->addButton(
"Cancel", 0, juce::KeyPress(juce::KeyPress::escapeKey));
597 m_messageBox->addButton(
"Ok", 1, juce::KeyPress(juce::KeyPress::returnKey));
598 m_messageBox->enterModalState(
true, juce::ModalCallbackFunction::create([=](
int returnValue) {
602 auto ADMOSCremoteIP = juce::IPAddress(m_messageBox->getTextEditorContents(
"ADM remote IP"));
603 auto ADMOSCremotePort = m_messageBox->getTextEditorContents(
"ADM remote port").getIntValue();
604 if (m_remoteComponent)
609 m_config->triggerConfigurationDump();
613 m_messageBox.reset();
617void MainComponent::setControlColour(
const juce::Colour& controlColour)
621 applyControlColour();
623 if (m_connectingComponent)
624 m_connectingComponent->lookAndFeelChanged();
627void MainComponent::applyControlColour()
634 case JUCEAppBasics::CustomLookAndFeel::PS_Light:
635 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringPeakColourId, m_controlColour.brighter());
636 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringRmsColourId, m_controlColour);
638 case JUCEAppBasics::CustomLookAndFeel::PS_Dark:
640 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringPeakColourId, m_controlColour.darker());
641 getLookAndFeel().setColour(JUCEAppBasics::CustomLookAndFeel::ColourIds::MeteringRmsColourId, m_controlColour);
649 if (m_remoteComponent)
650 m_remoteComponent->setControlsSize(
ctrlsSize);
653void MainComponent::setStatus(
const Status& s)
656 juce::MessageManager::callAsync([
safeThis = juce::Component::SafePointer<MainComponent>(
this)]() {
664 return m_currentStatus;
667void MainComponent::connectToMema()
669 if (m_connectingComponent)
670 m_connectingComponent->setMasterServiceDescription(m_selectedService.description);
671 if (m_discoverComponent)
672 m_discoverComponent->setMasterServiceDescription(m_selectedService.description);
674 setStatus(Status::Connecting);
684 if (Status::Connecting == getStatus())
686 auto sl = m_discoverComponent->getAvailableServices();
687 auto const&
iter = std::find_if(
sl.begin(),
sl.end(), [=](
const auto&
service) { return service.description == m_selectedService.description; });
690 if ((m_selectedService.address !=
iter->address && m_selectedService.port !=
iter->port && m_selectedService.description !=
iter->description) || !m_networkConnection->isConnected())
692 m_selectedService = *
iter;
693 if (m_networkConnection)
694 m_networkConnection->ConnectToSocket(m_selectedService.address.toString(), m_selectedService.port);
696 else if (m_networkConnection && !m_networkConnection->isConnected())
697 m_networkConnection->RetryConnectToSocket();
707 if (
key == juce::KeyPress(juce::KeyPress::F11Key, juce::ModifierKeys::ctrlModifier, 0) ||
708 key == juce::KeyPress(
'f', juce::ModifierKeys::commandModifier | juce::ModifierKeys::ctrlModifier, 0))
710 toggleFullscreenMode();
735 if (m_settingsItems[
i].
second == 1)
743 if (m_settingsItems[
i].
second == 1)
751 if (m_settingsItems[
i].
second == 1)
759 if (m_settingsItems[
i].
second == 1)
770 if (m_remoteComponent)
775 if (m_remoteComponent)
797 if (m_networkConnection)
798 m_networkConnection->disconnect();
800 m_selectedService = {};
858 if (m_remoteComponent)
866 return juce::Desktop::getInstance().getKioskModeComponent() !=
nullptr;
870 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.
@ PluginProcessingState
Plugin enabled and pre/post processing state; sent bidirectionally between Mema and Mema....
@ 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.