Collection of custom reaper scripts
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
4.6 KiB

  1. -- Basic gui stuff by forum user "spk77": https://forum.cockos.com/showthread.php?t=161557
  2. ----------------
  3. -- Menu class --
  4. ----------------
  5. -- To create a new menu instance, call this function like this:
  6. -- menu_name = Menu("menu_name")
  7. local Menu =
  8. class(
  9. function(menu, id)
  10. menu.id = id
  11. menu.items = {} -- Menu items are collected to this table
  12. menu.items_str = ""
  13. menu.curr_item_pos = 1
  14. end
  15. )
  16. ------------------
  17. -- Menu methods --
  18. ------------------
  19. --[[
  20. -- True if menu item label starts with "prefix"
  21. function Menu:label_starts_with(label, prefix)
  22. return string.sub(label, 1, string.len(prefix)) == prefix
  23. end
  24. --]]
  25. -- Returns "menu item table" (or false if "id" not found)
  26. function Menu:get_item_from_id(id)
  27. for i=1, #self.items do
  28. if self.items[i].id == id then
  29. return self.items[i]
  30. end
  31. end
  32. return false
  33. end
  34. -- Updates "menu item type" variables (_has_submenu, _last_item_in_submenu etc.)
  35. function Menu:update_item(item_table)
  36. local t = item_table
  37. t._has_submenu = false
  38. t._last_item_in_submenu = false
  39. t.id = self.curr_item_pos
  40. if string.sub(t.label, 1, 1) == ">" or
  41. string.sub(t.label, 1, 2) == "<>" or
  42. string.sub(t.label, 1, 2) == "><" then
  43. t._has_submenu = true
  44. t.id = -1
  45. self.curr_item_pos = self.curr_item_pos - 1
  46. --end
  47. elseif string.sub(t.label, 1, 1) == "<" then
  48. t._has_submenu = false
  49. t._last_item_in_submenu = true
  50. end
  51. --t.id = self.curr_item_pos
  52. self.curr_item_pos = self.curr_item_pos + 1
  53. end
  54. -- Returns the created table and table index in "menu_obj.items"
  55. function Menu:add_item(...)
  56. local t = ... or {}
  57. self.items[#self.items+1] = t -- add new menu item at the end of menu
  58. -- Parse arguments
  59. for i,v in pairs(t) do
  60. --msg(i .. " = " .. tostring(v))
  61. if i == "label" then
  62. t.label = v
  63. elseif i == "selected" then
  64. t.selected = v
  65. elseif i == "active" then
  66. t.active = v
  67. elseif i == "toggleable" then
  68. t.toggleable = v
  69. elseif i == "command" then
  70. t.command = v
  71. end
  72. end
  73. -- Default values for menu items
  74. -- (Edit these)
  75. if t.label == nil or t.label == "" then
  76. t.label = tostring(#self.items) -- if label is nil or "" -> label is set to "table index in menu_obj.items"
  77. end
  78. if t.selected == nil then
  79. t.selected = false -- edit
  80. end
  81. if t.active == nil then
  82. t.active = true -- edit
  83. end
  84. if t.toggleable == nil then
  85. t.toggleable = false -- edit
  86. end
  87. return t, #self.items
  88. end
  89. -- Get menu item table at index
  90. function Menu:get_item(index)
  91. if self.items[index] == nil then
  92. return false
  93. end
  94. return self.items[index]
  95. end
  96. -- Show menu at mx, my
  97. function Menu:show(mx, my)
  98. gfx.x = mx
  99. gfx.y = my
  100. -- Check which items has a function to call when a menu is about to be shown
  101. for i=1, #self.items do
  102. if self.items[i].on_menu_show ~= nil then
  103. self.items[i].on_menu_show()
  104. end
  105. -- Update item
  106. self:update_item(self.items[i])
  107. end
  108. -- Convert menu item tables to string
  109. self.items_str = self:table_to_string() or ""
  110. self.val = gfx.showmenu(self.items_str)
  111. if self.val > 0 then
  112. self:update(self.val)
  113. end
  114. self.curr_item_pos = 1 -- set "menu item position counter" back to the initial value
  115. end
  116. function Menu:update(menu_item_index)
  117. -- check which "menu item id" matches with "menu_item_index"
  118. for i=1, #self.items do
  119. if self.items[i].id == menu_item_index then
  120. menu_item_index = i
  121. break
  122. end
  123. end
  124. local i = menu_item_index
  125. -- if menu item is "toggleable" then toggle "selected" state
  126. if self.items[i].toggleable then
  127. self.items[i].selected = not self.items[i].selected
  128. end
  129. -- if menu item has a "command" (function), then call that function
  130. if self.items[i].command ~= nil then
  131. self.items[i].command()
  132. end
  133. end
  134. -- Convert "Menu_obj.items" to string
  135. function Menu:table_to_string()
  136. if self.items == nil then
  137. return
  138. end
  139. self.items_str = ""
  140. for i=1, #self.items do
  141. local temp_str = ""
  142. local menu_item = self.items[i]
  143. if menu_item.selected then
  144. temp_str = "!"
  145. end
  146. if not menu_item.active then
  147. temp_str = temp_str .. "#"
  148. end
  149. if menu_item.label ~= "" then
  150. temp_str = temp_str .. menu_item.label .. "|"
  151. end
  152. self.items_str = self.items_str .. temp_str
  153. end
  154. return self.items_str
  155. end
  156. --END of Menu class----------------------------------------------------
  157. return Menu