1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "base/object_ptr.h" 11 #include "mtproto/sender.h" 12 #include "ui/rp_widget.h" 13 #include "ui/effects/animations.h" 14 15 namespace Main { 16 class Account; 17 } // namespace Main; 18 19 namespace Ui { 20 class SlideAnimation; 21 class CrossFadeAnimation; 22 class FlatLabel; 23 template <typename Widget> 24 class FadeWrap; 25 } // namespace Ui 26 27 namespace Intro { 28 namespace details { 29 30 struct Data; 31 enum class StackAction; 32 enum class Animate; 33 34 class Step : public Ui::RpWidget { 35 public: 36 Step( 37 QWidget *parent, 38 not_null<Main::Account*> account, 39 not_null<Data*> data, 40 bool hasCover = false); 41 ~Step(); 42 account()43 [[nodiscard]] Main::Account &account() const { 44 return *_account; 45 } 46 47 // It should not be called in StartWidget, in other steps it should be 48 // present and not changing. 49 [[nodiscard]] MTP::Sender &api() const; 50 void apiClear(); 51 finishInit()52 virtual void finishInit() { 53 } setInnerFocus()54 virtual void setInnerFocus() { 55 setFocus(); 56 } 57 58 void setGoCallback( 59 Fn<void(Step *step, StackAction action, Animate animate)> callback); 60 void setShowResetCallback(Fn<void()> callback); 61 void setShowTermsCallback(Fn<void()> callback); 62 void setCancelNearestDcCallback(Fn<void()> callback); 63 void setAcceptTermsCallback( 64 Fn<void(Fn<void()> callback)> callback); 65 66 void prepareShowAnimated(Step *after); 67 void showAnimated(Animate animate); 68 void showFast(); 69 [[nodiscard]] bool animating() const; 70 void setShowAnimationClipping(QRect clipping); 71 72 [[nodiscard]] bool hasCover() const; 73 [[nodiscard]] virtual bool hasBack() const; 74 virtual void activate(); 75 virtual void cancelled(); 76 virtual void finished(); 77 78 virtual void submit() = 0; 79 [[nodiscard]] virtual rpl::producer<QString> nextButtonText() const; 80 81 [[nodiscard]] int contentLeft() const; 82 [[nodiscard]] int contentTop() const; 83 84 void setErrorCentered(bool centered); 85 void showError(rpl::producer<QString> text); hideError()86 void hideError() { 87 showError(rpl::single(QString())); 88 } 89 90 protected: 91 void paintEvent(QPaintEvent *e) override; 92 void resizeEvent(QResizeEvent *e) override; 93 94 void setTitleText(rpl::producer<QString> titleText); 95 void setDescriptionText(rpl::producer<QString> descriptionText); 96 void setDescriptionText( 97 rpl::producer<TextWithEntities> richDescriptionText); 98 bool paintAnimated(Painter &p, QRect clip); 99 100 void fillSentCodeData(const MTPDauth_sentCode &type); 101 102 void showDescription(); 103 void hideDescription(); 104 getData()105 [[nodiscard]] not_null<Data*> getData() const { 106 return _data; 107 } 108 void finish(const MTPUser &user, QImage &&photo = QImage()); 109 void createSession( 110 const MTPUser &user, 111 QImage photo, 112 const QVector<MTPDialogFilter> &filters); 113 114 void goBack(); 115 116 template <typename StepType> goNext()117 void goNext() { 118 goNext(new StepType(parentWidget(), _account, _data)); 119 } 120 121 template <typename StepType> goReplace(Animate animate)122 void goReplace(Animate animate) { 123 goReplace(new StepType(parentWidget(), _account, _data), animate); 124 } 125 showResetButton()126 void showResetButton() { 127 if (_showResetCallback) _showResetCallback(); 128 } showTerms()129 void showTerms() { 130 if (_showTermsCallback) _showTermsCallback(); 131 } acceptTerms(Fn<void ()> callback)132 void acceptTerms(Fn<void()> callback) { 133 if (_acceptTermsCallback) { 134 _acceptTermsCallback(callback); 135 } 136 } cancelNearestDcRequest()137 void cancelNearestDcRequest() { 138 if (_cancelNearestDcCallback) _cancelNearestDcCallback(); 139 } 140 141 virtual int errorTop() const; 142 143 private: 144 struct CoverAnimation { 145 CoverAnimation() = default; 146 CoverAnimation(CoverAnimation &&other) = default; 147 CoverAnimation &operator=(CoverAnimation &&other) = default; 148 ~CoverAnimation(); 149 150 std::unique_ptr<Ui::CrossFadeAnimation> title; 151 std::unique_ptr<Ui::CrossFadeAnimation> description; 152 153 // From content top till the next button top. 154 QPixmap contentSnapshotWas; 155 QPixmap contentSnapshotNow; 156 157 QRect clipping; 158 }; 159 void updateLabelsPosition(); 160 void paintContentSnapshot( 161 Painter &p, 162 const QPixmap &snapshot, 163 float64 alpha, 164 float64 howMuchHidden); 165 void refreshError(const QString &text); 166 167 void goNext(Step *step); 168 void goReplace(Step *step, Animate animate); 169 170 [[nodiscard]] CoverAnimation prepareCoverAnimation(Step *step); 171 [[nodiscard]] QPixmap prepareContentSnapshot(); 172 [[nodiscard]] QPixmap prepareSlideAnimation(); 173 void showFinished(); 174 175 void prepareCoverMask(); 176 void paintCover(Painter &p, int top); 177 178 const not_null<Main::Account*> _account; 179 const not_null<Data*> _data; 180 mutable std::optional<MTP::Sender> _api; 181 182 bool _hasCover = false; 183 Fn<void(Step *step, StackAction action, Animate animate)> _goCallback; 184 Fn<void()> _showResetCallback; 185 Fn<void()> _showTermsCallback; 186 Fn<void()> _cancelNearestDcCallback; 187 Fn<void(Fn<void()> callback)> _acceptTermsCallback; 188 189 rpl::variable<QString> _titleText; 190 object_ptr<Ui::FlatLabel> _title; 191 rpl::variable<TextWithEntities> _descriptionText; 192 object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _description; 193 194 bool _errorCentered = false; 195 rpl::variable<QString> _errorText; 196 object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _error = { nullptr }; 197 198 Ui::Animations::Simple _a_show; 199 CoverAnimation _coverAnimation; 200 std::unique_ptr<Ui::SlideAnimation> _slideAnimation; 201 QPixmap _coverMask; 202 203 }; 204 205 206 } // namespace details 207 } // namespace Intro 208