diff --git a/src/fontmanager.cpp b/src/fontmanager.cpp index 6c060c698..e0005dc34 100644 --- a/src/fontmanager.cpp +++ b/src/fontmanager.cpp @@ -1,63 +1,61 @@ #include "fontmanager.hpp" -#define DEFAULT_FONT "Arial" +#include namespace chatterino { -FontManager FontManager::instance; - FontManager::FontManager() - : _generation(0) + : currentFontFamily("/appearance/currentFontFamily", "Arial") + , currentFontSize("/appearance/currentFontSize", 14) + , currentFont(this->currentFontFamily.getValue().c_str(), currentFontSize.getValue()) { - _medium = new QFont(DEFAULT_FONT, 14); - _mediumBold = new QFont(DEFAULT_FONT, 14); - _mediumItalic = new QFont(DEFAULT_FONT, 14); - _small = new QFont(DEFAULT_FONT, 10); - _large = new QFont(DEFAULT_FONT, 16); - _veryLarge = new QFont(DEFAULT_FONT, 18); - - _metricsMedium = new QFontMetrics(*_medium); - _metricsMediumBold = new QFontMetrics(*_mediumBold); - _metricsMediumItalic = new QFontMetrics(*_mediumItalic); - _metricsSmall = new QFontMetrics(*_small); - _metricsLarge = new QFontMetrics(*_large); - _metricsVeryLarge = new QFontMetrics(*_veryLarge); + this->currentFontFamily.valueChanged.connect([this](const std::string &newValue) { + this->currentFont.setFamily(newValue.c_str()); // + }); + this->currentFontSize.valueChanged.connect([this](const int &newValue) { + this->currentFont.setSize(newValue); // + }); } QFont &FontManager::getFont(Type type) { - if (type == Medium) - return *_medium; - if (type == MediumBold) - return *_mediumBold; - if (type == MediumItalic) - return *_mediumItalic; - if (type == Small) - return *_small; - if (type == Large) - return *_large; - if (type == VeryLarge) - return *_veryLarge; - - return *_medium; + return this->currentFont.getFont(type); } QFontMetrics &FontManager::getFontMetrics(Type type) { - if (type == Medium) - return *_metricsMedium; - if (type == MediumBold) - return *_metricsMediumBold; - if (type == MediumItalic) - return *_metricsMediumItalic; - if (type == Small) - return *_metricsSmall; - if (type == Large) - return *_metricsLarge; - if (type == VeryLarge) - return *_metricsVeryLarge; + return this->currentFont.getFontMetrics(type); +} - return *_metricsMedium; +FontManager::FontData &FontManager::Font::getFontData(Type type) +{ + switch (type) { + case Small: + return this->small; + case Medium: + return this->medium; + case MediumBold: + return this->mediumBold; + case MediumItalic: + return this->mediumItalic; + case Large: + return this->large; + case VeryLarge: + return this->veryLarge; + default: + qDebug() << "Unknown font type:" << type << ", defaulting to medium"; + return this->medium; + } +} + +QFont &FontManager::Font::getFont(Type type) +{ + return this->getFontData(type).font; +} + +QFontMetrics &FontManager::Font::getFontMetrics(Type type) +{ + return this->getFontData(type).metrics; } } // namespace chatterino diff --git a/src/fontmanager.hpp b/src/fontmanager.hpp index 2ca41e4a3..118086c6d 100644 --- a/src/fontmanager.hpp +++ b/src/fontmanager.hpp @@ -2,52 +2,126 @@ #include #include +#include namespace chatterino { class FontManager { public: - enum Type : char { Medium, MediumBold, MediumItalic, Small, Large, VeryLarge }; + enum Type : uint8_t { + Small, + Medium, + MediumBold, + MediumItalic, + Large, + VeryLarge, + }; + // FontManager is initialized only once, on first use static FontManager &getInstance() { + static FontManager instance; + return instance; } QFont &getFont(Type type); QFontMetrics &getFontMetrics(Type type); - int getGeneration() + int getGeneration() const { - return _generation; + return this->generation; } void incGeneration() { - _generation++; + this->generation++; } -private: - static FontManager instance; + pajlada::Settings::Setting currentFontFamily; + pajlada::Settings::Setting currentFontSize; +private: FontManager(); - QFont *_medium; - QFont *_mediumBold; - QFont *_mediumItalic; - QFont *_small; - QFont *_large; - QFont *_veryLarge; + struct FontData { + FontData(QFont &&_font) + : font(_font) + , metrics(this->font) + { + } - QFontMetrics *_metricsMedium; - QFontMetrics *_metricsMediumBold; - QFontMetrics *_metricsMediumItalic; - QFontMetrics *_metricsSmall; - QFontMetrics *_metricsLarge; - QFontMetrics *_metricsVeryLarge; + QFont font; + QFontMetrics metrics; + }; - int _generation; + struct Font { + Font() = delete; + + explicit Font(const char *fontFamilyName, int mediumSize) + : small(QFont(fontFamilyName, mediumSize - 4)) + , medium(QFont(fontFamilyName, mediumSize)) + , mediumBold(QFont(fontFamilyName, mediumSize, 50)) + , mediumItalic(QFont(fontFamilyName, mediumSize, -1, true)) + , large(QFont(fontFamilyName, mediumSize)) + , veryLarge(QFont(fontFamilyName, mediumSize)) + { + } + + void setFamily(const char *newFamily) + { + this->small.font.setFamily(newFamily); + this->medium.font.setFamily(newFamily); + this->mediumBold.font.setFamily(newFamily); + this->mediumItalic.font.setFamily(newFamily); + this->large.font.setFamily(newFamily); + this->veryLarge.font.setFamily(newFamily); + + this->updateMetrics(); + } + + void setSize(int newMediumSize) + { + this->small.font.setPointSize(newMediumSize - 4); + this->medium.font.setPointSize(newMediumSize); + this->mediumBold.font.setPointSize(newMediumSize); + this->mediumItalic.font.setPointSize(newMediumSize); + this->large.font.setPointSize(newMediumSize + 2); + this->veryLarge.font.setPointSize(newMediumSize + 4); + + this->updateMetrics(); + } + + void updateMetrics() + { + this->small.metrics = QFontMetrics(this->small.font); + this->medium.metrics = QFontMetrics(this->medium.font); + this->mediumBold.metrics = QFontMetrics(this->mediumBold.font); + this->mediumItalic.metrics = QFontMetrics(this->mediumItalic.font); + this->large.metrics = QFontMetrics(this->large.font); + this->veryLarge.metrics = QFontMetrics(this->veryLarge.font); + } + + FontData &getFontData(Type type); + + QFont &getFont(Type type); + QFontMetrics &getFontMetrics(Type type); + + FontData small; + FontData medium; + FontData mediumBold; + FontData mediumItalic; + FontData large; + FontData veryLarge; + }; + + // Future plans: + // Could have multiple fonts in here, such as "Menu font", "Application font", "Chat font" + + Font currentFont; + + int generation = 0; }; } // namespace chatterino diff --git a/src/resources.cpp b/src/resources.cpp index 11e46bfbe..6b75afd76 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -18,27 +18,29 @@ inline messages::LazyLoadedImage *lli(EmoteManager &emoteManager, WindowManager } // namespace -Resources::Resources(EmoteManager &emoteManager, WindowManager &windowManager) - : badgeStaff(lli(emoteManager, windowManager, ":/images/staff_bg.png")) - , badgeAdmin(lli(emoteManager, windowManager, ":/images/admin_bg.png")) - , badgeGlobalModerator(lli(emoteManager, windowManager, ":/images/globalmod_bg.png")) - , badgeModerator(lli(emoteManager, windowManager, ":/images/moderator_bg.png")) - , badgeTurbo(lli(emoteManager, windowManager, ":/images/turbo_bg.png")) - , badgeBroadcaster(lli(emoteManager, windowManager, ":/images/broadcaster_bg.png")) - , badgePremium(lli(emoteManager, windowManager, ":/images/twitchprime_bg.png")) - , badgeVerified(lli(emoteManager, windowManager, ":/images/verified.png", 0.25)) - , cheerBadge100000(lli(emoteManager, windowManager, ":/images/cheer100000")) - , cheerBadge10000(lli(emoteManager, windowManager, ":/images/cheer10000")) - , cheerBadge5000(lli(emoteManager, windowManager, ":/images/cheer5000")) - , cheerBadge1000(lli(emoteManager, windowManager, ":/images/cheer1000")) - , cheerBadge100(lli(emoteManager, windowManager, ":/images/cheer100")) - , cheerBadge1(lli(emoteManager, windowManager, ":/images/cheer1")) - , buttonBan(lli(emoteManager, windowManager, ":/images/button_ban.png", 0.25)) - , buttonTimeout(lli(emoteManager, windowManager, ":/images/button_timeout.png", 0.25)) +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)) + , 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)) { QString badgesUrl("https://badges.twitch.tv/v1/badges/global/display?language=en"); - util::urlJsonFetch(badgesUrl, [this, &emoteManager, &windowManager](QJsonObject &root) { + util::urlJsonFetch(badgesUrl, [this](QJsonObject &root) { QJsonObject sets = root.value("badge_sets").toObject(); for (QJsonObject::iterator it = sets.begin(); it != sets.end(); ++it) { @@ -51,7 +53,7 @@ Resources::Resources(EmoteManager &emoteManager, WindowManager &windowManager) ++versionIt) { std::string kkey = versionIt.key().toStdString(); QJsonObject versionObj = versionIt.value().toObject(); - BadgeVersion v(std::move(versionObj), emoteManager, windowManager); + BadgeVersion v(std::move(versionObj), this->emoteManager, this->windowManager); versionsMap.emplace(kkey, v); } } @@ -75,24 +77,35 @@ Resources::BadgeVersion::BadgeVersion(QJsonObject &&root, EmoteManager &emoteMan { } -void Resources::Channel::loadData() -{ - /* - if (this->loaded) { - return; - } - - this->loaded = true; - - if (this->id.empty()) { - //util::urlJsonFetch() - } - */ -} - void Resources::loadChannelData(const std::string &roomID, bool bypassCache) { qDebug() << "Load channel data for" << QString::fromStdString(roomID); + + // Step 1: Get + + QString url = "https://badges.twitch.tv/v1/badges/channels/" + QString::fromStdString(roomID) + + "/display?language=en"; + + util::urlJsonFetch(url, [this](QJsonObject &root) { + QJsonObject sets = root.value("badge_sets").toObject(); + + for (QJsonObject::iterator it = sets.begin(); it != sets.end(); ++it) { + QJsonObject versions = it.value().toObject().value("versions").toObject(); + + auto &badgeSet = this->badgeSets[it.key().toStdString()]; + auto &versionsMap = badgeSet.versions; + + for (auto versionIt = std::begin(versions); versionIt != std::end(versions); + ++versionIt) { + std::string kkey = versionIt.key().toStdString(); + QJsonObject versionObj = versionIt.value().toObject(); + BadgeVersion v(std::move(versionObj), this->emoteManager, this->windowManager); + versionsMap.emplace(kkey, v); + } + } + + this->dynamicBadgesLoaded = true; + }); } } // namespace chatterino diff --git a/src/resources.hpp b/src/resources.hpp index e9bd4eade..a7608c4b1 100644 --- a/src/resources.hpp +++ b/src/resources.hpp @@ -12,6 +12,9 @@ class WindowManager; class Resources { + EmoteManager &emoteManager; + WindowManager &windowManager; + public: explicit Resources(EmoteManager &emoteManager, WindowManager &windowManager); @@ -60,13 +63,9 @@ public: messages::LazyLoadedImage *buttonTimeout; struct Channel { - std::string id; + std::map badgeSets; - std::mutex globalMapMutex; - - void loadData(); - - // std::atomic loaded = false; + bool loaded = false; }; // channelId diff --git a/src/twitch/twitchmessagebuilder.cpp b/src/twitch/twitchmessagebuilder.cpp index dd12bb203..d7867f0f5 100644 --- a/src/twitch/twitchmessagebuilder.cpp +++ b/src/twitch/twitchmessagebuilder.cpp @@ -95,7 +95,7 @@ SharedMessage TwitchMessageBuilder::parse(const Communi::IrcPrivateMessage *ircM iterator = tags.find("display-name"); if (iterator == tags.end()) { - displayName = ircMessage->account(); + displayName = b.userName; } else { displayName = iterator.value().toString(); } diff --git a/src/widgets/settingsdialog.cpp b/src/widgets/settingsdialog.cpp index 4d1e11171..6f6bf81fb 100644 --- a/src/widgets/settingsdialog.cpp +++ b/src/widgets/settingsdialog.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,22 @@ void SettingsDialog::addTabs() auto form = new QFormLayout(); auto combo = new QComboBox(); auto slider = new QSlider(Qt::Horizontal); + auto font = new QPushButton("select"); + font->connect(font, &QPushButton::clicked, []() { + auto fontManager = FontManager::getInstance(); + QFontDialog dialog(fontManager.getFont(FontManager::Medium)); + + dialog.connect(&dialog, &QFontDialog::fontSelected, [&dialog](const QFont &font) { + auto fontManager = FontManager::getInstance(); + fontManager.currentFontFamily = font.family().toStdString(); + fontManager.currentFontSize = font.pointSize(); + }); + + dialog.show(); + dialog.exec(); + }); + auto compactTabs = createCheckbox("Hide tab X", settings.hideTabX); auto hidePreferencesButton = createCheckbox("Hide preferences button (ctrl+p to show)", settings.hidePreferencesButton);