forked from len0rd/rockbox
lua add submenu module + cleanup
allows menus + submenus + context menus all with simple tables menu_t which is a table of strings func_t which are the corresponding functions to go with those strings see lua_scripts/submenu_demo.lua Change-Id: I907b74b4abef0ecbe49f181d0ced6e6d20e94de5
This commit is contained in:
parent
d5695822a7
commit
63b6281505
8 changed files with 478 additions and 120 deletions
28
apps/plugins/lua/include_lua/menubuttons.lua
Normal file
28
apps/plugins/lua/include_lua/menubuttons.lua
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
local rbac_is_loaded = (package.loaded.actions ~= nil)
|
||||||
|
require("actions") -- Contains rb.actions & rb.contexts
|
||||||
|
|
||||||
|
-- Menu Button definitions --
|
||||||
|
local button_t = {
|
||||||
|
CANCEL = rb.actions.PLA_CANCEL,
|
||||||
|
DOWN = rb.actions.PLA_DOWN,
|
||||||
|
DOWNR = rb.actions.PLA_DOWN_REPEAT,
|
||||||
|
EXIT = rb.actions.PLA_EXIT,
|
||||||
|
LEFT = rb.actions.PLA_LEFT,
|
||||||
|
LEFTR = rb.actions.PLA_LEFT_REPEAT,
|
||||||
|
RIGHT = rb.actions.PLA_RIGHT,
|
||||||
|
RIGHTR = rb.actions.PLA_RIGHT_REPEAT,
|
||||||
|
SEL = rb.actions.PLA_SELECT,
|
||||||
|
SELREL = rb.actions.PLA_SELECT_REL,
|
||||||
|
SELR = rb.actions.PLA_SELECT_REPEAT,
|
||||||
|
UP = rb.actions.PLA_UP,
|
||||||
|
UPR = rb.actions.PLA_UP_REPEAT,
|
||||||
|
}
|
||||||
|
|
||||||
|
if not rbac_is_loaded then
|
||||||
|
rb.actions = nil
|
||||||
|
rb.contexts = nil
|
||||||
|
package.loaded.actionss = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return button_t
|
46
apps/plugins/lua/include_lua/menucoresettings.lua
Normal file
46
apps/plugins/lua/include_lua/menucoresettings.lua
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
--menu core settings loaded from rockbox user settings
|
||||||
|
--Bilgus 4/2021
|
||||||
|
|
||||||
|
local function get_core_settings()
|
||||||
|
local rbs_is_loaded = (package.loaded.rbsettings ~= nil)
|
||||||
|
local s_is_loaded = (package.loaded.settings ~= nil)
|
||||||
|
|
||||||
|
require("rbsettings")
|
||||||
|
require("settings")
|
||||||
|
rb.metadata = nil -- remove track metadata settings
|
||||||
|
|
||||||
|
local rb_settings = rb.settings.dump('global_settings', "system")
|
||||||
|
local color_table = {}
|
||||||
|
local talk_table = {}
|
||||||
|
local list_settings_table = {}
|
||||||
|
local list_settings = "cursor_style|show_icons|statusbar|scrollbar|scrollbar_width|list_separator_height|backdrop_file|"
|
||||||
|
for key, value in pairs(rb_settings) do
|
||||||
|
key = key or ""
|
||||||
|
if (key:find("color")) then
|
||||||
|
color_table[key]=value
|
||||||
|
elseif (key:find("talk")) then
|
||||||
|
talk_table[key]=value
|
||||||
|
elseif (list_settings:find(key)) then
|
||||||
|
list_settings_table[key]=value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not s_is_loaded then
|
||||||
|
rb.settings = nil
|
||||||
|
package.loaded.settings = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if not rbs_is_loaded then
|
||||||
|
rb.system = nil
|
||||||
|
rb.metadata = nil
|
||||||
|
package.loaded.rbsettings = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
rb.core_color_table = color_table
|
||||||
|
rb.core_talk_table = talk_table
|
||||||
|
rb.core_list_settings_table = list_settings_table
|
||||||
|
end
|
||||||
|
get_core_settings()
|
||||||
|
get_core_settings = nil
|
||||||
|
package.loaded.menucoresettings = nil
|
||||||
|
collectgarbage("collect")
|
|
@ -343,20 +343,15 @@ local _print = {} do
|
||||||
tld.line_end_color = line_end_color
|
tld.line_end_color = line_end_color
|
||||||
end
|
end
|
||||||
|
|
||||||
line_separator = ld.line_separator
|
line_separator = ld.line_separator or o.drawsep
|
||||||
|
local indent = line_indent < 0 and 0 or line_indent --rb scroller doesn't like negative offset!
|
||||||
if o.line == 1 and o.header then
|
if o.line == 1 and o.header then
|
||||||
--rb scroller doesn't like negative offset!
|
|
||||||
local indent = line_indent < 0 and 0 or line_indent
|
|
||||||
set_desc(ld, true, 1, false, rb.STYLE_DEFAULT,
|
set_desc(ld, true, 1, false, rb.STYLE_DEFAULT,
|
||||||
indent, o.fg_pattern, o.bg_pattern, o.bg_pattern)
|
indent, o.fg_pattern, o.bg_pattern, o.bg_pattern)
|
||||||
ld.show_cursor = false
|
ld.show_cursor = false
|
||||||
elseif s_lines[o.line] then
|
elseif s_lines[o.line] then
|
||||||
--/* Display line selector */
|
--/* Display line selector */
|
||||||
local style = show_cursor == true and rb.STYLE_DEFAULT or linestyle
|
local style = show_cursor == true and rb.STYLE_DEFAULT or linestyle
|
||||||
|
|
||||||
local indent = line_indent < 0 and 0 or line_indent
|
|
||||||
--rb scroller doesn't like negative offset!
|
|
||||||
local ovfl = (o.ovfl == "auto" and w >= o.width and x == 0)
|
local ovfl = (o.ovfl == "auto" and w >= o.width and x == 0)
|
||||||
set_desc(ld, ovfl, 0, true, style, indent,
|
set_desc(ld, ovfl, 0, true, style, indent,
|
||||||
o.bg_pattern, o.sel_pattern, o.sel_pattern)
|
o.bg_pattern, o.sel_pattern, o.sel_pattern)
|
||||||
|
@ -377,7 +372,9 @@ local _print = {} do
|
||||||
if ld.selected == true then
|
if ld.selected == true then
|
||||||
rb.set_viewport(o) -- revert drawmode if selected
|
rb.set_viewport(o) -- revert drawmode if selected
|
||||||
end
|
end
|
||||||
rb.lcd_drawline(0, line * h, o.width, line * h)
|
if not o.header then
|
||||||
|
rb.lcd_drawline(0, line * h, o.width, line * h)
|
||||||
|
end
|
||||||
rb.lcd_drawline(0, line * h + h, o.width, line * h + h) --only to add the last line
|
rb.lcd_drawline(0, line * h + h, o.width, line * h + h) --only to add the last line
|
||||||
-- but we don't have an idea which line is the last line here so every line is the last line!
|
-- but we don't have an idea which line is the last line here so every line is the last line!
|
||||||
end
|
end
|
||||||
|
@ -457,6 +454,7 @@ local _print = {} do
|
||||||
_print.opt.line = set_line
|
_print.opt.line = set_line
|
||||||
_print.opt.linedesc = set_linedesc
|
_print.opt.linedesc = set_linedesc
|
||||||
_print.opt.autoupdate = set_update
|
_print.opt.autoupdate = set_update
|
||||||
|
_print.selected = function() return s_lines end
|
||||||
_print.clear = clear
|
_print.clear = clear
|
||||||
_print.f = printf
|
_print.f = printf
|
||||||
|
|
||||||
|
|
|
@ -23,74 +23,18 @@
|
||||||
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
|
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
|
||||||
|
|
||||||
require("printtable")
|
require("printtable")
|
||||||
|
require("menucoresettings") --loads user settings from rockbox
|
||||||
|
|
||||||
local _clr = require("color")
|
local _clr = require("color")
|
||||||
|
|
||||||
|
|
||||||
local _LCD = rb.lcd_framebuffer()
|
local _LCD = rb.lcd_framebuffer()
|
||||||
|
|
||||||
--[[ -- dpad requires:
|
--[[ -- dpad requires:
|
||||||
require("actions") -- Contains rb.actions & rb.contexts
|
local BUTTON = require("menubuttons")
|
||||||
local _timer = require("timer")
|
local _timer = require("timer")
|
||||||
-- Button definitions --
|
|
||||||
local CANCEL_BUTTON = rb.actions.PLA_CANCEL
|
|
||||||
local DOWN_BUTTON = rb.actions.PLA_DOWN
|
|
||||||
local DOWNR_BUTTON = rb.actions.PLA_DOWN_REPEAT
|
|
||||||
local EXIT_BUTTON = rb.actions.PLA_EXIT
|
|
||||||
local LEFT_BUTTON = rb.actions.PLA_LEFT
|
|
||||||
local LEFTR_BUTTON = rb.actions.PLA_LEFT_REPEAT
|
|
||||||
local RIGHT_BUTTON = rb.actions.PLA_RIGHT
|
|
||||||
local RIGHTR_BUTTON = rb.actions.PLA_RIGHT_REPEAT
|
|
||||||
local SEL_BUTTON = rb.actions.PLA_SELECT
|
|
||||||
local SELREL_BUTTON = rb.actions.PLA_SELECT_REL
|
|
||||||
local SELR_BUTTON = rb.actions.PLA_SELECT_REPEAT
|
|
||||||
local UP_BUTTON = rb.actions.PLA_UP
|
|
||||||
local UPR_BUTTON = rb.actions.PLA_UP_REPEAT
|
|
||||||
]]
|
]]
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
local function get_core_settings()
|
|
||||||
if rb.core_color_table ~= nil and rb.core_talk_table ~= nil and
|
|
||||||
rb.core_list_settings_table ~= nil then return end
|
|
||||||
|
|
||||||
local rbs_is_loaded = (package.loaded.rbsettings ~= nil)
|
|
||||||
local s_is_loaded = (package.loaded.settings ~= nil)
|
|
||||||
|
|
||||||
require("rbsettings")
|
|
||||||
require("settings")
|
|
||||||
rb.metadata = nil -- remove track metadata settings
|
|
||||||
|
|
||||||
local rb_settings = rb.settings.dump('global_settings', "system")
|
|
||||||
local color_table = {}
|
|
||||||
local talk_table = {}
|
|
||||||
local list_settings_table = {}
|
|
||||||
local list_settings = "cursor_style|show_icons|statusbar|scrollbar|scrollbar_width|list_separator_height|backdrop_file|"
|
|
||||||
for key, value in pairs(rb_settings) do
|
|
||||||
key = key or ""
|
|
||||||
if (key:find("color")) then
|
|
||||||
color_table[key]=value
|
|
||||||
elseif (key:find("talk")) then
|
|
||||||
talk_table[key]=value
|
|
||||||
elseif (list_settings:find(key)) then
|
|
||||||
list_settings_table[key]=value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not s_is_loaded then
|
|
||||||
rb.settings = nil
|
|
||||||
package.loaded.settings = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if not rbs_is_loaded then
|
|
||||||
rb.system = nil
|
|
||||||
rb.metadata = nil
|
|
||||||
package.loaded.rbsettings = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
rb.core_color_table = color_table
|
|
||||||
rb.core_talk_table = talk_table
|
|
||||||
rb.core_list_settings_table = list_settings_table
|
|
||||||
collectgarbage("collect")
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[ cursor style button routine
|
--[[ cursor style button routine
|
||||||
-- left / right are x, xi is increment xir is increment when repeat
|
-- left / right are x, xi is increment xir is increment when repeat
|
||||||
-- up / down are y, yi is increment yir is increment when repeat
|
-- up / down are y, yi is increment yir is increment when repeat
|
||||||
|
@ -112,44 +56,44 @@ local function dpad(x, xi, xir, y, yi, yir, timeout, overflow)
|
||||||
while true do
|
while true do
|
||||||
button = rb.get_plugin_action(timeout)
|
button = rb.get_plugin_action(timeout)
|
||||||
|
|
||||||
if button == CANCEL_BUTTON then
|
if button == BUTTON.CANCEL then
|
||||||
cancel = 1
|
cancel = 1
|
||||||
break;
|
break;
|
||||||
elseif button == EXIT_BUTTON then
|
elseif button == BUTTON.EXIT then
|
||||||
cancel = 1
|
cancel = 1
|
||||||
break;
|
break;
|
||||||
elseif button == SEL_BUTTON then
|
elseif button == BUTTON.SEL then
|
||||||
select = 1
|
select = 1
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
elseif button == SELR_BUTTON then
|
elseif button == BUTTON.SELR then
|
||||||
select = 2
|
select = 2
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
elseif button == SELREL_BUTTON then
|
elseif button == BUTTON.SELREL then
|
||||||
select = -1
|
select = -1
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
elseif button == LEFT_BUTTON then
|
elseif button == BUTTON.LEFT then
|
||||||
x_chg = x_chg - xi
|
x_chg = x_chg - xi
|
||||||
if scroll_is_fixed then
|
if scroll_is_fixed then
|
||||||
cancel = 1
|
cancel = 1
|
||||||
break;
|
break;
|
||||||
end
|
end
|
||||||
elseif button == LEFTR_BUTTON then
|
elseif button == BUTTON.LEFTR then
|
||||||
x_chg = x_chg - xir
|
x_chg = x_chg - xir
|
||||||
elseif button == RIGHT_BUTTON then
|
elseif button == BUTTON.RIGHT then
|
||||||
x_chg = x_chg + xi
|
x_chg = x_chg + xi
|
||||||
if scroll_is_fixed then
|
if scroll_is_fixed then
|
||||||
select = 1
|
select = 1
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
end
|
end
|
||||||
elseif button == RIGHTR_BUTTON then
|
elseif button == BUTTON.RIGHTR then
|
||||||
x_chg = x_chg + xir
|
x_chg = x_chg + xir
|
||||||
elseif button == UP_BUTTON then
|
elseif button == BUTTON.UP then
|
||||||
y_chg = y_chg + yi
|
y_chg = y_chg + yi
|
||||||
elseif button == UPR_BUTTON then
|
elseif button == BUTTON.UPR then
|
||||||
y_chg = y_chg + yir
|
y_chg = y_chg + yir
|
||||||
elseif button == DOWN_BUTTON then
|
elseif button == BUTTON.DOWN then
|
||||||
y_chg = y_chg - yi
|
y_chg = y_chg - yi
|
||||||
elseif button == DOWNR_BUTTON then
|
elseif button == BUTTON.DOWNR then
|
||||||
y_chg = y_chg - yir
|
y_chg = y_chg - yir
|
||||||
elseif timeout >= 0 then--and rb.button_queue_count() < 1 then
|
elseif timeout >= 0 then--and rb.button_queue_count() < 1 then
|
||||||
break;
|
break;
|
||||||
|
@ -175,7 +119,6 @@ function print_menu(menu_t, func_t, selected, settings, copy_screen)
|
||||||
if selected then vcur = selected + 1 end
|
if selected then vcur = selected + 1 end
|
||||||
if vcur and vcur <= 1 then vcur = 2 end
|
if vcur and vcur <= 1 then vcur = 2 end
|
||||||
|
|
||||||
get_core_settings()
|
|
||||||
local c_table = rb.core_color_table or {}
|
local c_table = rb.core_color_table or {}
|
||||||
|
|
||||||
if not settings then
|
if not settings then
|
||||||
|
@ -239,7 +182,7 @@ function print_menu(menu_t, func_t, selected, settings, copy_screen)
|
||||||
if copy_screen == true then _LCD:copy(screen_img) end
|
if copy_screen == true then _LCD:copy(screen_img) end
|
||||||
|
|
||||||
if func_t and func_t[i] then
|
if func_t and func_t[i] then
|
||||||
if func_t[i](i, menu_t) == true then break end
|
if func_t[i](i, menu_t, func_t) == true then break end
|
||||||
else
|
else
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
263
apps/plugins/lua/include_lua/printsubmenu.lua
Normal file
263
apps/plugins/lua/include_lua/printsubmenu.lua
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
--[[
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 William Wilgus
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
]]
|
||||||
|
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
|
||||||
|
menu_ctx = {}
|
||||||
|
local last_ctx = false
|
||||||
|
local p_settings
|
||||||
|
|
||||||
|
--[[root menu tables
|
||||||
|
expanded menus get inserted / removed
|
||||||
|
and context menus replace them but never overwritten
|
||||||
|
unless you want a new root menu
|
||||||
|
]]
|
||||||
|
menu_t = {}
|
||||||
|
func_t = {}
|
||||||
|
|
||||||
|
require("printmenus")
|
||||||
|
|
||||||
|
local BUTTON = require("menubuttons")
|
||||||
|
local last_sel = 0
|
||||||
|
|
||||||
|
local function display_context_menu() end -- forward declaration
|
||||||
|
|
||||||
|
local function dpad(x, xi, xir, y, yi, yir, timeout, overflow, selected)
|
||||||
|
local scroll_is_fixed = overflow ~= "manual"
|
||||||
|
if timeout == nil then timeout = -1 end
|
||||||
|
local cancel, select = 0, 0
|
||||||
|
local x_chg, y_chg = 0, 0
|
||||||
|
local button
|
||||||
|
while true do
|
||||||
|
button = rb.get_plugin_action(timeout)
|
||||||
|
|
||||||
|
if button == BUTTON.CANCEL then
|
||||||
|
cancel = 1
|
||||||
|
break;
|
||||||
|
elseif button == BUTTON.EXIT then
|
||||||
|
cancel = 1
|
||||||
|
break;
|
||||||
|
elseif button == BUTTON.SEL then
|
||||||
|
last_sel = 1
|
||||||
|
timeout = timeout + 1
|
||||||
|
elseif button == BUTTON.SELR then
|
||||||
|
last_sel = 2
|
||||||
|
if display_context_menu(selected or -1) == true then
|
||||||
|
select = 1
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
timeout = timeout + 1
|
||||||
|
elseif button == BUTTON.SELREL then
|
||||||
|
if last_sel == 1 then
|
||||||
|
select = 1
|
||||||
|
end
|
||||||
|
last_sel = 0
|
||||||
|
timeout = timeout + 1
|
||||||
|
elseif button == BUTTON.LEFT then
|
||||||
|
x_chg = x_chg - xi
|
||||||
|
if scroll_is_fixed then
|
||||||
|
cancel = 1
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
elseif button == BUTTON.LEFTR then
|
||||||
|
x_chg = x_chg - xir
|
||||||
|
elseif button == BUTTON.RIGHT then
|
||||||
|
x_chg = x_chg + xi
|
||||||
|
if scroll_is_fixed then
|
||||||
|
select = 1
|
||||||
|
timeout = timeout + 1
|
||||||
|
end
|
||||||
|
elseif button == BUTTON.RIGHTR then
|
||||||
|
x_chg = x_chg + xir
|
||||||
|
elseif button == BUTTON.UP then
|
||||||
|
y_chg = y_chg + yi
|
||||||
|
elseif button == BUTTON.UPR then
|
||||||
|
y_chg = y_chg + yir
|
||||||
|
elseif button == BUTTON.DOWN then
|
||||||
|
y_chg = y_chg - yi
|
||||||
|
elseif button == BUTTON.DOWNR then
|
||||||
|
y_chg = y_chg - yir
|
||||||
|
elseif timeout >= 0 then--and rb.button_queue_count() < 1 then
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
|
||||||
|
if x_chg ~= 0 or y_chg ~= 0 then
|
||||||
|
timeout = timeout + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
x = x + x_chg
|
||||||
|
y = y + y_chg
|
||||||
|
|
||||||
|
return cancel, select, x_chg, x, y_chg, y, 0xffff
|
||||||
|
end -- dpad
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function menu_set_defaults(settings, ctx)
|
||||||
|
p_settings = settings or {wrap = true, hasheader = true, justify = "left", dpad_fn = dpad}
|
||||||
|
menu_ctx = ctx or {collapse_fn = {}, lv = 0, update = false, start = 1}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ctx_loop()
|
||||||
|
local loopfn = ctx_loop
|
||||||
|
ctx_loop = function() end --prevent another execution
|
||||||
|
local mt, ft = get_menu()
|
||||||
|
local i
|
||||||
|
repeat
|
||||||
|
if menu_ctx.update then mt, ft = get_menu(); menu_ctx.update = false end
|
||||||
|
_, i = print_menu(mt, ft, menu_ctx.start, p_settings)
|
||||||
|
until menu_ctx.quit
|
||||||
|
|
||||||
|
ctx_loop = loopfn --restore for another run
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_menu()
|
||||||
|
return menu_t, func_t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function push_ctx(new_getmenu)
|
||||||
|
last_ctx = last_ctx or {}
|
||||||
|
table.insert(last_ctx, menu_ctx)
|
||||||
|
menu_ctx.getmenu = get_menu
|
||||||
|
menu_ctx.settings = p_settings
|
||||||
|
--menu_ctx is a new variable after this point
|
||||||
|
menu_set_defaults()
|
||||||
|
menu_ctx.update = true
|
||||||
|
if type(new_getmenu) == 'function' then
|
||||||
|
get_menu = new_getmenu
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pop_ctx()
|
||||||
|
menu_ctx = table.remove(last_ctx)
|
||||||
|
if menu_ctx then
|
||||||
|
get_menu = menu_ctx.getmenu
|
||||||
|
p_settings = menu_ctx.settings
|
||||||
|
if menu_ctx.restorefn then
|
||||||
|
menu_ctx.restorefn(menu_t, func_t)
|
||||||
|
menu_ctx.restorefn = nil
|
||||||
|
end
|
||||||
|
menu_ctx.getmenu = nil
|
||||||
|
menu_ctx.settings = nil
|
||||||
|
menu_ctx.update = true
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function display_context_menu_internal(sel)
|
||||||
|
|
||||||
|
if sel <= 0 or not menu_ctx.user_context_fn then return false end
|
||||||
|
local parent = get_parent() or 0
|
||||||
|
local user_context_fn = menu_ctx.user_context_fn
|
||||||
|
local function display_context_menu(i, menu_t, func_t)
|
||||||
|
|
||||||
|
local function new_getmenu()
|
||||||
|
local mt, ft = user_context_fn(parent, i, menu_t, func_t)
|
||||||
|
ft[0] = pop_ctx --set back fn
|
||||||
|
return mt, ft
|
||||||
|
end
|
||||||
|
push_ctx(new_getmenu)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local funct = func_t[sel]
|
||||||
|
local function restore_fn(mt, ft)
|
||||||
|
ft[sel] = funct
|
||||||
|
menu_ctx.start = sel - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
menu_ctx.restorefn = restore_fn
|
||||||
|
-- insert into the current fn table so it gets execd by the menu
|
||||||
|
func_t[sel] = display_context_menu
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_parent(lv)
|
||||||
|
lv = lv or #menu_ctx.collapse_fn
|
||||||
|
collectgarbage("step")
|
||||||
|
local t = menu_ctx.collapse_fn[lv] or {}
|
||||||
|
return t[2] or -1
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_menu(mt, ft, user_context_fn, settings)
|
||||||
|
local function empty_fn() end
|
||||||
|
menu_set_defaults(settings)
|
||||||
|
if type(user_context_fn) == 'function' then
|
||||||
|
display_context_menu = display_context_menu_internal
|
||||||
|
menu_ctx.user_context_fn = user_context_fn
|
||||||
|
else
|
||||||
|
display_context_menu = empty_fn
|
||||||
|
menu_ctx.user_context_fn = false
|
||||||
|
end
|
||||||
|
p_settings = settings or p_settings
|
||||||
|
menu_t, func_t = mt, ft
|
||||||
|
ctx_loop()
|
||||||
|
end
|
||||||
|
|
||||||
|
function create_sub_menu(lv, mt, ft)
|
||||||
|
if lv < 1 then error("Level < 1") end
|
||||||
|
-- everything in lua is 1 based menu level is no exception
|
||||||
|
local lv_tab = string.rep ("\t", lv)
|
||||||
|
local function submenu_closure(i, m, f)
|
||||||
|
menu_ctx.lv = lv
|
||||||
|
local lv_out, menusz_out, start_item
|
||||||
|
local item_in, item_out = i, i
|
||||||
|
if lv <= #menu_ctx.collapse_fn then --something else expanded??
|
||||||
|
repeat
|
||||||
|
local collapse_fn = table.remove(menu_ctx.collapse_fn)
|
||||||
|
if collapse_fn then
|
||||||
|
lv_out, item_out, menusz_out = collapse_fn[1](i, m, f)
|
||||||
|
-- if the item i is below this menu, it needs to shift too
|
||||||
|
if item_in > item_out then i = i - (menusz_out) end
|
||||||
|
end
|
||||||
|
until not collapse_fn or lv >= lv_out
|
||||||
|
menu_ctx.start = i
|
||||||
|
if item_out == item_in then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
local menu_sz = #mt
|
||||||
|
menu_ctx.start = i
|
||||||
|
start_item = i
|
||||||
|
menu_ctx.update = true
|
||||||
|
for item, _ in ipairs(mt) do
|
||||||
|
i = i + 1
|
||||||
|
table.insert(m, i, lv_tab .. mt[item])
|
||||||
|
table.insert(f, i, ft[item])
|
||||||
|
end
|
||||||
|
|
||||||
|
local function collapse_closure(i, m, f)
|
||||||
|
--creates a closure around lv, start_item and menu_sz
|
||||||
|
for j = 1, menu_sz, 1 do
|
||||||
|
table.remove(m, start_item + 1)
|
||||||
|
table.remove(f, start_item + 1)
|
||||||
|
end
|
||||||
|
return lv, start_item, menu_sz
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(menu_ctx.collapse_fn, lv, {collapse_closure, start_item})
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return submenu_closure
|
||||||
|
end
|
||||||
|
|
|
@ -22,28 +22,12 @@
|
||||||
]]
|
]]
|
||||||
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
|
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
|
||||||
|
|
||||||
require("actions") -- Contains rb.actions & rb.contexts
|
|
||||||
|
|
||||||
local _clr = require("color")
|
local _clr = require("color")
|
||||||
local _print = require("print")
|
local _print = require("print")
|
||||||
local _timer = require("timer")
|
local _timer = require("timer")
|
||||||
|
local BUTTON = require("menubuttons")
|
||||||
local sb_width = 5
|
local sb_width = 5
|
||||||
|
|
||||||
-- Button definitions --
|
|
||||||
local CANCEL_BUTTON = rb.actions.PLA_CANCEL
|
|
||||||
local DOWN_BUTTON = rb.actions.PLA_DOWN
|
|
||||||
local DOWNR_BUTTON = rb.actions.PLA_DOWN_REPEAT
|
|
||||||
local EXIT_BUTTON = rb.actions.PLA_EXIT
|
|
||||||
local LEFT_BUTTON = rb.actions.PLA_LEFT
|
|
||||||
local LEFTR_BUTTON = rb.actions.PLA_LEFT_REPEAT
|
|
||||||
local RIGHT_BUTTON = rb.actions.PLA_RIGHT
|
|
||||||
local RIGHTR_BUTTON = rb.actions.PLA_RIGHT_REPEAT
|
|
||||||
local SEL_BUTTON = rb.actions.PLA_SELECT
|
|
||||||
local SELREL_BUTTON = rb.actions.PLA_SELECT_REL
|
|
||||||
local SELR_BUTTON = rb.actions.PLA_SELECT_REPEAT
|
|
||||||
local UP_BUTTON = rb.actions.PLA_UP
|
|
||||||
local UPR_BUTTON = rb.actions.PLA_UP_REPEAT
|
|
||||||
|
|
||||||
-- clamps value to >= min and <= max
|
-- clamps value to >= min and <= max
|
||||||
local function clamp(iVal, iMin, iMax)
|
local function clamp(iVal, iMin, iMax)
|
||||||
if iMin > iMax then
|
if iMin > iMax then
|
||||||
|
@ -71,7 +55,7 @@ end
|
||||||
-- time since last button press is returned in ticks..
|
-- time since last button press is returned in ticks..
|
||||||
-- make xi, xir, yi, yir negative to flip direction...
|
-- make xi, xir, yi, yir negative to flip direction...
|
||||||
]]
|
]]
|
||||||
local function dpad(x, xi, xir, y, yi, yir, timeout, overflow)
|
local function dpad(x, xi, xir, y, yi, yir, timeout, overflow, selected)
|
||||||
local scroll_is_fixed = overflow ~= "manual"
|
local scroll_is_fixed = overflow ~= "manual"
|
||||||
_timer("dpad") -- start a persistant timer; keeps time between button events
|
_timer("dpad") -- start a persistant timer; keeps time between button events
|
||||||
if timeout == nil then timeout = -1 end
|
if timeout == nil then timeout = -1 end
|
||||||
|
@ -81,44 +65,44 @@ local function dpad(x, xi, xir, y, yi, yir, timeout, overflow)
|
||||||
while true do
|
while true do
|
||||||
button = rb.get_plugin_action(timeout)
|
button = rb.get_plugin_action(timeout)
|
||||||
|
|
||||||
if button == CANCEL_BUTTON then
|
if button == BUTTON.CANCEL then
|
||||||
cancel = 1
|
cancel = 1
|
||||||
break;
|
break;
|
||||||
elseif button == EXIT_BUTTON then
|
elseif button == BUTTON.EXIT then
|
||||||
cancel = 1
|
cancel = 1
|
||||||
break;
|
break;
|
||||||
elseif button == SEL_BUTTON then
|
elseif button == BUTTON.SEL then
|
||||||
select = 1
|
select = 1
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
elseif button == SELR_BUTTON then
|
elseif button == BUTTON.SELR then
|
||||||
select = 2
|
select = 2
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
elseif button == SELREL_BUTTON then
|
elseif button == BUTTON.SELREL then
|
||||||
select = -1
|
select = -1
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
elseif button == LEFT_BUTTON then
|
elseif button == BUTTON.LEFT then
|
||||||
x_chg = x_chg - xi
|
x_chg = x_chg - xi
|
||||||
if scroll_is_fixed then
|
if scroll_is_fixed then
|
||||||
cancel = 1
|
cancel = 1
|
||||||
break;
|
break;
|
||||||
end
|
end
|
||||||
elseif button == LEFTR_BUTTON then
|
elseif button == BUTTON.LEFTR then
|
||||||
x_chg = x_chg - xir
|
x_chg = x_chg - xir
|
||||||
elseif button == RIGHT_BUTTON then
|
elseif button == BUTTON.RIGHT then
|
||||||
x_chg = x_chg + xi
|
x_chg = x_chg + xi
|
||||||
if scroll_is_fixed then
|
if scroll_is_fixed then
|
||||||
select = 1
|
select = 1
|
||||||
timeout = timeout + 1
|
timeout = timeout + 1
|
||||||
end
|
end
|
||||||
elseif button == RIGHTR_BUTTON then
|
elseif button == BUTTON.RIGHTR then
|
||||||
x_chg = x_chg + xir
|
x_chg = x_chg + xir
|
||||||
elseif button == UP_BUTTON then
|
elseif button == BUTTON.UP then
|
||||||
y_chg = y_chg + yi
|
y_chg = y_chg + yi
|
||||||
elseif button == UPR_BUTTON then
|
elseif button == BUTTON.UPR then
|
||||||
y_chg = y_chg + yir
|
y_chg = y_chg + yir
|
||||||
elseif button == DOWN_BUTTON then
|
elseif button == BUTTON.DOWN then
|
||||||
y_chg = y_chg - yi
|
y_chg = y_chg - yi
|
||||||
elseif button == DOWNR_BUTTON then
|
elseif button == BUTTON.DOWNR then
|
||||||
y_chg = y_chg - yir
|
y_chg = y_chg - yir
|
||||||
elseif timeout >= 0 then--and rb.button_queue_count() < 1 then
|
elseif timeout >= 0 then--and rb.button_queue_count() < 1 then
|
||||||
break;
|
break;
|
||||||
|
@ -247,7 +231,8 @@ function print_table(t, t_count, settings)
|
||||||
rb.lcd_update()
|
rb.lcd_update()
|
||||||
|
|
||||||
local quit, select, x_chg, xi, y_chg, yi, timeb =
|
local quit, select, x_chg, xi, y_chg, yi, timeb =
|
||||||
dpad_fn(t_p.col, -1, -t_p.col_scrl, t_p.row, -1, -t_p.row_scrl, nil, overflow)
|
dpad_fn(t_p.col, -1, -t_p.col_scrl, t_p.row, -1, -t_p.row_scrl,
|
||||||
|
nil, overflow, (t_p.row + t_p.vcursor - 1))
|
||||||
|
|
||||||
t_p.vcursor = t_p.vcursor + y_chg
|
t_p.vcursor = t_p.vcursor + y_chg
|
||||||
|
|
||||||
|
@ -316,7 +301,7 @@ function print_table(t, t_count, settings)
|
||||||
if t[i] == nil then
|
if t[i] == nil then
|
||||||
rb.splash(1, string.format("ERROR %d is nil", i))
|
rb.splash(1, string.format("ERROR %d is nil", i))
|
||||||
t[i] = "???"
|
t[i] = "???"
|
||||||
if rb.get_plugin_action(10) == CANCEL_BUTTON then return 0 end
|
if rb.get_plugin_action(10) == BUTTON.CANCEL then return 0 end
|
||||||
end
|
end
|
||||||
|
|
||||||
if m_sel == true and t[i]:sub(-1) == "\0" then
|
if m_sel == true and t[i]:sub(-1) == "\0" then
|
||||||
|
|
|
@ -16,11 +16,13 @@ LUA_OBJ := $(call c2obj, $(LUA_SRC))
|
||||||
OTHER_SRC += $(LUA_SRC)
|
OTHER_SRC += $(LUA_SRC)
|
||||||
|
|
||||||
LUA_INCLUDEDIR := $(LUA_SRCDIR)/include_lua
|
LUA_INCLUDEDIR := $(LUA_SRCDIR)/include_lua
|
||||||
LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua draw.lua draw_floodfill.lua draw_poly.lua \
|
LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua \
|
||||||
draw_num.lua draw_text.lua files.lua image.lua image_save.lua lcd.lua math_ex.lua \
|
draw.lua draw_floodfill.lua draw_poly.lua draw_num.lua \
|
||||||
print.lua timer.lua playlist.lua pcm.lua sound.lua printmenus.lua\
|
draw_text.lua files.lua image.lua image_save.lua lcd.lua \
|
||||||
rbcompat.lua rbsettings.lua poly_points.lua printtable.lua)
|
math_ex.lua print.lua timer.lua playlist.lua pcm.lua \
|
||||||
|
sound.lua rbcompat.lua rbsettings.lua poly_points.lua \
|
||||||
|
printtable.lua printmenus.lua printsubmenu.lua \
|
||||||
|
menubuttons.lua menucoresettings.lua)
|
||||||
|
|
||||||
ifndef APP_TYPE
|
ifndef APP_TYPE
|
||||||
ROCKS += $(LUA_BUILDDIR)/lua.rock
|
ROCKS += $(LUA_BUILDDIR)/lua.rock
|
||||||
|
|
93
apps/plugins/lua_scripts/submenu_demo.lua
Normal file
93
apps/plugins/lua_scripts/submenu_demo.lua
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
--Bilgus 4/2021 Menu with subitems and context demo
|
||||||
|
require("printsubmenu")
|
||||||
|
|
||||||
|
local scrpath = rb.current_path()
|
||||||
|
|
||||||
|
local function get_ctx_menu(parent, sel, menu_t, func_t)
|
||||||
|
local mt = {"Context menu " .. (menu_t[parent] or "ROOT") ..
|
||||||
|
" : " .. menu_t[sel], "Quit", "Action 1", "Action 2"}
|
||||||
|
local ft = {false, function() menu_ctx.quit = true return true end}
|
||||||
|
return mt, ft
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ITEM_MENU()
|
||||||
|
|
||||||
|
local function flung(i, menu_t, func_t)
|
||||||
|
local parent = get_parent() or 0
|
||||||
|
rb.splash(100, "flung " .. (menu_t[parent] or "?"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function foo(i, menu_t, func_t)
|
||||||
|
local parent = get_parent() or 0
|
||||||
|
rb.splash(100, "FOO " .. menu_t[parent])
|
||||||
|
end
|
||||||
|
|
||||||
|
local function far(i, menu_t, func_t)
|
||||||
|
local parent = get_parent() or 0
|
||||||
|
rb.splash(100, "far" .. menu_t[parent])
|
||||||
|
end
|
||||||
|
|
||||||
|
return {"Flung", "FOO", "Far"},
|
||||||
|
{flung, foo, far}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function USERITEMS()
|
||||||
|
|
||||||
|
return {"Item_1", "Item_2", "Item_3"},
|
||||||
|
{create_sub_menu(2, ITEM_MENU()), create_sub_menu(2, ITEM_MENU()),
|
||||||
|
create_sub_menu(2, ITEM_MENU()), function() end}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MAIN_MENU()
|
||||||
|
|
||||||
|
local function go_back(i, m, f)
|
||||||
|
local parent = get_parent() or 0
|
||||||
|
if parent > 0 then
|
||||||
|
f[parent](parent, m, f)
|
||||||
|
else
|
||||||
|
menu_ctx.quit = true
|
||||||
|
end
|
||||||
|
menu_ctx.start = parent - 1
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local mt = {
|
||||||
|
[1] = "lua Menu Demo",
|
||||||
|
[2] = "Items",
|
||||||
|
[3] = "Back",
|
||||||
|
}
|
||||||
|
|
||||||
|
local ft = {
|
||||||
|
[0] = go_back, --if user cancels do this function
|
||||||
|
[1] = false, -- shouldn't happen title occupies this slot
|
||||||
|
[2] = create_sub_menu(1, USERITEMS()),
|
||||||
|
[3] = go_back,
|
||||||
|
}
|
||||||
|
return mt, ft, get_ctx_menu
|
||||||
|
end
|
||||||
|
|
||||||
|
function ShowMain()
|
||||||
|
set_menu(MAIN_MENU())
|
||||||
|
end
|
||||||
|
|
||||||
|
--ShowMainMenu()
|
||||||
|
ShowMain()
|
||||||
|
rb.lcd_clear_display()
|
||||||
|
rb.lcd_update()
|
||||||
|
local lu = collectgarbage("collect")
|
||||||
|
local used, allocd, free = rb.mem_stats()
|
||||||
|
local lu = collectgarbage("count")
|
||||||
|
local fmt = function(t, v) return string.format("%s: %d Kb\n", t, v /1024) end
|
||||||
|
|
||||||
|
-- this is how lua recommends to concat strings rather than ..
|
||||||
|
local s_t = {}
|
||||||
|
s_t[1] = "rockbox:\n"
|
||||||
|
s_t[2] = fmt("Used ", used)
|
||||||
|
s_t[3] = fmt("Allocd ", allocd)
|
||||||
|
s_t[4] = fmt("Free ", free)
|
||||||
|
s_t[5] = "\nlua:\n"
|
||||||
|
s_t[6] = fmt("Used", lu * 1024)
|
||||||
|
s_t[7] = "\n\nNote that the rockbox used count is a high watermark"
|
||||||
|
rb.splash_scroller(5 * rb.HZ, table.concat(s_t))
|
||||||
|
--require("print_lua_func")
|
||||||
|
os.exit(1, "Goodbye")
|
Loading…
Add table
Add a link
Reference in a new issue