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: Made nicknames searchable in the Settings dialog search bar. (#5886)
- 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: 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)
+27
View File
@@ -15,6 +15,7 @@
#include "controllers/nicknames/Nickname.hpp"
#include "controllers/sound/ISoundController.hpp"
#include "singletons/Toasts.hpp"
#include "util/QMagicEnumTagged.hpp"
#include "util/RapidJsonSerializeQString.hpp" // IWYU pragma: keep
#include "widgets/NotebookEnums.hpp"
@@ -97,6 +98,28 @@ enum class TabStyle : std::uint8_t {
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.
// These settings are still accessed concurrently in the code but it is bad practice.
class Settings
@@ -336,6 +359,10 @@ public:
BoolSetting animateEmotes = {"/emotes/enableGifAnimations", true};
BoolSetting enableZeroWidthEmotes = {"/emotes/enableZeroWidthEmotes", true};
FloatSetting emoteScale = {"/emotes/scale", 1.f};
EnumStringSetting<EmoteTooltipScale> emoteTooltipScale = {
"/emotes/tooltipScale",
EmoteTooltipScale::Medium,
};
BoolSetting showUnlistedSevenTVEmotes = {
"/emotes/showUnlistedSevenTVEmotes", false};
QStringSetting emojiSet = {"/emotes/emojiSet", "Twitter"};
+8 -11
View File
@@ -14,8 +14,7 @@ TooltipEntryWidget::TooltipEntryWidget(ImagePtr image, const QString &text,
QWidget *parent)
: QWidget(parent)
, image_(image)
, customImgWidth_(customWidth)
, customImgHeight_(customHeight)
, customSize(customWidth, customHeight)
{
auto *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
@@ -40,12 +39,11 @@ void TooltipEntryWidget::setWordWrap(bool wrap)
void TooltipEntryWidget::setImageScale(int w, int h)
{
if (this->customImgWidth_ == w && this->customImgHeight_ == h)
if (this->customSize == QSize{w, h})
{
return;
}
this->customImgWidth_ = w;
this->customImgHeight_ = h;
this->customSize = QSize{w, h};
this->refreshPixmap();
}
@@ -88,13 +86,12 @@ bool TooltipEntryWidget::refreshPixmap()
}
pixmap->setDevicePixelRatio(this->devicePixelRatio());
if (this->customImgWidth_ > 0 || this->customImgHeight_ > 0)
if (!this->customSize.isEmpty())
{
this->displayImage_->setPixmap(pixmap->scaled(this->customImgWidth_,
this->customImgHeight_,
Qt::KeepAspectRatio));
if (this->displayImage_->size() !=
QSize{this->customImgWidth_, this->customImgHeight_})
this->displayImage_->setPixmap(
pixmap->scaled(this->customSize, Qt::KeepAspectRatio));
if (this->displayImage_->pixmap().size() != this->customSize)
{
this->adjustSize();
}
+1 -2
View File
@@ -35,8 +35,7 @@ private:
bool attemptRefresh_ = false;
ImagePtr image_ = nullptr;
int customImgWidth_ = 0;
int customImgHeight_ = 0;
QSize customSize;
};
} // namespace chatterino
+19
View File
@@ -7,6 +7,8 @@
#include <QPainter>
#include <utility>
namespace {
// number of columns in grid mode
@@ -30,6 +32,23 @@ inline constexpr T *tooltipParentFor(T *desiredParent)
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)
: BaseWindow({BaseWindow::TopMost, BaseWindow::DontFocus,
BaseWindow::DisableLayoutSave},
+3
View File
@@ -7,6 +7,7 @@
#include <QGridLayout>
#include <QLabel>
#include <QLayout>
#include <QString>
#include <QVBoxLayout>
#include <QWidget>
@@ -20,6 +21,8 @@ struct TooltipEntry {
QString text;
int customWidth = 0;
int customHeight = 0;
static TooltipEntry scaled(ImagePtr image, QString text, float scale);
};
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);
}
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 chatterino {
@@ -2037,12 +2055,12 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
if (emoteElement)
{
this->tooltipWidget_->setOne({
auto scale = getSettings()->emoteTooltipScale.getEnum();
this->tooltipWidget_->setOne(TooltipEntry::scaled(
showThumbnail
? emoteElement->getEmote()->images.getImage(3.0)
: nullptr,
element->getTooltip(),
});
element->getTooltip(), getTooltipScale(scale)));
}
else if (layeredEmoteElement)
{
@@ -2073,18 +2091,22 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
if (i == 0)
{
// First entry gets a large image and full description
entries.push_back({showThumbnail
? emote->images.getImage(3.0)
: nullptr,
emoteTooltips[i]});
auto scale =
getSettings()->emoteTooltipScale.getEnum();
entries.push_back(TooltipEntry::scaled(
showThumbnail ? emote->images.getImage(3.0)
: nullptr,
emoteTooltips[i], getTooltipScale(scale)));
}
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});
auto scale =
getSettings()->emoteTooltipScale.getEnum();
entries.push_back(TooltipEntry::scaled(
showThumbnail ? emote->images.getImage(1.0)
: nullptr,
emote->name.string, getTooltipScale(scale)));
}
}
@@ -2101,12 +2123,12 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
}
else if (badgeElement)
{
this->tooltipWidget_->setOne({
auto scale = getSettings()->emoteTooltipScale.getEnum();
this->tooltipWidget_->setOne(TooltipEntry::scaled(
showThumbnail
? badgeElement->getEmote()->images.getImage(3.0)
: nullptr,
element->getTooltip(),
});
element->getTooltip(), getTooltipScale(scale)));
}
}
else
@@ -658,6 +658,9 @@ void GeneralPage::initLayout(GeneralPageView &layout)
return args.index;
},
false);
SettingWidget::dropdown("Emote & badge thumbnail size on hover",
s.emoteTooltipScale)
->addTo(layout);
layout.addDropdown("Emoji style",
{
"Twitter",