This repository has been archived on 2025-12-11. You can view files and clone it, but cannot push or open issues or pull requests.

265 lines
6.0 KiB
Lua
Raw Normal View History

2025-02-02 10:40:42 +01:00
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