diff options
Diffstat (limited to 'lua/main_menu.lua')
| -rw-r--r-- | lua/main_menu.lua | 120 |
1 files changed, 108 insertions, 12 deletions
diff --git a/lua/main_menu.lua b/lua/main_menu.lua index 9c52340b..da90fd44 100644 --- a/lua/main_menu.lua +++ b/lua/main_menu.lua @@ -7,23 +7,94 @@ local playing = require("playing") local styles = require("styles") local filesystem = require("filesystem") local screen = require("screen") +local font = require("font") +local theme = require("theme") +local img = require("images") +local playback = require("playback") return widgets.MenuScreen:new { createUi = function(self) widgets.MenuScreen.createUi(self) + -- At the top, a card showing details about the current track. Hidden if + -- there is no track currently playing. + -- || Cool Song 0:01 + + local now_playing = lvgl.Button(self.root, { + flex = { + flex_direction = "row", + flex_wrap = "nowrap", + justify_content = "flex-start", + align_items = "center", + align_content = "flex-start", + }, + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + margin_all = 2, + pad_column = 4, + border_color = "#FFFFFF", + border_width = 1, + }) + + local play_pause = now_playing:Image { src = img.play } + local title = now_playing:Label { + flex_grow = 1, + h = lvgl.SIZE_CONTENT, + text = " ", + long_mode = 1, + } + local time_remaining = now_playing:Label { + text = " ", + text_font = font.fusion_10, + } + + now_playing:onClicked(function() backstack.push(playing:new()) end) + + local has_focus = false + local track_duration = nil + + self.bindings = self.bindings + { + playback.playing:bind(function(playing) + if playing then + play_pause:set_src(img.play) + else + play_pause:set_src(img.pause) + end + end), + playback.track:bind(function(track) + if not track then + now_playing:add_flag(lvgl.FLAG.HIDDEN) + return + else + has_focus = true + now_playing:clear_flag(lvgl.FLAG.HIDDEN) + end + title:set { text = track.title } + if track.duration then + track_duration = track.duration + end + end), + playback.position:bind(function(pos) + if not pos then return end + if not track_duration then return end + local remaining = track_duration - pos + if remaining < 0 then remaining = 0 end + time_remaining:set { + text = string.format("%d:%02d", remaining // 60, remaining % 60) + } + end), + } + + -- Next, a list showing the user's prefer's music source. This defaults to + -- a list of all available database indexes, but could also be the contents + -- of the SD card root. + local list = lvgl.List(self.root, { w = lvgl.PCT(100), h = lvgl.PCT(100), flex_grow = 1, }) - local now_playing = list:add_btn(nil, "Now Playing") - now_playing:onClicked(function() - backstack.push(playing:new()) - end) - now_playing:add_style(styles.list_item) - local indexes = database.indexes() for _, idx in ipairs(indexes) do local btn = list:add_btn(nil, tostring(idx)) @@ -34,21 +105,46 @@ return widgets.MenuScreen:new { }) end) btn:add_style(styles.list_item) + if not has_focus then + has_focus = true + btn:focus() + end end - local files = list:add_btn(nil, "Files") - files:onClicked(function() + -- Finally, the bottom bar with icon buttons for other device features. + + local bottom_bar = lvgl.Object(self.root, { + flex = { + flex_direction = "row", + flex_wrap = "nowrap", + justify_content = "space-evenly", + align_items = "center", + align_content = "flex-start", + }, + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + pad_top = 4, + }) + + local queue_btn = bottom_bar:Button {} + queue_btn:Image { src = img.queue } + theme.set_style(queue_btn, "icon_enabled") + + local files_btn = bottom_bar:Button {} + files_btn:onClicked(function() backstack.push(require("file_browser"):new { title = "Files", iterator = filesystem.iterator(""), }) end) - files:add_style(styles.list_item) + files_btn:Image { src = img.files } + theme.set_style(files_btn, "icon_enabled") - local settings = list:add_btn(nil, "Settings") - settings:onClicked(function() + local settings_btn = bottom_bar:Button {} + settings_btn:onClicked(function() backstack.push(require("settings"):new()) end) - settings:add_style(styles.list_item) + settings_btn:Image { src = img.settings } + theme.set_style(settings_btn, "icon_enabled") end, } |
