From ab9a15cb4eee26294dd23bc8df9cdb063b2cdd50 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Tue, 14 May 2024 20:34:31 -0400 Subject: [PATCH] work on updating mapping settings controls --- CMakeLists.txt | 5 +- Source/MainComponent.cpp | 297 +++++++++++++++-------------- Source/MainComponent.h | 30 +-- Source/MappingSettingsControls.cpp | 236 +++++++++++++++++++++++ Source/MappingSettingsControls.h | 67 +++++++ Source/MappingSettingsPanel.cpp | 47 +++++ Source/MappingSettingsPanel.h | 49 +++++ 7 files changed, 576 insertions(+), 155 deletions(-) create mode 100644 Source/MappingSettingsControls.cpp create mode 100644 Source/MappingSettingsControls.h create mode 100644 Source/MappingSettingsPanel.cpp create mode 100644 Source/MappingSettingsPanel.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 49afb05..f149cb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ add_subdirectory($ENV{juce_DIR} subprojects/juce) juce_add_gui_app( LumatoneEditor PRODUCT_NAME "Lumatone Editor" - VERSION "1.2.0" + VERSION "1.5.0b" BUNDLE_ID "com.Lumatone.LumatoneEditor" # ICON_SMALL "${CMAKE_CURRENT_SOURCE_DIR}/BinaryData/Assets/PNG/AppIcon@1x.png" # ICON_BIG "${CMAKE_CURRENT_SOURCE_DIR}/BinaryData/Assets/PNG/AppIcon@3x.png" @@ -44,7 +44,7 @@ if (UNIX) set(LibraryPath "${CMAKE_CURRENT_SOURCE_DIR}/Libraries/mac") set(LibraryInclude "${LibraryPath}/include") set(LibraryCode "${LibraryInclude}/libssh2.h") - + add_library(SSHLib SHARED IMPORTED) set_target_properties( SSHLib PROPERTIES IMPORTED_LOCATION "${LibraryPath}/lib/libssh2.dylib") endif() @@ -140,4 +140,3 @@ target_link_libraries(LumatoneEditor # COMMAND install_name_tool -change @rpath/libssh2.dylib @loader_path/../Frameworks/libssh2.dylib $ # ) # endif() - diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 303b34c..0519fa3 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -15,12 +15,12 @@ #include "LumatoneMenu.h" #include "MidiEditArea.h" -#include "NoteEditArea.h" -#include "IsomorphicMassAssign.h" +// #include "NoteEditArea.h" +// #include "IsomorphicMassAssign.h" -#include "CurvesArea.h" +// #include "CurvesArea.h" #include "GlobalSettingsArea.h" -#include "MappingSettingsComponent.h" +#include "MappingSettingsPanel.h" #include "./ColourPaletteWindow.h" @@ -47,14 +47,14 @@ MainContentComponent::MainContentComponent(const LumatoneEditorState& stateIn, j addAndMakeVisible(allKeysOverview.get()); // Edit function area - noteEditArea.reset(new NoteEditArea(stateIn)); - noteEditArea->getOctaveBoardSelectorTab()->addChangeListener(this); - noteEditArea->getColourViewComponent()->addListener(this); // Open up ColourPaletteWindow + // noteEditArea.reset(new NoteEditArea(stateIn)); + // noteEditArea->getOctaveBoardSelectorTab()->addChangeListener(this); + // noteEditArea->getColourViewComponent()->addListener(this); // Open up ColourPaletteWindow - mappingSettingsComponent = std::make_unique(stateIn); + mappingSettingsComponent = std::make_unique(stateIn); - curvesArea.reset(new CurvesArea(stateIn)); - addAndMakeVisible(curvesArea.get()); + // curvesArea.reset(new CurvesArea(stateIn)); + // addAndMakeVisible(curvesArea.get()); globalSettingsArea.reset(new GlobalSettingsArea(stateIn)); addAndMakeVisible(globalSettingsArea.get()); @@ -62,9 +62,9 @@ MainContentComponent::MainContentComponent(const LumatoneEditorState& stateIn, j sectionTabs = std::make_unique(juce::TabbedButtonBar::TabsAtTop); addAndMakeVisible(*sectionTabs); - sectionTabs->addTab("Key Editor", juce::Colour(), noteEditArea.get(), false); - sectionTabs->addTab("AutoGenerator", juce::Colour(), noteEditArea.get(), false); - sectionTabs->addTab("Advanced", juce::Colour(), noteEditArea.get(), false); + sectionTabs->addTab("Key Editor", juce::Colour(), mappingSettingsComponent.get(), false); + sectionTabs->addTab("AutoGenerator", juce::Colour(), mappingSettingsComponent.get(), false); + sectionTabs->addTab("Advanced", juce::Colour(), mappingSettingsComponent.get(), false); sectionTabs->addTab("Mapping Settings", juce::Colour(), mappingSettingsComponent.get(), false); btnLoadFile.reset(new juce::TextButton("btnLoadFile")); @@ -101,10 +101,10 @@ MainContentComponent::MainContentComponent(const LumatoneEditorState& stateIn, j setSize(DEFAULTMAINWINDOWWIDTH, DEFAULTMAINWINDOWHEIGHT); // Select first board and first key - noteEditArea->getOctaveBoardSelectorTab()->setCurrentTabIndex(0, true); + // noteEditArea->getOctaveBoardSelectorTab()->setCurrentTabIndex(0, true); // The above call is supposed to update changeListener - but apparently doesn't... Call it manually then. XXX - changeListenerCallback(noteEditArea->getOctaveBoardSelectorTab()); - noteEditArea->changeSingleKeySelection(0); + // changeListenerCallback(noteEditArea->getOctaveBoardSelectorTab()); + // noteEditArea->changeSingleKeySelection(0); btnLoadFile->getProperties().set(LumatoneEditorStyleIDs::textButtonIconHashCode, LumatoneEditorIcon::LoadIcon); btnSaveFile->getProperties().set(LumatoneEditorStyleIDs::textButtonIconHashCode, LumatoneEditorIcon::SaveIcon); @@ -114,6 +114,9 @@ MainContentComponent::MainContentComponent(const LumatoneEditorState& stateIn, j // Only enable when connected btnImportFile->setEnabled(false); + // DEBUG + sectionTabs->setCurrentTabIndex(3); + // Initialize mapping structure //deleteAll(); } @@ -126,10 +129,10 @@ MainContentComponent::~MainContentComponent() btnSaveFile = nullptr; btnImportFile = nullptr; - globalSettingsArea = nullptr; - curvesArea = nullptr; + // globalSettingsArea = nullptr; + // curvesArea = nullptr; mappingSettingsComponent = nullptr; - noteEditArea = nullptr; + // noteEditArea = nullptr; midiEditArea = nullptr; allKeysOverview = nullptr; @@ -140,7 +143,7 @@ MainContentComponent::~MainContentComponent() void MainContentComponent::saveStateToPropertiesFile(PropertiesFile* propertiesFile) { - noteEditArea->saveStateToPropertiesFile(propertiesFile); + // noteEditArea->saveStateToPropertiesFile(propertiesFile); // globalSettingsArea->saveStateToPropertiesFile(propertiesFile); } @@ -169,95 +172,95 @@ void MainContentComponent::saveStateToPropertiesFile(PropertiesFile* propertiesF // newData = *getMappingData(); //} -TabbedButtonBar *MainContentComponent::getOctaveBoardSelectorTab() -{ - return noteEditArea->getOctaveBoardSelectorTab(); -} - -LumatoneAction* MainContentComponent::createDeleteCurrentSectionAction() -{ - auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); - if (currentSetSelection >= 0 && currentSetSelection < getOctaveBoardSize()) - { - auto keySet = LumatoneBoard(); - return new LumatoneEditAction::SectionEditAction(this, currentSetSelection, keySet); - } - else - return nullptr; -} - -bool MainContentComponent::copyCurrentSubBoardData() -{ - auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); - if (currentSetSelection >= 0 && currentSetSelection < getOctaveBoardSize()) - { - *copiedSubBoardData = getBoard(currentSetSelection); - return true; - } - else - return false; -} - -LumatoneAction* MainContentComponent::createPasteCurrentSectionAction() -{ - auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); - if (currentSetSelection >= 0 && currentSetSelection < getNumBoards() - && !copiedSubBoardData->isEmpty()) - { - return new LumatoneEditAction::SectionEditAction(this, currentSetSelection, *copiedSubBoardData); - } - else - return nullptr; -} - -LumatoneAction* MainContentComponent::createModifiedPasteCurrentSectionAction(CommandID commandID) -{ - auto currentSetSelectionIndex = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); - if (currentSetSelectionIndex >= 0 && currentSetSelectionIndex < getNumBoards() - && !copiedSubBoardData->isEmpty()) - { - - auto modifiedSection = getBoard(currentSetSelectionIndex); - auto octaveSize = getOctaveBoardSize(); - - for (int i = 0; i < octaveSize; i++) - { - LumatoneKey copiedKey = copiedSubBoardData->getKey(i); - LumatoneKey currentSectionKey = getKey(currentSetSelectionIndex, i); - - switch (commandID) - { - case Lumatone::Menu::commandIDs::pasteOctaveBoardNotes: - currentSectionKey.setNoteOrCC(copiedKey.getMidiNumber()); - break; - - case Lumatone::Menu::commandIDs::pasteOctaveBoardChannels: - currentSectionKey.setChannelNumber(copiedKey.getMidiChannel()); - break; - - case Lumatone::Menu::commandIDs::pasteOctaveBoardColours: - currentSectionKey.setColour(copiedKey.getColour()); - break; - - case Lumatone::Menu::commandIDs::pasteOctaveBoardTypes: - currentSectionKey.setKeyType(copiedKey.getType()); - currentSectionKey.setDefaultCCFader(copiedKey.isCCFaderDefault()); - break; - - default: - jassertfalse; - currentSectionKey = copiedKey; - break; - } - - modifiedSection.setKey(currentSectionKey, i); - } - - return new LumatoneEditAction::SectionEditAction(this, currentSetSelectionIndex, modifiedSection); - } - else - return nullptr; -} +// TabbedButtonBar *MainContentComponent::getOctaveBoardSelectorTab() +// { +// return noteEditArea->getOctaveBoardSelectorTab(); +// } + +// LumatoneAction* MainContentComponent::createDeleteCurrentSectionAction() +// { +// auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); +// if (currentSetSelection >= 0 && currentSetSelection < getOctaveBoardSize()) +// { +// auto keySet = LumatoneBoard(); +// return new LumatoneEditAction::SectionEditAction(this, currentSetSelection, keySet); +// } +// else +// return nullptr; +// } + +// bool MainContentComponent::copyCurrentSubBoardData() +// { +// auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); +// if (currentSetSelection >= 0 && currentSetSelection < getOctaveBoardSize()) +// { +// *copiedSubBoardData = getBoard(currentSetSelection); +// return true; +// } +// else +// return false; +// } + +// LumatoneAction* MainContentComponent::createPasteCurrentSectionAction() +// { +// auto currentSetSelection = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); +// if (currentSetSelection >= 0 && currentSetSelection < getNumBoards() +// && !copiedSubBoardData->isEmpty()) +// { +// return new LumatoneEditAction::SectionEditAction(this, currentSetSelection, *copiedSubBoardData); +// } +// else +// return nullptr; +// } + +// LumatoneAction* MainContentComponent::createModifiedPasteCurrentSectionAction(CommandID commandID) +// { +// auto currentSetSelectionIndex = noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex(); +// if (currentSetSelectionIndex >= 0 && currentSetSelectionIndex < getNumBoards() +// && !copiedSubBoardData->isEmpty()) +// { + +// auto modifiedSection = getBoard(currentSetSelectionIndex); +// auto octaveSize = getOctaveBoardSize(); + +// for (int i = 0; i < octaveSize; i++) +// { +// LumatoneKey copiedKey = copiedSubBoardData->getKey(i); +// LumatoneKey currentSectionKey = getKey(currentSetSelectionIndex, i); + +// switch (commandID) +// { +// case Lumatone::Menu::commandIDs::pasteOctaveBoardNotes: +// currentSectionKey.setNoteOrCC(copiedKey.getMidiNumber()); +// break; + +// case Lumatone::Menu::commandIDs::pasteOctaveBoardChannels: +// currentSectionKey.setChannelNumber(copiedKey.getMidiChannel()); +// break; + +// case Lumatone::Menu::commandIDs::pasteOctaveBoardColours: +// currentSectionKey.setColour(copiedKey.getColour()); +// break; + +// case Lumatone::Menu::commandIDs::pasteOctaveBoardTypes: +// currentSectionKey.setKeyType(copiedKey.getType()); +// currentSectionKey.setDefaultCCFader(copiedKey.isCCFaderDefault()); +// break; + +// default: +// jassertfalse; +// currentSectionKey = copiedKey; +// break; +// } + +// modifiedSection.setKey(currentSectionKey, i); +// } + +// return new LumatoneEditAction::SectionEditAction(this, currentSetSelectionIndex, modifiedSection); +// } +// else +// return nullptr; +// } bool MainContentComponent::canPasteCopiedSubBoard() const { @@ -267,8 +270,8 @@ bool MainContentComponent::canPasteCopiedSubBoard() const void MainContentComponent::updateDeveloperMode() { // TODO This can just be implemented individually in handleStatePropertyChange - curvesArea->setDeveloperMode(inDeveloperMode); - globalSettingsArea->setDeveloperMode(inDeveloperMode); + // curvesArea->setDeveloperMode(inDeveloperMode); + // globalSettingsArea->setDeveloperMode(inDeveloperMode); } void MainContentComponent::connectionStateChanged(ConnectionState state) @@ -387,10 +390,10 @@ void MainContentComponent::connectionStateChanged(ConnectionState state) void MainContentComponent::changeListenerCallback(ChangeBroadcaster *source) { - if (source == noteEditArea->getOctaveBoardSelectorTab()) - { - // allKeysOverview->setCurrentSetSelection(noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex()); - } + // if (source == noteEditArea->getOctaveBoardSelectorTab()) + // { + // // allKeysOverview->setCurrentSetSelection(noteEditArea->getOctaveBoardSelectorTab()->getCurrentTabIndex()); + // } } void MainContentComponent::buttonClicked(Button* btn) @@ -406,21 +409,21 @@ void MainContentComponent::buttonClicked(Button* btn) ColourPaletteWindow* paletteWindow = new ColourPaletteWindow(*this); paletteWindow->setSize(proportionOfWidth(popupWidth), proportionOfHeight(popupHeight)); - if (btn == noteEditArea->getColourViewComponent()) - { - colourEdit = noteEditArea->getColourViewComponent(); + // if (btn == noteEditArea->getColourViewComponent()) + // { + // colourEdit = noteEditArea->getColourViewComponent(); - auto colourTextEditor = noteEditArea->getSingleNoteColourTextEditor(); - paletteWindow->listenToColourSelection(static_cast(colourTextEditor)); + // auto colourTextEditor = noteEditArea->getSingleNoteColourTextEditor(); + // paletteWindow->listenToColourSelection(static_cast(colourTextEditor)); - // Shouldn't be necessary when Isomorphic is moved from dev to public - auto isomorphicPanel = noteEditArea->getIsomorphicMassAssignPanel(); - if (isomorphicPanel != nullptr) - paletteWindow->listenToColourSelection(static_cast(isomorphicPanel)); + // // Shouldn't be necessary when Isomorphic is moved from dev to public + // auto isomorphicPanel = noteEditArea->getIsomorphicMassAssignPanel(); + // if (isomorphicPanel != nullptr) + // paletteWindow->listenToColourSelection(static_cast(isomorphicPanel)); - paletteWindow->addColourSelectorToGroup(noteEditArea.get()); - paletteWindow->setCurrentColourSelector(noteEditArea->getSingleNoteColourTextEditor()); - } + // paletteWindow->addColourSelectorToGroup(noteEditArea.get()); + // paletteWindow->setCurrentColourSelector(noteEditArea->getSingleNoteColourTextEditor()); + // } Rectangle componentArea = colourEdit->getScreenBounds().translated(-getScreenX(), -getScreenY()); @@ -441,7 +444,9 @@ void MainContentComponent::paint (Graphics& g) g.fillAll(getEditorLookAndFeel().findColour(LumatoneEditorColourIDs::MediumBackground)); g.setColour(getEditorLookAndFeel().findColour(LumatoneEditorColourIDs::LightBackground)); - g.fillRect(controlsArea); + // g.setColour(juce::Colours::green); + g.fillRect(controlsAreaBackground); + } void MainContentComponent::resized() @@ -450,7 +455,10 @@ void MainContentComponent::resized() // If you add any child components, this is where you should // update their positions. int newWidth = getWidth(); - int newHeight = getHeight(); + // int newHeight = getHeight(); + + contentWidth = proportionOfWidth(contentWidthRatio); + contentMargin = juce::roundToInt((newWidth - contentWidth) * 0.5); // Logo, MIDI edit area and connection state int midiAreaHeight = proportionOfHeight(headerHeight); @@ -459,13 +467,18 @@ void MainContentComponent::resized() // Bounds for controls, where background is darker int footerY = proportionOfHeight(footerAreaY); int footerHeight = getHeight() - footerY; - controlsArea = getBounds().withTop(proportionOfHeight(controlsAreaY)).withBottom(footerY); + + controlsAreaBackground = getBounds().withTop(proportionOfHeight(controlsAreaY)).withBottom(footerY); + controlsArea = controlsAreaBackground.withSizeKeepingCentre(contentWidth, controlsAreaBackground.getHeight()); + + controlsLabelYPos = proportionOfHeight(controlSectionTabsY); // All keys overview/virtual keyboard playing - int newKeysOverviewAreaHeight = jmax(controlsArea.getY() - midiAreaHeight, MINIMALTERPSTRAKEYSETAREAHEIGHT); - int keyboardMarginTop = juce::roundToInt(newKeysOverviewAreaHeight * lumatoneGraphicMarginTop); - int keyboardHeight = juce::roundToInt(newKeysOverviewAreaHeight * lumatoneGraphicH); - allKeysOverview->setBounds(0, midiAreaHeight + keyboardMarginTop, newWidth, keyboardHeight); + // int newKeysOverviewAreaHeight = jmax(controlsLabelYPos - midiAreaHeight, MINIMALTERPSTRAKEYSETAREAHEIGHT); + // int keyboardMarginTop = juce::roundToInt(newKeysOverviewAreaHeight * lumatoneGraphicMarginTop); + // int keyboardHeight = juce::roundToInt(newKeysOverviewAreaHeight * lumatoneGraphicH); + + allKeysOverview->setBounds(contentMargin, midiAreaHeight, contentWidth, controlsLabelYPos - midiAreaHeight); int btnHeight = roundToInt(getHeight() * fileButtonH); int btnMargin = roundToInt(getWidth() * saveloadMarginW); @@ -487,20 +500,22 @@ void MainContentComponent::resized() // noteEditArea->setSize(proportionOfWidth(assignWidth), proportionOfHeight(assignHeight)); // noteEditArea->setControlsTopLeftPosition(proportionOfWidth(assignMarginX), controlsArea.getY()); - sectionTabs->setBounds(proportionOfWidth(assignMarginX), controlsArea.getY(), proportionOfWidth(assignWidth), proportionOfHeight(assignHeight)); + sectionTabs->setBounds(contentMargin, controlsLabelYPos, contentWidth, footerY - controlsArea.getY()); // generalOptionsArea->setBounds(getLocalBounds().toFloat().getProportion(generalSettingsBounds).toNearestInt()); // pedalSensitivityDlg->setBounds(getLocalBounds().toFloat().getProportion(pedalSettingsBounds).toNearestInt()); - curvesArea->setBounds(getLocalBounds().toFloat().getProportion(curvesAreaBounds).toNearestInt()); + // curvesArea->setBounds(getLocalBounds().toFloat().getProportion(curvesAreaBounds).toNearestInt()); - globalSettingsArea->setBounds(getLocalBounds() - .withTop(roundToInt(getHeight() * footerAreaY)) - .withTrimmedRight(footerHeight) - ); + // globalSettingsArea->setBounds(getLocalBounds() + // .withTop(roundToInt(getHeight() * footerAreaY)) + // .withTrimmedRight(footerHeight) + // ); resizeLabelWithHeight(lblAppName.get(), roundToInt(footerHeight * lumatoneVersionHeight), 1.0f, " "); - lblAppName->setTopLeftPosition(proportionOfWidth(lumatoneVersionMarginX), footerY + (footerHeight - lblAppName->getHeight()) * 0.5f); + lblAppName->setTopLeftPosition( + proportionOfWidth(lumatoneVersionMarginX), + footerY + juce::roundToInt((footerHeight - lblAppName->getHeight()) * 0.5f)); resizeLabelWithHeight(lblAppVersion.get(), roundToInt(lblAppName->getHeight() * 0.75f)); lblAppVersion->setTopLeftPosition(lblAppName->getRight(), lblAppName->getBottom() - lblAppVersion->getHeight()); diff --git a/Source/MainComponent.h b/Source/MainComponent.h index a08f290..b11d43a 100644 --- a/Source/MainComponent.h +++ b/Source/MainComponent.h @@ -19,9 +19,7 @@ class LumatoneKeyboardComponent; class MidiEditArea; -class NoteEditArea; -class MappingSettingsComponent; -class CurvesArea; +class MappingSettingsPanel; class GlobalSettingsArea; @@ -44,13 +42,13 @@ class MainContentComponent : public juce::Component void saveStateToPropertiesFile(PropertiesFile* propertiesFile); juce::TabbedButtonBar* getOctaveBoardSelectorTab(); - CurvesArea* getCurvesArea() { return curvesArea.get(); } + // CurvesArea* getCurvesArea() { return curvesArea.get(); } // Board edit operations - LumatoneAction* createDeleteCurrentSectionAction(); - bool copyCurrentSubBoardData(); - LumatoneAction* createPasteCurrentSectionAction(); - LumatoneAction* createModifiedPasteCurrentSectionAction(CommandID commandID); + LumatoneAction* createDeleteCurrentSectionAction(){return nullptr;}; + bool copyCurrentSubBoardData(){return false;}; + LumatoneAction* createPasteCurrentSectionAction(){return nullptr;}; + LumatoneAction* createModifiedPasteCurrentSectionAction(CommandID commandID){return nullptr;}; bool canPasteCopiedSubBoard() const; // Implementation of ChangeListener @@ -93,10 +91,10 @@ class MainContentComponent : public juce::Component std::unique_ptr allKeysOverview; // Edit fields for setting key and button parameters, and edits for single keys - std::unique_ptr noteEditArea; - std::unique_ptr mappingSettingsComponent; + // std::unique_ptr noteEditArea; + std::unique_ptr mappingSettingsComponent; - std::unique_ptr curvesArea; + // std::unique_ptr curvesArea; std::unique_ptr globalSettingsArea; std::unique_ptr sectionTabs; @@ -115,10 +113,20 @@ class MainContentComponent : public juce::Component //============================================================================== // Position and Size helpers + int contentMargin; + int contentWidth; + + int controlsLabelYPos; juce::Rectangle controlsArea; + juce::Rectangle controlsAreaBackground; + + const float contentWidthRatio = 0.871f; const float headerHeight = 0.0837f; + const float controlSectionTabsY = 0.63f; + // const float controlsLabelHeight = 0.033f; + const float controlsAreaY = 0.662f; const float controlsAreaHeight = 0.43f; diff --git a/Source/MappingSettingsControls.cpp b/Source/MappingSettingsControls.cpp new file mode 100644 index 0000000..585d666 --- /dev/null +++ b/Source/MappingSettingsControls.cpp @@ -0,0 +1,236 @@ +/* +============================================================================== + + MappingSettingsControls.h + Created: 15 Jan 2023 + Author: Vincenzo + +============================================================================== +*/ + +#include "MappingSettingsControls.h" + +#include "LumatoneEditorLookAndFeel.h" + +#include "./lumatone_editor_library/graphics/view_constants.h" + +//============================================================================== +MappingSettingsControls::MappingSettingsControls (const LumatoneEditorState& stateIn) + : LumatoneEditorState("MappingSettingsControls", stateIn) +{ + labelGeneralSettingslTitle.reset (new juce::Label ("labelGeneralSettingslTitle", juce::translate("General Settings"))); + labelGeneralSettingslTitle->setFont(getAppFonts().getFont(LumatoneEditorFont::UniviaProBold)); + labelGeneralSettingslTitle->setJustificationType (juce::Justification::centredLeft); + labelGeneralSettingslTitle->setEditable (false, false, false); + labelGeneralSettingslTitle->setColour(Label::ColourIds::textColourId, getEditorLookAndFeel().findColour(LumatoneEditorColourIDs::LabelBlue)); + labelGeneralSettingslTitle->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000)); + addAndMakeVisible (labelGeneralSettingslTitle.get()); + + buttonAfterTouchActive.reset (new juce::ToggleButton ("buttonAfterTouchActive")); + buttonAfterTouchActive->setButtonText (juce::translate("Polyphonic Aftertouch")); + buttonAfterTouchActive->onClick = [&]() + { + setAftertouchEnabled(buttonAfterTouchActive->getToggleState()); + }; + addAndMakeVisible (buttonAfterTouchActive.get()); + + buttonLightOnKeyStrokes.reset (new juce::ToggleButton ("buttonLightOnKeyStrokes")); + buttonLightOnKeyStrokes->setButtonText (juce::translate("Light on Keystrokes")); + buttonLightOnKeyStrokes->onClick = [&]() + { + setLightOnKeyStrokes(buttonLightOnKeyStrokes->getToggleState()); + }; + addAndMakeVisible (buttonLightOnKeyStrokes.get()); + + labelExprContrSensitivity.reset (new juce::Label ("labelExprContrSensitivity", juce::translate("Sensitivity"))); + labelExprContrSensitivity->setFont(getAppFonts().getFont(LumatoneEditorFont::GothamNarrowMedium)); + labelExprContrSensitivity->setJustificationType (juce::Justification::centred); + labelExprContrSensitivity->setEditable (false, false, false); + labelExprContrSensitivity->setColour (juce::TextEditor::textColourId, juce::Colours::black); + labelExprContrSensitivity->setColour (juce::TextEditor::backgroundColourId, juce::Colour (0x00000000)); + addAndMakeVisible (labelExprContrSensitivity.get()); + + btnInvertExpression.reset (new juce::ToggleButton ("btnInvertExpression")); + btnInvertExpression->setButtonText (juce::translate("Invert")); + btnInvertExpression->onClick = [&]() + { + setInvertExpression(btnInvertExpression->getToggleState()); + }; + addAndMakeVisible (btnInvertExpression.get()); + + lblExpression.reset (new juce::Label ("lblExpression", juce::translate("Expression"))); + lblExpression->setFont(getAppFonts().getFont(LumatoneEditorFont::UniviaProBold)); + 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)); + addAndMakeVisible (lblExpression.get()); + + sldExprCtrlSensitivity.reset (new juce::Slider ("sldExprCtrlSensitivity")); + sldExprCtrlSensitivity->setRange (0, 127, 1); + sldExprCtrlSensitivity->setSliderStyle (juce::Slider::RotaryHorizontalVerticalDrag); + sldExprCtrlSensitivity->setTextBoxStyle (juce::Slider::TextBoxBelow, false, 60, 20); + sldExprCtrlSensitivity->onValueChange = [&] () + { + exprSensitivitySliderCallback(); + }; + addAndMakeVisible (sldExprCtrlSensitivity.get()); + + btnInvertSustain.reset (new juce::ToggleButton ("btnInvertSustain")); + btnInvertSustain->setButtonText (juce::translate("Invert")); + btnInvertSustain->onClick = [&]() + { + setInvertSustain(btnInvertSustain->getToggleState()); + }; + // addAndMakeVisible (btnInvertSustain.get()); + + lblSustain.reset (new juce::Label ("lblSustain", juce::translate("Sustain"))); + lblSustain->setFont(getAppFonts().getFont(LumatoneEditorFont::UniviaProBold)); + 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)); + // addAndMakeVisible (lblSustain.get()); + + + addEditorListener(this); +} + +MappingSettingsControls::~MappingSettingsControls() +{ + removeEditorListener(this); + + labelGeneralSettingslTitle = nullptr; + buttonAfterTouchActive = nullptr; + buttonLightOnKeyStrokes = nullptr; +} + +//============================================================================== +void MappingSettingsControls::paint (juce::Graphics& g) +{ + g.setColour(juce::Colour(0xff212626)); + g.fillRoundedRectangle(getLocalBounds().toFloat().withTop(proportionOfHeight(SETTINGSAREAMARGINHEIGHT)), roundedCornerSize); +} + +void MappingSettingsControls::resized() +{ + float w = getWidth(); + float h = getHeight(); + + roundedCornerSize = roundToInt(getWindowBounds().getHeight() * ROUNDEDCORNERTOAPPHEIGHT); + + resizeLabelWithHeight(labelGeneralSettingslTitle.get(), roundToInt(getHeight() * SETTINGSLABELHEIGHT)); + labelGeneralSettingslTitle->setTopLeftPosition(roundToInt(getWidth() * SETTINGSLABELMARGINWIDTH), 0); + + int marginX = roundToInt(getParentWidth() * SETTINGSCONTROLMARGINTOAPPWIDTH); + + buttonAfterTouchActive->setBounds( + marginX, proportionOfHeight(0.3f), proportionOfWidth(1.0f), proportionOfHeight(SETTINGSTOGGLEHEIGHTSCALAR) + ); + + buttonLightOnKeyStrokes->setBounds( + marginX, proportionOfHeight(0.5f), proportionOfWidth(1.0f), proportionOfHeight(SETTINGSTOGGLEHEIGHTSCALAR) + ); + + roundedCornerSize = roundToInt(getWindowBounds().getHeight() * ROUNDEDCORNERTOAPPHEIGHT); + + 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); + lblExpression->setBounds(expressionBounds.getX() + lblMarginX, 0, lblWidth, lblHeight); + lblSustain->setBounds(sustainBounds.getX() + lblMarginX, 0, lblWidth, lblHeight); + + 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() + ); +} + +void MappingSettingsControls::loadFromMapping() +{ + buttonAfterTouchActive->setToggleState(getAftertouchOn(), juce::NotificationType::dontSendNotification); + buttonLightOnKeyStrokes->setToggleState(getLightOnKeyStrokes(), juce::NotificationType::dontSendNotification); + btnInvertExpression->setToggleState(getInvertExpression(), juce::NotificationType::dontSendNotification); + btnInvertSustain->setToggleState(getInvertSustain(), juce::NotificationType::dontSendNotification); + sldExprCtrlSensitivity->setValue(getExpressionSensitivity(), juce::NotificationType::dontSendNotification); +} + +void MappingSettingsControls::exprSensitivitySliderCallback() +{ + 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); + } + + setExpressionSensitivity(newSensitvity); +} + +void MappingSettingsControls::lightOnKeyStrokesChanged(bool lightOn) +{ + buttonLightOnKeyStrokes->setToggleState(getLightOnKeyStrokes(), dontSendNotification); +} + +void MappingSettingsControls::aftertouchToggled(bool enabled) +{ + buttonAfterTouchActive->setToggleState(getAftertouchOn(), dontSendNotification); +} + +void MappingSettingsControls::expressionPedalSensitivityChanged(unsigned char value) +{ + sldExprCtrlSensitivity->setValue(getExpressionSensitivity(), dontSendNotification); +} + +void MappingSettingsControls::invertFootControllerChanged(bool inverted) +{ + btnInvertExpression->setToggleState(getInvertExpression(), dontSendNotification); +} + +void MappingSettingsControls::invertSustainToggled(bool inverted) +{ + btnInvertSustain->setToggleState(getInvertSustain(), dontSendNotification); +} + +void MappingSettingsControls::firmwareVersionChanged() +{ + if (getFirmwareSupport().versionAcknowledgesCommand(getLumatoneVersion(), INVERT_SUSTAIN_PEDAL)) + { + btnInvertSustain->setEnabled(true); + btnInvertSustain->setTooltip(""); + } + else + { + btnInvertSustain->setEnabled(false); + btnInvertSustain->setTooltip("This feature is not supported by the firmware version of your Lumatone."); + } +} diff --git a/Source/MappingSettingsControls.h b/Source/MappingSettingsControls.h new file mode 100644 index 0000000..5d1fba3 --- /dev/null +++ b/Source/MappingSettingsControls.h @@ -0,0 +1,67 @@ +/* + ============================================================================== + + MappingSettingsControls.h + Created: 15 Jan 2023 + Author: Vincenzo + + ============================================================================== +*/ + +#ifndef LUMATONE_EDITOR_MAPPING_SETTINGS_COMPONENT_H +#define LUMATONE_EDITOR_MAPPING_SETTINGS_COMPONENT_H + +#include "./lumatone_editor_library/listeners/editor_listener.h" +#include "LumatoneEditorState.h" + +class MappingSettingsControls : public juce::Component + , public LumatoneEditorState + , public LumatoneEditor::EditorListener +{ +public: + MappingSettingsControls(const LumatoneEditorState& stateIn); + ~MappingSettingsControls() override; + + void paint (juce::Graphics& g) override; + void resized() override; + + void loadFromMapping(); + + // LumatoneEditor::EditorListener Implementation + void lightOnKeyStrokesChanged(bool lightOn) override; + void aftertouchToggled(bool enabled) override; + + void expressionPedalSensitivityChanged(unsigned char value) override; + void invertFootControllerChanged(bool inverted) override; + + void invertSustainToggled(bool inverted) override; + + void firmwareVersionChanged() override; + +private: + + void exprSensitivitySliderCallback(); + +private: + int roundedCornerSize = 0; + juce::Rectangle expressionBounds; + juce::Rectangle sustainBounds; + const float sectionMarginWidth = 0.05f; + + //============================================================================== + std::unique_ptr labelGeneralSettingslTitle; + std::unique_ptr buttonAfterTouchActive; + std::unique_ptr buttonLightOnKeyStrokes; + + std::unique_ptr labelExprContrSensitivity; + std::unique_ptr btnInvertExpression; + std::unique_ptr lblExpression; + std::unique_ptr sldExprCtrlSensitivity; + std::unique_ptr btnInvertSustain; + std::unique_ptr lblSustain; + + //============================================================================== + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MappingSettingsControls) +}; + +#endif // LUMATONE_EDITOR_MAPPING_SETTINGS_COMPONENT_H diff --git a/Source/MappingSettingsPanel.cpp b/Source/MappingSettingsPanel.cpp new file mode 100644 index 0000000..0042b31 --- /dev/null +++ b/Source/MappingSettingsPanel.cpp @@ -0,0 +1,47 @@ +/* + ============================================================================== + + MappingSettingsPanel.h + Created: 14 May 2024 + Author: Vincenzo + + ============================================================================== +*/ + +#include "./MappingSettingsPanel.h" +#include "./MappingSettingsControls.h" +#include "./CurvesArea.h" + +MappingSettingsPanel::MappingSettingsPanel(const LumatoneEditorState& stateIn) + : juce::Component("MappingSettingsPanel") + , LumatoneEditorState(stateIn) +{ + settingsControls = std::make_unique(stateIn); + addAndMakeVisible(settingsControls.get()); + + curvesArea = std::make_unique(stateIn); + addAndMakeVisible(curvesArea.get()); +} + +MappingSettingsPanel::~MappingSettingsPanel() +{ + curvesArea = nullptr; + settingsControls = nullptr; +} + +void MappingSettingsPanel::paint(juce::Graphics& g) +{ + +} + +void MappingSettingsPanel::resized() +{ + contentMarginY = proportionOfHeight(contentMarginHeightRatio); + contentHeight = juce::roundToInt(getHeight() - contentMarginY * 2); + + settingsControls->setBounds(0, contentMarginY, proportionOfWidth(controlsWidthRatio), contentHeight); + + int curvesAreaW = proportionOfWidth(curvesAreaWidthRatio); + int curvesAreaX = getWidth() - curvesAreaW; + curvesArea->setBounds(curvesAreaX, contentMarginY, curvesAreaW, contentHeight); +} diff --git a/Source/MappingSettingsPanel.h b/Source/MappingSettingsPanel.h new file mode 100644 index 0000000..80014c0 --- /dev/null +++ b/Source/MappingSettingsPanel.h @@ -0,0 +1,49 @@ +/* + ============================================================================== + + MappingSettingsPanel.h + Created: 14 May 2024 + Author: Vincenzo + + ============================================================================== +*/ + +#ifndef LUMATONE_EDITOR_MAPPING_SETTINGS_PANEL_H +#define LUMATONE_EDITOR_MAPPING_SETTINGS_PANEL_H + +// #include "./lumatone_editor_library/listeners/editor_listener.h" +#include "LumatoneEditorState.h" + +class MappingSettingsControls; +class CurvesArea; + +class MappingSettingsPanel : public juce::Component + , public LumatoneEditorState + // , public LumatoneEditor::EditorListener +{ +public: + MappingSettingsPanel(const LumatoneEditorState& stateIn); + ~MappingSettingsPanel() override; + + + void paint(juce::Graphics& g) override; + void resized() override; + + +private: + + std::unique_ptr settingsControls; + std::unique_ptr curvesArea; + + + int contentMarginY; + int contentHeight; + + const float contentMarginHeightRatio = 0.07f; + + const float controlsWidthRatio = 0.466f; + const float curvesAreaWidthRatio = 0.512f; + +}; + +#endif //LUMATONE_EDITOR_MAPPING_SETTINGS_PANEL_H