mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
feat: add system theme on Qt 6.5 and up (#5118)
* feat: add system theme on Qt 6.5 * chroe: add changelog entry * refactor: add separate settings * fix: qt 5 * Update changelog entry --------- Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
parent
7d7f1b3bea
commit
c32ee8e5b5
5 changed files with 105 additions and 11 deletions
|
@ -26,6 +26,7 @@
|
||||||
- Minor: Normalized the input padding between light & dark themes. (#5095)
|
- Minor: Normalized the input padding between light & dark themes. (#5095)
|
||||||
- Minor: Add `--activate <channel>` (or `-a`) command line option to activate or add a Twitch channel. (#5111)
|
- Minor: Add `--activate <channel>` (or `-a`) command line option to activate or add a Twitch channel. (#5111)
|
||||||
- Minor: Chatters from recent-messages are now added to autocompletion. (#5116)
|
- Minor: Chatters from recent-messages are now added to autocompletion. (#5116)
|
||||||
|
- Minor: Added a _System_ theme that updates according to the system's color scheme (requires Qt 6.5). (#5118)
|
||||||
- Minor: Added support for the `{input.text}` placeholder in the **Split** -> **Run a command** hotkey. (#5130)
|
- Minor: Added support for the `{input.text}` placeholder in the **Split** -> **Run a command** hotkey. (#5130)
|
||||||
- Bugfix: Fixed an issue where certain emojis did not send to Twitch chat correctly. (#4840)
|
- Bugfix: Fixed an issue where certain emojis did not send to Twitch chat correctly. (#4840)
|
||||||
- Bugfix: Fixed capitalized channel names in log inclusion list not being logged. (#4848)
|
- Bugfix: Fixed capitalized channel names in log inclusion list not being logged. (#4848)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "common/QLogging.hpp"
|
#include "common/QLogging.hpp"
|
||||||
#include "singletons/Paths.hpp"
|
#include "singletons/Paths.hpp"
|
||||||
#include "singletons/Resources.hpp"
|
#include "singletons/Resources.hpp"
|
||||||
|
#include "singletons/WindowManager.hpp"
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
@ -13,6 +14,9 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||||
|
# include <QStyleHints>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -219,6 +223,11 @@ bool Theme::isLightTheme() const
|
||||||
return this->isLight_;
|
return this->isLight_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Theme::isSystemTheme() const
|
||||||
|
{
|
||||||
|
return this->themeName == u"System"_s;
|
||||||
|
}
|
||||||
|
|
||||||
void Theme::initialize(Settings &settings, const Paths &paths)
|
void Theme::initialize(Settings &settings, const Paths &paths)
|
||||||
{
|
{
|
||||||
this->themeName.connect(
|
this->themeName.connect(
|
||||||
|
@ -227,15 +236,51 @@ void Theme::initialize(Settings &settings, const Paths &paths)
|
||||||
this->update();
|
this->update();
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
|
auto updateIfSystem = [this](const auto &) {
|
||||||
|
if (this->isSystemTheme())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this->darkSystemThemeName.connect(updateIfSystem, false);
|
||||||
|
this->lightSystemThemeName.connect(updateIfSystem, false);
|
||||||
|
|
||||||
this->loadAvailableThemes(paths);
|
this->loadAvailableThemes(paths);
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||||
|
QObject::connect(qApp->styleHints(), &QStyleHints::colorSchemeChanged,
|
||||||
|
&this->lifetime_, [this] {
|
||||||
|
if (this->isSystemTheme())
|
||||||
|
{
|
||||||
|
this->update();
|
||||||
|
getIApp()->getWindows()->forceLayoutChannelViews();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
this->update();
|
this->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Theme::update()
|
void Theme::update()
|
||||||
{
|
{
|
||||||
auto oTheme = this->findThemeByKey(this->themeName);
|
auto currentTheme = [&]() -> QString {
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||||
|
if (this->isSystemTheme())
|
||||||
|
{
|
||||||
|
switch (qApp->styleHints()->colorScheme())
|
||||||
|
{
|
||||||
|
case Qt::ColorScheme::Light:
|
||||||
|
return this->lightSystemThemeName;
|
||||||
|
case Qt::ColorScheme::Unknown:
|
||||||
|
case Qt::ColorScheme::Dark:
|
||||||
|
return this->darkSystemThemeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return this->themeName;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto oTheme = this->findThemeByKey(currentTheme());
|
||||||
|
|
||||||
constexpr const double nsToMs = 1.0 / 1000000.0;
|
constexpr const double nsToMs = 1.0 / 1000000.0;
|
||||||
QElapsedTimer timer;
|
QElapsedTimer timer;
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
void initialize(Settings &settings, const Paths &paths) final;
|
void initialize(Settings &settings, const Paths &paths) final;
|
||||||
|
|
||||||
bool isLightTheme() const;
|
bool isLightTheme() const;
|
||||||
|
bool isSystemTheme() const;
|
||||||
|
|
||||||
struct TabColors {
|
struct TabColors {
|
||||||
QColor text;
|
QColor text;
|
||||||
|
@ -153,6 +154,9 @@ public:
|
||||||
pajlada::Signals::NoArgSignal updated;
|
pajlada::Signals::NoArgSignal updated;
|
||||||
|
|
||||||
QStringSetting themeName{"/appearance/theme/name", "Dark"};
|
QStringSetting themeName{"/appearance/theme/name", "Dark"};
|
||||||
|
QStringSetting lightSystemThemeName{"/appearance/theme/lightSystem",
|
||||||
|
"Light"};
|
||||||
|
QStringSetting darkSystemThemeName{"/appearance/theme/darkSystem", "Dark"};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isLight_ = false;
|
bool isLight_ = false;
|
||||||
|
@ -164,6 +168,8 @@ private:
|
||||||
// This will only be populated when auto-reloading themes
|
// This will only be populated when auto-reloading themes
|
||||||
QJsonObject currentThemeJson_;
|
QJsonObject currentThemeJson_;
|
||||||
|
|
||||||
|
QObject lifetime_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Figure out which themes are available in the Themes directory
|
* Figure out which themes are available in the Themes directory
|
||||||
*
|
*
|
||||||
|
|
|
@ -122,16 +122,49 @@ void GeneralPage::initLayout(GeneralPageView &layout)
|
||||||
|
|
||||||
layout.addTitle("Interface");
|
layout.addTitle("Interface");
|
||||||
|
|
||||||
layout.addDropdown<QString>(
|
{
|
||||||
"Theme", getIApp()->getThemes()->availableThemes(),
|
auto *themes = getIApp()->getThemes();
|
||||||
getIApp()->getThemes()->themeName,
|
auto available = themes->availableThemes();
|
||||||
[](const auto *combo, const auto &themeKey) {
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||||
return combo->findData(themeKey, Qt::UserRole);
|
available.emplace_back("System", "System");
|
||||||
},
|
#endif
|
||||||
[](const auto &args) {
|
|
||||||
return args.combobox->itemData(args.index, Qt::UserRole).toString();
|
auto addThemeDropdown = [&](auto name, auto &setting,
|
||||||
},
|
const auto &options,
|
||||||
{}, Theme::fallbackTheme.name);
|
const QString &tooltip = {}) {
|
||||||
|
return layout.addDropdown<QString>(
|
||||||
|
name, options, setting,
|
||||||
|
[](const auto *combo, const auto &themeKey) {
|
||||||
|
return combo->findData(themeKey, Qt::UserRole);
|
||||||
|
},
|
||||||
|
[](const auto &args) {
|
||||||
|
return args.combobox->itemData(args.index, Qt::UserRole)
|
||||||
|
.toString();
|
||||||
|
},
|
||||||
|
tooltip, Theme::fallbackTheme.name);
|
||||||
|
};
|
||||||
|
|
||||||
|
addThemeDropdown("Theme", themes->themeName, available);
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
|
||||||
|
auto *darkDropdown = addThemeDropdown(
|
||||||
|
"Dark system theme", themes->darkSystemThemeName,
|
||||||
|
themes->availableThemes(),
|
||||||
|
"This theme is selected if your system is in a dark theme and you "
|
||||||
|
"enabled the adaptive 'System' theme.");
|
||||||
|
auto *lightDropdown = addThemeDropdown(
|
||||||
|
"Light system theme", themes->lightSystemThemeName,
|
||||||
|
themes->availableThemes(),
|
||||||
|
"This theme is selected if your system is in a light theme and you "
|
||||||
|
"enabled the adaptive 'System' theme.");
|
||||||
|
|
||||||
|
auto isSystem = [](const auto &s) {
|
||||||
|
return s == "System";
|
||||||
|
};
|
||||||
|
layout.enableIf(darkDropdown, themes->themeName, isSystem);
|
||||||
|
layout.enableIf(lightDropdown, themes->themeName, isSystem);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
layout.addDropdown<QString>(
|
layout.addDropdown<QString>(
|
||||||
"Font", {"Segoe UI", "Arial", "Choose..."},
|
"Font", {"Segoe UI", "Arial", "Choose..."},
|
||||||
|
|
|
@ -306,6 +306,15 @@ public:
|
||||||
return combo;
|
return combo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void enableIf(QComboBox *widget, auto &setting, auto cb)
|
||||||
|
{
|
||||||
|
auto updateVisibility = [cb = std::move(cb), &setting, widget]() {
|
||||||
|
auto enabled = cb(setting.getValue());
|
||||||
|
widget->setEnabled(enabled);
|
||||||
|
};
|
||||||
|
setting.connect(updateVisibility, this->managedConnections_);
|
||||||
|
}
|
||||||
|
|
||||||
DescriptionLabel *addDescription(const QString &text);
|
DescriptionLabel *addDescription(const QString &text);
|
||||||
|
|
||||||
void addSeperator();
|
void addSeperator();
|
||||||
|
|
Loading…
Reference in a new issue