/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/channel_statistics/boosts/giveaway/boost_badge.h" #include "ui/effects/radial_animation.h" #include "ui/painter.h" #include "ui/rect.h" #include "ui/rp_widget.h" #include "ui/widgets/labels.h" #include "styles/style_giveaway.h" #include "styles/style_statistics.h" #include "styles/style_widgets.h" namespace Info::Statistics { not_null InfiniteRadialAnimationWidget( not_null parent, int size, const style::InfiniteRadialAnimation *st) { class Widget final : public Ui::RpWidget { public: Widget( not_null p, int size, const style::InfiniteRadialAnimation *st) : Ui::RpWidget(p) , _st(st ? st : &st::startGiveawayButtonLoading) , _animation([=] { update(); }, *_st) { resize(size, size); shownValue() | rpl::start_with_next([=](bool v) { return v ? _animation.start() : _animation.stop(anim::type::instant); }, lifetime()); } protected: void paintEvent(QPaintEvent *e) override { auto p = QPainter(this); p.setPen(st::activeButtonFg); p.setBrush(st::activeButtonFg); const auto r = rect() - Margins(_st->thickness); _animation.draw(p, r.topLeft(), r.size(), width()); } private: const style::InfiniteRadialAnimation *_st; Ui::InfiniteRadialAnimation _animation; }; return Ui::CreateChild(parent.get(), size, st); } void AddChildToWidgetCenter( not_null parent, not_null child) { parent->sizeValue( ) | rpl::start_with_next([=](const QSize &s) { const auto size = child->size(); child->moveToLeft( (s.width() - size.width()) / 2, (s.height() - size.height()) / 2); }, child->lifetime()); } QImage CreateBadge( const style::TextStyle &textStyle, const QString &text, int badgeHeight, const style::margins &textPadding, const style::color &bg, const style::color &fg, float64 bgOpacity, const style::margins &iconPadding, const style::icon &icon) { auto badgeText = Ui::Text::String(textStyle, text); const auto badgeTextWidth = badgeText.maxWidth(); const auto badgex = 0; const auto badgey = 0; const auto badgeh = 0 + badgeHeight; const auto badgew = badgeTextWidth + rect::m::sum::h(textPadding); auto result = QImage( QSize(badgew, badgeh) * style::DevicePixelRatio(), QImage::Format_ARGB32_Premultiplied); result.fill(Qt::transparent); result.setDevicePixelRatio(style::DevicePixelRatio()); { auto p = Painter(&result); p.setPen(Qt::NoPen); p.setBrush(bg); const auto r = QRect(badgex, badgey, badgew, badgeh); { auto hq = PainterHighQualityEnabler(p); auto o = ScopedPainterOpacity(p, bgOpacity); p.drawRoundedRect(r, badgeh / 2, badgeh / 2); } p.setPen(fg); p.setBrush(Qt::NoBrush); badgeText.drawLeftElided( p, r.x() + textPadding.left(), badgey + textPadding.top(), badgew, badgew * 2); icon.paint( p, QPoint(r.x() + iconPadding.left(), r.y() + iconPadding.top()), badgew * 2); } return result; } void AddLabelWithBadgeToButton( not_null parent, rpl::producer text, rpl::producer number, rpl::producer shown) { struct State { QImage badge; }; const auto state = parent->lifetime().make_state(); const auto label = Ui::CreateChild( parent.get(), st::startGiveawayButtonLabelSimple); std::move( text ) | rpl::start_with_next([=](const QString &s) { label->setText(s); }, label->lifetime()); const auto count = Ui::CreateChild(parent.get()); count->paintRequest( ) | rpl::start_with_next([=] { auto p = QPainter(count); p.drawImage(0, 0, state->badge); }, count->lifetime()); std::move( number ) | rpl::start_with_next([=](int c) { state->badge = Info::Statistics::CreateBadge( st::startGiveawayButtonTextStyle, QString::number(c), st::boostsListBadgeHeight, st::startGiveawayButtonBadgeTextPadding, st::activeButtonFg, st::activeButtonBg, 1., st::boostsListMiniIconPadding, st::startGiveawayButtonMiniIcon); count->resize(state->badge.size() / style::DevicePixelRatio()); count->update(); }, count->lifetime()); std::move( shown ) | rpl::start_with_next([=](bool shown) { count->setVisible(shown); label->setVisible(shown); }, count->lifetime()); rpl::combine( parent->sizeValue(), label->sizeValue(), count->sizeValue() ) | rpl::start_with_next([=]( const QSize &s, const QSize &s1, const QSize &s2) { const auto sum = st::startGiveawayButtonMiniIconSkip + s1.width() + s2.width(); const auto contentLeft = (s.width() - sum) / 2; label->moveToLeft(contentLeft, (s.height() - s1.height()) / 2); count->moveToLeft( contentLeft + sum - s2.width(), (s.height() - s2.height()) / 2 + st::boostsListMiniIconSkip); }, parent->lifetime()); } } // namespace Info::Statistics