diff --git a/src/libaudcore/drct.cc b/src/libaudcore/drct.cc index 15b5a2ca2..d2177d117 100644 --- a/src/libaudcore/drct.cc +++ b/src/libaudcore/drct.cc @@ -217,7 +217,7 @@ EXPORT void aud_drct_pl_prev() if (playlist == Playlist()) playlist = Playlist::active_playlist(); - playlist.prev_song(); + playlist.prev_song(aud_get_bool("repeat")); } EXPORT void aud_drct_pl_prev_album() @@ -226,7 +226,7 @@ EXPORT void aud_drct_pl_prev_album() if (playlist == Playlist()) playlist = Playlist::active_playlist(); - playlist.prev_album(); + playlist.prev_album(aud_get_bool("repeat")); } static void add_list(Index && items, int at, bool to_temp, diff --git a/src/libaudcore/playlist-data.cc b/src/libaudcore/playlist-data.cc index cdf7fda92..9a789e12d 100644 --- a/src/libaudcore/playlist-data.cc +++ b/src/libaudcore/playlist-data.cc @@ -866,12 +866,18 @@ PlaylistData::PosChange PlaylistData::shuffle_pos_random(bool repeat, return NO_POS; } -int PlaylistData::pos_before(int ref_pos, bool shuffle) const +int PlaylistData::pos_before(int ref_pos, bool shuffle, bool repeat) const { if (shuffle) return shuffle_pos_before(ref_pos); - return (ref_pos > 0) ? ref_pos - 1 : -1; + if (ref_pos > 0) + return ref_pos - 1; + + if (repeat) + return m_entries.len() - 1; + + return -1; } PlaylistData::PosChange PlaylistData::pos_after(int ref_pos, bool shuffle, @@ -1005,10 +1011,10 @@ void PlaylistData::set_position(int entry_num) queue_position_change(); } -bool PlaylistData::prev_song() +bool PlaylistData::prev_song(bool repeat) { bool shuffle = aud_get_bool("shuffle"); - int pos = pos_before(position(), shuffle); + int pos = pos_before(position(), shuffle, repeat); if (pos < 0) return false; @@ -1027,7 +1033,7 @@ bool PlaylistData::next_song(bool repeat) return true; } -bool PlaylistData::prev_album() +bool PlaylistData::prev_album(bool repeat) { bool shuffle = aud_get_bool("shuffle"); int pos = position(); @@ -1041,7 +1047,7 @@ bool PlaylistData::prev_album() while (1) { - auto prev_entry = entry_at(pos_before(pos, shuffle)); + auto prev_entry = entry_at(pos_before(pos, shuffle, repeat)); if (!prev_entry || !same_album(entry->tuple, prev_entry->tuple)) break; @@ -1053,7 +1059,7 @@ bool PlaylistData::prev_album() // we're at the start of the current album // one more song back puts us in the previous album - pos = pos_before(pos, shuffle); + pos = pos_before(pos, shuffle, repeat); in_prev_album = true; } diff --git a/src/libaudcore/playlist-data.h b/src/libaudcore/playlist-data.h index 662261e3a..cc6394d92 100644 --- a/src/libaudcore/playlist-data.h +++ b/src/libaudcore/playlist-data.h @@ -100,9 +100,9 @@ class PlaylistData void set_position(int entry_num); - bool prev_song(); + bool prev_song(bool repeat); bool next_song(bool repeat); - bool prev_album(); + bool prev_album(bool repeat); bool next_album(bool repeat); int next_unscanned_entry(int entry_num) const; @@ -159,7 +159,7 @@ class PlaylistData PosChange shuffle_pos_after(int ref_pos, bool by_album) const; PosChange shuffle_pos_random(bool repeat, bool by_album) const; - int pos_before(int ref_pos, bool shuffle) const; + int pos_before(int ref_pos, bool shuffle, bool repeat) const; PosChange pos_after(int ref_pos, bool shuffle, bool by_album) const; PosChange pos_new(bool repeat, bool shuffle, bool by_album, int hint_pos) const; diff --git a/src/libaudcore/playlist.cc b/src/libaudcore/playlist.cc index 910d352b4..c7c247f3d 100644 --- a/src/libaudcore/playlist.cc +++ b/src/libaudcore/playlist.cc @@ -657,11 +657,19 @@ EXPORT void Playlist::set_position(int entry_num) const } EXPORT bool Playlist::prev_song() const { - SIMPLE_WRAPPER(bool, false, prev_song); + SIMPLE_WRAPPER(bool, false, prev_song, false); +} +EXPORT bool Playlist::prev_song(bool repeat) const +{ + SIMPLE_WRAPPER(bool, false, prev_song, repeat); } EXPORT bool Playlist::prev_album() const { - SIMPLE_WRAPPER(bool, false, prev_album); + SIMPLE_WRAPPER(bool, false, prev_album, false); +} +EXPORT bool Playlist::prev_album(bool repeat) const +{ + SIMPLE_WRAPPER(bool, false, prev_album, repeat); } EXPORT bool Playlist::next_song(bool repeat) const { diff --git a/src/libaudcore/playlist.h b/src/libaudcore/playlist.h index a521f1cb2..05088acea 100644 --- a/src/libaudcore/playlist.h +++ b/src/libaudcore/playlist.h @@ -253,12 +253,24 @@ class Playlist * true on success, false if playlist position was not changed. */ bool prev_song() const; + /* Returns the playlist position to the previous entry in playback order. + * At the beginning of the playlist, wraps around to the end if + * is true. Returns true on success, false if playlist position was not + * changed. */ + bool prev_song(bool repeat) const; + /* Returns the playlist position to the first entry in playback order where * the album is not the current album. Does not support wrapping past the * beginning of the playlist. Returns true on success, false if playlist * position was not changed. */ bool prev_album() const; + /* Returns the playlist position to the first entry of the previous album + * in playback order, taking current shuffle settings into account. At the + * beginning of the playlist, wraps around to the end if is true. + * Returns true on success, false if playlist position was not changed. */ + bool prev_album(bool repeat) const; + /* Gets/sets the entry which has keyboard focus (-1 = no entry). */ int get_focus() const; void set_focus(int entry) const;