From 0bbab2bd59bace05268cf14631bc42689c380d53 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 30 Jan 2026 20:15:04 +0400 Subject: [PATCH] Support colored/iconed bot buttons. --- .../SourceFiles/chat_helpers/bot_keyboard.cpp | 35 ++++++-- .../history/history_item_components.cpp | 89 +++++++++++++------ .../history/history_item_components.h | 21 +++-- .../history/history_item_reply_markup.cpp | 65 ++++++++++++-- .../history/history_item_reply_markup.h | 16 +++- .../history/view/history_view_element.cpp | 69 +++++++++++--- .../history/view/history_view_message.cpp | 3 +- .../view/history_view_service_message.cpp | 3 +- .../SourceFiles/ui/chat/group_call_bar.cpp | 1 + 9 files changed, 243 insertions(+), 59 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp index e3ddd4d689..17fc46c5b4 100644 --- a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp +++ b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp @@ -33,7 +33,6 @@ public: Ui::BubbleRounding outer, RectParts sides) const override; - void startPaint(QPainter &p, const Ui::ChatStyle *st) const override; const style::TextStyle &textStyle() const override; void repaint(not_null item) const override; @@ -42,8 +41,13 @@ protected: QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, Ui::BubbleRounding rounding, float64 howMuchOver) const override; + void paintButtonStart( + QPainter &p, + const Ui::ChatStyle *st, + HistoryMessageMarkupButton::Color color) const override; void paintButtonIcon( QPainter &p, const Ui::ChatStyle *st, @@ -54,6 +58,7 @@ protected: QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, int outerWidth, Ui::BubbleRounding rounding) const override; int minButtonWidth(HistoryMessageMarkupButton::Type type) const override; @@ -69,8 +74,12 @@ Style::Style( : ReplyKeyboard::Style(st), _parent(parent) { } -void Style::startPaint(QPainter &p, const Ui::ChatStyle *st) const { - p.setPen(st::botKbColor); +void Style::paintButtonStart( + QPainter &p, + const Ui::ChatStyle *st, + HistoryMessageMarkupButton::Color color) const { + using Color = HistoryMessageMarkupButton::Color; + p.setPen((color == Color::Normal) ? st::botKbColor : st::white); p.setFont(st::botKbStyle.font); } @@ -93,9 +102,23 @@ void Style::paintButtonBg( QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, Ui::BubbleRounding rounding, float64 howMuchOver) const { - Ui::FillRoundRect(p, rect, st::botKbBg, Ui::BotKeyboardCorners); + using Color = HistoryMessageMarkupButton::Color; + if (color == Color::Normal) { + Ui::FillRoundRect(p, rect, st::botKbBg, Ui::BotKeyboardCorners); + } else { + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush((color == Color::Primary) + ? QColor(0x29, 0x8a, 0xcf) + : (color == Color::Danger) + ? QColor(0xe0, 0x53, 0x56) + : QColor(0x61, 0xc7, 0x52)); + const auto radius = st::roundRadiusSmall; + p.drawRoundedRect(rect, radius, radius); + } } void Style::paintButtonIcon( @@ -111,6 +134,7 @@ void Style::paintButtonLoading( QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, int outerWidth, Ui::BubbleRounding rounding) const { // Buttons with loading progress should not appear here. @@ -148,7 +172,8 @@ void BotKeyboard::paintEvent(QPaintEvent *e) { nullptr, Ui::BubbleRounding(), width(), - clip.translated(-x, -st::botKbScroll.deltat)); + clip.translated(-x, -st::botKbScroll.deltat), + _controller->isGifPausedAtLeastFor(Window::GifPauseReason::Any)); } } diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index a94a72a611..fc05c7fbba 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -748,6 +748,7 @@ ReplyKeyboard::ReplyKeyboard( , _st(std::move(s)) { if (const auto markup = _item->Get()) { const auto owner = &_item->history()->owner(); + const auto session = &owner->session(); const auto context = _item->fullId(); const auto rowCount = int(markup->data.rows.size()); _rows.reserve(rowCount); @@ -778,18 +779,24 @@ ReplyKeyboard::ReplyKeyboard( return withEmoji(st::chatSuggestDeclineIcon); } else if (type == Type::SuggestChange) { return withEmoji(st::chatSuggestChangeIcon); - } else if (type != Type::Buy) { - return TextWithEntities(); } auto result = TextWithEntities(); - auto firstPart = true; - for (const auto &part : text.split(QChar(0x2B50))) { - if (!firstPart) { - result.append(Ui::Text::IconEmoji( - &st::starIconEmojiLarge)); + if (const auto iconId = row[j].visual.iconId) { + using namespace Data; + result.append(SingleCustomEmoji(iconId)).append(' '); + } + if (type == Type::Buy) { + auto firstPart = true; + for (const auto &part : text.split(QChar(0x2B50))) { + if (!firstPart) { + result.append(Ui::Text::IconEmoji( + &st::starIconEmojiLarge)); + } + result.append(part); + firstPart = false; } - result.append(part); - firstPart = false; + } else if (!result.entities.empty()) { + result.append(text); } return result.entities.empty() ? TextWithEntities() @@ -805,7 +812,11 @@ ReplyKeyboard::ReplyKeyboard( button.text.setMarkedText( _st->textStyle(), TextUtilities::SingleLine(textWithEntities), - kMarkupTextOptions); + kMarkupTextOptions, + Core::TextContext({ + .session = session, + .repaint = [=] { _st->repaint(_item); }, + })); } else { button.text.setText( _st->textStyle(), @@ -813,6 +824,7 @@ ReplyKeyboard::ReplyKeyboard( kPlainTextOptions); } button.characters = text.isEmpty() ? 1 : text.size(); + button.color = row[j].visual.color; newRow.push_back(std::move(button)); } _rows.push_back(std::move(newRow)); @@ -827,7 +839,6 @@ void ReplyKeyboard::updateMessageId() { button.link->setMessageId(msgId); } } - } void ReplyKeyboard::resize(int width, int height) { @@ -947,11 +958,11 @@ void ReplyKeyboard::paint( const Ui::ChatStyle *st, Ui::BubbleRounding rounding, int outerWidth, - const QRect &clip) const { + const QRect &clip, + bool paused) const { Assert(_st != nullptr); Assert(_width > 0); - _st->startPaint(p, st); auto number = hasFastButtonMode() ? 1 : 0; for (auto y = 0, rowsCount = int(_rows.size()); y != rowsCount; ++y) { for (auto x = 0, count = int(_rows[y].size()); x != count; ++x) { @@ -982,7 +993,13 @@ void ReplyKeyboard::paint( && (rounding.bottomRight == Corner::Large)) ? Corner::Large : Corner::Small; - _st->paintButton(p, st, outerWidth, button, buttonRounding); + _st->paintButton( + p, + st, + outerWidth, + button, + buttonRounding, + paused); if (number) { p.setFont(st::dialogsUnreadFont); @@ -1174,11 +1191,16 @@ void ReplyKeyboard::Style::paintButton( const Ui::ChatStyle *st, int outerWidth, const ReplyKeyboard::Button &button, - Ui::BubbleRounding rounding) const { + Ui::BubbleRounding rounding, + bool paused) const { const auto &rect = button.rect; - paintButtonBg(p, st, rect, rounding, button.howMuchOver); + paintButtonBg(p, st, rect, button.color, rounding, button.howMuchOver); if (button.ripple) { - const auto color = st ? &st->msgBotKbRippleBg()->c : nullptr; + const auto color = st + ? &st->msgBotKbRippleBg()->c + : (button.color != HistoryMessageMarkupButton::Color::Normal) + ? &st::shadowFg->c + : nullptr; button.ripple->paint(p, rect.x(), rect.y(), outerWidth, color); if (button.ripple->empty()) { button.ripple.reset(); @@ -1190,7 +1212,13 @@ void ReplyKeyboard::Style::paintButton( || button.type == HistoryMessageMarkupButton::Type::Game) { if (const auto data = button.link->getButton()) { if (data->requestId) { - paintButtonLoading(p, st, rect, outerWidth, rounding); + paintButtonLoading( + p, + st, + rect, + button.color, + outerWidth, + rounding); } } } @@ -1203,13 +1231,17 @@ void ReplyKeyboard::Style::paintButton( tx += (tw - st::botKbStyle.font->elidew) / 2; tw = st::botKbStyle.font->elidew; } - button.text.drawElided( - p, - tx, - rect.y() + _st->textTop + ((rect.height() - _st->height) / 2), - tw, - 1, - style::al_top); + paintButtonStart(p, st, button.color); + button.text.draw(p, { + .position = { + tx, + rect.y() + _st->textTop + ((rect.height() - _st->height) / 2), + }, + .availableWidth = tw, + .align = style::al_top, + .paused = paused || On(PowerSaving::kEmojiChat), + .elisionLines = 1, + }); if (button.type == HistoryMessageMarkupButton::Type::SimpleWebView) { const auto &icon = st::markupWebview; st::markupWebview.paint( @@ -1261,6 +1293,7 @@ void HistoryMessageReplyMarkup::updateSuggestControls( | ReplyMarkupFlag::SuggestionDecline; } using Type = HistoryMessageMarkupButton::Type; + using Visual = HistoryMessageMarkupButton::Visual; const auto has = [&](Type type) { return !data.rows.empty() && ranges::contains( @@ -1276,10 +1309,12 @@ void HistoryMessageReplyMarkup::updateSuggestControls( { Type::SuggestDecline, tr::lng_action_gift_offer_decline(tr::now), + Visual(), }, { Type::SuggestAccept, tr::lng_action_gift_offer_accept(tr::now), + Visual(), }, }); } else if (actions == SuggestionActions::AcceptAndDecline) { @@ -1296,15 +1331,18 @@ void HistoryMessageReplyMarkup::updateSuggestControls( { Type::SuggestDecline, tr::lng_suggest_action_decline(tr::now), + Visual(), }, { Type::SuggestAccept, tr::lng_suggest_action_accept(tr::now), + Visual(), }, }); data.rows.push_back({ { Type::SuggestChange, tr::lng_suggest_action_change(tr::now), + Visual(), } }); data.flags |= ReplyMarkupFlag::SuggestionAccept | ReplyMarkupFlag::SuggestionDecline; @@ -1336,6 +1374,7 @@ void HistoryMessageReplyMarkup::updateSuggestControls( data.rows.push_back({ { Type::SuggestDecline, tr::lng_suggest_action_decline(tr::now), + Visual(), } }); data.flags |= ReplyMarkupFlag::SuggestionDecline; } diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h index 095602c604..4267e928fb 100644 --- a/Telegram/SourceFiles/history/history_item_components.h +++ b/Telegram/SourceFiles/history/history_item_components.h @@ -457,9 +457,6 @@ public: Style(const style::BotKeyboardButton &st) : _st(&st) { } - virtual void startPaint( - QPainter &p, - const Ui::ChatStyle *st) const = 0; virtual const style::TextStyle &textStyle() const = 0; int buttonSkip() const; @@ -478,8 +475,13 @@ public: QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, Ui::BubbleRounding rounding, float64 howMuchOver) const = 0; + virtual void paintButtonStart( + QPainter &p, + const Ui::ChatStyle *st, + HistoryMessageMarkupButton::Color color) const = 0; virtual void paintButtonIcon( QPainter &p, const Ui::ChatStyle *st, @@ -490,6 +492,7 @@ public: QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, int outerWidth, Ui::BubbleRounding rounding) const = 0; virtual int minButtonWidth( @@ -503,7 +506,8 @@ public: const Ui::ChatStyle *st, int outerWidth, const ReplyKeyboard::Button &button, - Ui::BubbleRounding rounding) const; + Ui::BubbleRounding rounding, + bool paused) const; friend class ReplyKeyboard; }; @@ -527,7 +531,8 @@ public: const Ui::ChatStyle *st, Ui::BubbleRounding rounding, int outerWidth, - const QRect &clip) const; + const QRect &clip, + bool paused) const; ClickHandlerPtr getLink(QPoint point) const; ClickHandlerPtr getLinkByIndex(int index) const; @@ -554,12 +559,14 @@ private: QRect rect; int characters = 0; float64 howMuchOver = 0.; - HistoryMessageMarkupButton::Type type; + HistoryMessageMarkupButton::Type type = {}; + HistoryMessageMarkupButton::Color color = {}; std::shared_ptr link; mutable std::unique_ptr ripple; }; struct ButtonCoords { - int i, j; + int i = 0; + int j = 0; }; void startAnimation(int i, int j, int direction); diff --git a/Telegram/SourceFiles/history/history_item_reply_markup.cpp b/Telegram/SourceFiles/history/history_item_reply_markup.cpp index 61e38a56ff..5646f5de4e 100644 --- a/Telegram/SourceFiles/history/history_item_reply_markup.cpp +++ b/Telegram/SourceFiles/history/history_item_reply_markup.cpp @@ -14,6 +14,28 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace { +[[nodiscard]] HistoryMessageMarkupButton::Visual ParseVisual( + const tl::conditional &style) { + if (!style) { + return {}; + } + using Color = HistoryMessageMarkupButton::Color; + const auto &data = style->data(); + if (data.vicon()) { + [[maybe_unused]] int a = 0; + } + return { + .iconId = data.vicon().value_or_empty(), + .color = (data.is_bg_danger() + ? Color::Danger + : data.is_bg_primary() + ? Color::Primary + : data.is_bg_success() + ? Color::Success + : Color::Normal), + }; +} + [[nodiscard]] RequestPeerQuery RequestPeerQueryFromTL( const MTPDkeyboardButtonRequestPeer &query) { using Type = RequestPeerQuery::Type; @@ -79,10 +101,12 @@ InlineBots::PeerTypes PeerTypesFromMTP( HistoryMessageMarkupButton::HistoryMessageMarkupButton( Type type, const QString &text, + Visual visual, const QByteArray &data, const QString &forwardText, int64 buttonId) : type(type) +, visual(visual) , text(text) , forwardText(forwardText) , data(data) @@ -122,23 +146,34 @@ void HistoryMessageMarkupData::fillRows( row.reserve(data.vbuttons().v.size()); for (const auto &button : data.vbuttons().v) { button.match([&](const MTPDkeyboardButton &data) { - row.emplace_back(Type::Default, qs(data.vtext())); + row.emplace_back( + Type::Default, + qs(data.vtext()), + ParseVisual(data.vstyle())); }, [&](const MTPDkeyboardButtonCallback &data) { row.emplace_back( (data.is_requires_password() ? Type::CallbackWithPassword : Type::Callback), qs(data.vtext()), + ParseVisual(data.vstyle()), qba(data.vdata())); }, [&](const MTPDkeyboardButtonRequestGeoLocation &data) { - row.emplace_back(Type::RequestLocation, qs(data.vtext())); + row.emplace_back( + Type::RequestLocation, + qs(data.vtext()), + ParseVisual(data.vstyle())); }, [&](const MTPDkeyboardButtonRequestPhone &data) { - row.emplace_back(Type::RequestPhone, qs(data.vtext())); + row.emplace_back( + Type::RequestPhone, + qs(data.vtext()), + ParseVisual(data.vstyle())); }, [&](const MTPDkeyboardButtonRequestPeer &data) { const auto query = RequestPeerQueryFromTL(data); row.emplace_back( Type::RequestPeer, qs(data.vtext()), + ParseVisual(data.vstyle()), QByteArray( reinterpret_cast(&query), sizeof(query)), @@ -148,12 +183,17 @@ void HistoryMessageMarkupData::fillRows( row.emplace_back( Type::Url, qs(data.vtext()), + ParseVisual(data.vstyle()), qba(data.vurl())); }, [&](const MTPDkeyboardButtonSwitchInline &data) { const auto type = data.is_same_peer() ? Type::SwitchInlineSame : Type::SwitchInline; - row.emplace_back(type, qs(data.vtext()), qba(data.vquery())); + row.emplace_back( + type, + qs(data.vtext()), + ParseVisual(data.vstyle()), + qba(data.vquery())); if (type == Type::SwitchInline) { // Optimization flag. // Fast check on all new messages if there is a switch button to auto-click it. @@ -163,13 +203,20 @@ void HistoryMessageMarkupData::fillRows( } } }, [&](const MTPDkeyboardButtonGame &data) { - row.emplace_back(Type::Game, qs(data.vtext())); + row.emplace_back( + Type::Game, + qs(data.vtext()), + ParseVisual(data.vstyle())); }, [&](const MTPDkeyboardButtonBuy &data) { - row.emplace_back(Type::Buy, qs(data.vtext())); + row.emplace_back( + Type::Buy, + qs(data.vtext()), + ParseVisual(data.vstyle())); }, [&](const MTPDkeyboardButtonUrlAuth &data) { row.emplace_back( Type::Auth, qs(data.vtext()), + ParseVisual(data.vstyle()), qba(data.vurl()), qs(data.vfwd_text().value_or_empty()), data.vbutton_id().v); @@ -187,11 +234,13 @@ void HistoryMessageMarkupData::fillRows( row.emplace_back( Type::RequestPoll, qs(data.vtext()), + ParseVisual(data.vstyle()), quiz); }, [&](const MTPDkeyboardButtonUserProfile &data) { row.emplace_back( Type::UserProfile, qs(data.vtext()), + ParseVisual(data.vstyle()), QByteArray::number(data.vuser_id().v)); }, [&](const MTPDinputKeyboardButtonUrlAuth &data) { LOG(("API Error: inputKeyboardButtonUrlAuth.")); @@ -203,16 +252,19 @@ void HistoryMessageMarkupData::fillRows( row.emplace_back( Type::WebView, qs(data.vtext()), + ParseVisual(data.vstyle()), data.vurl().v); }, [&](const MTPDkeyboardButtonSimpleWebView &data) { row.emplace_back( Type::SimpleWebView, qs(data.vtext()), + ParseVisual(data.vstyle()), data.vurl().v); }, [&](const MTPDkeyboardButtonCopy &data) { row.emplace_back( Type::CopyText, qs(data.vtext()), + ParseVisual(data.vstyle()), data.vcopy_text().v); }, [&](const MTPDinputKeyboardButtonRequestPeer &data) { LOG(("API Error: inputKeyboardButtonRequestPeer.")); @@ -283,6 +335,7 @@ void HistoryMessageMarkupData::fillForwardedData( row.emplace_back( newType, text, + button.visual, button.data, QString(), button.buttonId); diff --git a/Telegram/SourceFiles/history/history_item_reply_markup.h b/Telegram/SourceFiles/history/history_item_reply_markup.h index f180606a35..2614b20c87 100644 --- a/Telegram/SourceFiles/history/history_item_reply_markup.h +++ b/Telegram/SourceFiles/history/history_item_reply_markup.h @@ -70,7 +70,7 @@ struct RequestPeerQuery { static_assert(std::is_trivially_copy_assignable_v); struct HistoryMessageMarkupButton { - enum class Type { + enum class Type : uchar { Default, Url, Callback, @@ -94,9 +94,22 @@ struct HistoryMessageMarkupButton { SuggestChange, }; + enum class Color : uchar { + Normal, + Primary, + Danger, + Success, + }; + + struct Visual { + DocumentId iconId = 0; + Color color = Color::Normal; + }; + HistoryMessageMarkupButton( Type type, const QString &text, + Visual visual, const QByteArray &data = QByteArray(), const QString &forwardText = QString(), int64 buttonId = 0); @@ -108,6 +121,7 @@ struct HistoryMessageMarkupButton { int column); Type type; + Visual visual; QString text, forwardText; QByteArray data; int64 buttonId = 0; diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index dee1ca525a..1a911d3e48 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -79,9 +79,6 @@ public: Ui::BubbleRounding outer, RectParts sides) const override; - void startPaint( - QPainter &p, - const Ui::ChatStyle *st) const override; const style::TextStyle &textStyle() const override; void repaint(not_null item) const override; @@ -90,8 +87,13 @@ protected: QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, Ui::BubbleRounding rounding, float64 howMuchOver) const override; + void paintButtonStart( + QPainter &p, + const Ui::ChatStyle *st, + HistoryMessageMarkupButton::Color color) const override; void paintButtonIcon( QPainter &p, const Ui::ChatStyle *st, @@ -102,6 +104,7 @@ protected: QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, int outerWidth, Ui::BubbleRounding rounding) const override; int minButtonWidth(HistoryMessageMarkupButton::Type type) const override; @@ -112,7 +115,18 @@ private: QColor color; }; using BubbleRoundingKey = uchar; - mutable base::flat_map _cachedBg; + struct CacheKey { + BubbleRoundingKey rounding; + HistoryMessageMarkupButton::Color color; + + friend inline constexpr auto operator<=>( + CacheKey, + CacheKey) = default; + friend inline constexpr bool operator==( + CacheKey, + CacheKey) = default; + }; + mutable base::flat_map _cachedBg; mutable base::flat_map _cachedOutline; mutable std::unique_ptr _glare; Fn _repaint; @@ -126,12 +140,14 @@ KeyboardStyle::KeyboardStyle( , _repaint(std::move(repaint)) { } -void KeyboardStyle::startPaint( +void KeyboardStyle::paintButtonStart( QPainter &p, - const Ui::ChatStyle *st) const { + const Ui::ChatStyle *st, + HistoryMessageMarkupButton::Color color) const { + using Color = HistoryMessageMarkupButton::Color; Expects(st != nullptr); - p.setPen(st->msgServiceFg()); + p.setPen((color == Color::Normal) ? st->msgServiceFg() : st::white); } const style::TextStyle &KeyboardStyle::textStyle() const { @@ -167,12 +183,13 @@ void KeyboardStyle::paintButtonBg( QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, Ui::BubbleRounding rounding, float64 howMuchOver) const { Expects(st != nullptr); using Corner = Ui::BubbleCornerRounding; - auto &cachedBg = _cachedBg[rounding.key()]; + auto &cachedBg = _cachedBg[CacheKey{ rounding.key(), color }]; const auto sti = &st->imageStyle(false); const auto ratio = style::DevicePixelRatio(); @@ -188,13 +205,34 @@ void KeyboardStyle::paintButtonBg( { auto painter = QPainter(&cachedBg.image); - const auto &small = sti->msgServiceBgCornersSmall; - const auto &large = sti->msgServiceBgCornersLarge; + using Color = HistoryMessageMarkupButton::Color; + const auto normal = (color == Color::Normal); + const auto colored = style::owned_color((color == Color::Primary) + ? QColor(0x37, 0x8e, 0xae) + : (color == Color::Danger) + ? QColor(0xc9, 0x54, 0x3e) + : QColor(0x48, 0x9d, 0x38)); + const auto smallColored = normal + ? Ui::CornersPixmaps() + : Ui::PrepareCornerPixmaps( + Ui::BubbleRadiusSmall(), + colored.color()); + const auto largeColored = normal + ? Ui::CornersPixmaps() + : Ui::PrepareCornerPixmaps( + Ui::BubbleRadiusLarge(), + colored.color()); + const auto small = normal + ? &sti->msgServiceBgCornersSmall + : &smallColored; + const auto large = normal + ? &sti->msgServiceBgCornersLarge + : &largeColored; auto corners = Ui::CornersPixmaps(); int radiuses[4]; for (auto i = 0; i != 4; ++i) { const auto isLarge = (rounding[i] == Corner::Large); - corners.p[i] = (isLarge ? large : small).p[i]; + corners.p[i] = (isLarge ? large : small)->p[i]; radiuses[i] = Ui::CachedCornerRadiusValue(isLarge ? Ui::CachedCornerRadius::BubbleLarge : Ui::CachedCornerRadius::BubbleSmall); @@ -206,7 +244,11 @@ void KeyboardStyle::paintButtonBg( radiuses[1], radiuses[2], radiuses[3]); - Ui::FillRoundRect(painter, r, sti->msgServiceBg, corners); + Ui::FillRoundRect( + painter, + r, + normal ? sti->msgServiceBg : colored.color(), + corners); } } p.drawImage(rect.topLeft(), cachedBg.image); @@ -255,6 +297,7 @@ void KeyboardStyle::paintButtonLoading( QPainter &p, const Ui::ChatStyle *st, const QRect &rect, + HistoryMessageMarkupButton::Color color, int outerWidth, Ui::BubbleRounding rounding) const { Expects(st != nullptr); @@ -270,7 +313,7 @@ void KeyboardStyle::paintButtonLoading( } const auto cacheKey = rounding.key(); - auto &cachedBg = _cachedBg[cacheKey]; + auto &cachedBg = _cachedBg[CacheKey{ cacheKey, color }]; if (!cachedBg.image.isNull()) { if (_glare && _glare->glare.birthTime) { const auto progress = _glare->progress(crl::now()); diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 1adfc02cd0..c60cfc0f4f 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -999,7 +999,8 @@ void Message::draw(Painter &p, const PaintContext &context) const { context.st, messageRounding, g.width(), - context.clip.translated(-keyboardPosition)); + context.clip.translated(-keyboardPosition), + context.paused); p.translate(-keyboardPosition); } diff --git a/Telegram/SourceFiles/history/view/history_view_service_message.cpp b/Telegram/SourceFiles/history/view/history_view_service_message.cpp index c629384294..b2af07bd0c 100644 --- a/Telegram/SourceFiles/history/view/history_view_service_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_service_message.cpp @@ -656,7 +656,8 @@ void Service::draw(Painter &p, const PaintContext &context) const { context.st, KeyboardRounding(), keyboardWidth, - context.clip.translated(-keyboardPosition)); + context.clip.translated(-keyboardPosition), + context.paused); p.translate(-keyboardPosition); } diff --git a/Telegram/SourceFiles/ui/chat/group_call_bar.cpp b/Telegram/SourceFiles/ui/chat/group_call_bar.cpp index 45a30b287e..d8740e3be6 100644 --- a/Telegram/SourceFiles/ui/chat/group_call_bar.cpp +++ b/Telegram/SourceFiles/ui/chat/group_call_bar.cpp @@ -191,6 +191,7 @@ void GroupCallBar::refreshScheduledProcess() { _inner.get(), tr::lng_group_call_join(), st::groupCallTopBarJoin); + _join->setTextTransform(RoundButton::TextTransform::NoTransform); setupRightButton(_join.get()); } } else if (!_scheduledProcess) {