diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index d9d3b9a6f..275cf3f73 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -82,7 +82,8 @@ using TLStickerSet = MTPmessages_StickerSet; [[nodiscard]] std::optional<QColor> ComputeImageColor( const style::icon &lockIcon, - const QImage &frame) { + const QImage &frame, + RectPart part) { if (frame.isNull() || frame.format() != QImage::Format_ARGB32_Premultiplied) { return {}; @@ -91,13 +92,29 @@ using TLStickerSet = MTPmessages_StickerSet; auto sg = int64(); auto sb = int64(); auto sa = int64(); - const auto factor = frame.devicePixelRatio(); + const auto factor = style::DevicePixelRatio(); const auto size = lockIcon.size() * factor; const auto width = std::min(frame.width(), size.width()); const auto height = std::min(frame.height(), size.height()); - const auto skipx = (frame.width() - width) / 2; const auto radius = st::roundRadiusSmall; - const auto skipy = std::max(frame.height() - height - radius, 0); + const auto skipx = (part == RectPart::TopLeft + || part == RectPart::Left + || part == RectPart::BottomLeft) + ? 0 + : (part == RectPart::Top + || part == RectPart::Center + || part == RectPart::Bottom) + ? (frame.width() - width) / 2 + : std::max(frame.width() - width - radius, 0); + const auto skipy = (part == RectPart::TopLeft + || part == RectPart::Top + || part == RectPart::TopRight) + ? 0 + : (part == RectPart::Left + || part == RectPart::Center + || part == RectPart::Right) + ? (frame.height() - height) / 2 + : std::max(frame.height() - height - radius, 0); const auto perline = frame.bytesPerLine(); const auto addperline = perline - (width * 4); auto bits = static_cast<const uchar*>(frame.bits()) @@ -121,17 +138,20 @@ using TLStickerSet = MTPmessages_StickerSet; [[nodiscard]] QColor ComputeLockColor( const style::icon &lockIcon, - const QImage &frame) { + const QImage &frame, + RectPart part) { return ComputeImageColor( lockIcon, - frame + frame, + part ).value_or(st::windowSubTextFg->c); } void ValidatePremiumLockBg( const style::icon &lockIcon, QImage &image, - const QImage &frame) { + const QImage &frame, + RectPart part) { if (!image.isNull()) { return; } @@ -142,7 +162,7 @@ void ValidatePremiumLockBg( QImage::Format_ARGB32_Premultiplied); image.setDevicePixelRatio(factor); auto p = QPainter(&image); - const auto color = ComputeLockColor(lockIcon, frame); + const auto color = ComputeLockColor(lockIcon, frame, part); p.fillRect( QRect(QPoint(), size), anim::color(color, st::windowSubTextFg, kGrayLockOpacity)); @@ -195,8 +215,10 @@ void ValidatePremiumStarFg(const style::icon &lockIcon, QImage &image) { StickerPremiumMark::StickerPremiumMark( not_null<Main::Session*> session, - const style::icon &lockIcon) -: _lockIcon(lockIcon) { + const style::icon &lockIcon, + RectPart part) +: _lockIcon(lockIcon) +, _part(part) { style::PaletteChanged( ) | rpl::start_with_next([=] { _lockGray = QImage(); @@ -221,9 +243,13 @@ void StickerPremiumMark::paint( const auto &bg = frame.isNull() ? _lockGray : backCache; const auto factor = style::DevicePixelRatio(); const auto radius = st::roundRadiusSmall; - const auto point = position + QPoint( - (singleSize.width() - (bg.width() / factor) - radius), - singleSize.height() - (bg.height() / factor) - radius); + const auto shiftx = (_part == RectPart::Center) + ? (singleSize.width() - (bg.width() / factor)) / 2 + : (singleSize.width() - (bg.width() / factor) - radius); + const auto shifty = (_part == RectPart::Center) + ? (singleSize.height() - (bg.height() / factor)) / 2 + : (singleSize.height() - (bg.height() / factor) - radius); + const auto point = position + QPoint(shiftx, shifty); p.drawImage(point, bg); if (_premium) { validateStar(); @@ -237,7 +263,7 @@ void StickerPremiumMark::validateLock( const QImage &frame, QImage &backCache) { auto &image = frame.isNull() ? _lockGray : backCache; - ValidatePremiumLockBg(_lockIcon, image, frame); + ValidatePremiumLockBg(_lockIcon, image, frame, _part); } void StickerPremiumMark::validateStar() { diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.h b/Telegram/SourceFiles/boxes/sticker_set_box.h index e718cc45e..07e0168e2 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.h +++ b/Telegram/SourceFiles/boxes/sticker_set_box.h @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/layers/box_content.h" #include "base/timer.h" #include "data/stickers/data_stickers.h" +#include "ui/rect_part.h" namespace Window { class SessionController; @@ -32,7 +33,8 @@ class StickerPremiumMark final { public: StickerPremiumMark( not_null<Main::Session*> session, - const style::icon &lockIcon); + const style::icon &lockIcon, + RectPart part = RectPart::Bottom); void paint( QPainter &p, @@ -49,6 +51,7 @@ private: const style::icon &_lockIcon; QImage _lockGray; QImage _star; + RectPart _part = RectPart::Bottom; bool _premium = false; rpl::lifetime _lifetime; diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp index 565ee6c7a..dc236146a 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/peer_gifts/info_peer_gifts_common.h" +#include "boxes/sticker_set_box.h" #include "chat_helpers/stickers_gift_box_pack.h" #include "chat_helpers/stickers_lottie.h" #include "core/ui_integration.h" @@ -159,6 +160,8 @@ void GiftButton::resizeEvent(QResizeEvent *e) { void GiftButton::paintEvent(QPaintEvent *e) { auto p = QPainter(this); + const auto hidden = v::is<GiftTypeStars>(_descriptor) + && v::get<GiftTypeStars>(_descriptor).hidden;; const auto position = QPoint(_extend.left(), _extend.top()); const auto background = _delegate->background(); const auto dpr = int(background.devicePixelRatio()); @@ -193,6 +196,7 @@ void GiftButton::paintEvent(QPaintEvent *e) { p.drawImage(_extend.left() + skip, _extend.top() + skip, image); } + auto frame = QImage(); if (_player && _player->ready()) { const auto paused = !isOver(); auto info = _player->frame( @@ -201,11 +205,12 @@ void GiftButton::paintEvent(QPaintEvent *e) { false, crl::now(), paused); + frame = info.image; const auto finished = (info.index + 1 == _player->framesCount()); if (!finished || !paused) { _player->markFrameShown(); } - const auto size = info.image.size() / style::DevicePixelRatio(); + const auto size = frame.size() / style::DevicePixelRatio(); p.drawImage( QRect( (width - size.width()) / 2, @@ -214,7 +219,21 @@ void GiftButton::paintEvent(QPaintEvent *e) { : st::giftBoxStickerTop), size.width(), size.height()), - info.image); + frame); + } + if (hidden) { + const auto topleft = QPoint( + (width - st::giftBoxStickerSize.width()) / 2, + (_text.isEmpty() + ? st::giftBoxStickerStarTop + : st::giftBoxStickerTop)); + _delegate->hiddenMark()->paint( + p, + frame, + _hiddenBgCache, + topleft, + st::giftBoxStickerSize, + width); } auto hq = PainterHighQualityEnabler(p); @@ -290,9 +309,16 @@ void GiftButton::paintEvent(QPaintEvent *e) { } Delegate::Delegate(not_null<Window::SessionController*> window) -: _window(window) { +: _window(window) +, _hiddenMark(std::make_unique<StickerPremiumMark>( + &window->session(), + st::giftBoxHiddenMark, + RectPart::Center)) { } +Delegate::Delegate(Delegate &&other) = default; + +Delegate::~Delegate() = default; TextWithEntities Delegate::star() { const auto owner = &_window->session().data(); @@ -385,4 +411,8 @@ DocumentData *Delegate::lookupSticker(const GiftDescriptor &descriptor) { }); } +not_null<StickerPremiumMark*> Delegate::hiddenMark() { + return _hiddenMark.get(); +} + } // namespace Info::PeerGifts diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h index c53ce9503..b8188454d 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h @@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/abstract_button.h" #include "ui/text/text.h" +class StickerPremiumMark; + namespace HistoryView { class StickerPlayer; } // namespace HistoryView @@ -43,6 +45,7 @@ struct GiftTypeStars { PeerData *from = nullptr; int limitedCount = 0; bool userpic = false; + bool hidden = false; bool mine = false; [[nodiscard]] friend inline bool operator==( @@ -67,6 +70,7 @@ public: [[nodiscard]] virtual QImage background() = 0; [[nodiscard]] virtual DocumentData *lookupSticker( const GiftDescriptor &descriptor) = 0; + [[nodiscard]] virtual not_null<StickerPremiumMark*> hiddenMark() = 0; }; class GiftButton final : public Ui::AbstractButton { @@ -85,6 +89,7 @@ private: void unsubscribe(); const not_null<GiftButtonDelegate*> _delegate; + QImage _hiddenBgCache; GiftDescriptor _descriptor; Ui::Text::String _text; Ui::Text::String _price; @@ -102,6 +107,8 @@ private: class Delegate final : public GiftButtonDelegate { public: explicit Delegate(not_null<Window::SessionController*> window); + Delegate(Delegate &&other); + ~Delegate(); TextWithEntities star() override; std::any textContext() override; @@ -109,9 +116,11 @@ public: QMargins buttonExtend() override; QImage background() override; DocumentData *lookupSticker(const GiftDescriptor &descriptor) override; + not_null<StickerPremiumMark*> hiddenMark() override; private: const not_null<Window::SessionController*> _window; + std::unique_ptr<StickerPremiumMark> _hiddenMark; QSize _single; QImage _bg; diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp index a10942055..a455dd3aa 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp @@ -40,6 +40,7 @@ constexpr auto kPerPage = 50; : to->owner().peer(gift.fromId).get()), .limitedCount = gift.gift.limitedCount, .userpic = true, + .hidden = gift.hidden, .mine = to->isSelf(), }; } diff --git a/Telegram/SourceFiles/ui/effects/credits.style b/Telegram/SourceFiles/ui/effects/credits.style index ff3d718b3..1209ba052 100644 --- a/Telegram/SourceFiles/ui/effects/credits.style +++ b/Telegram/SourceFiles/ui/effects/credits.style @@ -125,3 +125,4 @@ giftBoxTextField: InputField(defaultInputField) { style: defaultTextStyle; } giftBoxTextPadding: margins(20px, 15px, 20px, 11px); +giftBoxHiddenMark: icon{{ "menu/stealth", premiumButtonFg }};