|
| 1 | +local Menu_class = {} |
| 2 | + |
| 3 | +------------------------------------------------------------------------------ |
| 4 | +-- Get script path func |
| 5 | +------------------------------------------------------------------------------ |
| 6 | +function get_script_path() |
| 7 | + local info = debug.getinfo(1,'S'); |
| 8 | + local script_path = info.source:match[[^@?(.*[\/])[^\/]-$]] |
| 9 | + return script_path |
| 10 | +end |
| 11 | + |
| 12 | + |
| 13 | +------------------------------------------------------------------------------ |
| 14 | +-- Import modules and initialize tables -- |
| 15 | +------------------------------------------------------------------------------ |
| 16 | +-- get "script path" |
| 17 | +local script_path = get_script_path() |
| 18 | +--msg(script_path) |
| 19 | + |
| 20 | +-- modify "package.path" |
| 21 | +package.path = package.path .. ";" .. script_path .. "?.lua" |
| 22 | +--msg(package.path) |
| 23 | + |
| 24 | +-- Import files ("classes", functions etc.)----------------- |
| 25 | +require "class" -- import "base class" |
| 26 | + |
| 27 | +---------------- |
| 28 | +-- Menu class -- |
| 29 | +---------------- |
| 30 | + |
| 31 | +-- To create a new menu instance, call this function like this: |
| 32 | +-- menu_name = Menu("menu_name") |
| 33 | +local Menu = |
| 34 | + class( |
| 35 | + function(menu, id) |
| 36 | + menu.id = id |
| 37 | + menu.items = {} -- Menu items are collected to this table |
| 38 | + menu.items_str = "" |
| 39 | + menu.curr_item_pos = 1 |
| 40 | + end |
| 41 | + ) |
| 42 | + |
| 43 | +Menu_class.create_menu = Menu |
| 44 | + |
| 45 | + |
| 46 | +------------------ |
| 47 | +-- Menu methods -- |
| 48 | +------------------ |
| 49 | + |
| 50 | +--[[ |
| 51 | +-- True if menu item label starts with "prefix" |
| 52 | +function Menu:label_starts_with(label, prefix) |
| 53 | + return string.sub(label, 1, string.len(prefix)) == prefix |
| 54 | +end |
| 55 | +--]] |
| 56 | + |
| 57 | + |
| 58 | +-- Returns "menu item table" (or false if "id" not found) |
| 59 | +function Menu:get_item_from_id(id) |
| 60 | + for i=1, #self.items do |
| 61 | + if self.items[i].id == id then |
| 62 | + return self.items[i] |
| 63 | + end |
| 64 | + end |
| 65 | + return false |
| 66 | +end |
| 67 | + |
| 68 | + |
| 69 | +-- Updates "menu item type" variables (_has_submenu, _last_item_in_submenu etc.) |
| 70 | +function Menu:update_item(item_table) |
| 71 | + local t = item_table |
| 72 | + t._has_submenu = false |
| 73 | + t._last_item_in_submenu = false |
| 74 | + t.id = self.curr_item_pos |
| 75 | + |
| 76 | + if string.sub(t.label, 1, 1) == ">" or |
| 77 | + string.sub(t.label, 1, 2) == "<>" or |
| 78 | + string.sub(t.label, 1, 2) == "><" then |
| 79 | + t._has_submenu = true |
| 80 | + t.id = -1 |
| 81 | + self.curr_item_pos = self.curr_item_pos - 1 |
| 82 | + --end |
| 83 | + elseif string.sub(t.label, 1, 1) == "<" then |
| 84 | + t._has_submenu = false |
| 85 | + t._last_item_in_submenu = true |
| 86 | + end |
| 87 | + --t.id = self.curr_item_pos |
| 88 | + if string.sub(t.label, 1, 1) ~= "|" then |
| 89 | + self.curr_item_pos = self.curr_item_pos + 1 |
| 90 | + end |
| 91 | +end |
| 92 | + |
| 93 | + |
| 94 | +-- Returns the created table and table index in "menu_obj.items" |
| 95 | +function Menu:add_item(...) |
| 96 | + local t = ... or {} |
| 97 | + self.items[#self.items+1] = t -- add new menu item at the end of menu |
| 98 | + |
| 99 | + -- Parse arguments |
| 100 | + for i,v in pairs(t) do |
| 101 | + --msg(i .. " = " .. tostring(v)) |
| 102 | + if i == "label" then |
| 103 | + t.label = v |
| 104 | + elseif i == "selected" then |
| 105 | + t.selected = v |
| 106 | + elseif i == "active" then |
| 107 | + t.active = v |
| 108 | + elseif i == "toggleable" then |
| 109 | + t.toggleable = v |
| 110 | + elseif i == "command" then |
| 111 | + t.command = v |
| 112 | + end |
| 113 | + end |
| 114 | + |
| 115 | + -- Default values for menu items |
| 116 | + -- (Edit these) |
| 117 | + if t.label == nil or t.label == "" then |
| 118 | + t.label = tostring(#self.items) -- if label is nil or "" -> label is set to "table index in menu_obj.items" |
| 119 | + end |
| 120 | + |
| 121 | + if t.selected == nil then |
| 122 | + t.selected = false -- edit |
| 123 | + end |
| 124 | + |
| 125 | + if t.active == nil then |
| 126 | + t.active = true -- edit |
| 127 | + end |
| 128 | + |
| 129 | + if t.toggleable == nil then |
| 130 | + t.toggleable = false -- edit |
| 131 | + end |
| 132 | + |
| 133 | + return t, #self.items |
| 134 | +end |
| 135 | + |
| 136 | + |
| 137 | +-- Get menu item table at index |
| 138 | +function Menu:get_item(index) |
| 139 | + if self.items[index] == nil then |
| 140 | + return false |
| 141 | + end |
| 142 | + return self.items[index] |
| 143 | +end |
| 144 | + |
| 145 | + |
| 146 | +-- Show menu at mx, my |
| 147 | +function Menu:show(mx, my) |
| 148 | + gfx.x = mx |
| 149 | + gfx.y = my |
| 150 | + |
| 151 | + -- Check which items has a function to call when a menu is about to be shown |
| 152 | + for i=1, #self.items do |
| 153 | + if self.items[i].on_menu_show ~= nil then |
| 154 | + self.items[i].on_menu_show() |
| 155 | + end |
| 156 | + -- Update item |
| 157 | + self:update_item(self.items[i]) |
| 158 | + end |
| 159 | + |
| 160 | + -- Convert menu item tables to string |
| 161 | + self.items_str = self:table_to_string() or "" |
| 162 | + self.val = gfx.showmenu(self.items_str) |
| 163 | + if self.val > 0 then |
| 164 | + self:update(self.val) |
| 165 | + end |
| 166 | + self.curr_item_pos = 1 -- set "menu item position counter" back to the initial value |
| 167 | + return self.val |
| 168 | +end |
| 169 | + |
| 170 | + |
| 171 | +function Menu:update(menu_item_index) |
| 172 | + -- check which "menu item id" matches with "menu_item_index" |
| 173 | + for i=1, #self.items do |
| 174 | + if self.items[i].id == menu_item_index then |
| 175 | + menu_item_index = i |
| 176 | + break |
| 177 | + end |
| 178 | + end |
| 179 | + local i = menu_item_index |
| 180 | + -- if menu item is "toggleable" then toggle "selected" state |
| 181 | + if self.items[i].toggleable then |
| 182 | + self.items[i].selected = not self.items[i].selected |
| 183 | + end |
| 184 | + -- if menu item has a "command" (function), then call that function |
| 185 | + if self.items[i].command ~= nil then |
| 186 | + self.items[i].command() |
| 187 | + end |
| 188 | +end |
| 189 | + |
| 190 | + |
| 191 | +-- Convert "Menu_obj.items" to string |
| 192 | +function Menu:table_to_string() |
| 193 | + if self.items == nil then |
| 194 | + return |
| 195 | + end |
| 196 | + self.items_str = "" |
| 197 | + |
| 198 | + for i=1, #self.items do |
| 199 | + local temp_str = "" |
| 200 | + local menu_item = self.items[i] |
| 201 | + if menu_item.selected then |
| 202 | + temp_str = "!" |
| 203 | + end |
| 204 | + |
| 205 | + if not menu_item.active then |
| 206 | + temp_str = temp_str .. "#" |
| 207 | + end |
| 208 | + |
| 209 | + if menu_item.label ~= "" then |
| 210 | + temp_str = temp_str .. menu_item.label .. "|" |
| 211 | + end |
| 212 | + |
| 213 | + self.items_str = self.items_str .. temp_str |
| 214 | + end |
| 215 | + |
| 216 | + return self.items_str |
| 217 | +end |
| 218 | + |
| 219 | +--END of Menu class---------------------------------------------------- |
| 220 | + |
| 221 | +return Menu_class |
0 commit comments