2023-01-31 14:07:52 +01:00
|
|
|
local isOpen = false
|
2023-02-04 22:13:12 +01:00
|
|
|
local menus = {}
|
2023-01-31 14:07:52 +01:00
|
|
|
local menuItems = {}
|
2023-02-04 22:13:12 +01:00
|
|
|
local currentRadial = nil
|
|
|
|
|
|
2023-02-17 01:50:17 +11:00
|
|
|
---@class RadialMenuItem
|
|
|
|
|
---@field id string
|
|
|
|
|
---@field icon string
|
|
|
|
|
---@field label string
|
|
|
|
|
---@field menu? string
|
|
|
|
|
---@field onSelect? function
|
2023-02-04 22:13:12 +01:00
|
|
|
|
2023-02-17 01:50:17 +11:00
|
|
|
---@class RadialMenuProps
|
|
|
|
|
---@field id string
|
|
|
|
|
---@field items RadialMenuItem[]
|
|
|
|
|
|
|
|
|
|
---Registers a radial sub menu with predefined options.
|
|
|
|
|
---@param radial RadialMenuProps
|
2023-02-04 22:13:12 +01:00
|
|
|
function lib.registerRadial(radial)
|
|
|
|
|
menus[radial.id] = radial
|
|
|
|
|
end
|
|
|
|
|
|
2023-02-17 01:50:17 +11:00
|
|
|
---Open a registered radial submenu with the given id.
|
|
|
|
|
---@param id string
|
2023-02-08 00:50:05 +11:00
|
|
|
local function showRadial(id)
|
2023-02-04 22:13:12 +01:00
|
|
|
local radial = menus[id]
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-02-04 22:13:12 +01:00
|
|
|
if not radial then return error('No radial menu with such id found.') end
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-02-04 22:13:12 +01:00
|
|
|
currentRadial = radial
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-02-18 21:26:58 +11:00
|
|
|
-- Hide current menu and allow for transition
|
|
|
|
|
SendNUIMessage({
|
|
|
|
|
action = 'openRadialMenu',
|
|
|
|
|
data = false
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
Wait(100)
|
|
|
|
|
|
|
|
|
|
-- If menu was closed during transition, don't open the submenu
|
|
|
|
|
if not isOpen then return end
|
|
|
|
|
|
2023-02-04 22:13:12 +01:00
|
|
|
SendNUIMessage({
|
|
|
|
|
action = 'openRadialMenu',
|
|
|
|
|
data = {
|
|
|
|
|
items = radial.items,
|
|
|
|
|
sub = true
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
end
|
2023-01-31 14:07:52 +01:00
|
|
|
|
2023-02-07 13:46:13 +01:00
|
|
|
function lib.hideRadial()
|
2023-02-08 00:50:05 +11:00
|
|
|
if not isOpen then return end
|
|
|
|
|
|
2023-02-07 13:46:13 +01:00
|
|
|
SendNUIMessage({
|
|
|
|
|
action = 'openRadialMenu',
|
|
|
|
|
data = false
|
|
|
|
|
})
|
2023-02-08 00:50:05 +11:00
|
|
|
|
|
|
|
|
SetNuiFocus(false, false)
|
|
|
|
|
|
|
|
|
|
isOpen = false
|
|
|
|
|
currentRadial = nil
|
2023-02-07 13:46:13 +01:00
|
|
|
end
|
|
|
|
|
|
2023-02-17 01:50:17 +11:00
|
|
|
---Registers an item or array of items in the global radial menu.
|
|
|
|
|
---@param items RadialMenuItem | RadialMenuItem[]
|
2023-01-31 14:07:52 +01:00
|
|
|
function lib.addRadialItem(items)
|
2023-02-08 00:19:51 +11:00
|
|
|
local menuSize = #menuItems
|
2023-02-08 00:26:08 +11:00
|
|
|
local invokingResource = GetInvokingResource()
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-01-31 14:07:52 +01:00
|
|
|
if table.type(items) == 'array' then
|
|
|
|
|
for i = 1, #items do
|
2023-02-02 11:28:59 +01:00
|
|
|
local item = items[i]
|
2023-02-08 00:26:08 +11:00
|
|
|
item.resource = invokingResource
|
2023-02-08 00:19:51 +11:00
|
|
|
menuSize += 1
|
|
|
|
|
menuItems[menuSize] = item
|
2023-01-31 14:07:52 +01:00
|
|
|
end
|
|
|
|
|
else
|
2023-02-08 00:26:08 +11:00
|
|
|
items.resource = invokingResource
|
2023-02-08 00:19:51 +11:00
|
|
|
menuItems[menuSize + 1] = items
|
2023-01-31 14:07:52 +01:00
|
|
|
end
|
2023-02-15 17:42:37 +01:00
|
|
|
|
|
|
|
|
if isOpen then
|
|
|
|
|
SendNUIMessage({
|
|
|
|
|
action = 'refreshItems',
|
|
|
|
|
data = menuItems
|
|
|
|
|
})
|
|
|
|
|
end
|
2023-01-31 14:07:52 +01:00
|
|
|
end
|
|
|
|
|
|
2023-02-17 01:50:17 +11:00
|
|
|
---Removes an item from the global radial menu with the given id.
|
|
|
|
|
---@param id string
|
2023-02-07 13:51:58 +01:00
|
|
|
function lib.removeRadialItem(id)
|
2023-01-31 14:07:52 +01:00
|
|
|
for i = 1, #menuItems do
|
2023-02-02 11:28:59 +01:00
|
|
|
local item = menuItems[i]
|
2023-02-07 13:51:58 +01:00
|
|
|
if item.id == id then
|
2023-02-02 11:28:59 +01:00
|
|
|
table.remove(menuItems, i)
|
2023-02-03 13:24:55 +01:00
|
|
|
break
|
2023-01-31 14:07:52 +01:00
|
|
|
end
|
|
|
|
|
end
|
2023-02-02 11:28:59 +01:00
|
|
|
if isOpen then
|
2023-02-03 13:24:55 +01:00
|
|
|
SendNUIMessage({
|
|
|
|
|
action = 'refreshItems',
|
|
|
|
|
data = menuItems
|
|
|
|
|
})
|
2023-02-02 11:28:59 +01:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2023-02-04 22:13:12 +01:00
|
|
|
RegisterNUICallback('radialClick', function(index, cb)
|
|
|
|
|
cb(1)
|
2023-02-08 10:17:44 +01:00
|
|
|
local item = not currentRadial and menuItems[index + 1] or currentRadial.items[index + 1]
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-02-18 19:35:59 +01:00
|
|
|
lib.hideRadial()
|
|
|
|
|
|
2023-02-04 22:13:12 +01:00
|
|
|
if item.onSelect then item.onSelect() end
|
2023-02-08 00:50:05 +11:00
|
|
|
if item.menu then return showRadial(item.menu) end
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-02-04 22:13:12 +01:00
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
RegisterNUICallback('radialBack', function(_, cb)
|
|
|
|
|
cb(1)
|
|
|
|
|
if currentRadial.menu then
|
2023-02-08 00:50:05 +11:00
|
|
|
return showRadial(currentRadial.menu)
|
2023-02-04 22:13:12 +01:00
|
|
|
end
|
2023-02-08 00:19:51 +11:00
|
|
|
|
|
|
|
|
currentRadial = nil
|
|
|
|
|
|
|
|
|
|
SendNUIMessage({
|
|
|
|
|
action = 'openRadialMenu',
|
|
|
|
|
data = {
|
|
|
|
|
items = menuItems
|
|
|
|
|
}
|
|
|
|
|
})
|
2023-02-04 22:13:12 +01:00
|
|
|
end)
|
|
|
|
|
|
2023-02-10 18:17:30 +01:00
|
|
|
RegisterNUICallback('radialClose', function(_, cb)
|
|
|
|
|
cb(1)
|
|
|
|
|
|
|
|
|
|
if not isOpen then return end
|
|
|
|
|
|
|
|
|
|
SetNuiFocus(false, false)
|
|
|
|
|
|
|
|
|
|
isOpen = false
|
|
|
|
|
currentRadial = nil
|
|
|
|
|
end)
|
|
|
|
|
|
2023-02-08 00:50:05 +11:00
|
|
|
lib.addKeybind({
|
|
|
|
|
name = 'ox_lib-radial',
|
|
|
|
|
description = 'Open radial menu',
|
|
|
|
|
defaultKey = 'z',
|
|
|
|
|
onPressed = function()
|
2023-02-18 21:56:39 +11:00
|
|
|
if isOpen then
|
|
|
|
|
return lib.hideRadial()
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if #menuItems == 0 or IsNuiFocused() or IsPauseMenuActive() then return end
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-02-08 00:50:05 +11:00
|
|
|
isOpen = true
|
|
|
|
|
|
|
|
|
|
SendNUIMessage({
|
|
|
|
|
action = 'openRadialMenu',
|
|
|
|
|
data = {
|
|
|
|
|
items = menuItems
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
SetNuiFocus(true, true)
|
|
|
|
|
SetNuiFocusKeepInput(true)
|
|
|
|
|
SetCursorLocation(0.5, 0.5)
|
2023-02-08 00:19:51 +11:00
|
|
|
|
2023-01-31 14:07:52 +01:00
|
|
|
while isOpen do
|
|
|
|
|
DisablePlayerFiring(cache.playerId, true)
|
|
|
|
|
DisableControlAction(0, 1, true)
|
|
|
|
|
DisableControlAction(0, 2, true)
|
|
|
|
|
Wait(0)
|
|
|
|
|
end
|
2023-02-08 00:50:05 +11:00
|
|
|
end,
|
2023-02-18 21:56:39 +11:00
|
|
|
-- onReleased = lib.hideRadial,
|
2023-02-08 00:50:05 +11:00
|
|
|
})
|
2023-02-08 00:26:08 +11:00
|
|
|
|
|
|
|
|
AddEventHandler('onClientResourceStop', function(resource)
|
|
|
|
|
for i = #menuItems, 1, -1 do
|
|
|
|
|
local item = menuItems[i]
|
|
|
|
|
|
|
|
|
|
if item.resource == resource then
|
|
|
|
|
table.remove(menuItems, i)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end)
|