mirror of https://github.com/procxx/kepka.git
Media player vector button added to new audio player cover.
This commit is contained in:
parent
e616c39608
commit
3c8fb5f1f6
Binary file not shown.
Before Width: | Height: | Size: 118 B |
Binary file not shown.
Before Width: | Height: | Size: 156 B |
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
|
@ -22,16 +22,42 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
using "basic.style";
|
||||
using "ui/widgets/widgets.style";
|
||||
|
||||
MediaPlayerButton {
|
||||
playPosition: point;
|
||||
playOuter: size;
|
||||
pausePosition: point;
|
||||
pauseOuter: size;
|
||||
pauseStroke: pixels;
|
||||
cancelPosition: point;
|
||||
cancelOuter: size;
|
||||
cancelStroke: pixels;
|
||||
}
|
||||
|
||||
mediaPlayerTitleButtonSize: size(titleHeight, titleHeight);
|
||||
mediaPlayerTitleButtonInner: size(25px, 25px);
|
||||
mediaPlayerTitleButtonInnerBg: #49708f;
|
||||
mediaPlayerTitleButtonTransformDuration: 200;
|
||||
mediaPlayerButtonTransformDuration: 200;
|
||||
|
||||
mediaPlayerTitleButtonPauseLeft: 8px;
|
||||
mediaPlayerTitleButtonPauseTop: 8px;
|
||||
mediaPlayerTitleButtonPauseStroke: 3px;
|
||||
mediaPlayerTitleButtonPlayLeft: 10px;
|
||||
mediaPlayerTitleButtonPlayTop: 7px;
|
||||
mediaPlayerTitleButton: MediaPlayerButton {
|
||||
playPosition: point(10px, 7px);
|
||||
playOuter: size(29px, 25px);
|
||||
pausePosition: point(8px, 8px);
|
||||
pauseOuter: size(25px, 25px);
|
||||
pauseStroke: 3px;
|
||||
cancelPosition: point(8px, 8px);
|
||||
cancelOuter: size(25px, 25px);
|
||||
cancelStroke: 2px;
|
||||
}
|
||||
mediaPlayerButton: MediaPlayerButton {
|
||||
playPosition: point(3px, 0px);
|
||||
playOuter: size(22px, 18px);
|
||||
pausePosition: point(1px, 1px);
|
||||
pauseOuter: size(16px, 18px);
|
||||
pauseStroke: 5px;
|
||||
cancelPosition: point(0px, 1px);
|
||||
cancelOuter: size(16px, 18px);
|
||||
cancelStroke: 3px;
|
||||
}
|
||||
|
||||
mediaPlayerMarginLeft: 10px;
|
||||
mediaPlayerMarginBottom: 10px;
|
||||
|
@ -41,35 +67,28 @@ mediaPlayerCoverHeight: 102px;
|
|||
mediaPlayerActiveFg: #54b5ed;
|
||||
mediaPlayerInactiveFg: #dfebf2;
|
||||
|
||||
mediaPlayerPlayButton: IconButton {
|
||||
width: 32px;
|
||||
mediaPlayerButtonSize: size(32px, 32px);
|
||||
mediaPlayerButtonPosition: point(8px, 7px);
|
||||
|
||||
mediaPlayerRepeatButton: IconButton {
|
||||
width: 31px;
|
||||
height: 32px;
|
||||
|
||||
opacity: 1.;
|
||||
overOpacity: 1.;
|
||||
|
||||
icon: icon {
|
||||
{ "player_play", mediaPlayerActiveFg, point(6px, 7px) },
|
||||
{ "player_repeat", mediaPlayerActiveFg, point(9px, 9px)}
|
||||
};
|
||||
iconPosition: point(0px, 0px);
|
||||
downIconPosition: point(0px, 0px);
|
||||
|
||||
duration: 0;
|
||||
}
|
||||
mediaPlayerPauseIcon: icon {
|
||||
{ "player_pause", mediaPlayerActiveFg, point(9px, 8px) }
|
||||
};
|
||||
|
||||
mediaPlayerRepeatButton: IconButton(mediaPlayerPlayButton) {
|
||||
width: 31px;
|
||||
icon: icon {
|
||||
{ "player_repeat", mediaPlayerActiveFg, point(9px, 9px)}
|
||||
};
|
||||
}
|
||||
mediaPlayerRepeatDisabledIcon: icon {
|
||||
{ "player_repeat", mediaPlayerInactiveFg, point(9px, 9px)}
|
||||
};
|
||||
mediaPlayerPreviousButton: IconButton(mediaPlayerPlayButton) {
|
||||
mediaPlayerPreviousButton: IconButton(mediaPlayerRepeatButton) {
|
||||
width: 37px;
|
||||
icon: icon {
|
||||
{ "player_previous", mediaPlayerActiveFg, point(10px, 10px) },
|
||||
|
|
|
@ -21,84 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "stdafx.h"
|
||||
#include "media/player/media_player_button.h"
|
||||
|
||||
#include "styles/style_media_player.h"
|
||||
#include "media/media_audio.h"
|
||||
#include "media/player/media_player_instance.h"
|
||||
#include "shortcuts.h"
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
TitleButton::TitleButton(QWidget *parent) : Button(parent) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
resize(st::mediaPlayerTitleButtonSize);
|
||||
|
||||
setClickedCallback([this]() {
|
||||
if (exists()) {
|
||||
if (_showPause) {
|
||||
instance()->pause();
|
||||
} else {
|
||||
instance()->play();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (exists()) {
|
||||
subscribe(instance()->updatedNotifier(), [this](const UpdatedEvent &e) {
|
||||
updatePauseState();
|
||||
});
|
||||
updatePauseState();
|
||||
finishIconTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void TitleButton::updatePauseState() {
|
||||
AudioMsgId playing;
|
||||
auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
|
||||
auto stopped = ((playbackState.state & AudioPlayerStoppedMask) || playbackState.state == AudioPlayerFinishing);
|
||||
auto showPause = !stopped && (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
|
||||
if (exists() && instance()->isSeeking()) {
|
||||
showPause = true;
|
||||
}
|
||||
setShowPause(showPause);
|
||||
}
|
||||
|
||||
void TitleButton::setShowPause(bool showPause) {
|
||||
if (_showPause != showPause) {
|
||||
_showPause = showPause;
|
||||
_iconTransformToPause.start([this] { update(); }, _showPause ? 0. : 1., _showPause ? 1. : 0., st::mediaPlayerTitleButtonTransformDuration);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void TitleButton::finishIconTransform() {
|
||||
if (_iconTransformToPause.animating(getms())) {
|
||||
_iconTransformToPause.finish();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void TitleButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
p.fillRect(rect(), st::titleBg);
|
||||
|
||||
p.setBrush(st::mediaPlayerTitleButtonInnerBg);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
p.drawEllipse((width() - st::mediaPlayerTitleButtonInner.width()) / 2, (height() - st::mediaPlayerTitleButtonInner.height()) / 2, st::mediaPlayerTitleButtonInner.width(), st::mediaPlayerTitleButtonInner.height());
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
|
||||
paintIcon(p);
|
||||
}
|
||||
|
||||
void TitleButton::onStateChanged(int oldState, ButtonStateChangeSource source) {
|
||||
if ((oldState & StateOver) != (_state & StateOver)) {
|
||||
auto over = (_state & StateOver);
|
||||
_iconFg.start([this] { update(); }, over ? st::titleButtonFg->c : st::titleButtonActiveFg->c, over ? st::titleButtonActiveFg->c : st::titleButtonFg->c, st::titleButtonDuration);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <int N>
|
||||
|
@ -119,65 +43,147 @@ QPainterPath interpolatePaths(QPointF (&from)[N], QPointF (&to)[N], float64 k) {
|
|||
|
||||
} // namespace
|
||||
|
||||
void TitleButton::paintIcon(Painter &p) {
|
||||
auto over = (_state & StateOver);
|
||||
auto icon = _iconFg.current(getms(), over ? st::titleButtonActiveFg->c : st::titleButtonFg->c);
|
||||
auto showPause = _iconTransformToPause.current(getms(), _showPause ? 1. : 0.);
|
||||
auto pauseWidth = st::mediaPlayerTitleButtonInner.width() - 2 * st::mediaPlayerTitleButtonPauseLeft;
|
||||
auto playWidth = pauseWidth;
|
||||
auto pauseHeight = st::mediaPlayerTitleButtonInner.height() - 2 * st::mediaPlayerTitleButtonPauseTop;
|
||||
auto playHeight = st::mediaPlayerTitleButtonInner.height() - 2 * st::mediaPlayerTitleButtonPlayTop;
|
||||
auto pauseStroke = st::mediaPlayerTitleButtonPauseStroke;
|
||||
PlayButtonLayout::PlayButtonLayout(const style::MediaPlayerButton &st, State state, UpdateCallback &&callback)
|
||||
: _st(st)
|
||||
, _state(state)
|
||||
, _oldState(state)
|
||||
, _nextState(state)
|
||||
, _callback(std_::move(callback)) {
|
||||
}
|
||||
|
||||
qreal left = (width() - st::mediaPlayerTitleButtonInner.width()) / 2;
|
||||
qreal top = (height() - st::mediaPlayerTitleButtonInner.height()) / 2;
|
||||
void PlayButtonLayout::setState(State state) {
|
||||
if (_nextState == state) return;
|
||||
|
||||
auto pauseLeft = left + st::mediaPlayerTitleButtonPauseLeft;
|
||||
auto playLeft = left + st::mediaPlayerTitleButtonPlayLeft;
|
||||
auto pauseTop = top + st::mediaPlayerTitleButtonPauseTop;
|
||||
auto playTop = top + st::mediaPlayerTitleButtonPlayTop;
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
if (showPause == 0.) {
|
||||
QPainterPath pathPlay;
|
||||
pathPlay.moveTo(playLeft, playTop);
|
||||
pathPlay.lineTo(playLeft + playWidth, playTop + (playHeight / 2.));
|
||||
pathPlay.lineTo(playLeft, playTop + playHeight);
|
||||
pathPlay.lineTo(playLeft, playTop);
|
||||
p.fillPath(pathPlay, icon);
|
||||
} else {
|
||||
QPointF pathLeftPause[] = {
|
||||
{ pauseLeft, pauseTop },
|
||||
{ pauseLeft + pauseStroke, pauseTop },
|
||||
{ pauseLeft + pauseStroke, pauseTop + pauseHeight },
|
||||
{ pauseLeft, pauseTop + pauseHeight },
|
||||
};
|
||||
QPointF pathLeftPlay[] = {
|
||||
{ playLeft, playTop },
|
||||
{ playLeft + (playWidth / 2.), playTop + (playHeight / 4.) },
|
||||
{ playLeft + (playWidth / 2.), playTop + (3 * playHeight / 4.) },
|
||||
{ playLeft, playTop + playHeight },
|
||||
};
|
||||
p.fillPath(interpolatePaths(pathLeftPause, pathLeftPlay, showPause), icon);
|
||||
|
||||
QPointF pathRightPause[] = {
|
||||
{ pauseLeft + pauseWidth - pauseStroke, pauseTop },
|
||||
{ pauseLeft + pauseWidth, pauseTop },
|
||||
{ pauseLeft + pauseWidth, pauseTop + pauseHeight },
|
||||
{ pauseLeft + pauseWidth - pauseStroke, pauseTop + pauseHeight },
|
||||
};
|
||||
QPointF pathRightPlay[] = {
|
||||
{ playLeft + (playWidth / 2.), playTop + (playHeight / 4.) },
|
||||
{ playLeft + playWidth, playTop + (playHeight / 2.) },
|
||||
{ playLeft + playWidth, playTop + (playHeight / 2.) },
|
||||
{ playLeft + (playWidth / 2.), playTop + (3 * playHeight / 4.) },
|
||||
};
|
||||
p.fillPath(interpolatePaths(pathRightPause, pathRightPlay, showPause), icon);
|
||||
_nextState = state;
|
||||
if (!_transformProgress.animating(getms())) {
|
||||
_oldState = _state;
|
||||
_state = _nextState;
|
||||
_transformBackward = false;
|
||||
if (_state != _oldState) startTransform(0., 1.);
|
||||
} else if (_oldState == _nextState) {
|
||||
qSwap(_oldState, _state);
|
||||
startTransform(_transformBackward ? 0. : 1., _transformBackward ? 1. : 0.);
|
||||
_transformBackward = !_transformBackward;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayButtonLayout::paint(Painter &p, const QBrush &brush) {
|
||||
if (_transformProgress.animating(getms())) {
|
||||
auto from = _oldState, to = _state;
|
||||
auto backward = _transformBackward;
|
||||
auto progress = _transformProgress.current(1.);
|
||||
if (from == State::Cancel || (from == State::Pause && to == State::Play)) {
|
||||
qSwap(from, to);
|
||||
backward = !backward;
|
||||
}
|
||||
if (backward) progress = 1. - progress;
|
||||
|
||||
t_assert(from != to);
|
||||
if (from == State::Play) {
|
||||
if (to == State::Pause) {
|
||||
paintPlayToPause(p, brush, progress);
|
||||
} else {
|
||||
t_assert(to == State::Cancel);
|
||||
paintPlayToCancel(p, brush, progress);
|
||||
}
|
||||
} else {
|
||||
t_assert(from == State::Pause && to == State::Cancel);
|
||||
paintPauseToCancel(p, brush, progress);
|
||||
}
|
||||
} else {
|
||||
switch (_state) {
|
||||
case State::Play: paintPlay(p, brush); break;
|
||||
case State::Pause: paintPlayToPause(p, brush, 1.); break;
|
||||
case State::Cancel: paintPlayToCancel(p, brush, 1.); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlayButtonLayout::paintPlay(Painter &p, const QBrush &brush) {
|
||||
auto playLeft = 0. + _st.playPosition.x();
|
||||
auto playTop = 0. + _st.playPosition.y();
|
||||
auto playWidth = _st.playOuter.width() - 2 * playLeft;
|
||||
auto playHeight = _st.playOuter.height() - 2 * playTop;
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
|
||||
QPainterPath pathPlay;
|
||||
pathPlay.moveTo(playLeft, playTop);
|
||||
pathPlay.lineTo(playLeft + playWidth, playTop + (playHeight / 2.));
|
||||
pathPlay.lineTo(playLeft, playTop + playHeight);
|
||||
pathPlay.lineTo(playLeft, playTop);
|
||||
p.fillPath(pathPlay, brush);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
}
|
||||
|
||||
void PlayButtonLayout::paintPlayToPause(Painter &p, const QBrush &brush, float64 progress) {
|
||||
auto playLeft = 0. + _st.playPosition.x();
|
||||
auto playTop = 0. + _st.playPosition.y();
|
||||
auto playWidth = _st.playOuter.width() - 2 * playLeft;
|
||||
auto playHeight = _st.playOuter.height() - 2 * playTop;
|
||||
|
||||
auto pauseLeft = 0. + _st.pausePosition.x();
|
||||
auto pauseTop = 0. + _st.pausePosition.y();
|
||||
auto pauseWidth = _st.pauseOuter.width() - 2 * pauseLeft;
|
||||
auto pauseHeight = _st.pauseOuter.height() - 2 * pauseTop;
|
||||
auto pauseStroke = 0. + _st.pauseStroke;
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
|
||||
QPointF pathLeftPause[] = {
|
||||
{ pauseLeft, pauseTop },
|
||||
{ pauseLeft + pauseStroke, pauseTop },
|
||||
{ pauseLeft + pauseStroke, pauseTop + pauseHeight },
|
||||
{ pauseLeft, pauseTop + pauseHeight },
|
||||
};
|
||||
QPointF pathLeftPlay[] = {
|
||||
{ playLeft, playTop },
|
||||
{ playLeft + (playWidth / 2.), playTop + (playHeight / 4.) },
|
||||
{ playLeft + (playWidth / 2.), playTop + (3 * playHeight / 4.) },
|
||||
{ playLeft, playTop + playHeight },
|
||||
};
|
||||
p.fillPath(interpolatePaths(pathLeftPause, pathLeftPlay, progress), brush);
|
||||
|
||||
QPointF pathRightPause[] = {
|
||||
{ pauseLeft + pauseWidth - pauseStroke, pauseTop },
|
||||
{ pauseLeft + pauseWidth, pauseTop },
|
||||
{ pauseLeft + pauseWidth, pauseTop + pauseHeight },
|
||||
{ pauseLeft + pauseWidth - pauseStroke, pauseTop + pauseHeight },
|
||||
};
|
||||
QPointF pathRightPlay[] = {
|
||||
{ playLeft + (playWidth / 2.), playTop + (playHeight / 4.) },
|
||||
{ playLeft + playWidth, playTop + (playHeight / 2.) },
|
||||
{ playLeft + playWidth, playTop + (playHeight / 2.) },
|
||||
{ playLeft + (playWidth / 2.), playTop + (3 * playHeight / 4.) },
|
||||
};
|
||||
p.fillPath(interpolatePaths(pathRightPause, pathRightPlay, progress), brush);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
}
|
||||
|
||||
void PlayButtonLayout::paintPlayToCancel(Painter &p, const QBrush &brush, float64 progress) {
|
||||
|
||||
}
|
||||
|
||||
void PlayButtonLayout::paintPauseToCancel(Painter &p, const QBrush &brush, float64 progress) {
|
||||
|
||||
}
|
||||
|
||||
void PlayButtonLayout::animationCallback() {
|
||||
if (!_transformProgress.animating()) {
|
||||
auto finalState = _nextState;
|
||||
_nextState = _state;
|
||||
setState(finalState);
|
||||
}
|
||||
_callback();
|
||||
}
|
||||
|
||||
void PlayButtonLayout::startTransform(float64 from, float64 to) {
|
||||
_transformProgress.start([this] { animationCallback(); }, from, to, st::mediaPlayerButtonTransformDuration);
|
||||
}
|
||||
|
||||
} // namespace Player
|
||||
} // namespace Media
|
||||
|
|
|
@ -21,30 +21,40 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#pragma once
|
||||
|
||||
#include "ui/button.h"
|
||||
#include "styles/style_media_player.h"
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
class TitleButton : public Button, private base::Subscriber {
|
||||
class PlayButtonLayout {
|
||||
public:
|
||||
TitleButton(QWidget *parent);
|
||||
enum class State {
|
||||
Play,
|
||||
Pause,
|
||||
Cancel,
|
||||
};
|
||||
using UpdateCallback = FloatAnimation::Callback;
|
||||
PlayButtonLayout(const style::MediaPlayerButton &st, State state, UpdateCallback &&callback);
|
||||
|
||||
void updatePauseState();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void onStateChanged(int oldState, ButtonStateChangeSource source) override;
|
||||
void setState(State state);
|
||||
void paint(Painter &p, const QBrush &brush);
|
||||
|
||||
private:
|
||||
void paintIcon(Painter &p);
|
||||
void animationCallback();
|
||||
void startTransform(float64 from, float64 to);
|
||||
|
||||
void setShowPause(bool showPause);
|
||||
void finishIconTransform();
|
||||
void paintPlay(Painter &p, const QBrush &brush);
|
||||
void paintPlayToPause(Painter &p, const QBrush &brush, float64 progress);
|
||||
void paintPlayToCancel(Painter &p, const QBrush &brush, float64 progress);
|
||||
void paintPauseToCancel(Painter &p, const QBrush &brush, float64 progress);
|
||||
|
||||
bool _showPause = true;
|
||||
FloatAnimation _iconTransformToPause;
|
||||
ColorAnimation _iconFg;
|
||||
const style::MediaPlayerButton &_st;
|
||||
|
||||
State _state, _oldState, _nextState;
|
||||
FloatAnimation _transformProgress;
|
||||
bool _transformBackward = false;
|
||||
|
||||
UpdateCallback _callback;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "ui/buttons/icon_button.h"
|
||||
#include "media/media_audio.h"
|
||||
#include "media/view/media_clip_playback.h"
|
||||
#include "media/player/media_player_button.h"
|
||||
#include "media/player/media_player_instance.h"
|
||||
#include "media/player/media_player_volume_controller.h"
|
||||
#include "styles/style_media_player.h"
|
||||
|
@ -35,11 +36,42 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
class CoverWidget::PlayButton : public Button {
|
||||
public:
|
||||
PlayButton(QWidget *parent);
|
||||
|
||||
using State = PlayButtonLayout::State;
|
||||
void setState(State state);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
PlayButtonLayout _layout;
|
||||
|
||||
};
|
||||
|
||||
CoverWidget::PlayButton::PlayButton(QWidget *parent) : Button(parent)
|
||||
, _layout(st::mediaPlayerButton, State::Pause, [this] { update(); }) {
|
||||
resize(st::mediaPlayerButtonSize);
|
||||
}
|
||||
|
||||
void CoverWidget::PlayButton::setState(State state) {
|
||||
_layout.setState(state);
|
||||
}
|
||||
|
||||
void CoverWidget::PlayButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
p.translate(st::mediaPlayerButtonPosition.x(), st::mediaPlayerButtonPosition.y());
|
||||
_layout.paint(p, st::mediaPlayerActiveFg);
|
||||
}
|
||||
|
||||
CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
||||
, _nameLabel(this, st::mediaPlayerName)
|
||||
, _timeLabel(this, st::mediaPlayerTime)
|
||||
, _playback(this, st::mediaPlayerPlayback)
|
||||
, _playPause(this, st::mediaPlayerPlayButton)
|
||||
, _playPause(this)
|
||||
, _volumeController(this)
|
||||
, _repeatTrack(this, st::mediaPlayerRepeatButton) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
|
@ -51,9 +83,7 @@ CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
|||
handleSeekFinished(value);
|
||||
});
|
||||
|
||||
if (_showPause) {
|
||||
_playPause->setIcon(&st::mediaPlayerPauseIcon);
|
||||
}
|
||||
_playPause->setState(_showPause ? PlayButton::State::Pause : PlayButton::State::Play);
|
||||
_playPause->setClickedCallback([this]() {
|
||||
if (exists()) {
|
||||
if (_showPause) {
|
||||
|
@ -173,7 +203,7 @@ void CoverWidget::handleSongUpdate(const UpdatedEvent &e) {
|
|||
}
|
||||
if (_showPause != showPause) {
|
||||
_showPause = showPause;
|
||||
_playPause->setIcon(_showPause ? &st::mediaPlayerPauseIcon : nullptr);
|
||||
_playPause->setState(showPause ? PlayButton::State::Pause : PlayButton::State::Play);
|
||||
}
|
||||
|
||||
updateTimeText(audioId, playbackState);
|
||||
|
|
|
@ -69,11 +69,12 @@ private:
|
|||
int64 _lastDurationMs = 0;
|
||||
QString _time;
|
||||
|
||||
class PlayButton;
|
||||
ChildWidget<FlatLabel> _nameLabel;
|
||||
ChildWidget<Ui::LabelSimple> _timeLabel;
|
||||
ChildWidget<Clip::Playback> _playback;
|
||||
ChildWidget<Ui::IconButton> _previousTrack = { nullptr };
|
||||
ChildWidget<Ui::IconButton> _playPause;
|
||||
ChildWidget<PlayButton> _playPause;
|
||||
ChildWidget<Ui::IconButton> _nextTrack = { nullptr };
|
||||
ChildWidget<VolumeController> _volumeController;
|
||||
ChildWidget<Ui::IconButton> _repeatTrack;
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "media/player/media_player_title_button.h"
|
||||
|
||||
#include "media/player/media_player_button.h"
|
||||
#include "media/media_audio.h"
|
||||
#include "media/player/media_player_instance.h"
|
||||
#include "shortcuts.h"
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
using State = PlayButtonLayout::State;
|
||||
|
||||
TitleButton::TitleButton(QWidget *parent) : Button(parent)
|
||||
, _layout(std_::make_unique<PlayButtonLayout>(st::mediaPlayerTitleButton, State::Pause, [this] { update(); })) {
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
resize(st::mediaPlayerTitleButtonSize);
|
||||
|
||||
setClickedCallback([this]() {
|
||||
if (exists()) {
|
||||
if (_showPause) {
|
||||
instance()->pause();
|
||||
} else {
|
||||
instance()->play();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (exists()) {
|
||||
subscribe(instance()->updatedNotifier(), [this](const UpdatedEvent &e) {
|
||||
updatePauseState();
|
||||
});
|
||||
updatePauseState();
|
||||
}
|
||||
}
|
||||
|
||||
void TitleButton::updatePauseState() {
|
||||
AudioMsgId playing;
|
||||
auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
|
||||
auto stopped = ((playbackState.state & AudioPlayerStoppedMask) || playbackState.state == AudioPlayerFinishing);
|
||||
auto showPause = !stopped && (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
|
||||
if (exists() && instance()->isSeeking()) {
|
||||
showPause = true;
|
||||
}
|
||||
setShowPause(showPause);
|
||||
}
|
||||
|
||||
void TitleButton::setShowPause(bool showPause) {
|
||||
if (_showPause != showPause) {
|
||||
_showPause = showPause;
|
||||
_layout->setState(_showPause ? PlayButtonLayout::State::Pause : PlayButtonLayout::State::Play);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void TitleButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
p.fillRect(rect(), st::titleBg);
|
||||
|
||||
p.setBrush(st::mediaPlayerTitleButtonInnerBg);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
p.drawEllipse((width() - st::mediaPlayerTitleButtonInner.width()) / 2, (height() - st::mediaPlayerTitleButtonInner.height()) / 2, st::mediaPlayerTitleButtonInner.width(), st::mediaPlayerTitleButtonInner.height());
|
||||
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||
|
||||
paintIcon(p);
|
||||
}
|
||||
|
||||
void TitleButton::onStateChanged(int oldState, ButtonStateChangeSource source) {
|
||||
if ((oldState & StateOver) != (_state & StateOver)) {
|
||||
auto over = (_state & StateOver);
|
||||
_iconFg.start([this] { update(); }, over ? st::titleButtonFg->c : st::titleButtonActiveFg->c, over ? st::titleButtonActiveFg->c : st::titleButtonFg->c, st::titleButtonDuration);
|
||||
}
|
||||
}
|
||||
|
||||
void TitleButton::paintIcon(Painter &p) {
|
||||
auto over = (_state & StateOver);
|
||||
auto icon = _iconFg.current(getms(), over ? st::titleButtonActiveFg->c : st::titleButtonFg->c);
|
||||
|
||||
auto left = (width() - st::mediaPlayerTitleButtonInner.width()) / 2;
|
||||
auto top = (height() - st::mediaPlayerTitleButtonInner.height()) / 2;
|
||||
p.translate(left, top);
|
||||
|
||||
_layout->paint(p, icon);
|
||||
}
|
||||
|
||||
TitleButton::~TitleButton() = default;
|
||||
|
||||
} // namespace Player
|
||||
} // namespace Media
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ui/button.h"
|
||||
|
||||
namespace Media {
|
||||
namespace Player {
|
||||
|
||||
class PlayButtonLayout;
|
||||
|
||||
class TitleButton : public Button, private base::Subscriber {
|
||||
public:
|
||||
TitleButton(QWidget *parent);
|
||||
|
||||
void updatePauseState();
|
||||
|
||||
~TitleButton();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
void onStateChanged(int oldState, ButtonStateChangeSource source) override;
|
||||
|
||||
private:
|
||||
void paintIcon(Painter &p);
|
||||
void setShowPause(bool showPause);
|
||||
|
||||
bool _showPause = true;
|
||||
std_::unique_ptr<PlayButtonLayout> _layout;
|
||||
ColorAnimation _iconFg;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Clip
|
||||
} // namespace Media
|
|
@ -28,7 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
|||
#include "boxes/contactsbox.h"
|
||||
#include "boxes/aboutbox.h"
|
||||
#include "media/media_audio.h"
|
||||
#include "media/player/media_player_button.h"
|
||||
#include "media/player/media_player_title_button.h"
|
||||
#include "media/player/media_player_widget.h"
|
||||
#include "media/player/media_player_instance.h"
|
||||
|
||||
|
|
|
@ -268,6 +268,8 @@
|
|||
'<(src_loc)/media/player/media_player_instance.h',
|
||||
'<(src_loc)/media/player/media_player_list.cpp',
|
||||
'<(src_loc)/media/player/media_player_list.h',
|
||||
'<(src_loc)/media/player/media_player_title_button.cpp',
|
||||
'<(src_loc)/media/player/media_player_title_button.h',
|
||||
'<(src_loc)/media/player/media_player_volume_controller.cpp',
|
||||
'<(src_loc)/media/player/media_player_volume_controller.h',
|
||||
'<(src_loc)/media/player/media_player_widget.cpp',
|
||||
|
|
Loading…
Reference in New Issue