diff options
Diffstat (limited to 'src/queue')
-rw-r--r-- | src/queue/Playlist.cxx | 3 | ||||
-rw-r--r-- | src/queue/Playlist.hxx | 12 | ||||
-rw-r--r-- | src/queue/PlaylistControl.cxx | 34 | ||||
-rw-r--r-- | src/queue/Queue.cxx | 21 | ||||
-rw-r--r-- | src/queue/Queue.hxx | 22 |
5 files changed, 81 insertions, 11 deletions
diff --git a/src/queue/Playlist.cxx b/src/queue/Playlist.cxx index 667e3457f..dfeb0d163 100644 --- a/src/queue/Playlist.cxx +++ b/src/queue/Playlist.cxx @@ -310,8 +310,7 @@ playlist::SetRandom(PlayerControl &pc, bool status) playlist is played after that */ unsigned current_order = queue.PositionToOrder(current_position); - queue.MoveOrder(current_order, 0); - current = 0; + current = queue.MoveOrder(current_order, 0); } else current = -1; } else diff --git a/src/queue/Playlist.hxx b/src/queue/Playlist.hxx index 32489e354..c04a0913a 100644 --- a/src/queue/Playlist.hxx +++ b/src/queue/Playlist.hxx @@ -356,6 +356,18 @@ public: } void SetConsume(bool new_value); + +private: + /** + * Prepare a manual song change: move the given song to the + * current playback order. This is done to avoid skipping + * upcoming songs in the order list. The newly selected song + * shall be inserted in the order list, and the rest shall be + * played after that as previously planned. + * + * @return the new order number of the given song + */ + unsigned MoveOrderToCurrent(unsigned old_order); }; #endif diff --git a/src/queue/PlaylistControl.cxx b/src/queue/PlaylistControl.cxx index 99012aedf..4b17386ae 100644 --- a/src/queue/PlaylistControl.cxx +++ b/src/queue/PlaylistControl.cxx @@ -56,6 +56,30 @@ playlist::Stop(PlayerControl &pc) } } +unsigned +playlist::MoveOrderToCurrent(unsigned old_order) +{ + if (!queue.random) + /* no-op because there is no order list */ + return old_order; + + if (playing) { + /* already playing: move the specified song after the + current one (because the current one has already + been playing and shall not be played again) */ + return queue.MoveOrderAfter(old_order, current); + } else if (current >= 0) { + /* not playing: move the specified song before the + current one, so it will be played eventually */ + return queue.MoveOrderBefore(old_order, current); + } else { + /* not playing anything: move the specified song to + the front */ + queue.SwapOrders(old_order, 0); + return 0; + } +} + void playlist::PlayPosition(PlayerControl &pc, int song) { @@ -90,13 +114,7 @@ playlist::PlayPosition(PlayerControl &pc, int song) number, because random mode is enabled */ i = queue.PositionToOrder(song); - if (!playing) - current = 0; - - /* swap the new song with the previous "current" one, - so playback continues as planned */ - queue.SwapOrders(i, current); - i = current; + i = MoveOrderToCurrent(i); } stop_on_error = false; @@ -205,6 +223,8 @@ playlist::SeekSongOrder(PlayerControl &pc, unsigned i, SongTime seek_time) /* seeking is not within the current song - prepare song change */ + i = MoveOrderToCurrent(i); + playing = true; current = i; diff --git a/src/queue/Queue.cxx b/src/queue/Queue.cxx index d248f306b..720778099 100644 --- a/src/queue/Queue.cxx +++ b/src/queue/Queue.cxx @@ -195,7 +195,7 @@ Queue::MoveRange(unsigned start, unsigned end, unsigned to) noexcept } } -void +unsigned Queue::MoveOrder(unsigned from_order, unsigned to_order) noexcept { assert(from_order < length); @@ -212,6 +212,25 @@ Queue::MoveOrder(unsigned from_order, unsigned to_order) noexcept } order[to_order] = from_position; + return to_order; +} + +unsigned +Queue::MoveOrderBefore(unsigned from_order, unsigned to_order) noexcept +{ + /* if "from_order" comes before "to_order", then the new + position is "to_order-1"; otherwise the "to_order" song is + moved one ahead */ + return MoveOrder(from_order, to_order - (from_order < to_order)); +} + +unsigned +Queue::MoveOrderAfter(unsigned from_order, unsigned to_order) noexcept +{ + /* if "from_order" comes after "to_order", then the new + position is "to_order+1"; otherwise the "to_order" song is + moved one back */ + return MoveOrder(from_order, to_order + (from_order > to_order)); } void diff --git a/src/queue/Queue.hxx b/src/queue/Queue.hxx index bd2f95c1a..06e800479 100644 --- a/src/queue/Queue.hxx +++ b/src/queue/Queue.hxx @@ -284,8 +284,28 @@ struct Queue { /** * Moves a song to a new position in the "order" list. + * + * @return to_order + */ + unsigned MoveOrder(unsigned from_order, unsigned to_order) noexcept; + + /** + * Moves a song to a new position in the "order" list before + * the given one. + * + * @return the new order number of the given "from" song + */ + unsigned MoveOrderBefore(unsigned from_order, + unsigned to_order) noexcept; + + /** + * Moves a song to a new position in the "order" list after + * the given one. + * + * @return the new order number of the given "from" song */ - void MoveOrder(unsigned from_order, unsigned to_order) noexcept; + unsigned MoveOrderAfter(unsigned from_order, + unsigned to_order) noexcept; /** * Moves a song to a new position. |