feat: setting to change emote/badge thumbnail size (#6126)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
Arne
2025-06-15 12:27:43 +02:00
committed by GitHub
parent 746b1c9210
commit 62c93d1d98
8 changed files with 98 additions and 27 deletions
+1
View File
@@ -15,6 +15,7 @@
- Minor: The JSON selector in the upload response can now query arrays using their indices like `foo.0`. (#6193) - Minor: The JSON selector in the upload response can now query arrays using their indices like `foo.0`. (#6193)
- Minor: Made nicknames searchable in the Settings dialog search bar. (#5886) - Minor: Made nicknames searchable in the Settings dialog search bar. (#5886)
- Minor: Added hotkey Action for opening account selector. (#6192) - Minor: Added hotkey Action for opening account selector. (#6192)
- Minor: Add a setting to change the emote and badge thumbnail size. (#6126)
- Bugfix: Automatic streamer mode detection now works from Flatpak. (#6250) - Bugfix: Automatic streamer mode detection now works from Flatpak. (#6250)
- Bugfix: Don't create native messaging manifest file if browser directory doesn't exist. (#6116) - Bugfix: Don't create native messaging manifest file if browser directory doesn't exist. (#6116)
- Bugfix: Fixed scrolling now working on inputs in the settings. (#6128) - Bugfix: Fixed scrolling now working on inputs in the settings. (#6128)
+27
View File
@@ -15,6 +15,7 @@
#include "controllers/nicknames/Nickname.hpp" #include "controllers/nicknames/Nickname.hpp"
#include "controllers/sound/ISoundController.hpp" #include "controllers/sound/ISoundController.hpp"
#include "singletons/Toasts.hpp" #include "singletons/Toasts.hpp"
#include "util/QMagicEnumTagged.hpp"
#include "util/RapidJsonSerializeQString.hpp" // IWYU pragma: keep #include "util/RapidJsonSerializeQString.hpp" // IWYU pragma: keep
#include "widgets/NotebookEnums.hpp" #include "widgets/NotebookEnums.hpp"
@@ -97,6 +98,28 @@ enum class TabStyle : std::uint8_t {
Compact, Compact,
}; };
enum class EmoteTooltipScale : std::uint8_t {
Small,
Medium,
Large,
Huge,
};
constexpr qmagicenum::customize_t qmagicenumDisplayName(
EmoteTooltipScale value) noexcept
{
switch (value)
{
case EmoteTooltipScale::Medium:
return "Medium (default)";
case EmoteTooltipScale::Small:
case EmoteTooltipScale::Large:
case EmoteTooltipScale::Huge:
return {};
}
}
/// Settings which are available for reading and writing on the gui thread. /// Settings which are available for reading and writing on the gui thread.
// These settings are still accessed concurrently in the code but it is bad practice. // These settings are still accessed concurrently in the code but it is bad practice.
class Settings class Settings
@@ -336,6 +359,10 @@ public:
BoolSetting animateEmotes = {"/emotes/enableGifAnimations", true}; BoolSetting animateEmotes = {"/emotes/enableGifAnimations", true};
BoolSetting enableZeroWidthEmotes = {"/emotes/enableZeroWidthEmotes", true}; BoolSetting enableZeroWidthEmotes = {"/emotes/enableZeroWidthEmotes", true};
FloatSetting emoteScale = {"/emotes/scale", 1.f}; FloatSetting emoteScale = {"/emotes/scale", 1.f};
EnumStringSetting<EmoteTooltipScale> emoteTooltipScale = {
"/emotes/tooltipScale",
EmoteTooltipScale::Medium,
};
BoolSetting showUnlistedSevenTVEmotes = { BoolSetting showUnlistedSevenTVEmotes = {
"/emotes/showUnlistedSevenTVEmotes", false}; "/emotes/showUnlistedSevenTVEmotes", false};
QStringSetting emojiSet = {"/emotes/emojiSet", "Twitter"}; QStringSetting emojiSet = {"/emotes/emojiSet", "Twitter"};
+8 -11
View File
@@ -14,8 +14,7 @@ TooltipEntryWidget::TooltipEntryWidget(ImagePtr image, const QString &text,
QWidget *parent) QWidget *parent)
: QWidget(parent) : QWidget(parent)
, image_(image) , image_(image)
, customImgWidth_(customWidth) , customSize(customWidth, customHeight)
, customImgHeight_(customHeight)
{ {
auto *layout = new QVBoxLayout(this); auto *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
@@ -40,12 +39,11 @@ void TooltipEntryWidget::setWordWrap(bool wrap)
void TooltipEntryWidget::setImageScale(int w, int h) void TooltipEntryWidget::setImageScale(int w, int h)
{ {
if (this->customImgWidth_ == w && this->customImgHeight_ == h) if (this->customSize == QSize{w, h})
{ {
return; return;
} }
this->customImgWidth_ = w; this->customSize = QSize{w, h};
this->customImgHeight_ = h;
this->refreshPixmap(); this->refreshPixmap();
} }
@@ -88,13 +86,12 @@ bool TooltipEntryWidget::refreshPixmap()
} }
pixmap->setDevicePixelRatio(this->devicePixelRatio()); pixmap->setDevicePixelRatio(this->devicePixelRatio());
if (this->customImgWidth_ > 0 || this->customImgHeight_ > 0) if (!this->customSize.isEmpty())
{ {
this->displayImage_->setPixmap(pixmap->scaled(this->customImgWidth_, this->displayImage_->setPixmap(
this->customImgHeight_, pixmap->scaled(this->customSize, Qt::KeepAspectRatio));
Qt::KeepAspectRatio));
if (this->displayImage_->size() != if (this->displayImage_->pixmap().size() != this->customSize)
QSize{this->customImgWidth_, this->customImgHeight_})
{ {
this->adjustSize(); this->adjustSize();
} }
+1 -2
View File
@@ -35,8 +35,7 @@ private:
bool attemptRefresh_ = false; bool attemptRefresh_ = false;
ImagePtr image_ = nullptr; ImagePtr image_ = nullptr;
int customImgWidth_ = 0; QSize customSize;
int customImgHeight_ = 0;
}; };
} // namespace chatterino } // namespace chatterino
+19
View File
@@ -7,6 +7,8 @@
#include <QPainter> #include <QPainter>
#include <utility>
namespace { namespace {
// number of columns in grid mode // number of columns in grid mode
@@ -30,6 +32,23 @@ inline constexpr T *tooltipParentFor(T *desiredParent)
namespace chatterino { namespace chatterino {
TooltipEntry TooltipEntry::scaled(ImagePtr image, QString text, float scale)
{
auto entry = TooltipEntry{
.image = std::move(image),
.text = std::move(text),
};
if (entry.image)
{
auto imgWidth = entry.image->width() / entry.image->scale();
auto imgHeight = entry.image->height() / entry.image->scale();
entry.customWidth = static_cast<int>(imgWidth * scale);
entry.customHeight = static_cast<int>(imgHeight * scale);
}
return entry;
}
TooltipWidget::TooltipWidget(BaseWidget *parent) TooltipWidget::TooltipWidget(BaseWidget *parent)
: BaseWindow({BaseWindow::TopMost, BaseWindow::DontFocus, : BaseWindow({BaseWindow::TopMost, BaseWindow::DontFocus,
BaseWindow::DisableLayoutSave}, BaseWindow::DisableLayoutSave},
+3
View File
@@ -7,6 +7,7 @@
#include <QGridLayout> #include <QGridLayout>
#include <QLabel> #include <QLabel>
#include <QLayout> #include <QLayout>
#include <QString>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWidget> #include <QWidget>
@@ -20,6 +21,8 @@ struct TooltipEntry {
QString text; QString text;
int customWidth = 0; int customWidth = 0;
int customHeight = 0; int customHeight = 0;
static TooltipEntry scaled(ImagePtr image, QString text, float scale);
}; };
enum class TooltipStyle { Vertical, Grid }; enum class TooltipStyle { Vertical, Grid };
+36 -14
View File
@@ -279,6 +279,24 @@ qreal highlightEasingFunction(qreal progress)
return 1.0 + pow((20.0 / 9.0) * (0.5 * progress - 0.5), 3.0); return 1.0 + pow((20.0 / 9.0) * (0.5 * progress - 0.5), 3.0);
} }
float getTooltipScale(EmoteTooltipScale emoteTooltipScale)
{
switch (emoteTooltipScale)
{
case EmoteTooltipScale::Small:
return 0.5F;
case EmoteTooltipScale::Medium:
return 1.0F;
case EmoteTooltipScale::Large:
return 1.5F;
case EmoteTooltipScale::Huge:
return 2.0F;
default:
return 1.0F;
}
}
} // namespace } // namespace
namespace chatterino { namespace chatterino {
@@ -2037,12 +2055,12 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
if (emoteElement) if (emoteElement)
{ {
this->tooltipWidget_->setOne({ auto scale = getSettings()->emoteTooltipScale.getEnum();
this->tooltipWidget_->setOne(TooltipEntry::scaled(
showThumbnail showThumbnail
? emoteElement->getEmote()->images.getImage(3.0) ? emoteElement->getEmote()->images.getImage(3.0)
: nullptr, : nullptr,
element->getTooltip(), element->getTooltip(), getTooltipScale(scale)));
});
} }
else if (layeredEmoteElement) else if (layeredEmoteElement)
{ {
@@ -2073,18 +2091,22 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
if (i == 0) if (i == 0)
{ {
// First entry gets a large image and full description // First entry gets a large image and full description
entries.push_back({showThumbnail auto scale =
? emote->images.getImage(3.0) getSettings()->emoteTooltipScale.getEnum();
: nullptr, entries.push_back(TooltipEntry::scaled(
emoteTooltips[i]}); showThumbnail ? emote->images.getImage(3.0)
: nullptr,
emoteTooltips[i], getTooltipScale(scale)));
} }
else else
{ {
// Every other entry gets a small image and just the emote name // Every other entry gets a small image and just the emote name
entries.push_back({showThumbnail auto scale =
? emote->images.getImage(1.0) getSettings()->emoteTooltipScale.getEnum();
: nullptr, entries.push_back(TooltipEntry::scaled(
emote->name.string}); showThumbnail ? emote->images.getImage(1.0)
: nullptr,
emote->name.string, getTooltipScale(scale)));
} }
} }
@@ -2101,12 +2123,12 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
} }
else if (badgeElement) else if (badgeElement)
{ {
this->tooltipWidget_->setOne({ auto scale = getSettings()->emoteTooltipScale.getEnum();
this->tooltipWidget_->setOne(TooltipEntry::scaled(
showThumbnail showThumbnail
? badgeElement->getEmote()->images.getImage(3.0) ? badgeElement->getEmote()->images.getImage(3.0)
: nullptr, : nullptr,
element->getTooltip(), element->getTooltip(), getTooltipScale(scale)));
});
} }
} }
else else
@@ -658,6 +658,9 @@ void GeneralPage::initLayout(GeneralPageView &layout)
return args.index; return args.index;
}, },
false); false);
SettingWidget::dropdown("Emote & badge thumbnail size on hover",
s.emoteTooltipScale)
->addTo(layout);
layout.addDropdown("Emoji style", layout.addDropdown("Emoji style",
{ {
"Twitter", "Twitter",