Paint unread mention badge as an icon.

This commit is contained in:
John Preston 2022-01-26 14:47:23 +03:00
parent 2a99f1a1ef
commit 6207770120
14 changed files with 156 additions and 93 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 995 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -333,19 +333,18 @@ void StickersBox::CounterWidget::setCounter(int counter) {
auto dummy = QImage(1, 1, QImage::Format_ARGB32_Premultiplied); auto dummy = QImage(1, 1, QImage::Format_ARGB32_Premultiplied);
Painter p(&dummy); Painter p(&dummy);
auto newWidth = 0; const auto badge = Dialogs::Ui::PaintUnreadBadge(p, _text, 0, 0, _st);
Dialogs::Ui::paintUnreadCount(p, _text, 0, 0, _st, &newWidth);
resize(newWidth, st::stickersFeaturedBadgeSize); resize(badge.width(), st::stickersFeaturedBadgeSize);
} }
void StickersBox::CounterWidget::paintEvent(QPaintEvent *e) { void StickersBox::CounterWidget::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
if (!_text.isEmpty()) { if (!_text.isEmpty()) {
auto unreadRight = rtl() ? 0 : width(); const auto unreadRight = rtl() ? 0 : width();
auto unreadTop = 0; const auto unreadTop = 0;
Dialogs::Ui::paintUnreadCount(p, _text, unreadRight, unreadTop, _st); Dialogs::Ui::PaintUnreadBadge(p, _text, unreadRight, unreadTop, _st);
} }
} }

View file

@ -302,3 +302,7 @@ dialogsMiniPreviewRadius: 2px;
dialogsMiniPreviewSkip: 2px; dialogsMiniPreviewSkip: 2px;
dialogsMiniPreviewRight: 3px; dialogsMiniPreviewRight: 3px;
dialogsMiniPlay: icon{{ "dialogs/dialogs_mini_play", videoPlayIconFg }}; dialogsMiniPlay: icon{{ "dialogs/dialogs_mini_play", videoPlayIconFg }};
dialogsUnreadMention: icon{{ "dialogs/dialogs_mention", dialogsUnreadFg }};
dialogsUnreadMentionOver: icon{{ "dialogs/dialogs_mention", dialogsUnreadFgOver }};
dialogsUnreadMentionActive: icon{{ "dialogs/dialogs_mention", dialogsUnreadFgActive }};

View file

@ -85,37 +85,61 @@ void PaintNarrowCounter(
bool displayUnreadMark, bool displayUnreadMark,
bool displayMentionBadge, bool displayMentionBadge,
int unreadCount, int unreadCount,
bool selected,
bool active, bool active,
bool unreadMuted, bool unreadMuted,
bool mentionMuted) { bool mentionMuted) {
auto skipBeforeMention = 0; auto skipBeforeMention = 0;
if (displayUnreadCounter || displayUnreadMark) { if (displayUnreadCounter || displayUnreadMark) {
auto counter = (unreadCount > 0) const auto counter = (unreadCount > 0)
? QString::number(unreadCount) ? QString::number(unreadCount)
: QString(); : QString();
const auto allowDigits = displayMentionBadge ? 1 : 3; const auto allowDigits = displayMentionBadge ? 1 : 3;
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize; const auto unreadRight = st::dialogsPadding.x()
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight; + st::dialogsPhotoSize;
auto unreadWidth = 0; const auto unreadTop = st::dialogsPadding.y()
+ st::dialogsPhotoSize
- st::dialogsUnreadHeight;
UnreadBadgeStyle st; UnreadBadgeStyle st;
st.active = active; st.active = active;
st.selected = selected;
st.muted = unreadMuted; st.muted = unreadMuted;
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth, allowDigits); const auto badge = PaintUnreadBadge(
skipBeforeMention += unreadWidth + st.padding; p,
counter,
unreadRight,
unreadTop,
st,
allowDigits);
skipBeforeMention += badge.width() + st.padding;
} }
if (displayMentionBadge) { if (displayMentionBadge) {
auto counter = qsl("@"); const auto counter = QString();
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize - skipBeforeMention; const auto unreadRight = st::dialogsPadding.x()
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight; + st::dialogsPhotoSize
auto unreadWidth = 0; - skipBeforeMention;
const auto unreadTop = st::dialogsPadding.y()
+ st::dialogsPhotoSize
- st::dialogsUnreadHeight;
UnreadBadgeStyle st; UnreadBadgeStyle st;
st.active = active; st.active = active;
st.selected = selected;
st.muted = mentionMuted; st.muted = mentionMuted;
st.padding = 0; st.padding = 0;
st.textTop = 0; st.textTop = 0;
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth); const auto badge = PaintUnreadBadge(
p,
counter,
unreadRight,
unreadTop,
st);
(st.active
? st::dialogsUnreadMentionActive
: st.selected
? st::dialogsUnreadMentionOver
: st::dialogsUnreadMention).paintInCenter(p, badge);
} }
} }
@ -136,40 +160,74 @@ int PaintWideCounter(
const auto initial = availableWidth; const auto initial = availableWidth;
auto hadOneBadge = false; auto hadOneBadge = false;
if (displayUnreadCounter || displayUnreadMark) { if (displayUnreadCounter || displayUnreadMark) {
auto counter = (unreadCount > 0) const auto counter = (unreadCount > 0)
? QString::number(unreadCount) ? QString::number(unreadCount)
: QString(); : QString();
auto unreadRight = fullWidth - st::dialogsPadding.x(); const auto unreadRight = fullWidth
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2; - st::dialogsPadding.x();
auto unreadWidth = 0; const auto unreadTop = texttop
+ st::dialogsTextFont->ascent
- st::dialogsUnreadFont->ascent
- (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
UnreadBadgeStyle st; UnreadBadgeStyle st;
st.active = active; st.active = active;
st.selected = selected;
st.muted = unreadMuted; st.muted = unreadMuted;
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth); const auto badge = PaintUnreadBadge(
availableWidth -= unreadWidth + st.padding; p,
counter,
unreadRight,
unreadTop,
st);
availableWidth -= badge.width() + st.padding;
hadOneBadge = true; hadOneBadge = true;
} else if (displayPinnedIcon) { } else if (displayPinnedIcon) {
auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon)); const auto &icon = active
icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth); ? st::dialogsPinnedIconActive
: selected
? st::dialogsPinnedIconOver
: st::dialogsPinnedIcon;
icon.paint(
p,
fullWidth - st::dialogsPadding.x() - icon.width(),
texttop,
fullWidth);
availableWidth -= icon.width() + st::dialogsUnreadPadding; availableWidth -= icon.width() + st::dialogsUnreadPadding;
hadOneBadge = true; hadOneBadge = true;
} }
if (displayMentionBadge) { if (displayMentionBadge) {
auto counter = qsl("@"); const auto counter = QString();
auto unreadRight = fullWidth - st::dialogsPadding.x() - (initial - availableWidth); const auto unreadRight = fullWidth
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2; - st::dialogsPadding.x()
auto unreadWidth = 0; - (initial - availableWidth);
const auto unreadTop = texttop
+ st::dialogsTextFont->ascent
- st::dialogsUnreadFont->ascent
- (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
UnreadBadgeStyle st; UnreadBadgeStyle st;
st.active = active; st.active = active;
st.selected = selected;
st.muted = mentionMuted; st.muted = mentionMuted;
st.padding = 0; st.padding = 0;
st.textTop = 0; st.textTop = 0;
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth); const auto badge = PaintUnreadBadge(
availableWidth -= unreadWidth + st.padding + (hadOneBadge ? st::dialogsUnreadPadding : 0); p,
counter,
unreadRight,
unreadTop,
st);
(st.active
? st::dialogsUnreadMentionActive
: st.selected
? st::dialogsUnreadMentionOver
: st::dialogsUnreadMention).paintInCenter(p, badge);
availableWidth -= badge.width()
+ st.padding
+ (hadOneBadge ? st::dialogsUnreadPadding : 0);
} }
return availableWidth; return availableWidth;
} }
@ -572,35 +630,7 @@ QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xof
return result; return result;
} }
} // namepsace void PaintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st) {
const style::icon *ChatTypeIcon(
not_null<PeerData*> peer,
bool active,
bool selected) {
if (peer->isChat() || peer->isMegagroup()) {
return &(active
? st::dialogsChatIconActive
: (selected ? st::dialogsChatIconOver : st::dialogsChatIcon));
} else if (peer->isChannel()) {
return &(active
? st::dialogsChannelIconActive
: (selected
? st::dialogsChannelIconOver
: st::dialogsChannelIcon));
} else if (const auto user = peer->asUser()) {
if (ShowUserBotIcon(user)) {
return &(active
? st::dialogsBotIconActive
: (selected
? st::dialogsBotIconOver
: st::dialogsBotIcon));
}
}
return nullptr;
}
void paintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st) {
Assert(rect.height() == st.size); Assert(rect.height() == st.size);
int index = (st.muted ? 0x03 : 0x00) + (st.active ? 0x02 : (st.selected ? 0x01 : 0x00)); int index = (st.muted ? 0x03 : 0x00) + (st.active ? 0x02 : (st.selected ? 0x01 : 0x00));
@ -634,46 +664,77 @@ void paintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st)
p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), badgeData->right[index]); p.drawPixmap(rect.x() + sizehalf + bar, rect.y(), badgeData->right[index]);
} }
} // namepsace
const style::icon *ChatTypeIcon(
not_null<PeerData*> peer,
bool active,
bool selected) {
if (peer->isChat() || peer->isMegagroup()) {
return &(active
? st::dialogsChatIconActive
: (selected ? st::dialogsChatIconOver : st::dialogsChatIcon));
} else if (peer->isChannel()) {
return &(active
? st::dialogsChannelIconActive
: (selected
? st::dialogsChannelIconOver
: st::dialogsChannelIcon));
} else if (const auto user = peer->asUser()) {
if (ShowUserBotIcon(user)) {
return &(active
? st::dialogsBotIconActive
: (selected
? st::dialogsBotIconOver
: st::dialogsBotIcon));
}
}
return nullptr;
}
UnreadBadgeStyle::UnreadBadgeStyle() UnreadBadgeStyle::UnreadBadgeStyle()
: size(st::dialogsUnreadHeight) : size(st::dialogsUnreadHeight)
, padding(st::dialogsUnreadPadding) , padding(st::dialogsUnreadPadding)
, font(st::dialogsUnreadFont) { , font(st::dialogsUnreadFont) {
} }
void paintUnreadCount( QRect PaintUnreadBadge(
Painter &p, Painter &p,
const QString &unreadCount, const QString &unreadCount,
int x, int x,
int y, int y,
const UnreadBadgeStyle &st, const UnreadBadgeStyle &st,
int *outUnreadWidth,
int allowDigits) { int allowDigits) {
const auto text = (allowDigits > 0) && (unreadCount.size() > allowDigits + 1) const auto text = (allowDigits > 0) && (unreadCount.size() > allowDigits + 1)
? qsl("..") + unreadCount.mid(unreadCount.size() - allowDigits) ? qsl("..") + unreadCount.mid(unreadCount.size() - allowDigits)
: unreadCount; : unreadCount;
int unreadWidth = st.font->width(text); const auto unreadRectHeight = st.size;
int unreadRectWidth = unreadWidth + 2 * st.padding; const auto unreadWidth = st.font->width(text);
int unreadRectHeight = st.size; const auto unreadRectWidth = std::max(
accumulate_max(unreadRectWidth, unreadRectHeight); unreadWidth + 2 * st.padding,
unreadRectHeight);
int unreadRectLeft = x; const auto unreadRectLeft = ((st.align & Qt::AlignHorizontal_Mask) & style::al_center)
if ((st.align & Qt::AlignHorizontal_Mask) & style::al_center) { ? (x - unreadRectWidth) / 2
unreadRectLeft = (x - unreadRectWidth) / 2; : ((st.align & Qt::AlignHorizontal_Mask) & style::al_right)
} else if ((st.align & Qt::AlignHorizontal_Mask) & style::al_right) { ? (x - unreadRectWidth)
unreadRectLeft = x - unreadRectWidth; : x;
} const auto unreadRectTop = y;
int unreadRectTop = y;
if (outUnreadWidth) {
*outUnreadWidth = unreadRectWidth;
}
paintUnreadBadge(p, QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight), st); const auto badge = QRect(unreadRectLeft, unreadRectTop, unreadRectWidth, unreadRectHeight);
PaintUnreadBadge(p, badge, st);
auto textTop = st.textTop ? st.textTop : (unreadRectHeight - st.font->height) / 2; const auto textTop = st.textTop ? st.textTop : (unreadRectHeight - st.font->height) / 2;
p.setFont(st.font); p.setFont(st.font);
p.setPen(st.active ? st::dialogsUnreadFgActive : (st.selected ? st::dialogsUnreadFgOver : st::dialogsUnreadFg)); p.setPen(st.active
? st::dialogsUnreadFgActive
: st.selected
? st::dialogsUnreadFgOver
: st::dialogsUnreadFg);
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + textTop + st.font->ascent, text); p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + textTop + st.font->ascent, text);
return badge;
} }
void RowPainter::paint( void RowPainter::paint(
@ -807,6 +868,7 @@ void RowPainter::paint(
displayUnreadMark, displayUnreadMark,
displayMentionBadge, displayMentionBadge,
unreadCount, unreadCount,
selected,
active, active,
unreadMuted, unreadMuted,
mentionMuted); mentionMuted);
@ -925,6 +987,7 @@ void RowPainter::paint(
displayUnreadMark, displayUnreadMark,
displayMentionBadge, displayMentionBadge,
unreadCount, unreadCount,
selected,
active, active,
unreadMuted, unreadMuted,
mentionMuted); mentionMuted);
@ -1018,13 +1081,12 @@ void PaintCollapsedRow(
const auto unreadRight = fullWidth - st::dialogsPadding.x(); const auto unreadRight = fullWidth - st::dialogsPadding.x();
UnreadBadgeStyle st; UnreadBadgeStyle st;
st.muted = true; st.muted = true;
paintUnreadCount( PaintUnreadBadge(
p, p,
QString::number(unread), QString::number(unread),
unreadRight, unreadRight,
unreadTop, unreadTop,
st, st);
nullptr);
} }
} }

View file

@ -83,13 +83,12 @@ struct UnreadBadgeStyle {
UnreadBadgeSize sizeId = UnreadBadgeInDialogs; UnreadBadgeSize sizeId = UnreadBadgeInDialogs;
style::font font; style::font font;
}; };
void paintUnreadCount( QRect PaintUnreadBadge(
Painter &p, Painter &p,
const QString &t, const QString &t,
int x, int x,
int y, int y,
const UnreadBadgeStyle &st, const UnreadBadgeStyle &st,
int *outUnreadWidth = nullptr,
int allowDigits = 0); int allowDigits = 0);
void clearUnreadBadgesCache(); void clearUnreadBadgesCache();

View file

@ -114,13 +114,12 @@ QImage UnreadBadge(not_null<PeerData*> peer) {
result.fill(Qt::transparent); result.fill(Qt::transparent);
Painter p(&result); Painter p(&result);
Dialogs::Ui::paintUnreadCount( Dialogs::Ui::PaintUnreadBadge(
p, p,
unread, unread,
result.width(), result.width(),
result.height() - unreadSt.size, result.height() - unreadSt.size,
unreadSt, unreadSt,
nullptr,
2); 2);
return result; return result;
} }

View file

@ -102,7 +102,7 @@ void HistoryDownButton::paintEvent(QPaintEvent *e) {
st.font = st::historyToDownBadgeFont; st.font = st::historyToDownBadgeFont;
st.size = st::historyToDownBadgeSize; st.size = st::historyToDownBadgeSize;
st.sizeId = Dialogs::Ui::UnreadBadgeInHistoryToDown; st.sizeId = Dialogs::Ui::UnreadBadgeInHistoryToDown;
Dialogs::Ui::paintUnreadCount(p, unreadString, width(), 0, st, nullptr, 4); Dialogs::Ui::PaintUnreadBadge(p, unreadString, width(), 0, st, 4);
} }
} }

View file

@ -40,7 +40,7 @@ void UnreadBadge::paintEvent(QPaintEvent *e) {
unreadSt.muted = !_active; unreadSt.muted = !_active;
auto unreadRight = width(); auto unreadRight = width();
auto unreadTop = 0; auto unreadTop = 0;
Dialogs::Ui::paintUnreadCount( Dialogs::Ui::PaintUnreadBadge(
p, p,
_text, _text,
unreadRight, unreadRight,

View file

@ -293,19 +293,19 @@ void MainMenu::AccountButton::paintEvent(QPaintEvent *e) {
const auto string = (_unreadBadge > 99) const auto string = (_unreadBadge > 99)
? "99+" ? "99+"
: QString::number(_unreadBadge); : QString::number(_unreadBadge);
auto unreadWidth = 0;
const auto skip = _st.itemPadding.right() const auto skip = _st.itemPadding.right()
- st::mainMenu.itemToggleShift; - st::mainMenu.itemToggleShift;
const auto unreadRight = width() - skip; const auto unreadRight = width() - skip;
const auto unreadTop = (height() - _unreadSt.size) / 2; const auto unreadTop = (height() - _unreadSt.size) / 2;
Dialogs::Ui::paintUnreadCount( const auto badge = Dialogs::Ui::PaintUnreadBadge(
p, p,
string, string,
unreadRight, unreadRight,
unreadTop, unreadTop,
_unreadSt, _unreadSt);
&unreadWidth); available -= badge.width()
available -= unreadWidth + skip + st::mainMenu.itemStyle.font->spacew; + skip
+ st::mainMenu.itemStyle.font->spacew;
} else { } else {
available -= _st.itemPadding.right(); available -= _st.itemPadding.right();
} }