265 lines
6.0 KiB
Lua
265 lines
6.0 KiB
Lua
local activeMenu
|
|
local Debug = ESX.GetConfig().EnableDebug
|
|
|
|
-- Global functions
|
|
-- [ Post | Open | Closed ]
|
|
|
|
function Post(fn, ...)
|
|
SendNUIMessage({
|
|
func = fn,
|
|
args = { ... },
|
|
})
|
|
end
|
|
|
|
function Open(position, eles, onSelect, onClose, canClose)
|
|
local canCloseMenu = canClose == nil and true or canClose
|
|
activeMenu = {
|
|
position = position,
|
|
eles = eles,
|
|
canClose = canCloseMenu,
|
|
onSelect = onSelect,
|
|
onClose = onClose,
|
|
}
|
|
|
|
LocalPlayer.state:set("context:active", true)
|
|
|
|
Post("Open", eles, position)
|
|
end
|
|
|
|
function Closed()
|
|
SetNuiFocus(false, false)
|
|
|
|
local menu = activeMenu
|
|
local cb = menu.onClose
|
|
|
|
activeMenu = nil
|
|
|
|
LocalPlayer.state:set("context:active", false)
|
|
|
|
if cb then
|
|
cb(menu)
|
|
end
|
|
end
|
|
|
|
-- Exports
|
|
-- [ Preview | Open | Close ]
|
|
|
|
exports("Preview", Open)
|
|
|
|
exports("Open", function(...)
|
|
Open(...)
|
|
SetNuiFocus(true, true)
|
|
end)
|
|
|
|
exports("Close", function()
|
|
if not activeMenu then
|
|
return
|
|
end
|
|
|
|
Post("Closed")
|
|
|
|
Closed()
|
|
end)
|
|
|
|
exports("Refresh", function(eles, position)
|
|
if not activeMenu then
|
|
return
|
|
end
|
|
|
|
activeMenu.eles = eles or activeMenu.eles
|
|
activeMenu.position = position or activeMenu.position
|
|
|
|
Post("Open", activeMenu.eles, activeMenu.position)
|
|
end)
|
|
|
|
-- NUI Callbacks
|
|
-- [ closed | selected | changed ]
|
|
|
|
RegisterNUICallback("closed", function(_, cb)
|
|
if not activeMenu or (activeMenu and not activeMenu.canClose) then
|
|
return cb(false)
|
|
end
|
|
cb(true)
|
|
Closed()
|
|
end)
|
|
|
|
RegisterNUICallback("selected", function(data, cb)
|
|
if not activeMenu or not activeMenu.onSelect or not data.index then
|
|
return
|
|
end
|
|
|
|
local index = tonumber(data.index)
|
|
local ele = activeMenu.eles[index]
|
|
|
|
if not ele or ele.input then
|
|
return
|
|
end
|
|
|
|
activeMenu:onSelect(ele)
|
|
if cb then
|
|
cb("ok")
|
|
end
|
|
end)
|
|
|
|
RegisterNUICallback("changed", function(data, cb)
|
|
if not activeMenu or not data.index or not data.value then
|
|
return
|
|
end
|
|
|
|
local index = tonumber(data.index)
|
|
local ele = activeMenu.eles[index]
|
|
|
|
if not ele or not ele.input then
|
|
return
|
|
end
|
|
|
|
if ele.inputType == "number" then
|
|
ele.inputValue = tonumber(data.value)
|
|
|
|
if ele.inputMin then
|
|
ele.inputValue = math.max(ele.inputMin, ele.inputValue)
|
|
end
|
|
|
|
if ele.inputMax then
|
|
ele.inputValue = math.min(ele.inputMax, ele.inputValue)
|
|
end
|
|
elseif ele.inputType == "text" then
|
|
ele.inputValue = data.value
|
|
elseif ele.inputType == "radio" then
|
|
ele.inputValue = data.value
|
|
end
|
|
if cb then
|
|
cb("ok")
|
|
end
|
|
end)
|
|
|
|
-- Keybind
|
|
|
|
local function focusPreview()
|
|
if not activeMenu or not activeMenu.onSelect then
|
|
return
|
|
end
|
|
|
|
SetNuiFocus(true, true)
|
|
end
|
|
|
|
if PREVIEW_KEYBIND then
|
|
RegisterCommand("previewContext", focusPreview)
|
|
|
|
RegisterKeyMapping("previewContext", "Preview Active Context", "keyboard", PREVIEW_KEYBIND)
|
|
end
|
|
|
|
exports("focusPreview", focusPreview)
|
|
|
|
-- Debug/Test
|
|
-- Commands:
|
|
-- [ ctx:preview | ctx:open | ctx:close | ctx:form ]
|
|
|
|
if Debug then
|
|
local position = "right"
|
|
|
|
local eles = {
|
|
{
|
|
unselectable = true,
|
|
icon = "fas fa-info-circle",
|
|
title = "Unselectable Item (Header/Label?)",
|
|
},
|
|
{
|
|
icon = "fas fa-check",
|
|
title = "Item A",
|
|
description = "Some description here. Add some words to make the text overflow.",
|
|
},
|
|
{
|
|
disabled = true,
|
|
icon = "fas fa-times",
|
|
title = "Disabled Item",
|
|
description = "Some description here. Add some words to make the text overflow.",
|
|
},
|
|
{
|
|
icon = "fas fa-check",
|
|
title = "Item B",
|
|
description = "Some description here. Add some words to make the text overflow.",
|
|
},
|
|
}
|
|
|
|
local function onSelect(menu, ele)
|
|
print("Ele selected", ele.title)
|
|
|
|
if ele.name == "close" then
|
|
exports["ui_context"]:Close()
|
|
end
|
|
|
|
if ele.name ~= "submit" then
|
|
return
|
|
end
|
|
|
|
for _, element in ipairs(menu.eles) do
|
|
if element.input then
|
|
print(element.name, element.inputType, element.inputValue)
|
|
end
|
|
end
|
|
|
|
exports["ui_context"]:Close()
|
|
end
|
|
|
|
local function onClose()
|
|
print("Menu closed.")
|
|
end
|
|
|
|
RegisterCommand("ctx:preview", function()
|
|
exports["ui_context"]:Preview(position, eles)
|
|
end)
|
|
|
|
RegisterCommand("ctx:open", function()
|
|
exports["ui_context"]:Open(position, eles, onSelect, onClose)
|
|
end)
|
|
|
|
RegisterCommand("ctx:close", function()
|
|
exports["ui_context"]:Close()
|
|
end)
|
|
|
|
RegisterCommand("ctx:form", function()
|
|
local formMenu = {
|
|
{
|
|
unselectable = true,
|
|
icon = "fas fa-info-circle",
|
|
title = "Unselectable Item (Header/Label?)",
|
|
},
|
|
{
|
|
icon = "",
|
|
title = "Input Text",
|
|
input = true,
|
|
inputType = "text",
|
|
inputPlaceholder = "Placeholder...",
|
|
name = "firstname",
|
|
},
|
|
{
|
|
icon = "",
|
|
title = "Input Text",
|
|
input = true,
|
|
inputType = "text",
|
|
inputPlaceholder = "Placeholder...",
|
|
name = "lastname",
|
|
},
|
|
{
|
|
icon = "",
|
|
title = "Input Number",
|
|
input = true,
|
|
inputType = "number",
|
|
inputPlaceholder = "Placeholder...",
|
|
inputValue = 0,
|
|
inputMin = 0,
|
|
inputMax = 50,
|
|
name = "age",
|
|
},
|
|
{
|
|
icon = "fas fa-check",
|
|
title = "Submit",
|
|
name = "submit",
|
|
},
|
|
}
|
|
|
|
exports["ui_context"]:Open(position, formMenu, onSelect, onClose)
|
|
end)
|
|
end
|