MIDI2LR 6.3.0.1
MIDI2LR is an application that interfaces MIDI controllers with Lightroom 6+/CC Classic. It processes MIDI input into develop parameter updates and photo actions, and sends MIDI output when parameters are changed for motorized feedback (on controllers that have motorized faders). A listing of available LightRoom commands is in the Wiki. Assistance on the code and design is welcome.
Loading...
Searching...
No Matches
MainContentComponent Class Referencefinal

#include <MainComponent.h>

Inheritance diagram for MainContentComponent:

Public Member Functions

 MainContentComponent (const CommandSet &command_set, Profile &profile, ProfileManager &profile_manager, SettingsManager &settings_manager, LrIpcOut &lr_ipc_out, MidiReceiver &midi_receiver, MidiSender &midi_sender)
 MainContentComponent (const MainContentComponent &other)=delete
 MainContentComponent (MainContentComponent &&other)=delete
 ~MainContentComponent ()
void Init ()
MainContentComponentoperator= (const MainContentComponent &other)=delete
MainContentComponentoperator= (MainContentComponent &&other)=delete
void SaveProfile () const

Private Member Functions

void AddComponent (juce::Component &component, int x, int y, int width, int height)
void DisconnectClicked ()
void handleAsyncUpdate () override
void LoadClicked ()
void LrIpcOutCallback (bool, bool)
void MidiCmdCallback (rsj::MidiMessage mm)
void paint (juce::Graphics &) override
void ProfileChanged (juce::XmlElement *xml_element, const juce::String &file_name)
void RemoveAllRowsClicked ()
void RemoveUnassignedClicked ()
void RescanClicked ()
void SettingsClicked ()
void timerCallback () override
void UpdateConnectionLabel (const char *text, juce::Colour colour)

Private Attributes

juce::Label command_label_ {"Command", ""}
CommandTable command_table_ {"Table", nullptr}
CommandTableModel command_table_model_
juce::Label connection_label_ {"Connection", juce::translate("Not connected to Lightroom")}
juce::TextButton disconnect_button_ {juce::translate("Halt sending to Lightroom")}
juce::String last_command_
juce::TextButton load_button_ {juce::translate("Load")}
LrIpcOutlr_ipc_out_
MidiReceivermidi_receiver_
MidiSendermidi_sender_
Profileprofile_
ProfileManagerprofile_manager_
juce::Label profile_name_label_ {"ProfileNameLabel", ""}
juce::TextButton remove_allrows_button_ {juce::translate("Clear ALL rows")}
juce::TextButton remove_unassigned_button_ {juce::translate("Remove unassigned rows")}
juce::TextButton rescan_button_ {juce::translate("Rescan MIDI devices")}
size_t row_to_select_ {0}
juce::TextButton save_button_ {juce::translate("Save")}
juce::TextButton settings_button_ {juce::translate("Settings")}
std::unique_ptr< juce::DialogWindow > settings_dialog_
SettingsManagersettings_manager_
juce::Label title_label_ {"Title", "MIDI2LR"}
juce::DropShadowEffect title_shadow_
juce::Label version_label_

Constructor & Destructor Documentation

◆ MainContentComponent() [1/3]

MainContentComponent::MainContentComponent ( const CommandSet & command_set,
Profile & profile,
ProfileManager & profile_manager,
SettingsManager & settings_manager,
LrIpcOut & lr_ipc_out,
MidiReceiver & midi_receiver,
MidiSender & midi_sender )
66 : ResizableLayout{this}, command_table_model_(command_set, profile), lr_ipc_out_{lr_ipc_out},
67 midi_receiver_{midi_receiver}, midi_sender_{midi_sender}, profile_(profile),
68 profile_manager_(profile_manager), settings_manager_(settings_manager) {
69 setSize(kMainWidth, kMainHeight);
70}
71
72catch (const std::exception& e) {
73 rsj::ExceptionResponse(e, std::source_location::current());
74 throw;
75}
LrIpcOut & lr_ipc_out_
Definition MainComponent.h:94
MidiReceiver & midi_receiver_
Definition MainComponent.h:95
CommandTableModel command_table_model_
Definition MainComponent.h:72
ProfileManager & profile_manager_
Definition MainComponent.h:98
Profile & profile_
Definition MainComponent.h:97
MidiSender & midi_sender_
Definition MainComponent.h:96
SettingsManager & settings_manager_
Definition MainComponent.h:99
void ExceptionResponse(gsl::czstring id, gsl::czstring fu, const std::exception &e) noexcept

◆ ~MainContentComponent()

MainContentComponent::~MainContentComponent ( )
78{
79 // prevent any pending AsyncUpdater callback from running after destruction
80 cancelPendingUpdate();
81
82 settings_manager_.SetDefaultProfile(profile_name_label_.getText());
83 juce::Timer::stopTimer();
84}
juce::Label profile_name_label_
Definition MainComponent.h:76

◆ MainContentComponent() [2/3]

MainContentComponent::MainContentComponent ( const MainContentComponent & other)
delete

◆ MainContentComponent() [3/3]

MainContentComponent::MainContentComponent ( MainContentComponent && other)
delete

Member Function Documentation

◆ AddComponent()

void MainContentComponent::AddComponent ( juce::Component & component,
int x,
int y,
int width,
int height )
private
196{
197 component.setBounds(x, y, width, height);
198 ResizableLayout::addToLayout(&component, anchorMidLeft, anchorMidRight);
199 juce::Component::addAndMakeVisible(component);
200}

◆ DisconnectClicked()

void MainContentComponent::DisconnectClicked ( )
private
177{
178 if (disconnect_button_.getToggleState()) {
179 lr_ipc_out_.SendingStop();
180 rsj::Log("Sending halted.", std::source_location::current());
181 }
182 else {
183 lr_ipc_out_.SendingRestart();
184 rsj::Log("Sending restarted.", std::source_location::current());
185 }
186}
juce::TextButton disconnect_button_
Definition MainComponent.h:87
void Log(const juce::String &info, const std::source_location &location=std::source_location::current()) noexcept
Definition Misc.cpp:112

References lr_ipc_out_, LrIpcOut::SendingRestart(), and LrIpcOut::SendingStop().

◆ handleAsyncUpdate()

void MainContentComponent::handleAsyncUpdate ( )
overrideprivate
411{
412 try {
413 /* Update the last command label and set its color to green */
414 command_label_.setText(last_command_, juce::NotificationType::dontSendNotification);
415 command_label_.setColour(juce::Label::backgroundColourId, juce::Colours::greenyellow);
416 juce::Timer::startTimer(1000);
417 /* Update the command table to add and/or select row corresponding to midi command */
418 command_table_.updateContent();
419 command_table_.selectRow(gsl::narrow_cast<int>(row_to_select_));
420 }
421 catch (const std::exception& e) {
422 rsj::ExceptionResponse(e, std::source_location::current());
423 throw;
424 }
425}
CommandTable command_table_
Definition MainComponent.h:71
juce::String last_command_
Definition MainComponent.h:86
juce::Label command_label_
Definition MainComponent.h:74
size_t row_to_select_
Definition MainComponent.h:100

◆ Init()

void MainContentComponent::Init ( )
203{
204 try {
208
209 /* Main title */
210 StandardLabelSettings(title_label_);
211 title_label_.setFont(juce::Font {juce::FontOptions(36.F, juce::Font::bold)});
212 title_label_.setComponentEffect(&title_shadow_);
213 AddComponent(title_label_, kMainLeft, 10, kFullWidth, 30);
214
215 /* Version label */
216 StandardLabelSettings(version_label_);
217 AddComponent(version_label_, kMainLeft, 40, kFullWidth, 10);
218
219 /* Connection status */
220 StandardLabelSettings(connection_label_);
221 connection_label_.setColour(juce::Label::textColourId, juce::Colours::black);
222 connection_label_.setColour(juce::Label::backgroundColourId, juce::Colours::red);
223 connection_label_.setJustificationType(juce::Justification::centred);
224 AddComponent(connection_label_, 200, 15, kConnectionLabelWidth, kStandardHeight);
225
226 /* Load button */
227 AddComponent(load_button_, kFirstButtonX, kTopButtonY, kButtonWidth, kStandardHeight);
228#if __cpp_lib_bind_front >= 202'306L
229 load_button_.onClick = std::bind_front<&MainContentComponent::LoadClicked>(this);
230#else
231 load_button_.onClick = std::bind_front(&MainContentComponent::LoadClicked, this);
232#endif
233
234 /* Save button */
235 AddComponent(save_button_, kSecondButtonX, kTopButtonY, kButtonWidth, kStandardHeight);
236#if __cpp_lib_bind_front >= 202'306L
237 save_button_.onClick = std::bind_front<&MainContentComponent::SaveProfile>(this);
238#else
239 save_button_.onClick = std::bind_front(&MainContentComponent::SaveProfile, this);
240#endif
241
242 /* Settings button */
243 AddComponent(settings_button_, kThirdButtonX, kTopButtonY, kButtonWidth, kStandardHeight);
244#if __cpp_lib_bind_front >= 202'306L
245 settings_button_.onClick = std::bind_front<&MainContentComponent::SettingsClicked>(this);
246#else
247 settings_button_.onClick = std::bind_front(&MainContentComponent::SettingsClicked, this);
248#endif
249
250 /* Command Table */
252 AddComponent(command_table_, kMainLeft, kCommandTableY, kFullWidth, kCommandTableHeight);
253
254 /* Profile name label */
255 StandardLabelSettings(profile_name_label_);
256 profile_name_label_.setColour(juce::Label::textColourId, juce::Colours::black);
257 profile_name_label_.setJustificationType(juce::Justification::centred);
258 AddComponent(profile_name_label_, kMainLeft, kProfileNameY, kLabelWidth, kStandardHeight);
259
260 /* Last MIDI command */
261 StandardLabelSettings(command_label_);
262 AddComponent(command_label_, kCommandLabelX, kCommandLabelY, kLabelWidth, kStandardHeight);
263
264 /* Remove row button */
265 AddComponent(remove_allrows_button_, kFirstButtonX, kBottomButtonY, kButtonWidth,
266 kStandardHeight);
267#if __cpp_lib_bind_front >= 202'306L
268 remove_allrows_button_.onClick =
269 std::bind_front<&MainContentComponent::RemoveAllRowsClicked>(this);
270#else
271 remove_allrows_button_.onClick =
272 std::bind_front(&MainContentComponent::RemoveAllRowsClicked, this);
273#endif
274
275 /* Rescan MIDI button */
276 AddComponent(rescan_button_, kSecondButtonX, kBottomButtonY, kButtonWidth, kStandardHeight);
277#if __cpp_lib_bind_front >= 202'306L
278 rescan_button_.onClick = std::bind_front<&MainContentComponent::RescanClicked>(this);
279#else
280 rescan_button_.onClick = std::bind_front(&MainContentComponent::RescanClicked, this);
281#endif
282
283 /* Disconnect button */
284 disconnect_button_.setClickingTogglesState(true);
285 AddComponent(disconnect_button_, kThirdButtonX, kBottomButtonY, kButtonWidth,
286 kStandardHeight);
287#if __cpp_lib_bind_front >= 202'306L
288 disconnect_button_.onClick = std::bind_front<&MainContentComponent::DisconnectClicked>(this);
289#else
290 disconnect_button_.onClick = std::bind_front(&MainContentComponent::DisconnectClicked, this);
291#endif
292
293 /* Delete unassigned rows */
294 AddComponent(remove_unassigned_button_, kFirstButtonX, kBottomButtonY2, kButtonWidth,
295 kStandardHeight);
296#if __cpp_lib_bind_front >= 202'306L
298 std::bind_front<&MainContentComponent::RemoveUnassignedClicked>(this);
299#else
301 std::bind_front(&MainContentComponent::RemoveUnassignedClicked, this);
302#endif
303
304 /* Try to load a default.xml if the user has not set a profile directory */
305 if (settings_manager_.GetProfileDirectory().isEmpty()) {
306 const auto filename {rsj::AppDataFilePath(kDefaultsFile)};
307 const auto default_profile {juce::File(filename.data())};
308 if (const auto parsed {juce::parseXML(default_profile)}) {
309 profile_.FromXml(parsed.get());
310 command_table_.updateContent();
311 }
312 }
313 else {
314 const auto last_prof {settings_manager_.GetDefaultProfile()};
315 if (last_prof != juce::String()) { profile_manager_.SwitchToProfile(last_prof); }
316 else { /* otherwise use the last profile from the profile directory */
317 profile_manager_.SwitchToProfile(0);
318 }
319 }
320
321 /* turn it on */
322 ResizableLayout::activateLayout();
323 }
324 catch (const std::exception& e) {
325 rsj::ExceptionResponse(e, std::source_location::current());
326 throw;
327 }
328}
void AddComponent(juce::Component &component, int x, int y, int width, int height)
Definition MainComponent.cpp:194
juce::TextButton rescan_button_
Definition MainComponent.h:91
void SaveProfile() const
Definition MainComponent.cpp:330
void ProfileChanged(juce::XmlElement *xml_element, const juce::String &file_name)
Definition MainComponent.cpp:391
void RemoveAllRowsClicked()
Definition MainComponent.cpp:159
juce::Label version_label_
Definition MainComponent.h:79
void DisconnectClicked()
Definition MainComponent.cpp:176
juce::TextButton settings_button_
Definition MainComponent.h:93
juce::Label connection_label_
Definition MainComponent.h:75
void LrIpcOutCallback(bool, bool)
Definition MainComponent.cpp:381
juce::TextButton save_button_
Definition MainComponent.h:92
juce::DropShadowEffect title_shadow_
Definition MainComponent.h:73
juce::TextButton load_button_
Definition MainComponent.h:88
void MidiCmdCallback(rsj::MidiMessage mm)
Definition MainComponent.cpp:348
void RescanClicked()
Definition MainComponent.cpp:167
juce::Label title_label_
Definition MainComponent.h:77
juce::TextButton remove_allrows_button_
Definition MainComponent.h:89
juce::TextButton remove_unassigned_button_
Definition MainComponent.h:90
void LoadClicked()
Definition MainComponent.cpp:95
void SettingsClicked()
Definition MainComponent.cpp:140
void RemoveUnassignedClicked()
Definition MainComponent.cpp:188
std::string AppDataFilePath(const std::string &file_name)

References lr_ipc_out_, LrIpcOutCallback(), midi_receiver_, MidiCmdCallback(), profile_, profile_manager_, settings_manager_, and ProfileManager::SwitchToProfile().

◆ LoadClicked()

void MainContentComponent::LoadClicked ( )
private
96{
97 try {
98 if (profile_.ProfileUnsaved()) {
99 if (juce::NativeMessageBox::showYesNoBox(juce::AlertWindow::WarningIcon,
100 juce::translate("MIDI2LR profiles"),
101 juce::translate("Profile changed. Do you want to save your changes? If you "
102 "continue without saving, your changes will be lost."))) {
103 SaveProfile();
104 }
105 }
106 juce::File profile_directory {settings_manager_.GetProfileDirectory()};
107 const auto directory_saved {profile_directory.exists()};
108 if (!directory_saved) [[unlikely]] {
109 profile_directory = juce::File::getSpecialLocation(juce::File::userDocumentsDirectory);
110 }
111 juce::FileChooser chooser {juce::translate("Open profile"), profile_directory, "*.xml", true};
112 if (chooser.browseForFileToOpen()) {
113 if (const auto parsed {juce::parseXML(chooser.getResult())}) {
114 const auto new_profile {chooser.getResult()};
115 lr_ipc_out_.SendCommand(fmt::format("ChangedToFullPath {}\n",
116 new_profile.getFullPathName().toStdString()));
117 profile_name_label_.setText(new_profile.getFileName(),
118 juce::NotificationType::dontSendNotification);
119 profile_.FromXml(parsed.get());
120 command_table_.updateContent();
121 command_table_.repaint();
122 if (!directory_saved) [[unlikely]] { /* haven't saved a directory yet */
123 settings_manager_.SetProfileDirectory(
124 new_profile.getParentDirectory().getFullPathName());
125 }
126 }
127 else {
128 rsj::Log(fmt::format("Unable to load profile {}.",
129 chooser.getResult().getFullPathName().toStdString()),
130 std::source_location::current());
131 }
132 }
133 }
134 catch (const std::exception& e) {
135 rsj::ExceptionResponse(e, std::source_location::current());
136 throw;
137 }
138}

References profile_, Profile::ProfileUnsaved(), SaveProfile(), and settings_manager_.

◆ LrIpcOutCallback()

void MainContentComponent::LrIpcOutCallback ( bool connected,
bool sending_blocked )
private
382{
383 const juce::MessageManagerLock mm_lock; /* as not called in message loop */
384 const auto& [text, color] {kConnectionStatus.at({connected, sending_blocked})};
385 UpdateConnectionLabel(text, color);
386}
void UpdateConnectionLabel(const char *text, juce::Colour colour)
Definition MainComponent.cpp:366

Referenced by Init().

◆ MidiCmdCallback()

void MainContentComponent::MidiCmdCallback ( rsj::MidiMessage mm)
private
349{
350 try {
351 /* Display the MIDI parameters and add/highlight row in table corresponding to the message.
352 * msg is 1-based for channel, which display expects */
353 const rsj::MidiMessageId msg {mm};
354 last_command_ = fmt::format("{}: {}{} [{}]", msg.channel, mm.message_type_byte,
355 msg.control_number, mm.value);
356 profile_.InsertUnassigned(msg);
357 row_to_select_ = gsl::narrow_cast<size_t>(profile_.GetRowForMessage(msg));
358 triggerAsyncUpdate();
359 }
360 catch (const std::exception& e) {
361 rsj::ExceptionResponse(e, std::source_location::current());
362 throw;
363 }
364}
MessageType message_type_byte
Definition MidiUtilities.h:121
int value
Definition MidiUtilities.h:124
int channel
Definition MidiUtilities.h:143
int control_number
Definition MidiUtilities.h:144

References rsj::MidiMessageId::MidiMessageId(), Profile::GetRowForMessage(), Profile::InsertUnassigned(), profile_, and row_to_select_.

Referenced by Init().

◆ operator=() [1/2]

MainContentComponent & MainContentComponent::operator= ( const MainContentComponent & other)
delete

◆ operator=() [2/2]

MainContentComponent & MainContentComponent::operator= ( MainContentComponent && other)
delete

◆ paint()

void MainContentComponent::paint ( juce::Graphics & g)
overrideprivate
344{ //-V2009 overridden method
345 g.fillAll(juce::Colours::white);
346}

◆ ProfileChanged()

void MainContentComponent::ProfileChanged ( juce::XmlElement * xml_element,
const juce::String & file_name )
private
393{ //-V2009 overridden method
394 try {
395 {
396 const juce::MessageManagerLock mm_lock;
397 profile_.FromXml(xml_element);
398 command_table_.updateContent();
399 profile_name_label_.setText(file_name, juce::NotificationType::dontSendNotification);
400 }
401 /* Send new CC parameters to MIDI Out devices */
402 lr_ipc_out_.SendCommand("FullRefresh 1\n");
403 }
404 catch (const std::exception& e) {
405 rsj::ExceptionResponse(e, std::source_location::current());
406 throw;
407 }
408}

References lr_ipc_out_, and profile_.

◆ RemoveAllRowsClicked()

void MainContentComponent::RemoveAllRowsClicked ( )
private
160{
161 if (command_table_.getNumRows() > 0) {
162 profile_.RemoveAllRows();
163 command_table_.updateContent();
164 }
165}

References profile_, and Profile::RemoveAllRows().

◆ RemoveUnassignedClicked()

void MainContentComponent::RemoveUnassignedClicked ( )
private
189{
190 profile_.RemoveUnassignedMessages();
191 command_table_.updateContent();
192}

References profile_, and Profile::RemoveUnassignedMessages().

◆ RescanClicked()

void MainContentComponent::RescanClicked ( )
private
168{
169 /* Re-enumerate MIDI IN and OUT devices */
170 midi_receiver_.RescanDevices();
171 midi_sender_.RescanDevices();
172 /* Send new CC parameters to MIDI Out devices */
173 lr_ipc_out_.SendCommand("FullRefresh 1\n");
174}

References lr_ipc_out_, midi_receiver_, midi_sender_, MidiReceiver::RescanDevices(), and MidiSender::RescanDevices().

◆ SaveProfile()

void MainContentComponent::SaveProfile ( ) const
331{
332 juce::File profile_directory {settings_manager_.GetProfileDirectory()};
333 if (!profile_directory.exists()) {
334 profile_directory = juce::File::getSpecialLocation(juce::File::userDocumentsDirectory);
335 }
336 juce::FileChooser chooser {juce::translate("Save profile"), profile_directory, "*.xml", true};
337 if (chooser.browseForFileToSave(true)) {
338 const auto selected_file {chooser.getResult().withFileExtension("xml")};
339 profile_.ToXmlFile(selected_file);
340 }
341}

References profile_.

Referenced by LoadClicked().

◆ SettingsClicked()

void MainContentComponent::SettingsClicked ( )
private
141{
142 try {
143 juce::DialogWindow::LaunchOptions dialog_options;
144 dialog_options.dialogTitle = juce::translate("Settings");
145 /* create new object */
146 auto component {std::make_unique<SettingsComponent>(settings_manager_)};
147 component->Init();
148 dialog_options.content.setOwned(component.release());
149 dialog_options.content->setSize(400, 300);
150 settings_dialog_.reset(dialog_options.create());
151 settings_dialog_->setVisible(true);
152 }
153 catch (const std::exception& e) {
154 rsj::ExceptionResponse(e, std::source_location::current());
155 throw;
156 }
157}
std::unique_ptr< juce::DialogWindow > settings_dialog_
Definition MainComponent.h:101

References settings_manager_.

◆ timerCallback()

void MainContentComponent::timerCallback ( )
overrideprivate
428{
429 /* reset the command label's background to white */
430 command_label_.setColour(juce::Label::backgroundColourId, juce::Colours::white);
431 juce::Timer::stopTimer();
432}

◆ UpdateConnectionLabel()

void MainContentComponent::UpdateConnectionLabel ( const char * text,
juce::Colour colour )
private
367{
368 connection_label_.setText(juce::translate(text), juce::NotificationType::dontSendNotification);
369 connection_label_.setColour(juce::Label::backgroundColourId, colour);
370}

Member Data Documentation

◆ command_label_

juce::Label MainContentComponent::command_label_ {"Command", ""}
private
74{"Command", ""};

◆ command_table_

CommandTable MainContentComponent::command_table_ {"Table", nullptr}
private
71{"Table", nullptr};

◆ command_table_model_

CommandTableModel MainContentComponent::command_table_model_
private

◆ connection_label_

juce::Label MainContentComponent::connection_label_ {"Connection", juce::translate("Not connected to Lightroom")}
private
75{"Connection", juce::translate("Not connected to Lightroom")};

◆ disconnect_button_

juce::TextButton MainContentComponent::disconnect_button_ {juce::translate("Halt sending to Lightroom")}
private
87{juce::translate("Halt sending to Lightroom")};

◆ last_command_

juce::String MainContentComponent::last_command_
private

◆ load_button_

juce::TextButton MainContentComponent::load_button_ {juce::translate("Load")}
private
88{juce::translate("Load")};

◆ lr_ipc_out_

LrIpcOut& MainContentComponent::lr_ipc_out_
private

◆ midi_receiver_

MidiReceiver& MainContentComponent::midi_receiver_
private

Referenced by Init(), and RescanClicked().

◆ midi_sender_

MidiSender& MainContentComponent::midi_sender_
private

Referenced by RescanClicked().

◆ profile_

◆ profile_manager_

ProfileManager& MainContentComponent::profile_manager_
private

Referenced by Init().

◆ profile_name_label_

juce::Label MainContentComponent::profile_name_label_ {"ProfileNameLabel", ""}
private
76{"ProfileNameLabel", ""};

◆ remove_allrows_button_

juce::TextButton MainContentComponent::remove_allrows_button_ {juce::translate("Clear ALL rows")}
private
89{juce::translate("Clear ALL rows")};

◆ remove_unassigned_button_

juce::TextButton MainContentComponent::remove_unassigned_button_ {juce::translate("Remove unassigned rows")}
private
90{juce::translate("Remove unassigned rows")};

◆ rescan_button_

juce::TextButton MainContentComponent::rescan_button_ {juce::translate("Rescan MIDI devices")}
private
91{juce::translate("Rescan MIDI devices")};

◆ row_to_select_

size_t MainContentComponent::row_to_select_ {0}
private
100{0};

Referenced by MidiCmdCallback().

◆ save_button_

juce::TextButton MainContentComponent::save_button_ {juce::translate("Save")}
private
92{juce::translate("Save")};

◆ settings_button_

juce::TextButton MainContentComponent::settings_button_ {juce::translate("Settings")}
private
93{juce::translate("Settings")};

◆ settings_dialog_

std::unique_ptr<juce::DialogWindow> MainContentComponent::settings_dialog_
private

◆ settings_manager_

SettingsManager& MainContentComponent::settings_manager_
private

Referenced by Init(), LoadClicked(), and SettingsClicked().

◆ title_label_

juce::Label MainContentComponent::title_label_ {"Title", "MIDI2LR"}
private
77{"Title", "MIDI2LR"};

◆ title_shadow_

juce::DropShadowEffect MainContentComponent::title_shadow_
private

◆ version_label_

juce::Label MainContentComponent::version_label_
private
Initial value:
{"Version", juce::translate("Version ") + juce::String {
ProjectInfo::versionString
}}
79 {"Version", juce::translate("Version ") + juce::String {
80 ProjectInfo::versionString
81 }};

The documentation for this class was generated from the following files:
  • C:/Users/rsjaf/source/repos/MIDI2LR/src/application/MainComponent.h
  • C:/Users/rsjaf/source/repos/MIDI2LR/src/application/MainComponent.cpp