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);
mediaPlayerWideWidth: 460px;
mediaPlayerHeight: 35px;
mediaPlayerPadding: 8px;
mediaPlayerNameTop: 22px;
@ -171,6 +172,8 @@ mediaPlayerVolumeToggle: IconButton(mediaPlayerRepeatButton) {
mediaPlayerVolumeMargin: 10px;
mediaPlayerVolumeSize: size(27px, 100px);
mediaPlayerControlsFade: icon {{ "fade_horizontal", mediaPlayerBg }};
mediaPlayerNextButton: IconButton(mediaPlayerPlayButton) {
icon: icon {
{ "player/player_forward", mediaPlayerActiveFg },

View File

@ -252,7 +252,7 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> session)
setMouseTracking(true);
resize(width(), st::mediaPlayerHeight + st::lineWidth);
_rightControls->show(anim::type::instant);
setupRightControls();
_nameLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
_timeLabel->setAttribute(Qt::WA_TransparentForMouseEvents);
@ -350,7 +350,25 @@ Widget::Widget(QWidget *parent, not_null<Main::Session*> session)
}, lifetime());
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() {
@ -358,7 +376,7 @@ void Widget::updateVolumeToggleIcon() {
const auto volume = Core::App().settings().songVolume();
return (volume == 0.)
? &st::mediaPlayerVolumeIcon0
: (volume < 0.5)
: (volume < 0.66)
? &st::mediaPlayerVolumeIcon1
: nullptr;
}());
@ -412,6 +430,7 @@ QPoint Widget::getPositionForVolumeWidget() const {
void Widget::volumeWidgetCreated(Dropdown *widget) {
_volumeToggle->installEventFilter(widget);
widget->installEventFilter(this);
}
QPoint Widget::getPositionForRepeatWidget() const {
@ -456,6 +475,8 @@ void Widget::handleSeekFinished(float64 progress) {
void Widget::resizeEvent(QResizeEvent *e) {
updateControlsGeometry();
_narrow = (width() < st::mediaPlayerWideWidth);
updateControlsWrapVisibility();
}
void Widget::updateControlsGeometry() {
@ -476,12 +497,21 @@ void Widget::updateControlsGeometry() {
}
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(
st::mediaPlayerCloseRight + _close->width(),
st::mediaPlayerPlayTop);
}
void Widget::updateControlsWrapVisibility() {
_rightControls->toggle(
_over || !_narrow,
isHidden() ? anim::type::instant : anim::type::normal);
}
void Widget::paintEvent(QPaintEvent *e) {
Painter p(this);
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) {
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) {
@ -522,7 +585,10 @@ void Widget::mouseReleaseEvent(QMouseEvent *e) {
void Widget::updateOverLabelsState(QPoint pos) {
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 over = labels.contains(pos);
updateOverLabelsState(over);

View File

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