├── .github
└── ISSUE_TEMPLATE
│ ├── bug-report.md
│ ├── feature-request.md
│ └── feature_request.md
├── CHANGES.md
├── License & More
├── CODE_OF_CONDUCT.md
├── LICENSE
└── _config.yml
├── NativeUI from Frazzle
├── MenuPool.lua
├── NativeUI.lua
├── UIMenu.lua
├── Utils.lua
├── __resource.lua
├── elements
│ ├── Badge.lua
│ ├── Colours.lua
│ ├── Sprite.lua
│ ├── StringMeasurer.lua
│ ├── UIResRectangle.lua
│ └── UIResText.lua
├── items
│ ├── UIMenuCheckboxItem.lua
│ ├── UIMenuColouredItem.lua
│ ├── UIMenuItem.lua
│ ├── UIMenuListItem.lua
│ ├── UIMenuProgressItem.lua
│ └── UIMenuSliderItem.lua
├── panels
│ ├── UIMenuColourPanel.lua
│ ├── UIMenuGridPanel.lua
│ └── UIMenuPercentagePanel.lua
└── windows
│ └── UIMenuHeritageWindow.lua
├── README.md
├── SimpleMenu.lua
├── Tutorial.html
├── __resource.lua
├── perms
└── perms.lua
├── tutorial.html
└── version.lua
/.github/ISSUE_TEMPLATE/bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | ---------------
2 | Newest Updates:
3 | ---------------
4 |
5 | * Added Version Checker
6 |
7 | * UI Changes
8 |
9 | * Cleaner UI (SubMenus in SubMenus)
10 |
11 | * UPDATE LINK: https://github.com/Thymester/SimpleMenu/releases
12 |
13 | * Past Update(s) Link: https://github.com/Thymester/SimpleMenu/releases
14 |
--------------------------------------------------------------------------------
/License & More/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at zieonngaming@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/License & More/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [2019] [Tyler]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/License & More/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-time-machine
--------------------------------------------------------------------------------
/NativeUI from Frazzle/MenuPool.lua:
--------------------------------------------------------------------------------
1 | MenuPool = setmetatable({}, MenuPool)
2 | MenuPool.__index = MenuPool
3 |
4 | function MenuPool.New()
5 | local _MenuPool = {
6 | Menus = {}
7 | }
8 | return setmetatable(_MenuPool, MenuPool)
9 | end
10 |
11 | function MenuPool:AddSubMenu(Menu, Text, Description, KeepPosition, KeepBanner)
12 | if Menu() == "UIMenu" then
13 | local Item = UIMenuItem.New(tostring(Text), Description or "")
14 | Menu:AddItem(Item)
15 | local SubMenu
16 | if KeepPosition then
17 | SubMenu = UIMenu.New(Menu.Title:Text(), Text, Menu.Position.X, Menu.Position.Y)
18 | else
19 | SubMenu = UIMenu.New(Menu.Title:Text(), Text)
20 | end
21 | if KeepBanner then
22 | if Menu.Logo ~= nil then
23 | SubMenu.Logo = Menu.Logo
24 | else
25 | SubMenu.Logo = nil
26 | SubMenu.Banner = Menu.Banner
27 | end
28 | end
29 | self:Add(SubMenu)
30 | Menu:BindMenuToItem(SubMenu, Item)
31 | return SubMenu
32 | end
33 | end
34 |
35 | function MenuPool:Add(Menu)
36 | if Menu() == "UIMenu" then
37 | table.insert(self.Menus, Menu)
38 | end
39 | end
40 |
41 | function MenuPool:MouseEdgeEnabled(bool)
42 | if bool ~= nil then
43 | for _, Menu in pairs(self.Menus) do
44 | Menu.Settings.MouseEdgeEnabled = tobool(bool)
45 | end
46 | end
47 | end
48 |
49 | function MenuPool:ControlDisablingEnabled(bool)
50 | if bool ~= nil then
51 | for _, Menu in pairs(self.Menus) do
52 | Menu.Settings.ControlDisablingEnabled = tobool(bool)
53 | end
54 | end
55 | end
56 |
57 | function MenuPool:ResetCursorOnOpen(bool)
58 | if bool ~= nil then
59 | for _, Menu in pairs(self.Menus) do
60 | Menu.Settings.ResetCursorOnOpen = tobool(bool)
61 | end
62 | end
63 | end
64 |
65 | function MenuPool:MultilineFormats(bool)
66 | if bool ~= nil then
67 | for _, Menu in pairs(self.Menus) do
68 | Menu.Settings.MultilineFormats = tobool(bool)
69 | end
70 | end
71 | end
72 |
73 | function MenuPool:Audio(Attribute, Setting)
74 | if Attribute ~= nil and Setting ~= nil then
75 | for _, Menu in pairs(self.Menus) do
76 | if Menu.Settings.Audio[Attribute] then
77 | Menu.Settings.Audio[Attribute] = Setting
78 | end
79 | end
80 | end
81 | end
82 |
83 | function MenuPool:WidthOffset(offset)
84 | if tonumber(offset) then
85 | for _, Menu in pairs(self.Menus) do
86 | Menu:SetMenuWidthOffset(tonumber(offset))
87 | end
88 | end
89 | end
90 |
91 | function MenuPool:CounterPreText(str)
92 | if str ~= nil then
93 | for _, Menu in pairs(self.Menus) do
94 | Menu.PageCounter.PreText = tostring(str)
95 | end
96 | end
97 | end
98 |
99 | function MenuPool:DisableInstructionalButtons(bool)
100 | if bool ~= nil then
101 | for _, Menu in pairs(self.Menus) do
102 | Menu.Settings.InstructionalButtons = tobool(bool)
103 | end
104 | end
105 | end
106 |
107 | function MenuPool:MouseControlsEnabled(bool)
108 | if bool ~= nil then
109 | for _, Menu in pairs(self.Menus) do
110 | Menu.Settings.MouseControlsEnabled = tobool(bool)
111 | end
112 | end
113 | end
114 |
115 | function MenuPool:RefreshIndex()
116 | for _, Menu in pairs(self.Menus) do
117 | Menu:RefreshIndex()
118 | end
119 | end
120 |
121 | function MenuPool:ProcessMenus()
122 | self:ProcessControl()
123 | self:ProcessMouse()
124 | self:Draw()
125 | end
126 |
127 | function MenuPool:ProcessControl()
128 | for _, Menu in pairs(self.Menus) do
129 | if Menu:Visible() then
130 | Menu:ProcessControl()
131 | end
132 | end
133 | end
134 |
135 | function MenuPool:ProcessMouse()
136 | for _, Menu in pairs(self.Menus) do
137 | if Menu:Visible() then
138 | Menu:ProcessMouse()
139 | end
140 | end
141 | end
142 |
143 | function MenuPool:Draw()
144 | for _, Menu in pairs(self.Menus) do
145 | if Menu:Visible() then
146 | Menu:Draw()
147 | end
148 | end
149 | end
150 |
151 | function MenuPool:IsAnyMenuOpen()
152 | local open = false
153 | for _, Menu in pairs(self.Menus) do
154 | if Menu:Visible() then
155 | open = true
156 | break
157 | end
158 | end
159 | return open
160 | end
161 |
162 | function MenuPool:CloseAllMenus()
163 | for _, Menu in pairs(self.Menus) do
164 | if Menu:Visible() then
165 | Menu:Visible(false)
166 | Menu.OnMenuClosed(Menu)
167 | end
168 | end
169 | end
170 |
171 | function MenuPool:SetBannerSprite(Sprite)
172 | if Sprite() == "Sprite" then
173 | for _, Menu in pairs(self.Menus) do
174 | Menu:SetBannerSprite(Sprite)
175 | end
176 | end
177 | end
178 |
179 | function MenuPool:SetBannerRectangle(Rectangle)
180 | if Rectangle() == "Rectangle" then
181 | for _, Menu in pairs(self.Menus) do
182 | Menu:SetBannerRectangle(Rectangle)
183 | end
184 | end
185 | end
186 |
187 | function MenuPool:TotalItemsPerPage(Value)
188 | if tonumber(Value) then
189 | for _, Menu in pairs(self.Menus) do
190 | Menu.Pagination.Total = Value - 1
191 | end
192 | end
193 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/UIMenu.lua:
--------------------------------------------------------------------------------
1 | UIMenu = setmetatable({}, UIMenu)
2 | UIMenu.__index = UIMenu
3 | UIMenu.__call = function() return "UIMenu" end
4 |
5 | function UIMenu.New(Title, Subtitle, X, Y, TxtDictionary, TxtName)
6 | local X, Y = tonumber(X) or 0, tonumber(Y) or 0
7 | if Title ~= nil then Title = tostring(Title) or "" else Title = "" end
8 | if Subtitle ~= nil then Subtitle = tostring(Subtitle) or "" else Subtitle = "" end
9 | if TxtDictionary ~= nil then TxtDictionary = tostring(TxtDictionary) or "commonmenu" else TxtDictionary = "commonmenu" end
10 | if TxtName ~= nil then TxtName = tostring(TxtName) or "interaction_bgd" else TxtName = "interaction_bgd" end
11 | local _UIMenu = {
12 | Logo = Sprite.New(TxtDictionary, TxtName, 0 + X, 0 + Y, 431, 107),
13 | Banner = nil,
14 | Title = UIResText.New(Title, 215 + X, 20 + Y, 1.15, 255, 255, 255, 255, 1, 1),
15 | Subtitle = {ExtraY = 0},
16 | WidthOffset = 0,
17 | Position = {X = X, Y = Y},
18 | Pagination = {Min = 0, Max = 9, Total = 9},
19 | PageCounter = {PreText = ""},
20 | Extra = {},
21 | Description = {},
22 | Items = {},
23 | Windows = {},
24 | Children = {},
25 | Controls = {
26 | Back = {
27 | Enabled = true,
28 | },
29 | Select = {
30 | Enabled = true,
31 | },
32 | Left = {
33 | Enabled = true,
34 | },
35 | Right = {
36 | Enabled = true,
37 | },
38 | Up = {
39 | Enabled = true,
40 | },
41 | Down = {
42 | Enabled = true,
43 | },
44 | },
45 | ParentMenu = nil,
46 | ParentItem = nil,
47 | _Visible = false,
48 | ActiveItem = 1000,
49 | Dirty = false;
50 | ReDraw = true,
51 | InstructionalScaleform = RequestScaleformMovie("INSTRUCTIONAL_BUTTONS"),
52 | InstructionalButtons = {},
53 | OnIndexChange = function(menu, newindex) end,
54 | OnListChange = function(menu, list, newindex) end,
55 | OnSliderChange = function(menu, slider, newindex) end,
56 | OnProgressChange = function(menu, progress, newindex) end,
57 | OnCheckboxChange = function(menu, item, checked) end,
58 | OnListSelect = function(menu, list, index) end,
59 | OnSliderSelect = function(menu, slider, index) end,
60 | OnProgressSelect = function(menu, progress, index) end,
61 | OnItemSelect = function(menu, item, index) end,
62 | OnMenuChanged = function(menu, newmenu, forward) end,
63 | OnMenuClosed = function(menu) end,
64 | Settings = {
65 | InstructionalButtons = true,
66 | MultilineFormats = true,
67 | ScaleWithSafezone = true,
68 | ResetCursorOnOpen = true,
69 | MouseControlsEnabled = true,
70 | MouseEdgeEnabled = true,
71 | ControlDisablingEnabled = true,
72 | Audio = {
73 | Library = "HUD_FRONTEND_DEFAULT_SOUNDSET",
74 | UpDown = "NAV_UP_DOWN",
75 | LeftRight = "NAV_LEFT_RIGHT",
76 | Select = "SELECT",
77 | Back = "BACK",
78 | Error = "ERROR",
79 | },
80 | EnabledControls = {
81 | Controller = {
82 | {0, 2}, -- Look Up and Down
83 | {0, 1}, -- Look Left and Right
84 | {0, 25}, -- Aim
85 | {0, 24}, -- Attack
86 | },
87 | Keyboard = {
88 | {0, 201}, -- Select
89 | {0, 195}, -- X axis
90 | {0, 196}, -- Y axis
91 | {0, 187}, -- Down
92 | {0, 188}, -- Up
93 | {0, 189}, -- Left
94 | {0, 190}, -- Right
95 | {0, 202}, -- Back
96 | {0, 217}, -- Select
97 | {0, 242}, -- Scroll down
98 | {0, 241}, -- Scroll up
99 | {0, 239}, -- Cursor X
100 | {0, 240}, -- Cursor Y
101 | {0, 31}, -- Move Up and Down
102 | {0, 30}, -- Move Left and Right
103 | {0, 21}, -- Sprint
104 | {0, 22}, -- Jump
105 | {0, 23}, -- Enter
106 | {0, 75}, -- Exit Vehicle
107 | {0, 71}, -- Accelerate Vehicle
108 | {0, 72}, -- Vehicle Brake
109 | {0, 59}, -- Move Vehicle Left and Right
110 | {0, 89}, -- Fly Yaw Left
111 | {0, 9}, -- Fly Left and Right
112 | {0, 8}, -- Fly Up and Down
113 | {0, 90}, -- Fly Yaw Right
114 | {0, 76}, -- Vehicle Handbrake
115 | },
116 | },
117 | }
118 | }
119 |
120 | if Subtitle ~= "" and Subtitle ~= nil then
121 | _UIMenu.Subtitle.Rectangle = UIResRectangle.New(0 + _UIMenu.Position.X, 107 + _UIMenu.Position.Y, 431, 37, 0, 0, 0, 255)
122 | _UIMenu.Subtitle.Text = UIResText.New(Subtitle, 8 + _UIMenu.Position.X, 110 + _UIMenu.Position.Y, 0.35, 245, 245, 245, 255, 0)
123 | _UIMenu.Subtitle.BackupText = Subtitle
124 | _UIMenu.Subtitle.Formatted = false
125 | if string.starts(Subtitle, "~") then
126 | _UIMenu.PageCounter.PreText = string.sub(Subtitle, 1, 3)
127 | end
128 | _UIMenu.PageCounter.Text = UIResText.New("", 425 + _UIMenu.Position.X, 110 + _UIMenu.Position.Y, 0.35, 245, 245, 245, 255, 0, "Right")
129 | _UIMenu.Subtitle.ExtraY = 37
130 | end
131 |
132 | _UIMenu.ArrowSprite = Sprite.New("commonmenu", "shop_arrows_upanddown", 190 + _UIMenu.Position.X, 147 + 37 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 50, 50)
133 | _UIMenu.Extra.Up = UIResRectangle.New(0 + _UIMenu.Position.X, 144 + 38 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 431, 18, 0, 0, 0, 200)
134 | _UIMenu.Extra.Down = UIResRectangle.New(0 + _UIMenu.Position.X, 144 + 18 + 38 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 431, 18, 0, 0, 0, 200)
135 |
136 | _UIMenu.Description.Bar = UIResRectangle.New(_UIMenu.Position.X, 123, 431, 4, 0, 0, 0, 255)
137 | _UIMenu.Description.Rectangle = Sprite.New("commonmenu", "gradient_bgd", _UIMenu.Position.X, 127, 431, 30)
138 | _UIMenu.Description.Text = UIResText.New("Description", _UIMenu.Position.X + 5, 125, 0.35)
139 |
140 | _UIMenu.Background = Sprite.New("commonmenu", "gradient_bgd", _UIMenu.Position.X, 144 + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 290, 25)
141 |
142 | Citizen.CreateThread(function()
143 | if not HasScaleformMovieLoaded(_UIMenu.InstructionalScaleform) then
144 | _UIMenu.InstructionalScaleform = RequestScaleformMovie("INSTRUCTIONAL_BUTTONS")
145 | while not HasScaleformMovieLoaded(_UIMenu.InstructionalScaleform) do
146 | Citizen.Wait(0)
147 | end
148 | end
149 | end)
150 | return setmetatable(_UIMenu, UIMenu)
151 | end
152 |
153 | function UIMenu:SetMenuWidthOffset(Offset)
154 | if tonumber(Offset) then
155 | self.WidthOffset = math.floor(tonumber(Offset))
156 | self.Logo:Size(431 + self.WidthOffset, 107)
157 | self.Title:Position(((self.WidthOffset + 431)/2) + self.Position.X, 20 + self.Position.Y)
158 | if self.Subtitle.Rectangle ~= nil then
159 | self.Subtitle.Rectangle:Size(431 + self.WidthOffset + 100, 37)
160 | self.PageCounter.Text:Position(425 + self.Position.X + self.WidthOffset, 110 + self.Position.Y)
161 | end
162 | if self.Banner ~= nil then
163 | self.Banner:Size(431 + self.WidthOffset, 107)
164 | end
165 | end
166 | end
167 |
168 | function UIMenu:DisEnableControls(bool)
169 | if bool then
170 | EnableAllControlActions(2)
171 | else
172 | DisableAllControlActions(2)
173 | end
174 |
175 | if bool then
176 | return
177 | else
178 | if Controller() then
179 | for Index = 1, #self.Settings.EnabledControls.Controller do
180 | EnableControlAction(self.Settings.EnabledControls.Controller[Index][1], self.Settings.EnabledControls.Controller[Index][2], true)
181 | end
182 | else
183 | for Index = 1, #self.Settings.EnabledControls.Keyboard do
184 | EnableControlAction(self.Settings.EnabledControls.Keyboard[Index][1], self.Settings.EnabledControls.Keyboard[Index][2], true)
185 | end
186 | end
187 | end
188 | end
189 |
190 | function UIMenu:InstructionalButtons(bool)
191 | if bool ~= nil then
192 | self.Settings.InstrucitonalButtons = tobool(bool)
193 | end
194 | end
195 |
196 | function UIMenu:SetBannerSprite(Sprite, IncludeChildren)
197 | if Sprite() == "Sprite" then
198 | self.Logo = Sprite
199 | self.Logo:Size(431 + self.WidthOffset, 107)
200 | self.Logo:Position(self.Position.X, self.Position.Y)
201 | self.Banner = nil
202 | if IncludeChildren then
203 | for Item, Menu in pairs(self.Children) do
204 | Menu.Logo = Sprite
205 | Menu.Logo:Size(431 + self.WidthOffset, 107)
206 | Menu.Logo:Position(self.Position.X, self.Position.Y)
207 | Menu.Banner = nil
208 | end
209 | end
210 | end
211 | end
212 |
213 | function UIMenu:SetBannerRectangle(Rectangle, IncludeChildren)
214 | if Rectangle() == "Rectangle" then
215 | self.Banner = Rectangle
216 | self.Banner:Size(431 + self.WidthOffset, 107)
217 | self.Banner:Position(self.Position.X, self.Position.Y)
218 | self.Logo = nil
219 | if IncludeChildren then
220 | for Item, Menu in pairs(self.Children) do
221 | Menu.Banner = Rectangle
222 | Menu.Banner:Size(431 + self.WidthOffset, 107)
223 | Menu:Position(self.Position.X, self.Position.Y)
224 | Menu.Logo = nil
225 | end
226 | end
227 | end
228 | end
229 |
230 | function UIMenu:CurrentSelection(value)
231 | if tonumber(value) then
232 | if #self.Items == 0 then
233 | self.ActiveItem = 0
234 | end
235 |
236 | self.Items[self:CurrentSelection()]:Selected(false)
237 | self.ActiveItem = 1000000 - (1000000 % #self.Items) + tonumber(value)
238 |
239 | if self:CurrentSelection() > self.Pagination.Max then
240 | self.Pagination.Min = self:CurrentSelection() - self.Pagination.Total
241 | self.Pagination.Max = self:CurrentSelection()
242 | elseif self:CurrentSelection() < self.Pagination.Min then
243 | self.Pagination.Min = self:CurrentSelection()
244 | self.Pagination.Max = self:CurrentSelection() + self.Pagination.Total
245 | end
246 | else
247 | if #self.Items == 0 then
248 | return 1
249 | else
250 | if self.ActiveItem % #self.Items == 0 then
251 | return 1
252 | else
253 | return self.ActiveItem % #self.Items + 1
254 | end
255 | end
256 | end
257 | end
258 |
259 | function UIMenu:CalculateWindowHeight()
260 | local Height = 0
261 | for i = 1, #self.Windows do
262 | Height = Height + self.Windows[i].Background:Size().Height
263 | end
264 | return Height
265 | end
266 |
267 | function UIMenu:CalculateItemHeightOffset(Item)
268 | if Item.Base then
269 | return Item.Base.Rectangle.Height
270 | else
271 | return Item.Rectangle.Height
272 | end
273 | end
274 |
275 | function UIMenu:CalculateItemHeight()
276 | local ItemOffset = 0 + self.Subtitle.ExtraY - 37
277 | for i = self.Pagination.Min + 1, self.Pagination.Max do
278 | local Item = self.Items[i]
279 | if Item ~= nil then
280 | ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
281 | end
282 | end
283 | return ItemOffset
284 | end
285 |
286 | function UIMenu:RecalculateDescriptionPosition()
287 | local WindowHeight = self:CalculateWindowHeight()
288 | self.Description.Bar:Position(self.Position.X, 149 + self.Position.Y + WindowHeight)
289 | self.Description.Rectangle:Position(self.Position.X, 149 + self.Position.Y + WindowHeight)
290 | self.Description.Text:Position(self.Position.X + 8, 155 + self.Position.Y + WindowHeight)
291 |
292 | self.Description.Bar:Size(431 + self.WidthOffset, 4)
293 | self.Description.Rectangle:Size(431 + self.WidthOffset, 30)
294 |
295 | self.Description.Bar:Position(self.Position.X, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Bar:Position().Y)
296 | self.Description.Rectangle:Position(self.Position.X, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Rectangle:Position().Y)
297 | self.Description.Text:Position(self.Position.X + 8, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Text:Position().Y)
298 | end
299 |
300 | function UIMenu:CaclulatePanelPosition(HasDescription)
301 | local Height = self:CalculateWindowHeight() + 149 + self.Position.Y
302 |
303 | if HasDescription then
304 | Height = Height + self.Description.Rectangle:Size().Height + 5
305 | end
306 |
307 | return self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + Height
308 | end
309 |
310 | function UIMenu:AddWindow(Window)
311 | if Window() == "UIMenuWindow" then
312 | Window:SetParentMenu(self)
313 | Window:Offset(self.Position.X, self.Position.Y)
314 | table.insert(self.Windows, Window)
315 | self.ReDraw = true
316 | self:RecalculateDescriptionPosition()
317 | end
318 | end
319 |
320 | function UIMenu:RemoveWindowAt(Index)
321 | if tonumber(Index) then
322 | if self.Windows[Index] then
323 | table.remove(self.Windows, Index)
324 | self.ReDraw = true
325 | self:RecalculateDescriptionPosition()
326 | end
327 | end
328 | end
329 |
330 | function UIMenu:AddItem(Item)
331 | if Item() == "UIMenuItem" then
332 | local SelectedItem = self:CurrentSelection()
333 | Item:SetParentMenu(self)
334 | Item:Offset(self.Position.X, self.Position.Y)
335 | Item:Position((#self.Items * 25) - 37 + self.Subtitle.ExtraY)
336 | table.insert(self.Items, Item)
337 | self:RecalculateDescriptionPosition()
338 | self:CurrentSelection(SelectedItem)
339 | end
340 | end
341 |
342 | function UIMenu:RemoveItemAt(Index)
343 | if tonumber(Index) then
344 | if self.Items[Index] then
345 | local SelectedItem = self:CurrentSelection()
346 | if #self.Items > self.Pagination.Total and self.Pagination.Max == #self.Items - 1 then
347 | self.Pagination.Min = self.Pagination.Min - 1
348 | self.Pagination.Max = self.Pagination.Max + 1
349 | end
350 | table.remove(self.Items, tonumber(Index))
351 | self:RecalculateDescriptionPosition()
352 | self:CurrentSelection(SelectedItem)
353 | end
354 | end
355 | end
356 |
357 | function UIMenu:RefreshIndex()
358 | if #self.Items == 0 then
359 | self.ActiveItem = 1000
360 | self.Pagination.Max = self.Pagination.Total + 1
361 | self.Pagination.Min = 0
362 | return
363 | end
364 | self.Items[self:CurrentSelection()]:Selected(false)
365 | self.ActiveItem = 1000 - (1000 % #self.Items)
366 | self.Pagination.Max = self.Pagination.Total + 1
367 | self.Pagination.Min = 0
368 | self.ReDraw = true
369 | end
370 |
371 | function UIMenu:Clear()
372 | self.Items = {}
373 | self.ReDraw = true
374 | self:RecalculateDescriptionPosition()
375 | end
376 |
377 | function UIMenu:MultilineFormat(str)
378 | if tostring(str) then
379 |
380 | local PixelPerLine = 425 + self.WidthOffset
381 | local AggregatePixels = 0
382 | local output = ""
383 | local words = string.split(tostring(str), " ")
384 |
385 | for i = 1, #words do
386 | local offset = MeasureStringWidth(words[i], 0, 0.35)
387 | AggregatePixels = AggregatePixels + offset
388 | if AggregatePixels > PixelPerLine then
389 | output = output .. "\n" .. words[i] .. " "
390 | AggregatePixels = offset + MeasureString(" ")
391 | else
392 | output = output .. words[i] .. " "
393 | AggregatePixels = AggregatePixels + MeasureString(" ")
394 | end
395 | end
396 | return output
397 | end
398 | end
399 |
400 | function UIMenu:DrawCalculations()
401 | local WindowHeight = self:CalculateWindowHeight()
402 |
403 | if self.Settings.MultilineFormats then
404 | if self.Subtitle.Rectangle and not self.Subtitle.Formatted then
405 | self.Subtitle.Formatted = true
406 | self.Subtitle.Text:Text(self:MultilineFormat(self.Subtitle.Text:Text()))
407 |
408 | local Linecount = #string.split(self.Subtitle.Text:Text(), "\n")
409 | self.Subtitle.ExtraY = ((Linecount == 1) and 37 or ((Linecount + 1) * 22))
410 | self.Subtitle.Rectangle:Size(431 + self.WidthOffset, self.Subtitle.ExtraY)
411 | end
412 | elseif self.Subtitle.Formatted then
413 | self.Subtitle.Formatted = false
414 | self.Subtitle.ExtraY = 37
415 | self.Subtitle.Rectangle:Size(431 + self.WidthOffset, self.Subtitle.ExtraY)
416 | self.Subtitle.Text:Text(self.Subtitle.BackupText)
417 | end
418 |
419 | self.Background:Size(431 + self.WidthOffset, self:CalculateItemHeight() + WindowHeight + ((self.Subtitle.ExtraY > 0) and 0 or 37))
420 |
421 | self.Extra.Up:Size(431 + self.WidthOffset, 18)
422 | self.Extra.Down:Size(431 + self.WidthOffset, 18)
423 |
424 | self.Extra.Up:Position(self.Position.X, 144 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
425 | self.Extra.Down:Position(self.Position.X, 144 + 18 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
426 |
427 | if self.WidthOffset > 0 then
428 | self.ArrowSprite:Position(190 + self.Position.X + (self.WidthOffset / 2), 137 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
429 | else
430 | self.ArrowSprite:Position(190 + self.Position.X + self.WidthOffset, 137 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
431 | end
432 |
433 | self.ReDraw = false
434 |
435 | if #self.Items ~= 0 and self.Items[self:CurrentSelection()]:Description() ~= "" then
436 | self:RecalculateDescriptionPosition()
437 |
438 | local description = self.Items[self:CurrentSelection()]:Description()
439 | if self.Settings.MultilineFormats then
440 | self.Description.Text:Text(self:MultilineFormat(description))
441 | else
442 | self.Description.Text:Text(description)
443 | end
444 |
445 | local Linecount = #string.split(self.Description.Text:Text(), "\n")
446 | self.Description.Rectangle:Size(431 + self.WidthOffset, ((Linecount == 1) and 37 or ((Linecount + 1) * 22)))
447 | end
448 | end
449 |
450 | function UIMenu:Visible(bool)
451 | if bool ~= nil then
452 | self._Visible = tobool(bool)
453 | self.JustOpened = tobool(bool)
454 | self.Dirty = tobool(bool)
455 | self:UpdateScaleform()
456 | if self.ParentMenu ~= nil or tobool(bool) == false then
457 | return
458 | end
459 | if self.Settings.ResetCursorOnOpen then
460 | local W, H = GetScreenResolution()
461 | SetCursorLocation(W / 2, H / 2)
462 | SetCursorSprite(1)
463 | end
464 | else
465 | return self._Visible
466 | end
467 | end
468 |
469 | function UIMenu:ProcessControl()
470 | if not self._Visible then
471 | return
472 | end
473 |
474 | if self.JustOpened then
475 | self.JustOpened = false
476 | return
477 | end
478 |
479 | if self.Controls.Back.Enabled and (IsDisabledControlJustReleased(0, 177) or IsDisabledControlJustReleased(1, 177) or IsDisabledControlJustReleased(2, 177) or IsDisabledControlJustReleased(0, 199) or IsDisabledControlJustReleased(1, 199) or IsDisabledControlJustReleased(2, 199)) then
480 | self:GoBack()
481 | end
482 |
483 | if #self.Items == 0 then
484 | return
485 | end
486 |
487 | if not self.UpPressed then
488 | if self.Controls.Up.Enabled and (IsDisabledControlJustPressed(0, 172) or IsDisabledControlJustPressed(1, 172) or IsDisabledControlJustPressed(2, 172) or IsDisabledControlJustPressed(0, 241) or IsDisabledControlJustPressed(1, 241) or IsDisabledControlJustPressed(2, 241) or IsDisabledControlJustPressed(2, 241)) then
489 | Citizen.CreateThread(function()
490 | self.UpPressed = true
491 | if #self.Items > self.Pagination.Total + 1 then
492 | self:GoUpOverflow()
493 | else
494 | self:GoUp()
495 | end
496 | self:UpdateScaleform()
497 | Citizen.Wait(175)
498 | while self.Controls.Up.Enabled and (IsDisabledControlPressed(0, 172) or IsDisabledControlPressed(1, 172) or IsDisabledControlPressed(2, 172) or IsDisabledControlPressed(0, 241) or IsDisabledControlPressed(1, 241) or IsDisabledControlPressed(2, 241) or IsDisabledControlPressed(2, 241)) do
499 | if #self.Items > self.Pagination.Total + 1 then
500 | self:GoUpOverflow()
501 | else
502 | self:GoUp()
503 | end
504 | self:UpdateScaleform()
505 | Citizen.Wait(125)
506 | end
507 | self.UpPressed = false
508 | end)
509 | end
510 | end
511 |
512 | if not self.DownPressed then
513 | if self.Controls.Down.Enabled and (IsDisabledControlJustPressed(0, 173) or IsDisabledControlJustPressed(1, 173) or IsDisabledControlJustPressed(2, 173) or IsDisabledControlJustPressed(0, 242) or IsDisabledControlJustPressed(1, 242) or IsDisabledControlJustPressed(2, 242)) then
514 | Citizen.CreateThread(function()
515 | self.DownPressed = true
516 | if #self.Items > self.Pagination.Total + 1 then
517 | self:GoDownOverflow()
518 | else
519 | self:GoDown()
520 | end
521 | self:UpdateScaleform()
522 | Citizen.Wait(175)
523 | while self.Controls.Down.Enabled and (IsDisabledControlPressed(0, 173) or IsDisabledControlPressed(1, 173) or IsDisabledControlPressed(2, 173) or IsDisabledControlPressed(0, 242) or IsDisabledControlPressed(1, 242) or IsDisabledControlPressed(2, 242)) do
524 | if #self.Items > self.Pagination.Total + 1 then
525 | self:GoDownOverflow()
526 | else
527 | self:GoDown()
528 | end
529 | self:UpdateScaleform()
530 | Citizen.Wait(125)
531 | end
532 | self.DownPressed = false
533 | end)
534 | end
535 | end
536 |
537 | if not self.LeftPressed then
538 | if self.Controls.Left.Enabled and (IsDisabledControlPressed(0, 174) or IsDisabledControlPressed(1, 174) or IsDisabledControlPressed(2, 174)) then
539 | Citizen.CreateThread(function()
540 | self.LeftPressed = true
541 | self:GoLeft()
542 | Citizen.Wait(175)
543 | while self.Controls.Left.Enabled and (IsDisabledControlPressed(0, 174) or IsDisabledControlPressed(1, 174) or IsDisabledControlPressed(2, 174)) do
544 | self:GoLeft()
545 | Citizen.Wait(125)
546 | end
547 | self.LeftPressed = false
548 | end)
549 | end
550 | end
551 |
552 | if not self.RightPressed then
553 | if self.Controls.Right.Enabled and (IsDisabledControlPressed(0, 175) or IsDisabledControlPressed(1, 175) or IsDisabledControlPressed(2, 175)) then
554 | Citizen.CreateThread(function()
555 | self.RightPressed = true
556 | self:GoRight()
557 | Citizen.Wait(175)
558 | while self.Controls.Right.Enabled and (IsDisabledControlPressed(0, 175) or IsDisabledControlPressed(1, 175) or IsDisabledControlPressed(2, 175)) do
559 | self:GoRight()
560 | Citizen.Wait(125)
561 | end
562 | self.RightPressed = false
563 | end)
564 | end
565 | end
566 |
567 | if self.Controls.Select.Enabled and (IsDisabledControlJustPressed(0, 201) or IsDisabledControlJustPressed(1, 201) or IsDisabledControlJustPressed(2, 201)) then
568 | self:SelectItem()
569 | end
570 | end
571 |
572 | function UIMenu:GoUpOverflow()
573 | if #self.Items <= self.Pagination.Total + 1 then
574 | return
575 | end
576 |
577 | if self:CurrentSelection() <= self.Pagination.Min + 1 then
578 | if self:CurrentSelection() == 1 then
579 | self.Pagination.Min = #self.Items - (self.Pagination.Total + 1)
580 | self.Pagination.Max = #self.Items
581 | self.Items[self:CurrentSelection()]:Selected(false)
582 | self.ActiveItem = 1000 - (1000 % #self.Items)
583 | self.ActiveItem = self.ActiveItem + (#self.Items - 1)
584 | self.Items[self:CurrentSelection()]:Selected(true)
585 | else
586 | self.Pagination.Min = self.Pagination.Min - 1
587 | self.Pagination.Max = self.Pagination.Max - 1
588 | self.Items[self:CurrentSelection()]:Selected(false)
589 | self.ActiveItem = self.ActiveItem - 1
590 | self.Items[self:CurrentSelection()]:Selected(true)
591 | end
592 | else
593 | self.Items[self:CurrentSelection()]:Selected(false)
594 | self.ActiveItem = self.ActiveItem - 1
595 | self.Items[self:CurrentSelection()]:Selected(true)
596 | end
597 | PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
598 | self.OnIndexChange(self, self:CurrentSelection())
599 | self.ReDraw = true
600 | end
601 |
602 | function UIMenu:GoUp()
603 | if #self.Items > self.Pagination.Total + 1 then
604 | return
605 | end
606 | self.Items[self:CurrentSelection()]:Selected(false)
607 | self.ActiveItem = self.ActiveItem - 1
608 | self.Items[self:CurrentSelection()]:Selected(true)
609 | PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
610 | self.OnIndexChange(self, self:CurrentSelection())
611 | self.ReDraw = true
612 | end
613 |
614 | function UIMenu:GoDownOverflow()
615 | if #self.Items <= self.Pagination.Total + 1 then
616 | return
617 | end
618 |
619 | if self:CurrentSelection() >= self.Pagination.Max then
620 | if self:CurrentSelection() == #self.Items then
621 | self.Pagination.Min = 0
622 | self.Pagination.Max = self.Pagination.Total + 1
623 | self.Items[self:CurrentSelection()]:Selected(false)
624 | self.ActiveItem = 1000 - (1000 % #self.Items)
625 | self.Items[self:CurrentSelection()]:Selected(true)
626 | else
627 | self.Pagination.Max = self.Pagination.Max + 1
628 | self.Pagination.Min = self.Pagination.Max - (self.Pagination.Total + 1)
629 | self.Items[self:CurrentSelection()]:Selected(false)
630 | self.ActiveItem = self.ActiveItem + 1
631 | self.Items[self:CurrentSelection()]:Selected(true)
632 | end
633 | else
634 | self.Items[self:CurrentSelection()]:Selected(false)
635 | self.ActiveItem = self.ActiveItem + 1
636 | self.Items[self:CurrentSelection()]:Selected(true)
637 | end
638 | PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
639 | self.OnIndexChange(self, self:CurrentSelection())
640 | self.ReDraw = true
641 | end
642 |
643 | function UIMenu:GoDown()
644 | if #self.Items > self.Pagination.Total + 1 then
645 | return
646 | end
647 |
648 | self.Items[self:CurrentSelection()]:Selected(false)
649 | self.ActiveItem = self.ActiveItem + 1
650 | self.Items[self:CurrentSelection()]:Selected(true)
651 | PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
652 | self.OnIndexChange(self, self:CurrentSelection())
653 | self.ReDraw = true
654 | end
655 |
656 | function UIMenu:GoLeft()
657 | local type, subtype = self.Items[self:CurrentSelection()]()
658 | if subtype ~= "UIMenuListItem" and subtype ~= "UIMenuSliderItem" and subtype ~= "UIMenuProgressItem" then
659 | return
660 | end
661 |
662 | if not self.Items[self:CurrentSelection()]:Enabled() then
663 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
664 | return
665 | end
666 |
667 | if subtype == "UIMenuListItem" then
668 | local Item = self.Items[self:CurrentSelection()]
669 | Item:Index(Item._Index - 1)
670 | self.OnListChange(self, Item, Item._Index)
671 | Item.OnListChanged(self, Item, Item._Index)
672 | PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
673 | elseif subtype == "UIMenuSliderItem" then
674 | local Item = self.Items[self:CurrentSelection()]
675 | Item:Index(Item._Index - 1)
676 | self.OnSliderChange(self, Item, Item:Index())
677 | Item.OnSliderChanged(self, Item, Item._Index)
678 | PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
679 | elseif subtype == "UIMenuProgressItem" then
680 | local Item = self.Items[self:CurrentSelection()]
681 | Item:Index(Item.Data.Index - 1)
682 | self.OnProgressChange(self, Item, Item.Data.Index)
683 | Item.OnProgressChanged(self, Item, Item.Data.Index)
684 | PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
685 | end
686 | end
687 |
688 | function UIMenu:GoRight()
689 | local type, subtype = self.Items[self:CurrentSelection()]()
690 | if subtype ~= "UIMenuListItem" and subtype ~= "UIMenuSliderItem" and subtype ~= "UIMenuProgressItem" then
691 | return
692 | end
693 |
694 | if not self.Items[self:CurrentSelection()]:Enabled() then
695 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
696 | return
697 | end
698 |
699 | if subtype == "UIMenuListItem" then
700 | local Item = self.Items[self:CurrentSelection()]
701 | Item:Index(Item._Index + 1)
702 | self.OnListChange(self, Item, Item._Index)
703 | Item.OnListChanged(self, Item, Item._Index)
704 | PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
705 | elseif subtype == "UIMenuSliderItem" then
706 | local Item = self.Items[self:CurrentSelection()]
707 | Item:Index(Item._Index + 1)
708 | self.OnSliderChange(self, Item, Item:Index())
709 | Item.OnSliderChanged(self, Item, Item._Index)
710 | PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
711 | elseif subtype == "UIMenuProgressItem" then
712 | local Item = self.Items[self:CurrentSelection()]
713 | Item:Index(Item.Data.Index + 1)
714 | self.OnProgressChange(self, Item, Item.Data.Index)
715 | Item.OnProgressChanged(self, Item, Item.Data.Index)
716 | PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
717 | end
718 | end
719 |
720 | function UIMenu:SelectItem()
721 | if not self.Items[self:CurrentSelection()]:Enabled() then
722 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
723 | return
724 | end
725 | local Item = self.Items[self:CurrentSelection()]
726 | local type, subtype = Item()
727 | if subtype == "UIMenuCheckboxItem" then
728 | Item.Checked = not Item.Checked
729 | PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
730 | self.OnCheckboxChange(self, Item, Item.Checked)
731 | Item.CheckboxEvent(self, Item, Item.Checked)
732 | elseif subtype == "UIMenuListItem" then
733 | PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
734 | self.OnListSelect(self, Item, Item._Index)
735 | Item.OnListSelected(self, Item, Item._Index)
736 | elseif subtype == "UIMenuSliderItem" then
737 | PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
738 | self.OnSliderSelect(self, Item, Item._Index)
739 | Item.OnSliderSelected(Item._Index)
740 | elseif subtype == "UIMenuProgressItem" then
741 | PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
742 | self.OnProgressSelect(self, Item, Item.Data.Index)
743 | Item.OnProgressSelected(Item.Data.Index)
744 | else
745 | PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
746 | self.OnItemSelect(self, Item, self:CurrentSelection())
747 | Item.Activated(self, Item)
748 | if not self.Children[Item] then
749 | return
750 | end
751 | self:Visible(false)
752 | self.Children[Item]:Visible(true)
753 | self.OnMenuChanged(self, self.Children[self.Items[self:CurrentSelection()]], true)
754 | end
755 | end
756 |
757 | function UIMenu:GoBack()
758 | PlaySoundFrontend(-1, self.Settings.Audio.Back, self.Settings.Audio.Library, true)
759 | self:Visible(false)
760 | if self.ParentMenu ~= nil then
761 | self.ParentMenu:Visible(true)
762 | self.OnMenuChanged(self, self.ParentMenu, false)
763 | if self.Settings.ResetCursorOnOpen then
764 | local W, H = GetActiveScreenResolution()
765 | SetCursorLocation(W / 2, H / 2)
766 | end
767 | end
768 | self.OnMenuClosed(self)
769 | end
770 |
771 | function UIMenu:BindMenuToItem(Menu, Item)
772 | if Menu() == "UIMenu" and Item() == "UIMenuItem" then
773 | Menu.ParentMenu = self
774 | Menu.ParentItem = Item
775 | self.Children[Item] = Menu
776 | end
777 | end
778 |
779 | function UIMenu:ReleaseMenuFromItem(Item)
780 | if Item() == "UIMenuItem" then
781 | if not self.Children[Item] then
782 | return false
783 | end
784 | self.Children[Item].ParentMenu = nil
785 | self.Children[Item].ParentItem = nil
786 | self.Children[Item] = nil
787 | return true
788 | end
789 | end
790 |
791 | function UIMenu:Draw()
792 | if not self._Visible then
793 | return
794 | end
795 |
796 | HideHudComponentThisFrame(19)
797 |
798 | if self.Settings.ControlDisablingEnabled then
799 | self:DisEnableControls(false)
800 | end
801 |
802 | if self.Settings.InstructionalButtons then
803 | DrawScaleformMovieFullscreen(self.InstructionalScaleform, 255, 255, 255, 255, 0)
804 | end
805 |
806 | if self.Settings.ScaleWithSafezone then
807 | ScreenDrawPositionBegin(76, 84)
808 | ScreenDrawPositionRatio(0, 0, 0, 0)
809 | end
810 |
811 | if self.ReDraw then
812 | self:DrawCalculations()
813 | end
814 |
815 | if self.Logo then
816 | self.Logo:Draw()
817 | elseif self.Banner then
818 | self.Banner:Draw()
819 | end
820 |
821 | self.Title:Draw()
822 |
823 | if self.Subtitle.Rectangle then
824 | self.Subtitle.Rectangle:Draw()
825 | self.Subtitle.Text:Draw()
826 | end
827 |
828 | if #self.Items ~= 0 or #self.Windows ~= 0 then
829 | self.Background:Draw()
830 | end
831 |
832 | if #self.Windows ~= 0 then
833 | local WindowOffset = 0
834 | for index = 1, #self.Windows do
835 | if self.Windows[index - 1] then
836 | WindowOffset = WindowOffset + self.Windows[index - 1].Background:Size().Height
837 | end
838 | local Window = self.Windows[index]
839 | Window:Position(WindowOffset + self.Subtitle.ExtraY - 37)
840 | Window:Draw()
841 | end
842 | end
843 |
844 | if #self.Items == 0 then
845 | if self.Settings.ScaleWithSafezone then
846 | ScreenDrawPositionEnd()
847 | end
848 | return
849 | end
850 |
851 | local CurrentSelection = self:CurrentSelection()
852 | self.Items[CurrentSelection]:Selected(true)
853 |
854 | if self.Items[CurrentSelection]:Description() ~= "" then
855 | self.Description.Bar:Draw()
856 | self.Description.Rectangle:Draw()
857 | self.Description.Text:Draw()
858 | end
859 |
860 | if self.Items[CurrentSelection].Panels ~= nil then
861 | if #self.Items[CurrentSelection].Panels ~= 0 then
862 | local PanelOffset = self:CaclulatePanelPosition(self.Items[CurrentSelection]:Description() ~= "")
863 | for index = 1, #self.Items[CurrentSelection].Panels do
864 | if self.Items[CurrentSelection].Panels[index - 1] then
865 | PanelOffset = PanelOffset + self.Items[CurrentSelection].Panels[index - 1].Background:Size().Height + 5
866 | end
867 | self.Items[CurrentSelection].Panels[index]:Position(PanelOffset)
868 | self.Items[CurrentSelection].Panels[index]:Draw()
869 | end
870 | end
871 | end
872 |
873 | local WindowHeight = self:CalculateWindowHeight()
874 |
875 | if #self.Items <= self.Pagination.Total + 1 then
876 | local ItemOffset = self.Subtitle.ExtraY - 37 + WindowHeight
877 | for index = 1, #self.Items do
878 | Item = self.Items[index]
879 | Item:Position(ItemOffset)
880 | Item:Draw()
881 | ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
882 | end
883 | else
884 | local ItemOffset = self.Subtitle.ExtraY - 37 + WindowHeight
885 | for index = self.Pagination.Min + 1, self.Pagination.Max, 1 do
886 | if self.Items[index] then
887 | Item = self.Items[index]
888 | Item:Position(ItemOffset)
889 | Item:Draw()
890 | ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
891 | end
892 | end
893 |
894 | self.Extra.Up:Draw()
895 | self.Extra.Down:Draw()
896 | self.ArrowSprite:Draw()
897 |
898 | if self.PageCounter.Text ~= nil then
899 | local Caption = self.PageCounter.PreText .. CurrentSelection .. " / " .. #self.Items
900 | self.PageCounter.Text:Text(Caption)
901 | self.PageCounter.Text:Draw()
902 | end
903 | end
904 |
905 | if self.Settings.ScaleWithSafezone then
906 | ScreenDrawPositionEnd()
907 | end
908 | end
909 |
910 | function UIMenu:ProcessMouse()
911 | if not self._Visible or self.JustOpened or #self.Items == 0 or tobool(Controller()) or not self.Settings.MouseControlsEnabled then
912 | EnableControlAction(0, 2, true)
913 | EnableControlAction(0, 1, true)
914 | EnableControlAction(0, 25, true)
915 | EnableControlAction(0, 24, true)
916 | if self.Dirty then
917 | for _, Item in pairs(self.Items) do
918 | if Item:Hovered() then
919 | Item:Hovered(false)
920 | end
921 | end
922 | end
923 | return
924 | end
925 |
926 | local SafeZone = {X = 0, Y = 0}
927 | local WindowHeight = self:CalculateWindowHeight()
928 | if self.Settings.ScaleWithSafezone then
929 | SafeZone = GetSafeZoneBounds()
930 | end
931 |
932 | local Limit = #self.Items
933 | local ItemOffset = 0
934 |
935 | ShowCursorThisFrame()
936 |
937 | if #self.Items > self.Pagination.Total + 1 then
938 | Limit = self.Pagination.Max
939 | end
940 |
941 | if IsMouseInBounds(0, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then
942 | SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() + 5)
943 | SetCursorSprite(6)
944 | elseif IsMouseInBounds(1920 - 30, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then
945 | SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() - 5)
946 | SetCursorSprite(7)
947 | elseif self.Settings.MouseEdgeEnabled then
948 | SetCursorSprite(1)
949 | end
950 |
951 | for i = self.Pagination.Min + 1, Limit, 1 do
952 | local X, Y = self.Position.X + SafeZone.X, self.Position.Y + 144 - 37 + self.Subtitle.ExtraY + ItemOffset + SafeZone.Y + WindowHeight
953 | local Item = self.Items[i]
954 | local Type, SubType = Item()
955 | local Width, Height = 431 + self.WidthOffset, self:CalculateItemHeightOffset(Item)
956 |
957 | if IsMouseInBounds(X, Y, Width, Height) then
958 | Item:Hovered(true)
959 | if not self.Controls.MousePressed then
960 | if IsDisabledControlJustPressed(0, 24) then
961 | Citizen.CreateThread(function()
962 | local _X, _Y, _Width, _Height = X, Y, Width, Height
963 | self.Controls.MousePressed = true
964 | if Item:Selected() and Item:Enabled() then
965 | if SubType == "UIMenuListItem" then
966 | if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
967 | self:GoLeft()
968 | elseif not IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
969 | self:SelectItem()
970 | end
971 | if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
972 | self:GoRight()
973 | elseif not IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
974 | self:SelectItem()
975 | end
976 | elseif SubType == "UIMenuSliderItem" then
977 | if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
978 | self:GoLeft()
979 | elseif not IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
980 | self:SelectItem()
981 | end
982 | if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
983 | self:GoRight()
984 | elseif not IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
985 | self:SelectItem()
986 | end
987 | elseif SubType == "UIMenuProgressItem" then
988 | if IsMouseInBounds(Item.Bar.X + SafeZone.X, Item.Bar.Y + SafeZone.Y - 12, Item.Data.Max, Item.Bar.Height + 24) then
989 | Item:CalculateProgress(math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X)
990 | self.OnProgressChange(self, Item, Item.Data.Index)
991 | Item.OnProgressChanged(self, Item, Item.Data.Index)
992 | else
993 | self:SelectItem()
994 | end
995 | else
996 | self:SelectItem()
997 | end
998 | elseif not Item:Selected() then
999 | self:CurrentSelection(i-1)
1000 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
1001 | self.OnIndexChange(self, self:CurrentSelection())
1002 | self.ReDraw = true
1003 | self:UpdateScaleform()
1004 | elseif not Item:Enabled() and Item:Selected() then
1005 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
1006 | end
1007 | Citizen.Wait(175)
1008 | while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_X, _Y, _Width, _Height) do
1009 | if Item:Selected() and Item:Enabled() then
1010 | if SubType == "UIMenuListItem" then
1011 | if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
1012 | self:GoLeft()
1013 | end
1014 | if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
1015 | self:GoRight()
1016 | end
1017 | elseif SubType == "UIMenuSliderItem" then
1018 | if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
1019 | self:GoLeft()
1020 | end
1021 | if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
1022 | self:GoRight()
1023 | end
1024 | elseif SubType == "UIMenuProgressItem" then
1025 | if IsMouseInBounds(Item.Bar.X + SafeZone.X, Item.Bar.Y + SafeZone.Y - 12, Item.Data.Max, Item.Bar.Height + 24) then
1026 | Item:CalculateProgress(math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X)
1027 | self.OnProgressChange(self, Item, Item.Data.Index)
1028 | Item.OnProgressChanged(self, Item, Item.Data.Index)
1029 | else
1030 | self:SelectItem()
1031 | end
1032 | end
1033 | elseif not Item:Selected() then
1034 | self:CurrentSelection(i-1)
1035 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
1036 | self.OnIndexChange(self, self:CurrentSelection())
1037 | self.ReDraw = true
1038 | self:UpdateScaleform()
1039 | elseif not Item:Enabled() and Item:Selected() then
1040 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
1041 | end
1042 | Citizen.Wait(125)
1043 | end
1044 | self.Controls.MousePressed = false
1045 | end)
1046 | end
1047 | end
1048 | else
1049 | Item:Hovered(false)
1050 | end
1051 | ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
1052 | end
1053 |
1054 | local ExtraX, ExtraY = self.Position.X + SafeZone.X, 144 + self:CalculateItemHeight() + self.Position.Y + SafeZone.Y + WindowHeight
1055 |
1056 | if #self.Items <= self.Pagination.Total + 1 then return end
1057 |
1058 | if IsMouseInBounds(ExtraX, ExtraY, 431 + self.WidthOffset, 18) then
1059 | self.Extra.Up:Colour(30, 30, 30, 255)
1060 | if not self.Controls.MousePressed then
1061 | if IsDisabledControlJustPressed(0, 24) then
1062 | Citizen.CreateThread(function()
1063 | local _ExtraX, _ExtraY = ExtraX, ExtraY
1064 | self.Controls.MousePressed = true
1065 | if #self.Items > self.Pagination.Total + 1 then
1066 | self:GoUpOverflow()
1067 | else
1068 | self:GoUp()
1069 | end
1070 | Citizen.Wait(175)
1071 | while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_ExtraX, _ExtraY, 431 + self.WidthOffset, 18) do
1072 | if #self.Items > self.Pagination.Total + 1 then
1073 | self:GoUpOverflow()
1074 | else
1075 | self:GoUp()
1076 | end
1077 | Citizen.Wait(125)
1078 | end
1079 | self.Controls.MousePressed = false
1080 | end)
1081 | end
1082 | end
1083 | else
1084 | self.Extra.Up:Colour(0, 0, 0, 200)
1085 | end
1086 |
1087 | if IsMouseInBounds(ExtraX, ExtraY + 18, 431 + self.WidthOffset, 18) then
1088 | self.Extra.Down:Colour(30, 30, 30, 255)
1089 | if not self.Controls.MousePressed then
1090 | if IsDisabledControlJustPressed(0, 24) then
1091 | Citizen.CreateThread(function()
1092 | local _ExtraX, _ExtraY = ExtraX, ExtraY
1093 | self.Controls.MousePressed = true
1094 | if #self.Items > self.Pagination.Total + 1 then
1095 | self:GoDownOverflow()
1096 | else
1097 | self:GoDown()
1098 | end
1099 | Citizen.Wait(175)
1100 | while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_ExtraX, _ExtraY + 18, 431 + self.WidthOffset, 18) do
1101 | if #self.Items > self.Pagination.Total + 1 then
1102 | self:GoDownOverflow()
1103 | else
1104 | self:GoDown()
1105 | end
1106 | Citizen.Wait(125)
1107 | end
1108 | self.Controls.MousePressed = false
1109 | end)
1110 | end
1111 | end
1112 | else
1113 | self.Extra.Down:Colour(0, 0, 0, 200)
1114 | end
1115 | end
1116 |
1117 | function UIMenu:AddInstructionButton(button)
1118 | if type(button) == "table" and #button == 2 then
1119 | table.insert(self.InstructionalButtons, button)
1120 | end
1121 | end
1122 |
1123 | function UIMenu:RemoveInstructionButton(button)
1124 | if type(button) == "table" then
1125 | for i = 1, #self.InstructionalButtons do
1126 | if button == self.InstructionalButtons[i] then
1127 | table.remove(self.InstructionalButtons, i)
1128 | break
1129 | end
1130 | end
1131 | else
1132 | if tonumber(button) then
1133 | if self.InstructionalButtons[tonumber(button)] then
1134 | table.remove(self.InstructionalButtons, tonumber(button))
1135 | end
1136 | end
1137 | end
1138 | end
1139 |
1140 | function UIMenu:AddEnabledControl(Inputgroup, Control, Controller)
1141 | if tonumber(Inputgroup) and tonumber(Control) then
1142 | table.insert(self.Settings.EnabledControls[(Controller and "Controller" or "Keyboard")], {Inputgroup, Control})
1143 | end
1144 | end
1145 |
1146 | function UIMenu:RemoveEnabledControl(Inputgroup, Control, Controller)
1147 | local Type = (Controller and "Controller" or "Keyboard")
1148 | for Index = 1, #self.Settings.EnabledControls[Type] do
1149 | if Inputgroup == self.Settings.EnabledControls[Type][Index][1] and Control == self.Settings.EnabledControls[Type][Index][2] then
1150 | table.remove(self.Settings.EnabledControls[Type], Index)
1151 | break
1152 | end
1153 | end
1154 | end
1155 |
1156 | function UIMenu:UpdateScaleform()
1157 | if not self._Visible or not self.Settings.InstructionalButtons then
1158 | return
1159 | end
1160 |
1161 | PushScaleformMovieFunction(self.InstructionalScaleform, "CLEAR_ALL")
1162 | PopScaleformMovieFunction()
1163 |
1164 | PushScaleformMovieFunction(self.InstructionalScaleform, "TOGGLE_MOUSE_BUTTONS")
1165 | PushScaleformMovieFunctionParameterInt(0)
1166 | PopScaleformMovieFunction()
1167 |
1168 | PushScaleformMovieFunction(self.InstructionalScaleform, "CREATE_CONTAINER")
1169 | PopScaleformMovieFunction()
1170 |
1171 | PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT")
1172 | PushScaleformMovieFunctionParameterInt(0)
1173 | PushScaleformMovieFunctionParameterString(GetControlInstructionalButton(2, 176, 0))
1174 | PushScaleformMovieFunctionParameterString("Select")
1175 | PopScaleformMovieFunction()
1176 |
1177 | if self.Controls.Back.Enabled then
1178 | PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT")
1179 | PushScaleformMovieFunctionParameterInt(1)
1180 | PushScaleformMovieFunctionParameterString(GetControlInstructionalButton(2, 177, 0))
1181 | PushScaleformMovieFunctionParameterString("Back")
1182 | PopScaleformMovieFunction()
1183 | end
1184 |
1185 | local count = 2
1186 |
1187 | for i = 1, #self.InstructionalButtons do
1188 | if self.InstructionalButtons[i] then
1189 | if #self.InstructionalButtons[i] == 2 then
1190 | PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT")
1191 | PushScaleformMovieFunctionParameterInt(count)
1192 | PushScaleformMovieFunctionParameterString(self.InstructionalButtons[i][1])
1193 | PushScaleformMovieFunctionParameterString(self.InstructionalButtons[i][2])
1194 | PopScaleformMovieFunction()
1195 | count = count + 1
1196 | end
1197 | end
1198 | end
1199 |
1200 | PushScaleformMovieFunction(self.InstructionalScaleform, "DRAW_INSTRUCTIONAL_BUTTONS")
1201 | PushScaleformMovieFunctionParameterInt(-1)
1202 | PopScaleformMovieFunction()
1203 | end
1204 |
--------------------------------------------------------------------------------
/NativeUI from Frazzle/Utils.lua:
--------------------------------------------------------------------------------
1 | function GetResolution()
2 | local W, H = GetActiveScreenResolution()
3 | if (W/H) > 3.5 then
4 | return GetScreenResolution()
5 | else
6 | return W, H
7 | end
8 | end
9 |
10 | function FormatXWYH(Value, Value2)
11 | return Value/1920, Value2/1080
12 | end
13 |
14 | function math.round(num, numDecimalPlaces)
15 | return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
16 | end
17 |
18 | function tobool(input)
19 | if input == "true" or tonumber(input) == 1 or input == true then
20 | return true
21 | else
22 | return false
23 | end
24 | end
25 |
26 | function string.split(inputstr, sep)
27 | if sep == nil then
28 | sep = "%s"
29 | end
30 | local t={} ; i=1
31 | for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
32 | t[i] = str
33 | i = i + 1
34 | end
35 |
36 | return t
37 | end
38 |
39 | function string.starts(String, Start)
40 | return string.sub(String, 1, string.len(Start)) == Start
41 | end
42 |
43 | function IsMouseInBounds(X, Y, Width, Height)
44 | local MX, MY = math.round(GetControlNormal(0, 239) * 1920), math.round(GetControlNormal(0, 240) * 1080)
45 | MX, MY = FormatXWYH(MX, MY)
46 | X, Y = FormatXWYH(X, Y)
47 | Width, Height = FormatXWYH(Width, Height)
48 | return (MX >= X and MX <= X + Width) and (MY > Y and MY < Y + Height)
49 | end
50 |
51 | function GetSafeZoneBounds()
52 | local SafeSize = GetSafeZoneSize()
53 | SafeSize = math.round(SafeSize, 2)
54 | SafeSize = (SafeSize * 100) - 90
55 | SafeSize = 10 - SafeSize
56 |
57 | local W, H = 1920, 1080
58 |
59 | return {X = math.round(SafeSize * ((W/H) * 5.4)), Y = math.round(SafeSize * 5.4)}
60 | end
61 |
62 | function Controller()
63 | return not IsInputDisabled(2)
64 | end
65 |
66 | --[[
67 |
68 | function UIMenu:ProcessMouse()
69 | if not self._Visible or self.JustOpened or #self.Items == 0 or tobool(Controller()) or not self.Settings.MouseControlsEnabled then
70 | EnableControlAction(0, 2, true)
71 | EnableControlAction(0, 1, true)
72 | EnableControlAction(0, 25, true)
73 | EnableControlAction(0, 24, true)
74 | if self.Dirty then
75 | for _, Item in pairs(self.Items) do
76 | if Item:Hovered() then
77 | Item:Hovered(false)
78 | end
79 | end
80 | end
81 | return
82 | end
83 |
84 | local SafeZone = GetSafeZoneBounds()
85 |
86 | local Limit = #self.Items - 1
87 | local Counter = 0
88 |
89 | ShowCursorThisFrame()
90 |
91 | if #self.Items > self.Pagination.Total + 1 then
92 | Limit = self.Pagination.Max
93 | end
94 |
95 | if IsMouseInBounds(0, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then
96 | SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() + 5)
97 | SetCursorSprite(6)
98 | elseif IsMouseInBounds(GetScreenResolutionMaintainRatio().Width - 30, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then
99 | SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() - 5)
100 | SetCursorSprite(7)
101 | elseif self.Settings.MouseEdgeEnabled then
102 | SetCursorSprite(1)
103 | end
104 |
105 | for i = self.Pagination.Min + 1, Limit, 1 do
106 | local X, Y = self.Position.X, self.Position.Y + 144 - 37 + self.Subtitle.ExtraY + (Counter * 38)
107 | local Width, Height = 431 + self.WidthOffset, 38
108 | local Item = self.Items[i]
109 | local Type, SubType = Item()
110 |
111 | DrawRectangle(X, Y, Width, Height, 255, 0, 0, 150)
112 | if SubType == "UIMenuListItem" or SubType == "UIMenuSliderItem" then
113 | DrawRectangle(Item.LeftArrow.X, Item.LeftArrow.Y, Item.LeftArrow.Width, Item.LeftArrow.Height, 0, 255, 0, 150)
114 | DrawRectangle(Item.RightArrow.X, Item.RightArrow.Y, Item.RightArrow.Width, Item.RightArrow.Height, 0, 255, 0, 150)
115 | end
116 |
117 | if IsMouseInBounds(X, Y, Width, Height) then
118 | Item:Hovered(true)
119 | if IsDisabledControlJustPressed(0, 24) then
120 | if Item:Selected() and Item:Enabled() then
121 | if SubType == "UIMenuListItem" then
122 | if IsMouseInBounds(Item.LeftArrow.X, Item.LeftArrow.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
123 | self:GoLeft()
124 | elseif not IsMouseInBounds(Item.RightArrow.X, Item.RightArrow.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
125 | self:SelectItem()
126 | end
127 | if IsMouseInBounds(Item.RightArrow.X, Item.RightArrow.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
128 | self:GoRight()
129 | elseif not IsMouseInBounds(Item.LeftArrow.X, Item.LeftArrow.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
130 | self:SelectItem()
131 | end
132 | elseif SubType == "UIMenuSliderItem" then
133 | if IsMouseInBounds(Item.LeftArrow.X, Item.LeftArrow.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
134 | self:GoLeft()
135 | elseif not IsMouseInBounds(Item.RightArrow.X, Item.RightArrow.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
136 | self:SelectItem()
137 | end
138 | if IsMouseInBounds(Item.RightArrow.X, Item.RightArrow.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
139 | self:GoRight()
140 | elseif not IsMouseInBounds(Item.LeftArrow.X, Item.LeftArrow.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
141 | self:SelectItem()
142 | end
143 | else
144 | self:SelectItem()
145 | end
146 | elseif not Item:Selected() then
147 | self:CurrentSelection(i-1)
148 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
149 | self.OnIndexChange(self, self:CurrentSelection())
150 | self.ReDraw = true
151 | elseif not Item:Enabled() and Item:Selected() then
152 | PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
153 | end
154 | end
155 | else
156 | Item:Hovered(false)
157 | end
158 | Counter = Counter + 1
159 | end
160 |
161 | local ExtraX, ExtraY = self.Position.X, 144 + 38 * (self.Pagination.Total + 1) + self.Position.Y - 37 + self.Subtitle.ExtraY
162 |
163 | if #self.Items <= self.Pagination.Total + 1 then return end
164 |
165 | if IsMouseInBounds(ExtraX, ExtraY, 431 + self.WidthOffset, 18) then
166 | self.Extra.Up:Colour(30, 30, 30, 255)
167 | if IsDisabledControlJustPressed(0, 24) then
168 | if #self.Items > self.Pagination.Total + 1 then
169 | self:GoUpOverflow()
170 | else
171 | self:GoUp()
172 | end
173 | end
174 | else
175 | self.Extra.Up:Colour(0, 0, 0, 200)
176 | end
177 |
178 | if IsMouseInBounds(ExtraX, ExtraY + 18, 431 + self.WidthOffset, 18) then
179 | self.Extra.Down:Colour(30, 30, 30, 255)
180 | if IsDisabledControlJustReleased(0, 24) then
181 | if #self.Items > self.Pagination.Total + 1 then
182 | self:GoDownOverflow()
183 | else
184 | self:GoDown()
185 | end
186 | end
187 | else
188 | self.Extra.Down:Colour(0, 0, 0, 200)
189 | end
190 | end
191 | --]]
--------------------------------------------------------------------------------
/NativeUI from Frazzle/__resource.lua:
--------------------------------------------------------------------------------
1 | resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9'
2 |
3 | --[[
4 | --All items unpacked
5 |
6 | client_scripts {
7 | "Utils.lua",
8 | "elements/UIResRectangle.lua",
9 | "elements/UIResText.lua",
10 | "elements/Sprite.lua",
11 | "elements/StringMeasurer.lua",
12 | "elements/Badge.lua",
13 | "elements/Colours.lua",
14 | "items/UIMenuItem.lua",
15 | "items/UIMenuCheckboxItem.lua",
16 | "items/UIMenuListItem.lua",
17 | "items/UIMenuSliderItem.lua",
18 | "items/UIMenuColouredItem.lua",
19 | "items/UIMenuprogressItem.lua",
20 | "windows/UIMenuHeritageWindow.lua",
21 | "panels/UIMenuGridPanel.lua",
22 | "panels/UIMenuColourPanel.lua",
23 | "panels/UIMenuPercentagePanel.lua",
24 | "UIMenu.lua",
25 | "MenuPool.lua",
26 | "MenuExample.lua",
27 | }
28 |
29 | --All items packed
30 | --]]
31 |
32 | client_script "NativeUI.lua"
--------------------------------------------------------------------------------
/NativeUI from Frazzle/elements/Badge.lua:
--------------------------------------------------------------------------------
1 | BadgeStyle = {
2 | None = 0,
3 | BronzeMedal = 1,
4 | GoldMedal = 2,
5 | SilverMedal = 3,
6 | Alert = 4,
7 | Crown = 5,
8 | Ammo = 6,
9 | Armour = 7,
10 | Barber = 8,
11 | Clothes = 9,
12 | Franklin = 10,
13 | Bike = 11,
14 | Car = 12,
15 | Gun = 13,
16 | Heart = 14,
17 | Makeup = 15,
18 | Mask = 16,
19 | Michael = 17,
20 | Star = 18,
21 | Tattoo = 19,
22 | Trevor = 20,
23 | Lock = 21,
24 | Tick = 22
25 | }
26 |
27 | BadgeTexture = {
28 | [0] = function()
29 | return ""
30 | end,
31 | [1] = function()
32 | return "mp_medal_bronze"
33 | end,
34 | [2] = function()
35 | return "mp_medal_gold"
36 | end,
37 | [3] = function()
38 | return "medal_silver"
39 | end,
40 | [4] = function()
41 | return "mp_alerttriangle"
42 | end,
43 | [5] = function()
44 | return "mp_hostcrown"
45 | end,
46 | [6] = function(Selected)
47 | if Selected then
48 | return "shop_ammo_icon_b"
49 | else
50 | return "shop_ammo_icon_a"
51 | end
52 | end,
53 | [7] = function(Selected)
54 | if Selected then
55 | return "shop_armour_icon_b"
56 | else
57 | return "shop_armour_icon_a"
58 | end
59 | end,
60 | [8] = function(Selected)
61 | if Selected then
62 | return "shop_barber_icon_b"
63 | else
64 | return "shop_barber_icon_a"
65 | end
66 | end,
67 | [9] = function(Selected)
68 | if Selected then
69 | return "shop_clothing_icon_b"
70 | else
71 | return "shop_clothing_icon_a"
72 | end
73 | end,
74 | [10] = function(Selected)
75 | if Selected then
76 | return "shop_franklin_icon_b"
77 | else
78 | return "shop_franklin_icon_a"
79 | end
80 | end,
81 | [11] = function(Selected)
82 | if Selected then
83 | return "shop_garage_bike_icon_b"
84 | else
85 | return "shop_garage_bike_icon_a"
86 | end
87 | end,
88 | [12] = function(Selected)
89 | if Selected then
90 | return "shop_garage_icon_b"
91 | else
92 | return "shop_garage_icon_a"
93 | end
94 | end,
95 | [13] = function(Selected)
96 | if Selected then
97 | return "shop_gunclub_icon_b"
98 | else
99 | return "shop_gunclub_icon_a"
100 | end
101 | end,
102 | [14] = function(Selected)
103 | if Selected then
104 | return "shop_health_icon_b"
105 | else
106 | return "shop_health_icon_a"
107 | end
108 | end,
109 | [15] = function(Selected)
110 | if Selected then
111 | return "shop_makeup_icon_b"
112 | else
113 | return "shop_makeup_icon_a"
114 | end
115 | end,
116 | [16] = function(Selected)
117 | if Selected then
118 | return "shop_mask_icon_b"
119 | else
120 | return "shop_mask_icon_a"
121 | end
122 | end,
123 | [17] = function(Selected)
124 | if Selected then
125 | return "shop_michael_icon_b"
126 | else
127 | return "shop_michael_icon_a"
128 | end
129 | end,
130 | [18] = function()
131 | return "shop_new_star"
132 | end,
133 | [19] = function(Selected)
134 | if Selected then
135 | return "shop_tattoos_icon_b"
136 | else
137 | return "shop_tattoos_icon_a"
138 | end
139 | end,
140 | [20] = function(Selected)
141 | if Selected then
142 | return "shop_trevor_icon_b"
143 | else
144 | return "shop_trevor_icon_a"
145 | end
146 | end,
147 | [21] = function()
148 | return "shop_lock"
149 | end,
150 | [22] = function()
151 | return "shop_tick_icon"
152 | end,
153 | }
154 |
155 | BadgeDictionary = {
156 | [0] = function(Selected)
157 | if Selected then
158 | return "commonmenu"
159 | else
160 | return "commonmenu"
161 | end
162 | end,
163 | }
164 |
165 | BadgeColour = {
166 | [5] = function(Selected)
167 | if Selected then
168 | return 0, 0, 0, 255
169 | else
170 | return 255, 255, 255, 255
171 | end
172 | end,
173 | [21] = function(Selected)
174 | if Selected then
175 | return 0, 0, 0, 255
176 | else
177 | return 255, 255, 255, 255
178 | end
179 | end,
180 | [22] = function(Selected)
181 | if Selected then
182 | return 0, 0, 0, 255
183 | else
184 | return 255, 255, 255, 255
185 | end
186 | end,
187 | }
188 |
189 | function GetBadgeTexture(Badge, Selected)
190 | if BadgeTexture[Badge] then
191 | return BadgeTexture[Badge](Selected)
192 | else
193 | return ""
194 | end
195 | end
196 |
197 | function GetBadgeDictionary(Badge, Selected)
198 | if BadgeDictionary[Badge] then
199 | return BadgeDictionary[Badge](Selected)
200 | else
201 | return "commonmenu"
202 | end
203 | end
204 |
205 | function GetBadgeColour(Badge, Selected)
206 | if BadgeColour[Badge] then
207 | return BadgeColour[Badge](Selected)
208 | else
209 | return 255, 255, 255, 255
210 | end
211 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/elements/Colours.lua:
--------------------------------------------------------------------------------
1 | Colours = {
2 | PureWhite = {255, 255, 255, 255},
3 | White = {240, 240, 240, 255},
4 | Black = {0, 0, 0, 255},
5 | Grey = {155, 155, 155, 255},
6 | GreyLight = {205, 205, 205, 255},
7 | GreyDark = {77, 77, 77, 255},
8 | Red = {224, 50, 50, 255},
9 | RedLight = {240, 153, 153, 255},
10 | RedDark = {112, 25, 25, 255},
11 | Blue = {93, 182, 229, 255},
12 | BlueLight = {174, 219, 242, 255},
13 | BlueDark = {47, 92, 115, 255},
14 | Yellow = {240, 200, 80, 255},
15 | YellowLight = {254, 235, 169, 255},
16 | YellowDark = {126, 107, 41, 255},
17 | Orange = {255, 133, 85, 255},
18 | OrangeLight = {255, 194, 170, 255},
19 | OrangeDark = {127, 66, 42, 255},
20 | Green = {114, 204, 114, 255},
21 | GreenLight = {185, 230, 185, 255},
22 | GreenDark = {57, 102, 57, 255},
23 | Purple = {132, 102, 226, 255},
24 | PurpleLight = {192, 179, 239, 255},
25 | PurpleDark = {67, 57, 111, 255},
26 | Pink = {203, 54, 148, 255},
27 | RadarHealth = {53, 154, 71, 255},
28 | RadarArmour = {93, 182, 229, 255},
29 | RadarDamage = {235, 36, 39, 255},
30 | NetPlayer1 = {194, 80, 80, 255},
31 | NetPlayer2 = {156, 110, 175, 255},
32 | NetPlayer3 = {255, 123, 196, 255},
33 | NetPlayer4 = {247, 159, 123, 255},
34 | NetPlayer5 = {178, 144, 132, 255},
35 | NetPlayer6 = {141, 206, 167, 255},
36 | NetPlayer7 = {113, 169, 175, 255},
37 | NetPlayer8 = {211, 209, 231, 255},
38 | NetPlayer9 = {144, 127, 153, 255},
39 | NetPlayer10 = {106, 196, 191, 255},
40 | NetPlayer11 = {214, 196, 153, 255},
41 | NetPlayer12 = {234, 142, 80, 255},
42 | NetPlayer13 = {152, 203, 234, 255},
43 | NetPlayer14 = {178, 98, 135, 255},
44 | NetPlayer15 = {144, 142, 122, 255},
45 | NetPlayer16 = {166, 117, 94, 255},
46 | NetPlayer17 = {175, 168, 168, 255},
47 | NetPlayer18 = {232, 142, 155, 255},
48 | NetPlayer19 = {187, 214, 91, 255},
49 | NetPlayer20 = {12, 123, 86, 255},
50 | NetPlayer21 = {123, 196, 255, 255},
51 | NetPlayer22 = {171, 60, 230, 255},
52 | NetPlayer23 = {206, 169, 13, 255},
53 | NetPlayer24 = {71, 99, 173, 255},
54 | NetPlayer25 = {42, 166, 185, 255},
55 | NetPlayer26 = {186, 157, 125, 255},
56 | NetPlayer27 = {201, 225, 255, 255},
57 | NetPlayer28 = {240, 240, 150, 255},
58 | NetPlayer29 = {237, 140, 161, 255},
59 | NetPlayer30 = {249, 138, 138, 255},
60 | NetPlayer31 = {252, 239, 166, 255},
61 | NetPlayer32 = {240, 240, 240, 255},
62 | SimpleBlipDefault = {159, 201, 166, 255},
63 | MenuBlue = {140, 140, 140, 255},
64 | MenuGreyLight = {140, 140, 140, 255},
65 | MenuBlueExtraDark = {40, 40, 40, 255},
66 | MenuYellow = {240, 160, 0, 255},
67 | MenuYellowDark = {240, 160, 0, 255},
68 | MenuGreen = {240, 160, 0, 255},
69 | MenuGrey = {140, 140, 140, 255},
70 | MenuGreyDark = {60, 60, 60, 255},
71 | MenuHighlight = {30, 30, 30, 255},
72 | MenuStandard = {140, 140, 140, 255},
73 | MenuDimmed = {75, 75, 75, 255},
74 | MenuExtraDimmed = {50, 50, 50, 255},
75 | BriefTitle = {95, 95, 95, 255},
76 | MidGreyMp = {100, 100, 100, 255},
77 | NetPlayer1Dark = {93, 39, 39, 255},
78 | NetPlayer2Dark = {77, 55, 89, 255},
79 | NetPlayer3Dark = {124, 62, 99, 255},
80 | NetPlayer4Dark = {120, 80, 80, 255},
81 | NetPlayer5Dark = {87, 72, 66, 255},
82 | NetPlayer6Dark = {74, 103, 83, 255},
83 | NetPlayer7Dark = {60, 85, 88, 255},
84 | NetPlayer8Dark = {105, 105, 64, 255},
85 | NetPlayer9Dark = {72, 63, 76, 255},
86 | NetPlayer10Dark = {53, 98, 95, 255},
87 | NetPlayer11Dark = {107, 98, 76, 255},
88 | NetPlayer12Dark = {117, 71, 40, 255},
89 | NetPlayer13Dark = {76, 101, 117, 255},
90 | NetPlayer14Dark = {65, 35, 47, 255},
91 | NetPlayer15Dark = {72, 71, 61, 255},
92 | NetPlayer16Dark = {85, 58, 47, 255},
93 | NetPlayer17Dark = {87, 84, 84, 255},
94 | NetPlayer18Dark = {116, 71, 77, 255},
95 | NetPlayer19Dark = {93, 107, 45, 255},
96 | NetPlayer20Dark = {6, 61, 43, 255},
97 | NetPlayer21Dark = {61, 98, 127, 255},
98 | NetPlayer22Dark = {85, 30, 115, 255},
99 | NetPlayer23Dark = {103, 84, 6, 255},
100 | NetPlayer24Dark = {35, 49, 86, 255},
101 | NetPlayer25Dark = {21, 83, 92, 255},
102 | NetPlayer26Dark = {93, 98, 62, 255},
103 | NetPlayer27Dark = {100, 112, 127, 255},
104 | NetPlayer28Dark = {120, 120, 75, 255},
105 | NetPlayer29Dark = {152, 76, 93, 255},
106 | NetPlayer30Dark = {124, 69, 69, 255},
107 | NetPlayer31Dark = {10, 43, 50, 255},
108 | NetPlayer32Dark = {95, 95, 10, 255},
109 | Bronze = {180, 130, 97, 255},
110 | Silver = {150, 153, 161, 255},
111 | Gold = {214, 181, 99, 255},
112 | Platinum = {166, 221, 190, 255},
113 | Gang1 = {29, 100, 153, 255},
114 | Gang2 = {214, 116, 15, 255},
115 | Gang3 = {135, 125, 142, 255},
116 | Gang4 = {229, 119, 185, 255},
117 | SameCrew = {252, 239, 166, 255},
118 | Freemode = {45, 110, 185, 255},
119 | PauseBg = {0, 0, 0, 255},
120 | Friendly = {93, 182, 229, 255},
121 | Enemy = {194, 80, 80, 255},
122 | Location = {240, 200, 80, 255},
123 | Pickup = {114, 204, 114, 255},
124 | PauseSingleplayer = {114, 204, 114, 255},
125 | FreemodeDark = {22, 55, 92, 255},
126 | InactiveMission = {154, 154, 154, 255},
127 | Damage = {194, 80, 80, 255},
128 | PinkLight = {252, 115, 201, 255},
129 | PmMitemHighlight = {252, 177, 49, 255},
130 | ScriptVariable = {0, 0, 0, 255},
131 | Yoga = {109, 247, 204, 255},
132 | Tennis = {241, 101, 34, 255},
133 | Golf = {214, 189, 97, 255},
134 | ShootingRange = {112, 25, 25, 255},
135 | FlightSchool = {47, 92, 115, 255},
136 | NorthBlue = {93, 182, 229, 255},
137 | SocialClub = {234, 153, 28, 255},
138 | PlatformBlue = {11, 55, 123, 255},
139 | PlatformGreen = {146, 200, 62, 255},
140 | PlatformGrey = {234, 153, 28, 255},
141 | FacebookBlue = {66, 89, 148, 255},
142 | IngameBg = {0, 0, 0, 255},
143 | Darts = {114, 204, 114, 255},
144 | Waypoint = {164, 76, 242, 255},
145 | Michael = {101, 180, 212, 255},
146 | Franklin = {171, 237, 171, 255},
147 | Trevor = {255, 163, 87, 255},
148 | GolfP1 = {240, 240, 240, 255},
149 | GolfP2 = {235, 239, 30, 255},
150 | GolfP3 = {255, 149, 14, 255},
151 | GolfP4 = {246, 60, 161, 255},
152 | WaypointLight = {210, 166, 249, 255},
153 | WaypointDark = {82, 38, 121, 255},
154 | PanelLight = {0, 0, 0, 255},
155 | MichaelDark = {72, 103, 116, 255},
156 | FranklinDark = {85, 118, 85, 255},
157 | TrevorDark = {127, 81, 43, 255},
158 | ObjectiveRoute = {240, 200, 80, 255},
159 | PausemapTint = {0, 0, 0, 255},
160 | PauseDeselect = {100, 100, 100, 255},
161 | PmWeaponsPurchasable = {45, 110, 185, 255},
162 | PmWeaponsLocked = {240, 240, 240, 255},
163 | ScreenBg = {0, 0, 0, 255},
164 | Chop = {224, 50, 50, 255},
165 | PausemapTintHalf = {0, 0, 0, 255},
166 | NorthBlueOfficial = {0, 71, 133, 255},
167 | ScriptVariable2 = {0, 0, 0, 255},
168 | H = {33, 118, 37, 255},
169 | HDark = {37, 102, 40, 255},
170 | T = {234, 153, 28, 255},
171 | TDark = {225, 140, 8, 255},
172 | HShard = {20, 40, 0, 255},
173 | ControllerMichael = {48, 255, 255, 255},
174 | ControllerFranklin = {48, 255, 0, 255},
175 | ControllerTrevor = {176, 80, 0, 255},
176 | ControllerChop = {127, 0, 0, 255},
177 | VideoEditorVideo = {53, 166, 224, 255},
178 | VideoEditorAudio = {162, 79, 157, 255},
179 | VideoEditorText = {104, 192, 141, 255},
180 | HbBlue = {29, 100, 153, 255},
181 | HbYellow = {234, 153, 28, 255},
182 | VideoEditorScore = {240, 160, 1, 255},
183 | VideoEditorAudioFadeout = {59, 34, 57, 255},
184 | VideoEditorTextFadeout = {41, 68, 53, 255},
185 | VideoEditorScoreFadeout = {82, 58, 10, 255},
186 | HeistBackground = {37, 102, 40, 255},
187 | VideoEditorAmbient = {240, 200, 80, 255},
188 | VideoEditorAmbientFadeout = {80, 70, 34, 255},
189 | Gb = {255, 133, 85, 255},
190 | G = {255, 194, 170, 255},
191 | B = {255, 133, 85, 255},
192 | LowFlow = {240, 200, 80, 255},
193 | LowFlowDark = {126, 107, 41, 255},
194 | G1 = {247, 159, 123, 255},
195 | G2 = {226, 134, 187, 255},
196 | G3 = {239, 238, 151, 255},
197 | G4 = {113, 169, 175, 255},
198 | G5 = {160, 140, 193, 255},
199 | G6 = {141, 206, 167, 255},
200 | G7 = {181, 214, 234, 255},
201 | G8 = {178, 144, 132, 255},
202 | G9 = {0, 132, 114, 255},
203 | G10 = {216, 85, 117, 255},
204 | G11 = {30, 100, 152, 255},
205 | G12 = {43, 181, 117, 255},
206 | G13 = {233, 141, 79, 255},
207 | G14 = {137, 210, 215, 255},
208 | G15 = {134, 125, 141, 255},
209 | Adversary = {109, 34, 33, 255},
210 | DegenRed = {255, 0, 0, 255},
211 | DegenYellow = {255, 255, 0, 255},
212 | DegenGreen = {0, 255, 0, 255},
213 | DegenCyan = {0, 255, 255, 255},
214 | DegenBlue = {0, 0, 255, 255},
215 | DegenMagenta = {255, 0, 255, 255},
216 | Stunt1 = {38, 136, 234, 255},
217 | Stunt2 = {224, 50, 50, 255},
218 | }
--------------------------------------------------------------------------------
/NativeUI from Frazzle/elements/Sprite.lua:
--------------------------------------------------------------------------------
1 | Sprite = setmetatable({}, Sprite)
2 | Sprite.__index = Sprite
3 | Sprite.__call = function() return "Sprite" end
4 |
5 | function Sprite.New(TxtDictionary, TxtName, X, Y, Width, Height, Heading, R, G, B, A)
6 | local _Sprite = {
7 | TxtDictionary = tostring(TxtDictionary),
8 | TxtName = tostring(TxtName),
9 | X = tonumber(X) or 0,
10 | Y = tonumber(Y) or 0,
11 | Width = tonumber(Width) or 0,
12 | Height = tonumber(Height) or 0,
13 | Heading = tonumber(Heading) or 0,
14 | _Colour = {R = tonumber(R) or 255, G = tonumber(G) or 255, B = tonumber(B) or 255, A = tonumber(A) or 255},
15 | }
16 | return setmetatable(_Sprite, Sprite)
17 | end
18 |
19 | function Sprite:Position(X, Y)
20 | if tonumber(X) and tonumber(Y) then
21 | self.X = tonumber(X)
22 | self.Y = tonumber(Y)
23 | else
24 | return {X = self.X, Y = self.Y}
25 | end
26 | end
27 |
28 | function Sprite:Size(Width, Height)
29 | if tonumber(Width) and tonumber(Width) then
30 | self.Width = tonumber(Width)
31 | self.Height = tonumber(Height)
32 | else
33 | return {Width = self.Width, Height = self.Height}
34 | end
35 | end
36 |
37 | function Sprite:Colour(R, G, B, A)
38 | if tonumber(R) or tonumber(G) or tonumber(B) or tonumber(A) then
39 | self._Colour.R = tonumber(R) or 255
40 | self._Colour.B = tonumber(B) or 255
41 | self._Colour.G = tonumber(G) or 255
42 | self._Colour.A = tonumber(A) or 255
43 | else
44 | return self._Colour
45 | end
46 | end
47 |
48 | function Sprite:Draw()
49 | if not HasStreamedTextureDictLoaded(self.TxtDictionary) then
50 | RequestStreamedTextureDict(self.TxtDictionary, true)
51 | end
52 | local Position = self:Position()
53 | local Size = self:Size()
54 | Size.Width, Size.Height = FormatXWYH(Size.Width, Size.Height)
55 | Position.X, Position.Y = FormatXWYH(Position.X, Position.Y)
56 | DrawSprite(self.TxtDictionary, self.TxtName, Position.X + Size.Width * 0.5, Position.Y + Size.Height * 0.5, Size.Width, Size.Height, self.Heading, self._Colour.R, self._Colour.G, self._Colour.B, self._Colour.A)
57 | end
58 |
59 | function DrawTexture(TxtDictionary, TxtName, X, Y, Width, Height, Heading, R, G, B, A)
60 | if not HasStreamedTextureDictLoaded(tostring(TxtDictionary) or "") then
61 | RequestStreamedTextureDict(tostring(TxtDictionary) or "", true)
62 | end
63 | X, Y, Width, Height = X or 0, Y or 0, Width or 0, Height or 0
64 | X, Y = FormatXWYH(X, Y)
65 | Width, Height = FormatXWYH(Width, Height)
66 | DrawSprite(tostring(TxtDictionary) or "", tostring(TxtName) or "", X + Width * 0.5, Y + Height * 0.5, Width, Height, tonumber(Heading) or 0, tonumber(R) or 255, tonumber(G) or 255, tonumber(B) or 255, tonumber(A) or 255)
67 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/elements/StringMeasurer.lua:
--------------------------------------------------------------------------------
1 | CharacterMap = {
2 | [' '] = 6,
3 | ['!'] = 6,
4 | ['"'] = 6,
5 | ['#'] = 11,
6 | ['$'] = 10,
7 | ['%'] = 17,
8 | ['&'] = 13,
9 | ['\\'] = 4,
10 | ['('] = 6,
11 | [')'] = 6,
12 | ['*'] = 7,
13 | ['+'] = 10,
14 | [','] = 4,
15 | ['-'] = 6,
16 | ['.'] = 4,
17 | ['/'] = 7,
18 | ['0'] = 12,
19 | ['1'] = 7,
20 | ['2'] = 11,
21 | ['3'] = 11,
22 | ['4'] = 11,
23 | ['5'] = 11,
24 | ['6'] = 12,
25 | ['7'] = 10,
26 | ['8'] = 11,
27 | ['9'] = 11,
28 | [':'] = 5,
29 | [';'] = 4,
30 | ['<'] = 9,
31 | ['='] = 9,
32 | ['>'] = 9,
33 | ['?'] = 10,
34 | ['@'] = 15,
35 | ['A'] = 12,
36 | ['B'] = 13,
37 | ['C'] = 14,
38 | ['D'] = 14,
39 | ['E'] = 12,
40 | ['F'] = 12,
41 | ['G'] = 15,
42 | ['H'] = 14,
43 | ['I'] = 5,
44 | ['J'] = 11,
45 | ['K'] = 13,
46 | ['L'] = 11,
47 | ['M'] = 16,
48 | ['N'] = 14,
49 | ['O'] = 16,
50 | ['P'] = 12,
51 | ['Q'] = 15,
52 | ['R'] = 13,
53 | ['S'] = 12,
54 | ['T'] = 11,
55 | ['U'] = 13,
56 | ['V'] = 12,
57 | ['W'] = 18,
58 | ['X'] = 11,
59 | ['Y'] = 11,
60 | ['Z'] = 12,
61 | ['['] = 6,
62 | [']'] = 6,
63 | ['^'] = 9,
64 | ['_'] = 18,
65 | ['`'] = 8,
66 | ['a'] = 11,
67 | ['b'] = 12,
68 | ['c'] = 11,
69 | ['d'] = 12,
70 | ['e'] = 12,
71 | ['f'] = 5,
72 | ['g'] = 13,
73 | ['h'] = 11,
74 | ['i'] = 4,
75 | ['j'] = 4,
76 | ['k'] = 10,
77 | ['l'] = 4,
78 | ['m'] = 18,
79 | ['n'] = 11,
80 | ['o'] = 12,
81 | ['p'] = 12,
82 | ['q'] = 12,
83 | ['r'] = 7,
84 | ['s'] = 9,
85 | ['t'] = 5,
86 | ['u'] = 11,
87 | ['v'] = 10,
88 | ['w'] = 14,
89 | ['x'] = 9,
90 | ['y'] = 10,
91 | ['z'] = 9,
92 | ['{'] = 6,
93 | ['|'] = 3,
94 | ['}'] = 6,
95 | }
96 |
97 | function MeasureString(str)
98 | local output = 0
99 | for i = 1, GetCharacterCount(str), 1 do
100 | if CharacterMap[string.sub(str, i, i)] then
101 | output = output + CharacterMap[string.sub(str, i, i)] + 1
102 | end
103 | end
104 | return output
105 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/elements/UIResRectangle.lua:
--------------------------------------------------------------------------------
1 | UIResRectangle = setmetatable({}, UIResRectangle)
2 | UIResRectangle.__index = UIResRectangle
3 | UIResRectangle.__call = function() return "Rectangle" end
4 |
5 | function UIResRectangle.New(X, Y, Width, Height, R, G, B, A)
6 | local _UIResRectangle = {
7 | X = tonumber(X) or 0,
8 | Y = tonumber(Y) or 0,
9 | Width = tonumber(Width) or 0,
10 | Height = tonumber(Height) or 0,
11 | _Colour = {R = tonumber(R) or 255, G = tonumber(G) or 255, B = tonumber(B) or 255, A = tonumber(A) or 255},
12 | }
13 | return setmetatable(_UIResRectangle, UIResRectangle)
14 | end
15 |
16 | function UIResRectangle:Position(X, Y)
17 | if tonumber(X) and tonumber(Y) then
18 | self.X = tonumber(X)
19 | self.Y = tonumber(Y)
20 | else
21 | return {X = self.X, Y = self.Y}
22 | end
23 | end
24 |
25 | function UIResRectangle:Size(Width, Height)
26 | if tonumber(Width) and tonumber(Height) then
27 | self.Width = tonumber(Width)
28 | self.Height = tonumber(Height)
29 | else
30 | return {Width = self.Width, Height = self.Height}
31 | end
32 | end
33 |
34 | function UIResRectangle:Colour(R, G, B, A)
35 | if tonumber(R) or tonumber(G) or tonumber(B) or tonumber(A) then
36 | self._Colour.R = tonumber(R) or 255
37 | self._Colour.B = tonumber(B) or 255
38 | self._Colour.G = tonumber(G) or 255
39 | self._Colour.A = tonumber(A) or 255
40 | else
41 | return self._Colour
42 | end
43 | end
44 |
45 | function UIResRectangle:Draw()
46 | local Position = self:Position()
47 | local Size = self:Size()
48 | Size.Width, Size.Height = FormatXWYH(Size.Width, Size.Height)
49 | Position.X, Position.Y = FormatXWYH(Position.X, Position.Y)
50 | DrawRect(Position.X + Size.Width * 0.5, Position.Y + Size.Height * 0.5, Size.Width, Size.Height, self._Colour.R, self._Colour.G, self._Colour.B, self._Colour.A)
51 | end
52 |
53 | function DrawRectangle(X, Y, Width, Height, R, G, B, A)
54 | X, Y, Width, Height = X or 0, Y or 0, Width or 0, Height or 0
55 | X, Y = FormatXWYH(X, Y)
56 | Width, Height = FormatXWYH(Width, Height)
57 | DrawRect(X + Width * 0.5, Y + Height * 0.5, Width, Height, tonumber(R) or 255, tonumber(G) or 255, tonumber(B) or 255, tonumber(A) or 255)
58 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/elements/UIResText.lua:
--------------------------------------------------------------------------------
1 | UIResText = setmetatable({}, UIResText)
2 | UIResText.__index = UIResText
3 | UIResText.__call = function() return "Text" end
4 |
5 | function GetCharacterCount(str)
6 | local characters = 0
7 | for c in str:gmatch("[%z\1-\127\194-\244][\128-\191]*") do
8 | local a = c:byte(1, -1)
9 | if a ~= nil then
10 | characters = characters + 1
11 | end
12 | end
13 | return characters
14 | end
15 |
16 | function GetByteCount(str)
17 | local bytes = 0
18 |
19 | for c in str:gmatch("[%z\1-\127\194-\244][\128-\191]*") do
20 | local a,b,c,d = c:byte(1, -1)
21 | if a ~= nil then
22 | bytes = bytes + 1
23 | end
24 | if b ~= nil then
25 | bytes = bytes + 1
26 | end
27 | if c ~= nil then
28 | bytes = bytes + 1
29 | end
30 | if d ~= nil then
31 | bytes = bytes + 1
32 | end
33 | end
34 | return bytes
35 | end
36 |
37 | function AddLongStringForAscii(str)
38 | local maxbytelength = 99
39 | for i = 0, GetCharacterCount(str), 99 do
40 | AddTextComponentSubstringPlayerName(string.sub(str, i, math.min(maxbytelength, GetCharacterCount(str) - i))) --needs changed
41 | end
42 | end
43 |
44 | function AddLongStringForUtf8(str)
45 | local maxbytelength = 99
46 | local bytecount = GetByteCount(str)
47 |
48 | if bytecount < maxbytelength then
49 | AddTextComponentSubstringPlayerName(str)
50 | return
51 | end
52 |
53 | local startIndex = 0
54 |
55 | for i = 0, GetCharacterCount(str), 1 do
56 | local length = i - startIndex
57 | if GetByteCount(string.sub(str, startIndex, length)) > maxbytelength then
58 | AddTextComponentSubstringPlayerName(string.sub(str, startIndex, length - 1))
59 | i = i - 1
60 | startIndex = startIndex + (length - 1)
61 | end
62 | end
63 | AddTextComponentSubstringPlayerName(string.sub(str, startIndex, GetCharacterCount(str) - startIndex))
64 | end
65 |
66 | function AddLongString(str)
67 | local bytecount = GetByteCount(str)
68 | if bytecount == GetCharacterCount(str) then
69 | AddLongStringForAscii(str)
70 | else
71 | AddLongStringForUtf8(str)
72 | end
73 | end
74 |
75 | function MeasureStringWidthNoConvert(str, font, scale)
76 | BeginTextCommandWidth("STRING")
77 | AddLongString(str)
78 | SetTextFont(font or 0)
79 | SetTextScale(1.0, scale or 0)
80 | return EndTextCommandGetWidth(true)
81 | end
82 |
83 | function MeasureStringWidth(str, font, scale)
84 | return MeasureStringWidthNoConvert(str, font, scale) * 1920
85 | end
86 |
87 | function UIResText.New(Text, X, Y, Scale, R, G, B, A, Font, Alignment, DropShadow, Outline, WordWrap)
88 | local _UIResText = {
89 | _Text = tostring(Text) or "",
90 | X = tonumber(X) or 0,
91 | Y = tonumber(Y) or 0,
92 | Scale = tonumber(Scale) or 0,
93 | _Colour = {R = tonumber(R) or 255, G = tonumber(G) or 255, B = tonumber(B) or 255, A = tonumber(A) or 255},
94 | Font = tonumber(Font) or 0,
95 | Alignment = Alignment or nil,
96 | DropShadow = Dropshadow or nil,
97 | Outline = Outline or nil,
98 | WordWrap = tonumber(WordWrap) or 0,
99 | }
100 | return setmetatable(_UIResText, UIResText)
101 | end
102 |
103 | function UIResText:Position(X, Y)
104 | if tonumber(X) and tonumber(Y) then
105 | self.X = tonumber(X)
106 | self.Y = tonumber(Y)
107 | else
108 | return {X = self.X, Y = self.Y}
109 | end
110 | end
111 |
112 | function UIResText:Colour(R, G, B, A)
113 | if tonumber(R) and tonumber(G) and tonumber(B) and tonumber(A) then
114 | self._Colour.R = tonumber(R)
115 | self._Colour.B = tonumber(B)
116 | self._Colour.G = tonumber(G)
117 | self._Colour.A = tonumber(A)
118 | else
119 | return self._Colour
120 | end
121 | end
122 |
123 | function UIResText:Text(Text)
124 | if tostring(Text) and Text ~= nil then
125 | self._Text = tostring(Text)
126 | else
127 | return self._Text
128 | end
129 | end
130 |
131 | function UIResText:Draw()
132 | local Position = self:Position()
133 | Position.X, Position.Y = FormatXWYH(Position.X, Position.Y)
134 |
135 | SetTextFont(self.Font)
136 | SetTextScale(1.0, self.Scale)
137 | SetTextColour(self._Colour.R, self._Colour.G, self._Colour.B, self._Colour.A)
138 |
139 | if self.DropShadow then
140 | SetTextDropShadow()
141 | end
142 | if self.Outline then
143 | SetTextOutline()
144 | end
145 |
146 | if self.Alignment ~= nil then
147 | if self.Alignment == 1 or self.Alignment == "Center" or self.Alignment == "Centre" then
148 | SetTextCentre(true)
149 | elseif self.Alignment == 2 or self.Alignment == "Right" then
150 | SetTextRightJustify(true)
151 | SetTextWrap(0, Position.X)
152 | end
153 | end
154 |
155 | if tonumber(self.WordWrap) then
156 | if tonumber(self.WordWrap) ~= 0 then
157 | SetTextWrap(Position.X, Position.X + (tonumber(self.WordWrap) / Resolution.Width))
158 | end
159 | end
160 |
161 | BeginTextCommandDisplayText("STRING")
162 | AddLongString(self._Text)
163 | EndTextCommandDisplayText(Position.X, Position.Y)
164 | end
165 |
166 | function RenderText(Text, X, Y, Font, Scale, R, G, B, A, Alignment, DropShadow, Outline, WordWrap)
167 | Text = tostring(Text)
168 | X, Y = FormatXWYH(X, Y)
169 | SetTextFont(Font or 0)
170 | SetTextScale(1.0, Scale or 0)
171 | SetTextColour(R or 255, G or 255, B or 255, A or 255)
172 |
173 | if DropShadow then
174 | SetTextDropShadow()
175 | end
176 | if Outline then
177 | SetTextOutline()
178 | end
179 |
180 | if Alignment ~= nil then
181 | if Alignment == 1 or Alignment == "Center" or Alignment == "Centre" then
182 | SetTextCentre(true)
183 | elseif Alignment == 2 or Alignment == "Right" then
184 | SetTextRightJustify(true)
185 | SetTextWrap(0, X)
186 | end
187 | end
188 |
189 | if tonumber(WordWrap) then
190 | if tonumber(WordWrap) ~= 0 then
191 | WordWrap, _ = FormatXWYH(WordWrap, 0)
192 | SetTextWrap(WordWrap, X - WordWrap)
193 | end
194 | end
195 |
196 | BeginTextCommandDisplayText("STRING")
197 | AddLongString(Text)
198 | EndTextCommandDisplayText(X, Y)
199 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/items/UIMenuCheckboxItem.lua:
--------------------------------------------------------------------------------
1 | UIMenuCheckboxItem = setmetatable({}, UIMenuCheckboxItem)
2 | UIMenuCheckboxItem.__index = UIMenuCheckboxItem
3 | UIMenuCheckboxItem.__call = function() return "UIMenuItem", "UIMenuCheckboxItem" end
4 |
5 | function UIMenuCheckboxItem.New(Text, Check, Description)
6 | local _UIMenuCheckboxItem = {
7 | Base = UIMenuItem.New(Text or "", Description or ""),
8 | CheckedSprite = Sprite.New("commonmenu", "shop_box_blank", 410, 95, 50, 50),
9 | Checked = tobool(Check),
10 | CheckboxEvent = function(menu, item, checked) end,
11 | }
12 | return setmetatable(_UIMenuCheckboxItem, UIMenuCheckboxItem)
13 | end
14 |
15 | function UIMenuCheckboxItem:SetParentMenu(Menu)
16 | if Menu() == "UIMenu" then
17 | self.Base.ParentMenu = Menu
18 | else
19 | return self.Base.ParentMenu
20 | end
21 | end
22 |
23 | function UIMenuCheckboxItem:Position(Y)
24 | if tonumber(Y) then
25 | self.Base:Position(Y)
26 | self.CheckedSprite:Position(380 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 138 + self.Base._Offset.Y)
27 | end
28 | end
29 |
30 | function UIMenuCheckboxItem:Selected(bool)
31 | if bool ~= nil then
32 | self.Base._Selected = tobool(bool)
33 | else
34 | return self.Base._Selected
35 | end
36 | end
37 |
38 | function UIMenuCheckboxItem:Hovered(bool)
39 | if bool ~= nil then
40 | self.Base._Hovered = tobool(bool)
41 | else
42 | return self.Base._Hovered
43 | end
44 | end
45 |
46 | function UIMenuCheckboxItem:Enabled(bool)
47 | if bool ~= nil then
48 | self.Base._Enabled = tobool(bool)
49 | else
50 | return self.Base._Enabled
51 | end
52 | end
53 |
54 | function UIMenuCheckboxItem:Description(str)
55 | if tostring(str) and str ~= nil then
56 | self.Base._Description = tostring(str)
57 | else
58 | return self.Base._Description
59 | end
60 | end
61 |
62 | function UIMenuCheckboxItem:Offset(X, Y)
63 | if tonumber(X) or tonumber(Y) then
64 | if tonumber(X) then
65 | self.Base._Offset.X = tonumber(X)
66 | end
67 | if tonumber(Y) then
68 | self.Base._Offset.Y = tonumber(Y)
69 | end
70 | else
71 | return self.Base._Offset
72 | end
73 | end
74 |
75 | function UIMenuCheckboxItem:Text(Text)
76 | if tostring(Text) and Text ~= nil then
77 | self.Base.Text:Text(tostring(Text))
78 | else
79 | return self.Base.Text:Text()
80 | end
81 | end
82 |
83 | function UIMenuCheckboxItem:SetLeftBadge()
84 | error("This item does not support badges")
85 | end
86 |
87 | function UIMenuCheckboxItem:SetRightBadge()
88 | error("This item does not support badges")
89 | end
90 |
91 | function UIMenuCheckboxItem:RightLabel()
92 | error("This item does not support a right label")
93 | end
94 |
95 | function UIMenuCheckboxItem:Draw()
96 | self.Base:Draw()
97 | self.CheckedSprite:Position(380 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.CheckedSprite.Y)
98 | if self.Base:Selected() then
99 | if self.Checked then
100 | self.CheckedSprite.TxtName = "shop_box_tickb"
101 | else
102 | self.CheckedSprite.TxtName = "shop_box_blankb"
103 | end
104 | else
105 | if self.Checked then
106 | self.CheckedSprite.TxtName = "shop_box_tick"
107 | else
108 | self.CheckedSprite.TxtName = "shop_box_blank"
109 | end
110 | end
111 | self.CheckedSprite:Draw()
112 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/items/UIMenuColouredItem.lua:
--------------------------------------------------------------------------------
1 | UIMenuColouredItem = setmetatable({}, UIMenuColouredItem)
2 | UIMenuColouredItem.__index = UIMenuColouredItem
3 | UIMenuColouredItem.__call = function() return "UIMenuItem", "UIMenuColouredItem" end
4 |
5 | function UIMenuColouredItem.New(Text, Description, MainColour, HighlightColour)
6 | if type(Colour) ~= "table" then Colour = {R = 0, G = 0, B = 0, A = 255} end
7 | if type(HighlightColour) ~= "table" then Colour = {R = 255, G = 255, B = 255, A = 255} end
8 | local _UIMenuColouredItem = {
9 | Base = UIMenuItem.New(Text or "", Description or ""),
10 | Rectangle = UIResRectangle.New(0, 0, 431, 38, MainColour.R, MainColour.G, MainColour.B, MainColour.A),
11 | MainColour = MainColour,
12 | HighlightColour = HighlightColour,
13 | Activated = function(menu, item) end,
14 | }
15 | _UIMenuColouredItem.Base.SelectedSprite:Colour(HighlightColour.R, HighlightColour.G, HighlightColour.B, HighlightColour.A)
16 | return setmetatable(_UIMenuColouredItem, UIMenuColouredItem)
17 | end
18 |
19 | function UIMenuColouredItem:SetParentMenu(Menu)
20 | if Menu() == "UIMenu" then
21 | self.Base.ParentMenu = Menu
22 | else
23 | return self.Base.ParentMenu
24 | end
25 | end
26 |
27 | function UIMenuColouredItem:Position(Y)
28 | if tonumber(Y) then
29 | self.Base:Position(Y)
30 | self.Rectangle:Position(self.Base._Offset.X, Y + 144 + self.Base._Offset.Y)
31 | end
32 | end
33 |
34 | function UIMenuColouredItem:Selected(bool)
35 | if bool ~= nil then
36 | self.Base._Selected = tobool(bool)
37 | else
38 | return self.Base._Selected
39 | end
40 | end
41 |
42 | function UIMenuColouredItem:Hovered(bool)
43 | if bool ~= nil then
44 | self.Base._Hovered = tobool(bool)
45 | else
46 | return self.Base._Hovered
47 | end
48 | end
49 |
50 | function UIMenuColouredItem:Enabled(bool)
51 | if bool ~= nil then
52 | self.Base._Enabled = tobool(bool)
53 | else
54 | return self.Base._Enabled
55 | end
56 | end
57 |
58 | function UIMenuColouredItem:Description(str)
59 | if tostring(str) and str ~= nil then
60 | self.Base._Description = tostring(str)
61 | else
62 | return self.Base._Description
63 | end
64 | end
65 |
66 | function UIMenuColouredItem:Offset(X, Y)
67 | if tonumber(X) or tonumber(Y) then
68 | if tonumber(X) then
69 | self.Base._Offset.X = tonumber(X)
70 | end
71 | if tonumber(Y) then
72 | self.Base._Offset.Y = tonumber(Y)
73 | end
74 | else
75 | return self.Base._Offset
76 | end
77 | end
78 |
79 | function UIMenuColouredItem:Text(Text)
80 | if tostring(Text) and Text ~= nil then
81 | self.Base.Text:Text(tostring(Text))
82 | else
83 | return self.Base.Text:Text()
84 | end
85 | end
86 |
87 | function UIMenuColouredItem:RightLabel(Text, MainColour, HighlightColour)
88 | if tostring(Text) and Text ~= nil then
89 | if type(MainColour) == "table" then
90 | self.Base.Label.MainColour = MainColour
91 | end
92 | if type(HighlightColour) == "table" then
93 | self.Base.Label.HighlightColour = HighlightColour
94 | end
95 | self.Base.Label.Text:Text(tostring(Text))
96 | else
97 | return self.Base.Label.Text:Text()
98 | end
99 | end
100 |
101 | function UIMenuColouredItem:SetLeftBadge(Badge)
102 | if tonumber(Badge) then
103 | self.Base.LeftBadge.Badge = tonumber(Badge)
104 | end
105 | end
106 |
107 | function UIMenuColouredItem:SetRightBadge(Badge)
108 | if tonumber(Badge) then
109 | self.Base.RightBadge.Badge = tonumber(Badge)
110 | end
111 | end
112 |
113 | function UIMenuColouredItem:Draw()
114 | self.Rectangle:Size(431 + self.ParentMenu.WidthOffset, self.Rectangle.Height)
115 | self.Rectangle:Draw()
116 | self.Base:Draw()
117 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/items/UIMenuItem.lua:
--------------------------------------------------------------------------------
1 | UIMenuItem = setmetatable({}, UIMenuItem)
2 | UIMenuItem.__index = UIMenuItem
3 | UIMenuItem.__call = function() return "UIMenuItem", "UIMenuItem" end
4 |
5 | function UIMenuItem.New(Text, Description)
6 | _UIMenuItem = {
7 | Rectangle = UIResRectangle.New(0, 0, 431, 38, 255, 255, 255, 20),
8 | Text = UIResText.New(tostring(Text) or "", 8, 0, 0.33, 245, 245, 245, 255, 0),
9 | _Description = tostring(Description) or "";
10 | SelectedSprite = Sprite.New("commonmenu", "gradient_nav", 0, 0, 431, 38),
11 | LeftBadge = { Sprite = Sprite.New("commonmenu", "", 0, 0, 40, 40), Badge = 0},
12 | RightBadge = { Sprite = Sprite.New("commonmenu", "", 0, 0, 40, 40), Badge = 0},
13 | Label = {
14 | Text = UIResText.New("", 0, 0, 0.35, 245, 245, 245, 255, 0, "Right"),
15 | MainColour = {R = 255, G = 255, B = 255, A = 255},
16 | HighlightColour = {R = 0, G = 0, B = 0, A = 255},
17 | },
18 | _Selected = false,
19 | _Hovered = false,
20 | _Enabled = true,
21 | _Offset = {X = 0, Y = 0},
22 | ParentMenu = nil,
23 | Panels = {},
24 | Activated = function(menu, item) end,
25 | ActivatedPanel = function(menu, item, panel, panelvalue) end,
26 | }
27 | return setmetatable(_UIMenuItem, UIMenuItem)
28 | end
29 |
30 | function UIMenuItem:SetParentMenu(Menu)
31 | if Menu ~= nil and Menu() == "UIMenu" then
32 | self.ParentMenu = Menu
33 | else
34 | return self.ParentMenu
35 | end
36 | end
37 |
38 | function UIMenuItem:Selected(bool)
39 | if bool ~= nil then
40 | self._Selected = tobool(bool)
41 | else
42 | return self._Selected
43 | end
44 | end
45 |
46 | function UIMenuItem:Hovered(bool)
47 | if bool ~= nil then
48 | self._Hovered = tobool(bool)
49 | else
50 | return self._Hovered
51 | end
52 | end
53 |
54 | function UIMenuItem:Enabled(bool)
55 | if bool ~= nil then
56 | self._Enabled = tobool(bool)
57 | else
58 | return self._Enabled
59 | end
60 | end
61 |
62 | function UIMenuItem:Description(str)
63 | if tostring(str) and str ~= nil then
64 | self._Description = tostring(str)
65 | else
66 | return self._Description
67 | end
68 | end
69 |
70 | function UIMenuItem:Offset(X, Y)
71 | if tonumber(X) or tonumber(Y) then
72 | if tonumber(X) then
73 | self._Offset.X = tonumber(X)
74 | end
75 | if tonumber(Y) then
76 | self._Offset.Y = tonumber(Y)
77 | end
78 | else
79 | return self._Offset
80 | end
81 | end
82 |
83 | function UIMenuItem:Position(Y)
84 | if tonumber(Y) then
85 | self.Rectangle:Position(self._Offset.X, Y + 144 + self._Offset.Y)
86 | self.SelectedSprite:Position(0 + self._Offset.X, Y + 144 + self._Offset.Y)
87 | self.Text:Position(8 + self._Offset.X, Y + 147 + self._Offset.Y)
88 | self.LeftBadge.Sprite:Position(0 + self._Offset.X, Y + 142 + self._Offset.Y)
89 | self.RightBadge.Sprite:Position(385 + self._Offset.X, Y + 142 + self._Offset.Y)
90 | self.Label.Text:Position(420 + self._Offset.X, Y + 148 + self._Offset.Y)
91 | end
92 | end
93 |
94 | function UIMenuItem:RightLabel(Text, MainColour, HighlightColour)
95 | if tostring(Text) and Text ~= nil then
96 | if type(MainColour) == "table" then
97 | self.Label.MainColour = MainColour
98 | end
99 | if type(HighlightColour) == "table" then
100 | self.Label.HighlightColour = HighlightColour
101 | end
102 | self.Label.Text:Text(tostring(Text))
103 | else
104 | return self.Label.Text:Text()
105 | end
106 | end
107 |
108 | function UIMenuItem:SetLeftBadge(Badge)
109 | if tonumber(Badge) then
110 | self.LeftBadge.Badge = tonumber(Badge)
111 | end
112 | end
113 |
114 | function UIMenuItem:SetRightBadge(Badge)
115 | if tonumber(Badge) then
116 | self.RightBadge.Badge = tonumber(Badge)
117 | end
118 | end
119 |
120 | function UIMenuItem:Text(Text)
121 | if tostring(Text) and Text ~= nil then
122 | self.Text:Text(tostring(Text))
123 | else
124 | return self.Text:Text()
125 | end
126 | end
127 |
128 | function UIMenuItem:AddPanel(Panel)
129 | if Panel() == "UIMenuPanel" then
130 | table.insert(self.Panels, Panel)
131 | Panel:SetParentItem(self)
132 | end
133 | end
134 |
135 | function UIMenuItem:RemovePanelAt(Index)
136 | if tonumber(Index) then
137 | if self.Panels[Index] then
138 | table.remove(self.Panels, tonumber(Index))
139 | end
140 | end
141 | end
142 |
143 | function UIMenuItem:FindPanelIndex(Panel)
144 | if Panel() == "UIMenuPanel" then
145 | for Index = 1, #self.Panels do
146 | if self.Panels[Index] == Panel then
147 | return Index
148 | end
149 | end
150 | end
151 | return nil
152 | end
153 |
154 | function UIMenuItem:FindPanelItem()
155 | for Index = #self.Items, 1, -1 do
156 | if self.Items[Index].Panel then
157 | return Index
158 | end
159 | end
160 | return nil
161 | end
162 |
163 | function UIMenuItem:Draw()
164 | self.Rectangle:Size(431 + self.ParentMenu.WidthOffset, self.Rectangle.Height)
165 | self.SelectedSprite:Size(431 + self.ParentMenu.WidthOffset, self.SelectedSprite.Height)
166 |
167 | if self._Hovered and not self._Selected then
168 | self.Rectangle:Draw()
169 | end
170 |
171 | if self._Selected then
172 | self.SelectedSprite:Draw()
173 | end
174 |
175 | if self._Enabled then
176 | if self._Selected then
177 | self.Text:Colour(0, 0, 0, 255)
178 | self.Label.Text:Colour(self.Label.HighlightColour.R, self.Label.HighlightColour.G, self.Label.HighlightColour.B, self.Label.HighlightColour.A)
179 | else
180 | self.Text:Colour(245, 245, 245, 255)
181 | self.Label.Text:Colour(self.Label.MainColour.R, self.Label.MainColour.G, self.Label.MainColour.B, self.Label.MainColour.A)
182 | end
183 | else
184 | self.Text:Colour(163, 159, 148, 255)
185 | self.Label.Text:Colour(163, 159, 148, 255)
186 | end
187 |
188 | if self.LeftBadge.Badge == BadgeStyle.None then
189 | self.Text:Position(8 + self._Offset.X, self.Text.Y)
190 | else
191 | self.Text:Position(35 + self._Offset.X, self.Text.Y)
192 | self.LeftBadge.Sprite.TxtDictionary = GetBadgeDictionary(self.LeftBadge.Badge, self._Selected)
193 | self.LeftBadge.Sprite.TxtName = GetBadgeTexture(self.LeftBadge.Badge, self._Selected)
194 | self.LeftBadge.Sprite:Colour(GetBadgeColour(self.LeftBadge.Badge, self._Selected))
195 | self.LeftBadge.Sprite:Draw()
196 | end
197 |
198 | if self.RightBadge.Badge ~= BadgeStyle.None then
199 | self.RightBadge.Sprite:Position(385 + self._Offset.X + self.ParentMenu.WidthOffset, self.RightBadge.Sprite.Y)
200 | self.RightBadge.Sprite.TxtDictionary = GetBadgeDictionary(self.RightBadge.Badge, self._Selected)
201 | self.RightBadge.Sprite.TxtName = GetBadgeTexture(self.RightBadge.Badge, self._Selected)
202 | self.RightBadge.Sprite:Colour(GetBadgeColour(self.RightBadge.Badge, self._Selected))
203 | self.RightBadge.Sprite:Draw()
204 | end
205 |
206 | if self.Label.Text:Text() ~= "" and string.len(self.Label.Text:Text()) > 0 then
207 | self.Label.Text:Position(420 + self._Offset.X + self.ParentMenu.WidthOffset, self.Label.Text.Y)
208 | self.Label.Text:Draw()
209 | end
210 |
211 | self.Text:Draw()
212 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/items/UIMenuListItem.lua:
--------------------------------------------------------------------------------
1 | UIMenuListItem = setmetatable({}, UIMenuListItem)
2 | UIMenuListItem.__index = UIMenuListItem
3 | UIMenuListItem.__call = function() return "UIMenuItem", "UIMenuListItem" end
4 |
5 | function UIMenuListItem.New(Text, Items, Index, Description)
6 | if type(Items) ~= "table" then Items = {} end
7 | if Index == 0 then Index = 1 end
8 | local _UIMenuListItem = {
9 | Base = UIMenuItem.New(Text or "", Description or ""),
10 | Items = Items,
11 | LeftArrow = Sprite.New("commonmenu", "arrowleft", 110, 105, 30, 30),
12 | RightArrow = Sprite.New("commonmenu", "arrowright", 280, 105, 30, 30),
13 | ItemText = UIResText.New("", 290, 104, 0.35, 255, 255, 255, 255, 0, "Right"),
14 | _Index = tonumber(Index) or 1,
15 | Panels = {},
16 | OnListChanged = function(menu, item, newindex) end,
17 | OnListSelected = function(menu, item, newindex) end,
18 | }
19 | return setmetatable(_UIMenuListItem, UIMenuListItem)
20 | end
21 |
22 | function UIMenuListItem:SetParentMenu(Menu)
23 | if Menu ~= nil and Menu() == "UIMenu" then
24 | self.Base.ParentMenu = Menu
25 | else
26 | return self.Base.ParentMenu
27 | end
28 | end
29 |
30 | function UIMenuListItem:Position(Y)
31 | if tonumber(Y) then
32 | self.LeftArrow:Position(300 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 147 + Y + self.Base._Offset.Y)
33 | self.RightArrow:Position(400 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 147 + Y + self.Base._Offset.Y)
34 | self.ItemText:Position(300 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 147 + Y + self.Base._Offset.Y)
35 | self.Base:Position(Y)
36 | end
37 | end
38 |
39 | function UIMenuListItem:Selected(bool)
40 | if bool ~= nil then
41 | self.Base._Selected = tobool(bool)
42 | else
43 | return self.Base._Selected
44 | end
45 | end
46 |
47 | function UIMenuListItem:Hovered(bool)
48 | if bool ~= nil then
49 | self.Base._Hovered = tobool(bool)
50 | else
51 | return self.Base._Hovered
52 | end
53 | end
54 |
55 | function UIMenuListItem:Enabled(bool)
56 | if bool ~= nil then
57 | self.Base._Enabled = tobool(bool)
58 | else
59 | return self.Base._Enabled
60 | end
61 | end
62 |
63 | function UIMenuListItem:Description(str)
64 | if tostring(str) and str ~= nil then
65 | self.Base._Description = tostring(str)
66 | else
67 | return self.Base._Description
68 | end
69 | end
70 |
71 | function UIMenuListItem:Offset(X, Y)
72 | if tonumber(X) or tonumber(Y) then
73 | if tonumber(X) then
74 | self.Base._Offset.X = tonumber(X)
75 | end
76 | if tonumber(Y) then
77 | self.Base._Offset.Y = tonumber(Y)
78 | end
79 | else
80 | return self.Base._Offset
81 | end
82 | end
83 |
84 | function UIMenuListItem:Text(Text)
85 | if tostring(Text) and Text ~= nil then
86 | self.Base.Text:Text(tostring(Text))
87 | else
88 | return self.Base.Text:Text()
89 | end
90 | end
91 |
92 | function UIMenuListItem:Index(Index)
93 | if tonumber(Index) then
94 | if tonumber(Index) > #self.Items then
95 | self._Index = 1
96 | elseif tonumber(Index) < 1 then
97 | self._Index = #self.Items
98 | else
99 | self._Index = tonumber(Index)
100 | end
101 | else
102 | return self._Index
103 | end
104 | end
105 |
106 | function UIMenuListItem:ItemToIndex(Item)
107 | for i = 1, #self.Items do
108 | if type(Item) == type(self.Items[i]) and Item == self.Items[i] then
109 | return i
110 | elseif type(self.Items[i]) == "table" and (type(Item) == type(self.Items[i].Name) or type(Item) == type(self.Items[i].Value)) and (Item == self.Items[i].Name or Item == self.Items[i].Value) then
111 | return i
112 | end
113 | end
114 | end
115 |
116 | function UIMenuListItem:IndexToItem(Index)
117 | if tonumber(Index) then
118 | if tonumber(Index) == 0 then Index = 1 end
119 | if self.Items[tonumber(Index)] then
120 | return self.Items[tonumber(Index)]
121 | end
122 | end
123 | end
124 |
125 | function UIMenuListItem:SetLeftBadge()
126 | error("This item does not support badges")
127 | end
128 |
129 | function UIMenuListItem:SetRightBadge()
130 | error("This item does not support badges")
131 | end
132 |
133 | function UIMenuListItem:RightLabel()
134 | error("This item does not support a right label")
135 | end
136 |
137 | function UIMenuListItem:AddPanel(Panel)
138 | if Panel() == "UIMenuPanel" then
139 | table.insert(self.Panels, Panel)
140 | Panel:SetParentItem(self)
141 | end
142 | end
143 |
144 | function UIMenuListItem:RemovePanelAt(Index)
145 | if tonumber(Index) then
146 | if self.Panels[Index] then
147 | table.remove(self.Panels, tonumber(Index))
148 | end
149 | end
150 | end
151 |
152 | function UIMenuListItem:FindPanelIndex(Panel)
153 | if Panel() == "UIMenuPanel" then
154 | for Index = 1, #self.Panels do
155 | if self.Panels[Index] == Panel then
156 | return Index
157 | end
158 | end
159 | end
160 | return nil
161 | end
162 |
163 | function UIMenuListItem:FindPanelItem()
164 | for Index = #self.Items, 1, -1 do
165 | if self.Items[Index].Panel then
166 | return Index
167 | end
168 | end
169 | return nil
170 | end
171 |
172 | function UIMenuListItem:Draw()
173 | self.Base:Draw()
174 |
175 | if self:Enabled() then
176 | if self:Selected() then
177 | self.ItemText:Colour(0, 0, 0, 255)
178 | self.LeftArrow:Colour(0, 0, 0, 255)
179 | self.RightArrow:Colour(0, 0, 0, 255)
180 | else
181 | self.ItemText:Colour(245, 245, 245, 255)
182 | self.LeftArrow:Colour(245, 245, 245, 255)
183 | self.RightArrow:Colour(245, 245, 245, 255)
184 | end
185 | else
186 | self.ItemText:Colour(163, 159, 148, 255)
187 | self.LeftArrow:Colour(163, 159, 148, 255)
188 | self.RightArrow:Colour(163, 159, 148, 255)
189 | end
190 |
191 | local Text = (type(self.Items[self._Index]) == "table") and tostring(self.Items[self._Index].Name) or tostring(self.Items[self._Index])
192 | local Offset = MeasureStringWidth(Text, 0, 0.35)
193 |
194 | self.ItemText:Text(Text)
195 | self.LeftArrow:Position(378 - Offset + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.LeftArrow.Y)
196 |
197 | if self:Selected() then
198 | self.LeftArrow:Draw()
199 | self.RightArrow:Draw()
200 | self.ItemText:Position(403 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.ItemText.Y)
201 | else
202 | self.ItemText:Position(418 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, self.ItemText.Y)
203 | end
204 |
205 | self.ItemText:Draw()
206 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/items/UIMenuProgressItem.lua:
--------------------------------------------------------------------------------
1 | UIMenuProgressItem = setmetatable({}, UIMenuProgressItem)
2 | UIMenuProgressItem.__index = UIMenuProgressItem
3 | UIMenuProgressItem.__call = function() return "UIMenuItem", "UIMenuProgressItem" end
4 |
5 | function UIMenuProgressItem.New(Text, Items, Index, Description, Counter)
6 | if type(Items) ~= "table" then Items = {} end
7 | if Index == 0 then Index = 1 end
8 | local _UIMenuProgressItem = {
9 | Base = UIMenuItem.New(Text or "", Description or ""),
10 | Data = {
11 | Items = Items,
12 | Counter = tobool(Counter),
13 | Max = 407.5,
14 | Index = tonumber(Index) or 1,
15 | },
16 | Background = UIResRectangle.New(0, 0, 415, 20),
17 | Bar = UIResRectangle.New(0, 0, 407.5, 12.5),
18 | OnProgressChanged = function(menu, item, newindex) end,
19 | OnProgressSelected = function(menu, item, newindex) end,
20 | }
21 |
22 | _UIMenuProgressItem.Base.Rectangle.Height = 60
23 | _UIMenuProgressItem.Base.SelectedSprite.Height = 60
24 |
25 | if _UIMenuProgressItem.Data.Counter then
26 | _UIMenuProgressItem.Base:RightLabel(_UIMenuProgressItem.Data.Index.."/"..#_UIMenuProgressItem.Data.Items)
27 | else
28 | _UIMenuProgressItem.Base:RightLabel((type(_UIMenuProgressItem.Data.Items[_UIMenuProgressItem.Data.Index]) == "table") and tostring(_UIMenuProgressItem.Data.Items[_UIMenuProgressItem.Data.Index].Name) or tostring(_UIMenuProgressItem.Data.Items[_UIMenuProgressItem.Data.Index]))
29 | end
30 |
31 | _UIMenuProgressItem.Bar.Width = _UIMenuProgressItem.Data.Index/#_UIMenuProgressItem.Data.Items * _UIMenuProgressItem.Data.Max
32 |
33 | return setmetatable(_UIMenuProgressItem, UIMenuProgressItem)
34 | end
35 |
36 | function UIMenuProgressItem:SetParentMenu(Menu)
37 | if Menu() == "UIMenu" then
38 | self.Base.ParentMenu = Menu
39 | else
40 | return self.Base.ParentMenu
41 | end
42 | end
43 |
44 | function UIMenuProgressItem:Position(Y)
45 | if tonumber(Y) then
46 | self.Base:Position(Y)
47 | self.Background:Position(8 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 177 + Y + self.Base._Offset.Y)
48 | self.Bar:Position(11.75 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 180.75 + Y + self.Base._Offset.Y)
49 | end
50 | end
51 |
52 | function UIMenuProgressItem:Selected(bool)
53 | if bool ~= nil then
54 | self.Base._Selected = tobool(bool)
55 | else
56 | return self.Base._Selected
57 | end
58 | end
59 |
60 | function UIMenuProgressItem:Hovered(bool)
61 | if bool ~= nil then
62 | self.Base._Hovered = tobool(bool)
63 | else
64 | return self.Base._Hovered
65 | end
66 | end
67 |
68 | function UIMenuProgressItem:Enabled(bool)
69 | if bool ~= nil then
70 | self.Base._Enabled = tobool(bool)
71 | else
72 | return self.Base._Enabled
73 | end
74 | end
75 |
76 | function UIMenuProgressItem:Description(str)
77 | if tostring(str) and str ~= nil then
78 | self.Base._Description = tostring(str)
79 | else
80 | return self.Base._Description
81 | end
82 | end
83 |
84 | function UIMenuProgressItem:Offset(X, Y)
85 | if tonumber(X) or tonumber(Y) then
86 | if tonumber(X) then
87 | self.Base._Offset.X = tonumber(X)
88 | end
89 | if tonumber(Y) then
90 | self.Base._Offset.Y = tonumber(Y)
91 | end
92 | else
93 | return self.Base._Offset
94 | end
95 | end
96 |
97 | function UIMenuProgressItem:Text(Text)
98 | if tostring(Text) and Text ~= nil then
99 | self.Base.Text:Text(tostring(Text))
100 | else
101 | return self.Base.Text:Text()
102 | end
103 | end
104 |
105 | function UIMenuProgressItem:Index(Index)
106 | if tonumber(Index) then
107 | if tonumber(Index) > #self.Data.Items then
108 | self.Data.Index = 1
109 | elseif tonumber(Index) < 1 then
110 | self.Data.Index = #self.Data.Items
111 | else
112 | self.Data.Index = tonumber(Index)
113 | end
114 |
115 | if self.Data.Counter then
116 | self.Base:RightLabel(self.Data.Index.."/"..#self.Data.Items)
117 | else
118 | self.Base:RightLabel((type(self.Data.Items[self.Data.Index]) == "table") and tostring(self.Data.Items[self.Data.Index].Name) or tostring(self.Data.Items[self.Data.Index]))
119 | end
120 |
121 | self.Bar.Width = self.Data.Index/#self.Data.Items * self.Data.Max
122 | else
123 | return self.Data.Index
124 | end
125 | end
126 |
127 | function UIMenuProgressItem:ItemToIndex(Item)
128 | for i = 1, #self.Data.Items do
129 | if type(Item) == type(self.Data.Items[i]) and Item == self.Data.Items[i] then
130 | return i
131 | elseif type(self.Data.Items[i]) == "table" and (type(Item) == type(self.Data.Items[i].Name) or type(Item) == type(self.Data.Items[i].Value)) and (Item == self.Data.Items[i].Name or Item == self.Data.Items[i].Value) then
132 | return i
133 | end
134 | end
135 | end
136 |
137 | function UIMenuProgressItem:IndexToItem(Index)
138 | if tonumber(Index) then
139 | if tonumber(Index) == 0 then Index = 1 end
140 | if self.Data.Items[tonumber(Index)] then
141 | return self.Data.Items[tonumber(Index)]
142 | end
143 | end
144 | end
145 |
146 | function UIMenuProgressItem:SetLeftBadge()
147 | error("This item does not support badges")
148 | end
149 |
150 | function UIMenuProgressItem:SetRightBadge()
151 | error("This item does not support badges")
152 | end
153 |
154 | function UIMenuProgressItem:RightLabel()
155 | error("This item does not support a right label")
156 | end
157 |
158 | function UIMenuProgressItem:CalculateProgress(CursorX)
159 | local Progress = CursorX - self.Bar.X
160 | self:Index(math.round(#self.Data.Items * (((Progress >= 0 and Progress <= self.Data.Max) and Progress or ((Progress < 0) and 0 or self.Data.Max))/self.Data.Max)))
161 | end
162 |
163 | function UIMenuProgressItem:Draw()
164 | self.Base:Draw()
165 |
166 | if self.Base._Selected then
167 | self.Background:Colour(table.unpack(Colours.Black))
168 | self.Bar:Colour(table.unpack(Colours.White))
169 | else
170 | self.Background:Colour(table.unpack(Colours.White))
171 | self.Bar:Colour(table.unpack(Colours.Black))
172 | end
173 |
174 | self.Background:Draw()
175 | self.Bar:Draw()
176 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/items/UIMenuSliderItem.lua:
--------------------------------------------------------------------------------
1 | UIMenuSliderItem = setmetatable({}, UIMenuSliderItem)
2 | UIMenuSliderItem.__index = UIMenuSliderItem
3 | UIMenuSliderItem.__call = function() return "UIMenuItem", "UIMenuSliderItem" end
4 |
5 | function UIMenuSliderItem.New(Text, Items, Index, Description, Divider)
6 | if type(Items) ~= "table" then Items = {} end
7 | if Index == 0 then Index = 1 end
8 | local _UIMenuSliderItem = {
9 | Base = UIMenuItem.New(Text or "", Description or ""),
10 | Items = Items,
11 | ShowDivider = tobool(Divider),
12 | LeftArrow = Sprite.New("commonmenutu", "arrowleft", 0, 105, 15, 15),
13 | RightArrow = Sprite.New("commonmenutu", "arrowright", 0, 105, 15, 15),
14 | Background = UIResRectangle.New(0, 0, 150, 9, 4, 32, 57, 255),
15 | Slider = UIResRectangle.New(0, 0, 75, 9, 57, 116, 200, 255),
16 | Divider = UIResRectangle.New(0, 0, 2.5, 20, 245, 245, 245, 255),
17 | _Index = tonumber(Index) or 1,
18 | OnSliderChanged = function(menu, item, newindex) end,
19 | OnSliderSelected = function(menu, item, newindex) end,
20 | }
21 | return setmetatable(_UIMenuSliderItem, UIMenuSliderItem)
22 | end
23 |
24 | function UIMenuSliderItem:SetParentMenu(Menu)
25 | if Menu() == "UIMenu" then
26 | self.Base.ParentMenu = Menu
27 | else
28 | return self.Base.ParentMenu
29 | end
30 | end
31 |
32 | function UIMenuSliderItem:Position(Y)
33 | if tonumber(Y) then
34 | self.Background:Position(250 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 158.5 + self.Base._Offset.Y)
35 | self.Slider:Position(250 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 158.5 + self.Base._Offset.Y)
36 | self.Divider:Position(323.5 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, Y + 153 + self.Base._Offset.Y)
37 | self.LeftArrow:Position(235 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 155.5 + Y + self.Base._Offset.Y)
38 | self.RightArrow:Position(400 + self.Base._Offset.X + self.Base.ParentMenu.WidthOffset, 155.5 + Y + self.Base._Offset.Y)
39 | self.Base:Position(Y)
40 | end
41 | end
42 |
43 | function UIMenuSliderItem:Selected(bool)
44 | if bool ~= nil then
45 | self.Base._Selected = tobool(bool)
46 | else
47 | return self.Base._Selected
48 | end
49 | end
50 |
51 | function UIMenuSliderItem:Hovered(bool)
52 | if bool ~= nil then
53 | self.Base._Hovered = tobool(bool)
54 | else
55 | return self.Base._Hovered
56 | end
57 | end
58 |
59 | function UIMenuSliderItem:Enabled(bool)
60 | if bool ~= nil then
61 | self.Base._Enabled = tobool(bool)
62 | else
63 | return self.Base._Enabled
64 | end
65 | end
66 |
67 | function UIMenuSliderItem:Description(str)
68 | if tostring(str) and str ~= nil then
69 | self.Base._Description = tostring(str)
70 | else
71 | return self.Base._Description
72 | end
73 | end
74 |
75 | function UIMenuSliderItem:Offset(X, Y)
76 | if tonumber(X) or tonumber(Y) then
77 | if tonumber(X) then
78 | self.Base._Offset.X = tonumber(X)
79 | end
80 | if tonumber(Y) then
81 | self.Base._Offset.Y = tonumber(Y)
82 | end
83 | else
84 | return self.Base._Offset
85 | end
86 | end
87 |
88 | function UIMenuSliderItem:Text(Text)
89 | if tostring(Text) and Text ~= nil then
90 | self.Base.Text:Text(tostring(Text))
91 | else
92 | return self.Base.Text:Text()
93 | end
94 | end
95 |
96 | function UIMenuSliderItem:Index(Index)
97 | if tonumber(Index) then
98 | if tonumber(Index) > #self.Items then
99 | self._Index = 1
100 | elseif tonumber(Index) < 1 then
101 | self._Index = #self.Items
102 | else
103 | self._Index = tonumber(Index)
104 | end
105 | else
106 | return self._Index
107 | end
108 | end
109 |
110 | function UIMenuSliderItem:ItemToIndex(Item)
111 | for i = 1, #self.Items do
112 | if type(Item) == type(self.Items[i]) and Item == self.Items[i] then
113 | return i
114 | end
115 | end
116 | end
117 |
118 | function UIMenuSliderItem:IndexToItem(Index)
119 | if tonumber(Index) then
120 | if tonumber(Index) == 0 then Index = 1 end
121 | if self.Items[tonumber(Index)] then
122 | return self.Items[tonumber(Index)]
123 | end
124 | end
125 | end
126 |
127 | function UIMenuSliderItem:SetLeftBadge()
128 | error("This item does not support badges")
129 | end
130 |
131 | function UIMenuSliderItem:SetRightBadge()
132 | error("This item does not support badges")
133 | end
134 |
135 | function UIMenuSliderItem:RightLabel()
136 | error("This item does not support a right label")
137 | end
138 |
139 | function UIMenuSliderItem:Draw()
140 | self.Base:Draw()
141 |
142 | if self:Enabled() then
143 | if self:Selected() then
144 | self.LeftArrow:Colour(0, 0, 0, 255)
145 | self.RightArrow:Colour(0, 0, 0, 255)
146 | else
147 | self.LeftArrow:Colour(245, 245, 245, 255)
148 | self.RightArrow:Colour(245, 245, 245, 255)
149 | end
150 | else
151 | self.LeftArrow:Colour(163, 159, 148, 255)
152 | self.RightArrow:Colour(163, 159, 148, 255)
153 | end
154 |
155 | local Offset = ((self.Background.Width - self.Slider.Width)/(#self.Items - 1)) * (self._Index-1)
156 |
157 | self.Slider:Position(250 + self.Base._Offset.X + Offset + self.Base.ParentMenu.WidthOffset, self.Slider.Y)
158 |
159 | if self:Selected() then
160 | self.LeftArrow:Draw()
161 | self.RightArrow:Draw()
162 | end
163 |
164 | self.Background:Draw()
165 | self.Slider:Draw()
166 | if self.ShowDivider then
167 | self.Divider:Draw()
168 | end
169 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/panels/UIMenuColourPanel.lua:
--------------------------------------------------------------------------------
1 | UIMenuColourPanel = setmetatable({}, UIMenuColourPanel)
2 | UIMenuColourPanel.__index = UIMenuColourPanel
3 | UIMenuColourPanel.__call = function() return "UIMenuPanel", "UIMenuColourPanel" end
4 |
5 | function UIMenuColourPanel.New(Title, Colours)
6 | _UIMenuColourPanel = {
7 | Data = {
8 | Pagination = {
9 | Min = 1,
10 | Max = 8,
11 | Total = 8,
12 | },
13 | Index = 1000,
14 | Items = Colours,
15 | Title = Title or "Title",
16 | Enabled = true,
17 | Value = 1,
18 | },
19 | Background = Sprite.New("commonmenu", "gradient_bgd", 0, 0, 431, 112),
20 | Bar = {},
21 | LeftArrow = Sprite.New("commonmenu", "arrowleft", 0, 0, 30, 30),
22 | RightArrow = Sprite.New("commonmenu", "arrowright", 0, 0, 30, 30),
23 | SelectedRectangle = UIResRectangle.New(0, 0, 44.5, 8),
24 | Text = UIResText.New(Title.." (1 of "..#Colours..")" or "Title".." (1 of "..#Colours..")", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
25 | ParentItem = nil,
26 | }
27 |
28 | for Index = 1, #Colours do
29 | if Index < 10 then
30 | table.insert(_UIMenuColourPanel.Bar, UIResRectangle.New(0, 0, 44.5, 44.5, table.unpack(Colours[Index])))
31 | else
32 | break
33 | end
34 | end
35 |
36 | if #_UIMenuColourPanel.Data.Items ~= 0 then
37 | _UIMenuColourPanel.Data.Index = 1000 - (1000 % #_UIMenuColourPanel.Data.Items)
38 | _UIMenuColourPanel.Data.Pagination.Max = _UIMenuColourPanel.Data.Pagination.Total + 1
39 | _UIMenuColourPanel.Data.Pagination.Min = 0
40 | end
41 | return setmetatable(_UIMenuColourPanel, UIMenuColourPanel)
42 | end
43 |
44 | function UIMenuColourPanel:SetParentItem(Item) -- required
45 | if Item() == "UIMenuItem" then
46 | self.ParentItem = Item
47 | else
48 | return self.ParentItem
49 | end
50 | end
51 |
52 | function UIMenuColourPanel:Enabled(Enabled)
53 | if type(Enabled) == "boolean" then
54 | self.Data.Enabled = Enabled
55 | else
56 | return self.Data.Enabled
57 | end
58 | end
59 |
60 | function UIMenuColourPanel:Position(Y) -- required
61 | if tonumber(Y) then
62 | local ParentOffsetX, ParentOffsetWidth = self.ParentItem:Offset().X, self.ParentItem:SetParentMenu().WidthOffset
63 |
64 | self.Background:Position(ParentOffsetX, Y)
65 | for Index = 1, #self.Bar do
66 | self.Bar[Index]:Position(15 + (44.5 * (Index - 1)) + ParentOffsetX + (ParentOffsetWidth/2), 55 + Y)
67 | end
68 | self.SelectedRectangle:Position(15 + (44.5 * ((self:CurrentSelection() - self.Data.Pagination.Min) - 1)) + ParentOffsetX + (ParentOffsetWidth/2), 47 + Y)
69 | self.LeftArrow:Position(7.5 + ParentOffsetX + (ParentOffsetWidth/2), 15 + Y)
70 | self.RightArrow:Position(393.5 + ParentOffsetX + (ParentOffsetWidth/2), 15 + Y)
71 | self.Text:Position(215.5 + ParentOffsetX + (ParentOffsetWidth/2), 15 + Y)
72 | end
73 | end
74 |
75 | function UIMenuColourPanel:CurrentSelection(value, PreventUpdate)
76 | if tonumber(value) then
77 | if #self.Data.Items == 0 then
78 | self.Data.Index = 0
79 | end
80 |
81 | self.Data.Index = 1000000 - (1000000 % #self.Data.Items) + tonumber(value)
82 |
83 | if self:CurrentSelection() > self.Data.Pagination.Max then
84 | self.Data.Pagination.Min = self:CurrentSelection() - (self.Data.Pagination.Total + 1)
85 | self.Data.Pagination.Max = self:CurrentSelection()
86 | elseif self:CurrentSelection() < self.Data.Pagination.Min then
87 | self.Data.Pagination.Min = self:CurrentSelection() - 1
88 | self.Data.Pagination.Max = self:CurrentSelection() + (self.Data.Pagination.Total + 1)
89 | end
90 |
91 | self:UpdateSelection(PreventUpdate)
92 | else
93 | if #self.Data.Items == 0 then
94 | return 1
95 | else
96 | if self.Data.Index % #self.Data.Items == 0 then
97 | return 1
98 | else
99 | return self.Data.Index % #self.Data.Items + 1
100 | end
101 | end
102 | end
103 | end
104 |
105 | function UIMenuColourPanel:UpdateParent(Colour)
106 | local _, ParentType = self.ParentItem()
107 | if ParentType == "UIMenuListItem" then
108 | local PanelItemIndex = self.ParentItem:FindPanelItem()
109 | local PanelIndex = self.ParentItem:FindPanelIndex(self)
110 | if PanelItemIndex then
111 | self.ParentItem.Items[PanelItemIndex].Value[PanelIndex] = Colour
112 | self.ParentItem:Index(PanelItemIndex)
113 | self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
114 | self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
115 | else
116 | for Index = 1, #self.ParentItem.Items do
117 | if type(self.ParentItem.Items[Index]) == "table" then
118 | if not self.ParentItem.Items[Index].Panels then self.ParentItem.Items[Index].Panels = {} end
119 | self.ParentItem.Items[Index].Panels[PanelIndex] = Colour
120 | else
121 | self.ParentItem.Items[Index] = {Name = tostring(self.ParentItem.Items[Index]), Value = self.ParentItem.Items[Index], Panels = {[PanelIndex] = Colour}}
122 | end
123 | end
124 | self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
125 | self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
126 | end
127 | elseif ParentType == "UIMenuItem" then
128 | self.ParentItem.ActivatedPanel(self.ParentItem.ParentMenu, self.ParentItem, self, Colour)
129 | end
130 | end
131 |
132 | function UIMenuColourPanel:UpdateSelection(PreventUpdate)
133 | local CurrentSelection = self:CurrentSelection()
134 | if not PreventUpdate then
135 | self:UpdateParent(CurrentSelection)
136 | end
137 | self.SelectedRectangle:Position(15 + (44.5 * ((CurrentSelection - self.Data.Pagination.Min) - 1)) + self.ParentItem:Offset().X, self.SelectedRectangle.Y)
138 | for Index = 1, 9 do
139 | self.Bar[Index]:Colour(table.unpack(self.Data.Items[self.Data.Pagination.Min + Index]))
140 | end
141 | self.Text:Text(self.Data.Title.." ("..CurrentSelection.." of "..#self.Data.Items..")")
142 | end
143 |
144 | function UIMenuColourPanel:Functions()
145 |
146 | local SafeZone = {X = 0, Y = 0}
147 | if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then
148 | SafeZone = GetSafeZoneBounds()
149 | end
150 |
151 |
152 | if IsMouseInBounds(self.LeftArrow.X + SafeZone.X, self.LeftArrow.Y + SafeZone.Y, self.LeftArrow.Width, self.LeftArrow.Height) then
153 | if IsDisabledControlJustPressed(0, 24) then
154 | if #self.Data.Items > self.Data.Pagination.Total + 1 then
155 | if self:CurrentSelection() <= self.Data.Pagination.Min + 1 then
156 | if self:CurrentSelection() == 1 then
157 | self.Data.Pagination.Min = #self.Data.Items - (self.Data.Pagination.Total + 1)
158 | self.Data.Pagination.Max = #self.Data.Items
159 | self.Data.Index = 1000 - (1000 % #self.Data.Items)
160 | self.Data.Index = self.Data.Index + (#self.Data.Items - 1)
161 | self:UpdateSelection()
162 | else
163 | self.Data.Pagination.Min = self.Data.Pagination.Min - 1
164 | self.Data.Pagination.Max = self.Data.Pagination.Max - 1
165 | self.Data.Index = self.Data.Index - 1
166 | self:UpdateSelection()
167 | end
168 | else
169 | self.Data.Index = self.Data.Index - 1
170 | self:UpdateSelection()
171 | end
172 | else
173 | self.Data.Index = self.Data.Index - 1
174 | self:UpdateSelection()
175 | end
176 | end
177 | end
178 |
179 | if IsMouseInBounds(self.RightArrow.X + SafeZone.X, self.RightArrow.Y + SafeZone.Y, self.RightArrow.Width, self.RightArrow.Height) then
180 | if IsDisabledControlJustPressed(0, 24) then
181 | if #self.Data.Items > self.Data.Pagination.Total + 1 then
182 | if self:CurrentSelection() >= self.Data.Pagination.Max then
183 | if self:CurrentSelection() == #self.Data.Items then
184 | self.Data.Pagination.Min = 0
185 | self.Data.Pagination.Max = self.Data.Pagination.Total + 1
186 | self.Data.Index = 1000 - (1000 % #self.Data.Items)
187 | self:UpdateSelection()
188 | else
189 | self.Data.Pagination.Max = self.Data.Pagination.Max + 1
190 | self.Data.Pagination.Min = self.Data.Pagination.Max - (self.Data.Pagination.Total + 1)
191 | self.Data.Index = self.Data.Index + 1
192 | self:UpdateSelection()
193 | end
194 | else
195 | self.Data.Index = self.Data.Index + 1
196 | self:UpdateSelection()
197 | end
198 | else
199 | self.Data.Index = self.Data.Index + 1
200 | self:UpdateSelection()
201 | end
202 | end
203 | end
204 |
205 | for Index = 1, #self.Bar do
206 | if IsMouseInBounds(self.Bar[Index].X + SafeZone.X, self.Bar[Index].Y + SafeZone.Y, self.Bar[Index].Width, self.Bar[Index].Height) then
207 | if IsDisabledControlJustPressed(0, 24) then
208 | self:CurrentSelection(self.Data.Pagination.Min + Index - 1)
209 | end
210 | end
211 | end
212 | end
213 |
214 | function UIMenuColourPanel:Draw() -- required
215 | if self.Data.Enabled then
216 | self.Background:Size(431 + self.ParentItem:SetParentMenu().WidthOffset, 112)
217 |
218 | self.Background:Draw()
219 | self.LeftArrow:Draw()
220 | self.RightArrow:Draw()
221 | self.Text:Draw()
222 | self.SelectedRectangle:Draw()
223 | for Index = 1, #self.Bar do
224 | self.Bar[Index]:Draw()
225 | end
226 | self:Functions()
227 | end
228 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/panels/UIMenuGridPanel.lua:
--------------------------------------------------------------------------------
1 | UIMenuGridPanel = setmetatable({}, UIMenuGridPanel)
2 | UIMenuGridPanel.__index = UIMenuGridPanel
3 | UIMenuGridPanel.__call = function() return "UIMenuPanel", "UIMenuGridPanel" end
4 |
5 | function UIMenuGridPanel.New(TopText, LeftText, RightText, BottomText)
6 | _UIMenuGridPanel = {
7 | Data = {
8 | Enabled = true,
9 | },
10 | Background = Sprite.New("commonmenu", "gradient_bgd", 0, 0, 431, 275),
11 | Grid = Sprite.New("pause_menu_pages_char_mom_dad", "nose_grid", 0, 0, 200, 200, 0),
12 | Circle = Sprite.New("mpinventory","in_world_circle", 0, 0, 20, 20, 0),
13 | Audio = {Slider = "CONTINUOUS_SLIDER", Library = "HUD_FRONTEND_DEFAULT_SOUNDSET", Id = nil},
14 | ParentItem = nil,
15 | Text = {
16 | Top = UIResText.New(TopText or "Top", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
17 | Left = UIResText.New(LeftText or "Left", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
18 | Right = UIResText.New(RightText or "Right", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
19 | Bottom = UIResText.New(BottomText or "Bottom", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
20 | },
21 | }
22 | return setmetatable(_UIMenuGridPanel, UIMenuGridPanel)
23 | end
24 |
25 | function UIMenuGridPanel:SetParentItem(Item) -- required
26 | if Item() == "UIMenuItem" then
27 | self.ParentItem = Item
28 | else
29 | return self.ParentItem
30 | end
31 | end
32 |
33 | function UIMenuGridPanel:Enabled(Enabled)
34 | if type(Enabled) == "boolean" then
35 | self.Data.Enabled = Enabled
36 | else
37 | return self.Data.Enabled
38 | end
39 | end
40 |
41 | function UIMenuGridPanel:CirclePosition(X, Y)
42 | if tonumber(X) and tonumber(Y) then
43 | self.Circle.X = (self.Grid.X + 20) + ((self.Grid.Width - 40) * ((X >= 0.0 and X <= 1.0) and X or 0.0)) - (self.Circle.Width/2)
44 | self.Circle.Y = (self.Grid.Y + 20) + ((self.Grid.Height - 40) * ((Y >= 0.0 and Y <= 1.0) and Y or 0.0)) - (self.Circle.Height/2)
45 | else
46 | return math.round((self.Circle.X - (self.Grid.X + 20) + (self.Circle.Width/2))/(self.Grid.Width - 40), 2), math.round((self.Circle.Y - (self.Grid.Y + 20) + (self.Circle.Height/2))/(self.Grid.Height - 40), 2)
47 | end
48 | end
49 |
50 | function UIMenuGridPanel:Position(Y) -- required
51 | if tonumber(Y) then
52 | local ParentOffsetX, ParentOffsetWidth = self.ParentItem:Offset().X, self.ParentItem:SetParentMenu().WidthOffset
53 |
54 | self.Background:Position(ParentOffsetX, Y)
55 | self.Grid:Position(ParentOffsetX + 115.5 + (ParentOffsetWidth/2), 37.5 + Y)
56 | self.Text.Top:Position(ParentOffsetX + 215.5 + (ParentOffsetWidth/2), 5 + Y)
57 | self.Text.Left:Position(ParentOffsetX + 57.75 + (ParentOffsetWidth/2), 120 + Y)
58 | self.Text.Right:Position(ParentOffsetX + 373.25 + (ParentOffsetWidth/2), 120 + Y)
59 | self.Text.Bottom:Position(ParentOffsetX + 215.5 + (ParentOffsetWidth/2), 240 + Y)
60 |
61 | if not self.CircleLocked then
62 | self.CircleLocked = true
63 | self:CirclePosition(0.5, 0.5)
64 | end
65 | end
66 | end
67 |
68 | function UIMenuGridPanel:UpdateParent(X, Y)
69 | local _, ParentType = self.ParentItem()
70 | self.Data.Value = {X = X, Y = Y}
71 | if ParentType == "UIMenuListItem" then
72 | local PanelItemIndex = self.ParentItem:FindPanelItem()
73 | if PanelItemIndex then
74 | self.ParentItem.Items[PanelItemIndex].Value[self.ParentItem:FindPanelIndex(self)] = {X = X, Y = Y}
75 | self.ParentItem:Index(PanelItemIndex)
76 | self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
77 | self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
78 | else
79 | local PanelIndex = self.ParentItem:FindPanelIndex(self)
80 | for Index = 1, #self.ParentItem.Items do
81 | if type(self.ParentItem.Items[Index]) == "table" then
82 | if not self.ParentItem.Items[Index].Panels then self.ParentItem.Items[Index].Panels = {} end
83 | self.ParentItem.Items[Index].Panels[PanelIndex] = {X = X, Y = Y}
84 | else
85 | self.ParentItem.Items[Index] = {Name = tostring(self.ParentItem.Items[Index]), Value = self.ParentItem.Items[Index], Panels = {[PanelIndex] = {X = X, Y = Y}}}
86 | end
87 | end
88 | self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
89 | self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
90 | end
91 | elseif ParentType == "UIMenuItem" then
92 | self.ParentItem.ActivatedPanel(self.ParentItem.ParentMenu, self.ParentItem, self, {X = X, Y = Y})
93 | end
94 | end
95 |
96 | function UIMenuGridPanel:Functions()
97 | local SafeZone = {X = 0, Y = 0}
98 | if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then
99 | SafeZone = GetSafeZoneBounds()
100 | end
101 |
102 | if IsMouseInBounds(self.Grid.X + 20 + SafeZone.X, self.Grid.Y + 20 + SafeZone.Y, self.Grid.Width - 40, self.Grid.Height - 40) then
103 | if IsDisabledControlJustPressed(0, 24) then
104 | if not self.Pressed then
105 | self.Pressed = true
106 | Citizen.CreateThread(function()
107 | self.Audio.Id = GetSoundId()
108 | PlaySoundFrontend(self.Audio.Id, self.Audio.Slider, self.Audio.Library, 1)
109 | while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.Grid.X + 20 + SafeZone.X, self.Grid.Y + 20 + SafeZone.Y, self.Grid.Width - 40, self.Grid.Height - 40) do
110 | Citizen.Wait(0)
111 | local CursorX, CursorY = math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X - (self.Circle.Width/2), math.round(GetControlNormal(0, 240) * 1080) - SafeZone.Y - (self.Circle.Height/2)
112 |
113 | self.Circle:Position(((CursorX > (self.Grid.X + 10 + self.Grid.Width - 40)) and (self.Grid.X + 10 + self.Grid.Width - 40) or ((CursorX < (self.Grid.X + 20 - (self.Circle.Width/2))) and (self.Grid.X + 20 - (self.Circle.Width/2)) or CursorX)), ((CursorY > (self.Grid.Y + 10 + self.Grid.Height - 40)) and (self.Grid.Y + 10 + self.Grid.Height - 40) or ((CursorY < (self.Grid.Y + 20 - (self.Circle.Height/2))) and (self.Grid.Y + 20 - (self.Circle.Height/2)) or CursorY)))
114 | end
115 | StopSound(self.Audio.Id)
116 | ReleaseSoundId(self.Audio.Id)
117 | self.Pressed = false
118 | end)
119 | Citizen.CreateThread(function()
120 | while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.Grid.X + 20 + SafeZone.X, self.Grid.Y + 20 + SafeZone.Y, self.Grid.Width - 40, self.Grid.Height - 40) do
121 | Citizen.Wait(75)
122 | local ResultX, ResultY = math.round((self.Circle.X - (self.Grid.X + 20) + (self.Circle.Width/2))/(self.Grid.Width - 40), 2), math.round((self.Circle.Y - (self.Grid.Y + 20) + (self.Circle.Height/2))/(self.Grid.Height - 40), 2)
123 |
124 | self:UpdateParent((((ResultX >= 0.0 and ResultX <= 1.0) and ResultX or ((ResultX <= 0) and 0.0) or 1.0) * 2) - 1, (((ResultY >= 0.0 and ResultY <= 1.0) and ResultY or ((ResultY <= 0) and 0.0) or 1.0) * 2) - 1)
125 | end
126 | end)
127 | end
128 | end
129 | end
130 | end
131 |
132 | function UIMenuGridPanel:Draw() -- required
133 | if self.Data.Enabled then
134 | self.Background:Size(431 + self.ParentItem:SetParentMenu().WidthOffset, 275)
135 |
136 | self.Background:Draw()
137 | self.Grid:Draw()
138 | self.Circle:Draw()
139 | self.Text.Top:Draw()
140 | self.Text.Left:Draw()
141 | self.Text.Right:Draw()
142 | self.Text.Bottom:Draw()
143 | self:Functions()
144 | end
145 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/panels/UIMenuPercentagePanel.lua:
--------------------------------------------------------------------------------
1 | UIMenuPercentagePanel = setmetatable({}, UIMenuPercentagePanel)
2 | UIMenuPercentagePanel.__index = UIMenuPercentagePanel
3 | UIMenuPercentagePanel.__call = function() return "UIMenuPanel", "UIMenuPercentagePanel" end
4 |
5 | function UIMenuPercentagePanel.New(MinText, MaxText)
6 | _UIMenuPercentagePanel = {
7 | Data = {
8 | Enabled = true,
9 | },
10 | Background = Sprite.New("commonmenu", "gradient_bgd", 0, 0, 431, 76),
11 | ActiveBar = UIResRectangle.New(0, 0, 413, 10, 245, 245, 245, 255),
12 | BackgroundBar = UIResRectangle.New(0, 0, 413, 10, 87, 87, 87, 255),
13 | Text = {
14 | Min = UIResText.New(MinText or "0%", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
15 | Max = UIResText.New("100%", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
16 | Title = UIResText.New(MaxText or "Opacity", 0, 0, 0.35, 255, 255, 255, 255, 0, "Centre"),
17 | },
18 | Audio = {Slider = "CONTINUOUS_SLIDER", Library = "HUD_FRONTEND_DEFAULT_SOUNDSET", Id = nil},
19 | ParentItem = nil,
20 | }
21 |
22 | return setmetatable(_UIMenuPercentagePanel, UIMenuPercentagePanel)
23 | end
24 |
25 | function UIMenuPercentagePanel:SetParentItem(Item) -- required
26 | if Item() == "UIMenuItem" then
27 | self.ParentItem = Item
28 | else
29 | return self.ParentItem
30 | end
31 | end
32 |
33 | function UIMenuPercentagePanel:Enabled(Enabled)
34 | if type(Enabled) == "boolean" then
35 | self.Data.Enabled = Enabled
36 | else
37 | return self.Data.Enabled
38 | end
39 | end
40 |
41 | function UIMenuPercentagePanel:Position(Y) -- required
42 | if tonumber(Y) then
43 | local ParentOffsetX, ParentOffsetWidth = self.ParentItem:Offset().X, self.ParentItem:SetParentMenu().WidthOffset
44 | self.Background:Position(ParentOffsetX, Y)
45 | self.ActiveBar:Position(ParentOffsetX + (ParentOffsetWidth/2) + 9, 50 + Y)
46 | self.BackgroundBar:Position(ParentOffsetX + (ParentOffsetWidth/2) + 9, 50 + Y)
47 | self.Text.Min:Position(ParentOffsetX + (ParentOffsetWidth/2) + 25, 15 + Y)
48 | self.Text.Max:Position(ParentOffsetX + (ParentOffsetWidth/2) + 398, 15 + Y)
49 | self.Text.Title:Position(ParentOffsetX + (ParentOffsetWidth/2) + 215.5, 15 + Y)
50 | end
51 | end
52 |
53 | function UIMenuPercentagePanel:Percentage(Value)
54 | if tonumber(Value) then
55 | local Percent = ((Value < 0.0) and 0.0) or ((Value > 1.0) and 1.0 or Value)
56 | self.ActiveBar:Size(self.BackgroundBar.Width * Percent, self.ActiveBar.Height)
57 | else
58 | local SafeZone = {X = 0, Y = 0}
59 | if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then
60 | SafeZone = GetSafeZoneBounds()
61 | end
62 |
63 | local Progress = (math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) - self.ActiveBar.X
64 | return math.round(((Progress >= 0 and Progress <= 413) and Progress or ((Progress < 0) and 0 or 413))/self.BackgroundBar.Width, 2)
65 | end
66 | end
67 |
68 | function UIMenuPercentagePanel:UpdateParent(Percentage)
69 | local _, ParentType = self.ParentItem()
70 | if ParentType == "UIMenuListItem" then
71 | local PanelItemIndex = self.ParentItem:FindPanelItem()
72 | if PanelItemIndex then
73 | self.ParentItem.Items[PanelItemIndex].Value[self.ParentItem:FindPanelIndex(self)] = Percentage
74 | self.ParentItem:Index(PanelItemIndex)
75 | self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
76 | self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
77 | else
78 | local PanelIndex = self.ParentItem:FindPanelIndex(self)
79 | for Index = 1, #self.ParentItem.Items do
80 | if type(self.ParentItem.Items[Index]) == "table" then
81 | if not self.ParentItem.Items[Index].Panels then self.ParentItem.Items[Index].Panels = {} end
82 | self.ParentItem.Items[Index].Panels[PanelIndex] = Percentage
83 | else
84 | self.ParentItem.Items[Index] = {Name = tostring(self.ParentItem.Items[Index]), Value = self.ParentItem.Items[Index], Panels = {[PanelIndex] = Percentage}}
85 | end
86 | end
87 | self.ParentItem.Base.ParentMenu.OnListChange(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
88 | self.ParentItem.OnListChanged(self.ParentItem.Base.ParentMenu, self.ParentItem, self.ParentItem._Index)
89 | end
90 | elseif ParentType == "UIMenuItem" then
91 | self.ParentItem.ActivatedPanel(self.ParentItem.ParentMenu, self.ParentItem, self, Percentage)
92 | end
93 | end
94 |
95 | function UIMenuPercentagePanel:Functions()
96 |
97 | local SafeZone = {X = 0, Y = 0}
98 | if self.ParentItem:SetParentMenu().Settings.ScaleWithSafezone then
99 | SafeZone = GetSafeZoneBounds()
100 | end
101 |
102 | if IsMouseInBounds(self.BackgroundBar.X + SafeZone.X, self.BackgroundBar.Y - 4 + SafeZone.Y, self.BackgroundBar.Width, self.BackgroundBar.Height + 8) then
103 | if IsDisabledControlJustPressed(0, 24) then
104 | if not self.Pressed then
105 | self.Pressed = true
106 | Citizen.CreateThread(function()
107 | self.Audio.Id = GetSoundId()
108 | PlaySoundFrontend(self.Audio.Id, self.Audio.Slider, self.Audio.Library, 1)
109 | while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.BackgroundBar.X + SafeZone.X, self.BackgroundBar.Y - 4 + SafeZone.Y, self.BackgroundBar.Width, self.BackgroundBar.Height + 8) do
110 | Citizen.Wait(0)
111 | local Progress = (math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) - self.ActiveBar.X
112 | self.ActiveBar:Size(((Progress >= 0 and Progress <= 413) and Progress or ((Progress < 0) and 0 or 413)), self.ActiveBar.Height)
113 | end
114 | StopSound(self.Audio.Id)
115 | ReleaseSoundId(self.Audio.Id)
116 | self.Pressed = false
117 | end)
118 | Citizen.CreateThread(function()
119 | while IsDisabledControlPressed(0, 24) and IsMouseInBounds(self.BackgroundBar.X + SafeZone.X, self.BackgroundBar.Y - 4 + SafeZone.Y, self.BackgroundBar.Width, self.BackgroundBar.Height + 8) do
120 | Citizen.Wait(75)
121 | local Progress = (math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X) - self.ActiveBar.X
122 | self:UpdateParent(math.round(((Progress >= 0 and Progress <= 413) and Progress or ((Progress < 0) and 0 or 413))/self.BackgroundBar.Width, 2))
123 | end
124 | end)
125 | end
126 | end
127 | end
128 | end
129 |
130 | function UIMenuPercentagePanel:Draw() -- required
131 | if self.Data.Enabled then
132 | self.Background:Size(431 + self.ParentItem:SetParentMenu().WidthOffset, 76)
133 | self.Background:Draw()
134 | self.BackgroundBar:Draw()
135 | self.ActiveBar:Draw()
136 | self.Text.Min:Draw()
137 | self.Text.Max:Draw()
138 | self.Text.Title:Draw()
139 | self:Functions()
140 | end
141 | end
--------------------------------------------------------------------------------
/NativeUI from Frazzle/windows/UIMenuHeritageWindow.lua:
--------------------------------------------------------------------------------
1 | UIMenuHeritageWindow = setmetatable({}, UIMenuHeritageWindow)
2 | UIMenuHeritageWindow.__index = UIMenuHeritageWindow
3 | UIMenuHeritageWindow.__call = function() return "UIMenuWindow", "UIMenuHeritageWindow" end
4 |
5 | function UIMenuHeritageWindow.New(Mum, Dad)
6 | if not tonumber(Mum) then Mum = 0 end
7 | if not (Mum >= 0 and Mum <= 21) then Mum = 0 end
8 | if not tonumber(Dad) then Dad = 0 end
9 | if not (Dad >= 0 and Dad <= 23) then Dad = 0 end
10 | _UIMenuHeritageWindow = {
11 | Background = Sprite.New("pause_menu_pages_char_mom_dad", "mumdadbg", 0, 0, 431, 228), -- Background is required, must be a sprite or a rectangle.
12 | MumSprite = Sprite.New("char_creator_portraits", ((Mum < 21) and "female_"..Mum or "special_female_"..(tonumber(string.sub(Mum, 2, 2)) - 1)), 0, 0, 228, 228),
13 | DadSprite = Sprite.New("char_creator_portraits", ((Dad < 21) and "male_"..Dad or "special_male_"..(tonumber(string.sub(Dad, 2, 2)) - 1)), 0, 0, 228, 228),
14 | Mum = Mum,
15 | Dad = Dad,
16 | _Offset = {X = 0, Y = 0}, -- required
17 | ParentMenu = nil, -- required
18 | }
19 | return setmetatable(_UIMenuHeritageWindow, UIMenuHeritageWindow)
20 | end
21 |
22 | function UIMenuHeritageWindow:SetParentMenu(Menu) -- required
23 | if Menu() == "UIMenu" then
24 | self.ParentMenu = Menu
25 | else
26 | return self.ParentMenu
27 | end
28 | end
29 |
30 | function UIMenuHeritageWindow:Offset(X, Y) -- required
31 | if tonumber(X) or tonumber(Y) then
32 | if tonumber(X) then
33 | self._Offset.X = tonumber(X)
34 | end
35 | if tonumber(Y) then
36 | self._Offset.Y = tonumber(Y)
37 | end
38 | else
39 | return self._Offset
40 | end
41 | end
42 |
43 | function UIMenuHeritageWindow:Position(Y) -- required
44 | if tonumber(Y) then
45 | self.Background:Position(self._Offset.X, 144 + Y + self._Offset.Y)
46 | self.MumSprite:Position(self._Offset.X + (self.ParentMenu.WidthOffset/2) + 25, 144 + Y + self._Offset.Y)
47 | self.DadSprite:Position(self._Offset.X + (self.ParentMenu.WidthOffset/2) + 195, 144 + Y + self._Offset.Y)
48 | end
49 | end
50 |
51 | function UIMenuHeritageWindow:Index(Mum, Dad)
52 | if not tonumber(Mum) then Mum = self.Mum end
53 | if not (Mum >= 0 and Mum <= 21) then Mum = self.Mum end
54 | if not tonumber(Dad) then Dad = self.Dad end
55 | if not (Dad >= 0 and Dad <= 23) then Dad = self.Dad end
56 |
57 | self.Mum = Mum
58 | self.Dad = Dad
59 |
60 | self.MumSprite.TxtName = ((self.Mum < 21) and "female_"..self.Mum or "special_female_"..(tonumber(string.sub(Mum, 2, 2)) - 1))
61 | self.DadSprite.TxtName = ((self.Dad < 21) and "male_"..self.Dad or "special_male_"..(tonumber(string.sub(Dad, 2, 2)) - 1))
62 | end
63 |
64 | function UIMenuHeritageWindow:Draw() -- required
65 | self.Background:Size(431 + self.ParentMenu.WidthOffset, 228)
66 | self.Background:Draw()
67 | self.DadSprite:Draw()
68 | self.MumSprite:Draw()
69 | end
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SimpleMenu
2 |
3 | [Visit the Wiki for MORE!](https://github.com/Thymester/SimpleMenu/wiki)
4 |
5 | # NOTE
6 |
7 | The code is a absolute mess. This was my first ever project and was extremely bad at coding.
8 |
--------------------------------------------------------------------------------
/Tutorial.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
# SimpleMenu Group
41 |
42 |
1: Uncomment Lines 453 - 458
78 |1: Download the Menu from FiveM Forums: SimpleMenu
84 |2: Drag & Drop the two folders into resources
85 |3: In order do the following:
86 |start NativeUI
start SimpleMenu
4: Do not change the name of any folders to maintain case sensitivity in server.cfg
- You may use this in any private or public project!
89 |Visit Releases at GitHub for Releases!
95 |# SimpleMenu Group
101 |add_ace identifier.steam:[Steam HEX Here] simplemenu.admin allow --Name of Person Here
add_ace identifier.steam:[Steam HEX Here] simplemenu.state allow --Name of Person Here
add_ace identifier.steam:[Steam HEX Here] simplemenu.highway allow --Name of Person Here
add_ace identifier.steam:[Steam HEX Here] simplemenu.sheriff allow --Name of Person Here
add_ace identifier.steam:[Steam HEX Here] simplemenu.emt allow --Name of Person Here
add_ace identifier.steam:[Steam HEX Here] simplemenu.emergency allow --Name of Person Here
1: Go to line 1871
113 |2: Uncomment lines 1871 - 1881
114 |NOTE: To uncomment, remove ""
115 |1: Go to lines 386 - 406
121 |2: Add Emergency Services spawn codes (On your server) to be able to spawn them in-game
122 |3: Must reload script after changes
123 |1: Go to 452 - 457
129 |2: Uncomment those lines by removing the two "--" before each submenu:AddItem()
1: Go to line 1681 and uncomment it
136 |2: Go to line 1683 and uncomment it
137 |3: Go to line 1689 and uncomment it which is commented from 1689 - 1693 (Remove "")
138 |To add the Custom Peds and Custom Cars, follow the templates located on lines 310 & 1234
139 |1: Healing
145 |2: Armour Giving
146 |3: Godmode
147 |4: Invisibility
148 |NOTE: There may or may not be more added from updates.
149 |For Custom Car Spawns
155 |1: Uncomment lines 385 & 387 (To uncomment, remove "--")
156 |2: Uncomment lines 393 - 397 (To uncomment, remove "")
157 |For Custom Ped Spawns
158 |1: Uncomment lines 1286 & 1288 (To uncomment, remove "--")
159 |2: Uncomment lines 1294 - 1298 (To uncomment, remove "")
160 |To add the Custom Peds and Custom Cars, follow the templates located on lines 310 & 1234
161 |NativeUI is from Frazzle, not myself. If you wish to download the files located on GitHub (SimpleMenu & NativeUI), they are NOT in a drag & drop format!
168 |