diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp index 144cdf4a9..643d2fd90 100644 --- a/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp +++ b/Telegram/SourceFiles/media/streaming/media_streaming_player.cpp @@ -958,7 +958,9 @@ void Player::unlock() { --_locks; if (!_locks) { stopAudio(); - setSpeed(1.); + if (active()) { + setSpeed(1.); + } setWaitForMarkAsShown(true); } } diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 53d8b5967..734cd86a3 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -227,6 +227,10 @@ OverlayWidget::OverlayWidget() , _dropdownShowTimer(this) { subscribe(Lang::Current().updated(), [this] { refreshLang(); }); + _lastPositiveVolume = (Global::VideoVolume() > 0.) + ? Global::VideoVolume() + : Global::kDefaultVolume; + setWindowIcon(Window::CreateIcon(&Core::App().activeAccount())); setWindowTitle(qsl("Media viewer")); @@ -2409,6 +2413,18 @@ float64 OverlayWidget::playbackControlsCurrentVolume() { return Global::VideoVolume(); } +void OverlayWidget::playbackControlsVolumeToggled() { + const auto volume = Global::VideoVolume(); + playbackControlsVolumeChanged(volume ? 0. : _lastPositiveVolume); +} + +void OverlayWidget::playbackControlsVolumeChangeFinished() { + const auto volume = Global::VideoVolume(); + if (volume > 0.) { + _lastPositiveVolume = volume; + } +} + void OverlayWidget::playbackControlsSpeedChanged(float64 speed) { if (_doc) { _doc->session().settings().setVideoPlaybackSpeed(speed); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index a72dcf936..e83ccd611 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -172,6 +172,8 @@ private: void playbackControlsSeekFinished(crl::time position) override; void playbackControlsVolumeChanged(float64 volume) override; float64 playbackControlsCurrentVolume() override; + void playbackControlsVolumeToggled() override; + void playbackControlsVolumeChangeFinished() override; void playbackControlsSpeedChanged(float64 speed); float64 playbackControlsCurrentSpeed() override; void playbackControlsToFullScreen() override; @@ -359,6 +361,7 @@ private: bool _streamingStartPaused = false; bool _fullScreenVideo = false; int _fullScreenZoomCache = 0; + float64 _lastPositiveVolume = 1.; std::unique_ptr _groupThumbs; QRect _groupThumbsRect; diff --git a/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp b/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp index f67fff407..3fde55bfb 100644 --- a/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp +++ b/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp @@ -29,8 +29,10 @@ PlaybackControls::PlaybackControls( , _playPauseResume(this, st::mediaviewPlayButton) , _playbackSlider(this, st::mediaviewPlayback) , _playbackProgress(std::make_unique()) +, _volumeToggle(this, st::mediaviewVolumeToggle) , _volumeController(this, st::mediaviewPlayback) , _speedController(this, st::mediaviewPlayback) +, _speedLabel(this, st::mediaviewPlayProgressLabel) , _fullScreenToggle(this, st::mediaviewFullScreenButton) , _pictureInPicture(this, st::mediaviewFullScreenButton) , _playedAlready(this, st::mediaviewPlayProgressLabel) @@ -54,12 +56,24 @@ PlaybackControls::PlaybackControls( _volumeController->setValue(_delegate->playbackControlsCurrentVolume()); _volumeController->setChangeProgressCallback([=](float64 value) { _delegate->playbackControlsVolumeChanged(value); + updateVolumeToggleIcon(); }); + _volumeController->setChangeFinishedCallback([=](float64) { + _delegate->playbackControlsVolumeChangeFinished(); + }); + updateVolumeToggleIcon(); + _volumeToggle->setClickedCallback([=] { + _delegate->playbackControlsVolumeToggled(); + _volumeController->setValue(_delegate->playbackControlsCurrentVolume()); + updateVolumeToggleIcon(); + }); + _speedController->setPseudoDiscrete( 7, [=](int index) { return (index + 2) / 4.; }, _delegate->playbackControlsCurrentSpeed(), - [=](float64 speed) { _delegate->playbackControlsSpeedChanged(speed); }); + [=](float64 speed) { updatePlaybackSpeed(speed); }); + updatePlaybackSpeed(_delegate->playbackControlsCurrentSpeed()); _speedController->setAlwaysDisplayMarker(false); _playPauseResume->addClickHandler([=] { @@ -172,12 +186,41 @@ void PlaybackControls::fadeUpdated(float64 opacity) { _speedController->setFadeOpacity(opacity); } +void PlaybackControls::updatePlaybackSpeed(float64 speed) { + _delegate->playbackControlsSpeedChanged(speed); + //const auto percent = int(std::round(speed * 100.)); + //_speedLabel->setText(QString::number(percent) + '%'); + _speedLabel->setText(QString::number(speed) + 'x'); + resizeEvent(nullptr); +} + void PlaybackControls::updatePlayback(const Player::TrackState &state) { updatePlayPauseResumeState(state); _playbackProgress->updateState(state, countDownloadedTillPercent(state)); updateTimeTexts(state); } +void PlaybackControls::updateVolumeToggleIcon() { + const auto volume = _delegate->playbackControlsCurrentVolume(); + _volumeToggle->setIconOverride([&] { + return (volume <= 0.) + ? nullptr + : (volume < 1 / 3.) + ? &st::mediaviewVolumeIcon1 + : (volume < 2 / 3.) + ? &st::mediaviewVolumeIcon2 + : &st::mediaviewVolumeIcon3; + }(), [&] { + return (volume <= 0.) + ? nullptr + : (volume < 1 / 3.) + ? &st::mediaviewVolumeIcon1Over + : (volume < 2 / 3.) + ? &st::mediaviewVolumeIcon2Over + : &st::mediaviewVolumeIcon3Over; + }()); +} + float64 PlaybackControls::countDownloadedTillPercent( const Player::TrackState &state) const { if (_loadingReady > 0 && _loadingReady == _loadingTotal) { @@ -317,12 +360,21 @@ void PlaybackControls::resizeEvent(QResizeEvent *e) { _pictureInPicture->moveToLeft(left, playTop); + auto right = skip; const auto volumeTop = playTop + (_fullScreenToggle->height() - _volumeController->height()) / 2; + const auto volumeIconTop = playTop + (_fullScreenToggle->height() - _volumeToggle->height()) / 2; _volumeController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height()); - _volumeController->moveToRight(skip, volumeTop); + _volumeController->moveToRight(right, volumeTop); + right += _volumeController->width(); + _volumeToggle->moveToRight(right, volumeIconTop); + right += _volumeToggle->width() + 2 * skip; + const auto speedTop = volumeTop; + const auto speedLabelTop = playTop + (_fullScreenToggle->height() - _speedLabel->height()) / 2; _speedController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height()); - _speedController->moveToRight(skip + _volumeController->width() + skip, volumeTop); + _speedController->moveToRight(right, volumeTop); + right += _speedController->width() + st::semiboldFont->spacew * 3; + _speedLabel->moveToRight(right, speedLabelTop); } void PlaybackControls::paintEvent(QPaintEvent *e) { diff --git a/Telegram/SourceFiles/media/view/media_view_playback_controls.h b/Telegram/SourceFiles/media/view/media_view_playback_controls.h index edff22b15..e2d20b887 100644 --- a/Telegram/SourceFiles/media/view/media_view_playback_controls.h +++ b/Telegram/SourceFiles/media/view/media_view_playback_controls.h @@ -36,6 +36,8 @@ public: virtual void playbackControlsSeekFinished(crl::time position) = 0; virtual void playbackControlsVolumeChanged(float64 volume) = 0; [[nodiscard]] virtual float64 playbackControlsCurrentVolume() = 0; + virtual void playbackControlsVolumeToggled() = 0; + virtual void playbackControlsVolumeChangeFinished() = 0; virtual void playbackControlsSpeedChanged(float64 speed) = 0; [[nodiscard]] virtual float64 playbackControlsCurrentSpeed() = 0; virtual void playbackControlsToFullScreen() = 0; @@ -71,6 +73,9 @@ private: [[nodiscard]] float64 countDownloadedTillPercent( const Player::TrackState &state) const; + void updatePlaybackSpeed(float64 speed); + void updateVolumeToggleIcon(); + void updatePlayPauseResumeState(const Player::TrackState &state); void updateTimeTexts(const Player::TrackState &state); void refreshTimeTexts(); @@ -91,8 +96,10 @@ private: object_ptr _playbackSlider; std::unique_ptr _playbackProgress; std::unique_ptr _receivedTillProgress; + object_ptr _volumeToggle; object_ptr _volumeController; object_ptr _speedController; + object_ptr _speedLabel; object_ptr _fullScreenToggle; object_ptr _pictureInPicture; object_ptr _playedAlready; diff --git a/Telegram/SourceFiles/media/view/mediaview.style b/Telegram/SourceFiles/media/view/mediaview.style index eef9f2dcd..40edc751a 100644 --- a/Telegram/SourceFiles/media/view/mediaview.style +++ b/Telegram/SourceFiles/media/view/mediaview.style @@ -59,6 +59,23 @@ mediaviewPlaybackTop: 28px; mediaviewVolumeWidth: 60px; mediaviewControllerRadius: roundRadiusLarge; +mediaviewVolumeIcon0: icon {{ "player_volume0", mediaviewPlaybackIconFg }}; +mediaviewVolumeIcon0Over: icon {{ "player_volume0", mediaviewPlaybackIconFgOver }}; +mediaviewVolumeIcon1: icon {{ "player_volume1", mediaviewPlaybackIconFg }}; +mediaviewVolumeIcon1Over: icon {{ "player_volume1", mediaviewPlaybackIconFgOver }}; +mediaviewVolumeIcon2: icon {{ "player_volume2", mediaviewPlaybackIconFg }}; +mediaviewVolumeIcon2Over: icon {{ "player_volume2", mediaviewPlaybackIconFgOver }}; +mediaviewVolumeIcon3: icon {{ "player_volume3", mediaviewPlaybackIconFg }}; +mediaviewVolumeIcon3Over: icon {{ "player_volume3", mediaviewPlaybackIconFgOver }}; +mediaviewVolumeToggle: IconButton { + width: 31px; + height: 29px; + + icon: mediaviewVolumeIcon0; + iconOver: mediaviewVolumeIcon0Over; + iconPosition: point(8px, 8px); +} + mediaviewLeft: icon {{ "mediaview_next-flip_horizontal", mediaviewControlFg }}; mediaviewRight: icon {{ "mediaview_next", mediaviewControlFg }}; mediaviewClose: icon {{ "mediaview_close", mediaviewControlFg }};