-
-
Notifications
You must be signed in to change notification settings - Fork 449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the ability to select custom themes in the settings dialog #4570
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
src/singletons/Theme.cpp
Outdated
} | ||
|
||
} // namespace | ||
|
||
namespace chatterino { | ||
|
||
const std::map<QString, ThemeDescriptor> Theme::builtInThemes{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: invalid case style for global constant 'builtInThemes' [readability-identifier-naming]
const std::map<QString, ThemeDescriptor> Theme::builtInThemes{ | |
const std::map<QString, ThemeDescriptor> Theme::BUILT_IN_THEMES{ |
src/singletons/Theme.cpp
Outdated
{ | ||
QFile file(getThemePath(this->themeName)); | ||
if (!file.open(QFile::ReadOnly)) | ||
QStringList themeNames; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'themeNames' is not initialized [cppcoreguidelines-init-variables]
QStringList themeNames; | |
QStringList themeNames = 0; |
namespace chatterino { | ||
|
||
class WindowManager; | ||
|
||
struct ThemeDescriptor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: constructor does not initialize these fields: path, custom [cppcoreguidelines-pro-type-member-init]
src/singletons/Theme.hpp:21:
- QString path;
+ QString path{};
src/singletons/Theme.hpp:23:
- bool custom;
+ bool custom{};
src/singletons/Theme.hpp
Outdated
class Theme final : public Singleton | ||
{ | ||
public: | ||
Theme(); | ||
static const std::map<QString, ThemeDescriptor> builtInThemes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: invalid case style for global constant 'builtInThemes' [readability-identifier-naming]
static const std::map<QString, ThemeDescriptor> builtInThemes; | |
static const std::map<QString, ThemeDescriptor> BUILT_IN_THEMES; |
static const std::map<QString, ThemeDescriptor> builtInThemes; | ||
|
||
// The built in theme that will be used if some theme parsing fails | ||
static const ThemeDescriptor fallbackTheme; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: invalid case style for global constant 'fallbackTheme' [readability-identifier-naming]
static const ThemeDescriptor fallbackTheme; | |
static const ThemeDescriptor FALLBACK_THEME; |
It'd be great if there was hot reloading of the current theme when the JSON file is modified. This would make creating themes and trying out different colors easy (compared to what I imagine is having to restart Chatterino after every change). There appears to be a Qt class that would make detecting the file change easy (in theory, barring os-specific annoyances): https://doc.qt.io/qt-6/qfilesystemwatcher.html. I haven't dug through the Theme code that much though, so it's possible that this is more difficult than it sounds. |
I would like that type of functionality in a V2/V3 kind of thing instead of in the initial release. I could see a world where theme creation isn't tested in Chatterino itself, but rather a web UI. Or there's a |
This should be the way to go. I had a small implementation that used the file system watcher, and it worked well (Windows & VSCode). |
3357fe1
to
bd1881b
Compare
These are only loaded on startup To make this hot reload, we'd need a file watcher or have it just refresh any time the settings page is opened
bd1881b
to
e7cfba8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
} | ||
|
||
} // namespace | ||
|
||
namespace chatterino { | ||
|
||
const std::vector<ThemeDescriptor> Theme::builtInThemes{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: invalid case style for global constant 'builtInThemes' [readability-identifier-naming]
const std::vector<ThemeDescriptor> Theme::builtInThemes{ | |
const std::vector<ThemeDescriptor> Theme::BUILT_IN_THEMES{ |
{ | ||
QFile file(getThemePath(this->themeName)); | ||
if (!file.open(QFile::ReadOnly)) | ||
std::vector<std::pair<QString, QVariant>> packagedThemes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'packagedThemes' is not initialized [cppcoreguidelines-init-variables]
std::vector<std::pair<QString, QVariant>> packagedThemes; | |
std::vector<std::pair<QString, QVariant>> packagedThemes = 0; |
} | ||
} | ||
|
||
std::optional<ThemeDescriptor> Theme::findThemeByKey(const QString &key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: method 'findThemeByKey' can be made static [readability-convert-member-functions-to-static]
std::optional<ThemeDescriptor> Theme::findThemeByKey(const QString &key) | |
static std::optional<ThemeDescriptor> Theme::findThemeByKey(const QString &key) |
|
||
namespace chatterino { | ||
|
||
class WindowManager; | ||
|
||
struct ThemeDescriptor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: constructor does not initialize these fields: key, path, name [cppcoreguidelines-pro-type-member-init]
src/singletons/Theme.hpp:21:
- QString key;
+ QString key{};
src/singletons/Theme.hpp:25:
- QString path;
+ QString path{};
src/singletons/Theme.hpp:28:
- QString name;
+ QString name{};
class Theme final : public Singleton | ||
{ | ||
public: | ||
Theme(); | ||
static const std::vector<ThemeDescriptor> builtInThemes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: invalid case style for global constant 'builtInThemes' [readability-identifier-naming]
static const std::vector<ThemeDescriptor> builtInThemes; | |
static const std::vector<ThemeDescriptor> BUILT_IN_THEMES; |
template <typename T> | ||
ComboBox *addDropdown( | ||
const QString &text, | ||
const std::vector<std::pair<QString, QVariant>> &items, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: all parameters should be named in a function [readability-named-parameter]
const std::vector<std::pair<QString, QVariant>> &items, | |
const std::vector<std::pair<QString, QVariant> /*unused*/> &items, |
std::function<T(DropdownArgs)> setValue, QString toolTipText = {}, | ||
const QString &defaultValueText = {}) | ||
{ | ||
auto *combo = this->addDropdown(text, {}, std::move(toolTipText)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'combo' is not initialized [cppcoreguidelines-init-variables]
auto *combo = this->addDropdown(text, {}, std::move(toolTipText)); | |
auto *combo = nullptr = this->addDropdown(text, {}, std::move(toolTipText)); |
Description
This loads themes (any .json file) from the /Themes directory on startup and lists those in the settings page.
The custom themes in that directory will have a Custom: prefix to show that they're custom.
In the settingsfile, we save the name of the theme (e.g. 'forsen', no more info).
When the theme is updated or on Chatterino startup, we find the best matching theme with that name, whether it's a built in theme or a custom theme.
There's currently no mechanism for making a theme that has the same name as a built in theme, and they still show up in the menu. IMO we should just not allow duplicate names for simplicity's sake.
There's a few things left to do, and a few things to discuss before taking this step, even though I still deem it to be "pre-production" even when this PR is merged in.
The changelog entry is left as a Dev entry on purpose since I don't think this is a feature that should be fully announced until there's more testing & better UX for users.