Fade out controls in a narrow player.

This commit is contained in:
John Preston 2021-11-24 17:44:47 +04:00
parent ca61b80fe5
commit 4b489ee7d2
3 changed files with 85 additions and 9 deletions

View file

@ -30,6 +30,7 @@ mediaPlayerButtonSize: size(25px, 30px);
mediaPlayerButtonPosition: point(5px, 10px); mediaPlayerButtonPosition: point(5px, 10px);
mediaPlayerWideWidth: 460px;
mediaPlayerHeight: 35px; mediaPlayerHeight: 35px;
mediaPlayerPadding: 8px; mediaPlayerPadding: 8px;
mediaPlayerNameTop: 22px; mediaPlayerNameTop: 22px;
@ -171,6 +172,8 @@ mediaPlayerVolumeToggle: IconButton(mediaPlayerRepeatButton) {
mediaPlayerVolumeMargin: 10px; mediaPlayerVolumeMargin: 10px;
mediaPlayerVolumeSize: size(27px, 100px); mediaPlayerVolumeSize: size(27px, 100px);
mediaPlayerControlsFade: icon {{ "fade_horizontal", mediaPlayerBg }};
mediaPlayerNextButton: IconButton(mediaPlayerPlayButton) { mediaPlayerNextButton: IconButton(mediaPlayerPlayButton) {
icon: icon { icon: icon {
{ "player/player_forward", mediaPlayerActiveFg }, { "player/player_forward", mediaPlayerActiveFg },

View file

@ -252,7 +252,7 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> session)
setMouseTracking(true); setMouseTracking(true);
resize(width(), st::mediaPlayerHeight + st::lineWidth); resize(width(), st::mediaPlayerHeight + st::lineWidth);
_rightControls->show(anim::type::instant); setupRightControls();
_nameLabel->setAttribute(Qt::WA_TransparentForMouseEvents); _nameLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
_timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents); _timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
@ -350,7 +350,25 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> session)
}, lifetime()); }, lifetime());
setType(AudioMsgId::Type::Song); setType(AudioMsgId::Type::Song);
//_playPause->finishTransform(); }
void Widget::setupRightControls() {
const auto raw = rightControls();
raw->paintRequest(
) | rpl::start_with_next([=](QRect clip) {
auto p = QPainter(raw);
const auto &icon = st::mediaPlayerControlsFade;
const auto fade = QRect(0, 0, icon.width(), raw->height());
if (fade.intersects(clip)) {
icon.fill(p, fade);
}
const auto fill = clip.intersected(
{ icon.width(), 0, raw->width() - icon.width(), raw->height() });
if (!fill.isEmpty()) {
p.fillRect(fill, st::mediaPlayerBg);
}
}, raw->lifetime());
_rightControls->show(anim::type::instant);
} }
void Widget::updateVolumeToggleIcon() { void Widget::updateVolumeToggleIcon() {
@ -358,7 +376,7 @@ void Widget::updateVolumeToggleIcon() {
const auto volume = Core::App().settings().songVolume(); const auto volume = Core::App().settings().songVolume();
return (volume == 0.) return (volume == 0.)
? &st::mediaPlayerVolumeIcon0 ? &st::mediaPlayerVolumeIcon0
: (volume < 0.5) : (volume < 0.66)
? &st::mediaPlayerVolumeIcon1 ? &st::mediaPlayerVolumeIcon1
: nullptr; : nullptr;
}()); }());
@ -412,6 +430,7 @@ QPoint Widget::getPositionForVolumeWidget() const {
void Widget::volumeWidgetCreated(Dropdown *widget) { void Widget::volumeWidgetCreated(Dropdown *widget) {
_volumeToggle->installEventFilter(widget); _volumeToggle->installEventFilter(widget);
widget->installEventFilter(this);
} }
QPoint Widget::getPositionForRepeatWidget() const { QPoint Widget::getPositionForRepeatWidget() const {
@ -456,6 +475,8 @@ void Widget::handleSeekFinished(float64 progress) {
void Widget::resizeEvent(QResizeEvent *e) { void Widget::resizeEvent(QResizeEvent *e) {
updateControlsGeometry(); updateControlsGeometry();
_narrow = (width() < st::mediaPlayerWideWidth);
updateControlsWrapVisibility();
} }
void Widget::updateControlsGeometry() { void Widget::updateControlsGeometry() {
@ -476,12 +497,21 @@ void Widget::updateControlsGeometry() {
} }
void Widget::updateControlsWrapGeometry() { void Widget::updateControlsWrapGeometry() {
rightControls()->resize(getTimeRight() + _timeLabel->width(), _repeatToggle->height()); const auto fade = st::mediaPlayerControlsFade.width();
rightControls()->resize(
getTimeRight() + _timeLabel->width() + fade,
_repeatToggle->height());
_rightControls->moveToRight( _rightControls->moveToRight(
st::mediaPlayerCloseRight + _close->width(), st::mediaPlayerCloseRight + _close->width(),
st::mediaPlayerPlayTop); st::mediaPlayerPlayTop);
} }
void Widget::updateControlsWrapVisibility() {
_rightControls->toggle(
_over || !_narrow,
isHidden() ? anim::type::instant : anim::type::normal);
}
void Widget::paintEvent(QPaintEvent *e) { void Widget::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
auto fill = e->rect().intersected(QRect(0, 0, width(), st::mediaPlayerHeight)); auto fill = e->rect().intersected(QRect(0, 0, width(), st::mediaPlayerHeight));
@ -490,8 +520,41 @@ void Widget::paintEvent(QPaintEvent *e) {
} }
} }
bool Widget::eventFilter(QObject *o, QEvent *e) {
const auto type = e->type();
if (type == QEvent::Enter) {
markOver(true);
} else if (type == QEvent::Leave) {
markOver(false);
}
return RpWidget::eventFilter(o, e);
}
void Widget::enterEventHook(QEnterEvent *e) {
markOver(true);
}
void Widget::leaveEventHook(QEvent *e) { void Widget::leaveEventHook(QEvent *e) {
updateOverLabelsState(false); markOver(false);
}
void Widget::markOver(bool over) {
if (over) {
_over = true;
_wontBeOver = false;
updateControlsWrapVisibility();
} else {
_wontBeOver = true;
InvokeQueued(this, [=] {
if (!_wontBeOver) {
return;
}
_wontBeOver = false;
_over = false;
updateControlsWrapVisibility();
updateOverLabelsState(false);
});
}
} }
void Widget::mouseMoveEvent(QMouseEvent *e) { void Widget::mouseMoveEvent(QMouseEvent *e) {
@ -522,7 +585,10 @@ void Widget::mouseReleaseEvent(QMouseEvent *e) {
void Widget::updateOverLabelsState(QPoint pos) { void Widget::updateOverLabelsState(QPoint pos) {
const auto left = getNameLeft(); const auto left = getNameLeft();
const auto right = getNameRight(); const auto right = width()
- _rightControls->x()
- _rightControls->width()
+ getTimeRight();
const auto labels = myrtlrect(left, 0, width() - right - left, height() - st::mediaPlayerPlayback.fullWidth); const auto labels = myrtlrect(left, 0, width() - right - left, height() - st::mediaPlayerPlayback.fullWidth);
const auto over = labels.contains(pos); const auto over = labels.contains(pos);
updateOverLabelsState(over); updateOverLabelsState(over);

View file

@ -41,7 +41,7 @@ class SpeedButton;
class Dropdown; class Dropdown;
struct TrackState; struct TrackState;
class Widget : public Ui::RpWidget, private base::Subscriber { class Widget final : public Ui::RpWidget, private base::Subscriber {
public: public:
Widget(QWidget *parent, not_null<Main::Session*> session); Widget(QWidget *parent, not_null<Main::Session*> session);
@ -64,17 +64,19 @@ public:
~Widget(); ~Widget();
protected: private:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
bool eventFilter(QObject *o, QEvent *e) override;
void enterEventHook(QEnterEvent *e) override;
void leaveEventHook(QEvent *e) override; void leaveEventHook(QEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override;
void mousePressEvent(QMouseEvent *e) override; void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override;
private:
[[nodiscard]] not_null<Ui::RpWidget*> rightControls(); [[nodiscard]] not_null<Ui::RpWidget*> rightControls();
void setupRightControls();
void handleSeekProgress(float64 progress); void handleSeekProgress(float64 progress);
void handleSeekFinished(float64 progress); void handleSeekFinished(float64 progress);
@ -92,6 +94,7 @@ private:
void updateControlsVisibility(); void updateControlsVisibility();
void updateControlsGeometry(); void updateControlsGeometry();
void updateControlsWrapGeometry(); void updateControlsWrapGeometry();
void updateControlsWrapVisibility();
void createPrevNextButtons(); void createPrevNextButtons();
void destroyPrevNextButtons(); void destroyPrevNextButtons();
@ -106,6 +109,7 @@ private:
void updateTimeText(const TrackState &state); void updateTimeText(const TrackState &state);
void updateTimeLabel(); void updateTimeLabel();
void markOver(bool over);
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
@ -126,6 +130,9 @@ private:
bool _labelsOver = false; bool _labelsOver = false;
bool _labelsDown = false; bool _labelsDown = false;
rpl::event_stream<bool> _togglePlaylistRequests; rpl::event_stream<bool> _togglePlaylistRequests;
bool _narrow = false;
bool _over = false;
bool _wontBeOver = false;
class PlayButton; class PlayButton;
class SpeedButton; class SpeedButton;