Fade out controls in a narrow player.
This commit is contained in:
		
							parent
							
								
									ca61b80fe5
								
							
						
					
					
						commit
						4b489ee7d2
					
				
					 3 changed files with 85 additions and 9 deletions
				
			
		| 
						 | 
					@ -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 },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue