summaryrefslogtreecommitdiff
path: root/src/queue
diff options
context:
space:
mode:
Diffstat (limited to 'src/queue')
-rw-r--r--src/queue/Playlist.cxx3
-rw-r--r--src/queue/Playlist.hxx12
-rw-r--r--src/queue/PlaylistControl.cxx34
-rw-r--r--src/queue/Queue.cxx21
-rw-r--r--src/queue/Queue.hxx22
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.