stand/lua: Create a "carousel" menu entry type

This is a pre-cursor to boot environment support in lualoader. Create a new
menu item type, "carousel_entry", that generally provides a callback to get
the list of items, a carousel_id for storing the current value, and the
standard name/func functions that an entry has.

The difference between this and a normal menu item, functionally, is that
selecting a carousel item will automatically rotate through available items
and wrap back at the beginning when the list is exhausted.

The 'name' function takes the choice index, current choice, and the list of
choices as parameters so that the menu item can decorate the name freely as
desired.

The 'func' function takes the current choice as a parameter, so it can act
accordingly.

The kernel menu item has been rewritten to use the carousel_entry type as
both an example and initial test of its functionality before it is used for
boot environment options.
This commit is contained in:
Kyle Evans 2018-02-16 14:39:41 +00:00
parent ecdc734299
commit ada26c4a88
2 changed files with 49 additions and 22 deletions

View File

@ -169,7 +169,21 @@ function drawer.drawmenu(m)
if (e.entry_type ~= "separator") then
entry_num = entry_num + 1;
screen.setcursor(x, y + line_num);
print(entry_num .. ". "..e.name());
local name = "";
if (e.entry_type == "carousel_entry") then
local carid = e.carousel_id;
local caridx = menu.getCarouselIndex(carid);
local choices = e.items();
if (#choices < caridx) then
caridx = 1;
end;
name = e.name(caridx, choices[caridx], choices);
else
name = e.name();
end
print(entry_num .. ". "..name);
-- fill the alias table
alias_table[tostring(entry_num)] = e;

View File

@ -39,7 +39,7 @@ local OnOff;
local skip;
local run;
local autoboot;
local current_kernel_index = 1;
local carousel_choices = {};
--loader menu tree:
--rooted at menu.welcome
@ -193,34 +193,25 @@ menu.welcome = {
-- kernel options
{
entry_type = "entry",
name = function()
local kernels = core.kernelList();
if #kernels == 0 then
entry_type = "carousel_entry",
carousel_id = "kernel",
items = core.kernelList,
name = function(idx, choice, all_choices)
if #all_choices == 0 then
return "Kernel: ";
end
local kernel_name = color.escapef(color.GREEN) ..
kernels[current_kernel_index] .. color.default();
if (current_kernel_index == 1) then
choice .. color.default();
if (idx == 1) then
kernel_name = "default/" .. kernel_name;
end
return color.highlight("K").."ernel: " .. kernel_name ..
" (" .. current_kernel_index ..
" of " .. #kernels .. ")";
" (" .. idx ..
" of " .. #all_choices .. ")";
end,
func = function()
-- dynamically build the kernel menu:
local kernels = core.kernelList();
-- Don't do anything if we don't have multiple kernels
if #kernels <= 1 then
return nil;
end
current_kernel_index = (current_kernel_index % #kernels)
+ 1;
local current_kernel = kernels[current_kernel_index];
config.reload(current_kernel)
func = function(choice)
config.reload(choice);
end,
alias = {"k", "K"}
},
@ -239,6 +230,19 @@ menu.welcome = {
};
-- The first item in every carousel is always the default item.
function menu.getCarouselIndex(id)
local val = carousel_choices[id];
if (val == nil) then
return 1;
end
return val;
end
function menu.setCarouselIndex(id, idx)
carousel_choices[id] = idx;
end
function menu.run(m)
if (menu.skip()) then
@ -283,6 +287,15 @@ function menu.run(m)
if (sel_entry.entry_type == "entry") then
-- run function
sel_entry.func();
elseif (sel_entry.entry_type == "carousel_entry") then
-- carousel (rotating) functionality
local carid = sel_entry.carousel_id;
local caridx = menu.getCarouselIndex(carid);
local choices = sel_entry.items();
caridx = (caridx % #choices) + 1;
menu.setCarouselIndex(carid, caridx);
sel_entry.func(choices[caridx]);
elseif (sel_entry.entry_type == "submenu") then
-- recurse
cont = menu.run(sel_entry.submenu());