| @@ -55,7 +55,8 @@ public: | |||||
| static Font getDefaultCodeFont(); | static Font getDefaultCodeFont(); | ||||
| static void showGlobalPreferences (ScopedPointer<Component>& ownerPointer); | |||||
| static void showGlobalPreferences (ScopedPointer<Component>& ownerPointer, | |||||
| bool showCodeEditorTab = false); | |||||
| static const char* getSchemeFileSuffix() { return ".scheme"; } | static const char* getSchemeFileSuffix() { return ".scheme"; } | ||||
| static const char* getSchemeFileWildCard() { return "*.scheme"; } | static const char* getSchemeFileWildCard() { return "*.scheme"; } | ||||
| @@ -118,6 +118,8 @@ void ProjucerApplication::initialise (const String& commandLine) | |||||
| settings->appearance.refreshPresetSchemeList(); | settings->appearance.refreshPresetSchemeList(); | ||||
| setColourScheme (settings->getGlobalProperties().getIntValue ("COLOUR SCHEME"), false); | setColourScheme (settings->getGlobalProperties().getIntValue ("COLOUR SCHEME"), false); | ||||
| setEditorColourScheme (settings->getGlobalProperties().getIntValue ("EDITOR COLOUR SCHEME"), false); | |||||
| updateEditorColourSchemeIfNeeded(); | |||||
| // do further initialisation in a moment when the message loop has started | // do further initialisation in a moment when the message loop has started | ||||
| triggerAsyncUpdate(); | triggerAsyncUpdate(); | ||||
| @@ -327,12 +329,13 @@ enum | |||||
| { | { | ||||
| recentProjectsBaseID = 100, | recentProjectsBaseID = 100, | ||||
| activeDocumentsBaseID = 300, | activeDocumentsBaseID = 300, | ||||
| colourSchemeBaseID = 1000 | |||||
| colourSchemeBaseID = 1000, | |||||
| codeEditorColourSchemeBaseID = 2000, | |||||
| }; | }; | ||||
| MenuBarModel* ProjucerApplication::getMenuModel() | MenuBarModel* ProjucerApplication::getMenuModel() | ||||
| { | { | ||||
| return menuModel.get(); | |||||
| return menuModel.get(); | |||||
| } | } | ||||
| StringArray ProjucerApplication::getMenuNames() | StringArray ProjucerApplication::getMenuNames() | ||||
| @@ -441,11 +444,37 @@ void ProjucerApplication::createBuildMenu (PopupMenu& menu) | |||||
| void ProjucerApplication::createColourSchemeItems (PopupMenu& menu) | void ProjucerApplication::createColourSchemeItems (PopupMenu& menu) | ||||
| { | { | ||||
| PopupMenu colourSchemes; | PopupMenu colourSchemes; | ||||
| colourSchemes.addItem (colourSchemeBaseID + 0, "Dark"); | |||||
| colourSchemes.addItem (colourSchemeBaseID + 1, "Grey"); | |||||
| colourSchemes.addItem (colourSchemeBaseID + 2, "Light"); | |||||
| colourSchemes.addItem (colourSchemeBaseID + 0, "Dark", true, selectedColourSchemeIndex == 0); | |||||
| colourSchemes.addItem (colourSchemeBaseID + 1, "Grey", true, selectedColourSchemeIndex == 1); | |||||
| colourSchemes.addItem (colourSchemeBaseID + 2, "Light", true, selectedColourSchemeIndex == 2); | |||||
| menu.addSubMenu ("Colour Scheme", colourSchemes); | menu.addSubMenu ("Colour Scheme", colourSchemes); | ||||
| //========================================================================== | |||||
| PopupMenu editorColourSchemes; | |||||
| auto& appearanceSettings = getAppSettings().appearance; | |||||
| appearanceSettings.refreshPresetSchemeList(); | |||||
| auto schemes = appearanceSettings.getPresetSchemes(); | |||||
| auto i = 0; | |||||
| for (auto s : schemes) | |||||
| { | |||||
| editorColourSchemes.addItem (codeEditorColourSchemeBaseID + i, s, | |||||
| globalPreferencesWindow == nullptr, | |||||
| selectedEditorColourSchemeIndex == i); | |||||
| ++i; | |||||
| } | |||||
| numEditorColourSchemes = i; | |||||
| editorColourSchemes.addSeparator(); | |||||
| editorColourSchemes.addItem (codeEditorColourSchemeBaseID + numEditorColourSchemes, | |||||
| "Create...", globalPreferencesWindow == nullptr); | |||||
| menu.addSubMenu ("Editor Colour Scheme", editorColourSchemes); | |||||
| } | } | ||||
| void ProjucerApplication::createWindowMenu (PopupMenu& menu) | void ProjucerApplication::createWindowMenu (PopupMenu& menu) | ||||
| @@ -487,21 +516,30 @@ void ProjucerApplication::createExtraAppleMenuItems (PopupMenu& menu) | |||||
| void ProjucerApplication::handleMainMenuCommand (int menuItemID) | void ProjucerApplication::handleMainMenuCommand (int menuItemID) | ||||
| { | { | ||||
| if (menuItemID >= recentProjectsBaseID && menuItemID < recentProjectsBaseID + 100) | |||||
| if (menuItemID >= recentProjectsBaseID && menuItemID < (recentProjectsBaseID + 100)) | |||||
| { | { | ||||
| // open a file from the "recent files" menu | // open a file from the "recent files" menu | ||||
| openFile (settings->recentFiles.getFile (menuItemID - recentProjectsBaseID)); | openFile (settings->recentFiles.getFile (menuItemID - recentProjectsBaseID)); | ||||
| } | } | ||||
| else if (menuItemID >= activeDocumentsBaseID && menuItemID < activeDocumentsBaseID + 200) | |||||
| else if (menuItemID >= activeDocumentsBaseID && menuItemID < (activeDocumentsBaseID + 200)) | |||||
| { | { | ||||
| if (OpenDocumentManager::Document* doc = openDocumentManager.getOpenDocument (menuItemID - activeDocumentsBaseID)) | if (OpenDocumentManager::Document* doc = openDocumentManager.getOpenDocument (menuItemID - activeDocumentsBaseID)) | ||||
| mainWindowList.openDocument (doc, true); | mainWindowList.openDocument (doc, true); | ||||
| else | else | ||||
| jassertfalse; | jassertfalse; | ||||
| } | } | ||||
| else if (menuItemID >= colourSchemeBaseID && menuItemID < colourSchemeBaseID + 3) | |||||
| else if (menuItemID >= colourSchemeBaseID && menuItemID < (colourSchemeBaseID + 3)) | |||||
| { | { | ||||
| setColourScheme (menuItemID - colourSchemeBaseID, true); | setColourScheme (menuItemID - colourSchemeBaseID, true); | ||||
| updateEditorColourSchemeIfNeeded(); | |||||
| } | |||||
| else if (menuItemID >= codeEditorColourSchemeBaseID && menuItemID < (codeEditorColourSchemeBaseID + numEditorColourSchemes)) | |||||
| { | |||||
| setEditorColourScheme (menuItemID - codeEditorColourSchemeBaseID, true); | |||||
| } | |||||
| else if (menuItemID == (codeEditorColourSchemeBaseID + numEditorColourSchemes)) | |||||
| { | |||||
| AppearanceSettings::showGlobalPreferences (globalPreferencesWindow, true); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -779,24 +817,25 @@ void ProjucerApplication::initCommandManager() | |||||
| registerGUIEditorCommands(); | registerGUIEditorCommands(); | ||||
| } | } | ||||
| void ProjucerApplication::setColourScheme (int index, bool saveSetting) | |||||
| void ProjucerApplication::selectEditorColourSchemeWithName (const String& schemeName) | |||||
| { | { | ||||
| auto& appearanceSettings = getAppSettings().appearance; | auto& appearanceSettings = getAppSettings().appearance; | ||||
| auto schemes = appearanceSettings.getPresetSchemes(); | |||||
| if (index == 0) | |||||
| { | |||||
| lookAndFeel.setColourScheme (LookAndFeel_V4::getDarkColourScheme()); | |||||
| appearanceSettings.selectPresetScheme (0); | |||||
| } | |||||
| else if (index == 1) | |||||
| { | |||||
| lookAndFeel.setColourScheme (LookAndFeel_V4::getGreyColourScheme()); | |||||
| appearanceSettings.selectPresetScheme (0); | |||||
| } | |||||
| else if (index == 2) | |||||
| auto schemeIndex = schemes.indexOf (schemeName); | |||||
| if (schemeIndex >= 0) | |||||
| setEditorColourScheme (schemeIndex, true); | |||||
| } | |||||
| void ProjucerApplication::setColourScheme (int index, bool saveSetting) | |||||
| { | |||||
| switch (index) | |||||
| { | { | ||||
| lookAndFeel.setColourScheme (LookAndFeel_V4::getLightColourScheme()); | |||||
| appearanceSettings.selectPresetScheme (1); | |||||
| case 0: lookAndFeel.setColourScheme (LookAndFeel_V4::getDarkColourScheme()); break; | |||||
| case 1: lookAndFeel.setColourScheme (LookAndFeel_V4::getGreyColourScheme()); break; | |||||
| case 2: lookAndFeel.setColourScheme (LookAndFeel_V4::getLightColourScheme()); break; | |||||
| default: break; | |||||
| } | } | ||||
| lookAndFeel.setupColours(); | lookAndFeel.setupColours(); | ||||
| @@ -817,4 +856,54 @@ void ProjucerApplication::setColourScheme (int index, bool saveSetting) | |||||
| auto& properties = settings->getGlobalProperties(); | auto& properties = settings->getGlobalProperties(); | ||||
| properties.setValue ("COLOUR SCHEME", index); | properties.setValue ("COLOUR SCHEME", index); | ||||
| } | } | ||||
| selectedColourSchemeIndex = index; | |||||
| getCommandManager().commandStatusChanged(); | |||||
| } | |||||
| void ProjucerApplication::setEditorColourScheme (int index, bool saveSetting) | |||||
| { | |||||
| auto& appearanceSettings = getAppSettings().appearance; | |||||
| auto schemes = appearanceSettings.getPresetSchemes(); | |||||
| index = jmin (index, schemes.size() - 1); | |||||
| appearanceSettings.selectPresetScheme (index); | |||||
| if (saveSetting) | |||||
| { | |||||
| auto& properties = settings->getGlobalProperties(); | |||||
| properties.setValue ("EDITOR COLOUR SCHEME", index); | |||||
| } | |||||
| selectedEditorColourSchemeIndex = index; | |||||
| getCommandManager().commandStatusChanged(); | |||||
| } | |||||
| bool ProjucerApplication::isEditorColourSchemeADefaultScheme (const StringArray& schemes, int editorColourSchemeIndex) | |||||
| { | |||||
| auto& schemeName = schemes[editorColourSchemeIndex]; | |||||
| return (schemeName == "Default (Dark)" || schemeName == "Default (Light)"); | |||||
| } | |||||
| int ProjucerApplication::getEditorColourSchemeForGUIColourScheme (const StringArray& schemes, int guiColourSchemeIndex) | |||||
| { | |||||
| auto defaultDarkEditorIndex = schemes.indexOf ("Default (Dark)"); | |||||
| auto defaultLightEditorIndex = schemes.indexOf ("Default (Light)"); | |||||
| // Can't find default code editor colour schemes! | |||||
| jassert (defaultDarkEditorIndex != -1 && defaultLightEditorIndex != -1); | |||||
| return (guiColourSchemeIndex == 2 ? defaultLightEditorIndex : defaultDarkEditorIndex); | |||||
| } | |||||
| void ProjucerApplication::updateEditorColourSchemeIfNeeded() | |||||
| { | |||||
| auto& appearanceSettings = getAppSettings().appearance; | |||||
| auto schemes = appearanceSettings.getPresetSchemes(); | |||||
| if (isEditorColourSchemeADefaultScheme (schemes, selectedEditorColourSchemeIndex)) | |||||
| setEditorColourScheme (getEditorColourSchemeForGUIColourScheme (schemes, selectedColourSchemeIndex), true); | |||||
| } | } | ||||
| @@ -111,6 +111,11 @@ public: | |||||
| bool isPaidOrGPL() const { return licenseController == nullptr || licenseController->getState().isPaidOrGPL(); } | bool isPaidOrGPL() const { return licenseController == nullptr || licenseController->getState().isPaidOrGPL(); } | ||||
| //============================================================================== | |||||
| void selectEditorColourSchemeWithName (const String& schemeName); | |||||
| static bool isEditorColourSchemeADefaultScheme (const StringArray& schemes, int editorColourSchemeIndex); | |||||
| static int getEditorColourSchemeForGUIColourScheme (const StringArray& schemes, int guiColourSchemeIndex); | |||||
| //============================================================================== | //============================================================================== | ||||
| ProjucerLookAndFeel lookAndFeel; | ProjucerLookAndFeel lookAndFeel; | ||||
| @@ -149,5 +154,14 @@ private: | |||||
| void handleAsyncUpdate() override; | void handleAsyncUpdate() override; | ||||
| void initCommandManager(); | void initCommandManager(); | ||||
| //============================================================================== | |||||
| void setColourScheme (int index, bool saveSetting); | void setColourScheme (int index, bool saveSetting); | ||||
| void setEditorColourScheme (int index, bool saveSetting); | |||||
| void updateEditorColourSchemeIfNeeded(); | |||||
| int selectedColourSchemeIndex; | |||||
| int selectedEditorColourSchemeIndex; | |||||
| int numEditorColourSchemes; | |||||
| }; | }; | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include "jucer_GlobalPreferences.h" | #include "jucer_GlobalPreferences.h" | ||||
| #include "../Utility/jucer_FloatingToolWindow.h" | #include "../Utility/jucer_FloatingToolWindow.h" | ||||
| #include "../Utility/jucer_ColourPropertyComponent.h" | #include "../Utility/jucer_ColourPropertyComponent.h" | ||||
| #include "jucer_Application.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| PathSettingsTab::PathSettingsTab (DependencyPathOS os) | PathSettingsTab::PathSettingsTab (DependencyPathOS os) | ||||
| @@ -186,6 +187,16 @@ struct AppearanceEditor | |||||
| loadButton.addListener (this); | loadButton.addListener (this); | ||||
| saveButton.addListener (this); | saveButton.addListener (this); | ||||
| lookAndFeelChanged(); | |||||
| saveSchemeState(); | |||||
| } | |||||
| ~EditorPanel() | |||||
| { | |||||
| if (hasSchemeBeenModifiedSinceSave()) | |||||
| saveScheme (true); | |||||
| } | } | ||||
| void rebuildProperties() | void rebuildProperties() | ||||
| @@ -212,23 +223,26 @@ struct AppearanceEditor | |||||
| { | { | ||||
| auto r = getLocalBounds(); | auto r = getLocalBounds(); | ||||
| panel.setBounds (r.removeFromTop (getHeight() - 28).reduced (10, 2)); | panel.setBounds (r.removeFromTop (getHeight() - 28).reduced (10, 2)); | ||||
| loadButton.setBounds (r.removeFromLeft (getWidth() / 2).reduced (10, 4)); | |||||
| saveButton.setBounds (r.reduced (10, 3)); | |||||
| loadButton.setBounds (r.removeFromLeft (getWidth() / 2).reduced (10, 1)); | |||||
| saveButton.setBounds (r.reduced (10, 1)); | |||||
| } | } | ||||
| private: | private: | ||||
| PropertyPanel panel; | PropertyPanel panel; | ||||
| TextButton loadButton, saveButton; | TextButton loadButton, saveButton; | ||||
| Font codeFont; | |||||
| Array<var> colourValues; | |||||
| void buttonClicked (Button* b) override | void buttonClicked (Button* b) override | ||||
| { | { | ||||
| if (b == &loadButton) | if (b == &loadButton) | ||||
| loadScheme(); | loadScheme(); | ||||
| else | else | ||||
| saveScheme(); | |||||
| saveScheme (false); | |||||
| } | } | ||||
| void saveScheme() | |||||
| void saveScheme (bool isExit) | |||||
| { | { | ||||
| FileChooser fc ("Select a file in which to save this colour-scheme...", | FileChooser fc ("Select a file in which to save this colour-scheme...", | ||||
| getAppSettings().appearance.getSchemesFolder() | getAppSettings().appearance.getSchemesFolder() | ||||
| @@ -240,6 +254,13 @@ struct AppearanceEditor | |||||
| File file (fc.getResult().withFileExtension (AppearanceSettings::getSchemeFileSuffix())); | File file (fc.getResult().withFileExtension (AppearanceSettings::getSchemeFileSuffix())); | ||||
| getAppSettings().appearance.writeToFile (file); | getAppSettings().appearance.writeToFile (file); | ||||
| getAppSettings().appearance.refreshPresetSchemeList(); | getAppSettings().appearance.refreshPresetSchemeList(); | ||||
| saveSchemeState(); | |||||
| ProjucerApplication::getApp().selectEditorColourSchemeWithName (file.getFileNameWithoutExtension()); | |||||
| } | |||||
| else if (isExit) | |||||
| { | |||||
| restorePreviousScheme(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -250,8 +271,13 @@ struct AppearanceEditor | |||||
| AppearanceSettings::getSchemeFileWildCard()); | AppearanceSettings::getSchemeFileWildCard()); | ||||
| if (fc.browseForFileToOpen()) | if (fc.browseForFileToOpen()) | ||||
| { | |||||
| if (getAppSettings().appearance.readFromFile (fc.getResult())) | if (getAppSettings().appearance.readFromFile (fc.getResult())) | ||||
| { | |||||
| rebuildProperties(); | rebuildProperties(); | ||||
| saveSchemeState(); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| void lookAndFeelChanged() override | void lookAndFeelChanged() override | ||||
| @@ -260,6 +286,45 @@ struct AppearanceEditor | |||||
| findColour (secondaryButtonBackgroundColourId)); | findColour (secondaryButtonBackgroundColourId)); | ||||
| } | } | ||||
| void saveSchemeState() | |||||
| { | |||||
| auto& appearance = getAppSettings().appearance; | |||||
| const auto colourNames = appearance.getColourNames(); | |||||
| codeFont = appearance.getCodeFont(); | |||||
| colourValues.clear(); | |||||
| for (int i = 0; i < colourNames.size(); ++i) | |||||
| colourValues.add (appearance.getColourValue (colourNames[i]).getValue()); | |||||
| } | |||||
| bool hasSchemeBeenModifiedSinceSave() | |||||
| { | |||||
| auto& appearance = getAppSettings().appearance; | |||||
| const auto colourNames = appearance.getColourNames(); | |||||
| if (codeFont != appearance.getCodeFont()) | |||||
| return true; | |||||
| for (int i = 0; i < colourNames.size(); ++i) | |||||
| if (colourValues[i] != appearance.getColourValue (colourNames[i]).getValue()) | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| void restorePreviousScheme() | |||||
| { | |||||
| auto& appearance = getAppSettings().appearance; | |||||
| const auto colourNames = appearance.getColourNames(); | |||||
| appearance.getCodeFontValue().setValue (codeFont.toString()); | |||||
| for (int i = 0; i < colourNames.size(); ++i) | |||||
| appearance.getColourValue (colourNames[i]).setValue (colourValues[i]); | |||||
| } | |||||
| JUCE_DECLARE_NON_COPYABLE (EditorPanel) | JUCE_DECLARE_NON_COPYABLE (EditorPanel) | ||||
| }; | }; | ||||
| @@ -325,16 +390,23 @@ struct AppearanceEditor | |||||
| }; | }; | ||||
| }; | }; | ||||
| void AppearanceSettings::showGlobalPreferences (ScopedPointer<Component>& ownerPointer) | |||||
| void AppearanceSettings::showGlobalPreferences (ScopedPointer<Component>& ownerPointer, bool showCodeEditorTab) | |||||
| { | { | ||||
| if (ownerPointer != nullptr) | if (ownerPointer != nullptr) | ||||
| ownerPointer->toFront (true); | ownerPointer->toFront (true); | ||||
| else | else | ||||
| { | |||||
| auto* prefs = new GlobalPreferencesComponent(); | |||||
| new FloatingToolWindow ("Preferences", | new FloatingToolWindow ("Preferences", | ||||
| "globalPreferencesEditorPos", | "globalPreferencesEditorPos", | ||||
| new GlobalPreferencesComponent(), | |||||
| prefs, | |||||
| ownerPointer, false, | ownerPointer, false, | ||||
| 500, 500, 500, 500, 500, 500); | 500, 500, 500, 500, 500, 500); | ||||
| if (showCodeEditorTab) | |||||
| prefs->setCurrentTabIndex (1); | |||||
| } | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -77,7 +77,7 @@ private: | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| /** This component implements the "Code Editor" tabl in the global preferences window, | |||||
| /** This component implements the "Code Editor" tab in the global preferences window, | |||||
| which sets font sizes and colours for the Projucer's code editor. | which sets font sizes and colours for the Projucer's code editor. | ||||
| The content is either an EditorPanel (the actual settings tab) or a FontScanPanel | The content is either an EditorPanel (the actual settings tab) or a FontScanPanel | ||||
| (shown if the tab is scanning for available fonts before showing the EditorPanel). | (shown if the tab is scanning for available fonts before showing the EditorPanel). | ||||
| @@ -83,20 +83,11 @@ PropertiesFile& StoredSettings::getProjectProperties (const String& projectUID) | |||||
| void StoredSettings::updateGlobalPreferences() | void StoredSettings::updateGlobalPreferences() | ||||
| { | { | ||||
| // update global settings editable from the global preferences window | |||||
| updateAppearanceSettings(); | |||||
| // update 'invisible' global settings | // update 'invisible' global settings | ||||
| updateRecentFiles(); | updateRecentFiles(); | ||||
| updateKeyMappings(); | updateKeyMappings(); | ||||
| } | } | ||||
| void StoredSettings::updateAppearanceSettings() | |||||
| { | |||||
| const ScopedPointer<XmlElement> xml (appearance.settings.createXml()); | |||||
| getGlobalProperties().setValue ("editorColours", xml); | |||||
| } | |||||
| void StoredSettings::updateRecentFiles() | void StoredSettings::updateRecentFiles() | ||||
| { | { | ||||
| getGlobalProperties().setValue ("recentFiles", recentFiles.toString()); | getGlobalProperties().setValue ("recentFiles", recentFiles.toString()); | ||||
| @@ -138,11 +129,6 @@ void StoredSettings::reload() | |||||
| recentFiles.restoreFromString (getGlobalProperties().getValue ("recentFiles")); | recentFiles.restoreFromString (getGlobalProperties().getValue ("recentFiles")); | ||||
| recentFiles.removeNonExistentFiles(); | recentFiles.removeNonExistentFiles(); | ||||
| ScopedPointer<XmlElement> xml = XmlDocument::parse (BinaryData::colourscheme_dark_xml); | |||||
| appearance.readFromXML (*xml); | |||||
| appearance.updateColourScheme(); | |||||
| loadSwatchColours(); | loadSwatchColours(); | ||||
| } | } | ||||
| @@ -82,7 +82,6 @@ private: | |||||
| } | } | ||||
| void updateGlobalPreferences(); | void updateGlobalPreferences(); | ||||
| void updateAppearanceSettings(); | |||||
| void updateRecentFiles(); | void updateRecentFiles(); | ||||
| void updateKeyMappings(); | void updateKeyMappings(); | ||||