diff --git a/chatterino.pro b/chatterino.pro index 83a604573..77dc7e0d3 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -55,8 +55,7 @@ SOURCES += \ src/application.cpp \ src/channel.cpp \ src/channeldata.cpp \ - src/colorscheme.cpp \ - src/ircmanager.cpp \ + src/singletons/ircmanager.cpp \ src/messages/lazyloadedimage.cpp \ src/messages/link.cpp \ src/messages/message.cpp \ @@ -74,23 +73,23 @@ SOURCES += \ src/messages/messageref.cpp \ src/logging/loggingmanager.cpp \ src/logging/loggingchannel.cpp \ - src/windowmanager.cpp \ - src/channelmanager.cpp \ - src/fontmanager.cpp \ - src/settingsmanager.cpp \ - src/emotemanager.cpp \ + src/singletons/windowmanager.cpp \ + src/singletons/channelmanager.cpp \ + src/singletons/fontmanager.cpp \ + src/singletons/settingsmanager.cpp \ + src/singletons/emotemanager.cpp \ src/messages/messagebuilder.cpp \ src/twitch/twitchmessagebuilder.cpp \ src/twitch/twitchparsemessage.cpp \ src/widgets/titlebar.cpp \ src/appdatapath.cpp \ - src/accountmanager.cpp \ + src/singletons/accountmanager.cpp \ src/twitch/twitchuser.cpp \ src/ircaccount.cpp \ src/widgets/accountpopup.cpp \ src/widgets/basewidget.cpp \ src/widgets/helper/resizingtextedit.cpp \ - src/completionmanager.cpp \ + src/singletons/completionmanager.cpp \ src/widgets/logindialog.cpp \ src/widgets/qualitypopup.cpp \ src/widgets/emotepopup.cpp \ @@ -100,7 +99,7 @@ SOURCES += \ src/widgets/helper/rippleeffectbutton.cpp \ src/messages/messagecolor.cpp \ src/util/networkmanager.cpp \ - src/commandmanager.cpp \ + src/singletons/commandmanager.cpp \ src/widgets/split.cpp \ src/widgets/helper/splitinput.cpp \ src/widgets/helper/splitheader.cpp \ @@ -110,16 +109,18 @@ SOURCES += \ src/widgets/helper/splitcolumn.cpp \ src/widgets/accountswitchwidget.cpp \ src/widgets/accountswitchpopupwidget.cpp \ - src/widgets/tooltipwidget.cpp + src/widgets/tooltipwidget.cpp \ + src/singletons/thememanager.cpp \ + src/twitch/twitchaccountmanager.cpp \ + src/singletons/helper/completionmodel.cpp HEADERS += \ src/precompiled_headers.hpp \ src/asyncexec.hpp \ src/channel.hpp \ - src/colorscheme.hpp \ src/concurrentmap.hpp \ src/emojis.hpp \ - src/ircmanager.hpp \ + src/singletons/ircmanager.hpp \ src/messages/lazyloadedimage.hpp \ src/messages/link.hpp \ src/messages/message.hpp \ @@ -144,11 +145,11 @@ HEADERS += \ src/messages/messageref.hpp \ src/logging/loggingmanager.hpp \ src/logging/loggingchannel.hpp \ - src/channelmanager.hpp \ - src/windowmanager.hpp \ - src/settingsmanager.hpp \ - src/fontmanager.hpp \ - src/emotemanager.hpp \ + src/singletons/channelmanager.hpp \ + src/singletons/windowmanager.hpp \ + src/singletons/settingsmanager.hpp \ + src/singletons/fontmanager.hpp \ + src/singletons/emotemanager.hpp \ src/util/urlfetch.hpp \ src/messages/messageparseargs.hpp \ src/messages/messagebuilder.hpp \ @@ -156,13 +157,13 @@ HEADERS += \ src/twitch/twitchparsemessage.hpp \ src/widgets/titlebar.hpp \ src/appdatapath.hpp \ - src/accountmanager.hpp \ + src/singletons/accountmanager.hpp \ src/twitch/twitchuser.hpp \ src/ircaccount.hpp \ src/widgets/accountpopup.hpp \ src/util/distancebetweenpoints.hpp \ src/widgets/basewidget.hpp \ - src/completionmanager.hpp \ + src/singletons/completionmanager.hpp \ src/widgets/helper/channelview.hpp \ src/twitch/twitchchannel.hpp \ src/widgets/helper/rippleeffectbutton.hpp \ @@ -174,7 +175,7 @@ HEADERS += \ src/debug/log.hpp \ src/util/benchmark.hpp \ src/util/networkmanager.hpp \ - src/commandmanager.hpp \ + src/singletons/commandmanager.hpp \ src/widgets/split.hpp \ src/widgets/helper/splitheader.hpp \ src/widgets/helper/splitinput.hpp \ @@ -189,7 +190,11 @@ HEADERS += \ src/const.hpp \ src/widgets/tooltipwidget.hpp \ src/precompiled_headers.hpp \ - src/messages/wordflags.hpp + src/messages/wordflags.hpp \ + src/singletons/thememanager.hpp \ + src/twitch/twitchaccountmanager.hpp \ + src/singletons/helper/completionmodel.hpp \ + src/singletons/helper/chatterinosetting.hpp PRECOMPILED_HEADER = @@ -210,20 +215,22 @@ win32 { } # Optional dependency on windows sdk 7.1 -win32:exists(C:\Program Files\Microsoft SDKs\Windows\v7.1\Include\Windows.h) { - LIBS += -L"C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib" \ - -ldwmapi \ - -lgdi32 +!contains(QMAKE_TARGET.arch, x86_64) { + win32:exists(C:\Program Files\Microsoft SDKs\Windows\v7.1\Include\Windows.h) { + LIBS += -L"C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib" \ + -ldwmapi \ + -lgdi32 -# SOURCES += platform/borderless/qwinwidget.cpp \ -# platform/borderless/winnativewindow.cpp \ -# platform/borderless/widget.cpp +# SOURCES += platform/borderless/qwinwidget.cpp \ +# platform/borderless/winnativewindow.cpp \ +# platform/borderless/widget.cpp -# HEADERS += platform/borderless/qwinwidget.h \ -# platform/borderless/winnativewindow.h \ -# platform/borderless/widget.h +# HEADERS += platform/borderless/qwinwidget.h \ +# platform/borderless/winnativewindow.h \ +# platform/borderless/widget.h - DEFINES += "USEWINSDK" + DEFINES += "USEWINSDK" + } } macx { diff --git a/src/application.cpp b/src/application.cpp index 9b652dd37..2ee52b156 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -1,8 +1,10 @@ #include "application.hpp" -#include "accountmanager.hpp" -#include "colorscheme.hpp" #include "logging/loggingmanager.hpp" -#include "settingsmanager.hpp" +#include "singletons/accountmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/thememanager.hpp" +#include "singletons/windowmanager.hpp" namespace chatterino { @@ -10,15 +12,11 @@ namespace chatterino { // It will create the instances of the major classes, and connect their signals to each other Application::Application() - : windowManager(this->channelManager, this->colorScheme) - , colorScheme(this->windowManager) - , channelManager(this->windowManager, this->ircManager) - , ircManager(this->channelManager, this->resources, this->windowManager) { logging::init(); SettingsManager::getInstance().load(); - this->windowManager.initMainWindow(); + WindowManager::getInstance().initMainWindow(); // Initialize everything we need EmoteManager::getInstance().loadGlobalEmotes(); @@ -39,17 +37,17 @@ Application::~Application() int Application::run(QApplication &qtApp) { // Start connecting to the IRC Servers (Twitch only for now) - this->ircManager.connect(); + IrcManager::getInstance().connect(); // Show main window - this->windowManager.getMainWindow().show(); + WindowManager::getInstance().getMainWindow().show(); return qtApp.exec(); } void Application::save() { - this->windowManager.save(); + WindowManager::getInstance().save(); } } // namespace chatterino diff --git a/src/application.hpp b/src/application.hpp index c6c69b51e..a15d837e7 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -1,12 +1,7 @@ #pragma once -#include "channelmanager.hpp" -#include "colorscheme.hpp" -#include "completionmanager.hpp" -#include "emotemanager.hpp" -#include "ircmanager.hpp" +#include "singletons/ircmanager.hpp" #include "resources.hpp" -#include "windowmanager.hpp" #include @@ -20,12 +15,6 @@ public: int run(QApplication &qtApp); - WindowManager windowManager; - ColorScheme colorScheme; - Resources resources; - ChannelManager channelManager; - IrcManager ircManager; - private: void save(); }; diff --git a/src/channel.cpp b/src/channel.cpp index 7b63a2a81..15858d997 100644 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -1,10 +1,10 @@ #include "channel.hpp" #include "debug/log.hpp" -#include "emotemanager.hpp" -#include "ircmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/ircmanager.hpp" #include "logging/loggingmanager.hpp" #include "messages/message.hpp" -#include "windowmanager.hpp" +#include "singletons/windowmanager.hpp" #include #include diff --git a/src/channel.hpp b/src/channel.hpp index 819eef5e1..d01d67a2d 100644 --- a/src/channel.hpp +++ b/src/channel.hpp @@ -1,7 +1,6 @@ #pragma once #include "concurrentmap.hpp" -#include "emotemanager.hpp" #include "logging/loggingchannel.hpp" #include "messages/lazyloadedimage.hpp" #include "messages/limitedqueue.hpp" diff --git a/src/channeldata.hpp b/src/channeldata.hpp index 8f06f88d8..d3d122506 100644 --- a/src/channeldata.hpp +++ b/src/channeldata.hpp @@ -17,4 +17,4 @@ private: // std::map subscriptionBadges; }; -}; // namespace chatterino +} // namespace chatterino diff --git a/src/messages/lazyloadedimage.cpp b/src/messages/lazyloadedimage.cpp index 496681ec5..9cb8e61bb 100644 --- a/src/messages/lazyloadedimage.cpp +++ b/src/messages/lazyloadedimage.cpp @@ -1,10 +1,10 @@ #include "messages/lazyloadedimage.hpp" #include "asyncexec.hpp" -#include "emotemanager.hpp" -#include "ircmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/ircmanager.hpp" +#include "singletons/windowmanager.hpp" #include "util/networkmanager.hpp" #include "util/urlfetch.hpp" -#include "windowmanager.hpp" #include #include @@ -81,7 +81,7 @@ void LazyLoadedImage::loadImage() EmoteManager::getInstance().incGeneration(); - WindowManager::instance->layoutVisibleChatWidgets(); + WindowManager::getInstance().layoutVisibleChatWidgets(); }); EmoteManager::getInstance().getGifUpdateSignal().connect([=]() { diff --git a/src/messages/message.cpp b/src/messages/message.cpp index 4d7ddc3ea..cf10749cf 100644 --- a/src/messages/message.cpp +++ b/src/messages/message.cpp @@ -1,10 +1,10 @@ #include "messages/message.hpp" #include "channel.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include "emojis.hpp" -#include "emotemanager.hpp" -#include "fontmanager.hpp" -#include "ircmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/fontmanager.hpp" +#include "singletons/ircmanager.hpp" #include "messages/link.hpp" #include "resources.hpp" #include "util/irchelpers.hpp" diff --git a/src/messages/messagebuilder.cpp b/src/messages/messagebuilder.cpp index 2a0014964..ac2658886 100644 --- a/src/messages/messagebuilder.cpp +++ b/src/messages/messagebuilder.cpp @@ -1,6 +1,6 @@ #include "messagebuilder.hpp" -#include "colorscheme.hpp" -#include "emotemanager.hpp" +#include "singletons/thememanager.hpp" +#include "singletons/emotemanager.hpp" #include "resources.hpp" #include diff --git a/src/messages/messagecolor.cpp b/src/messages/messagecolor.cpp index 135d0298a..769f5528b 100644 --- a/src/messages/messagecolor.cpp +++ b/src/messages/messagecolor.cpp @@ -19,17 +19,17 @@ MessageColor::Type MessageColor::getType() const return this->type; } -const QColor &MessageColor::getColor(ColorScheme &colorScheme) const +const QColor &MessageColor::getColor(ThemeManager &themeManager) const { switch (this->type) { case Type::Custom: return this->color; case Type::Text: - return colorScheme.Text; + return themeManager.Text; case Type::System: - return colorScheme.SystemMessageColor; + return themeManager.SystemMessageColor; case Type::Link: - return colorScheme.TextLink; + return themeManager.TextLink; } static QColor _default; diff --git a/src/messages/messagecolor.hpp b/src/messages/messagecolor.hpp index 48079f9c7..a021bd102 100644 --- a/src/messages/messagecolor.hpp +++ b/src/messages/messagecolor.hpp @@ -2,7 +2,7 @@ #include -#include +#include "singletons/thememanager.hpp" namespace chatterino { namespace messages { @@ -16,7 +16,7 @@ public: explicit MessageColor(Type type = Text); Type getType() const; - const QColor &getColor(ColorScheme &colorScheme) const; + const QColor &getColor(ThemeManager &themeManager) const; private: Type type; diff --git a/src/messages/messageref.cpp b/src/messages/messageref.cpp index ea36b2115..f4e552b2c 100644 --- a/src/messages/messageref.cpp +++ b/src/messages/messageref.cpp @@ -1,6 +1,6 @@ #include "messages/messageref.hpp" -#include "emotemanager.hpp" -#include "settingsmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/settingsmanager.hpp" #include diff --git a/src/messages/word.cpp b/src/messages/word.cpp index 245d67fcc..2db6d74ad 100644 --- a/src/messages/word.cpp +++ b/src/messages/word.cpp @@ -1,5 +1,5 @@ #include "messages/word.hpp" -#include "settingsmanager.hpp" +#include "singletons/settingsmanager.hpp" #include "util/benchmark.hpp" namespace chatterino { diff --git a/src/messages/word.hpp b/src/messages/word.hpp index 38c551769..cc99017e7 100644 --- a/src/messages/word.hpp +++ b/src/messages/word.hpp @@ -1,6 +1,6 @@ #pragma once -#include "fontmanager.hpp" +#include "singletons/fontmanager.hpp" #include "messages/lazyloadedimage.hpp" #include "messages/link.hpp" #include "messages/messagecolor.hpp" diff --git a/src/resources.cpp b/src/resources.cpp index 2f620390a..af85b300d 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -1,7 +1,7 @@ #include "resources.hpp" -#include "emotemanager.hpp" +//#include "singletons/emotemanager.hpp" +//#include "singletons/windowmanager.hpp" #include "util/urlfetch.hpp" -#include "windowmanager.hpp" #include @@ -41,6 +41,12 @@ Resources::Resources() this->loadChatterinoBadges(); } +Resources &Resources::getInstance() +{ + static Resources instance; + return instance; +} + Resources::BadgeVersion::BadgeVersion(QJsonObject &&root) : badgeImage1x(new messages::LazyLoadedImage(root.value("image_url_1x").toString())) , badgeImage2x(new messages::LazyLoadedImage(root.value("image_url_2x").toString())) diff --git a/src/resources.hpp b/src/resources.hpp index 6288d5a69..d0bdd03f2 100644 --- a/src/resources.hpp +++ b/src/resources.hpp @@ -10,9 +10,11 @@ namespace chatterino { class Resources { -public: explicit Resources(); +public: + static Resources &getInstance(); + messages::LazyLoadedImage *badgeStaff; messages::LazyLoadedImage *badgeAdmin; messages::LazyLoadedImage *badgeGlobalModerator; diff --git a/src/singletons/accountmanager.cpp b/src/singletons/accountmanager.cpp new file mode 100644 index 000000000..30e72e161 --- /dev/null +++ b/src/singletons/accountmanager.cpp @@ -0,0 +1,45 @@ +#include "singletons/accountmanager.hpp" + +namespace chatterino { + +namespace { + +inline QString getEnvString(const char *target) +{ + char *val = std::getenv(target); + if (val == nullptr) { + return QString(); + } + + return QString(val); +} + +} // namespace + +AccountManager::AccountManager() +{ +} + +AccountManager &AccountManager::getInstance() +{ + static AccountManager instance; + return instance; +} + +void AccountManager::load() +{ + this->Twitch.reloadUsers(); + + auto currentUser = this->Twitch.findUserByUsername( + QString::fromStdString(this->Twitch.currentUsername.getValue())); + + if (currentUser) { + this->Twitch.currentUser = currentUser; + } else { + this->Twitch.currentUser = this->Twitch.anonymousUser; + } + + this->Twitch.userChanged.invoke(); +} + +} // namespace chatterino diff --git a/src/singletons/accountmanager.hpp b/src/singletons/accountmanager.hpp new file mode 100644 index 000000000..7634375ed --- /dev/null +++ b/src/singletons/accountmanager.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "twitch/twitchaccountmanager.hpp" + +namespace chatterino { + +class AccountManager +{ + AccountManager(); + +public: + static AccountManager &getInstance(); + + void load(); + + twitch::TwitchAccountManager Twitch; +}; + +} // namespace chatterino diff --git a/src/channelmanager.cpp b/src/singletons/channelmanager.cpp similarity index 73% rename from src/channelmanager.cpp rename to src/singletons/channelmanager.cpp index 3df5e97e4..45134c937 100644 --- a/src/channelmanager.cpp +++ b/src/singletons/channelmanager.cpp @@ -1,20 +1,21 @@ -#include "channelmanager.hpp" -#include "ircmanager.hpp" +#include "singletons/channelmanager.hpp" +#include "singletons/ircmanager.hpp" using namespace chatterino::twitch; namespace chatterino { -ChannelManager *ChannelManager::instance = nullptr; - -ChannelManager::ChannelManager(WindowManager &_windowManager, IrcManager &_ircManager) - : windowManager(_windowManager) - , ircManager(_ircManager) - , whispersChannel(new TwitchChannel(_ircManager, "/whispers", true)) - , mentionsChannel(new TwitchChannel(_ircManager, "/mentions", true)) - , emptyChannel(new TwitchChannel(_ircManager, "", true)) +ChannelManager &ChannelManager::getInstance() +{ + static ChannelManager instance; + return instance; +} + +ChannelManager::ChannelManager() + : whispersChannel(new Channel("/whispers")) + , mentionsChannel(new Channel("/mentions")) + , emptyChannel(new Channel("")) { - ChannelManager::instance = this; } const std::vector> ChannelManager::getItems() @@ -30,7 +31,7 @@ const std::vector> ChannelManager::getItems() return items; } -std::shared_ptr ChannelManager::addTwitchChannel(const QString &rawChannelName) +std::shared_ptr ChannelManager::addTwitchChannel(const QString &rawChannelName) { QString channelName = rawChannelName.toLower(); @@ -47,11 +48,11 @@ std::shared_ptr ChannelManager::addTwitchChannel(const QString &r auto it = this->twitchChannels.find(channelName); if (it == this->twitchChannels.end()) { - auto channel = std::make_shared(this->ircManager, channelName); + auto channel = std::make_shared(channelName); this->twitchChannels.insert(channelName, std::make_tuple(channel, 1)); - this->ircManager.joinChannel(channelName); + this->ircJoin.invoke(channelName); return channel; } @@ -61,7 +62,7 @@ std::shared_ptr ChannelManager::addTwitchChannel(const QString &r return std::get<0>(it.value()); } -std::shared_ptr ChannelManager::getTwitchChannel(const QString &channel) +std::shared_ptr ChannelManager::getTwitchChannel(const QString &channel) { QMutexLocker locker(&this->channelsMutex); @@ -107,7 +108,7 @@ void ChannelManager::removeTwitchChannel(const QString &channel) std::get<1>(a.value())--; if (std::get<1>(a.value()) == 0) { - this->ircManager.partChannel(c); + this->ircPart.invoke(c); this->twitchChannels.remove(c); } } @@ -126,7 +127,7 @@ const std::string &ChannelManager::getUserID(const std::string &username) return temporary; } -void ChannelManager::doOnAll(std::function)> func) +void ChannelManager::doOnAll(std::function)> func) { for (const auto &channel : this->twitchChannels) { func(std::get<0>(channel)); diff --git a/src/channelmanager.hpp b/src/singletons/channelmanager.hpp similarity index 51% rename from src/channelmanager.hpp rename to src/singletons/channelmanager.hpp index 02200e646..b74a6cdf0 100644 --- a/src/channelmanager.hpp +++ b/src/singletons/channelmanager.hpp @@ -13,28 +13,25 @@ class IrcManager; class ChannelManager { + explicit ChannelManager(); + public: - explicit ChannelManager(WindowManager &_windowManager, IrcManager &_ircManager); - - static ChannelManager *instance; - - WindowManager &windowManager; - IrcManager &ircManager; + static ChannelManager &getInstance(); const std::vector> getItems(); - std::shared_ptr addTwitchChannel(const QString &channel); - std::shared_ptr getTwitchChannel(const QString &channel); + std::shared_ptr addTwitchChannel(const QString &channel); + std::shared_ptr getTwitchChannel(const QString &channel); void removeTwitchChannel(const QString &channel); const std::string &getUserID(const std::string &username); - void doOnAll(std::function)> func); + void doOnAll(std::function)> func); // Special channels - const std::shared_ptr whispersChannel; - const std::shared_ptr mentionsChannel; - const std::shared_ptr emptyChannel; + const std::shared_ptr whispersChannel; + const std::shared_ptr mentionsChannel; + const std::shared_ptr emptyChannel; private: std::map usernameToID; @@ -42,6 +39,11 @@ private: QMutex channelsMutex; QMap, int>> twitchChannels; + + pajlada::Signals::Signal ircJoin; + pajlada::Signals::Signal ircPart; + + friend class IrcManager; }; } // namespace chatterino diff --git a/src/commandmanager.cpp b/src/singletons/commandmanager.cpp similarity index 89% rename from src/commandmanager.cpp rename to src/singletons/commandmanager.cpp index 6179b3542..335d8289b 100644 --- a/src/commandmanager.cpp +++ b/src/singletons/commandmanager.cpp @@ -1,8 +1,14 @@ -#include "commandmanager.hpp" +#include "singletons/commandmanager.hpp" #include namespace chatterino { +CommandManager &CommandManager::getInstance() +{ + static CommandManager instance; + return instance; +} + // QString CommandManager::execCommand(QString text) //{ // QStringList words = text.split(' ', QString::SkipEmptyParts); diff --git a/src/commandmanager.hpp b/src/singletons/commandmanager.hpp similarity index 83% rename from src/commandmanager.hpp rename to src/singletons/commandmanager.hpp index 2fb566ec3..c5c2dfac7 100644 --- a/src/commandmanager.hpp +++ b/src/singletons/commandmanager.hpp @@ -7,7 +7,11 @@ namespace chatterino { class CommandManager { - // public: + CommandManager() = default; + +public: + static CommandManager &getInstance(); + // CommandManager() = delete; // QString execCommand(QString text); diff --git a/src/singletons/completionmanager.cpp b/src/singletons/completionmanager.cpp new file mode 100644 index 000000000..a3b52d6a0 --- /dev/null +++ b/src/singletons/completionmanager.cpp @@ -0,0 +1,28 @@ +#include "singletons/completionmanager.hpp" +#include "common.hpp" +#include "debug/log.hpp" +#include "singletons/channelmanager.hpp" +#include "singletons/emotemanager.hpp" + +namespace chatterino { + +CompletionManager &CompletionManager::getInstance() +{ + static CompletionManager instance; + return instance; +} + +CompletionModel *CompletionManager::createModel(const std::string &channelName) +{ + auto it = this->models.find(channelName); + if (it != this->models.end()) { + return it->second; + } + + CompletionModel *ret = new CompletionModel(qS(channelName)); + this->models[channelName] = ret; + + return ret; +} + +} // namespace chatterino diff --git a/src/singletons/completionmanager.hpp b/src/singletons/completionmanager.hpp new file mode 100644 index 000000000..d8a9ee30a --- /dev/null +++ b/src/singletons/completionmanager.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include +#include + +#include "helper/completionmodel.hpp" + +namespace chatterino { +class CompletionManager +{ + CompletionManager() = default; + +public: + static CompletionManager &getInstance(); + + CompletionModel *createModel(const std::string &channelName); + +private: + std::map models; +}; + +} // namespace chatterino diff --git a/src/emotemanager.cpp b/src/singletons/emotemanager.cpp similarity index 96% rename from src/emotemanager.cpp rename to src/singletons/emotemanager.cpp index ac44e27d9..24e42aa81 100644 --- a/src/emotemanager.cpp +++ b/src/singletons/emotemanager.cpp @@ -1,10 +1,11 @@ #include "emotemanager.hpp" #include "common.hpp" -#include "settingsmanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/windowmanager.hpp" #include "util/urlfetch.hpp" -#include "windowmanager.hpp" #include +#include #include #include #include @@ -21,8 +22,10 @@ using namespace chatterino::messages; namespace chatterino { -EmoteManager::EmoteManager() - : findShortCodesRegex(":([-+\\w]+):") +EmoteManager::EmoteManager(SettingsManager &_settingsManager, WindowManager &_windowManager) + : settingsManager(_settingsManager) + , windowManager(_windowManager) + , findShortCodesRegex(":([-+\\w]+):") { auto &accountManager = AccountManager::getInstance(); @@ -33,6 +36,12 @@ EmoteManager::EmoteManager() }); } +EmoteManager &EmoteManager::getInstance() +{ + static EmoteManager instance(SettingsManager::getInstance(), WindowManager::getInstance()); + return instance; +} + void EmoteManager::loadGlobalEmotes() { this->loadEmojis(); @@ -507,7 +516,7 @@ boost::signals2::signal &EmoteManager::getGifUpdateSignal() this->gifUpdateTimer.setInterval(30); this->gifUpdateTimer.start(); - SettingsManager::getInstance().enableGifAnimations.connect([this](bool enabled, auto) { + this->settingsManager.enableGifAnimations.connect([this](bool enabled, auto) { if (enabled) { this->gifUpdateTimer.start(); } else { @@ -517,7 +526,8 @@ boost::signals2::signal &EmoteManager::getGifUpdateSignal() QObject::connect(&this->gifUpdateTimer, &QTimer::timeout, [this] { this->gifUpdateTimerSignal(); - WindowManager::instance->repaintGifEmotes(); + // fourtf: + this->windowManager.repaintGifEmotes(); }); } diff --git a/src/emotemanager.hpp b/src/singletons/emotemanager.hpp similarity index 94% rename from src/emotemanager.hpp rename to src/singletons/emotemanager.hpp index ebf30ad09..6f827a9b4 100644 --- a/src/emotemanager.hpp +++ b/src/singletons/emotemanager.hpp @@ -18,6 +18,9 @@ namespace chatterino { +class SettingsManager; +class WindowManager; + struct EmoteData { EmoteData() { @@ -35,14 +38,10 @@ typedef ConcurrentMap EmoteMap; class EmoteManager { - EmoteManager(); + explicit EmoteManager(SettingsManager &manager, WindowManager &windowManager); public: - static EmoteManager &getInstance() - { - static EmoteManager instance; - return instance; - } + static EmoteManager &getInstance(); void loadGlobalEmotes(); @@ -79,6 +78,9 @@ public: ConcurrentMap miscImageCache; private: + SettingsManager &settingsManager; + WindowManager &windowManager; + /// Emojis QRegularExpression findShortCodesRegex; diff --git a/src/fontmanager.cpp b/src/singletons/fontmanager.cpp similarity index 94% rename from src/fontmanager.cpp rename to src/singletons/fontmanager.cpp index b0c11be17..21fabe8e6 100644 --- a/src/fontmanager.cpp +++ b/src/singletons/fontmanager.cpp @@ -1,4 +1,4 @@ -#include "fontmanager.hpp" +#include "singletons/fontmanager.hpp" #include @@ -23,6 +23,13 @@ FontManager::FontManager() }); } +FontManager &FontManager::getInstance() +{ + static FontManager instance; + + return instance; +} + QFont &FontManager::getFont(Type type, float dpi) { // return this->currentFont.getFont(type); diff --git a/src/fontmanager.hpp b/src/singletons/fontmanager.hpp similarity index 95% rename from src/fontmanager.hpp rename to src/singletons/fontmanager.hpp index 0e6ff8b1e..ee2ff6f9d 100644 --- a/src/fontmanager.hpp +++ b/src/singletons/fontmanager.hpp @@ -11,6 +11,7 @@ class FontManager { FontManager(const FontManager &) = delete; FontManager(FontManager &&) = delete; + FontManager(); public: enum Type : uint8_t { @@ -24,12 +25,7 @@ public: }; // FontManager is initialized only once, on first use - static FontManager &getInstance() - { - static FontManager instance; - - return instance; - } + static FontManager &getInstance(); QFont &getFont(Type type, float dpi); QFontMetrics &getFontMetrics(Type type, float dpi); @@ -50,8 +46,6 @@ public: pajlada::Signals::NoArgSignal fontChanged; private: - FontManager(); - struct FontData { FontData(QFont &&_font) : font(_font) @@ -68,7 +62,7 @@ private: explicit Font(const char *fontFamilyName, int mediumSize) : small(QFont(fontFamilyName, mediumSize - 4)) - , mediumSmall(QFont(fontFamilyName, mediumSize -2)) + , mediumSmall(QFont(fontFamilyName, mediumSize - 2)) , medium(QFont(fontFamilyName, mediumSize)) , mediumBold(QFont(fontFamilyName, mediumSize, QFont::DemiBold)) , mediumItalic(QFont(fontFamilyName, mediumSize, -1, true)) diff --git a/src/singletons/helper/chatterinosetting.hpp b/src/singletons/helper/chatterinosetting.hpp new file mode 100644 index 000000000..59591d73c --- /dev/null +++ b/src/singletons/helper/chatterinosetting.hpp @@ -0,0 +1,67 @@ +#pragma once + +namespace chatterino { +static void _registerSetting(std::weak_ptr setting); + +template +class ChatterinoSetting : public pajlada::Settings::Setting +{ +public: + ChatterinoSetting(const std::string &_path, const Type &_defaultValue) + : pajlada::Settings::Setting(_path, _defaultValue) + { + _registerSetting(this->data); + } + + void saveRecall(); + + ChatterinoSetting &operator=(const Type &newValue) + { + assert(this->data != nullptr); + + this->setValue(newValue); + + return *this; + } + + template + ChatterinoSetting &operator=(const T2 &newValue) + { + assert(this->data != nullptr); + + this->setValue(newValue); + + return *this; + } + + ChatterinoSetting &operator=(Type &&newValue) noexcept + { + assert(this->data != nullptr); + + this->setValue(std::move(newValue)); + + return *this; + } + + bool operator==(const Type &rhs) const + { + assert(this->data != nullptr); + + return this->getValue() == rhs; + } + + bool operator!=(const Type &rhs) const + { + assert(this->data != nullptr); + + return this->getValue() != rhs; + } + + operator const Type() const + { + assert(this->data != nullptr); + + return this->getValue(); + } +}; +} diff --git a/src/completionmanager.cpp b/src/singletons/helper/completionmodel.cpp similarity index 80% rename from src/completionmanager.cpp rename to src/singletons/helper/completionmodel.cpp index 00d1b57d5..9c8b630ac 100644 --- a/src/completionmanager.cpp +++ b/src/singletons/helper/completionmodel.cpp @@ -1,105 +1,88 @@ -#include "completionmanager.hpp" -#include "channelmanager.hpp" -#include "common.hpp" -#include "debug/log.hpp" -#include "emotemanager.hpp" - -namespace chatterino { - -CompletionModel::CompletionModel(const QString &_channelName) - : channelName(_channelName) -{ -} - -void CompletionModel::refresh() -{ - // debug::Log("[CompletionModel:{}] Refreshing...]", this->channelName); - - auto &emoteManager = EmoteManager::getInstance(); - this->emotes.clear(); - - // User-specific: Twitch Emotes - // TODO: Fix this so it properly updates with the proper api. oauth token needs proper scope - for (const auto &m : emoteManager.twitchAccountEmotes) { - for (const auto &emoteName : m.second.emoteCodes) { - this->addString(emoteName); - } - } - - // Global: BTTV Global Emotes - std::vector &bttvGlobalEmoteCodes = emoteManager.bttvGlobalEmoteCodes; - for (const auto &m : bttvGlobalEmoteCodes) { - this->addString(m); - } - - // Global: FFZ Global Emotes - std::vector &ffzGlobalEmoteCodes = emoteManager.ffzGlobalEmoteCodes; - for (const auto &m : ffzGlobalEmoteCodes) { - this->addString(m); - } - - // Channel-specific: BTTV Channel Emotes - std::vector &bttvChannelEmoteCodes = - emoteManager.bttvChannelEmoteCodes[this->channelName.toStdString()]; - for (const auto &m : bttvChannelEmoteCodes) { - this->addString(m); - } - - // Channel-specific: FFZ Channel Emotes - std::vector &ffzChannelEmoteCodes = - emoteManager.ffzChannelEmoteCodes[this->channelName.toStdString()]; - for (const auto &m : ffzChannelEmoteCodes) { - this->addString(m); - } - - // Global: Emojis - const auto &emojiShortCodes = emoteManager.emojiShortCodes; - for (const auto &m : emojiShortCodes) { - this->addString(":" + m + ":"); - } - - // Channel-specific: Usernames - auto *channelManager = ChannelManager::instance; - auto c = channelManager->getTwitchChannel(this->channelName); - if (!c) { - return; - } - auto usernames = c->getUsernamesForCompletions(); - for (const auto &name : usernames) { - assert(!name.displayName.isEmpty()); - this->addString(name.displayName); - this->addString('@' + name.displayName); - - if (!name.localizedName.isEmpty()) { - this->addString(name.localizedName); - this->addString('@' + name.localizedName); - } - } -} - -void CompletionModel::addString(const std::string &str) -{ - // Always add a space at the end of completions - this->emotes.push_back(qS(str) + " "); -} - -void CompletionModel::addString(const QString &str) -{ - // Always add a space at the end of completions - this->emotes.push_back(str + " "); -} - -CompletionModel *CompletionManager::createModel(const std::string &channelName) -{ - auto it = this->models.find(channelName); - if (it != this->models.end()) { - return it->second; - } - - CompletionModel *ret = new CompletionModel(qS(channelName)); - this->models[channelName] = ret; - - return ret; -} - -} // namespace chatterino +#include "completionmodel.hpp" + +#include "common.hpp" +#include "debug/log.hpp" +#include "singletons/channelmanager.hpp" +#include "singletons/completionmanager.hpp" +#include "singletons/emotemanager.hpp" + +namespace chatterino { +CompletionModel::CompletionModel(const QString &_channelName) + : channelName(_channelName) +{ +} + +void CompletionModel::refresh() +{ + // debug::Log("[CompletionModel:{}] Refreshing...]", this->channelName); + + auto &emoteManager = EmoteManager::getInstance(); + this->emotes.clear(); + + // User-specific: Twitch Emotes + // TODO: Fix this so it properly updates with the proper api. oauth token needs proper scope + for (const auto &m : emoteManager.twitchAccountEmotes) { + for (const auto &emoteName : m.second.emoteCodes) { + this->addString(emoteName); + } + } + + // Global: BTTV Global Emotes + std::vector &bttvGlobalEmoteCodes = emoteManager.bttvGlobalEmoteCodes; + for (const auto &m : bttvGlobalEmoteCodes) { + this->addString(m); + } + + // Global: FFZ Global Emotes + std::vector &ffzGlobalEmoteCodes = emoteManager.ffzGlobalEmoteCodes; + for (const auto &m : ffzGlobalEmoteCodes) { + this->addString(m); + } + + // Channel-specific: BTTV Channel Emotes + std::vector &bttvChannelEmoteCodes = + emoteManager.bttvChannelEmoteCodes[this->channelName.toStdString()]; + for (const auto &m : bttvChannelEmoteCodes) { + this->addString(m); + } + + // Channel-specific: FFZ Channel Emotes + std::vector &ffzChannelEmoteCodes = + emoteManager.ffzChannelEmoteCodes[this->channelName.toStdString()]; + for (const auto &m : ffzChannelEmoteCodes) { + this->addString(m); + } + + // Global: Emojis + const auto &emojiShortCodes = emoteManager.emojiShortCodes; + for (const auto &m : emojiShortCodes) { + this->addString(":" + m + ":"); + } + + // Channel-specific: Usernames + auto c = ChannelManager::getInstance().getTwitchChannel(this->channelName); + auto usernames = c->getUsernamesForCompletions(); + for (const auto &name : usernames) { + assert(!name.displayName.isEmpty()); + this->addString(name.displayName); + this->addString('@' + name.displayName); + + if (!name.localizedName.isEmpty()) { + this->addString(name.localizedName); + this->addString('@' + name.localizedName); + } + } +} + +void CompletionModel::addString(const std::string &str) +{ + // Always add a space at the end of completions + this->emotes.push_back(qS(str) + " "); +} + +void CompletionModel::addString(const QString &str) +{ + // Always add a space at the end of completions + this->emotes.push_back(str + " "); +} +} diff --git a/src/completionmanager.hpp b/src/singletons/helper/completionmodel.hpp similarity index 69% rename from src/completionmanager.hpp rename to src/singletons/helper/completionmodel.hpp index d2f8eb0bf..b9f866d0a 100644 --- a/src/completionmanager.hpp +++ b/src/singletons/helper/completionmodel.hpp @@ -1,59 +1,41 @@ -#pragma once - -#include -#include - -#include -#include - -namespace chatterino { - -class CompletionModel : public QAbstractListModel -{ -public: - CompletionModel(const QString &_channelName); - - virtual int columnCount(const QModelIndex &) const override - { - return 1; - } - - virtual QVariant data(const QModelIndex &index, int) const override - { - // TODO: Implement more safely - return QVariant(this->emotes.at(index.row())); - } - - virtual int rowCount(const QModelIndex &) const override - { - return this->emotes.size(); - } - - void refresh(); - -private: - void addString(const std::string &str); - void addString(const QString &str); - - QVector emotes; - - QString channelName; -}; - -class CompletionManager -{ - CompletionManager() = default; - - std::map models; - -public: - static CompletionManager &getInstance() - { - static CompletionManager instance; - return instance; - } - - CompletionModel *createModel(const std::string &channelName); -}; - -} // namespace chatterino +#pragma once + +#include +#include + +#include +#include + +namespace chatterino { +class CompletionModel : public QAbstractListModel +{ +public: + CompletionModel(const QString &_channelName); + + virtual int columnCount(const QModelIndex &) const override + { + return 1; + } + + virtual QVariant data(const QModelIndex &index, int) const override + { + // TODO: Implement more safely + return QVariant(this->emotes.at(index.row())); + } + + virtual int rowCount(const QModelIndex &) const override + { + return this->emotes.size(); + } + + void refresh(); + +private: + void addString(const std::string &str); + void addString(const QString &str); + + QVector emotes; + + QString channelName; +}; +} diff --git a/src/ircmanager.cpp b/src/singletons/ircmanager.cpp similarity index 92% rename from src/ircmanager.cpp rename to src/singletons/ircmanager.cpp index 4ed684741..49e429280 100644 --- a/src/ircmanager.cpp +++ b/src/singletons/ircmanager.cpp @@ -1,17 +1,18 @@ -#include "ircmanager.hpp" -#include "accountmanager.hpp" +#include "singletons/ircmanager.hpp" #include "asyncexec.hpp" #include "channel.hpp" -#include "channelmanager.hpp" #include "debug/log.hpp" -#include "emotemanager.hpp" #include "messages/messageparseargs.hpp" -#include "settingsmanager.hpp" +#include "resources.hpp" +#include "singletons/accountmanager.hpp" +#include "singletons/channelmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/windowmanager.hpp" #include "twitch/twitchmessagebuilder.hpp" #include "twitch/twitchparsemessage.hpp" #include "twitch/twitchuser.hpp" #include "util/urlfetch.hpp" -#include "windowmanager.hpp" #include #include @@ -27,16 +28,17 @@ using namespace chatterino::messages; namespace chatterino { IrcManager::IrcManager(ChannelManager &_channelManager, Resources &_resources, - WindowManager &_windowManager) + AccountManager &_accountManager) : channelManager(_channelManager) , resources(_resources) - , windowManager(_windowManager) + , accountManager(_accountManager) { this->messageSuffix.append(' '); this->messageSuffix.append(QChar(0x206D)); - AccountManager::getInstance().Twitch.userChanged.connect([this]() { - this->setUser(AccountManager::getInstance().Twitch.getCurrent()); + this->account = accountManager.Twitch.getCurrent(); + accountManager.Twitch.userChanged.connect([this]() { + this->setUser(accountManager.Twitch.getCurrent()); debug::Log("[IrcManager] Reconnecting to Twitch IRC as new user {}", this->account->getUserName()); @@ -66,6 +68,13 @@ IrcManager::IrcManager(ChannelManager &_channelManager, Resources &_resources, &IrcManager::onDisconnected); } +IrcManager &IrcManager::getInstance() +{ + static IrcManager instance(ChannelManager::getInstance(), Resources::getInstance(), + AccountManager::getInstance()); + return instance; +} + void IrcManager::setUser(std::shared_ptr newAccount) { this->account = newAccount; @@ -231,8 +240,7 @@ void IrcManager::privateMessageReceived(Communi::IrcPrivateMessage *message) messages::MessageParseArgs args; - twitch::TwitchMessageBuilder builder(c.get(), this->resources, this->windowManager, message, - args); + twitch::TwitchMessageBuilder builder(c.get(), message, args); c->addMessage(builder.parse()); } @@ -282,8 +290,11 @@ void IrcManager::handleRoomStateMessage(Communi::IrcMessage *message) if (iterator != tags.end()) { auto roomID = iterator.value().toString(); - auto channel = QString(message->toData()).split("#").at(1); - channelManager.getTwitchChannel(channel)->setRoomID(roomID); + auto channel = channelManager.getTwitchChannel(QString(message->toData()).split("#").at(1)); + auto twitchChannel = dynamic_cast(channel.get()); + if (twitchChannel != nullptr) { + twitchChannel->setRoomID(roomID); + } this->resources.loadChannelData(roomID); } @@ -495,7 +506,7 @@ void IrcManager::onConnected() { std::shared_ptr msg(Message::createSystemMessage("connected to chat")); - this->channelManager.doOnAll([msg](std::shared_ptr channel) { + this->channelManager.doOnAll([msg](std::shared_ptr channel) { assert(channel); channel->addMessage(msg); }); @@ -505,7 +516,7 @@ void IrcManager::onDisconnected() { std::shared_ptr msg(Message::createSystemMessage("disconnected from chat")); - this->channelManager.doOnAll([msg](std::shared_ptr channel) { + this->channelManager.doOnAll([msg](std::shared_ptr channel) { assert(channel); channel->addMessage(msg); }); diff --git a/src/ircmanager.hpp b/src/singletons/ircmanager.hpp similarity index 92% rename from src/ircmanager.hpp rename to src/singletons/ircmanager.hpp index e56e052d5..b7ad474b6 100644 --- a/src/ircmanager.hpp +++ b/src/singletons/ircmanager.hpp @@ -20,14 +20,17 @@ namespace chatterino { class ChannelManager; class Resources; -class WindowManager; +class AccountManager; class IrcManager : public QObject { - Q_OBJECT + // Q_OBJECT + + IrcManager(ChannelManager &channelManager, Resources &resources, + AccountManager &accountManager); public: - IrcManager(ChannelManager &channelManager, Resources &resources, WindowManager &windowManager); + static IrcManager &getInstance(); void connect(); void disconnect(); @@ -48,12 +51,13 @@ public: pajlada::Signals::Signal onPrivateMessage; void privateMessageReceived(Communi::IrcPrivateMessage *message); + Communi::IrcConnection *getReadConnection(); + +private: ChannelManager &channelManager; Resources &resources; - WindowManager &windowManager; + AccountManager &accountManager; - Communi::IrcConnection* getReadConnection(); -private: // variables std::shared_ptr account = nullptr; diff --git a/src/settingsmanager.cpp b/src/singletons/settingsmanager.cpp similarity index 99% rename from src/settingsmanager.cpp rename to src/singletons/settingsmanager.cpp index b8a7f683a..bd450ef04 100644 --- a/src/settingsmanager.cpp +++ b/src/singletons/settingsmanager.cpp @@ -1,4 +1,4 @@ -#include "settingsmanager.hpp" +#include "singletons/settingsmanager.hpp" #include "appdatapath.hpp" #include "debug/log.hpp" diff --git a/src/settingsmanager.hpp b/src/singletons/settingsmanager.hpp similarity index 76% rename from src/settingsmanager.hpp rename to src/singletons/settingsmanager.hpp index 29c311429..0f54682bb 100644 --- a/src/settingsmanager.hpp +++ b/src/singletons/settingsmanager.hpp @@ -2,6 +2,7 @@ #include "messages/word.hpp" #include "setting.hpp" +#include "singletons/helper/chatterinosetting.hpp" #include #include @@ -11,68 +12,6 @@ namespace chatterino { static void _registerSetting(std::weak_ptr setting); -template -class ChatterinoSetting : public pajlada::Settings::Setting -{ -public: - ChatterinoSetting(const std::string &_path, const Type &_defaultValue) - : pajlada::Settings::Setting(_path, _defaultValue) - { - _registerSetting(this->data); - } - - void saveRecall(); - - ChatterinoSetting &operator=(const Type &newValue) - { - assert(this->data != nullptr); - - this->setValue(newValue); - - return *this; - } - - template - ChatterinoSetting &operator=(const T2 &newValue) - { - assert(this->data != nullptr); - - this->setValue(newValue); - - return *this; - } - - ChatterinoSetting &operator=(Type &&newValue) noexcept - { - assert(this->data != nullptr); - - this->setValue(std::move(newValue)); - - return *this; - } - - bool operator==(const Type &rhs) const - { - assert(this->data != nullptr); - - return this->getValue() == rhs; - } - - bool operator!=(const Type &rhs) const - { - assert(this->data != nullptr); - - return this->getValue() != rhs; - } - - operator const Type() const - { - assert(this->data != nullptr); - - return this->getValue(); - } -}; - class SettingsManager : public QObject { Q_OBJECT diff --git a/src/colorscheme.cpp b/src/singletons/thememanager.cpp similarity index 78% rename from src/colorscheme.cpp rename to src/singletons/thememanager.cpp index addaf51f1..f71fffbe9 100644 --- a/src/colorscheme.cpp +++ b/src/singletons/thememanager.cpp @@ -1,7 +1,6 @@ #define LOOKUP_COLOR_COUNT 360 -#include "colorscheme.hpp" -#include "windowmanager.hpp" +#include "thememanager.hpp" #include @@ -28,32 +27,30 @@ double getMultiplierByTheme(const std::string &themeName) } // namespace detail -ColorScheme *ColorScheme::instance = nullptr; +ThemeManager &ThemeManager::getInstance() +{ + static ThemeManager instance; + return instance; +} -ColorScheme::ColorScheme(WindowManager &windowManager) +ThemeManager::ThemeManager() : themeName("/appearance/theme/name", "Dark") , themeHue("/appearance/theme/hue", 0.0) { - ColorScheme::instance = this; - this->update(); this->themeName.connectSimple([this](auto) { this->update(); }); this->themeHue.connectSimple([this](auto) { this->update(); }); - - this->updated.connect([&windowManager] { - windowManager.repaintVisibleChatWidgets(); // - }); } -void ColorScheme::update() +void ThemeManager::update() { - this->setColors(this->themeHue, detail::getMultiplierByTheme(this->themeName)); + this->actuallyUpdate(this->themeHue, detail::getMultiplierByTheme(this->themeName)); } // hue: theme color (0 - 1) // multiplier: 1 = white, 0.8 = light, -0.8 dark, -1 black -void ColorScheme::setColors(double hue, double multiplier) +void ThemeManager::actuallyUpdate(double hue, double multiplier) { lightTheme = multiplier > 0; @@ -126,7 +123,7 @@ void ColorScheme::setColors(double hue, double multiplier) this->updated(); } -QColor ColorScheme::blendColors(const QColor &color1, const QColor &color2, qreal ratio) +QColor ThemeManager::blendColors(const QColor &color1, const QColor &color2, qreal ratio) { int r = color1.red() * (1 - ratio) + color2.red() * ratio; int g = color1.green() * (1 - ratio) + color2.green() * ratio; @@ -135,7 +132,7 @@ QColor ColorScheme::blendColors(const QColor &color1, const QColor &color2, qrea return QColor(r, g, b, 255); } -void ColorScheme::normalizeColor(QColor &color) +void ThemeManager::normalizeColor(QColor &color) { if (this->lightTheme) { if (color.lightnessF() > 0.5f) { @@ -143,10 +140,10 @@ void ColorScheme::normalizeColor(QColor &color) } if (color.lightnessF() > 0.4f && color.hueF() > 0.1 && color.hueF() < 0.33333) { - color.setHslF( - color.hueF(), color.saturationF(), - color.lightnessF() - sin((color.hueF() - 0.1) / (0.3333 - 0.1) * 3.14159) * - color.saturationF() * 0.2); + color.setHslF(color.hueF(), color.saturationF(), + color.lightnessF() - + sin((color.hueF() - 0.1) / (0.3333 - 0.1) * 3.14159) * + color.saturationF() * 0.2); } } else { if (color.lightnessF() < 0.5f) { @@ -154,10 +151,10 @@ void ColorScheme::normalizeColor(QColor &color) } if (color.lightnessF() < 0.6f && color.hueF() > 0.54444 && color.hueF() < 0.83333) { - color.setHslF( - color.hueF(), color.saturationF(), - color.lightnessF() + sin((color.hueF() - 0.54444) / (0.8333 - 0.54444) * 3.14159) * - color.saturationF() * 0.4); + color.setHslF(color.hueF(), color.saturationF(), + color.lightnessF() + + sin((color.hueF() - 0.54444) / (0.8333 - 0.54444) * 3.14159) * + color.saturationF() * 0.4); } } } diff --git a/src/colorscheme.hpp b/src/singletons/thememanager.hpp similarity index 90% rename from src/colorscheme.hpp rename to src/singletons/thememanager.hpp index a8de6134a..1d969e5c1 100644 --- a/src/colorscheme.hpp +++ b/src/singletons/thememanager.hpp @@ -9,18 +9,18 @@ namespace chatterino { class WindowManager; -class ColorScheme +class ThemeManager { + ThemeManager(); + public: - explicit ColorScheme(WindowManager &windowManager); + static ThemeManager &getInstance(); inline bool isLightTheme() const { return this->lightTheme; } - static ColorScheme *instance; - QString InputStyleSheet; QColor SystemMessageColor; @@ -90,7 +90,7 @@ private: pajlada::Settings::Setting themeName; pajlada::Settings::Setting themeHue; - void setColors(double hue, double multiplier); + void actuallyUpdate(double hue, double multiplier); QColor blendColors(const QColor &color1, const QColor &color2, qreal ratio); double middleLookupTable[360] = {}; @@ -100,6 +100,10 @@ private: double toValue); bool lightTheme = false; + + pajlada::Signals::NoArgSignal repaintVisibleChatWidgets; + + friend class WindowManager; }; } // namespace chatterino diff --git a/src/windowmanager.cpp b/src/singletons/windowmanager.cpp similarity index 74% rename from src/windowmanager.cpp rename to src/singletons/windowmanager.cpp index f39dd748c..e8cca5014 100644 --- a/src/windowmanager.cpp +++ b/src/singletons/windowmanager.cpp @@ -1,27 +1,27 @@ #include "windowmanager.hpp" #include "appdatapath.hpp" -#include "channelmanager.hpp" -#include "colorscheme.hpp" -#include "settingsmanager.hpp" +#include "singletons/thememanager.hpp" #include #include #include namespace chatterino { -WindowManager *WindowManager::instance = nullptr; - -WindowManager::WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme) - : channelManager(_channelManager) - , colorScheme(_colorScheme) +WindowManager &WindowManager::getInstance() { - WindowManager::instance = this; + static WindowManager instance(ThemeManager::getInstance()); + return instance; +} + +WindowManager::WindowManager(ThemeManager &_themeManager) + : themeManager(_themeManager) +{ + _themeManager.repaintVisibleChatWidgets.connect([this] { this->repaintVisibleChatWidgets(); }); } void WindowManager::initMainWindow() { - this->selectedWindow = this->mainWindow = - new widgets::Window("main", this->channelManager, this->colorScheme, true); + this->selectedWindow = this->mainWindow = new widgets::Window("main", this->themeManager, true); } static const std::string &getSettingsPath() @@ -67,7 +67,7 @@ widgets::Window &WindowManager::getSelectedWindow() widgets::Window &WindowManager::createWindow() { - auto *window = new widgets::Window("external", this->channelManager, this->colorScheme, false); + auto *window = new widgets::Window("external", this->themeManager, false); window->getNotebook().addNewPage(); this->windows.push_back(window); diff --git a/src/windowmanager.hpp b/src/singletons/windowmanager.hpp similarity index 75% rename from src/windowmanager.hpp rename to src/singletons/windowmanager.hpp index befa39f72..b1d221a89 100644 --- a/src/windowmanager.hpp +++ b/src/singletons/windowmanager.hpp @@ -4,19 +4,14 @@ namespace chatterino { -class ChannelManager; -class ColorScheme; -class CompletionManager; +class ThemeManager; class WindowManager { + explicit WindowManager(ThemeManager &_themeManager); + public: - explicit WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme); - - static WindowManager *instance; - - ChannelManager &channelManager; - ColorScheme &colorScheme; + static WindowManager &getInstance(); void layoutVisibleChatWidgets(Channel *channel = nullptr); void repaintVisibleChatWidgets(Channel *channel = nullptr); @@ -37,6 +32,8 @@ public: boost::signals2::signal layout; private: + ThemeManager &themeManager; + std::vector windows; widgets::Window *mainWindow = nullptr; diff --git a/src/accountmanager.cpp b/src/twitch/twitchaccountmanager.cpp similarity index 89% rename from src/accountmanager.cpp rename to src/twitch/twitchaccountmanager.cpp index 7eff95fc6..70ad8d0a7 100644 --- a/src/accountmanager.cpp +++ b/src/twitch/twitchaccountmanager.cpp @@ -1,222 +1,190 @@ -#include "accountmanager.hpp" -#include "common.hpp" -#include "const.hpp" -#include "debug/log.hpp" - -namespace chatterino { - -namespace { - -inline QString getEnvString(const char *target) -{ - char *val = std::getenv(target); - if (val == nullptr) { - return QString(); - } - - return QString(val); -} - -} // namespace - -TwitchAccountManager::TwitchAccountManager() -{ - this->anonymousUser.reset(new twitch::TwitchUser(twitch::ANONYMOUS_USERNAME, "", "")); - - this->currentUsername.connect([this](const auto &newValue, auto) { - QString newUsername(QString::fromStdString(newValue)); - auto user = this->findUserByUsername(newUsername); - if (user) { - debug::Log("[AccountManager:currentUsernameChanged] User successfully updated to {}", - newUsername); - this->currentUser = user; - } else { - debug::Log( - "[AccountManager:currentUsernameChanged] User successfully updated to anonymous"); - this->currentUser = this->anonymousUser; - } - - this->userChanged.invoke(); - }); -} - -std::shared_ptr TwitchAccountManager::getCurrent() -{ - if (!this->currentUser) { - return this->anonymousUser; - } - - return this->currentUser; -} - -std::vector TwitchAccountManager::getUsernames() const -{ - std::vector userNames; - - std::lock_guard lock(this->mutex); - - for (const auto &user : this->users) { - userNames.push_back(user->getUserName()); - } - - return userNames; -} - -std::shared_ptr TwitchAccountManager::findUserByUsername( - const QString &username) const -{ - std::lock_guard lock(this->mutex); - - for (const auto &user : this->users) { - if (username.compare(user->getUserName(), Qt::CaseInsensitive) == 0) { - return user; - } - } - - return nullptr; -} - -bool TwitchAccountManager::userExists(const QString &username) const -{ - return this->findUserByUsername(username) != nullptr; -} - -void TwitchAccountManager::reloadUsers() -{ - auto keys = pajlada::Settings::SettingManager::getObjectKeys("/accounts"); - - UserData userData; - - bool listUpdated = false; - - for (const auto &uid : keys) { - if (uid == "current") { - continue; - } - - std::string username = - pajlada::Settings::Setting::get("/accounts/" + uid + "/username"); - std::string userID = - pajlada::Settings::Setting::get("/accounts/" + uid + "/userID"); - std::string clientID = - pajlada::Settings::Setting::get("/accounts/" + uid + "/clientID"); - std::string oauthToken = - pajlada::Settings::Setting::get("/accounts/" + uid + "/oauthToken"); - - if (username.empty() || userID.empty() || clientID.empty() || oauthToken.empty()) { - continue; - } - - userData.username = qS(username); - userData.userID = qS(userID); - userData.clientID = qS(clientID); - userData.oauthToken = qS(oauthToken); - - switch (this->addUser(userData)) { - case AddUserResponse::UserAlreadyExists: { - debug::Log("User {} already exists", userData.username); - // Do nothing - } break; - case AddUserResponse::UserValuesUpdated: { - debug::Log("User {} already exists, and values updated!", userData.username); - if (userData.username == this->getCurrent()->getNickName()) { - debug::Log("It was the current user, so we need to reconnect stuff!"); - this->userChanged.invoke(); - } - } break; - case AddUserResponse::UserAdded: { - debug::Log("Added user {}", userData.username); - listUpdated = true; - } break; - } - } - - if (listUpdated) { - this->userListUpdated.invoke(); - } -} - -bool TwitchAccountManager::removeUser(const QString &username) -{ - if (!this->userExists(username)) { - return false; - } - - this->mutex.lock(); - this->users.erase(std::remove_if(this->users.begin(), this->users.end(), [username](auto user) { - if (user->getNickName() == username) { - std::string userID(user->getUserId().toStdString()); - assert(!userID.empty()); - pajlada::Settings::SettingManager::removeSetting("/accounts/uid" + userID); - return true; - } - return false; - })); - this->mutex.unlock(); - - if (username == qS(this->currentUsername.getValue())) { - // The user that was removed is the current user, log into the anonymous user - this->currentUsername = ""; - } - - this->userListUpdated.invoke(); - - return true; -} - -TwitchAccountManager::AddUserResponse TwitchAccountManager::addUser( - const TwitchAccountManager::UserData &userData) -{ - auto previousUser = this->findUserByUsername(userData.username); - if (previousUser) { - bool userUpdated = false; - - if (previousUser->setOAuthClient(userData.clientID)) { - userUpdated = true; - } - - if (previousUser->setOAuthToken(userData.oauthToken)) { - userUpdated = true; - } - - if (userUpdated) { - return AddUserResponse::UserValuesUpdated; - } else { - return AddUserResponse::UserAlreadyExists; - } - } - - auto newUser = std::make_shared(userData.username, userData.oauthToken, - userData.clientID); - - // Set users User ID without the uid prefix - newUser->setUserId(userData.userID); - - std::lock_guard lock(this->mutex); - - this->users.push_back(newUser); - - return AddUserResponse::UserAdded; -} - -AccountManager::AccountManager() -{ -} - -void AccountManager::load() -{ - this->Twitch.reloadUsers(); - - auto currentUser = this->Twitch.findUserByUsername( - QString::fromStdString(this->Twitch.currentUsername.getValue())); - - if (currentUser) { - this->Twitch.currentUser = currentUser; - } else { - this->Twitch.currentUser = this->Twitch.anonymousUser; - } - - this->Twitch.userChanged.invoke(); -} - -} // namespace chatterino +#include "twitchaccountmanager.hpp" + +#include "common.hpp" +#include "const.hpp" +#include "debug/log.hpp" + +namespace chatterino { +namespace twitch { + +TwitchAccountManager::TwitchAccountManager() +{ + this->anonymousUser.reset(new twitch::TwitchUser(twitch::ANONYMOUS_USERNAME, "", "")); + + this->currentUsername.connect([this](const auto &newValue, auto) { + QString newUsername(QString::fromStdString(newValue)); + auto user = this->findUserByUsername(newUsername); + if (user) { + debug::Log("[AccountManager:currentUsernameChanged] User successfully updated to {}", + newUsername); + this->currentUser = user; + } else { + debug::Log( + "[AccountManager:currentUsernameChanged] User successfully updated to anonymous"); + this->currentUser = this->anonymousUser; + } + + this->userChanged.invoke(); + }); +} + +std::shared_ptr TwitchAccountManager::getCurrent() +{ + if (!this->currentUser) { + return this->anonymousUser; + } + + return this->currentUser; +} + +std::vector TwitchAccountManager::getUsernames() const +{ + std::vector userNames; + + std::lock_guard lock(this->mutex); + + for (const auto &user : this->users) { + userNames.push_back(user->getUserName()); + } + + return userNames; +} + +std::shared_ptr TwitchAccountManager::findUserByUsername( + const QString &username) const +{ + std::lock_guard lock(this->mutex); + + for (const auto &user : this->users) { + if (username.compare(user->getUserName(), Qt::CaseInsensitive) == 0) { + return user; + } + } + + return nullptr; +} + +bool TwitchAccountManager::userExists(const QString &username) const +{ + return this->findUserByUsername(username) != nullptr; +} + +void TwitchAccountManager::reloadUsers() +{ + auto keys = pajlada::Settings::SettingManager::getObjectKeys("/accounts"); + + UserData userData; + + bool listUpdated = false; + + for (const auto &uid : keys) { + if (uid == "current") { + continue; + } + + std::string username = + pajlada::Settings::Setting::get("/accounts/" + uid + "/username"); + std::string userID = + pajlada::Settings::Setting::get("/accounts/" + uid + "/userID"); + std::string clientID = + pajlada::Settings::Setting::get("/accounts/" + uid + "/clientID"); + std::string oauthToken = + pajlada::Settings::Setting::get("/accounts/" + uid + "/oauthToken"); + + if (username.empty() || userID.empty() || clientID.empty() || oauthToken.empty()) { + continue; + } + + userData.username = qS(username); + userData.userID = qS(userID); + userData.clientID = qS(clientID); + userData.oauthToken = qS(oauthToken); + + switch (this->addUser(userData)) { + case AddUserResponse::UserAlreadyExists: { + debug::Log("User {} already exists", userData.username); + // Do nothing + } break; + case AddUserResponse::UserValuesUpdated: { + debug::Log("User {} already exists, and values updated!", userData.username); + if (userData.username == this->getCurrent()->getNickName()) { + debug::Log("It was the current user, so we need to reconnect stuff!"); + this->userChanged.invoke(); + } + } break; + case AddUserResponse::UserAdded: { + debug::Log("Added user {}", userData.username); + listUpdated = true; + } break; + } + } + + if (listUpdated) { + this->userListUpdated.invoke(); + } +} + +bool TwitchAccountManager::removeUser(const QString &username) +{ + if (!this->userExists(username)) { + return false; + } + + this->mutex.lock(); + this->users.erase(std::remove_if(this->users.begin(), this->users.end(), [username](auto user) { + if (user->getNickName() == username) { + std::string userID(user->getUserId().toStdString()); + assert(!userID.empty()); + pajlada::Settings::SettingManager::removeSetting("/accounts/uid" + userID); + return true; + } + return false; + })); + this->mutex.unlock(); + + if (username == qS(this->currentUsername.getValue())) { + // The user that was removed is the current user, log into the anonymous user + this->currentUsername = ""; + } + + this->userListUpdated.invoke(); + + return true; +} + +TwitchAccountManager::AddUserResponse TwitchAccountManager::addUser( + const TwitchAccountManager::UserData &userData) +{ + auto previousUser = this->findUserByUsername(userData.username); + if (previousUser) { + bool userUpdated = false; + + if (previousUser->setOAuthClient(userData.clientID)) { + userUpdated = true; + } + + if (previousUser->setOAuthToken(userData.oauthToken)) { + userUpdated = true; + } + + if (userUpdated) { + return AddUserResponse::UserValuesUpdated; + } else { + return AddUserResponse::UserAlreadyExists; + } + } + + auto newUser = std::make_shared(userData.username, userData.oauthToken, + userData.clientID); + + // Set users User ID without the uid prefix + newUser->setUserId(userData.userID); + + std::lock_guard lock(this->mutex); + + this->users.push_back(newUser); + + return AddUserResponse::UserAdded; +} +} +} diff --git a/src/accountmanager.hpp b/src/twitch/twitchaccountmanager.hpp similarity index 81% rename from src/accountmanager.hpp rename to src/twitch/twitchaccountmanager.hpp index 14640bf64..3ef786599 100644 --- a/src/accountmanager.hpp +++ b/src/twitch/twitchaccountmanager.hpp @@ -1,76 +1,65 @@ -#pragma once - -#include "twitch/twitchuser.hpp" - -#include - -#include -#include - -namespace chatterino { - -class AccountManager; - -class TwitchAccountManager -{ -public: - TwitchAccountManager(); - - struct UserData { - QString username; - QString userID; - QString clientID; - QString oauthToken; - }; - - // Returns the current twitchUsers, or the anonymous user if we're not currently logged in - std::shared_ptr getCurrent(); - - std::vector getUsernames() const; - - std::shared_ptr findUserByUsername(const QString &username) const; - bool userExists(const QString &username) const; - - void reloadUsers(); - - bool removeUser(const QString &username); - - pajlada::Settings::Setting currentUsername = {"/accounts/current", ""}; - pajlada::Signals::NoArgSignal userChanged; - pajlada::Signals::NoArgSignal userListUpdated; - -private: - enum class AddUserResponse { - UserAlreadyExists, - UserValuesUpdated, - UserAdded, - }; - AddUserResponse addUser(const UserData &data); - - std::shared_ptr currentUser; - - std::shared_ptr anonymousUser; - std::vector> users; - mutable std::mutex mutex; - - friend class AccountManager; -}; - -class AccountManager -{ -public: - static AccountManager &getInstance() - { - static AccountManager instance; - return instance; - } - - void load(); - - TwitchAccountManager Twitch; - -private: - AccountManager(); -}; - -} // namespace chatterino +#pragma once + +#include "twitch/twitchuser.hpp" + +#include + +#include +#include + +// +// Warning: This class is not supposed to be created directly. +// Get yourself an instance from our friends over at AccountManager.hpp +// + +namespace chatterino { +class AccountManager; + +namespace twitch { + +class TwitchAccountManager +{ + TwitchAccountManager(); + +public: + struct UserData { + QString username; + QString userID; + QString clientID; + QString oauthToken; + }; + + // Returns the current twitchUsers, or the anonymous user if we're not currently logged in + std::shared_ptr getCurrent(); + + std::vector getUsernames() const; + + std::shared_ptr findUserByUsername(const QString &username) const; + bool userExists(const QString &username) const; + + void reloadUsers(); + + bool removeUser(const QString &username); + + pajlada::Settings::Setting currentUsername = {"/accounts/current", ""}; + pajlada::Signals::NoArgSignal userChanged; + pajlada::Signals::NoArgSignal userListUpdated; + +private: + enum class AddUserResponse { + UserAlreadyExists, + UserValuesUpdated, + UserAdded, + }; + AddUserResponse addUser(const UserData &data); + + std::shared_ptr currentUser; + + std::shared_ptr anonymousUser; + std::vector> users; + mutable std::mutex mutex; + + friend class chatterino::AccountManager; +}; +} +} diff --git a/src/twitch/twitchchannel.cpp b/src/twitch/twitchchannel.cpp index ddf8b8cba..ca4b299fc 100644 --- a/src/twitch/twitchchannel.cpp +++ b/src/twitch/twitchchannel.cpp @@ -1,6 +1,6 @@ #include "twitchchannel.hpp" #include "debug/log.hpp" -#include "emotemanager.hpp" +#include "singletons/emotemanager.hpp" #include "util/urlfetch.hpp" #include @@ -9,24 +9,20 @@ namespace chatterino { namespace twitch { -TwitchChannel::TwitchChannel(IrcManager &ircManager, const QString &channelName, bool _isSpecial) +TwitchChannel::TwitchChannel(const QString &channelName) : Channel(channelName) - , ircManager(ircManager) , bttvChannelEmotes(new EmoteMap) , ffzChannelEmotes(new EmoteMap) , subscriptionURL("https://www.twitch.tv/subs/" + name) , channelURL("https://twitch.tv/" + name) , popoutPlayerURL("https://player.twitch.tv/?channel=" + name) , isLive(false) - , isSpecial(_isSpecial) { debug::Log("[TwitchChannel:{}] Opened", this->name); this->dontAddMessages = true; - if (!this->isSpecial) { - this->reloadChannelEmotes(); - } + this->reloadChannelEmotes(); this->liveStatusTimer = new QTimer; QObject::connect(this->liveStatusTimer, &QTimer::timeout, [this]() { @@ -56,7 +52,7 @@ bool TwitchChannel::isEmpty() const bool TwitchChannel::canSendMessage() const { - return !this->isEmpty() && !this->isSpecial; + return !this->isEmpty(); } void TwitchChannel::setRoomID(const QString &_roomID) @@ -85,7 +81,7 @@ void TwitchChannel::sendMessage(const QString &message) // Do last message processing QString parsedMessage = emoteManager.replaceShortCodes(message); - this->ircManager.sendMessage(this->name, parsedMessage); + IrcManager::getInstance().sendMessage(this->name, parsedMessage); } void TwitchChannel::setLive(bool newLiveStatus) @@ -159,7 +155,7 @@ void TwitchChannel::fetchRecentMessages() { static QString genericURL = "https://tmi.twitch.tv/api/rooms/%1/recent_messages?client_id=" + getDefaultClientID(); - static auto readConnection = this->ircManager.getReadConnection(); + static auto readConnection = IrcManager::getInstance().getReadConnection(); util::twitch::get(genericURL.arg(roomID), QThread::currentThread(), [=](QJsonObject obj) { this->dontAddMessages = false; @@ -169,7 +165,7 @@ void TwitchChannel::fetchRecentMessages() QByteArray content = msgArray[i].toString().toUtf8(); auto msg = Communi::IrcMessage::fromData(content, readConnection); auto privMsg = static_cast(msg); - this->ircManager.privateMessageReceived(privMsg); + IrcManager::getInstance().privateMessageReceived(privMsg); } }); } diff --git a/src/twitch/twitchchannel.hpp b/src/twitch/twitchchannel.hpp index de450c2fb..f317fdb0e 100644 --- a/src/twitch/twitchchannel.hpp +++ b/src/twitch/twitchchannel.hpp @@ -2,7 +2,8 @@ #include "channel.hpp" #include "concurrentmap.hpp" -#include "ircmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/ircmanager.hpp" namespace chatterino { namespace twitch { @@ -12,8 +13,7 @@ class TwitchChannel : public Channel QTimer *liveStatusTimer; public: - explicit TwitchChannel(IrcManager &ircManager, const QString &channelName, - bool _isSpecial = false); + explicit TwitchChannel(const QString &channelName); ~TwitchChannel(); void reloadChannelEmotes(); @@ -22,8 +22,8 @@ public: bool canSendMessage() const override; void sendMessage(const QString &message) override; - const std::shared_ptr bttvChannelEmotes; - const std::shared_ptr ffzChannelEmotes; + const std::shared_ptr bttvChannelEmotes; + const std::shared_ptr ffzChannelEmotes; const QString subscriptionURL; const QString channelURL; @@ -47,10 +47,6 @@ private: void refreshLiveStatus(); void fetchRecentMessages(); - - IrcManager &ircManager; - - bool isSpecial; }; } // namespace twitch diff --git a/src/twitch/twitchmessagebuilder.cpp b/src/twitch/twitchmessagebuilder.cpp index ab89cc921..44481f905 100644 --- a/src/twitch/twitchmessagebuilder.cpp +++ b/src/twitch/twitchmessagebuilder.cpp @@ -1,11 +1,12 @@ -#include "twitch/twitchmessagebuilder.hpp" -#include "colorscheme.hpp" +#include "twitchmessagebuilder.hpp" #include "debug/log.hpp" -#include "emotemanager.hpp" -#include "ircmanager.hpp" #include "resources.hpp" -#include "settingsmanager.hpp" -#include "windowmanager.hpp" +#include "singletons/emotemanager.hpp" +#include "singletons/ircmanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/thememanager.hpp" +#include "singletons/windowmanager.hpp" +#include "twitch/twitchchannel.hpp" #include #include @@ -16,19 +17,15 @@ using namespace chatterino::messages; namespace chatterino { namespace twitch { -TwitchMessageBuilder::TwitchMessageBuilder(TwitchChannel *_channel, Resources &_resources, - WindowManager &_windowManager, +TwitchMessageBuilder::TwitchMessageBuilder(Channel *_channel, const Communi::IrcPrivateMessage *_ircMessage, const messages::MessageParseArgs &_args) : channel(_channel) - , twitchChannel(_channel) - , resources(_resources) - , windowManager(_windowManager) - , colorScheme(this->windowManager.colorScheme) + , twitchChannel(dynamic_cast(_channel)) , ircMessage(_ircMessage) , args(_args) , tags(this->ircMessage->tags()) - , usernameColor(this->colorScheme.SystemMessageColor) + , usernameColor(ThemeManager::getInstance().SystemMessageColor) { } @@ -42,7 +39,7 @@ SharedMessage TwitchMessageBuilder::parse() this->parseUsername(); // this->message->setCollapsedDefault(true); - // this->appendWord(Word(this->resources.badgeCollapsed, Word::Collapsed, QString(), + // this->appendWord(Word(Resources::getInstance().badgeCollapsed, Word::Collapsed, QString(), // QString())); // The timestamp is always appended to the builder @@ -268,6 +265,10 @@ void TwitchMessageBuilder::parseMessageID() void TwitchMessageBuilder::parseRoomID() { + if (this->twitchChannel == nullptr) { + return; + } + auto iterator = this->tags.find("room-id"); if (iterator != std::end(this->tags)) { @@ -470,7 +471,7 @@ void TwitchMessageBuilder::parseHighlights() } if (doAlert) { - QApplication::alert(windowManager.getMainWindow().window(), 2500); + QApplication::alert(WindowManager::getInstance().getMainWindow().window(), 2500); } } } @@ -481,9 +482,9 @@ void TwitchMessageBuilder::appendModerationButtons() static QString buttonBanTooltip("Ban user"); static QString buttonTimeoutTooltip("Timeout user"); - this->appendWord(Word(this->resources.buttonBan, Word::ButtonBan, QString(), buttonBanTooltip, - Link(Link::UserBan, ircMessage->account()))); - this->appendWord(Word(this->resources.buttonTimeout, Word::ButtonTimeout, QString(), + this->appendWord(Word(Resources::getInstance().buttonBan, Word::ButtonBan, QString(), + buttonBanTooltip, Link(Link::UserBan, ircMessage->account()))); + this->appendWord(Word(Resources::getInstance().buttonTimeout, Word::ButtonTimeout, QString(), buttonTimeoutTooltip, Link(Link::UserTimeout, ircMessage->account()))); } @@ -535,13 +536,15 @@ bool TwitchMessageBuilder::tryAppendEmote(QString &emoteString) if (emoteManager.bttvGlobalEmotes.tryGet(emoteString, emoteData)) { // BTTV Global Emote return this->appendEmote(emoteData); - } else if (this->twitchChannel->bttvChannelEmotes->tryGet(emoteString, emoteData)) { + } else if (this->twitchChannel != nullptr && + this->twitchChannel->bttvChannelEmotes->tryGet(emoteString, emoteData)) { // BTTV Channel Emote return this->appendEmote(emoteData); } else if (emoteManager.ffzGlobalEmotes.tryGet(emoteString, emoteData)) { // FFZ Global Emote return this->appendEmote(emoteData); - } else if (this->twitchChannel->ffzChannelEmotes->tryGet(emoteString, emoteData)) { + } else if (this->twitchChannel != nullptr && + this->twitchChannel->ffzChannelEmotes->tryGet(emoteString, emoteData)) { // FFZ Channel Emote return this->appendEmote(emoteData); } else if (emoteManager.getChatterinoEmotes().tryGet(emoteString, emoteData)) { @@ -564,7 +567,7 @@ bool TwitchMessageBuilder::appendEmote(EmoteData &emoteData) void TwitchMessageBuilder::parseTwitchBadges() { - const auto &channelResources = this->resources.channels[this->roomID]; + const auto &channelResources = Resources::getInstance().channels[this->roomID]; auto iterator = this->tags.find("badges"); @@ -581,7 +584,7 @@ void TwitchMessageBuilder::parseTwitchBadges() } if (badge.startsWith("bits/")) { - if (!this->resources.dynamicBadgesLoaded) { + if (!Resources::getInstance().dynamicBadgesLoaded) { // Do nothing continue; } @@ -590,7 +593,7 @@ void TwitchMessageBuilder::parseTwitchBadges() std::string versionKey = cheerAmountQS.toStdString(); try { - auto &badgeSet = this->resources.badgeSets.at("bits"); + auto &badgeSet = Resources::getInstance().badgeSets.at("bits"); try { auto &badgeVersion = badgeSet.versions.at(versionKey); @@ -606,34 +609,35 @@ void TwitchMessageBuilder::parseTwitchBadges() debug::Log("No badge set with key bits. Exception: {}", e.what()); } } else if (badge == "staff/1") { - appendWord(Word(this->resources.badgeStaff, Word::BadgeGlobalAuthority, QString(), - QString("Twitch Staff"))); + appendWord(Word(Resources::getInstance().badgeStaff, Word::BadgeGlobalAuthority, + QString(), QString("Twitch Staff"))); } else if (badge == "admin/1") { - appendWord(Word(this->resources.badgeAdmin, Word::BadgeGlobalAuthority, QString(), - QString("Twitch Admin"))); + appendWord(Word(Resources::getInstance().badgeAdmin, Word::BadgeGlobalAuthority, + QString(), QString("Twitch Admin"))); } else if (badge == "global_mod/1") { - appendWord(Word(this->resources.badgeGlobalModerator, Word::BadgeGlobalAuthority, - QString(), QString("Global Moderator"))); + appendWord(Word(Resources::getInstance().badgeGlobalModerator, + Word::BadgeGlobalAuthority, QString(), QString("Global Moderator"))); } else if (badge == "moderator/1") { // TODO: Implement custom FFZ moderator badge - appendWord(Word(this->resources.badgeModerator, Word::BadgeChannelAuthority, QString(), + appendWord(Word(Resources::getInstance().badgeModerator, Word::BadgeChannelAuthority, + QString(), QString("Channel Moderator"))); // custom badge } else if (badge == "turbo/1") { - appendWord(Word(this->resources.badgeTurbo, Word::BadgeVanity, QString(), + appendWord(Word(Resources::getInstance().badgeTurbo, Word::BadgeVanity, QString(), QString("Turbo Subscriber"))); } else if (badge == "broadcaster/1") { - appendWord(Word(this->resources.badgeBroadcaster, Word::BadgeChannelAuthority, + appendWord(Word(Resources::getInstance().badgeBroadcaster, Word::BadgeChannelAuthority, QString(), QString("Channel Broadcaster"))); } else if (badge == "premium/1") { - appendWord(Word(this->resources.badgePremium, Word::BadgeVanity, QString(), + appendWord(Word(Resources::getInstance().badgePremium, Word::BadgeVanity, QString(), QString("Twitch Prime"))); } else if (badge.startsWith("partner/")) { int index = badge.midRef(8).toInt(); switch (index) { case 1: { - appendWord(Word(this->resources.badgeVerified, Word::BadgeVanity, QString(), - "Twitch Verified")); + appendWord(Word(Resources::getInstance().badgeVerified, Word::BadgeVanity, + QString(), "Twitch Verified")); } break; default: { printf("[TwitchMessageBuilder] Unhandled partner badge index: %d\n", index); @@ -648,8 +652,9 @@ void TwitchMessageBuilder::parseTwitchBadges() auto badgeSetIt = channelResources.badgeSets.find("subscriber"); if (badgeSetIt == channelResources.badgeSets.end()) { // Fall back to default badge - appendWord(Word(this->resources.badgeSubscriber, Word::Flags::BadgeSubscription, - QString(), QString("Twitch Subscriber"))); + appendWord(Word(Resources::getInstance().badgeSubscriber, + Word::Flags::BadgeSubscription, QString(), + QString("Twitch Subscriber"))); continue; } @@ -661,8 +666,9 @@ void TwitchMessageBuilder::parseTwitchBadges() if (badgeVersionIt == badgeSet.versions.end()) { // Fall back to default badge - appendWord(Word(this->resources.badgeSubscriber, Word::Flags::BadgeSubscription, - QString(), QString("Twitch Subscriber"))); + appendWord(Word(Resources::getInstance().badgeSubscriber, + Word::Flags::BadgeSubscription, QString(), + QString("Twitch Subscriber"))); continue; } @@ -671,7 +677,7 @@ void TwitchMessageBuilder::parseTwitchBadges() appendWord(Word(badgeVersion.badgeImage1x, Word::Flags::BadgeSubscription, QString(), QString("Twitch " + QString::fromStdString(badgeVersion.title)))); } else { - if (!this->resources.dynamicBadgesLoaded) { + if (!Resources::getInstance().dynamicBadgesLoaded) { // Do nothing continue; } @@ -689,7 +695,7 @@ void TwitchMessageBuilder::parseTwitchBadges() std::string versionKey = parts[1].toStdString(); try { - auto &badgeSet = this->resources.badgeSets.at(badgeSetKey); + auto &badgeSet = Resources::getInstance().badgeSets.at(badgeSetKey); try { auto &badgeVersion = badgeSet.versions.at(versionKey); @@ -711,7 +717,7 @@ void TwitchMessageBuilder::parseTwitchBadges() void TwitchMessageBuilder::parseChatterinoBadges() { - auto &badges = this->resources.chatterinoBadges; + auto &badges = Resources::getInstance().chatterinoBadges; auto it = badges.find(this->userName.toStdString()); if (it == badges.end()) { diff --git a/src/twitch/twitchmessagebuilder.hpp b/src/twitch/twitchmessagebuilder.hpp index 3a04c3ac1..69711803a 100644 --- a/src/twitch/twitchmessagebuilder.hpp +++ b/src/twitch/twitchmessagebuilder.hpp @@ -2,8 +2,9 @@ #include "messages/messagebuilder.hpp" #include "messages/messageparseargs.hpp" -#include "resources.hpp" -#include "twitch/twitchchannel.hpp" +#include "singletons/emotemanager.hpp" + +#include #include #include @@ -12,9 +13,10 @@ namespace chatterino { class WindowManager; class Channel; -class ColorScheme; +class ThemeManager; namespace twitch { +class TwitchChannel; class TwitchMessageBuilder : public messages::MessageBuilder { @@ -27,16 +29,11 @@ public: TwitchMessageBuilder() = delete; - explicit TwitchMessageBuilder(TwitchChannel *_channel, Resources &_resources, - WindowManager &_windowManager, - const Communi::IrcPrivateMessage *_ircMessage, + explicit TwitchMessageBuilder(Channel *_channel, const Communi::IrcPrivateMessage *_ircMessage, const messages::MessageParseArgs &_args); Channel *channel; TwitchChannel *twitchChannel; - Resources &resources; - WindowManager &windowManager; - ColorScheme &colorScheme; const Communi::IrcPrivateMessage *ircMessage; messages::MessageParseArgs args; const QVariantMap tags; diff --git a/src/twitch/twitchparsemessage.cpp b/src/twitch/twitchparsemessage.cpp index 8c3bd82b1..f784f824a 100644 --- a/src/twitch/twitchparsemessage.cpp +++ b/src/twitch/twitchparsemessage.cpp @@ -1,8 +1,8 @@ //#include "twitchparsemessage.hpp" //#include "colorscheme.hpp" //#include "emojis.hpp" -//#include "emotemanager.hpp" -//#include "ircmanager.hpp" +//#include "singletons/emotemanager.hpp" +//#include "singletons/ircmanager.hpp" //#include "resources.hpp" //#include "twitch/twitchmessagebuilder.hpp" // diff --git a/src/util/urlfetch.hpp b/src/util/urlfetch.hpp index 3240ca13e..972f175e9 100644 --- a/src/util/urlfetch.hpp +++ b/src/util/urlfetch.hpp @@ -1,6 +1,6 @@ #pragma once -#include "accountmanager.hpp" +#include "singletons/accountmanager.hpp" #include "credentials.hpp" #include "debug/log.hpp" #include "util/networkmanager.hpp" diff --git a/src/widgets/accountpopup.cpp b/src/widgets/accountpopup.cpp index a770f8fe0..5e7060011 100644 --- a/src/widgets/accountpopup.cpp +++ b/src/widgets/accountpopup.cpp @@ -1,8 +1,8 @@ #include "widgets/accountpopup.hpp" -#include "accountmanager.hpp" +#include "singletons/accountmanager.hpp" #include "channel.hpp" #include "credentials.hpp" -#include "settingsmanager.hpp" +#include "singletons/settingsmanager.hpp" #include "ui_accountpopupform.h" #include "util/urlfetch.hpp" diff --git a/src/widgets/accountswitchwidget.cpp b/src/widgets/accountswitchwidget.cpp index 5ffc5ff36..54984c94f 100644 --- a/src/widgets/accountswitchwidget.cpp +++ b/src/widgets/accountswitchwidget.cpp @@ -1,5 +1,5 @@ #include "accountswitchwidget.hpp" -#include "accountmanager.hpp" +#include "singletons/accountmanager.hpp" #include "const.hpp" namespace chatterino { diff --git a/src/widgets/basewidget.cpp b/src/widgets/basewidget.cpp index 5dfb5d4a4..0c314747f 100644 --- a/src/widgets/basewidget.cpp +++ b/src/widgets/basewidget.cpp @@ -1,6 +1,6 @@ #include "widgets/basewidget.hpp" -#include "colorscheme.hpp" -#include "settingsmanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/thememanager.hpp" #include "widgets/tooltipwidget.hpp" #include @@ -12,23 +12,23 @@ namespace chatterino { namespace widgets { -BaseWidget::BaseWidget(ColorScheme &_colorScheme, QWidget *parent) +BaseWidget::BaseWidget(ThemeManager &_themeManager, QWidget *parent) : QWidget(parent) - , colorScheme(_colorScheme) + , themeManager(_themeManager) { this->init(); } BaseWidget::BaseWidget(BaseWidget *parent) : QWidget(parent) - , colorScheme(*ColorScheme::instance) + , themeManager(ThemeManager::getInstance()) { this->init(); } BaseWidget::BaseWidget(QWidget *parent) : QWidget(parent) - , colorScheme(*ColorScheme::instance) + , themeManager(ThemeManager::getInstance()) { } @@ -49,7 +49,7 @@ float BaseWidget::getDpiMultiplier() void BaseWidget::init() { - auto connection = this->colorScheme.updated.connect([this]() { + auto connection = this->themeManager.updated.connect([this]() { this->refreshTheme(); this->update(); diff --git a/src/widgets/basewidget.hpp b/src/widgets/basewidget.hpp index d696f90a3..74c811892 100644 --- a/src/widgets/basewidget.hpp +++ b/src/widgets/basewidget.hpp @@ -4,7 +4,7 @@ namespace chatterino { -class ColorScheme; +class ThemeManager; namespace widgets { @@ -13,13 +13,13 @@ class BaseWidget : public QWidget Q_OBJECT public: - explicit BaseWidget(ColorScheme &_colorScheme, QWidget *parent); + explicit BaseWidget(ThemeManager &_themeManager, QWidget *parent); explicit BaseWidget(BaseWidget *parent); explicit BaseWidget(QWidget *parent = nullptr); - ColorScheme &colorScheme; + ThemeManager &themeManager; float getDpiMultiplier(); diff --git a/src/widgets/emotepopup.cpp b/src/widgets/emotepopup.cpp index 074fee8c6..c01be6388 100644 --- a/src/widgets/emotepopup.cpp +++ b/src/widgets/emotepopup.cpp @@ -12,8 +12,8 @@ using namespace chatterino::messages; namespace chatterino { namespace widgets { -EmotePopup::EmotePopup(ColorScheme &colorScheme) - : BaseWidget(colorScheme, 0) +EmotePopup::EmotePopup(ThemeManager &themeManager) + : BaseWidget(themeManager, 0) { this->initAsWindow(); diff --git a/src/widgets/emotepopup.hpp b/src/widgets/emotepopup.hpp index fa1f5dcbb..028ff03a7 100644 --- a/src/widgets/emotepopup.hpp +++ b/src/widgets/emotepopup.hpp @@ -10,7 +10,7 @@ namespace widgets { class EmotePopup : public BaseWidget { public: - explicit EmotePopup(ColorScheme &); + explicit EmotePopup(ThemeManager &); void loadChannel(std::shared_ptr channel); void loadEmojis(); diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp index 3afab3b56..c9d1c9893 100644 --- a/src/widgets/helper/channelview.cpp +++ b/src/widgets/helper/channelview.cpp @@ -1,17 +1,17 @@ -#include "widgets/helper/channelview.hpp" -#include "channelmanager.hpp" -#include "colorscheme.hpp" +#include "channelview.hpp" #include "debug/log.hpp" #include "messages/limitedqueuesnapshot.hpp" #include "messages/message.hpp" #include "messages/messageref.hpp" -#include "settingsmanager.hpp" +#include "singletons/channelmanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/thememanager.hpp" +#include "singletons/windowmanager.hpp" #include "ui_accountpopupform.h" #include "util/benchmark.hpp" #include "util/distancebetweenpoints.hpp" #include "widgets/split.hpp" #include "widgets/tooltipwidget.hpp" -#include "windowmanager.hpp" #include #include @@ -51,7 +51,7 @@ ChannelView::ChannelView(BaseWidget *parent) this->queueUpdate(); }); - WindowManager &windowManager = *WindowManager::instance; + WindowManager &windowManager = WindowManager::getInstance(); this->repaintGifsConnection = windowManager.repaintGifs.connect([&] { this->updateGifEmotes(); }); @@ -445,7 +445,7 @@ void ChannelView::paintEvent(QPaintEvent * /*event*/) // this->onlyUpdateEmotes = false; // for (const GifEmoteData &item : this->gifEmotes) { -// painter.fillRect(item.rect, this->colorScheme.ChatBackground); +// painter.fillRect(item.rect, this->themeManager.ChatBackground); // painter.drawPixmap(item.rect, *item.image->getPixmap()); // } @@ -457,7 +457,7 @@ void ChannelView::paintEvent(QPaintEvent * /*event*/) // update all messages this->gifEmotes.clear(); - painter.fillRect(rect(), this->colorScheme.ChatBackground); + painter.fillRect(rect(), this->themeManager.ChatBackground); // draw messages this->drawMessages(painter); @@ -466,7 +466,7 @@ void ChannelView::paintEvent(QPaintEvent * /*event*/) // draw gif emotes for (GifEmoteData &item : this->gifEmotes) { - // painter.fillRect(item.rect, this->colorScheme.ChatBackground); + // painter.fillRect(item.rect, this->themeManager.ChatBackground); painter.drawPixmap(item.rect, *item.image->getPixmap()); } @@ -588,8 +588,8 @@ void ChannelView::updateMessageBuffer(messages::MessageRef *messageRef, QPixmap //} else { painter.fillRect(buffer->rect(), (messageRef->getMessage()->containsHighlightedPhrase()) - ? this->colorScheme.ChatBackgroundHighlighted - : this->colorScheme.ChatBackground); + ? this->themeManager.ChatBackgroundHighlighted + : this->themeManager.ChatBackground); //} // draw selection @@ -613,9 +613,9 @@ void ChannelView::updateMessageBuffer(messages::MessageRef *messageRef, QPixmap } // text else { - QColor color = wordPart.getWord().getTextColor().getColor(this->colorScheme); + QColor color = wordPart.getWord().getTextColor().getColor(this->themeManager); - this->colorScheme.normalizeColor(color); + this->themeManager.normalizeColor(color); painter.setPen(color); painter.setFont(wordPart.getWord().getFont(this->getDpiMultiplier())); @@ -636,7 +636,7 @@ void ChannelView::drawMessageSelection(QPainter &painter, messages::MessageRef * return; } - QColor selectionColor = this->colorScheme.Selection; + QColor selectionColor = this->themeManager.Selection; int charIndex = 0; size_t i = 0; diff --git a/src/widgets/helper/droppreview.cpp b/src/widgets/helper/droppreview.cpp index b52526cca..cc38de915 100644 --- a/src/widgets/helper/droppreview.cpp +++ b/src/widgets/helper/droppreview.cpp @@ -1,5 +1,5 @@ #include "widgets/helper/droppreview.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include #include @@ -20,7 +20,7 @@ void NotebookPageDropPreview::paintEvent(QPaintEvent *) QPainter painter(this); painter.fillRect(8, 8, this->width() - 17, this->height() - 17, - this->colorScheme.DropPreviewBackground); + this->themeManager.DropPreviewBackground); } void NotebookPageDropPreview::hideEvent(QHideEvent *) diff --git a/src/widgets/helper/notebookbutton.cpp b/src/widgets/helper/notebookbutton.cpp index c09b2acda..1f6de41ad 100644 --- a/src/widgets/helper/notebookbutton.cpp +++ b/src/widgets/helper/notebookbutton.cpp @@ -1,5 +1,5 @@ #include "widgets/helper/notebookbutton.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include "widgets/helper/rippleeffectbutton.hpp" #include @@ -23,16 +23,16 @@ void NotebookButton::paintEvent(QPaintEvent *) QColor background; QColor foreground; - background = this->colorScheme.TabBackground; + background = this->themeManager.TabBackground; if (mouseDown) { - // background = this->colorScheme.TabSelectedBackground; - foreground = this->colorScheme.TabHoverText; + // background = this->themeManager.TabSelectedBackground; + foreground = this->themeManager.TabHoverText; } else if (mouseOver) { - // background = this->colorScheme.TabHoverText; - foreground = this->colorScheme.TabHoverText; + // background = this->themeManager.TabHoverText; + foreground = this->themeManager.TabHoverText; } else { - // background = this->colorScheme.TabPanelBackground; + // background = this->themeManager.TabPanelBackground; foreground = QColor(70, 80, 80); } diff --git a/src/widgets/helper/notebooktab.cpp b/src/widgets/helper/notebooktab.cpp index 3f7aa146f..02d370f9e 100644 --- a/src/widgets/helper/notebooktab.cpp +++ b/src/widgets/helper/notebooktab.cpp @@ -1,8 +1,8 @@ #include "widgets/helper/notebooktab.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include "common.hpp" #include "debug/log.hpp" -#include "settingsmanager.hpp" +#include "singletons/settingsmanager.hpp" #include "util/helpers.hpp" #include "widgets/notebook.hpp" #include "widgets/textinputdialog.hpp" @@ -167,24 +167,24 @@ void NotebookTab::paintEvent(QPaintEvent *) if (this->selected) { if (this->window() == QApplication::activeWindow()) { - painter.fillRect(rect(), this->colorScheme.TabSelectedBackground); - fg = this->colorScheme.TabSelectedText; + painter.fillRect(rect(), this->themeManager.TabSelectedBackground); + fg = this->themeManager.TabSelectedText; } else { - painter.fillRect(rect(), this->colorScheme.TabSelectedUnfocusedBackground); - fg = this->colorScheme.TabSelectedUnfocusedText; + painter.fillRect(rect(), this->themeManager.TabSelectedUnfocusedBackground); + fg = this->themeManager.TabSelectedUnfocusedText; } } else if (this->mouseOver) { - painter.fillRect(rect(), this->colorScheme.TabHoverBackground); - fg = this->colorScheme.TabHoverText; + painter.fillRect(rect(), this->themeManager.TabHoverBackground); + fg = this->themeManager.TabHoverText; } else if (this->highlightState == HighlightState::Highlighted) { - painter.fillRect(rect(), this->colorScheme.TabHighlightedBackground); - fg = this->colorScheme.TabHighlightedText; + painter.fillRect(rect(), this->themeManager.TabHighlightedBackground); + fg = this->themeManager.TabHighlightedText; } else if (this->highlightState == HighlightState::NewMessage) { - painter.fillRect(rect(), this->colorScheme.TabNewMessageBackground); - fg = this->colorScheme.TabHighlightedText; + painter.fillRect(rect(), this->themeManager.TabNewMessageBackground); + fg = this->themeManager.TabHighlightedText; } else { - painter.fillRect(rect(), this->colorScheme.TabBackground); - fg = this->colorScheme.TabText; + painter.fillRect(rect(), this->themeManager.TabBackground); + fg = this->themeManager.TabText; } painter.setPen(fg); diff --git a/src/widgets/helper/notebooktab.hpp b/src/widgets/helper/notebooktab.hpp index 9988eb6e9..b890ad036 100644 --- a/src/widgets/helper/notebooktab.hpp +++ b/src/widgets/helper/notebooktab.hpp @@ -10,7 +10,7 @@ namespace chatterino { -class ColorScheme; +class ThemeManager; namespace widgets { diff --git a/src/widgets/helper/resizingtextedit.cpp b/src/widgets/helper/resizingtextedit.cpp index 415eb74c6..cc072ef44 100644 --- a/src/widgets/helper/resizingtextedit.cpp +++ b/src/widgets/helper/resizingtextedit.cpp @@ -1,5 +1,5 @@ #include "widgets/helper/resizingtextedit.hpp" -#include "completionmanager.hpp" +#include "singletons/completionmanager.hpp" ResizingTextEdit::ResizingTextEdit() { diff --git a/src/widgets/helper/rippleeffectbutton.cpp b/src/widgets/helper/rippleeffectbutton.cpp index 5b07f2afa..2c25dcb83 100644 --- a/src/widgets/helper/rippleeffectbutton.cpp +++ b/src/widgets/helper/rippleeffectbutton.cpp @@ -3,7 +3,7 @@ #include #include -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" namespace chatterino { namespace widgets { @@ -37,7 +37,7 @@ void RippleEffectButton::fancyPaint(QPainter &painter) if (this->mouseEffectColor) { c = this->mouseEffectColor.get(); } else { - c = this->colorScheme.isLightTheme() ? QColor(0, 0, 0) : QColor(255, 255, 255); + c = this->themeManager.isLightTheme() ? QColor(0, 0, 0) : QColor(255, 255, 255); } if (this->hoverMultiplier > 0) { diff --git a/src/widgets/helper/rippleeffectlabel.cpp b/src/widgets/helper/rippleeffectlabel.cpp index 2be3b7cad..47fbea8e7 100644 --- a/src/widgets/helper/rippleeffectlabel.cpp +++ b/src/widgets/helper/rippleeffectlabel.cpp @@ -1,5 +1,5 @@ #include "widgets/helper/rippleeffectlabel.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include "widgets/helper/splitheader.hpp" #include diff --git a/src/widgets/helper/rippleeffectlabel.hpp b/src/widgets/helper/rippleeffectlabel.hpp index 2c8c45cc0..08a05e837 100644 --- a/src/widgets/helper/rippleeffectlabel.hpp +++ b/src/widgets/helper/rippleeffectlabel.hpp @@ -11,7 +11,7 @@ namespace chatterino { -class ColorScheme; +class ThemeManager; namespace widgets { diff --git a/src/widgets/helper/scrollbarhighlight.cpp b/src/widgets/helper/scrollbarhighlight.cpp index 1809db371..93f34c422 100644 --- a/src/widgets/helper/scrollbarhighlight.cpp +++ b/src/widgets/helper/scrollbarhighlight.cpp @@ -1,5 +1,5 @@ #include "widgets/helper/scrollbarhighlight.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include "widgets/scrollbar.hpp" namespace chatterino { @@ -7,9 +7,9 @@ namespace widgets { ScrollBarHighlight::ScrollBarHighlight(double _position, int _colorIndex, ScrollBar *parent, Style _style, QString _tag) - : colorScheme(parent->colorScheme) + : themeManager(parent->themeManager) , position(_position) - , colorIndex(std::max(0, std::min(this->colorScheme.HighlightColorCount, _colorIndex))) + , colorIndex(std::max(0, std::min(this->themeManager.HighlightColorCount, _colorIndex))) , style(_style) , tag(_tag) { diff --git a/src/widgets/helper/scrollbarhighlight.hpp b/src/widgets/helper/scrollbarhighlight.hpp index cca7215d2..9be6f1681 100644 --- a/src/widgets/helper/scrollbarhighlight.hpp +++ b/src/widgets/helper/scrollbarhighlight.hpp @@ -4,7 +4,7 @@ namespace chatterino { -class ColorScheme; +class ThemeManager; namespace widgets { @@ -18,7 +18,7 @@ public: ScrollBarHighlight(double _position, int _colorIndex, ScrollBar *parent, Style _style = Default, QString _tag = ""); - ColorScheme &colorScheme; + ThemeManager &themeManager; double getPosition() { diff --git a/src/widgets/helper/splitheader.cpp b/src/widgets/helper/splitheader.cpp index 8c61610cf..646455f2c 100644 --- a/src/widgets/helper/splitheader.cpp +++ b/src/widgets/helper/splitheader.cpp @@ -1,5 +1,5 @@ #include "widgets/helper/splitheader.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include "twitch/twitchchannel.hpp" #include "util/urlfetch.hpp" #include "widgets/split.hpp" @@ -135,8 +135,8 @@ void SplitHeader::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.fillRect(rect(), this->colorScheme.ChatHeaderBackground); - painter.setPen(this->colorScheme.ChatHeaderBorder); + painter.fillRect(rect(), this->themeManager.ChatHeaderBackground); + painter.setPen(this->themeManager.ChatHeaderBorder); painter.drawRect(0, 0, width() - 1, height() - 1); } @@ -217,7 +217,7 @@ void SplitHeader::rightButtonClicked() void SplitHeader::refreshTheme() { QPalette palette; - palette.setColor(QPalette::Foreground, this->colorScheme.Text); + palette.setColor(QPalette::Foreground, this->themeManager.Text); this->leftLabel.setPalette(palette); this->channelNameLabel.setPalette(palette); diff --git a/src/widgets/helper/splitheader.hpp b/src/widgets/helper/splitheader.hpp index 9a6f77e26..bfe47e1d4 100644 --- a/src/widgets/helper/splitheader.hpp +++ b/src/widgets/helper/splitheader.hpp @@ -16,7 +16,7 @@ namespace chatterino { -class ColorScheme; +class ThemeManager; namespace widgets { diff --git a/src/widgets/helper/splitinput.cpp b/src/widgets/helper/splitinput.cpp index 8f9fe3201..08d05cdf5 100644 --- a/src/widgets/helper/splitinput.cpp +++ b/src/widgets/helper/splitinput.cpp @@ -1,8 +1,8 @@ #include "widgets/helper/splitinput.hpp" -#include "colorscheme.hpp" -#include "completionmanager.hpp" -#include "ircmanager.hpp" -#include "settingsmanager.hpp" +#include "singletons/completionmanager.hpp" +#include "singletons/ircmanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/thememanager.hpp" #include "widgets/notebook.hpp" #include "widgets/split.hpp" #include "widgets/splitcontainer.hpp" @@ -55,7 +55,7 @@ SplitInput::SplitInput(Split *_chatWidget) connect(&this->emotesLabel, &RippleEffectLabel::clicked, [this] { if (this->emotePopup == nullptr) { - this->emotePopup = new EmotePopup(this->colorScheme); + this->emotePopup = new EmotePopup(this->themeManager); } this->emotePopup->resize((int)(300 * this->emotePopup->getDpiMultiplier()), @@ -210,13 +210,13 @@ void SplitInput::refreshTheme() { QPalette palette; - palette.setColor(QPalette::Foreground, this->colorScheme.Text); + palette.setColor(QPalette::Foreground, this->themeManager.Text); this->textLengthLabel.setPalette(palette); - this->textInput.setStyleSheet(this->colorScheme.InputStyleSheet); + this->textInput.setStyleSheet(this->themeManager.InputStyleSheet); - this->hbox.setMargin((this->colorScheme.isLightTheme() ? 4 : 2) * this->getDpiMultiplier()); + this->hbox.setMargin((this->themeManager.isLightTheme() ? 4 : 2) * this->getDpiMultiplier()); } void SplitInput::editTextChanged() @@ -244,10 +244,10 @@ void SplitInput::paintEvent(QPaintEvent *) { QPainter painter(this); - painter.fillRect(this->rect(), this->colorScheme.ChatInputBackground); + painter.fillRect(this->rect(), this->themeManager.ChatInputBackground); - QPen pen(this->colorScheme.ChatInputBorder); - if (this->colorScheme.isLightTheme()) { + QPen pen(this->themeManager.ChatInputBorder); + if (this->themeManager.isLightTheme()) { pen.setWidth((int)(6 * this->getDpiMultiplier())); } painter.setPen(pen); diff --git a/src/widgets/notebook.cpp b/src/widgets/notebook.cpp index 2e67e59b6..f8e24340f 100644 --- a/src/widgets/notebook.cpp +++ b/src/widgets/notebook.cpp @@ -1,6 +1,6 @@ #include "widgets/notebook.hpp" -#include "colorscheme.hpp" #include "debug/log.hpp" +#include "singletons/thememanager.hpp" #include "widgets/accountswitchpopupwidget.hpp" #include "widgets/helper/notebookbutton.hpp" #include "widgets/helper/notebooktab.hpp" @@ -22,11 +22,9 @@ namespace chatterino { namespace widgets { -Notebook::Notebook(ChannelManager &_channelManager, Window *parent, bool _showButtons, - const std::string &settingPrefix) +Notebook::Notebook(Window *parent, bool _showButtons, const std::string &settingPrefix) : BaseWidget(parent) , settingRoot(fS("{}/notebook", settingPrefix)) - , channelManager(_channelManager) , addButton(this) , settingsButton(this) , userButton(this) @@ -58,7 +56,7 @@ SplitContainer *Notebook::addNewPage() SplitContainer *Notebook::addPage(const std::string &uuid, bool select) { auto tab = new NotebookTab(this, uuid); - auto page = new SplitContainer(this->channelManager, this, tab, uuid); + auto page = new SplitContainer(this, tab, uuid); tab->show(); diff --git a/src/widgets/notebook.hpp b/src/widgets/notebook.hpp index e7b8b32f5..ab90b06d8 100644 --- a/src/widgets/notebook.hpp +++ b/src/widgets/notebook.hpp @@ -25,8 +25,7 @@ class Notebook : public BaseWidget public: enum HighlightType { none, highlighted, newMessage }; - explicit Notebook(ChannelManager &_channelManager, Window *parent, bool _showButtons, - const std::string &settingPrefix); + explicit Notebook(Window *parent, bool _showButtons, const std::string &settingPrefix); SplitContainer *addNewPage(); SplitContainer *addPage(const std::string &uuid, bool select = false); @@ -58,9 +57,6 @@ public slots: void usersButtonClicked(); void addPageButtonClicked(); -public: - ChannelManager &channelManager; - private: QList pages; diff --git a/src/widgets/scrollbar.cpp b/src/widgets/scrollbar.cpp index ba991c139..fdd47b2e2 100644 --- a/src/widgets/scrollbar.cpp +++ b/src/widgets/scrollbar.cpp @@ -1,5 +1,5 @@ #include "widgets/scrollbar.hpp" -#include "colorscheme.hpp" +#include "singletons/thememanager.hpp" #include "widgets/helper/channelview.hpp" #include @@ -234,22 +234,22 @@ void ScrollBar::paintEvent(QPaintEvent *) int xOffset = mouseOver ? 0 : width() - (int)(4 * this->getDpiMultiplier()); QPainter painter(this); - // painter.fillRect(rect(), this->colorScheme.ScrollbarBG); + // painter.fillRect(rect(), this->themeManager.ScrollbarBG); painter.fillRect(QRect(xOffset, 0, width(), this->buttonHeight), - this->colorScheme.ScrollbarArrow); + this->themeManager.ScrollbarArrow); painter.fillRect(QRect(xOffset, height() - this->buttonHeight, width(), this->buttonHeight), - this->colorScheme.ScrollbarArrow); + this->themeManager.ScrollbarArrow); this->thumbRect.setX(xOffset); // mouse over thumb if (this->mouseDownIndex == 2) { - painter.fillRect(this->thumbRect, this->colorScheme.ScrollbarThumbSelected); + painter.fillRect(this->thumbRect, this->themeManager.ScrollbarThumbSelected); } // mouse not over thumb else { - painter.fillRect(this->thumbRect, this->colorScheme.ScrollbarThumb); + painter.fillRect(this->thumbRect, this->themeManager.ScrollbarThumb); } // ScrollBarHighlight *highlight = highlights; diff --git a/src/widgets/scrollbar.hpp b/src/widgets/scrollbar.hpp index 4e6407159..58c2117ef 100644 --- a/src/widgets/scrollbar.hpp +++ b/src/widgets/scrollbar.hpp @@ -1,5 +1,6 @@ #pragma once +#include "singletons/settingsmanager.hpp" #include "widgets/basewidget.hpp" #include "widgets/helper/scrollbarhighlight.hpp" @@ -7,11 +8,10 @@ #include #include #include -#include namespace chatterino { -class ColorScheme; +class ThemeManager; namespace widgets { diff --git a/src/widgets/settingsdialog.cpp b/src/widgets/settingsdialog.cpp index 37a254632..b15d86234 100644 --- a/src/widgets/settingsdialog.cpp +++ b/src/widgets/settingsdialog.cpp @@ -1,12 +1,12 @@ #include "widgets/settingsdialog.hpp" -#include "accountmanager.hpp" +#include "singletons/accountmanager.hpp" #include "const.hpp" #include "debug/log.hpp" #include "twitch/twitchmessagebuilder.hpp" #include "twitch/twitchuser.hpp" #include "widgets/helper/settingsdialogtab.hpp" #include "widgets/logindialog.hpp" -#include "windowmanager.hpp" +#include "singletons/windowmanager.hpp" #include #include diff --git a/src/widgets/settingsdialog.hpp b/src/widgets/settingsdialog.hpp index 9ac34f0e2..2783e5705 100644 --- a/src/widgets/settingsdialog.hpp +++ b/src/widgets/settingsdialog.hpp @@ -1,6 +1,6 @@ #pragma once -#include "settingsmanager.hpp" +#include "singletons/settingsmanager.hpp" #include "widgets/accountswitchwidget.hpp" #include "widgets/helper/settingsdialogtab.hpp" diff --git a/src/widgets/split.cpp b/src/widgets/split.cpp index 6ddd98e08..4cd505e09 100644 --- a/src/widgets/split.cpp +++ b/src/widgets/split.cpp @@ -1,14 +1,14 @@ #include "widgets/split.hpp" -#include "channelmanager.hpp" -#include "colorscheme.hpp" -#include "settingsmanager.hpp" +#include "singletons/channelmanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/thememanager.hpp" +#include "singletons/windowmanager.hpp" #include "twitch/twitchmessagebuilder.hpp" #include "util/urlfetch.hpp" #include "widgets/qualitypopup.hpp" #include "widgets/splitcontainer.hpp" #include "widgets/textinputdialog.hpp" #include "widgets/window.hpp" -#include "windowmanager.hpp" #include #include @@ -45,14 +45,13 @@ inline void ezShortcut(Split *w, const char *key, T t) } // namespace -Split::Split(ChannelManager &_channelManager, SplitContainer *parent, const std::string &_uuid) +Split::Split(SplitContainer *parent, const std::string &_uuid) : BaseWidget(parent) , uuid(_uuid) , settingRoot(fS("/splits/{}", this->uuid)) , channelName(fS("{}/channelName", this->settingRoot)) , parentPage(*parent) - , channelManager(_channelManager) - , channel(_channelManager.emptyChannel) + , channel(ChannelManager::getInstance().emptyChannel) , vbox(this) , header(this) , view(this) @@ -171,17 +170,18 @@ double Split::getFlexSizeY() void Split::channelNameUpdated(const std::string &newChannelName) { + auto &cman = ChannelManager::getInstance(); + // remove current channel if (!this->channel->isEmpty()) { - this->channelManager.removeTwitchChannel(this->channel->name); + cman.removeTwitchChannel(this->channel->name); } // update messages if (newChannelName.empty()) { - this->setChannel(this->channelManager.emptyChannel); + this->setChannel(cman.emptyChannel); } else { - this->setChannel( - this->channelManager.addTwitchChannel(QString::fromStdString(newChannelName))); + this->setChannel(cman.addTwitchChannel(QString::fromStdString(newChannelName))); } // update header @@ -236,7 +236,7 @@ void Split::paintEvent(QPaintEvent *) // color the background of the chat QPainter painter(this); - painter.fillRect(this->rect(), this->colorScheme.ChatBackground); + painter.fillRect(this->rect(), this->themeManager.ChatBackground); } /// Slots @@ -264,10 +264,9 @@ void Split::doChangeChannel() void Split::doPopup() { - Window &window = WindowManager::instance->createWindow(); + Window &window = WindowManager::getInstance().createWindow(); - Split *split = new Split(this->channelManager, - static_cast(window.getNotebook().getSelectedPage()), + Split *split = new Split(static_cast(window.getNotebook().getSelectedPage()), this->uuid); window.getNotebook().getSelectedPage()->addToLayout(split); @@ -396,7 +395,7 @@ void Split::doOpenViewerList() QList labelList; for (auto &x : labels) { auto label = new QListWidgetItem(x); - label->setBackgroundColor(this->colorScheme.ChatHeaderBackground); + label->setBackgroundColor(this->themeManager.ChatHeaderBackground); labelList.append(label); } auto loadingLabel = new QLabel("Loading..."); @@ -453,7 +452,7 @@ void Split::doOpenViewerList() dockVbox->addWidget(resultList); resultList->hide(); - multiWidget->setStyleSheet(this->colorScheme.InputStyleSheet); + multiWidget->setStyleSheet(this->themeManager.InputStyleSheet); multiWidget->setLayout(dockVbox); viewerDock->setWidget(multiWidget); viewerDock->show(); diff --git a/src/widgets/split.hpp b/src/widgets/split.hpp index 87d349722..98861744a 100644 --- a/src/widgets/split.hpp +++ b/src/widgets/split.hpp @@ -19,9 +19,6 @@ namespace chatterino { -class ChannelManager; -class ColorScheme; - namespace widgets { class SplitContainer; @@ -46,10 +43,9 @@ class Split : public BaseWidget const std::string settingRoot; public: - Split(ChannelManager &_channelManager, SplitContainer *parent, const std::string &_uuid); + Split(SplitContainer *parent, const std::string &_uuid); ~Split(); - ChannelManager &channelManager; pajlada::Settings::Setting channelName; boost::signals2::signal channelChanged; diff --git a/src/widgets/splitcontainer.cpp b/src/widgets/splitcontainer.cpp index c70e9ab14..ece607e37 100644 --- a/src/widgets/splitcontainer.cpp +++ b/src/widgets/splitcontainer.cpp @@ -1,6 +1,6 @@ #include "widgets/splitcontainer.hpp" -#include "colorscheme.hpp" #include "common.hpp" +#include "singletons/thememanager.hpp" #include "util/helpers.hpp" #include "widgets/helper/notebooktab.hpp" #include "widgets/notebook.hpp" @@ -25,13 +25,11 @@ bool SplitContainer::isDraggingSplit = false; Split *SplitContainer::draggingSplit = nullptr; std::pair SplitContainer::dropPosition = std::pair(-1, -1); -SplitContainer::SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab, - const std::string &_uuid) - : BaseWidget(parent->colorScheme, parent) +SplitContainer::SplitContainer(Notebook *parent, NotebookTab *_tab, const std::string &_uuid) + : BaseWidget(parent->themeManager, parent) , uuid(_uuid) , settingRoot(fS("/containers/{}", this->uuid)) , chats(fS("{}/chats", this->settingRoot)) - , channelManager(_channelManager) , tab(_tab) , dropPreview(this) , chatWidgets() @@ -387,17 +385,17 @@ void SplitContainer::paintEvent(QPaintEvent *) QPainter painter(this); if (this->ui.hbox.count() == 0) { - painter.fillRect(rect(), this->colorScheme.ChatBackground); + painter.fillRect(rect(), this->themeManager.ChatBackground); - painter.setPen(this->colorScheme.Text); + painter.setPen(this->themeManager.Text); painter.drawText(rect(), "Add Chat", QTextOption(Qt::AlignCenter)); } else { - painter.fillRect(rect(), this->colorScheme.ChatSeperator); + painter.fillRect(rect(), this->themeManager.ChatSeperator); } QColor accentColor = (QApplication::activeWindow() == this->window() - ? this->colorScheme.TabSelectedBackground - : this->colorScheme.TabSelectedUnfocusedBackground); + ? this->themeManager.TabSelectedBackground + : this->themeManager.TabSelectedUnfocusedBackground); painter.fillRect(0, 0, width(), 2, accentColor); } @@ -432,7 +430,7 @@ std::pair SplitContainer::getChatPosition(const Split *chatWidget) Split *SplitContainer::createChatWidget(const std::string &uuid) { - auto split = new Split(this->channelManager, this, uuid); + auto split = new Split(this, uuid); split->getChannelView().highlightedMessageReceived.connect([this] { this->tab->setHighlightState(HighlightState::Highlighted); // diff --git a/src/widgets/splitcontainer.hpp b/src/widgets/splitcontainer.hpp index 22edac719..ca9a05109 100644 --- a/src/widgets/splitcontainer.hpp +++ b/src/widgets/splitcontainer.hpp @@ -26,16 +26,13 @@ class SplitContainer : public BaseWidget const std::string settingRoot; public: - SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab, - const std::string &_uuid); + SplitContainer(Notebook *parent, NotebookTab *_tab, const std::string &_uuid); const std::string &getUUID() const { return this->uuid; } - ChannelManager &channelManager; - std::pair removeFromLayout(Split *widget); void addToLayout(Split *widget, std::pair position = std::pair(-1, -1)); diff --git a/src/widgets/tooltipwidget.cpp b/src/widgets/tooltipwidget.cpp index f3ff543bd..cd502a3ca 100644 --- a/src/widgets/tooltipwidget.cpp +++ b/src/widgets/tooltipwidget.cpp @@ -1,6 +1,6 @@ #include "tooltipwidget.hpp" -#include "colorscheme.hpp" -#include "fontmanager.hpp" +#include "singletons/thememanager.hpp" +#include "singletons/fontmanager.hpp" #include #include diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index 628d238e7..7d52d43d7 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -1,8 +1,8 @@ #include "widgets/window.hpp" -#include "accountmanager.hpp" -#include "channelmanager.hpp" -#include "colorscheme.hpp" -#include "settingsmanager.hpp" +#include "singletons/accountmanager.hpp" +#include "singletons/channelmanager.hpp" +#include "singletons/settingsmanager.hpp" +#include "singletons/thememanager.hpp" #include "widgets/notebook.hpp" #include "widgets/settingsdialog.hpp" #include "widgets/split.hpp" @@ -14,15 +14,13 @@ namespace chatterino { namespace widgets { -Window::Window(const QString &windowName, ChannelManager &_channelManager, - ColorScheme &_colorScheme, bool _isMainWindow) - : BaseWidget(_colorScheme, nullptr) +Window::Window(const QString &windowName, ThemeManager &_themeManager, bool _isMainWindow) + : BaseWidget(_themeManager, nullptr) , settingRoot(fS("/windows/{}", windowName)) , windowGeometry(this->settingRoot) , dpi(this->getDpiMultiplier()) - , channelManager(_channelManager) - , colorScheme(_colorScheme) - , notebook(this->channelManager, this, _isMainWindow, this->settingRoot) + , themeManager(_themeManager) + , notebook(this, _isMainWindow, this->settingRoot) { this->initAsWindow(); @@ -110,7 +108,7 @@ void Window::closeEvent(QCloseEvent *) void Window::refreshTheme() { QPalette palette; - palette.setColor(QPalette::Background, this->colorScheme.TabBackground); + palette.setColor(QPalette::Background, this->themeManager.TabBackground); this->setPalette(palette); } diff --git a/src/widgets/window.hpp b/src/widgets/window.hpp index 870446295..11a31cf5f 100644 --- a/src/widgets/window.hpp +++ b/src/widgets/window.hpp @@ -16,7 +16,7 @@ namespace chatterino { class ChannelManager; -class ColorScheme; +class ThemeManager; class CompletionManager; namespace widgets { @@ -45,8 +45,7 @@ class Window : public BaseWidget WindowGeometry windowGeometry; public: - explicit Window(const QString &windowName, ChannelManager &_channelManager, - ColorScheme &_colorScheme, bool isMainWindow); + explicit Window(const QString &windowName, ThemeManager &_themeManager, bool isMainWindow); void repaintVisibleChatWidgets(Channel *channel = nullptr); @@ -60,15 +59,14 @@ protected: virtual void closeEvent(QCloseEvent *event) override; private: + ThemeManager &themeManager; + float dpi; virtual void refreshTheme() override; void loadGeometry(); - ChannelManager &channelManager; - ColorScheme &colorScheme; - Notebook notebook; TitleBar titleBar;