/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "base/timer.h" #include "media/media_common.h" #include "ui/rp_widget.h" #include "ui/effects/animations.h" namespace style { struct MediaSpeedMenu; struct MediaSpeedButton; struct DropdownMenu; } // namespace style namespace Ui { class DropdownMenu; class AbstractButton; class IconButton; } // namespace Ui namespace Ui::Menu { class Menu; } // namespace Ui::Menu namespace Media::Player { class SpeedButton; class Dropdown final : public Ui::RpWidget { public: explicit Dropdown(QWidget *parent); bool overlaps(const QRect &globalRect); QMargins getMargin() const; protected: void paintEvent(QPaintEvent *e) override; void enterEventHook(QEnterEvent *e) override; void leaveEventHook(QEvent *e) override; bool eventFilter(QObject *obj, QEvent *e) override; private: void startHide(); void startShow(); void otherEnter(); void otherLeave(); void appearanceCallback(); void hidingFinished(); void startAnimation(); bool _hiding = false; QPixmap _cache; Ui::Animations::Simple _a_appearance; base::Timer _hideTimer; base::Timer _showTimer; }; class WithDropdownController { public: WithDropdownController( not_null button, not_null menuParent, const style::DropdownMenu &menuSt, Qt::Alignment menuAlign, Fn menuOverCallback); virtual ~WithDropdownController() = default; [[nodiscard]] not_null button() const; Ui::DropdownMenu *menu() const; void updateDropdownGeometry(); void hideTemporarily(); void showBack(); protected: void showMenu(); private: virtual void fillMenu(not_null menu) = 0; const not_null _button; const not_null _menuParent; const style::DropdownMenu &_menuSt; const Qt::Alignment _menuAlign = Qt::AlignTop | Qt::AlignRight; const Fn _menuOverCallback; base::unique_qptr _menu; bool _temporarilyHidden = false; bool _overButton = false; }; class OrderController final : public WithDropdownController { public: OrderController( not_null button, not_null menuParent, Fn menuOverCallback, rpl::producer value, Fn change); private: void fillMenu(not_null menu) override; void updateIcon(); const not_null _button; rpl::variable _appOrder; Fn _change; }; class SpeedController final : public WithDropdownController { public: SpeedController( not_null button, not_null menuParent, Fn menuOverCallback, Fn value, Fn change); [[nodiscard]] rpl::producer<> saved() const; private: void fillMenu(not_null menu) override; [[nodiscard]] float64 speed() const; [[nodiscard]] bool isDefault() const; [[nodiscard]] float64 lastNonDefaultSpeed() const; void toggleDefault(); void setSpeed(float64 newSpeed); void save(); const style::MediaSpeedButton &_st; Fn _lookup; Fn _change; float64 _speed = kSpedUpDefault; bool _isDefault = true; rpl::event_stream _speedChanged; rpl::event_stream<> _saved; }; } // namespace Media::Player