From 787e8740e9b5a7ccfb294613e69c20a7b6a80f72 Mon Sep 17 00:00:00 2001 From: Dax Date: Sun, 3 Feb 2019 14:23:17 +0100 Subject: [PATCH] Improved Theming support --- dialogs/aboutdialog.cpp | 6 +- dialogs/settingsdialog.cpp | 26 ++++++--- dialogs/settingsdialog.h | 4 ++ dialogs/settingsdialog.ui | 8 ++- main.cpp | 6 +- redasmsettings.cpp | 5 +- redasmsettings.h | 9 ++- themeprovider.cpp | 84 +++++++++++++++++++--------- themeprovider.h | 12 +++- themes.qrc | 4 +- themes/{disassembler => }/dark.json | 14 +++++ themes/{disassembler => }/light.json | 0 12 files changed, 121 insertions(+), 57 deletions(-) rename themes/{disassembler => }/dark.json (73%) rename themes/{disassembler => }/light.json (100%) diff --git a/dialogs/aboutdialog.cpp b/dialogs/aboutdialog.cpp index 19636cad..b23a58f5 100644 --- a/dialogs/aboutdialog.cpp +++ b/dialogs/aboutdialog.cpp @@ -1,6 +1,6 @@ #include "aboutdialog.h" #include "ui_aboutdialog.h" -#include "../redasmsettings.h" +#include "../themeprovider.h" #include AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) @@ -13,9 +13,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia this->initItems(); this->initDepends(); - REDasmSettings settings; - - if(settings.isDarkTheme()) + if(ThemeProvider::isDarkTheme()) ui->lblLogo->setPixmap(QPixmap(QString::fromUtf8(":/res/logo_big_dark.png"))); else ui->lblLogo->setPixmap(QPixmap(QString::fromUtf8(":/res/logo_big.png"))); diff --git a/dialogs/settingsdialog.cpp b/dialogs/settingsdialog.cpp index c7b174eb..d1e3d8d8 100644 --- a/dialogs/settingsdialog.cpp +++ b/dialogs/settingsdialog.cpp @@ -1,25 +1,35 @@ #include "settingsdialog.h" #include "ui_settingsdialog.h" +#include "../themeprovider.h" #include "../redasmsettings.h" -#include SettingsDialog::SettingsDialog(QWidget *parent): QDialog(parent), ui(new Ui::SettingsDialog) { ui->setupUi(this); - - ui->cbTheme->addItem("Light", REDasmSettings::Theme::Light); - ui->cbTheme->addItem("Dark", REDasmSettings::Theme::Dark); - - REDasmSettings settings; - ui->cbTheme->setCurrentIndex(settings.currentTheme()); + ui->cbTheme->addItems(ThemeProvider::themes()); + this->selectCurrentTheme(); connect(this, &QDialog::accepted, this, &SettingsDialog::onAccepted); } SettingsDialog::~SettingsDialog() { delete ui; } +void SettingsDialog::selectCurrentTheme() +{ + REDasmSettings settings; + + for(int i = 0; i < ui->cbTheme->count(); i++) + { + if(QString::compare(ui->cbTheme->itemText(i), settings.currentTheme(), Qt::CaseInsensitive)) + continue; + + ui->cbTheme->setCurrentIndex(i); + break; + } +} + void SettingsDialog::onAccepted() { REDasmSettings settings; - settings.changeTheme(ui->cbTheme->currentData().toInt()); + settings.changeTheme(ui->cbTheme->currentText()); } diff --git a/dialogs/settingsdialog.h b/dialogs/settingsdialog.h index 2eaa3aac..7167bffb 100644 --- a/dialogs/settingsdialog.h +++ b/dialogs/settingsdialog.h @@ -2,6 +2,7 @@ #define SETTINGSDIALOG_H #include +#include namespace Ui { class SettingsDialog; @@ -15,6 +16,9 @@ class SettingsDialog : public QDialog explicit SettingsDialog(QWidget *parent = nullptr); ~SettingsDialog(); + private: + void selectCurrentTheme(); + private slots: void onAccepted(); diff --git a/dialogs/settingsdialog.ui b/dialogs/settingsdialog.ui index 370907d5..83649db2 100644 --- a/dialogs/settingsdialog.ui +++ b/dialogs/settingsdialog.ui @@ -6,10 +6,16 @@ 0 0 - 340 + 370 68 + + + 0 + 0 + + Settings diff --git a/main.cpp b/main.cpp index dc0b5cc2..6aa18e23 100644 --- a/main.cpp +++ b/main.cpp @@ -27,11 +27,7 @@ int main(int argc, char *argv[]) QtWebEngine::initialize(); REDasmSettings::setDefaultFormat(REDasmSettings::IniFormat); - REDasmSettings settings; - - if(settings.isDarkTheme()) - ThemeProvider::selectDarkTheme(); - + ThemeProvider::applyTheme(); MainWindow w; w.show(); diff --git a/redasmsettings.cpp b/redasmsettings.cpp index 25e4947b..1ed8dbf4 100644 --- a/redasmsettings.cpp +++ b/redasmsettings.cpp @@ -17,7 +17,6 @@ void REDasmSettings::updateRecentFiles(const QString &s) } QByteArray REDasmSettings::geometry() const { return this->value("geometry").toByteArray(); } +QString REDasmSettings::currentTheme() const { return this->value("selected_theme", "light").toString(); } void REDasmSettings::changeGeometry(const QByteArray &ba) { this->setValue("geometry", ba); } -bool REDasmSettings::isDarkTheme() const { return this->value("theme") == Theme::Dark; } -int REDasmSettings::currentTheme() const { return this->value("theme", 0).toInt(); } -void REDasmSettings::changeTheme(int theme) { this->setValue("theme", theme); } +void REDasmSettings::changeTheme(const QString& theme) { this->setValue("selected_theme", theme.toLower()); } diff --git a/redasmsettings.h b/redasmsettings.h index e05010c8..91d96c0a 100644 --- a/redasmsettings.h +++ b/redasmsettings.h @@ -14,14 +14,13 @@ class REDasmSettings : public QSettings public: explicit REDasmSettings(QObject *parent = NULL); - bool hasGeometry() const; QStringList recentFiles() const; - void updateRecentFiles(const QString& s = QString()); QByteArray geometry() const; + QString currentTheme() const; + bool hasGeometry() const; + void updateRecentFiles(const QString& s = QString()); void changeGeometry(const QByteArray& ba); - bool isDarkTheme() const; - int currentTheme() const; - void changeTheme(int theme); + void changeTheme(const QString& theme); }; #endif // REDASMSETTINGS_H diff --git a/themeprovider.cpp b/themeprovider.cpp index df686691..a530cbc4 100644 --- a/themeprovider.cpp +++ b/themeprovider.cpp @@ -4,39 +4,53 @@ #include #include #include +#include #include "redasmsettings.h" +#define THEME_UI_SET_COLOR(palette, key) if(m_theme.contains(#key)) palette.setColor(QPalette::key, m_theme[#key].toString()) + QJsonObject ThemeProvider::m_theme; -void ThemeProvider::loadTheme(const QString& theme) +QStringList ThemeProvider::themes() { return ThemeProvider::readThemes(":/themes"); } +QString ThemeProvider::theme(const QString &name) { return QString(":/themes/%1.json").arg(name.toLower()); } + +bool ThemeProvider::isDarkTheme() +{ + if(!m_theme.contains("dark")) + return false; + + return m_theme["dark"] == true; +} + +bool ThemeProvider::loadTheme(const QString& theme) { if(!m_theme.isEmpty()) - return; + return true; - QFile f(QString(":/themes/disassembler/%1.json").arg(theme)); + QFile f(QString(":/themes/%1.json").arg(theme.toLower())); if(!f.open(QFile::ReadOnly)) - { - qWarning("Cannot load '%s' theme", qUtf8Printable(theme)); - return; - } + return false; QJsonDocument doc = QJsonDocument::fromJson(f.readAll()); if(doc.isObject()) m_theme = doc.object(); + else + return false; - f.close(); + return true; } QColor ThemeProvider::themeValue(const QString &name) { - REDasmSettings settings; + if(m_theme.isEmpty()) + { + REDasmSettings settings; - if(settings.isDarkTheme()) - ThemeProvider::loadTheme("dark"); - else - ThemeProvider::loadTheme("light"); + if(!ThemeProvider::loadTheme(settings.currentTheme())) + return QColor(); + } if(m_theme.contains(name)) return QColor(m_theme[name].toString()); @@ -48,28 +62,46 @@ QIcon ThemeProvider::icon(const QString &name) { REDasmSettings settings; - return QIcon(QString(":/res/%1/%2.png").arg(settings.isDarkTheme() ? "dark" : "light") + return QIcon(QString(":/res/%1/%2.png").arg(ThemeProvider::isDarkTheme() ? "dark" : "light") .arg(name)); } QColor ThemeProvider::seekColor() { return ThemeProvider::themeValue("seek"); } QColor ThemeProvider::dottedColor() { return ThemeProvider::themeValue("dotted_fg"); } -void ThemeProvider::selectDarkTheme() +void ThemeProvider::applyTheme() { + REDasmSettings settings; + + if(!ThemeProvider::loadTheme(settings.currentTheme())) + return; + QPalette palette = qApp->palette(); - palette.setColor(QPalette::Shadow, "#2b2b2b"); - palette.setColor(QPalette::Base, "#262626"); - palette.setColor(QPalette::Text, "#ecf0f1"); - palette.setColor(QPalette::Window, "#2b2b2b"); - palette.setColor(QPalette::WindowText, "#ecf0f1"); - palette.setColor(QPalette::Button, "#2b2b2b"); - palette.setColor(QPalette::ButtonText, "#ecf0f1"); - palette.setColor(QPalette::Highlight, "#d95459"); - palette.setColor(QPalette::HighlightedText, "#ecf0f1"); - palette.setColor(QPalette::ToolTipBase, "#2b2b2b"); - palette.setColor(QPalette::ToolTipText, "#ecf0f1"); + THEME_UI_SET_COLOR(palette, Shadow); + THEME_UI_SET_COLOR(palette, Base); + THEME_UI_SET_COLOR(palette, Text); + THEME_UI_SET_COLOR(palette, Window); + THEME_UI_SET_COLOR(palette, WindowText); + THEME_UI_SET_COLOR(palette, Button); + THEME_UI_SET_COLOR(palette, ButtonText); + THEME_UI_SET_COLOR(palette, Highlight); + THEME_UI_SET_COLOR(palette, HighlightedText); + THEME_UI_SET_COLOR(palette, ToolTipBase); + THEME_UI_SET_COLOR(palette, ToolTipText); qApp->setPalette(palette); } + +QStringList ThemeProvider::readThemes(const QString &path) +{ + QStringList themes = QDir(path).entryList({"*.json"}); + + for(QString& theme : themes) + { + theme.remove(".json"); + theme.front() = theme.front().toUpper(); + } + + return themes; +} diff --git a/themeprovider.h b/themeprovider.h index d5b849e0..025e8c67 100644 --- a/themeprovider.h +++ b/themeprovider.h @@ -16,15 +16,21 @@ class ThemeProvider ThemeProvider(const ThemeProvider&) = delete; public: - static void loadTheme(const QString &theme); + static QStringList uiThemes(); + static QStringList themes(); + static QString uiTheme(const QString& name); + static QString theme(const QString& name); static bool contains(const QString& name); + static bool isDarkTheme(); static QColor themeValue(const QString& name); static QIcon icon(const QString& name); static QColor seekColor(); static QColor dottedColor(); + static void applyTheme(); - public: - static void selectDarkTheme(); + private: + static bool loadTheme(const QString &theme); + static QStringList readThemes(const QString& path); private: static QJsonObject m_theme; diff --git a/themes.qrc b/themes.qrc index a5062f83..df58c798 100644 --- a/themes.qrc +++ b/themes.qrc @@ -1,6 +1,6 @@ - themes/disassembler/light.json - themes/disassembler/dark.json + themes/dark.json + themes/light.json diff --git a/themes/disassembler/dark.json b/themes/dark.json similarity index 73% rename from themes/disassembler/dark.json rename to themes/dark.json index 2c1b4b0c..fd324ee9 100644 --- a/themes/disassembler/dark.json +++ b/themes/dark.json @@ -1,4 +1,18 @@ { + "dark": true, + + "Shadow": "#2b2b2b", + "Base": "#262626", + "Text": "#ecf0f1", + "Window": "#2b2b2b", + "WindowText": "#ecf0f1", + "Button": "#2b2b2b", + "ButtonText": "#ecf0f1", + "Highlight": "#d95459", + "HighlightedText": "#ecf0f1", + "ToolTipBase": "#2b2b2b", + "ToolTipText": "#ecf0f1", + "address_fg": "#6a89b4", "segment_fg": "#2ecc71", "function_fg": "#3498db", diff --git a/themes/disassembler/light.json b/themes/light.json similarity index 100% rename from themes/disassembler/light.json rename to themes/light.json