diff --git a/lua/images.lua b/lua/images.lua index d7939305..5acfa8fe 100644 --- a/lua/images.lua +++ b/lua/images.lua @@ -23,6 +23,7 @@ local img = { usb = lvgl.ImgData("//lua/img/usb.png"), listened = lvgl.ImgData("//lua/img/listened.png"), unlistened = lvgl.ImgData("//lua/img/unlistened.png"), + info = lvgl.ImgData("//lua/img/info.png"), } return img diff --git a/lua/img/info.png b/lua/img/info.png new file mode 100644 index 00000000..9a14815e Binary files /dev/null and b/lua/img/info.png differ diff --git a/lua/playing.lua b/lua/playing.lua index 86ecf20c..84e31962 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -6,6 +6,7 @@ local playback = require("playback") local queue = require("queue") local screen = require("screen") local theme = require("theme") +local track_info = require("track_info") local img = require("images") @@ -176,7 +177,7 @@ return screen:new { }, w = lvgl.PCT(100), h = lvgl.SIZE_CONTENT, - pad_column = 8, + pad_column = 6, pad_all = 2, } @@ -230,6 +231,14 @@ 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()) + 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") + controls:Object({ flex_grow = 1, h = 1 }) -- spacer diff --git a/lua/track_info.lua b/lua/track_info.lua new file mode 100644 index 00000000..4018f246 --- /dev/null +++ b/lua/track_info.lua @@ -0,0 +1,85 @@ +local backstack = require("backstack") +local font = require("font") +local lvgl = require("lvgl") +local playback = require("playback") +local screen = require("screen") +local widgets = require("widgets") + +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 info = lvgl.List(self.root, { + w = lvgl.PCT(100), + h = lvgl.PCT(100), + flex_grow = 1, + }) + + -- Use buttons so we can scroll through the list, and labels so we can + -- change the text as the track changes. + local label = function(text) + local b = info:add_btn(nil, "") + local ret = b:Label { + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + text = text, + text_font = font.fusion_10, + text_align = 1, -- left + } + return ret + end + + local album_artist = label("Loading...") + local genre = label("") + local disc = label("") + local tracknum = label("") + local encoding = label("") + local sample_rate = label("") + local num_channels = label("") + local bits_per_sample = label("") + local path = label("") + + self.bindings = self.bindings + { + playback.track:bind(function(track) + if not track then + return + end + + -- Genres are stored in a table of (genre, bool) pairs + local function genres(tbl) + local all = {} + for item,_ in pairs(tbl) do + table.insert(all, item) + end + return table.concat(all, ", ") + end + + album_artist:set { text = "Album artist: " .. (track.album_artist or "") } + genre:set { text = "Genre: " .. (track.genre and genres(track.genre) or "") } + disc:set { text = "Disc: " .. (track.disc or "") } + tracknum:set { text = "Track: " .. (track.track or "") } + encoding:set { text = "Encoding: " .. (track.encoding or "") } + sample_rate:set { text = "Sample rate: " .. (track.sample_rate or "") } + num_channels:set { text = "Channels: " .. (track.num_channels or "") } + bits_per_sample:set { text = "Bits per sample: " .. (track.bits_per_sample or "") } + path:set { text = "Path: " .. (track.uri or "") } + end), + } + end, +}