Added initial animation to custom top bar in premium settings.

This commit is contained in:
23rd 2022-05-23 07:01:31 +03:00
parent a284fa3273
commit 2a4faf22f6
4 changed files with 155 additions and 58 deletions

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 76 73" xmlns="http://www.w3.org/2000/svg">
<title>Star</title>
<g fill="none" fill-rule="evenodd">
<g transform="translate(-5 -5)" fill="#fff">
<path d="m40.806 66.037-17.389 10.627c-1.5943 0.97436-3.6766 0.4718-4.651-1.1225-0.47558-0.77817-0.61685-1.7154-0.39178-2.5992l2.8114-11.039c0.91458-3.5913 3.3384-6.6111 6.6467-8.281l15.265-7.7056c0.84279-0.42542 1.1811-1.4535 0.7557-2.2963-0.3335-0.66067-1.0543-1.0317-1.7857-0.91925l-17.288 2.6578c-4.0448 0.62183-8.1617-0.52596-11.301-3.1508l-7.112-5.9459c-1.4335-1.1985-1.624-3.3321-0.42557-4.7656 0.58391-0.69842 1.4246-1.1321 2.3322-1.2029l20.357-1.5894c1.3848-0.10811 2.5919-0.98375 3.1246-2.2665l7.8535-18.913c0.71656-1.7256 2.6963-2.5436 4.4219-1.8271 0.82676 0.34331 1.4838 1.0003 1.8271 1.8271l7.8535 18.913c0.53267 1.2828 1.7398 2.1584 3.1246 2.2665l20.456 1.5971c1.8628 0.14544 3.255 1.7734 3.1096 3.6363-0.070088 0.89771-0.49515 1.7304-1.1811 2.3138l-15.589 13.259c-1.0616 0.90287-1.5248 2.3263-1.1979 3.681l4.7945 19.87c0.43827 1.8163-0.67888 3.6441-2.4952 4.0824-0.87218 0.21045-1.7922 0.065833-2.5578-0.40204l-17.515-10.704c-1.1827-0.72283-2.6706-0.72283-3.8533 0z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -26,6 +26,7 @@
<file alias="recording/info_video_landscape.svg">../../art/recording/recording_info_video_landscape.svg</file>
<file alias="recording/info_video_portrait.svg">../../art/recording/recording_info_video_portrait.svg</file>
<file alias="icons/settings/dino.svg">../../icons/settings/dino.svg</file>
<file alias="icons/settings/star.svg">../../icons/settings/star.svg</file>
</qresource>
<qresource prefix="/icons">
<file alias="calls/hands.lottie">../../icons/calls/hands.lottie</file>

View file

@ -425,6 +425,8 @@ settingsPremiumDescriptionSkip: 3px;
settingsPremiumButtonPadding: margins(11px, 11px, 11px, 3px);
settingsPremiumTopBarBackIcon: icon {{ "info/info_back", premiumButtonFg }};
settingsPremiumTopBarBackIconOver: icon {{ "info/info_back", premiumButtonFg }};
settingsPremiumStarSize: size(77px, 73px);
settingsPremiumStarTopSkip: 42px;
settingsPremiumTopBarBack: IconButton(infoTopBarBack) {
icon: settingsPremiumTopBarBackIcon;
iconOver: settingsPremiumTopBarBackIconOver;

View file

@ -37,11 +37,137 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_layers.h"
#include "styles/style_settings.h"
#include <QSvgRenderer>
namespace Settings {
namespace {
using SectionCustomTopBarData = Info::Settings::SectionCustomTopBarData;
constexpr auto kBodyAnimationPart = 0.90;
constexpr auto kTitleAnimationPart = 0.15;
class TopBar final : public Ui::RpWidget {
public:
TopBar(not_null<QWidget*> parent);
void setRoundEdges(bool value);
void setTextPosition(int x, int y);
protected:
void paintEvent(QPaintEvent *e) override;
private:
QSvgRenderer _star;
Ui::Text::String _title;
Ui::Text::String _about;
QPoint _titlePosition;
bool _roundEdges = true;
};
TopBar::TopBar(not_null<QWidget*> parent)
: Ui::RpWidget(parent)
, _star(u":/gui/icons/settings/star.svg"_q)
, _title(st::boxTitle.style, tr::lng_premium_summary_title(tr::now)) {
_about.setMarkedText(
st::aboutLabel.style,
tr::lng_premium_summary_top_about(tr::now, Ui::Text::RichLangValue));
}
void TopBar::setRoundEdges(bool value) {
_roundEdges = value;
update();
}
void TopBar::setTextPosition(int x, int y) {
_titlePosition = { x, y };
}
void TopBar::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(e->rect(), Qt::transparent);
const auto progress = (height() - minimumHeight())
/ float64(maximumHeight() - minimumHeight());
const auto topProgress = 1. -
std::clamp(
(1. - progress) / kBodyAnimationPart,
0.,
1.);
const auto bodyProgress = topProgress;
const auto r = rect();
auto pathTop = QPainterPath();
if (_roundEdges) {
pathTop.addRoundedRect(r, st::boxRadius, st::boxRadius);
} else {
pathTop.addRect(r);
}
auto pathBottom = QPainterPath();
pathBottom.addRect(
QRect(
QPoint(r.x(), r.y() + r.height() - st::boxRadius),
QSize(r.width(), st::boxRadius)));
const auto gradientPointTop = r.height() / 3. * 2.;
auto gradient = QLinearGradient(
QPointF(0, gradientPointTop),
QPointF(r.width(), r.height() - gradientPointTop));
gradient.setColorAt(0., st::premiumButtonBg1->c);
gradient.setColorAt(.6, st::premiumButtonBg2->c);
gradient.setColorAt(1., st::premiumButtonBg3->c);
PainterHighQualityEnabler hq(p);
p.fillPath(pathTop + pathBottom, gradient);
p.setOpacity(bodyProgress);
const auto &starSize = st::settingsPremiumStarSize;
const auto starRect = QRectF(
QPointF(
(width() - starSize.width()) / 2,
st::settingsPremiumStarTopSkip * topProgress),
st::settingsPremiumStarSize);
_star.render(&p, starRect);
p.setPen(st::premiumButtonFg);
const auto &padding = st::boxRowPadding;
const auto availableWidth = width() - padding.left() - padding.right();
const auto titleTop = starRect.top()
+ starRect.height()
+ st::changePhoneTitlePadding.top();
const auto aboutTop = titleTop
+ _title.countHeight(availableWidth)
+ st::changePhoneTitlePadding.bottom();
p.setFont(st::aboutLabel.style.font);
_about.draw(p, padding.left(), aboutTop, availableWidth, style::al_top);
// Subtitle.
p.setFont(st::boxTitle.style.font);
_title.draw(p, padding.left(), titleTop, availableWidth, style::al_top);
// Title.
const auto titleProgress =
std::clamp(
(kTitleAnimationPart - progress) / kTitleAnimationPart,
0.,
1.);
if (titleProgress > 0.) {
p.setOpacity(titleProgress);
const auto availableWidth = width() - _titlePosition.x() * 2;
_title.drawElided(
p,
_titlePosition.x(),
_titlePosition.y(),
availableWidth);
}
}
class Premium : public Section<Premium> {
public:
Premium(
@ -108,29 +234,6 @@ void Premium::setStepDataReference(std::any &data) {
void Premium::setupContent() {
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
content->add(
object_ptr<Ui::CenterWrap<>>(
content,
object_ptr<Ui::FlatLabel>(
content,
tr::lng_premium_summary_title(),
st::changePhoneTitle)),
st::changePhoneTitlePadding);
const auto wrap = content->add(
object_ptr<Ui::CenterWrap<>>(
content,
object_ptr<Ui::FlatLabel>(
content,
tr::lng_premium_summary_top_about(Ui::Text::RichLangValue),
st::changePhoneDescription)),
st::changePhoneDescriptionPadding);
wrap->resize(
wrap->width(),
st::settingLocalPasscodeDescriptionHeight);
AddSkip(content);
AddDivider(content);
AddSkip(content);
const auto &st = st::settingsButton;
@ -266,42 +369,17 @@ void Premium::setupContent() {
QPointer<Ui::RpWidget> Premium::createPinnedToTop(
not_null<QWidget*> parent) {
const auto container = Ui::CreateChild<Ui::VerticalLayout>(parent.get());
const auto content = container->add(object_ptr<Ui::RpWidget>(container));
content->resize(content->width(), st::introQrStepsTop);
const auto content = Ui::CreateChild<TopBar>(parent.get());
container->setAttribute(Qt::WA_OpaquePaintEvent, false);
content->setAttribute(Qt::WA_OpaquePaintEvent, false);
content->paintRequest(
) | rpl::start_with_next([=](const QRect &paintRect) {
Painter p(content);
p.fillRect(paintRect, Qt::transparent);
const auto rect = content->rect();
auto pathTop = QPainterPath();
pathTop.addRoundedRect(rect, st::boxRadius, st::boxRadius);
auto pathBottom = QPainterPath();
pathBottom.addRect(
QRect(
QPoint(rect.x(), rect.y() + rect.height() - st::boxRadius),
QSize(rect.width(), st::boxRadius)));
const auto gradientPointTop = rect.height() / 3. * 2.;
auto gradient = QLinearGradient(
QPointF(0, gradientPointTop),
QPointF(rect.width(), rect.height() - gradientPointTop));
gradient.setColorAt(0., st::premiumButtonBg1->c);
gradient.setColorAt(.6, st::premiumButtonBg2->c);
gradient.setColorAt(1., st::premiumButtonBg3->c);
PainterHighQualityEnabler hq(p);
p.fillPath(pathTop + pathBottom, gradient);
_wrap.value(
) | rpl::start_with_next([=](Info::Wrap wrap) {
content->setRoundEdges(wrap == Info::Wrap::Layer);
}, content->lifetime());
container->setMaximumHeight(st::introQrStepsTop);
container->setMinimumHeight(st::infoLayerTopBarHeight);
content->setMaximumHeight(st::introQrStepsTop);
content->setMinimumHeight(st::infoLayerTopBarHeight);
content->resize(content->width(), content->maximumHeight());
_wrap.value(
) | rpl::start_with_next([=](Info::Wrap wrap) {
@ -319,6 +397,13 @@ QPointer<Ui::RpWidget> Premium::createPinnedToTop(
_back->entity()->addClickHandler([=] {
_showBack.fire({});
});
_back->toggledValue(
) | rpl::start_with_next([=](bool toggled) {
const auto &st = isLayer ? st::infoLayerTopBar : st::infoTopBar;
content->setTextPosition(
toggled ? st.back.width : st.titlePosition.x(),
st.titlePosition.y());
}, _back->lifetime());
if (!isLayer) {
_close = nullptr;
@ -335,9 +420,9 @@ QPointer<Ui::RpWidget> Premium::createPinnedToTop(
_close->moveToRight(0, 0);
}, _close->lifetime());
}
}, container->lifetime());
}, content->lifetime());
return Ui::MakeWeak(not_null<Ui::RpWidget*>{ container });
return Ui::MakeWeak(not_null<Ui::RpWidget*>{ content });
}
QPointer<Ui::RpWidget> Premium::createPinnedToBottom(