diff --git a/src/shared/Core/SkywardHubCore.cpp b/src/shared/Core/SkywardHubCore.cpp index bccda02102b40d1a81699b4a435d1e5b4748c10b..daa743efe2b4525183d051aa111b970546ec077b 100644 --- a/src/shared/Core/SkywardHubCore.cpp +++ b/src/shared/Core/SkywardHubCore.cpp @@ -37,6 +37,21 @@ SkywardHubCore& SkywardHubCore::getInstance() void SkywardHubCore::init() { + + QSettings userSettings("Skyward ER", "SkywardHub"); + + userSettings.beginGroup("Customization"); + QString themePath = + userSettings + .value("Theme-Path", SkywardHubStrings::defaultThemeFilePath) + .toString(); + + activeTheme = userSettings.value("Theme-Name", "Default").toString(); + + userSettings.endGroup(); + + loadStyleSheet(themePath); + XmlObject settings; settings.loadFromFile(SkywardHubStrings::defaultSettingsFilePath); @@ -60,11 +75,6 @@ void SkywardHubCore::init() SkywardHubStrings::defaultConfigurationIconPath, ""); } -QList<QAction*> SkywardHubCore::getHubMenuActions() -{ - return hubMenuActionsList; -} - SkywardHubCore::SkywardHubCore() { checkDefaultFolders(); @@ -94,6 +104,8 @@ void SkywardHubCore::buildHubMenuActions() hubMenuActionsList.append(newWindow); connect(newWindow, &QAction::triggered, this, &SkywardHubCore::addNewWindow); + + buildThemesMenuSelector(); } void SkywardHubCore::loadConfigurationFromXmlObject(XmlObject configuration) @@ -114,11 +126,18 @@ void SkywardHubCore::addNewWindow() return addWindowFromXml(empty->toXmlObject()); } +void SkywardHubCore::setupMenu(QMenu& menu) +{ + menu.addActions(hubMenuActionsList); + menu.addMenu(themeSelectionMenu); +} + void SkywardHubCore::addWindowFromXml(XmlObject settings) { Window* newWindow = new Window(settings); newWindow->show(); newWindow->activateWindow(); + newWindow->setStyleSheet(activeThemeStyleSheet); windowsList.push_back(newWindow); connect(newWindow, &Window::onWindowClosed, this, @@ -202,3 +221,139 @@ QString SkywardHubCore::saveConfiguration(QString configName, return resultTxt; } + +void SkywardHubCore::buildThemesMenuSelector() +{ + themeSelectionMenu = new QMenu("Themes"); + + for (auto pair : SkywardHubStrings::defaultThemes.toStdMap()) + { + QAction* builtinThemeAction = new QAction(pair.first); + builtinThemeAction->setData(pair.second); + themeSelectionMenu->addAction(builtinThemeAction); + } + + themeSelectionMenu->addSeparator(); + + QList<QAction*> availableThemes = fetchAvailableThemes(); + + themeSelectionMenu->addActions(availableThemes); + + if (availableThemes.size() > 0) + { + themeSelectionMenu->addSeparator(); + } + + QAction* openThemesFolder = new QAction("Open Folder"); + + themeSelectionMenu->addAction(openThemesFolder); + + initializeActiveTheme(); + + connect(themeSelectionMenu, &QMenu::triggered, this, + &SkywardHubCore::onThemeSelected); +} + +QList<QAction*> SkywardHubCore::fetchAvailableThemes() +{ + QDir* themesDirectory = + new QDir(SkywardHubStrings::defaultThemesFolderPath); + + QStringList entries = themesDirectory->entryList(QDir::Files, QDir::Name); + + QList<QAction*> actions; + + for (QString& fileName : entries) + { + QAction* newAction = new QAction(fileName.remove(".qss")); + newAction->setData(SkywardHubStrings::defaultThemesFolderPath + "/" + + fileName + ".qss"); + actions.append(newAction); + } + + return actions; +} + +void SkywardHubCore::onThemeSelected(QAction* action) +{ + + if (action->text() == "Open Folder") + { + QDesktopServices::openUrl( + QUrl::fromLocalFile(SkywardHubStrings::defaultConfigurationFolder)); + return; + } + + QString themePath = action->data().toString(); + loadStyleSheet(themePath); + + unsetOldActiveTheme(); + setActiveTheme(action); +} + +void SkywardHubCore::loadStyleSheet(QString path) +{ + QFile styleSheetFile(path); + styleSheetFile.open(QFile::ReadOnly); + activeThemeStyleSheet = styleSheetFile.readAll(); + + for (Window* window : windowsList) + { + window->setStyleSheet(activeThemeStyleSheet); + } + + qApp->setStyleSheet(activeThemeStyleSheet); + + styleSheetFile.close(); +} + +void SkywardHubCore::setActiveTheme(QAction* action) +{ + + action->setEnabled(false); + + QSettings settings("Skyward ER", "SkywardHub"); + settings.beginGroup("Customization"); + settings.setValue("Theme-Name", action->text()); + settings.setValue("Theme-Path", action->data().toString()); + settings.endGroup(); + + activeTheme = action->text(); +} + +void SkywardHubCore::unsetOldActiveTheme() +{ + QAction* lastActiveTheme = getActiveThemeAction(); + if (lastActiveTheme == nullptr) + return; + + lastActiveTheme->setEnabled(true); +} + +void SkywardHubCore::initializeActiveTheme() +{ + QAction* currentActiveTheme = getActiveThemeAction(); + if (currentActiveTheme == nullptr) + return; + + currentActiveTheme->setEnabled(false); +} + +QAction* SkywardHubCore::getActiveThemeAction() +{ + if (activeTheme == "") + return nullptr; + + const QList<QAction*> menuActions = themeSelectionMenu->actions(); + + auto foundAction = std::find_if(menuActions.begin(), menuActions.end(), + [this](QAction* act) + { return act->text() == activeTheme; }); + + if (foundAction != menuActions.end()) + { + return *foundAction; + } + + return nullptr; +} diff --git a/src/shared/Core/SkywardHubCore.h b/src/shared/Core/SkywardHubCore.h index d59100e0941711a702d70d4d286b312fe1aeca4c..0715a1eb37c510e42133a63f050fa6a3829274a7 100644 --- a/src/shared/Core/SkywardHubCore.h +++ b/src/shared/Core/SkywardHubCore.h @@ -36,12 +36,28 @@ public: void init(); - QList<QAction *> getHubMenuActions(); + /** + * This method setups the core menu to the application + * It adds themes selection function to the menu with other + * core functionalities + * + * @param menu is the menu to which the actions/submenus will + * be added to + */ + void setupMenu(QMenu &menu); public slots: void addNewWindow(); void addWindowFromXml(XmlObject settings); + /** + * This method is called when a theme from the Themes menu is selected + * + * @param action The action performed by the user on the QMenu. In this + * scenario the action corresponds to the selected theme + */ + void onThemeSelected(QAction *action); + private: SkywardHubCore(); @@ -53,8 +69,35 @@ private: QString saveConfiguration(QString configName, QString configIconPath, QString description); + void buildThemesMenuSelector(); + + /** + * This method fetches all available themes in the default themes folder + */ + QList<QAction *> fetchAvailableThemes(); + + /** + * This method loads the stylesheet located at the given path + * @param path The path where the stylesheet is located + */ + void loadStyleSheet(QString path); + + /** + * This method unsets the previous active theme + */ + void unsetOldActiveTheme(); + + void initializeActiveTheme(); + + QAction *getActiveThemeAction(); + + void setActiveTheme(QAction *action); + QList<Window *> windowsList; QList<QAction *> hubMenuActionsList; + QMenu *themeSelectionMenu; + QString activeTheme; + QString activeThemeStyleSheet; public: SkywardHubCore(const SkywardHubCore &) = delete; diff --git a/src/shared/Modules/Module.cpp b/src/shared/Modules/Module.cpp index 1e759785f0b3d78af65164d5f5f62d8994b18c2c..d4a3dd4567e0621c49f9a9829044bb358267ccc6 100644 --- a/src/shared/Modules/Module.cpp +++ b/src/shared/Modules/Module.cpp @@ -54,8 +54,8 @@ Module::Module(ModuleId id) : id(id) // Load hub actions menu.addSeparator(); - menu.addActions( - SkywardHubCore::getInstance().getHubMenuActions()); + + SkywardHubCore::getInstance().setupMenu(menu); menu.exec(mapToGlobal(pos)); }); diff --git a/src/shared/Modules/SkywardHubStrings.h b/src/shared/Modules/SkywardHubStrings.h index ea9e16f7e912f830d7718d670f1b78b8ed7f4c76..3fe3e14c9ae661b3dea8b87ec0c3b055a4f149c6 100644 --- a/src/shared/Modules/SkywardHubStrings.h +++ b/src/shared/Modules/SkywardHubStrings.h @@ -38,8 +38,6 @@ static const QString defaultPrefabsFolder = static const QString defaultConfigurationFileName = "default.xml"; static const QString defaultConfigurationIconPath = defaultConfigurationFolder + "/" + "defaultConfigIcon.svg"; -static const QString defaultThemesFolderPath = - defaultConfigurationFolder + "/" + "Themes"; // Xml Tags Name static const QString skywardHubInitFileTag = "LoadOnLaunch"; @@ -84,4 +82,7 @@ static const QString mavlink_component_id_name = "component_id"; static const QString defaultThemesFolderPath = defaultConfigurationFolder + "/" + "Themes"; static const QString defaultThemeFilePath = ":/assets/styles/global.qss"; +static const QMap<QString, QString> defaultThemes{ + {"Default", ":/assets/styles/global.qss"}, + {"White Mode", ":/assets/styles/white-mode.qss"}}; }; // namespace SkywardHubStrings