overview_layout.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  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 "layout/layout_item_base.h"
  9. #include "layout/layout_document_generic_preview.h"
  10. #include "media/clip/media_clip_reader.h"
  11. #include "core/click_handler_types.h"
  12. #include "ui/effects/animations.h"
  13. #include "ui/effects/radial_animation.h"
  14. class Image;
  15. namespace style {
  16. struct RoundCheckbox;
  17. struct OverviewFileLayout;
  18. } // namespace style
  19. namespace Data {
  20. class Media;
  21. class PhotoMedia;
  22. class DocumentMedia;
  23. } // namespace Data
  24. namespace Ui {
  25. class SpoilerAnimation;
  26. } // namespace Ui
  27. namespace Overview {
  28. namespace Layout {
  29. class Checkbox;
  30. class ItemBase;
  31. class Delegate;
  32. class PaintContext : public PaintContextBase {
  33. public:
  34. PaintContext(crl::time ms, bool selecting, bool paused)
  35. : PaintContextBase(ms, selecting)
  36. , paused(paused) {
  37. }
  38. bool skipBorder = false;
  39. bool paused = false;
  40. };
  41. class ItemBase : public LayoutItemBase, public base::has_weak_ptr {
  42. public:
  43. ItemBase(not_null<Delegate*> delegate, not_null<HistoryItem*> parent);
  44. ~ItemBase();
  45. virtual void paint(
  46. Painter &p,
  47. const QRect &clip,
  48. TextSelection selection,
  49. const PaintContext *context) = 0;
  50. [[nodiscard]] QDateTime dateTime() const;
  51. [[nodiscard]] not_null<HistoryItem*> getItem() const {
  52. return _parent;
  53. }
  54. void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
  55. void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
  56. void invalidateCache();
  57. virtual void itemDataChanged() {
  58. }
  59. virtual void clearHeavyPart() {
  60. }
  61. protected:
  62. [[nodiscard]] not_null<HistoryItem*> parent() const {
  63. return _parent;
  64. }
  65. [[nodiscard]] not_null<Delegate*> delegate() const {
  66. return _delegate;
  67. }
  68. void paintCheckbox(
  69. Painter &p,
  70. QPoint position,
  71. bool selected,
  72. const PaintContext *context);
  73. [[nodiscard]] virtual const style::RoundCheckbox &checkboxStyle() const;
  74. private:
  75. void ensureCheckboxCreated();
  76. const not_null<Delegate*> _delegate;
  77. const not_null<HistoryItem*> _parent;
  78. const QDateTime _dateTime;
  79. std::unique_ptr<Checkbox> _check;
  80. };
  81. class RadialProgressItem : public ItemBase {
  82. public:
  83. RadialProgressItem(
  84. not_null<Delegate*> delegate,
  85. not_null<HistoryItem*> parent)
  86. : ItemBase(delegate, parent) {
  87. }
  88. RadialProgressItem(const RadialProgressItem &other) = delete;
  89. void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
  90. virtual void clearSpoiler() {
  91. }
  92. ~RadialProgressItem();
  93. protected:
  94. ClickHandlerPtr _openl, _savel, _cancell;
  95. void setLinks(
  96. ClickHandlerPtr &&openl,
  97. ClickHandlerPtr &&savel,
  98. ClickHandlerPtr &&cancell);
  99. void setDocumentLinks(
  100. not_null<DocumentData*> document,
  101. bool forceOpen = false);
  102. void radialAnimationCallback(crl::time now) const;
  103. void ensureRadial();
  104. void checkRadialFinished() const;
  105. bool isRadialAnimation() const {
  106. if (_radial) {
  107. if (_radial->animating()) {
  108. return true;
  109. }
  110. checkRadialFinished();
  111. }
  112. return false;
  113. }
  114. virtual float64 dataProgress() const = 0;
  115. virtual bool dataFinished() const = 0;
  116. virtual bool dataLoaded() const = 0;
  117. virtual bool iconAnimated() const {
  118. return false;
  119. }
  120. mutable std::unique_ptr<Ui::RadialAnimation> _radial;
  121. Ui::Animations::Simple _a_iconOver;
  122. };
  123. class StatusText {
  124. public:
  125. // duration = -1 - no duration, duration = -2 - "GIF" duration
  126. void update(
  127. int64 newSize,
  128. int64 fullSize,
  129. TimeId duration,
  130. TimeId realDuration);
  131. void setSize(int64 newSize);
  132. [[nodiscard]] int64 size() const {
  133. return _size;
  134. }
  135. [[nodiscard]] QString text() const {
  136. return _text;
  137. }
  138. private:
  139. // >= 0 will contain download / upload string, _size = loaded bytes
  140. // < 0 will contain played string, _size = -(seconds + 1) played
  141. // 0xFFFFFFF0LL will contain status for not yet downloaded file
  142. // 0xFFFFFFF1LL will contain status for already downloaded file
  143. // 0xFFFFFFF2LL will contain status for failed to download / upload file
  144. int64 _size = 0;
  145. QString _text;
  146. };
  147. struct Info : public RuntimeComponent<Info, LayoutItemBase> {
  148. int top = 0;
  149. };
  150. struct MediaOptions {
  151. bool spoiler = false;
  152. bool pinned = false;
  153. bool story = false;
  154. };
  155. class Photo final : public ItemBase {
  156. public:
  157. Photo(
  158. not_null<Delegate*> delegate,
  159. not_null<HistoryItem*> parent,
  160. not_null<PhotoData*> photo,
  161. MediaOptions options);
  162. ~Photo();
  163. void initDimensions() override;
  164. int32 resizeGetHeight(int32 width) override;
  165. void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
  166. TextState getState(
  167. QPoint point,
  168. StateRequest request) const override;
  169. void itemDataChanged() override;
  170. void clearHeavyPart() override;
  171. private:
  172. void ensureDataMediaCreated() const;
  173. void setPixFrom(not_null<Image*> image);
  174. void clearSpoiler();
  175. const not_null<PhotoData*> _data;
  176. mutable std::shared_ptr<Data::PhotoMedia> _dataMedia;
  177. ClickHandlerPtr _link;
  178. std::unique_ptr<Ui::SpoilerAnimation> _spoiler;
  179. QPixmap _pix;
  180. bool _goodLoaded = false;
  181. bool _pinned = false;
  182. bool _story = false;
  183. };
  184. class Gif final : public RadialProgressItem {
  185. public:
  186. Gif(
  187. not_null<Delegate*> delegate,
  188. not_null<HistoryItem*> parent,
  189. not_null<DocumentData*> gif);
  190. ~Gif();
  191. void initDimensions() override;
  192. int32 resizeGetHeight(int32 width) override;
  193. void paint(
  194. Painter &p,
  195. const QRect &clip,
  196. TextSelection selection,
  197. const PaintContext *context) override;
  198. TextState getState(
  199. QPoint point,
  200. StateRequest request) const override;
  201. void clearHeavyPart() override;
  202. void setPosition(int32 position) override;
  203. protected:
  204. float64 dataProgress() const override;
  205. bool dataFinished() const override;
  206. bool dataLoaded() const override;
  207. bool iconAnimated() const override;
  208. private:
  209. QSize countFrameSize() const;
  210. int contentWidth() const;
  211. int contentHeight() const;
  212. void validateThumbnail(
  213. Image *image,
  214. QSize size,
  215. QSize frame,
  216. bool good);
  217. void prepareThumbnail(QSize size, QSize frame);
  218. void update();
  219. void ensureDataMediaCreated() const;
  220. void updateStatusText();
  221. void clipCallback(Media::Clip::Notification notification);
  222. Media::Clip::ReaderPointer _gif;
  223. const not_null<DocumentData*> _data;
  224. mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
  225. StatusText _status;
  226. QImage _thumb;
  227. bool _thumbGood = false;
  228. };
  229. class Video final : public RadialProgressItem {
  230. public:
  231. Video(
  232. not_null<Delegate*> delegate,
  233. not_null<HistoryItem*> parent,
  234. not_null<DocumentData*> video,
  235. MediaOptions options);
  236. ~Video();
  237. void initDimensions() override;
  238. int32 resizeGetHeight(int32 width) override;
  239. void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
  240. TextState getState(
  241. QPoint point,
  242. StateRequest request) const override;
  243. void itemDataChanged() override;
  244. void clearHeavyPart() override;
  245. void clearSpoiler() override;
  246. protected:
  247. float64 dataProgress() const override;
  248. bool dataFinished() const override;
  249. bool dataLoaded() const override;
  250. bool iconAnimated() const override;
  251. private:
  252. void ensureDataMediaCreated() const;
  253. void updateStatusText();
  254. const not_null<DocumentData*> _data;
  255. PhotoData *_videoCover = nullptr;
  256. mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
  257. mutable std::shared_ptr<Data::PhotoMedia> _videoCoverMedia;
  258. StatusText _status;
  259. QString _duration;
  260. std::unique_ptr<Ui::SpoilerAnimation> _spoiler;
  261. QPixmap _pix;
  262. bool _pixBlurred = true;
  263. bool _pinned = false;
  264. bool _story = false;
  265. };
  266. class Voice final : public RadialProgressItem {
  267. public:
  268. Voice(
  269. not_null<Delegate*> delegate,
  270. not_null<HistoryItem*> parent,
  271. not_null<DocumentData*> voice,
  272. const style::OverviewFileLayout &st);
  273. void initDimensions() override;
  274. void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
  275. TextState getState(
  276. QPoint point,
  277. StateRequest request) const override;
  278. void clearHeavyPart() override;
  279. protected:
  280. float64 dataProgress() const override;
  281. bool dataFinished() const override;
  282. bool dataLoaded() const override;
  283. bool iconAnimated() const override;
  284. const style::RoundCheckbox &checkboxStyle() const override;
  285. private:
  286. void ensureDataMediaCreated() const;
  287. const not_null<DocumentData*> _data;
  288. mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
  289. StatusText _status;
  290. ClickHandlerPtr _namel;
  291. const style::OverviewFileLayout &_st;
  292. Ui::Text::String _name;
  293. Ui::Text::String _details;
  294. Ui::Text::String _caption;
  295. int _nameVersion = 0;
  296. void updateName();
  297. bool updateStatusText();
  298. };
  299. struct DocumentFields {
  300. not_null<DocumentData*> document;
  301. TimeId dateOverride = 0;
  302. bool forceFileLayout = false;
  303. };
  304. class Document final : public RadialProgressItem {
  305. public:
  306. Document(
  307. not_null<Delegate*> delegate,
  308. not_null<HistoryItem*> parent,
  309. DocumentFields fields,
  310. const style::OverviewFileLayout &st);
  311. void initDimensions() override;
  312. void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
  313. TextState getState(
  314. QPoint point,
  315. StateRequest request) const override;
  316. void clearHeavyPart() override;
  317. protected:
  318. float64 dataProgress() const override;
  319. bool dataFinished() const override;
  320. bool dataLoaded() const override;
  321. bool iconAnimated() const override;
  322. const style::RoundCheckbox &checkboxStyle() const override;
  323. private:
  324. [[nodiscard]] bool downloadInCorner() const;
  325. void drawCornerDownload(QPainter &p, bool selected, const PaintContext *context) const;
  326. [[nodiscard]] TextState cornerDownloadTextState(
  327. QPoint point,
  328. StateRequest request) const;
  329. [[nodiscard]] bool songLayout() const;
  330. void ensureDataMediaCreated() const;
  331. not_null<DocumentData*> _data;
  332. mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
  333. StatusText _status;
  334. ClickHandlerPtr _msgl, _namel;
  335. const style::OverviewFileLayout &_st;
  336. const ::Layout::DocumentGenericPreview _generic;
  337. bool _thumbLoaded = false;
  338. bool _forceFileLayout = false;
  339. QPixmap _thumb;
  340. Ui::Text::String _name;
  341. QString _date, _ext;
  342. int _datew = 0;
  343. int _extw = 0;
  344. int _thumbw = 0;
  345. bool withThumb() const;
  346. bool updateStatusText();
  347. };
  348. class Link final : public ItemBase {
  349. public:
  350. Link(
  351. not_null<Delegate*> delegate,
  352. not_null<HistoryItem*> parent,
  353. Data::Media *media);
  354. void initDimensions() override;
  355. int32 resizeGetHeight(int32 width) override;
  356. void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override;
  357. TextState getState(
  358. QPoint point,
  359. StateRequest request) const override;
  360. void clearHeavyPart() override;
  361. protected:
  362. const style::RoundCheckbox &checkboxStyle() const override;
  363. private:
  364. void ensurePhotoMediaCreated();
  365. void ensureDocumentMediaCreated();
  366. void validateThumbnail();
  367. ClickHandlerPtr _photol;
  368. QString _title, _letter;
  369. int _titlew = 0;
  370. WebPageData *_page = nullptr;
  371. std::shared_ptr<Data::PhotoMedia> _photoMedia;
  372. std::shared_ptr<Data::DocumentMedia> _documentMedia;
  373. int _pixw = 0;
  374. int _pixh = 0;
  375. Ui::Text::String _text;
  376. QPixmap _thumbnail;
  377. bool _thumbnailBlurred = true;
  378. struct LinkEntry {
  379. LinkEntry() = default;
  380. LinkEntry(const QString &url, const QString &text);
  381. QString text;
  382. int width = 0;
  383. std::shared_ptr<TextClickHandler> lnk;
  384. };
  385. QVector<LinkEntry> _links;
  386. };
  387. } // namespace Layout
  388. } // namespace Overview