From 323ff443ec86f078ee5d2f7e24fd4a90e1b3b765 Mon Sep 17 00:00:00 2001 From: Vincenzo Sicurella Date: Sat, 6 Jan 2024 16:11:46 -0500 Subject: [PATCH] fix loading recent files and colour palettes --- Source/LumatoneEditorState.cpp | 81 ++++++++++++++++++++++------ Source/LumatoneEditorState.h | 30 +++++++---- Source/LumatoneMenu.cpp | 1 + Source/Main.cpp | 97 +++++++--------------------------- Source/Main.h | 11 +--- Source/MainComponent.cpp | 2 +- 6 files changed, 109 insertions(+), 113 deletions(-) diff --git a/Source/LumatoneEditorState.cpp b/Source/LumatoneEditorState.cpp index aee4b950..61f0d685 100644 --- a/Source/LumatoneEditorState.cpp +++ b/Source/LumatoneEditorState.cpp @@ -23,6 +23,7 @@ juce::Array GetLumatoneEditorProperty() properties.add(LumatoneEditorProperty::InCalibrationMode); properties.add(LumatoneEditorProperty::FirmwareUpdatePerformed); properties.add(LumatoneEditorProperty::ColourPalettes); + properties.add(LumatoneEditorProperty::CurrentFile); properties.add(LumatoneEditorProperty::RecentFiles); properties.add(LumatoneEditorProperty::UserDocumentsDirectory); properties.add(LumatoneEditorProperty::UserMappingsDirectory); @@ -50,7 +51,14 @@ LumatoneEditorState::LumatoneEditorState(juce::String name, LumatoneFirmwareDriv #endif propertiesFile = std::make_shared(options); + DBG(propertiesFile->createXml("LumatoneEditorSettings")->toString()); jassert(propertiesFile != nullptr); + + recentFiles = std::make_shared(); + recentFiles->restoreFromString(propertiesFile->getValue(LumatoneEditorProperty::RecentFiles)); + recentFiles->removeNonExistentFiles(); + + colourPalettes = std::make_shared>(); } LumatoneEditorState::LumatoneEditorState(juce::String name, const LumatoneEditorState &stateIn) @@ -58,11 +66,17 @@ LumatoneEditorState::LumatoneEditorState(juce::String name, const LumatoneEditor , appFonts(stateIn.appFonts) , lookAndFeel(stateIn.lookAndFeel) , propertiesFile(stateIn.propertiesFile) + , recentFiles(stateIn.recentFiles) + , colourPalettes(stateIn.colourPalettes) { } LumatoneEditorState::~LumatoneEditorState() { + recentFiles = nullptr; + propertiesFile = nullptr; + lookAndFeel = nullptr; + appFonts = nullptr; } juce::var LumatoneEditorState::getProperty(juce::Identifier propertyId) const @@ -70,17 +84,20 @@ juce::var LumatoneEditorState::getProperty(juce::Identifier propertyId) const return propertiesFile->getValue(propertyId.toString()); } -juce::RecentlyOpenedFilesList LumatoneEditorState::getRecentFiles() const +juce::RecentlyOpenedFilesList& LumatoneEditorState::getRecentFiles() +{ + return *recentFiles; +} + +const juce::Array& LumatoneEditorState::getColourPalettes() { - juce::RecentlyOpenedFilesList recentFiles; - recentFiles.restoreFromString(propertiesFile->getValue("RecentFiles")); - recentFiles.removeNonExistentFiles(); - return recentFiles; + loadColourPalettesFromFile(); + return *colourPalettes; } juce::File LumatoneEditorState::getUserDocumentsDirectory() const { - juce::String possibleDirectory = propertiesFile->getValue("UserDocumentsDirectory"); + juce::String possibleDirectory = propertiesFile->getValue(LumatoneEditorProperty::UserDocumentsDirectory); juce::File directory; if (juce::File::isAbsolutePath(possibleDirectory)) @@ -101,7 +118,7 @@ juce::File LumatoneEditorState::getUserMappingsDirectory() const { juce::File parentFolder = getUserDocumentsDirectory(); - juce::String possibleDirectory = propertiesFile->getValue("UserMappingsDirectory"); + juce::String possibleDirectory = propertiesFile->getValue(LumatoneEditorProperty::UserMappingsDirectory); juce::File directory; if (juce::File::isAbsolutePath(possibleDirectory)) @@ -122,7 +139,7 @@ juce::File LumatoneEditorState::getUserPalettesDirectory() const { juce::File parentFolder = getUserDocumentsDirectory(); - juce::String possibleDirectory = propertiesFile->getValue("UserPalettesDirectory"); + juce::String possibleDirectory = propertiesFile->getValue(LumatoneEditorProperty::UserPalettesDirectory); juce::File directory; if (juce::File::isAbsolutePath(possibleDirectory)) @@ -160,9 +177,9 @@ void LumatoneEditorState::setDeveloperMode(bool developerModeOn) state.setPropertyExcludingListener(this, LumatoneEditorProperty::DeveloperModeOn, inDeveloperMode, undoManager); } -bool LumatoneEditorState::sendSysExToDevice() const +bool LumatoneEditorState::doSendChangesToDevice() const { - return LumatoneApplicationState::sendSysExToDevice() && editorMode == EditorMode::ONLINE; + return LumatoneApplicationState::doSendChangesToDevice() && editorMode == EditorMode::ONLINE; } juce::ValueTree LumatoneEditorState::loadStateProperties(juce::ValueTree stateIn) @@ -206,10 +223,13 @@ void LumatoneEditorState::handleStatePropertyChange(juce::ValueTree stateIn, con else if (property == LumatoneEditorProperty::ColourPalettes) { + } + else if (property == LumatoneEditorProperty::CurrentFile) + { + currentFile = juce::File(stateIn[property]); } else if (property == LumatoneEditorProperty::RecentFiles) { - } else if (property == LumatoneEditorProperty::UserDocumentsDirectory) { @@ -239,12 +259,31 @@ void LumatoneEditorState::handleStatePropertyChange(juce::ValueTree stateIn, con void LumatoneEditorState::setColourPalettes(const juce::Array &palettesIn) { - colourPalettes = palettesIn; + *colourPalettes = palettesIn; +} + +void LumatoneEditorState::loadColourPalettesFromFile() +{ + auto directory = getUserPalettesDirectory(); + auto foundPaletteFiles = directory.findChildFiles(juce::File::TypesOfFileToFind::findFiles, true, '*' + juce::String(PALETTEFILEEXTENSION)); + + juce::Array newPalettes; + + auto paletteSorter = LumatoneEditorPaletteSorter(); + for (auto file : foundPaletteFiles) + { + LumatoneEditorColourPalette palette = LumatoneEditorColourPalette::loadFromFile(file); + newPalettes.addSorted(paletteSorter, palette); + } + + setColourPalettes(newPalettes); } void LumatoneEditorState::addPalette(const LumatoneEditorColourPalette &newPalette) { - colourPalettes.add(newPalette); + colourPalettes->add(newPalette); + // TODO + state.setPropertyExcludingListener(this, LumatoneEditorProperty::ColourPalettes, "", nullptr); } bool LumatoneEditorState::deletePaletteFile(juce::File pathToPalette) @@ -260,13 +299,14 @@ bool LumatoneEditorState::deletePaletteFile(juce::File pathToPalette) } // Open a SysEx mapping from the file specified in currentFile -bool LumatoneEditorState::openFromCurrentFile() +bool LumatoneEditorState::resetToCurrentFile() { if (getCurrentFile().getFullPathName().isEmpty()) { // Replace with blank file LumatoneLayout defaultLayout; setCompleteConfig(defaultLayout); + setHasChangesToSave(false); return true; } @@ -294,7 +334,7 @@ bool LumatoneEditorState::openFromCurrentFile() // undoManager.clearUndoHistory(); // Add file to recent files list - recentFiles.addFile(currentFile); + recentFiles->addFile(currentFile); return true; } @@ -309,9 +349,18 @@ bool LumatoneEditorState::openFromCurrentFile() bool LumatoneEditorState::setCurrentFile(File fileToOpen) { currentFile = fileToOpen; - return openFromCurrentFile(); + state.setPropertyExcludingListener(this, LumatoneEditorProperty::CurrentFile, currentFile.getFullPathName(), nullptr); + return resetToCurrentFile(); } +// open a file from the "recent files" menu +bool LumatoneEditorState::openRecentFile(int recentFileIndex) +{ + jassert(recentFileIndex >= 0 && recentFileIndex < recentFiles->getNumFiles()); + return setCurrentFile(recentFiles->getFile(recentFileIndex)); +} + + void LumatoneEditorState::setEditMode(EditorMode editMode) { editorMode = editMode; diff --git a/Source/LumatoneEditorState.h b/Source/LumatoneEditorState.h index de9db332..b8f9db5c 100644 --- a/Source/LumatoneEditorState.h +++ b/Source/LumatoneEditorState.h @@ -34,7 +34,8 @@ namespace LumatoneEditorProperty static const juce::Identifier FirmwareUpdatePerformed = juce::Identifier("FirmwareUpdatePerformed"); static const juce::Identifier ColourPalettes = juce::Identifier("ColourPalettes"); - + + static const juce::Identifier CurrentFile = juce::Identifier("CurrentFile"); static const juce::Identifier RecentFiles = juce::Identifier("RecentFiles"); static const juce::Identifier AutoConnectDevice = juce::Identifier("AutoConnectDevice"); @@ -79,7 +80,8 @@ class LumatoneEditorState : public LumatoneApplicationState LumatoneEditorLookAndFeel& getEditorLookAndFeel() { return *lookAndFeel; } - const juce::Array& getColourPalettes() { return colourPalettes; } + //const juce::Array& getColourPalettes() { return colourPalettes; } + const juce::Array& getColourPalettes(); const LumatoneEditorFontLibrary& getAppFonts() const { return *appFonts; } @@ -88,7 +90,8 @@ class LumatoneEditorState : public LumatoneApplicationState // juce::PropertiesFile& getPropertiesFile() { return *propertiesFile; } juce::File getCurrentFile() const { return currentFile; } - juce::RecentlyOpenedFilesList getRecentFiles() const; + juce::RecentlyOpenedFilesList& getRecentFiles(); + juce::File getUserDocumentsDirectory() const; juce::File getUserMappingsDirectory() const; juce::File getUserPalettesDirectory() const; @@ -97,20 +100,27 @@ class LumatoneEditorState : public LumatoneApplicationState // Font getAppFont(LumatoneEditorFont fontIdIn, float height = 12.0f) { return appFonts.getFont(fontIdIn, height); } public: - - bool sendSysExToDevice() const override; + bool doSendChangesToDevice() const override; protected: juce::ValueTree loadStateProperties(juce::ValueTree stateIn) override; void handleStatePropertyChange(juce::ValueTree stateIn, const juce::Identifier& property) override; + bool resetToCurrentFile(); + bool openRecentFile(int recentFileIndex); + + void addPalette(const LumatoneEditorColourPalette& newPalette); + bool deletePaletteFile(juce::File pathToPalette); + +public: + + + // Only main app should access these private: void setColourPalettes(const juce::Array& palettesIn); - void addPalette(const LumatoneEditorColourPalette& newPalette); - bool deletePaletteFile(juce::File pathToPalette); + void loadColourPalettesFromFile(); - bool openFromCurrentFile(); bool setCurrentFile(juce::File fileToOpen); void setEditMode(EditorMode editMode); @@ -130,10 +140,10 @@ class LumatoneEditorState : public LumatoneApplicationState std::shared_ptr appFonts; std::shared_ptr lookAndFeel; - juce::Array colourPalettes; + std::shared_ptr> colourPalettes; juce::File currentFile; - juce::RecentlyOpenedFilesList recentFiles; + std::shared_ptr recentFiles; std::shared_ptr propertiesFile; diff --git a/Source/LumatoneMenu.cpp b/Source/LumatoneMenu.cpp index 13f22221..eda71d0b 100644 --- a/Source/LumatoneMenu.cpp +++ b/Source/LumatoneMenu.cpp @@ -82,6 +82,7 @@ namespace Lumatone { { // open a file from the "recent files" menu // TerpstraSysExApplication::getApp().openRecentFile(menuItemID - recentFilesBaseID); + openRecentFile(menuItemID - recentFilesBaseID); } } diff --git a/Source/Main.cpp b/Source/Main.cpp index 825dd402..fe2efa5d 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -47,14 +47,8 @@ TerpstraSysExApplication::TerpstraSysExApplication() LocalisedStrings::setCurrentMappings(new LocalisedStrings(localisation, false)); LocalisedStrings::getCurrentMappings()->setFallback(new LocalisedStrings(BinaryData::engb_txt, false)); - reloadColourPalettes(); + state.loadColourPalettesFromFile(); } -// -//LumatoneFirmwareDriver& TerpstraSysExApplication::initializeDriver() -//{ -// firmwareDriver = new LumatoneFirmwareDriver(LumatoneFirmwareDriver::HostMode::Driver); -// return *firmwareDriver; -//} //============================================================================== void TerpstraSysExApplication::initialise(const String& commandLine) @@ -98,7 +92,7 @@ void TerpstraSysExApplication::initialise(const String& commandLine) if (state.getCurrentFile().existsAsFile()) - state.openFromCurrentFile(); + state.resetToCurrentFile(); } void TerpstraSysExApplication::shutdown() @@ -106,14 +100,14 @@ void TerpstraSysExApplication::shutdown() // Add your application's shutdown code here.. // Save documents directories (Future: provide option to change them and save after changed by user) - state.propertiesFile->setValue("UserDocumentsDirectory", state.getUserDocumentsDirectory().getFullPathName()); - state.propertiesFile->setValue("UserMappingsDirectory", state.getUserMappingsDirectory().getFullPathName()); - state.propertiesFile->setValue("UserPalettesDirectory", state.getUserPalettesDirectory().getFullPathName()); + state.propertiesFile->setValue(LumatoneEditorProperty::UserDocumentsDirectory, state.getUserDocumentsDirectory().getFullPathName()); + state.propertiesFile->setValue(LumatoneEditorProperty::UserMappingsDirectory, state.getUserMappingsDirectory().getFullPathName()); + state.propertiesFile->setValue(LumatoneEditorProperty::UserPalettesDirectory, state.getUserPalettesDirectory().getFullPathName()); // Save recent files list - state.recentFiles.removeNonExistentFiles(); + state.recentFiles->removeNonExistentFiles(); jassert(state.propertiesFile != nullptr); - state.propertiesFile->setValue("RecentFiles", state.recentFiles.toString()); + state.propertiesFile->setValue(LumatoneEditorProperty::RecentFiles, state.recentFiles->toString()); // Save state of main window mainWindow->saveStateToPropertiesFile(state.propertiesFile.get()); @@ -228,26 +222,14 @@ bool TerpstraSysExApplication::saveColourPalette(LumatoneEditorColourPalette& pa } // if (success) - // reloadColourPalettes(); + // loadColourPalettesFromFile(); return success; } -void TerpstraSysExApplication::reloadColourPalettes() +void TerpstraSysExApplication::loadPropertiesFile() { - auto directory = state.getUserPalettesDirectory(); - auto foundPaletteFiles = directory.findChildFiles(juce::File::TypesOfFileToFind::findFiles, true, '*' + juce::String(PALETTEFILEEXTENSION)); - - juce::Array newPalettes; - auto paletteSorter = LumatoneEditorPaletteSorter(); - for (auto file : foundPaletteFiles) - { - LumatoneEditorColourPalette palette = LumatoneEditorColourPalette::loadFromFile(file); - newPalettes.addSorted(paletteSorter, palette); - } - - state.setColourPalettes(newPalettes); } void TerpstraSysExApplication::getAllCommands(Array & commands) @@ -416,12 +398,12 @@ bool TerpstraSysExApplication::perform(const InvocationInfo& info) bool TerpstraSysExApplication::openSysExMapping() { - fileChooser = std::make_unique("Open a Lumatone key mapping", state.recentFiles.getFile(0).getParentDirectory(), "*.ltn;*.tsx"); + fileChooser = std::make_unique("Open a Lumatone key mapping", state.recentFiles->getFile(0).getParentDirectory(), "*.ltn;*.tsx"); fileChooser->launchAsync(FileBrowserComponent::FileChooserFlags::canSelectFiles | FileBrowserComponent::FileChooserFlags::openMode, [&](const FileChooser& chooser) { - state.currentFile = chooser.getResult(); - state.openFromCurrentFile(); + setCurrentFile(chooser.getResult()); + state.resetToCurrentFile(); }); return true; @@ -433,12 +415,11 @@ bool TerpstraSysExApplication::saveSysExMapping(std::function saveFileCallback) { - fileChooser = std::make_unique("Lumatone Key Mapping Files", state.recentFiles.getFile(0).getParentDirectory(), "*.ltn"); + fileChooser = std::make_unique("Lumatone Key Mapping Files", state.recentFiles->getFile(0).getParentDirectory(), "*.ltn"); fileChooser->launchAsync(FileBrowserComponent::FileChooserFlags::saveMode | FileBrowserComponent::FileChooserFlags::warnAboutOverwriting, [this, saveFileCallback](const FileChooser& chooser) { @@ -458,25 +439,15 @@ bool TerpstraSysExApplication::saveSysExMappingAs(std::function save bool TerpstraSysExApplication::resetSysExMapping() { - // Clear file state.setCurrentFile(juce::File()); - - // Clear all edit fields - // ((MainContentComponent*)(mainWindow->getContentComponent()))->deleteAll(); - - //state.setHasChangesToSave(false); - - // Clear undoable actions - // ToDo (?) - // undoManager.clearUndoHistory(); - - - // Window title - // updateMainTitle(); - + updateMainTitle(); return true; } +bool TerpstraSysExApplication::setCurrentFile(juce::File file) +{ + return state.setCurrentFile(file); +} // Saves the current mapping to file, specified in state.getCurrentFile(). bool TerpstraSysExApplication::saveCurrentFile(std::function saveFileCallback) @@ -497,19 +468,10 @@ bool TerpstraSysExApplication::saveCurrentFile(std::function // ToDo undo history? // Add file to recent files list - or put it on top of the list - state.recentFiles.addFile(state.currentFile); - + state.recentFiles->addFile(state.currentFile); return retc; } -// open a file from the "recent files" menu -bool TerpstraSysExApplication::openRecentFile(int recentFileIndex) -{ - jassert(recentFileIndex >= 0 && recentFileIndex < state.recentFiles.getNumFiles()); - state.currentFile = state.recentFiles.getFile(recentFileIndex); - return state.openFromCurrentFile(); -} - bool TerpstraSysExApplication::deleteSubBoardData() { return performUndoableAction(((MainContentComponent*)(mainWindow->getContentComponent()))->createDeleteCurrentSectionAction()); @@ -589,11 +551,6 @@ bool TerpstraSysExApplication::redo() return false; } -// LumatoneColourModel* TerpstraSysExApplication::getColourModel() -// { -// return &colourModel; -// } - bool TerpstraSysExApplication::toggleDeveloperMode() { state.setDeveloperMode(!state.getInDeveloperMode()); @@ -603,12 +560,6 @@ bool TerpstraSysExApplication::toggleDeveloperMode() // return ((MainContentComponent*)(mainWindow->getContentComponent()))->state.setDeveloperMode(newMode); } -// void TerpstraSysExApplication::state.setEditMode(EditorMode editMode) -// { -// state.setEditMode(editMode); -// // lumatoneController->setSysExSendingMode(editMode); -// } - // bool TerpstraSysExApplication::generalOptionsDialog() // { // GeneralOptionsDlg* optionsWindow = new GeneralOptionsDlg(); @@ -737,7 +688,7 @@ void TerpstraSysExApplication::requestConfigurationFromDevice() { // retc == 2: "No" -> no saving, overwrite DBG("Overwriting current edits"); - // setHasChangesToSave(false); + state.setHasChangesToSave(false); requestConfigurationFromDevice(); } }) @@ -773,14 +724,6 @@ void TerpstraSysExApplication::updateMainTitle() mainWindow->setName(windowTitle); } -// void TerpstraSysExApplication::setHasChangesToSave(bool value) -// { - // if (value != hasCh) - // { - // hasChangesToSave = value; - // updateMainTitle(); - // } -// } // //https://forum.juce.com/t/closing-dialog-windows-on-shutdown/27326/6 void TerpstraSysExApplication::setOpenDialogWindow(DialogWindow* dialogWindowIn) diff --git a/Source/Main.h b/Source/Main.h index 569420bf..e87a6757 100644 --- a/Source/Main.h +++ b/Source/Main.h @@ -43,15 +43,9 @@ class TerpstraSysExApplication : public JUCEApplication void systemRequestedQuit() override; void anotherInstanceStarted(const String& commandLine) override; - // static TerpstraSysExApplication& getApp() - // { - // TerpstraSysExApplication* const app = dynamic_cast (JUCEApplication::getInstance()); - // jassert(app != nullptr); - // return *app; - // } + void loadPropertiesFile(); // Menu functionality - //Lumatone::Menu::MainMenuModel* getMainMenu() { return menuModel.get(); } void getAllCommands(Array & commands) override; void getCommandInfo(CommandID commandID, ApplicationCommandInfo& result) override; bool perform(const InvocationInfo& info) override; @@ -61,11 +55,10 @@ class TerpstraSysExApplication : public JUCEApplication bool saveSysExMappingAs(std::function saveFileCallback = CHOOSE_FILE_NOOP); bool resetSysExMapping(); + bool setCurrentFile(juce::File file); bool saveCurrentFile(std::function saveFileCallback = CHOOSE_FILE_NOOP); - bool openRecentFile(int recentFileIndex); bool saveColourPalette(LumatoneEditorColourPalette& palette, juce::File pathToPalette=juce::File()); - void reloadColourPalettes(); bool deleteSubBoardData(); bool copySubBoardData(); diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 09381d4f..dd953d4c 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -371,7 +371,7 @@ void MainContentComponent::buttonClicked(Button* btn) if (colourEdit) { // May be better asynchronous on a timer - // TerpstraSysExApplication::getApp().reloadColourPalettes(); + // TerpstraSysExApplication::getApp().loadColourPalettesFromFile(); auto palettes = getColourPalettes(); ColourPaletteWindow* paletteWindow = new ColourPaletteWindow(palettes);