| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*
- 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/object_ptr.h"
- #include "ui/effects/animations.h"
- #include "ui/rect_part.h"
- #include "ui/rp_widget.h"
- namespace Window {
- class SessionController;
- enum class Column;
- } // namespace Window
- namespace Media {
- namespace View {
- class PlaybackProgress;
- } // namespace View
- } // namespace Media
- namespace Media {
- namespace Streaming {
- class Instance;
- } // namespace Streaming
- } // namespace Media
- namespace Media {
- namespace Player {
- class RoundPainter {
- public:
- RoundPainter(not_null<HistoryItem*> item);
- bool fillFrame(const QSize &size);
- const QImage &frame() const;
- private:
- const not_null<HistoryItem*> _item;
- QImage _roundingMask;
- QImage _frame;
- };
- class Float final : public Ui::RpWidget {
- public:
- Float(
- QWidget *parent,
- not_null<HistoryItem*> item,
- Fn<void(bool visible)> toggleCallback,
- Fn<void(bool closed)> draggedCallback,
- Fn<void(not_null<const HistoryItem*>)> doubleClickedCallback);
- [[nodiscard]] HistoryItem *item() const {
- return _item;
- }
- void setOpacity(float64 opacity) {
- if (_opacity != opacity) {
- _opacity = opacity;
- update();
- }
- }
- [[nodiscard]] float64 countOpacityByParent() const {
- return outRatio();
- }
- [[nodiscard]] bool isReady() const {
- return (getStreamed() != nullptr);
- }
- void detach();
- [[nodiscard]] bool detached() const {
- return !_item;
- }
- [[nodiscard]] bool dragged() const {
- return _drag;
- }
- void resetMouseState() {
- _down = false;
- if (_drag) {
- finishDrag(false);
- }
- }
- protected:
- void paintEvent(QPaintEvent *e) override;
- void mouseMoveEvent(QMouseEvent *e) override;
- void mousePressEvent(QMouseEvent *e) override;
- void mouseReleaseEvent(QMouseEvent *e) override;
- void mouseDoubleClickEvent(QMouseEvent *e) override;
- private:
- [[nodiscard]] float64 outRatio() const;
- [[nodiscard]] Streaming::Instance *getStreamed() const;
- [[nodiscard]] View::PlaybackProgress *getPlayback() const;
- void repaintItem();
- void prepareShadow();
- bool hasFrame() const;
- [[nodiscard]] QRect getInnerRect() const;
- void finishDrag(bool closed);
- void pauseResume();
- HistoryItem *_item = nullptr;
- Fn<void(bool visible)> _toggleCallback;
- std::unique_ptr<RoundPainter> _roundPainter;
- float64 _opacity = 1.;
- QPixmap _shadow;
- bool _down = false;
- QPoint _downPoint;
- bool _drag = false;
- QPoint _dragLocalPoint;
- Fn<void(bool closed)> _draggedCallback;
- Fn<void(not_null<const HistoryItem*>)> _doubleClickedCallback;
- };
- class FloatSectionDelegate {
- public:
- virtual QRect floatPlayerAvailableRect() = 0;
- virtual bool floatPlayerHandleWheelEvent(QEvent *e) = 0;
- };
- class FloatDelegate {
- public:
- virtual not_null<Ui::RpWidget*> floatPlayerWidget() = 0;
- virtual void floatPlayerToggleGifsPaused(bool paused) = 0;
- virtual not_null<FloatSectionDelegate*> floatPlayerGetSection(
- Window::Column column) = 0;
- virtual void floatPlayerEnumerateSections(Fn<void(
- not_null<FloatSectionDelegate*> widget,
- Window::Column widgetColumn)> callback) = 0;
- virtual bool floatPlayerIsVisible(not_null<HistoryItem*> item) = 0;
- virtual rpl::producer<> floatPlayerCheckVisibilityRequests() {
- return _checkVisibility.events();
- }
- virtual rpl::producer<> floatPlayerHideAllRequests() {
- return _hideAll.events();
- }
- virtual rpl::producer<> floatPlayerShowVisibleRequests() {
- return _showVisible.events();
- }
- virtual rpl::producer<> floatPlayerRaiseAllRequests() {
- return _raiseAll.events();
- }
- virtual rpl::producer<> floatPlayerUpdatePositionsRequests() {
- return _updatePositions.events();
- }
- virtual rpl::producer<> floatPlayerAreaUpdates() {
- return _areaUpdates.events();
- }
- virtual void floatPlayerDoubleClickEvent(
- not_null<const HistoryItem*> item) {
- }
- struct FloatPlayerFilterWheelEventRequest {
- not_null<QObject*> object;
- not_null<QEvent*> event;
- not_null<std::optional<bool>*> result;
- };
- virtual auto floatPlayerFilterWheelEventRequests()
- -> rpl::producer<FloatPlayerFilterWheelEventRequest> {
- return _filterWheelEvent.events();
- }
- virtual ~FloatDelegate() = default;
- protected:
- void floatPlayerCheckVisibility() {
- _checkVisibility.fire({});
- }
- void floatPlayerHideAll() {
- _hideAll.fire({});
- }
- void floatPlayerShowVisible() {
- _showVisible.fire({});
- }
- void floatPlayerRaiseAll() {
- _raiseAll.fire({});
- }
- void floatPlayerUpdatePositions() {
- _updatePositions.fire({});
- }
- void floatPlayerAreaUpdated() {
- _areaUpdates.fire({});
- }
- std::optional<bool> floatPlayerFilterWheelEvent(
- not_null<QObject*> object,
- not_null<QEvent*> event) {
- auto result = std::optional<bool>();
- _filterWheelEvent.fire({ object, event, &result });
- return result;
- }
- private:
- rpl::event_stream<> _checkVisibility;
- rpl::event_stream<> _hideAll;
- rpl::event_stream<> _showVisible;
- rpl::event_stream<> _raiseAll;
- rpl::event_stream<> _updatePositions;
- rpl::event_stream<> _areaUpdates;
- rpl::event_stream<FloatPlayerFilterWheelEventRequest> _filterWheelEvent;
- };
- class FloatController final {
- public:
- explicit FloatController(not_null<FloatDelegate*> delegate);
- void replaceDelegate(not_null<FloatDelegate*> delegate);
- [[nodiscard]] rpl::producer<FullMsgId> closeEvents() const {
- return _closeEvents.events();
- }
- private:
- struct Item {
- template <typename ToggleCallback, typename DraggedCallback>
- Item(
- not_null<QWidget*> parent,
- not_null<HistoryItem*> item,
- ToggleCallback toggle,
- DraggedCallback dragged,
- Fn<void(not_null<const HistoryItem*>)> doubleClicked);
- bool hiddenByWidget = false;
- bool hiddenByHistory = false;
- bool visible = false;
- RectPart animationSide;
- Ui::Animations::Simple visibleAnimation;
- Window::Column column;
- RectPart corner;
- QPoint dragFrom;
- Ui::Animations::Simple draggedAnimation;
- bool hiddenByDrag = false;
- object_ptr<Float> widget;
- };
- void checkCurrent();
- void create(not_null<HistoryItem*> item);
- void toggle(not_null<Item*> instance);
- void updatePosition(not_null<Item*> instance);
- void remove(not_null<Item*> instance);
- Item *current() const {
- return _items.empty() ? nullptr : _items.back().get();
- }
- void finishDrag(
- not_null<Item*> instance,
- bool closed);
- void updateColumnCorner(QPoint center);
- QPoint getPosition(not_null<Item*> instance) const;
- QPoint getHiddenPosition(
- QPoint position,
- QSize size,
- RectPart side) const;
- RectPart getSide(QPoint center) const;
- void startDelegateHandling();
- void checkVisibility();
- void hideAll();
- void showVisible();
- void raiseAll();
- void updatePositions();
- std::optional<bool> filterWheelEvent(
- not_null<QObject*> object,
- not_null<QEvent*> event);
- not_null<FloatDelegate*> _delegate;
- not_null<Ui::RpWidget*> _parent;
- std::vector<std::unique_ptr<Item>> _items;
- rpl::event_stream<FullMsgId> _closeEvents;
- rpl::lifetime _delegateLifetime;
- rpl::lifetime _lifetime;
- };
- } // namespace Player
- } // namespace Media
|