diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index d0605f9c9..bfd931857 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -813,8 +813,6 @@ PRIVATE media/player/media_player_instance.h media/player/media_player_panel.cpp media/player/media_player_panel.h - media/player/media_player_repeat_controls.cpp - media/player/media_player_repeat_controls.h media/player/media_player_volume_controller.cpp media/player/media_player_volume_controller.h media/player/media_player_widget.cpp diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 50fd731aa..a36fbea4a 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -81,8 +81,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/player/media_player_panel.h" #include "media/player/media_player_widget.h" #include "media/player/media_player_dropdown.h" -#include "media/player/media_player_repeat_controls.h" -#include "media/player/media_player_volume_controller.h" #include "media/player/media_player_instance.h" #include "media/player/media_player_float.h" #include "base/qthelp_regex.h" @@ -801,8 +799,6 @@ void MainWidget::closeBothPlayers() { if (_player) { _player->hide(anim::type::normal); } - _playerVolume.destroyDelayed(); - _playerRepeat.destroyDelayed(); _playerPlaylist->hideIgnoringEnterEvents(); Media::Player::instance()->stop(AudioMsgId::Type::Voice); @@ -821,7 +817,7 @@ void MainWidget::createPlayer() { if (!_player) { _player.create( this, - object_ptr(this, &session()), + object_ptr(this, this, _controller), _controller->adaptive().oneColumnValue()); rpl::merge( _player->heightValue() | rpl::map_to(true), @@ -849,14 +845,6 @@ void MainWidget::createPlayer() { _playerPlaylist->showFromOther(); }, _player->lifetime()); - _playerVolume.create(this); - Media::Player::PrepareVolumeDropdown( - _playerVolume.data(), - _controller); - _player->entity()->volumeWidgetCreated(_playerVolume); - _playerRepeat.create(this); - Media::Player::PrepareRepeatDropdown(_playerRepeat.data()); - _player->entity()->repeatWidgetCreated(_playerRepeat); orderWidgets(); if (_a_show.animating()) { _player->show(anim::type::instant); @@ -890,8 +878,6 @@ void MainWidget::playerHeightUpdated() { if (!_playerHeight && _player->isHidden()) { const auto state = Media::Player::instance()->getState(Media::Player::instance()->getActiveType()); if (!state.id || Media::Player::IsStoppedOrStopping(state.state)) { - _playerVolume.destroyDelayed(); - _playerRepeat.destroyDelayed(); _player.destroyDelayed(); } } @@ -1539,15 +1525,7 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation( floatPlayerHideAll(); if (_player) { - _player->hideShadow(); - } - auto playerVolumeVisible = _playerVolume && !_playerVolume->isHidden(); - if (playerVolumeVisible) { - _playerVolume->hide(); - } - auto playerRepeatVisible = _playerRepeat && !_playerRepeat->isHidden(); - if (playerRepeatVisible) { - _playerRepeat->hide(); + _player->entity()->hideShadowAndDropdowns(); } auto playerPlaylistVisible = !_playerPlaylist->isHidden(); if (playerPlaylistVisible) { @@ -1573,17 +1551,11 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation( height() - sectionTop)); } - if (playerVolumeVisible) { - _playerVolume->show(); - } - if (playerRepeatVisible) { - _playerRepeat->show(); - } if (playerPlaylistVisible) { _playerPlaylist->show(); } if (_player) { - _player->showShadow(); + _player->entity()->showShadowAndDropdowns(); } floatPlayerShowVisible(); @@ -1848,11 +1820,8 @@ void MainWidget::orderWidgets() { _connecting->raise(); floatPlayerRaiseAll(); _playerPlaylist->raise(); - if (_playerVolume) { - _playerVolume->raise(); - } - if (_playerRepeat) { - _playerRepeat->raise(); + if (_player) { + _player->entity()->raiseDropdowns(); } if (_hider) _hider->raise(); } @@ -1861,15 +1830,7 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m QPixmap result; floatPlayerHideAll(); if (_player) { - _player->hideShadow(); - } - auto playerVolumeVisible = _playerVolume && !_playerVolume->isHidden(); - if (playerVolumeVisible) { - _playerVolume->hide(); - } - auto playerRepeatVisible = _playerRepeat && !_playerRepeat->isHidden(); - if (playerRepeatVisible) { - _playerRepeat->hide(); + _player->entity()->hideShadowAndDropdowns(); } auto playerPlaylistVisible = !_playerPlaylist->isHidden(); if (playerPlaylistVisible) { @@ -1898,17 +1859,11 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m _thirdShadow->show(); } } - if (playerVolumeVisible) { - _playerVolume->show(); - } - if (playerRepeatVisible) { - _playerRepeat->show(); - } if (playerPlaylistVisible) { _playerPlaylist->show(); } if (_player) { - _player->showShadow(); + _player->entity()->showShadowAndDropdowns(); } floatPlayerShowVisible(); return result; @@ -2193,7 +2148,9 @@ void MainWidget::updateControlsGeometry() { _mainSection->setGeometryWithTopMoved(mainSectionGeometry, _contentScrollAddToY); } refreshResizeAreas(); - updateMediaPlayerPosition(); + if (_player) { + _player->entity()->updateDropdownsGeometry(); + } updateMediaPlaylistPosition(_playerPlaylist->x()); _contentScrollAddToY = 0; @@ -2392,22 +2349,6 @@ void MainWidget::updateThirdColumnToCurrentChat( } } -void MainWidget::updateMediaPlayerPosition() { - if (!_player) { - return; - } - if (_playerVolume) { - auto relativePosition = _player->entity()->getPositionForVolumeWidget(); - auto playerMargins = _playerVolume->getMargin(); - _playerVolume->moveToLeft(_player->x() + relativePosition.x() - playerMargins.left(), _player->y() + relativePosition.y() - playerMargins.top()); - } - if (_playerRepeat) { - auto relativePosition = _player->entity()->getPositionForRepeatWidget(); - auto playerMargins = _playerRepeat->getMargin(); - _playerRepeat->moveToLeft(_player->x() + relativePosition.x() - playerMargins.left(), _player->y() + relativePosition.y() - playerMargins.top()); - } -} - void MainWidget::updateMediaPlaylistPosition(int x) { if (_player) { auto playlistLeft = x; @@ -2429,12 +2370,10 @@ void MainWidget::returnTabbedSelector() { } } -void MainWidget::keyPressEvent(QKeyEvent *e) { -} - bool MainWidget::eventFilter(QObject *o, QEvent *e) { if (e->type() == QEvent::FocusIn) { - if (const auto widget = qobject_cast(o)) { + if (o->isWidgetType()) { + const auto widget = static_cast(o); if (_history == widget || _history->isAncestorOf(widget) || (_mainSection && (_mainSection == widget || _mainSection->isAncestorOf(widget))) || (_thirdSection && (_thirdSection == widget || _thirdSection->isAncestorOf(widget)))) { @@ -2555,10 +2494,8 @@ void MainWidget::searchInChat(Dialogs::Key chat) { } bool MainWidget::contentOverlapped(const QRect &globalRect) { - return (_history->contentOverlapped(globalRect) - || _playerPlaylist->overlaps(globalRect) - || (_playerVolume && _playerVolume->overlaps(globalRect))) - || (_playerRepeat && _playerRepeat->overlaps(globalRect)); + return _history->contentOverlapped(globalRect) + || _playerPlaylist->overlaps(globalRect); } void MainWidget::activate() { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 87ce1a6e4..98c1d877f 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -55,7 +55,6 @@ class Widget; namespace Media { namespace Player { class Widget; -class Dropdown; class Panel; struct TrackState; } // namespace Player @@ -241,7 +240,6 @@ public Q_SLOTS: protected: void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *e) override; - void keyPressEvent(QKeyEvent *e) override; bool eventFilter(QObject *o, QEvent *e) override; private: @@ -249,7 +247,6 @@ private: void handleAdaptiveLayoutUpdate(); void updateWindowAdaptiveLayout(); void handleAudioUpdate(const Media::Player::TrackState &state); - void updateMediaPlayerPosition(); void updateMediaPlaylistPosition(int x); void updateControlsGeometry(); void updateDialogsWidthAnimated(); @@ -366,8 +363,6 @@ private: object_ptr> _player = { nullptr }; - object_ptr _playerVolume = { nullptr }; - object_ptr _playerRepeat = { nullptr }; object_ptr _playerPlaylist; bool _playerUsingPanel = false; diff --git a/Telegram/SourceFiles/media/player/media_player_dropdown.cpp b/Telegram/SourceFiles/media/player/media_player_dropdown.cpp index 855c8e46e..64e4adac5 100644 --- a/Telegram/SourceFiles/media/player/media_player_dropdown.cpp +++ b/Telegram/SourceFiles/media/player/media_player_dropdown.cpp @@ -33,10 +33,12 @@ Dropdown::Dropdown(QWidget *parent) } QMargins Dropdown::getMargin() const { - const auto top = st::mediaPlayerHeight + const auto top1 = st::mediaPlayerHeight + st::lineWidth - st::mediaPlayerPlayTop - st::mediaPlayerVolumeToggle.height; + const auto top2 = st::mediaPlayerPlayback.fullWidth; + const auto top = std::max(top1, top2); return QMargins(st::mediaPlayerVolumeMargin, top, st::mediaPlayerVolumeMargin, st::mediaPlayerVolumeMargin); } diff --git a/Telegram/SourceFiles/media/player/media_player_repeat_controls.cpp b/Telegram/SourceFiles/media/player/media_player_repeat_controls.cpp deleted file mode 100644 index f57baf109..000000000 --- a/Telegram/SourceFiles/media/player/media_player_repeat_controls.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* -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 -*/ -#include "media/player/media_player_repeat_controls.h" - -#include "media/player/media_player_dropdown.h" -#include "media/player/media_player_instance.h" -#include "ui/widgets/buttons.h" -#include "core/core_settings.h" -#include "core/application.h" -#include "styles/style_media_player.h" - -namespace Media::Player { - -void PrepareRepeatDropdown(not_null dropdown) { - const auto makeButton = [&] { - const auto result = Ui::CreateChild( - dropdown.get(), - st::mediaPlayerRepeatButton); - result->show(); - return result; - }; - - const auto repeatOne = makeButton(); - const auto repeatAll = makeButton(); - const auto shuffle = makeButton(); - const auto reverse = makeButton(); - - Core::App().settings().playerRepeatModeValue( - ) | rpl::start_with_next([=](RepeatMode mode) { - const auto one = (mode == RepeatMode::One); - repeatOne->setIconOverride(one - ? &st::mediaPlayerRepeatOneIcon - : &st::mediaPlayerRepeatOneDisabledIcon, - one ? nullptr : &st::mediaPlayerRepeatOneDisabledIconOver); - repeatOne->setRippleColorOverride( - one ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg); - const auto all = (mode == RepeatMode::All); - repeatAll->setIconOverride(all - ? nullptr - : &st::mediaPlayerRepeatDisabledIcon, - all ? nullptr : &st::mediaPlayerRepeatDisabledIconOver); - repeatAll->setRippleColorOverride( - all ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg); - }, dropdown->lifetime()); - - Core::App().settings().playerOrderModeValue( - ) | rpl::start_with_next([=](OrderMode mode) { - const auto shuffled = (mode == OrderMode::Shuffle); - shuffle->setIconOverride(shuffled - ? &st::mediaPlayerShuffleIcon - : &st::mediaPlayerShuffleIcon, - shuffled ? nullptr : &st::mediaPlayerShuffleIcon); - shuffle->setRippleColorOverride( - shuffled ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg); - const auto reversed = (mode == OrderMode::Reverse); - reverse->setIconOverride(reversed - ? &st::mediaPlayerReverseIcon - : &st::mediaPlayerReverseDisabledIcon, - reversed ? nullptr : &st::mediaPlayerReverseDisabledIconOver); - reverse->setRippleColorOverride( - reversed ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg); - }, dropdown->lifetime()); - - const auto toggleRepeat = [](RepeatMode mode) { - auto &settings = Core::App().settings(); - const auto active = (settings.playerRepeatMode() == mode); - settings.setPlayerRepeatMode(active ? RepeatMode::None : mode); - Core::App().saveSettingsDelayed(); - }; - const auto toggleOrder = [](OrderMode mode) { - auto &settings = Core::App().settings(); - const auto active = (settings.playerOrderMode() == mode); - settings.setPlayerOrderMode(active ? OrderMode::Default : mode); - Core::App().saveSettingsDelayed(); - }; - repeatOne->setClickedCallback([=] { toggleRepeat(RepeatMode::One); }); - repeatAll->setClickedCallback([=] { toggleRepeat(RepeatMode::All); }); - shuffle->setClickedCallback([=] { toggleOrder(OrderMode::Shuffle); }); - reverse->setClickedCallback([=] { toggleOrder(OrderMode::Reverse); }); - - dropdown->sizeValue( - ) | rpl::start_with_next([=](QSize size) { - const auto rect = QRect(QPoint(), size); - const auto inner = rect.marginsRemoved(dropdown->getMargin()); - const auto skip = (inner.height() - repeatOne->height() * 4) / 3; - auto top = 0; - const auto move = [&](auto &widget) { - widget->move((size.width() - widget->width()) / 2, top); - top += widget->height() + skip; - }; - move(repeatOne); - move(repeatAll); - move(shuffle); - move(reverse); - }, dropdown->lifetime()); -} - -} // namespace Media::Player diff --git a/Telegram/SourceFiles/media/player/media_player_repeat_controls.h b/Telegram/SourceFiles/media/player/media_player_repeat_controls.h deleted file mode 100644 index 17cac6868..000000000 --- a/Telegram/SourceFiles/media/player/media_player_repeat_controls.h +++ /dev/null @@ -1,16 +0,0 @@ -/* -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 - -namespace Media::Player { - -class Dropdown; - -void PrepareRepeatDropdown(not_null dropdown); - -} // namespace Media::Player diff --git a/Telegram/SourceFiles/media/player/media_player_widget.cpp b/Telegram/SourceFiles/media/player/media_player_widget.cpp index fea02545b..476a0ccf5 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.cpp +++ b/Telegram/SourceFiles/media/player/media_player_widget.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/player/media_player_button.h" #include "media/player/media_player_instance.h" #include "media/player/media_player_dropdown.h" +#include "media/player/media_player_volume_controller.h" #include "styles/style_media_player.h" #include "styles/style_media_view.h" #include "history/history_item.h" @@ -238,9 +239,12 @@ QPoint Widget::PlayButton::prepareRippleStartPosition() const { return QPoint(mapFromGlobal(QCursor::pos()) - st::mediaPlayerButton.rippleAreaPosition); } -Widget::Widget(QWidget *parent, not_null session) +Widget::Widget( + QWidget *parent, + not_null dropdownsParent, + not_null controller) : RpWidget(parent) -, _session(session) +, _controller(controller) , _nameLabel(this, st::mediaPlayerName) , _rightControls(this, object_ptr(this)) , _timeLabel(rightControls(), st::mediaPlayerTime) @@ -252,6 +256,7 @@ Widget::Widget(QWidget *parent, not_null session) , _close(this, st::mediaPlayerClose) , _shadow(this) , _playbackSlider(this, st::mediaPlayerPlayback) +, _volume(dropdownsParent.get()) , _playbackProgress(std::make_unique()) , _speedController( std::make_unique( @@ -357,6 +362,10 @@ Widget::Widget(QWidget *parent, not_null session) handleSongUpdate(state); }, lifetime()); + PrepareVolumeDropdown(_volume.data(), controller); + _volumeToggle->installEventFilter(_volume.data()); + _volume->installEventFilter(this); + setType(AudioMsgId::Type::Song); } @@ -419,37 +428,36 @@ void Widget::setShadowGeometryToLeft(int x, int y, int w, int h) { _shadow->setGeometryToLeft(x, y, w, h); } -void Widget::showShadow() { +void Widget::showShadowAndDropdowns() { _shadow->show(); _playbackSlider->setVisible(_type == AudioMsgId::Type::Song); + if (_volumeHidden) { + _volumeHidden = false; + _volume->show(); + } } -void Widget::hideShadow() { +void Widget::updateDropdownsGeometry() { + const auto position = _volume->parentWidget()->mapFromGlobal( + _volumeToggle->mapToGlobal( + QPoint( + (_volumeToggle->width() - st::mediaPlayerVolumeSize.width()) / 2, + height()))); + const auto playerMargins = _volume->getMargin(); + _volume->move(position - QPoint(playerMargins.left(), playerMargins.top())); +} + +void Widget::hideShadowAndDropdowns() { _shadow->hide(); _playbackSlider->hide(); + if (!_volume->isHidden()) { + _volumeHidden = true; + _volume->hide(); + } } -QPoint Widget::getPositionForVolumeWidget() const { - auto x = _volumeToggle->x() + _rightControls->x(); - x += (_volumeToggle->width() - st::mediaPlayerVolumeSize.width()) / 2; - if (rtl()) x = width() - x - st::mediaPlayerVolumeSize.width(); - return QPoint(x, height()); -} - -void Widget::volumeWidgetCreated(Dropdown *widget) { - _volumeToggle->installEventFilter(widget); - widget->installEventFilter(this); -} - -QPoint Widget::getPositionForRepeatWidget() const { - auto x = _orderToggle->x() + _rightControls->x(); - x += (_orderToggle->width() - st::mediaPlayerVolumeSize.width()) / 2; - if (rtl()) x = width() - x - st::mediaPlayerVolumeSize.width(); - return QPoint(x, height()); -} - -void Widget::repeatWidgetCreated(Dropdown *widget) { - _orderToggle->installEventFilter(widget); +void Widget::raiseDropdowns() { + _volume->raise(); } Widget::~Widget() = default; @@ -502,6 +510,8 @@ void Widget::updateControlsGeometry() { updatePlayPrevNextPositions(); _playbackSlider->setGeometry(0, height() - st::mediaPlayerPlayback.fullWidth, width(), st::mediaPlayerPlayback.fullWidth); + + updateDropdownsGeometry(); } void Widget::updateControlsWrapGeometry() { diff --git a/Telegram/SourceFiles/media/player/media_player_widget.h b/Telegram/SourceFiles/media/player/media_player_widget.h index 84c022dc2..968144386 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.h +++ b/Telegram/SourceFiles/media/player/media_player_widget.h @@ -29,9 +29,9 @@ class PlaybackProgress; } // namespace Clip } // namespace Media -namespace Main { -class Session; -} // namespace Main +namespace Window { +class SessionController; +} // namespace Window namespace Media { namespace Player { @@ -43,20 +43,19 @@ struct TrackState; class Widget final : public Ui::RpWidget, private base::Subscriber { public: - Widget(QWidget *parent, not_null session); + Widget( + QWidget *parent, + not_null dropdownsParent, + not_null controller); void setCloseCallback(Fn callback); void setShowItemCallback(Fn)> callback); void stopAndClose(); void setShadowGeometryToLeft(int x, int y, int w, int h); - void showShadow(); - void hideShadow(); - - [[nodiscard]] QPoint getPositionForVolumeWidget() const; - void volumeWidgetCreated(Dropdown *widget); - - [[nodiscard]] QPoint getPositionForRepeatWidget() const; - void repeatWidgetCreated(Dropdown *widget); + void hideShadowAndDropdowns(); + void showShadowAndDropdowns(); + void updateDropdownsGeometry(); + void raiseDropdowns(); [[nodiscard]] rpl::producer togglePlaylistRequests() const { return _togglePlaylistRequests.events(); @@ -111,7 +110,7 @@ private: void updateTimeLabel(); void markOver(bool over); - const not_null _session; + const not_null _controller; crl::time _seekPositionMs = -1; crl::time _lastDurationMs = 0; @@ -133,6 +132,7 @@ private: bool _narrow = false; bool _over = false; bool _wontBeOver = false; + bool _volumeHidden = false; class PlayButton; class SpeedController; @@ -149,6 +149,7 @@ private: object_ptr _close; object_ptr _shadow = { nullptr }; object_ptr _playbackSlider; + object_ptr _volume; std::unique_ptr _playbackProgress; std::unique_ptr _speedController;