| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /*
- 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 "ui/boxes/show_or_premium_box.h"
- #include "base/object_ptr.h"
- #include "lang/lang_keys.h"
- #include "ui/effects/premium_graphics.h"
- #include "ui/layers/generic_box.h"
- #include "ui/text/text_utilities.h"
- #include "ui/widgets/buttons.h"
- #include "ui/widgets/gradient_round_button.h"
- #include "ui/widgets/labels.h"
- #include "ui/painter.h"
- #include "styles/style_layers.h"
- #include "styles/style_premium.h"
- namespace Ui {
- namespace {
- constexpr auto kShowOrLineOpacity = 0.3;
- [[nodiscard]] object_ptr<RpWidget> MakeShowOrPremiumIcon(
- not_null<RpWidget*> parent,
- not_null<const style::icon*> icon) {
- const auto margin = st::showOrIconMargin;
- const auto padding = st::showOrIconPadding;
- const auto inner = padding.top() + icon->height() + padding.bottom();
- const auto full = margin.top() + inner + margin.bottom();
- auto result = object_ptr<FixedHeightWidget>(parent, full);
- const auto raw = result.data();
- raw->resize(st::boxWideWidth, full);
- raw->paintRequest(
- ) | rpl::start_with_next([=] {
- auto p = QPainter(raw);
- auto hq = PainterHighQualityEnabler(p);
- const auto width = raw->width();
- const auto position = QPoint((width - inner) / 2, margin.top());
- const auto rect = QRect(position, QSize(inner, inner));
- const auto shift = QPoint(padding.left(), padding.top());
- p.setPen(Qt::NoPen);
- p.setBrush(st::showOrIconBg);
- p.drawEllipse(rect);
- icon->paint(p, position + shift, width);
- }, raw->lifetime());
- return result;
- }
- } // namespace
- object_ptr<RpWidget> MakeShowOrLabel(
- not_null<RpWidget*> parent,
- rpl::producer<QString> text) {
- auto result = object_ptr<FlatLabel>(
- parent,
- std::move(text),
- st::showOrLabel);
- const auto raw = result.data();
- raw->paintRequest(
- ) | rpl::start_with_next([=] {
- auto p = QPainter(raw);
- const auto full = st::showOrLineWidth;
- const auto left = (raw->width() - full) / 2;
- const auto text = raw->textMaxWidth() + 2 * st::showOrLabelSkip;
- const auto fill = (full - text) / 2;
- const auto stroke = st::lineWidth;
- const auto top = st::showOrLineTop;
- p.setOpacity(kShowOrLineOpacity);
- p.fillRect(left, top, fill, stroke, st::windowSubTextFg);
- const auto start = left + full - fill;
- p.fillRect(start, top, fill, stroke, st::windowSubTextFg);
- }, raw->lifetime());
- return result;
- }
- void ShowOrPremiumBox(
- not_null<GenericBox*> box,
- ShowOrPremium type,
- QString shortName,
- Fn<void()> justShow,
- Fn<void()> toPremium) {
- struct Skin {
- rpl::producer<QString> showTitle;
- rpl::producer<TextWithEntities> showAbout;
- rpl::producer<QString> showButton;
- rpl::producer<QString> orPremium;
- rpl::producer<QString> premiumTitle;
- rpl::producer<TextWithEntities> premiumAbout;
- rpl::producer<QString> premiumButton;
- QString toast;
- const style::icon *icon = nullptr;
- };
- auto skin = (type == ShowOrPremium::LastSeen)
- ? Skin{
- tr::lng_lastseen_show_title(),
- tr::lng_lastseen_show_about(
- lt_user,
- rpl::single(TextWithEntities{ shortName }),
- Text::RichLangValue),
- tr::lng_lastseen_show_button(),
- tr::lng_lastseen_or(),
- tr::lng_lastseen_premium_title(),
- tr::lng_lastseen_premium_about(
- lt_user,
- rpl::single(TextWithEntities{ shortName }),
- Text::RichLangValue),
- tr::lng_lastseen_premium_button(),
- tr::lng_lastseen_shown_toast(tr::now),
- &st::showOrIconLastSeen,
- }
- : Skin{
- tr::lng_readtime_show_title(),
- tr::lng_readtime_show_about(
- lt_user,
- rpl::single(TextWithEntities{ shortName }),
- Text::RichLangValue),
- tr::lng_readtime_show_button(),
- tr::lng_readtime_or(),
- tr::lng_readtime_premium_title(),
- tr::lng_readtime_premium_about(
- lt_user,
- rpl::single(TextWithEntities{ shortName }),
- Text::RichLangValue),
- tr::lng_readtime_premium_button(),
- tr::lng_readtime_shown_toast(tr::now),
- &st::showOrIconReadTime,
- };
- box->setStyle(st::showOrBox);
- box->setWidth(st::boxWideWidth);
- box->addTopButton(st::boxTitleClose, [=] {
- box->closeBox();
- });
- const auto buttonPadding = QMargins(
- st::showOrBox.buttonPadding.left(),
- 0,
- st::showOrBox.buttonPadding.right(),
- 0);
- box->addRow(MakeShowOrPremiumIcon(box, skin.icon));
- box->addRow(
- object_ptr<FlatLabel>(
- box,
- std::move(skin.showTitle),
- st::boostCenteredTitle),
- st::showOrTitlePadding + buttonPadding);
- box->addRow(
- object_ptr<FlatLabel>(
- box,
- std::move(skin.showAbout),
- st::boostText),
- st::showOrAboutPadding + buttonPadding);
- const auto show = box->addRow(
- object_ptr<RoundButton>(
- box,
- std::move(skin.showButton),
- st::showOrShowButton),
- buttonPadding);
- show->setTextTransform(RoundButton::TextTransform::NoTransform);
- box->addRow(
- MakeShowOrLabel(box, std::move(skin.orPremium)),
- st::showOrLabelPadding + buttonPadding);
- box->addRow(
- object_ptr<FlatLabel>(
- box,
- std::move(skin.premiumTitle),
- st::boostCenteredTitle),
- st::showOrTitlePadding + buttonPadding);
- box->addRow(
- object_ptr<FlatLabel>(
- box,
- std::move(skin.premiumAbout),
- st::boostText),
- st::showOrPremiumAboutPadding + buttonPadding);
- const auto premium = CreateChild<GradientButton>(
- box.get(),
- Premium::ButtonGradientStops());
- premium->resize(st::showOrShowButton.width, st::showOrShowButton.height);
- const auto label = CreateChild<FlatLabel>(
- premium,
- std::move(skin.premiumButton),
- st::premiumPreviewButtonLabel);
- label->setAttribute(Qt::WA_TransparentForMouseEvents);
- rpl::combine(
- premium->widthValue(),
- label->widthValue()
- ) | rpl::start_with_next([=](int outer, int width) {
- label->moveToLeft(
- (outer - width) / 2,
- st::premiumPreviewBox.button.textTop,
- outer);
- }, label->lifetime());
- box->setShowFinishedCallback([=] {
- premium->startGlareAnimation();
- });
- box->addButton(
- object_ptr<AbstractButton>::fromRaw(premium));
- show->setClickedCallback([box, justShow, toast = skin.toast] {
- justShow();
- box->uiShow()->showToast(toast);
- box->closeBox();
- });
- premium->setClickedCallback(std::move(toPremium));
- }
- } // namespace Ui
|