diff --git a/resources/[standalone]/MenuAPI/.gitattributes b/resources/[standalone]/MenuAPI/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/resources/[standalone]/MenuAPI/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/resources/[standalone]/MenuAPI/.gitignore b/resources/[standalone]/MenuAPI/.gitignore new file mode 100644 index 0000000..6fd0a37 --- /dev/null +++ b/resources/[standalone]/MenuAPI/.gitignore @@ -0,0 +1,41 @@ +# Compiled Lua sources +luac.out + +# luarocks build files +*.src.rock +*.zip +*.tar.gz + +# Object files +*.o +*.os +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo +*.def +*.exp + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + diff --git a/resources/[standalone]/MenuAPI/LICENSE b/resources/[standalone]/MenuAPI/LICENSE new file mode 100644 index 0000000..867c5e8 --- /dev/null +++ b/resources/[standalone]/MenuAPI/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 MrXogos + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/resources/[standalone]/MenuAPI/client/client.lua b/resources/[standalone]/MenuAPI/client/client.lua new file mode 100644 index 0000000..8888fd1 --- /dev/null +++ b/resources/[standalone]/MenuAPI/client/client.lua @@ -0,0 +1,73 @@ +CachedMenu = {} + +function RegisterKey(fc, uniqid, description, key) + RegisterCommand(uniqid .. GetCurrentResourceName(), fc, false) + RegisterKeyMapping(uniqid .. GetCurrentResourceName(), description, 'keyboard', key) +end +-------------- +-- Sending info about changing item in menu +-------------- +RegisterKey(function() + SendNUIMessage({ type = "up" }) +end, "menuapiup", "Tast op", "UP") + +RegisterKey(function() + SendNUIMessage({ type = "down" }) +end, "menuapidown", "Tast ned", "DOWN") +-------------- +-- Sending info about selecting item +-------------- +RegisterKey(function() + SendNUIMessage({ type = "enter" }) +end, "menuapie", "Tast E", "E") + +RegisterKey(function() + SendNUIMessage({ type = "enter" }) +end, "menuapienter", "Tast ENTER", "RETURN") +-------------- +-- closing menu keys +-------------- +RegisterKey(function() + CloseAll() +end, "menuapiesc", "Tast ESC", "escape") + +RegisterKey(function() + CloseAll() +end, "menuapiescaper", "Tast slet", "back") +-------------- + +--CreateThread(function() +-- Wait(200) +-- local vehicles = { +-- [1] = { label = "police car", model = "police"}, +-- [2] = { label = "A FOCKING TANK?!", model = "rhino"}, +-- [3] = { label = "a nice car!", model = "cerberus3"} +-- } +-- +-- local menu = CreateMenu("identifier") +-- +-- menu.SetMenuTitle("Vehicle spawner") +-- +-- menu.SetProperties({ +-- float = "right", +-- position = "middle", +-- }) +-- +-- for k,v in ipairs(vehicles) do +-- menu.AddItem(k, v.label, nil, { model = v.model }) +-- end +-- +-- menu.OnSelectEvent(function(index, data) +-- RequestModel(data.model) +-- local coords = GetEntityCoords(PlayerPedId()) +-- while not HasModelLoaded(data.model) do +-- Wait(33) +-- end +-- local vehicle = CreateVehicle(data.model, coords.x, coords.y, coords.z, GetEntityHeading(PlayerPedId()), true, true) +-- SetVehicleOnGroundProperly(vehicle) +-- SetModelAsNoLongerNeeded(data.model) +-- TaskWarpPedIntoVehicle(PlayerPedId(), vehicle, -1) +-- end) +-- +-- menu.Open() +--end) \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/client/events.lua b/resources/[standalone]/MenuAPI/client/events.lua new file mode 100644 index 0000000..08998c1 --- /dev/null +++ b/resources/[standalone]/MenuAPI/client/events.lua @@ -0,0 +1,42 @@ +--------------- Input related only ---------------- +-- User send input froom html +RegisterNUICallback("inputmethod", function(data) + if CachedMenu[data.identifier] then + CallOn(data.identifier, "inputtext", data.message) + end +end) + +-- User send input froom html +RegisterNUICallback("close", function(data) + local menu = CachedMenu[data.identifier] + if menu then + menu.self.Close() + end +end) +--------------- Menu related only ---------------- +-- click on item +RegisterNUICallback("clickItem", function(data) + local identifier = data.identifier + local menuData = CachedMenu[identifier].Items[data.index] + if CachedMenu[identifier] and menuData then + local callBack = menuData.cb + if callBack then + callBack() + end + CallOn(identifier, "selectitem", data.index, menuData.data or {}) + end +end) + +-- calls when player select new item, and check for events & call them +RegisterNUICallback("selectNew", function(data) + local identifier = data.identifier + if CachedMenu[identifier] and CachedMenu[identifier].Items[data.index] then + CallOn(identifier, "changeitem", data.newIndex, data.oldIndex, CachedMenu[identifier].Items[data.newIndex].data or {}) + end +end) + + +-- unregister events if resource is stopped +AddEventHandler('onResourceStop', function(resourceName) + RemoveEventsWithNameResource(resourceName) +end) \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/client/exports/main.lua b/resources/[standalone]/MenuAPI/client/exports/main.lua new file mode 100644 index 0000000..01775ac --- /dev/null +++ b/resources/[standalone]/MenuAPI/client/exports/main.lua @@ -0,0 +1,19 @@ +function ExitAllOpenedMenu() + for k,v in pairs(CachedMenu) do + if v.self.IsOpen() then + CallOn(v.self.GetIdentifier(), "exit") + end + end + SendNUIMessage({ type = "ui", status = false }) +end + +exports("ExitAllOpenedMenu", ExitAllOpenedMenu) + +function CloseAll() + for k,v in pairs(CachedMenu) do + v.self.Close() + end + SendNUIMessage({ type = "ui", status = false }) +end + +exports("CloseAll", CloseAll) \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/client/module/input.lua b/resources/[standalone]/MenuAPI/client/module/input.lua new file mode 100644 index 0000000..a9d3c23 --- /dev/null +++ b/resources/[standalone]/MenuAPI/client/module/input.lua @@ -0,0 +1,97 @@ +function CreateInputMenu(identifier) + local self = {} + self.isOpen_ = false + local _menuTitle = "RCORE" + self.identifier_ = identifier + local _properties = { + float = "middle_screen", + position = "middle_screen", + ChooseText = "Accepter", + CloseText = "Luk", + } + -------------- + self.GetIdentifier = function() + return self.identifier_ + end + + self.IsOpen = function() + return self.isOpen_ + end + -------------- + self.SetMenuTitle = function(title) + _menuTitle = title + end + + self.GetMenuTitle = function() + return _menuTitle + end + -------------- + self.SetProperties = function(properties) + _properties = { + float = properties.float or "middle_screen", + position = properties.position or "middle_screen", + ChooseText = properties.ChooseText or "Accepter", + CloseText = properties.CloseText or "Luk", + } + end + + self.GetProperties = function() + return _properties + end + -------------- + self.OnCloseEvent = function(cb) + On(identifier, "close", cb) + end + + self.OnOpenEvent = function(cb) + On(identifier, "open", cb) + end + + self.OnExitEvent = function(cb) + On(identifier, "exit", cb) + end + + self.OnInputText = function(cb) + On(identifier, "inputtext", cb) + end + + self.On = function(eventName, cb) + On(identifier, eventName, cb) + end + -------------- + self.Open = function() + if not CachedMenu[identifier] then + CachedMenu[identifier] = {} + end + CachedMenu[identifier] = { + MenuTitle = _menuTitle, + Properties = _properties, + self = self, + } + + SendNUIMessage({ type = "title_input", title = _menuTitle }) + SendNUIMessage({ type = "ui_input", identifier = identifier, properties = _properties, status = true }) + + CallOn(identifier, "open") + self.isOpen_ = true + SetNuiFocus(true, true) + end + -------------- + self.Close = function() + SendNUIMessage({ type = "ui_input", status = false }) + CallOn(identifier, "close") + self.isOpen_ = false + SetNuiFocus(false, false) + end + -------------- + self.Destroy = function() + SendNUIMessage({ type = "ui_input", status = false }) + CallOn(identifier, "exit") + CachedMenu[identifier] = nil + Events[identifier] = nil + SetNuiFocus(false, false) + end + return self +end + +exports("CreateInputMenu", CreateInputMenu) \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/client/module/menu.lua b/resources/[standalone]/MenuAPI/client/module/menu.lua new file mode 100644 index 0000000..d09801a --- /dev/null +++ b/resources/[standalone]/MenuAPI/client/module/menu.lua @@ -0,0 +1,109 @@ +function CreateMenu(identifier) + local self = {} + self.isOpen_ = false + local _menuTitle = "RCORE" + self.identifier_ = identifier + local _properties = { + float = "right", + position = "middle", + } + local items = {} + -------------- + self.GetIdentifier = function() + return self.identifier_ + end + + self.IsOpen = function() + return self.isOpen_ + end + -------------- + self.SetMenuTitle = function(title) + _menuTitle = title + end + + self.GetMenuTitle = function() + return _menuTitle + end + -------------- + self.SetProperties = function(properties) + _properties = properties + end + + self.GetProperties = function() + return _properties + end + -------------- + self.OnCloseEvent = function(cb) + On(identifier, "close", cb) + end + + self.OnOpenEvent = function(cb) + On(identifier, "open", cb) + end + + self.OnExitEvent = function(cb) + On(identifier, "exit", cb) + end + + self.OnChangeItemEvent = function(cb) + On(identifier, "changeitem", cb) + end + + self.OnSelectEvent = function(cb) + On(identifier, "selectitem", cb) + end + + self.On = function(eventName, cb) + On(identifier, eventName, cb) + end + -------------- + self.AddItem = function(index, text, cb, data) + items[index] = { + label = text, + index = index, + data = data or {}, + cb = cb, + } + end + -------------- + self.Open = function() + if not CachedMenu[identifier] then + CachedMenu[identifier] = {} + end + CachedMenu[identifier] = { + MenuTitle = _menuTitle, + Properties = _properties, + Items = items, + self = self, + } + SendNUIMessage({ type = "reset" }) + SendNUIMessage({ type = "title", title = _menuTitle }) + for k, v in ipairs(items) do + SendNUIMessage({ + type = "add", + label = v.label, + index = k, + }) + end + SendNUIMessage({ type = "ui", identifier = identifier, properties = _properties, status = true }) + CallOn(identifier, "open") + self.isOpen_ = true + end + -------------- + self.Close = function() + SendNUIMessage({ type = "ui", status = false }) + CallOn(identifier, "close") + self.isOpen_ = false + end + -------------- + self.Destroy = function() + SendNUIMessage({ type = "ui", status = false }) + CallOn(identifier, "exit") + CachedMenu[identifier] = nil + Events[identifier] = nil + end + return self +end + + +exports("CreateMenu", CreateMenu) \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/client/system/events.lua b/resources/[standalone]/MenuAPI/client/system/events.lua new file mode 100644 index 0000000..df57bb2 --- /dev/null +++ b/resources/[standalone]/MenuAPI/client/system/events.lua @@ -0,0 +1,64 @@ +Events = {} +--OnCloseEvent, OnOpenEvent, OnChangeItemEvent, OnSelectEvent +ValidEvents = { + ["close"] = true, + ["open"] = true, + ["changeitem"] = true, + ["selectitem"] = true, + ["exit"] = true, + ["inputtext"] = true, +} + +function ValidateEvents(eventName) + return type(eventName) == "string" and ValidEvents[string.lower(eventName)] ~= nil +end + +function ValidateInvokingEvent(identifier, eventName) + return Events[identifier] ~= nil and Events[identifier][eventName] ~= nil +end + +function RemoveEventsWithNameResource(nameResource) + for identifier, v in pairs(Events) do + for event, value in pairs(v) do + for resource, val in pairs(value) do + if resource == nameResource then + Events[identifier][event][resource] = nil + break + end + end + end + end +end + +--Register event +--Return true if event is registered, false if is not +function On(identifier, eventName, cb) + local invokingName = GetInvokingResource() or identifier + eventName = string.lower(eventName) + if not ValidateEvents(eventName) then + return false + end + + if Events[identifier] == nil then + Events[identifier] = {} + end + + if Events[identifier][eventName] == nil then + Events[identifier][eventName] = {} + end + + Events[identifier][eventName][invokingName] = cb + return true +end + +--Call event +--@internal +function CallOn(identifier, eventName, ...) + if ValidateInvokingEvent(identifier, eventName) then + for key, value in pairs(Events[identifier][eventName]) do + if type(value) == "table" or type(value) == "function" then + value(...) + end + end + end +end diff --git a/resources/[standalone]/MenuAPI/fxmanifest.lua b/resources/[standalone]/MenuAPI/fxmanifest.lua new file mode 100644 index 0000000..f4c15a1 --- /dev/null +++ b/resources/[standalone]/MenuAPI/fxmanifest.lua @@ -0,0 +1,17 @@ +fx_version 'cerulean' +games { 'gta5' } + +client_scripts { + "client/*.lua", + "client/exports/*.lua", + "client/system/*.lua", + "client/module/*.lua", +} + +files { + "html/css/*.css", + "html/*.html", + "html/scripts/*.js", +} + +ui_page "html/index.html" \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/html/css/reset.css b/resources/[standalone]/MenuAPI/html/css/reset.css new file mode 100644 index 0000000..a7ad53e --- /dev/null +++ b/resources/[standalone]/MenuAPI/html/css/reset.css @@ -0,0 +1,48 @@ +/* https://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/html/css/style.css b/resources/[standalone]/MenuAPI/html/css/style.css new file mode 100644 index 0000000..360bfae --- /dev/null +++ b/resources/[standalone]/MenuAPI/html/css/style.css @@ -0,0 +1,169 @@ +.container { + min-width: 280px; + max-width: 371px; + width: auto; + height: auto; + background: rgb(228,228,228); + background: linear-gradient(0deg, rgba(99, 99, 99, 0.54) 0%, rgba(0, 0, 0, 0.48) 100%); + + max-width: 279px !important; + padding-right: 0px !important; + padding-left: 0px !important; + margin-right: auto !important; + margin-left: auto !important; +} + +.container.top{ + position: absolute; + top: 20px; +} + +.container.bottom{ + position: absolute; + bottom: 20px; +} + +.container.bottom.right{ + position: absolute; + bottom: 20px; + right: 20px; +} + +.container.bottom.left{ + position: absolute; + bottom: 20px; + left: 20px; +} + +.container.top.right{ + position: absolute; + top: 20px; + right: 20px; +} + +.container.top.left{ + position: absolute; + top: 20px; + left: 20px; +} + +.container.middle.right{ + position: absolute; + bottom: 40%; + right: 20px; +} + +.container.middle_screen.middle_screen{ + position: fixed; + top: 50%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +.container.middle.left{ + position: absolute; + bottom: 40%; + left: 20px; +} + +.title { + width: 100%; + padding: 1px 0px; + text-align: center; + background: rgb(13,37,91); + background: linear-gradient(94deg, rgba(13,37,91,1) 0%, rgba(101,146,247,1) 100%); +} +.title p { + font-family: Montserrat, Calibri, Arial; + font-size: 20px; + color: #fff; + font-weight: bold; + text-shadow: 1px 1px 4px #000000; + padding: 13px; + overflow-wrap: break-word; +} + +.menu { + width: 100%; + padding: 9px 0px; +} +.menu p { + padding: 0; + margin: 0; + font-family: Montserrat, Calibri, Arial; + font-size: 18px; + color: #fff; + text-align: center; + text-shadow: 1px 1px 4px #000000; +} + +.menu.active { + width: 100%; + background: #2f37389c; +} +.menu.active p { + font-family: Montserrat, Calibri, Arial; + color: #fff; + text-align: center; +} + +.button p{ + font-family: Montserrat, Calibri, Arial; + text-align: center; + position: relative; + top: 7px; + color: white; +} + +.button:hover{ + background: #000000a6; + transition: background-color 200ms linear; +} + +.button{ + position: relative; + left: 6px; + bottom: 3px; + background: #00000057; + height: 40px; + width: 121px; + float: left; + margin: 6px; + border-radius: 8px; + transition: background-color 200ms linear; +} + +#input input{ + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -30%); + width: 90%; + text-align: center; +} + +#scrolldiv{ + max-height: 14vw; + overflow: auto; +} + +/* width */ +::-webkit-scrollbar { + width: 10px; +} + +/* Track */ +::-webkit-scrollbar-track { + background: #f1f1f1; +} + +/* Handle */ +::-webkit-scrollbar-thumb { + background: #888; +} + +/* Handle on hover */ +::-webkit-scrollbar-thumb:hover { + background: #555; +} \ No newline at end of file diff --git a/resources/[standalone]/MenuAPI/html/index.html b/resources/[standalone]/MenuAPI/html/index.html new file mode 100644 index 0000000..36336ab --- /dev/null +++ b/resources/[standalone]/MenuAPI/html/index.html @@ -0,0 +1,46 @@ + + +
+ + + + + + + +{{titleMenu}}
+E||125