message_bar.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 "ui/effects/animations.h"
  9. #include "ui/rect_part.h"
  10. #include "ui/rp_widget.h"
  11. class Painter;
  12. namespace style {
  13. struct MessageBar;
  14. } // namespace style
  15. namespace Ui {
  16. class SpoilerAnimation;
  17. struct MessageBarContent {
  18. int index = 0;
  19. int count = 1;
  20. QString title;
  21. TextWithEntities text;
  22. Text::MarkedContext context;
  23. QImage preview;
  24. Fn<void()> spoilerRepaint;
  25. style::margins margins;
  26. };
  27. class MessageBar final {
  28. public:
  29. MessageBar(
  30. not_null<QWidget*> parent,
  31. const style::MessageBar &st,
  32. Fn<bool()> customEmojiPaused);
  33. void set(MessageBarContent &&content);
  34. void set(rpl::producer<MessageBarContent> content);
  35. [[nodiscard]] not_null<RpWidget*> widget() {
  36. return &_widget;
  37. }
  38. void customEmojiRepaint();
  39. void finishAnimating();
  40. private:
  41. enum class BodyAnimation : char {
  42. Full,
  43. Text,
  44. None,
  45. };
  46. struct Animation {
  47. Animations::Simple bodyMoved;
  48. Animations::Simple imageShown;
  49. Animations::Simple barScroll;
  50. Animations::Simple barTop;
  51. QPixmap bodyOrTextFrom;
  52. QPixmap bodyOrTextTo;
  53. QPixmap titleSame;
  54. QPixmap titleFrom;
  55. QPixmap titleTo;
  56. QPixmap imageFrom;
  57. QPixmap imageTo;
  58. std::unique_ptr<SpoilerAnimation> spoilerFrom;
  59. BodyAnimation bodyAnimation = BodyAnimation::None;
  60. RectPart movingTo = RectPart::None;
  61. };
  62. struct BarState {
  63. float64 scroll = 0.;
  64. float64 size = 0.;
  65. float64 skip = 0.;
  66. float64 offset = 0.;
  67. };
  68. void setup();
  69. void paint(Painter &p);
  70. void paintLeftBar(Painter &p);
  71. void tweenTo(MessageBarContent &&content);
  72. void updateFromContent(MessageBarContent &&content);
  73. [[nodiscard]] QPixmap prepareImage(const QImage &preview);
  74. [[nodiscard]] QRect imageRect() const;
  75. [[nodiscard]] QRect titleRangeRect(int from, int till) const;
  76. [[nodiscard]] QRect bodyRect(bool withImage) const;
  77. [[nodiscard]] QRect bodyRect() const;
  78. [[nodiscard]] QRect textRect() const;
  79. auto makeGrabGuard();
  80. [[nodiscard]] QPixmap grabBodyOrTextPart(BodyAnimation type);
  81. [[nodiscard]] QPixmap grabTitleBase(int till);
  82. [[nodiscard]] QPixmap grabTitlePart(int from);
  83. [[nodiscard]] QPixmap grabTitleRange(int from, int till);
  84. [[nodiscard]] QPixmap grabImagePart();
  85. [[nodiscard]] QPixmap grabBodyPart();
  86. [[nodiscard]] QPixmap grabTextPart();
  87. [[nodiscard]] BarState countBarState(int index) const;
  88. [[nodiscard]] BarState countBarState() const;
  89. void ensureGradientsCreated(int size);
  90. void paintImageWithSpoiler(
  91. QPainter &p,
  92. QRect rect,
  93. const QPixmap &image,
  94. SpoilerAnimation *spoiler,
  95. crl::time now,
  96. bool paused) const;
  97. [[nodiscard]] static BodyAnimation DetectBodyAnimationType(
  98. Animation *currentAnimation,
  99. const MessageBarContent &currentContent,
  100. const MessageBarContent &nextContent);
  101. const style::MessageBar &_st;
  102. RpWidget _widget;
  103. Fn<bool()> _customEmojiPaused;
  104. MessageBarContent _content;
  105. rpl::lifetime _contentLifetime;
  106. Text::String _title, _text;
  107. QPixmap _image, _topBarGradient, _bottomBarGradient;
  108. std::unique_ptr<Animation> _animation;
  109. std::unique_ptr<SpoilerAnimation> _spoiler;
  110. bool _customEmojiRepaintScheduled = false;
  111. };
  112. } // namespace Ui