From fef60a9da0216bdcb266d935bbfea03aba8905b4 Mon Sep 17 00:00:00 2001 From: Tayou Date: Sat, 29 Oct 2022 19:27:20 +0200 Subject: [PATCH 1/5] add support for multiple custom themes also moved theme related code from Application.cpp to new ui/themes/ThemeManager.cpp, this class should cleanly isolate theme related functions and help avoid code duplication in future theme related additions. Themes can now be just qss or css files, they won't have color pallette information with them in that case Signed-off-by: Tayou --- launcher/Application.cpp | 70 ++-------- launcher/Application.h | 9 +- launcher/CMakeLists.txt | 2 + launcher/ui/themes/CustomTheme.cpp | 202 +++++++++++++++++++--------- launcher/ui/themes/CustomTheme.h | 43 +++++- launcher/ui/themes/SystemTheme.cpp | 49 ++++++- launcher/ui/themes/ThemeManager.cpp | 152 +++++++++++++++++++++ launcher/ui/themes/ThemeManager.h | 44 ++++++ 8 files changed, 445 insertions(+), 126 deletions(-) create mode 100644 launcher/ui/themes/ThemeManager.cpp create mode 100644 launcher/ui/themes/ThemeManager.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 2da8ac56..7b33361c 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1,7 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2022 Tayou + * + * PolyMC - Minecraft Launcher * Copyright (C) 2022 Lenny McLennington * * This program is free software: you can redistribute it and/or modify @@ -54,12 +57,6 @@ #include "ui/pages/global/APIPage.h" #include "ui/pages/global/CustomCommandsPage.h" -#include "ui/themes/ITheme.h" -#include "ui/themes/SystemTheme.h" -#include "ui/themes/DarkTheme.h" -#include "ui/themes/BrightTheme.h" -#include "ui/themes/CustomTheme.h" - #ifdef Q_OS_WIN #include "ui/WinDarkmode.h" #include @@ -749,28 +746,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) qDebug() << "<> Instance icons intialized."; } - // Icon themes + // Themes { - // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! - // set icon theme search path! - auto searchPaths = QIcon::themeSearchPaths(); - searchPaths.append("iconthemes"); - QIcon::setThemeSearchPaths(searchPaths); - qDebug() << "<> Icon themes initialized."; - } + m_themeManager = new ThemeManager(m_mainWindow); - // Initialize widget themes - { - auto insertTheme = [this](ITheme * theme) - { - m_themes.insert(std::make_pair(theme->id(), std::unique_ptr(theme))); - }; - auto darkTheme = new DarkTheme(); - insertTheme(new SystemTheme()); - insertTheme(darkTheme); - insertTheme(new BrightTheme()); - insertTheme(new CustomTheme(darkTheme, "custom")); - qDebug() << "<> Widget themes initialized."; + m_themeManager->InitializeThemes(); } // initialize and load all instances @@ -880,6 +860,10 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) performMainStartupAction(); } +ThemeManager* Application::getThemeManager() { + return Application::m_themeManager; +} + bool Application::createSetupWizard() { bool javaRequired = [&]() @@ -1127,43 +1111,17 @@ std::shared_ptr Application::javalist() std::vector Application::getValidApplicationThemes() { - std::vector ret; - auto iter = m_themes.cbegin(); - while (iter != m_themes.cend()) - { - ret.push_back((*iter).second.get()); - iter++; - } - return ret; + return m_themeManager->getValidApplicationThemes(); } void Application::setApplicationTheme(const QString& name, bool initial) { - auto systemPalette = qApp->palette(); - auto themeIter = m_themes.find(name); - if(themeIter != m_themes.end()) - { - auto & theme = (*themeIter).second; - theme->apply(initial); -#ifdef Q_OS_WIN - if (m_mainWindow && IsWindows10OrGreater()) { - if (QString::compare(theme->id(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); - } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); - } - } -#endif - } - else - { - qWarning() << "Tried to set invalid theme:" << name; - } + m_themeManager->setApplicationTheme(name, initial); } void Application::setIconTheme(const QString& name) { - QIcon::setThemeName(name); + m_themeManager->setIconTheme(name); } QIcon Application::getThemedIcon(const QString& name) diff --git a/launcher/Application.h b/launcher/Application.h index 8fa0ab10..33d8db29 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,6 +45,8 @@ #include #include +#include "ui/themes/ThemeManager.h" + #include #include "minecraft/launch/MinecraftServerTarget.h" @@ -198,6 +201,8 @@ public: void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); + ThemeManager* getThemeManager(); + signals: void updateAllowedChanged(bool status); void globalSettingsAboutToOpen(); @@ -255,9 +260,9 @@ private: std::shared_ptr m_javalist; std::shared_ptr m_translations; std::shared_ptr m_globalSettingsProvider; - std::map> m_themes; std::unique_ptr m_mcedit; QSet m_features; + ThemeManager* m_themeManager; QMap> m_profilers; diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 0dae47df..5b0d9282 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -650,6 +650,8 @@ SET(LAUNCHER_SOURCES ui/themes/ITheme.h ui/themes/SystemTheme.cpp ui/themes/SystemTheme.h + ui/themes/ThemeManager.cpp + ui/themes/ThemeManager.h # Processes LaunchController.h diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index 3e3e27de..3c35bf37 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -1,12 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher + * Copyright (C) 2022 Tayou + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Authors: Andrew Okin + * Peterix + * Orochimarufan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "CustomTheme.h" -#include #include #include +#include "ThemeManager.h" const char * themeFile = "theme.json"; -const char * styleFile = "themeStyle.css"; -static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAmount, QColor &fadeColor, QString &name, QString &widgets) +static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAmount, QColor &fadeColor, QString &name, QString &widgets, QString &qssFilePath, bool &dataIncomplete) { QFileInfo pathInfo(path); if(pathInfo.exists() && pathInfo.isFile()) @@ -15,8 +52,11 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm { auto doc = Json::requireDocument(path, "Theme JSON file"); const QJsonObject root = doc.object(); + dataIncomplete = !root.contains("qssFilePath"); name = Json::requireString(root, "name", "Theme name"); widgets = Json::requireString(root, "widgets", "Qt widget theme"); + qssFilePath = Json::ensureString(root, "qssFilePath", "themeStyle.css"); + //auto colorFileList = Json::ensureArray(root, "colorFiles"); auto colorsRoot = Json::requireObject(root, "colors", "colors object"); auto readColor = [&](QString colorName) -> QColor { @@ -26,7 +66,7 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm QColor color(colorValue); if(!color.isValid()) { - qWarning() << "Color value" << colorValue << "for" << colorName << "was not recognized."; + themeWarningLog << "Color value" << colorValue << "for" << colorName << "was not recognized."; return QColor(); } return color; @@ -42,7 +82,7 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm } else { - qDebug() << "Color value for" << colorName << "was not present."; + themeDebugLog << "Color value for" << colorName << "was not present."; } }; @@ -68,23 +108,24 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm } catch (const Exception &e) { - qWarning() << "Couldn't load theme json: " << e.cause(); + themeWarningLog << "Couldn't load theme json: " << e.cause(); return false; } } else { - qDebug() << "No theme json present."; + themeDebugLog << "No theme json present."; return false; } return true; } -static bool writeThemeJson(const QString &path, const QPalette &palette, double fadeAmount, QColor fadeColor, QString name, QString widgets) +static bool writeThemeJson(const QString &path, const QPalette &palette, double fadeAmount, QColor fadeColor, QString name, QString widgets, QString qssFilePath) { QJsonObject rootObj; rootObj.insert("name", name); rootObj.insert("widgets", widgets); + rootObj.insert("qssFilePath", qssFilePath); QJsonObject colorsObj; auto insertColor = [&](QPalette::ColorRole role, QString colorName) @@ -119,75 +160,112 @@ static bool writeThemeJson(const QString &path, const QPalette &palette, double } catch (const Exception &e) { - qWarning() << "Failed to write theme json to" << path; + themeWarningLog << "Failed to write theme json to" << path; return false; } } -CustomTheme::CustomTheme(ITheme* baseTheme, QString folder) +/// @brief +/// @param baseTheme Base Theme +/// @param fileInfo FileInfo object for file to load +/// @param isManifest whether to load a theme manifest or a qss file +CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest) { - m_id = folder; - QString path = FS::PathCombine("themes", m_id); - QString pathResources = FS::PathCombine("themes", m_id, "resources"); + if (isManifest) { + m_id = fileInfo.dir().dirName(); - qDebug() << "Loading theme" << m_id; + QString path = FS::PathCombine("themes", m_id); + QString pathResources = FS::PathCombine("themes", m_id, "resources"); - if(!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources)) - { - qWarning() << "couldn't create folder for theme!"; - m_palette = baseTheme->colorScheme(); - m_styleSheet = baseTheme->appStyleSheet(); - return; - } - - auto themeFilePath = FS::PathCombine(path, themeFile); - - m_palette = baseTheme->colorScheme(); - if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets)) - { - m_name = "Custom"; - m_palette = baseTheme->colorScheme(); - m_fadeColor = baseTheme->fadeColor(); - m_fadeAmount = baseTheme->fadeAmount(); - m_widgets = baseTheme->qtTheme(); - - QFileInfo info(themeFilePath); - if(!info.exists()) + if(!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources)) { - writeThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, "Custom", m_widgets); - } - } - else - { - m_palette = fadeInactive(m_palette, m_fadeAmount, m_fadeColor); - } - - auto cssFilePath = FS::PathCombine(path, styleFile); - QFileInfo info (cssFilePath); - if(info.isFile()) - { - try - { - // TODO: validate css? - m_styleSheet = QString::fromUtf8(FS::read(cssFilePath)); - } - catch (const Exception &e) - { - qWarning() << "Couldn't load css:" << e.cause() << "from" << cssFilePath; + themeWarningLog << "X couldn't create folder for theme!"; + m_palette = baseTheme->colorScheme(); m_styleSheet = baseTheme->appStyleSheet(); + return; } - } - else - { - qDebug() << "No theme css present."; - m_styleSheet = baseTheme->appStyleSheet(); + + auto themeFilePath = FS::PathCombine(path, themeFile); + + bool jsonDataIncomplete = false; + + m_palette = baseTheme->colorScheme(); + if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath, jsonDataIncomplete)) + { + themeDebugLog << "Did not read theme json file correctly, writing new one to: " << themeFilePath; + m_name = "Custom"; + m_palette = baseTheme->colorScheme(); + m_fadeColor = baseTheme->fadeColor(); + m_fadeAmount = baseTheme->fadeAmount(); + m_widgets = baseTheme->qtTheme(); + m_qssFilePath = "themeStyle.css"; + + QFileInfo info(themeFilePath); + } + else + { + m_palette = fadeInactive(m_palette, m_fadeAmount, m_fadeColor); + } + + if(jsonDataIncomplete) + { + writeThemeJson(fileInfo.absoluteFilePath(), m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath); + } + + auto cssFilePath = FS::PathCombine(path, m_qssFilePath); + QFileInfo info (cssFilePath); + if(info.isFile()) + { + try + { + // TODO: validate css? + m_styleSheet = QString::fromUtf8(FS::read(cssFilePath)); + } + catch (const Exception &e) + { + themeWarningLog << "X Couldn't load css:" << e.cause() << "from" << cssFilePath; + m_styleSheet = baseTheme->appStyleSheet(); + } + } + else + { + themeDebugLog << "X No theme css present."; + m_styleSheet = baseTheme->appStyleSheet(); + try + { + FS::write(cssFilePath, m_styleSheet.toUtf8()); + } + catch (const Exception &e) + { + themeWarningLog << "X Couldn't write css:" << e.cause() << "to" << cssFilePath; + } + } + } else { + m_id = fileInfo.fileName(); + m_name = fileInfo.baseName(); + QString path = fileInfo.filePath(); + //themeDebugLog << "Theme ID: " << m_id; + //themeDebugLog << "Theme Name: " << m_name; + //themeDebugLog << "Theme Path: " << path; + + if(!FS::ensureFilePathExists(path)) + { + themeWarningLog << m_name << " Theme file path doesn't exist!"; + m_palette = baseTheme->colorScheme(); + m_styleSheet = baseTheme->appStyleSheet(); + return; + } + + m_palette = baseTheme->colorScheme(); try { - FS::write(cssFilePath, m_styleSheet.toUtf8()); + // TODO: validate qss? + m_styleSheet = QString::fromUtf8(FS::read(path)); } catch (const Exception &e) { - qWarning() << "Couldn't write css:" << e.cause() << "to" << cssFilePath; + themeWarningLog << "Couldn't load qss:" << e.cause() << "from" << path; + m_styleSheet = baseTheme->appStyleSheet(); } } } diff --git a/launcher/ui/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h index d216895d..f4a7b737 100644 --- a/launcher/ui/themes/CustomTheme.h +++ b/launcher/ui/themes/CustomTheme.h @@ -1,11 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher + * Copyright (C) 2022 Tayou + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Authors: Andrew Okin + * Peterix + * Orochimarufan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #pragma once #include "ITheme.h" +#include +#include class CustomTheme: public ITheme { public: - CustomTheme(ITheme * baseTheme, QString folder); + CustomTheme(ITheme * baseTheme, QFileInfo& file, bool isManifest); virtual ~CustomTheme() {} QString id() override; @@ -27,5 +67,6 @@ private: /* data */ QString m_name; QString m_id; QString m_widgets; + QString m_qssFilePath; }; diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index 49b1afaa..b8eb2a3c 100644 --- a/launcher/ui/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp @@ -1,30 +1,69 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher + * Copyright (C) 2022 Tayou + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2013-2021 MultiMC Contributors + * + * Authors: Andrew Okin + * Peterix + * Orochimarufan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "SystemTheme.h" #include #include #include #include +#include "ThemeManager.h" SystemTheme::SystemTheme() { - qDebug() << "Determining System Theme..."; + themeDebugLog << "Determining System Theme..."; const auto & style = QApplication::style(); systemPalette = style->standardPalette(); QString lowerThemeName = style->objectName(); - qDebug() << "System theme seems to be:" << lowerThemeName; + themeDebugLog << "System theme seems to be:" << lowerThemeName; QStringList styles = QStyleFactory::keys(); for(auto &st: styles) { - qDebug() << "Considering theme from theme factory:" << st.toLower(); + themeDebugLog << "Considering theme from theme factory:" << st.toLower(); if(st.toLower() == lowerThemeName) { systemTheme = st; - qDebug() << "System theme has been determined to be:" << systemTheme; + themeDebugLog << "System theme has been determined to be:" << systemTheme; return; } } // fall back to fusion if we can't find the current theme. systemTheme = "Fusion"; - qDebug() << "System theme not found, defaulted to Fusion"; + themeDebugLog << "System theme not found, defaulted to Fusion"; } void SystemTheme::apply(bool initial) diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp new file mode 100644 index 00000000..6e1566d2 --- /dev/null +++ b/launcher/ui/themes/ThemeManager.cpp @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher + * Copyright (C) 2022 Tayou + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "ThemeManager.h" + +#include "ui/themes/SystemTheme.h" +#include "ui/themes/DarkTheme.h" +#include "ui/themes/BrightTheme.h" +#include "ui/themes/CustomTheme.h" +#include +#include +#include +#include + +#include "Application.h" + +#ifdef Q_OS_WIN +#include +#include "ui/WinDarkmode.h" +#endif + +ThemeManager::ThemeManager(MainWindow* mainWindow) { + m_mainWindow = mainWindow; +} + +/// @brief Adds the Theme to the list of themes +/// @param theme The Theme to add +/// @return Theme ID +QString ThemeManager::AddTheme(ITheme * theme) { + m_themes.insert(std::make_pair(theme->id(), std::unique_ptr(theme))); + return theme->id(); +} + +/// @brief Gets the Theme from the List via ID +/// @param themeId Theme ID of theme to fetch +/// @return Theme at themeId +ITheme* ThemeManager::GetTheme(QString themeId) { + return m_themes[themeId].get(); +} + +void ThemeManager::InitializeThemes() { + + + // Icon themes + { + // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! + // set icon theme search path! + auto searchPaths = QIcon::themeSearchPaths(); + searchPaths.append("iconthemes"); + QIcon::setThemeSearchPaths(searchPaths); + themeDebugLog << "<> Icon themes initialized."; + } + + // Initialize widget themes + { + themeDebugLog << "<> Initializing Widget Themes"; + themeDebugLog "✓ Loading Built-in Theme:" << AddTheme(new SystemTheme()); + auto darkThemeId = AddTheme(new DarkTheme()); + themeDebugLog "✓ Loading Built-in Theme:" << darkThemeId; + themeDebugLog "✓ Loading Built-in Theme:" << AddTheme(new BrightTheme()); + + // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in dropdown? Dunno how to do that though) + QString themeFolder = (new QDir("./themes/"))->absoluteFilePath(""); + themeDebugLog << "Theme Folder Path: " << themeFolder; + + QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (directoryIterator.hasNext()) { + QDir dir(directoryIterator.next()); + QFileInfo themeJson(dir.absoluteFilePath("theme.json")); + if (themeJson.exists()) { + // Load "theme.json" based themes + themeDebugLog "✓ Loading JSON Theme from:" << themeJson.absoluteFilePath(); + CustomTheme* theme = new CustomTheme(GetTheme(darkThemeId), themeJson, true); + AddTheme(theme); + } else { + // Load pure QSS Themes + QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), {"*.qss", "*.css"}, QDir::Files); + while (stylesheetFileIterator.hasNext()) { + QFile customThemeFile(stylesheetFileIterator.next()); + QFileInfo customThemeFileInfo(customThemeFile); + themeDebugLog "✓ Loading QSS Theme from:" << customThemeFileInfo.absoluteFilePath(); + CustomTheme* theme = new CustomTheme(GetTheme(darkThemeId), customThemeFileInfo, false); + AddTheme(theme); + } + } + } + + themeDebugLog << "<> Widget themes initialized."; + } +} + +std::vector ThemeManager::getValidApplicationThemes() +{ + std::vector ret; + auto iter = m_themes.cbegin(); + while (iter != m_themes.cend()) + { + ret.push_back((*iter).second.get()); + iter++; + } + return ret; +} + +void ThemeManager::setIconTheme(const QString& name) +{ + QIcon::setThemeName(name); +} + +void ThemeManager::applyCurrentlySelectedTheme() { + setIconTheme(APPLICATION->settings()->get("IconTheme").toString()); + themeDebugLog() << "<> Icon theme set."; + setApplicationTheme(APPLICATION->settings()->get("ApplicationTheme").toString(), true); + themeDebugLog() << "<> Application theme set."; +} + +void ThemeManager::setApplicationTheme(const QString& name, bool initial) +{ + auto systemPalette = qApp->palette(); + auto themeIter = m_themes.find(name); + if(themeIter != m_themes.end()) + { + auto & theme = (*themeIter).second; + theme->apply(initial); +#ifdef Q_OS_WIN + if (m_mainWindow && IsWindows10OrGreater()) { + if (QString::compare(theme->id(), "dark") == 0) { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + } else { + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + } + } +#endif + } + else + { + qWarning() << "Tried to set invalid theme:" << name; + } +} diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h new file mode 100644 index 00000000..fa6ea236 --- /dev/null +++ b/launcher/ui/themes/ThemeManager.h @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher + * Copyright (C) 2022 Tayou + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "ui/themes/ITheme.h" +#include "ui/MainWindow.h" + +#define themeDebugLog qDebug() << "[Themes]" +#define themeWarningLog qWarning() << "[Themes]" + +class ThemeManager { +public: + ThemeManager(MainWindow* mainWindow); + void InitializeThemes(); + + std::vector getValidApplicationThemes(); + void setIconTheme(const QString& name); + void applyCurrentlySelectedTheme(); + void setApplicationTheme(const QString& name, bool initial); + +private: + std::map> m_themes; + MainWindow* m_mainWindow; + + QString AddTheme(ITheme * theme); + ITheme* GetTheme(QString themeId); +}; + From a3f5ea359827abb7949070cdcd8d56be50ab3360 Mon Sep 17 00:00:00 2001 From: Tayou Date: Tue, 1 Nov 2022 15:41:08 +0100 Subject: [PATCH 2/5] added suggested changes Signed-off-by: Tayou --- launcher/Application.cpp | 18 +++------ launcher/Application.h | 9 ++--- launcher/ui/themes/CustomTheme.cpp | 24 ++++++------ launcher/ui/themes/CustomTheme.h | 3 +- launcher/ui/themes/SystemTheme.cpp | 10 ++--- launcher/ui/themes/ThemeManager.cpp | 60 +++++++++++++++-------------- launcher/ui/themes/ThemeManager.h | 15 ++++++-- 7 files changed, 68 insertions(+), 71 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 7b33361c..fa202312 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -2,10 +2,8 @@ /* * Prism Launcher * Copyright (C) 2022 Sefa Eyeoglu - * Copyright (C) 2022 Tayou - * - * PolyMC - Minecraft Launcher * Copyright (C) 2022 Lenny McLennington + * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,6 +69,8 @@ #include "ui/pagedialog/PageDialog.h" +#include "ui/themes/ThemeManager.h" + #include "ApplicationMessage.h" #include @@ -747,11 +747,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) } // Themes - { - m_themeManager = new ThemeManager(m_mainWindow); - - m_themeManager->InitializeThemes(); - } + m_themeManager = std::make_unique(m_mainWindow); // initialize and load all instances { @@ -860,10 +856,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) performMainStartupAction(); } -ThemeManager* Application::getThemeManager() { - return Application::m_themeManager; -} - bool Application::createSetupWizard() { bool javaRequired = [&]() @@ -1109,7 +1101,7 @@ std::shared_ptr Application::javalist() return m_javalist; } -std::vector Application::getValidApplicationThemes() +QList Application::getValidApplicationThemes() { return m_themeManager->getValidApplicationThemes(); } diff --git a/launcher/Application.h b/launcher/Application.h index 33d8db29..ec434c6c 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -45,8 +45,6 @@ #include #include -#include "ui/themes/ThemeManager.h" - #include #include "minecraft/launch/MinecraftServerTarget.h" @@ -71,6 +69,7 @@ class BaseDetachedToolFactory; class TranslationsModel; class ITheme; class MCEditTool; +class ThemeManager; namespace Meta { class Index; @@ -121,7 +120,7 @@ public: void setIconTheme(const QString& name); - std::vector getValidApplicationThemes(); + QList getValidApplicationThemes(); void setApplicationTheme(const QString& name, bool initial); @@ -201,8 +200,6 @@ public: void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); - ThemeManager* getThemeManager(); - signals: void updateAllowedChanged(bool status); void globalSettingsAboutToOpen(); @@ -262,7 +259,7 @@ private: std::shared_ptr m_globalSettingsProvider; std::unique_ptr m_mcedit; QSet m_features; - ThemeManager* m_themeManager; + std::unique_ptr m_themeManager; QMap> m_profilers; diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index 3c35bf37..c346d42f 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -66,7 +66,7 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm QColor color(colorValue); if(!color.isValid()) { - themeWarningLog << "Color value" << colorValue << "for" << colorName << "was not recognized."; + themeWarningLog() << "Color value" << colorValue << "for" << colorName << "was not recognized."; return QColor(); } return color; @@ -82,7 +82,7 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm } else { - themeDebugLog << "Color value for" << colorName << "was not present."; + themeDebugLog() << "Color value for" << colorName << "was not present."; } }; @@ -108,13 +108,13 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm } catch (const Exception &e) { - themeWarningLog << "Couldn't load theme json: " << e.cause(); + themeWarningLog() << "Couldn't load theme json: " << e.cause(); return false; } } else { - themeDebugLog << "No theme json present."; + themeDebugLog() << "No theme json present."; return false; } return true; @@ -160,7 +160,7 @@ static bool writeThemeJson(const QString &path, const QPalette &palette, double } catch (const Exception &e) { - themeWarningLog << "Failed to write theme json to" << path; + themeWarningLog() << "Failed to write theme json to" << path; return false; } } @@ -179,7 +179,7 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest if(!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources)) { - themeWarningLog << "X couldn't create folder for theme!"; + themeWarningLog() << "couldn't create folder for theme!"; m_palette = baseTheme->colorScheme(); m_styleSheet = baseTheme->appStyleSheet(); return; @@ -192,7 +192,7 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest m_palette = baseTheme->colorScheme(); if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath, jsonDataIncomplete)) { - themeDebugLog << "Did not read theme json file correctly, writing new one to: " << themeFilePath; + themeDebugLog() << "Did not read theme json file correctly, writing new one to: " << themeFilePath; m_name = "Custom"; m_palette = baseTheme->colorScheme(); m_fadeColor = baseTheme->fadeColor(); @@ -223,13 +223,13 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest } catch (const Exception &e) { - themeWarningLog << "X Couldn't load css:" << e.cause() << "from" << cssFilePath; + themeWarningLog() << "Couldn't load css:" << e.cause() << "from" << cssFilePath; m_styleSheet = baseTheme->appStyleSheet(); } } else { - themeDebugLog << "X No theme css present."; + themeDebugLog() << "No theme css present."; m_styleSheet = baseTheme->appStyleSheet(); try { @@ -237,7 +237,7 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest } catch (const Exception &e) { - themeWarningLog << "X Couldn't write css:" << e.cause() << "to" << cssFilePath; + themeWarningLog() << "Couldn't write css:" << e.cause() << "to" << cssFilePath; } } } else { @@ -250,7 +250,7 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest if(!FS::ensureFilePathExists(path)) { - themeWarningLog << m_name << " Theme file path doesn't exist!"; + themeWarningLog() << m_name << " Theme file path doesn't exist!"; m_palette = baseTheme->colorScheme(); m_styleSheet = baseTheme->appStyleSheet(); return; @@ -264,7 +264,7 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest } catch (const Exception &e) { - themeWarningLog << "Couldn't load qss:" << e.cause() << "from" << path; + themeWarningLog() << "Couldn't load qss:" << e.cause() << "from" << path; m_styleSheet = baseTheme->appStyleSheet(); } } diff --git a/launcher/ui/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h index f4a7b737..6d1f46b4 100644 --- a/launcher/ui/themes/CustomTheme.h +++ b/launcher/ui/themes/CustomTheme.h @@ -39,8 +39,7 @@ #pragma once #include "ITheme.h" -#include -#include +#include class CustomTheme: public ITheme { diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index b8eb2a3c..ec24c6d7 100644 --- a/launcher/ui/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp @@ -45,25 +45,25 @@ SystemTheme::SystemTheme() { - themeDebugLog << "Determining System Theme..."; + themeDebugLog() << "Determining System Theme..."; const auto & style = QApplication::style(); systemPalette = style->standardPalette(); QString lowerThemeName = style->objectName(); - themeDebugLog << "System theme seems to be:" << lowerThemeName; + themeDebugLog() << "System theme seems to be:" << lowerThemeName; QStringList styles = QStyleFactory::keys(); for(auto &st: styles) { - themeDebugLog << "Considering theme from theme factory:" << st.toLower(); + themeDebugLog() << "Considering theme from theme factory:" << st.toLower(); if(st.toLower() == lowerThemeName) { systemTheme = st; - themeDebugLog << "System theme has been determined to be:" << systemTheme; + themeDebugLog() << "System theme has been determined to be:" << systemTheme; return; } } // fall back to fusion if we can't find the current theme. systemTheme = "Fusion"; - themeDebugLog << "System theme not found, defaulted to Fusion"; + themeDebugLog() << "System theme not found, defaulted to Fusion"; } void SystemTheme::apply(bool initial) diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 6e1566d2..3c338fd6 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -29,20 +29,25 @@ #include "Application.h" #ifdef Q_OS_WIN -#include +#include +// this is needed for versionhelpers.h, it is also included in WinDarkmode, but we can't rely on that. +// Ultimately this should be included in versionhelpers, but that is outside of the project. #include "ui/WinDarkmode.h" +#include #endif ThemeManager::ThemeManager(MainWindow* mainWindow) { m_mainWindow = mainWindow; + InitializeThemes(); } /// @brief Adds the Theme to the list of themes /// @param theme The Theme to add /// @return Theme ID -QString ThemeManager::AddTheme(ITheme * theme) { - m_themes.insert(std::make_pair(theme->id(), std::unique_ptr(theme))); - return theme->id(); +QString ThemeManager::AddTheme(std::unique_ptr theme) { + QString id = theme->id(); + m_themes.emplace(id, std::move(theme)); + return id; } /// @brief Gets the Theme from the List via ID @@ -62,20 +67,20 @@ void ThemeManager::InitializeThemes() { auto searchPaths = QIcon::themeSearchPaths(); searchPaths.append("iconthemes"); QIcon::setThemeSearchPaths(searchPaths); - themeDebugLog << "<> Icon themes initialized."; + themeDebugLog() << "<> Icon themes initialized."; } // Initialize widget themes { - themeDebugLog << "<> Initializing Widget Themes"; - themeDebugLog "✓ Loading Built-in Theme:" << AddTheme(new SystemTheme()); - auto darkThemeId = AddTheme(new DarkTheme()); - themeDebugLog "✓ Loading Built-in Theme:" << darkThemeId; - themeDebugLog "✓ Loading Built-in Theme:" << AddTheme(new BrightTheme()); + themeDebugLog() << "<> Initializing Widget Themes"; + themeDebugLog() << "Loading Built-in Theme:" << AddTheme(std::make_unique()); + auto darkThemeId = AddTheme(std::make_unique()); + themeDebugLog() << "Loading Built-in Theme:" << darkThemeId; + themeDebugLog() << "Loading Built-in Theme:" << AddTheme(std::make_unique()); - // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in dropdown? Dunno how to do that though) - QString themeFolder = (new QDir("./themes/"))->absoluteFilePath(""); - themeDebugLog << "Theme Folder Path: " << themeFolder; + // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in dropdown?) + QString themeFolder = QDir("./themes/").absoluteFilePath(""); + themeDebugLog() << "Theme Folder Path: " << themeFolder; QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); while (directoryIterator.hasNext()) { @@ -83,34 +88,30 @@ void ThemeManager::InitializeThemes() { QFileInfo themeJson(dir.absoluteFilePath("theme.json")); if (themeJson.exists()) { // Load "theme.json" based themes - themeDebugLog "✓ Loading JSON Theme from:" << themeJson.absoluteFilePath(); - CustomTheme* theme = new CustomTheme(GetTheme(darkThemeId), themeJson, true); - AddTheme(theme); + themeDebugLog() << "Loading JSON Theme from:" << themeJson.absoluteFilePath(); + AddTheme(std::make_unique(GetTheme(darkThemeId), themeJson, true)); } else { // Load pure QSS Themes QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), {"*.qss", "*.css"}, QDir::Files); while (stylesheetFileIterator.hasNext()) { QFile customThemeFile(stylesheetFileIterator.next()); QFileInfo customThemeFileInfo(customThemeFile); - themeDebugLog "✓ Loading QSS Theme from:" << customThemeFileInfo.absoluteFilePath(); - CustomTheme* theme = new CustomTheme(GetTheme(darkThemeId), customThemeFileInfo, false); - AddTheme(theme); + themeDebugLog() << "Loading QSS Theme from:" << customThemeFileInfo.absoluteFilePath(); + AddTheme(std::make_unique(GetTheme(darkThemeId), customThemeFileInfo, false)); } } } - themeDebugLog << "<> Widget themes initialized."; + themeDebugLog() << "<> Widget themes initialized."; } } -std::vector ThemeManager::getValidApplicationThemes() +QList ThemeManager::getValidApplicationThemes() { - std::vector ret; - auto iter = m_themes.cbegin(); - while (iter != m_themes.cend()) - { - ret.push_back((*iter).second.get()); - iter++; + QList ret; + ret.reserve(m_themes.size()); + for (auto&& [id, theme] : m_themes) { + ret.append(theme.get()); } return ret; } @@ -133,7 +134,8 @@ void ThemeManager::setApplicationTheme(const QString& name, bool initial) auto themeIter = m_themes.find(name); if(themeIter != m_themes.end()) { - auto & theme = (*themeIter).second; + auto & theme = themeIter->second; + themeDebugLog() << "applying theme" << theme->name(); theme->apply(initial); #ifdef Q_OS_WIN if (m_mainWindow && IsWindows10OrGreater()) { @@ -147,6 +149,6 @@ void ThemeManager::setApplicationTheme(const QString& name, bool initial) } else { - qWarning() << "Tried to set invalid theme:" << name; + themeWarningLog() << "Tried to set invalid theme:" << name; } } diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h index fa6ea236..871e6fe2 100644 --- a/launcher/ui/themes/ThemeManager.h +++ b/launcher/ui/themes/ThemeManager.h @@ -15,21 +15,28 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#pragma once #include #include "ui/themes/ITheme.h" #include "ui/MainWindow.h" -#define themeDebugLog qDebug() << "[Themes]" -#define themeWarningLog qWarning() << "[Themes]" +inline auto themeDebugLog() { + return qDebug() << "[Theme]"; +} +inline auto themeWarningLog() { + return qWarning() << "[Theme]"; +} class ThemeManager { public: ThemeManager(MainWindow* mainWindow); + + // maybe make private? Or put in ctor? void InitializeThemes(); - std::vector getValidApplicationThemes(); + QList getValidApplicationThemes(); void setIconTheme(const QString& name); void applyCurrentlySelectedTheme(); void setApplicationTheme(const QString& name, bool initial); @@ -38,7 +45,7 @@ private: std::map> m_themes; MainWindow* m_mainWindow; - QString AddTheme(ITheme * theme); + QString AddTheme(std::unique_ptr theme); ITheme* GetTheme(QString themeId); }; From afcdf4b9cf5c65d67657bf6a682eb43d61b21ee6 Mon Sep 17 00:00:00 2001 From: Tayou Date: Mon, 31 Oct 2022 13:00:41 +0100 Subject: [PATCH 3/5] condensed icon theme code Signed-off-by: Tayou --- launcher/ui/pages/global/LauncherPage.cpp | 42 ++--------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 4ae7509c..a1cbbc33 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -384,46 +384,8 @@ void LauncherPage::loadSettings() m_currentUpdateChannel = s->get("UpdateChannel").toString(); //FIXME: make generic auto theme = s->get("IconTheme").toString(); - if (theme == "pe_colored") - { - ui->themeComboBox->setCurrentIndex(0); - } - else if (theme == "pe_light") - { - ui->themeComboBox->setCurrentIndex(1); - } - else if (theme == "pe_dark") - { - ui->themeComboBox->setCurrentIndex(2); - } - else if (theme == "pe_blue") - { - ui->themeComboBox->setCurrentIndex(3); - } - else if (theme == "OSX") - { - ui->themeComboBox->setCurrentIndex(4); - } - else if (theme == "iOS") - { - ui->themeComboBox->setCurrentIndex(5); - } - else if (theme == "flat") - { - ui->themeComboBox->setCurrentIndex(6); - } - else if (theme == "flat_white") - { - ui->themeComboBox->setCurrentIndex(7); - } - else if (theme == "multimc") - { - ui->themeComboBox->setCurrentIndex(8); - } - else if (theme == "custom") - { - ui->themeComboBox->setCurrentIndex(9); - } + QStringList iconThemeOptions{"pe_colored", "pe_light", "pe_dark", "pe_blue", "OSX", "iOS", "flat", "flat_white", "multimc", "custom"}; + ui->themeComboBox->setCurrentIndex(iconThemeOptions.indexOf(theme)); { auto currentTheme = s->get("ApplicationTheme").toString(); From e9bfd43ff73a482433e725aec715012c3c6c2a2c Mon Sep 17 00:00:00 2001 From: Tayou Date: Thu, 3 Nov 2022 04:54:57 +0100 Subject: [PATCH 4/5] added requested changes Signed-off-by: Tayou --- launcher/Application.cpp | 2 +- launcher/Application.h | 2 +- launcher/ui/pages/global/LauncherPage.cpp | 3 ++- launcher/ui/themes/CustomTheme.cpp | 22 +++++++--------------- launcher/ui/themes/CustomTheme.h | 6 +----- launcher/ui/themes/SystemTheme.cpp | 6 +----- launcher/ui/themes/ThemeManager.cpp | 2 +- launcher/ui/themes/ThemeManager.h | 2 +- 8 files changed, 15 insertions(+), 30 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index fa202312..d27176c5 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Lenny McLennington * Copyright (C) 2022 Tayou diff --git a/launcher/Application.h b/launcher/Application.h index ec434c6c..78ab8fbd 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Tayou * diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index a1cbbc33..7c7aaf4e 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (c) 2022 dada513 + * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index c346d42f..a61bdbaf 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify @@ -20,10 +20,6 @@ * * Copyright 2013-2021 MultiMC Contributors * - * Authors: Andrew Okin - * Peterix - * Orochimarufan - * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -56,7 +52,6 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm name = Json::requireString(root, "name", "Theme name"); widgets = Json::requireString(root, "widgets", "Qt widget theme"); qssFilePath = Json::ensureString(root, "qssFilePath", "themeStyle.css"); - //auto colorFileList = Json::ensureArray(root, "colorFiles"); auto colorsRoot = Json::requireObject(root, "colors", "colors object"); auto readColor = [&](QString colorName) -> QColor { @@ -165,7 +160,6 @@ static bool writeThemeJson(const QString &path, const QPalette &palette, double } } -/// @brief /// @param baseTheme Base Theme /// @param fileInfo FileInfo object for file to load /// @param isManifest whether to load a theme manifest or a qss file @@ -199,8 +193,6 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest m_fadeAmount = baseTheme->fadeAmount(); m_widgets = baseTheme->qtTheme(); m_qssFilePath = "themeStyle.css"; - - QFileInfo info(themeFilePath); } else { @@ -212,18 +204,18 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest writeThemeJson(fileInfo.absoluteFilePath(), m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath); } - auto cssFilePath = FS::PathCombine(path, m_qssFilePath); - QFileInfo info (cssFilePath); + auto qssFilePath = FS::PathCombine(path, m_qssFilePath); + QFileInfo info (qssFilePath); if(info.isFile()) { try { // TODO: validate css? - m_styleSheet = QString::fromUtf8(FS::read(cssFilePath)); + m_styleSheet = QString::fromUtf8(FS::read(qssFilePath)); } catch (const Exception &e) { - themeWarningLog() << "Couldn't load css:" << e.cause() << "from" << cssFilePath; + themeWarningLog() << "Couldn't load css:" << e.cause() << "from" << qssFilePath; m_styleSheet = baseTheme->appStyleSheet(); } } @@ -233,11 +225,11 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest m_styleSheet = baseTheme->appStyleSheet(); try { - FS::write(cssFilePath, m_styleSheet.toUtf8()); + FS::write(qssFilePath, m_styleSheet.toUtf8()); } catch (const Exception &e) { - themeWarningLog() << "Couldn't write css:" << e.cause() << "to" << cssFilePath; + themeWarningLog() << "Couldn't write css:" << e.cause() << "to" << qssFilePath; } } } else { diff --git a/launcher/ui/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h index 6d1f46b4..e845d23d 100644 --- a/launcher/ui/themes/CustomTheme.h +++ b/launcher/ui/themes/CustomTheme.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify @@ -20,10 +20,6 @@ * * Copyright 2013-2021 MultiMC Contributors * - * Authors: Andrew Okin - * Peterix - * Orochimarufan - * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/launcher/ui/themes/SystemTheme.cpp b/launcher/ui/themes/SystemTheme.cpp index ec24c6d7..a63d1741 100644 --- a/launcher/ui/themes/SystemTheme.cpp +++ b/launcher/ui/themes/SystemTheme.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify @@ -20,10 +20,6 @@ * * Copyright 2013-2021 MultiMC Contributors * - * Authors: Andrew Okin - * Peterix - * Orochimarufan - * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 3c338fd6..4b7cd46d 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h index 871e6fe2..96088d82 100644 --- a/launcher/ui/themes/ThemeManager.h +++ b/launcher/ui/themes/ThemeManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * Prism Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Tayou * * This program is free software: you can redistribute it and/or modify From c2f37716e59055636bee2d1549a16809c408e45b Mon Sep 17 00:00:00 2001 From: Tayou Date: Thu, 3 Nov 2022 05:05:07 +0100 Subject: [PATCH 5/5] clang_format for PR files I'm getting a rendezvous... I thought I did this already Signed-off-by: Tayou --- launcher/ui/themes/CustomTheme.cpp | 121 +++++++++++----------------- launcher/ui/themes/CustomTheme.h | 12 ++- launcher/ui/themes/ThemeManager.cpp | 49 +++++------ launcher/ui/themes/ThemeManager.h | 17 ++-- 4 files changed, 87 insertions(+), 112 deletions(-) diff --git a/launcher/ui/themes/CustomTheme.cpp b/launcher/ui/themes/CustomTheme.cpp index a61bdbaf..3ad61668 100644 --- a/launcher/ui/themes/CustomTheme.cpp +++ b/launcher/ui/themes/CustomTheme.cpp @@ -33,19 +33,24 @@ * limitations under the License. */ #include "CustomTheme.h" -#include #include +#include #include "ThemeManager.h" -const char * themeFile = "theme.json"; +const char* themeFile = "theme.json"; -static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAmount, QColor &fadeColor, QString &name, QString &widgets, QString &qssFilePath, bool &dataIncomplete) +static bool readThemeJson(const QString& path, + QPalette& palette, + double& fadeAmount, + QColor& fadeColor, + QString& name, + QString& widgets, + QString& qssFilePath, + bool& dataIncomplete) { QFileInfo pathInfo(path); - if(pathInfo.exists() && pathInfo.isFile()) - { - try - { + if (pathInfo.exists() && pathInfo.isFile()) { + try { auto doc = Json::requireDocument(path, "Theme JSON file"); const QJsonObject root = doc.object(); dataIncomplete = !root.contains("qssFilePath"); @@ -53,14 +58,11 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm widgets = Json::requireString(root, "widgets", "Qt widget theme"); qssFilePath = Json::ensureString(root, "qssFilePath", "themeStyle.css"); auto colorsRoot = Json::requireObject(root, "colors", "colors object"); - auto readColor = [&](QString colorName) -> QColor - { + auto readColor = [&](QString colorName) -> QColor { auto colorValue = Json::ensureString(colorsRoot, colorName, QString()); - if(!colorValue.isEmpty()) - { + if (!colorValue.isEmpty()) { QColor color(colorValue); - if(!color.isValid()) - { + if (!color.isValid()) { themeWarningLog() << "Color value" << colorValue << "for" << colorName << "was not recognized."; return QColor(); } @@ -68,15 +70,11 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm } return QColor(); }; - auto readAndSetColor = [&](QPalette::ColorRole role, QString colorName) - { + auto readAndSetColor = [&](QPalette::ColorRole role, QString colorName) { auto color = readColor(colorName); - if(color.isValid()) - { + if (color.isValid()) { palette.setColor(role, color); - } - else - { + } else { themeDebugLog() << "Color value for" << colorName << "was not present."; } }; @@ -96,26 +94,28 @@ static bool readThemeJson(const QString &path, QPalette &palette, double &fadeAm readAndSetColor(QPalette::Highlight, "Highlight"); readAndSetColor(QPalette::HighlightedText, "HighlightedText"); - //fade + // fade fadeColor = readColor("fadeColor"); fadeAmount = Json::ensureDouble(colorsRoot, "fadeAmount", 0.5, "fade amount"); - } - catch (const Exception &e) - { + } catch (const Exception& e) { themeWarningLog() << "Couldn't load theme json: " << e.cause(); return false; } - } - else - { + } else { themeDebugLog() << "No theme json present."; return false; } return true; } -static bool writeThemeJson(const QString &path, const QPalette &palette, double fadeAmount, QColor fadeColor, QString name, QString widgets, QString qssFilePath) +static bool writeThemeJson(const QString& path, + const QPalette& palette, + double fadeAmount, + QColor fadeColor, + QString name, + QString widgets, + QString qssFilePath) { QJsonObject rootObj; rootObj.insert("name", name); @@ -123,10 +123,7 @@ static bool writeThemeJson(const QString &path, const QPalette &palette, double rootObj.insert("qssFilePath", qssFilePath); QJsonObject colorsObj; - auto insertColor = [&](QPalette::ColorRole role, QString colorName) - { - colorsObj.insert(colorName, palette.color(role).name()); - }; + auto insertColor = [&](QPalette::ColorRole role, QString colorName) { colorsObj.insert(colorName, palette.color(role).name()); }; // palette insertColor(QPalette::Window, "Window"); @@ -148,13 +145,10 @@ static bool writeThemeJson(const QString &path, const QPalette &palette, double colorsObj.insert("fadeAmount", fadeAmount); rootObj.insert("colors", colorsObj); - try - { + try { Json::write(rootObj, path); return true; - } - catch (const Exception &e) - { + } catch (const Exception& e) { themeWarningLog() << "Failed to write theme json to" << path; return false; } @@ -171,8 +165,7 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest QString path = FS::PathCombine("themes", m_id); QString pathResources = FS::PathCombine("themes", m_id, "resources"); - if(!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources)) - { + if (!FS::ensureFolderPathExists(path) || !FS::ensureFolderPathExists(pathResources)) { themeWarningLog() << "couldn't create folder for theme!"; m_palette = baseTheme->colorScheme(); m_styleSheet = baseTheme->appStyleSheet(); @@ -184,8 +177,7 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest bool jsonDataIncomplete = false; m_palette = baseTheme->colorScheme(); - if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath, jsonDataIncomplete)) - { + if (!readThemeJson(themeFilePath, m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath, jsonDataIncomplete)) { themeDebugLog() << "Did not read theme json file correctly, writing new one to: " << themeFilePath; m_name = "Custom"; m_palette = baseTheme->colorScheme(); @@ -193,42 +185,30 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest m_fadeAmount = baseTheme->fadeAmount(); m_widgets = baseTheme->qtTheme(); m_qssFilePath = "themeStyle.css"; - } - else - { + } else { m_palette = fadeInactive(m_palette, m_fadeAmount, m_fadeColor); } - if(jsonDataIncomplete) - { + if (jsonDataIncomplete) { writeThemeJson(fileInfo.absoluteFilePath(), m_palette, m_fadeAmount, m_fadeColor, m_name, m_widgets, m_qssFilePath); } auto qssFilePath = FS::PathCombine(path, m_qssFilePath); - QFileInfo info (qssFilePath); - if(info.isFile()) - { - try - { + QFileInfo info(qssFilePath); + if (info.isFile()) { + try { // TODO: validate css? m_styleSheet = QString::fromUtf8(FS::read(qssFilePath)); - } - catch (const Exception &e) - { + } catch (const Exception& e) { themeWarningLog() << "Couldn't load css:" << e.cause() << "from" << qssFilePath; m_styleSheet = baseTheme->appStyleSheet(); } - } - else - { + } else { themeDebugLog() << "No theme css present."; m_styleSheet = baseTheme->appStyleSheet(); - try - { + try { FS::write(qssFilePath, m_styleSheet.toUtf8()); - } - catch (const Exception &e) - { + } catch (const Exception& e) { themeWarningLog() << "Couldn't write css:" << e.cause() << "to" << qssFilePath; } } @@ -236,12 +216,11 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest m_id = fileInfo.fileName(); m_name = fileInfo.baseName(); QString path = fileInfo.filePath(); - //themeDebugLog << "Theme ID: " << m_id; - //themeDebugLog << "Theme Name: " << m_name; - //themeDebugLog << "Theme Path: " << path; + // themeDebugLog << "Theme ID: " << m_id; + // themeDebugLog << "Theme Name: " << m_name; + // themeDebugLog << "Theme Path: " << path; - if(!FS::ensureFilePathExists(path)) - { + if (!FS::ensureFilePathExists(path)) { themeWarningLog() << m_name << " Theme file path doesn't exist!"; m_palette = baseTheme->colorScheme(); m_styleSheet = baseTheme->appStyleSheet(); @@ -249,13 +228,10 @@ CustomTheme::CustomTheme(ITheme* baseTheme, QFileInfo& fileInfo, bool isManifest } m_palette = baseTheme->colorScheme(); - try - { + try { // TODO: validate qss? m_styleSheet = QString::fromUtf8(FS::read(path)); - } - catch (const Exception &e) - { + } catch (const Exception& e) { themeWarningLog() << "Couldn't load qss:" << e.cause() << "from" << path; m_styleSheet = baseTheme->appStyleSheet(); } @@ -267,7 +243,6 @@ QStringList CustomTheme::searchPaths() return { FS::PathCombine("themes", m_id, "resources") }; } - QString CustomTheme::id() { return m_id; diff --git a/launcher/ui/themes/CustomTheme.h b/launcher/ui/themes/CustomTheme.h index e845d23d..f2b1b06e 100644 --- a/launcher/ui/themes/CustomTheme.h +++ b/launcher/ui/themes/CustomTheme.h @@ -34,13 +34,12 @@ */ #pragma once -#include "ITheme.h" #include +#include "ITheme.h" -class CustomTheme: public ITheme -{ -public: - CustomTheme(ITheme * baseTheme, QFileInfo& file, bool isManifest); +class CustomTheme : public ITheme { + public: + CustomTheme(ITheme* baseTheme, QFileInfo& file, bool isManifest); virtual ~CustomTheme() {} QString id() override; @@ -54,7 +53,7 @@ public: QString qtTheme() override; QStringList searchPaths() override; -private: /* data */ + private: /* data */ QPalette m_palette; QColor m_fadeColor; double m_fadeAmount; @@ -64,4 +63,3 @@ private: /* data */ QString m_widgets; QString m_qssFilePath; }; - diff --git a/launcher/ui/themes/ThemeManager.cpp b/launcher/ui/themes/ThemeManager.cpp index 4b7cd46d..01a38a86 100644 --- a/launcher/ui/themes/ThemeManager.cpp +++ b/launcher/ui/themes/ThemeManager.cpp @@ -17,26 +17,27 @@ */ #include "ThemeManager.h" -#include "ui/themes/SystemTheme.h" -#include "ui/themes/DarkTheme.h" -#include "ui/themes/BrightTheme.h" -#include "ui/themes/CustomTheme.h" +#include #include #include #include -#include +#include "ui/themes/BrightTheme.h" +#include "ui/themes/CustomTheme.h" +#include "ui/themes/DarkTheme.h" +#include "ui/themes/SystemTheme.h" #include "Application.h" #ifdef Q_OS_WIN -#include -// this is needed for versionhelpers.h, it is also included in WinDarkmode, but we can't rely on that. +#include +// this is needed for versionhelpers.h, it is also included in WinDarkmode, but we can't rely on that. // Ultimately this should be included in versionhelpers, but that is outside of the project. #include "ui/WinDarkmode.h" #include #endif -ThemeManager::ThemeManager(MainWindow* mainWindow) { +ThemeManager::ThemeManager(MainWindow* mainWindow) +{ m_mainWindow = mainWindow; InitializeThemes(); } @@ -44,7 +45,8 @@ ThemeManager::ThemeManager(MainWindow* mainWindow) { /// @brief Adds the Theme to the list of themes /// @param theme The Theme to add /// @return Theme ID -QString ThemeManager::AddTheme(std::unique_ptr theme) { +QString ThemeManager::AddTheme(std::unique_ptr theme) +{ QString id = theme->id(); m_themes.emplace(id, std::move(theme)); return id; @@ -53,13 +55,13 @@ QString ThemeManager::AddTheme(std::unique_ptr theme) { /// @brief Gets the Theme from the List via ID /// @param themeId Theme ID of theme to fetch /// @return Theme at themeId -ITheme* ThemeManager::GetTheme(QString themeId) { +ITheme* ThemeManager::GetTheme(QString themeId) +{ return m_themes[themeId].get(); } -void ThemeManager::InitializeThemes() { - - +void ThemeManager::InitializeThemes() +{ // Icon themes { // TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies! @@ -78,7 +80,8 @@ void ThemeManager::InitializeThemes() { themeDebugLog() << "Loading Built-in Theme:" << darkThemeId; themeDebugLog() << "Loading Built-in Theme:" << AddTheme(std::make_unique()); - // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in dropdown?) + // TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in + // dropdown?) QString themeFolder = QDir("./themes/").absoluteFilePath(""); themeDebugLog() << "Theme Folder Path: " << themeFolder; @@ -92,7 +95,7 @@ void ThemeManager::InitializeThemes() { AddTheme(std::make_unique(GetTheme(darkThemeId), themeJson, true)); } else { // Load pure QSS Themes - QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), {"*.qss", "*.css"}, QDir::Files); + QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), { "*.qss", "*.css" }, QDir::Files); while (stylesheetFileIterator.hasNext()) { QFile customThemeFile(stylesheetFileIterator.next()); QFileInfo customThemeFileInfo(customThemeFile); @@ -121,7 +124,8 @@ void ThemeManager::setIconTheme(const QString& name) QIcon::setThemeName(name); } -void ThemeManager::applyCurrentlySelectedTheme() { +void ThemeManager::applyCurrentlySelectedTheme() +{ setIconTheme(APPLICATION->settings()->get("IconTheme").toString()); themeDebugLog() << "<> Icon theme set."; setApplicationTheme(APPLICATION->settings()->get("ApplicationTheme").toString(), true); @@ -132,23 +136,20 @@ void ThemeManager::setApplicationTheme(const QString& name, bool initial) { auto systemPalette = qApp->palette(); auto themeIter = m_themes.find(name); - if(themeIter != m_themes.end()) - { - auto & theme = themeIter->second; + if (themeIter != m_themes.end()) { + auto& theme = themeIter->second; themeDebugLog() << "applying theme" << theme->name(); theme->apply(initial); #ifdef Q_OS_WIN if (m_mainWindow && IsWindows10OrGreater()) { if (QString::compare(theme->id(), "dark") == 0) { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true); } else { - WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); + WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false); } } #endif - } - else - { + } else { themeWarningLog() << "Tried to set invalid theme:" << name; } } diff --git a/launcher/ui/themes/ThemeManager.h b/launcher/ui/themes/ThemeManager.h index 96088d82..b85cb742 100644 --- a/launcher/ui/themes/ThemeManager.h +++ b/launcher/ui/themes/ThemeManager.h @@ -19,18 +19,20 @@ #include -#include "ui/themes/ITheme.h" #include "ui/MainWindow.h" +#include "ui/themes/ITheme.h" -inline auto themeDebugLog() { - return qDebug() << "[Theme]"; +inline auto themeDebugLog() +{ + return qDebug() << "[Theme]"; } -inline auto themeWarningLog() { - return qWarning() << "[Theme]"; +inline auto themeWarningLog() +{ + return qWarning() << "[Theme]"; } class ThemeManager { -public: + public: ThemeManager(MainWindow* mainWindow); // maybe make private? Or put in ctor? @@ -41,11 +43,10 @@ public: void applyCurrentlySelectedTheme(); void setApplicationTheme(const QString& name, bool initial); -private: + private: std::map> m_themes; MainWindow* m_mainWindow; QString AddTheme(std::unique_ptr theme); ITheme* GetTheme(QString themeId); }; -