Rockbox Technical Forums

Support and General Use => Plugins/Viewers => Topic started by: Bilgus on September 14, 2019, 05:56:11 AM

Title: lua do_menu example with callback
Post by: Bilgus on September 14, 2019, 05:56:11 AM
@fprockboxer asked about detecting long press on menu items this is now possible in the latest dev version

Code: [Select]
require "actions"
rb.contexts = nil -- not needed

local act = rb.actions
local last_action = act.ACTION_NONE

local function menu_callback(action)
    if action == act.ACTION_STD_CONTEXT then
        last_action = action
        action = act.ACTION_STD_OK
    else
        --rb.splash(0, action)
    end
    return action
end

-- Function to display the main menu of this script --
function ShowMainMenu()
    start = nil
    mainmenu = {"Item 1", "Item 2", "Item 3", "Exit"}

    while true do

        s = rb.do_menu("Test", mainmenu, start, menu_callback)         

        start = s >= 0 and s or start
        if last_action == act.ACTION_STD_CONTEXT then
            last_action = act.ACTION_NONE
            rb.splash(2 * rb.HZ, "You long pressed Item " .. s + 1)
        elseif s == 0 then rb.splash(2 * rb.HZ, "You selected Item 1")
        elseif s == 1 then rb.splash(2 * rb.HZ, "You selected Item 2")
        elseif s == 2 then rb.splash(2 * rb.HZ, "You selected Item 3")
        elseif s == 3 then os.exit()
        elseif s == -2 then os.exit()

        else
        rb.splash(2 * rb.HZ, "Error! Selected index: " .. s)
        end
    end
end

ShowMainMenu()

Title: Re: lua do_menu example with callback
Post by: Bilgus on September 14, 2019, 01:36:46 PM
An expanded example

Code: [Select]
-- Example script to demonstrate the development of a simple Rockbox plugin in LUA.
-- Written by Gabriel Maia (gbl08ma on the Rockbox community).
-- Licensed under GNU GPL v2 or, at your choice, any later version.

-- Function to display the main menu of this script

require "actions"
rb.contexts = nil -- not needed

local act = rb.actions
local last_action = act.ACTION_NONE

-- We can intercept the actions from the menu and add our own functionality
local function menu_callback(action)
    if action == act.ACTION_STD_CONTEXT then
        last_action = action
        action = act.ACTION_STD_OK -- select the item so we get the item#
    else
        --rb.splash(0, action)
    end
    return action
end

local function splash_selection(sItem)
    -- if s item is nil we will get an error so subsitute <Unknown> in that case
    rb.splash(2 * rb.HZ, "You selected " .. sItem or "<Unknown>") --show a message for two seconds
end

function ShowMainMenu(start) -- we invoke this function every time we want to display the main menu of the script
    local mainmenu = {"Item 1", "Item 2", "Item 3 >", "Exit"} -- define the items of the menu
    local s
    while true do -- don't exit of program until user selects Exit
        s = rb.do_menu("Test", mainmenu, start, menu_callback) -- actually tell Rockbox to draw the menu
    --[[ In the line above: "Test" is the title of the menu, mainmenu is an array with the items
         of the menu, nil is a null value that needs to be there, and the last parameter is
         whether the theme should be drawn on the menu or not.
         the variable s will hold the index of the selected item on the menu.
         the index is zero based. This means that the first item is 0, the second one is 1, etc.]]
        start = s >= 0 and s or start
        if last_action == act.ACTION_STD_CONTEXT and s < 2 then
            last_action = act.ACTION_NONE
            if ShowContextmenu(s) == -2 then s = -2 end
        elseif s == 0 then rb.splash(2 * rb.HZ, "You selected Item 1") --show a message for two seconds
        elseif s == 1 then rb.splash(2 * rb.HZ, "You selected Item 2") --show a message for two seconds
        elseif s == 2 then return ShowSubmenu1, s -- by returning the next menu function we can use less memory
        elseif s == 3 or s == -2 then return nil, s -- exit
        else rb.splash(2 * rb.HZ, "Error! Selected index: " .. s)
        --[[   something strange happened. The program shows this message when
               the selected item is not on the index from 0 to 3 (in this case), and displays
               the selected index. Having this type of error handling is not
               required, but it might be nice to have specially while you're still
               developing the plugin.]]
        end
    end
end

-- Submenu 1
function ShowSubmenu1(item) -- function to draw the submenu 1, which will be displayed when
                        -- user selects Item 3 on main menu
    local submenu1 = {"Sub Item 1", "Sub Item 2", "< Back", "Exit Now"}
    local s1
    local start, loop = nil, true
    local title = "Item "  .. item + 1 .. " menu"
    while loop do -- don't exit program until user selects Exit
        s1 = rb.do_menu(title, submenu1, nil)

        if     s1 >= 0 and s1 < 2 then
            splash_selection(submenu1[s1 + 1])
            return ShowMainMenu, nil
        elseif s1 == 2 or s1 == -2 then return ShowMainMenu, item -- go back to main menu
        elseif s1 == 3 then loop = false -- exit
        end
    end
end

-- Submenu 1
function ShowContextmenu(item) -- function to draw the submenu 1, which will be displayed when
                               -- user long presses Item 1/2 on main menu
    local ctxmenu1 = {"Ctx Item 1", "Ctx Item 2", "Return"}
    local s1
    local title = "Context Menu Item: " .. item + 1
    s1 = rb.do_menu(title, ctxmenu1, nil)

    if     s1 >= 0 and s1 < 2 then
        splash_selection(ctxmenu1[s1 + 1])
    end
    return -- go back
end

--[[
 code written out of any function will be executed when the file is "played" on the file browser.
 if you don't put anything out of a function (not even a call to the main function, like we do here),
 the script will simply do nothing.
]]
local nextmenu, item = ShowMainMenu, nil
while nextmenu do
    nextmenu, item = nextmenu(item) -- display menu
end