diff --git a/lua/images.lua b/lua/images.lua index 404ae66e..b10d0f74 100644 --- a/lua/images.lua +++ b/lua/images.lua @@ -28,6 +28,7 @@ local img = { listened = lvgl.ImgData("//lua/img/listened.png"), unlistened = lvgl.ImgData("//lua/img/unlistened.png"), info = lvgl.ImgData("//lua/img/info.png"), + menu = lvgl.ImgData("//lua/img/menu.png"), } return img diff --git a/lua/img/menu.png b/lua/img/menu.png new file mode 100644 index 00000000..afb1a921 Binary files /dev/null and b/lua/img/menu.png differ diff --git a/lua/playing.lua b/lua/playing.lua index cee25c21..08cdaaa2 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -10,7 +10,7 @@ local playback = require("playback") local queue = require("queue") local screen = require("screen") local theme = require("theme") -local track_info = require("track_info") +local playing_menu = require("playing_menu") local img = require("images") @@ -235,13 +235,13 @@ return screen:new { theme.set_subject(shuffle_btn, icon_enabled_class) local shuffle_desc = widgets.Description(shuffle_btn) - local info_btn = controls:Button {} - info_btn:onClicked(function() - backstack.push(track_info:new()) + local menu_btn = controls:Button {} + menu_btn:onClicked(function() + backstack.push(playing_menu:new()) end) - local info_img = info_btn:Image { src = img.info } - theme.set_subject(info_btn, icon_enabled_class) - local info_desc = widgets.Description(info_btn, "Track info") + local menu_img = menu_btn:Image { src = img.menu } + theme.set_subject(menu_btn, icon_enabled_class) + local menu_desc = widgets.Description(menu_btn, "Track info") controls:Object({ flex_grow = 1, h = 1 }) -- spacer @@ -273,9 +273,15 @@ return screen:new { end), queue.ready:bind(function(ready) if not ready then - title:set { text = "Loading..." } + if queue.loading:get() then + title:set { text = "Loading..." } + else + title:set{text=""} + end album:set{text=""} artist:set{text=""} + cur_time:set { text = format_time(0) } + end_time:set { text = format_time(0) } end end), playback.track:bind(function(track) diff --git a/lua/playing_menu.lua b/lua/playing_menu.lua new file mode 100644 index 00000000..8ab2961b --- /dev/null +++ b/lua/playing_menu.lua @@ -0,0 +1,141 @@ + +-- SPDX-FileCopyrightText: 2025 ailurux +-- +-- SPDX-License-Identifier: GPL-3.0-only + +local lvgl = require("lvgl") +local widgets = require("widgets") +local backstack = require("backstack") +local font = require("font") +local playback = require("playback") +local queue = require("queue") +local screen = require("screen") +local theme = require("theme") +local track_info = require("track_info") +local styles = require("styles") + +return screen:new { + create_ui = function(self) + self.root = lvgl.Object(nil, { + flex = { + flex_direction = "column", + flex_wrap = "wrap", + justify_content = "center", + align_items = "center", + align_content = "center", + }, + w = lvgl.HOR_RES(), + h = lvgl.VER_RES(), + }) + self.root:center() + + self.status_bar = widgets.StatusBar(self, { + back_cb = backstack.pop, + transparent_bg = true, + }) + + + local menu_items = lvgl.List(self.root, { + w = lvgl.PCT(100), + h = lvgl.PCT(100), + flex_grow = 1, + }) + + local info_btn = menu_items:add_btn(nil, "Track Info") + info_btn:onClicked(function() + backstack.push(track_info:new()) + end) + info_btn:add_style(styles.list_item) + + local current_artist = nil + local album_artist = nil + local current_album = nil + + local artist_btn = menu_items:add_btn(nil, "Go To Artist") + artist_btn:add_style(styles.list_item) + artist_btn:onClicked(function() + local found_iter = nil + local media_type = nil + for _, idx in ipairs(database.indexes()) do + if idx:id() == database.IndexTypes.ALL_ARTISTS then + -- Find the sub-index for this artist. + local artist_iter = idx:iter() + -- Workaround for lack of pairs/ipairs on these iterators. + local artist_record = artist_iter:next() + while artist_record do + if artist_record:title() == current_artist then + found_iter = artist_record:contents() + media_type = idx:type() + goto artist_done + end + artist_record = artist_iter:next() + end + end + end + ::artist_done:: + if found_iter then + backstack.push(require("browser"):new { + title = current_artist, + iterator = found_iter, + mediatype = media_type, + }) + end + end) + + local album_btn = menu_items:add_btn(nil, "Go To Album") + album_btn:add_style(styles.list_item) + album_btn:onClicked(function() + local found_iter = nil + local media_type = nil + for _, idx in ipairs(database.indexes()) do + if idx:id() == database.IndexTypes.ALBUMS_BY_ARTIST then + -- Find the sub-index for this artist. + local artist_iter = idx:iter() + -- Workaround for lack of pairs/ipairs on these iterators. + local artist_record = artist_iter:next() + while artist_record do + if artist_record:title() == album_artist then + -- Find the sub-sub-index for this album. + local album_iter = artist_record:contents() + local album_record = album_iter:next() + while album_record do + if album_record:title() == current_album then + found_iter = album_record:contents() + media_type = idx:type() + goto album_done + end + album_record = album_iter:next() + end + end + artist_record = artist_iter:next() + end + end + end + ::album_done:: + if found_iter then + backstack.push(require("browser"):new { + title = current_album, + iterator = found_iter, + mediatype = media_type, + }) + end + end) + + + local clear_btn = menu_items:add_btn(nil, "Clear Queue") + clear_btn:onClicked(function() + queue.clear() + backstack.pop() + end) + clear_btn:add_style(styles.list_item) + + self.bindings = self.bindings + { + playback.track:bind(function(track) + current_artist = track.artist + current_album = track.album + album_artist = track.album_artist + end), + } + + end +} diff --git a/src/tangara/lua/lua_database.cpp b/src/tangara/lua/lua_database.cpp index 2a3ab59d..e79d6141 100644 --- a/src/tangara/lua/lua_database.cpp +++ b/src/tangara/lua/lua_database.cpp @@ -406,6 +406,31 @@ static auto lua_database(lua_State* state) -> int { lua_rawset(state, -3); + lua_pushliteral(state, "IndexTypes"); + lua_newtable(state); + lua_pushliteral(state, "ALBUMS_BY_ARTIST"); + lua_pushinteger(state, (int)database::kAlbumsByArtist.id); + lua_rawset(state, -3); + lua_pushliteral(state, "TRACKS_BY_GENRE"); + lua_pushinteger(state, (int)database::kTracksByGenre.id); + lua_rawset(state, -3); + lua_pushliteral(state, "ALL_TRACKS"); + lua_pushinteger(state, (int)database::kAllTracks.id); + lua_rawset(state, -3); + lua_pushliteral(state, "ALL_ALBUMS"); + lua_pushinteger(state, (int)database::kAllAlbums.id); + lua_rawset(state, -3); + lua_pushliteral(state, "ALL_ARTISTS"); + lua_pushinteger(state, (int)database::kAllArtists.id); + lua_rawset(state, -3); + lua_pushliteral(state, "PODCASTS"); + lua_pushinteger(state, (int)database::kPodcasts.id); + lua_rawset(state, -3); + lua_pushliteral(state, "AUDIOBOOKS"); + lua_pushinteger(state, (int)database::kAudiobooks.id); + lua_rawset(state, -3); + lua_rawset(state, -3); + return 1; }