Multiple icon themes!
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
parent
e8c44e700d
commit
97662f5c8e
@ -1163,6 +1163,11 @@ QList<ITheme*> Application::getValidApplicationThemes()
|
|||||||
return m_themeManager->getValidApplicationThemes();
|
return m_themeManager->getValidApplicationThemes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<IconTheme*> Application::getValidIconThemes()
|
||||||
|
{
|
||||||
|
return m_themeManager->getValidIconThemes();
|
||||||
|
}
|
||||||
|
|
||||||
void Application::applyCurrentlySelectedTheme(bool initial)
|
void Application::applyCurrentlySelectedTheme(bool initial)
|
||||||
{
|
{
|
||||||
m_themeManager->applyCurrentlySelectedTheme(initial);
|
m_themeManager->applyCurrentlySelectedTheme(initial);
|
||||||
|
@ -70,6 +70,7 @@ class TranslationsModel;
|
|||||||
class ITheme;
|
class ITheme;
|
||||||
class MCEditTool;
|
class MCEditTool;
|
||||||
class ThemeManager;
|
class ThemeManager;
|
||||||
|
class IconTheme;
|
||||||
|
|
||||||
namespace Meta {
|
namespace Meta {
|
||||||
class Index;
|
class Index;
|
||||||
@ -124,6 +125,8 @@ public:
|
|||||||
|
|
||||||
QList<ITheme*> getValidApplicationThemes();
|
QList<ITheme*> getValidApplicationThemes();
|
||||||
|
|
||||||
|
QList<IconTheme*> getValidIconThemes();
|
||||||
|
|
||||||
void setApplicationTheme(const QString& name);
|
void setApplicationTheme(const QString& name);
|
||||||
|
|
||||||
shared_qobject_ptr<ExternalUpdater> updater() {
|
shared_qobject_ptr<ExternalUpdater> updater() {
|
||||||
|
@ -759,6 +759,8 @@ SET(LAUNCHER_SOURCES
|
|||||||
ui/themes/ITheme.h
|
ui/themes/ITheme.h
|
||||||
ui/themes/SystemTheme.cpp
|
ui/themes/SystemTheme.cpp
|
||||||
ui/themes/SystemTheme.h
|
ui/themes/SystemTheme.h
|
||||||
|
ui/themes/IconTheme.cpp
|
||||||
|
ui/themes/IconTheme.h
|
||||||
ui/themes/ThemeManager.cpp
|
ui/themes/ThemeManager.cpp
|
||||||
ui/themes/ThemeManager.h
|
ui/themes/ThemeManager.h
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[Icon Theme]
|
[Icon Theme]
|
||||||
Name=multimc
|
Name=Legacy
|
||||||
Comment=Default Icons
|
Comment=Default Icons
|
||||||
Inherits=default
|
Inherits=default
|
||||||
Directories=8x8,16x16,22x22,24x24,32x32,32x32/instances,48x48,50x50/instances,64x64,128x128/instances,256x256,scalable,scalable/instances
|
Directories=8x8,16x16,22x22,24x24,32x32,32x32/instances,48x48,50x50/instances,64x64,128x128/instances,256x256,scalable,scalable/instances
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[Icon Theme]
|
[Icon Theme]
|
||||||
Name=pe_blue
|
Name=Simple (Blue)
|
||||||
Comment=Icons by pexner (blue)
|
Comment=Icons by pexner (blue)
|
||||||
Inherits=multimc
|
Inherits=multimc
|
||||||
Directories=scalable
|
Directories=scalable
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[Icon Theme]
|
[Icon Theme]
|
||||||
Name=pe_colored
|
Name=Simple (Colored)
|
||||||
Comment=Icons by pexner (colored)
|
Comment=Icons by pexner (colored)
|
||||||
Inherits=multimc
|
Inherits=multimc
|
||||||
Directories=scalable
|
Directories=scalable
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[Icon Theme]
|
[Icon Theme]
|
||||||
Name=pe_dark
|
Name=Simple (Dark)
|
||||||
Comment=Icons by pexner (dark)
|
Comment=Icons by pexner (dark)
|
||||||
Inherits=multimc
|
Inherits=multimc
|
||||||
Directories=scalable
|
Directories=scalable
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
[Icon Theme]
|
[Icon Theme]
|
||||||
Name=pe_light
|
Name=Simple (Light)
|
||||||
Comment=Icons by pexner (light)
|
Comment=Icons by pexner (light)
|
||||||
Inherits=multimc
|
Inherits=multimc
|
||||||
Directories=scalable
|
Directories=scalable
|
||||||
|
35
launcher/ui/themes/IconTheme.cpp
Normal file
35
launcher/ui/themes/IconTheme.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "IconTheme.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
IconTheme::IconTheme(const QString& id, const QString& path) : m_id(id), m_path(path) {}
|
||||||
|
|
||||||
|
bool IconTheme::load()
|
||||||
|
{
|
||||||
|
QString path = m_path + "/index.theme";
|
||||||
|
|
||||||
|
if (!QFile::exists(path))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QSettings settings(path, QSettings::IniFormat);
|
||||||
|
settings.beginGroup("Icon Theme");
|
||||||
|
m_name = settings.value("Name").toString();
|
||||||
|
settings.endGroup();
|
||||||
|
return !m_name.isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IconTheme::id()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IconTheme::path()
|
||||||
|
{
|
||||||
|
return m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString IconTheme::name()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
18
launcher/ui/themes/IconTheme.h
Normal file
18
launcher/ui/themes/IconTheme.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class IconTheme {
|
||||||
|
public:
|
||||||
|
IconTheme(const QString& id, const QString& path);
|
||||||
|
|
||||||
|
bool load();
|
||||||
|
QString id();
|
||||||
|
QString path();
|
||||||
|
QString name();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_id;
|
||||||
|
QString m_path;
|
||||||
|
QString m_name;
|
||||||
|
};
|
@ -55,50 +55,84 @@ ITheme* ThemeManager::getTheme(QString themeId)
|
|||||||
void ThemeManager::initializeThemes()
|
void ThemeManager::initializeThemes()
|
||||||
{
|
{
|
||||||
// Icon themes
|
// Icon themes
|
||||||
{
|
initializeIcons();
|
||||||
// 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
|
// Initialize widget themes
|
||||||
{
|
initializeWidgets();
|
||||||
themeDebugLog() << "<> Initializing Widget Themes";
|
}
|
||||||
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<SystemTheme>());
|
|
||||||
auto darkThemeId = addTheme(std::make_unique<DarkTheme>());
|
|
||||||
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
|
|
||||||
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<BrightTheme>());
|
|
||||||
|
|
||||||
// TODO: need some way to differentiate same name themes in different subdirectories (maybe smaller grey text next to theme name in
|
void ThemeManager::initializeIcons()
|
||||||
// dropdown?)
|
{
|
||||||
QString themeFolder = QDir("./themes/").absoluteFilePath("");
|
// TODO: icon themes and instance icons do not mesh well together. Rearrange and fix discrepancies!
|
||||||
themeDebugLog() << "Theme Folder Path: " << themeFolder;
|
// set icon theme search path!
|
||||||
|
|
||||||
QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
QString themeFolder = "iconthemes";
|
||||||
while (directoryIterator.hasNext()) {
|
|
||||||
QDir dir(directoryIterator.next());
|
auto searchPaths = QIcon::themeSearchPaths();
|
||||||
QFileInfo themeJson(dir.absoluteFilePath("theme.json"));
|
searchPaths.append(themeFolder);
|
||||||
if (themeJson.exists()) {
|
QIcon::setThemeSearchPaths(searchPaths);
|
||||||
// Load "theme.json" based themes
|
|
||||||
themeDebugLog() << "Loading JSON Theme from:" << themeJson.absoluteFilePath();
|
themeDebugLog() << "<> Initializing Icon Themes";
|
||||||
addTheme(std::make_unique<CustomTheme>(getTheme(darkThemeId), themeJson, true));
|
|
||||||
} else {
|
for (const QString& id : builtinIcons) {
|
||||||
// Load pure QSS Themes
|
IconTheme theme(id, QString(":/icons/%1").arg(id));
|
||||||
QDirIterator stylesheetFileIterator(dir.absoluteFilePath(""), { "*.qss", "*.css" }, QDir::Files);
|
if (!theme.load()) {
|
||||||
while (stylesheetFileIterator.hasNext()) {
|
themeWarningLog() << "Couldn't load built-in icon theme" << id;
|
||||||
QFile customThemeFile(stylesheetFileIterator.next());
|
continue;
|
||||||
QFileInfo customThemeFileInfo(customThemeFile);
|
|
||||||
themeDebugLog() << "Loading QSS Theme from:" << customThemeFileInfo.absoluteFilePath();
|
|
||||||
addTheme(std::make_unique<CustomTheme>(getTheme(darkThemeId), customThemeFileInfo, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
themeDebugLog() << "<> Widget themes initialized.";
|
m_icons.append(theme);
|
||||||
|
themeDebugLog() << "Loaded Built-In Icon Theme" << id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDirIterator directoryIterator(themeFolder, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||||
|
while (directoryIterator.hasNext()) {
|
||||||
|
QDir dir(directoryIterator.next());
|
||||||
|
IconTheme theme(dir.dirName(), dir.path());
|
||||||
|
if (!theme.load())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_icons.append(theme);
|
||||||
|
themeDebugLog() << "Loaded Custom Icon Theme from" << dir.path();
|
||||||
|
}
|
||||||
|
|
||||||
|
themeDebugLog() << "<> Icon themes initialized.";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeManager::initializeWidgets()
|
||||||
|
{
|
||||||
|
themeDebugLog() << "<> Initializing Widget Themes";
|
||||||
|
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<SystemTheme>());
|
||||||
|
auto darkThemeId = addTheme(std::make_unique<DarkTheme>());
|
||||||
|
themeDebugLog() << "Loading Built-in Theme:" << darkThemeId;
|
||||||
|
themeDebugLog() << "Loading Built-in Theme:" << addTheme(std::make_unique<BrightTheme>());
|
||||||
|
|
||||||
|
// 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()) {
|
||||||
|
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();
|
||||||
|
addTheme(std::make_unique<CustomTheme>(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();
|
||||||
|
addTheme(std::make_unique<CustomTheme>(getTheme(darkThemeId), customThemeFileInfo, false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
themeDebugLog() << "<> Widget themes initialized.";
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ITheme*> ThemeManager::getValidApplicationThemes()
|
QList<ITheme*> ThemeManager::getValidApplicationThemes()
|
||||||
@ -111,6 +145,15 @@ QList<ITheme*> ThemeManager::getValidApplicationThemes()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<IconTheme*> ThemeManager::getValidIconThemes()
|
||||||
|
{
|
||||||
|
QList<IconTheme*> ret;
|
||||||
|
ret.reserve(m_icons.size());
|
||||||
|
for (IconTheme& theme : m_icons)
|
||||||
|
ret.append(&theme);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void ThemeManager::setIconTheme(const QString& name)
|
void ThemeManager::setIconTheme(const QString& name)
|
||||||
{
|
{
|
||||||
QIcon::setThemeName(name);
|
QIcon::setThemeName(name);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include "IconTheme.h"
|
||||||
#include "ui/MainWindow.h"
|
#include "ui/MainWindow.h"
|
||||||
#include "ui/themes/ITheme.h"
|
#include "ui/themes/ITheme.h"
|
||||||
|
|
||||||
@ -36,6 +37,7 @@ class ThemeManager {
|
|||||||
ThemeManager(MainWindow* mainWindow);
|
ThemeManager(MainWindow* mainWindow);
|
||||||
|
|
||||||
QList<ITheme*> getValidApplicationThemes();
|
QList<ITheme*> getValidApplicationThemes();
|
||||||
|
QList<IconTheme*> getValidIconThemes();
|
||||||
void setIconTheme(const QString& name);
|
void setIconTheme(const QString& name);
|
||||||
void applyCurrentlySelectedTheme(bool initial = false);
|
void applyCurrentlySelectedTheme(bool initial = false);
|
||||||
void setApplicationTheme(const QString& name, bool initial = false);
|
void setApplicationTheme(const QString& name, bool initial = false);
|
||||||
@ -49,9 +51,15 @@ class ThemeManager {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<QString, std::unique_ptr<ITheme>> m_themes;
|
std::map<QString, std::unique_ptr<ITheme>> m_themes;
|
||||||
|
QList<IconTheme> m_icons;
|
||||||
MainWindow* m_mainWindow;
|
MainWindow* m_mainWindow;
|
||||||
|
|
||||||
void initializeThemes();
|
void initializeThemes();
|
||||||
QString addTheme(std::unique_ptr<ITheme> theme);
|
QString addTheme(std::unique_ptr<ITheme> theme);
|
||||||
ITheme* getTheme(QString themeId);
|
ITheme* getTheme(QString themeId);
|
||||||
|
void initializeIcons();
|
||||||
|
void initializeWidgets();
|
||||||
|
|
||||||
|
const QStringList builtinIcons{ "pe_colored", "pe_light", "pe_dark", "pe_blue", "breeze_light", "breeze_dark",
|
||||||
|
"OSX", "iOS", "flat", "flat_white", "multimc" };
|
||||||
};
|
};
|
||||||
|
@ -73,10 +73,9 @@ void ThemeCustomizationWidget::showFeatures(ThemeFields features) {
|
|||||||
void ThemeCustomizationWidget::applyIconTheme(int index) {
|
void ThemeCustomizationWidget::applyIconTheme(int index) {
|
||||||
auto settings = APPLICATION->settings();
|
auto settings = APPLICATION->settings();
|
||||||
auto originalIconTheme = settings->get("IconTheme").toString();
|
auto originalIconTheme = settings->get("IconTheme").toString();
|
||||||
auto& newIconTheme = m_iconThemeOptions[index].first;
|
auto newIconTheme = ui->iconsComboBox->currentData().toString();
|
||||||
settings->set("IconTheme", newIconTheme);
|
|
||||||
|
|
||||||
if (originalIconTheme != newIconTheme) {
|
if (originalIconTheme != newIconTheme) {
|
||||||
|
settings->set("IconTheme", newIconTheme);
|
||||||
APPLICATION->applyCurrentlySelectedTheme();
|
APPLICATION->applyCurrentlySelectedTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,12 +111,17 @@ void ThemeCustomizationWidget::loadSettings()
|
|||||||
{
|
{
|
||||||
auto settings = APPLICATION->settings();
|
auto settings = APPLICATION->settings();
|
||||||
|
|
||||||
auto iconTheme = settings->get("IconTheme").toString();
|
{
|
||||||
for (auto& iconThemeFromList : m_iconThemeOptions) {
|
auto currentIconTheme = settings->get("IconTheme").toString();
|
||||||
QIcon iconForComboBox = QIcon(QString(":/icons/%1/scalable/settings").arg(iconThemeFromList.first));
|
auto iconThemes = APPLICATION->getValidIconThemes();
|
||||||
ui->iconsComboBox->addItem(iconForComboBox, iconThemeFromList.second);
|
int idx = 0;
|
||||||
if (iconTheme == iconThemeFromList.first) {
|
for (auto iconTheme : iconThemes) {
|
||||||
ui->iconsComboBox->setCurrentIndex(ui->iconsComboBox->count() - 1);
|
QIcon iconForComboBox = QIcon(iconTheme->path() + "/scalable/settings");
|
||||||
|
ui->iconsComboBox->addItem(iconForComboBox, iconTheme->name(), iconTheme->id());
|
||||||
|
if (currentIconTheme == iconTheme->id()) {
|
||||||
|
ui->iconsComboBox->setCurrentIndex(idx);
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class ThemeCustomizationWidget : public QWidget {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ThemeCustomizationWidget(QWidget* parent = nullptr);
|
explicit ThemeCustomizationWidget(QWidget* parent = nullptr);
|
||||||
~ThemeCustomizationWidget();
|
~ThemeCustomizationWidget() override;
|
||||||
|
|
||||||
void showFeatures(ThemeFields features);
|
void showFeatures(ThemeFields features);
|
||||||
|
|
||||||
@ -53,22 +53,7 @@ class ThemeCustomizationWidget : public QWidget {
|
|||||||
private:
|
private:
|
||||||
Ui::ThemeCustomizationWidget* ui;
|
Ui::ThemeCustomizationWidget* ui;
|
||||||
|
|
||||||
//TODO finish implementing
|
QList<std::pair<QString, QString>> m_catOptions{
|
||||||
QList<std::pair<QString, QString>> m_iconThemeOptions{
|
|
||||||
{ "pe_colored", QObject::tr("Simple (Colored Icons)") },
|
|
||||||
{ "pe_light", QObject::tr("Simple (Light Icons)") },
|
|
||||||
{ "pe_dark", QObject::tr("Simple (Dark Icons)") },
|
|
||||||
{ "pe_blue", QObject::tr("Simple (Blue Icons)") },
|
|
||||||
{ "breeze_light", QObject::tr("Breeze Light") },
|
|
||||||
{ "breeze_dark", QObject::tr("Breeze Dark") },
|
|
||||||
{ "OSX", QObject::tr("OSX") },
|
|
||||||
{ "iOS", QObject::tr("iOS") },
|
|
||||||
{ "flat", QObject::tr("Flat") },
|
|
||||||
{ "flat_white", QObject::tr("Flat (White)") },
|
|
||||||
{ "multimc", QObject::tr("Legacy") },
|
|
||||||
{ "custom", QObject::tr("Custom") }
|
|
||||||
};
|
|
||||||
QList<std::pair<QString, QString>> m_catOptions{
|
|
||||||
{ "kitteh", QObject::tr("Background Cat (from MultiMC)") },
|
{ "kitteh", QObject::tr("Background Cat (from MultiMC)") },
|
||||||
{ "rory", QObject::tr("Rory ID 11 (drawn by Ashtaka)") },
|
{ "rory", QObject::tr("Rory ID 11 (drawn by Ashtaka)") },
|
||||||
{ "rory-flat", QObject::tr("Rory ID 11 (flat edition, drawn by Ashtaka)") },
|
{ "rory-flat", QObject::tr("Rory ID 11 (flat edition, drawn by Ashtaka)") },
|
||||||
|
Loading…
Reference in New Issue
Block a user