Add a second dropdown with playback mode controls.
|
@ -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
|
||||
|
|
BIN
Telegram/Resources/icons/player/player_repeat_one.png
Normal file
After Width: | Height: | Size: 262 B |
BIN
Telegram/Resources/icons/player/player_repeat_one@2x.png
Normal file
After Width: | Height: | Size: 304 B |
BIN
Telegram/Resources/icons/player/player_repeat_one@3x.png
Normal file
After Width: | Height: | Size: 377 B |
BIN
Telegram/Resources/icons/player/player_repeat_reverse.png
Normal file
After Width: | Height: | Size: 246 B |
BIN
Telegram/Resources/icons/player/player_repeat_reverse@2x.png
Normal file
After Width: | Height: | Size: 301 B |
BIN
Telegram/Resources/icons/player/player_repeat_reverse@3x.png
Normal file
After Width: | Height: | Size: 371 B |
BIN
Telegram/Resources/icons/player/player_repeat_shuffle.png
Normal file
After Width: | Height: | Size: 269 B |
BIN
Telegram/Resources/icons/player/player_repeat_shuffle@2x.png
Normal file
After Width: | Height: | Size: 290 B |
BIN
Telegram/Resources/icons/player/player_repeat_shuffle@3x.png
Normal file
After Width: | Height: | Size: 387 B |
BIN
Telegram/Resources/icons/player/player_reverse.png
Normal file
After Width: | Height: | Size: 198 B |
BIN
Telegram/Resources/icons/player/player_reverse@2x.png
Normal file
After Width: | Height: | Size: 212 B |
BIN
Telegram/Resources/icons/player/player_reverse@3x.png
Normal file
After Width: | Height: | Size: 298 B |
BIN
Telegram/Resources/icons/player/player_shuffle.png
Normal file
After Width: | Height: | Size: 346 B |
BIN
Telegram/Resources/icons/player/player_shuffle@2x.png
Normal file
After Width: | Height: | Size: 537 B |
BIN
Telegram/Resources/icons/player/player_shuffle@3x.png
Normal file
After Width: | Height: | Size: 761 B |
|
@ -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() {
|
||||
|
|
|
@ -368,6 +368,7 @@ private:
|
|||
object_ptr<Window::TopBarWrapWidget<Media::Player::Widget>> _player
|
||||
= { nullptr };
|
||||
object_ptr<Media::Player::Dropdown> _playerVolume = { nullptr };
|
||||
object_ptr<Media::Player::Dropdown> _playerRepeat = { nullptr };
|
||||
object_ptr<Media::Player::Panel> _playerPlaylist;
|
||||
bool _playerUsingPanel = false;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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*> dropdown,
|
||||
not_null<Window::SessionController*> controller) {
|
||||
const auto makeButton = [&] {
|
||||
const auto result = Ui::CreateChild<Ui::IconButton>(
|
||||
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
|
|
@ -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*> dropdown,
|
||||
not_null<Window::SessionController*> controller);
|
||||
|
||||
} // namespace Media::Player
|
|
@ -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) {
|
||||
|
|
|
@ -53,6 +53,9 @@ public:
|
|||
QPoint getPositionForVolumeWidget() const;
|
||||
void volumeWidgetCreated(Dropdown *widget);
|
||||
|
||||
QPoint getPositionForRepeatWidget() const;
|
||||
void repeatWidgetCreated(Dropdown *widget);
|
||||
|
||||
~Widget();
|
||||
|
||||
protected:
|
||||
|
|