diff options
Diffstat (limited to 'apps/plugins/lua/include_lua/printsubmenu.lua')
-rw-r--r-- | apps/plugins/lua/include_lua/printsubmenu.lua | 135 |
1 files changed, 93 insertions, 42 deletions
diff --git a/apps/plugins/lua/include_lua/printsubmenu.lua b/apps/plugins/lua/include_lua/printsubmenu.lua index 3c61b5fda8..f4b93db98d 100644 --- a/apps/plugins/lua/include_lua/printsubmenu.lua +++ b/apps/plugins/lua/include_lua/printsubmenu.lua | |||
@@ -21,15 +21,31 @@ | |||
21 | ****************************************************************************/ | 21 | ****************************************************************************/ |
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 | --GLOBALS | ||
24 | menu_ctx = {} | 25 | menu_ctx = {} |
26 | submenu_insert = table.insert | ||
27 | submenu_remove = table.remove | ||
28 | |||
25 | local last_ctx = false | 29 | local last_ctx = false |
26 | local p_settings | 30 | local p_settings |
31 | local function empty_fn() end | ||
27 | 32 | ||
28 | --[[root menu tables | 33 | --[[root menu tables |
29 | expanded menus get inserted / removed | 34 | expanded menus get inserted / removed |
30 | and context menus replace them but never overwritten | 35 | and context menus replace them but unless you |
31 | unless you want a new root menu | 36 | want a new root menu they are never overwritten |
37 | func_t functions get 3 variables passed by the menu_system | ||
38 | func_t[i] =function sample(i, menu_t, func_t] | ||
39 | this function gets run on user selection | ||
40 | for every function in func_t: | ||
41 | 'i' is the selected item | ||
42 | 'menu_t' is the current strings table | ||
43 | 'func_t' is the current function table | ||
44 | |||
45 | menu_t[i] will returnm the text of the item user selected and | ||
46 | func_t[i] will return the function we are currently in | ||
32 | ]] | 47 | ]] |
48 | |||
33 | menu_t = {} | 49 | menu_t = {} |
34 | func_t = {} | 50 | func_t = {} |
35 | 51 | ||
@@ -110,16 +126,9 @@ local function dpad(x, xi, xir, y, yi, yir, timeout, overflow, selected) | |||
110 | return cancel, select, x_chg, x, y_chg, y, 0xffff | 126 | return cancel, select, x_chg, x, y_chg, y, 0xffff |
111 | end -- dpad | 127 | end -- dpad |
112 | 128 | ||
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() | 129 | local function ctx_loop() |
121 | local loopfn = ctx_loop | 130 | local loopfn = ctx_loop |
122 | ctx_loop = function() end --prevent another execution | 131 | ctx_loop = empty_fn() --prevent another execution |
123 | local mt, ft = get_menu() | 132 | local mt, ft = get_menu() |
124 | local i | 133 | local i |
125 | repeat | 134 | repeat |
@@ -130,25 +139,23 @@ local function ctx_loop() | |||
130 | ctx_loop = loopfn --restore for another run | 139 | ctx_loop = loopfn --restore for another run |
131 | end | 140 | end |
132 | 141 | ||
133 | function get_menu() | 142 | --[[ push_ctx() save surrent menu and load another ]] |
134 | return menu_t, func_t | ||
135 | end | ||
136 | |||
137 | local function push_ctx(new_getmenu) | 143 | local function push_ctx(new_getmenu) |
138 | last_ctx = last_ctx or {} | 144 | last_ctx = last_ctx or {} |
139 | table.insert(last_ctx, menu_ctx) | 145 | submenu_insert(last_ctx, menu_ctx) |
140 | menu_ctx.getmenu = get_menu | 146 | menu_ctx.getmenu = get_menu |
141 | menu_ctx.settings = p_settings | 147 | menu_ctx.settings = p_settings |
142 | --menu_ctx is a new variable after this point | 148 | --menu_ctx is a new variable after this point |
143 | menu_set_defaults() | 149 | submenu_set_defaults() |
144 | menu_ctx.update = true | 150 | menu_ctx.update = true |
145 | if type(new_getmenu) == 'function' then | 151 | if type(new_getmenu) == 'function' then |
146 | get_menu = new_getmenu | 152 | get_menu = new_getmenu |
147 | end | 153 | end |
148 | end | 154 | end |
149 | 155 | ||
156 | --[[ pop_ctx() restore last menu ]] | ||
150 | local function pop_ctx() | 157 | local function pop_ctx() |
151 | menu_ctx = table.remove(last_ctx) | 158 | menu_ctx = submenu_remove(last_ctx) |
152 | if menu_ctx then | 159 | if menu_ctx then |
153 | get_menu = menu_ctx.getmenu | 160 | get_menu = menu_ctx.getmenu |
154 | p_settings = menu_ctx.settings | 161 | p_settings = menu_ctx.settings |
@@ -163,13 +170,17 @@ local function pop_ctx() | |||
163 | end | 170 | end |
164 | end | 171 | end |
165 | 172 | ||
173 | --[[ display_context_menu_internal() supplies a new get_menu function that returns | ||
174 | the context menu 'user_context_fn' supplied by set_menu() | ||
175 | this menu is immediately displayed and when finished will | ||
176 | automatically restore the last menu | ||
177 | ]] | ||
166 | local function display_context_menu_internal(sel) | 178 | local function display_context_menu_internal(sel) |
167 | |||
168 | if sel <= 0 or not menu_ctx.user_context_fn then return false end | 179 | if sel <= 0 or not menu_ctx.user_context_fn then return false end |
169 | local parent = get_parent() or 0 | 180 | local parent = submenu_get_parent() or 0 |
170 | local user_context_fn = menu_ctx.user_context_fn | 181 | local user_context_fn = menu_ctx.user_context_fn |
171 | local function display_context_menu(i, menu_t, func_t) | ||
172 | 182 | ||
183 | local function display_context_menu(i, menu_t, func_t) | ||
173 | local function new_getmenu() | 184 | local function new_getmenu() |
174 | local mt, ft = user_context_fn(parent, i, menu_t, func_t) | 185 | local mt, ft = user_context_fn(parent, i, menu_t, func_t) |
175 | ft[0] = pop_ctx --set back fn | 186 | ft[0] = pop_ctx --set back fn |
@@ -179,6 +190,7 @@ local function display_context_menu_internal(sel) | |||
179 | return true | 190 | return true |
180 | end | 191 | end |
181 | 192 | ||
193 | --save the current function in closure restore_fn for later | ||
182 | local funct = func_t[sel] | 194 | local funct = func_t[sel] |
183 | local function restore_fn(mt, ft) | 195 | local function restore_fn(mt, ft) |
184 | ft[sel] = funct | 196 | ft[sel] = funct |
@@ -192,30 +204,43 @@ local function display_context_menu_internal(sel) | |||
192 | return true | 204 | return true |
193 | end | 205 | end |
194 | 206 | ||
195 | function get_parent(lv) | 207 | --[[ submenu_get_parent() gets the parent of the top most level |
196 | lv = lv or #menu_ctx.collapse_fn | 208 | if lv is supplied it instead gets the parent of that level ]] |
209 | function submenu_get_parent(lv) | ||
210 | lv = lv or #menu_ctx.collapse_fn or 1 | ||
197 | collectgarbage("step") | 211 | collectgarbage("step") |
198 | local t = menu_ctx.collapse_fn[lv] or {} | 212 | local t = menu_ctx.collapse_fn[lv] or {} |
199 | return t[2] or -1 | 213 | return t[2] or -1, lv |
200 | end | 214 | end |
201 | 215 | ||
202 | function set_menu(mt, ft, user_context_fn, settings) | 216 | --[[ submenu_collapse() collapses submenu till level or ROOT is reached ]] |
203 | local function empty_fn() end | 217 | function submenu_collapse(parent, lv) |
204 | menu_set_defaults(settings) | 218 | local lv_out, menu_sz = 0, 0 |
205 | if type(user_context_fn) == 'function' then | 219 | local item_out = -1 |
206 | display_context_menu = display_context_menu_internal | 220 | local items_removed = 0 |
207 | menu_ctx.user_context_fn = user_context_fn | 221 | if lv <= #menu_ctx.collapse_fn then |
208 | else | 222 | repeat |
209 | display_context_menu = empty_fn | 223 | local collapse_fn = submenu_remove(menu_ctx.collapse_fn) |
210 | menu_ctx.user_context_fn = false | 224 | if collapse_fn then |
225 | lv_out, item_out, menu_sz = collapse_fn[1](parent, menu_t, func_t) | ||
226 | items_removed = items_removed + menu_sz | ||
227 | end | ||
228 | |||
229 | until not collapse_fn or lv >= lv_out | ||
211 | end | 230 | end |
212 | p_settings = settings or p_settings | 231 | return lv_out, item_out, items_removed |
213 | menu_t, func_t = mt, ft | ||
214 | ctx_loop() | ||
215 | end | 232 | end |
216 | 233 | ||
217 | function create_sub_menu(lv, mt, ft) | 234 | --[[ submenu_create() supply level of submenu > 0, ROOT is lv 0 |
235 | supply menu strings table and function table | ||
236 | closure returned run this function to expand the menu | ||
237 | ]] | ||
238 | function submenu_create(lv, mt, ft) | ||
218 | if lv < 1 then error("Level < 1") end | 239 | if lv < 1 then error("Level < 1") end |
240 | if type(mt) ~= 'table' or type(ft) ~= 'table' then | ||
241 | error("mt and ft must be tables") | ||
242 | end | ||
243 | |||
219 | -- everything in lua is 1 based menu level is no exception | 244 | -- everything in lua is 1 based menu level is no exception |
220 | local lv_tab = string.rep ("\t", lv) | 245 | local lv_tab = string.rep ("\t", lv) |
221 | local function submenu_closure(i, m, f) | 246 | local function submenu_closure(i, m, f) |
@@ -224,7 +249,7 @@ function create_sub_menu(lv, mt, ft) | |||
224 | local item_in, item_out = i, i | 249 | local item_in, item_out = i, i |
225 | if lv <= #menu_ctx.collapse_fn then --something else expanded?? | 250 | if lv <= #menu_ctx.collapse_fn then --something else expanded?? |
226 | repeat | 251 | repeat |
227 | local collapse_fn = table.remove(menu_ctx.collapse_fn) | 252 | local collapse_fn = submenu_remove(menu_ctx.collapse_fn) |
228 | if collapse_fn then | 253 | if collapse_fn then |
229 | lv_out, item_out, menusz_out = collapse_fn[1](i, m, f) | 254 | 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 | 255 | -- if the item i is below this menu, it needs to shift too |
@@ -241,23 +266,49 @@ function create_sub_menu(lv, mt, ft) | |||
241 | menu_ctx.update = true | 266 | menu_ctx.update = true |
242 | for item, _ in ipairs(mt) do | 267 | for item, _ in ipairs(mt) do |
243 | i = i + 1 | 268 | i = i + 1 |
244 | table.insert(m, i, lv_tab .. mt[item]) | 269 | submenu_insert(m, i, lv_tab .. mt[item]) |
245 | table.insert(f, i, ft[item]) | 270 | submenu_insert(f, i, ft[item]) |
246 | end | 271 | end |
247 | 272 | ||
248 | local function collapse_closure(i, m, f) | 273 | local function collapse_closure(i, m, f) |
249 | --creates a closure around lv, start_item and menu_sz | 274 | --creates a closure around lv, start_item and menu_sz |
250 | for j = 1, menu_sz, 1 do | 275 | for j = 1, menu_sz, 1 do |
251 | table.remove(m, start_item + 1) | 276 | submenu_remove(m, start_item + 1) |
252 | table.remove(f, start_item + 1) | 277 | submenu_remove(f, start_item + 1) |
253 | end | 278 | end |
254 | return lv, start_item, menu_sz | 279 | return lv, start_item, menu_sz |
255 | end | 280 | end |
256 | 281 | ||
257 | table.insert(menu_ctx.collapse_fn, lv, {collapse_closure, start_item}) | 282 | submenu_insert(menu_ctx.collapse_fn, lv, {collapse_closure, start_item}) |
258 | return true | 283 | return true |
259 | end | 284 | end |
260 | 285 | ||
261 | return submenu_closure | 286 | return submenu_closure |
262 | end | 287 | end |
263 | 288 | ||
289 | -- | ||
290 | function submenu_set_defaults(settings, ctx) | ||
291 | p_settings = settings or {wrap = true, hasheader = true, justify = "left", dpad_fn = dpad} | ||
292 | menu_ctx = ctx or {collapse_fn = {}, lv = 0, update = false, start = 1} | ||
293 | end | ||
294 | |||
295 | --[[ get_menu() returns the ROOT string and fn tables]] | ||
296 | function get_menu() | ||
297 | return menu_t, func_t | ||
298 | end | ||
299 | |||
300 | --[[ set_menu() set your menu and the menu has now been entered ]] | ||
301 | function set_menu(mt, ft, user_context_fn, settings) | ||
302 | |||
303 | submenu_set_defaults(settings) | ||
304 | if type(user_context_fn) == 'function' then | ||
305 | display_context_menu = display_context_menu_internal | ||
306 | menu_ctx.user_context_fn = user_context_fn | ||
307 | else | ||
308 | display_context_menu = empty_fn | ||
309 | menu_ctx.user_context_fn = false | ||
310 | end | ||
311 | p_settings = settings or p_settings | ||
312 | menu_t, func_t = mt, ft | ||
313 | ctx_loop() | ||
314 | end | ||