mirror of
https://github.com/jimathy/jim_bridge.git
synced 2026-08-17 05:56:02 +01:00
(Beta) Fixes for multiframework support
This commit is contained in:
@@ -1,290 +1,290 @@
|
||||
--- Opens a menu using the configured menu system.
|
||||
---
|
||||
--- This function translates code and creates menus in several different menu scripts, depending on the configured menu system specified in `Config.System.Menu`.
|
||||
---
|
||||
---@param Menu table A table containing the menu options to display.
|
||||
--- Each menu item can include:
|
||||
--- - **header** (`string`): The text to display for the menu item.
|
||||
--- - **txt** (`string`, optional): Additional text or description.
|
||||
--- - **icon** (`string`, optional): Icon to display with the menu item.
|
||||
--- - **onSelect** (`function`, optional): Function to execute when the menu item is selected.
|
||||
--- - **arrow** (`boolean`, optional): Whether to display an arrow next to the item (for certain menus).
|
||||
--- - **params** (`table`, optional): Additional parameters, such as events and arguments.
|
||||
--- - **isMenuHeader** (`boolean`, optional): Marks the item as a header.
|
||||
--- - **disabled** (`boolean`, optional): Disables the menu item if `true`.
|
||||
---
|
||||
---@param data table A table containing configuration data for the menu.
|
||||
--- - **header** (`string`): The header/title of the menu.
|
||||
--- - **headertxt** (`string`, optional): Additional header text.
|
||||
--- - **onBack** (`function`, optional): Function to call when the "Return" option is selected.
|
||||
--- - **onExit** (`function`, optional): Function to call when the menu is exited.
|
||||
--- - **onSelected** (`function`, optional): Function to call when a menu item is selected (for certain menu systems).
|
||||
--- - **canClose** (`boolean`, optional): Whether the menu can be closed by the user.
|
||||
---
|
||||
---@usage
|
||||
--- ```lua
|
||||
--- openMenu({
|
||||
--- { header = "Option 1", txt = "Description 1", onSelect = function() print("Option 1 selected") end },
|
||||
--- { header = "Option 2", txt = "Description 2", onSelect = function() print("Option 2 selected") end },
|
||||
--- }, {
|
||||
--- header = "Main Menu",
|
||||
--- headertxt = "Select an option",
|
||||
--- onBack = function() print("Return selected") end,
|
||||
--- onExit = function() print("Menu closed") end,
|
||||
--- canClose = true,
|
||||
--- })
|
||||
--- ```
|
||||
function openMenu(Menu, data)
|
||||
if Config.System.Menu == "jim" then
|
||||
if data.onBack then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
title = "Return",
|
||||
onSelect = data.onBack,
|
||||
})
|
||||
end
|
||||
exports["jim-nui"]:openMenu({
|
||||
title = data.header..(data.headertxt and " -- "..data.headertxt or ""),
|
||||
canClose = data.canClose and data.canClose or nil,
|
||||
onClose = (data.onBack and data.onBack) or (data.onExit and data.onExit) or nil,
|
||||
onExit = data.onExit and data.onExit or nil,
|
||||
options = Menu,
|
||||
})
|
||||
|
||||
elseif Config.System.Menu == "ox" then
|
||||
local index = nil
|
||||
if data.onBack and not data.onSelected then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
title = "Return",
|
||||
onSelect = data.onBack,
|
||||
label = "Return",
|
||||
})
|
||||
end
|
||||
for k in pairs(Menu) do
|
||||
if data.onSelected and Menu[k].arrow then
|
||||
Menu[k].icon = "fas fa-angle-right"
|
||||
end
|
||||
if not Menu[k].title then
|
||||
if Menu[k].header ~= nil and Menu[k].header ~= "" then
|
||||
Menu[k].title = Menu[k].header
|
||||
Menu[k].label = Menu[k].header
|
||||
if Menu[k].txt then Menu[k].description = Menu[k].txt else Menu[k].description = "" end
|
||||
else
|
||||
Menu[k].title = Menu[k].txt
|
||||
Menu[k].label = Menu[k].txt
|
||||
end
|
||||
end
|
||||
if Menu[k].params then
|
||||
Menu[k].event = Menu[k].params.event
|
||||
Menu[k].args = Menu[k].params.args or {}
|
||||
end
|
||||
if Menu[k].isMenuHeader then
|
||||
Menu[k].disabled = true
|
||||
end
|
||||
end
|
||||
local menuID = 'Menu'
|
||||
(data.onSelected and lib.registerMenu or lib.registerContext)({
|
||||
id = menuID,
|
||||
title = data.header..br..br..(data.headertxt and data.headertxt or ""),
|
||||
position = 'top-right',
|
||||
options = Menu,
|
||||
canClose = data.canClose and data.canClose or nil,
|
||||
onClose = (data.onBack and data.onBack) or (data.onExit and data.onExit) or nil,
|
||||
onExit = data.onExit and data.onExit or nil,
|
||||
onSelected = data.onSelected and (function(selected) index = selected end) or nil,
|
||||
}, data.onSelected and (function(x, y, args)
|
||||
if Menu[x].refresh then
|
||||
if Menu[x].onSelect then
|
||||
Menu[x].onSelect()
|
||||
end
|
||||
lib.showMenu(menuID, index)
|
||||
else
|
||||
if Menu[x].onSelect then
|
||||
Menu[x].onSelect()
|
||||
else
|
||||
lib.showMenu(menuID, index)
|
||||
end
|
||||
end
|
||||
end) or nil)
|
||||
if data.onSelected then
|
||||
lib.showMenu(menuID, 1)
|
||||
else
|
||||
lib.showContext(menuID)
|
||||
end
|
||||
|
||||
elseif Config.System.Menu == "qb" then
|
||||
if data.onBack then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
header = " ",
|
||||
txt = "Return",
|
||||
params = {
|
||||
isAction = true,
|
||||
event = data.onBack,
|
||||
},
|
||||
})
|
||||
elseif data.canClose then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-xmark",
|
||||
header = " ",
|
||||
txt = "Close",
|
||||
params = {
|
||||
isAction = true,
|
||||
event = data.onExit and data.onExit or (function() exports[QBMenuExport]:closeMenu() end),
|
||||
},
|
||||
})
|
||||
end
|
||||
if data.header ~= nil then
|
||||
local tempMenu = {}
|
||||
for k, v in pairs(Menu) do tempMenu[k + 1] = v end
|
||||
tempMenu[1] = { header = data.header, txt = data.headertxt or "", isMenuHeader = true }
|
||||
Menu = tempMenu
|
||||
end
|
||||
for k in pairs(Menu) do
|
||||
if not Menu[k].params or not Menu[k].params.event then
|
||||
if Menu[k].onSelect then
|
||||
Menu[k].params = {
|
||||
isAction = true,
|
||||
event = Menu[k].onSelect,
|
||||
}
|
||||
else
|
||||
Menu[k].params = {
|
||||
isAction = true,
|
||||
event = function() end,
|
||||
}
|
||||
end
|
||||
end
|
||||
if not Menu[k].header then Menu[k].header = " " end
|
||||
if Menu[k].arrow then Menu[k].icon = "fas fa-angle-right" end
|
||||
end
|
||||
exports[QBMenuExport]:openMenu(Menu)
|
||||
|
||||
elseif Config.System.Menu == "gta" then
|
||||
WarMenu.CreateMenu(tostring(Menu),
|
||||
data.header,
|
||||
data.headertxt or " ",
|
||||
{
|
||||
titleColor = { 222, 255, 255 },
|
||||
maxOptionCountOnScreen = 15,
|
||||
width = 0.25,
|
||||
x = 0.7,
|
||||
})
|
||||
if WarMenu.IsAnyMenuOpened() then return end
|
||||
WarMenu.OpenMenu(tostring(Menu))
|
||||
CreateThread(function()
|
||||
local close = true
|
||||
while true do
|
||||
if WarMenu.Begin(tostring(Menu)) then
|
||||
if data.onBack then
|
||||
if WarMenu.SpriteButton("Return", 'commonmenu', "arrowleft", 127, 127, 127) then
|
||||
WarMenu.CloseMenu()
|
||||
Wait(10)
|
||||
data.onBack()
|
||||
end
|
||||
end
|
||||
for k in pairs(Menu) do
|
||||
local pressed = WarMenu.Button(Menu[k].header)
|
||||
if not Menu[k].header then
|
||||
Menu[k].header = Menu[k].txt
|
||||
Menu[k].txt = nil
|
||||
end
|
||||
if Menu[k].txt and Menu[k].txt ~= "" and WarMenu.IsItemHovered() then
|
||||
if Menu[k].disabled or Menu[k].isMenuHeader then
|
||||
WarMenu.ToolTip("~r~"..Menu[k].txt, 0.18, true)
|
||||
else
|
||||
WarMenu.ToolTip(
|
||||
(Menu[k].blip and "~BLIP_".."8".."~ " or "")..
|
||||
Menu[k].txt:gsub("%:", ":~g~"):gsub("%\n", "\n~s~"), 0.18,
|
||||
true)
|
||||
end
|
||||
end
|
||||
if pressed and not Menu[k].isMenuHeader then
|
||||
WarMenu.CloseMenu()
|
||||
close = false
|
||||
Menu[k].onSelect()
|
||||
end
|
||||
end
|
||||
WarMenu.End()
|
||||
else
|
||||
return
|
||||
end
|
||||
if not WarMenu.IsAnyMenuOpened() and close then
|
||||
stopTempCam(cam)
|
||||
if data.onExit then data.onExit() end
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
|
||||
elseif Config.System.Menu == "esx" then
|
||||
for k in pairs(Menu) do
|
||||
Menu[k].label = Menu[k].header
|
||||
Menu[k].name = "button"..k
|
||||
end
|
||||
if data.canClose then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-xmark",
|
||||
label = "Close",
|
||||
name = "close",
|
||||
onSelect = data.onExit,
|
||||
})
|
||||
end
|
||||
if data.onBack then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
label = "Return",
|
||||
name = "return",
|
||||
onSelect = data.onBack,
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open("default", getScript(), "Example_Menu", {
|
||||
title = data.header,
|
||||
align = 'top-right',
|
||||
elements = Menu,
|
||||
},
|
||||
function(menuData, menu)
|
||||
for k in pairs(Menu) do
|
||||
if menuData.current.name == Menu[k].name then
|
||||
menu.close()
|
||||
Wait(10)
|
||||
Menu[k].onSelect()
|
||||
end
|
||||
end
|
||||
end,
|
||||
function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
--- A line break constant used for formatting menu headers.
|
||||
br = (Config.System.Menu == "ox" or Config.System.Menu == "gta") and "\n" or "<br>"
|
||||
|
||||
--- Checks if the menu system is classified as 'ox' or 'gta'.
|
||||
---
|
||||
--- This function is used to decide how to make line breaks in menu headers.
|
||||
---
|
||||
--- @return boolean Returns `true` if the menu system is 'ox' or 'gta'; otherwise, `false`.
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- if isOx() then
|
||||
--- -- Use specific formatting
|
||||
--- end
|
||||
--- ```
|
||||
function isOx() return (Config.System.Menu == "ox" or Config.System.Menu == "gta") end
|
||||
|
||||
|
||||
--- Checks if any WarMenu menu is currently open.
|
||||
---
|
||||
--- @return boolean Returns `true` if a WarMenu menu is open; otherwise, `false`.
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- if isWarMenuOpen() then
|
||||
--- -- Do something
|
||||
--- end
|
||||
--- ```
|
||||
--- Opens a menu using the configured menu system.
|
||||
---
|
||||
--- This function translates code and creates menus in several different menu scripts, depending on the configured menu system specified in `Config.System.Menu`.
|
||||
---
|
||||
---@param Menu table A table containing the menu options to display.
|
||||
--- Each menu item can include:
|
||||
--- - **header** (`string`): The text to display for the menu item.
|
||||
--- - **txt** (`string`, optional): Additional text or description.
|
||||
--- - **icon** (`string`, optional): Icon to display with the menu item.
|
||||
--- - **onSelect** (`function`, optional): Function to execute when the menu item is selected.
|
||||
--- - **arrow** (`boolean`, optional): Whether to display an arrow next to the item (for certain menus).
|
||||
--- - **params** (`table`, optional): Additional parameters, such as events and arguments.
|
||||
--- - **isMenuHeader** (`boolean`, optional): Marks the item as a header.
|
||||
--- - **disabled** (`boolean`, optional): Disables the menu item if `true`.
|
||||
---
|
||||
---@param data table A table containing configuration data for the menu.
|
||||
--- - **header** (`string`): The header/title of the menu.
|
||||
--- - **headertxt** (`string`, optional): Additional header text.
|
||||
--- - **onBack** (`function`, optional): Function to call when the "Return" option is selected.
|
||||
--- - **onExit** (`function`, optional): Function to call when the menu is exited.
|
||||
--- - **onSelected** (`function`, optional): Function to call when a menu item is selected (for certain menu systems).
|
||||
--- - **canClose** (`boolean`, optional): Whether the menu can be closed by the user.
|
||||
---
|
||||
---@usage
|
||||
--- ```lua
|
||||
--- openMenu({
|
||||
--- { header = "Option 1", txt = "Description 1", onSelect = function() print("Option 1 selected") end },
|
||||
--- { header = "Option 2", txt = "Description 2", onSelect = function() print("Option 2 selected") end },
|
||||
--- }, {
|
||||
--- header = "Main Menu",
|
||||
--- headertxt = "Select an option",
|
||||
--- onBack = function() print("Return selected") end,
|
||||
--- onExit = function() print("Menu closed") end,
|
||||
--- canClose = true,
|
||||
--- })
|
||||
--- ```
|
||||
function openMenu(Menu, data)
|
||||
if Config.System.Menu == "jim" then
|
||||
if data.onBack then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
title = "Return",
|
||||
onSelect = data.onBack,
|
||||
})
|
||||
end
|
||||
exports["jim-nui"]:openMenu({
|
||||
title = data.header..(data.headertxt and " -- "..data.headertxt or ""),
|
||||
canClose = data.canClose and data.canClose or nil,
|
||||
onClose = (data.onBack and data.onBack) or (data.onExit and data.onExit) or nil,
|
||||
onExit = data.onExit and data.onExit or nil,
|
||||
options = Menu,
|
||||
})
|
||||
|
||||
elseif Config.System.Menu == "ox" then
|
||||
local index = nil
|
||||
if data.onBack and not data.onSelected then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
title = "Return",
|
||||
onSelect = data.onBack,
|
||||
label = "Return",
|
||||
})
|
||||
end
|
||||
for k in pairs(Menu) do
|
||||
if data.onSelected and Menu[k].arrow then
|
||||
Menu[k].icon = "fas fa-angle-right"
|
||||
end
|
||||
if not Menu[k].title then
|
||||
if Menu[k].header ~= nil and Menu[k].header ~= "" then
|
||||
Menu[k].title = Menu[k].header
|
||||
Menu[k].label = Menu[k].header
|
||||
if Menu[k].txt then Menu[k].description = Menu[k].txt else Menu[k].description = "" end
|
||||
else
|
||||
Menu[k].title = Menu[k].txt
|
||||
Menu[k].label = Menu[k].txt
|
||||
end
|
||||
end
|
||||
if Menu[k].params then
|
||||
Menu[k].event = Menu[k].params.event
|
||||
Menu[k].args = Menu[k].params.args or {}
|
||||
end
|
||||
if Menu[k].isMenuHeader then
|
||||
Menu[k].disabled = true
|
||||
end
|
||||
end
|
||||
local menuID = 'Menu'
|
||||
(data.onSelected and lib.registerMenu or lib.registerContext)({
|
||||
id = menuID,
|
||||
title = data.header..br..br..(data.headertxt and data.headertxt or ""),
|
||||
position = 'top-right',
|
||||
options = Menu,
|
||||
canClose = data.canClose and data.canClose or nil,
|
||||
onClose = (data.onBack and data.onBack) or (data.onExit and data.onExit) or nil,
|
||||
onExit = data.onExit and data.onExit or nil,
|
||||
onSelected = data.onSelected and (function(selected) index = selected end) or nil,
|
||||
}, data.onSelected and (function(x, y, args)
|
||||
if Menu[x].refresh then
|
||||
if Menu[x].onSelect then
|
||||
Menu[x].onSelect()
|
||||
end
|
||||
lib.showMenu(menuID, index)
|
||||
else
|
||||
if Menu[x].onSelect then
|
||||
Menu[x].onSelect()
|
||||
else
|
||||
lib.showMenu(menuID, index)
|
||||
end
|
||||
end
|
||||
end) or nil)
|
||||
if data.onSelected then
|
||||
lib.showMenu(menuID, 1)
|
||||
else
|
||||
lib.showContext(menuID)
|
||||
end
|
||||
|
||||
elseif Config.System.Menu == "qb" then
|
||||
if data.onBack then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
header = " ",
|
||||
txt = "Return",
|
||||
params = {
|
||||
isAction = true,
|
||||
event = data.onBack,
|
||||
},
|
||||
})
|
||||
elseif data.canClose then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-xmark",
|
||||
header = " ",
|
||||
txt = "Close",
|
||||
params = {
|
||||
isAction = true,
|
||||
event = data.onExit and data.onExit or (function() exports[QBMenuExport]:closeMenu() end),
|
||||
},
|
||||
})
|
||||
end
|
||||
if data.header ~= nil then
|
||||
local tempMenu = {}
|
||||
for k, v in pairs(Menu) do tempMenu[k + 1] = v end
|
||||
tempMenu[1] = { header = data.header, txt = data.headertxt or "", isMenuHeader = true }
|
||||
Menu = tempMenu
|
||||
end
|
||||
for k in pairs(Menu) do
|
||||
if not Menu[k].params or not Menu[k].params.event then
|
||||
if Menu[k].onSelect then
|
||||
Menu[k].params = {
|
||||
isAction = true,
|
||||
event = Menu[k].onSelect,
|
||||
}
|
||||
else
|
||||
Menu[k].params = {
|
||||
isAction = true,
|
||||
event = function() end,
|
||||
}
|
||||
end
|
||||
end
|
||||
if not Menu[k].header then Menu[k].header = " " end
|
||||
if Menu[k].arrow then Menu[k].icon = "fas fa-angle-right" end
|
||||
end
|
||||
exports[QBMenuExport]:openMenu(Menu)
|
||||
|
||||
elseif Config.System.Menu == "gta" then
|
||||
WarMenu.CreateMenu(tostring(Menu),
|
||||
data.header,
|
||||
data.headertxt or " ",
|
||||
{
|
||||
titleColor = { 222, 255, 255 },
|
||||
maxOptionCountOnScreen = 15,
|
||||
width = 0.25,
|
||||
x = 0.7,
|
||||
})
|
||||
if WarMenu.IsAnyMenuOpened() then return end
|
||||
WarMenu.OpenMenu(tostring(Menu))
|
||||
CreateThread(function()
|
||||
local close = true
|
||||
while true do
|
||||
if WarMenu.Begin(tostring(Menu)) then
|
||||
if data.onBack then
|
||||
if WarMenu.SpriteButton("Return", 'commonmenu', "arrowleft", 127, 127, 127) then
|
||||
WarMenu.CloseMenu()
|
||||
Wait(10)
|
||||
data.onBack()
|
||||
end
|
||||
end
|
||||
for k in pairs(Menu) do
|
||||
local pressed = WarMenu.Button(Menu[k].header)
|
||||
if not Menu[k].header then
|
||||
Menu[k].header = Menu[k].txt
|
||||
Menu[k].txt = nil
|
||||
end
|
||||
if Menu[k].txt and Menu[k].txt ~= "" and WarMenu.IsItemHovered() then
|
||||
if Menu[k].disabled or Menu[k].isMenuHeader then
|
||||
WarMenu.ToolTip("~r~"..Menu[k].txt, 0.18, true)
|
||||
else
|
||||
WarMenu.ToolTip(
|
||||
(Menu[k].blip and "~BLIP_".."8".."~ " or "")..
|
||||
Menu[k].txt:gsub("%:", ":~g~"):gsub("%\n", "\n~s~"), 0.18,
|
||||
true)
|
||||
end
|
||||
end
|
||||
if pressed and not Menu[k].isMenuHeader then
|
||||
WarMenu.CloseMenu()
|
||||
close = false
|
||||
Menu[k].onSelect()
|
||||
end
|
||||
end
|
||||
WarMenu.End()
|
||||
else
|
||||
return
|
||||
end
|
||||
if not WarMenu.IsAnyMenuOpened() and close then
|
||||
stopTempCam(cam)
|
||||
if data.onExit then data.onExit() end
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
|
||||
elseif Config.System.Menu == "esx" then
|
||||
for k in pairs(Menu) do
|
||||
Menu[k].label = Menu[k].header
|
||||
Menu[k].name = "button"..k
|
||||
end
|
||||
if data.canClose then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-xmark",
|
||||
label = "Close",
|
||||
name = "close",
|
||||
onSelect = data.onExit,
|
||||
})
|
||||
end
|
||||
if data.onBack then
|
||||
table.insert(Menu, 1, {
|
||||
icon = "fas fa-circle-arrow-left",
|
||||
label = "Return",
|
||||
name = "return",
|
||||
onSelect = data.onBack,
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open("default", getScript(), "Example_Menu", {
|
||||
title = data.header,
|
||||
align = 'top-right',
|
||||
elements = Menu,
|
||||
},
|
||||
function(menuData, menu)
|
||||
for k in pairs(Menu) do
|
||||
if menuData.current.name == Menu[k].name then
|
||||
menu.close()
|
||||
Wait(10)
|
||||
Menu[k].onSelect()
|
||||
end
|
||||
end
|
||||
end,
|
||||
function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
--- A line break constant used for formatting menu headers.
|
||||
br = (Config.System.Menu == "ox" or Config.System.Menu == "gta") and "\n" or "<br>"
|
||||
|
||||
--- Checks if the menu system is classified as 'ox' or 'gta'.
|
||||
---
|
||||
--- This function is used to decide how to make line breaks in menu headers.
|
||||
---
|
||||
--- @return boolean Returns `true` if the menu system is 'ox' or 'gta'; otherwise, `false`.
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- if isOx() then
|
||||
--- -- Use specific formatting
|
||||
--- end
|
||||
--- ```
|
||||
function isOx() return (Config.System.Menu == "ox" or Config.System.Menu == "gta") end
|
||||
|
||||
|
||||
--- Checks if any WarMenu menu is currently open.
|
||||
---
|
||||
--- @return boolean Returns `true` if a WarMenu menu is open; otherwise, `false`.
|
||||
---
|
||||
--- @usage
|
||||
--- ```lua
|
||||
--- if isWarMenuOpen() then
|
||||
--- -- Do something
|
||||
--- end
|
||||
--- ```
|
||||
function isWarMenuOpen() if Config.System.Menu == "gta" then return WarMenu.IsAnyMenuOpened() else return false end end
|
||||
Reference in New Issue
Block a user