call_mute_button.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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 "base/unique_qptr.h"
  9. #include "ui/effects/animations.h"
  10. #include "ui/effects/cross_line.h"
  11. #include "ui/effects/gradient.h"
  12. #include "ui/effects/radial_animation.h"
  13. #include "ui/widgets/call_button.h"
  14. #include "ui/widgets/tooltip.h"
  15. #include "lottie/lottie_icon.h"
  16. namespace style {
  17. struct CallMuteButton;
  18. } // namespace style
  19. namespace st {
  20. extern const style::InfiniteRadialAnimation &callConnectingRadial;
  21. } // namespace st
  22. namespace Ui {
  23. class BlobsWidget;
  24. class AbstractButton;
  25. class FlatLabel;
  26. class RpWidget;
  27. class AnimatedLabel;
  28. enum class CallMuteButtonType {
  29. Connecting,
  30. Active,
  31. Muted,
  32. ForceMuted,
  33. RaisedHand,
  34. ScheduledCanStart,
  35. ScheduledSilent,
  36. ScheduledNotify,
  37. };
  38. enum class CallMuteButtonExpandType {
  39. None,
  40. Normal,
  41. Expanded,
  42. };
  43. struct CallMuteButtonState {
  44. QString text;
  45. QString subtext;
  46. QString tooltip;
  47. CallMuteButtonType type = CallMuteButtonType::Connecting;
  48. CallMuteButtonExpandType expandType = CallMuteButtonExpandType::None;
  49. };
  50. class CallMuteButton final : private AbstractTooltipShower {
  51. public:
  52. explicit CallMuteButton(
  53. not_null<RpWidget*> parent,
  54. const style::CallMuteButton &st,
  55. rpl::producer<bool> &&hideBlobs,
  56. CallMuteButtonState initial = CallMuteButtonState());
  57. ~CallMuteButton();
  58. void setState(const CallMuteButtonState &state);
  59. void setStyle(const style::CallMuteButton &st);
  60. void setLevel(float level);
  61. [[nodiscard]] rpl::producer<Qt::MouseButton> clicks();
  62. [[nodiscard]] QSize innerSize() const;
  63. void moveInner(QPoint position);
  64. void shake();
  65. void setVisible(bool visible);
  66. void show() {
  67. setVisible(true);
  68. }
  69. void hide() {
  70. setVisible(false);
  71. }
  72. [[nodiscard]] bool isHidden() const;
  73. void raise();
  74. void lower();
  75. [[nodiscard]] not_null<RpWidget*> outer() const;
  76. [[nodiscard]] rpl::producer<CallButtonColors> colorOverrides() const;
  77. [[nodiscard]] rpl::lifetime &lifetime();
  78. private:
  79. enum class HandleMouseState {
  80. Enabled,
  81. Blocked,
  82. Disabled,
  83. };
  84. struct RadialInfo {
  85. std::optional<RadialState> state = std::nullopt;
  86. bool isDirectionToShow = false;
  87. rpl::variable<float64> rawShowProgress = 0.;
  88. float64 realShowProgress = 0.;
  89. const style::InfiniteRadialAnimation &st = st::callConnectingRadial;
  90. };
  91. struct IconState {
  92. int index = -1;
  93. int frameFrom = 0;
  94. int frameTo = 0;
  95. inline bool operator==(const IconState &other) const {
  96. return (index == other.index)
  97. && (frameFrom == other.frameFrom)
  98. && (frameTo == other.frameTo);
  99. }
  100. inline bool operator!=(const IconState &other) const {
  101. return !(*this == other);
  102. }
  103. bool valid() const {
  104. return (index >= 0);
  105. }
  106. explicit operator bool() const {
  107. return valid();
  108. }
  109. };
  110. void init();
  111. void refreshIcons();
  112. void refreshGradients();
  113. void refreshLabels();
  114. void overridesColors(
  115. CallMuteButtonType fromType,
  116. CallMuteButtonType toType,
  117. float64 progress);
  118. void setHandleMouseState(HandleMouseState state);
  119. void updateCenterLabelGeometry(QRect my, QSize size);
  120. void updateLabelGeometry(QRect my, QSize size);
  121. void updateSublabelGeometry(QRect my, QSize size);
  122. void updateLabelsGeometry();
  123. [[nodiscard]] IconState iconStateFrom(CallMuteButtonType previous);
  124. [[nodiscard]] IconState randomWavingState();
  125. [[nodiscard]] IconState iconStateAnimated(CallMuteButtonType previous);
  126. void scheduleIconState(const IconState &state);
  127. void startIconState(const IconState &state);
  128. void iconAnimationCallback();
  129. QString tooltipText() const override;
  130. QPoint tooltipPos() const override;
  131. bool tooltipWindowActive() const override;
  132. const style::Tooltip *tooltipSt() const override;
  133. [[nodiscard]] static HandleMouseState HandleMouseStateFromType(
  134. CallMuteButtonType type);
  135. rpl::variable<CallMuteButtonState> _state;
  136. float _level = 0.;
  137. QRect _muteIconRect;
  138. HandleMouseState _handleMouseState = HandleMouseState::Enabled;
  139. not_null<const style::CallMuteButton*> _st;
  140. QSize _lottieSize;
  141. int _bgSize = 0;
  142. int _bgSkip = 0;
  143. const base::unique_qptr<BlobsWidget> _blobs;
  144. const base::unique_qptr<AbstractButton> _content;
  145. base::unique_qptr<AnimatedLabel> _centerLabel;
  146. base::unique_qptr<AnimatedLabel> _label;
  147. base::unique_qptr<AnimatedLabel> _sublabel;
  148. int _labelShakeShift = 0;
  149. RadialInfo _radialInfo;
  150. std::unique_ptr<InfiniteRadialAnimation> _radial;
  151. const base::flat_map<CallMuteButtonType, anim::gradient_colors> _colors;
  152. anim::linear_gradients<CallMuteButtonType> _linearGradients;
  153. anim::radial_gradients<CallMuteButtonType> _glowGradients;
  154. std::array<std::optional<Lottie::Icon>, 2> _icons;
  155. IconState _iconState;
  156. std::optional<IconState> _scheduledState;
  157. Animations::Simple _switchAnimation;
  158. Animations::Simple _shakeAnimation;
  159. rpl::variable<CallButtonColors> _colorOverrides;
  160. };
  161. } // namespace Ui