Use composition for playbackSpeed button.

This commit is contained in:
John Preston 2021-11-24 18:02:27 +04:00
parent 4b489ee7d2
commit cdf09e0519
2 changed files with 84 additions and 75 deletions

View file

@ -62,72 +62,38 @@ private:
}; };
class Widget::SpeedButton : public Ui::IconButton { class Widget::SpeedController final {
public: public:
SpeedButton(QWidget *parent, const style::IconButton &st); explicit SpeedController(not_null<Ui::IconButton*> button);
[[nodiscard]] rpl::producer<> saved() const; [[nodiscard]] rpl::producer<> saved() const;
protected:
void contextMenuEvent(QContextMenuEvent *e) override;
private: private:
class SpeedController final { [[nodiscard]] float64 speed() const;
public: [[nodiscard]] bool isDefault() const;
SpeedController() { [[nodiscard]] float64 lastNonDefaultSpeed() const;
setSpeed(Core::App().settings().voicePlaybackSpeed()); void toggleDefault();
_speed = Core::App().settings().voicePlaybackSpeed(true); void setSpeed(float64 newSpeed);
} void save();
void showContextMenu(not_null<QContextMenuEvent*> e);
[[nodiscard]] rpl::producer<float64> speedValue() const {
return _speedChanged.events_starting_with(speed());
}
[[nodiscard]] rpl::producer<> saved() const {
return _saved.events();
}
[[nodiscard]] float64 speed() const {
return _isDefault ? 1. : _speed;
}
[[nodiscard]] bool isDefault() const {
return _isDefault;
}
[[nodiscard]] float64 lastNonDefaultSpeed() const {
return _speed;
}
void toggleDefault() {
_isDefault = !_isDefault;
_speedChanged.fire(speed());
}
void setSpeed(float64 newSpeed) {
if (!(_isDefault = (newSpeed == 1.))) {
_speed = newSpeed;
}
_speedChanged.fire(speed());
}
void save() {
Core::App().settings().setVoicePlaybackSpeed(speed());
Core::App().saveSettingsDelayed();
_saved.fire({});
}
private:
float64 _speed = 2.;
bool _isDefault = true;
rpl::event_stream<float64> _speedChanged;
rpl::event_stream<> _saved;
};
SpeedController _speed;
const not_null<Ui::IconButton*> _button;
base::unique_qptr<Ui::PopupMenu> _menu; base::unique_qptr<Ui::PopupMenu> _menu;
float64 _speed = 2.;
bool _isDefault = true;
rpl::event_stream<float64> _speedChanged;
rpl::event_stream<> _saved;
}; };
Widget::SpeedButton::SpeedButton(QWidget *parent, const style::IconButton &st) Widget::SpeedController::SpeedController(not_null<Ui::IconButton*> button)
: IconButton(parent, st) { : _button(button) {
setClickedCallback([=] { setSpeed(Core::App().settings().voicePlaybackSpeed());
_speed.toggleDefault(); _speed = Core::App().settings().voicePlaybackSpeed(true);
_speed.save();
button->setClickedCallback([=] {
toggleDefault();
save();
}); });
struct Icons { struct Icons {
@ -135,10 +101,11 @@ Widget::SpeedButton::SpeedButton(QWidget *parent, const style::IconButton &st)
const style::icon *over = nullptr; const style::icon *over = nullptr;
}; };
_speed.speedValue( _speedChanged.events_starting_with(
speed()
) | rpl::start_with_next([=](float64 speed) { ) | rpl::start_with_next([=](float64 speed) {
const auto isDefaultSpeed = _speed.isDefault(); const auto isDefaultSpeed = isDefault();
const auto nonDefaultSpeed = _speed.lastNonDefaultSpeed(); const auto nonDefaultSpeed = lastNonDefaultSpeed();
const auto icons = [&]() -> Icons { const auto icons = [&]() -> Icons {
if (nonDefaultSpeed == .5) { if (nonDefaultSpeed == .5) {
@ -171,24 +138,66 @@ Widget::SpeedButton::SpeedButton(QWidget *parent, const style::IconButton &st)
} }
}(); }();
setIconOverride(icons.icon, icons.over); button->setIconOverride(icons.icon, icons.over);
setRippleColorOverride(isDefaultSpeed button->setRippleColorOverride(isDefaultSpeed
? &st::mediaPlayerSpeedDisabledRippleBg ? &st::mediaPlayerSpeedDisabledRippleBg
: nullptr); : nullptr);
}, lifetime()); }, button->lifetime());
button->events(
) | rpl::filter([=](not_null<QEvent*> e) {
return (e->type() == QEvent::ContextMenu);
}) | rpl::start_with_next([=](not_null<QEvent*> e) {
showContextMenu(static_cast<QContextMenuEvent*>(e.get()));
}, button->lifetime());
} }
void Widget::SpeedButton::contextMenuEvent(QContextMenuEvent *e) { rpl::producer<> Widget::SpeedController::saved() const {
return _saved.events();
}
float64 Widget::SpeedController::speed() const {
return _isDefault ? 1. : _speed;
}
bool Widget::SpeedController::isDefault() const {
return _isDefault;
}
float64 Widget::SpeedController::lastNonDefaultSpeed() const {
return _speed;
}
void Widget::SpeedController::toggleDefault() {
_isDefault = !_isDefault;
_speedChanged.fire(speed());
}
void Widget::SpeedController::setSpeed(float64 newSpeed) {
if (!(_isDefault = (newSpeed == 1.))) {
_speed = newSpeed;
}
_speedChanged.fire(speed());
}
void Widget::SpeedController::save() {
Core::App().settings().setVoicePlaybackSpeed(speed());
Core::App().saveSettingsDelayed();
_saved.fire({});
}
void Widget::SpeedController::showContextMenu(
not_null<QContextMenuEvent*> e) {
_menu = base::make_unique_q<Ui::PopupMenu>( _menu = base::make_unique_q<Ui::PopupMenu>(
this, _button,
st::mediaPlayerPopupMenu); st::mediaPlayerPopupMenu);
const auto setPlaybackSpeed = [=](float64 speed) { const auto setPlaybackSpeed = [=](float64 speed) {
_speed.setSpeed(speed); setSpeed(speed);
_speed.save(); save();
}; };
const auto currentSpeed = _speed.speed(); const auto currentSpeed = speed();
const auto addSpeed = [&](float64 speed, QString text = QString()) { const auto addSpeed = [&](float64 speed, QString text = QString()) {
if (text.isEmpty()) { if (text.isEmpty()) {
text = QString::number(speed); text = QString::number(speed);
@ -206,10 +215,6 @@ void Widget::SpeedButton::contextMenuEvent(QContextMenuEvent *e) {
_menu->popup(e->globalPos()); _menu->popup(e->globalPos());
} }
rpl::producer<> Widget::SpeedButton::saved() const {
return _speed.saved();
}
Widget::PlayButton::PlayButton(QWidget *parent) : Ui::RippleButton(parent, st::mediaPlayerButton.ripple) Widget::PlayButton::PlayButton(QWidget *parent) : Ui::RippleButton(parent, st::mediaPlayerButton.ripple)
, _layout(st::mediaPlayerButton, [this] { update(); }) { , _layout(st::mediaPlayerButton, [this] { update(); }) {
resize(st::mediaPlayerButtonSize); resize(st::mediaPlayerButtonSize);
@ -247,7 +252,10 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> session)
, _close(this, st::mediaPlayerClose) , _close(this, st::mediaPlayerClose)
, _shadow(this) , _shadow(this)
, _playbackSlider(this, st::mediaPlayerPlayback) , _playbackSlider(this, st::mediaPlayerPlayback)
, _playbackProgress(std::make_unique<View::PlaybackProgress>()) { , _playbackProgress(std::make_unique<View::PlaybackProgress>())
, _speedController(
std::make_unique<SpeedController>(
_playbackSpeed.data())) {
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
setMouseTracking(true); setMouseTracking(true);
resize(width(), st::mediaPlayerHeight + st::lineWidth); resize(width(), st::mediaPlayerHeight + st::lineWidth);
@ -318,7 +326,7 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> session)
Core::App().saveSettingsDelayed(); Core::App().saveSettingsDelayed();
}); });
_playbackSpeed->saved( _speedController->saved(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
instance()->updateVoicePlaybackSpeed(); instance()->updateVoicePlaybackSpeed();
}, lifetime()); }, lifetime());

View file

@ -135,7 +135,7 @@ private:
bool _wontBeOver = false; bool _wontBeOver = false;
class PlayButton; class PlayButton;
class SpeedButton; class SpeedController;
object_ptr<Ui::FlatLabel> _nameLabel; object_ptr<Ui::FlatLabel> _nameLabel;
object_ptr<Ui::FadeWrap<Ui::RpWidget>> _rightControls; object_ptr<Ui::FadeWrap<Ui::RpWidget>> _rightControls;
object_ptr<Ui::LabelSimple> _timeLabel; object_ptr<Ui::LabelSimple> _timeLabel;
@ -145,11 +145,12 @@ private:
object_ptr<Ui::IconButton> _volumeToggle; object_ptr<Ui::IconButton> _volumeToggle;
object_ptr<Ui::IconButton> _repeatToggle; object_ptr<Ui::IconButton> _repeatToggle;
object_ptr<Ui::IconButton> _orderToggle; object_ptr<Ui::IconButton> _orderToggle;
object_ptr<SpeedButton> _playbackSpeed; object_ptr<Ui::IconButton> _playbackSpeed;
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; object_ptr<Ui::FilledSlider> _playbackSlider;
std::unique_ptr<View::PlaybackProgress> _playbackProgress; std::unique_ptr<View::PlaybackProgress> _playbackProgress;
std::unique_ptr<SpeedController> _speedController;
rpl::lifetime _playlistChangesLifetime; rpl::lifetime _playlistChangesLifetime;