MENU_LIB_VER = 1.
1
MENU_LIB_LINK = "[Link]
function MENU_LIB_ERROR_OUTDATED()
error([Link]("You have an outdated version of the \"Object-oriented
gui\" please redownload it at: %s.", MENU_LIB_LINK))
end
local function CreateMT()
local MT = {}
MT.__index = MT
return MT
end
local CallbackItems = {}
local BaseMT = CreateMT()
function [Link](name, path, _type, cfg_value)
local Base = {
name = name,
path = path,
full_path = name and [Link]("%s>%s", path, name) or nil,
cfg_value = cfg_value,
type = _type,
}
function Base:set_visible(state)
gui.set_visible(self.full_path or [Link], state)
if self.call_callbacks_on_set_visible then
for Callback, _ in pairs(CallbackItems[self.full_path or [Link]]) do
Callback(self:get())
end
end
end
function Base:add_callback(func, call, on_set_vis)
if not CallbackItems[self.full_path or [Link]] then
CallbackItems[self.full_path or [Link]] = {}
end
CallbackItems[self.full_path or [Link]][func] = {Item = self, OldValue =
self:get()}
if call then
func(self:get())
end
self.call_callbacks_on_set_visible = on_set_vis
return func
end
function Base:get()
return self.cfg_value:get_int()
end
function Base:set(val)
self.cfg_value:set_int(tonumber(val))
end
function Base:has_updated(Old)
return self:get() ~= Old
end
function Base:update_callback_value()
return self:get()
end
function Base:bind_to(other)
if [Link] == "reference" or [Link] == "reference" or [Link] ==
[Link] then
other:add_callback(function (value)
self:set(value)
end)
else
utils.error_print("menu lib. base:bind_to other type differed from self
type")
end
end
return setmetatable(Base, BaseMT)
end
local ReferenceMT = CreateMT()
function [Link](path)
local Base = [Link](nil, path, "reference")
[Link] = {gui.get_config_item(path)}
function Base:get()
if not [Link][2] then
return [Link][1]:get_int()
else
local Ret = {}
for _, Item in pairs([Link]) do
[Link](Ret, Item:get_int())
end
return Ret
end
end
function Base:get_combo_items()
return gui.get_combo_items(self.full_path or [Link])
end
function Base:set_combo_items(items)
return gui.set_combo_items(self.full_path or [Link], items)
end
function Base:get_listbox_items()
return gui.get_listbox_items(self.full_path or [Link])
end
function Base:set_listbox_items(items)
return gui.set_listbox_items(self.full_path or [Link], items)
end
function Base:set(value)
local ValueType = type(value)
if not [Link][2] then
if ValueType == "table" then
error("menu lib. reference:set value type differed from reference
type")
end
-- need to do this or api freaks out
local IntValue = ValueType == "boolean" and (value == true and 1 or 0)
or tonumber(value)
[Link][1]:set_int(IntValue)
else
if ValueType ~= "table" then
error("menu lib. reference:set value type differed from reference
type")
end
for i, v in pairs(value) do
if not [Link][i] then
error("menu lib. reference:set reference index does not exist:
%s", i)
end
-- need to do this or api freaks out
local IntValue = type(v) == "boolean" and (v == true and 1 or 0) or
tonumber(v)
[Link][i]:set_int(IntValue)
end
end
end
function Base:has_updated(Old)
if not [Link][2] then
return self:get() ~= Old
else
for i, Item in pairs([Link]) do
if Item:get_int() ~= Old[i] then
return true, i
end
end
return false
end
end
function Base:update_callback_value()
return self:get()
end
return setmetatable(Base, ReferenceMT)
end
local CheckboxMT = CreateMT()
function [Link](name, path)
local Base = [Link](name, path, "checkbox", gui.add_checkbox(name, path))
function Base:get()
return self.cfg_value:get_bool()
end
function Base:set(val)
if type(val) == "boolean" then
self.cfg_value:set_bool(val)
elseif type(val) == "number" then
self.cfg_value:set_bool(val > 0)
else
error("menu lib. checkbox:set invalid value type. Accepted types
[number, boolean]")
end
end
return setmetatable(Base, CheckboxMT)
end
local SliderMT = CreateMT()
function [Link](name, path, min, max, step)
local Base = [Link](name, path, "slider", gui.add_slider(name, path, min,
max, step))
return setmetatable(Base, SliderMT)
end
local ComboMT = CreateMT()
function [Link](name, path, items)
local Base = [Link](name, path, "combo", gui.add_combo(name, path, items))
[Link] = items
function Base:get_items()
[Link] = gui.get_combo_items(self.full_path)
return [Link]
end
function Base:set_items(items)
[Link] = items
gui.set_combo_items(self.full_path, [Link])
end
return setmetatable(Base, ComboMT)
end
local MultiComboMT = CreateMT()
function [Link](name, path, items)
local Base = [Link](name, path, "multi-combo")
Base.cfg_values = {gui.add_multi_combo(name, path, items)}
[Link] = items
function Base:get(flags)
local ignore_array = flags and [Link](flags, "-a")
local ignore_dict = flags and [Link](flags, "-d")
local Ret = {}
for i, CfgValue in pairs(self.cfg_values) do
local IndexValue = CfgValue:get_bool()
if not ignore_array then
Ret[i] = IndexValue
end
if not ignore_dict then
Ret[[Link][i]] = IndexValue
end
end
return Ret
end
function Base:set(values)
if type(values) ~= "table" then
error("menu lib. multi_combo:set value type must be a table")
end
for i, val in pairs(values) do
local IndexType = type(i)
if IndexType == "number" then
if not self.cfg_values[i] then
error([Link]("menu lib. multi_combo:set index does not
exist: %s", i))
end
if type(val) ~= "boolean" then
error("menu lib. multi_combo:set value must be a boolean")
end
self.cfg_values[i]:set_bool(val)
elseif IndexType == "string" then
local CfgIndex = -1
for ItemIndex, ItemName in pairs([Link]) do
if i == ItemName then
CfgIndex = ItemIndex
break
end
end
if CfgIndex == -1 or not self.cfg_values[CfgIndex] then
error([Link]("menu lib. multi_combo:set index does not
exist: %s", i))
end
if type(val) == "boolean" then
self.cfg_values[CfgIndex]:set_bool(val)
elseif type(val) == "number" then
self.cfg_values[CfgIndex]:set_bool(val > 0)
else
error([Link]("menu lib. multi_combo:set invalid value
type %s. Accepted types [number, boolean]", i))
end
end
end
end
function Base:has_updated(Old)
for i, CfgItem in pairs(self.cfg_values) do
if Old[i] == nil then
return true, i
end
if CfgItem:get_bool() ~= Old[i] then
return true, i
end
end
return false
end
function Base:at(idx)
if type(idx) == "string" then
for ItemIndex, ItemName in pairs([Link]) do
if ItemName == idx then
idx = ItemIndex
break
end
end
end
if not self.cfg_values[idx] then
return nil
end
return self.cfg_values[idx]:get_bool()
end
function Base:get_active_names()
local ActiveNames = {}
for Index, ConfigValue in pairs(Base.cfg_values) do
if ConfigValue:get_bool() then
[Link](ActiveNames, [Link][Index])
end
end
return ActiveNames
end
return setmetatable(Base, MultiComboMT)
end
local ButtonMT = CreateMT()
function [Link](name, path, callback, confirm)
local Base = [Link](name, path, "button")
Base.is_confirm = confirm ~= nil
[Link] = nil
[Link] = nil
Base.add_callback = nil
Base.has_updated = nil
Base.update_callback_value = nil
if Base.is_confirm then
if [Link].allow_insecure then
-- try a nuch of times to make a spaced name (this is so we can have
multiple confirm ones in one spot)
for i = 1, 50 do
local rep = (" "):rep(i)
local ConfirmName = [Link]("%s%s%s", rep, "Confirm", rep)
local CancelName = [Link]("%s%s%s", rep, "Cancel", rep)
local ConfirmPath = [Link]("%s>%s", path, ConfirmName)
local CancelPath = [Link]("%s>%s", path, CancelName)
local MainPath = Base.full_path or [Link]
-- pcall this until it doesnt error (the error will be "control id
is already in use")
local s, res = pcall(gui.add_button, ConfirmName, path, function ()
callback()
gui.set_visible(ConfirmPath, false)
gui.set_visible(CancelPath, false)
gui.set_visible(MainPath, true)
end)
if s then
gui.add_button(CancelName, path, function ()
gui.set_visible(ConfirmPath, false)
gui.set_visible(CancelPath, false)
gui.set_visible(MainPath, true)
end)
Base.confirm_path = path .. ConfirmName
Base.cancel_path = path .. CancelName
gui.set_visible(ConfirmPath, false)
gui.set_visible(CancelPath, false)
gui.add_button(name, path, function ()
gui.set_visible(ConfirmPath, true)
gui.set_visible(CancelPath, true)
gui.set_visible(MainPath, false)
end)
Base.set_visible = function(self, state)
gui.set_visible(ConfirmPath, false)
gui.set_visible(CancelPath, false)
gui.set_visible(MainPath, state)
end
break
end
end
else
utils.error_print("Cannot create confirmable button without \"Allow
unsafe scripts\" on")
end
else
gui.add_button(name, path, callback)
end
return setmetatable(Base, ButtonMT)
end
local TextboxMT = CreateMT()
function [Link](name, path)
local Base = [Link](name, path, "textbox", gui.add_textbox(name, path))
function Base:get()
return self.cfg_value:get_string()
end
function Base:set(str)
self.cfg_value:set_string(tostring(str))
end
return setmetatable(Base, TextboxMT)
end
local ListboxMT = CreateMT()
function [Link](name, path, items_to_show, search_bar, items)
local Base = [Link](name, path, "listbox", gui.add_listbox(name, path,
items_to_show, search_bar, items))
[Link] = items
function Base:get_items()
[Link] = gui.get_listbox_items(self.full_path)
return [Link]
end
function Base:set_items(items)
[Link] = items
gui.set_listbox_items(self.full_path, [Link])
end
return setmetatable(Base, ListboxMT)
end
local KeybindMT = CreateMT()
function [Link](item)
local path = type(item) == "table" and (item.full_path or [Link] or "") or
item
local Base = [Link](nil, path, "keybind", gui.add_keybind(path))
[Link] = nil
[Link] = nil
Base.add_callback = nil
Base.has_updated = nil
Base.update_callback_value = nil
function Base:get_info()
return gui.get_keybind([Link])
end
return setmetatable(Base, KeybindMT)
end
local ColorpickerMT = CreateMT()
function [Link](item, alpha_bar, default_color)
local path = type(item) == "table" and (item.full_path or [Link] or "") or
item
local Base = [Link](nil, path, "color picker", gui.add_colorpicker(path,
alpha_bar == nil and true or alpha_bar, default_color or [Link]("#FFFFFF")))
function Base:get()
return self.cfg_value:get_color()
end
function Base:set(color)
self.cfg_value:set_color(color)
end
function Base:has_updated(Old)
local self_color = self:get()
return self_color.r ~= Old.r or self_color.g ~= Old.g or self_color.b ~=
Old.b or self_color.a ~= Old.a
end
return setmetatable(Base, ColorpickerMT)
end
utils.new_timer(1, function()
for FullPath, Callbacks in pairs(CallbackItems) do
for Callback, Inst in pairs(Callbacks) do
local HasUpdated, Other = [Link]:has_updated([Link])
if HasUpdated then
[Link] = [Link]:update_callback_value()
Callback([Link], Other)
end
end
end
end):start()
return
{
add_checkbox = [Link],
add_slider = [Link],
add_combo = [Link],
add_multi_combo = [Link],
add_button = [Link],
add_textbox = [Link],
add_listbox = [Link],
add_keybind = [Link],
add_colorpicker = [Link],
get_reference = [Link],
}