mirror of https://github.com/procxx/kepka.git
Add sample PiP controls.
This commit is contained in:
parent
63090fb75f
commit
b88219902f
|
@ -2317,6 +2317,12 @@ void OverlayWidget::playbackControlsFromFullScreen() {
|
|||
playbackToggleFullScreen();
|
||||
}
|
||||
|
||||
void OverlayWidget::playbackControlsToPictureInPicture() {
|
||||
if (!videoIsGifv()) {
|
||||
switchToPip();
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayWidget::playbackPauseResume() {
|
||||
Expects(_streamed != nullptr);
|
||||
|
||||
|
@ -2412,11 +2418,6 @@ void OverlayWidget::switchToPip() {
|
|||
void OverlayWidget::playbackToggleFullScreen() {
|
||||
Expects(_streamed != nullptr);
|
||||
|
||||
if (!videoIsGifv() && !_fullScreenVideo) {
|
||||
switchToPip();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!videoShown() || (videoIsGifv() && !_fullScreenVideo)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -174,6 +174,7 @@ private:
|
|||
float64 playbackControlsCurrentVolume() override;
|
||||
void playbackControlsToFullScreen() override;
|
||||
void playbackControlsFromFullScreen() override;
|
||||
void playbackControlsToPictureInPicture() override;
|
||||
void playbackPauseResume();
|
||||
void playbackToggleFullScreen();
|
||||
void playbackPauseOnCall();
|
||||
|
|
|
@ -10,11 +10,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "media/streaming/media_streaming_player.h"
|
||||
#include "media/streaming/media_streaming_document.h"
|
||||
#include "media/streaming/media_streaming_utility.h"
|
||||
#include "media/audio/media_audio.h"
|
||||
#include "core/application.h"
|
||||
#include "ui/platform/ui_platform_utility.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "window/window_controller.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_mediaview.h"
|
||||
#include "styles/style_layers.h" // st::boxTitleClose
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QScreen>
|
||||
|
@ -564,16 +568,6 @@ void PipPanel::moveAnimated(QPoint to) {
|
|||
anim::easeOutCirc);
|
||||
}
|
||||
|
||||
void PipPanel::keyPressEvent(QKeyEvent *e) {
|
||||
if (e->key() == Qt::Key_Space) {
|
||||
//playbackPauseResume();
|
||||
} else if (e->key() == Qt::Key_Escape) {
|
||||
//crl::on_main(this, [=] {
|
||||
// _closeAndContinue();
|
||||
//});
|
||||
}
|
||||
}
|
||||
|
||||
Pip::Pip(
|
||||
QWidget *parent,
|
||||
std::shared_ptr<Streaming::Document> document,
|
||||
|
@ -583,8 +577,32 @@ Pip::Pip(
|
|||
, _panel(parent, [=](QPainter &p, const FrameRequest &request) {
|
||||
paint(p, request);
|
||||
})
|
||||
, _playPauseResume(
|
||||
std::in_place,
|
||||
&_panel,
|
||||
object_ptr<Ui::IconButton>(&_panel, st::mediaviewPlayButton))
|
||||
, _pictureInPicture(
|
||||
std::in_place,
|
||||
&_panel,
|
||||
object_ptr<Ui::IconButton>(&_panel, st::mediaviewFullScreenButton))
|
||||
, _close(
|
||||
std::in_place,
|
||||
&_panel,
|
||||
object_ptr<Ui::IconButton>(&_panel, st::boxTitleClose))
|
||||
, _closeAndContinue(std::move(closeAndContinue))
|
||||
, _destroy(std::move(destroy)) {
|
||||
_close->entity()->addClickHandler([=] {
|
||||
_panel.close();
|
||||
});
|
||||
_pictureInPicture->entity()->addClickHandler([=] {
|
||||
_closeAndContinue();
|
||||
});
|
||||
_playPauseResume->entity()->addClickHandler([=] {
|
||||
playbackPauseResume();
|
||||
});
|
||||
_close->show(anim::type::instant);
|
||||
_pictureInPicture->show(anim::type::instant);
|
||||
_playPauseResume->show(anim::type::instant);
|
||||
setupPanel();
|
||||
setupStreaming();
|
||||
}
|
||||
|
@ -597,13 +615,35 @@ void Pip::setupPanel() {
|
|||
_panel.setAspectRatio(size);
|
||||
}
|
||||
_panel.setPosition(PipPanel::Position());
|
||||
//_panel.events(
|
||||
//) | rpl::filter([=](not_null<QEvent*> e) {
|
||||
// return (e->type() == QEvent::WindowActivate);
|
||||
//}) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||
// int a = 0;
|
||||
//}, _panel.lifetime());
|
||||
_panel.show();
|
||||
|
||||
_panel.sizeValue(
|
||||
) | rpl::start_with_next([=](QSize size) {
|
||||
_close->moveToLeft(0, 0, size.width());
|
||||
const auto skip = st::mediaviewFullScreenLeft;
|
||||
const auto sum = _playPauseResume->width() + skip + _pictureInPicture->width();
|
||||
const auto left = (size.width() - sum) / 2;
|
||||
const auto top = size.height() - _playPauseResume->height() - skip;
|
||||
_playPauseResume->moveToLeft(left, top);
|
||||
_pictureInPicture->moveToRight(left, top);
|
||||
}, _panel.lifetime());
|
||||
|
||||
_panel.events(
|
||||
) | rpl::filter([=](not_null<QEvent*> e) {
|
||||
return e->type() == QEvent::Close;
|
||||
}) | rpl::start_with_next([=] {
|
||||
_destroy();
|
||||
}, _panel.lifetime());
|
||||
}
|
||||
|
||||
void Pip::updatePlayPauseResumeState(const Player::TrackState &state) {
|
||||
auto showPause = Player::ShowPauseIcon(state.state);
|
||||
if (showPause != _showPause) {
|
||||
_showPause = showPause;
|
||||
_playPauseResume->entity()->setIconOverride(
|
||||
_showPause ? &st::mediaviewPauseIcon : nullptr,
|
||||
_showPause ? &st::mediaviewPauseIconOver : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void Pip::setupStreaming() {
|
||||
|
@ -632,39 +672,59 @@ void Pip::handleStreamingUpdate(Streaming::Update &&update) {
|
|||
update.data.match([&](Information &update) {
|
||||
_panel.setAspectRatio(update.video.size);
|
||||
}, [&](const PreloadedVideo &update) {
|
||||
//updatePlaybackState();
|
||||
updatePlaybackState();
|
||||
}, [&](const UpdateVideo &update) {
|
||||
_panel.update();
|
||||
Core::App().updateNonIdle();
|
||||
//updatePlaybackState();
|
||||
updatePlaybackState();
|
||||
}, [&](const PreloadedAudio &update) {
|
||||
//updatePlaybackState();
|
||||
updatePlaybackState();
|
||||
}, [&](const UpdateAudio &update) {
|
||||
//updatePlaybackState();
|
||||
updatePlaybackState();
|
||||
}, [&](WaitingForData) {
|
||||
}, [&](MutedByOther) {
|
||||
}, [&](Finished) {
|
||||
//updatePlaybackState();
|
||||
updatePlaybackState();
|
||||
});
|
||||
}
|
||||
|
||||
void Pip::updatePlaybackState() {
|
||||
const auto state = _instance.player().prepareLegacyState();
|
||||
if (state.position != kTimeUnknown && state.length != kTimeUnknown) {
|
||||
updatePlayPauseResumeState(state);
|
||||
}
|
||||
}
|
||||
|
||||
void Pip::handleStreamingError(Streaming::Error &&error) {
|
||||
_panel.close();
|
||||
}
|
||||
|
||||
void Pip::playbackPauseResume() {
|
||||
if (_instance.player().finished() || !_instance.player().active()) {
|
||||
//restartAtSeekPosition(0);
|
||||
if (_instance.player().failed()) {
|
||||
_panel.close();
|
||||
} else if (_instance.player().finished()
|
||||
|| !_instance.player().active()) {
|
||||
restartAtSeekPosition(0);
|
||||
} else if (_instance.player().paused()) {
|
||||
_instance.resume();
|
||||
//updatePlaybackState();
|
||||
//playbackPauseMusic();
|
||||
updatePlaybackState();
|
||||
} else {
|
||||
_instance.pause();
|
||||
//updatePlaybackState();
|
||||
updatePlaybackState();
|
||||
}
|
||||
}
|
||||
|
||||
void Pip::restartAtSeekPosition(crl::time position) {
|
||||
if (!_instance.info().video.cover.isNull()) {
|
||||
_instance.saveFrameToCover();
|
||||
}
|
||||
auto options = Streaming::PlaybackOptions();
|
||||
options.position = position;
|
||||
options.audioId = _instance.player().prepareLegacyState().id;
|
||||
_instance.play(options);
|
||||
updatePlaybackState();
|
||||
}
|
||||
|
||||
QImage Pip::videoFrame(const FrameRequest &request) const {
|
||||
if (_instance.player().ready()) {
|
||||
return _instance.frame(request);
|
||||
|
|
|
@ -13,7 +13,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
template <typename Widget>
|
||||
class FadeWrap;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
struct TrackState;
|
||||
} // namespace Player
|
||||
|
||||
namespace View {
|
||||
|
||||
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||
|
@ -49,7 +59,6 @@ protected:
|
|||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void keyPressEvent(QKeyEvent *e) override;
|
||||
|
||||
private:
|
||||
void setPositionDefault();
|
||||
|
@ -97,6 +106,10 @@ private:
|
|||
void handleStreamingUpdate(Streaming::Update &&update);
|
||||
void handleStreamingError(Streaming::Error &&error);
|
||||
|
||||
void updatePlaybackState();
|
||||
void updatePlayPauseResumeState(const Player::TrackState &state);
|
||||
void restartAtSeekPosition(crl::time position);
|
||||
|
||||
[[nodiscard]] QImage videoFrame(const FrameRequest &request) const;
|
||||
[[nodiscard]] QImage videoFrameForDirectPaint(
|
||||
const FrameRequest &request) const;
|
||||
|
@ -105,6 +118,11 @@ private:
|
|||
PipPanel _panel;
|
||||
QSize _size;
|
||||
|
||||
base::unique_qptr<Ui::FadeWrap<Ui::IconButton>> _playPauseResume;
|
||||
base::unique_qptr< Ui::FadeWrap<Ui::IconButton>> _pictureInPicture;
|
||||
base::unique_qptr< Ui::FadeWrap<Ui::IconButton>> _close;
|
||||
bool _showPause = false;
|
||||
|
||||
FnMut<void()> _closeAndContinue;
|
||||
FnMut<void()> _destroy;
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ PlaybackControls::PlaybackControls(
|
|||
, _playbackProgress(std::make_unique<PlaybackProgress>())
|
||||
, _volumeController(this, st::mediaviewPlayback)
|
||||
, _fullScreenToggle(this, st::mediaviewFullScreenButton)
|
||||
, _pictureInPicture(this, st::mediaviewFullScreenButton)
|
||||
, _playedAlready(this, st::mediaviewPlayProgressLabel)
|
||||
, _toPlayLeft(this, st::mediaviewPlayProgressLabel)
|
||||
, _fadeAnimation(std::make_unique<Ui::FadeAnimation>(this)) {
|
||||
|
@ -42,6 +43,13 @@ PlaybackControls::PlaybackControls(
|
|||
fadeUpdated(opacity);
|
||||
});
|
||||
|
||||
_pictureInPicture->setIconOverride(
|
||||
&st::mediaviewFullScreenOutIcon,
|
||||
&st::mediaviewFullScreenOutIconOver);
|
||||
_pictureInPicture->addClickHandler([=] {
|
||||
_delegate->playbackControlsToPictureInPicture();
|
||||
});
|
||||
|
||||
_volumeController->setValue(_delegate->playbackControlsCurrentVolume());
|
||||
_volumeController->setChangeProgressCallback([=](float64 value) {
|
||||
_delegate->playbackControlsVolumeChanged(value);
|
||||
|
@ -275,26 +283,31 @@ void PlaybackControls::setInFullScreen(bool inFullScreen) {
|
|||
}
|
||||
|
||||
void PlaybackControls::resizeEvent(QResizeEvent *e) {
|
||||
int playTop = (height() - _playPauseResume->height()) / 2;
|
||||
_playPauseResume->moveToLeft(st::mediaviewPlayPauseLeft, playTop);
|
||||
const auto skip = st::mediaviewFullScreenLeft;
|
||||
|
||||
int fullScreenTop = (height() - _fullScreenToggle->height()) / 2;
|
||||
_fullScreenToggle->moveToRight(st::mediaviewFullScreenLeft, fullScreenTop);
|
||||
|
||||
_volumeController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height());
|
||||
_volumeController->moveToRight(st::mediaviewFullScreenLeft + _fullScreenToggle->width() + st::mediaviewVolumeLeft, st::mediaviewPlaybackTop);
|
||||
|
||||
auto playbackWidth = width() - st::mediaviewPlayPauseLeft - _playPauseResume->width() - playTop - fullScreenTop - _volumeController->width() - st::mediaviewVolumeLeft - _fullScreenToggle->width() - st::mediaviewFullScreenLeft;
|
||||
auto playbackWidth = width() - 2 * skip;
|
||||
_playbackSlider->resize(playbackWidth, st::mediaviewPlayback.seekSize.height());
|
||||
_playbackSlider->moveToLeft(st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop, st::mediaviewPlaybackTop);
|
||||
|
||||
_playedAlready->moveToLeft(st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop, st::mediaviewPlayProgressTop);
|
||||
_toPlayLeft->moveToRight(width() - (st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop) - playbackWidth, st::mediaviewPlayProgressTop);
|
||||
_playbackSlider->moveToLeft(st::mediaviewPlayPauseLeft, st::mediaviewPlaybackTop);
|
||||
|
||||
_playedAlready->moveToLeft(st::mediaviewPlayPauseLeft, st::mediaviewPlayProgressTop);
|
||||
_toPlayLeft->moveToRight(st::mediaviewPlayPauseLeft, st::mediaviewPlayProgressTop);
|
||||
if (_downloadProgress) {
|
||||
const auto left = (_playbackSlider->width() - _downloadProgress->width()) / 2;
|
||||
_downloadProgress->move(_playbackSlider->x() + left, st::mediaviewPlayProgressTop);
|
||||
}
|
||||
|
||||
auto left = skip;
|
||||
const auto playTop = height() - _playPauseResume->height() - skip;
|
||||
_playPauseResume->moveToLeft(left, playTop);
|
||||
left += _playPauseResume->width() + skip;
|
||||
|
||||
_fullScreenToggle->moveToLeft(left, playTop);
|
||||
left += _fullScreenToggle->width() + skip;
|
||||
|
||||
_pictureInPicture->moveToLeft(left, playTop);
|
||||
|
||||
_volumeController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height());
|
||||
_volumeController->moveToRight(skip, playTop + (_fullScreenToggle->height() - _volumeController->height()) / 2);
|
||||
}
|
||||
|
||||
void PlaybackControls::paintEvent(QPaintEvent *e) {
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
[[nodiscard]] virtual float64 playbackControlsCurrentVolume() = 0;
|
||||
virtual void playbackControlsToFullScreen() = 0;
|
||||
virtual void playbackControlsFromFullScreen() = 0;
|
||||
virtual void playbackControlsToPictureInPicture() = 0;
|
||||
};
|
||||
|
||||
PlaybackControls(QWidget *parent, not_null<Delegate*> delegate);
|
||||
|
@ -90,6 +91,7 @@ private:
|
|||
std::unique_ptr<PlaybackProgress> _receivedTillProgress;
|
||||
object_ptr<Ui::MediaSlider> _volumeController;
|
||||
object_ptr<Ui::IconButton> _fullScreenToggle;
|
||||
object_ptr<Ui::IconButton> _pictureInPicture;
|
||||
object_ptr<Ui::LabelSimple> _playedAlready;
|
||||
object_ptr<Ui::LabelSimple> _toPlayLeft;
|
||||
object_ptr<Ui::LabelSimple> _downloadProgress = { nullptr };
|
||||
|
|
|
@ -24,7 +24,7 @@ mediaviewPlayback: MediaSlider {
|
|||
duration: mediaviewOverDuration;
|
||||
}
|
||||
|
||||
mediaviewControllerSize: size(600px, 50px);
|
||||
mediaviewControllerSize: size(480px, 100px);
|
||||
mediaviewPlayProgressLabel: LabelSimple(defaultLabelSimple) {
|
||||
font: semiboldFont;
|
||||
textFg: mediaviewPlaybackProgressFg;
|
||||
|
@ -57,7 +57,7 @@ mediaviewFullScreenOutIconOver: icon {{ "media_fullscreen_from", mediaviewPlayba
|
|||
mediaviewPlaybackTop: 28px;
|
||||
|
||||
mediaviewVolumeWidth: 60px;
|
||||
mediaviewControllerRadius: 25px;
|
||||
mediaviewControllerRadius: roundRadiusLarge;
|
||||
|
||||
mediaviewLeft: icon {{ "mediaview_next-flip_horizontal", mediaviewControlFg }};
|
||||
mediaviewRight: icon {{ "mediaview_next", mediaviewControlFg }};
|
||||
|
|
Loading…
Reference in New Issue