diff --git a/src/application.cpp b/src/application.cpp index 5949c0d4f..357244d73 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -10,13 +10,10 @@ namespace chatterino { // It will create the instances of the major classes, and connect their signals to each other Application::Application() - : completionManager(this->emoteManager) - , windowManager(this->channelManager, this->colorScheme, this->completionManager) + : windowManager(this->channelManager, this->colorScheme) , colorScheme(this->windowManager) - , emoteManager(this->windowManager) - , resources(this->emoteManager, this->windowManager) - , channelManager(this->windowManager, this->emoteManager, this->ircManager) - , ircManager(this->channelManager, this->resources, this->emoteManager, this->windowManager) + , channelManager(this->windowManager, this->ircManager) + , ircManager(this->channelManager, this->resources, this->windowManager) { logging::init(); SettingsManager::getInstance().load(); @@ -24,7 +21,7 @@ Application::Application() this->windowManager.initMainWindow(); // Initialize everything we need - this->emoteManager.loadGlobalEmotes(); + EmoteManager::getInstance().loadGlobalEmotes(); AccountManager::getInstance().load(); diff --git a/src/application.hpp b/src/application.hpp index 2c294c2e5..df27441cf 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -20,10 +20,8 @@ public: int run(QApplication &qtApp); - CompletionManager completionManager; WindowManager windowManager; ColorScheme colorScheme; - EmoteManager emoteManager; Resources resources; ChannelManager channelManager; IrcManager ircManager; diff --git a/src/channelmanager.cpp b/src/channelmanager.cpp index 9e9cdd2c7..6371de46e 100644 --- a/src/channelmanager.cpp +++ b/src/channelmanager.cpp @@ -5,14 +5,12 @@ using namespace chatterino::twitch; namespace chatterino { -ChannelManager::ChannelManager(WindowManager &_windowManager, EmoteManager &_emoteManager, - IrcManager &_ircManager) +ChannelManager::ChannelManager(WindowManager &_windowManager, IrcManager &_ircManager) : windowManager(_windowManager) - , emoteManager(_emoteManager) , ircManager(_ircManager) - , whispersChannel(new TwitchChannel(_emoteManager, _ircManager, "/whispers", true)) - , mentionsChannel(new TwitchChannel(_emoteManager, _ircManager, "/mentions", true)) - , emptyChannel(new TwitchChannel(_emoteManager, _ircManager, "", true)) + , whispersChannel(new TwitchChannel(_ircManager, "/whispers", true)) + , mentionsChannel(new TwitchChannel(_ircManager, "/mentions", true)) + , emptyChannel(new TwitchChannel(_ircManager, "", true)) { } @@ -46,8 +44,7 @@ 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->emoteManager, this->ircManager, channelName); + auto channel = std::make_shared(this->ircManager, channelName); this->twitchChannels.insert(channelName, std::make_tuple(channel, 1)); @@ -126,16 +123,6 @@ const std::string &ChannelManager::getUserID(const std::string &username) return temporary; } -EmoteManager &ChannelManager::getEmoteManager() -{ - return this->emoteManager; -} - -WindowManager &ChannelManager::getWindowManager() -{ - return this->windowManager; -} - void ChannelManager::doOnAll(std::function)> func) { for (const auto &channel : this->twitchChannels) { diff --git a/src/channelmanager.hpp b/src/channelmanager.hpp index 77a5712a4..0484360c4 100644 --- a/src/channelmanager.hpp +++ b/src/channelmanager.hpp @@ -9,17 +9,14 @@ namespace chatterino { class WindowManager; -class EmoteManager; class IrcManager; class ChannelManager { public: - explicit ChannelManager(WindowManager &_windowManager, EmoteManager &_emoteManager, - IrcManager &_ircManager); + explicit ChannelManager(WindowManager &_windowManager, IrcManager &_ircManager); WindowManager &windowManager; - EmoteManager &emoteManager; IrcManager &ircManager; const std::vector> getItems(); @@ -29,8 +26,6 @@ public: void removeTwitchChannel(const QString &channel); const std::string &getUserID(const std::string &username); - EmoteManager &getEmoteManager(); - WindowManager &getWindowManager(); void doOnAll(std::function)> func); diff --git a/src/completionmanager.cpp b/src/completionmanager.cpp index 393739dad..9c4ba7362 100644 --- a/src/completionmanager.cpp +++ b/src/completionmanager.cpp @@ -10,30 +10,26 @@ void CompletionModel::addString(const std::string &str) this->emotes.push_back(qS(str) + " "); } -CompletionManager::CompletionManager(EmoteManager &_emoteManager) - : emoteManager(_emoteManager) -{ -} - CompletionModel *CompletionManager::createModel(const std::string &channelName) { CompletionModel *ret = new CompletionModel(); + auto &emoteManager = EmoteManager::getInstance(); this->updateModel(ret, channelName); - this->emoteManager.bttvGlobalEmoteCodes.updated.connect([=]() { + emoteManager.bttvGlobalEmoteCodes.updated.connect([=]() { this->updateModel(ret, channelName); // }); - this->emoteManager.ffzGlobalEmoteCodes.updated.connect([=]() { + emoteManager.ffzGlobalEmoteCodes.updated.connect([=]() { this->updateModel(ret, channelName); // }); - this->emoteManager.bttvChannelEmoteCodes[channelName].updated.connect([=]() { + emoteManager.bttvChannelEmoteCodes[channelName].updated.connect([=]() { this->updateModel(ret, channelName); // }); - this->emoteManager.ffzChannelEmoteCodes[channelName].updated.connect([=]() { + emoteManager.ffzChannelEmoteCodes[channelName].updated.connect([=]() { this->updateModel(ret, channelName); // }); @@ -42,37 +38,38 @@ CompletionModel *CompletionManager::createModel(const std::string &channelName) void CompletionManager::updateModel(CompletionModel *model, const std::string &channelName) { + auto &emoteManager = EmoteManager::getInstance(); + model->emotes.clear(); - for (const auto &m : this->emoteManager.twitchAccountEmotes) { + for (const auto &m : emoteManager.twitchAccountEmotes) { for (const auto &emoteName : m.second.emoteCodes) { model->addString(emoteName); } } - std::vector &bttvGlobalEmoteCodes = this->emoteManager.bttvGlobalEmoteCodes; + std::vector &bttvGlobalEmoteCodes = emoteManager.bttvGlobalEmoteCodes; for (const auto &m : bttvGlobalEmoteCodes) { model->addString(m); } - std::vector &ffzGlobalEmoteCodes = this->emoteManager.ffzGlobalEmoteCodes; + std::vector &ffzGlobalEmoteCodes = emoteManager.ffzGlobalEmoteCodes; for (const auto &m : ffzGlobalEmoteCodes) { model->addString(m); } std::vector &bttvChannelEmoteCodes = - this->emoteManager.bttvChannelEmoteCodes[channelName]; + emoteManager.bttvChannelEmoteCodes[channelName]; for (const auto &m : bttvChannelEmoteCodes) { model->addString(m); } - std::vector &ffzChannelEmoteCodes = - this->emoteManager.ffzChannelEmoteCodes[channelName]; + std::vector &ffzChannelEmoteCodes = emoteManager.ffzChannelEmoteCodes[channelName]; for (const auto &m : ffzChannelEmoteCodes) { model->addString(m); } - const auto &emojiShortCodes = this->emoteManager.emojiShortCodes; + const auto &emojiShortCodes = emoteManager.emojiShortCodes; for (const auto &m : emojiShortCodes) { model->addString(":" + m + ":"); } diff --git a/src/completionmanager.hpp b/src/completionmanager.hpp index 3d70be8bf..686644839 100644 --- a/src/completionmanager.hpp +++ b/src/completionmanager.hpp @@ -35,15 +35,17 @@ public: class CompletionManager { - CompletionManager(EmoteManager &_emoteManager); - - EmoteManager &emoteManager; + CompletionManager() = default; public: + static CompletionManager &getInstance() + { + static CompletionManager instance; + return instance; + } + CompletionModel *createModel(const std::string &channelName); void updateModel(CompletionModel *model, const std::string &channelName = std::string()); - - friend class Application; }; } // namespace chatterino diff --git a/src/emotemanager.cpp b/src/emotemanager.cpp index fcdb2348b..9ff7690b9 100644 --- a/src/emotemanager.cpp +++ b/src/emotemanager.cpp @@ -20,14 +20,9 @@ using namespace chatterino::messages; namespace chatterino { -EmoteManager *EmoteManager::instance = nullptr; - -EmoteManager::EmoteManager(WindowManager &_windowManager) - : windowManager(_windowManager) - , findShortCodesRegex(":([-+\\w]+):") +EmoteManager::EmoteManager() + : findShortCodesRegex(":([-+\\w]+):") { - this->instance = this; - pajlada::Settings::Setting roomID( "/accounts/current/roomID", "", pajlada::Settings::SettingOption::DoNotWriteToJSON); @@ -82,8 +77,7 @@ void EmoteManager::reloadBTTVChannelEmotes(const QString &channelName, std::weak link = link.replace("{{id}}", id).replace("{{image}}", "1x"); auto emote = this->getBTTVChannelEmoteFromCaches().getOrAdd(id, [this, &code, &link] { - return EmoteData(new LazyLoadedImage(*this, this->windowManager, link, 1, code, - code + "\nChannel BTTV Emote")); + return EmoteData(new LazyLoadedImage(link, 1, code, code + "\nChannel BTTV Emote")); }); this->bttvChannelEmotes.insert(code, emote); @@ -131,8 +125,8 @@ void EmoteManager::reloadFFZChannelEmotes(const QString &channelName, std::weak_ auto emote = this->getFFZChannelEmoteFromCaches().getOrAdd(id, [this, &code, &url1] { - return EmoteData(new LazyLoadedImage(*this, this->windowManager, url1, 1, - code, code + "\nGlobal FFZ Emote")); + return EmoteData( + new LazyLoadedImage(url1, 1, code, code + "\nGlobal FFZ Emote")); }); this->ffzChannelEmotes.insert(code, emote); @@ -231,8 +225,7 @@ void EmoteManager::loadEmojis() "emojione/2.2.6/assets/png/" + code + ".png"; - this->emojis.insert(code, - EmoteData(new LazyLoadedImage(*this, this->windowManager, url, 0.35))); + this->emojis.insert(code, EmoteData(new LazyLoadedImage(url, 0.35))); // TODO(pajlada): The vectors in emojiFirstByte need to be sorted by // emojiData.code.length() @@ -310,7 +303,7 @@ void EmoteManager::parseEmojis(std::vector> &pars // Create or fetch cached emoji image auto emojiImage = this->emojiCache.getOrAdd(url, [this, &url] { - return EmoteData(new LazyLoadedImage(*this, this->windowManager, url, 0.35)); // + return EmoteData(new LazyLoadedImage(url, 0.35)); // }); // Push the emoji as a word to parsedWords @@ -440,8 +433,7 @@ void EmoteManager::loadBTTVEmotes() QString url = tmp.replace("{{id}}", id).replace("{{image}}", "1x"); this->bttvGlobalEmotes.insert( - code, new LazyLoadedImage(*this, this->windowManager, url, 1, code, - code + "\nGlobal BTTV Emote")); + code, new LazyLoadedImage(url, 1, code, code + "\nGlobal BTTV Emote")); codes.push_back(code.toStdString()); } @@ -486,8 +478,7 @@ void EmoteManager::loadFFZEmotes() QString url1 = "http:" + urls.value("1").toString(); this->ffzGlobalEmotes.insert( - code, new LazyLoadedImage(*this, this->windowManager, url1, 1, code, - code + "\nGlobal FFZ Emote")); + code, new LazyLoadedImage(url1, 1, code, code + "\nGlobal FFZ Emote")); codes.push_back(code.toStdString()); } @@ -507,8 +498,7 @@ EmoteData EmoteManager::getTwitchEmoteById(long id, const QString &emoteName) return _twitchEmoteFromCache.getOrAdd(id, [this, &emoteName, &id] { qreal scale; QString url = getTwitchEmoteLink(id, scale); - return new LazyLoadedImage(*this, this->windowManager, url, scale, emoteName, - emoteName + "\nTwitch Emote"); + return new LazyLoadedImage(url, scale, emoteName, emoteName + "\nTwitch Emote"); }); } @@ -539,7 +529,7 @@ boost::signals2::signal &EmoteManager::getGifUpdateSignal() QObject::connect(&_gifUpdateTimer, &QTimer::timeout, [this] { _gifUpdateTimerSignal(); - this->windowManager.repaintGifEmotes(); + WindowManager::instance->repaintGifEmotes(); }); } diff --git a/src/emotemanager.hpp b/src/emotemanager.hpp index b64cbd85d..0d6d7a175 100644 --- a/src/emotemanager.hpp +++ b/src/emotemanager.hpp @@ -17,8 +17,6 @@ namespace chatterino { -class WindowManager; - struct EmoteData { EmoteData() { @@ -36,10 +34,14 @@ typedef ConcurrentMap EmoteMap; class EmoteManager { -public: - explicit EmoteManager(WindowManager &_windowManager); + EmoteManager(); - static EmoteManager *instance; +public: + static EmoteManager &getInstance() + { + static EmoteManager instance; + return instance; + } void loadGlobalEmotes(); @@ -76,8 +78,6 @@ public: ConcurrentMap miscImageCache; private: - WindowManager &windowManager; - /// Emojis QRegularExpression findShortCodesRegex; diff --git a/src/ircmanager.cpp b/src/ircmanager.cpp index 1e2bd605c..7c93d2130 100644 --- a/src/ircmanager.cpp +++ b/src/ircmanager.cpp @@ -26,10 +26,9 @@ using namespace chatterino::messages; namespace chatterino { IrcManager::IrcManager(ChannelManager &_channelManager, Resources &_resources, - EmoteManager &_emoteManager, WindowManager &_windowManager) + WindowManager &_windowManager) : channelManager(_channelManager) , resources(_resources) - , emoteManager(_emoteManager) , windowManager(_windowManager) { AccountManager::getInstance().Twitch.userChanged.connect([this]() { @@ -224,8 +223,8 @@ void IrcManager::privateMessageReceived(Communi::IrcPrivateMessage *message) messages::MessageParseArgs args; - twitch::TwitchMessageBuilder builder(c.get(), this->resources, this->emoteManager, - this->windowManager, message, args); + twitch::TwitchMessageBuilder builder(c.get(), this->resources, this->windowManager, message, + args); c->addMessage(builder.parse()); } diff --git a/src/ircmanager.hpp b/src/ircmanager.hpp index ac143a04f..00bc298dc 100644 --- a/src/ircmanager.hpp +++ b/src/ircmanager.hpp @@ -20,7 +20,6 @@ namespace chatterino { class ChannelManager; class Resources; -class EmoteManager; class WindowManager; class IrcManager : public QObject @@ -28,8 +27,7 @@ class IrcManager : public QObject Q_OBJECT public: - IrcManager(ChannelManager &channelManager, Resources &resources, EmoteManager &emoteManager, - WindowManager &windowManager); + IrcManager(ChannelManager &channelManager, Resources &resources, WindowManager &windowManager); void connect(); void disconnect(); @@ -51,7 +49,6 @@ public: ChannelManager &channelManager; Resources &resources; - EmoteManager &emoteManager; WindowManager &windowManager; private: diff --git a/src/messages/lazyloadedimage.cpp b/src/messages/lazyloadedimage.cpp index 74c9750ff..496681ec5 100644 --- a/src/messages/lazyloadedimage.cpp +++ b/src/messages/lazyloadedimage.cpp @@ -19,12 +19,9 @@ namespace chatterino { namespace messages { -LazyLoadedImage::LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager, - const QString &url, qreal scale, const QString &name, +LazyLoadedImage::LazyLoadedImage(const QString &url, qreal scale, const QString &name, const QString &tooltip, const QMargins &margin, bool isHat) - : emoteManager(_emoteManager) - , windowManager(_windowManager) - , currentPixmap(nullptr) + : currentPixmap(nullptr) , url(url) , name(name) , tooltip(tooltip) @@ -35,12 +32,9 @@ LazyLoadedImage::LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_wi { } -LazyLoadedImage::LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager, - QPixmap *image, qreal scale, const QString &name, +LazyLoadedImage::LazyLoadedImage(QPixmap *image, qreal scale, const QString &name, const QString &tooltip, const QMargins &margin, bool isHat) - : emoteManager(_emoteManager) - , windowManager(_windowManager) - , currentPixmap(image) + : currentPixmap(image) , name(name) , tooltip(tooltip) , margin(margin) @@ -85,12 +79,12 @@ void LazyLoadedImage::loadImage() lli->animated = true; } - lli->emoteManager.incGeneration(); + EmoteManager::getInstance().incGeneration(); - lli->windowManager.layoutVisibleChatWidgets(); + WindowManager::instance->layoutVisibleChatWidgets(); }); - this->emoteManager.getGifUpdateSignal().connect([=]() { + EmoteManager::getInstance().getGifUpdateSignal().connect([=]() { this->gifUpdateTimout(); }); // For some reason when Boost signal is in thread scope and thread deletes the signal // doesn't work, so this is the fix. diff --git a/src/messages/lazyloadedimage.hpp b/src/messages/lazyloadedimage.hpp index 83867f0f8..96a9f61da 100644 --- a/src/messages/lazyloadedimage.hpp +++ b/src/messages/lazyloadedimage.hpp @@ -4,10 +4,6 @@ #include namespace chatterino { - -class EmoteManager; -class WindowManager; - namespace messages { class LazyLoadedImage : public QObject @@ -15,13 +11,11 @@ class LazyLoadedImage : public QObject public: LazyLoadedImage() = delete; - explicit LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager, - const QString &_url, qreal _scale = 1, const QString &_name = "", + explicit LazyLoadedImage(const QString &_url, qreal _scale = 1, const QString &_name = "", const QString &_tooltip = "", const QMargins &_margin = QMargins(), bool isHat = false); - explicit LazyLoadedImage(EmoteManager &_emoteManager, WindowManager &_windowManager, - QPixmap *_currentPixmap, qreal _scale = 1, const QString &_name = "", + explicit LazyLoadedImage(QPixmap *_currentPixmap, qreal _scale = 1, const QString &_name = "", const QString &_tooltip = "", const QMargins &_margin = QMargins(), bool isHat = false); @@ -39,9 +33,6 @@ public: int getScaledHeight() const; private: - EmoteManager &emoteManager; - WindowManager &windowManager; - struct FrameData { QPixmap *image; int duration; diff --git a/src/messages/messageref.cpp b/src/messages/messageref.cpp index 2d8ca571d..2551fa625 100644 --- a/src/messages/messageref.cpp +++ b/src/messages/messageref.cpp @@ -33,6 +33,8 @@ int MessageRef::getHeight() const // return true if redraw is required bool MessageRef::layout(int width, float dpiMultiplyer) { + auto &emoteManager = EmoteManager::getInstance(); + bool layoutRequired = false; // check if width changed @@ -41,9 +43,9 @@ bool MessageRef::layout(int width, float dpiMultiplyer) this->currentLayoutWidth = width; // check if emotes changed - bool imagesChanged = this->emoteGeneration != EmoteManager::instance->getGeneration(); + bool imagesChanged = this->emoteGeneration != emoteManager.getGeneration(); layoutRequired |= imagesChanged; - this->emoteGeneration = EmoteManager::instance->getGeneration(); + this->emoteGeneration = emoteManager.getGeneration(); // check if text changed bool textChanged = this->fontGeneration != FontManager::getInstance().getGeneration(); diff --git a/src/resources.cpp b/src/resources.cpp index 3411bba78..350df4d3f 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -9,49 +9,41 @@ namespace chatterino { namespace { -inline messages::LazyLoadedImage *lli(EmoteManager &emoteManager, WindowManager &windowManager, - const char *pixmapPath, qreal scale = 1) +inline messages::LazyLoadedImage *lli(const char *pixmapPath, qreal scale = 1) { - return new messages::LazyLoadedImage(emoteManager, windowManager, new QPixmap(pixmapPath), - scale); + return new messages::LazyLoadedImage(new QPixmap(pixmapPath), scale); } } // namespace -Resources::Resources(EmoteManager &em, WindowManager &wm) - : emoteManager(em) - , windowManager(wm) - , badgeStaff(lli(em, wm, ":/images/staff_bg.png")) - , badgeAdmin(lli(em, wm, ":/images/admin_bg.png")) - , badgeGlobalModerator(lli(em, wm, ":/images/globalmod_bg.png")) - , badgeModerator(lli(em, wm, ":/images/moderator_bg.png")) - , badgeTurbo(lli(em, wm, ":/images/turbo_bg.png")) - , badgeBroadcaster(lli(em, wm, ":/images/broadcaster_bg.png")) - , badgePremium(lli(em, wm, ":/images/twitchprime_bg.png")) - , badgeVerified(lli(em, wm, ":/images/verified.png", 0.25)) - , badgeSubscriber(lli(em, wm, ":/images/subscriber.png", 0.25)) - , cheerBadge100000(lli(em, wm, ":/images/cheer100000")) - , cheerBadge10000(lli(em, wm, ":/images/cheer10000")) - , cheerBadge5000(lli(em, wm, ":/images/cheer5000")) - , cheerBadge1000(lli(em, wm, ":/images/cheer1000")) - , cheerBadge100(lli(em, wm, ":/images/cheer100")) - , cheerBadge1(lli(em, wm, ":/images/cheer1")) - , buttonBan(lli(em, wm, ":/images/button_ban.png", 0.25)) - , buttonTimeout(lli(em, wm, ":/images/button_timeout.png", 0.25)) +Resources::Resources() + : badgeStaff(lli(":/images/staff_bg.png")) + , badgeAdmin(lli(":/images/admin_bg.png")) + , badgeGlobalModerator(lli(":/images/globalmod_bg.png")) + , badgeModerator(lli(":/images/moderator_bg.png")) + , badgeTurbo(lli(":/images/turbo_bg.png")) + , badgeBroadcaster(lli(":/images/broadcaster_bg.png")) + , badgePremium(lli(":/images/twitchprime_bg.png")) + , badgeVerified(lli(":/images/verified.png", 0.25)) + , badgeSubscriber(lli(":/images/subscriber.png", 0.25)) + , cheerBadge100000(lli(":/images/cheer100000")) + , cheerBadge10000(lli(":/images/cheer10000")) + , cheerBadge5000(lli(":/images/cheer5000")) + , cheerBadge1000(lli(":/images/cheer1000")) + , cheerBadge100(lli(":/images/cheer100")) + , cheerBadge1(lli(":/images/cheer1")) + , buttonBan(lli(":/images/button_ban.png", 0.25)) + , buttonTimeout(lli(":/images/button_timeout.png", 0.25)) { this->loadDynamicTwitchBadges(); this->loadChatterinoBadges(); } -Resources::BadgeVersion::BadgeVersion(QJsonObject &&root, EmoteManager &emoteManager, - WindowManager &windowManager) - : badgeImage1x(new messages::LazyLoadedImage(emoteManager, windowManager, - root.value("image_url_1x").toString())) - , badgeImage2x(new messages::LazyLoadedImage(emoteManager, windowManager, - root.value("image_url_2x").toString())) - , badgeImage4x(new messages::LazyLoadedImage(emoteManager, windowManager, - root.value("image_url_4x").toString())) +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())) + , badgeImage4x(new messages::LazyLoadedImage(root.value("image_url_4x").toString())) , description(root.value("description").toString().toStdString()) , title(root.value("title").toString().toStdString()) , clickAction(root.value("clickAction").toString().toStdString()) @@ -83,7 +75,7 @@ void Resources::loadChannelData(const QString &roomID, bool bypassCache) ++versionIt) { std::string kkey = versionIt.key().toStdString(); QJsonObject versionObj = versionIt.value().toObject(); - BadgeVersion v(std::move(versionObj), this->emoteManager, this->windowManager); + BadgeVersion v(std::move(versionObj)); versionsMap.emplace(kkey, v); } } @@ -111,7 +103,7 @@ void Resources::loadDynamicTwitchBadges() ++versionIt) { std::string kkey = versionIt.key().toStdString(); QJsonObject versionObj = versionIt.value().toObject(); - BadgeVersion v(std::move(versionObj), this->emoteManager, this->windowManager); + BadgeVersion v(std::move(versionObj)); versionsMap.emplace(kkey, v); } } @@ -139,9 +131,7 @@ void Resources::loadChatterinoBadges() const QString &badgeVariantImageURL = badgeVariant.value("image").toString(); auto badgeVariantPtr = std::make_shared( - badgeVariantTooltip, - new messages::LazyLoadedImage(this->emoteManager, this->windowManager, - badgeVariantImageURL)); + badgeVariantTooltip, new messages::LazyLoadedImage(badgeVariantImageURL)); QJsonArray badgeVariantUsers = badgeVariant.value("users").toArray(); diff --git a/src/resources.hpp b/src/resources.hpp index cf6ac0300..ac918ec8a 100644 --- a/src/resources.hpp +++ b/src/resources.hpp @@ -8,16 +8,10 @@ namespace chatterino { -class EmoteManager; -class WindowManager; - class Resources { - EmoteManager &emoteManager; - WindowManager &windowManager; - public: - explicit Resources(EmoteManager &emoteManager, WindowManager &windowManager); + explicit Resources(); messages::LazyLoadedImage *badgeStaff; messages::LazyLoadedImage *badgeAdmin; @@ -41,8 +35,7 @@ public: struct BadgeVersion { BadgeVersion() = delete; - explicit BadgeVersion(QJsonObject &&root, EmoteManager &emoteManager, - WindowManager &windowManager); + explicit BadgeVersion(QJsonObject &&root); messages::LazyLoadedImage *badgeImage1x; messages::LazyLoadedImage *badgeImage2x; diff --git a/src/twitch/twitchchannel.cpp b/src/twitch/twitchchannel.cpp index c0e038bbd..78dc72166 100644 --- a/src/twitch/twitchchannel.cpp +++ b/src/twitch/twitchchannel.cpp @@ -9,10 +9,8 @@ namespace chatterino { namespace twitch { -TwitchChannel::TwitchChannel(EmoteManager &emoteManager, IrcManager &ircManager, - const QString &channelName, bool _isSpecial) +TwitchChannel::TwitchChannel(IrcManager &ircManager, const QString &channelName, bool _isSpecial) : Channel(channelName) - , emoteManager(emoteManager) , ircManager(ircManager) , bttvChannelEmotes(new EmoteMap) , ffzChannelEmotes(new EmoteMap) @@ -63,18 +61,22 @@ void TwitchChannel::setRoomID(const QString &_roomID) void TwitchChannel::reloadChannelEmotes() { + auto &emoteManager = EmoteManager::getInstance(); + debug::Log("[TwitchChannel:{}] Reloading channel emotes", this->name); - this->emoteManager.reloadBTTVChannelEmotes(this->name, this->bttvChannelEmotes); - this->emoteManager.reloadFFZChannelEmotes(this->name, this->ffzChannelEmotes); + emoteManager.reloadBTTVChannelEmotes(this->name, this->bttvChannelEmotes); + emoteManager.reloadFFZChannelEmotes(this->name, this->ffzChannelEmotes); } void TwitchChannel::sendMessage(const QString &message) { + auto &emoteManager = EmoteManager::getInstance(); + debug::Log("[TwitchChannel:{}] Send message: {}", this->name, message); // Do last message processing - QString parsedMessage = this->emoteManager.replaceShortCodes(message); + QString parsedMessage = emoteManager.replaceShortCodes(message); this->ircManager.sendMessage(this->name, parsedMessage); } diff --git a/src/twitch/twitchchannel.hpp b/src/twitch/twitchchannel.hpp index 0caa97f03..260f20f64 100644 --- a/src/twitch/twitchchannel.hpp +++ b/src/twitch/twitchchannel.hpp @@ -12,8 +12,8 @@ class TwitchChannel : public Channel QTimer *liveStatusTimer; public: - explicit TwitchChannel(EmoteManager &emoteManager, IrcManager &ircManager, - const QString &channelName, bool _isSpecial = false); + explicit TwitchChannel(IrcManager &ircManager, const QString &channelName, + bool _isSpecial = false); ~TwitchChannel(); void reloadChannelEmotes(); @@ -44,7 +44,6 @@ private: void setLive(bool newLiveStatus); void refreshLiveStatus(); - EmoteManager &emoteManager; IrcManager &ircManager; bool isSpecial; diff --git a/src/twitch/twitchmessagebuilder.cpp b/src/twitch/twitchmessagebuilder.cpp index 6391b1dee..a6e3b70d9 100644 --- a/src/twitch/twitchmessagebuilder.cpp +++ b/src/twitch/twitchmessagebuilder.cpp @@ -17,7 +17,6 @@ namespace chatterino { namespace twitch { TwitchMessageBuilder::TwitchMessageBuilder(TwitchChannel *_channel, Resources &_resources, - EmoteManager &_emoteManager, WindowManager &_windowManager, const Communi::IrcPrivateMessage *_ircMessage, const messages::MessageParseArgs &_args) @@ -26,7 +25,6 @@ TwitchMessageBuilder::TwitchMessageBuilder(TwitchChannel *_channel, Resources &_ , resources(_resources) , windowManager(_windowManager) , colorScheme(this->windowManager.colorScheme) - , emoteManager(_emoteManager) , ircMessage(_ircMessage) , args(_args) , tags(this->ircMessage->tags()) @@ -37,6 +35,7 @@ TwitchMessageBuilder::TwitchMessageBuilder(TwitchChannel *_channel, Resources &_ SharedMessage TwitchMessageBuilder::parse() { SettingsManager &settings = SettingsManager::getInstance(); + EmoteManager &emoteManager = EmoteManager::getInstance(); this->originalMessage = this->ircMessage->content(); @@ -83,7 +82,7 @@ SharedMessage TwitchMessageBuilder::parse() QStringList emoteString = iterator.value().toString().split('/'); for (QString emote : emoteString) { - this->appendTwitchEmote(ircMessage, emote, twitchEmotes, emoteManager); + this->appendTwitchEmote(ircMessage, emote, twitchEmotes); } struct { @@ -172,14 +171,10 @@ SharedMessage TwitchMessageBuilder::parse() LazyLoadedImage *imageAnimated = emoteManager.miscImageCache.getOrAdd( bitsLinkAnimated, [this, &bitsLinkAnimated] { - return new LazyLoadedImage(this->emoteManager, this->windowManager, - bitsLinkAnimated); - }); - LazyLoadedImage *image = - emoteManager.miscImageCache.getOrAdd(bitsLink, [this, &bitsLink] { - return new LazyLoadedImage(this->emoteManager, this->windowManager, - bitsLink); + return new LazyLoadedImage(bitsLinkAnimated); }); + LazyLoadedImage *image = emoteManager.miscImageCache.getOrAdd( + bitsLink, [this, &bitsLink] { return new LazyLoadedImage(bitsLink); }); this->appendWord(Word(imageAnimated, Word::BitsAnimated, QString("cheer"), QString("Twitch Cheer"), @@ -464,9 +459,9 @@ void TwitchMessageBuilder::appendModerationButtons() void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage, const QString &emote, - std::vector> &vec, - EmoteManager &emoteManager) + std::vector> &vec) { + EmoteManager &emoteManager = EmoteManager::getInstance(); if (!emote.contains(':')) { return; } @@ -504,6 +499,7 @@ void TwitchMessageBuilder::appendTwitchEmote(const Communi::IrcPrivateMessage *i bool TwitchMessageBuilder::tryAppendEmote(QString &emoteString) { + EmoteManager &emoteManager = EmoteManager::getInstance(); EmoteData emoteData; if (emoteManager.bttvGlobalEmotes.tryGet(emoteString, emoteData)) { diff --git a/src/twitch/twitchmessagebuilder.hpp b/src/twitch/twitchmessagebuilder.hpp index 6ddc35055..3a04c3ac1 100644 --- a/src/twitch/twitchmessagebuilder.hpp +++ b/src/twitch/twitchmessagebuilder.hpp @@ -1,6 +1,5 @@ #pragma once -#include "emotemanager.hpp" #include "messages/messagebuilder.hpp" #include "messages/messageparseargs.hpp" #include "resources.hpp" @@ -29,7 +28,7 @@ public: TwitchMessageBuilder() = delete; explicit TwitchMessageBuilder(TwitchChannel *_channel, Resources &_resources, - EmoteManager &_emoteManager, WindowManager &_windowManager, + WindowManager &_windowManager, const Communi::IrcPrivateMessage *_ircMessage, const messages::MessageParseArgs &_args); @@ -38,7 +37,6 @@ public: Resources &resources; WindowManager &windowManager; ColorScheme &colorScheme; - EmoteManager &emoteManager; const Communi::IrcPrivateMessage *ircMessage; messages::MessageParseArgs args; const QVariantMap tags; @@ -66,8 +64,7 @@ private: void appendModerationButtons(); void appendTwitchEmote(const Communi::IrcPrivateMessage *ircMessage, const QString &emote, - std::vector> &vec, - EmoteManager &emoteManager); + std::vector> &vec); bool tryAppendEmote(QString &emoteString); bool appendEmote(EmoteData &emoteData); diff --git a/src/widgets/emotepopup.cpp b/src/widgets/emotepopup.cpp index c812f0e1f..6ea249fbb 100644 --- a/src/widgets/emotepopup.cpp +++ b/src/widgets/emotepopup.cpp @@ -11,10 +11,8 @@ using namespace chatterino::messages; namespace chatterino { namespace widgets { -EmotePopup::EmotePopup(ColorScheme &colorScheme, EmoteManager &emoteManager, - WindowManager &windowManager) +EmotePopup::EmotePopup(ColorScheme &colorScheme) : BaseWidget(colorScheme, 0) - , emoteManager(emoteManager) { this->initAsWindow(); @@ -22,8 +20,8 @@ EmotePopup::EmotePopup(ColorScheme &colorScheme, EmoteManager &emoteManager, this->setLayout(layout); layout->setMargin(0); - view = new ChannelView(windowManager, this); - layout->addWidget(view); + this->view = new ChannelView(this); + layout->addWidget(this->view); } void EmotePopup::loadChannel(std::shared_ptr _channel) @@ -58,18 +56,20 @@ void EmotePopup::loadChannel(std::shared_ptr _channel) emoteChannel->addMessage(builder2.getMessage()); }; - addEmotes(this->emoteManager.bttvGlobalEmotes, "BetterTTV Global Emotes", - "BetterTTV Global Emote"); + EmoteManager &emoteManager = EmoteManager::getInstance(); + + addEmotes(emoteManager.bttvGlobalEmotes, "BetterTTV Global Emotes", "BetterTTV Global Emote"); addEmotes(*channel->bttvChannelEmotes.get(), "BetterTTV Channel Emotes", "BetterTTV Channel Emote"); - addEmotes(this->emoteManager.ffzGlobalEmotes, "FrankerFaceZ Global Emotes", + addEmotes(emoteManager.ffzGlobalEmotes, "FrankerFaceZ Global Emotes", "FrankerFaceZ Global Emote"); addEmotes(*channel->ffzChannelEmotes.get(), "FrankerFaceZ Channel Emotes", "FrankerFaceZ Channel Emote"); - // addEmotes(this->emoteManager.getEmojis(), "Emojis", "Emoji"); + // addEmotes(emoteManager.getEmojis(), "Emojis", "Emoji"); this->view->setChannel(emoteChannel); } + } // namespace widgets } // namespace chatterino diff --git a/src/widgets/emotepopup.hpp b/src/widgets/emotepopup.hpp index 373fcd1ac..282f1ddc5 100644 --- a/src/widgets/emotepopup.hpp +++ b/src/widgets/emotepopup.hpp @@ -1,7 +1,6 @@ #pragma once #include "channel.hpp" -#include "emotemanager.hpp" #include "widgets/basewidget.hpp" #include "widgets/helper/channelview.hpp" @@ -11,13 +10,13 @@ namespace widgets { class EmotePopup : public BaseWidget { public: - explicit EmotePopup(ColorScheme &, EmoteManager &, WindowManager &); + explicit EmotePopup(ColorScheme &); void loadChannel(std::shared_ptr channel); private: ChannelView *view; - EmoteManager &emoteManager; }; -} -} + +} // namespace widgets +} // namespace chatterino diff --git a/src/widgets/helper/channelview.cpp b/src/widgets/helper/channelview.cpp index 4e7d94fe0..fea69dbbe 100644 --- a/src/widgets/helper/channelview.cpp +++ b/src/widgets/helper/channelview.cpp @@ -28,9 +28,8 @@ using namespace chatterino::messages; namespace chatterino { namespace widgets { -ChannelView::ChannelView(WindowManager &windowManager, BaseWidget *parent) +ChannelView::ChannelView(BaseWidget *parent) : BaseWidget(parent) - , windowManager(windowManager) , scrollBar(this) , userPopupWidget(std::shared_ptr()) { @@ -51,6 +50,8 @@ ChannelView::ChannelView(WindowManager &windowManager, BaseWidget *parent) this->queueUpdate(); }); + WindowManager &windowManager = *WindowManager::instance; + this->repaintGifsConnection = windowManager.repaintGifs.connect([&] { this->updateGifEmotes(); }); this->layoutConnection = windowManager.layout.connect([&] { this->layoutMessages(); }); @@ -240,9 +241,8 @@ QString ChannelView::getSelectedText() if (first) { first = false; - bool isSingleWord = - isSingleMessage && - this->selection.max.charIndex - charIndex < part.getCharacterLength(); + bool isSingleWord = isSingleMessage && this->selection.max.charIndex - charIndex < + part.getCharacterLength(); if (isSingleWord) { // return single word @@ -519,10 +519,9 @@ void ChannelView::updateMessageBuffer(messages::MessageRef *messageRef, QPixmap // this->selectionMax.messageIndex >= messageIndex) { // painter.fillRect(buffer->rect(), QColor(24, 55, 25)); //} else { - painter.fillRect(buffer->rect(), - (messageRef->getMessage()->getCanHighlightTab()) - ? this->colorScheme.ChatBackgroundHighlighted - : this->colorScheme.ChatBackground); + painter.fillRect(buffer->rect(), (messageRef->getMessage()->getCanHighlightTab()) + ? this->colorScheme.ChatBackgroundHighlighted + : this->colorScheme.ChatBackground); //} // draw selection diff --git a/src/widgets/helper/channelview.hpp b/src/widgets/helper/channelview.hpp index 95ab2b671..fe86c7a9d 100644 --- a/src/widgets/helper/channelview.hpp +++ b/src/widgets/helper/channelview.hpp @@ -85,7 +85,7 @@ class ChannelView : public BaseWidget Q_OBJECT public: - explicit ChannelView(WindowManager &windowManager, BaseWidget *parent = 0); + explicit ChannelView(BaseWidget *parent = 0); ~ChannelView(); void updateGifEmotes(); @@ -123,7 +123,6 @@ private: QRect rect; }; - WindowManager &windowManager; QTimer updateTimer; bool updateQueued = false; diff --git a/src/widgets/helper/splitinput.cpp b/src/widgets/helper/splitinput.cpp index e505b7831..d4e5f3526 100644 --- a/src/widgets/helper/splitinput.cpp +++ b/src/widgets/helper/splitinput.cpp @@ -13,11 +13,9 @@ namespace chatterino { namespace widgets { -SplitInput::SplitInput(Split *_chatWidget, EmoteManager &emoteManager, WindowManager &windowManager) +SplitInput::SplitInput(Split *_chatWidget) : BaseWidget(_chatWidget) , chatWidget(_chatWidget) - , emoteManager(emoteManager) - , windowManager(windowManager) , emotesLabel(this) { this->setMaximumHeight(150); @@ -55,8 +53,7 @@ SplitInput::SplitInput(Split *_chatWidget, EmoteManager &emoteManager, WindowMan connect(&this->emotesLabel, &RippleEffectLabel::clicked, [this] { if (this->emotePopup == nullptr) { - this->emotePopup = - new EmotePopup(this->colorScheme, this->emoteManager, this->windowManager); + this->emotePopup = new EmotePopup(this->colorScheme); } this->emotePopup->resize(300, 500); @@ -69,8 +66,8 @@ SplitInput::SplitInput(Split *_chatWidget, EmoteManager &emoteManager, WindowMan this->refreshTheme(); textLengthLabel.setHidden(!SettingsManager::getInstance().showMessageLength); - auto completer = new QCompleter( - this->chatWidget->completionManager.createModel(this->chatWidget->channelName)); + auto completer = + new QCompleter(CompletionManager::getInstance().createModel(this->chatWidget->channelName)); this->textInput.setCompleter(completer); diff --git a/src/widgets/helper/splitinput.hpp b/src/widgets/helper/splitinput.hpp index 278f2e4da..985b70685 100644 --- a/src/widgets/helper/splitinput.hpp +++ b/src/widgets/helper/splitinput.hpp @@ -1,6 +1,5 @@ #pragma once -#include "emotemanager.hpp" #include "resizingtextedit.hpp" #include "widgets/basewidget.hpp" #include "widgets/emotepopup.hpp" @@ -26,7 +25,7 @@ class SplitInput : public BaseWidget Q_OBJECT public: - SplitInput(Split *_chatWidget, EmoteManager &, WindowManager &); + SplitInput(Split *_chatWidget); ~SplitInput(); void clearSelection(); @@ -40,8 +39,6 @@ protected: private: Split *const chatWidget; EmotePopup *emotePopup = nullptr; - EmoteManager &emoteManager; - WindowManager &windowManager; pajlada::Signals::Signal::Connection textLengthVisibleChangedConnection; QHBoxLayout hbox; diff --git a/src/widgets/notebook.cpp b/src/widgets/notebook.cpp index fc220adf0..ba7d2e6bd 100644 --- a/src/widgets/notebook.cpp +++ b/src/widgets/notebook.cpp @@ -22,7 +22,6 @@ namespace widgets { Notebook::Notebook(ChannelManager &_channelManager, Window *parent, bool _showButtons) : BaseWidget(parent) , channelManager(_channelManager) - , completionManager(parent->completionManager) , addButton(this) , settingsButton(this) , userButton(this) diff --git a/src/widgets/notebook.hpp b/src/widgets/notebook.hpp index 93582422a..ba14d94e4 100644 --- a/src/widgets/notebook.hpp +++ b/src/widgets/notebook.hpp @@ -12,7 +12,6 @@ namespace chatterino { class ChannelManager; -class CompletionManager; namespace widgets { @@ -58,7 +57,6 @@ public slots: public: ChannelManager &channelManager; - CompletionManager &completionManager; private: QList pages; diff --git a/src/widgets/split.cpp b/src/widgets/split.cpp index 252c00e80..931f6331e 100644 --- a/src/widgets/split.cpp +++ b/src/widgets/split.cpp @@ -52,12 +52,11 @@ Split::Split(ChannelManager &_channelManager, SplitContainer *parent) , channelName("/chatWidgets/" + std::to_string(index++) + "/channelName") , parentPage(*parent) , channelManager(_channelManager) - , completionManager(parent->completionManager) , channel(_channelManager.emptyChannel) , vbox(this) , header(this) - , view(_channelManager.getWindowManager(), this) - , input(this, _channelManager.getEmoteManager(), _channelManager.getWindowManager()) + , view(this) + , input(this) , flexSizeX(1) , flexSizeY(1) { diff --git a/src/widgets/split.hpp b/src/widgets/split.hpp index 31b0eef35..92086737a 100644 --- a/src/widgets/split.hpp +++ b/src/widgets/split.hpp @@ -22,7 +22,6 @@ namespace chatterino { class ChannelManager; class ColorScheme; -class CompletionManager; namespace widgets { @@ -49,7 +48,6 @@ public: ~Split(); ChannelManager &channelManager; - CompletionManager &completionManager; pajlada::Settings::Setting channelName; boost::signals2::signal channelChanged; diff --git a/src/widgets/splitcontainer.cpp b/src/widgets/splitcontainer.cpp index 46303eefd..0c1c0fcf9 100644 --- a/src/widgets/splitcontainer.cpp +++ b/src/widgets/splitcontainer.cpp @@ -26,7 +26,6 @@ std::pair SplitContainer::dropPosition = std::pair(-1, -1); SplitContainer::SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab) : BaseWidget(parent->colorScheme, parent) , channelManager(_channelManager) - , completionManager(parent->completionManager) , tab(_tab) , dropPreview(this) , chatWidgets() diff --git a/src/widgets/splitcontainer.hpp b/src/widgets/splitcontainer.hpp index 91c28ccc3..8482e4d56 100644 --- a/src/widgets/splitcontainer.hpp +++ b/src/widgets/splitcontainer.hpp @@ -17,7 +17,6 @@ namespace chatterino { class ChannelManager; -class CompletionManager; namespace widgets { @@ -29,7 +28,6 @@ public: SplitContainer(ChannelManager &_channelManager, Notebook *parent, NotebookTab *_tab); ChannelManager &channelManager; - CompletionManager &completionManager; std::pair removeFromLayout(Split *widget); void addToLayout(Split *widget, std::pair position = std::pair(-1, -1)); diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index 8de0ae4fb..bbd805496 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -2,9 +2,9 @@ #include "channelmanager.hpp" #include "colorscheme.hpp" #include "settingsmanager.hpp" -#include "widgets/split.hpp" #include "widgets/notebook.hpp" #include "widgets/settingsdialog.hpp" +#include "widgets/split.hpp" #include #include @@ -16,12 +16,10 @@ namespace chatterino { namespace widgets { -Window::Window(ChannelManager &_channelManager, ColorScheme &_colorScheme, - CompletionManager &_completionManager, bool _isMainWindow) +Window::Window(ChannelManager &_channelManager, ColorScheme &_colorScheme, bool _isMainWindow) : BaseWidget(_colorScheme, nullptr) , channelManager(_channelManager) , colorScheme(_colorScheme) - , completionManager(_completionManager) , notebook(this->channelManager, this, _isMainWindow) , dpi(this->getDpiMultiplier()) // , windowGeometry("/windows/0/geometry") diff --git a/src/widgets/window.hpp b/src/widgets/window.hpp index e1ea34e0a..a9c747e3e 100644 --- a/src/widgets/window.hpp +++ b/src/widgets/window.hpp @@ -26,8 +26,7 @@ class Window : public BaseWidget Q_OBJECT public: - explicit Window(ChannelManager &_channelManager, ColorScheme &_colorScheme, - CompletionManager &_completionManager, bool isMainWindow); + explicit Window(ChannelManager &_channelManager, ColorScheme &_colorScheme, bool isMainWindow); void repaintVisibleChatWidgets(Channel *channel = nullptr); @@ -51,7 +50,6 @@ private: ChannelManager &channelManager; ColorScheme &colorScheme; - CompletionManager &completionManager; Notebook notebook; bool loaded = false; diff --git a/src/windowmanager.cpp b/src/windowmanager.cpp index 93c511d61..3ef4e07b2 100644 --- a/src/windowmanager.cpp +++ b/src/windowmanager.cpp @@ -11,11 +11,9 @@ namespace chatterino { WindowManager *WindowManager::instance = nullptr; -WindowManager::WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme, - CompletionManager &_completionManager) +WindowManager::WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme) : channelManager(_channelManager) , colorScheme(_colorScheme) - , completionManager(_completionManager) { WindowManager::instance = this; } @@ -23,7 +21,7 @@ WindowManager::WindowManager(ChannelManager &_channelManager, ColorScheme &_colo void WindowManager::initMainWindow() { this->selectedWindow = this->mainWindow = - new widgets::Window(this->channelManager, this->colorScheme, this->completionManager, true); + new widgets::Window(this->channelManager, this->colorScheme, true); } static const std::string &getSettingsPath() @@ -69,8 +67,7 @@ widgets::Window &WindowManager::getSelectedWindow() widgets::Window &WindowManager::createWindow() { - auto *window = new widgets::Window(this->channelManager, this->colorScheme, - this->completionManager, false); + auto *window = new widgets::Window(this->channelManager, this->colorScheme, false); window->loadDefaults(); diff --git a/src/windowmanager.hpp b/src/windowmanager.hpp index b819103e5..28b121d6d 100644 --- a/src/windowmanager.hpp +++ b/src/windowmanager.hpp @@ -11,14 +11,12 @@ class CompletionManager; class WindowManager { public: - explicit WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme, - CompletionManager &_completionManager); + explicit WindowManager(ChannelManager &_channelManager, ColorScheme &_colorScheme); static WindowManager *instance; ChannelManager &channelManager; ColorScheme &colorScheme; - CompletionManager &completionManager; void layoutVisibleChatWidgets(Channel *channel = nullptr); void repaintVisibleChatWidgets(Channel *channel = nullptr);