media_player_dropdown.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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/timer.h"
  9. #include "media/media_common.h"
  10. #include "ui/rp_widget.h"
  11. #include "ui/effects/animations.h"
  12. namespace style {
  13. struct MediaSpeedMenu;
  14. struct MediaSpeedButton;
  15. struct DropdownMenu;
  16. } // namespace style
  17. namespace Ui {
  18. class DropdownMenu;
  19. class AbstractButton;
  20. class IconButton;
  21. } // namespace Ui
  22. namespace Ui::Menu {
  23. class Menu;
  24. } // namespace Ui::Menu
  25. namespace Media::Player {
  26. class Dropdown final : public Ui::RpWidget {
  27. public:
  28. explicit Dropdown(QWidget *parent);
  29. bool overlaps(const QRect &globalRect);
  30. QMargins getMargin() const;
  31. protected:
  32. void paintEvent(QPaintEvent *e) override;
  33. void enterEventHook(QEnterEvent *e) override;
  34. void leaveEventHook(QEvent *e) override;
  35. bool eventFilter(QObject *obj, QEvent *e) override;
  36. private:
  37. void startHide();
  38. void startShow();
  39. void otherEnter();
  40. void otherLeave();
  41. void appearanceCallback();
  42. void hidingFinished();
  43. void startAnimation();
  44. bool _hiding = false;
  45. QPixmap _cache;
  46. Ui::Animations::Simple _a_appearance;
  47. base::Timer _hideTimer;
  48. base::Timer _showTimer;
  49. };
  50. class WithDropdownController {
  51. public:
  52. WithDropdownController(
  53. not_null<Ui::AbstractButton*> button,
  54. not_null<QWidget*> menuParent,
  55. const style::DropdownMenu &menuSt,
  56. Qt::Alignment menuAlign,
  57. Fn<void(bool)> menuOverCallback);
  58. virtual ~WithDropdownController() = default;
  59. [[nodiscard]] not_null<Ui::AbstractButton*> button() const;
  60. Ui::DropdownMenu *menu() const;
  61. void updateDropdownGeometry();
  62. [[nodiscard]] rpl::producer<bool> menuToggledValue() const;
  63. void hideTemporarily();
  64. void showBack();
  65. protected:
  66. void showMenu();
  67. private:
  68. virtual void fillMenu(not_null<Ui::DropdownMenu*> menu) = 0;
  69. const not_null<Ui::AbstractButton*> _button;
  70. const not_null<QWidget*> _menuParent;
  71. const style::DropdownMenu &_menuSt;
  72. const Qt::Alignment _menuAlign = Qt::AlignTop | Qt::AlignRight;
  73. const Fn<void(bool)> _menuOverCallback;
  74. base::unique_qptr<Ui::DropdownMenu> _menu;
  75. rpl::variable<bool> _menuToggled;
  76. bool _temporarilyHidden = false;
  77. bool _overButton = false;
  78. };
  79. class OrderController final : public WithDropdownController {
  80. public:
  81. OrderController(
  82. not_null<Ui::IconButton*> button,
  83. not_null<QWidget*> menuParent,
  84. Fn<void(bool)> menuOverCallback,
  85. rpl::producer<OrderMode> value,
  86. Fn<void(OrderMode)> change);
  87. private:
  88. void fillMenu(not_null<Ui::DropdownMenu*> menu) override;
  89. void updateIcon();
  90. const not_null<Ui::IconButton*> _button;
  91. rpl::variable<OrderMode> _appOrder;
  92. Fn<void(OrderMode)> _change;
  93. };
  94. class SpeedController final : public WithDropdownController {
  95. public:
  96. SpeedController(
  97. not_null<Ui::AbstractButton*> button,
  98. const style::MediaSpeedButton &st,
  99. not_null<QWidget*> menuParent,
  100. Fn<void(bool)> menuOverCallback,
  101. Fn<float64(bool lastNonDefault)> value,
  102. Fn<void(float64)> change,
  103. std::vector<int> qualities = {},
  104. Fn<VideoQuality()> quality = nullptr,
  105. Fn<void(int)> changeQuality = nullptr);
  106. [[nodiscard]] rpl::producer<> saved() const;
  107. [[nodiscard]] rpl::producer<float64> realtimeValue() const;
  108. private:
  109. void fillMenu(not_null<Ui::DropdownMenu*> menu) override;
  110. [[nodiscard]] float64 speed() const;
  111. [[nodiscard]] bool isDefault() const;
  112. [[nodiscard]] float64 lastNonDefaultSpeed() const;
  113. void toggleDefault();
  114. void setSpeed(float64 newSpeed);
  115. void setQuality(VideoQuality quality);
  116. void save();
  117. const style::MediaSpeedButton &_st;
  118. Fn<float64(bool lastNonDefault)> _lookup;
  119. Fn<void(float64)> _change;
  120. float64 _speed = kSpedUpDefault;
  121. bool _isDefault = true;
  122. rpl::event_stream<float64> _speedChanged;
  123. rpl::event_stream<> _saved;
  124. std::vector<int> _qualities;
  125. Fn<VideoQuality()> _lookupQuality;
  126. Fn<void(int)> _changeQuality;
  127. rpl::variable<VideoQuality> _quality;
  128. };
  129. } // namespace Media::Player