From 665679b8854d34c13d8eb92167aa8a4691619d8b Mon Sep 17 00:00:00 2001 From: ailurux Date: Fri, 16 Feb 2024 12:55:11 +1100 Subject: WIP: seeking in lua example --- lua/playing.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lua/playing.lua') diff --git a/lua/playing.lua b/lua/playing.lua index c6a3f47e..22b3390f 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -147,7 +147,8 @@ return function(opts) local play_pause_btn = controls:Button {} play_pause_btn:onClicked(function() - playback.playing:set(not playback.playing:get()) + --playback.playing:set(not playback.playing:get()) + playback.position:set(playback.position:get() + 5) end) play_pause_btn:focus() local play_pause_img = play_pause_btn:Image { src = img.pause } -- cgit v1.2.3 From d25e5860c7cfcd4a5349c67f088ed6e4f55ffaed Mon Sep 17 00:00:00 2001 From: ailurux Date: Fri, 16 Feb 2024 15:10:45 +1100 Subject: Only update scrubber if not currently dragging --- lua/playing.lua | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'lua/playing.lua') diff --git a/lua/playing.lua b/lua/playing.lua index 22b3390f..4767e42f 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -112,13 +112,17 @@ return function(opts) } playlist:Object({ w = 3, h = 1 }) -- spacer - local scrubber = screen.root:Bar { + local scrubber = screen.root:Slider { w = lvgl.PCT(100), h = 5, range = { min = 0, max = 100 }, value = 0, } + scrubber:onevent(lvgl.EVENT.RELEASED, function() + playback.position:set(scrubber:value()) + end) + local controls = screen.root:Object { flex = { flex_direction = "row", @@ -147,8 +151,7 @@ return function(opts) local play_pause_btn = controls:Button {} play_pause_btn:onClicked(function() - --playback.playing:set(not playback.playing:get()) - playback.position:set(playback.position:get() + 5) + playback.playing:set(not playback.playing:get()) end) play_pause_btn:focus() local play_pause_img = play_pause_btn:Image { src = img.pause } @@ -183,7 +186,9 @@ return function(opts) cur_time:set { text = format_time(pos) } - scrubber:set { value = pos } + if not scrubber:is_dragged() then + scrubber:set { value = pos } + end end), playback.track:bind(function(track) if not track then return end -- cgit v1.2.3 From ef72b25660912ff247997089abfb93e9f0b52809 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 7 Mar 2024 10:59:03 +1100 Subject: use prototype inheritance for lua screens, rather than functions this gives us a way to give each screen nice little hooks, like 'onShown' and 'onHidden'. later we can use these hooks to disable bindings for screens that aren't in-use. --- lua/playing.lua | 439 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 224 insertions(+), 215 deletions(-) (limited to 'lua/playing.lua') diff --git a/lua/playing.lua b/lua/playing.lua index 4767e42f..947bdec9 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -4,6 +4,7 @@ local backstack = require("backstack") local font = require("font") local playback = require("playback") local queue = require("queue") +local screen = require("screen") local img = { play = "//lua/img/play.png", @@ -18,219 +19,227 @@ local img = { repeat_disabled = "//lua/img/repeat_disabled.png", } -return function(opts) - local screen = {} - screen.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(), - }) - screen.root:center() - - screen.status_bar = widgets.StatusBar(screen.root, { - back_cb = backstack.pop, - transparent_bg = true, - }) - - local info = screen.root:Object { - flex = { - flex_direction = "column", - flex_wrap = "wrap", - justify_content = "center", - align_items = "center", - align_content = "center", - }, - w = lvgl.PCT(100), - h = lvgl.SIZE_CONTENT, - flex_grow = 1, - } - - local artist = info:Label { - w = lvgl.PCT(100), - h = lvgl.SIZE_CONTENT, - text = "", - text_font = font.fusion_10, - text_align = 2, - } - - local title = info:Label { - w = lvgl.PCT(100), - h = lvgl.SIZE_CONTENT, - text = "", - text_align = 2, - } - - local playlist = screen.root:Object { - flex = { - flex_direction = "row", - justify_content = "center", - align_items = "center", - align_content = "center", - }, - w = lvgl.PCT(100), - h = lvgl.SIZE_CONTENT, - } - - playlist:Object({ w = 3, h = 1 }) -- spacer - - local cur_time = playlist:Label { - w = lvgl.SIZE_CONTENT, - h = lvgl.SIZE_CONTENT, - text = "", - text_font = font.fusion_10, - } - - playlist:Object({ flex_grow = 1, h = 1 }) -- spacer - - local playlist_pos = playlist:Label { - text = "", - text_font = font.fusion_10, - } - playlist:Label { - text = "/", - text_font = font.fusion_10, - } - local playlist_total = playlist:Label { - text = "", - text_font = font.fusion_10, - } - - playlist:Object({ flex_grow = 1, h = 1 }) -- spacer - - local end_time = playlist:Label { - w = lvgl.SIZE_CONTENT, - h = lvgl.SIZE_CONTENT, - align = lvgl.ALIGN.RIGHT_MID, - text = "", - text_font = font.fusion_10, - } - playlist:Object({ w = 3, h = 1 }) -- spacer - - local scrubber = screen.root:Slider { - w = lvgl.PCT(100), - h = 5, - range = { min = 0, max = 100 }, - value = 0, - } - - scrubber:onevent(lvgl.EVENT.RELEASED, function() - playback.position:set(scrubber:value()) - end) - - local controls = screen.root:Object { - flex = { - flex_direction = "row", - justify_content = "center", - align_items = "center", - align_content = "center", - }, - w = lvgl.PCT(100), - h = lvgl.SIZE_CONTENT, - pad_column = 8, - pad_all = 2, - } - - - controls:Object({ flex_grow = 1, h = 1 }) -- spacer - - local repeat_btn = controls:Button {} - repeat_btn:onClicked(function() - queue.repeat_track:set(not queue.repeat_track:get()) - end) - local repeat_img = repeat_btn:Image { src = img.repeat_enabled } - - 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) - play_pause_btn:focus() - 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 } - - local shuffle_btn = controls:Button {} - shuffle_btn:onClicked(function() - queue.random:set(not queue.random:get()) - end) - local shuffle_img = shuffle_btn:Image { src = img.shuffle } - - controls:Object({ flex_grow = 1, h = 1 }) -- spacer - - - local format_time = function(time) - return string.format("%d:%02d", time // 60, time % 60) +local is_now_playing_shown = false + +return screen:new { + createUi = 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.root, { + back_cb = backstack.pop, + transparent_bg = true, + }) + + local info = self.root:Object { + flex = { + flex_direction = "column", + flex_wrap = "wrap", + justify_content = "center", + align_items = "center", + align_content = "center", + }, + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + flex_grow = 1, + } + + local artist = info:Label { + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + text = "", + text_font = font.fusion_10, + text_align = 2, + } + + local title = info:Label { + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + text = "", + text_align = 2, + } + + local playlist = self.root:Object { + flex = { + flex_direction = "row", + justify_content = "center", + align_items = "center", + align_content = "center", + }, + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + } + + playlist:Object({ w = 3, h = 1 }) -- spacer + + local cur_time = playlist:Label { + w = lvgl.SIZE_CONTENT, + h = lvgl.SIZE_CONTENT, + text = "", + text_font = font.fusion_10, + } + + playlist:Object({ flex_grow = 1, h = 1 }) -- spacer + + local playlist_pos = playlist:Label { + text = "", + text_font = font.fusion_10, + } + playlist:Label { + text = "/", + text_font = font.fusion_10, + } + local playlist_total = playlist:Label { + text = "", + text_font = font.fusion_10, + } + + playlist:Object({ flex_grow = 1, h = 1 }) -- spacer + + local end_time = playlist:Label { + w = lvgl.SIZE_CONTENT, + h = lvgl.SIZE_CONTENT, + align = lvgl.ALIGN.RIGHT_MID, + text = "", + text_font = font.fusion_10, + } + playlist:Object({ w = 3, h = 1 }) -- spacer + + local scrubber = self.root:Slider { + w = lvgl.PCT(100), + h = 5, + range = { min = 0, max = 100 }, + value = 0, + } + + scrubber:onevent(lvgl.EVENT.RELEASED, function() + playback.position:set(scrubber:value()) + end) + + local controls = self.root:Object { + flex = { + flex_direction = "row", + justify_content = "center", + align_items = "center", + align_content = "center", + }, + w = lvgl.PCT(100), + h = lvgl.SIZE_CONTENT, + pad_column = 8, + pad_all = 2, + } + + + controls:Object({ flex_grow = 1, h = 1 }) -- spacer + + local repeat_btn = controls:Button {} + repeat_btn:onClicked(function() + queue.repeat_track:set(not queue.repeat_track:get()) + end) + local repeat_img = repeat_btn:Image { src = img.repeat_enabled } + + 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) + play_pause_btn:focus() + 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 } + + local shuffle_btn = controls:Button {} + shuffle_btn:onClicked(function() + queue.random:set(not queue.random:get()) + end) + local shuffle_img = shuffle_btn:Image { src = img.shuffle } + + controls:Object({ flex_grow = 1, h = 1 }) -- spacer + + + local format_time = function(time) + return string.format("%d:%02d", time // 60, time % 60) + end + + self.bindings = { + playback.playing:bind(function(playing) + if playing then + play_pause_img:set_src(img.pause) + else + play_pause_img:set_src(img.play) + end + end), + playback.position:bind(function(pos) + if not pos then return end + cur_time:set { + text = format_time(pos) + } + if not scrubber:is_dragged() then + scrubber:set { value = pos } + end + end), + playback.track:bind(function(track) + if not track then return end + end_time:set { + text = format_time(track.duration) + } + title:set { text = track.title } + artist:set { text = track.artist } + scrubber:set { + range = { min = 0, max = track.duration } + } + end), + 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.random:bind(function(shuffling) + if shuffling then + shuffle_img:set_src(img.shuffle) + else + shuffle_img:set_src(img.shuffle_disabled) + end + end), + queue.repeat_track:bind(function(en) + if en then + repeat_img:set_src(img.repeat_enabled) + else + repeat_img:set_src(img.repeat_disabled) + end + end), + queue.size:bind(function(num) + if not num then return end + playlist_total:set { text = tostring(num) } + end), + } + end, + onShown = function() is_now_playing_shown = true end, + onHidden = function() is_now_playing_shown = false end, + pushIfNotShown = function(self) + if not is_now_playing_shown then + backstack.push(self:new()) + end end - - screen.bindings = { - playback.playing:bind(function(playing) - if playing then - play_pause_img:set_src(img.pause) - else - play_pause_img:set_src(img.play) - end - end), - playback.position:bind(function(pos) - if not pos then return end - cur_time:set { - text = format_time(pos) - } - if not scrubber:is_dragged() then - scrubber:set { value = pos } - end - end), - playback.track:bind(function(track) - if not track then return end - end_time:set { - text = format_time(track.duration) - } - title:set { text = track.title } - artist:set { text = track.artist } - scrubber:set { - range = { min = 0, max = track.duration } - } - end), - 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.random:bind(function(shuffling) - if shuffling then - shuffle_img:set_src(img.shuffle) - else - shuffle_img:set_src(img.shuffle_disabled) - end - end), - queue.repeat_track:bind(function(en) - if en then - repeat_img:set_src(img.repeat_enabled) - else - repeat_img:set_src(img.repeat_disabled) - end - end), - queue.size:bind(function(num) - if not num then return end - playlist_total:set { text = tostring(num) } - end), - } - - return screen -end +} -- cgit v1.2.3 From 654dcb34d61bc8313ff0d3a62e73bdf945c231ad Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 20 Mar 2024 18:23:33 +1100 Subject: Support pinning decoded images to RAM --- lua/playing.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'lua/playing.lua') diff --git a/lua/playing.lua b/lua/playing.lua index 947bdec9..a0b9fde3 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -7,16 +7,16 @@ local queue = require("queue") local screen = require("screen") 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", - shuffle = "//lua/img/shuffle.png", - shuffle_disabled = "//lua/img/shuffle_disabled.png", - repeat_enabled = "//lua/img/repeat.png", - repeat_disabled = "//lua/img/repeat_disabled.png", + play = lvgl.ImgData("//lua/img/play.png"), + pause = lvgl.ImgData("//lua/img/pause.png"), + next = lvgl.ImgData("//lua/img/next.png"), + next_disabled = lvgl.ImgData("//lua/img/next_disabled.png"), + prev = lvgl.ImgData("//lua/img/prev.png"), + prev_disabled = lvgl.ImgData("//lua/img/prev_disabled.png"), + shuffle = lvgl.ImgData("//lua/img/shuffle.png"), + shuffle_disabled = lvgl.ImgData("//lua/img/shuffle_disabled.png"), + repeat_enabled = lvgl.ImgData("//lua/img/repeat.png"), + repeat_disabled = lvgl.ImgData("//lua/img/repeat_disabled.png"), } local is_now_playing_shown = false -- cgit v1.2.3 From 489fbceb2b5a623ea502ab647f023d2e2e566121 Mon Sep 17 00:00:00 2001 From: ailurux Date: Wed, 27 Mar 2024 16:07:22 +1100 Subject: Update icons and volume dialogue to use themes --- lua/playing.lua | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'lua/playing.lua') diff --git a/lua/playing.lua b/lua/playing.lua index 947bdec9..a1ba2cc1 100644 --- a/lua/playing.lua +++ b/lua/playing.lua @@ -5,22 +5,22 @@ local font = require("font") local playback = require("playback") local queue = require("queue") local screen = require("screen") +local theme = require("theme") 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", shuffle = "//lua/img/shuffle.png", - shuffle_disabled = "//lua/img/shuffle_disabled.png", - repeat_enabled = "//lua/img/repeat.png", - repeat_disabled = "//lua/img/repeat_disabled.png", + repeat_src = "//lua/img/repeat.png", -- repeat is a reserved word } local is_now_playing_shown = false +local icon_enabled_class = "icon_enabled" +local icon_disabled_class = "icon_disabled" + return screen:new { createUi = function(self) self.root = lvgl.Object(nil, { @@ -146,11 +146,14 @@ return screen:new { repeat_btn:onClicked(function() queue.repeat_track:set(not queue.repeat_track:get()) end) - local repeat_img = repeat_btn:Image { src = img.repeat_enabled } + local repeat_img = repeat_btn:Image { src = img.repeat_src } + theme.set_style(repeat_img, icon_enabled_class) + local prev_btn = controls:Button {} prev_btn:onClicked(queue.previous) - local prev_img = prev_btn:Image { src = img.prev_disabled } + local prev_img = prev_btn:Image { src = img.prev } + theme.set_style(prev_img, icon_disabled_class) local play_pause_btn = controls:Button {} play_pause_btn:onClicked(function() @@ -158,16 +161,19 @@ return screen:new { end) play_pause_btn:focus() local play_pause_img = play_pause_btn:Image { src = img.pause } + theme.set_style(play_pause_img, icon_enabled_class) local next_btn = controls:Button {} next_btn:onClicked(queue.next) - local next_img = next_btn:Image { src = img.next_disabled } + local next_img = next_btn:Image { src = img.next } + theme.set_style(next_img, icon_disabled_class) local shuffle_btn = controls:Button {} shuffle_btn:onClicked(function() queue.random:set(not queue.random:get()) end) local shuffle_img = shuffle_btn:Image { src = img.shuffle } + theme.set_style(shuffle_img, icon_enabled_class) controls:Object({ flex_grow = 1, h = 1 }) -- spacer @@ -208,26 +214,19 @@ return screen:new { 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 + theme.set_style( + next_img, pos < queue.size:get() and icon_enabled_class or icon_disabled_class ) - prev_img:set_src( - pos > 1 and img.prev or img.prev_disabled + + theme.set_style( + prev_img, pos > 1 and icon_enabled_class or icon_disabled_class ) end), queue.random:bind(function(shuffling) - if shuffling then - shuffle_img:set_src(img.shuffle) - else - shuffle_img:set_src(img.shuffle_disabled) - end + theme.set_style(shuffle_img, shuffling and icon_enabled_class or icon_disabled_class) end), queue.repeat_track:bind(function(en) - if en then - repeat_img:set_src(img.repeat_enabled) - else - repeat_img:set_src(img.repeat_disabled) - end + theme.set_style(repeat_img, en and icon_enabled_class or icon_disabled_class) end), queue.size:bind(function(num) if not num then return end -- cgit v1.2.3