From 5c55f62600d60d14bd08c385e5d90ef772932980 Mon Sep 17 00:00:00 2001 From: kornes <28986062+kornes@users.noreply.github.com> Date: Sat, 8 Apr 2023 13:43:38 +0000 Subject: [PATCH] Fix emote & badge tooltips not showing up when thumbnails were hidden (#4509) Co-authored-by: Rasmus Karlsson --- CHANGELOG.md | 1 + src/singletons/Settings.hpp | 14 ++- src/widgets/helper/ChannelView.cpp | 141 ++++++++++++---------- src/widgets/settingspages/GeneralPage.cpp | 24 +++- 4 files changed, 106 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17e2dc96..e3377e24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Bugfix: Fixed blocked user list sticking around when switching from a logged in user to being logged out. (#4437) - Bugfix: Fixed search popup ignoring setting for message scrollback limit. (#4496) - Bugfix: Fixed a memory leak that occurred when loading message history. This was mostly noticeable with unstable internet connections where reconnections were frequent or long-running instances of Chatterino. (#4499) +- Bugfix: Fixed emote & badge tooltips not showing up when thumbnails were hidden. (#4509) - Dev: Disabling precompiled headers on Windows is now tested in CI. (#4472) - Dev: Themes are now stored as JSON files in `resources/themes`. (#4471) - Dev: Ignore unhandled BTTV user-events. (#4438) diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index 46768141..3ac50388 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -74,6 +74,14 @@ enum HelixTimegateOverride : int { AlwaysUseHelix = 3, }; +enum ThumbnailPreviewMode : int { + DontShow = 0, + + AlwaysShow = 1, + + ShowOnShift = 2, +}; + /// Settings which are availlable for reading and writing on the gui thread. // These settings are still accessed concurrently in the code but it is bad practice. class Settings : public ABSettings, public ConcurrentSettings @@ -217,7 +225,6 @@ public: FloatSetting emoteScale = {"/emotes/scale", 1.f}; BoolSetting showUnlistedSevenTVEmotes = { "/emotes/showUnlistedSevenTVEmotes", false}; - QStringSetting emojiSet = {"/emotes/emojiSet", "Twitter"}; BoolSetting stackBits = {"/emotes/stackBits", false}; @@ -478,9 +485,12 @@ public: HelixTimegateOverride::Timegate, }; - IntSetting emotesTooltipPreview = {"/misc/emotesTooltipPreview", 1}; BoolSetting openLinksIncognito = {"/misc/openLinksIncognito", 0}; + EnumSetting emotesTooltipPreview = { + "/misc/emotesTooltipPreview", + ThumbnailPreviewMode::AlwaysShow, + }; QStringSetting cachePath = {"/cache/path", ""}; BoolSetting restartOnCrash = {"/misc/restartOnCrash", false}; BoolSetting attachExtensionToAnyProcess = { diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index a534db3e..b05b8623 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -1672,81 +1672,88 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event) { auto badgeElement = dynamic_cast(element); - if ((badgeElement || emoteElement || layeredEmoteElement) && - getSettings()->emotesTooltipPreview.getValue()) + if (badgeElement || emoteElement || layeredEmoteElement) { - if (event->modifiers() == Qt::ShiftModifier || - getSettings()->emotesTooltipPreview.getValue() == 1) + auto showThumbnailSetting = + getSettings()->emotesTooltipPreview.getValue(); + + bool showThumbnail = + showThumbnailSetting == ThumbnailPreviewMode::AlwaysShow || + (showThumbnailSetting == ThumbnailPreviewMode::ShowOnShift && + event->modifiers() == Qt::ShiftModifier); + + if (emoteElement) { - if (emoteElement) + tooltipWidget->setOne({ + showThumbnail + ? emoteElement->getEmote()->images.getImage(3.0) + : nullptr, + element->getTooltip(), + }); + } + else if (layeredEmoteElement) + { + auto &layeredEmotes = layeredEmoteElement->getEmotes(); + // Should never be empty but ensure it + if (!layeredEmotes.empty()) { - tooltipWidget->setOne({ - emoteElement->getEmote()->images.getImage(3.0), - element->getTooltip(), - }); - } - else if (layeredEmoteElement) - { - auto &layeredEmotes = layeredEmoteElement->getEmotes(); - // Should never be empty but ensure it - if (!layeredEmotes.empty()) + std::vector entries; + entries.reserve(layeredEmotes.size()); + + auto &emoteTooltips = + layeredEmoteElement->getEmoteTooltips(); + + // Someone performing some tomfoolery could put an emote with tens, + // if not hundreds of zero-width emotes on a single emote. If the + // tooltip may take up more than three rows, truncate everything else. + bool truncating = false; + size_t upperLimit = layeredEmotes.size(); + if (layeredEmotes.size() > TOOLTIP_EMOTE_ENTRIES_LIMIT) { - std::vector entries; - entries.reserve(layeredEmotes.size()); - - auto &emoteTooltips = - layeredEmoteElement->getEmoteTooltips(); - - // Someone performing some tomfoolery could put an emote with tens, - // if not hundreds of zero-width emotes on a single emote. If the - // tooltip may take up more than three rows, truncate everything else. - bool truncating = false; - size_t upperLimit = layeredEmotes.size(); - if (layeredEmotes.size() > TOOLTIP_EMOTE_ENTRIES_LIMIT) - { - upperLimit = TOOLTIP_EMOTE_ENTRIES_LIMIT - 1; - truncating = true; - } - - for (size_t i = 0; i < upperLimit; ++i) - { - const auto &emote = layeredEmotes[i].ptr; - if (i == 0) - { - // First entry gets a large image and full description - entries.push_back({emote->images.getImage(3.0), - emoteTooltips[i]}); - } - else - { - // Every other entry gets a small image and just the emote name - entries.push_back({emote->images.getImage(1.0), - emote->name.string}); - } - } - - if (truncating) - { - entries.push_back({nullptr, "..."}); - } - - auto style = layeredEmotes.size() > 2 - ? TooltipStyle::Grid - : TooltipStyle::Vertical; - tooltipWidget->set(entries, style); + upperLimit = TOOLTIP_EMOTE_ENTRIES_LIMIT - 1; + truncating = true; } - } - else if (badgeElement) - { - tooltipWidget->setOne({ - badgeElement->getEmote()->images.getImage(3.0), - element->getTooltip(), - }); + + for (size_t i = 0; i < upperLimit; ++i) + { + const auto &emote = layeredEmotes[i].ptr; + if (i == 0) + { + // First entry gets a large image and full description + entries.push_back({showThumbnail + ? emote->images.getImage(3.0) + : nullptr, + emoteTooltips[i]}); + } + else + { + // Every other entry gets a small image and just the emote name + entries.push_back({showThumbnail + ? emote->images.getImage(1.0) + : nullptr, + emote->name.string}); + } + } + + if (truncating) + { + entries.push_back({nullptr, "..."}); + } + + auto style = layeredEmotes.size() > 2 + ? TooltipStyle::Grid + : TooltipStyle::Vertical; + tooltipWidget->set(entries, style); } } - else + else if (badgeElement) { - tooltipWidget->clearEntries(); + tooltipWidget->setOne({ + showThumbnail + ? badgeElement->getEmote()->images.getImage(3.0) + : nullptr, + element->getTooltip(), + }); } } else diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index 27e9d94a..4054870a 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -416,16 +416,30 @@ void GeneralPage::initLayout(GeneralPageView &layout) }); }, false); - layout.addDropdown( - "Show info on hover", {"Don't show", "Always show", "Hold shift"}, + layout.addDropdown::type>( + "Show emote & badge thumbnail on hover", + { + "Don't show", + "Always show", + "Hold shift", + }, s.emotesTooltipPreview, - [](int index) { - return index; + [](auto val) { + switch (val) + { + case ThumbnailPreviewMode::DontShow: + return "Don't show"; + case ThumbnailPreviewMode::AlwaysShow: + return "Always show"; + case ThumbnailPreviewMode::ShowOnShift: + return "Hold shift"; + } + return ""; }, [](auto args) { return args.index; }, - false, "Show emote name, provider, and author on hover."); + false); layout.addDropdown("Emoji style", { "Twitter",