2 -- $Id: MenuItem.lua,v 1.8 2005/03/29 21:04:19 cpressey Exp $
4 -- BEGIN lib/menu.lua --
6 local POSIX = require("posix")
7 local FileName = require("filename")
8 local App = require("app")
14 -- Global "class" variable.
17 -- Global (but private) data and functions.
18 local next_id = 0 -- next unique id to create
19 local new_id = function() -- Create a new unique identifier.
21 return tostring(next_id)
25 MenuItem.new = function(tab)
27 local id = tab.id or "menu_action_" .. new_id()
28 local name = tab.name or ""
29 local short_desc = tab.short_desc
30 local long_desc = tab.long_desc
31 local effect = tab.effect
33 method.to_action = function(item)
37 short_desc = short_desc,
38 long_desc = long_desc,
50 -- Global "class" variable:
53 -- Global (and public) symbolic constants:
57 -- Global (but private) state variables in the class:
58 local menu_stack = {} -- stack of the most recently displayed menus
59 local make_exit_item = function()
60 local exit_item_name = "Exit"
62 if table.getn(menu_stack) > 0 then
63 exit_item_name = "Return to " ..
64 menu_stack[table.getn(menu_stack)]:get_name()
68 name = exit_item_name,
75 -- Create a new menu object instance.
76 Menu.new = function(opt)
79 local menu_id = opt.menu_id or "menu_form_" .. new_id()
80 local ui = opt.ui or App.ui
81 local name = opt.name or ""
82 local exit_item = opt.exit_item or make_exit_item()
83 local continue_constraint = opt.continue_constraint
86 local map_items_to_actions = function(item)
91 action[k] = item[k]:to_action()
98 method.add_item = function(menu, tab)
99 -- XXX: if tab is already a MenuItem object,
100 -- just add it, else:
101 table.insert(item, MenuItem.new(tab))
104 method.get_name = function(menu)
109 -- Populate this menu with items derived from the Lua script files
110 -- in the given directory. Each script should end with a return
111 -- statement that returns a table describing the menu item.
113 method.from_dir = function(menu, dir)
114 local i, filename, filenames
116 filenames = POSIX.dir(dir)
117 table.sort(filenames)
119 for i, filename in filenames do
120 local full_file = dir .. "/" .. filename
122 if filename ~= FileName.basename(App.current_script) and
123 not FileName.is_dir(full_file) and
124 string.find(filename, "^[^%.].*%.lua$") then
125 local tab = App.run_script(full_file)
132 menu:add_item(exit_item)
138 -- Present this menu to the user.
140 method.present = function(menu)
141 table.insert(menu_stack, menu)
142 local response = ui:present({
145 short_desc = opt.short_desc,
146 long_desc = opt.long_desc,
148 actions = map_items_to_actions(item)
150 table.remove(menu_stack)
154 method.loop = function(menu)
155 local result = Menu.CONTINUE
157 while result == Menu.CONTINUE do
158 result = menu:present().result
159 if continue_constraint then
160 result = continue_constraint(result)
168 -- Create a new menu object instance automatically from
169 -- the Lua script files in the same directory as the Lua
170 -- script file that invoked this function.
171 Menu.auto = function(opt)
172 local menu = Menu.new(opt)
174 menu:from_dir(FileName.dirname(App.current_script))
178 -- END of lib/menu.lua --