init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
287
Telegram/SourceFiles/media/player/media_player_float.h
Normal file
287
Telegram/SourceFiles/media/player/media_player_float.h
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
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
|
||||
Reference in New Issue
Block a user