Improve playlist autoscrolling

Fixes #420
This commit is contained in:
Jonas Kvinge
2020-08-23 19:37:24 +02:00
parent 4e5755f218
commit 82142751de
10 changed files with 81 additions and 66 deletions

View File

@@ -548,11 +548,11 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
connect(app_->playlist_manager(), SIGNAL(EditingFinished(QModelIndex)), SLOT(PlaylistEditFinished(QModelIndex)));
connect(app_->playlist_manager(), SIGNAL(Error(QString)), SLOT(ShowErrorDialog(QString)));
connect(app_->playlist_manager(), SIGNAL(SummaryTextChanged(QString)), ui_->playlist_summary, SLOT(setText(QString)));
connect(app_->playlist_manager(), SIGNAL(PlayRequested(QModelIndex)), SLOT(PlayIndex(QModelIndex)));
connect(app_->playlist_manager(), SIGNAL(PlayRequested(QModelIndex, Playlist::AutoScroll)), SLOT(PlayIndex(QModelIndex, Playlist::AutoScroll)));
connect(ui_->playlist->view(), SIGNAL(doubleClicked(QModelIndex)), SLOT(PlaylistDoubleClick(QModelIndex)));
connect(ui_->playlist->view(), SIGNAL(PlayItem(QModelIndex)), SLOT(PlayIndex(QModelIndex)));
connect(ui_->playlist->view(), SIGNAL(PlayPause()), app_->player(), SLOT(PlayPause()));
connect(ui_->playlist->view(), SIGNAL(PlayItem(QModelIndex, Playlist::AutoScroll)), SLOT(PlayIndex(QModelIndex, Playlist::AutoScroll)));
connect(ui_->playlist->view(), SIGNAL(PlayPause(Playlist::AutoScroll)), app_->player(), SLOT(PlayPause(Playlist::AutoScroll)));
connect(ui_->playlist->view(), SIGNAL(RightClicked(QPoint, QModelIndex)), SLOT(PlaylistRightClick(QPoint, QModelIndex)));
connect(ui_->playlist->view(), SIGNAL(SeekForward()), app_->player(), SLOT(SeekForward()));
connect(ui_->playlist->view(), SIGNAL(SeekBackward()), app_->player(), SLOT(SeekBackward()));
@@ -1364,7 +1364,7 @@ void MainWindow::ResumePlaybackSeek(const int playback_position) {
}
void MainWindow::PlayIndex(const QModelIndex &idx) {
void MainWindow::PlayIndex(const QModelIndex &idx, Playlist::AutoScroll autoscroll) {
if (!idx.isValid()) return;
@@ -1375,7 +1375,7 @@ void MainWindow::PlayIndex(const QModelIndex &idx) {
}
app_->playlist_manager()->SetActiveToCurrent();
app_->player()->PlayAt(row, Engine::Manual, true);
app_->player()->PlayAt(row, Engine::Manual, autoscroll, true);
}
@@ -1392,13 +1392,13 @@ void MainWindow::PlaylistDoubleClick(const QModelIndex &idx) {
switch (doubleclick_playlist_addmode_) {
case BehaviourSettingsPage::PlaylistAddBehaviour_Play:
app_->playlist_manager()->SetActiveToCurrent();
app_->player()->PlayAt(row, Engine::Manual, true);
app_->player()->PlayAt(row, Engine::Manual, Playlist::AutoScroll_Never, true);
break;
case BehaviourSettingsPage::PlaylistAddBehaviour_Enqueue:
app_->playlist_manager()->current()->queue()->ToggleTracks(QModelIndexList() << idx);
if (app_->player()->GetState() != Engine::Playing) {
app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), Engine::Manual, true);
app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), Engine::Manual, Playlist::AutoScroll_Never, true);
}
break;
}
@@ -1870,10 +1870,10 @@ void MainWindow::PlaylistRightClick(const QPoint &global_pos, const QModelIndex
void MainWindow::PlaylistPlay() {
if (app_->playlist_manager()->current()->current_row() == playlist_menu_index_.row()) {
app_->player()->PlayPause();
app_->player()->PlayPause(Playlist::AutoScroll_Never);
}
else {
PlayIndex(playlist_menu_index_);
PlayIndex(playlist_menu_index_, Playlist::AutoScroll_Never);
}
}
@@ -2161,7 +2161,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) {
}
break;
case CommandlineOptions::Player_PlayPause:
app_->player()->PlayPause();
app_->player()->PlayPause(Playlist::AutoScroll_Maybe);
break;
case CommandlineOptions::Player_Pause:
app_->player()->Pause();
@@ -2236,7 +2236,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) {
app_->player()->SeekTo(app_->player()->engine()->position_nanosec() / kNsecPerSec + options.seek_by());
}
if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), Engine::Manual, true);
if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), Engine::Manual, Playlist::AutoScroll_Maybe, true);
if (options.show_osd()) app_->player()->ShowOSD();
@@ -2740,7 +2740,7 @@ void MainWindow::ShowConsole() {
void MainWindow::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Space) {
app_->player()->PlayPause();
app_->player()->PlayPause(Playlist::AutoScroll_Never);
event->accept();
}
else if (event->key() == Qt::Key_Left) {

View File

@@ -56,6 +56,7 @@
#include "mac_startup.h"
#include "osd/osdbase.h"
#include "collection/collectionmodel.h"
#include "playlist/playlist.h"
#include "playlist/playlistitem.h"
#include "settings/settingsdialog.h"
#include "settings/behavioursettingspage.h"
@@ -173,7 +174,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
void ChangeCollectionQueryMode(QAction *action);
void PlayIndex(const QModelIndex &idx);
void PlayIndex(const QModelIndex &idx, Playlist::AutoScroll autoscroll);
void PlaylistDoubleClick(const QModelIndex &idx);
void StopAfterCurrent();

View File

@@ -81,6 +81,7 @@ Player::Player(Application *app, QObject *parent)
analyzer_(nullptr),
equalizer_(nullptr),
stream_change_type_(Engine::First),
autoscroll_(Playlist::AutoScroll_Maybe),
last_state_(Engine::Empty),
nb_errors_received_(0),
volume_before_mute_(100),
@@ -265,7 +266,7 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) {
case UrlHandler::LoadResult::NoMoreTracks:
qLog(Debug) << "URL handler for" << result.original_url_ << "said no more tracks" << is_current;
if (is_current) NextItem(stream_change_type_);
if (is_current) NextItem(stream_change_type_, autoscroll_);
break;
case UrlHandler::LoadResult::TrackAvailable: {
@@ -321,7 +322,7 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) {
if (update) {
if (is_current) {
item->SetTemporaryMetadata(song);
app_->playlist_manager()->active()->InformOfCurrentSongChange();
app_->playlist_manager()->active()->InformOfCurrentSongChange(autoscroll_);
}
else if (is_next) {
next_item->SetTemporaryMetadata(song);
@@ -352,17 +353,17 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) {
}
void Player::Next() { NextInternal(Engine::Manual); }
void Player::Next() { NextInternal(Engine::Manual, Playlist::AutoScroll_Always); }
void Player::NextInternal(const Engine::TrackChangeFlags change) {
void Player::NextInternal(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) {
if (HandleStopAfter()) return;
if (HandleStopAfter(autoscroll)) return;
NextItem(change);
NextItem(change, autoscroll);
}
void Player::NextItem(const Engine::TrackChangeFlags change) {
void Player::NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll) {
Playlist *active_playlist = app_->playlist_manager()->active();
@@ -391,17 +392,17 @@ void Player::NextItem(const Engine::TrackChangeFlags change) {
return;
}
PlayAt(i, change, false);
PlayAt(i, change, autoscroll, false);
}
bool Player::HandleStopAfter() {
bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) {
if (app_->playlist_manager()->active()->stop_after_current()) {
// Find what the next track would've been, and mark that one as current so it plays next time the user presses Play.
const int next_row = app_->playlist_manager()->active()->next_row();
if (next_row != -1) {
app_->playlist_manager()->active()->set_current_row(next_row, true);
app_->playlist_manager()->active()->set_current_row(next_row, autoscroll, true);
}
app_->playlist_manager()->active()->StopAfter(-1);
@@ -419,13 +420,13 @@ void Player::TrackEnded() {
app_->playlist_manager()->collection_backend()->IncrementPlayCountAsync(current_item_->Metadata().id());
}
if (HandleStopAfter()) return;
if (HandleStopAfter(Playlist::AutoScroll_Maybe)) return;
NextInternal(Engine::Auto);
NextInternal(Engine::Auto, Playlist::AutoScroll_Maybe);
}
void Player::PlayPause() {
void Player::PlayPause(Playlist::AutoScroll autoscroll) {
switch (engine_->state()) {
case Engine::Paused:
@@ -451,7 +452,7 @@ void Player::PlayPause() {
int i = app_->playlist_manager()->active()->current_row();
if (i == -1) i = app_->playlist_manager()->active()->last_played_row();
if (i == -1) i = 0;
PlayAt(i, Engine::First, true);
PlayAt(i, Engine::First, autoscroll, true);
break;
}
}
@@ -496,21 +497,21 @@ void Player::PreviousItem(const Engine::TrackChangeFlags change) {
QDateTime now = QDateTime::currentDateTime();
if (last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(now) >= 2) {
last_pressed_previous_ = now;
PlayAt(app_->playlist_manager()->active()->current_row(), change, false);
PlayAt(app_->playlist_manager()->active()->current_row(), change, Playlist::AutoScroll_Always, false);
return;
}
last_pressed_previous_ = now;
}
int i = app_->playlist_manager()->active()->previous_row(ignore_repeat_track);
app_->playlist_manager()->active()->set_current_row(i);
app_->playlist_manager()->active()->set_current_row(i, Playlist::AutoScroll_Always);
if (i == -1) {
Stop();
PlayAt(i, change, true);
PlayAt(i, change, Playlist::AutoScroll_Always, true);
return;
}
PlayAt(i, change, false);
PlayAt(i, change, Playlist::AutoScroll_Always, false);
}
@@ -558,7 +559,7 @@ void Player::SetVolume(const int value) {
int Player::GetVolume() const { return engine_->volume(); }
void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const bool reshuffle) {
void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle) {
if (current_item_ && change == Engine::Manual && engine_->position_nanosec() != engine_->length_nanosec()) {
emit TrackSkipped(current_item_);
@@ -569,7 +570,7 @@ void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const bool
}
if (reshuffle) app_->playlist_manager()->active()->ReshuffleIndices();
app_->playlist_manager()->active()->set_current_row(index);
app_->playlist_manager()->active()->set_current_row(index, autoscroll);
if (app_->playlist_manager()->active()->current_row() == -1) {
// Maybe index didn't exist in the playlist.
return;
@@ -583,12 +584,13 @@ void Player::PlayAt(const int index, Engine::TrackChangeFlags change, const bool
if (loading_async_.contains(url)) return;
stream_change_type_ = change;
autoscroll_ = autoscroll;
HandleLoadResult(url_handlers_[url.scheme()]->StartLoading(url));
}
else {
qLog(Debug) << "Playing song" << current_item_->Metadata().title() << url;
if (current_item_->HasTemporaryMetadata()) {
app_->playlist_manager()->active()->InformOfCurrentSongChange();
app_->playlist_manager()->active()->InformOfCurrentSongChange(autoscroll);
}
engine_->Play(url, current_item_->Url(), change, current_item_->Metadata().has_cue(), current_item_->effective_beginning_nanosec(), current_item_->effective_end_nanosec());
}
@@ -743,6 +745,7 @@ void Player::TrackAboutToEnd() {
// Get the actual track URL rather than the stream URL.
if (url_handlers_.contains(url.scheme())) {
if (loading_async_.contains(url)) return;
autoscroll_ = Playlist::AutoScroll_Maybe;
UrlHandler::LoadResult result = url_handlers_[url.scheme()]->StartLoading(url);
switch (result.type_) {
case UrlHandler::LoadResult::Error:
@@ -781,7 +784,7 @@ void Player::InvalidSongRequested(const QUrl &url) {
return;
}
NextItem(Engine::Auto);
NextItem(Engine::Auto, Playlist::AutoScroll_Maybe);
}

View File

@@ -37,6 +37,7 @@
#include "urlhandler.h"
#include "engine/engine_fwd.h"
#include "engine/enginetype.h"
#include "playlist/playlist.h"
#include "playlist/playlistitem.h"
#include "settings/behavioursettingspage.h"
@@ -72,10 +73,10 @@ class PlayerInterface : public QObject {
virtual void ReloadSettings() = 0;
// Manual track change to the specified track
virtual void PlayAt(const int row, Engine::TrackChangeFlags change, const bool reshuffle) = 0;
virtual void PlayAt(const int index, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle) = 0;
// If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist
virtual void PlayPause() = 0;
virtual void PlayPause(Playlist::AutoScroll autoscroll = Playlist::AutoScroll_Always) = 0;
virtual void RestartOrPrevious() = 0;
// Skips this track. Might load more of the current radio station.
@@ -158,8 +159,8 @@ class Player : public PlayerInterface {
public slots:
void ReloadSettings() override;
void PlayAt(const int row, Engine::TrackChangeFlags change, const bool reshuffle) override;
void PlayPause() override;
void PlayAt(const int index, Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle) override;
void PlayPause(Playlist::AutoScroll autoscroll = Playlist::AutoScroll_Always) override;
void RestartOrPrevious() override;
void Next() override;
void Previous() override;
@@ -191,10 +192,10 @@ class Player : public PlayerInterface {
void TrackAboutToEnd();
void TrackEnded();
// Play the next item on the playlist - disregarding radio stations like last.fm that might have more tracks.
void NextItem(const Engine::TrackChangeFlags change);
void NextItem(const Engine::TrackChangeFlags change, const Playlist::AutoScroll autoscroll);
void PreviousItem(const Engine::TrackChangeFlags change);
void NextInternal(const Engine::TrackChangeFlags);
void NextInternal(const Engine::TrackChangeFlags, const Playlist::AutoScroll autoscroll);
void FatalError();
void ValidSongRequested(const QUrl&);
@@ -205,7 +206,7 @@ class Player : public PlayerInterface {
private:
// Returns true if we were supposed to stop after this track.
bool HandleStopAfter();
bool HandleStopAfter(const Playlist::AutoScroll autoscroll);
private:
Application *app_;
@@ -221,6 +222,7 @@ class Player : public PlayerInterface {
PlaylistItemPtr current_item_;
Engine::TrackChangeFlags stream_change_type_;
Playlist::AutoScroll autoscroll_;
Engine::State last_state_;
int nb_errors_received_;