From b49b196bf666c210eb372b044867a0f70b340749 Mon Sep 17 00:00:00 2001 From: hsstraub Date: Sun, 16 May 2021 19:05:02 +0200 Subject: [PATCH 001/183] Undo edit operations one by one --- Source/Main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Main.cpp b/Source/Main.cpp index 1d4f628f..fa8dd6b0 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -504,6 +504,7 @@ bool TerpstraSysExApplication::pasteSubBoardData() bool TerpstraSysExApplication::performUndoableAction(UndoableAction* editAction) { + undoManager.beginNewTransaction(); if (undoManager.perform(editAction)) // UndoManager will check for nullptr and also for disposing of the object { setHasChangesToSave(true); From 699076fb00a0a8b24813bb6b12d22759a1b90fb7 Mon Sep 17 00:00:00 2001 From: hsstraub Date: Sun, 16 May 2021 22:21:35 +0200 Subject: [PATCH 002/183] Undo section edits (paste, delete) --- Source/EditActions.cpp | 69 +++++++++++++++++++++++-- Source/EditActions.h | 28 +++++++++- Source/Main.cpp | 68 ++++++++++++------------ Source/MainComponent.cpp | 39 ++++---------- Source/MainComponent.h | 4 +- Source/NoteOnOffVelocityCurveDialog.cpp | 29 ----------- Source/NoteOnOffVelocityCurveDialog.h | 6 --- Source/TerpstraMidiDriver.h | 4 +- 8 files changed, 142 insertions(+), 105 deletions(-) diff --git a/Source/EditActions.cpp b/Source/EditActions.cpp index 589197e9..f0965e58 100644 --- a/Source/EditActions.cpp +++ b/Source/EditActions.cpp @@ -13,6 +13,8 @@ namespace Lumatone { + // ============================================================================== + // Implementation of SingleNoteAssignAction SingleNoteAssignAction::SingleNoteAssignAction( int setSelection, int keySelection, @@ -122,7 +124,7 @@ namespace Lumatone { keySelection, mappingInEdit.sets[setSelection].theKeys[keySelection]); - // Notfy that there are changes: in calling function + // Notify that there are changes: in calling function } else { @@ -139,9 +141,70 @@ namespace Lumatone { } } - int SingleNoteAssignAction::getSizeInUnits() + + // ============================================================================== + // Implementation of SectionEditAction + + SectionEditAction::SectionEditAction(int setSelection, TerpstraKeys& newSectionValue) + : setSelection(setSelection) + , newData(newSectionValue) + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + + previousData = mainComponent->getMappingInEdit().sets[setSelection]; + } + + bool SectionEditAction::isValid() const + { + return setSelection >= 0 && setSelection < NUMBEROFBOARDS; + } + + bool SectionEditAction::perform() + { + if (setSelection >= 0 && setSelection < NUMBEROFBOARDS) + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.sets[setSelection] = newData; + + // Send to device + TerpstraSysExApplication::getApp().getMidiDriver().sendAllParamsOfBoard(setSelection + 1, mappingInEdit.sets[setSelection]); + + // Notify that there are changes: in calling function + return true; + } + else + { + jassertfalse; + return false; + } + } + + bool SectionEditAction::undo() { - return 2 * sizeof(int) + 6 * sizeof(bool) + 2 * sizeof(TerpstraKey); + if (setSelection >= 0 && setSelection < NUMBEROFBOARDS) + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.sets[setSelection] = previousData; + + // Send to device + TerpstraSysExApplication::getApp().getMidiDriver().sendAllParamsOfBoard(setSelection + 1, mappingInEdit.sets[setSelection]); + + // Notify that there are changes: in calling function + return true; + } + else + { + jassertfalse; + return false; + } + } } \ No newline at end of file diff --git a/Source/EditActions.h b/Source/EditActions.h index 7b300f2a..fec77776 100644 --- a/Source/EditActions.h +++ b/Source/EditActions.h @@ -30,7 +30,7 @@ namespace Lumatone { int newNoteNumber = 0, TerpstraKey::COLOURTYPE newColour = juce::Colour()); - SingleNoteAssignAction(SingleNoteAssignAction& second) + SingleNoteAssignAction(const SingleNoteAssignAction& second) : setSelection(second.setSelection) , keySelection(second.keySelection) , setKeyType(second.setKeyType) @@ -45,7 +45,7 @@ namespace Lumatone { virtual bool perform() override; virtual bool undo() override; - int getSizeInUnits() override; + int getSizeInUnits() override { return sizeof(SingleNoteAssignAction); } private: int setSelection = - 1; @@ -60,4 +60,28 @@ namespace Lumatone { TerpstraKey newData; }; + class SectionEditAction : public UndoableAction + { + public: + SectionEditAction(int setSelection, TerpstraKeys& newSectionValue); + + SectionEditAction(const SectionEditAction& second) + : setSelection(second.setSelection) + , previousData(second.previousData) + , newData(second.newData) + {} + + bool isValid() const; + + virtual bool perform() override; + virtual bool undo() override; + int getSizeInUnits() override { return sizeof(SectionEditAction); } + + private: + int setSelection = -1; + + TerpstraKeys previousData; + TerpstraKeys newData; + }; + } \ No newline at end of file diff --git a/Source/Main.cpp b/Source/Main.cpp index fa8dd6b0..f0073fbb 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -84,7 +84,7 @@ TerpstraSysExApplication::TerpstraSysExApplication() userDocumentsDirectory = File::getSpecialLocation(File::userDocumentsDirectory).getChildFile("Lumatone Editor"); userDocumentsDirectory.createDirectory(); } - + possibleDirectory = propertiesFile->getValue("UserMappingsDirectory"); if (File::isAbsolutePath(possibleDirectory)) { @@ -95,7 +95,7 @@ TerpstraSysExApplication::TerpstraSysExApplication() userMappingsDirectory = userDocumentsDirectory.getChildFile("Mappings"); userMappingsDirectory.createDirectory(); } - + possibleDirectory = propertiesFile->getValue("UserPalettesDirectory"); if (File::isAbsolutePath(possibleDirectory)) { @@ -144,10 +144,10 @@ void TerpstraSysExApplication::initialise(const String& commandLine) // ToDo switch on/off isomorphic mass assign mode // Try to open a config file - if (File::isAbsolutePath(commandLineParameter)) - { - currentFile = File(commandLineParameter); - } + if (File::isAbsolutePath(commandLineParameter)) + { + currentFile = File(commandLineParameter); + } else { // If file name is with quotes, try removing the quotes @@ -176,12 +176,12 @@ void TerpstraSysExApplication::initialise(const String& commandLine) void TerpstraSysExApplication::shutdown() { - // Add your application's shutdown code here.. + // Add your application's shutdown code here.. // Save documents directories (Future: provide option to change them and save after changed by user) propertiesFile->setValue("UserDocumentsDirectory", userDocumentsDirectory.getFullPathName()); - propertiesFile->setValue("UserMappingsDirectory", userMappingsDirectory.getFullPathName()); - propertiesFile->setValue("UserPalettesDirectory", userPalettesDirectory.getFullPathName()); + propertiesFile->setValue("UserMappingsDirectory", userMappingsDirectory.getFullPathName()); + propertiesFile->setValue("UserPalettesDirectory", userPalettesDirectory.getFullPathName()); // Save recent files list recentFiles.removeNonExistentFiles(); @@ -197,16 +197,16 @@ void TerpstraSysExApplication::shutdown() LocalisedStrings::setCurrentMappings(nullptr); - mainWindow = nullptr; // (deletes our window) + mainWindow = nullptr; // (deletes our window) //commandManager = nullptr; - deviceMonitor = nullptr; + deviceMonitor = nullptr; } //============================================================================== void TerpstraSysExApplication::systemRequestedQuit() { - // This is called when the app is being asked to quit: you can ignore this - // request and let the app carry on running, or call quit() to allow the app to close. + // This is called when the app is being asked to quit: you can ignore this + // request and let the app carry on running, or call quit() to allow the app to close. // If there are changes: ask for save if (hasChangesToSave) @@ -231,9 +231,9 @@ void TerpstraSysExApplication::systemRequestedQuit() void TerpstraSysExApplication::anotherInstanceStarted(const String& commandLine) { - // When another instance of the app is launched while this one is running, - // this method is invoked, and the commandLine parameter tells you what - // the other instance's command-line arguments were. + // When another instance of the app is launched while this one is running, + // this method is invoked, and the commandLine parameter tells you what + // the other instance's command-line arguments were. } void TerpstraSysExApplication::reloadColourPalettes() @@ -278,8 +278,8 @@ bool TerpstraSysExApplication::saveColourPalette(LumatoneEditorColourPalette& pa } } - success = palette.saveToFile(pathToFile); - + success = palette.saveToFile(pathToFile); + // TODO error handling? } @@ -453,7 +453,7 @@ bool TerpstraSysExApplication::saveSysExMappingAs() if (chooser.browseForFileToSave(true)) { currentFile = chooser.getResult(); - if (saveCurrentFile() ) + if (saveCurrentFile()) { // Window title updateMainTitle(); @@ -487,8 +487,7 @@ bool TerpstraSysExApplication::resetSysExMapping() bool TerpstraSysExApplication::deleteSubBoardData() { - return ((MainContentComponent*)(mainWindow->getContentComponent()))->deleteCurrentSubBoardData(); - // ToDo Add to undo history + return performUndoableAction(((MainContentComponent*)(mainWindow->getContentComponent()))->createDeleteCurrentSectionAction()); } bool TerpstraSysExApplication::copySubBoardData() @@ -498,20 +497,23 @@ bool TerpstraSysExApplication::copySubBoardData() bool TerpstraSysExApplication::pasteSubBoardData() { - return ((MainContentComponent*)(mainWindow->getContentComponent()))->pasteCurrentSubBoardData(); - // ToDo Add to undo history + return performUndoableAction(((MainContentComponent*)(mainWindow->getContentComponent()))->createPasteCurrentSectionAction());; } bool TerpstraSysExApplication::performUndoableAction(UndoableAction* editAction) { - undoManager.beginNewTransaction(); - if (undoManager.perform(editAction)) // UndoManager will check for nullptr and also for disposing of the object + if (editAction != nullptr) { - setHasChangesToSave(true); - ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshKeyDataFields(); + undoManager.beginNewTransaction(); + if (undoManager.perform(editAction)) // UndoManager will check for nullptr and also for disposing of the object + { + setHasChangesToSave(true); + ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshKeyDataFields(); + return true; + } } - else - return false; + + return false; } bool TerpstraSysExApplication::undo() @@ -712,7 +714,7 @@ bool TerpstraSysExApplication::saveCurrentFile() void TerpstraSysExApplication::sendCurrentConfigurationToDevice() { auto theConfig = ((MainContentComponent*)(mainWindow->getContentComponent()))->getMappingInEdit(); - + // MIDI channel, MIDI note, colour and key type config for all keys getMidiDriver().sendCompleteMapping(theConfig); @@ -772,7 +774,7 @@ void TerpstraSysExApplication::requestConfigurationFromDevice() void TerpstraSysExApplication::updateMainTitle() { String windowTitle("Lumatone Editor"); - if (!currentFile.getFileName().isEmpty() ) + if (!currentFile.getFileName().isEmpty()) windowTitle << " - " << currentFile.getFileName(); if (hasChangesToSave) windowTitle << "*"; @@ -803,7 +805,7 @@ bool TerpstraSysExApplication::aboutTerpstraSysEx() << "Based on the program 'TerpstraSysEx' @ Dylan Horvath 2007" << newLine << newLine << "For help on using this program, or any questions relating to the Lumatone keyboard, go to" << newLine - << newLine + << newLine << "http://lumatone.io" << newLine << newLine << "or" << newLine @@ -837,4 +839,4 @@ bool TerpstraSysExApplication::aboutTerpstraSysEx() //============================================================================== // This macro generates the main() routine that launches the app. -START_JUCE_APPLICATION (TerpstraSysExApplication) +START_JUCE_APPLICATION(TerpstraSysExApplication) diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 831e4709..2eeb9e75 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -11,6 +11,7 @@ #include "MainComponent.h" #include "ViewConstants.h" #include "Main.h" +#include "EditActions.h" //============================================================================== @@ -129,24 +130,15 @@ void MainContentComponent::getData(TerpstraKeyMapping& newData) newData = mappingData; } -bool MainContentComponent::deleteCurrentSubBoardData() +UndoableAction* MainContentComponent::createDeleteCurrentSectionAction() { auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); if (currentSetSelection >= 0 && currentSetSelection < TerpstraSysExApplication::getApp().getOctaveBoardSize()) - { - // Delete subboard data - mappingData.sets[currentSetSelection] = TerpstraKeys(); - - // Refresh display - refreshKeyDataFields(); - - // Mark that there are changes - TerpstraSysExApplication::getApp().setHasChangesToSave(true); - - return true; + { + return new Lumatone::SectionEditAction(currentSetSelection, TerpstraKeys()); } else - return false; + return nullptr; } bool MainContentComponent::copyCurrentSubBoardData() @@ -161,25 +153,16 @@ bool MainContentComponent::copyCurrentSubBoardData() return false; } -bool MainContentComponent::pasteCurrentSubBoardData() +UndoableAction* MainContentComponent::createPasteCurrentSectionAction() { auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); - if (currentSetSelection >= 0 && currentSetSelection < TerpstraSysExApplication::getApp().getOctaveBoardSize()) - { - if (!copiedSubBoardData.isEmpty()) - { - mappingData.sets[currentSetSelection] = copiedSubBoardData; - - // Refresh display - refreshKeyDataFields(); - - // Mark that there are changes - TerpstraSysExApplication::getApp().setHasChangesToSave(true); - } - return true; + if (currentSetSelection >= 0 && currentSetSelection < TerpstraSysExApplication::getApp().getOctaveBoardSize() + && !copiedSubBoardData.isEmpty()) + { + return new Lumatone::SectionEditAction(currentSetSelection, copiedSubBoardData); } else - return false; + return nullptr; } bool MainContentComponent::setDeveloperMode(bool developerModeOn) diff --git a/Source/MainComponent.h b/Source/MainComponent.h index 9d65f08c..6aaa8331 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -56,9 +56,9 @@ class MainContentComponent : public Component, CurvesArea* getCurvesArea() { return curvesArea.get(); } // Board edit operations - bool deleteCurrentSubBoardData(); + UndoableAction* createDeleteCurrentSectionAction(); bool copyCurrentSubBoardData(); - bool pasteCurrentSubBoardData(); + UndoableAction* createPasteCurrentSectionAction(); bool setDeveloperMode(bool developerModeOn); diff --git a/Source/NoteOnOffVelocityCurveDialog.cpp b/Source/NoteOnOffVelocityCurveDialog.cpp index 28e2857d..ad361dee 100644 --- a/Source/NoteOnOffVelocityCurveDialog.cpp +++ b/Source/NoteOnOffVelocityCurveDialog.cpp @@ -17,32 +17,3 @@ NoteOnOffVelocityCurveDialog::NoteOnOffVelocityCurveDialog() : VelocityCurveDlgBase(TerpstraVelocityCurveConfig::VelocityCurveType::noteOnNoteOff) { } - -//NoteOnOffVelocityCurveDialog::~NoteOnOffVelocityCurveDialog() -//{ -//} - -//float NoteOnOffVelocityCurveDialog::beamWidth(int xPos) -//{ -// auto mappingInEdit = getMappingInEdit(); -// if ( mappingInEdit == nullptr) // Security at start of program -// return 1; // ad-hoc -// -// if (xPos == 0) -// { -// return (getWidth() - 2.0f * cbEditMode->getX()) * mappingInEdit->velocityIntervalTableValues[0] / 2048.0f; -// } -// else if (xPos < VELOCITYINTERVALTABLESIZE) -// { -// return (getWidth() - 2.0f * cbEditMode->getX()) * (mappingInEdit->velocityIntervalTableValues[xPos] - mappingInEdit->velocityIntervalTableValues[xPos-1]) / 2048.0f; -// } -// else if (xPos == VELOCITYINTERVALTABLESIZE) -// { -// return (getWidth() - 2.0f * cbEditMode->getX()) * (2048.0f - mappingInEdit->velocityIntervalTableValues[xPos-1]) / 2048.0f; -// } -// else -// { -// jassertfalse; -// return 1; -// } -//} \ No newline at end of file diff --git a/Source/NoteOnOffVelocityCurveDialog.h b/Source/NoteOnOffVelocityCurveDialog.h index cfa7a2b0..47e5292b 100644 --- a/Source/NoteOnOffVelocityCurveDialog.h +++ b/Source/NoteOnOffVelocityCurveDialog.h @@ -15,13 +15,7 @@ // Note on/on velocity curve dialog. Horizontal axis stands for ticks class NoteOnOffVelocityCurveDialog : public VelocityCurveDlgBase { public: - //============================================================================== NoteOnOffVelocityCurveDialog(); - //~NoteOnOffVelocityCurveDialog() override; - - //protected: - // virtual float beamWidth(int xPos) override; - }; class FaderVelocityCurveDialog : public VelocityCurveDlgBase { diff --git a/Source/TerpstraMidiDriver.h b/Source/TerpstraMidiDriver.h index f3ab8024..6de958e9 100644 --- a/Source/TerpstraMidiDriver.h +++ b/Source/TerpstraMidiDriver.h @@ -162,7 +162,7 @@ class TerpstraMidiDriver : public HajuMidiDriver, public MidiInputCallback, publ ////////////////////////////////// // Combined (hi-level) commands - // Send all parametrizations of one sub board + // Send all parametrizations of one section. Attention: section index is 1-based! void sendAllParamsOfBoard(int boardIndex, TerpstraKeys boardData); // Send and save a complete key mapping @@ -177,7 +177,7 @@ class TerpstraMidiDriver : public HajuMidiDriver, public MidiInputCallback, publ ////////////////////////////////// // Single (mid-level) commands - // Send parametrization of one key to the device + // Send parametrization of one key to the device. Attention: section index is 1-based! void sendKeyParam(int boardIndex, int keyIndex, TerpstraKey keyData); // Send expression pedal sensivity From 0f5ad351981ef1b89fe96b982500739ef29f5b92 Mon Sep 17 00:00:00 2001 From: hsstraub Date: Sun, 16 May 2021 22:32:48 +0200 Subject: [PATCH 003/183] Removed http://terpstrakeyboard.com from about box --- Source/Main.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Source/Main.cpp b/Source/Main.cpp index e66a0f57..ac0ca28c 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -729,13 +729,9 @@ bool TerpstraSysExApplication::aboutTerpstraSysEx() << newLine << "Based on the program 'TerpstraSysEx' @ Dylan Horvath 2007" << newLine << newLine - << "For help on using this program, or any questions relating to the Lumatone keyboard, go to" << newLine + << "For help on using this program, or any questions relating to the Lumatone keyboard, go to:" << newLine << newLine - << "http://lumatone.io" << newLine - << newLine - << "or" << newLine - << newLine - << "http://terpstrakeyboard.com"; + << "http://lumatone.io"; DialogWindow::LaunchOptions options; Label* label = new Label(); From b3167abb3a4f255886785c723a6d052b1a309b87 Mon Sep 17 00:00:00 2001 From: hsstraub Date: Tue, 18 May 2021 23:15:46 +0200 Subject: [PATCH 004/183] InvertFootControllerEditAction --- Source/EditActions.cpp | 42 ++++++++++++++++++++++++++++++++++ Source/EditActions.h | 17 ++++++++++++++ Source/Main.cpp | 10 +++++--- Source/MainComponent.cpp | 16 +++++++++---- Source/MainComponent.h | 1 + Source/PedalSensitivityDlg.cpp | 33 ++------------------------ 6 files changed, 80 insertions(+), 39 deletions(-) diff --git a/Source/EditActions.cpp b/Source/EditActions.cpp index f0965e58..59044809 100644 --- a/Source/EditActions.cpp +++ b/Source/EditActions.cpp @@ -207,4 +207,46 @@ namespace Lumatone { } + // ============================================================================== + // Implementation of SectionEditAction + + InvertFootControllerEditAction::InvertFootControllerEditAction(bool newValue) + : newData(newValue) + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + + previousData = mainComponent->getMappingInEdit().invertFootController; + } + + bool InvertFootControllerEditAction::perform() + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.invertFootController = newData; + + // Send to device + TerpstraSysExApplication::getApp().getMidiDriver().sendInvertFootController(newData); + + // Notify that there are changes: in calling function + return true; + } + + bool InvertFootControllerEditAction::undo() + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.invertFootController = previousData; + + // Send to device + TerpstraSysExApplication::getApp().getMidiDriver().sendInvertFootController(newData); + + // Notify that there are changes: in calling function + return true; + } + } \ No newline at end of file diff --git a/Source/EditActions.h b/Source/EditActions.h index fec77776..6f50a4c2 100644 --- a/Source/EditActions.h +++ b/Source/EditActions.h @@ -84,4 +84,21 @@ namespace Lumatone { TerpstraKeys newData; }; + class InvertFootControllerEditAction : public UndoableAction + { + public: + InvertFootControllerEditAction(bool newValue); + + InvertFootControllerEditAction(const InvertFootControllerEditAction& second) + : previousData(second.previousData), newData(second.newData) + {} + + virtual bool perform() override; + virtual bool undo() override; + int getSizeInUnits() override { return sizeof(InvertFootControllerEditAction); } + + private: + bool previousData; + bool newData;; + }; } \ No newline at end of file diff --git a/Source/Main.cpp b/Source/Main.cpp index aeb4875a..75b7ee0f 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -505,7 +505,11 @@ bool TerpstraSysExApplication::performUndoableAction(UndoableAction* editAction) if (undoManager.perform(editAction)) // UndoManager will check for nullptr and also for disposing of the object { setHasChangesToSave(true); - ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshKeyDataFields(); + ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshAllFields(); + generalOptionsArea->loadFromMapping(); + pedalSensitivityDlg->loadFromMapping(); + curvesArea->loadFromMapping(); + curvesArea->repaint(); return true; } } @@ -518,7 +522,7 @@ bool TerpstraSysExApplication::undo() if (undoManager.undo()) { setHasChangesToSave(true); - ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshKeyDataFields(); + ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshAllFields(); return true; } else @@ -530,7 +534,7 @@ bool TerpstraSysExApplication::redo() if (undoManager.redo()) { setHasChangesToSave(true); - ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshKeyDataFields(); + ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshAllFields(); return true; } else diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 2eeb9e75..c76da10c 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -110,11 +110,7 @@ void MainContentComponent::setData(TerpstraKeyMapping& newData, bool withRefresh if (withRefresh) { - refreshKeyDataFields(); - generalOptionsArea->loadFromMapping(); - pedalSensitivityDlg->loadFromMapping(); - curvesArea->loadFromMapping(); - curvesArea->repaint(); + refreshAllFields(); } } @@ -401,3 +397,13 @@ void MainContentComponent::refreshKeyDataFields() allKeysOverview->repaint(); noteEditArea->refreshKeyFields(); } + +void MainContentComponent::refreshAllFields() +{ + refreshKeyDataFields(); + generalOptionsArea->loadFromMapping(); + pedalSensitivityDlg->loadFromMapping(); + curvesArea->loadFromMapping(); + curvesArea->repaint(); +} + diff --git a/Source/MainComponent.h b/Source/MainComponent.h index 6aaa8331..e428f945 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -79,6 +79,7 @@ class MainContentComponent : public Component, void resized(); void refreshKeyDataFields(); + void refreshAllFields(); private: //============================================================================== diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index 7d42f33a..71b71a08 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -19,6 +19,7 @@ //[Headers] You can add your own extra header files here... #include "Main.h" +#include "EditActions.h" //[/Headers] #include "PedalSensitivityDlg.h" @@ -131,9 +132,7 @@ void PedalSensitivityDlg::buttonClicked (juce::Button* buttonThatWasClicked) if (buttonThatWasClicked == btnInvertFootCtrl.get()) { //[UserButtonCode_btnInvertFootCtrl] -- add your button handler code here.. - ((MainContentComponent*)getParentComponent())->getMappingInEdit().invertFootController = btnInvertFootCtrl->getToggleState(); - TerpstraSysExApplication::getApp().setHasChangesToSave(true); - TerpstraSysExApplication::getApp().getMidiDriver().sendInvertFootController(btnInvertFootCtrl->getToggleState()); + TerpstraSysExApplication::getApp().performUndoableAction(new Lumatone::InvertFootControllerEditAction(btnInvertFootCtrl->getToggleState())); //[/UserButtonCode_btnInvertFootCtrl] } @@ -177,34 +176,6 @@ void PedalSensitivityDlg::sliderValueChanged (juce::Slider* sliderThatWasMoved) //[MiscUserCode] You can add your own definitions of your custom methods or any other code here... - -//void PedalSensitivityDlg::textEditorTextChanged(TextEditor& textEdit) -//{ -//} -// -//void PedalSensitivityDlg::textEditorFocusLost(TextEditor& textEdit) -//{ -// if (&textEdit == txtExprCtrlSensivity.get()) -// { -// int newSensitvity = textEdit.getText().getIntValue(); -// if (newSensitvity < 0) -// { -// newSensitvity = 0; -// textEdit.setText(String(newSensitvity)); -// } -// -// if (newSensitvity > 0x7f) -// { -// newSensitvity = 0x7f; -// textEdit.setText(String(newSensitvity)); -// } -// -// ((MainContentComponent*)getParentComponent())->getMappingInEdit().expressionControllerSensivity = newSensitvity; -// TerpstraSysExApplication::getApp().setHasChangesToSave(true); -// TerpstraSysExApplication::getApp().getMidiDriver().sendExpressionPedalSensivity(newSensitvity); -// } -//} - void PedalSensitivityDlg::lookAndFeelChanged() { auto newLookAndFeel = dynamic_cast(&getLookAndFeel()); From 7c4b3e75fdc5a971083a580ab5afefa042656807 Mon Sep 17 00:00:00 2001 From: hsstraub Date: Thu, 20 May 2021 13:28:14 +0200 Subject: [PATCH 005/183] ExprPedalSensivityEditAction --- Source/EditActions.cpp | 46 ++++++++++++++++++++++++++++++++-- Source/EditActions.h | 21 +++++++++++++++- Source/Main.cpp | 4 --- Source/PedalSensitivityDlg.cpp | 4 +-- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/Source/EditActions.cpp b/Source/EditActions.cpp index 59044809..f98b0caa 100644 --- a/Source/EditActions.cpp +++ b/Source/EditActions.cpp @@ -208,7 +208,7 @@ namespace Lumatone { } // ============================================================================== - // Implementation of SectionEditAction + // Implementation of InvertFootControllerEditAction InvertFootControllerEditAction::InvertFootControllerEditAction(bool newValue) : newData(newValue) @@ -243,7 +243,49 @@ namespace Lumatone { mappingInEdit.invertFootController = previousData; // Send to device - TerpstraSysExApplication::getApp().getMidiDriver().sendInvertFootController(newData); + TerpstraSysExApplication::getApp().getMidiDriver().sendInvertFootController(previousData); + + // Notify that there are changes: in calling function + return true; + } + + // ============================================================================== + // Implementation of ExprPedalSensivityEditAction + + ExprPedalSensivityEditAction::ExprPedalSensivityEditAction(int newValue) + : newData(newValue) + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + + previousData = mainComponent->getMappingInEdit().expressionControllerSensivity; + } + + bool ExprPedalSensivityEditAction::perform() + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.expressionControllerSensivity = newData; + + // Send to device + TerpstraSysExApplication::getApp().getMidiDriver().sendExpressionPedalSensivity(newData); + + // Notify that there are changes: in calling function + return true; + } + + bool ExprPedalSensivityEditAction::undo() + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.expressionControllerSensivity = previousData; + + // Send to device + TerpstraSysExApplication::getApp().getMidiDriver().sendExpressionPedalSensivity(previousData); // Notify that there are changes: in calling function return true; diff --git a/Source/EditActions.h b/Source/EditActions.h index 6f50a4c2..ed2d5b07 100644 --- a/Source/EditActions.h +++ b/Source/EditActions.h @@ -99,6 +99,25 @@ namespace Lumatone { private: bool previousData; - bool newData;; + bool newData; }; + + class ExprPedalSensivityEditAction : public UndoableAction + { + public: + ExprPedalSensivityEditAction(int newValue); + + ExprPedalSensivityEditAction(const ExprPedalSensivityEditAction& second) + : previousData(second.previousData), newData(second.newData) + {} + + virtual bool perform() override; + virtual bool undo() override; + int getSizeInUnits() override { return sizeof(ExprPedalSensivityEditAction); } + + private: + int previousData; + int newData;; + }; + } \ No newline at end of file diff --git a/Source/Main.cpp b/Source/Main.cpp index 75b7ee0f..afd6d83c 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -506,10 +506,6 @@ bool TerpstraSysExApplication::performUndoableAction(UndoableAction* editAction) { setHasChangesToSave(true); ((MainContentComponent*)(mainWindow->getContentComponent()))->refreshAllFields(); - generalOptionsArea->loadFromMapping(); - pedalSensitivityDlg->loadFromMapping(); - curvesArea->loadFromMapping(); - curvesArea->repaint(); return true; } } diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index 71b71a08..d2a70c2f 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -162,9 +162,7 @@ void PedalSensitivityDlg::sliderValueChanged (juce::Slider* sliderThatWasMoved) sldExprCtrlSensivity->setValue(newSensitvity); } - ((MainContentComponent*)getParentComponent())->getMappingInEdit().expressionControllerSensivity = newSensitvity; - TerpstraSysExApplication::getApp().setHasChangesToSave(true); - TerpstraSysExApplication::getApp().getMidiDriver().sendExpressionPedalSensivity(newSensitvity); + TerpstraSysExApplication::getApp().performUndoableAction(new Lumatone::ExprPedalSensivityEditAction(newSensitvity)); //[/UserSliderCode_sldExprCtrlSensivity] } From 2a6df58f8686a27f9bea151c7b7ed17b7762a413 Mon Sep 17 00:00:00 2001 From: hsstraub Date: Fri, 21 May 2021 18:43:10 +0200 Subject: [PATCH 006/183] Velocity curve obsolete stuff removed --- Source/KeyboardDataStructure.cpp | 19 +++++++ Source/KeyboardDataStructure.h | 1 + Source/VelocityCurveDlgBase.cpp | 81 +++++++++++----------------- Source/VelocityCurveDlgBase.h | 7 +-- Source/VelocityCurveEditStrategy.cpp | 20 +++---- Source/VelocityCurveEditStrategy.h | 12 ++--- 6 files changed, 70 insertions(+), 70 deletions(-) diff --git a/Source/KeyboardDataStructure.cpp b/Source/KeyboardDataStructure.cpp index 7c88c783..781f4e12 100644 --- a/Source/KeyboardDataStructure.cpp +++ b/Source/KeyboardDataStructure.cpp @@ -458,3 +458,22 @@ StringArray TerpstraKeyMapping::toStringArray() // // return result; //} + +TerpstraVelocityCurveConfig* TerpstraKeyMapping::getVelocityCurveConfig(TerpstraVelocityCurveConfig::VelocityCurveType velocityCurveType) +{ + switch (velocityCurveType) + { + case TerpstraVelocityCurveConfig::VelocityCurveType::noteOnNoteOff: + return ¬eOnOffVelocityCurveConfig; + + case TerpstraVelocityCurveConfig::VelocityCurveType::fader: + return &faderConfig; + case TerpstraVelocityCurveConfig::VelocityCurveType::afterTouch: + return &afterTouchConfig; + case TerpstraVelocityCurveConfig::VelocityCurveType::lumaTouch: + return &lumaTouchConfig; + default: + jassertfalse; + return nullptr; + } +} \ No newline at end of file diff --git a/Source/KeyboardDataStructure.h b/Source/KeyboardDataStructure.h index 3216463d..26c93d80 100644 --- a/Source/KeyboardDataStructure.h +++ b/Source/KeyboardDataStructure.h @@ -118,6 +118,7 @@ class TerpstraKeyMapping // The colours that are used //SortedSet getUsedColours(); + TerpstraVelocityCurveConfig* getVelocityCurveConfig(TerpstraVelocityCurveConfig::VelocityCurveType velocityCurveType); public: // Key configuration diff --git a/Source/VelocityCurveDlgBase.cpp b/Source/VelocityCurveDlgBase.cpp index a08caa84..5261ea82 100644 --- a/Source/VelocityCurveDlgBase.cpp +++ b/Source/VelocityCurveDlgBase.cpp @@ -7,7 +7,7 @@ the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded and re-saved. - Created with Projucer version: 6.0.5 + Created with Projucer version: 6.0.7 ------------------------------------------------------------------------------ @@ -29,9 +29,9 @@ //============================================================================== VelocityCurveDlgBase::VelocityCurveDlgBase (TerpstraVelocityCurveConfig::VelocityCurveType typeValue) - : freeDrawingStrategy(beamTableFrame, velocityBeamTable), - linearDrawingStrategy(beamTableFrame, velocityBeamTable), - quadraticDrawingStrategy(beamTableFrame, velocityBeamTable) + : freeDrawingStrategy(velocityBeamTable), + linearDrawingStrategy(velocityBeamTable), + quadraticDrawingStrategy(velocityBeamTable) { //[Constructor_pre] You can add your own custom stuff here.. velocityCurveType = typeValue; @@ -50,6 +50,7 @@ VelocityCurveDlgBase::VelocityCurveDlgBase (TerpstraVelocityCurveConfig::Velocit cbEditMode->setBounds (8, 8, 296, 24); + //[UserPreSize] cbEditMode->getProperties().set(LumatoneEditorStyleIDs::roundedDiagonalCorners, 0); @@ -100,6 +101,8 @@ void VelocityCurveDlgBase::paint (juce::Graphics& g) //[UserPrePaint] Add your own custom painting code here.. //[/UserPrePaint] + g.fillAll (juce::Colour (0xffbad0de)); + //[UserPaint] Add your own custom painting code here.. g.fillAll(backgroundColour); @@ -108,10 +111,10 @@ void VelocityCurveDlgBase::paint (juce::Graphics& g) // Build contour path beamTableContour.clear(); beamTableContour.startNewSubPath(0, h); - + for (int x = 0; x < 128; x++) beamTableContour.lineTo(velocityBeamTable[x]->getX(), h - velocityBeamTable[x]->getBeamHeightFromValue()); - + beamTableContour.lineTo(getWidth(), h); beamTableContour.closeSubPath(); @@ -119,9 +122,6 @@ void VelocityCurveDlgBase::paint (juce::Graphics& g) g.setGradientFill(beamColourGradient); g.fillPath(beamTableContour); - //g.setColour(findColour(VelocityCurveBeam::outlineColourId)); - //g.strokePath(beamTableFrame, PathStrokeType(1.000f)); - auto currentDrawingStrategy = getCurrentDrawingStrategy(); if (currentDrawingStrategy != nullptr) { @@ -152,24 +152,12 @@ void VelocityCurveDlgBase::resized() //[UserResized] Add your own custom resize handling here.. - //float graphicsXPadding = cbEditMode->getX(); - //float graphicsYPos = cbEditMode->getBottom() + BEAMTABLERIMABOVE; - //float graphicsBottom = h - BEAMTABLERIMABOVE; - - //beamTableFrame.clear(); - //beamTableFrame.startNewSubPath(graphicsXPadding, graphicsYPos); - //beamTableFrame.lineTo(graphicsXPadding, graphicsBottom); - //beamTableFrame.lineTo(w - graphicsXPadding, graphicsBottom); - //beamTableFrame.lineTo(w - graphicsXPadding, graphicsYPos); - //beamTableFrame.closeSubPath(); - cbEditMode->setBounds(0, 0, xUnit * 11, xUnit * 3); auto currentDrawingStrategy = getCurrentDrawingStrategy(); if (currentDrawingStrategy != nullptr) currentDrawingStrategy->resized(); - //float velocityGraphicsHeight = graphicsBottom - graphicsYPos; float velocityBeamXPos = 0; for (int x = 0; x < 128; x++) { @@ -230,27 +218,16 @@ void VelocityCurveDlgBase::comboBoxChanged (juce::ComboBox* comboBoxThatHasChang //[/UsercomboBoxChanged_Post] } - - -//[MiscUserCode] You can add your own definitions of your custom methods or any other code here... - -void VelocityCurveDlgBase::paintOverChildren(juce::Graphics& g) -{ - //int roundedCornerSize = getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT; - //Rectangle controlsBounds = getLocalBounds().toFloat().reduced(roundedCornerSize); - //g.setColour(Colour(0xff272b2f)); - //g.drawRoundedRectangle(controlsBounds, roundedCornerSize, 4.0f); -} - void VelocityCurveDlgBase::lookAndFeelChanged() { + //[UserCode_lookAndFeelChanged] -- Add your code here... auto lookAndFeel = dynamic_cast(&getLookAndFeel()); if (lookAndFeel) { beamColourGradient.clearColours(); beamColourGradient.addColour(0.0, lookAndFeel->findColour(LumatoneEditorColourIDs::CurveGradientMin)); beamColourGradient.addColour(1.0, lookAndFeel->findColour(LumatoneEditorColourIDs::CurveGradientMax)); - + backgroundColour = lookAndFeel->findColour(LumatoneEditorColourIDs::ControlBoxBackground); gridColour = lookAndFeel->findColour(LumatoneEditorColourIDs::CurveGridColour); @@ -287,6 +264,19 @@ void VelocityCurveDlgBase::loadFromMapping() for (int x = 0; x < 128; x++) velocityBeamTable[x]->setValue(x); } + //[/UserCode_lookAndFeelChanged] +} + + + +//[MiscUserCode] You can add your own definitions of your custom methods or any other code here... + +void VelocityCurveDlgBase::paintOverChildren(juce::Graphics& g) +{ + //int roundedCornerSize = getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT; + //Rectangle controlsBounds = getLocalBounds().toFloat().reduced(roundedCornerSize); + //g.setColour(Colour(0xff272b2f)); + //g.drawRoundedRectangle(controlsBounds, roundedCornerSize, 4.0f); } void VelocityCurveDlgBase::sendVelocityTableToController() @@ -378,21 +368,7 @@ TerpstraVelocityCurveConfig* VelocityCurveDlgBase::getConfigInEdit() if(mappingInEdit == nullptr) return nullptr; - switch(velocityCurveType) - { - case TerpstraVelocityCurveConfig::VelocityCurveType::noteOnNoteOff: - return &mappingInEdit->noteOnOffVelocityCurveConfig; - - case TerpstraVelocityCurveConfig::VelocityCurveType::fader: - return &mappingInEdit->faderConfig; - case TerpstraVelocityCurveConfig::VelocityCurveType::afterTouch: - return &mappingInEdit->afterTouchConfig; - case TerpstraVelocityCurveConfig::VelocityCurveType::lumaTouch: - return &mappingInEdit->lumaTouchConfig; - default: - jassertfalse; - return nullptr; - } + return mappingInEdit->getVelocityCurveConfig(velocityCurveType); } VelocityCurveEditStrategyBase* VelocityCurveDlgBase::getCurrentDrawingStrategy() @@ -421,10 +397,13 @@ VelocityCurveEditStrategyBase* VelocityCurveDlgBase::getCurrentDrawingStrategy() BEGIN_JUCER_METADATA + + + velocityBeamTable[128]; diff --git a/Source/VelocityCurveEditStrategy.cpp b/Source/VelocityCurveEditStrategy.cpp index 3b2bc3c2..0d28c9f3 100644 --- a/Source/VelocityCurveEditStrategy.cpp +++ b/Source/VelocityCurveEditStrategy.cpp @@ -17,9 +17,9 @@ VelocityCurveEditStrategyBase class */ VelocityCurveEditStrategyBase::VelocityCurveEditStrategyBase( - Path& beamTableFrameRef, + //Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr) - : beamTableFrame(beamTableFrameRef), velocityBeamTable(velocityBeamTablePtr) + : /*beamTableFrame(beamTableFrameRef), */velocityBeamTable(velocityBeamTablePtr) { } @@ -30,9 +30,9 @@ VelocityCurveFreeDrawingStrategy class */ VelocityCurveFreeDrawingStrategy::VelocityCurveFreeDrawingStrategy( - Path& beamTableFrameRef, + //Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr) - : VelocityCurveEditStrategyBase(beamTableFrameRef, velocityBeamTablePtr) + : VelocityCurveEditStrategyBase(/*beamTableFrameRef, */velocityBeamTablePtr) { } @@ -132,9 +132,9 @@ VelocityCurveSegmentEditStrategyBase class */ VelocityCurveSegmentEditStrategyBase::VelocityCurveSegmentEditStrategyBase( - Path& beamTableFrameRef, + //Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr) - : VelocityCurveEditStrategyBase(beamTableFrameRef, velocityBeamTablePtr) + : VelocityCurveEditStrategyBase(/*beamTableFrameRef, */velocityBeamTablePtr) , mouseXPosition(-1), draggedOriginalXPosition(-1) { fixPointBeamHeights[0] = 0; @@ -346,9 +346,9 @@ VelocityCurveLinearDrawingStrategy class */ VelocityCurveLinearDrawingStrategy::VelocityCurveLinearDrawingStrategy( - Path& beamTableFrameRef, + //Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr) - : VelocityCurveSegmentEditStrategyBase(beamTableFrameRef, velocityBeamTablePtr) + : VelocityCurveSegmentEditStrategyBase(/*beamTableFrameRef, */velocityBeamTablePtr) { } @@ -470,9 +470,9 @@ VelocityCurveQuadraticDrawingStrategy class */ VelocityCurveQuadraticDrawingStrategy::VelocityCurveQuadraticDrawingStrategy( - Path& beamTableFrameRef, + //Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr) - : VelocityCurveSegmentEditStrategyBase(beamTableFrameRef, velocityBeamTablePtr) + : VelocityCurveSegmentEditStrategyBase(/*beamTableFrameRef, */velocityBeamTablePtr) { } diff --git a/Source/VelocityCurveEditStrategy.h b/Source/VelocityCurveEditStrategy.h index a96171c1..32c19805 100644 --- a/Source/VelocityCurveEditStrategy.h +++ b/Source/VelocityCurveEditStrategy.h @@ -23,7 +23,7 @@ Base class for velocity curve editing class VelocityCurveEditStrategyBase { public: - VelocityCurveEditStrategyBase(Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr); + VelocityCurveEditStrategyBase(/*Path& beamTableFrameRef,*/ std::unique_ptr* velocityBeamTablePtr); // Set value table (e. g. from LMT file) virtual bool setEditConfig(int velocityTableValues[]) = 0; @@ -47,7 +47,7 @@ class VelocityCurveEditStrategyBase virtual void mouseUp(const MouseEvent &event, juce::Point localPoint) { }; protected: - Path& beamTableFrame; + //Path& beamTableFrame; std::unique_ptr* velocityBeamTable; }; @@ -59,7 +59,7 @@ Velocity curve editing via free drawing class VelocityCurveFreeDrawingStrategy : public VelocityCurveEditStrategyBase { public: - VelocityCurveFreeDrawingStrategy(Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr); + VelocityCurveFreeDrawingStrategy(/*Path& beamTableFrameRef,*/ std::unique_ptr* velocityBeamTablePtr); bool setEditConfig(int velocityTableValues[]) override; bool exportEditConfig(int velocityTableValues[]) override; @@ -83,7 +83,7 @@ Base class for velocity curve editing with segments class VelocityCurveSegmentEditStrategyBase : public VelocityCurveEditStrategyBase { public: - VelocityCurveSegmentEditStrategyBase(Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr); + VelocityCurveSegmentEditStrategyBase(/*Path& beamTableFrameRef, */std::unique_ptr* velocityBeamTablePtr); bool setEditConfig(int velocityTableValues[]) override; bool exportEditConfig(int velocityTableValues[]) override; @@ -123,7 +123,7 @@ Velocity curve editing via line segments class VelocityCurveLinearDrawingStrategy : public VelocityCurveSegmentEditStrategyBase { public: - VelocityCurveLinearDrawingStrategy(Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr); + VelocityCurveLinearDrawingStrategy(/*Path& beamTableFrameRef, */std::unique_ptr* velocityBeamTablePtr); bool setEditConfigFromVelocityTable() override; void setVelocityTableValuesFromEditConfig() override; @@ -145,7 +145,7 @@ Velocity curve editing via quadratic curves class VelocityCurveQuadraticDrawingStrategy : public VelocityCurveSegmentEditStrategyBase { public: - VelocityCurveQuadraticDrawingStrategy(Path& beamTableFrameRef, std::unique_ptr* velocityBeamTablePtr); + VelocityCurveQuadraticDrawingStrategy(/*Path& beamTableFrameRef,*/ std::unique_ptr* velocityBeamTablePtr); bool setEditConfigFromVelocityTable() override; void setVelocityTableValuesFromEditConfig() override; From 96e347c504da1f6dcbe8b90fdc7e06f964b497ef Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Mon, 14 Jun 2021 22:11:19 -0400 Subject: [PATCH 007/183] Tweaks & auto incr. note label fix --- Source/SingleNoteAssign.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/Source/SingleNoteAssign.cpp b/Source/SingleNoteAssign.cpp index d7794876..71868644 100644 --- a/Source/SingleNoteAssign.cpp +++ b/Source/SingleNoteAssign.cpp @@ -153,8 +153,7 @@ SingleNoteAssign::SingleNoteAssign () ccFaderFlipBtn->addListener(this); ccFaderFlipBtn->setTooltip(translate("Toggle CC polarity inversion. Default, arrow down: values increase with key press. Inverted, arrow up: values decrease with key press.")); addAndMakeVisible(ccFaderFlipBtn.get()); - ccFaderFlipBtn->setColour(TextButton::ColourIds::buttonColourId, Colours::white.withAlpha(0.05f)); - ccFaderFlipBtn->setColour(TextButton::ColourIds::buttonOnColourId, Colours::grey.withAlpha(0.1f)); + ccFaderFlipBtn->setToggleState(TerpstraSysExApplication::getApp().getPropertiesFile()->getBoolValue("InvertSustainGlobal", false), dontSendNotification); faderUpArrow = getArrowPath(Point(0.5f, 1.0f), Point(0.5f, 0.0f), 0.5f, 0.25f); faderDownArrow = getArrowPath(Point(0.5f, 0.0f), Point(0.5f, 1.0f), 0.5f, 0.75f); @@ -324,9 +323,9 @@ void SingleNoteAssign::resized() return roundToInt(parametersFont.getStringWidthFloat(btn->getButtonText()) + toggleWidthMargin); }; - for (int i = 0; i <= SingleNoteFlexRows::channelIncrement; i++) + for (int r = 0; r <= SingleNoteFlexRows::channelIncrement; r++) { - auto row = flexRows.getReference(i); + auto row = flexRows.getReference(r); row.items.clear(); // Generalize row properties @@ -339,12 +338,12 @@ void SingleNoteAssign::resized() auto controlItem = FlexItem(ctrlTemplateItem); auto getAndPerformBounds = [&] () { - auto bounds = Rectangle(controlsX, flexBounds[i - 1].getBottom() + halfMarginY, rowWidth, controlH); + auto bounds = Rectangle(controlsX, flexBounds[r - 1].getBottom() + halfMarginY, rowWidth, controlH); flexBounds.add(bounds); row.performLayout(bounds); }; - switch (i) + switch (r) { case SingleNoteFlexRows::keyType: { @@ -355,7 +354,7 @@ void SingleNoteAssign::resized() row.items.add(controlItem); flexBounds.add(Rectangle(controlsX, controlAreaTop + halfMarginY, rowWidth, controlH)); - row.performLayout(flexBounds[i]); + row.performLayout(flexBounds[r]); break; } case SingleNoteFlexRows::keyColour: @@ -404,8 +403,8 @@ void SingleNoteAssign::resized() // Position Auto-Increment section since channelIncrement is relative to it separatorY = channelInput->getBottom() + halfMarginY; autoIncrementLabel->setBounds(controlsX, separatorY + halfMarginY, w - controlsX, controlHScaled); - noteAutoIncrButton->setTopLeftPosition(controlsX, autoIncrementLabel->getBottom() + halfMarginY); - resizeToggleButtonWithHeight(noteAutoIncrButton.get(), parametersFont, toggleHeightScaled); + noteAutoIncrButton->setBounds(controlsX, autoIncrementLabel->getBottom() + halfMarginY, + rowWidth, toggleHeightScaled); break; } case SingleNoteFlexRows::channelIncrement: @@ -417,7 +416,7 @@ void SingleNoteAssign::resized() row.items.add(controlItem); flexBounds.add(Rectangle(controlsX, noteAutoIncrButton->getBottom() + halfMarginY, rowWidth, controlH)); - row.performLayout(flexBounds[i]); + row.performLayout(flexBounds[r]); break; } default: @@ -630,9 +629,6 @@ void SingleNoteAssign::restoreStateFromPropertiesFile(PropertiesFile* properties keyTypeToggleButton->setToggleState( propertiesFile->getBoolValue("SingleNoteKeyTypeSetActive", true), juce::NotificationType::sendNotification); - ccFaderFlipBtn->setToggleState( - propertiesFile->getBoolValue("SingleNoteKeyCCFlipped", false), - juce::NotificationType::sendNotification); } void SingleNoteAssign::saveStateToPropertiesFile(PropertiesFile* propertiesFile) @@ -641,7 +637,6 @@ void SingleNoteAssign::saveStateToPropertiesFile(PropertiesFile* propertiesFile) propertiesFile->setValue("SingleNoteChannelSetActive", setChannelToggleButton->getToggleState()); propertiesFile->setValue("SingleNoteColourSetActive", setColourToggleButton->getToggleState()); propertiesFile->setValue("SingleNoteKeyTypeSetActive", keyTypeToggleButton->getToggleState()); - } void SingleNoteAssign::redrawCCFlipBtn() From 885a2a4851b54300782b82afdfadd7d3a09c6e0a Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Tue, 15 Jun 2021 21:13:12 -0400 Subject: [PATCH 008/183] Fixed on-connection return code mismatch --- Source/MidiEditArea.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Source/MidiEditArea.cpp b/Source/MidiEditArea.cpp index 599abbaa..7c5479d7 100644 --- a/Source/MidiEditArea.cpp +++ b/Source/MidiEditArea.cpp @@ -592,19 +592,20 @@ void MidiEditArea::onOpenConnectionToDevice() auto retc = alert->runModalLoop(); - if (retc == 1) + DBG("Connection window returned: " + String(retc)); + if (retc == 1) // Send { - TerpstraSysExApplication::getApp().requestConfigurationFromDevice(); - liveEditorBtn->setToggleState(true, NotificationType::dontSendNotification); - lblConnectionState->setText("Connected", NotificationType::dontSendNotification); + TerpstraSysExApplication::getApp().sendCurrentConfigurationToDevice(); + liveEditorBtn->setToggleState(true, dontSendNotification); + lblConnectionState->setText("Connected", NotificationType::dontSendNotification); } - else if (retc == 2) + else if (retc == 2) // Import { - TerpstraSysExApplication::getApp().sendCurrentConfigurationToDevice(); - liveEditorBtn->setToggleState(true, dontSendNotification); - lblConnectionState->setText("Connected", NotificationType::dontSendNotification); + TerpstraSysExApplication::getApp().requestConfigurationFromDevice(); + liveEditorBtn->setToggleState(true, NotificationType::dontSendNotification); + lblConnectionState->setText("Connected", NotificationType::dontSendNotification); } - else + else // Offline { offlineEditorBtn->setToggleState(true, NotificationType::sendNotification); lblConnectionState->setText("Offline", NotificationType::dontSendNotification); From eaa885759298793c4469aa54e8692ee214118ef8 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 17 Jun 2021 19:42:29 -0400 Subject: [PATCH 009/183] Add CC fader polarity to key struct, plus associated control and styling --- Source/EditActions.cpp | 21 +++++++-- Source/EditActions.h | 8 +++- Source/KeyboardDataStructure.h | 9 ++-- Source/LumatoneController.cpp | 20 +++++--- Source/LumatoneController.h | 2 +- Source/SingleNoteAssign.cpp | 39 ++++++++-------- Source/SingleNoteAssign.h | 2 +- Source/ViewComponents.cpp | 84 ++++++++++++++++++++++------------ Source/ViewComponents.h | 1 + 9 files changed, 117 insertions(+), 69 deletions(-) diff --git a/Source/EditActions.cpp b/Source/EditActions.cpp index f27ebe23..bf17d398 100644 --- a/Source/EditActions.cpp +++ b/Source/EditActions.cpp @@ -22,13 +22,15 @@ namespace Lumatone { bool setChannel, bool setNote, bool setColour, + bool setCCPolarity, LumatoneKeyType newKeyType, int newChannelNumber, int newNoteNumber, - TerpstraKey::COLOURTYPE newColour) + TerpstraKey::COLOURTYPE newColour, + bool newCCFaderIsDefault) : setSelection(setSelection), keySelection(keySelection) - , setKeyType(setKeyType), setChannel(setChannel), setNote(setNote), setColour(setColour) - , newData(newKeyType, newChannelNumber, newNoteNumber, newColour) + , setKeyType(setKeyType), setChannel(setChannel), setNote(setNote), setColour(setColour), setCCFaderPolarity(setCCPolarity) + , newData(newKeyType, newChannelNumber, newNoteNumber, newColour, newCCFaderIsDefault) { auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); jassert(mainComponent != nullptr); @@ -45,7 +47,7 @@ namespace Lumatone { { if (setSelection >= 0 && setSelection < NUMBEROFBOARDS && keySelection >= 0 && keySelection < TerpstraSysExApplication::getApp().getOctaveBoardSize()) { - if (setKeyType || setChannel || setNote || setColour) + if (setKeyType || setChannel || setNote || setColour || setCCFaderPolarity) { auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); jassert(mainComponent != nullptr); @@ -67,6 +69,10 @@ namespace Lumatone { { mappingInEdit.sets[setSelection].theKeys[keySelection].colour = newData.colour; } + if (setCCFaderPolarity) + { + mappingInEdit.sets[setSelection].theKeys[keySelection].ccFaderDefault = newData.ccFaderDefault; + } // Send to device TerpstraSysExApplication::getApp().getLumatoneController().sendKeyParam( @@ -95,7 +101,7 @@ namespace Lumatone { { if (setSelection >= 0 && setSelection < NUMBEROFBOARDS && keySelection >= 0 && keySelection < TerpstraSysExApplication::getApp().getOctaveBoardSize()) { - if (setKeyType || setChannel || setNote || setColour) + if (setKeyType || setChannel || setNote || setColour || setCCFaderPolarity) { auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); jassert(mainComponent != nullptr); @@ -117,6 +123,11 @@ namespace Lumatone { { mappingInEdit.sets[setSelection].theKeys[keySelection].colour = previousData.colour; } + if (setCCFaderPolarity) + { + mappingInEdit.sets[setSelection].theKeys[keySelection].ccFaderDefault = previousData.ccFaderDefault; + } + // Send to device TerpstraSysExApplication::getApp().getLumatoneController().sendKeyParam( diff --git a/Source/EditActions.h b/Source/EditActions.h index b0e31c45..f2eb7b8b 100644 --- a/Source/EditActions.h +++ b/Source/EditActions.h @@ -25,10 +25,12 @@ namespace Lumatone { bool setChannel, bool setNote, bool setColour, + bool ccFaderDefault, LumatoneKeyType newKeyType = LumatoneKeyType::noteOnNoteOff, int newChannelNumber = 0, int newNoteNumber = 0, - TerpstraKey::COLOURTYPE newColour = juce::Colour()); + TerpstraKey::COLOURTYPE newColour = juce::Colour(), + bool newCCFaderDefault = true); SingleNoteAssignAction(const SingleNoteAssignAction& second) : setSelection(second.setSelection) @@ -37,6 +39,7 @@ namespace Lumatone { , setChannel(second.setChannel) , setNote(second.setNote) , setColour(second.setColour) + , setCCFaderPolarity(second.setCCFaderPolarity) , previousData(second.previousData) , newData(second.newData) {} @@ -55,6 +58,7 @@ namespace Lumatone { bool setChannel = false; bool setNote = false; bool setColour = false; + bool setCCFaderPolarity = false; TerpstraKey previousData; TerpstraKey newData; @@ -120,4 +124,4 @@ namespace Lumatone { int newData;; }; -} \ No newline at end of file +} diff --git a/Source/KeyboardDataStructure.h b/Source/KeyboardDataStructure.h index dc2625c3..8a74fe42 100644 --- a/Source/KeyboardDataStructure.h +++ b/Source/KeyboardDataStructure.h @@ -20,19 +20,20 @@ class TerpstraKey typedef juce::Colour COLOURTYPE; public: - TerpstraKey() { noteNumber = 0; channelNumber = 0; colour = juce::Colour(); keyType = noteOnNoteOff; }; - TerpstraKey(LumatoneKeyType newKeyType, int newChannelNumber, int newNoteNumber, COLOURTYPE newColour) + TerpstraKey() { noteNumber = 0; channelNumber = 0; colour = juce::Colour(); keyType = noteOnNoteOff; ccFaderDefault = false; }; + TerpstraKey(LumatoneKeyType newKeyType, int newChannelNumber, int newNoteNumber, COLOURTYPE newColour, bool invertCCFader = false) { - keyType = newKeyType; channelNumber = newChannelNumber; noteNumber = newNoteNumber; colour = newColour; + keyType = newKeyType; channelNumber = newChannelNumber; noteNumber = newNoteNumber; colour = newColour; ccFaderDefault = invertCCFader; } bool isEmpty() const { return channelNumber == 0; } - bool operator!=(const TerpstraKey& second) const { return noteNumber != second.noteNumber || channelNumber != second.channelNumber || colour != second.colour || keyType != second.keyType; } + bool operator!=(const TerpstraKey& second) const { return noteNumber != second.noteNumber || channelNumber != second.channelNumber || colour != second.colour || keyType != second.keyType || ccFaderDefault != second.ccFaderDefault; } public: int noteNumber; int channelNumber; COLOURTYPE colour; + bool ccFaderDefault; LumatoneKeyType keyType; }; diff --git a/Source/LumatoneController.cpp b/Source/LumatoneController.cpp index 793a3c57..1690314b 100644 --- a/Source/LumatoneController.cpp +++ b/Source/LumatoneController.cpp @@ -233,9 +233,14 @@ void LumatoneController::testCurrentDeviceConnection() // Send parametrization of one key to the device void LumatoneController::sendKeyParam(int boardIndex, int keyIndex, TerpstraKey keyData) { - sendKeyConfig(boardIndex, keyIndex, keyData.noteNumber, keyData.channelNumber, keyData.keyType /*, TODO fader cc polarity */); - sendKeyColourConfig(boardIndex, keyIndex, keyData.colour); + // Enum is 1-based making LumatoneKeyType::disabled = 4, but should send value 0 + int keyType = keyData.keyType; + if (keyType >= LumatoneKeyType::disabled) + keyType = 0; + // Default CC polarity = 1, Inverted CC polarity = 0 + sendKeyConfig(boardIndex, keyIndex, keyData.noteNumber, keyData.channelNumber, keyType, keyData.ccFaderDefault); + sendKeyColourConfig(boardIndex, keyIndex, keyData.colour); } // Send configuration of a certain look up table @@ -264,7 +269,7 @@ void LumatoneController::sendTableConfig(TerpstraVelocityCurveConfig::VelocityCu // Mid-level firmware functions // Send note, channel, cc, and fader polarity data -void LumatoneController::sendKeyConfig(int boardIndex, int keyIndex, int noteOrCCNum, int channel, LumatoneKeyType keyType, bool faderUpIsNull) +void LumatoneController::sendKeyConfig(int boardIndex, int keyIndex, int noteOrCCNum, int channel, int keyType, bool faderUpIsNull) { midiDriver.sendKeyFunctionParameters(boardIndex, keyIndex, noteOrCCNum, channel, keyType, faderUpIsNull); } @@ -463,7 +468,8 @@ int LumatoneController::pingLumatone(uint8 pingId) void LumatoneController::invertSustainPedal(bool setInverted) { - midiDriver.sendInvertSustainPedal(setInverted); + if (firmwareSupport.versionAcknowledgesCommand(determinedVersion, INVERT_SUSTAIN_PEDAL)) + midiDriver.sendInvertSustainPedal(setInverted); } //============================================================================= @@ -541,8 +547,8 @@ void LumatoneController::noAnswerToMessage(const MidiMessage& midiMessage) FirmwareSupport::Error LumatoneController::handleOctaveConfigResponse( const MidiMessage& midiMessage, - std::function < FirmwareSupport::Error(const MidiMessage&, int&, uint8, int*)> unpackFunction, - std::function callbackFunctionIfNoError) + std::function unpackFunction, + std::function callbackFunctionIfNoError) { int boardId = -1; int channelData[56]; @@ -559,7 +565,7 @@ FirmwareSupport::Error LumatoneController::handleOctaveConfigResponse( FirmwareSupport::Error LumatoneController::handleTableConfigResponse( const MidiMessage& midiMessage, std::function unpackFunction, - std::function callbackFunctionIfNoError) + std::function callbackFunctionIfNoError) { int veloctiyData[128]; auto errorCode = unpackFunction(midiMessage, veloctiyData); diff --git a/Source/LumatoneController.h b/Source/LumatoneController.h index f4ae1ec3..93cd4fef 100644 --- a/Source/LumatoneController.h +++ b/Source/LumatoneController.h @@ -118,7 +118,7 @@ class LumatoneController : protected TerpstraMidiDriver::Listener, // Single (mid-level) commands // Send note, channel, cc, and fader polarity data - void sendKeyConfig(int boardIndex, int keyIndex, int noteOrCCNum, int channel, LumatoneKeyType keyType, bool faderUpIsNull = true); + void sendKeyConfig(int boardIndex, int keyIndex, int noteOrCCNum, int channel, int keyType, bool faderUpIsNull = true); void sendKeyColourConfig(int boardIndex, int keyIndex, Colour colour); diff --git a/Source/SingleNoteAssign.cpp b/Source/SingleNoteAssign.cpp index 71868644..caaa9ec1 100644 --- a/Source/SingleNoteAssign.cpp +++ b/Source/SingleNoteAssign.cpp @@ -148,13 +148,12 @@ SingleNoteAssign::SingleNoteAssign () keyTypeToggleButton->setButtonText(translate("KeyType")); keyTypeToggleButton->setColour(ToggleButton::ColourIds::textColourId, toggleTextColour); - ccFaderFlipBtn.reset(new juce::ImageButton()); - ccFaderFlipBtn->setClickingTogglesState(true); - ccFaderFlipBtn->addListener(this); - ccFaderFlipBtn->setTooltip(translate("Toggle CC polarity inversion. Default, arrow down: values increase with key press. Inverted, arrow up: values decrease with key press.")); - addAndMakeVisible(ccFaderFlipBtn.get()); - ccFaderFlipBtn->setToggleState(TerpstraSysExApplication::getApp().getPropertiesFile()->getBoolValue("InvertSustainGlobal", false), dontSendNotification); - + ccFaderIsDefault.reset(new juce::ImageButton()); + ccFaderIsDefault->setClickingTogglesState(true); + ccFaderIsDefault->addListener(this); + ccFaderIsDefault->setTooltip(translate("Toggle CC polarity inversion. Default, arrow down: values increase with key press. Inverted, arrow up: values decrease with key press.")); + addAndMakeVisible(ccFaderIsDefault.get()); + ccFaderIsDefault->setToggleState(true, dontSendNotification); faderUpArrow = getArrowPath(Point(0.5f, 1.0f), Point(0.5f, 0.0f), 0.5f, 0.25f); faderDownArrow = getArrowPath(Point(0.5f, 0.0f), Point(0.5f, 1.0f), 0.5f, 0.75f); @@ -206,7 +205,6 @@ SingleNoteAssign::SingleNoteAssign () setColourToggleButton->setToggleState(true, juce::NotificationType::sendNotification); keyTypeToggleButton->setToggleState(true, juce::NotificationType::sendNotification); keyTypeCombo->setSelectedId(LumatoneKeyType::noteOnNoteOff); - juce::Timer::callAfterDelay(500, [&]{keyTypeCombo->setSelectedId(2, sendNotification);}); //[/Constructor] } @@ -379,7 +377,7 @@ void SingleNoteAssign::resized() if (keyTypeCombo->getSelectedId() == LumatoneKeyType::continuousController) { - auto ccInvertItem = FlexItem(controlH, controlH, *ccFaderFlipBtn.get()); + auto ccInvertItem = FlexItem(controlH, controlH, *ccFaderIsDefault.get()); ccInvertItem.margin = FlexItem::Margin(0, halfMarginX, 0, 0); row.items.add(ccInvertItem); } @@ -487,7 +485,7 @@ void SingleNoteAssign::buttonClicked (juce::Button* buttonThatWasClicked) } //[UserbuttonClicked_Post] - else if (buttonThatWasClicked == ccFaderFlipBtn.get()) + else if (buttonThatWasClicked == ccFaderIsDefault.get()) { } //[/UserbuttonClicked_Post] @@ -506,12 +504,12 @@ void SingleNoteAssign::comboBoxChanged (juce::ComboBox* comboBoxThatHasChanged) if (keyTypeCombo->getSelectedId() == LumatoneKeyType::continuousController) { setNoteToggleButton->setButtonText("CC #:"); - ccFaderFlipBtn->setVisible(true); + ccFaderIsDefault->setVisible(true); } else { setNoteToggleButton->setButtonText("Note # (0-127):"); - ccFaderFlipBtn->setVisible(false); + ccFaderIsDefault->setVisible(false); } resized(); @@ -577,8 +575,9 @@ UndoableAction* SingleNoteAssign::createEditAction(int setSelection, int keySele setSelection, keySelection, keyTypeToggleButton->getToggleState(), setChannelToggleButton->getToggleState(), setNoteToggleButton->getToggleState(), setColourToggleButton->getToggleState(), + (LumatoneKeyType)keyTypeCombo->getSelectedId() == LumatoneKeyType::continuousController, (LumatoneKeyType)keyTypeCombo->getSelectedId(), newChannel, - newNote, colourSubwindow->getColourAsObject()); + newNote, colourSubwindow->getColourAsObject(), ccFaderIsDefault->getToggleState()); jassert(editAction != nullptr && editAction->isValid()); @@ -644,7 +643,7 @@ void SingleNoteAssign::redrawCCFlipBtn() Path arrowPath, faderPath, arrowInvertedPath, faderInvertedPath; getCCPolarityIconPath(false, arrowPath, faderPath); getCCPolarityIconPath(true, arrowInvertedPath, faderInvertedPath); - auto defaultImg = Image(Image::PixelFormat::ARGB, ccFaderFlipBtn->getWidth(), ccFaderFlipBtn->getHeight(), true); + auto defaultImg = Image(Image::PixelFormat::ARGB, ccFaderIsDefault->getWidth(), ccFaderIsDefault->getHeight(), true); auto invertedImg = defaultImg.createCopy(); Graphics g(defaultImg); @@ -659,9 +658,9 @@ void SingleNoteAssign::redrawCCFlipBtn() auto lookAndFeel = &TerpstraSysExApplication::getApp().getLookAndFeel(); auto background = lookAndFeel->findColour(TextButton::ColourIds::buttonColourId); g.setColour(background); - g.fillRoundedRectangle(ccFaderFlipBtn->getLocalBounds().toFloat(), 5.0f); + g.fillRoundedRectangle(ccFaderIsDefault->getLocalBounds().toFloat(), 5.0f); gi.setColour(background); - gi.fillRoundedRectangle(ccFaderFlipBtn->getLocalBounds().toFloat(), 5.0f); + gi.fillRoundedRectangle(ccFaderIsDefault->getLocalBounds().toFloat(), 5.0f); auto arrowStroke = PathStrokeType(PHI, PathStrokeType::JointStyle::curved); auto colour = lookAndFeel->findColour(LumatoneEditorColourIDs::ActiveText).brighter(0.1); @@ -676,10 +675,10 @@ void SingleNoteAssign::redrawCCFlipBtn() // auto mouseOverImg = ccFaderFlipBtn->getToggleState() ? &invertedImg : &defaultImg; auto highlight = Colours::white.withAlpha(0.0333f); - ccFaderFlipBtn->setImages(false, false, true, - defaultImg, 1.0f, Colour(), - defaultImg, 1.0f, highlight, - invertedImg, 1.0f, Colour()); + ccFaderIsDefault->setImages(false, false, true, + invertedImg, 1.0f, Colour(), + invertedImg, 1.0f, highlight, + defaultImg, 1.0f, Colour()); } //[/MiscUserCode] diff --git a/Source/SingleNoteAssign.h b/Source/SingleNoteAssign.h index 1abbc489..d6c53971 100644 --- a/Source/SingleNoteAssign.h +++ b/Source/SingleNoteAssign.h @@ -115,7 +115,7 @@ class SingleNoteAssign : public Component, const Colour toggleTextColour = Colour(0xffcbcbcb); - std::unique_ptr ccFaderFlipBtn; + std::unique_ptr ccFaderIsDefault; Path faderDownArrow; Path faderUpArrow; //[/UserVariables] diff --git a/Source/ViewComponents.cpp b/Source/ViewComponents.cpp index a2354cfd..3a4afc86 100644 --- a/Source/ViewComponents.cpp +++ b/Source/ViewComponents.cpp @@ -43,16 +43,26 @@ TerpstraKey TerpstraKeyEdit::getValue() const newValue.channelNumber = midiChannelLabel->getText().getIntValue(); newValue.colour = keyColour; newValue.keyType = keyType; + newValue.ccFaderDefault = ccFaderDefault; return newValue; } void TerpstraKeyEdit::setValue(TerpstraKey newValue) { - midiNoteLabel->setText(String(newValue.noteNumber), juce::NotificationType::sendNotification); - midiChannelLabel->setText(String(newValue.channelNumber), juce::NotificationType::sendNotification); + if (keyType >= LumatoneKeyType::disabled) + { + midiNoteLabel->setText("x", juce::NotificationType::sendNotification); + midiChannelLabel->setText("x", juce::NotificationType::sendNotification); + } + else + { + midiNoteLabel->setText(String(newValue.noteNumber), juce::NotificationType::sendNotification); + midiChannelLabel->setText(String(newValue.channelNumber), juce::NotificationType::sendNotification); + } keyColour = newValue.colour; keyType = newValue.keyType; + ccFaderDefault = newValue.ccFaderDefault; String newTooltip = translate("KeyType") + " "; switch (keyType) @@ -62,6 +72,11 @@ void TerpstraKeyEdit::setValue(TerpstraKey newValue) break; case LumatoneKeyType::continuousController: newTooltip += translate("ContinuousController"); + newTooltip += newLine; + if (ccFaderDefault) + newTooltip += "CC Default (0->127)"; + else + newTooltip += "CC Inverted (127->0)"; break; case LumatoneKeyType::lumaTouch: newTooltip += translate("Lumatouch"); @@ -111,26 +126,28 @@ void TerpstraKeyEdit::paint(Graphics& g) textColour = textColour.brighter(); } - if (currentValue.keyType == LumatoneKeyType::disabled) - { - midiChannelLabel->setVisible(false); - midiNoteLabel->setVisible(false); - } - else - { - midiChannelLabel->setVisible(true); - midiChannelLabel->setColour(juce::Label::textColourId, textColour); - midiNoteLabel->setVisible(true); - midiNoteLabel->setColour(juce::Label::textColourId, textColour); - } - // Look depending on Key type - if (currentValue.keyType == LumatoneKeyType::continuousController) + midiChannelLabel->setColour(juce::Label::textColourId, textColour); + midiNoteLabel->setColour(juce::Label::textColourId, textColour); + + // Look depending on Key type + if (currentValue.keyType == LumatoneKeyType::continuousController) { // Key type is continuous controller. Set colour gradient. float w = this->getWidth(); float h = this->getHeight(); + Colour inside, outside; + if (currentValue.ccFaderDefault) + { + outside = bgColour.darker(); + inside = bgColour.brighter(); + } + else + { + outside = bgColour.brighter(); + inside = bgColour.darker(); + } g.setGradientFill( - ColourGradient(bgColour.darker(), w * 0.5f, h * 0.5f, bgColour.brighter(), w * 0.5f, 0.0f, true)); + ColourGradient(inside, w * 0.5f, h * 0.5f, outside, w * 0.5f, 0.0f, true)); } else { @@ -152,17 +169,26 @@ void TerpstraKeyEdit::paint(Graphics& g) g.strokePath(hexOutline, PathStrokeType(lineWidth)); } - if (currentValue.keyType == LumatoneKeyType::disabled) - { - float w = this->getWidth(); - float h = this->getHeight(); - float xProportion = 0.25f; - // Draw X on key - g.setColour(bgColour.contrasting(0.5f)); - g.drawLine(w * xProportion, h * xProportion, w * (1-xProportion), h * (1-xProportion), 2); - g.drawLine(w * (1 - xProportion), h * xProportion, w * xProportion, h * (1 - xProportion), 2); - } - +// if (currentValue.keyType == LumatoneKeyType::disabled) +// { +// float w = this->getWidth(); +// float h = this->getHeight(); +// float xProportion = 0.25f; +// // Draw X on key +// g.setColour(bgColour.contrasting(0.5f)); +// g.drawLine(w * xProportion, h * xProportion, w * (1-xProportion), h * (1-xProportion), 2); +// g.drawLine(w * (1 - xProportion), h * xProportion, w * xProportion, h * (1 - xProportion), 2); +// } + +// if (currentValue.keyType == LumatoneKeyType::disabled) +// { +// TerpstraSysExApplication::getApp().getLookAndFeel().getLabelFont(*midiNoteLabel); +// g.setColour(textColour); +// g.setFont(midiChannelLabel->getFont()); +// g.drawText("x", midiChannelLabel->getBounds(), midiChannelLabel->getJustificationType()); +// g.drawText("x", midiNoteLabel->getBounds(), midiChannelLabel->getJustificationType()); +// } + // Something parametrized or not? if (currentValue.isEmpty()) { @@ -184,7 +210,7 @@ void TerpstraKeyEdit::resized() // Draw hexagon hexPath.clear(); hexPath.addPolygon(centre.toFloat(), 6, radius, TERPSTRASINGLEKEYROTATIONANGLE); - Rectangle hexBounds = hexPath.getBounds().reduced(1, 1); + //Rectangle hexBounds = hexPath.getBounds().reduced(1, 1); float lblSize = radius * TERPSTRASINGLEKEYLABELSIZE; float lblOffset = radius * 0.375f; diff --git a/Source/ViewComponents.h b/Source/ViewComponents.h index 898d6163..da2e285e 100644 --- a/Source/ViewComponents.h +++ b/Source/ViewComponents.h @@ -52,6 +52,7 @@ class TerpstraKeyEdit : public Component, public SettableTooltipClient juce::Colour keyColour; LumatoneKeyType keyType; + bool ccFaderDefault; float keySize; From 2beaf5d9dca5c3fb0958b883722ea81fadf1f261 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 17 Jun 2021 19:43:19 -0400 Subject: [PATCH 010/183] Update key commands to support Mac command button --- Source/Main.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Source/Main.cpp b/Source/Main.cpp index cee1cc23..05fd9fbc 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -322,22 +322,22 @@ void TerpstraSysExApplication::getCommandInfo(CommandID commandID, ApplicationCo { case Lumatone::Menu::commandIDs::openSysExMapping: result.setInfo("Load file mapping", "Open a Lumatone key mapping", "File", 0); - result.addDefaultKeypress('o', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('o', ModifierKeys::commandModifier); break; case Lumatone::Menu::commandIDs::saveSysExMapping: result.setInfo("Save mapping", "Save the current mapping to file", "File", 0); - result.addDefaultKeypress('s', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('s', ModifierKeys::commandModifier); break; case Lumatone::Menu::commandIDs::saveSysExMappingAs: result.setInfo("Save mapping as...", "Save the current mapping to new file", "File", 0); - result.addDefaultKeypress('a', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('a', ModifierKeys::commandModifier); break; case Lumatone::Menu::commandIDs::resetSysExMapping: result.setInfo("New", "Start new mapping. Clear all edit fields, do not save current edits.", "File", 0); - result.addDefaultKeypress('n', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('n', ModifierKeys::commandModifier); break; case Lumatone::Menu::commandIDs::deleteOctaveBoard: @@ -347,23 +347,23 @@ void TerpstraSysExApplication::getCommandInfo(CommandID commandID, ApplicationCo case Lumatone::Menu::commandIDs::copyOctaveBoard: result.setInfo("Copy", "Copy section data", "Edit", 0); - result.addDefaultKeypress('c', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('c', ModifierKeys::commandModifier); break; case Lumatone::Menu::commandIDs::pasteOctaveBoard: result.setInfo("Paste", "Paste section data", "Edit", 0); - result.addDefaultKeypress('v', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('v', ModifierKeys::commandModifier); break; case Lumatone::Menu::commandIDs::undo: result.setInfo("Undo", "Undo latest edit", "Edit", 0); - result.addDefaultKeypress('z', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('z', ModifierKeys::commandModifier); result.setActive(undoManager.canUndo()); break; case Lumatone::Menu::commandIDs::redo: result.setInfo("Redo", "Redo latest edit", "Edit", 0); - result.addDefaultKeypress('y', ModifierKeys::ctrlModifier); + result.addDefaultKeypress('y', ModifierKeys::commandModifier); result.setActive(undoManager.canRedo()); break; @@ -373,7 +373,8 @@ void TerpstraSysExApplication::getCommandInfo(CommandID commandID, ApplicationCo case Lumatone::Debug::commandIDs::toggleDeveloperMode: result.setInfo("Toggle Developer Mode", "Show/hide controls for tweaking internal parameters", "Edit", 0); - result.addDefaultKeypress('m', juce::ModifierKeys::allKeyboardModifiers); + result.addDefaultKeypress('m', + juce::ModifierKeys::ctrlModifier + juce::ModifierKeys::altModifier + juce::ModifierKeys::shiftModifier); break; default: @@ -716,6 +717,7 @@ void TerpstraSysExApplication::sendCurrentConfigurationToDevice() getLumatoneController().sendLightOnKeyStrokes(theConfig.lightOnKeyStrokes); getLumatoneController().sendInvertFootController(theConfig.invertExpression); getLumatoneController().sendExpressionPedalSensivity(theConfig.expressionControllerSensivity); + getLumatoneController().invertSustainPedal(theConfig.invertSustain); // Velocity curve config getLumatoneController().setVelocityIntervalConfig(theConfig.velocityIntervalTableValues); From 4f08645aafc6f781b3e712b99059a707d751e628 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 17 Jun 2021 20:15:23 -0400 Subject: [PATCH 011/183] Support for importing CC Fader polarity config --- Source/LumatoneController.cpp | 19 +++++++++++++++++++ Source/LumatoneController.h | 7 +++++++ Source/MainComponent.cpp | 8 ++++++++ Source/MainComponent.h | 2 ++ 4 files changed, 36 insertions(+) diff --git a/Source/LumatoneController.cpp b/Source/LumatoneController.cpp index 1690314b..1930923d 100644 --- a/Source/LumatoneController.cpp +++ b/Source/LumatoneController.cpp @@ -151,6 +151,7 @@ void LumatoneController::sendGetMappingOfBoardRequest(int boardIndex) getChannelConfig(boardIndex); getNoteConfig(boardIndex); getKeyTypeConfig(boardIndex); + getFaderTypeConfig(boardIndex); } void LumatoneController::sendGetCompleteMappingRequest() @@ -423,6 +424,11 @@ void LumatoneController::sendVelocityIntervalConfigRequest() midiDriver.sendVelocityIntervalConfigRequest(); } +void LumatoneController::getFaderTypeConfig(int boardIndex) +{ + midiDriver.sendFaderTypeConfigRequest(boardIndex); +} + // This command is used to read back the serial identification number of the keyboard. void LumatoneController::sendGetSerialIdentityRequest() { @@ -669,6 +675,15 @@ FirmwareSupport::Error LumatoneController::handleFaderConfigResponse(const MidiM return handleTableConfigResponse(midiMessage, unpack, callback); } +FirmwareSupport::Error LumatoneController::handleFaderTypeConfigResponse(const MidiMessage& midiMessage) +{ + auto unpack = [&](const MidiMessage& msg, int& boardId, uint8 numKeys, int* data) { + return midiDriver.unpackGetTypeConfigResponse(msg, boardId, numKeys, data); + }; + auto callback = [&](int boardId, void* data) { firmwareListeners.call(&FirmwareListener::faderTypeConfigReceived, boardId, (int*)data); }; + return handleOctaveConfigResponse(midiMessage, unpack, callback); +} + FirmwareSupport::Error LumatoneController::handleSerialIdentityResponse(const MidiMessage& midiMessage) { int serialBytes[6]; @@ -874,6 +889,10 @@ void LumatoneController::timerCallback() case GET_VELOCITY_CONFIG: errorCode = handleVelocityConfigResponse(midiMessage); break; + + case GET_FADER_TYPE_CONFIGURATION: + errorCode = handleFaderTypeConfigResponse(midiMessage); + break; case GET_SERIAL_IDENTITY: errorCode = handleSerialIdentityResponse(midiMessage); diff --git a/Source/LumatoneController.h b/Source/LumatoneController.h index 93cd4fef..dbc4b75c 100644 --- a/Source/LumatoneController.h +++ b/Source/LumatoneController.h @@ -183,6 +183,9 @@ class LumatoneController : protected TerpstraMidiDriver::Listener, void sendVelocityIntervalConfigRequest(); + // CMD 22h: Read back the fader type of all keys on the targeted board. + void getFaderTypeConfig(int boardIndex); + // This command is used to read back the serial identification number of the keyboard. void sendGetSerialIdentityRequest(); @@ -282,6 +285,8 @@ class LumatoneController : protected TerpstraMidiDriver::Listener, virtual void faderConfigReceived(const int* faderData) {}; + virtual void faderTypeConfigReceived(int octaveIndex, const int* faderTypeData) {}; + virtual void serialIdentityReceived(int inputDeviceIndex, const int* serialBytes) {}; virtual void lumatouchConfigReceived(const int* lumatouchData) {}; @@ -362,6 +367,8 @@ class LumatoneController : protected TerpstraMidiDriver::Listener, FirmwareSupport::Error handleVelocityIntervalConfigResponse(const MidiMessage& midiMessage); FirmwareSupport::Error handleFaderConfigResponse(const MidiMessage& midiMessage); + + FirmwareSupport::Error handleFaderTypeConfigResponse(const MidiMessage& midiMessage); FirmwareSupport::Error handleSerialIdentityResponse(const MidiMessage& midiMessage); diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index ca63d807..c54a5135 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -257,6 +257,14 @@ void MainContentComponent::faderConfigReceived(const int* faderData) curvesArea->loadFromMapping(); } +void MainContentComponent::faderTypeConfigReceived(int octaveIndex, const int* faderTypeData) +{ + for (int keyIndex = 0; keyIndex < TerpstraSysExApplication::getApp().getOctaveBoardSize(); keyIndex++) + { + this->mappingData.sets[octaveIndex - 1].theKeys[keyIndex].ccFaderDefault = faderTypeData[keyIndex]; + } +} + void MainContentComponent::lumatouchConfigReceived(const int* lumatouchData) { this->mappingData.lumaTouchConfig.editStrategy = TerpstraVelocityCurveConfig::EDITSTRATEGYINDEX::freeDrawing; diff --git a/Source/MainComponent.h b/Source/MainComponent.h index 55186679..e5fc7dfd 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -93,6 +93,8 @@ class MainContentComponent : public Component, void faderConfigReceived(const int* faderData) override; + void faderTypeConfigReceived(int octaveIndex, const int* faderTypeData) override; + void lumatouchConfigReceived(const int* lumatouchData) override; void firmwareRevisionReceived(FirmwareVersion version) override; From ac4eebd5ebd469e3ab390ce9de289d4935aa1ce4 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 17 Jun 2021 20:26:16 -0400 Subject: [PATCH 012/183] added disabledDefault key type for explicit import, fixed disabled key edit issues --- Source/LumatoneFirmwareDefinitions.h | 1 + Source/ViewComponents.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/LumatoneFirmwareDefinitions.h b/Source/LumatoneFirmwareDefinitions.h index 86cfb332..e589b02c 100644 --- a/Source/LumatoneFirmwareDefinitions.h +++ b/Source/LumatoneFirmwareDefinitions.h @@ -177,6 +177,7 @@ typedef enum typedef enum { + disabledDefault = 0, noteOnNoteOff = 1, continuousController = 2, lumaTouch = 3, diff --git a/Source/ViewComponents.cpp b/Source/ViewComponents.cpp index 3a4afc86..4021a97f 100644 --- a/Source/ViewComponents.cpp +++ b/Source/ViewComponents.cpp @@ -50,8 +50,9 @@ TerpstraKey TerpstraKeyEdit::getValue() const void TerpstraKeyEdit::setValue(TerpstraKey newValue) { - if (keyType >= LumatoneKeyType::disabled) + if (newValue.keyType == LumatoneKeyType::disabled || newValue.keyType == LumatoneKeyType::disabledDefault) { + newValue.keyType = LumatoneKeyType::disabled; midiNoteLabel->setText("x", juce::NotificationType::sendNotification); midiChannelLabel->setText("x", juce::NotificationType::sendNotification); } From a43d1b9d628fc5bfd006ddf6d52ec7ca39cfd9d8 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 17 Jun 2021 20:36:01 -0400 Subject: [PATCH 013/183] support undo for invert sustain --- Source/EditActions.cpp | 41 ++++++++++++++++++++++++++++++++++ Source/EditActions.h | 18 +++++++++++++++ Source/PedalSensitivityDlg.cpp | 6 +---- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Source/EditActions.cpp b/Source/EditActions.cpp index bf17d398..e2f2e26a 100644 --- a/Source/EditActions.cpp +++ b/Source/EditActions.cpp @@ -302,4 +302,45 @@ namespace Lumatone { return true; } + // ============================================================================== + // Implementation of InvertSustainEditAction + + InvertSustainEditAction::InvertSustainEditAction(bool newValue) + : newData(newValue) + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + + previousData = mainComponent->getMappingInEdit().invertSustain; + } + + bool InvertSustainEditAction::perform() + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.invertSustain = newData; + + // Send to device + TerpstraSysExApplication::getApp().getLumatoneController().invertSustainPedal(newData); + + // Notify that there are changes: in calling function + return true; + } + + bool InvertSustainEditAction::undo() + { + auto mainComponent = TerpstraSysExApplication::getApp().getMainContentComponent(); + jassert(mainComponent != nullptr); + TerpstraKeyMapping& mappingInEdit = mainComponent->getMappingInEdit(); + + mappingInEdit.invertSustain = previousData; + + // Send to device + TerpstraSysExApplication::getApp().getLumatoneController().invertSustainPedal(previousData); + + // Notify that there are changes: in calling function + return true; + } } diff --git a/Source/EditActions.h b/Source/EditActions.h index f2eb7b8b..c711eaf3 100644 --- a/Source/EditActions.h +++ b/Source/EditActions.h @@ -124,4 +124,22 @@ namespace Lumatone { int newData;; }; + class InvertSustainEditAction : public UndoableAction + { + public: + InvertSustainEditAction(bool newValue); + + InvertSustainEditAction(const InvertSustainEditAction& second) + : previousData(second.previousData), newData(second.newData) + {} + + virtual bool perform() override; + virtual bool undo() override; + int getSizeInUnits() override { return sizeof(InvertSustainEditAction); } + + private: + int previousData; + int newData;; + }; + } diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index e0f7bda4..5d1fbfde 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -163,11 +163,7 @@ void PedalSensitivityDlg::buttonClicked (juce::Button* buttonThatWasClicked) else if (buttonThatWasClicked == btnInvertSustain.get()) { //[UserButtonCode_btnInvertSustain] -- add your button handler code here.. - // TODO: make undoable action - bool invert = btnInvertSustain->getToggleState(); - ((MainContentComponent*)getParentComponent())->getMappingInEdit().invertSustain = invert; - TerpstraSysExApplication::getApp().setHasChangesToSave(true); - TerpstraSysExApplication::getApp().getLumatoneController().invertSustainPedal(invert); + TerpstraSysExApplication::getApp().performUndoableAction(new Lumatone::InvertSustainEditAction(btnInvertSustain->getToggleState())); //[/UserButtonCode_btnInvertSustain] } From 42cc1e474410708427a3c184cfe150e561637a4e Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 17 Jun 2021 20:49:48 -0400 Subject: [PATCH 014/183] Hotfix: consider STATE response successful, don't auto-disable demo mode --- Source/DeviceActivityMonitor.cpp | 5 +++++ Source/TerpstraMidiDriver.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Source/DeviceActivityMonitor.cpp b/Source/DeviceActivityMonitor.cpp index b0e66cd6..0436baa9 100644 --- a/Source/DeviceActivityMonitor.cpp +++ b/Source/DeviceActivityMonitor.cpp @@ -437,6 +437,11 @@ void DeviceActivityMonitor::midiMessageReceived(MidiInput* source, const MidiMes break; } } + // Consider a response from a different firmware state as successful + else if (sysExData[MSG_STATUS] == TerpstraMIDIAnswerReturnCode::STATE) + { + onTestResponseReceived(); + } } // Edge case if we're disconnected but get a response diff --git a/Source/TerpstraMidiDriver.cpp b/Source/TerpstraMidiDriver.cpp index 29137b54..cafc9e86 100644 --- a/Source/TerpstraMidiDriver.cpp +++ b/Source/TerpstraMidiDriver.cpp @@ -1356,11 +1356,11 @@ void TerpstraMidiDriver::handleIncomingMidiMessage(MidiInput* source, const Midi // Check answer state (error yes/no) auto answerState = message.getSysExData()[5]; // if answer state is "busy": resend message after a little delay - if (answerState == TerpstraMIDIAnswerReturnCode::STATE) - { - // turn demo mode off - startDemoMode(false); - } +// if (answerState == TerpstraMIDIAnswerReturnCode::STATE) +// { +// // turn demo mode off +// startDemoMode(false); +// } if ( answerState == TerpstraMIDIAnswerReturnCode::BUSY) { From 0fe4b8ea3e29a2365991f16bae8e2539ba58a389 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 17 Jun 2021 22:42:05 -0400 Subject: [PATCH 015/183] Add CCInvert flag to LTNs and fix default --- Source/KeyboardDataStructure.cpp | 12 +++++++++++- Source/KeyboardDataStructure.h | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Source/KeyboardDataStructure.cpp b/Source/KeyboardDataStructure.cpp index 3495b7af..34f9699c 100644 --- a/Source/KeyboardDataStructure.cpp +++ b/Source/KeyboardDataStructure.cpp @@ -348,6 +348,14 @@ void TerpstraKeyMapping::fromStringArray(const StringArray& stringArray) } } else jassert(false); + } else if ((pos1 = currentLine.indexOf("CCInvert_")) >= 0) { + int keyIndex = currentLine.substring(pos1 + 9, currentLine.length()).getIntValue(); + if (boardIndex >= 0 && boardIndex < NUMBEROFBOARDS) { + if (keyIndex >= 0 && keyIndex < 56) + sets[boardIndex].theKeys[keyIndex].ccFaderDefault = false; + else + jassert(false); + } } // General options else if ((pos1 = currentLine.indexOf("AfterTouchActive=")) >= 0) { @@ -423,6 +431,8 @@ StringArray TerpstraKeyMapping::toStringArray() result.add("Col_" + String(keyIndex) + "=" + sets[boardIndex].theKeys[keyIndex].colour.toDisplayString(false)); if (sets[boardIndex].theKeys[keyIndex].keyType != LumatoneKeyType::noteOnNoteOff) result.add("KTyp_" + String(keyIndex) + "=" + String(sets[boardIndex].theKeys[keyIndex].keyType)); + if (sets[boardIndex].theKeys[keyIndex].ccFaderDefault != true) + result.add("CCInvert_" + String(keyIndex)); } } @@ -483,4 +493,4 @@ TerpstraVelocityCurveConfig* TerpstraKeyMapping::getVelocityCurveConfig(Terpstra jassertfalse; return nullptr; } -} \ No newline at end of file +} diff --git a/Source/KeyboardDataStructure.h b/Source/KeyboardDataStructure.h index 8a74fe42..0bf2df4e 100644 --- a/Source/KeyboardDataStructure.h +++ b/Source/KeyboardDataStructure.h @@ -20,7 +20,7 @@ class TerpstraKey typedef juce::Colour COLOURTYPE; public: - TerpstraKey() { noteNumber = 0; channelNumber = 0; colour = juce::Colour(); keyType = noteOnNoteOff; ccFaderDefault = false; }; + TerpstraKey() { noteNumber = 0; channelNumber = 0; colour = juce::Colour(); keyType = noteOnNoteOff; ccFaderDefault = true; }; TerpstraKey(LumatoneKeyType newKeyType, int newChannelNumber, int newNoteNumber, COLOURTYPE newColour, bool invertCCFader = false) { keyType = newKeyType; channelNumber = newChannelNumber; noteNumber = newNoteNumber; colour = newColour; ccFaderDefault = invertCCFader; From 10905ce8fdfaef834488693b67f6360f04c9a16a Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Fri, 18 Jun 2021 09:59:41 -0400 Subject: [PATCH 016/183] Don't launch window larger than primary display --- Source/Main.h | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Source/Main.h b/Source/Main.h index 14025d05..89d230e7 100644 --- a/Source/Main.h +++ b/Source/Main.h @@ -157,12 +157,21 @@ class TerpstraSysExApplication : public JUCEApplication void restoreStateFromPropertiesFile(PropertiesFile* propertiesFile) { - if (!restoreWindowStateFromString(propertiesFile->getValue("MainWindowState"))) - { - // Default window state - setSize(DEFAULTMAINWINDOWWIDTH, DEFAULTMAINWINDOWHEIGHT); - } - + int maxWindowHeight = Desktop::getInstance().getDisplays().getPrimaryDisplay()->userArea.getHeight(); + String windowState = propertiesFile->getValue("MainWindowState"); + auto windowProperties = StringArray::fromTokens(windowState, false); + bool useSavedState = windowProperties[windowProperties.size() - 1].getIntValue() <= maxWindowHeight; + if (useSavedState) + { + useSavedState = restoreWindowStateFromString(propertiesFile->getValue("MainWindowState")); + } + + if (!useSavedState) + { + // Default window state + setSize(DEFAULTMAINWINDOWWIDTH, DEFAULTMAINWINDOWHEIGHT); + } + ((MainContentComponent*)(getContentComponent()))->restoreStateFromPropertiesFile(propertiesFile); } From 8a05eda9f5db8f0c83f01970c19c1c22151f4475 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Fri, 18 Jun 2021 18:01:17 -0400 Subject: [PATCH 017/183] Merge sensitivity undo action (previously forgot) --- Source/PedalSensitivityDlg.cpp | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index 5d1fbfde..a991ea50 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -178,23 +178,8 @@ void PedalSensitivityDlg::sliderValueChanged (juce::Slider* sliderThatWasMoved) if (sliderThatWasMoved == sldExprCtrlSensitivity.get()) { - //[UserSliderCode_sldExprCtrlSensivity] -- add your slider handling code here.. - int newSensitvity = sldExprCtrlSensitivity->getValue(); - // ToDo value checking: encapsulate in keyboard data structure? - if (newSensitvity < 0) - { - newSensitvity = 0; - sldExprCtrlSensitivity->setValue(newSensitvity); - } - - if (newSensitvity > 0x7f) - { - newSensitvity = 0x7f; - sldExprCtrlSensitivity->setValue(newSensitvity); - } - - TerpstraSysExApplication::getApp().performUndoableAction(new Lumatone::ExprPedalSensivityEditAction(newSensitvity)); - //[/UserSliderCode_sldExprCtrlSensivity] + //[UserSliderCode_sldExprCtrlSensitivity] -- add your slider handling code here.. + //[/UserSliderCode_sldExprCtrlSensitivity] } //[UsersliderValueChanged_Post] From b4a363a1b76e4d0099d97da51bdbde9d7cbc7874 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sat, 19 Jun 2021 20:40:34 -0400 Subject: [PATCH 018/183] Made pull-down fonts a bit larger --- Source/LumatoneEditorLookAndFeel.h | 7 +------ Source/LumatoneEditorStyleCommon.h | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Source/LumatoneEditorLookAndFeel.h b/Source/LumatoneEditorLookAndFeel.h index b2e4d2a2..7dcd66d6 100644 --- a/Source/LumatoneEditorLookAndFeel.h +++ b/Source/LumatoneEditorLookAndFeel.h @@ -734,15 +734,11 @@ class LumatoneEditorLookAndFeel : public LookAndFeel_V4 } g.fillPath(boxShape); - g.setFont(getComboBoxFont(box)); - g.setColour(textColour); - int realButtonX = jmax(margin, box.getWidth() - box.getHeight()); if (buttonW > 0) { g.setColour(textColour); - g.setFont(appFonts[LumatoneEditorFont::GothamNarrowLight].withHeight(buttonH * 0.5f).withHorizontalScale(2.0f)); g.drawFittedText("v", realButtonX, 0, box.getHeight(), box.getHeight(), Justification::centred, 1); } @@ -869,7 +865,6 @@ class LumatoneEditorLookAndFeel : public LookAndFeel_V4 if (target) { font = getComboBoxFont(*target); - font.setHeight(font.getHeight() * CONTROLBOXFONTHEIGHTSCALAR); textColour = target->findColour(ComboBox::ColourIds::textColourId); margin = target->proportionOfHeight(comboBoxRoundedCornerScalar); } @@ -898,7 +893,7 @@ class LumatoneEditorLookAndFeel : public LookAndFeel_V4 g.setColour(textColour); g.setFont(font); - g.drawFittedText(item.text, areaToUse.withTrimmedLeft(margin), Justification::centredLeft, 1); + g.drawFittedText(item.text, areaToUse.withTrimmedLeft(margin).withTrimmedRight(margin), Justification::centredLeft, 1); } void getIdealPopupMenuItemSizeWithOptions(const String& text, bool isSeparator, int standardMenuItemHeight, int& idealWidth, int& idealHeight, diff --git a/Source/LumatoneEditorStyleCommon.h b/Source/LumatoneEditorStyleCommon.h index 8f722e5e..de7d1f4d 100644 --- a/Source/LumatoneEditorStyleCommon.h +++ b/Source/LumatoneEditorStyleCommon.h @@ -40,7 +40,7 @@ #if JUCE_MAC #define GLOBALFONTSCALAR 0.9f - #define CONTROLBOXFONTHEIGHTSCALAR 0.66f + #define CONTROLBOXFONTHEIGHTSCALAR 0.7f #elif JUCE_WINDOWS #define GLOBALFONTSCALAR 1.0f #define CONTROLBOXFONTHEIGHTSCALAR 0.8f From 827bdb0fca924ca0ac00411dc2b3a9678fb9202e Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sat, 19 Jun 2021 22:31:29 -0400 Subject: [PATCH 019/183] Fixed preprocessor flag and menu destruction --- Source/FirmwareTransfer.cpp | 8 ++++---- Source/Main.cpp | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/FirmwareTransfer.cpp b/Source/FirmwareTransfer.cpp index a64fb632..e7727685 100644 --- a/Source/FirmwareTransfer.cpp +++ b/Source/FirmwareTransfer.cpp @@ -316,7 +316,7 @@ FirmwareTransfer::StatusCode FirmwareTransfer::performFirmwareUpdate() -#ifdef JUCE_WIN +#if JUCE_WINDOWS // Create socket and connect to port 22 sock = socket(AF_INET, SOCK_STREAM, 0); @@ -339,11 +339,11 @@ FirmwareTransfer::StatusCode FirmwareTransfer::performFirmwareUpdate() { DBG("failed to connect!"); -#if WIN32 + #if WIN32 closesocket(sock); -#else + #else close(sock); -#endif + #endif return StatusCode::HostConnectErr; } diff --git a/Source/Main.cpp b/Source/Main.cpp index 05fd9fbc..ca4fd450 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -186,6 +186,8 @@ void TerpstraSysExApplication::shutdown() #if JUCE_MAC MenuBarModel::setMacMainMenu(nullptr); +#else + mainWindow->setMenuBarComponent(nullptr); #endif menuModel = nullptr; From 1c76211debe9131e37ab5b90598fa02bb2ea4250 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sun, 20 Jun 2021 16:09:37 -0400 Subject: [PATCH 020/183] Invert pedal buttons won't overlap sensitivity control --- Source/PedalSensitivityDlg.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index a991ea50..c588b7d4 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -136,13 +136,14 @@ void PedalSensitivityDlg::resized() resizeLabelWithHeight(labelPedalTitle.get(), roundToInt(getHeight() * SETTINGSLABELHEIGHT)); labelPedalTitle->setTopLeftPosition(roundToInt(getWidth() * SETTINGSLABELMARGINWIDTH), 0); - + + sldExprCtrlSensitivity->setBounds(getLocalBounds().toFloat().getProportion(sliderBoundsProps).toNearestInt()); + int marginX = roundToInt(getParentWidth() * SETTINGSCONTROLMARGINTOAPPWIDTH); int buttonHeight = roundToInt(h * SETTINGSTOGGLEHEIGHTSCALAR); - btnInvertExpression->setBounds(marginX, proportionOfHeight(0.3f), w, buttonHeight); - btnInvertSustain->setBounds(marginX, proportionOfHeight(0.5), w, buttonHeight); - - sldExprCtrlSensitivity->setBounds(getLocalBounds().toFloat().getProportion(sliderBoundsProps).toNearestInt()); + int buttonWidth = roundToInt(sldExprCtrlSensitivity->getX() - marginX); + btnInvertExpression->setBounds(marginX, proportionOfHeight(0.3f), buttonWidth, buttonHeight); + btnInvertSustain->setBounds(marginX, proportionOfHeight(0.5), buttonWidth, buttonHeight); resizeLabelWithHeight(labelExprContrSensitivity.get(), buttonHeight * 1.2f, 1.0f, ""); labelExprContrSensitivity->setCentrePosition(sldExprCtrlSensitivity->getBounds().getCentreX(), btnInvertExpression->getBounds().getCentreY()); From ec01d39ea03be140467987542fc91cbb7c9192f0 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sun, 20 Jun 2021 16:14:02 -0400 Subject: [PATCH 021/183] Hide Import button before version is received --- Source/AllKeysOverview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/AllKeysOverview.cpp b/Source/AllKeysOverview.cpp index 3b6cc172..37a1f103 100644 --- a/Source/AllKeysOverview.cpp +++ b/Source/AllKeysOverview.cpp @@ -222,7 +222,7 @@ AllKeysOverview::AllKeysOverview() //[Constructor] You can add your own custom stuff here.. currentSetSelection = -1; - + buttonReceive->setVisible(false); showDeveloperMode(TerpstraSysExApplication::getApp().getPropertiesFile()->getBoolValue("DeveloperMode", false)); //[/Constructor] } @@ -415,6 +415,7 @@ void AllKeysOverview::showDeveloperMode(bool developerModeOn) void AllKeysOverview::firmwareRevisionReceived(FirmwareVersion version) { setFirmwareVersion(version); + buttonReceive->setVisible(true); } void AllKeysOverview::resetOctaveSize() From d4966dcf80e3932259400390da94595059a4a041 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sun, 20 Jun 2021 20:23:54 -0400 Subject: [PATCH 022/183] Connection label & logo in red when offline --- Source/MidiEditArea.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/MidiEditArea.cpp b/Source/MidiEditArea.cpp index 7c5479d7..0546fb16 100644 --- a/Source/MidiEditArea.cpp +++ b/Source/MidiEditArea.cpp @@ -225,7 +225,7 @@ void MidiEditArea::paint (juce::Graphics& g) g.fillRoundedRectangle(ioBounds, round(getHeight() * controlBoundsCornerRadius)); } - g.setColour(connectedColours[isConnected]); + g.setColour(connectedColours[(int)(isConnected && liveEditorBtn->getToggleState())]); drawPathToFillBounds(g, logomarkPath, logomarkBounds); //[/UserPaint] } @@ -437,6 +437,9 @@ void MidiEditArea::buttonClicked (juce::Button* buttonThatWasClicked) jassertfalse; break; } + + lblConnectionState->setColour(Label::ColourIds::textColourId, connectedColours[(int)liveEditorBtn->getToggleState()]); + repaint(); } //[/UserbuttonClicked_Post] } From d890598fbc6d10c5b9ff22b361a75c2314b99b15 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sun, 20 Jun 2021 21:13:04 -0400 Subject: [PATCH 023/183] Prevent invalid keytype through LumatoneController --- Source/LumatoneController.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/Source/LumatoneController.cpp b/Source/LumatoneController.cpp index 1930923d..e5a7836c 100644 --- a/Source/LumatoneController.cpp +++ b/Source/LumatoneController.cpp @@ -122,7 +122,7 @@ void LumatoneController::sendAllParamsOfBoard(int boardIndex, TerpstraKeys board for (int keyIndex = 0; keyIndex < octaveSize; keyIndex++) { auto key = &boardData.theKeys[keyIndex]; - midiDriver.sendKeyFunctionParameters(boardIndex, keyIndex, key->noteNumber, key->channelNumber, key->keyType); + midiDriver.sendKeyFunctionParameters(boardIndex, keyIndex, key->noteNumber, key->channelNumber, key->keyType & 0x3); midiDriver.sendKeyLightParameters(boardIndex, keyIndex, key->colour.getRed(), key->colour.getGreen(), key->colour.getBlue()); } } @@ -131,7 +131,7 @@ void LumatoneController::sendAllParamsOfBoard(int boardIndex, TerpstraKeys board for (int keyIndex = 0; keyIndex < octaveSize; keyIndex++) { auto key = &boardData.theKeys[keyIndex]; - midiDriver.sendKeyFunctionParameters(boardIndex, keyIndex, key->noteNumber, key->channelNumber, key->keyType); + midiDriver.sendKeyFunctionParameters(boardIndex, keyIndex, key->noteNumber, key->channelNumber, key->keyType & 0x3); midiDriver.sendKeyLightParameters_Version_1_0_0(boardIndex, keyIndex, key->colour.getRed() / 2, key->colour.getGreen() / 2, key->colour.getBlue() / 2); } } @@ -233,14 +233,9 @@ void LumatoneController::testCurrentDeviceConnection() // Send parametrization of one key to the device void LumatoneController::sendKeyParam(int boardIndex, int keyIndex, TerpstraKey keyData) -{ - // Enum is 1-based making LumatoneKeyType::disabled = 4, but should send value 0 - int keyType = keyData.keyType; - if (keyType >= LumatoneKeyType::disabled) - keyType = 0; - +{ // Default CC polarity = 1, Inverted CC polarity = 0 - sendKeyConfig(boardIndex, keyIndex, keyData.noteNumber, keyData.channelNumber, keyType, keyData.ccFaderDefault); + sendKeyConfig(boardIndex, keyIndex, keyData.noteNumber, keyData.channelNumber, keyData.keyType, keyData.ccFaderDefault); sendKeyColourConfig(boardIndex, keyIndex, keyData.colour); } @@ -272,7 +267,7 @@ void LumatoneController::sendTableConfig(TerpstraVelocityCurveConfig::VelocityCu // Send note, channel, cc, and fader polarity data void LumatoneController::sendKeyConfig(int boardIndex, int keyIndex, int noteOrCCNum, int channel, int keyType, bool faderUpIsNull) { - midiDriver.sendKeyFunctionParameters(boardIndex, keyIndex, noteOrCCNum, channel, keyType, faderUpIsNull); + midiDriver.sendKeyFunctionParameters(boardIndex, keyIndex, noteOrCCNum, channel, keyType & 0x3, faderUpIsNull); } void LumatoneController::sendKeyColourConfig(int boardIndex, int keyIndex, Colour colour) @@ -740,7 +735,7 @@ FirmwareSupport::Error LumatoneController::handlePingResponse(const MidiMessage& void LumatoneController::handleMidiDriverError(FirmwareSupport::Error errorToHandle, int commandReceived) { - DBG("ERROR: " + firmwareSupport.errorToString(errorToHandle)); + DBG("ERROR from command " + String(commandReceived) + ": " + firmwareSupport.errorToString(errorToHandle)); // Generic handling if (commandReceived < CHANGE_KEY_NOTE) From d106ba3c71b57e17053eac15376041abd1fcf8cd Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sun, 20 Jun 2021 21:56:25 -0400 Subject: [PATCH 024/183] Temp. revert alert window style --- Source/LumatoneEditorLookAndFeel.h | 56 +++++++++++++++--------------- Source/MidiEditArea.cpp | 2 +- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Source/LumatoneEditorLookAndFeel.h b/Source/LumatoneEditorLookAndFeel.h index 7dcd66d6..33236f91 100644 --- a/Source/LumatoneEditorLookAndFeel.h +++ b/Source/LumatoneEditorLookAndFeel.h @@ -1093,24 +1093,24 @@ class LumatoneEditorLookAndFeel : public LookAndFeel_V4 // return window; //} - virtual void drawAlertBox(Graphics& g, AlertWindow& window, const Rectangle &textArea, TextLayout& layout) override - { - g.setColour(findColour(AlertWindow::ColourIds::backgroundColourId)); - //g.fillRoundedRectangle(window.getLocalBounds().toFloat(), 15); - g.fillAll(); + //virtual void drawAlertBox(Graphics& g, AlertWindow& window, const Rectangle &textArea, TextLayout& layout) override + //{ + // g.setColour(findColour(AlertWindow::ColourIds::backgroundColourId)); + // //g.fillRoundedRectangle(window.getLocalBounds().toFloat(), 15); + // g.fillAll(); - g.setColour(findColour(AlertWindow::ColourIds::outlineColourId)); - g.drawRect(window.getLocalBounds(), 2); + // g.setColour(findColour(AlertWindow::ColourIds::outlineColourId)); + // g.drawRect(window.getLocalBounds(), 2); - g.setColour(findColour(AlertWindow::ColourIds::textColourId)); - float widthRatio = 0.05f; - float heightRatio = 0.15f; - - layout.draw(g, - textArea.constrainedWithin( - window.getLocalBounds().reduced(window.getWidth() * widthRatio, window.getHeight() * heightRatio) - ).toFloat()); - } + // g.setColour(findColour(AlertWindow::ColourIds::textColourId)); + // float widthRatio = 0.05f; + // float heightRatio = 0.15f; + // + // layout.draw(g, + // textArea.constrainedWithin( + // window.getLocalBounds().reduced(window.getWidth() * widthRatio, window.getHeight() * heightRatio) + // ).toFloat()); + //} //virtual Array getWidthsForTextButtons(AlertWindow& window, const Array& btns) override //{ @@ -1122,20 +1122,20 @@ class LumatoneEditorLookAndFeel : public LookAndFeel_V4 // return 16; //} - virtual Font getAlertWindowTitleFont() override - { - return getAppFont(LumatoneEditorFont::UniviaProBold).withHeight(18); - } + //virtual Font getAlertWindowTitleFont() override + //{ + // return getAppFont(LumatoneEditorFont::UniviaProBold).withHeight(18); + //} - virtual Font getAlertWindowMessageFont() override - { - return getAppFont(LumatoneEditorFont::GothamNarrowMedium).withHeight(16); - } + //virtual Font getAlertWindowMessageFont() override + //{ + // return getAppFont(LumatoneEditorFont::GothamNarrowMedium).withHeight(16); + //} - virtual Font getAlertWindowFont() override - { - return getAppFont(LumatoneEditorFont::GothamNarrowMedium).withHeight(14); - } + //virtual Font getAlertWindowFont() override + //{ + // return getAppFont(LumatoneEditorFont::GothamNarrowMedium).withHeight(14); + //} public: //============================================================================================== diff --git a/Source/MidiEditArea.cpp b/Source/MidiEditArea.cpp index 0546fb16..1c4eb111 100644 --- a/Source/MidiEditArea.cpp +++ b/Source/MidiEditArea.cpp @@ -584,7 +584,7 @@ void MidiEditArea::onOpenConnectionToDevice() alert->addButton("Send Editor layout", 1); alert->addButton("Keep Editing Offline", 0); alert->addButton("Import From Lumatone", 2); - alert->setLookAndFeel(&lookAndFeel); + //alert->setLookAndFeel(&lookAndFeel); /* alert = lookAndFeel.createAlertWindow("Connection established!", translate("Do you want to send the current setup to your Lumatone?"), "Import from Lumatone", From 04bbc1aa68819bbcdb84eb134dc2b6ae8a1a46a4 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Wed, 23 Jun 2021 20:24:44 -0400 Subject: [PATCH 025/183] Fix Connected label resizing --- Source/MidiEditArea.cpp | 25 +++++++++++-------------- Source/MidiEditArea.h | 3 --- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/Source/MidiEditArea.cpp b/Source/MidiEditArea.cpp index 1c4eb111..5dbe1430 100644 --- a/Source/MidiEditArea.cpp +++ b/Source/MidiEditArea.cpp @@ -213,7 +213,7 @@ void MidiEditArea::paint (juce::Graphics& g) //[UserPaint] Add your own custom painting code here.. g.fillAll(lookAndFeel.findColour(LumatoneEditorColourIDs::LightBackground)); - // Dark backrgound for title and logomark + // Dark background for title and logomark g.setColour(lookAndFeel.findColour(LumatoneEditorColourIDs::DarkBackground)); g.fillRect(lumatoneLabelBounds); g.fillRect(connectivityArea); @@ -249,9 +249,14 @@ void MidiEditArea::resized() round(w * controlBoundsWidth), round(h * controlBoundsHeight) ); + int logomarkSize = round(h * logomarkHeight); + logomarkBounds.setSize(logomarkSize, logomarkSize); + logomarkBounds.setCentre(ioBounds.getRight() + roundToInt((getWidth() - ioBounds.getRight()) * 0.5f), round(h * 0.5f)); + if (isConnected) { - resizeLabelWithHeight(lblEditMode.get(), round(h* editModeHeight)); + int lblHeight = roundToInt(h * editModeHeight); + resizeLabelWithHeight(lblEditMode.get(), lblHeight); lblEditMode->setTopLeftPosition( lumatoneLabelBounds.getRight() + round(w * editModeX), round((h - lblEditMode->getHeight()) * 0.5f) @@ -267,15 +272,12 @@ void MidiEditArea::resized() liveEditorBtn->getRight(), liveEditorBtn->getY(), round(w * offlineEditButtonWidth), liveEditorBtn->getHeight() ); - connectivityArea = getBounds().toFloat().withLeft(round(w * connectedAreaX)); - lblConnectionState->setJustificationType (juce::Justification::centredLeft); - resizeLabelWithHeight(lblConnectionState.get(), round(h * connectivityHeight)); - lblConnectionState->setTopLeftPosition( - round(w * connectedX), - round((h - lblConnectionState->getHeight()) * 0.5f) - ); + int logoMargin = w - logomarkBounds.getRight(); + lblConnectionState->setTopLeftPosition(connectivityArea.getX(), round((h - lblHeight) * 0.5f)); + lblConnectionState->setSize(logomarkBounds.getX() - connectivityArea.getX() - logoMargin, lblHeight); + lblConnectionState->setJustificationType (juce::Justification::centredRight); } else { @@ -322,11 +324,6 @@ void MidiEditArea::resized() offlineMsgLabel->setSize(connectivityArea.getX() - pleaseConnectLabel->getX(), round(h * connectionDirectionsHeight)); offlineMsgLabel->setFont(offlineMsgLabel->getFont().withHeight(offlineMsgLabel->getHeight())); } - - - int logomarkSize = round(h * logomarkHeight); - logomarkBounds.setSize(logomarkSize, logomarkSize); - logomarkBounds.setCentre(ioBounds.getRight() + roundToInt((getWidth() - ioBounds.getRight()) * 0.5f), round(h* 0.5f)); //[/UserResized] } diff --git a/Source/MidiEditArea.h b/Source/MidiEditArea.h index 2ce58a49..12ba5ad3 100644 --- a/Source/MidiEditArea.h +++ b/Source/MidiEditArea.h @@ -169,11 +169,8 @@ class MidiEditArea : public Component, const float connectedAreaX = 0.8387f; const float controlBoundsMarginScalar = 0.0325f; - const float connectedX = 0.871f; const float connectivityHeight = 0.1957f; - const float logomarkX = 0.9559f; - const float logomarkY = 0.2222f; const float logomarkHeight = 0.5f; //[/UserVariables] From 1766b4121035b73c3a3881d1c008cd9016ae1852 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Wed, 23 Jun 2021 22:10:11 -0400 Subject: [PATCH 026/183] Improve resizing of palette popup --- Source/ColourSelectionPanels.h | 50 +++++++++++++++++----------------- Source/HexagonPalette.h | 10 +++---- Source/MainComponent.h | 4 +-- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Source/ColourSelectionPanels.h b/Source/ColourSelectionPanels.h index 17b88eb6..c38d6a2f 100644 --- a/Source/ColourSelectionPanels.h +++ b/Source/ColourSelectionPanels.h @@ -48,27 +48,27 @@ class ColourPalettesPanel : public Component int getHeightFromNumRows(int numRowsIn) { - return round(viewableHeight * 0.5f * numRowsIn); + return roundToInt(viewableHeight * 0.48f * numRowsIn); } void paint(Graphics& g) override { ////Draws rectangles around items and margins -// for (auto item : flexBox.items) -// { -// g.setColour(Colours::red); -// g.drawRect(item.currentBounds); -// -// g.setColour(Colours::green); -// g.drawRect(item.currentBounds.getX(), item.currentBounds.getBottom(), item.width, item.margin.bottom, 1.0f); -// -// g.setColour(Colours::yellow); -// g.drawRect(item.currentBounds.getX() - item.margin.left - 1, item.currentBounds.getY(), item.margin.left - 1, item.currentBounds.getHeight(), 1.0f); -// g.drawRect(item.currentBounds.getRight() + 1, item.currentBounds.getY(), item.margin.right - 1, item.currentBounds.getHeight(), 1.0f); -// -// g.setColour(Colours::violet); -// g.drawRect(item.currentBounds.getX(), item.currentBounds.getY() - item.margin.top, item.width, item.margin.top); -// } + //for (auto item : flexBox.items) + //{ + // g.setColour(Colours::red); + // g.drawRect(item.currentBounds); + + // g.setColour(Colours::green); + // g.drawRect(item.currentBounds.getX(), item.currentBounds.getBottom(), item.width, item.margin.bottom, 1.0f); + + // g.setColour(Colours::yellow); + // g.drawRect(item.currentBounds.getX() - item.margin.left - 1, item.currentBounds.getY(), item.margin.left - 1, item.currentBounds.getHeight(), 1.0f); + // g.drawRect(item.currentBounds.getRight() + 1, item.currentBounds.getY(), item.margin.right - 1, item.currentBounds.getHeight(), 1.0f); + + // g.setColour(Colours::violet); + // g.drawRect(item.currentBounds.getX(), item.currentBounds.getY() - item.margin.top, item.width, item.margin.top); + //} }; void resized() override @@ -238,12 +238,12 @@ class ColourPalettesPanel : public Component Array> controlGroupHitBoxes; int lastPaletteMouseOver = -1; - const float itemWidthScalar = 0.28f; - const float itemHeightScalar = 0.25f; + const float itemWidthScalar = 0.265f; + const float itemHeightScalar = 0.24f; - const float topMarginScalar = 0.042f; - const float horizontalMarginScalar = 0.025f; - const float bottomMarginScalar = 0.075f; + const float topMarginScalar = 0.06f; + const float horizontalMarginScalar = 0.0367f; + const float bottomMarginScalar = 0.08f; const float btmMarginCtrlScalar = 0.06f; const float buttonWidthScalar = 0.333333f; @@ -401,19 +401,19 @@ class PaletteEditPanel : public Component, float leftCenter = leftWidth * 0.5f; resizeLabelWithHeight(editPaletteLabel.get(), proportionOfHeight(editPaletteHeight)); - editPaletteLabel->setCentrePosition(leftCenter, round(editPaletteLabel->getHeight() * 0.5f + proportionOfHeight(editPaletteLabelY))); + editPaletteLabel->setCentrePosition(leftCenter, roundToInt(editPaletteLabel->getHeight() * 0.5f + proportionOfHeight(editPaletteLabelY))); float paletteWidth = proportionOfWidth(paletteWidthScalar); float paletteHeight = proportionOfHeight(paletteHeightScalar); paletteControl->setSize(paletteWidth, paletteHeight); - paletteControl->setCentrePosition(leftCenter, round(paletteHeight * 0.5f + proportionOfHeight(paletteY))); + paletteControl->setCentrePosition(leftCenter, roundToInt(paletteHeight * 0.5f + proportionOfHeight(paletteY))); saveButton->setSize(proportionOfWidth(buttonWidth), proportionOfHeight(buttonHeight)); - saveButton->setCentrePosition(leftCenter, round(saveButton->getHeight() * 0.5f + proportionOfHeight(buttonY))); + saveButton->setCentrePosition(leftCenter, roundToInt(saveButton->getHeight() * 0.5f + proportionOfHeight(buttonY))); cancelButton->setBounds(saveButton->getBounds().translated(0, saveButton->getHeight() * 1.125f)); colourPicker->setSize(proportionOfWidth(pickerWidth), proportionOfHeight(pickerHeight)); - colourPicker->setTopLeftPosition(leftWidth, round((getHeight() - colourPicker->getHeight()) * 0.5f)); + colourPicker->setTopLeftPosition(leftWidth, roundToInt((getHeight() - colourPicker->getHeight()) * 0.5f)); float leftMargin = colourPicker->getRight() * 0.03f * 0.5f; paletteNameEditor->setBounds(Rectangle( diff --git a/Source/HexagonPalette.h b/Source/HexagonPalette.h index 645fb58f..5127f5ce 100644 --- a/Source/HexagonPalette.h +++ b/Source/HexagonPalette.h @@ -50,11 +50,11 @@ class HexagonPalette: public Palette g.setColour(getSwatchColour(i)); g.fillPath(swatch); - -#if JUCE_DEBUG - g.setColour(getSwatchColour(i).contrasting()); - g.drawFittedText(String(i), swatch.getBounds().toNearestInt(), Justification::centred, 1); -#endif +// +//#if JUCE_DEBUG +// g.setColour(getSwatchColour(i).contrasting()); +// g.drawFittedText(String(i), swatch.getBounds().toNearestInt(), Justification::centred, 1); +//#endif } if (selectedSwatch >= 0) diff --git a/Source/MainComponent.h b/Source/MainComponent.h index e5fc7dfd..b5964be2 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -151,8 +151,8 @@ class MainContentComponent : public Component, const float footerAreaY = 0.96f; - const float popupWidth = 0.2879f; - const float popupHeight = 0.2615f; + const float popupWidth = 0.3f; + const float popupHeight = 0.273f; const float lumatoneVersionMarginX = 0.02f; const float lumatoneVersionWidth = 0.2f; From 2093218ccec75d88b8bea83a403da28b722aced3 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Wed, 23 Jun 2021 22:19:03 -0400 Subject: [PATCH 027/183] refactor round to roundToInt --- Source/AllKeysOverview.cpp | 24 ++++++++--------- Source/GeneralOptionsDlg.cpp | 2 +- Source/IsomorphicMassAssign.cpp | 8 +++--- Source/LumatoneEditorStyleCommon.h | 42 +++++++++++++++--------------- Source/MidiEditArea.cpp | 40 ++++++++++++++-------------- Source/PedalSensitivityDlg.cpp | 2 +- Source/SingleNoteAssign.cpp | 4 +-- 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Source/AllKeysOverview.cpp b/Source/AllKeysOverview.cpp index 37a1f103..531b1e43 100644 --- a/Source/AllKeysOverview.cpp +++ b/Source/AllKeysOverview.cpp @@ -61,8 +61,8 @@ void KeyMiniDisplayInsideAllKeysOverview::paint(Graphics& g) if (colourGraphic && shadowGraphic) { - int x = round((getWidth() - colourGraphic->getWidth()) * 0.5f); - int y = round((getHeight() - colourGraphic->getHeight()) * 0.5f); + int x = roundToInt((getWidth() - colourGraphic->getWidth()) * 0.5f); + int y = roundToInt((getHeight() - colourGraphic->getHeight()) * 0.5f); g.drawImageAt(*colourGraphic, x, y, true); g.drawImageAt(*shadowGraphic, x, y); @@ -283,27 +283,27 @@ void AllKeysOverview::resized() graphicWidth, graphicHeight ); - int btnHeight = round(getHeight() * saveLoadH); - int btnMargin = round(getWidth() * saveloadMarginW); - int saveLoadWidth = round(getWidth() * saveLoadW); - int btnY = lumatoneBounds.getY() - round(getHeight() * btnYFromImageTop); + int btnHeight = roundToInt(getHeight() * saveLoadH); + int btnMargin = roundToInt(getWidth() * saveloadMarginW); + int saveLoadWidth = roundToInt(getWidth() * saveLoadW); + int btnY = lumatoneBounds.getY() - roundToInt(getHeight() * btnYFromImageTop); - int halfWidthX = round(getWidth() * 0.5f); + int halfWidthX = roundToInt(getWidth() * 0.5f); btnLoadFile->setBounds(halfWidthX - btnMargin - saveLoadWidth, btnY, saveLoadWidth, btnHeight); btnSaveFile->setBounds(halfWidthX + btnMargin, btnY, saveLoadWidth, btnHeight); - octaveLineY = lumatoneBounds.getBottom() + round(getHeight() * octaveLineYRatio); + octaveLineY = lumatoneBounds.getBottom() + roundToInt(getHeight() * octaveLineYRatio); - int importY = lumatoneBounds.getY() - round(getHeight() * importYFromImageTop); - int importWidth = round(getWidth() * importW); + int importY = lumatoneBounds.getY() - roundToInt(getHeight() * importYFromImageTop); + int importWidth = roundToInt(getWidth() * importW); buttonReceive->setBounds(lumatoneBounds.getRight() - importWidth, importY, importWidth, btnHeight); resizeLabelWithHeight(lblFirmwareVersion.get(), btnHeight * 0.6f); lblFirmwareVersion->setTopLeftPosition(lumatoneBounds.getX(), lumatoneBounds.getY() - btnHeight * 0.6f); - int keyWidth = round(lumatoneBounds.getWidth() * keyW); - int keyHeight = round(lumatoneBounds.getHeight() * keyH); + int keyWidth = roundToInt(lumatoneBounds.getWidth() * keyW); + int keyHeight = roundToInt(lumatoneBounds.getHeight() * keyH); // Scale key graphics once lumatoneGraphic = imageProcessor->resizeImage(ImageCache::getFromHashCode(LumatoneEditorAssets::LumatoneGraphic), lumatoneBounds.getWidth(), lumatoneBounds.getHeight()); diff --git a/Source/GeneralOptionsDlg.cpp b/Source/GeneralOptionsDlg.cpp index 2e0ffe6c..4effdbea 100644 --- a/Source/GeneralOptionsDlg.cpp +++ b/Source/GeneralOptionsDlg.cpp @@ -91,7 +91,7 @@ void GeneralOptionsDlg::resized() //[UserResized] Add your own custom resize handling here.. - roundedCornerSize = round(getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); + roundedCornerSize = roundToInt(getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); resizeLabelWithHeight(labelGeneralSettingslTitle.get(), roundToInt(getHeight() * SETTINGSLABELHEIGHT)); labelGeneralSettingslTitle->setTopLeftPosition(roundToInt(getWidth() * SETTINGSLABELMARGINWIDTH), 0); diff --git a/Source/IsomorphicMassAssign.cpp b/Source/IsomorphicMassAssign.cpp index 75c51f30..61e7bc6e 100644 --- a/Source/IsomorphicMassAssign.cpp +++ b/Source/IsomorphicMassAssign.cpp @@ -252,11 +252,11 @@ void IsomorphicMassAssign::resized() int width = getWidth(); int height = getHeight(); - int controlWidth = round(width * 0.4f); - int controlHeight = round(height * controlHeightScalar); + int controlWidth = roundToInt(width * 0.4f); + int controlHeight = roundToInt(height * controlHeightScalar); - int xMargin = round(width * xMarginScalar); - int yMargin = round(height * yMarginScalar); + int xMargin = roundToInt(width * xMarginScalar); + int yMargin = roundToInt(height * yMarginScalar); int xEnd = width - xMargin; flexBox.items.clear(); diff --git a/Source/LumatoneEditorStyleCommon.h b/Source/LumatoneEditorStyleCommon.h index de7d1f4d..d970c107 100644 --- a/Source/LumatoneEditorStyleCommon.h +++ b/Source/LumatoneEditorStyleCommon.h @@ -271,10 +271,10 @@ static void addArcToPath(Path& pathIn, Rectangle& ellipseBounds, float fr /// /// /// -static void setWidthRetainingAspectRatio(Component* component, const Image& image, int widthIn) -{ - component->setSize(widthIn, round(image.getHeight() / (float) image.getWidth() * widthIn)); -} +//static void setWidthRetainingAspectRatio(Component* component, const Image& image, int widthIn) +//{ +// component->setSize(widthIn, round(image.getHeight() / (float) image.getWidth() * widthIn)); +//} /// /// Sets the height of a component while retaining the aspect ratio of a given image @@ -282,10 +282,10 @@ static void setWidthRetainingAspectRatio(Component* component, const Image& imag /// /// /// -static void setHeightRetainingAspectRatio(Component* component, const Image& image, int heightIn) -{ - component->setSize(round(image.getWidth() / (float) image.getHeight() * heightIn), heightIn); -} +//static void setHeightRetainingAspectRatio(Component* component, const Image& image, int heightIn) +//{ +// component->setSize(round(image.getWidth() / (float) image.getHeight() * heightIn), heightIn); +//} /// /// Sets the width of an ImageComponent while retaining the aspect ratio of its image @@ -304,10 +304,10 @@ static void setHeightRetainingAspectRatio(Component* component, const Image& ima /// /// /// -static void setHeightRetainingAspectRatio(ImageComponent* component, int heightIn) -{ - setHeightRetainingAspectRatio(component, component->getImage(), heightIn); -} +//static void setHeightRetainingAspectRatio(ImageComponent* component, int heightIn) +//{ +// setHeightRetainingAspectRatio(component, component->getImage(), heightIn); +//} /// /// Sets the width of an ImageButton while retaining the aspect ratio of its normal image @@ -315,10 +315,10 @@ static void setHeightRetainingAspectRatio(ImageComponent* component, int heightI /// /// /// -static void setWidthRetainingAspectRatio(ImageButton* component, int widthIn) -{ - setWidthRetainingAspectRatio(component, component->getNormalImage(), widthIn); -} +//static void setWidthRetainingAspectRatio(ImageButton* component, int widthIn) +//{ +// setWidthRetainingAspectRatio(component, component->getNormalImage(), widthIn); +//} /// /// Sets the height of an ImageButton while retaining the aspect ratio of its normal image @@ -326,10 +326,10 @@ static void setWidthRetainingAspectRatio(ImageButton* component, int widthIn) /// /// /// -static void setHeightRetainingAspectRatio(ImageButton* component, int heightIn) -{ - setHeightRetainingAspectRatio(component, component->getNormalImage(), heightIn); -} +//static void setHeightRetainingAspectRatio(ImageButton* component, int heightIn) +//{ +// setHeightRetainingAspectRatio(component, component->getNormalImage(), heightIn); +//} static void resizeLabelWithHeight(Label* label, int height, float fontHeightScalar = 1.0f, String textSuffix = "_") { @@ -381,7 +381,7 @@ static float scalarToFitString(Label& labelIn) static void resizeToggleButtonWithHeight(ToggleButton* btn, Font font, int heightIn, String textSuffix = "_") { font.setHeight(font.getHeight() * GLOBALFONTSCALAR); - btn->setSize(btn->getHeight() + round(font.getStringWidth(btn->getButtonText() + textSuffix)), heightIn); + btn->setSize(btn->getHeight() + roundToInt(font.getStringWidth(btn->getButtonText() + textSuffix)), heightIn); } static void drawPathToFillBounds(Graphics& g, const Path& path, Rectangle boundsToFill) diff --git a/Source/MidiEditArea.cpp b/Source/MidiEditArea.cpp index 5dbe1430..4c75d41d 100644 --- a/Source/MidiEditArea.cpp +++ b/Source/MidiEditArea.cpp @@ -222,7 +222,7 @@ void MidiEditArea::paint (juce::Graphics& g) if (!isConnected) { g.setColour(lookAndFeel.findColour(LumatoneEditorColourIDs::LightBackground)); - g.fillRoundedRectangle(ioBounds, round(getHeight() * controlBoundsCornerRadius)); + g.fillRoundedRectangle(ioBounds, roundToInt(getHeight() * controlBoundsCornerRadius)); } g.setColour(connectedColours[(int)(isConnected && liveEditorBtn->getToggleState())]); @@ -239,43 +239,43 @@ void MidiEditArea::resized() //[UserResized] Add your own custom resize handling here.. - lumatoneLabelBounds = getBounds().withRight(round(w * lumatoneLabelAreaWidth)); + lumatoneLabelBounds = getBounds().withRight(roundToInt(w * lumatoneLabelAreaWidth)); resizeLabelWithWidth(lumatoneLabel.get(), lumatoneLabelBounds.proportionOfWidth(lumatoneLabelWidthInArea)); lumatoneLabel->setCentrePosition(lumatoneLabelBounds.getCentre()); // Also used to position logomark ioBounds.setBounds( - round(w * controlBoundsX), round(h * controlBoundsY), - round(w * controlBoundsWidth), round(h * controlBoundsHeight) + roundToInt(w * controlBoundsX), roundToInt(h * controlBoundsY), + roundToInt(w * controlBoundsWidth), roundToInt(h * controlBoundsHeight) ); - int logomarkSize = round(h * logomarkHeight); + int logomarkSize = roundToInt(h * logomarkHeight); logomarkBounds.setSize(logomarkSize, logomarkSize); - logomarkBounds.setCentre(ioBounds.getRight() + roundToInt((getWidth() - ioBounds.getRight()) * 0.5f), round(h * 0.5f)); + logomarkBounds.setCentre(ioBounds.getRight() + roundToInt((getWidth() - ioBounds.getRight()) * 0.5f), roundToInt(h * 0.5f)); if (isConnected) { int lblHeight = roundToInt(h * editModeHeight); resizeLabelWithHeight(lblEditMode.get(), lblHeight); lblEditMode->setTopLeftPosition( - lumatoneLabelBounds.getRight() + round(w * editModeX), - round((h - lblEditMode->getHeight()) * 0.5f) + lumatoneLabelBounds.getRight() + roundToInt(w * editModeX), + roundToInt((h - lblEditMode->getHeight()) * 0.5f) ); - liveEditorBtn->setSize(round(w * liveEditButtonWidth), round(h* editModeButtonHeight)); + liveEditorBtn->setSize(roundToInt(w * liveEditButtonWidth), roundToInt(h* editModeButtonHeight)); liveEditorBtn->setTopLeftPosition( lblEditMode->getRight(), - round((h - liveEditorBtn->getHeight()) * 0.5f) + roundToInt((h - liveEditorBtn->getHeight()) * 0.5f) ); offlineEditorBtn->setBounds( - liveEditorBtn->getRight(), liveEditorBtn->getY(), round(w * offlineEditButtonWidth), liveEditorBtn->getHeight() + liveEditorBtn->getRight(), liveEditorBtn->getY(), roundToInt(w * offlineEditButtonWidth), liveEditorBtn->getHeight() ); - connectivityArea = getBounds().toFloat().withLeft(round(w * connectedAreaX)); + connectivityArea = getBounds().toFloat().withLeft(roundToInt(w * connectedAreaX)); int logoMargin = w - logomarkBounds.getRight(); - lblConnectionState->setTopLeftPosition(connectivityArea.getX(), round((h - lblHeight) * 0.5f)); + lblConnectionState->setTopLeftPosition(connectivityArea.getX(), roundToInt((h - lblHeight) * 0.5f)); lblConnectionState->setSize(logomarkBounds.getX() - connectivityArea.getX() - logoMargin, lblHeight); lblConnectionState->setJustificationType (juce::Justification::centredRight); } @@ -283,10 +283,10 @@ void MidiEditArea::resized() { int controlHeight = roundToInt(ioBounds.getHeight() * midiDeviceControlBoundsHeight); - connectivityArea = getBounds().toFloat().withLeft(round(w * disconnectedAreaX)); + connectivityArea = getBounds().toFloat().withLeft(roundToInt(w * disconnectedAreaX)); - int lblMarginX = round(ioBounds.getWidth() * controlBoundsMarginScalar); - int lblMarginY = round((ioBounds.getHeight() - h * connectivityHeight) * 0.5f); + int lblMarginX = roundToInt(ioBounds.getWidth() * controlBoundsMarginScalar); + int lblMarginY = roundToInt((ioBounds.getHeight() - h * connectivityHeight) * 0.5f); ioAreaFlexBox.items.clear(); ioAreaFlexBox.items.add(FlexItem(*btnAutoConnect).withFlex(0).withWidth(controlHeight * 1.6f).withHeight(controlHeight)); @@ -317,11 +317,11 @@ void MidiEditArea::resized() ioBounds.reduced(lblMarginX, lblMarginY) ); - pleaseConnectLabel->setTopLeftPosition(round(w * pleaseConnectX), round(h * pleaseConnectY)); - resizeLabelWithHeight(pleaseConnectLabel.get(), round(h * pleaseConnectHeight)); + pleaseConnectLabel->setTopLeftPosition(roundToInt(w * pleaseConnectX), roundToInt(h * pleaseConnectY)); + resizeLabelWithHeight(pleaseConnectLabel.get(), roundToInt(h * pleaseConnectHeight)); - offlineMsgLabel->setTopLeftPosition(round(w * connectionDirectionsX), round(h * connectionDirectionsY)); - offlineMsgLabel->setSize(connectivityArea.getX() - pleaseConnectLabel->getX(), round(h * connectionDirectionsHeight)); + offlineMsgLabel->setTopLeftPosition(roundToInt(w * connectionDirectionsX), roundToInt(h * connectionDirectionsY)); + offlineMsgLabel->setSize(connectivityArea.getX() - pleaseConnectLabel->getX(), roundToInt(h * connectionDirectionsHeight)); offlineMsgLabel->setFont(offlineMsgLabel->getFont().withHeight(offlineMsgLabel->getHeight())); } //[/UserResized] diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index c588b7d4..0f468dcb 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -132,7 +132,7 @@ void PedalSensitivityDlg::resized() //[UserResized] Add your own custom resize handling here.. - roundedCornerSize = round(getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); + roundedCornerSize = roundToInt(getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); resizeLabelWithHeight(labelPedalTitle.get(), roundToInt(getHeight() * SETTINGSLABELHEIGHT)); labelPedalTitle->setTopLeftPosition(roundToInt(getWidth() * SETTINGSLABELMARGINWIDTH), 0); diff --git a/Source/SingleNoteAssign.cpp b/Source/SingleNoteAssign.cpp index caaa9ec1..352cff00 100644 --- a/Source/SingleNoteAssign.cpp +++ b/Source/SingleNoteAssign.cpp @@ -284,9 +284,9 @@ void SingleNoteAssign::resized() float h = getHeight(); if (getParentComponent()) // This changes when the tab changes - roundedCornerSize = round(getParentComponent()->getParentComponent()->getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); + roundedCornerSize = roundToInt(getParentComponent()->getParentComponent()->getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); - int controlAreaTop = round(h * controlAreaYScalar); + int controlAreaTop = roundToInt(h * controlAreaYScalar); int toggleHeight = roundToInt(h * toggleHeightScalar); int toggleHeightScaled = roundToInt(toggleHeight * GLOBALFONTSCALAR); From c962592a49cfd23eac64d3f2abab5d59e4720f50 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 24 Jun 2021 19:53:21 -0400 Subject: [PATCH 028/183] Decoupled expression & sustain pedal areas --- Source/LumatoneEditorLookAndFeel.h | 5 +- Source/LumatoneEditorStyleCommon.h | 2 +- Source/MainComponent.cpp | 4 - Source/NoteEditArea.cpp | 4 +- Source/PedalSensitivityDlg.cpp | 127 +++++++++++++++++++---------- Source/PedalSensitivityDlg.h | 12 +-- 6 files changed, 95 insertions(+), 59 deletions(-) diff --git a/Source/LumatoneEditorLookAndFeel.h b/Source/LumatoneEditorLookAndFeel.h index 33236f91..99a8d833 100644 --- a/Source/LumatoneEditorLookAndFeel.h +++ b/Source/LumatoneEditorLookAndFeel.h @@ -613,7 +613,10 @@ class LumatoneEditorLookAndFeel : public LookAndFeel_V4 label->setColour(Label::ColourIds::textColourId, textColour); int sliderSize = jmin(sld.getWidth(), sld.getHeight()); - sld.setTextBoxStyle(Slider::TextEntryBoxPosition::TextBoxBelow, false, roundToInt(sliderSize * 0.5f), roundToInt((sld.getHeight() - sliderSize * 0.5f) * 0.5f)); + sld.setTextBoxStyle(Slider::TextEntryBoxPosition::TextBoxBelow, false, + roundToInt(sliderSize * 0.5f), + roundToInt((sld.getHeight() - sliderSize * 0.5f) * 0.75f) + ); return label; } diff --git a/Source/LumatoneEditorStyleCommon.h b/Source/LumatoneEditorStyleCommon.h index de7d1f4d..1bc5fd37 100644 --- a/Source/LumatoneEditorStyleCommon.h +++ b/Source/LumatoneEditorStyleCommon.h @@ -32,7 +32,7 @@ #define SETTINGSAREAMARGINHEIGHT 0.1714f -#define SETTINGSLABELHEIGHT 0.14f +#define SETTINGSLABELHEIGHT 0.13f #define SETTINGSLABELMARGINWIDTH 0.01f #define SETTINGSCONTROLMARGINTOAPPWIDTH 0.01171875f diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index c54a5135..3ab6b613 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -346,10 +346,6 @@ void MainContentComponent::resized() controlsArea = getBounds().withTop(proportionOfHeight(controlsAreaY)).withBottom(footerY); // All keys overview/virtual keyboard playing - // New height of subset field area, with minimal value - int noteEditAreaWidth = noteEditArea->getWidth(); - int noteEditAreaHeight = noteEditArea->getHeight(); - int newKeysOverviewAreaHeight = jmax(controlsArea.getY() - midiAreaHeight, MINIMALTERPSTRAKEYSETAREAHEIGHT); allKeysOverview->setBounds(0, midiAreaHeight, newWidth, newKeysOverviewAreaHeight); diff --git a/Source/NoteEditArea.cpp b/Source/NoteEditArea.cpp index 847ab694..ab9fa706 100644 --- a/Source/NoteEditArea.cpp +++ b/Source/NoteEditArea.cpp @@ -139,7 +139,7 @@ void NoteEditArea::resized() resizeLabelWithHeight(labelWindowTitle.get(), roundToInt(octaveBoardSelectorTab->getHeight() * assignLabelTabDepthHeight)); labelWindowTitle->setTopLeftPosition(roundToInt(getWidth() * assignLabelMarginX), roundToInt((octaveTabsArea.getHeight() - labelWindowTitle->getHeight()) * 0.5f)); - + keyEditBounds.setBounds( getWidth() * keyEditMarginX, contentBackground.getHeight() * assignMarginYInContent + contentBackground.getY(), getWidth() * keyEditWidth, contentBackground.getHeight() * assignControlsHeightInContent @@ -153,7 +153,7 @@ void NoteEditArea::resized() // Single Key fields - keyEditBounds = contentBackground.withLeft(assignControlsBounds.getRight() + assignControlsBounds.getX() / 2); + keyEditBounds = contentBackground.withLeft(assignControlsBounds.getRight() + assignControlsBounds.getX() * 0.5f); tilingGeometry.fitTilingTo( keyEditBounds, diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index c588b7d4..0a82968b 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -35,7 +35,7 @@ PedalSensitivityDlg::PedalSensitivityDlg () //[/Constructor_pre] labelExprContrSensitivity.reset (new juce::Label ("new label", - TRANS("Sensitivity:"))); + TRANS("Sensitivity"))); addAndMakeVisible (labelExprContrSensitivity.get()); labelExprContrSensitivity->setFont (juce::Font (15.00f, juce::Font::plain).withTypefaceStyle ("Regular")); labelExprContrSensitivity->setJustificationType (juce::Justification::centredLeft); @@ -43,48 +43,61 @@ PedalSensitivityDlg::PedalSensitivityDlg () labelExprContrSensitivity->setColour (juce::TextEditor::textColourId, juce::Colours::black); labelExprContrSensitivity->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000)); - labelExprContrSensitivity->setBounds (6, 35, 64, 24); + labelExprContrSensitivity->setBounds (13, 152, 74, 24); btnInvertExpression.reset (new juce::ToggleButton ("btnInvertExpression")); addAndMakeVisible (btnInvertExpression.get()); - btnInvertExpression->setButtonText (TRANS("Invert Expression")); + btnInvertExpression->setButtonText (TRANS("Invert")); btnInvertExpression->addListener (this); - btnInvertExpression->setBounds (8, 96, 162, 24); + btnInvertExpression->setBounds (10, 32, 99, 24); - labelPedalTitle.reset (new juce::Label ("labelPedalTitle", - TRANS("Pedal Settings"))); - addAndMakeVisible (labelPedalTitle.get()); - labelPedalTitle->setFont (juce::Font (18.00f, juce::Font::plain).withTypefaceStyle ("Regular")); - labelPedalTitle->setJustificationType (juce::Justification::centredLeft); - labelPedalTitle->setEditable (false, false, false); - labelPedalTitle->setColour (juce::Label::textColourId, juce::Colour (0xff61acc8)); - labelPedalTitle->setColour (juce::TextEditor::textColourId, juce::Colours::black); - labelPedalTitle->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000)); + lblExpression.reset (new juce::Label ("lblExpression", + TRANS("Expression"))); + addAndMakeVisible (lblExpression.get()); + lblExpression->setFont (juce::Font (18.00f, juce::Font::plain).withTypefaceStyle ("Regular")); + lblExpression->setJustificationType (juce::Justification::centredLeft); + lblExpression->setEditable (false, false, false); + lblExpression->setColour (juce::Label::textColourId, juce::Colour (0xff61acc8)); + lblExpression->setColour (juce::TextEditor::textColourId, juce::Colours::black); + lblExpression->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000)); - labelPedalTitle->setBounds (6, 3, 104, 24); + lblExpression->setBounds (6, 3, 104, 24); sldExprCtrlSensitivity.reset (new juce::Slider ("sldExprCtrlSensitivity")); addAndMakeVisible (sldExprCtrlSensitivity.get()); sldExprCtrlSensitivity->setRange (0, 127, 1); sldExprCtrlSensitivity->setSliderStyle (juce::Slider::RotaryHorizontalVerticalDrag); - sldExprCtrlSensitivity->setTextBoxStyle (juce::Slider::TextBoxLeft, false, 60, 20); + sldExprCtrlSensitivity->setTextBoxStyle (juce::Slider::TextBoxBelow, false, 60, 20); sldExprCtrlSensitivity->addListener (this); - sldExprCtrlSensitivity->setBounds (77, 12, 160, 72); + sldExprCtrlSensitivity->setBounds (-32, 49, 160, 97); btnInvertSustain.reset (new juce::ToggleButton ("btnInvertSustain")); addAndMakeVisible (btnInvertSustain.get()); - btnInvertSustain->setButtonText (TRANS("Invert Sustain")); + btnInvertSustain->setButtonText (TRANS("Invert")); btnInvertSustain->addListener (this); - btnInvertSustain->setBounds (8, 72, 150, 24); + btnInvertSustain->setBounds (125, 32, 86, 24); + + lblSustain.reset (new juce::Label ("lblSustain", + TRANS("Sustain"))); + addAndMakeVisible (lblSustain.get()); + lblSustain->setFont (juce::Font (18.00f, juce::Font::plain).withTypefaceStyle ("Regular")); + lblSustain->setJustificationType (juce::Justification::centredLeft); + lblSustain->setEditable (false, false, false); + lblSustain->setColour (juce::Label::textColourId, juce::Colour (0xff61acc8)); + lblSustain->setColour (juce::TextEditor::textColourId, juce::Colours::black); + lblSustain->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000)); + + lblSustain->setBounds (121, 3, 99, 24); //[UserPreSize] - labelPedalTitle->setFont(TerpstraSysExApplication::getApp().getAppFont(LumatoneEditorFont::UniviaProBold)); + lblExpression->setFont(TerpstraSysExApplication::getApp().getAppFont(LumatoneEditorFont::UniviaProBold)); + lblSustain->setFont(TerpstraSysExApplication::getApp().getAppFont(LumatoneEditorFont::UniviaProBold)); labelExprContrSensitivity->setFont(TerpstraSysExApplication::getApp().getAppFont(LumatoneEditorFont::GothamNarrowMedium)); - + labelExprContrSensitivity->setJustificationType(Justification::centred); TerpstraSysExApplication::getApp().getLumatoneController().addFirmwareListener(this); //[/UserPreSize] @@ -102,9 +115,10 @@ PedalSensitivityDlg::~PedalSensitivityDlg() labelExprContrSensitivity = nullptr; btnInvertExpression = nullptr; - labelPedalTitle = nullptr; + lblExpression = nullptr; sldExprCtrlSensitivity = nullptr; btnInvertSustain = nullptr; + lblSustain = nullptr; //[Destructor]. You can add your own custom destruction code here.. @@ -119,7 +133,8 @@ void PedalSensitivityDlg::paint (juce::Graphics& g) //[UserPaint] Add your own custom painting code here.. g.setColour(Colour(0xff212626)); - g.fillRoundedRectangle(getLocalBounds().toFloat().withTop(proportionOfHeight(SETTINGSAREAMARGINHEIGHT)), roundedCornerSize); + g.fillRoundedRectangle(expressionBounds, roundedCornerSize); + g.fillRoundedRectangle(sustainBounds, roundedCornerSize); //[/UserPaint] } @@ -132,21 +147,38 @@ void PedalSensitivityDlg::resized() //[UserResized] Add your own custom resize handling here.. - roundedCornerSize = round(getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); + roundedCornerSize = roundToInt(getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); - resizeLabelWithHeight(labelPedalTitle.get(), roundToInt(getHeight() * SETTINGSLABELHEIGHT)); - labelPedalTitle->setTopLeftPosition(roundToInt(getWidth() * SETTINGSLABELMARGINWIDTH), 0); + int areaMarginWidth = roundToInt(w * sectionMarginWidth) * 0.5f; + int areaMarginHeight = roundToInt(h * SETTINGSAREAMARGINHEIGHT); - sldExprCtrlSensitivity->setBounds(getLocalBounds().toFloat().getProportion(sliderBoundsProps).toNearestInt()); + expressionBounds = getLocalBounds().toFloat().withTop(areaMarginHeight).withRight(roundToInt(w * 0.5f - areaMarginWidth)); + sustainBounds = getLocalBounds().toFloat().withTop(areaMarginHeight).withLeft(roundToInt(w * 0.5f + areaMarginWidth)); - int marginX = roundToInt(getParentWidth() * SETTINGSCONTROLMARGINTOAPPWIDTH); - int buttonHeight = roundToInt(h * SETTINGSTOGGLEHEIGHTSCALAR); - int buttonWidth = roundToInt(sldExprCtrlSensitivity->getX() - marginX); - btnInvertExpression->setBounds(marginX, proportionOfHeight(0.3f), buttonWidth, buttonHeight); - btnInvertSustain->setBounds(marginX, proportionOfHeight(0.5), buttonWidth, buttonHeight); + int lblMarginX = roundToInt(w * SETTINGSLABELMARGINWIDTH); + int lblWidth = roundToInt(w * 0.5f); + int lblHeight = roundToInt(h * SETTINGSLABELHEIGHT); + lblExpression->setBounds(expressionBounds.getX() + lblMarginX, 0, lblWidth, lblHeight); + lblSustain->setBounds(sustainBounds.getX() + lblMarginX, 0, lblWidth, lblHeight); - resizeLabelWithHeight(labelExprContrSensitivity.get(), buttonHeight * 1.2f, 1.0f, ""); - labelExprContrSensitivity->setCentrePosition(sldExprCtrlSensitivity->getBounds().getCentreX(), btnInvertExpression->getBounds().getCentreY()); + int controlMargin = roundToInt(getParentWidth() * SETTINGSCONTROLMARGINTOAPPWIDTH); + int buttonHeight = roundToInt(h * SETTINGSTOGGLEHEIGHTSCALAR); + int buttonY = roundToInt(h * 0.3f); + btnInvertExpression->setBounds(expressionBounds.withTrimmedLeft(controlMargin).withTop(buttonY).withHeight(buttonHeight).toNearestInt()); + btnInvertSustain->setBounds(sustainBounds.withTrimmedLeft(controlMargin).withTop(buttonY).withHeight(buttonHeight).toNearestInt()); + + sldExprCtrlSensitivity->setBounds( + expressionBounds.reduced(expressionBounds.getWidth() * 0.2f, 0) + .withTop(btnInvertExpression->getBottom() + buttonHeight) + .withTrimmedBottom(buttonHeight * 1.5f) + .toNearestInt() + ); + + labelExprContrSensitivity->setBounds( + expressionBounds.withTop(sldExprCtrlSensitivity->getBottom() + buttonHeight * 0.1f) + .withTrimmedBottom(buttonHeight * 0.5f) + .toNearestInt() + ); //[/UserResized] } @@ -196,7 +228,8 @@ void PedalSensitivityDlg::lookAndFeelChanged() auto newLookAndFeel = dynamic_cast(&getLookAndFeel()); if (newLookAndFeel) { - labelPedalTitle->setColour(Label::ColourIds::textColourId, newLookAndFeel->findColour(LumatoneEditorColourIDs::LabelBlue)); + lblExpression->setColour(Label::ColourIds::textColourId, newLookAndFeel->findColour(LumatoneEditorColourIDs::LabelBlue)); + lblSustain->setColour(Label::ColourIds::textColourId, newLookAndFeel->findColour(LumatoneEditorColourIDs::LabelBlue)); labelExprContrSensitivity->setColour(Label::ColourIds::textColourId, newLookAndFeel->findColour(LumatoneEditorColourIDs::DescriptionText)); } } @@ -243,27 +276,31 @@ BEGIN_JUCER_METADATA initialHeight="96"> void cacheImages() { - //ImageCache::addImageToCache(ImageCache::getFromMemory(BinaryData::ImportIcon4x_png, BinaryData::ImportIcon4x_pngSize), LumatoneEditorAssets::ImportIcon); - //ImageCache::addImageToCache(ImageCache::getFromMemory(BinaryData::SaveIcon4x_png, BinaryData::SaveIcon4x_pngSize), LumatoneEditorAssets::SaveIcon); - //ImageCache::addImageToCache(ImageCache::getFromMemory(BinaryData::LoadIcon4x_png, BinaryData::LoadIcon4x_pngSize), LumatoneEditorAssets::LoadIcon); ImageCache::addImageToCache(ImageCache::getFromMemory(BinaryData::KeyboardBase_png, BinaryData::KeyboardBase_pngSize), LumatoneEditorAssets::LumatoneGraphic); ImageCache::addImageToCache(ImageCache::getFromMemory(BinaryData::KeybedShadows_png, BinaryData::KeybedShadows_pngSize), LumatoneEditorAssets::KeybedShadows); ImageCache::addImageToCache(ImageCache::getFromMemory(BinaryData::KeyShape2x_png, BinaryData::KeyShape2x_pngSize), LumatoneEditorAssets::KeyShape); From eeecb9589a25174093d7d12c2228529fb2960adc Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Fri, 25 Jun 2021 20:34:31 -0400 Subject: [PATCH 032/183] Improved toggle & control spacing --- Source/SingleNoteAssign.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/SingleNoteAssign.cpp b/Source/SingleNoteAssign.cpp index 3a130b30..23819584 100644 --- a/Source/SingleNoteAssign.cpp +++ b/Source/SingleNoteAssign.cpp @@ -309,6 +309,7 @@ void SingleNoteAssign::resized() instructionsAreaBounds.setBounds(0, 0, w, controlAreaTop); instructionsFont.setHeight(instructionsAreaBounds.getHeight() * fontHeightInBounds); controlsX = roundToInt(w * controlsXScalar); + instructionsBounds.setBounds(marginX, 0, w - marginX * 2, controlAreaTop); @@ -334,7 +335,7 @@ void SingleNoteAssign::resized() toggleItem.associatedComponent = btn; }; - auto controlItem = FlexItem(ctrlTemplateItem); + auto controlItem = FlexItem(ctrlTemplateItem).withMargin(FlexItem::Margin(0, 0, 0, halfMarginX)); auto getAndPerformBounds = [&] () { auto bounds = Rectangle(controlsX, flexBounds[r - 1].getBottom() + halfMarginY, rowWidth, controlH); @@ -362,7 +363,7 @@ void SingleNoteAssign::resized() row.items.add(toggleItem); auto colourItem = FlexItem(controlH * 1.5f, controlH, *colourSubwindow.get()); - colourItem.margin = FlexItem::Margin(0, halfMarginX, 0, 0); + colourItem.margin = FlexItem::Margin(0, halfMarginX, 0, halfMarginX); row.items.add(colourItem); controlItem.associatedComponent = colourTextEditor.get(); @@ -381,6 +382,7 @@ void SingleNoteAssign::resized() auto ccInvertItem = FlexItem(controlH, controlH, *ccFaderIsDefault.get()); ccInvertItem.margin = FlexItem::Margin(0, halfMarginX, 0, 0); row.items.add(ccInvertItem); + controlItem.margin = FlexItem::Margin(); } controlItem.associatedComponent = noteInput.get(); From 911fcdf2c21054af0e8f9c29c1890c5d9bf70e63 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sun, 27 Jun 2021 21:47:09 -0400 Subject: [PATCH 033/183] Separate offline to online dialog --- Source/MidiEditArea.cpp | 46 +++++++++++++++++++++++++++++++---------- Source/MidiEditArea.h | 1 + 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Source/MidiEditArea.cpp b/Source/MidiEditArea.cpp index 4c75d41d..89e95536 100644 --- a/Source/MidiEditArea.cpp +++ b/Source/MidiEditArea.cpp @@ -419,7 +419,7 @@ void MidiEditArea::buttonClicked (juce::Button* buttonThatWasClicked) switch (sysExSendingMode) { case LumatoneController::sysExSendingMode::liveEditor: - onOpenConnectionToDevice(); + openOfflineConnection(); break; case LumatoneController::sysExSendingMode::offlineEditor: @@ -578,7 +578,7 @@ void MidiEditArea::onOpenConnectionToDevice() TerpstraSysExApplication::getApp().getLumatoneController().sendGetFirmwareRevisionRequest(); alert.reset(new AlertWindow("Connection established!", translate("Do you want to send the current setup to your Lumatone?"), AlertWindow::AlertIconType::QuestionIcon, getParentComponent())); - alert->addButton("Send Editor layout", 1); + alert->addButton("Send Editor Layout", 1); alert->addButton("Keep Editing Offline", 0); alert->addButton("Import From Lumatone", 2); //alert->setLookAndFeel(&lookAndFeel); @@ -590,20 +590,18 @@ void MidiEditArea::onOpenConnectionToDevice() AlertWindow::AlertIconType::WarningIcon, 3, getParentComponent())*/; - auto retc = alert->runModalLoop(); - - DBG("Connection window returned: " + String(retc)); + auto retc = alert->runModalLoop(); if (retc == 1) // Send { - TerpstraSysExApplication::getApp().sendCurrentConfigurationToDevice(); - liveEditorBtn->setToggleState(true, dontSendNotification); - lblConnectionState->setText("Connected", NotificationType::dontSendNotification); + TerpstraSysExApplication::getApp().sendCurrentConfigurationToDevice(); + liveEditorBtn->setToggleState(true, dontSendNotification); + lblConnectionState->setText("Connected", NotificationType::dontSendNotification); } else if (retc == 2) // Import { - TerpstraSysExApplication::getApp().requestConfigurationFromDevice(); - liveEditorBtn->setToggleState(true, NotificationType::dontSendNotification); - lblConnectionState->setText("Connected", NotificationType::dontSendNotification); + TerpstraSysExApplication::getApp().requestConfigurationFromDevice(); + liveEditorBtn->setToggleState(true, NotificationType::dontSendNotification); + lblConnectionState->setText("Connected", NotificationType::dontSendNotification); } else // Offline { @@ -616,6 +614,32 @@ void MidiEditArea::onOpenConnectionToDevice() } } +void MidiEditArea::openOfflineConnection() +{ + jassert(alert == nullptr); + + if (alert == nullptr) + { + alert.reset(new AlertWindow("Live Mode", "Do you want to send the current setup to your Lumatone?", AlertWindow::AlertIconType::QuestionIcon, getParentComponent())); + alert->addButton("Send Editor Layout", 1); + alert->addButton("Keep Editing Offline", 0); + + auto retc = alert->runModalLoop(); + if (retc == 1) + { + TerpstraSysExApplication::getApp().sendCurrentConfigurationToDevice(); + liveEditorBtn->setToggleState(true, dontSendNotification); + lblConnectionState->setText("Connected", NotificationType::dontSendNotification); + } + else + { + offlineEditorBtn->setToggleState(true, NotificationType::sendNotification); + } + + alert = nullptr; + } +} + void MidiEditArea::refreshInputMenuAndSetSelected(int inputDeviceIndex, juce::NotificationType notificationType) { cbMidiInput->clear(NotificationType::dontSendNotification); diff --git a/Source/MidiEditArea.h b/Source/MidiEditArea.h index 12ba5ad3..4169fc7f 100644 --- a/Source/MidiEditArea.h +++ b/Source/MidiEditArea.h @@ -54,6 +54,7 @@ class MidiEditArea : public Component, void attemptDeviceConnection(); void onOpenConnectionToDevice(); + void openOfflineConnection(); // For now, preserve connection functionality and make sure internal combo boxes are up to date void refreshInputMenuAndSetSelected(int inputDeviceIndex, juce::NotificationType notificationType = NotificationType::sendNotification); From 6d33bc9f385ad2caf2d26f761245ddcaa522481c Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sun, 27 Jun 2021 22:17:14 -0400 Subject: [PATCH 034/183] Improve destruction of FirmwareTransfer thread --- Source/FirmwareTransfer.cpp | 4 ++-- Source/FirmwareTransfer.h | 2 +- Source/LumatoneController.cpp | 14 +++++++++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Source/FirmwareTransfer.cpp b/Source/FirmwareTransfer.cpp index e7727685..9058fcef 100644 --- a/Source/FirmwareTransfer.cpp +++ b/Source/FirmwareTransfer.cpp @@ -142,7 +142,7 @@ void FirmwareTransfer::run() else if (transferRequested) { - prepareForUpdate(); + prepareAndRunUpdate(); transferRequested = false; } } @@ -198,7 +198,7 @@ static FirmwareTransfer::StatusCode shutdownSSHSession(LIBSSH2_SESSION* session, return returnCode; } -bool FirmwareTransfer::prepareForUpdate() +bool FirmwareTransfer::prepareAndRunUpdate() { StatusCode returnStatus = StatusCode::Initialize; listeners.call(&FirmwareTransfer::ProcessListener::firmwareTransferUpdate, returnStatus, statusCodeToMessage(returnStatus)); diff --git a/Source/FirmwareTransfer.h b/Source/FirmwareTransfer.h index f3017bcb..27d6cc70 100644 --- a/Source/FirmwareTransfer.h +++ b/Source/FirmwareTransfer.h @@ -94,7 +94,7 @@ class FirmwareTransfer : public juce::ThreadWithProgressWindow private: // Return true if update was successful - bool prepareForUpdate(); + bool prepareAndRunUpdate(); StatusCode performFirmwareUpdate(); // header only in .cpp diff --git a/Source/LumatoneController.cpp b/Source/LumatoneController.cpp index e5a7836c..4b31a03d 100644 --- a/Source/LumatoneController.cpp +++ b/Source/LumatoneController.cpp @@ -105,6 +105,8 @@ bool LumatoneController::requestFirmwareUpdate(File firmwareFile, FirmwareTransf return firmwareTransfer->requestFirmwareUpdate(firmwareFile.getFullPathName()); } + else + jassertfalse; return false; } @@ -506,6 +508,9 @@ void LumatoneController::midiMessageReceived(MidiInput* source, const MidiMessag midiDriver.unpackGetFirmwareRevisionResponse(midiMessage, incomingVersion.major, incomingVersion.minor, incomingVersion.revision); if (incomingVersion.isValid()) // Keyboard will return 0.0.0 before fully booted { + incomingVersion.major = 420; + incomingVersion.minor = 69; + incomingVersion.revision = 666; waitingForTestResponse = false; startTimer(UPDATETIMEOUT); } @@ -778,7 +783,12 @@ void LumatoneController::firmwareTransferUpdate(FirmwareTransfer::StatusCode sta default: if (statusCode < FirmwareTransfer::StatusCode::NoErr) + { + // Update failed deviceMonitor.intializeConnectionLossDetection(); + + juce::Timer::callAfterDelay(20, [&] { firmwareTransfer->signalThreadShouldExit(); }); + } break; } } @@ -940,6 +950,7 @@ void LumatoneController::timerCallback() { firmwareTransfer->incrementProgress(); + // Reset connection and start polling with GetFirmwareRevision if (!waitingForTestResponse) { waitingForTestResponse = true; @@ -947,6 +958,7 @@ void LumatoneController::timerCallback() midiDriver.closeMidiOutput(); deviceMonitor.initializeDeviceDetection(); } + else if (midiDriver.hasDevicesDefined()) { onFirmwareUpdateReceived(); @@ -978,7 +990,7 @@ void LumatoneController::timerCallback() void LumatoneController::exitSignalSent() { - firmwareTransfer->waitForThreadToExit(20); + firmwareTransfer->stopThread(20); firmwareTransfer = nullptr; } From e338481691de43fba3bd8e6855079d5ff759cb72 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Mon, 28 Jun 2021 23:31:07 -0400 Subject: [PATCH 035/183] Improve firmware update confirmation and thread closing --- Source/LumatoneController.cpp | 47 +++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/Source/LumatoneController.cpp b/Source/LumatoneController.cpp index 4b31a03d..59eea1c3 100644 --- a/Source/LumatoneController.cpp +++ b/Source/LumatoneController.cpp @@ -94,6 +94,7 @@ bool LumatoneController::requestFirmwareUpdate(File firmwareFile, FirmwareTransf { if (firmwareTransfer == nullptr) { + incomingVersion = FirmwareVersion(0, 0, 0); firmwareTransfer.reset(new FirmwareTransfer(midiDriver)); firmwareTransfer->addTransferListener(this); firmwareTransfer->addListener(this); @@ -499,22 +500,20 @@ void LumatoneController::midiMessageReceived(MidiInput* source, const MidiMessag startTimer(bufferReadTimeoutMs); } } - else if (midiMessage.isSysEx()) + + // Handle firmware update confirmation responses + else { auto sysExData = midiMessage.getSysExData(); switch (sysExData[CMD_ID]) { case GET_FIRMWARE_REVISION: midiDriver.unpackGetFirmwareRevisionResponse(midiMessage, incomingVersion.major, incomingVersion.minor, incomingVersion.revision); - if (incomingVersion.isValid()) // Keyboard will return 0.0.0 before fully booted + if (incomingVersion.isValid()) { - incomingVersion.major = 420; - incomingVersion.minor = 69; - incomingVersion.revision = 666; - waitingForTestResponse = false; startTimer(UPDATETIMEOUT); + break; } - break; default: break; @@ -786,7 +785,6 @@ void LumatoneController::firmwareTransferUpdate(FirmwareTransfer::StatusCode sta { // Update failed deviceMonitor.intializeConnectionLossDetection(); - juce::Timer::callAfterDelay(20, [&] { firmwareTransfer->signalThreadShouldExit(); }); } break; @@ -950,8 +948,27 @@ void LumatoneController::timerCallback() { firmwareTransfer->incrementProgress(); + if (waitingForTestResponse) + { + if (midiDriver.hasDevicesDefined() && incomingVersion.isValid()) + { + waitingForTestResponse = true; + onFirmwareUpdateReceived(); + } + + // THIS IS A KLUDGE! Something kills DeviceActivityMonitor's timer after device comes back online and I'm not yet sure why - vsicurella + else if (!deviceMonitor.isTimerRunning()) + { + deviceMonitor.initializeDeviceDetection(); + } + else + { + sendGetFirmwareRevisionRequest(); + } + } + // Reset connection and start polling with GetFirmwareRevision - if (!waitingForTestResponse) + else if (!incomingVersion.isValid()) { waitingForTestResponse = true; midiDriver.closeMidiInput(); @@ -959,17 +976,6 @@ void LumatoneController::timerCallback() deviceMonitor.initializeDeviceDetection(); } - else if (midiDriver.hasDevicesDefined()) - { - onFirmwareUpdateReceived(); - } - - // THIS IS A KLUDGE; Something kills DeviceActivityMonitor's timer after device comes back online and I'm not yet sure why - vsicurella - else if (!deviceMonitor.isTimerRunning()) - { - deviceMonitor.initializeDeviceDetection(); - } - startTimer(UPDATETIMEOUT); } } @@ -990,7 +996,6 @@ void LumatoneController::timerCallback() void LumatoneController::exitSignalSent() { - firmwareTransfer->stopThread(20); firmwareTransfer = nullptr; } From 8526e0915fa03fa55e82bc7258a0d514e94934ef Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Mon, 28 Jun 2021 23:31:41 -0400 Subject: [PATCH 036/183] Add connection issue suggestion --- Source/FirmwareTransfer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/FirmwareTransfer.h b/Source/FirmwareTransfer.h index 27d6cc70..9524e386 100644 --- a/Source/FirmwareTransfer.h +++ b/Source/FirmwareTransfer.h @@ -158,7 +158,8 @@ class FirmwareTransfer : public juce::ThreadWithProgressWindow return translate("Error: Could not prepare device communication protool"); case FirmwareTransfer::StatusCode::HostConnectErr: - return translate("Error: Could not communicate with Lumatone"); + return translate("Error: Could not communicate with Lumatone" + "\nPlease make sure you are connected over USB."); case FirmwareTransfer::StatusCode::SessionEstErr: return translate("Error: Could not verify connection with Lumatone"); From cf20990d7d4677a6984844ac02dec67f6f4ff286 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Mon, 28 Jun 2021 23:32:17 -0400 Subject: [PATCH 037/183] Debug macro for firmware file filter --- Source/FileBrowserComponent.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/FileBrowserComponent.h b/Source/FileBrowserComponent.h index 798d1979..06f265bc 100644 --- a/Source/FileBrowserComponent.h +++ b/Source/FileBrowserComponent.h @@ -18,7 +18,15 @@ class PathBrowserComponent : public Component, public Button::Listener { public: - PathBrowserComponent(const String dialogBoxTitle, const File& fileIn = File::getSpecialLocation(File::SpecialLocationType::userDocumentsDirectory), String fileTypeFilter = "") + PathBrowserComponent(const String dialogBoxTitle, + const File& fileIn = File::getSpecialLocation(File::SpecialLocationType::userDocumentsDirectory), + String fileTypeFilter = +#if JUCE_DEBUG + "" +#else + "*.tgz" +#endif + ) : chooser(dialogBoxTitle, File(), fileTypeFilter) { setName(dialogBoxTitle); From 19414966ebdc41beeb6f5d31456b92e2febfae1c Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Mon, 28 Jun 2021 23:42:41 -0400 Subject: [PATCH 038/183] Disable controls if unsupported firmware version --- Source/GlobalSettingsArea.cpp | 15 ++++++++++++++- Source/GlobalSettingsArea.h | 9 ++++++++- Source/PedalSensitivityDlg.cpp | 12 +++++++----- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Source/GlobalSettingsArea.cpp b/Source/GlobalSettingsArea.cpp index c1a38e80..d37d11c8 100644 --- a/Source/GlobalSettingsArea.cpp +++ b/Source/GlobalSettingsArea.cpp @@ -62,8 +62,11 @@ GlobalSettingsArea::GlobalSettingsArea () //[UserPreSize] lblDeveloperMode.reset(new Label("DeveloperModeLabel", "Developer Mode")); addChildComponent(lblDeveloperMode.get()); - setDeveloperMode(TerpstraSysExApplication::getApp().getPropertiesFile()->getBoolValue("DeveloperMode", false)); + + TerpstraSysExApplication::getApp().getLumatoneController().addStatusListener(this); + + buttonCalibrate->setEnabled(false); //[/UserPreSize] //[Constructor] You can add your own custom stuff here.. @@ -238,6 +241,16 @@ void GlobalSettingsArea::setDeveloperMode(bool devModeOn) repaint(); } +void GlobalSettingsArea::connectionEstablished(int inputDevice, int outputDevice) +{ + buttonCalibrate->setEnabled(true); +} + +void GlobalSettingsArea::connectionLost() +{ + buttonCalibrate->setEnabled(false); +} + //[/MiscUserCode] diff --git a/Source/GlobalSettingsArea.h b/Source/GlobalSettingsArea.h index 10e258c2..33dc924e 100644 --- a/Source/GlobalSettingsArea.h +++ b/Source/GlobalSettingsArea.h @@ -22,6 +22,7 @@ //[Headers] -- You can add your own extra header files here -- #include #include "ColourEditComponent.h" +#include "LumatoneController.h" #include "Settings/SettingsContainer.h" //[/Headers] @@ -37,7 +38,8 @@ */ class GlobalSettingsArea : public juce::Component, public ChangeListener, - public juce::Button::Listener + public juce::Button::Listener, + public LumatoneController::StatusListener { public: //============================================================================== @@ -56,6 +58,11 @@ class GlobalSettingsArea : public juce::Component, void lookAndFeelChanged() override; void setDeveloperMode(bool devModeOn); + + // LumatoneController::StatusListener implementation + void connectionEstablished(int inputDevice, int outputDevice) override; + void connectionLost() override; + //[/UserMethods] void paint (juce::Graphics& g) override; diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index 0a82968b..41e56042 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -151,10 +151,10 @@ void PedalSensitivityDlg::resized() int areaMarginWidth = roundToInt(w * sectionMarginWidth) * 0.5f; int areaMarginHeight = roundToInt(h * SETTINGSAREAMARGINHEIGHT); - + expressionBounds = getLocalBounds().toFloat().withTop(areaMarginHeight).withRight(roundToInt(w * 0.5f - areaMarginWidth)); sustainBounds = getLocalBounds().toFloat().withTop(areaMarginHeight).withLeft(roundToInt(w * 0.5f + areaMarginWidth)); - + int lblMarginX = roundToInt(w * SETTINGSLABELMARGINWIDTH); int lblWidth = roundToInt(w * 0.5f); int lblHeight = roundToInt(h * SETTINGSLABELHEIGHT); @@ -166,7 +166,7 @@ void PedalSensitivityDlg::resized() int buttonY = roundToInt(h * 0.3f); btnInvertExpression->setBounds(expressionBounds.withTrimmedLeft(controlMargin).withTop(buttonY).withHeight(buttonHeight).toNearestInt()); btnInvertSustain->setBounds(sustainBounds.withTrimmedLeft(controlMargin).withTop(buttonY).withHeight(buttonHeight).toNearestInt()); - + sldExprCtrlSensitivity->setBounds( expressionBounds.reduced(expressionBounds.getWidth() * 0.2f, 0) .withTop(btnInvertExpression->getBottom() + buttonHeight) @@ -249,11 +249,13 @@ void PedalSensitivityDlg::firmwareRevisionReceived(FirmwareVersion version) if (firmwareSupport.versionAcknowledgesCommand(version, INVERT_SUSTAIN_PEDAL)) { - btnInvertSustain->setVisible(true); + btnInvertSustain->setEnabled(true); + btnInvertSustain->setTooltip(""); } else { - btnInvertSustain->setVisible(false); + btnInvertSustain->setEnabled(false); + btnInvertSustain->setTooltip("This feature is not supported by the firmware version of your Lumatone."); } } From 661c474b4fa18cac64846d266c0e2f5cfda15e82 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Tue, 29 Jun 2021 20:19:57 -0400 Subject: [PATCH 039/183] User-friendly firmware version string --- Source/AllKeysOverview.cpp | 6 +++++- Source/LumatoneFirmwareDefinitions.h | 9 +++++++++ Source/Main.h | 2 +- Source/Settings/FirmwareDlg.cpp | 4 ++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Source/AllKeysOverview.cpp b/Source/AllKeysOverview.cpp index 531b1e43..76162c37 100644 --- a/Source/AllKeysOverview.cpp +++ b/Source/AllKeysOverview.cpp @@ -388,12 +388,16 @@ void AllKeysOverview::setFirmwareVersion(FirmwareVersion versionIn) { if (versionIn.revision == 55) { - lblFirmwareVersion->setText("Prototype 55-keys", NotificationType::dontSendNotification); + lblFirmwareVersion->setText("55-keys Prototype", NotificationType::dontSendNotification); } } else { +#if JUCE_DEBUG lblFirmwareVersion->setText("Firmware version: " + versionIn.toString(), NotificationType::dontSendNotification); +#else + lblFirmwareVersion->setText("Firmware version: " + versionIn.toDisplayString(), NotificationType::dontSendNotification); +#endif } lblFirmwareVersion->setVisible(true); diff --git a/Source/LumatoneFirmwareDefinitions.h b/Source/LumatoneFirmwareDefinitions.h index e589b02c..3e9fabc4 100644 --- a/Source/LumatoneFirmwareDefinitions.h +++ b/Source/LumatoneFirmwareDefinitions.h @@ -219,6 +219,15 @@ struct FirmwareVersion String toString() const { return String(major) + "." + String(minor) + "." + String(revision); } + String toDisplayString() const + { + String str = String(major) + "." + String(minor); + if (revision > 0) + str += ("." + String(revision)); + + return str; + } + //============================================================================ static FirmwareVersion fromString(String firmwareVersion) diff --git a/Source/Main.h b/Source/Main.h index 89d230e7..66c30135 100644 --- a/Source/Main.h +++ b/Source/Main.h @@ -54,7 +54,7 @@ class TerpstraSysExApplication : public JUCEApplication int getOctaveBoardSize() const { return lumatoneController.getOctaveSize(); } FirmwareVersion getFirmwareVersion() const { return lumatoneController.getFirmwareVersion(); } - String getFirmwareVersionStr() const { return lumatoneController.getFirmwareVersion().toString(); } + String getFirmwareVersionStr() const { return lumatoneController.getFirmwareVersion().toDisplayString(); } void reloadColourPalettes(); bool saveColourPalette(LumatoneEditorColourPalette& palette, File pathToPalette); diff --git a/Source/Settings/FirmwareDlg.cpp b/Source/Settings/FirmwareDlg.cpp index 38ef9573..6e2464cc 100644 --- a/Source/Settings/FirmwareDlg.cpp +++ b/Source/Settings/FirmwareDlg.cpp @@ -138,7 +138,7 @@ void FirmwareDlg::firmwareTransferUpdate(FirmwareTransfer::StatusCode statusCode firmwareUpdateInProgress = false; } - if (msg!= "") + if (msg != "") { msgLog += (msg + "\n"); infoNeedsUpdate = true; @@ -158,7 +158,7 @@ void FirmwareDlg::timerCallback() void FirmwareDlg::firmwareRevisionReceived(FirmwareVersion version) { updateFirmwareVersionLabel(); - postMessage("Firmware update complete! Lumatone is now running firmware version " + version.toString()); + postMessage("Firmware update complete! Lumatone is now running firmware version " + version.toDisplayString()); } void FirmwareDlg::postMessage(String msg) From c0763cc0d48c7c4ec968355dbbd833afbb42c6c7 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Tue, 29 Jun 2021 20:30:11 -0400 Subject: [PATCH 040/183] Added command 0x46 Reset Default Presets --- Source/LumatoneController.cpp | 8 +++++++- Source/LumatoneController.h | 3 +++ Source/LumatoneFirmwareDefinitions.h | 3 ++- Source/TerpstraMidiDriver.cpp | 7 +++++++ Source/TerpstraMidiDriver.h | 3 +++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Source/LumatoneController.cpp b/Source/LumatoneController.cpp index 59eea1c3..05adfd92 100644 --- a/Source/LumatoneController.cpp +++ b/Source/LumatoneController.cpp @@ -476,6 +476,12 @@ void LumatoneController::invertSustainPedal(bool setInverted) midiDriver.sendInvertSustainPedal(setInverted); } +void LumatoneController::resetPresetsToFactoryDefault() +{ + if (firmwareSupport.versionAcknowledgesCommand(determinedVersion, RESET_DEFAULT_PRESETS)) + midiDriver.sendResetDefaultPresetsRequest(); +} + //============================================================================= // Communication and broadcasting @@ -917,7 +923,7 @@ void LumatoneController::timerCallback() if (sysExData[MSG_STATUS] == 1) { if (event.numBytes > 8) - DBG("WARNING UNIMPLEMENTED RESPONSE HANDLING CMD " + String(cmd)); + DBG("WARNING: UNIMPLEMENTED RESPONSE HANDLING CMD " + String(cmd)); } else { diff --git a/Source/LumatoneController.h b/Source/LumatoneController.h index dbc4b75c..79f55c7c 100644 --- a/Source/LumatoneController.h +++ b/Source/LumatoneController.h @@ -206,6 +206,9 @@ class LumatoneController : protected TerpstraMidiDriver::Listener, // Invert the polarity of the sustain pedal void invertSustainPedal(bool setInverted); + // Reset preset mappings to factory mappings + void resetPresetsToFactoryDefault(); + //============================================================================ // FirmwareTransfer::Listener diff --git a/Source/LumatoneFirmwareDefinitions.h b/Source/LumatoneFirmwareDefinitions.h index 3e9fabc4..53b53d77 100644 --- a/Source/LumatoneFirmwareDefinitions.h +++ b/Source/LumatoneFirmwareDefinitions.h @@ -165,6 +165,7 @@ System exclusive command bytes #define SET_EXPRESSION_PEDAL_THRESHOLD 0x43 #define GET_EXPRESSION_PEDAL_THRESHOLD 0x44 #define INVERT_SUSTAIN_PEDAL 0x45 +#define RESET_DEFAULT_PRESETS 0x46 typedef enum { @@ -406,7 +407,7 @@ struct FirmwareSupport else if (CMD <= SET_AFTERTOUCH_TRIGGER_DELAY) // 0x3F return LumatoneFirmwareVersion::VERSION_1_0_14; - else if (CMD <= INVERT_SUSTAIN_PEDAL) //0x45 + else if (CMD <= RESET_DEFAULT_PRESETS) //0x45 return LumatoneFirmwareVersion::VERSION_1_0_15; else diff --git a/Source/TerpstraMidiDriver.cpp b/Source/TerpstraMidiDriver.cpp index cafc9e86..78c49472 100644 --- a/Source/TerpstraMidiDriver.cpp +++ b/Source/TerpstraMidiDriver.cpp @@ -611,11 +611,18 @@ void TerpstraMidiDriver::sendGetExpressionPedalADCThresholdRequest() sendSysExRequest(0, GET_EXPRESSION_PEDAL_THRESHOLD); } +// CMD 45h: Configure the on/off settings of the sustain pedal void TerpstraMidiDriver::sendInvertSustainPedal(bool setInverted) { sendSysExToggle(0, INVERT_SUSTAIN_PEDAL, setInverted); } +// CMD 46h: Replace current presets with factory presets +void TerpstraMidiDriver::sendResetDefaultPresetsRequest() +{ + sendSysExRequest(0, RESET_DEFAULT_PRESETS); +} + /* ============================================================================== Low-level SysEx calls diff --git a/Source/TerpstraMidiDriver.h b/Source/TerpstraMidiDriver.h index 6558d4f4..9bef36a9 100644 --- a/Source/TerpstraMidiDriver.h +++ b/Source/TerpstraMidiDriver.h @@ -291,6 +291,9 @@ class TerpstraMidiDriver : public HajuMidiDriver, public MidiInputCallback, publ // CMD 45h: Configure the on/off settings of the sustain pedal void sendInvertSustainPedal(bool setInverted); + // CMD 46h: Replace current presets with factory presets + void sendResetDefaultPresetsRequest(); + //============================================================================ // Implementation of bidirectional communication with acknowledge messages From df8af3e95604fc93b4680ae5018edddb509fd4bc Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Tue, 29 Jun 2021 21:59:46 -0400 Subject: [PATCH 041/183] Preset settings dialog for resetting to factory defaults --- Source/Settings/FirmwareDlg.cpp | 5 +- Source/Settings/FirmwareDlg.h | 6 ++ Source/Settings/PresetSettingsDlg.cpp | 84 +++++++++++++++++++++++++++ Source/Settings/PresetSettingsDlg.h | 47 +++++++++++++++ Source/Settings/SettingsContainer.cpp | 11 +++- Source/Settings/SettingsContainer.h | 4 +- TerpstraSysEx.jucer | 4 ++ 7 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 Source/Settings/PresetSettingsDlg.cpp create mode 100644 Source/Settings/PresetSettingsDlg.h diff --git a/Source/Settings/FirmwareDlg.cpp b/Source/Settings/FirmwareDlg.cpp index 6e2464cc..19cee2e1 100644 --- a/Source/Settings/FirmwareDlg.cpp +++ b/Source/Settings/FirmwareDlg.cpp @@ -68,10 +68,7 @@ void FirmwareDlg::paint(Graphics& g) void FirmwareDlg::resized() { - int margin = 12; - int doubleMargin = margin * 2; - int buttonWidth = proportionOfWidth(0.3f); - int buttonHeight = 30; + int buttonWidth = proportionOfWidth(buttonWidthScalar); //checkUpdateBtn->setBounds(margin, margin, buttonWidth, buttonHeight); diff --git a/Source/Settings/FirmwareDlg.h b/Source/Settings/FirmwareDlg.h index 677932e4..ef1a9718 100644 --- a/Source/Settings/FirmwareDlg.h +++ b/Source/Settings/FirmwareDlg.h @@ -70,4 +70,10 @@ class FirmwareDlg : public Component, String msgLog; bool infoNeedsUpdate = false; const int infoUpdateTimeoutMs = 100; + + // Style helpers + int margin = 12; + int doubleMargin = margin * 2; + float buttonWidthScalar = 0.3f; + int buttonHeight = 30; }; diff --git a/Source/Settings/PresetSettingsDlg.cpp b/Source/Settings/PresetSettingsDlg.cpp new file mode 100644 index 00000000..94fb3dd5 --- /dev/null +++ b/Source/Settings/PresetSettingsDlg.cpp @@ -0,0 +1,84 @@ +/* + ============================================================================== + + PresetSettingsDlg.cpp + Created: 29 Jun 2021 9:10:00pm + Author: Vincenzo + + ============================================================================== +*/ + +#include "PresetSettingsDlg.h" +#include "../Main.h" + +PresetSettingsDlg::PresetSettingsDlg() +{ + resetPresetsBtn.reset(new TextButton( + translate("Reset Presets To Factory Default"), + translate("Clear the mapping presets stored on the device and replace with factory mappings.") + )); + addAndMakeVisible(resetPresetsBtn.get()); + resetPresetsBtn->addListener(this); + + TerpstraSysExApplication::getApp().getLumatoneController().addFirmwareListener(this); + + setSupportedControls(TerpstraSysExApplication::getApp().getFirmwareVersion()); + + flexBox.justifyContent = FlexBox::JustifyContent::flexStart; + flexBox.alignContent = FlexBox::AlignContent::flexStart; +} + +PresetSettingsDlg::~PresetSettingsDlg() +{ + TerpstraSysExApplication::getApp().getLumatoneController().removeFirmwareListener(this); + resetPresetsBtn = nullptr; +} + +void PresetSettingsDlg::paint(Graphics& g) +{ + +} + +void PresetSettingsDlg::resized() +{ + Font btnFont = getLookAndFeel().getTextButtonFont(*resetPresetsBtn.get(), buttonHeight); + + int btnWidth = btnFont.getStringWidth(resetPresetsBtn->getButtonText()) * 1.2f; + + flexBox.items.clear(); + + FlexItem btnItem = FlexItem().withWidth(btnWidth).withHeight(buttonHeight); + btnItem.associatedComponent = resetPresetsBtn.get(); + flexBox.items.add(btnItem); + + flexBox.performLayout(getLocalBounds().reduced(margin)); +} + +void PresetSettingsDlg::buttonClicked(Button* btn) +{ + if (btn == resetPresetsBtn.get()) + { + TerpstraSysExApplication::getApp().getLumatoneController().resetPresetsToFactoryDefault(); + } +} + +void PresetSettingsDlg::firmwareRevisionReceived(FirmwareVersion version) +{ + setSupportedControls(version); +} + +void PresetSettingsDlg::setSupportedControls(FirmwareVersion version) +{ + FirmwareSupport support; + if (support.versionAcknowledgesCommand(version, RESET_DEFAULT_PRESETS)) + { + resetPresetsBtn->setEnabled(true); + resetPresetsBtn->setTooltip(translate("Clear the mapping presets stored on the device and replace with factory mappings.")); + } + else + { + resetPresetsBtn->setEnabled(false); + resetPresetsBtn->setTooltip(translate("This feature is not supported by your Lumatone firmware version.")); + // TODO: better approach for changing tooltips + } +} \ No newline at end of file diff --git a/Source/Settings/PresetSettingsDlg.h b/Source/Settings/PresetSettingsDlg.h new file mode 100644 index 00000000..2dc5117e --- /dev/null +++ b/Source/Settings/PresetSettingsDlg.h @@ -0,0 +1,47 @@ +/* + ============================================================================== + + PresetSettingsDlg.h + Created: 29 Jun 2021 9:10:00pm + Author: Vincenzo + + ============================================================================== +*/ + +#pragma once +#include "../LumatoneController.h" + +class PresetSettingsDlg : public Component, + protected Button::Listener, + protected LumatoneController::FirmwareListener + +{ +public: + + PresetSettingsDlg(); + ~PresetSettingsDlg(); + + void paint(Graphics& g) override; + + void resized() override; + + void buttonClicked(Button* btn) override; + + void setSupportedControls(FirmwareVersion version); + + //========================================================================= + // LumatoneController::FirmwareListener implementation + + void firmwareRevisionReceived(FirmwareVersion version) override; + + +private: + + std::unique_ptr resetPresetsBtn; + FlexBox flexBox; + + // Style helpers + int margin = 12; + int doubleMargin = margin * 2; + int buttonHeight = 30; +}; \ No newline at end of file diff --git a/Source/Settings/SettingsContainer.cpp b/Source/Settings/SettingsContainer.cpp index 38603d2a..536a718d 100644 --- a/Source/Settings/SettingsContainer.cpp +++ b/Source/Settings/SettingsContainer.cpp @@ -31,7 +31,11 @@ void SettingsCategoryModel::paintListBoxItem(int rowNumber, Graphics& g, int wid SettingsContainer::SettingsContainer() : Component("SettingsContainer"), - model({"Calibrate", "Firmware"}) + model({ + "Calibrate", + "Firmware", + "Presets" + }) { categoryList.reset(new ListBox("CategoryList")); categoryList->setModel(&model); @@ -45,6 +49,7 @@ SettingsContainer::SettingsContainer() SettingsContainer::~SettingsContainer() { + settingsPanel = nullptr; categoryList = nullptr; } @@ -91,6 +96,10 @@ void SettingsContainer::showPanel(int editorSettingCategory) case LumatoneEditorSettingCategories::Firmware: newPanel = new FirmwareDlg(); break; + + case LumatoneEditorSettingCategories::Presets: + newPanel = new PresetSettingsDlg(); + break; } if (newPanel) diff --git a/Source/Settings/SettingsContainer.h b/Source/Settings/SettingsContainer.h index 5b25a0aa..2b403b23 100644 --- a/Source/Settings/SettingsContainer.h +++ b/Source/Settings/SettingsContainer.h @@ -12,10 +12,12 @@ #include "../LumatoneEditorLookAndFeel.h" #include "CalibrationDlg.h" #include "FirmwareDlg.h" +#include "PresetSettingsDlg.h" typedef enum { Calibration = 0, - Firmware = 1 + Firmware = 1, + Presets = 2 } LumatoneEditorSettingCategories; class SettingsCategoryModel : public ListBoxModel, public ChangeBroadcaster diff --git a/TerpstraSysEx.jucer b/TerpstraSysEx.jucer index 4aa8dbba..01b1d378 100644 --- a/TerpstraSysEx.jucer +++ b/TerpstraSysEx.jucer @@ -95,6 +95,10 @@ file="Source/Settings/SettingsContainer.cpp"/> + + From a6954a24ec1b7cc3d05cfe8f9e4d2abfd53c00ac Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Wed, 30 Jun 2021 00:00:47 -0400 Subject: [PATCH 042/183] Midi settings panel and set peripheral channel implementation --- Source/LumatoneController.cpp | 14 ++ Source/LumatoneController.h | 6 + Source/Settings/MidiSettingsDlg.cpp | 219 ++++++++++++++++++++++++++ Source/Settings/MidiSettingsDlg.h | 145 +++++++++++++++++ Source/Settings/PresetSettingsDlg.h | 1 - Source/Settings/SettingsContainer.cpp | 11 +- Source/Settings/SettingsContainer.h | 6 +- TerpstraSysEx.jucer | 4 + 8 files changed, 400 insertions(+), 6 deletions(-) create mode 100644 Source/Settings/MidiSettingsDlg.cpp create mode 100644 Source/Settings/MidiSettingsDlg.h diff --git a/Source/LumatoneController.cpp b/Source/LumatoneController.cpp index 05adfd92..d7da82ca 100644 --- a/Source/LumatoneController.cpp +++ b/Source/LumatoneController.cpp @@ -470,6 +470,20 @@ int LumatoneController::pingLumatone(uint8 pingId) return midiDriver.ping(pingId); } +// Set MIDI Channels of peripheral controllers, pitch & mod wheels, expression & sustain pedals +void LumatoneController::setPeripheralChannels(int pitchWheelChannel, int modWheelChannel, int expressionChannel, int sustainChannel) +{ + if (firmwareSupport.versionAcknowledgesCommand(determinedVersion, SET_PERIPHERAL_CHANNELS)) + midiDriver.setPeripheralChannels(pitchWheelChannel, modWheelChannel, expressionChannel, sustainChannel); +} + +// Get MIDI Channels of peripheral controllers, pitch & mod wheels, expression & sustain pedals +void LumatoneController::getPeripheralChannels() +{ + if (firmwareSupport.versionAcknowledgesCommand(determinedVersion, GET_PERIPHERAL_CHANNELS)) + midiDriver.getPeripheralChannels(); +} + void LumatoneController::invertSustainPedal(bool setInverted) { if (firmwareSupport.versionAcknowledgesCommand(determinedVersion, INVERT_SUSTAIN_PEDAL)) diff --git a/Source/LumatoneController.h b/Source/LumatoneController.h index 79f55c7c..c027fe63 100644 --- a/Source/LumatoneController.h +++ b/Source/LumatoneController.h @@ -203,6 +203,12 @@ class LumatoneController : protected TerpstraMidiDriver::Listener, // Send a value from 0-127 for the Lumatone to echo back, returns actual value sent (in case of 7-bit masking); used for auto device connection and monitoring int pingLumatone(uint8 pingId); + // Set MIDI Channels of peripheral controllers, pitch & mod wheels, expression & sustain pedals + void setPeripheralChannels(int pitchWheelChannel, int modWheelChannel, int expressionChannel, int sustainChannel); + + // Get MIDI Channels of peripheral controllers, pitch & mod wheels, expression & sustain pedals + void getPeripheralChannels(); + // Invert the polarity of the sustain pedal void invertSustainPedal(bool setInverted); diff --git a/Source/Settings/MidiSettingsDlg.cpp b/Source/Settings/MidiSettingsDlg.cpp new file mode 100644 index 00000000..205af508 --- /dev/null +++ b/Source/Settings/MidiSettingsDlg.cpp @@ -0,0 +1,219 @@ +/* + ============================================================================== + + MidiSettingsDlg.cpp + Created: 29 Jun 2021 10:02:43pm + Author: Vincenzo + + ============================================================================== +*/ + +#include "MidiSettingsDlg.h" +#include "../Main.h" + +MidiSettingsDlg::MidiSettingsDlg() +{ + setMidiChannelHeader.reset(new Label("SetMidiChannelHeader", "Set Controller MIDI Channel")); + setMidiChannelHeader->setJustificationType(Justification::centred); + setMidiChannelHeader->setFont(TerpstraSysExApplication::getApp().getAppFont(LumatoneEditorFont::UniviaPro)); + addAndMakeVisible(setMidiChannelHeader.get()); + + controlLabelFont = TerpstraSysExApplication::getApp().getAppFont(LumatoneEditorFont::GothamNarrowMedium); + + for (auto controlName : ControlNames) + { + auto lbl = setMidiChannelLabels.add(new Label(controlName + " Label", controlName + ": ")); + lbl->setJustificationType(Justification::centredRight); + lbl->setFont(controlLabelFont); + addAndMakeVisible(*lbl); + + auto sld = setMidiChannelSliders.add(new Slider(Slider::SliderStyle::IncDecButtons, Slider::TextEntryBoxPosition::TextBoxLeft)); + sld->setRange(1, 16, 1); + sld->setName(controlName); + sld->setTooltip("Set MIDI Channel for " + controlName + " messages."); + sld->addListener(this); + addAndMakeVisible(*sld); + + auto btn = setOmniChannelButtons.add(new ToggleButton("All Channels")); + btn->setName(controlName); + btn->setTooltip("Send " + controlName + " messages on all MIDI channels."); + btn->addListener(this); + addAndMakeVisible(*btn); + + // Help with resizing + if (controlName.length() > longestControlName.length()) + longestControlName = controlName; + } + + flexBox.flexWrap = FlexBox::Wrap::noWrap; + flexBox.flexDirection = FlexBox::Direction::column; + flexBox.justifyContent = FlexBox::JustifyContent::flexStart; + flexBox.alignContent = FlexBox::AlignContent::flexStart; + + TerpstraSysExApplication::getApp().getLumatoneController().addFirmwareListener(this); + + setSupportedControls(TerpstraSysExApplication::getApp().getFirmwareVersion()); +} + +MidiSettingsDlg::~MidiSettingsDlg() +{ + TerpstraSysExApplication::getApp().getLumatoneController().removeFirmwareListener(this); + setMidiChannelHeader = nullptr; + setMidiChannelLabels.clear(); + setMidiChannelSliders.clear(); + setOmniChannelButtons.clear(); +} + +void MidiSettingsDlg::paint(Graphics& g) +{ + +} + +void MidiSettingsDlg::resized() +{ + int rowHeight = proportionOfHeight(fontHeightInBounds); + + auto setMidiChannelControlBounds = getLocalBounds().reduced(margin).withTrimmedTop(rowHeight + margin); + + controlLabelFont.setHeight(rowHeight); + int labelWidth = controlLabelFont.getStringWidth(longestControlName); + int sldWidth = labelWidth *(PHI - 1); + int btnWidth = controlLabelFont.getStringWidth("All Channels"); + int btnHeight = rowHeight * 0.6f; + + flexRows.clear(); + flexBox.items.clear(); + + auto controlMargin = FlexItem::Margin(0, margin * 0.5f, 0, 0); + + for (int i = 0; i < ControlNames.size(); i++) + { + flexRows.add(FlexBox( + FlexBox::Direction::row, + FlexBox::Wrap::noWrap, + FlexBox::AlignContent::center, + FlexBox::AlignItems::center, + FlexBox::JustifyContent::flexStart + )); + + FlexBox& flexRow = flexRows.getReference(i); + + auto lbl = setMidiChannelLabels[i]; + auto lblItem = FlexItem(labelWidth, rowHeight, *lbl).withMargin(controlMargin); + flexRow.items.add(lblItem); + + auto sld = setMidiChannelSliders[i]; + //sld->setTextBoxStyle(Slider::TextEntryBoxPosition::TextBoxLeft, false, sldWidth * 0.5f, rowHeight); + auto sldItem = FlexItem(sldWidth, rowHeight, *sld).withMargin(controlMargin); + flexRow.items.add(sldItem.withFlex(1.0f)); + + auto btn = setOmniChannelButtons[i]; + auto btnItem = FlexItem(btnWidth, btnHeight, *btn); + flexRow.items.add(btnItem.withFlex(1.0f)); + + auto rowItem = FlexItem(getWidth(), rowHeight); + rowItem.associatedFlexBox = &flexRow; + rowItem.margin = FlexItem::Margin(0, 0, margin, 0); + + flexBox.items.add(rowItem); + } + + flexBox.performLayout(setMidiChannelControlBounds); + + setMidiChannelHeader->setBounds(setMidiChannelControlBounds.withY(margin).withHeight(rowHeight)); +} + +void MidiSettingsDlg::sliderValueChanged(Slider* sld) +{ + int controlIndex = setMidiChannelSliders.indexOf(sld); + + if (controlIndex >= 0 && controlIndex < ControlNames.size()) + { + channelSettings.setChannel((PeripheralChannel)controlIndex, sld->getValue()); + sendChannelSettings(); + } +} + +void MidiSettingsDlg::buttonClicked(Button* btn) +{ + int controlIndex = setOmniChannelButtons.indexOf(static_cast(btn)); + + if (controlIndex >= 0 && controlIndex < ControlNames.size()) + { + // TODO: make omni channel explicit + channelSettings.setChannel((PeripheralChannel)controlIndex, 17); + sendChannelSettings(); + + // Disable slider if all channels is enabled + setMidiChannelSliders[controlIndex]->setEnabled(!btn->getToggleState()); + } +} + +void MidiSettingsDlg::setSupportedControls(FirmwareVersion version) +{ + bool setChannelsEnabled = false; + + FirmwareSupport support; + if (support.versionAcknowledgesCommand(version, SET_PERIPHERAL_CHANNELS)) + { + setChannelsEnabled = true; + TerpstraSysExApplication::getApp().getLumatoneController().getPeripheralChannels(); + } + + for (int i = 0; i < ControlNames.size(); i++) + { + setMidiChannelSliders[i]->setEnabled(setChannelsEnabled); + setOmniChannelButtons[i]->setEnabled(setChannelsEnabled); + + if (!setChannelsEnabled) + { + setMidiChannelSliders[i]->setTooltip(translate("This feature is not supported by your Lumatone's firmware version.")); + setOmniChannelButtons[i]->setTooltip(translate("This feature is not supported by your Lumatone's firmware version.")); + } + } +} + +void MidiSettingsDlg::updateChannelSettings(int pitchWheelChannel, int modWheelChannel, int expressionChannel, int sustainPedalChannel) +{ + channelSettings.setChannel(PeripheralChannel::PitchWheel, pitchWheelChannel); + channelSettings.setChannel(PeripheralChannel::ModWheel, modWheelChannel); + channelSettings.setChannel(PeripheralChannel::Expression, expressionChannel); + channelSettings.setChannel(PeripheralChannel::Sustain, sustainPedalChannel); + + for (int i = 0; i < ControlNames.size(); i++) + { + if (channelSettings.getChannel((PeripheralChannel)i) > 16) + { + setMidiChannelSliders[i]->setEnabled(false); + setOmniChannelButtons[i]->setToggleState(true, dontSendNotification); + } + else + { + setMidiChannelSliders[i]->setEnabled(true); + setOmniChannelButtons[i]->setToggleState(false, dontSendNotification); + } + } +} + +void MidiSettingsDlg::sendChannelSettings() +{ + TerpstraSysExApplication::getApp().getLumatoneController().setPeripheralChannels( + channelSettings.pitchWheel, + channelSettings.modWheel, + channelSettings.expressionPedal, + channelSettings.sustainPedal + ); +} + +//========================================================================= +// LumatoneController::FirmwareListener implementation + +void MidiSettingsDlg::firmwareRevisionReceived(FirmwareVersion version) +{ + setSupportedControls(version); +} + +void MidiSettingsDlg::peripheralMidiChannelsReceived(int pitchWheelChannel, int modWheelChannel, int expressionChannel, int sustainPedalChannel) +{ + updateChannelSettings(pitchWheelChannel, modWheelChannel, expressionChannel, sustainPedalChannel); +} diff --git a/Source/Settings/MidiSettingsDlg.h b/Source/Settings/MidiSettingsDlg.h new file mode 100644 index 00000000..6fbc75e5 --- /dev/null +++ b/Source/Settings/MidiSettingsDlg.h @@ -0,0 +1,145 @@ +/* + ============================================================================== + + MidiSettingsDlg.h + Created: 29 Jun 2021 10:02:43pm + Author: Vincenzo + + ============================================================================== +*/ + +#pragma once + +#include "../LumatoneController.h" + +class MidiSettingsDlg : public Component, + protected Slider::Listener, + protected ToggleButton::Listener, + protected LumatoneController::FirmwareListener +{ +public: + + MidiSettingsDlg(); + ~MidiSettingsDlg(); + + void paint(Graphics & g) override; + + void resized() override; + + void sliderValueChanged(Slider* sld) override; + + void buttonClicked(Button* btn) override; + + void setSupportedControls(FirmwareVersion version); + + void updateChannelSettings(int pitchWheelChannel, int modWheelChannel, int expressionChannel, int sustainPedalChannel); + + void sendChannelSettings(); + + //========================================================================= + // LumatoneController::FirmwareListener implementation + + void firmwareRevisionReceived(FirmwareVersion version) override; + + void peripheralMidiChannelsReceived(int pitchWheelChannel, int modWheelChannel, int expressionChannel, int sustainPedalChannel) override; + + + +private: + //========================================================================= + + const StringArray ControlNames = + { + "Pitch Wheel", + "Mod Wheel", + "Expression Pedal", + "Sustain Pedal" + }; + + // TODO: Move these somewhere more common? + + typedef enum + { + PitchWheel = 0, + ModWheel, + Expression, + Sustain + } PeripheralChannel; + + struct PeripheralChannelSettings + { + int pitchWheel = 1; + int modWheel = 1; + int expressionPedal = 1; + int sustainPedal = 1; + + void setChannel(PeripheralChannel controlId, int channelIn) + { + if (channelIn < 1) + channelIn = 1; + + if (channelIn > 16) + channelIn = 17; // Set to Omni + + switch (controlId) + { + case PeripheralChannel::PitchWheel: + pitchWheel = channelIn; + break; + + case PeripheralChannel::ModWheel: + modWheel = channelIn; + break; + + case PeripheralChannel::Expression: + expressionPedal = channelIn; + break; + + case PeripheralChannel::Sustain: + sustainPedal = channelIn; + break; + } + } + + int getChannel(PeripheralChannel controlId) + { + switch (controlId) + { + case PeripheralChannel::PitchWheel: + return pitchWheel; + + case PeripheralChannel::ModWheel: + return modWheel; + + case PeripheralChannel::Expression: + return expressionPedal; + + case PeripheralChannel::Sustain: + return sustainPedal; + } + + return 0; + } + }; + +private: + + std::unique_ptr /// - void listenToColourSelection(ColourSelectionListener* listenerIn) { paletteGroup->addColourSelectionListener(listenerIn); } + void listenToColourSelection(ColourSelectionListener* listenerIn) { colourSelectorGroup->addColourSelectionListener(listenerIn); } + + /// + /// Adds a colour selector component to the colour selection group + /// + /// + void addColourSelectorToGroup(ColourSelectionBroadcaster* broadcaster) { colourSelectorGroup->addSelector(broadcaster); } + + /// + /// Force a colour selector (added to the group) to be selected + /// + /// + void setCurrentColourSelector(ColourSelectionBroadcaster* newSelector) + { + // This statement is kind of a kludge - vsicurella + if (colourSelectorGroup->getIndexOfSelector(newSelector) < 0) + colourSelectorGroup->addSelector(newSelector); + + colourSelectorGroup->setCurrentSelector(newSelector); + } private: @@ -72,7 +91,7 @@ class ColourPaletteWindow : public juce::Component, std::unique_ptr palettePanelViewport; - std::unique_ptr paletteGroup; + std::unique_ptr colourSelectorGroup; int paletteIndexEditing = -1; bool paletteEditingIsNew = false; diff --git a/Source/ColourSelectionGroup.h b/Source/ColourSelectionGroup.h index 6e9cdac5..8e66f4dd 100644 --- a/Source/ColourSelectionGroup.h +++ b/Source/ColourSelectionGroup.h @@ -26,14 +26,13 @@ class ColourSelectionBroadcaster public: ColourSelectionBroadcaster() {}; - virtual ~ColourSelectionBroadcaster() {}; virtual Colour getSelectedColour() = 0; virtual void deselectColour() = 0; void addColourSelectionListener(ColourSelectionListener* listenerIn) { selectorListeners.add(listenerIn); } - void removeColourSelectionListener(ColourSelectionListener* listenerIn) { selectorListeners.add(listenerIn); } + void removeColourSelectionListener(ColourSelectionListener* listenerIn) { selectorListeners.remove(listenerIn); } protected: @@ -45,6 +44,12 @@ class ColourSelectionGroup : public ColourSelectionBroadcaster, { public: + ~ColourSelectionGroup() + { + for (auto selector : colourSelectors) + selector->removeColourSelectionListener(this); + } + /// /// Adds a ColourPaletteComponent and returns the palette's group index /// @@ -105,6 +110,23 @@ class ColourSelectionGroup : public ColourSelectionBroadcaster, return colourSelectors.indexOf(selectorIn); } + void setCurrentSelector(ColourSelectionBroadcaster* selector) + { + auto index = colourSelectors.indexOf(selector); + + if (index >= 0 && index < colourSelectors.size()) + { + if (selectedBroadcasterIndex >= 0 && getSelectedBroadcaster() != selector) + { + getSelectedBroadcaster()->deselectColour(); + } + + selectedBroadcasterIndex = index; + + selectorListeners.call(&ColourSelectionListener::colourChangedCallback, selector, selector->getSelectedColour()); + } + } + //========================================================================= /// @@ -114,14 +136,7 @@ class ColourSelectionGroup : public ColourSelectionBroadcaster, /// void colourChangedCallback(ColourSelectionBroadcaster* source, Colour newColour) override { - if (getSelectedBroadcaster() && getSelectedBroadcaster() != source) - { - getSelectedBroadcaster()->deselectColour(); - } - - selectedBroadcasterIndex = colourSelectors.indexOf(source); - - selectorListeners.call(&ColourSelectionListener::colourChangedCallback, source, newColour); + setCurrentSelector(source); } private: diff --git a/Source/ColourSelectionPanels.h b/Source/ColourSelectionPanels.h index 7650e5af..bdcb8f50 100644 --- a/Source/ColourSelectionPanels.h +++ b/Source/ColourSelectionPanels.h @@ -280,7 +280,8 @@ class ColourPalettesPanel : public Component */ class CustomPickerPanel : public Component, public ChangeListener, - public ColourSelectionBroadcaster + public ColourSelectionBroadcaster, + public ColourSelectionListener { public: @@ -319,6 +320,12 @@ class CustomPickerPanel : public Component, selectorListeners.call(&ColourSelectionListener::colourChangedCallback, this, colourPicker->getCurrentColour()); } + void colourChangedCallback(ColourSelectionBroadcaster* source, Colour newColour) override + { + if (this != source) + colourPicker->setCurrentColour(newColour, dontSendNotification); + } + //============================================================================== Colour getSelectedColour() override diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 3ab6b613..8d672b8e 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -303,6 +303,8 @@ void MainContentComponent::buttonClicked(Button* btn) { colourEdit = noteEditArea->getColourEditComponent(); paletteWindow->listenToColourSelection(noteEditArea->getSingleNoteColourTextEditor()); + paletteWindow->addColourSelectorToGroup(noteEditArea.get()); + paletteWindow->setCurrentColourSelector(noteEditArea->getSingleNoteColourTextEditor()); } Rectangle componentArea = colourEdit->getScreenBounds().translated(-getScreenX(), -getScreenY()); diff --git a/Source/NoteEditArea.cpp b/Source/NoteEditArea.cpp index c5111070..0adab438 100644 --- a/Source/NoteEditArea.cpp +++ b/Source/NoteEditArea.cpp @@ -87,7 +87,8 @@ NoteEditArea::NoteEditArea () // Single Key fields resetOctaveSize(false); - /* Dont want to resize niri + /* Don't want to resize now + /* //[/UserPreSize] setSize (760, 470); @@ -95,8 +96,15 @@ NoteEditArea::NoteEditArea () //[Constructor] You can add your own custom stuff here.. */ + // First octaveboard selection, selection on first key: see MainComponent (Has to be done after change listener has been established) + auto singleNoteAssign = dynamic_cast(editFunctionsTab->getTabContentComponent(0)); + if (singleNoteAssign != nullptr) + { + addColourSelectionListener(singleNoteAssign); + } + //[/Constructor] } @@ -125,7 +133,7 @@ NoteEditArea::~NoteEditArea() void NoteEditArea::paint (juce::Graphics& g) { //[UserPrePaint] Add your own custom painting code here.. - + /* //[/UserPrePaint] @@ -216,35 +224,44 @@ void NoteEditArea::mouseDown (const juce::MouseEvent& e) // Select field changeSingleKeySelection(keyIndex); - // Perform the edit, according to edit mode. Including sending to device - auto setSelection = octaveBoardSelectorTab->getCurrentTabIndex(); - jassert(setSelection >= 0 && setSelection < NUMBEROFBOARDS && keyIndex >= 0 && keyIndex < TerpstraSysExApplication::getApp().getOctaveBoardSize()); - - int editMode = editFunctionsTab->getCurrentTabIndex(); - switch (editMode) - { - case noteEditMode::SingleNoteAssignMode: + // Grab key colour - may be replaced with eyedropper tool + if (e.mods.isAltDown()) { - auto editAction = dynamic_cast(editFunctionsTab->getTabContentComponent(editMode))->createEditAction(setSelection, keyIndex); - TerpstraSysExApplication::getApp().performUndoableAction(editAction); - break; + auto colour = terpstraKeyFields[keyIndex]->getValue().colour; + selectorListeners.call(&ColourSelectionListener::colourChangedCallback, this, colour); } - case noteEditMode::IsomorphicMassAssignMode: + // Standard assign action + else { - bool mappingChanged = dynamic_cast(editFunctionsTab->getTabContentComponent(editMode))->performMouseDown(setSelection, keyIndex); - if (mappingChanged) - { - TerpstraSysExApplication::getApp().setHasChangesToSave(true); + // Perform the edit, according to edit mode. Including sending to device + auto setSelection = octaveBoardSelectorTab->getCurrentTabIndex(); + jassert(setSelection >= 0 && setSelection < NUMBEROFBOARDS&& keyIndex >= 0 && keyIndex < TerpstraSysExApplication::getApp().getOctaveBoardSize()); - // Refresh key fields (all may be affected) - ((MainContentComponent*)getParentComponent())->refreshKeyDataFields(); + int editMode = editFunctionsTab->getCurrentTabIndex(); + switch (editMode) + { + case noteEditMode::SingleNoteAssignMode: + { + auto editAction = dynamic_cast(editFunctionsTab->getTabContentComponent(noteEditMode::SingleNoteAssignMode))->createEditAction(setSelection, keyIndex); + TerpstraSysExApplication::getApp().performUndoableAction(editAction); + break; + } + case noteEditMode::IsomorphicMassAssignMode: + { + bool mappingChanged = dynamic_cast(editFunctionsTab->getTabContentComponent(editMode))->performMouseDown(setSelection, keyIndex); + if (mappingChanged) + { + TerpstraSysExApplication::getApp().setHasChangesToSave(true); + + // Refresh key fields (all may be affected) + ((MainContentComponent*)getParentComponent())->refreshKeyDataFields(); + } + break; + } + default: + break; } - break; - } - default: - break; } - break; } } @@ -369,6 +386,23 @@ void NoteEditArea::resetOctaveSize(bool refreshAndResize) } } } + +Colour NoteEditArea::getSelectedColour() +{ + if (currentSingleKeySelection >= 0 && currentSingleKeySelection < TerpstraSysExApplication::getApp().getOctaveBoardSize()) + { + return terpstraKeyFields[currentSingleKeySelection]->getValue().colour; + } + + auto singleNoteAssign = dynamic_cast(editFunctionsTab->getTabContentComponent(SingleNoteAssignMode)); + if (singleNoteAssign != nullptr) + { + return singleNoteAssign->getColourEditComponent()->getColourAsObject(); + } + + return Colour(); +} + //[/MiscUserCode] @@ -382,10 +416,10 @@ void NoteEditArea::resetOctaveSize(bool refreshAndResize) BEGIN_JUCER_METADATA + parentClasses="public Component, public ChangeListener, public ColourSelectionBroadcaster" + constructorParams="" variableInitialisers="currentSingleKeySelection(-1)" + snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330" + fixedSize="0" initialWidth="760" initialHeight="470"> diff --git a/Source/NoteEditArea.h b/Source/NoteEditArea.h index 1399e34d..2b2afeeb 100644 --- a/Source/NoteEditArea.h +++ b/Source/NoteEditArea.h @@ -44,7 +44,8 @@ //[/Comments] */ class NoteEditArea : public Component, - public ChangeListener + public ChangeListener, + public ColourSelectionBroadcaster { public: //============================================================================== @@ -82,6 +83,10 @@ class NoteEditArea : public Component, void resetOctaveSize(bool refreshAndResize=true); + // ColourSelectionBroadcaster Implementation + Colour getSelectedColour() override; + void deselectColour() override {}; + //[/UserMethods] void paint (juce::Graphics& g) override; diff --git a/Source/SingleNoteAssign.cpp b/Source/SingleNoteAssign.cpp index 23819584..67f2efdb 100644 --- a/Source/SingleNoteAssign.cpp +++ b/Source/SingleNoteAssign.cpp @@ -34,6 +34,7 @@ SingleNoteAssign::SingleNoteAssign () //[Constructor_pre] You can add your own custom stuff here.. //[/Constructor_pre] + setName ("SingleNoteAssign"); noteAutoIncrButton.reset (new juce::ToggleButton ("noteAutoIncrButton")); addAndMakeVisible (noteAutoIncrButton.get()); noteAutoIncrButton->setButtonText (TRANS("Notes-Per-Click")); @@ -147,7 +148,7 @@ SingleNoteAssign::SingleNoteAssign () keyTypeToggleButton->setButtonText(translate("KeyType")); keyTypeToggleButton->setColour(ToggleButton::ColourIds::textColourId, toggleTextColour); - + ccFaderIsDefault.reset(new juce::ImageButton()); ccFaderIsDefault->setClickingTogglesState(true); ccFaderIsDefault->addListener(this); @@ -182,7 +183,7 @@ SingleNoteAssign::SingleNoteAssign () // TODO: load last active colour? colourTextEditor->addColourSelectionListener(this); - + // Set up FlexBox rows for (int i = 0; i <= SingleNoteFlexRows::channelIncrement; i++) { @@ -193,7 +194,7 @@ SingleNoteAssign::SingleNoteAssign () FlexBox::AlignItems::center, FlexBox::JustifyContent::flexStart)); } - + //[/UserPreSize] setSize (320, 400); @@ -288,21 +289,21 @@ void SingleNoteAssign::resized() roundedCornerSize = roundToInt(getParentComponent()->getParentComponent()->getParentHeight() * ROUNDEDCORNERTOAPPHEIGHT); int controlAreaTop = roundToInt(h * controlAreaYScalar); - + int toggleHeight = roundToInt(h * toggleHeightScalar); int toggleHeightScaled = roundToInt(toggleHeight * GLOBALFONTSCALAR); - + int controlH = roundToInt(h * controlHeightScalar); int controlHScaled = roundToInt(controlH * GLOBALFONTSCALAR); - + int marginX = roundToInt(controlH * 0.6f); int marginY = roundToInt(h * yMarginScalar); int halfMarginX = roundToInt(marginX * 0.5f); int halfMarginY = roundToInt(marginY * 0.5f); - + int rowWidth = roundToInt(w - marginX * 2); int toggleWidthMargin = toggleHeight + marginX * 1.25f; // Toggle icon + combined margins - + //[/UserPreResize] //[UserResized] Add your own custom resize handling here.. @@ -310,49 +311,49 @@ void SingleNoteAssign::resized() instructionsFont.setHeight(instructionsAreaBounds.getHeight() * fontHeightInBounds); controlsX = roundToInt(w * controlsXScalar); - + instructionsBounds.setBounds(marginX, 0, w - marginX * 2, controlAreaTop); parametersFont.setHeight(toggleHeightScaled); - + flexBounds.clear(); auto tglTemplateItem = FlexItem().withHeight(toggleHeightScaled).withAlignSelf(FlexItem::AlignSelf::center); auto ctrlTemplateItem = FlexItem(FlexItem::autoValue, controlH).withFlex(1.0f); - + auto getTglWidth = [=](ToggleButton* btn) { return roundToInt(parametersFont.getStringWidthFloat(btn->getButtonText()) + toggleWidthMargin); }; - + for (int r = 0; r <= SingleNoteFlexRows::channelIncrement; r++) { auto row = flexRows.getReference(r); row.items.clear(); - + // Generalize row properties auto toggleItem = FlexItem(tglTemplateItem); auto setupToggleItem = [&] (ToggleButton* btn) { toggleItem.width = getTglWidth(btn); toggleItem.associatedComponent = btn; }; - + auto controlItem = FlexItem(ctrlTemplateItem).withMargin(FlexItem::Margin(0, 0, 0, halfMarginX)); - + auto getAndPerformBounds = [&] () { auto bounds = Rectangle(controlsX, flexBounds[r - 1].getBottom() + halfMarginY, rowWidth, controlH); flexBounds.add(bounds); row.performLayout(bounds); }; - + switch (r) { case SingleNoteFlexRows::keyType: { setupToggleItem(keyTypeToggleButton.get()); row.items.add(toggleItem); - + controlItem.associatedComponent = keyTypeCombo.get(); row.items.add(controlItem); - + flexBounds.add(Rectangle(controlsX, controlAreaTop + halfMarginY, rowWidth, controlH)); row.performLayout(flexBounds[r]); break; @@ -361,14 +362,14 @@ void SingleNoteAssign::resized() { setupToggleItem(setColourToggleButton.get()); row.items.add(toggleItem); - + auto colourItem = FlexItem(controlH * 1.5f, controlH, *colourSubwindow.get()); colourItem.margin = FlexItem::Margin(0, halfMarginX, 0, halfMarginX); row.items.add(colourItem); - + controlItem.associatedComponent = colourTextEditor.get(); row.items.add(controlItem); - + getAndPerformBounds(); break; } @@ -376,7 +377,7 @@ void SingleNoteAssign::resized() { setupToggleItem(setNoteToggleButton.get()); row.items.add(toggleItem); - + if (keyTypeCombo->getSelectedId() == LumatoneKeyType::continuousController) { auto ccInvertItem = FlexItem(controlH, controlH, *ccFaderIsDefault.get()); @@ -384,10 +385,10 @@ void SingleNoteAssign::resized() row.items.add(ccInvertItem); controlItem.margin = FlexItem::Margin(); } - + controlItem.associatedComponent = noteInput.get(); row.items.add(controlItem); - + getAndPerformBounds(); break; } @@ -395,12 +396,12 @@ void SingleNoteAssign::resized() { setupToggleItem(setChannelToggleButton.get()); row.items.add(toggleItem); - + controlItem.associatedComponent = channelInput.get(); row.items.add(controlItem); - + getAndPerformBounds(); - + // Position Auto-Increment section since channelIncrement is relative to it separatorY = channelInput->getBottom() + halfMarginY; autoIncrementLabel->setBounds(controlsX, separatorY + halfMarginY, w - controlsX, controlHScaled); @@ -412,10 +413,10 @@ void SingleNoteAssign::resized() { setupToggleItem(channelAutoIncrButton.get()); row.items.add(toggleItem); - + controlItem.associatedComponent = channelAutoIncrNoteInput.get(); row.items.add(controlItem); - + flexBounds.add(Rectangle(controlsX, noteAutoIncrButton->getBottom() + halfMarginY, rowWidth, controlH)); row.performLayout(flexBounds[r]); break; @@ -429,12 +430,12 @@ void SingleNoteAssign::resized() colourTextEditor->applyFontToAllText(TerpstraSysExApplication::getApp().getAppFont(LumatoneEditorFont::GothamNarrowMedium, controlHScaled * CONTROLBOXFONTHEIGHTSCALAR), true); noteInput->setTextBoxStyle(Slider::TextEntryBoxPosition::TextBoxLeft, false, roundToInt(noteInput->getWidth() * incDecButtonTextBoxWidthScalar), noteInput->getHeight()); - + if (keyTypeCombo->getSelectedId() == LumatoneKeyType::continuousController) redrawCCFlipBtn(); - + channelInput->setTextBoxStyle(Slider::TextEntryBoxPosition::TextBoxLeft, false, roundToInt(channelInput->getWidth() * incDecButtonTextBoxWidthScalar), channelInput->getHeight()); - + channelAutoIncrNoteInput->setTextBoxStyle(Slider::TextEntryBoxPosition::TextBoxLeft, false, roundToInt(channelAutoIncrNoteInput->getWidth() * incDecButtonTextBoxWidthScalar), channelAutoIncrNoteInput->getHeight()); //[/UserResized] } @@ -565,8 +566,12 @@ void SingleNoteAssign::lookAndFeelChanged() void SingleNoteAssign::colourChangedCallback(ColourSelectionBroadcaster* source, Colour newColour) { - if (source == colourTextEditor.get()) - colourSubwindow->setColour(colourTextEditor->getText()); + if (source != colourTextEditor.get()) + { + colourTextEditor->setText(newColour.toDisplayString(false), false); + } + + colourSubwindow->setColour(colourTextEditor->getText()); } /// Called from parent when one of the keys is clicked @@ -575,7 +580,7 @@ UndoableAction* SingleNoteAssign::createEditAction(int setSelection, int keySele { int newNote = noteInput->getValue(); int newChannel = channelInput->getValue(); - + auto editAction = new Lumatone::SingleNoteAssignAction( setSelection, keySelection, keyTypeToggleButton->getToggleState(), setChannelToggleButton->getToggleState(), @@ -585,7 +590,7 @@ UndoableAction* SingleNoteAssign::createEditAction(int setSelection, int keySele newNote, colourSubwindow->getColourAsObject(), ccFaderIsDefault->getToggleState()); jassert(editAction != nullptr && editAction->isValid()); - + // Auto increment note if (noteAutoIncrButton->getToggleState()) { @@ -650,36 +655,36 @@ void SingleNoteAssign::redrawCCFlipBtn() getCCPolarityIconPath(true, arrowInvertedPath, faderInvertedPath); auto defaultImg = Image(Image::PixelFormat::ARGB, ccFaderIsDefault->getWidth(), ccFaderIsDefault->getHeight(), true); auto invertedImg = defaultImg.createCopy(); - + Graphics g(defaultImg); Graphics gi(invertedImg); - + auto transform = AffineTransform::scale(defaultImg.getWidth(), defaultImg.getHeight()); arrowPath.applyTransform(transform); faderPath.applyTransform(transform); arrowInvertedPath.applyTransform(transform); faderInvertedPath.applyTransform(transform); - + auto lookAndFeel = &TerpstraSysExApplication::getApp().getLookAndFeel(); auto background = lookAndFeel->findColour(TextButton::ColourIds::buttonColourId); g.setColour(background); g.fillRoundedRectangle(ccFaderIsDefault->getLocalBounds().toFloat(), 5.0f); gi.setColour(background); gi.fillRoundedRectangle(ccFaderIsDefault->getLocalBounds().toFloat(), 5.0f); - + auto arrowStroke = PathStrokeType(PHI, PathStrokeType::JointStyle::curved); auto colour = lookAndFeel->findColour(LumatoneEditorColourIDs::ActiveText).brighter(0.1); g.setColour(colour); g.strokePath(arrowPath, arrowStroke); g.fillPath(faderPath); - + gi.setColour(colour); gi.strokePath(arrowInvertedPath, arrowStroke); gi.fillPath(faderInvertedPath); - + // auto mouseOverImg = ccFaderFlipBtn->getToggleState() ? &invertedImg : &defaultImg; auto highlight = Colours::white.withAlpha(0.0333f); - + ccFaderIsDefault->setImages(false, false, true, invertedImg, 1.0f, Colour(), invertedImg, 1.0f, highlight, @@ -697,7 +702,7 @@ void SingleNoteAssign::redrawCCFlipBtn() BEGIN_JUCER_METADATA - flexRows; Array> flexBounds; // Primarily for debugging enum SingleNoteFlexRows @@ -112,11 +112,11 @@ class SingleNoteAssign : public Component, const float controlBoxFontHeightScalar = 0.75f; const float incDecButtonTextBoxWidthScalar = 0.4f; - + const float separatorThicknessScalar = 0.005f; const Colour toggleTextColour = Colour(0xffcbcbcb); - + std::unique_ptr ccFaderIsDefault; Path faderDownArrow; Path faderUpArrow; @@ -136,7 +136,7 @@ class SingleNoteAssign : public Component, std::unique_ptr colourTextEditor; std::unique_ptr channelInput; std::unique_ptr channelAutoIncrNoteInput; - + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SingleNoteAssign) From 9b82c690b6bbdd269039b2f0ccb3294bee124035 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 15 Jul 2021 22:20:10 -0400 Subject: [PATCH 070/183] set settings dialog L&F to nullptr on exit (attempt to fix crash on quit) --- Source/GlobalSettingsArea.cpp | 1 + Source/PedalSensitivityDlg.cpp | 2 +- Source/Settings/SettingsContainer.cpp | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/GlobalSettingsArea.cpp b/Source/GlobalSettingsArea.cpp index 7841325d..e9d9499d 100644 --- a/Source/GlobalSettingsArea.cpp +++ b/Source/GlobalSettingsArea.cpp @@ -131,6 +131,7 @@ GlobalSettingsArea::~GlobalSettingsArea() //[Destructor]. You can add your own custom destruction code here.. if (settingsAreOpen) { + settingsDialog->setLookAndFeel(nullptr); settingsDialog->exitModalState(0); settingsDialog = nullptr; } diff --git a/Source/PedalSensitivityDlg.cpp b/Source/PedalSensitivityDlg.cpp index 391f3ed1..5ac8359d 100644 --- a/Source/PedalSensitivityDlg.cpp +++ b/Source/PedalSensitivityDlg.cpp @@ -173,7 +173,7 @@ void PedalSensitivityDlg::resized() .withTrimmedBottom(buttonHeight * 1.5f) .toNearestInt() ); - + labelExprContrSensitivity->setBounds( expressionBounds.withTop(sldExprCtrlSensitivity->getBottom() + buttonHeight * 0.1f) .withTrimmedBottom(buttonHeight * 0.5f) diff --git a/Source/Settings/SettingsContainer.cpp b/Source/Settings/SettingsContainer.cpp index 60dd15d1..2fc59c89 100644 --- a/Source/Settings/SettingsContainer.cpp +++ b/Source/Settings/SettingsContainer.cpp @@ -52,6 +52,11 @@ SettingsContainer::~SettingsContainer() { settingsPanel = nullptr; categoryList = nullptr; + + setLookAndFeel(nullptr); + if (auto parentWindow = findParentComponentOfClass()) + parentWindow->setLookAndFeel(nullptr); + sendChangeMessage(); } From ee220ccb0a659d021290d809ac1df24cb9186ca5 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Thu, 15 Jul 2021 22:22:25 -0400 Subject: [PATCH 071/183] Generic dylib names --- TerpstraSysEx.jucer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TerpstraSysEx.jucer b/TerpstraSysEx.jucer index 499419b2..600014e1 100644 --- a/TerpstraSysEx.jucer +++ b/TerpstraSysEx.jucer @@ -321,7 +321,7 @@ Date: Thu, 15 Jul 2021 22:25:01 -0400 Subject: [PATCH 072/183] windows installer tweaks --- .../InnoSetup/LumatoneEditorWinInstallerScript.iss | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Installers/InnoSetup/LumatoneEditorWinInstallerScript.iss b/Installers/InnoSetup/LumatoneEditorWinInstallerScript.iss index 4293c767..a738288a 100644 --- a/Installers/InnoSetup/LumatoneEditorWinInstallerScript.iss +++ b/Installers/InnoSetup/LumatoneEditorWinInstallerScript.iss @@ -24,6 +24,7 @@ AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} +AllowNoIcons=yes DefaultDirName={autopf64}\{#MyAppName} ChangesAssociations=yes DisableProgramGroupPage=yes @@ -34,7 +35,7 @@ OutputDir=.\ OutputBaseFilename=Install {#MyAppName} {#MyAppVersion} Compression=lzma SolidCompression=yes -UsePreviousAppDir=no +UsePreviousAppDir=yes WizardStyle=modern [Languages] @@ -58,14 +59,14 @@ Source: "vc_redist.x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion deleteafteri Root: HKA; Subkey: "Software\Classes\{#MappingAssocExt}\OpenWithProgIds"; ValueType: string; ValueName: "{#MappingAssocKey}"; ValueData: "%"; Flags: uninsdeletevalue Root: HKA; Subkey: "Software\Classes\{#MappingAssocExt}"; ValueType: string; ValueName: ""; ValueData: "{#MappingAssocName}"; Flags: uninsdeletekey Root: HKA; Subkey: "Software\Classes\{#MappingAssocExt}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\ltn.ico" -Root: HKA; Subkey: "Software\Classes\{#MappingAssocExt}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" -Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: {#MappingAssocExt}; ValueData: "" +Root: HKA; Subkey: "Software\Classes\{#MappingAssocExt}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeNameDest}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeNameDest}\SupportedTypes"; ValueType: string; ValueName: {#MappingAssocExt}; ValueData: "" Root: HKA; Subkey: "Software\Classes\{#PaletteAssocExt}"; ValueType: string; ValueName: ""; ValueData: "{#PaletteAssocName}"; Flags: uninsdeletekey Root: HKA; Subkey: "Software\Classes\{#PaletteAssocExt}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData:"{app}\ltp.ico" [Icons] -Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" -Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeNameDest}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeNameDest}"; Tasks: desktopicon [Code] // Pulled from https://stackoverflow.com/questions/24574035/how-to-install-microsoft-vc-redistributables-silently-in-inno-setup From 49331513fae693523da2d6a2fe72df52e4ab119e Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Fri, 16 Jul 2021 18:28:21 -0400 Subject: [PATCH 073/183] Keep managed pointer to open dialog window to delete on shutdown --- Source/GlobalSettingsArea.cpp | 23 ++++------------------- Source/GlobalSettingsArea.h | 3 --- Source/Main.cpp | 16 +++++++++++++++- Source/Main.h | 5 +++++ Source/Settings/SettingsContainer.cpp | 18 ++++-------------- Source/Settings/SettingsContainer.h | 2 +- 6 files changed, 29 insertions(+), 38 deletions(-) diff --git a/Source/GlobalSettingsArea.cpp b/Source/GlobalSettingsArea.cpp index e9d9499d..98342f24 100644 --- a/Source/GlobalSettingsArea.cpp +++ b/Source/GlobalSettingsArea.cpp @@ -129,12 +129,6 @@ GlobalSettingsArea::~GlobalSettingsArea() //[Destructor]. You can add your own custom destruction code here.. - if (settingsAreOpen) - { - settingsDialog->setLookAndFeel(nullptr); - settingsDialog->exitModalState(0); - settingsDialog = nullptr; - } //[/Destructor] } @@ -203,7 +197,6 @@ void GlobalSettingsArea::buttonClicked (juce::Button* buttonThatWasClicked) auto settingsComponent = new SettingsContainer(); settingsComponent->setLookAndFeel(&getLookAndFeel()); - settingsComponent->addChangeListener(this); DialogWindow::LaunchOptions launchOptions; launchOptions.content.setOwned(settingsComponent); @@ -216,11 +209,12 @@ void GlobalSettingsArea::buttonClicked (juce::Button* buttonThatWasClicked) launchOptions.dialogBackgroundColour = Colour(); - settingsDialog = launchOptions.launchAsync(); - settingsDialog->centreWithSize(548, 240); + auto settingsDialog = launchOptions.launchAsync(); settingsDialog->setLookAndFeel(&TerpstraSysExApplication::getApp().getLookAndFeel().compactWindowStyle); + settingsDialog->centreWithSize(548, 240); + + TerpstraSysExApplication::getApp().setOpenDialogWindow(settingsDialog); - settingsAreOpen = true; //[/UserButtonCode_buttonCalibrate] } @@ -255,15 +249,6 @@ void GlobalSettingsArea::changeListenerCallback(ChangeBroadcaster *source) String activeMacroButtonColour = activeMacroButtonColourEdit->getColourAsString(); TerpstraSysExApplication::getApp().getLumatoneController().sendMacroButtonActiveColour(activeMacroButtonColour); } - else - { - auto settings = dynamic_cast(source); - if (settings != nullptr) - { - // Settings dialog was exited - settingsAreOpen = false; - } - } } void GlobalSettingsArea::restoreStateFromPropertiesFile(PropertiesFile* propertiesFile) diff --git a/Source/GlobalSettingsArea.h b/Source/GlobalSettingsArea.h index b8218da7..07cee346 100644 --- a/Source/GlobalSettingsArea.h +++ b/Source/GlobalSettingsArea.h @@ -78,9 +78,6 @@ class GlobalSettingsArea : public juce::Component, std::unique_ptr