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);
Painter p(&dummy);
auto newWidth = 0;
Dialogs::Ui::paintUnreadCount(p, _text, 0, 0, _st, &newWidth);
const auto badge = Dialogs::Ui::PaintUnreadBadge(p, _text, 0, 0, _st);
resize(newWidth, st::stickersFeaturedBadgeSize);
resize(badge.width(), st::stickersFeaturedBadgeSize);
}
void StickersBox::CounterWidget::paintEvent(QPaintEvent *e) {
Painter p(this);
if (!_text.isEmpty()) {
auto unreadRight = rtl() ? 0 : width();
auto unreadTop = 0;
Dialogs::Ui::paintUnreadCount(p, _text, unreadRight, unreadTop, _st);
const auto unreadRight = rtl() ? 0 : width();
const auto unreadTop = 0;
Dialogs::Ui::PaintUnreadBadge(p, _text, unreadRight, unreadTop, _st);
}
}

View file

@ -302,3 +302,7 @@ dialogsMiniPreviewRadius: 2px;
dialogsMiniPreviewSkip: 2px;
dialogsMiniPreviewRight: 3px;
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 displayMentionBadge,
int unreadCount,
bool selected,
bool active,
bool unreadMuted,
bool mentionMuted) {
auto skipBeforeMention = 0;
if (displayUnreadCounter || displayUnreadMark) {
auto counter = (unreadCount > 0)
const auto counter = (unreadCount > 0)
? QString::number(unreadCount)
: QString();
const auto allowDigits = displayMentionBadge ? 1 : 3;
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize;
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight;
auto unreadWidth = 0;
const auto unreadRight = st::dialogsPadding.x()
+ st::dialogsPhotoSize;
const auto unreadTop = st::dialogsPadding.y()
+ st::dialogsPhotoSize
- st::dialogsUnreadHeight;
UnreadBadgeStyle st;
st.active = active;
st.selected = selected;
st.muted = unreadMuted;
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth, allowDigits);
skipBeforeMention += unreadWidth + st.padding;
const auto badge = PaintUnreadBadge(
p,
counter,
unreadRight,
unreadTop,
st,
allowDigits);
skipBeforeMention += badge.width() + st.padding;
}
if (displayMentionBadge) {
auto counter = qsl("@");
auto unreadRight = st::dialogsPadding.x() + st::dialogsPhotoSize - skipBeforeMention;
auto unreadTop = st::dialogsPadding.y() + st::dialogsPhotoSize - st::dialogsUnreadHeight;
auto unreadWidth = 0;
const auto counter = QString();
const auto unreadRight = st::dialogsPadding.x()
+ st::dialogsPhotoSize
- skipBeforeMention;
const auto unreadTop = st::dialogsPadding.y()
+ st::dialogsPhotoSize
- st::dialogsUnreadHeight;
UnreadBadgeStyle st;
st.active = active;
st.selected = selected;
st.muted = mentionMuted;
st.padding = 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;
auto hadOneBadge = false;
if (displayUnreadCounter || displayUnreadMark) {
auto counter = (unreadCount > 0)
const auto counter = (unreadCount > 0)
? QString::number(unreadCount)
: QString();
auto unreadRight = fullWidth - st::dialogsPadding.x();
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
auto unreadWidth = 0;
const auto unreadRight = fullWidth
- st::dialogsPadding.x();
const auto unreadTop = texttop
+ st::dialogsTextFont->ascent
- st::dialogsUnreadFont->ascent
- (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
UnreadBadgeStyle st;
st.active = active;
st.selected = selected;
st.muted = unreadMuted;
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
availableWidth -= unreadWidth + st.padding;
const auto badge = PaintUnreadBadge(
p,
counter,
unreadRight,
unreadTop,
st);
availableWidth -= badge.width() + st.padding;
hadOneBadge = true;
} else if (displayPinnedIcon) {
auto &icon = (active ? st::dialogsPinnedIconActive : (selected ? st::dialogsPinnedIconOver : st::dialogsPinnedIcon));
icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth);
const auto &icon = active
? st::dialogsPinnedIconActive
: selected
? st::dialogsPinnedIconOver
: st::dialogsPinnedIcon;
icon.paint(
p,
fullWidth - st::dialogsPadding.x() - icon.width(),
texttop,
fullWidth);
availableWidth -= icon.width() + st::dialogsUnreadPadding;
hadOneBadge = true;
}
if (displayMentionBadge) {
auto counter = qsl("@");
auto unreadRight = fullWidth - st::dialogsPadding.x() - (initial - availableWidth);
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
auto unreadWidth = 0;
const auto counter = QString();
const auto unreadRight = fullWidth
- st::dialogsPadding.x()
- (initial - availableWidth);
const auto unreadTop = texttop
+ st::dialogsTextFont->ascent
- st::dialogsUnreadFont->ascent
- (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
UnreadBadgeStyle st;
st.active = active;
st.selected = selected;
st.muted = mentionMuted;
st.padding = 0;
st.textTop = 0;
paintUnreadCount(p, counter, unreadRight, unreadTop, st, &unreadWidth);
availableWidth -= unreadWidth + st.padding + (hadOneBadge ? st::dialogsUnreadPadding : 0);
const auto badge = PaintUnreadBadge(
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;
}
@ -572,35 +630,7 @@ QImage colorizeCircleHalf(UnreadBadgeSizeData *data, int size, int half, int xof
return result;
}
} // 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;
}
void paintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st) {
void PaintUnreadBadge(Painter &p, const QRect &rect, const UnreadBadgeStyle &st) {
Assert(rect.height() == st.size);
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]);
}
} // 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()
: size(st::dialogsUnreadHeight)
, padding(st::dialogsUnreadPadding)
, font(st::dialogsUnreadFont) {
}
void paintUnreadCount(
QRect PaintUnreadBadge(
Painter &p,
const QString &unreadCount,
int x,
int y,
const UnreadBadgeStyle &st,
int *outUnreadWidth,
int allowDigits) {
const auto text = (allowDigits > 0) && (unreadCount.size() > allowDigits + 1)
? qsl("..") + unreadCount.mid(unreadCount.size() - allowDigits)
: unreadCount;
int unreadWidth = st.font->width(text);
int unreadRectWidth = unreadWidth + 2 * st.padding;
int unreadRectHeight = st.size;
accumulate_max(unreadRectWidth, unreadRectHeight);
const auto unreadRectHeight = st.size;
const auto unreadWidth = st.font->width(text);
const auto unreadRectWidth = std::max(
unreadWidth + 2 * st.padding,
unreadRectHeight);
int unreadRectLeft = x;
if ((st.align & Qt::AlignHorizontal_Mask) & style::al_center) {
unreadRectLeft = (x - unreadRectWidth) / 2;
} else if ((st.align & Qt::AlignHorizontal_Mask) & style::al_right) {
unreadRectLeft = x - unreadRectWidth;
}
int unreadRectTop = y;
if (outUnreadWidth) {
*outUnreadWidth = unreadRectWidth;
}
const auto unreadRectLeft = ((st.align & Qt::AlignHorizontal_Mask) & style::al_center)
? (x - unreadRectWidth) / 2
: ((st.align & Qt::AlignHorizontal_Mask) & style::al_right)
? (x - unreadRectWidth)
: x;
const auto unreadRectTop = y;
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.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);
return badge;
}
void RowPainter::paint(
@ -807,6 +868,7 @@ void RowPainter::paint(
displayUnreadMark,
displayMentionBadge,
unreadCount,
selected,
active,
unreadMuted,
mentionMuted);
@ -925,6 +987,7 @@ void RowPainter::paint(
displayUnreadMark,
displayMentionBadge,
unreadCount,
selected,
active,
unreadMuted,
mentionMuted);
@ -1018,13 +1081,12 @@ void PaintCollapsedRow(
const auto unreadRight = fullWidth - st::dialogsPadding.x();
UnreadBadgeStyle st;
st.muted = true;
paintUnreadCount(
PaintUnreadBadge(
p,
QString::number(unread),
unreadRight,
unreadTop,
st,
nullptr);
st);
}
}

View file

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

View file

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

View file

@ -102,7 +102,7 @@ void HistoryDownButton::paintEvent(QPaintEvent *e) {
st.font = st::historyToDownBadgeFont;
st.size = st::historyToDownBadgeSize;
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;
auto unreadRight = width();
auto unreadTop = 0;
Dialogs::Ui::paintUnreadCount(
Dialogs::Ui::PaintUnreadBadge(
p,
_text,
unreadRight,

View file

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