ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]
:toc: left
:toclevels: 5

= GUI

This module adds GUI features.

[WARNING]
====
If GUI customization is needed, it's possible to use `GUI:setDiv` to add additional CSS (the override order should depends on `GUI:setDiv` call order).

.It's even possible to load a custom client-side `design.css` file like this:
[source,lua]
----
-- client-side
function MyExt.event:NUIready()
  vRP.EXT.GUI:addDiv("my_ext_css", LoadResourceFile("my_ext", "design.css"), "")
end
----
====

== Extension

=== Menu

[source,lua]
----
self.user
self.name
self.data
self.title
self.options
self.css
self.closed

-- dispatcher events:
--- close(menu)
--- remove(menu)
--- select(menu, id)
Menu:listen(name, callback)

-- add option
-- title: option title (html)
-- action(menu, value, mod, index): (optional) select callback
--- value: option value
--- mod: action modulation
---- -1: left
---- 0: valid
---- 1: right
-- description: (optional) option description (html)
--- callback(menu, value): should return a string or nil
-- value: (optional) option value, can be anything, option index by default
-- index: (optional) by default the option is added at the end, but an index can be used to insert the option
Menu:addOption(title, action, description, value, index)

-- update menu option
-- title: (optional) as Menu:addOption
-- description: (optional) as Menu:addOption
-- will trigger client update if current menu
Menu:updateOption(id, title, description)
----

=== User

[source,lua]
----
self.menu_stack -- stack of menus
self.request_ids
self.requests

-- return current menu or nil
User:getMenu()

-- open menu (build and open menu)
-- data: (optional) menu build data 
-- return menu
User:openMenu(name, data)

-- close menu
-- menu: (optional) menu to close, if nil, will close the current menu
User:closeMenu(menu)

-- close and rebuild current menu (no remove)
-- menu is rebuilt, listeners are kept
User:actualizeMenu()

-- close all menus
User:closeMenus()

-- prompt textual (and multiline) information from player
-- return entered text
User:prompt(title, default_text)

-- REQUEST

-- ask something to a player with a limited amount of time to answer (yes|no request)
-- time: request duration in seconds
-- return true (yes) or false (no)
User:request(text, time)
----

=== Server

[source,lua]
----
self.cfg
self.menu_builders -- map of name => callbacks list

-- register a menu builder function
-- name: menu type name
-- builder(menu): callback to modify the menu
GUI:registerMenuBuilder(name, builder)

-- TUNNEL

-- open the general player menu
GUI.tunnel:openMainMenu()

-- can be used to implement a custom menu

GUI.tunnel:closeMenu()
GUI.tunnel:triggerMenuOption(id, mod)
GUI.tunnel:triggerMenuSelect(id)
----

=== Client

[source,lua]
----
self.paused
self.menu_data

-- CONTROLS/GUI

GUI:isPaused()

-- get native GUI coordinates based on UI description
-- x_align, y_align: integers, see https://runtime.fivem.net/doc/natives/#_0xB8A850F20A067EB6
-- x, y: floats, UI defined coordinates
GUI:getNativeCoords(x_align, y_align, x, y)

-- get minimap rect in pixels
-- return x, y, w, h
GUI:getMinimapRect()

-- hide/show GUI
GUI:setVisible(flag)

-- MENU

GUI:isMenuOpen()

-- ANNOUNCE

-- add an announce to the queue
-- background: image url (800x150)
-- content: announce html content
GUI:announce(background,content)

-- PROGRESS BAR

-- create/update a progress bar
-- anchor:
--- "minimap"
--- "center"
--- "botright"
-- r,g,b: RGB 256 color
-- value: 0-1
GUI:setProgressBar(name,anchor,text,r,g,b,value)

-- set progress bar value 0-1
GUI:setProgressBarValue(name,value)

-- set progress bar text
GUI:setProgressBarText(name,text)

-- remove a progress bar
GUI:removeProgressBar(name)

-- DIV

-- set a div
-- css: plain global css, the div class is "div_name"
-- content: html content of the div
GUI:setDiv(name,css,content)

-- set the div css
GUI:setDivCss(name,css)

-- set the div content
GUI:setDivContent(name,content)

-- execute js for the div
-- js: code, "this" is the div
GUI:divExecuteJS(name,js)

-- remove the div
GUI:removeDiv(name)

-- TUNNEL

GUI.tunnel.announce = GUI.announce
GUI.tunnel.setProgressBar = GUI.setProgressBar
GUI.tunnel.setProgressBarValue = GUI.setProgressBarValue
GUI.tunnel.setProgressBarText = GUI.setProgressBarText
GUI.tunnel.removeProgressBar = GUI.removeProgressBar
GUI.tunnel.setDiv = GUI.setDiv
GUI.tunnel.setDivCss = GUI.setDivCss
GUI.tunnel.setDivContent = GUI.setDivContent
GUI.tunnel.divExecuteJS = GUI.divExecuteJS
GUI.tunnel.removeDiv = GUI.removeDiv
----

.Events
[horizontal]
`NUIready()`:: called when the vRP NUI is ready
`pauseChange(paused)`:: called when the game pause state changes
`menuOpen(menudata)`:: called when the menu is opened (can be used to implement a custom menu)
`menuClose()`:: called when the menu is closed (can be used to implement a custom menu)
`menuSetSelectEvent(select_event)`:: called when the select event flag is set (if true, the menu must trigger the server-side option select event) (can be used to implement a custom menu)
`menuOptionUpdate(index, title, description)`:: called when a menu option is updated (can be used to implement a custom menu)

== Menu

=== main

Main menu.
