mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Make Media::Clip::Playback independent of slider.
Now animation of the playback progress is processed inside the Media::Clip::Playback and the sliders just hold plain float64 value.
This commit is contained in:
parent
8446fa5a4d
commit
87ff770020
12 changed files with 149 additions and 116 deletions
|
@ -72,7 +72,8 @@ CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _nameLabel(this, st::mediaPlayerName)
|
, _nameLabel(this, st::mediaPlayerName)
|
||||||
, _timeLabel(this, st::mediaPlayerTime)
|
, _timeLabel(this, st::mediaPlayerTime)
|
||||||
, _close(this, st::mediaPlayerPanelClose)
|
, _close(this, st::mediaPlayerPanelClose)
|
||||||
, _playback(std::make_unique<Clip::Playback>(new Ui::MediaSlider(this, st::mediaPlayerPanelPlayback)))
|
, _playbackSlider(this, st::mediaPlayerPanelPlayback)
|
||||||
|
, _playback(std::make_unique<Clip::Playback>())
|
||||||
, _playPause(this)
|
, _playPause(this)
|
||||||
, _volumeToggle(this, st::mediaPlayerVolumeToggle)
|
, _volumeToggle(this, st::mediaPlayerVolumeToggle)
|
||||||
, _volumeController(this)
|
, _volumeController(this)
|
||||||
|
@ -86,11 +87,19 @@ CoverWidget::CoverWidget(QWidget *parent) : TWidget(parent)
|
||||||
_timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
|
||||||
_playback->setChangeProgressCallback([this](float64 value) {
|
_playback->setInLoadingStateChangedCallback([this](bool loading) {
|
||||||
handleSeekProgress(value);
|
_playbackSlider->setDisabled(loading);
|
||||||
});
|
});
|
||||||
_playback->setChangeFinishedCallback([this](float64 value) {
|
_playback->setValueChangedCallback([this](float64 value) {
|
||||||
|
_playbackSlider->setValue(value);
|
||||||
|
});
|
||||||
|
_playbackSlider->setChangeProgressCallback([this](float64 value) {
|
||||||
|
handleSeekProgress(value);
|
||||||
|
_playback->setValue(value, false);
|
||||||
|
});
|
||||||
|
_playbackSlider->setChangeFinishedCallback([this](float64 value) {
|
||||||
handleSeekFinished(value);
|
handleSeekFinished(value);
|
||||||
|
_playback->setValue(value, false);
|
||||||
});
|
});
|
||||||
_playPause->setClickedCallback([this] {
|
_playPause->setClickedCallback([this] {
|
||||||
instance()->playPauseCancelClicked();
|
instance()->playPauseCancelClicked();
|
||||||
|
@ -168,7 +177,7 @@ void CoverWidget::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
int skip = (st::mediaPlayerPanelPlayback.seekSize.width() / 2);
|
int skip = (st::mediaPlayerPanelPlayback.seekSize.width() / 2);
|
||||||
int length = (width() - 2 * st::mediaPlayerPanelPadding + st::mediaPlayerPanelPlayback.seekSize.width());
|
int length = (width() - 2 * st::mediaPlayerPanelPadding + st::mediaPlayerPanelPlayback.seekSize.width());
|
||||||
_playback->setGeometry(st::mediaPlayerPanelPadding - skip, st::mediaPlayerPanelPlaybackTop, length, 2 * st::mediaPlayerPanelPlaybackPadding + st::mediaPlayerPanelPlayback.width);
|
_playbackSlider->setGeometry(st::mediaPlayerPanelPadding - skip, st::mediaPlayerPanelPlaybackTop, length, 2 * st::mediaPlayerPanelPlaybackPadding + st::mediaPlayerPanelPlayback.width);
|
||||||
|
|
||||||
auto top = st::mediaPlayerPanelVolumeToggleTop;
|
auto top = st::mediaPlayerPanelVolumeToggleTop;
|
||||||
auto right = st::mediaPlayerPanelPlayLeft;
|
auto right = st::mediaPlayerPanelPlayLeft;
|
||||||
|
@ -269,11 +278,11 @@ void CoverWidget::updateTimeText(const TrackState &state) {
|
||||||
|
|
||||||
if (state.id.audio()->loading()) {
|
if (state.id.audio()->loading()) {
|
||||||
_time = QString::number(qRound(state.id.audio()->progress() * 100)) + '%';
|
_time = QString::number(qRound(state.id.audio()->progress() * 100)) + '%';
|
||||||
_playback->setDisabled(true);
|
_playbackSlider->setDisabled(true);
|
||||||
} else {
|
} else {
|
||||||
display = display / frequency;
|
display = display / frequency;
|
||||||
_time = formatDurationText(display);
|
_time = formatDurationText(display);
|
||||||
_playback->setDisabled(false);
|
_playbackSlider->setDisabled(false);
|
||||||
}
|
}
|
||||||
if (_seekPositionMs < 0) {
|
if (_seekPositionMs < 0) {
|
||||||
updateTimeLabel();
|
updateTimeLabel();
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Ui {
|
||||||
class FlatLabel;
|
class FlatLabel;
|
||||||
class LabelSimple;
|
class LabelSimple;
|
||||||
class IconButton;
|
class IconButton;
|
||||||
|
class MediaSlider;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
@ -80,6 +81,7 @@ private:
|
||||||
object_ptr<Ui::FlatLabel> _nameLabel;
|
object_ptr<Ui::FlatLabel> _nameLabel;
|
||||||
object_ptr<Ui::LabelSimple> _timeLabel;
|
object_ptr<Ui::LabelSimple> _timeLabel;
|
||||||
object_ptr<Ui::IconButton> _close;
|
object_ptr<Ui::IconButton> _close;
|
||||||
|
object_ptr<Ui::MediaSlider> _playbackSlider;
|
||||||
std::unique_ptr<Clip::Playback> _playback;
|
std::unique_ptr<Clip::Playback> _playback;
|
||||||
object_ptr<Ui::IconButton> _previousTrack = { nullptr };
|
object_ptr<Ui::IconButton> _previousTrack = { nullptr };
|
||||||
object_ptr<PlayButton> _playPause;
|
object_ptr<PlayButton> _playPause;
|
||||||
|
|
|
@ -45,12 +45,10 @@ VolumeController::VolumeController(QWidget *parent) : TWidget(parent)
|
||||||
});
|
});
|
||||||
subscribe(Global::RefSongVolumeChanged(), [this] {
|
subscribe(Global::RefSongVolumeChanged(), [this] {
|
||||||
if (!_slider->isChanging()) {
|
if (!_slider->isChanging()) {
|
||||||
_slider->setValue(Global::SongVolume(), true);
|
_slider->setValue(Global::SongVolume());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
setVolume(Global::SongVolume());
|
||||||
auto animated = false;
|
|
||||||
setVolume(Global::SongVolume(), animated);
|
|
||||||
|
|
||||||
resize(st::mediaPlayerPanelVolumeWidth, 2 * st::mediaPlayerPanelPlaybackPadding + st::mediaPlayerPanelPlayback.width);
|
resize(st::mediaPlayerPanelVolumeWidth, 2 * st::mediaPlayerPanelPlaybackPadding + st::mediaPlayerPanelPlayback.width);
|
||||||
}
|
}
|
||||||
|
@ -65,8 +63,8 @@ void VolumeController::resizeEvent(QResizeEvent *e) {
|
||||||
_slider->setGeometry(rect());
|
_slider->setGeometry(rect());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VolumeController::setVolume(float64 volume, bool animated) {
|
void VolumeController::setVolume(float64 volume) {
|
||||||
_slider->setValue(volume, animated);
|
_slider->setValue(volume);
|
||||||
if (volume > 0) {
|
if (volume > 0) {
|
||||||
Global::SetRememberedSongVolume(volume);
|
Global::SetRememberedSongVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setVolume(float64 volume, bool animated = true);
|
void setVolume(float64 volume);
|
||||||
void applyVolumeChange(float64 volume);
|
void applyVolumeChange(float64 volume);
|
||||||
|
|
||||||
object_ptr<Ui::MediaSlider> _slider;
|
object_ptr<Ui::MediaSlider> _slider;
|
||||||
|
|
|
@ -91,7 +91,8 @@ Widget::Widget(QWidget *parent) : TWidget(parent)
|
||||||
, _repeatTrack(this, st::mediaPlayerRepeatButton)
|
, _repeatTrack(this, st::mediaPlayerRepeatButton)
|
||||||
, _close(this, st::mediaPlayerClose)
|
, _close(this, st::mediaPlayerClose)
|
||||||
, _shadow(this, st::shadowFg)
|
, _shadow(this, st::shadowFg)
|
||||||
, _playback(std::make_unique<Clip::Playback>(new Ui::FilledSlider(this, st::mediaPlayerPlayback))) {
|
, _playbackSlider(this, st::mediaPlayerPlayback)
|
||||||
|
, _playback(std::make_unique<Clip::Playback>()) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
resize(width(), st::mediaPlayerHeight + st::lineWidth);
|
resize(width(), st::mediaPlayerHeight + st::lineWidth);
|
||||||
|
@ -99,11 +100,19 @@ Widget::Widget(QWidget *parent) : TWidget(parent)
|
||||||
_nameLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_nameLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
_timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
_playback->setChangeProgressCallback([this](float64 value) {
|
_playback->setInLoadingStateChangedCallback([this](bool loading) {
|
||||||
handleSeekProgress(value);
|
_playbackSlider->setDisabled(loading);
|
||||||
});
|
});
|
||||||
_playback->setChangeFinishedCallback([this](float64 value) {
|
_playback->setValueChangedCallback([this](float64 value) {
|
||||||
|
_playbackSlider->setValue(value);
|
||||||
|
});
|
||||||
|
_playbackSlider->setChangeProgressCallback([this](float64 value) {
|
||||||
|
handleSeekProgress(value);
|
||||||
|
_playback->setValue(value, false);
|
||||||
|
});
|
||||||
|
_playbackSlider->setChangeFinishedCallback([this](float64 value) {
|
||||||
handleSeekFinished(value);
|
handleSeekFinished(value);
|
||||||
|
_playback->setValue(value, false);
|
||||||
});
|
});
|
||||||
_playPause->setClickedCallback([this] {
|
_playPause->setClickedCallback([this] {
|
||||||
instance()->playPauseCancelClicked();
|
instance()->playPauseCancelClicked();
|
||||||
|
@ -167,12 +176,12 @@ void Widget::setShadowGeometryToLeft(int x, int y, int w, int h) {
|
||||||
|
|
||||||
void Widget::showShadow() {
|
void Widget::showShadow() {
|
||||||
_shadow->show();
|
_shadow->show();
|
||||||
_playback->show();
|
_playbackSlider->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::hideShadow() {
|
void Widget::hideShadow() {
|
||||||
_shadow->hide();
|
_shadow->hide();
|
||||||
_playback->hide();
|
_playbackSlider->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint Widget::getPositionForVolumeWidget() const {
|
QPoint Widget::getPositionForVolumeWidget() const {
|
||||||
|
@ -223,7 +232,7 @@ void Widget::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
updatePlayPrevNextPositions();
|
updatePlayPrevNextPositions();
|
||||||
|
|
||||||
_playback->setGeometry(0, height() - st::mediaPlayerPlayback.fullWidth, width(), st::mediaPlayerPlayback.fullWidth);
|
_playbackSlider->setGeometry(0, height() - st::mediaPlayerPlayback.fullWidth, width(), st::mediaPlayerPlayback.fullWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::paintEvent(QPaintEvent *e) {
|
void Widget::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -346,11 +355,11 @@ void Widget::updateTimeText(const TrackState &state) {
|
||||||
|
|
||||||
if (state.id.audio()->loading()) {
|
if (state.id.audio()->loading()) {
|
||||||
_time = QString::number(qRound(state.id.audio()->progress() * 100)) + '%';
|
_time = QString::number(qRound(state.id.audio()->progress() * 100)) + '%';
|
||||||
_playback->setDisabled(true);
|
_playbackSlider->setDisabled(true);
|
||||||
} else {
|
} else {
|
||||||
display = display / frequency;
|
display = display / frequency;
|
||||||
_time = formatDurationText(display);
|
_time = formatDurationText(display);
|
||||||
_playback->setDisabled(false);
|
_playbackSlider->setDisabled(false);
|
||||||
}
|
}
|
||||||
if (_seekPositionMs < 0) {
|
if (_seekPositionMs < 0) {
|
||||||
updateTimeLabel();
|
updateTimeLabel();
|
||||||
|
|
|
@ -27,6 +27,7 @@ class FlatLabel;
|
||||||
class LabelSimple;
|
class LabelSimple;
|
||||||
class IconButton;
|
class IconButton;
|
||||||
class PlainShadow;
|
class PlainShadow;
|
||||||
|
class FilledSlider;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
@ -101,6 +102,7 @@ private:
|
||||||
object_ptr<Ui::IconButton> _repeatTrack;
|
object_ptr<Ui::IconButton> _repeatTrack;
|
||||||
object_ptr<Ui::IconButton> _close;
|
object_ptr<Ui::IconButton> _close;
|
||||||
object_ptr<Ui::PlainShadow> _shadow = { nullptr };
|
object_ptr<Ui::PlainShadow> _shadow = { nullptr };
|
||||||
|
object_ptr<Ui::FilledSlider> _playbackSlider;
|
||||||
std::unique_ptr<Clip::Playback> _playback;
|
std::unique_ptr<Clip::Playback> _playback;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,8 @@ namespace Clip {
|
||||||
|
|
||||||
Controller::Controller(QWidget *parent) : TWidget(parent)
|
Controller::Controller(QWidget *parent) : TWidget(parent)
|
||||||
, _playPauseResume(this, st::mediaviewPlayButton)
|
, _playPauseResume(this, st::mediaviewPlayButton)
|
||||||
, _playback(std::make_unique<Playback>(new Ui::MediaSlider(this, st::mediaviewPlayback)))
|
, _playbackSlider(this, st::mediaviewPlayback)
|
||||||
|
, _playback(std::make_unique<Playback>())
|
||||||
, _volumeController(this)
|
, _volumeController(this)
|
||||||
, _fullScreenToggle(this, st::mediaviewFullScreenButton)
|
, _fullScreenToggle(this, st::mediaviewFullScreenButton)
|
||||||
, _playedAlready(this, st::mediaviewPlayProgressLabel)
|
, _playedAlready(this, st::mediaviewPlayProgressLabel)
|
||||||
|
@ -50,11 +51,19 @@ Controller::Controller(QWidget *parent) : TWidget(parent)
|
||||||
connect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed()));
|
connect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed()));
|
||||||
connect(_volumeController, SIGNAL(volumeChanged(float64)), this, SIGNAL(volumeChanged(float64)));
|
connect(_volumeController, SIGNAL(volumeChanged(float64)), this, SIGNAL(volumeChanged(float64)));
|
||||||
|
|
||||||
_playback->setChangeProgressCallback([this](float64 value) {
|
_playback->setInLoadingStateChangedCallback([this](bool loading) {
|
||||||
handleSeekProgress(value);
|
_playbackSlider->setDisabled(loading);
|
||||||
});
|
});
|
||||||
_playback->setChangeFinishedCallback([this](float64 value) {
|
_playback->setValueChangedCallback([this](float64 value) {
|
||||||
|
_playbackSlider->setValue(value);
|
||||||
|
});
|
||||||
|
_playbackSlider->setChangeProgressCallback([this](float64 value) {
|
||||||
|
handleSeekProgress(value);
|
||||||
|
_playback->setValue(value, false);
|
||||||
|
});
|
||||||
|
_playbackSlider->setChangeFinishedCallback([this](float64 value) {
|
||||||
handleSeekFinished(value);
|
handleSeekFinished(value);
|
||||||
|
_playback->setValue(value, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +102,7 @@ void Controller::hideAnimated() {
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
void Controller::startFading(Callback start) {
|
void Controller::startFading(Callback start) {
|
||||||
start();
|
start();
|
||||||
_playback->show();
|
_playbackSlider->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::fadeFinished() {
|
void Controller::fadeFinished() {
|
||||||
|
@ -101,7 +110,7 @@ void Controller::fadeFinished() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::fadeUpdated(float64 opacity) {
|
void Controller::fadeUpdated(float64 opacity) {
|
||||||
_playback->setFadeOpacity(opacity);
|
_playbackSlider->setFadeOpacity(opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::updatePlayback(const Player::TrackState &state) {
|
void Controller::updatePlayback(const Player::TrackState &state) {
|
||||||
|
@ -178,12 +187,12 @@ void Controller::setInFullScreen(bool inFullScreen) {
|
||||||
|
|
||||||
void Controller::grabStart() {
|
void Controller::grabStart() {
|
||||||
showChildren();
|
showChildren();
|
||||||
_playback->hide();
|
_playbackSlider->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::grabFinish() {
|
void Controller::grabFinish() {
|
||||||
hideChildren();
|
hideChildren();
|
||||||
_playback->show();
|
_playbackSlider->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::resizeEvent(QResizeEvent *e) {
|
void Controller::resizeEvent(QResizeEvent *e) {
|
||||||
|
@ -195,9 +204,9 @@ void Controller::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
_volumeController->moveToRight(st::mediaviewFullScreenLeft + _fullScreenToggle->width() + st::mediaviewVolumeLeft, (height() - _volumeController->height()) / 2);
|
_volumeController->moveToRight(st::mediaviewFullScreenLeft + _fullScreenToggle->width() + st::mediaviewVolumeLeft, (height() - _volumeController->height()) / 2);
|
||||||
|
|
||||||
int playbackWidth = width() - st::mediaviewPlayPauseLeft - _playPauseResume->width() - playTop - fullScreenTop - _volumeController->width() - st::mediaviewVolumeLeft - _fullScreenToggle->width() - st::mediaviewFullScreenLeft;
|
auto playbackWidth = width() - st::mediaviewPlayPauseLeft - _playPauseResume->width() - playTop - fullScreenTop - _volumeController->width() - st::mediaviewVolumeLeft - _fullScreenToggle->width() - st::mediaviewFullScreenLeft;
|
||||||
_playback->resize(playbackWidth, st::mediaviewPlayback.seekSize.height());
|
_playbackSlider->resize(playbackWidth, st::mediaviewPlayback.seekSize.height());
|
||||||
_playback->moveToLeft(st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop, st::mediaviewPlaybackTop);
|
_playbackSlider->moveToLeft(st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop, st::mediaviewPlaybackTop);
|
||||||
|
|
||||||
_playedAlready->moveToLeft(st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop, st::mediaviewPlayProgressTop);
|
_playedAlready->moveToLeft(st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop, st::mediaviewPlayProgressTop);
|
||||||
_toPlayLeft->moveToRight(width() - (st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop) - playbackWidth, st::mediaviewPlayProgressTop);
|
_toPlayLeft->moveToRight(width() - (st::mediaviewPlayPauseLeft + _playPauseResume->width() + playTop) - playbackWidth, st::mediaviewPlayProgressTop);
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Ui {
|
||||||
class LabelSimple;
|
class LabelSimple;
|
||||||
class FadeAnimation;
|
class FadeAnimation;
|
||||||
class IconButton;
|
class IconButton;
|
||||||
|
class MediaSlider;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
@ -86,6 +87,7 @@ private:
|
||||||
TimeMs _lastDurationMs = 0;
|
TimeMs _lastDurationMs = 0;
|
||||||
|
|
||||||
object_ptr<Ui::IconButton> _playPauseResume;
|
object_ptr<Ui::IconButton> _playPauseResume;
|
||||||
|
object_ptr<Ui::MediaSlider> _playbackSlider;
|
||||||
std::unique_ptr<Playback> _playback;
|
std::unique_ptr<Playback> _playback;
|
||||||
object_ptr<VolumeController> _volumeController;
|
object_ptr<VolumeController> _volumeController;
|
||||||
object_ptr<Ui::IconButton> _fullScreenToggle;
|
object_ptr<Ui::IconButton> _fullScreenToggle;
|
||||||
|
|
|
@ -26,14 +26,19 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
namespace Media {
|
namespace Media {
|
||||||
namespace Clip {
|
namespace Clip {
|
||||||
|
|
||||||
Playback::Playback(Ui::ContinuousSlider *slider) : _slider(slider) {
|
Playback::Playback() : _a_value(animation(this, &Playback::step_value)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playback::updateState(const Player::TrackState &state) {
|
void Playback::updateState(const Player::TrackState &state) {
|
||||||
qint64 position = 0, length = state.length;
|
qint64 position = 0, length = state.length;
|
||||||
|
|
||||||
auto wasDisabled = _slider->isDisabled();
|
auto wasInLoadingState = _inLoadingState;
|
||||||
if (wasDisabled) setDisabled(false);
|
if (wasInLoadingState) {
|
||||||
|
_inLoadingState = false;
|
||||||
|
if (_inLoadingStateChanged) {
|
||||||
|
_inLoadingStateChanged(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_playing = !Player::IsStopped(state.state);
|
_playing = !Player::IsStopped(state.state);
|
||||||
if (_playing || state.state == Player::State::Stopped) {
|
if (_playing || state.state == Player::State::Stopped) {
|
||||||
|
@ -44,25 +49,60 @@ void Playback::updateState(const Player::TrackState &state) {
|
||||||
position = 0;
|
position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float64 progress = 0.;
|
auto progress = 0.;
|
||||||
if (position > length) {
|
if (position > length) {
|
||||||
progress = 1.;
|
progress = 1.;
|
||||||
} else if (length) {
|
} else if (length) {
|
||||||
progress = length ? snap(float64(position) / length, 0., 1.) : 0.;
|
progress = length ? snap(float64(position) / length, 0., 1.) : 0.;
|
||||||
}
|
}
|
||||||
if (length != _length || position != _position || wasDisabled) {
|
if (length != _length || position != _position || wasInLoadingState) {
|
||||||
auto animated = (length && _length&& progress > _slider->value());
|
auto animated = (length && _length && progress > value());
|
||||||
_slider->setValue(progress, animated);
|
setValue(progress, animated);
|
||||||
_position = position;
|
_position = position;
|
||||||
_length = length;
|
_length = length;
|
||||||
}
|
}
|
||||||
_slider->update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playback::updateLoadingState(float64 progress) {
|
void Playback::updateLoadingState(float64 progress) {
|
||||||
setDisabled(true);
|
if (!_inLoadingState) {
|
||||||
auto animated = progress > _slider->value();
|
_inLoadingState = true;
|
||||||
_slider->setValue(progress, animated);
|
if (_inLoadingStateChanged) {
|
||||||
|
_inLoadingStateChanged(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto animated = (progress > value());
|
||||||
|
setValue(progress, animated);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float64 Playback::value() const {
|
||||||
|
return a_value.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Playback::setValue(float64 value, bool animated) {
|
||||||
|
if (animated) {
|
||||||
|
a_value.start(value);
|
||||||
|
_a_value.start();
|
||||||
|
} else {
|
||||||
|
a_value = anim::value(value, value);
|
||||||
|
_a_value.stop();
|
||||||
|
}
|
||||||
|
if (_valueChanged) {
|
||||||
|
_valueChanged(a_value.current());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Playback::step_value(float64 ms, bool timer) {
|
||||||
|
auto dt = ms / (2 * AudioVoiceMsgUpdateView);
|
||||||
|
if (dt >= 1) {
|
||||||
|
_a_value.stop();
|
||||||
|
a_value.finish();
|
||||||
|
} else {
|
||||||
|
a_value.update(qMin(dt, 1.), anim::linear);
|
||||||
|
}
|
||||||
|
if (timer && _valueChanged) {
|
||||||
|
_valueChanged(a_value.current());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Clip
|
} // namespace Clip
|
||||||
|
|
|
@ -31,41 +31,31 @@ namespace Clip {
|
||||||
|
|
||||||
class Playback {
|
class Playback {
|
||||||
public:
|
public:
|
||||||
Playback(Ui::ContinuousSlider *slider);
|
Playback();
|
||||||
|
|
||||||
|
void setValueChangedCallback(base::lambda<void(float64)> callback) {
|
||||||
|
_valueChanged = std::move(callback);
|
||||||
|
}
|
||||||
|
void setInLoadingStateChangedCallback(base::lambda<void(bool)> callback) {
|
||||||
|
_inLoadingStateChanged = std::move(callback);
|
||||||
|
}
|
||||||
|
void setValue(float64 value, bool animated);
|
||||||
|
|
||||||
void updateState(const Player::TrackState &state);
|
void updateState(const Player::TrackState &state);
|
||||||
void updateLoadingState(float64 progress);
|
void updateLoadingState(float64 progress);
|
||||||
|
|
||||||
void setFadeOpacity(float64 opacity) {
|
|
||||||
_slider->setFadeOpacity(opacity);
|
|
||||||
}
|
|
||||||
void setChangeProgressCallback(Ui::ContinuousSlider::Callback &&callback) {
|
|
||||||
_slider->setChangeProgressCallback(std::move(callback));
|
|
||||||
}
|
|
||||||
void setChangeFinishedCallback(Ui::ContinuousSlider::Callback &&callback) {
|
|
||||||
_slider->setChangeFinishedCallback(std::move(callback));
|
|
||||||
}
|
|
||||||
void setGeometry(int x, int y, int w, int h) {
|
|
||||||
_slider->setGeometry(x, y, w, h);
|
|
||||||
}
|
|
||||||
void hide() {
|
|
||||||
_slider->hide();
|
|
||||||
}
|
|
||||||
void show() {
|
|
||||||
_slider->show();
|
|
||||||
}
|
|
||||||
void moveToLeft(int x, int y) {
|
|
||||||
_slider->moveToLeft(x, y);
|
|
||||||
}
|
|
||||||
void resize(int w, int h) {
|
|
||||||
_slider->resize(w, h);
|
|
||||||
}
|
|
||||||
void setDisabled(bool disabled) {
|
|
||||||
_slider->setDisabled(disabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ContinuousSlider *_slider;
|
float64 value() const;
|
||||||
|
void step_value(float64 ms, bool timer);
|
||||||
|
|
||||||
|
// This can animate for a very long time (like in music playing),
|
||||||
|
// so it should be a BasicAnimation, not an Animation.
|
||||||
|
anim::value a_value;
|
||||||
|
BasicAnimation _a_value;
|
||||||
|
base::lambda<void(float64)> _valueChanged;
|
||||||
|
|
||||||
|
bool _inLoadingState = false;
|
||||||
|
base::lambda<void(bool)> _inLoadingStateChanged;
|
||||||
|
|
||||||
int64 _position = 0;
|
int64 _position = 0;
|
||||||
int64 _length = 0;
|
int64 _length = 0;
|
||||||
|
|
|
@ -27,15 +27,10 @@ constexpr auto kByWheelFinishedTimeout = 1000;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ContinuousSlider::ContinuousSlider(QWidget *parent) : TWidget(parent)
|
ContinuousSlider::ContinuousSlider(QWidget *parent) : TWidget(parent) {
|
||||||
, _a_value(animation(this, &ContinuousSlider::step_value)) {
|
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
float64 ContinuousSlider::value() const {
|
|
||||||
return a_value.current();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContinuousSlider::setDisabled(bool disabled) {
|
void ContinuousSlider::setDisabled(bool disabled) {
|
||||||
if (_disabled != disabled) {
|
if (_disabled != disabled) {
|
||||||
_disabled = disabled;
|
_disabled = disabled;
|
||||||
|
@ -50,7 +45,7 @@ void ContinuousSlider::setMoveByWheel(bool move) {
|
||||||
_byWheelFinished = std::make_unique<SingleTimer>();
|
_byWheelFinished = std::make_unique<SingleTimer>();
|
||||||
_byWheelFinished->setTimeoutHandler([this] {
|
_byWheelFinished->setTimeoutHandler([this] {
|
||||||
if (_changeFinishedCallback) {
|
if (_changeFinishedCallback) {
|
||||||
_changeFinishedCallback(getCurrentValue(getms()));
|
_changeFinishedCallback(getCurrentValue());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -59,14 +54,8 @@ void ContinuousSlider::setMoveByWheel(bool move) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContinuousSlider::setValue(float64 value, bool animated) {
|
void ContinuousSlider::setValue(float64 value) {
|
||||||
if (animated) {
|
_value = value;
|
||||||
a_value.start(value);
|
|
||||||
_a_value.start();
|
|
||||||
} else {
|
|
||||||
a_value = anim::value(value, value);
|
|
||||||
_a_value.stop();
|
|
||||||
}
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,17 +64,6 @@ void ContinuousSlider::setFadeOpacity(float64 opacity) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContinuousSlider::step_value(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
|
|
||||||
if (dt >= 1) {
|
|
||||||
_a_value.stop();
|
|
||||||
a_value.finish();
|
|
||||||
} else {
|
|
||||||
a_value.update(qMin(dt, 1.), anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ContinuousSlider::mouseMoveEvent(QMouseEvent *e) {
|
void ContinuousSlider::mouseMoveEvent(QMouseEvent *e) {
|
||||||
if (_mouseDown) {
|
if (_mouseDown) {
|
||||||
updateDownValueFromPos(e->pos());
|
updateDownValueFromPos(e->pos());
|
||||||
|
@ -115,8 +93,7 @@ void ContinuousSlider::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
if (_changeFinishedCallback) {
|
if (_changeFinishedCallback) {
|
||||||
_changeFinishedCallback(_downValue);
|
_changeFinishedCallback(_downValue);
|
||||||
}
|
}
|
||||||
a_value = anim::value(_downValue, _downValue);
|
_value = _downValue;
|
||||||
_a_value.stop();
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,8 +116,8 @@ void ContinuousSlider::wheelEvent(QWheelEvent *e) {
|
||||||
deltaX *= -1;
|
deltaX *= -1;
|
||||||
}
|
}
|
||||||
auto delta = (qAbs(deltaX) > qAbs(deltaY)) ? deltaX : deltaY;
|
auto delta = (qAbs(deltaX) > qAbs(deltaY)) ? deltaX : deltaY;
|
||||||
auto finalValue = snap(a_value.to() + delta * coef, 0., 1.);
|
auto finalValue = snap(_value + delta * coef, 0., 1.);
|
||||||
setValue(finalValue, false);
|
setValue(finalValue);
|
||||||
if (_changeProgressCallback) {
|
if (_changeProgressCallback) {
|
||||||
_changeProgressCallback(finalValue);
|
_changeProgressCallback(finalValue);
|
||||||
}
|
}
|
||||||
|
@ -197,7 +174,7 @@ void FilledSlider::paintEvent(QPaintEvent *e) {
|
||||||
auto lineWidthRounded = qFloor(lineWidth);
|
auto lineWidthRounded = qFloor(lineWidth);
|
||||||
auto lineWidthPartial = lineWidth - lineWidthRounded;
|
auto lineWidthPartial = lineWidth - lineWidthRounded;
|
||||||
auto seekRect = getSeekRect();
|
auto seekRect = getSeekRect();
|
||||||
auto value = getCurrentValue(ms);
|
auto value = getCurrentValue();
|
||||||
auto from = seekRect.x(), mid = qRound(from + value * seekRect.width()), end = from + seekRect.width();
|
auto from = seekRect.x(), mid = qRound(from + value * seekRect.width()), end = from + seekRect.width();
|
||||||
if (mid > from) {
|
if (mid > from) {
|
||||||
p.setOpacity(masterOpacity);
|
p.setOpacity(masterOpacity);
|
||||||
|
@ -244,7 +221,7 @@ void MediaSlider::paintEvent(QPaintEvent *e) {
|
||||||
auto disabled = isDisabled();
|
auto disabled = isDisabled();
|
||||||
auto over = getCurrentOverFactor(ms);
|
auto over = getCurrentOverFactor(ms);
|
||||||
auto seekRect = getSeekRect();
|
auto seekRect = getSeekRect();
|
||||||
auto value = getCurrentValue(ms);
|
auto value = getCurrentValue();
|
||||||
|
|
||||||
// invert colors and value for vertical
|
// invert colors and value for vertical
|
||||||
if (!horizontal) value = 1. - value;
|
if (!horizontal) value = 1. - value;
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
float64 value() const;
|
float64 value() const;
|
||||||
void setValue(float64 value, bool animated);
|
void setValue(float64 value);
|
||||||
void setFadeOpacity(float64 opacity);
|
void setFadeOpacity(float64 opacity);
|
||||||
void setDisabled(bool disabled);
|
void setDisabled(bool disabled);
|
||||||
bool isDisabled() const {
|
bool isDisabled() const {
|
||||||
|
@ -69,9 +69,8 @@ protected:
|
||||||
float64 fadeOpacity() const {
|
float64 fadeOpacity() const {
|
||||||
return _fadeOpacity;
|
return _fadeOpacity;
|
||||||
}
|
}
|
||||||
float64 getCurrentValue(TimeMs ms) {
|
float64 getCurrentValue() {
|
||||||
_a_value.step(ms);
|
return _mouseDown ? _downValue : _value;
|
||||||
return _mouseDown ? _downValue : a_value.current();
|
|
||||||
}
|
}
|
||||||
float64 getCurrentOverFactor(TimeMs ms) {
|
float64 getCurrentOverFactor(TimeMs ms) {
|
||||||
return _disabled ? 0. : _a_over.current(ms, _over ? 1. : 0.);
|
return _disabled ? 0. : _a_over.current(ms, _over ? 1. : 0.);
|
||||||
|
@ -91,7 +90,6 @@ private:
|
||||||
return _byWheelFinished != nullptr;
|
return _byWheelFinished != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void step_value(float64 ms, bool timer);
|
|
||||||
void setOver(bool over);
|
void setOver(bool over);
|
||||||
float64 computeValue(const QPoint &pos) const;
|
float64 computeValue(const QPoint &pos) const;
|
||||||
void updateDownValueFromPos(const QPoint &pos);
|
void updateDownValueFromPos(const QPoint &pos);
|
||||||
|
@ -107,10 +105,7 @@ private:
|
||||||
bool _over = false;
|
bool _over = false;
|
||||||
Animation _a_over;
|
Animation _a_over;
|
||||||
|
|
||||||
// This can animate for a very long time (like in music playing),
|
float64 _value = 0.;
|
||||||
// so it should be a BasicAnimation, not an Animation.
|
|
||||||
anim::value a_value;
|
|
||||||
BasicAnimation _a_value;
|
|
||||||
|
|
||||||
bool _mouseDown = false;
|
bool _mouseDown = false;
|
||||||
float64 _downValue = 0.;
|
float64 _downValue = 0.;
|
||||||
|
|
Loading…
Add table
Reference in a new issue