diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index bfd931857..d0605f9c9 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -813,6 +813,8 @@ 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/Resources/icons/player/player_repeat_one.png b/Telegram/Resources/icons/player/player_repeat_one.png new file mode 100644 index 000000000..8020d6df3 Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_one.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_one@2x.png b/Telegram/Resources/icons/player/player_repeat_one@2x.png new file mode 100644 index 000000000..cd137b24e Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_one@2x.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_one@3x.png b/Telegram/Resources/icons/player/player_repeat_one@3x.png new file mode 100644 index 000000000..ec01cba5c Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_one@3x.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_reverse.png b/Telegram/Resources/icons/player/player_repeat_reverse.png new file mode 100644 index 000000000..6928cf64d Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_reverse.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_reverse@2x.png b/Telegram/Resources/icons/player/player_repeat_reverse@2x.png new file mode 100644 index 000000000..6aa3d20bf Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_reverse@2x.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_reverse@3x.png b/Telegram/Resources/icons/player/player_repeat_reverse@3x.png new file mode 100644 index 000000000..2981d37eb Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_reverse@3x.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_shuffle.png b/Telegram/Resources/icons/player/player_repeat_shuffle.png new file mode 100644 index 000000000..dcb08429b Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_shuffle.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_shuffle@2x.png b/Telegram/Resources/icons/player/player_repeat_shuffle@2x.png new file mode 100644 index 000000000..0aa1c6aee Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_shuffle@2x.png differ diff --git a/Telegram/Resources/icons/player/player_repeat_shuffle@3x.png b/Telegram/Resources/icons/player/player_repeat_shuffle@3x.png new file mode 100644 index 000000000..5fe95448e Binary files /dev/null and b/Telegram/Resources/icons/player/player_repeat_shuffle@3x.png differ diff --git a/Telegram/Resources/icons/player/player_reverse.png b/Telegram/Resources/icons/player/player_reverse.png new file mode 100644 index 000000000..dea0be2df Binary files /dev/null and b/Telegram/Resources/icons/player/player_reverse.png differ diff --git a/Telegram/Resources/icons/player/player_reverse@2x.png b/Telegram/Resources/icons/player/player_reverse@2x.png new file mode 100644 index 000000000..d3af5baf6 Binary files /dev/null and b/Telegram/Resources/icons/player/player_reverse@2x.png differ diff --git a/Telegram/Resources/icons/player/player_reverse@3x.png b/Telegram/Resources/icons/player/player_reverse@3x.png new file mode 100644 index 000000000..9b01d7a1b Binary files /dev/null and b/Telegram/Resources/icons/player/player_reverse@3x.png differ diff --git a/Telegram/Resources/icons/player/player_shuffle.png b/Telegram/Resources/icons/player/player_shuffle.png new file mode 100644 index 000000000..662958889 Binary files /dev/null and b/Telegram/Resources/icons/player/player_shuffle.png differ diff --git a/Telegram/Resources/icons/player/player_shuffle@2x.png b/Telegram/Resources/icons/player/player_shuffle@2x.png new file mode 100644 index 000000000..54d44448f Binary files /dev/null and b/Telegram/Resources/icons/player/player_shuffle@2x.png differ diff --git a/Telegram/Resources/icons/player/player_shuffle@3x.png b/Telegram/Resources/icons/player/player_shuffle@3x.png new file mode 100644 index 000000000..14dc3efdd Binary files /dev/null and b/Telegram/Resources/icons/player/player_shuffle@3x.png differ diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index feeece08c..846dd8a58 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -81,6 +81,7 @@ 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" @@ -813,6 +814,7 @@ void MainWidget::closeBothPlayers() { _player->hide(anim::type::normal); } _playerVolume.destroyDelayed(); + _playerRepeat.destroyDelayed(); _playerPlaylist->hideIgnoringEnterEvents(); Media::Player::instance()->stop(AudioMsgId::Type::Voice); @@ -849,6 +851,11 @@ void MainWidget::createPlayer() { _playerVolume.data(), _controller); _player->entity()->volumeWidgetCreated(_playerVolume); + _playerRepeat.create(this); + Media::Player::PrepareRepeatDropdown( + _playerRepeat.data(), + _controller); + _player->entity()->repeatWidgetCreated(_playerRepeat); orderWidgets(); if (_a_show.animating()) { _player->show(anim::type::instant); @@ -883,6 +890,7 @@ void MainWidget::playerHeightUpdated() { 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(); } } @@ -1536,6 +1544,10 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation( if (playerVolumeVisible) { _playerVolume->hide(); } + auto playerRepeatVisible = _playerRepeat && !_playerRepeat->isHidden(); + if (playerRepeatVisible) { + _playerRepeat->hide(); + } auto playerPlaylistVisible = !_playerPlaylist->isHidden(); if (playerPlaylistVisible) { _playerPlaylist->hide(); @@ -1563,6 +1575,9 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation( if (playerVolumeVisible) { _playerVolume->show(); } + if (playerRepeatVisible) { + _playerRepeat->show(); + } if (playerPlaylistVisible) { _playerPlaylist->show(); } @@ -1822,6 +1837,9 @@ void MainWidget::orderWidgets() { if (_playerVolume) { _playerVolume->raise(); } + if (_playerRepeat) { + _playerRepeat->raise(); + } _sideShadow->raise(); if (_thirdShadow) { _thirdShadow->raise(); @@ -1855,6 +1873,10 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m if (playerVolumeVisible) { _playerVolume->hide(); } + auto playerRepeatVisible = _playerRepeat && !_playerRepeat->isHidden(); + if (playerRepeatVisible) { + _playerRepeat->hide(); + } auto playerPlaylistVisible = !_playerPlaylist->isHidden(); if (playerPlaylistVisible) { _playerPlaylist->hide(); @@ -1885,6 +1907,9 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m if (playerVolumeVisible) { _playerVolume->show(); } + if (playerRepeatVisible) { + _playerRepeat->show(); + } if (playerPlaylistVisible) { _playerPlaylist->show(); } @@ -2374,11 +2399,19 @@ void MainWidget::updateThirdColumnToCurrentChat( } void MainWidget::updateMediaPlayerPosition() { - if (_player && _playerVolume) { + 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) { @@ -2529,8 +2562,9 @@ void MainWidget::searchInChat(Dialogs::Key chat) { bool MainWidget::contentOverlapped(const QRect &globalRect) { return (_history->contentOverlapped(globalRect) - || _playerPlaylist->overlaps(globalRect) - || (_playerVolume && _playerVolume->overlaps(globalRect))); + || _playerPlaylist->overlaps(globalRect) + || (_playerVolume && _playerVolume->overlaps(globalRect))) + || (_playerRepeat && _playerRepeat->overlaps(globalRect)); } void MainWidget::activate() { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index beb97010d..91402ca22 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -368,6 +368,7 @@ 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.style b/Telegram/SourceFiles/media/player/media_player.style index ab91473f1..22a726790 100644 --- a/Telegram/SourceFiles/media/player/media_player.style +++ b/Telegram/SourceFiles/media/player/media_player.style @@ -67,10 +67,40 @@ mediaPlayerRepeatDisabledIcon: icon { mediaPlayerRepeatDisabledIconOver: icon { { "player/player_repeat", menuIconFgOver, point(9px, 11px)} }; -mediaPlayerRepeatDisabledRippleBg: windowBgOver; -mediaPlayerRepeatInactiveIcon: icon { - { "player/player_repeat", mediaPlayerInactiveFg, point(9px, 11px)} +mediaPlayerRepeatOneIcon: icon { + { "player/player_repeat_one", mediaPlayerActiveFg, point(9px, 11px)} }; +mediaPlayerRepeatOneDisabledIcon: icon { + { "player/player_repeat_one", menuIconFg, point(9px, 11px)} +}; +mediaPlayerRepeatOneDisabledIconOver: icon { + { "player/player_repeat_one", menuIconFgOver, point(9px, 11px)} +}; +mediaPlayerReverseIcon: icon { + { "player/player_reverse", mediaPlayerActiveFg, point(9px, 11px)} +}; +mediaPlayerReverseDisabledIcon: icon { + { "player/player_reverse", menuIconFg, point(9px, 11px)} +}; +mediaPlayerReverseDisabledIconOver: icon { + { "player/player_reverse", menuIconFgOver, point(9px, 11px)} +}; +mediaPlayerShuffleIcon: icon { + { "player/player_shuffle", mediaPlayerActiveFg, point(9px, 11px)} +}; +mediaPlayerShuffleDisabledIcon: icon { + { "player/player_shuffle", menuIconFg, point(9px, 11px)} +}; +mediaPlayerShuffleDisabledIconOver: icon { + { "player/player_shuffle", menuIconFgOver, point(9px, 11px)} +}; +mediaPlayerRepeatReverseIcon: icon { + { "player/player_repeat_reverse", mediaPlayerActiveFg, point(9px, 11px)} +}; +mediaPlayerRepeatShuffleIcon: icon { + { "player/player_repeat_shuffle", mediaPlayerActiveFg, point(9px, 11px)} +}; +mediaPlayerRepeatDisabledRippleBg: windowBgOver; mediaPlayerSpeedButton: IconButton { width: 31px; diff --git a/Telegram/SourceFiles/media/player/media_player_repeat_controls.cpp b/Telegram/SourceFiles/media/player/media_player_repeat_controls.cpp new file mode 100644 index 000000000..fe8bfc882 --- /dev/null +++ b/Telegram/SourceFiles/media/player/media_player_repeat_controls.cpp @@ -0,0 +1,53 @@ +/* +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 "ui/widgets/buttons.h" +#include "styles/style_media_player.h" + +namespace Media::Player { + +void PrepareRepeatDropdown( + not_null dropdown, + not_null controller) { + const auto makeButton = [&] { + const auto result = Ui::CreateChild( + dropdown.get(), + st::mediaPlayerRepeatButton); + result->show(); + return result; + }; + + const auto repeatOne = makeButton(); + const auto repeat = makeButton(); + const auto shuffle = makeButton(); + const auto reverse = makeButton(); + + repeatOne->setIconOverride(&st::mediaPlayerRepeatOneIcon); + shuffle->setIconOverride(&st::mediaPlayerShuffleIcon); + reverse->setIconOverride(&st::mediaPlayerReverseIcon); + + 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(repeat); + 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 new file mode 100644 index 000000000..ae3f31de9 --- /dev/null +++ b/Telegram/SourceFiles/media/player/media_player_repeat_controls.h @@ -0,0 +1,22 @@ +/* +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 Window { +class SessionController; +} // namespace Window + +namespace Media::Player { + +class Dropdown; + +void PrepareRepeatDropdown( + not_null dropdown, + not_null controller); + +} // namespace Media::Player diff --git a/Telegram/SourceFiles/media/player/media_player_widget.cpp b/Telegram/SourceFiles/media/player/media_player_widget.cpp index dee206a2b..a28481de8 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.cpp +++ b/Telegram/SourceFiles/media/player/media_player_widget.cpp @@ -398,6 +398,17 @@ void Widget::volumeWidgetCreated(Dropdown *widget) { _volumeToggle->installEventFilter(widget); } +QPoint Widget::getPositionForRepeatWidget() const { + auto x = _repeatToggle->x(); + x += (_repeatToggle->width() - st::mediaPlayerVolumeSize.width()) / 2; + if (rtl()) x = width() - x - st::mediaPlayerVolumeSize.width(); + return QPoint(x, height()); +} + +void Widget::repeatWidgetCreated(Dropdown *widget) { + _repeatToggle->installEventFilter(widget); +} + Widget::~Widget() = default; void Widget::handleSeekProgress(float64 progress) { diff --git a/Telegram/SourceFiles/media/player/media_player_widget.h b/Telegram/SourceFiles/media/player/media_player_widget.h index 0373bec7b..e918835e9 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.h +++ b/Telegram/SourceFiles/media/player/media_player_widget.h @@ -53,6 +53,9 @@ public: QPoint getPositionForVolumeWidget() const; void volumeWidgetCreated(Dropdown *widget); + QPoint getPositionForRepeatWidget() const; + void repeatWidgetCreated(Dropdown *widget); + ~Widget(); protected: