peer_short_info_box.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "data/data_birthday.h"
  9. #include "ui/layers/box_content.h"
  10. namespace style {
  11. struct ShortInfoCover;
  12. struct ShortInfoBox;
  13. } // namespace style
  14. namespace Ui::Menu {
  15. struct MenuCallback;
  16. } // namespace Ui::Menu
  17. namespace Media::Streaming {
  18. class Document;
  19. class Instance;
  20. struct Update;
  21. enum class Error;
  22. struct Information;
  23. } // namespace Media::Streaming
  24. namespace Ui {
  25. class VerticalLayout;
  26. class RpWidget;
  27. } // namespace Ui
  28. enum class PeerShortInfoType {
  29. Self,
  30. User,
  31. Group,
  32. Channel,
  33. };
  34. struct PeerShortInfoFields {
  35. QString name;
  36. QString channelName;
  37. QString channelLink;
  38. QString phone;
  39. QString link;
  40. TextWithEntities about;
  41. QString username;
  42. Data::Birthday birthday;
  43. bool isBio = false;
  44. };
  45. struct PeerShortInfoUserpic {
  46. int index = 0;
  47. int count = 0;
  48. QImage photo;
  49. float64 photoLoadingProgress = 0.;
  50. std::shared_ptr<Media::Streaming::Document> videoDocument;
  51. crl::time videoStartPosition = 0;
  52. QString additionalStatus;
  53. };
  54. class PeerShortInfoCover final {
  55. public:
  56. PeerShortInfoCover(
  57. not_null<QWidget*> parent,
  58. const style::ShortInfoCover &st,
  59. rpl::producer<QString> name,
  60. rpl::producer<QString> status,
  61. rpl::producer<PeerShortInfoUserpic> userpic,
  62. Fn<bool()> videoPaused);
  63. ~PeerShortInfoCover();
  64. [[nodiscard]] not_null<Ui::RpWidget*> widget() const;
  65. [[nodiscard]] object_ptr<Ui::RpWidget> takeOwned();
  66. [[nodiscard]] gsl::span<const QImage, 4> roundMask() const;
  67. void setScrollTop(int scrollTop);
  68. [[nodiscard]] rpl::producer<int> moveRequests() const;
  69. [[nodiscard]] rpl::lifetime &lifetime();
  70. private:
  71. struct CustomLabelStyle;
  72. struct Radial;
  73. void paint(QPainter &p);
  74. void paintCoverImage(QPainter &p, const QImage &image);
  75. void paintBars(QPainter &p);
  76. void paintShadow(QPainter &p);
  77. void paintRadial(QPainter &p);
  78. [[nodiscard]] QImage currentVideoFrame() const;
  79. void applyUserpic(PeerShortInfoUserpic &&value);
  80. void applyAdditionalStatus(const QString &status);
  81. [[nodiscard]] QRect radialRect() const;
  82. void videoWaiting();
  83. void checkStreamedIsStarted();
  84. void handleStreamingUpdate(Media::Streaming::Update &&update);
  85. void handleStreamingError(Media::Streaming::Error &&error);
  86. void streamingReady(Media::Streaming::Information &&info);
  87. void clearVideo();
  88. void updateRadialState();
  89. void refreshCoverCursor();
  90. void refreshBarImages();
  91. void refreshLabelsGeometry();
  92. const style::ShortInfoCover &_st;
  93. object_ptr<Ui::RpWidget> _owned;
  94. const not_null<Ui::RpWidget*> _widget;
  95. std::unique_ptr<CustomLabelStyle> _nameStyle;
  96. object_ptr<Ui::FlatLabel> _name;
  97. std::unique_ptr<CustomLabelStyle> _statusStyle;
  98. object_ptr<Ui::FlatLabel> _status;
  99. object_ptr<Ui::FlatLabel> _additionalStatus = { nullptr };
  100. std::array<QImage, 4> _roundMask;
  101. std::array<QImage, 4> _roundMaskRetina;
  102. QImage _userpicImage;
  103. QImage _roundedTopImage;
  104. QImage _barSmall;
  105. QImage _barLarge;
  106. QImage _shadowTop;
  107. int _scrollTop = 0;
  108. int _smallWidth = 0;
  109. int _largeWidth = 0;
  110. int _index = 0;
  111. int _count = 0;
  112. style::cursor _cursor = style::cur_default;
  113. std::unique_ptr<Media::Streaming::Instance> _videoInstance;
  114. crl::time _videoStartPosition = 0;
  115. crl::time _videoPosition = 0;
  116. crl::time _videoDuration = 0;
  117. Fn<bool()> _videoPaused;
  118. QImage _shadowBottom;
  119. std::unique_ptr<Radial> _radial;
  120. float64 _photoLoadingProgress = 0.;
  121. rpl::event_stream<int> _moveRequests;
  122. };
  123. class PeerShortInfoBox final : public Ui::BoxContent {
  124. public:
  125. PeerShortInfoBox(
  126. QWidget*,
  127. PeerShortInfoType type,
  128. rpl::producer<PeerShortInfoFields> fields,
  129. rpl::producer<QString> status,
  130. rpl::producer<PeerShortInfoUserpic> userpic,
  131. Fn<bool()> videoPaused,
  132. const style::ShortInfoBox *stOverride);
  133. ~PeerShortInfoBox();
  134. [[nodiscard]] rpl::producer<> openRequests() const;
  135. [[nodiscard]] rpl::producer<int> moveRequests() const;
  136. [[nodiscard]] auto fillMenuRequests() const
  137. -> rpl::producer<Ui::Menu::MenuCallback>;
  138. protected:
  139. void contextMenuEvent(QContextMenuEvent *e) override;
  140. private:
  141. void prepare() override;
  142. void prepareRows();
  143. void resizeEvent(QResizeEvent *e) override;
  144. void refreshRoundedTopImage(const QColor &color);
  145. int fillRoundedTopHeight();
  146. [[nodiscard]] rpl::producer<QString> nameValue() const;
  147. [[nodiscard]] rpl::producer<TextWithEntities> channelValue() const;
  148. [[nodiscard]] rpl::producer<TextWithEntities> linkValue() const;
  149. [[nodiscard]] rpl::producer<QString> phoneValue() const;
  150. [[nodiscard]] rpl::producer<QString> usernameValue() const;
  151. [[nodiscard]] rpl::producer<QString> birthdayLabel() const;
  152. [[nodiscard]] rpl::producer<QString> birthdayValue() const;
  153. [[nodiscard]] rpl::producer<TextWithEntities> aboutValue() const;
  154. const style::ShortInfoBox &_st;
  155. const PeerShortInfoType _type = PeerShortInfoType::User;
  156. rpl::variable<PeerShortInfoFields> _fields;
  157. QColor _roundedTopColor;
  158. QImage _roundedTop;
  159. object_ptr<Ui::RpWidget> _topRoundBackground;
  160. object_ptr<Ui::ScrollArea> _scroll;
  161. not_null<Ui::VerticalLayout*> _rows;
  162. PeerShortInfoCover _cover;
  163. base::unique_qptr<Ui::RpWidget> _menuHolder;
  164. rpl::event_stream<Ui::Menu::MenuCallback> _fillMenuRequests;
  165. rpl::event_stream<> _openRequests;
  166. };