Formalize zero-width emote implementation (#4314)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
Daniel Sage
2023-03-18 12:30:08 -04:00
committed by GitHub
parent db97a14cdc
commit 0acbc0d2c3
18 changed files with 947 additions and 146 deletions
+86 -12
View File
@@ -64,6 +64,7 @@
#define DRAW_WIDTH (this->width())
#define SELECTION_RESUME_SCROLLING_MSG_THRESHOLD 3
#define CHAT_HOVER_PAUSE_DURATION 1000
#define TOOLTIP_EMOTE_ENTRIES_LIMIT 7
namespace chatterino {
namespace {
@@ -1658,10 +1659,12 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
auto element = &hoverLayoutElement->getCreator();
bool isLinkValid = hoverLayoutElement->getLink().isValid();
auto emoteElement = dynamic_cast<const EmoteElement *>(element);
auto layeredEmoteElement =
dynamic_cast<const LayeredEmoteElement *>(element);
bool isNotEmote = emoteElement == nullptr && layeredEmoteElement == nullptr;
if (element->getTooltip().isEmpty() ||
(isLinkValid && emoteElement == nullptr &&
!getSettings()->linkInfoTooltip))
(isLinkValid && isNotEmote && !getSettings()->linkInfoTooltip))
{
tooltipWidget->hide();
}
@@ -1669,7 +1672,7 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
{
auto badgeElement = dynamic_cast<const BadgeElement *>(element);
if ((badgeElement || emoteElement) &&
if ((badgeElement || emoteElement || layeredEmoteElement) &&
getSettings()->emotesTooltipPreview.getValue())
{
if (event->modifiers() == Qt::ShiftModifier ||
@@ -1677,18 +1680,73 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
{
if (emoteElement)
{
tooltipWidget->setImage(
emoteElement->getEmote()->images.getImage(3.0));
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<TooltipEntry> 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)
{
auto &emote = layeredEmotes[i];
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);
}
}
else if (badgeElement)
{
tooltipWidget->setImage(
badgeElement->getEmote()->images.getImage(3.0));
tooltipWidget->setOne({
badgeElement->getEmote()->images.getImage(3.0),
element->getTooltip(),
});
}
}
else
{
tooltipWidget->clearImage();
tooltipWidget->clearEntries();
}
}
else
@@ -1711,7 +1769,7 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
auto thumbnailSize = getSettings()->thumbnailSize;
if (!thumbnailSize)
{
tooltipWidget->clearImage();
tooltipWidget->clearEntries();
}
else
{
@@ -1724,19 +1782,23 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
shouldHideThumbnail
? Image::fromResourcePixmap(getResources().streamerMode)
: element->getThumbnail();
tooltipWidget->setImage(std::move(thumb));
if (element->getThumbnailType() ==
MessageElement::ThumbnailType::Link_Thumbnail)
{
tooltipWidget->setImageScale(thumbnailSize, thumbnailSize);
tooltipWidget->setOne({std::move(thumb),
element->getTooltip(), thumbnailSize,
thumbnailSize});
}
else
{
tooltipWidget->setOne({std::move(thumb), ""});
}
}
}
tooltipWidget->moveTo(this, event->globalPos());
tooltipWidget->setWordWrap(isLinkValid);
tooltipWidget->setText(element->getTooltip());
tooltipWidget->show();
}
@@ -2134,6 +2196,18 @@ void ChannelView::addImageContextMenuItems(
addEmoteContextMenuItems(*emoteElement->getEmote(), creatorFlags,
menu);
}
else if (auto layeredElement =
dynamic_cast<const LayeredEmoteElement *>(&creator))
{
// Give each emote its own submenu
for (auto &emote : layeredElement->getUniqueEmotes())
{
auto emoteAction = menu.addAction(emote->name.string);
auto emoteMenu = new QMenu(&menu);
emoteAction->setMenu(emoteMenu);
addEmoteContextMenuItems(*emote, creatorFlags, *emoteMenu);
}
}
}
// add seperator