Added initial animation to custom top bar in premium settings.
This commit is contained in:
		
							parent
							
								
									a284fa3273
								
							
						
					
					
						commit
						2a4faf22f6
					
				
					 4 changed files with 155 additions and 58 deletions
				
			
		
							
								
								
									
										9
									
								
								Telegram/Resources/icons/settings/star.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Telegram/Resources/icons/settings/star.svg
									
										
									
									
									
										Normal 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  | 
| 
						 | 
				
			
			@ -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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue