From 3f1fadbeef571a6653f5648c2b78073ddd37d169 Mon Sep 17 00:00:00 2001 From: Robin Howard Date: Sun, 21 Jan 2024 18:13:49 +1100 Subject: [PATCH 1/3] Plumb queue next+previous through to Lua, incl. with stubs and docs. --- ldoc-stubs/queue.lua | 6 ++++++ luals-stubs/queue.lua | 3 +++ src/ui/include/ui_fsm.hpp | 3 +++ src/ui/ui_fsm.cpp | 26 ++++++++++++++++++++------ 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/ldoc-stubs/queue.lua b/ldoc-stubs/queue.lua index 83849624..2d6a2a29 100644 --- a/ldoc-stubs/queue.lua +++ b/ldoc-stubs/queue.lua @@ -19,4 +19,10 @@ queue.replay = types.Property -- @see types.Property queue.random = types.Property +--- Moves forward in the play queue, looping back around to the beginning if repeat is on. +function queue.next() end + +--- Moves backward in the play queue, looping back around to the end if repeat is on. +function queue.previous() end + return queue diff --git a/luals-stubs/queue.lua b/luals-stubs/queue.lua index 0c63b8c1..ece99c69 100644 --- a/luals-stubs/queue.lua +++ b/luals-stubs/queue.lua @@ -8,4 +8,7 @@ --- @field random Property Determines whether, when progressing to the next track in the queue, the next track will be chosen randomly. The random selection algorithm used is a Miller Shuffle, which guarantees that no repeat selections will be made until every item in the queue has been played. Writeable. local queue = {} +function queue.next() end +function queue.previous() end + return queue diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp index 9de1169b..3ddef738 100644 --- a/src/ui/include/ui_fsm.hpp +++ b/src/ui/include/ui_fsm.hpp @@ -164,6 +164,9 @@ class Lua : public UiState { auto SetPlaying(const lua::LuaValue&) -> bool; auto SetRandom(const lua::LuaValue&) -> bool; auto SetRepeat(const lua::LuaValue&) -> bool; + + auto QueueNext(lua_State*) -> int; + auto QueuePrevious(lua_State*) -> int; }; } // namespace states diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp index e532e693..fe790816 100644 --- a/src/ui/ui_fsm.cpp +++ b/src/ui/ui_fsm.cpp @@ -396,12 +396,16 @@ void Lua::entry() { {"track", &sPlaybackTrack}, {"position", &sPlaybackPosition}, }); - sLua->bridge().AddPropertyModule("queue", { - {"position", &sQueuePosition}, - {"size", &sQueueSize}, - {"replay", &sQueueRepeat}, - {"random", &sQueueRandom}, - }); + sLua->bridge().AddPropertyModule( + "queue", + { + {"next", [&](lua_State* s) { return QueueNext(s); }}, + {"previous", [&](lua_State* s) { return QueuePrevious(s); }}, + {"position", &sQueuePosition}, + {"size", &sQueueSize}, + {"replay", &sQueueRepeat}, + {"random", &sQueueRandom}, + }); sLua->bridge().AddPropertyModule("volume", { {"current_pct", &sVolumeCurrentPct}, @@ -476,6 +480,16 @@ auto Lua::PushLuaScreen(lua_State* s) -> int { return 0; } +auto Lua::QueueNext(lua_State*) -> int { + sServices->track_queue().next(); + return 0; +} + +auto Lua::QueuePrevious(lua_State*) -> int { + sServices->track_queue().previous(); + return 0; +} + auto Lua::PopLuaScreen(lua_State* s) -> int { PopScreen(); luavgl_set_root(s, sCurrentScreen->content()); From 429abd12377e2b79336e6364d6743bb3df50b3ac Mon Sep 17 00:00:00 2001 From: Robin Howard Date: Sun, 21 Jan 2024 18:14:33 +1100 Subject: [PATCH 2/3] Fix bug where calling TrackQueue's next() repeatedly would increase the position despite running off the end of the queue. --- src/audio/track_queue.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/audio/track_queue.cpp b/src/audio/track_queue.cpp index 7e08e3a2..6bab60e7 100644 --- a/src/audio/track_queue.cpp +++ b/src/audio/track_queue.cpp @@ -200,9 +200,12 @@ auto TrackQueue::next() -> void { shuffle_->next(); pos_ = shuffle_->current(); } else { - pos_++; - if (pos_ >= tracks_.size() && repeat_) { - pos_ = 0; + if (pos_ + 1 >= tracks_.size()) { + if (repeat_) { + pos_ = 0; + } + } else { + pos_++; } } From 2f93ac3c59dd04a238f949ba5b28ad4fcbaa9a47 Mon Sep 17 00:00:00 2001 From: Robin Howard Date: Sun, 21 Jan 2024 18:16:28 +1100 Subject: [PATCH 3/3] Add next+prev buttons to the Now Playing screen. --- lua/playing.lua | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/lua/playing.lua b/lua/playing.lua index bb3f9f27..df15545a 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -5,6 +5,15 @@ local font = require("font") local playback = require("playback") local queue = require("queue") +local img = { + play = "//lua/img/play.png", + pause = "//lua/img/pause.png", + next = "//lua/img/next.png", + next_disabled = "//lua/img/next_disabled.png", + prev = "//lua/img/prev.png", + prev_disabled = "//lua/img/prev_disabled.png", +} + return function(opts) local screen = {} screen.root = lvgl.Object(nil, { @@ -106,19 +115,20 @@ return function(opts) controls:Object({ flex_grow = 1, h = 1 }) -- spacer - controls:Image { - src = "//lua/img/prev.png", - } + local prev_btn = controls:Button {} + prev_btn:onClicked(queue.previous) + local prev_img = prev_btn:Image { src = img.prev_disabled } + local play_pause_btn = controls:Button {} play_pause_btn:onClicked(function() playback.playing:set(not playback.playing:get()) end) - local play_pause_img = play_pause_btn:Image { - src = "//lua/img/pause.png", - } - controls:Image { - src = "//lua/img/next.png", - } + local play_pause_img = play_pause_btn:Image { src = img.pause } + + local next_btn = controls:Button {} + next_btn:onClicked(queue.next) + local next_img = next_btn:Image { src = img.next_disabled } + controls:Object({ flex_grow = 1, h = 1 }) -- spacer local end_time = controls:Label { @@ -136,9 +146,9 @@ return function(opts) screen.bindings = { playback.playing:bind(function(playing) if playing then - play_pause_img:set_src("//lua/img/pause.png") + play_pause_img:set_src(img.pause) else - play_pause_img:set_src("//lua/img/play.png") + play_pause_img:set_src(img.play) end end), playback.position:bind(function(pos) @@ -162,6 +172,13 @@ return function(opts) queue.position:bind(function(pos) if not pos then return end playlist_pos:set { text = tostring(pos) } + + next_img:set_src( + pos < queue.size:get() and img.next or img.next_disabled + ) + prev_img:set_src( + pos > 1 and img.prev or img.prev_disabled + ) end), queue.size:bind(function(num) if not num then return end