From afb336ed4180875cd5416bcb38faeb7e623ffa1a Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 5 Jul 2022 22:29:46 +0300 Subject: [PATCH] Added list for options of premium gifts. --- Telegram/SourceFiles/ui/effects/premium.style | 12 ++ .../ui/effects/premium_graphics.cpp | 156 ++++++++++++++++++ .../SourceFiles/ui/effects/premium_graphics.h | 13 ++ 3 files changed, 181 insertions(+) diff --git a/Telegram/SourceFiles/ui/effects/premium.style b/Telegram/SourceFiles/ui/effects/premium.style index 60424da01..fbaea3834 100644 --- a/Telegram/SourceFiles/ui/effects/premium.style +++ b/Telegram/SourceFiles/ui/effects/premium.style @@ -95,3 +95,15 @@ premiumAccountsLabelRadius: 6; premiumAccountsNameTop: 13px; premiumAccountsPadding: margins(0px, 20px, 0px, 14px); premiumAccountsHeight: 105px; + +premiumGiftRowHeight: 56px; +premiumGiftRowBorderWidth: 2px; +premiumGiftRowBorderRadius: 9px; +premiumGiftRowPaddings: margins(19px, 2px, 17px, 2px); +premiumGiftRowMargins: margins(14px, 0px, 15px, 0px); +premiumGiftRowSubtitleTop: 7px; +premiumGiftRowTextLeft: 53px; +premiumGiftRowBadgeHeight: 18px; +premiumGiftRowBadgeRadius: 4px; +premiumGiftRowBadgeMargins: margins(5px, 1px, 5px, 0px); + diff --git a/Telegram/SourceFiles/ui/effects/premium_graphics.cpp b/Telegram/SourceFiles/ui/effects/premium_graphics.cpp index 8a5614ebe..c8de47fe0 100644 --- a/Telegram/SourceFiles/ui/effects/premium_graphics.cpp +++ b/Telegram/SourceFiles/ui/effects/premium_graphics.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/premium_graphics.h" #include "lang/lang_keys.h" +#include "ui/abstract_button.h" #include "ui/effects/animations.h" #include "ui/effects/gradient.h" #include "ui/effects/numbers_animation.h" @@ -22,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_settings.h" #include "styles/style_layers.h" #include "styles/style_widgets.h" +#include "styles/style_window.h" #include @@ -853,6 +855,13 @@ QGradientStops FullHeightGradientStops() { }; } +QGradientStops GiftGradientStops() { + return { + { 0., st::premiumButtonBg1->c }, + { 1., st::premiumButtonBg2->c }, + }; +} + void ShowListBox( not_null box, std::vector entries) { @@ -925,5 +934,152 @@ void ShowListBox( box->setWidth(st::boxWideWidth); } +void AddGiftOptions( + not_null parent, + std::shared_ptr group, + std::vector gifts) { + + struct Edges { + Ui::RpWidget *top = nullptr; + Ui::RpWidget *bottom = nullptr; + }; + const auto edges = parent->lifetime().make_state(); + struct Animation { + int nowIndex = 0; + Ui::Animations::Simple animation; + }; + const auto animation = parent->lifetime().make_state(); + + const auto stops = GiftGradientStops(); + + const auto addRow = [&](const GiftInfo &info, int index) { + const auto row = parent->add( + object_ptr(parent), + st::premiumGiftRowPaddings); + row->resize(row->width(), st::premiumGiftRowHeight); + { + if (!index) { + edges->top = row; + } + edges->bottom = row; + } + + const auto &stCheckbox = st::defaultBoxCheckbox; + const auto radio = Ui::CreateChild( + row, + group, + index, + QString(), + stCheckbox); + radio->setAttribute(Qt::WA_TransparentForMouseEvents); + + row->sizeValue( + ) | rpl::start_with_next([=, margins = stCheckbox.margin]( + const QSize &s) { + const auto radioHeight = radio->height() + - margins.top() + - margins.bottom(); + radio->moveToLeft( + st::premiumGiftRowMargins.left(), + (s.height() - radioHeight) / 2); + }, radio->lifetime()); + + row->paintRequest( + ) | rpl::start_with_next([=](const QRect &r) { + Painter p(row); + PainterHighQualityEnabler hq(p); + + p.fillRect(r, Qt::transparent); + + const auto left = st::premiumGiftRowTextLeft; + const auto borderWidth = st::premiumGiftRowBorderWidth; + const auto halfHeight = row->height() / 2; + + const auto titleFont = st::semiboldFont; + p.setFont(titleFont); + p.setPen(st::boxTextFg); + p.drawText( + left, + st::premiumGiftRowSubtitleTop + titleFont->ascent, + info.duration); + + const auto discountFont = st::windowFiltersButton.badgeStyle.font; + const auto discountWidth = discountFont->width(info.discount); + const auto &discountMargins = st::premiumGiftRowBadgeMargins; + const auto discountRect = QRect( + left, + halfHeight + discountMargins.top(), + discountWidth + + discountMargins.left() + + discountMargins.right(), + st::premiumGiftRowBadgeHeight); + { + const auto from = edges->top->y(); + const auto to = edges->bottom->y() + edges->bottom->height(); + auto partialGradient = PartialGradient(from, to, stops); + + p.setPen(Qt::NoPen); + p.setBrush(partialGradient.compute(row->y(), row->height())); + const auto round = st::premiumGiftRowBadgeRadius; + p.drawRoundedRect(discountRect, round, round); + } + + if (animation->nowIndex == index) { + const auto progress = animation->animation.value(1.); + const auto w = row->width(); + auto gradient = QLinearGradient(w - w * progress, 0, w * 2, 0); + gradient.setSpread(QGradient::Spread::RepeatSpread); + gradient.setStops(stops); + const auto pen = QPen(QBrush(gradient), borderWidth); + p.setPen(pen); + p.setBrush(Qt::NoBrush); + const auto borderRect = row->rect() + - QMargins( + pen.width() / 2, + pen.width() / 2, + pen.width() / 2, + pen.width() / 2); + const auto round = st::premiumGiftRowBorderRadius; + p.drawRoundedRect(borderRect, round, round); + } + + p.setPen(st::boxBg); + p.setFont(discountFont); + p.drawText(discountRect, info.discount, style::al_center); + + const auto perRect = QMargins(0, 0, row->width(), 0) + + discountRect.translated( + discountRect.width() + discountMargins.left(), + 0); + p.setPen(st::windowSubTextFg); + p.setFont(st::shareBoxListItem.nameStyle.font); + p.drawText(perRect, info.perMonth, style::al_left); + + const auto totalRect = row->rect() + - QMargins(0, 0, st::premiumGiftRowMargins.right(), 0); + p.setFont(st::normalFont); + p.drawText(totalRect, info.total, style::al_right); + }, row->lifetime()); + + row->setClickedCallback([=, duration = st::defaultCheck.duration] { + group->setValue(index); + animation->nowIndex = group->value(); + animation->animation.stop(); + animation->animation.start( + [=] { parent->update(); }, + 0., + 1., + duration); + }); + + }; + for (auto i = 0; i < gifts.size(); i++) { + addRow(gifts[i], i); + } + + parent->resizeToWidth(parent->height()); + parent->update(); +} + } // namespace Premium } // namespace Ui diff --git a/Telegram/SourceFiles/ui/effects/premium_graphics.h b/Telegram/SourceFiles/ui/effects/premium_graphics.h index ede3346eb..644daa202 100644 --- a/Telegram/SourceFiles/ui/effects/premium_graphics.h +++ b/Telegram/SourceFiles/ui/effects/premium_graphics.h @@ -29,6 +29,13 @@ class VerticalLayout; namespace Premium { +struct GiftInfo { + QString duration; + QString discount; + QString perMonth; + QString total; +}; + void AddBubbleRow( not_null parent, rpl::producer<> showFinishes, @@ -70,6 +77,7 @@ void AddAccountsRow( [[nodiscard]] QGradientStops ButtonGradientStops(); [[nodiscard]] QGradientStops LockGradientStops(); [[nodiscard]] QGradientStops FullHeightGradientStops(); +[[nodiscard]] QGradientStops GiftGradientStops(); struct ListEntry final { rpl::producer subtitle; @@ -82,5 +90,10 @@ void ShowListBox( not_null box, std::vector entries); +void AddGiftOptions( + not_null parent, + std::shared_ptr group, + std::vector gifts); + } // namespace Premium } // namespace Ui