diff options
-rw-r--r-- | apps/plugins/lua/include_lua/menubuttons.lua | 28 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/menucoresettings.lua | 46 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/print.lua | 14 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/printmenus.lua | 91 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/printsubmenu.lua | 263 | ||||
-rw-r--r-- | apps/plugins/lua/include_lua/printtable.lua | 51 | ||||
-rw-r--r-- | apps/plugins/lua/lua.make | 12 | ||||
-rw-r--r-- | apps/plugins/lua_scripts/submenu_demo.lua | 93 |
8 files changed, 478 insertions, 120 deletions
diff --git a/apps/plugins/lua/include_lua/menubuttons.lua b/apps/plugins/lua/include_lua/menubuttons.lua new file mode 100644 index 0000000000..e358d94a10 --- /dev/null +++ b/apps/plugins/lua/include_lua/menubuttons.lua | |||
@@ -0,0 +1,28 @@ | |||
1 | |||
2 | local rbac_is_loaded = (package.loaded.actions ~= nil) | ||
3 | require("actions") -- Contains rb.actions & rb.contexts | ||
4 | |||
5 | -- Menu Button definitions -- | ||
6 | local button_t = { | ||
7 | CANCEL = rb.actions.PLA_CANCEL, | ||
8 | DOWN = rb.actions.PLA_DOWN, | ||
9 | DOWNR = rb.actions.PLA_DOWN_REPEAT, | ||
10 | EXIT = rb.actions.PLA_EXIT, | ||
11 | LEFT = rb.actions.PLA_LEFT, | ||
12 | LEFTR = rb.actions.PLA_LEFT_REPEAT, | ||
13 | RIGHT = rb.actions.PLA_RIGHT, | ||
14 | RIGHTR = rb.actions.PLA_RIGHT_REPEAT, | ||
15 | SEL = rb.actions.PLA_SELECT, | ||
16 | SELREL = rb.actions.PLA_SELECT_REL, | ||
17 | SELR = rb.actions.PLA_SELECT_REPEAT, | ||
18 | UP = rb.actions.PLA_UP, | ||
19 | UPR = rb.actions.PLA_UP_REPEAT, | ||
20 | } | ||
21 | |||
22 | if not rbac_is_loaded then | ||
23 | rb.actions = nil | ||
24 | rb.contexts = nil | ||
25 | package.loaded.actionss = nil | ||
26 | end | ||
27 | |||
28 | return button_t | ||
diff --git a/apps/plugins/lua/include_lua/menucoresettings.lua b/apps/plugins/lua/include_lua/menucoresettings.lua new file mode 100644 index 0000000000..01128830f3 --- /dev/null +++ b/apps/plugins/lua/include_lua/menucoresettings.lua | |||
@@ -0,0 +1,46 @@ | |||
1 | --menu core settings loaded from rockbox user settings | ||
2 | --Bilgus 4/2021 | ||
3 | |||
4 | local function get_core_settings() | ||
5 | local rbs_is_loaded = (package.loaded.rbsettings ~= nil) | ||
6 | local s_is_loaded = (package.loaded.settings ~= nil) | ||
7 | |||
8 | require("rbsettings") | ||
9 | require("settings") | ||
10 | rb.metadata = nil -- remove track metadata settings | ||
11 | |||
12 | local rb_settings = rb.settings.dump('global_settings', "system") | ||
13 | local color_table = {} | ||
14 | local talk_table = {} | ||
15 | local list_settings_table = {} | ||
16 | local list_settings = "cursor_style|show_icons|statusbar|scrollbar|scrollbar_width|list_separator_height|backdrop_file|" | ||
17 | for key, value in pairs(rb_settings) do | ||
18 | key = key or "" | ||
19 | if (key:find("color")) then | ||
20 | color_table[key]=value | ||
21 | elseif (key:find("talk")) then | ||
22 | talk_table[key]=value | ||
23 | elseif (list_settings:find(key)) then | ||
24 | list_settings_table[key]=value | ||
25 | end | ||
26 | end | ||
27 | |||
28 | if not s_is_loaded then | ||
29 | rb.settings = nil | ||
30 | package.loaded.settings = nil | ||
31 | end | ||
32 | |||
33 | if not rbs_is_loaded then | ||
34 | rb.system = nil | ||
35 | rb.metadata = nil | ||
36 | package.loaded.rbsettings = nil | ||
37 | end | ||
38 | |||
39 | rb.core_color_table = color_table | ||
40 | rb.core_talk_table = talk_table | ||
41 | rb.core_list_settings_table = list_settings_table | ||
42 | end | ||
43 | get_core_settings() | ||
44 | get_core_settings = nil | ||
45 | package.loaded.menucoresettings = nil | ||
46 | collectgarbage("collect") | ||
diff --git a/apps/plugins/lua/include_lua/print.lua b/apps/plugins/lua/include_lua/print.lua index 3b4c389848..6f2010422a 100644 --- a/apps/plugins/lua/include_lua/print.lua +++ b/apps/plugins/lua/include_lua/print.lua | |||
@@ -343,20 +343,15 @@ local _print = {} do | |||
343 | tld.line_end_color = line_end_color | 343 | tld.line_end_color = line_end_color |
344 | end | 344 | end |
345 | 345 | ||
346 | line_separator = ld.line_separator | 346 | line_separator = ld.line_separator or o.drawsep |
347 | 347 | local indent = line_indent < 0 and 0 or line_indent --rb scroller doesn't like negative offset! | |
348 | if o.line == 1 and o.header then | 348 | if o.line == 1 and o.header then |
349 | --rb scroller doesn't like negative offset! | ||
350 | local indent = line_indent < 0 and 0 or line_indent | ||
351 | set_desc(ld, true, 1, false, rb.STYLE_DEFAULT, | 349 | set_desc(ld, true, 1, false, rb.STYLE_DEFAULT, |
352 | indent, o.fg_pattern, o.bg_pattern, o.bg_pattern) | 350 | indent, o.fg_pattern, o.bg_pattern, o.bg_pattern) |
353 | ld.show_cursor = false | 351 | ld.show_cursor = false |
354 | elseif s_lines[o.line] then | 352 | elseif s_lines[o.line] then |
355 | --/* Display line selector */ | 353 | --/* Display line selector */ |
356 | local style = show_cursor == true and rb.STYLE_DEFAULT or linestyle | 354 | local style = show_cursor == true and rb.STYLE_DEFAULT or linestyle |
357 | |||
358 | local indent = line_indent < 0 and 0 or line_indent | ||
359 | --rb scroller doesn't like negative offset! | ||
360 | local ovfl = (o.ovfl == "auto" and w >= o.width and x == 0) | 355 | local ovfl = (o.ovfl == "auto" and w >= o.width and x == 0) |
361 | set_desc(ld, ovfl, 0, true, style, indent, | 356 | set_desc(ld, ovfl, 0, true, style, indent, |
362 | o.bg_pattern, o.sel_pattern, o.sel_pattern) | 357 | o.bg_pattern, o.sel_pattern, o.sel_pattern) |
@@ -377,7 +372,9 @@ local _print = {} do | |||
377 | if ld.selected == true then | 372 | if ld.selected == true then |
378 | rb.set_viewport(o) -- revert drawmode if selected | 373 | rb.set_viewport(o) -- revert drawmode if selected |
379 | end | 374 | end |
380 | rb.lcd_drawline(0, line * h, o.width, line * h) | 375 | if not o.header then |
376 | rb.lcd_drawline(0, line * h, o.width, line * h) | ||
377 | end | ||
381 | rb.lcd_drawline(0, line * h + h, o.width, line * h + h) --only to add the last line | 378 | rb.lcd_drawline(0, line * h + h, o.width, line * h + h) --only to add the last line |
382 | -- but we don't have an idea which line is the last line here so every line is the last line! | 379 | -- but we don't have an idea which line is the last line here so every line is the last line! |
383 | end | 380 | end |
@@ -457,6 +454,7 @@ local _print = {} do | |||
457 | _print.opt.line = set_line | 454 | _print.opt.line = set_line |
458 | _print.opt.linedesc = set_linedesc | 455 | _print.opt.linedesc = set_linedesc |
459 | _print.opt.autoupdate = set_update | 456 | _print.opt.autoupdate = set_update |
457 | _print.selected = function() return s_lines end | ||
460 | _print.clear = clear | 458 | _print.clear = clear |
461 | _print.f = printf | 459 | _print.f = printf |
462 | 460 | ||
diff --git a/apps/plugins/lua/include_lua/printmenus.lua b/apps/plugins/lua/include_lua/printmenus.lua index 3e8f870104..938d99a5ed 100644 --- a/apps/plugins/lua/include_lua/printmenus.lua +++ b/apps/plugins/lua/include_lua/printmenus.lua | |||
@@ -23,74 +23,18 @@ | |||
23 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end | 23 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end |
24 | 24 | ||
25 | require("printtable") | 25 | require("printtable") |
26 | require("menucoresettings") --loads user settings from rockbox | ||
26 | 27 | ||
27 | local _clr = require("color") | 28 | local _clr = require("color") |
28 | 29 | ||
30 | |||
29 | local _LCD = rb.lcd_framebuffer() | 31 | local _LCD = rb.lcd_framebuffer() |
30 | 32 | ||
31 | --[[ -- dpad requires: | 33 | --[[ -- dpad requires: |
32 | require("actions") -- Contains rb.actions & rb.contexts | 34 | local BUTTON = require("menubuttons") |
33 | local _timer = require("timer") | 35 | local _timer = require("timer") |
34 | -- Button definitions -- | ||
35 | local CANCEL_BUTTON = rb.actions.PLA_CANCEL | ||
36 | local DOWN_BUTTON = rb.actions.PLA_DOWN | ||
37 | local DOWNR_BUTTON = rb.actions.PLA_DOWN_REPEAT | ||
38 | local EXIT_BUTTON = rb.actions.PLA_EXIT | ||
39 | local LEFT_BUTTON = rb.actions.PLA_LEFT | ||
40 | local LEFTR_BUTTON = rb.actions.PLA_LEFT_REPEAT | ||
41 | local RIGHT_BUTTON = rb.actions.PLA_RIGHT | ||
42 | local RIGHTR_BUTTON = rb.actions.PLA_RIGHT_REPEAT | ||
43 | local SEL_BUTTON = rb.actions.PLA_SELECT | ||
44 | local SELREL_BUTTON = rb.actions.PLA_SELECT_REL | ||
45 | local SELR_BUTTON = rb.actions.PLA_SELECT_REPEAT | ||
46 | local UP_BUTTON = rb.actions.PLA_UP | ||
47 | local UPR_BUTTON = rb.actions.PLA_UP_REPEAT | ||
48 | ]] | 36 | ]] |
49 | -------------------------------------------------------------------------------- | 37 | -------------------------------------------------------------------------------- |
50 | local function get_core_settings() | ||
51 | if rb.core_color_table ~= nil and rb.core_talk_table ~= nil and | ||
52 | rb.core_list_settings_table ~= nil then return end | ||
53 | |||
54 | local rbs_is_loaded = (package.loaded.rbsettings ~= nil) | ||
55 | local s_is_loaded = (package.loaded.settings ~= nil) | ||
56 | |||
57 | require("rbsettings") | ||
58 | require("settings") | ||
59 | rb.metadata = nil -- remove track metadata settings | ||
60 | |||
61 | local rb_settings = rb.settings.dump('global_settings', "system") | ||
62 | local color_table = {} | ||
63 | local talk_table = {} | ||
64 | local list_settings_table = {} | ||
65 | local list_settings = "cursor_style|show_icons|statusbar|scrollbar|scrollbar_width|list_separator_height|backdrop_file|" | ||
66 | for key, value in pairs(rb_settings) do | ||
67 | key = key or "" | ||
68 | if (key:find("color")) then | ||
69 | color_table[key]=value | ||
70 | elseif (key:find("talk")) then | ||
71 | talk_table[key]=value | ||
72 | elseif (list_settings:find(key)) then | ||
73 | list_settings_table[key]=value | ||
74 | end | ||
75 | end | ||
76 | |||
77 | if not s_is_loaded then | ||
78 | rb.settings = nil | ||
79 | package.loaded.settings = nil | ||
80 | end | ||
81 | |||
82 | if not rbs_is_loaded then | ||
83 | rb.system = nil | ||
84 | rb.metadata = nil | ||
85 | package.loaded.rbsettings = nil | ||
86 | end | ||
87 | |||
88 | rb.core_color_table = color_table | ||
89 | rb.core_talk_table = talk_table | ||
90 | rb.core_list_settings_table = list_settings_table | ||
91 | collectgarbage("collect") | ||
92 | end | ||
93 | |||
94 | --[[ cursor style button routine | 38 | --[[ cursor style button routine |
95 | -- left / right are x, xi is increment xir is increment when repeat | 39 | -- left / right are x, xi is increment xir is increment when repeat |
96 | -- up / down are y, yi is increment yir is increment when repeat | 40 | -- 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) | |||
112 | while true do | 56 | while true do |
113 | button = rb.get_plugin_action(timeout) | 57 | button = rb.get_plugin_action(timeout) |
114 | 58 | ||
115 | if button == CANCEL_BUTTON then | 59 | if button == BUTTON.CANCEL then |
116 | cancel = 1 | 60 | cancel = 1 |
117 | break; | 61 | break; |
118 | elseif button == EXIT_BUTTON then | 62 | elseif button == BUTTON.EXIT then |
119 | cancel = 1 | 63 | cancel = 1 |
120 | break; | 64 | break; |
121 | elseif button == SEL_BUTTON then | 65 | elseif button == BUTTON.SEL then |
122 | select = 1 | 66 | select = 1 |
123 | timeout = timeout + 1 | 67 | timeout = timeout + 1 |
124 | elseif button == SELR_BUTTON then | 68 | elseif button == BUTTON.SELR then |
125 | select = 2 | 69 | select = 2 |
126 | timeout = timeout + 1 | 70 | timeout = timeout + 1 |
127 | elseif button == SELREL_BUTTON then | 71 | elseif button == BUTTON.SELREL then |
128 | select = -1 | 72 | select = -1 |
129 | timeout = timeout + 1 | 73 | timeout = timeout + 1 |
130 | elseif button == LEFT_BUTTON then | 74 | elseif button == BUTTON.LEFT then |
131 | x_chg = x_chg - xi | 75 | x_chg = x_chg - xi |
132 | if scroll_is_fixed then | 76 | if scroll_is_fixed then |
133 | cancel = 1 | 77 | cancel = 1 |
134 | break; | 78 | break; |
135 | end | 79 | end |
136 | elseif button == LEFTR_BUTTON then | 80 | elseif button == BUTTON.LEFTR then |
137 | x_chg = x_chg - xir | 81 | x_chg = x_chg - xir |
138 | elseif button == RIGHT_BUTTON then | 82 | elseif button == BUTTON.RIGHT then |
139 | x_chg = x_chg + xi | 83 | x_chg = x_chg + xi |
140 | if scroll_is_fixed then | 84 | if scroll_is_fixed then |
141 | select = 1 | 85 | select = 1 |
142 | timeout = timeout + 1 | 86 | timeout = timeout + 1 |
143 | end | 87 | end |
144 | elseif button == RIGHTR_BUTTON then | 88 | elseif button == BUTTON.RIGHTR then |
145 | x_chg = x_chg + xir | 89 | x_chg = x_chg + xir |
146 | elseif button == UP_BUTTON then | 90 | elseif button == BUTTON.UP then |
147 | y_chg = y_chg + yi | 91 | y_chg = y_chg + yi |
148 | elseif button == UPR_BUTTON then | 92 | elseif button == BUTTON.UPR then |
149 | y_chg = y_chg + yir | 93 | y_chg = y_chg + yir |
150 | elseif button == DOWN_BUTTON then | 94 | elseif button == BUTTON.DOWN then |
151 | y_chg = y_chg - yi | 95 | y_chg = y_chg - yi |
152 | elseif button == DOWNR_BUTTON then | 96 | elseif button == BUTTON.DOWNR then |
153 | y_chg = y_chg - yir | 97 | y_chg = y_chg - yir |
154 | elseif timeout >= 0 then--and rb.button_queue_count() < 1 then | 98 | elseif timeout >= 0 then--and rb.button_queue_count() < 1 then |
155 | break; | 99 | break; |
@@ -175,7 +119,6 @@ function print_menu(menu_t, func_t, selected, settings, copy_screen) | |||
175 | if selected then vcur = selected + 1 end | 119 | if selected then vcur = selected + 1 end |
176 | if vcur and vcur <= 1 then vcur = 2 end | 120 | if vcur and vcur <= 1 then vcur = 2 end |
177 | 121 | ||
178 | get_core_settings() | ||
179 | local c_table = rb.core_color_table or {} | 122 | local c_table = rb.core_color_table or {} |
180 | 123 | ||
181 | if not settings then | 124 | if not settings then |
@@ -239,7 +182,7 @@ function print_menu(menu_t, func_t, selected, settings, copy_screen) | |||
239 | if copy_screen == true then _LCD:copy(screen_img) end | 182 | if copy_screen == true then _LCD:copy(screen_img) end |
240 | 183 | ||
241 | if func_t and func_t[i] then | 184 | if func_t and func_t[i] then |
242 | if func_t[i](i, menu_t) == true then break end | 185 | if func_t[i](i, menu_t, func_t) == true then break end |
243 | else | 186 | else |
244 | break | 187 | break |
245 | end | 188 | end |
diff --git a/apps/plugins/lua/include_lua/printsubmenu.lua b/apps/plugins/lua/include_lua/printsubmenu.lua new file mode 100644 index 0000000000..3c61b5fda8 --- /dev/null +++ b/apps/plugins/lua/include_lua/printsubmenu.lua | |||
@@ -0,0 +1,263 @@ | |||
1 | --[[ | ||
2 | /*************************************************************************** | ||
3 | * __________ __ ___. | ||
4 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
5 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
6 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
7 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
8 | * \/ \/ \/ \/ \/ | ||
9 | * $Id$ | ||
10 | * | ||
11 | * Copyright (C) 2021 William Wilgus | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | ]] | ||
23 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end | ||
24 | menu_ctx = {} | ||
25 | local last_ctx = false | ||
26 | local p_settings | ||
27 | |||
28 | --[[root menu tables | ||
29 | expanded menus get inserted / removed | ||
30 | and context menus replace them but never overwritten | ||
31 | unless you want a new root menu | ||
32 | ]] | ||
33 | menu_t = {} | ||
34 | func_t = {} | ||
35 | |||
36 | require("printmenus") | ||
37 | |||
38 | local BUTTON = require("menubuttons") | ||
39 | local last_sel = 0 | ||
40 | |||
41 | local function display_context_menu() end -- forward declaration | ||
42 | |||
43 | local function dpad(x, xi, xir, y, yi, yir, timeout, overflow, selected) | ||
44 | local scroll_is_fixed = overflow ~= "manual" | ||
45 | if timeout == nil then timeout = -1 end | ||
46 | local cancel, select = 0, 0 | ||
47 | local x_chg, y_chg = 0, 0 | ||
48 | local button | ||
49 | while true do | ||
50 | button = rb.get_plugin_action(timeout) | ||
51 | |||
52 | if button == BUTTON.CANCEL then | ||
53 | cancel = 1 | ||
54 | break; | ||
55 | elseif button == BUTTON.EXIT then | ||
56 | cancel = 1 | ||
57 | break; | ||
58 | elseif button == BUTTON.SEL then | ||
59 | last_sel = 1 | ||
60 | timeout = timeout + 1 | ||
61 | elseif button == BUTTON.SELR then | ||
62 | last_sel = 2 | ||
63 | if display_context_menu(selected or -1) == true then | ||
64 | select = 1 | ||
65 | break; | ||
66 | end | ||
67 | timeout = timeout + 1 | ||
68 | elseif button == BUTTON.SELREL then | ||
69 | if last_sel == 1 then | ||
70 | select = 1 | ||
71 | end | ||
72 | last_sel = 0 | ||
73 | timeout = timeout + 1 | ||
74 | elseif button == BUTTON.LEFT then | ||
75 | x_chg = x_chg - xi | ||
76 | if scroll_is_fixed then | ||
77 | cancel = 1 | ||
78 | break; | ||
79 | end | ||
80 | elseif button == BUTTON.LEFTR then | ||
81 | x_chg = x_chg - xir | ||
82 | elseif button == BUTTON.RIGHT then | ||
83 | x_chg = x_chg + xi | ||
84 | if scroll_is_fixed then | ||
85 | select = 1 | ||
86 | timeout = timeout + 1 | ||
87 | end | ||
88 | elseif button == BUTTON.RIGHTR then | ||
89 | x_chg = x_chg + xir | ||
90 | elseif button == BUTTON.UP then | ||
91 | y_chg = y_chg + yi | ||
92 | elseif button == BUTTON.UPR then | ||
93 | y_chg = y_chg + yir | ||
94 | elseif button == BUTTON.DOWN then | ||
95 | y_chg = y_chg - yi | ||
96 | elseif button == BUTTON.DOWNR then | ||
97 | y_chg = y_chg - yir | ||
98 | elseif timeout >= 0 then--and rb.button_queue_count() < 1 then | ||
99 | break; | ||
100 | end | ||
101 | |||
102 | if x_chg ~= 0 or y_chg ~= 0 then | ||
103 | timeout = timeout + 1 | ||
104 | end | ||
105 | end | ||
106 | |||
107 | x = x + x_chg | ||
108 | y = y + y_chg | ||
109 | |||
110 | return cancel, select, x_chg, x, y_chg, y, 0xffff | ||
111 | end -- dpad | ||
112 | |||
113 | |||
114 | |||
115 | local function menu_set_defaults(settings, ctx) | ||
116 | p_settings = settings or {wrap = true, hasheader = true, justify = "left", dpad_fn = dpad} | ||
117 | menu_ctx = ctx or {collapse_fn = {}, lv = 0, update = false, start = 1} | ||
118 | end | ||
119 | |||
120 | local function ctx_loop() | ||
121 | local loopfn = ctx_loop | ||
122 | ctx_loop = function() end --prevent another execution | ||
123 | local mt, ft = get_menu() | ||
124 | local i | ||
125 | repeat | ||
126 | if menu_ctx.update then mt, ft = get_menu(); menu_ctx.update = false end | ||
127 | _, i = print_menu(mt, ft, menu_ctx.start, p_settings) | ||
128 | until menu_ctx.quit | ||
129 | |||
130 | ctx_loop = loopfn --restore for another run | ||
131 | end | ||
132 | |||
133 | function get_menu() | ||
134 | return menu_t, func_t | ||
135 | end | ||
136 | |||
137 | local function push_ctx(new_getmenu) | ||
138 | last_ctx = last_ctx or {} | ||
139 | table.insert(last_ctx, menu_ctx) | ||
140 | menu_ctx.getmenu = get_menu | ||
141 | menu_ctx.settings = p_settings | ||
142 | --menu_ctx is a new variable after this point | ||
143 | menu_set_defaults() | ||
144 | menu_ctx.update = true | ||
145 | if type(new_getmenu) == 'function' then | ||
146 | get_menu = new_getmenu | ||
147 | end | ||
148 | end | ||
149 | |||
150 | local function pop_ctx() | ||
151 | menu_ctx = table.remove(last_ctx) | ||
152 | if menu_ctx then | ||
153 | get_menu = menu_ctx.getmenu | ||
154 | p_settings = menu_ctx.settings | ||
155 | if menu_ctx.restorefn then | ||
156 | menu_ctx.restorefn(menu_t, func_t) | ||
157 | menu_ctx.restorefn = nil | ||
158 | end | ||
159 | menu_ctx.getmenu = nil | ||
160 | menu_ctx.settings = nil | ||
161 | menu_ctx.update = true | ||
162 | return true | ||
163 | end | ||
164 | end | ||
165 | |||
166 | local function display_context_menu_internal(sel) | ||
167 | |||
168 | if sel <= 0 or not menu_ctx.user_context_fn then return false end | ||
169 | local parent = get_parent() or 0 | ||
170 | local user_context_fn = menu_ctx.user_context_fn | ||
171 | local function display_context_menu(i, menu_t, func_t) | ||
172 | |||
173 | local function new_getmenu() | ||
174 | local mt, ft = user_context_fn(parent, i, menu_t, func_t) | ||
175 | ft[0] = pop_ctx --set back fn | ||
176 | return mt, ft | ||
177 | end | ||
178 | push_ctx(new_getmenu) | ||
179 | return true | ||
180 | end | ||
181 | |||
182 | local funct = func_t[sel] | ||
183 | local function restore_fn(mt, ft) | ||
184 | ft[sel] = funct | ||
185 | menu_ctx.start = sel - 1 | ||
186 | end | ||
187 | |||
188 | menu_ctx.restorefn = restore_fn | ||
189 | -- insert into the current fn table so it gets execd by the menu | ||
190 | func_t[sel] = display_context_menu | ||
191 | |||
192 | return true | ||
193 | end | ||
194 | |||
195 | function get_parent(lv) | ||
196 | lv = lv or #menu_ctx.collapse_fn | ||
197 | collectgarbage("step") | ||
198 | local t = menu_ctx.collapse_fn[lv] or {} | ||
199 | return t[2] or -1 | ||
200 | end | ||
201 | |||
202 | function set_menu(mt, ft, user_context_fn, settings) | ||
203 | local function empty_fn() end | ||
204 | menu_set_defaults(settings) | ||
205 | if type(user_context_fn) == 'function' then | ||
206 | display_context_menu = display_context_menu_internal | ||
207 | menu_ctx.user_context_fn = user_context_fn | ||
208 | else | ||
209 | display_context_menu = empty_fn | ||
210 | menu_ctx.user_context_fn = false | ||
211 | end | ||
212 | p_settings = settings or p_settings | ||
213 | menu_t, func_t = mt, ft | ||
214 | ctx_loop() | ||
215 | end | ||
216 | |||
217 | function create_sub_menu(lv, mt, ft) | ||
218 | if lv < 1 then error("Level < 1") end | ||
219 | -- everything in lua is 1 based menu level is no exception | ||
220 | local lv_tab = string.rep ("\t", lv) | ||
221 | local function submenu_closure(i, m, f) | ||
222 | menu_ctx.lv = lv | ||
223 | local lv_out, menusz_out, start_item | ||
224 | local item_in, item_out = i, i | ||
225 | if lv <= #menu_ctx.collapse_fn then --something else expanded?? | ||
226 | repeat | ||
227 | local collapse_fn = table.remove(menu_ctx.collapse_fn) | ||
228 | if collapse_fn then | ||
229 | lv_out, item_out, menusz_out = collapse_fn[1](i, m, f) | ||
230 | -- if the item i is below this menu, it needs to shift too | ||
231 | if item_in > item_out then i = i - (menusz_out) end | ||
232 | end | ||
233 | until not collapse_fn or lv >= lv_out | ||
234 | menu_ctx.start = i | ||
235 | if item_out == item_in then return end | ||
236 | end | ||
237 | |||
238 | local menu_sz = #mt | ||
239 | menu_ctx.start = i | ||
240 | start_item = i | ||
241 | menu_ctx.update = true | ||
242 | for item, _ in ipairs(mt) do | ||
243 | i = i + 1 | ||
244 | table.insert(m, i, lv_tab .. mt[item]) | ||
245 | table.insert(f, i, ft[item]) | ||
246 | end | ||
247 | |||
248 | local function collapse_closure(i, m, f) | ||
249 | --creates a closure around lv, start_item and menu_sz | ||
250 | for j = 1, menu_sz, 1 do | ||
251 | table.remove(m, start_item + 1) | ||
252 | table.remove(f, start_item + 1) | ||
253 | end | ||
254 | return lv, start_item, menu_sz | ||
255 | end | ||
256 | |||
257 | table.insert(menu_ctx.collapse_fn, lv, {collapse_closure, start_item}) | ||
258 | return true | ||
259 | end | ||
260 | |||
261 | return submenu_closure | ||
262 | end | ||
263 | |||
diff --git a/apps/plugins/lua/include_lua/printtable.lua b/apps/plugins/lua/include_lua/printtable.lua index c23d801f83..bf81c7b060 100644 --- a/apps/plugins/lua/include_lua/printtable.lua +++ b/apps/plugins/lua/include_lua/printtable.lua | |||
@@ -22,28 +22,12 @@ | |||
22 | ]] | 22 | ]] |
23 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end | 23 | if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end |
24 | 24 | ||
25 | require("actions") -- Contains rb.actions & rb.contexts | ||
26 | |||
27 | local _clr = require("color") | 25 | local _clr = require("color") |
28 | local _print = require("print") | 26 | local _print = require("print") |
29 | local _timer = require("timer") | 27 | local _timer = require("timer") |
28 | local BUTTON = require("menubuttons") | ||
30 | local sb_width = 5 | 29 | local sb_width = 5 |
31 | 30 | ||
32 | -- Button definitions -- | ||
33 | local CANCEL_BUTTON = rb.actions.PLA_CANCEL | ||
34 | local DOWN_BUTTON = rb.actions.PLA_DOWN | ||
35 | local DOWNR_BUTTON = rb.actions.PLA_DOWN_REPEAT | ||
36 | local EXIT_BUTTON = rb.actions.PLA_EXIT | ||
37 | local LEFT_BUTTON = rb.actions.PLA_LEFT | ||
38 | local LEFTR_BUTTON = rb.actions.PLA_LEFT_REPEAT | ||
39 | local RIGHT_BUTTON = rb.actions.PLA_RIGHT | ||
40 | local RIGHTR_BUTTON = rb.actions.PLA_RIGHT_REPEAT | ||
41 | local SEL_BUTTON = rb.actions.PLA_SELECT | ||
42 | local SELREL_BUTTON = rb.actions.PLA_SELECT_REL | ||
43 | local SELR_BUTTON = rb.actions.PLA_SELECT_REPEAT | ||
44 | local UP_BUTTON = rb.actions.PLA_UP | ||
45 | local UPR_BUTTON = rb.actions.PLA_UP_REPEAT | ||
46 | |||
47 | -- clamps value to >= min and <= max | 31 | -- clamps value to >= min and <= max |
48 | local function clamp(iVal, iMin, iMax) | 32 | local function clamp(iVal, iMin, iMax) |
49 | if iMin > iMax then | 33 | if iMin > iMax then |
@@ -71,7 +55,7 @@ end | |||
71 | -- time since last button press is returned in ticks.. | 55 | -- time since last button press is returned in ticks.. |
72 | -- make xi, xir, yi, yir negative to flip direction... | 56 | -- make xi, xir, yi, yir negative to flip direction... |
73 | ]] | 57 | ]] |
74 | local function dpad(x, xi, xir, y, yi, yir, timeout, overflow) | 58 | local function dpad(x, xi, xir, y, yi, yir, timeout, overflow, selected) |
75 | local scroll_is_fixed = overflow ~= "manual" | 59 | local scroll_is_fixed = overflow ~= "manual" |
76 | _timer("dpad") -- start a persistant timer; keeps time between button events | 60 | _timer("dpad") -- start a persistant timer; keeps time between button events |
77 | if timeout == nil then timeout = -1 end | 61 | if timeout == nil then timeout = -1 end |
@@ -81,44 +65,44 @@ local function dpad(x, xi, xir, y, yi, yir, timeout, overflow) | |||
81 | while true do | 65 | while true do |
82 | button = rb.get_plugin_action(timeout) | 66 | button = rb.get_plugin_action(timeout) |
83 | 67 | ||
84 | if button == CANCEL_BUTTON then | 68 | if button == BUTTON.CANCEL then |
85 | cancel = 1 | 69 | cancel = 1 |
86 | break; | 70 | break; |
87 | elseif button == EXIT_BUTTON then | 71 | elseif button == BUTTON.EXIT then |
88 | cancel = 1 | 72 | cancel = 1 |
89 | break; | 73 | break; |
90 | elseif button == SEL_BUTTON then | 74 | elseif button == BUTTON.SEL then |
91 | select = 1 | 75 | select = 1 |
92 | timeout = timeout + 1 | 76 | timeout = timeout + 1 |
93 | elseif button == SELR_BUTTON then | 77 | elseif button == BUTTON.SELR then |
94 | select = 2 | 78 | select = 2 |
95 | timeout = timeout + 1 | 79 | timeout = timeout + 1 |
96 | elseif button == SELREL_BUTTON then | 80 | elseif button == BUTTON.SELREL then |
97 | select = -1 | 81 | select = -1 |
98 | timeout = timeout + 1 | 82 | timeout = timeout + 1 |
99 | elseif button == LEFT_BUTTON then | 83 | elseif button == BUTTON.LEFT then |
100 | x_chg = x_chg - xi | 84 | x_chg = x_chg - xi |
101 | if scroll_is_fixed then | 85 | if scroll_is_fixed then |
102 | cancel = 1 | 86 | cancel = 1 |
103 | break; | 87 | break; |
104 | end | 88 | end |
105 | elseif button == LEFTR_BUTTON then | 89 | elseif button == BUTTON.LEFTR then |
106 | x_chg = x_chg - xir | 90 | x_chg = x_chg - xir |
107 | elseif button == RIGHT_BUTTON then | 91 | elseif button == BUTTON.RIGHT then |
108 | x_chg = x_chg + xi | 92 | x_chg = x_chg + xi |
109 | if scroll_is_fixed then | 93 | if scroll_is_fixed then |
110 | select = 1 | 94 | select = 1 |
111 | timeout = timeout + 1 | 95 | timeout = timeout + 1 |
112 | end | 96 | end |
113 | elseif button == RIGHTR_BUTTON then | 97 | elseif button == BUTTON.RIGHTR then |
114 | x_chg = x_chg + xir | 98 | x_chg = x_chg + xir |
115 | elseif button == UP_BUTTON then | 99 | elseif button == BUTTON.UP then |
116 | y_chg = y_chg + yi | 100 | y_chg = y_chg + yi |
117 | elseif button == UPR_BUTTON then | 101 | elseif button == BUTTON.UPR then |
118 | y_chg = y_chg + yir | 102 | y_chg = y_chg + yir |
119 | elseif button == DOWN_BUTTON then | 103 | elseif button == BUTTON.DOWN then |
120 | y_chg = y_chg - yi | 104 | y_chg = y_chg - yi |
121 | elseif button == DOWNR_BUTTON then | 105 | elseif button == BUTTON.DOWNR then |
122 | y_chg = y_chg - yir | 106 | y_chg = y_chg - yir |
123 | elseif timeout >= 0 then--and rb.button_queue_count() < 1 then | 107 | elseif timeout >= 0 then--and rb.button_queue_count() < 1 then |
124 | break; | 108 | break; |
@@ -247,7 +231,8 @@ function print_table(t, t_count, settings) | |||
247 | rb.lcd_update() | 231 | rb.lcd_update() |
248 | 232 | ||
249 | local quit, select, x_chg, xi, y_chg, yi, timeb = | 233 | local quit, select, x_chg, xi, y_chg, yi, timeb = |
250 | dpad_fn(t_p.col, -1, -t_p.col_scrl, t_p.row, -1, -t_p.row_scrl, nil, overflow) | 234 | dpad_fn(t_p.col, -1, -t_p.col_scrl, t_p.row, -1, -t_p.row_scrl, |
235 | nil, overflow, (t_p.row + t_p.vcursor - 1)) | ||
251 | 236 | ||
252 | t_p.vcursor = t_p.vcursor + y_chg | 237 | t_p.vcursor = t_p.vcursor + y_chg |
253 | 238 | ||
@@ -316,7 +301,7 @@ function print_table(t, t_count, settings) | |||
316 | if t[i] == nil then | 301 | if t[i] == nil then |
317 | rb.splash(1, string.format("ERROR %d is nil", i)) | 302 | rb.splash(1, string.format("ERROR %d is nil", i)) |
318 | t[i] = "???" | 303 | t[i] = "???" |
319 | if rb.get_plugin_action(10) == CANCEL_BUTTON then return 0 end | 304 | if rb.get_plugin_action(10) == BUTTON.CANCEL then return 0 end |
320 | end | 305 | end |
321 | 306 | ||
322 | if m_sel == true and t[i]:sub(-1) == "\0" then | 307 | if m_sel == true and t[i]:sub(-1) == "\0" then |
diff --git a/apps/plugins/lua/lua.make b/apps/plugins/lua/lua.make index 1e74277549..f6dba72aed 100644 --- a/apps/plugins/lua/lua.make +++ b/apps/plugins/lua/lua.make | |||
@@ -16,11 +16,13 @@ LUA_OBJ := $(call c2obj, $(LUA_SRC)) | |||
16 | OTHER_SRC += $(LUA_SRC) | 16 | OTHER_SRC += $(LUA_SRC) |
17 | 17 | ||
18 | LUA_INCLUDEDIR := $(LUA_SRCDIR)/include_lua | 18 | LUA_INCLUDEDIR := $(LUA_SRCDIR)/include_lua |
19 | LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua draw.lua draw_floodfill.lua draw_poly.lua \ | 19 | LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua \ |
20 | draw_num.lua draw_text.lua files.lua image.lua image_save.lua lcd.lua math_ex.lua \ | 20 | draw.lua draw_floodfill.lua draw_poly.lua draw_num.lua \ |
21 | print.lua timer.lua playlist.lua pcm.lua sound.lua printmenus.lua\ | 21 | draw_text.lua files.lua image.lua image_save.lua lcd.lua \ |
22 | rbcompat.lua rbsettings.lua poly_points.lua printtable.lua) | 22 | math_ex.lua print.lua timer.lua playlist.lua pcm.lua \ |
23 | 23 | sound.lua rbcompat.lua rbsettings.lua poly_points.lua \ | |
24 | printtable.lua printmenus.lua printsubmenu.lua \ | ||
25 | menubuttons.lua menucoresettings.lua) | ||
24 | 26 | ||
25 | ifndef APP_TYPE | 27 | ifndef APP_TYPE |
26 | ROCKS += $(LUA_BUILDDIR)/lua.rock | 28 | ROCKS += $(LUA_BUILDDIR)/lua.rock |
diff --git a/apps/plugins/lua_scripts/submenu_demo.lua b/apps/plugins/lua_scripts/submenu_demo.lua new file mode 100644 index 0000000000..75fec11979 --- /dev/null +++ b/apps/plugins/lua_scripts/submenu_demo.lua | |||
@@ -0,0 +1,93 @@ | |||
1 | --Bilgus 4/2021 Menu with subitems and context demo | ||
2 | require("printsubmenu") | ||
3 | |||
4 | local scrpath = rb.current_path() | ||
5 | |||
6 | local function get_ctx_menu(parent, sel, menu_t, func_t) | ||
7 | local mt = {"Context menu " .. (menu_t[parent] or "ROOT") .. | ||
8 | " : " .. menu_t[sel], "Quit", "Action 1", "Action 2"} | ||
9 | local ft = {false, function() menu_ctx.quit = true return true end} | ||
10 | return mt, ft | ||
11 | end | ||
12 | |||
13 | local function ITEM_MENU() | ||
14 | |||
15 | local function flung(i, menu_t, func_t) | ||
16 | local parent = get_parent() or 0 | ||
17 | rb.splash(100, "flung " .. (menu_t[parent] or "?")) | ||
18 | end | ||
19 | |||
20 | local function foo(i, menu_t, func_t) | ||
21 | local parent = get_parent() or 0 | ||
22 | rb.splash(100, "FOO " .. menu_t[parent]) | ||
23 | end | ||
24 | |||
25 | local function far(i, menu_t, func_t) | ||
26 | local parent = get_parent() or 0 | ||
27 | rb.splash(100, "far" .. menu_t[parent]) | ||
28 | end | ||
29 | |||
30 | return {"Flung", "FOO", "Far"}, | ||
31 | {flung, foo, far} | ||
32 | end | ||
33 | |||
34 | local function USERITEMS() | ||
35 | |||
36 | return {"Item_1", "Item_2", "Item_3"}, | ||
37 | {create_sub_menu(2, ITEM_MENU()), create_sub_menu(2, ITEM_MENU()), | ||
38 | create_sub_menu(2, ITEM_MENU()), function() end} | ||
39 | end | ||
40 | |||
41 | local function MAIN_MENU() | ||
42 | |||
43 | local function go_back(i, m, f) | ||
44 | local parent = get_parent() or 0 | ||
45 | if parent > 0 then | ||
46 | f[parent](parent, m, f) | ||
47 | else | ||
48 | menu_ctx.quit = true | ||
49 | end | ||
50 | menu_ctx.start = parent - 1 | ||
51 | return true | ||
52 | end | ||
53 | |||
54 | local mt = { | ||
55 | [1] = "lua Menu Demo", | ||
56 | [2] = "Items", | ||
57 | [3] = "Back", | ||
58 | } | ||
59 | |||
60 | local ft = { | ||
61 | [0] = go_back, --if user cancels do this function | ||
62 | [1] = false, -- shouldn't happen title occupies this slot | ||
63 | [2] = create_sub_menu(1, USERITEMS()), | ||
64 | [3] = go_back, | ||
65 | } | ||
66 | return mt, ft, get_ctx_menu | ||
67 | end | ||
68 | |||
69 | function ShowMain() | ||
70 | set_menu(MAIN_MENU()) | ||
71 | end | ||
72 | |||
73 | --ShowMainMenu() | ||
74 | ShowMain() | ||
75 | rb.lcd_clear_display() | ||
76 | rb.lcd_update() | ||
77 | local lu = collectgarbage("collect") | ||
78 | local used, allocd, free = rb.mem_stats() | ||
79 | local lu = collectgarbage("count") | ||
80 | local fmt = function(t, v) return string.format("%s: %d Kb\n", t, v /1024) end | ||
81 | |||
82 | -- this is how lua recommends to concat strings rather than .. | ||
83 | local s_t = {} | ||
84 | s_t[1] = "rockbox:\n" | ||
85 | s_t[2] = fmt("Used ", used) | ||
86 | s_t[3] = fmt("Allocd ", allocd) | ||
87 | s_t[4] = fmt("Free ", free) | ||
88 | s_t[5] = "\nlua:\n" | ||
89 | s_t[6] = fmt("Used", lu * 1024) | ||
90 | s_t[7] = "\n\nNote that the rockbox used count is a high watermark" | ||
91 | rb.splash_scroller(5 * rb.HZ, table.concat(s_t)) | ||
92 | --require("print_lua_func") | ||
93 | os.exit(1, "Goodbye") | ||