Show round videos in Info layer.

This commit is contained in:
John Preston 2018-11-05 17:18:54 +04:00
parent 466444e17d
commit ef64d9c188
8 changed files with 267 additions and 40 deletions

View file

@ -29,6 +29,7 @@ LayerWidget::LayerWidget(
: _controller(controller)
, _content(this, controller, Wrap::Layer, memento) {
setupHeightConsumers();
_controller->replaceFloatPlayerDelegate(floatPlayerDelegate());
}
LayerWidget::LayerWidget(
@ -37,6 +38,35 @@ LayerWidget::LayerWidget(
: _controller(controller)
, _content(memento->takeContent(this, Wrap::Layer)) {
setupHeightConsumers();
_controller->replaceFloatPlayerDelegate(floatPlayerDelegate());
}
auto LayerWidget::floatPlayerDelegate()
-> not_null<::Media::Player::FloatDelegate*> {
return static_cast<::Media::Player::FloatDelegate*>(this);
}
not_null<Ui::RpWidget*> LayerWidget::floatPlayerWidget() {
return this;
}
not_null<Window::Controller*> LayerWidget::floatPlayerController() {
return _controller;
}
not_null<Window::AbstractSectionWidget*> LayerWidget::floatPlayerGetSection(
Window::Column column) {
return _content;
}
void LayerWidget::floatPlayerEnumerateSections(Fn<void(
not_null<Window::AbstractSectionWidget*> widget,
Window::Column widgetColumn)> callback) {
callback(_content, Window::Column::Second);
}
bool LayerWidget::floatPlayerIsVisible(not_null<HistoryItem*> item) {
return false;
}
void LayerWidget::setupHeightConsumers() {
@ -56,6 +86,7 @@ void LayerWidget::setupHeightConsumers() {
}
void LayerWidget::showFinished() {
floatPlayerShowVisible();
}
void LayerWidget::parentResized() {
@ -189,6 +220,7 @@ int LayerWidget::resizeGetHeight(int newWidth) {
move(newGeometry.topLeft());
}
floatPlayerUpdatePositions();
return desiredHeight;
}
@ -221,4 +253,8 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
}
}
LayerWidget::~LayerWidget() {
_controller->restoreFloatPlayerDelegate(floatPlayerDelegate());
}
} // namespace Info

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "window/layer_widget.h"
#include "media/player/media_player_float.h"
namespace Window {
class Controller;
@ -20,7 +21,9 @@ class MoveMemento;
class WrapWidget;
class TopBar;
class LayerWidget : public Window::LayerWidget {
class LayerWidget
: public Window::LayerWidget
, private ::Media::Player::FloatDelegate {
public:
LayerWidget(
not_null<Window::Controller*> controller,
@ -41,6 +44,8 @@ public:
static int MinimalSupportedWidth();
~LayerWidget();
protected:
int resizeGetHeight(int newWidth) override;
void doSetInnerFocus() override;
@ -48,6 +53,16 @@ protected:
void paintEvent(QPaintEvent *e) override;
private:
not_null<::Media::Player::FloatDelegate*> floatPlayerDelegate();
not_null<Ui::RpWidget*> floatPlayerWidget() override;
not_null<Window::Controller*> floatPlayerController() override;
not_null<Window::AbstractSectionWidget*> floatPlayerGetSection(
Window::Column column) override;
void floatPlayerEnumerateSections(Fn<void(
not_null<Window::AbstractSectionWidget*> widget,
Window::Column widgetColumn)> callback) override;
bool floatPlayerIsVisible(not_null<HistoryItem*> item) override;
void setupHeightConsumers();
not_null<Window::Controller*> _controller;

View file

@ -228,11 +228,16 @@ MainWidget::MainWidget(
this,
_controller,
Media::Player::Panel::Layout::OnlyPlaylist)
, _playerPanel(this, _controller, Media::Player::Panel::Layout::Full)
, _playerFloats(floatPlayerDelegate()) {
, _playerPanel(this, _controller, Media::Player::Panel::Layout::Full) {
Messenger::Instance().mtp()->setUpdatesHandler(rpcDone(&MainWidget::updateReceived));
Messenger::Instance().mtp()->setGlobalFailHandler(rpcFail(&MainWidget::updateFail));
_controller->setDefaultFloatPlayerDelegate(floatPlayerDelegate());
_controller->floatPlayerClosed(
) | rpl::start_with_next([=](FullMsgId itemId) {
floatPlayerClosed(itemId);
}, lifetime());
_ptsWaiter.setRequesting(true);
updateScrollColors();
setupConnectingWidget();
@ -435,7 +440,13 @@ void MainWidget::floatPlayerEnumerateSections(Fn<void(
}
}
void MainWidget::floatPlayerCloseHook(FullMsgId itemId) {
bool MainWidget::floatPlayerIsVisible(not_null<HistoryItem*> item) {
auto isVisible = false;
Auth().data().queryItemVisibility().notify({ item, &isVisible }, true);
return isVisible;
}
void MainWidget::floatPlayerClosed(FullMsgId itemId) {
if (_player) {
const auto voiceData = Media::Player::instance()->current(
AudioMsgId::Type::Voice);
@ -649,7 +660,7 @@ void MainWidget::noHider(HistoryHider *destroyed) {
} else {
_history->showAnimated(Window::SlideDirection::FromRight, animationParams);
}
_playerFloats.checkVisibility();
floatPlayerCheckVisibility();
}
} else {
if (_forwardConfirm) {
@ -688,7 +699,7 @@ void MainWidget::hiderLayer(object_ptr<HistoryHider> h) {
updateControlsGeometry();
_dialogs->activate();
}
_playerFloats.checkVisibility();
floatPlayerCheckVisibility();
}
void MainWidget::showForwardLayer(MessageIdsList &&items) {
@ -1820,7 +1831,7 @@ void MainWidget::ui_showPeerHistory(
_dialogs->update();
}
_playerFloats.checkVisibility();
floatPlayerCheckVisibility();
}
PeerData *MainWidget::ui_getPeerForMouseAction() {
@ -1905,10 +1916,10 @@ Window::SectionSlideParams MainWidget::prepareThirdSectionAnimation(Window::Sect
if (!_thirdSection->hasTopBarShadow()) {
result.withTopBarShadow = false;
}
_playerFloats.hideAll();
floatPlayerHideAll();
auto sectionTop = getThirdSectionTop();
result.oldContentCache = _thirdSection->grabForShowAnimation(result);
_playerFloats.showVisible();
floatPlayerShowVisible();
return result;
}
@ -1926,7 +1937,7 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(
result.withTopBarShadow = false;
}
_playerFloats.hideAll();
floatPlayerHideAll();
if (_player) {
_player->hideShadow();
}
@ -1974,7 +1985,7 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(
if (_player) {
_player->showShadow();
}
_playerFloats.showVisible();
floatPlayerShowVisible();
return result;
}
@ -2116,7 +2127,7 @@ void MainWidget::showNewSection(
}
}
_playerFloats.checkVisibility();
floatPlayerCheckVisibility();
orderWidgets();
}
@ -2223,7 +2234,7 @@ void MainWidget::orderWidgets() {
_connecting->raise();
_playerPlaylist->raise();
_playerPanel->raise();
_playerFloats.raiseAll();
floatPlayerRaiseAll();
if (_hider) _hider->raise();
}
@ -2236,7 +2247,7 @@ QRect MainWidget::historyRect() const {
QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams &params) {
QPixmap result;
_playerFloats.hideAll();
floatPlayerHideAll();
if (_player) {
_player->hideShadow();
}
@ -2287,7 +2298,7 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams &param
if (_player) {
_player->showShadow();
}
_playerFloats.showVisible();
floatPlayerShowVisible();
return result;
}
@ -2424,7 +2435,7 @@ void MainWidget::hideAll() {
_player->setVisible(false);
_playerHeight = 0;
}
_playerFloats.hideAll();
floatPlayerHideAll();
}
void MainWidget::showAll() {
@ -2497,8 +2508,8 @@ void MainWidget::showAll() {
_playerHeight = _player->contentHeight();
}
updateControlsGeometry();
_playerFloats.checkVisibility();
_playerFloats.showVisible();
floatPlayerCheckVisibility();
floatPlayerShowVisible();
App::wnd()->checkHistoryActivation();
}
@ -2609,7 +2620,7 @@ void MainWidget::updateControlsGeometry() {
updateMediaPlaylistPosition(_playerPlaylist->x());
_contentScrollAddToY = 0;
_playerFloats.updatePositions();
floatPlayerUpdatePositions();
}
void MainWidget::refreshResizeAreas() {
@ -2852,7 +2863,7 @@ bool MainWidget::eventFilter(QObject *o, QEvent *e) {
return true;
}
} else if (e->type() == QEvent::Wheel) {
if (const auto result = _playerFloats.filterWheelEvent(o, e)) {
if (const auto result = floatPlayerFilterWheelEvent(o, e)) {
return *result;
}
}

View file

@ -470,7 +470,8 @@ private:
void floatPlayerEnumerateSections(Fn<void(
not_null<Window::AbstractSectionWidget*> widget,
Window::Column widgetColumn)> callback) override;
void floatPlayerCloseHook(FullMsgId itemId) override;
bool floatPlayerIsVisible(not_null<HistoryItem*> item) override;
void floatPlayerClosed(FullMsgId itemId);
bool getDifferenceTimeChanged(ChannelData *channel, int32 ms, ChannelGetDifferenceTime &channelCurTime, TimeMs &curTime);
@ -523,7 +524,6 @@ private:
object_ptr<Media::Player::Panel> _playerPlaylist;
object_ptr<Media::Player::Panel> _playerPanel;
bool _playerUsingPanel = false;
Media::Player::FloatController _playerFloats;
QPointer<ConfirmBox> _forwardConfirm; // for single column layout
object_ptr<HistoryHider> _hider = { nullptr };

View file

@ -305,6 +305,58 @@ FloatController::FloatController(not_null<FloatDelegate*> delegate)
checkCurrent();
}
});
startDelegateHandling();
}
void FloatController::replaceDelegate(not_null<FloatDelegate*> delegate) {
_delegateLifetime.destroy();
_delegate = delegate;
_parent = _delegate->floatPlayerWidget();
// Currently moving floats between windows is not supported.
Assert(_controller == _delegate->floatPlayerController());
startDelegateHandling();
for (const auto &item : _items) {
item->widget->setParent(_parent);
}
checkVisibility();
}
void FloatController::startDelegateHandling() {
_delegate->floatPlayerCheckVisibilityRequests(
) | rpl::start_with_next([=] {
checkVisibility();
}, _delegateLifetime);
_delegate->floatPlayerHideAllRequests(
) | rpl::start_with_next([=] {
hideAll();
}, _delegateLifetime);
_delegate->floatPlayerShowVisibleRequests(
) | rpl::start_with_next([=] {
showVisible();
}, _delegateLifetime);
_delegate->floatPlayerRaiseAllRequests(
) | rpl::start_with_next([=] {
raiseAll();
}, _delegateLifetime);
_delegate->floatPlayerUpdatePositionsRequests(
) | rpl::start_with_next([=] {
updatePositions();
}, _delegateLifetime);
_delegate->floatPlayerFilterWheelEventRequests(
) | rpl::start_with_next([=](
const FloatDelegate::FloatPlayerFilterWheelEventRequest &request) {
*request.result = filterWheelEvent(request.object, request.event);
}, _delegateLifetime);
}
void FloatController::checkCurrent() {
@ -364,16 +416,15 @@ void FloatController::toggle(not_null<Item*> instance) {
}
void FloatController::checkVisibility() {
auto instance = current();
const auto instance = current();
if (!instance) {
return;
}
auto amVisible = false;
if (auto item = instance->widget->item()) {
Auth().data().queryItemVisibility().notify({ item, &amVisible }, true);
}
instance->hiddenByHistory = amVisible;
const auto item = instance->widget->item();
instance->hiddenByHistory = item
? _delegate->floatPlayerIsVisible(item)
: false;
toggle(instance);
updatePosition(instance);
}
@ -405,8 +456,8 @@ void FloatController::updatePositions() {
}
std::optional<bool> FloatController::filterWheelEvent(
QObject *object,
QEvent *event) {
not_null<QObject*> object,
not_null<QEvent*> event) {
for (const auto &instance : _items) {
if (instance->widget == object) {
const auto section = _delegate->floatPlayerGetSection(
@ -575,7 +626,7 @@ void FloatController::finishDrag(not_null<Item*> instance, bool closed) {
if (closed) {
if (const auto item = instance->widget->item()) {
_delegate->floatPlayerCloseHook(item->fullId());
_closeEvents.fire(item->fullId());
}
instance->widget->detach();
}

View file

@ -104,7 +104,65 @@ public:
virtual void floatPlayerEnumerateSections(Fn<void(
not_null<Window::AbstractSectionWidget*> widget,
Window::Column widgetColumn)> callback) = 0;
virtual void floatPlayerCloseHook(FullMsgId itemId) = 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();;
}
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();
}
protected:
void floatPlayerCheckVisibility() {
_checkVisibility.fire({});
}
void floatPlayerHideAll() {
_hideAll.fire({});
}
void floatPlayerShowVisible() {
_showVisible.fire({});
}
void floatPlayerRaiseAll() {
_raiseAll.fire({});
}
void floatPlayerUpdatePositions() {
_updatePositions.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<FloatPlayerFilterWheelEventRequest> _filterWheelEvent;
};
@ -112,14 +170,10 @@ class FloatController : private base::Subscriber {
public:
explicit FloatController(not_null<FloatDelegate*> delegate);
void checkVisibility();
void hideAll();
void showVisible();
void raiseAll();
void updatePositions();
std::optional<bool> filterWheelEvent(
QObject *object,
QEvent *event);
void replaceDelegate(not_null<FloatDelegate*> delegate);
rpl::producer<FullMsgId> closeEvents() const {
return _closeEvents.events();
}
private:
struct Item {
@ -163,11 +217,24 @@ private:
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;
not_null<Window::Controller*> _controller;
std::vector<std::unique_ptr<Item>> _items;
rpl::event_stream<FullMsgId> _closeEvents;
rpl::lifetime _delegateLifetime;
};
} // namespace Player

View file

@ -551,6 +551,40 @@ void Controller::roundVideoFinished(not_null<RoundController*> video) {
}
}
void Controller::setDefaultFloatPlayerDelegate(
not_null<Media::Player::FloatDelegate*> delegate) {
Expects(_defaultFloatPlayerDelegate == nullptr);
_defaultFloatPlayerDelegate = delegate;
_floatPlayers = std::make_unique<Media::Player::FloatController>(
delegate);
_floatPlayers->closeEvents();
}
void Controller::replaceFloatPlayerDelegate(
not_null<Media::Player::FloatDelegate*> replacement) {
Expects(_floatPlayers != nullptr);
_replacementFloatPlayerDelegate = replacement;
_floatPlayers->replaceDelegate(replacement);
}
void Controller::restoreFloatPlayerDelegate(
not_null<Media::Player::FloatDelegate*> replacement) {
Expects(_floatPlayers != nullptr);
if (_replacementFloatPlayerDelegate == replacement) {
_replacementFloatPlayerDelegate = nullptr;
_floatPlayers->replaceDelegate(_defaultFloatPlayerDelegate);
}
}
rpl::producer<FullMsgId> Controller::floatPlayerClosed() const {
Expects(_floatPlayers != nullptr);
return _floatPlayers->closeEvents();
}
Controller::~Controller() = default;
} // namespace Window

View file

@ -22,6 +22,8 @@ enum class Type;
namespace Media {
namespace Player {
class RoundController;
class FloatController;
class FloatDelegate;
} // namespace Player
} // namespace Media
@ -242,6 +244,14 @@ public:
RoundController *roundVideo(FullMsgId contextId) const;
void roundVideoFinished(not_null<RoundController*> video);
void setDefaultFloatPlayerDelegate(
not_null<Media::Player::FloatDelegate*> delegate);
void replaceFloatPlayerDelegate(
not_null<Media::Player::FloatDelegate*> replacement);
void restoreFloatPlayerDelegate(
not_null<Media::Player::FloatDelegate*> replacement);
rpl::producer<FullMsgId> floatPlayerClosed() const;
rpl::lifetime &lifetime() {
return _lifetime;
}
@ -275,6 +285,9 @@ private:
base::Variable<bool> _dialogsListDisplayForced = { false };
std::unique_ptr<RoundController> _roundVideo;
std::unique_ptr<Media::Player::FloatController> _floatPlayers;
Media::Player::FloatDelegate *_defaultFloatPlayerDelegate = nullptr;
Media::Player::FloatDelegate *_replacementFloatPlayerDelegate = nullptr;
rpl::lifetime _lifetime;