├── .prettierignore ├── .gitignore ├── examples └── nativeUI-example │ ├── src │ ├── include │ │ └── nativeui │ │ │ ├── utils │ │ │ ├── UUIDV4.d.ts │ │ │ ├── Number.d.ts │ │ │ ├── Common.d.ts │ │ │ ├── Size.d.ts │ │ │ ├── Point.d.ts │ │ │ ├── Color.d.ts │ │ │ ├── Scaleform.d.ts │ │ │ ├── LiteEvent.d.ts │ │ │ └── Screen.d.ts │ │ │ ├── modules │ │ │ ├── IElement.d.ts │ │ │ ├── ListItem.d.ts │ │ │ ├── ItemsCollection.d.ts │ │ │ ├── Container.d.ts │ │ │ ├── Rectangle.d.ts │ │ │ ├── ResRectangle.d.ts │ │ │ ├── InstructionalButton.d.ts │ │ │ ├── Text.d.ts │ │ │ ├── ResText.d.ts │ │ │ ├── MidsizedMessage.d.ts │ │ │ ├── Sprite.d.ts │ │ │ ├── Message.d.ts │ │ │ └── BigMessage.d.ts │ │ │ ├── enums │ │ │ ├── ChangeDirection.d.ts │ │ │ ├── Alignment.d.ts │ │ │ ├── Font.d.ts │ │ │ ├── BadgeStyle.d.ts │ │ │ ├── HudColor.d.ts │ │ │ └── Control.d.ts │ │ │ ├── items │ │ │ ├── UIMenuCheckboxItem.d.ts │ │ │ ├── UIMenuSliderItem.d.ts │ │ │ ├── UIMenuListItem.d.ts │ │ │ ├── UIMenuAutoListItem.d.ts │ │ │ ├── UIMenuDynamicListItem.d.ts │ │ │ └── UIMenuItem.d.ts │ │ │ └── NativeUi.d.ts │ └── tsconfig.json │ ├── .gitignore │ ├── fxmanifest.lua │ ├── client.config.js │ └── package.json ├── src ├── enums │ ├── ChangeDirection.ts │ ├── Alignment.ts │ ├── Font.ts │ ├── ChangeDirection.js │ ├── Alignment.js │ ├── Font.js │ ├── BadgeStyle.ts │ ├── BadgeStyle.js │ ├── HudColor.ts │ └── Control.ts ├── modules │ ├── IElement.js │ ├── IElement.ts │ ├── ListItem.js │ ├── ListItem.ts │ ├── InstructionalButton.js │ ├── ItemsCollection.ts │ ├── ItemsCollection.js │ ├── Rectangle.js │ ├── Rectangle.ts │ ├── ResRectangle.js │ ├── Container.js │ ├── MidsizedMessage.js │ ├── ResRectangle.ts │ ├── Container.ts │ ├── MidsizedMessage.ts │ ├── InstructionalButton.ts │ ├── Text.js │ ├── BigMessage.js │ ├── Sprite.js │ ├── BigMessage.ts │ ├── Text.ts │ ├── ResText.js │ ├── Sprite.ts │ ├── Message.js │ ├── ResText.ts │ └── Message.ts ├── utils │ ├── Size.js │ ├── Common.ts │ ├── Common.js │ ├── Size.ts │ ├── Number.js │ ├── Number.ts │ ├── Color.js │ ├── LiteEvent.js │ ├── Color.ts │ ├── UUIDV4.ts │ ├── UUIDV4.js │ ├── LiteEvent.ts │ ├── Point.js │ ├── Point.ts │ ├── Screen.js │ ├── Scaleform.js │ ├── Scaleform.ts │ └── Screen.ts └── items │ ├── UIMenuCheckboxItem.js │ ├── UIMenuCheckboxItem.ts │ ├── UIMenuSliderItem.js │ ├── UIMenuSliderItem.ts │ ├── UIMenuDynamicListItem.js │ ├── UIMenuListItem.js │ ├── UIMenuListItem.ts │ ├── UIMenuDynamicListItem.ts │ ├── UIMenuAutoListItem.js │ ├── UIMenuAutoListItem.ts │ ├── UIMenuItem.js │ └── UIMenuItem.ts ├── rollup.config.js ├── tsconfig.json ├── package.json ├── README.md └── LICENSE /.prettierignore: -------------------------------------------------------------------------------- 1 | StringMeasurer.ts -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | index.js 2 | dist/ 3 | node_modules/ 4 | package-lock.json 5 | .npmrc 6 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/UUIDV4.d.ts: -------------------------------------------------------------------------------- 1 | export default function UUIDV4(): string; 2 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/Number.d.ts: -------------------------------------------------------------------------------- 1 | export declare const fixFloat: (n: number) => number; 2 | -------------------------------------------------------------------------------- /src/enums/ChangeDirection.ts: -------------------------------------------------------------------------------- 1 | enum ChangeDirection { 2 | Left, 3 | Right 4 | } 5 | 6 | export default ChangeDirection; -------------------------------------------------------------------------------- /src/enums/Alignment.ts: -------------------------------------------------------------------------------- 1 | export enum Alignment { 2 | Left, 3 | Centered, 4 | Right 5 | } 6 | 7 | export default Alignment; -------------------------------------------------------------------------------- /src/modules/IElement.js: -------------------------------------------------------------------------------- 1 | export default class IElement { 2 | constructor() { 3 | this.Enabled = true; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /examples/nativeUI-example/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | dist/ 3 | node_modules/ 4 | package-lock.json 5 | yarn-error.log 6 | yarn.lock 7 | *.zip -------------------------------------------------------------------------------- /src/modules/IElement.ts: -------------------------------------------------------------------------------- 1 | export default class IElement { 2 | public Enabled: boolean; 3 | 4 | constructor() { 5 | this.Enabled = true; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/Size.js: -------------------------------------------------------------------------------- 1 | export default class Size { 2 | constructor(w = 0, h = 0) { 3 | this.Width = w; 4 | this.Height = h; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/IElement.d.ts: -------------------------------------------------------------------------------- 1 | export default class IElement { 2 | Enabled: boolean; 3 | constructor(); 4 | } 5 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/Common.d.ts: -------------------------------------------------------------------------------- 1 | export default class Common { 2 | static PlaySound(audioName: string, audioRef: string): void; 3 | } 4 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/enums/ChangeDirection.d.ts: -------------------------------------------------------------------------------- 1 | declare enum ChangeDirection { 2 | Left = 0, 3 | Right = 1 4 | } 5 | export default ChangeDirection; 6 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/Size.d.ts: -------------------------------------------------------------------------------- 1 | export default class Size { 2 | Width: number; 3 | Height: number; 4 | constructor(w?: number, h?: number); 5 | } 6 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/enums/Alignment.d.ts: -------------------------------------------------------------------------------- 1 | export declare enum Alignment { 2 | Left = 0, 3 | Centered = 1, 4 | Right = 2 5 | } 6 | export default Alignment; 7 | -------------------------------------------------------------------------------- /src/enums/Font.ts: -------------------------------------------------------------------------------- 1 | enum Font { 2 | ChaletLondon = 0, 3 | HouseScript = 1, 4 | Monospace = 2, 5 | CharletComprimeColonge = 4, 6 | Pricedown = 7 7 | } 8 | 9 | export default Font; 10 | -------------------------------------------------------------------------------- /examples/nativeUI-example/fxmanifest.lua: -------------------------------------------------------------------------------- 1 | resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9' 2 | 3 | fx_version 'adamant' 4 | game 'common' 5 | 6 | client_scripts { 7 | 'dist/client.js', 8 | } -------------------------------------------------------------------------------- /src/utils/Common.ts: -------------------------------------------------------------------------------- 1 | export default class Common { 2 | public static PlaySound(audioName: string, audioRef: string) { 3 | PlaySound(-1, audioName, audioRef, false, 0, true); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/utils/Common.js: -------------------------------------------------------------------------------- 1 | import game from 'natives'; 2 | export default class Common { 3 | static PlaySound(audioName, audioRef) { 4 | PlaySound(-1, audioName, audioRef, false, 0, true); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/Size.ts: -------------------------------------------------------------------------------- 1 | export default class Size { 2 | public Width: number; 3 | public Height: number; 4 | 5 | constructor(w: number = 0, h: number = 0) { 6 | this.Width = w; 7 | this.Height = h; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/ListItem.d.ts: -------------------------------------------------------------------------------- 1 | export default class ListItem { 2 | readonly Id: string; 3 | DisplayText: string; 4 | Data: any; 5 | constructor(text?: string, data?: any); 6 | } 7 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/enums/Font.d.ts: -------------------------------------------------------------------------------- 1 | declare enum Font { 2 | ChaletLondon = 0, 3 | HouseScript = 1, 4 | Monospace = 2, 5 | CharletComprimeColonge = 4, 6 | Pricedown = 7 7 | } 8 | export default Font; 9 | -------------------------------------------------------------------------------- /src/modules/ListItem.js: -------------------------------------------------------------------------------- 1 | import UUIDV4 from "../utils/UUIDV4"; 2 | export default class ListItem { 3 | constructor(text = "", data = null) { 4 | this.Id = UUIDV4(); 5 | this.DisplayText = text; 6 | this.Data = data; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/enums/ChangeDirection.js: -------------------------------------------------------------------------------- 1 | var ChangeDirection; 2 | (function (ChangeDirection) { 3 | ChangeDirection[ChangeDirection["Left"] = 0] = "Left"; 4 | ChangeDirection[ChangeDirection["Right"] = 1] = "Right"; 5 | })(ChangeDirection || (ChangeDirection = {})); 6 | export default ChangeDirection; 7 | -------------------------------------------------------------------------------- /src/enums/Alignment.js: -------------------------------------------------------------------------------- 1 | export var Alignment; 2 | (function (Alignment) { 3 | Alignment[Alignment["Left"] = 0] = "Left"; 4 | Alignment[Alignment["Centered"] = 1] = "Centered"; 5 | Alignment[Alignment["Right"] = 2] = "Right"; 6 | })(Alignment || (Alignment = {})); 7 | export default Alignment; 8 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/ItemsCollection.d.ts: -------------------------------------------------------------------------------- 1 | import ListItem from "../modules/ListItem"; 2 | export default class ItemsCollection { 3 | private items; 4 | constructor(items: ListItem[] | string[] | number[]); 5 | length(): number; 6 | getListItems(): any[]; 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/Number.js: -------------------------------------------------------------------------------- 1 | Number.isInteger = Number.isInteger || function (value) { 2 | return typeof value === 'number' && 3 | isFinite(value) && 4 | Math.floor(value) === value; 5 | }; 6 | export const fixFloat = (n) => { 7 | return Number.isInteger(n) ? n : parseFloat(n.toFixed(10)); 8 | }; 9 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/Point.d.ts: -------------------------------------------------------------------------------- 1 | export default class Point { 2 | X: number; 3 | Y: number; 4 | constructor(x: number, y: number); 5 | static Parse(point: number[]): Point; 6 | static Parse(point: { 7 | X: number; 8 | Y: number; 9 | }): Point; 10 | } 11 | -------------------------------------------------------------------------------- /src/modules/ListItem.ts: -------------------------------------------------------------------------------- 1 | import UUIDV4 from "../utils/UUIDV4"; 2 | 3 | export default class ListItem { 4 | public readonly Id: string = UUIDV4(); 5 | 6 | public DisplayText: string; 7 | public Data: any; 8 | 9 | constructor(text: string = "", data: any = null) { 10 | this.DisplayText = text; 11 | this.Data = data; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/utils/Number.ts: -------------------------------------------------------------------------------- 1 | Number.isInteger = Number.isInteger || function(value) { 2 | return typeof value === 'number' && 3 | isFinite(value) && 4 | Math.floor(value) === value; 5 | }; 6 | 7 | export const 8 | fixFloat = (n: number) => { 9 | return Number.isInteger(n) ? n : parseFloat(n.toFixed(10)); 10 | } 11 | ; -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/Color.d.ts: -------------------------------------------------------------------------------- 1 | export default class Color { 2 | static Empty: Color; 3 | static Transparent: Color; 4 | static Black: Color; 5 | static White: Color; 6 | static WhiteSmoke: Color; 7 | R: number; 8 | G: number; 9 | B: number; 10 | A: number; 11 | constructor(r: number, g: number, b: number, a?: number); 12 | } 13 | -------------------------------------------------------------------------------- /src/enums/Font.js: -------------------------------------------------------------------------------- 1 | var Font; 2 | (function (Font) { 3 | Font[Font["ChaletLondon"] = 0] = "ChaletLondon"; 4 | Font[Font["HouseScript"] = 1] = "HouseScript"; 5 | Font[Font["Monospace"] = 2] = "Monospace"; 6 | Font[Font["CharletComprimeColonge"] = 4] = "CharletComprimeColonge"; 7 | Font[Font["Pricedown"] = 7] = "Pricedown"; 8 | })(Font || (Font = {})); 9 | export default Font; 10 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/Container.d.ts: -------------------------------------------------------------------------------- 1 | import Size from "../utils/Size"; 2 | import Rectangle from "./Rectangle"; 3 | import Point from '../utils/Point'; 4 | import Color from '../utils/Color'; 5 | export default class Container extends Rectangle { 6 | Items: any[]; 7 | constructor(pos: Point, size: Size, color: Color); 8 | addItem(item: any): void; 9 | Draw(offset?: Size): void; 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/Color.js: -------------------------------------------------------------------------------- 1 | export default class Color { 2 | constructor(r, g, b, a = 255) { 3 | this.R = r; 4 | this.G = g; 5 | this.B = b; 6 | this.A = a; 7 | } 8 | } 9 | Color.Empty = new Color(0, 0, 0, 0); 10 | Color.Transparent = new Color(0, 0, 0, 0); 11 | Color.Black = new Color(0, 0, 0, 255); 12 | Color.White = new Color(255, 255, 255, 255); 13 | Color.WhiteSmoke = new Color(245, 245, 245, 255); 14 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/Rectangle.d.ts: -------------------------------------------------------------------------------- 1 | import Color from "../utils/Color"; 2 | import Point from "../utils/Point"; 3 | import Size from "../utils/Size"; 4 | import IElement from "./IElement"; 5 | export default class Rectangle extends IElement { 6 | Pos: Point; 7 | Size: Size; 8 | Color: Color; 9 | constructor(pos: Point, size: Size, color: Color); 10 | Draw(pos: Point | Size, size: Size, color: Color): void; 11 | } 12 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/ResRectangle.d.ts: -------------------------------------------------------------------------------- 1 | import Point from "../utils/Point"; 2 | import Size from "../utils/Size"; 3 | import Rectangle from "./Rectangle"; 4 | import Color from '../utils/Color'; 5 | export default class ResRectangle extends Rectangle { 6 | constructor(pos: Point, size: Size, color: Color); 7 | Draw(): void; 8 | Draw(offset: any): void; 9 | Draw(pos: Point | Size, size: Size, color: Color): void; 10 | } 11 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "*": ["types/*"] 6 | }, 7 | "outDir": "./", 8 | "noImplicitAny": false, 9 | "module": "es6", 10 | "target": "es6", 11 | "allowJs": true, 12 | "lib": ["es2017"], 13 | "types": ["@citizenfx/client", "@types/node"], 14 | "moduleResolution": "node" 15 | }, 16 | "include": ["./**/*"], 17 | "exclude": [] 18 | } 19 | -------------------------------------------------------------------------------- /src/enums/BadgeStyle.ts: -------------------------------------------------------------------------------- 1 | enum BadgeStyle { 2 | None, 3 | BronzeMedal, 4 | GoldMedal, 5 | SilverMedal, 6 | Alert, 7 | Crown, 8 | Ammo, 9 | Armour, 10 | Barber, 11 | Clothes, 12 | Franklin, 13 | Bike, 14 | Car, 15 | Gun, 16 | Heart, 17 | Makeup, 18 | Mask, 19 | Michael, 20 | Star, 21 | Tattoo, 22 | Trevor, 23 | Lock, 24 | Tick, 25 | Sale, 26 | ArrowLeft, 27 | ArrowRight, 28 | Audio1, 29 | Audio2, 30 | Audio3, 31 | AudioInactive, 32 | AudioMute 33 | } 34 | 35 | export default BadgeStyle; 36 | -------------------------------------------------------------------------------- /src/utils/LiteEvent.js: -------------------------------------------------------------------------------- 1 | export default class LiteEvent { 2 | constructor() { 3 | this.handlers = []; 4 | } 5 | on(handler) { 6 | this.handlers.push(handler); 7 | } 8 | off(handler) { 9 | this.handlers = this.handlers.filter(h => h !== handler); 10 | } 11 | emit(...args) { 12 | this.handlers.slice(0).forEach(h => h(...args)); 13 | } 14 | expose() { 15 | return this; 16 | } 17 | count() { 18 | return this.handlers.length; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/items/UIMenuCheckboxItem.d.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import UIMenuItem from "./UIMenuItem"; 3 | export default class UIMenuCheckboxItem extends UIMenuItem { 4 | private readonly _checkedSprite; 5 | Checked: boolean; 6 | constructor(text: string, check?: boolean, description?: string); 7 | SetVerticalPosition(y: number): void; 8 | Draw(): void; 9 | SetRightBadge(badge: BadgeStyle): this; 10 | SetRightLabel(text: string): this; 11 | } 12 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/Scaleform.d.ts: -------------------------------------------------------------------------------- 1 | export default class Scaleform { 2 | private _handle; 3 | private scaleForm; 4 | constructor(scaleForm: string); 5 | get handle(): number; 6 | get isValid(): boolean; 7 | get isLoaded(): boolean; 8 | private callFunctionHead; 9 | callFunction(funcName: string, ...args: any[]): void; 10 | callFunctionReturn(funcName: string, ...args: any[]): number; 11 | render2D(): void; 12 | recreate(): void; 13 | destroy(): void; 14 | } 15 | -------------------------------------------------------------------------------- /examples/nativeUI-example/client.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: "./src/client.ts", 5 | module: { 6 | rules: [ 7 | { 8 | test: /\.tsx?$/, 9 | use: "ts-loader", 10 | exclude: /node_modules/ 11 | } 12 | ] 13 | }, 14 | optimization: { 15 | minimize: true 16 | }, 17 | resolve: { 18 | extensions: [".tsx", ".ts", ".js"] 19 | }, 20 | output: { 21 | filename: "client.js", 22 | path: path.resolve(__dirname, "dist") 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/InstructionalButton.d.ts: -------------------------------------------------------------------------------- 1 | import UIMenuItem from "../items/UIMenuItem"; 2 | import Control from '../enums/Control'; 3 | export default class InstructionalButton { 4 | Text: string; 5 | get ItemBind(): UIMenuItem; 6 | private _itemBind; 7 | private readonly _buttonString; 8 | private readonly _buttonControl; 9 | private readonly _usingControls; 10 | constructor(text: string, control: Control, buttonString?: string); 11 | BindToItem(item: UIMenuItem): void; 12 | GetButtonId(): string; 13 | } 14 | -------------------------------------------------------------------------------- /src/utils/Color.ts: -------------------------------------------------------------------------------- 1 | export default class Color { 2 | public static Empty = new Color(0, 0, 0, 0); 3 | public static Transparent = new Color(0, 0, 0, 0); 4 | public static Black = new Color(0, 0, 0, 255); 5 | public static White = new Color(255, 255, 255, 255); 6 | public static WhiteSmoke = new Color(245, 245, 245, 255); 7 | 8 | public R: number; 9 | public G: number; 10 | public B: number; 11 | public A: number; 12 | 13 | constructor(r: number, g: number, b: number, a = 255) { 14 | this.R = r; 15 | this.G = g; 16 | this.B = b; 17 | this.A = a; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/LiteEvent.d.ts: -------------------------------------------------------------------------------- 1 | interface ILiteEvent { 2 | on(handler: { 3 | (...args: any[]): void; 4 | }): void; 5 | off(handler: { 6 | (...args: any[]): void; 7 | }): void; 8 | } 9 | export default class LiteEvent implements ILiteEvent { 10 | private handlers; 11 | on(handler: { 12 | (...args: any[]): void; 13 | }): void; 14 | off(handler: { 15 | (...args: any[]): void; 16 | }): void; 17 | emit(...args: any[]): void; 18 | expose(): ILiteEvent; 19 | count(): number; 20 | } 21 | export {}; 22 | -------------------------------------------------------------------------------- /src/utils/UUIDV4.ts: -------------------------------------------------------------------------------- 1 | export default function UUIDV4(): string { 2 | let uuid: string = ""; 3 | let ii: number; 4 | 5 | for (ii = 0; ii < 32; ii += 1) { 6 | switch (ii) { 7 | case 8: 8 | case 20: 9 | uuid += "-"; 10 | uuid += ((Math.random() * 16) | 0).toString(16); 11 | break; 12 | case 12: 13 | uuid += "-"; 14 | uuid += "4"; 15 | break; 16 | case 16: 17 | uuid += "-"; 18 | uuid += ((Math.random() * 4) | 8).toString(16); 19 | break; 20 | default: 21 | uuid += ((Math.random() * 16) | 0).toString(16); 22 | } 23 | } 24 | return uuid; 25 | } 26 | -------------------------------------------------------------------------------- /src/modules/InstructionalButton.js: -------------------------------------------------------------------------------- 1 | export default class InstructionalButton { 2 | constructor(text, control, buttonString = null) { 3 | this._itemBind = null; 4 | this.Text = text; 5 | this._buttonControl = control; 6 | this._usingControls = buttonString == null; 7 | this._buttonString = buttonString; 8 | } 9 | get ItemBind() { return this._itemBind; } 10 | BindToItem(item) { 11 | this._itemBind = item; 12 | } 13 | GetButtonId() { 14 | return this._usingControls ? GetControlInstructionalButton(2, this._buttonControl, false) : "t_" + this._buttonString; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/nativeUI-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nativeui-example", 3 | "version": "1.0.0", 4 | "repository": "https://github.com/PichotM/FiveM-NativeUI", 5 | "author": "PichotM", 6 | "scripts": { 7 | "build": "webpack --mode production --config client.config.js", 8 | "watch": "webpack --mode development --watch true --config client.config.js" 9 | }, 10 | "license": "MIT", 11 | "private": false, 12 | "devDependencies": { 13 | "@citizenfx/client": "^1.0.2692-1", 14 | "@types/node": "^12.7.7", 15 | "ts-loader": "^6.0.2", 16 | "typescript": "^3.3.1", 17 | "webpack": "^4.41.0", 18 | "webpack-cli": "^3.3.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import {resolve} from "path"; 2 | import typescript from "rollup-plugin-typescript2"; 3 | import {terser} from "rollup-plugin-terser"; 4 | 5 | const input = resolve(__dirname, "src/NativeUi.ts"); 6 | 7 | const file = () => { 8 | const path = `dist/nativeui/nativeui.js` 9 | return { 10 | file: resolve(__dirname, path), 11 | name: "NativeUI", 12 | format: "es", 13 | plugins: [ terser() ] 14 | } 15 | } 16 | 17 | export default { 18 | input, 19 | output: [ 20 | file() 21 | ], 22 | external: ["@citizenfx/client"], 23 | plugins: [ 24 | typescript({ abortOnError: false}) 25 | ] 26 | }; -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/utils/Screen.d.ts: -------------------------------------------------------------------------------- 1 | import Font from "../enums/Font"; 2 | import Point from "./Point"; 3 | import Size from "./Size"; 4 | export default class Screen { 5 | static Width: number; 6 | static Height: number; 7 | static get ResolutionMaintainRatio(): Size; 8 | static MousePosition(relative?: boolean): { 9 | X: number; 10 | Y: number; 11 | }; 12 | static IsMouseInBounds(topLeft: Point, boxSize: Size): boolean; 13 | static GetTextWidth(text: string, font: Font, scale: number): number; 14 | static GetLineCount(text: string, position: Point, font: Font, scale: number, wrap: number): number; 15 | } 16 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/Text.d.ts: -------------------------------------------------------------------------------- 1 | import Color from "../utils/Color"; 2 | import Point from "../utils/Point"; 3 | import IElement from "./IElement"; 4 | import Size from '../utils/Size'; 5 | export default class Text extends IElement { 6 | Caption: string; 7 | Pos: Point; 8 | Scale: number; 9 | Color: Color; 10 | Font: number; 11 | Centered: boolean; 12 | constructor(caption: string, pos: Point, scale: number, color: Color, font: number, centered: boolean); 13 | Draw(caption: Size, pos: Point, scale: number, color: Color, font: string | number, centered: boolean): void; 14 | static AddLongString(text: string): void; 15 | } 16 | export { Text }; 17 | -------------------------------------------------------------------------------- /src/utils/UUIDV4.js: -------------------------------------------------------------------------------- 1 | export default function UUIDV4() { 2 | let uuid = ""; 3 | let ii; 4 | for (ii = 0; ii < 32; ii += 1) { 5 | switch (ii) { 6 | case 8: 7 | case 20: 8 | uuid += "-"; 9 | uuid += ((Math.random() * 16) | 0).toString(16); 10 | break; 11 | case 12: 12 | uuid += "-"; 13 | uuid += "4"; 14 | break; 15 | case 16: 16 | uuid += "-"; 17 | uuid += ((Math.random() * 4) | 8).toString(16); 18 | break; 19 | default: 20 | uuid += ((Math.random() * 16) | 0).toString(16); 21 | } 22 | } 23 | return uuid; 24 | } 25 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/ResText.d.ts: -------------------------------------------------------------------------------- 1 | import Alignment from "../enums/Alignment"; 2 | import Color from "../utils/Color"; 3 | import Point from "../utils/Point"; 4 | import Size from "../utils/Size"; 5 | import Text from "./Text"; 6 | export default class ResText extends Text { 7 | TextAlignment: Alignment; 8 | DropShadow: boolean; 9 | Outline: boolean; 10 | Wrap: number; 11 | get WordWrap(): Size; 12 | set WordWrap(value: Size); 13 | constructor(caption: string, pos: Point, scale: number, color?: Color, font?: number, centered?: Alignment); 14 | Draw(): void; 15 | Draw(offset: Size): void; 16 | Draw(caption: Size, pos: Point, scale: number, color: Color, font: string | number, arg2: any): void; 17 | } 18 | -------------------------------------------------------------------------------- /src/utils/LiteEvent.ts: -------------------------------------------------------------------------------- 1 | interface ILiteEvent { 2 | on(handler: { (...args: any[]): void }): void; 3 | off(handler: { (...args: any[]): void }): void; 4 | } 5 | 6 | export default class LiteEvent implements ILiteEvent { 7 | private handlers: { (...args: any[]): void }[] = []; 8 | 9 | public on(handler: { (...args: any[]): void }): void { 10 | this.handlers.push(handler); 11 | } 12 | 13 | public off(handler: { (...args: any[]): void }): void { 14 | this.handlers = this.handlers.filter(h => h !== handler); 15 | } 16 | 17 | public emit(...args: any[]) { 18 | this.handlers.slice(0).forEach(h => h(...args)); 19 | } 20 | 21 | public expose(): ILiteEvent { 22 | return this; 23 | } 24 | 25 | public count(): number { 26 | return this.handlers.length; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/enums/BadgeStyle.d.ts: -------------------------------------------------------------------------------- 1 | declare enum 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 | Sale = 23, 26 | ArrowLeft = 24, 27 | ArrowRight = 25, 28 | Audio1 = 26, 29 | Audio2 = 27, 30 | Audio3 = 28, 31 | AudioInactive = 29, 32 | AudioMute = 30 33 | } 34 | export default BadgeStyle; 35 | -------------------------------------------------------------------------------- /src/utils/Point.js: -------------------------------------------------------------------------------- 1 | export default class Point { 2 | constructor(x, y) { 3 | this.X = 0; 4 | this.Y = 0; 5 | this.X = x; 6 | this.Y = y; 7 | } 8 | static Parse(arg) { 9 | if (typeof arg === "object") { 10 | if (arg.length) { 11 | return new Point(arg[0], arg[1]); 12 | } 13 | else if (arg.X && arg.Y) { 14 | return new Point(arg.X, arg.Y); 15 | } 16 | } 17 | else if (typeof arg === "string") { 18 | if (arg.indexOf(",") !== -1) { 19 | const arr = arg.split(","); 20 | return new Point(parseFloat(arr[0]), parseFloat(arr[1])); 21 | } 22 | } 23 | return new Point(0, 0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "baseUrl": ".", 5 | "paths": { 6 | "*": ["types/*"] 7 | }, 8 | "module": "ESNext", 9 | "moduleResolution": "Node", 10 | "declaration": true, 11 | "resolveJsonModule": true, 12 | "declarationDir": "dist/nativeui/types", 13 | "allowSyntheticDefaultImports": true, 14 | "removeComments": true, 15 | "sourceMap": false, 16 | "types": ["@citizenfx/client", "@types/node"], 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": false, 19 | "noImplicitReturns": true, 20 | "allowJs": false, 21 | "emitDecoratorMetadata": true, 22 | "experimentalDecorators": true 23 | }, 24 | "include": [ 25 | "src" 26 | ] 27 | } -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/items/UIMenuSliderItem.d.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import UIMenuItem from "./UIMenuItem"; 3 | export default class UIMenuSliderItem extends UIMenuItem { 4 | private _arrowLeft; 5 | private _arrowRight; 6 | private _rectangleBackground; 7 | private _rectangleSlider; 8 | private _rectangleDivider; 9 | private _items; 10 | private _index; 11 | get Index(): number; 12 | set Index(value: number); 13 | constructor(text: string, items: any[], index: number, description?: string, divider?: boolean, data?: any); 14 | SetVerticalPosition(y: number): void; 15 | IndexToItem(index: number): any; 16 | Draw(): void; 17 | SetRightBadge(badge: BadgeStyle): void; 18 | SetRightLabel(text: string): void; 19 | } 20 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/MidsizedMessage.d.ts: -------------------------------------------------------------------------------- 1 | import HudColor from '../enums/HudColor'; 2 | import Message from './Message'; 3 | export default class MidsizedMessage extends Message { 4 | static Initialize(scaleForm: string, transitionOutAnimName: string): void; 5 | static ShowMidsizedMessage(title: string, message?: string, time?: number): void; 6 | static ShowBridgesKnivesProgress(title: string, totalToDo: number, message: string, info: string, completed: number, time?: number): void; 7 | static ShowCondensedShardMessage(title: string, message: string, bgColor: HudColor, useDarkerShard: boolean, time?: number): void; 8 | static ShowMidsizedShardMessage(title: string, message: string, bgColor: HudColor, useDarkerShard: boolean, useCondensedShard: boolean, time?: number): void; 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/Point.ts: -------------------------------------------------------------------------------- 1 | export default class Point { 2 | public X: number = 0; 3 | public Y: number = 0; 4 | 5 | constructor(x: number, y: number) { 6 | this.X = x; 7 | this.Y = y; 8 | } 9 | 10 | public static Parse(point: number[]): Point; 11 | public static Parse(point: { X: number; Y: number }): Point; 12 | public static Parse(arg: any): Point { 13 | if (typeof arg === "object") { 14 | if (arg.length) { 15 | // Array 16 | return new Point(arg[0], arg[1]); 17 | } else if (arg.X && arg.Y) { 18 | // Object 19 | return new Point(arg.X, arg.Y); 20 | } 21 | } else if (typeof arg === "string") { 22 | if (arg.indexOf(",") !== -1) { 23 | const arr = arg.split(","); 24 | return new Point(parseFloat(arr[0]), parseFloat(arr[1])); 25 | } 26 | } 27 | return new Point(0, 0); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/Sprite.d.ts: -------------------------------------------------------------------------------- 1 | import Color from "../utils/Color"; 2 | import Point from "../utils/Point"; 3 | import Size from "../utils/Size"; 4 | export default class Sprite { 5 | TextureName: string; 6 | Pos: Point; 7 | Size: Size; 8 | Heading: number; 9 | Color: Color; 10 | Visible: boolean; 11 | private _textureDict; 12 | constructor(textureDict: string, textureName: string, pos: Point, size: Size, heading?: number, color?: Color); 13 | LoadTextureDictionary(): void; 14 | private requestTextureDictPromise; 15 | set TextureDict(v: string); 16 | get TextureDict(): string; 17 | get IsTextureDictionaryLoaded(): number; 18 | Draw(textureDictionary?: string, textureName?: string, pos?: Point, size?: Size, heading?: number, color?: Color, loadTexture?: boolean): void; 19 | } 20 | -------------------------------------------------------------------------------- /src/modules/ItemsCollection.ts: -------------------------------------------------------------------------------- 1 | import ListItem from "../modules/ListItem"; 2 | 3 | export default class ItemsCollection { 4 | private items: ListItem[] | string[] | number[]; 5 | 6 | constructor(items: ListItem[] | string[] | number[]) { 7 | if (items.length === 0) throw new Error("ItemsCollection cannot be empty"); 8 | this.items = items; 9 | } 10 | 11 | public length() { 12 | return this.items.length; 13 | } 14 | 15 | public getListItems() { 16 | const items = []; 17 | for (const item of this.items) { 18 | if (item instanceof ListItem) { 19 | items.push(item); 20 | } else if (typeof item == "string") { 21 | items.push(new ListItem(item)); 22 | } else if (typeof item == "number") { 23 | items.push(new ListItem(item.toString())); 24 | } 25 | } 26 | return items; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/modules/ItemsCollection.js: -------------------------------------------------------------------------------- 1 | import ListItem from "../modules/ListItem"; 2 | export default class ItemsCollection { 3 | constructor(items) { 4 | if (items.length === 0) 5 | throw new Error("ItemsCollection cannot be empty"); 6 | this.items = items; 7 | } 8 | length() { 9 | return this.items.length; 10 | } 11 | getListItems() { 12 | const items = []; 13 | for (const item of this.items) { 14 | if (item instanceof ListItem) { 15 | items.push(item); 16 | } 17 | else if (typeof item == "string") { 18 | items.push(new ListItem(item)); 19 | } 20 | else if (typeof item == "number") { 21 | items.push(new ListItem(item.toString())); 22 | } 23 | } 24 | return items; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/modules/Rectangle.js: -------------------------------------------------------------------------------- 1 | import Point from "../utils/Point"; 2 | import Size from "../utils/Size"; 3 | import IElement from "./IElement"; 4 | export default class Rectangle extends IElement { 5 | constructor(pos, size, color) { 6 | super(); 7 | this.Enabled = true; 8 | this.Pos = pos; 9 | this.Size = size; 10 | this.Color = color; 11 | } 12 | Draw(pos, size, color) { 13 | if (!pos) 14 | pos = new Size(0, 0); 15 | if (!size && !color) { 16 | pos = new Point(this.Pos.X + pos.Width, this.Pos.Y + pos.Height); 17 | size = this.Size; 18 | color = this.Color; 19 | } 20 | const w = size.Width / 1280.0; 21 | const h = size.Height / 720.0; 22 | const x = pos.X / 1280.0 + w * 0.5; 23 | const y = pos.Y / 720.0 + h * 0.5; 24 | DrawRect(x, y, w, h, color.R, color.G, color.B, color.A, false); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/modules/Rectangle.ts: -------------------------------------------------------------------------------- 1 | import Color from "../utils/Color"; 2 | import Point from "../utils/Point"; 3 | import Size from "../utils/Size"; 4 | import IElement from "./IElement"; 5 | 6 | export default class Rectangle extends IElement { 7 | public Pos: Point; 8 | public Size: Size; 9 | public Color: Color; 10 | 11 | constructor(pos: Point, size: Size, color: Color) { 12 | super(); 13 | this.Enabled = true; 14 | this.Pos = pos; 15 | this.Size = size; 16 | this.Color = color; 17 | } 18 | 19 | public Draw(pos: Point | Size, size: Size, color: Color) { 20 | if (!pos) pos = new Size(0, 0); 21 | if (!size && !color) { 22 | pos = new Point(this.Pos.X + (pos as Size).Width, this.Pos.Y + (pos as Size).Height); 23 | size = this.Size; 24 | color = this.Color; 25 | } 26 | const w = size.Width / 1280.0; 27 | const h = size.Height / 720.0; 28 | const x = (pos as Point).X / 1280.0 + w * 0.5; 29 | const y = (pos as Point).Y / 720.0 + h * 0.5; 30 | 31 | DrawRect(x, y, w, h, color.R, color.G, color.B, color.A); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/Message.d.ts: -------------------------------------------------------------------------------- 1 | import Scaleform from '../utils/Scaleform'; 2 | export default class Message { 3 | private static _messageVisible; 4 | private static _transitionOutTimeout; 5 | private static _transitionOutFinishedTimeout; 6 | private static _delayedTransitionInTimeout; 7 | private static _scaleform; 8 | private static _transitionOutTimeMs; 9 | private static _transitionOutAnimName; 10 | protected static Initialize(scaleForm: string, transitionOutAnimName: string): void; 11 | static get IsVisible(): boolean; 12 | protected static get Scaleform(): Scaleform; 13 | private static Load; 14 | private static SetDelayedTransition; 15 | static ShowCustomShard(funcName: string, time?: number, ...funcArgs: any[]): void; 16 | static ShowComplexCustomShard(messageHandler: { 17 | (): void; 18 | }, time?: number): void; 19 | protected static TransitionOut(): void; 20 | private static TransitionIn; 21 | private static SetTransitionOutTimer; 22 | protected static Render(): void; 23 | } 24 | -------------------------------------------------------------------------------- /src/modules/ResRectangle.js: -------------------------------------------------------------------------------- 1 | import Point from "../utils/Point"; 2 | import Size from "../utils/Size"; 3 | import Rectangle from "./Rectangle"; 4 | import Screen from "../utils/Screen"; 5 | export default class ResRectangle extends Rectangle { 6 | constructor(pos, size, color) { 7 | super(pos, size, color); 8 | } 9 | Draw(pos, size, color) { 10 | if (!pos) 11 | pos = new Size(); 12 | if (pos && !size && !color) { 13 | pos = new Point(this.Pos.X + pos.Width, this.Pos.Y + pos.Height); 14 | size = this.Size; 15 | color = this.Color; 16 | } 17 | const screenw = Screen.Width; 18 | const screenh = Screen.Height; 19 | const height = 1080.0; 20 | const ratio = screenw / screenh; 21 | const width = height * ratio; 22 | const w = size.Width / width; 23 | const h = size.Height / height; 24 | const x = pos.X / width + w * 0.5; 25 | const y = pos.Y / height + h * 0.5; 26 | DrawRect(x, y, w, h, color.R, color.G, color.B, color.A, false); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@PichotM/fivem-nativeui", 3 | "version": "1.4.4", 4 | "description": "NativeUI for FiveM written in Javascript / TypeScript", 5 | "main": "dist/nativeui/nativeui.min.js", 6 | "types": "dist/nativeui/types/NativeUi.d.ts", 7 | "scripts": { 8 | "build": "rollup -c", 9 | "watch": "rollup -cw" 10 | }, 11 | "files": [ 12 | "dist" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/PichotM/FiveM-NativeUI.git" 17 | }, 18 | "keywords": [ 19 | "fivem", 20 | "nativeui" 21 | ], 22 | "license": "Apache-2.0", 23 | "bugs": { 24 | "url": "https://github.com/PichotM/FiveM-NativeUI/issues" 25 | }, 26 | "homepage": "https://github.com/PichotM/FiveM-NativeUI#readme", 27 | "devDependencies": { 28 | "@citizenfx/client": "^1.0.2692-1", 29 | "@types/node": "^14.0.11", 30 | "rollup": "^2.15.0", 31 | "rollup-plugin-terser": "^6.1.0", 32 | "rollup-plugin-typescript2": "^0.27.1", 33 | "typescript": "^3.9.5" 34 | }, 35 | "publishConfig": { 36 | "registry": "https://npm.pkg.github.com" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/modules/BigMessage.d.ts: -------------------------------------------------------------------------------- 1 | import HudColor from '../enums/HudColor'; 2 | import Message from './Message'; 3 | export default class BigMessage extends Message { 4 | static Initialize(scaleForm: string, transitionOutAnimName: string): void; 5 | static ShowMissionPassedMessage(msg: string, subtitle?: string, time?: number): void; 6 | static ShowColoredShard(msg: string, desc: string, textColor: HudColor, bgColor: HudColor, time?: number): void; 7 | static ShowOldMessage(msg: string, time?: number): void; 8 | static ShowSimpleShard(title: string, subtitle?: string, time?: number): void; 9 | static ShowRankupMessage(msg: string, subtitle: string, rank: number, time?: number): void; 10 | static ShowPlaneMessage(title: string, planeName: string, planeHash: number, time?: number): void; 11 | static ShowWeaponPurchasedMessage(bigMessage: string, weaponName: string, weaponHash: number, time?: number): void; 12 | static ShowWastedMessage(title: string, message: string, color: HudColor, darkenBackground: boolean, time?: number): void; 13 | static ShowMpMessageLarge(msg: string, subtitle?: string, time?: number): void; 14 | } 15 | -------------------------------------------------------------------------------- /src/modules/Container.js: -------------------------------------------------------------------------------- 1 | import Size from "../utils/Size"; 2 | import Rectangle from "./Rectangle"; 3 | import Screen from "../utils/Screen"; 4 | export default class Container extends Rectangle { 5 | constructor(pos, size, color) { 6 | super(pos, size, color); 7 | this.Items = []; 8 | } 9 | addItem(item) { 10 | this.Items.push(item); 11 | } 12 | Draw(offset) { 13 | if (!this.Enabled) 14 | return; 15 | offset = offset || new Size(); 16 | const screenw = Screen.Width; 17 | const screenh = Screen.Height; 18 | const height = 1080.0; 19 | const ratio = screenw / screenh; 20 | const width = height * ratio; 21 | const w = this.Size.Width / width; 22 | const h = this.Size.Height / height; 23 | const x = (this.Pos.X + offset.Width) / width + w * 0.5; 24 | const y = (this.Pos.Y + offset.Height) / height + h * 0.5; 25 | DrawRect(x, y, w, h, this.Color.R, this.Color.G, this.Color.B, this.Color.A, false); 26 | for (var item of this.Items) 27 | item.Draw(new Size(this.Pos.X + offset.Width, this.Pos.Y + offset.Height)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/modules/MidsizedMessage.js: -------------------------------------------------------------------------------- 1 | import Message from './Message'; 2 | export default class MidsizedMessage extends Message { 3 | static Initialize(scaleForm, transitionOutAnimName) { 4 | super.Initialize(scaleForm, transitionOutAnimName); 5 | setTick(() => this.Render()); 6 | } 7 | static ShowMidsizedMessage(title, message = "", time = 5000) { 8 | this.ShowCustomShard("SHOW_MIDSIZED_MESSAGE", time, title, message); 9 | } 10 | static ShowBridgesKnivesProgress(title, totalToDo, message, info, completed, time = 5000) { 11 | this.ShowCustomShard("SHOW_BRIDGES_KNIVES_PROGRESS", time, title, totalToDo, message, info, completed); 12 | } 13 | static ShowCondensedShardMessage(title, message, bgColor, useDarkerShard, time = 5000) { 14 | this.ShowCustomShard("SHOW_COND_SHARD_MESSAGE", time, title, message, bgColor, useDarkerShard); 15 | } 16 | static ShowMidsizedShardMessage(title, message, bgColor, useDarkerShard, useCondensedShard, time = 5000) { 17 | this.ShowCustomShard("SHOW_SHARD_MIDSIZED_MESSAGE", time, title, message, bgColor, useDarkerShard, useCondensedShard); 18 | } 19 | } 20 | MidsizedMessage.Initialize("MIDSIZED_MESSAGE", "SHARD_ANIM_OUT"); 21 | -------------------------------------------------------------------------------- /src/modules/ResRectangle.ts: -------------------------------------------------------------------------------- 1 | import Point from "../utils/Point"; 2 | import Size from "../utils/Size"; 3 | import Rectangle from "./Rectangle"; 4 | import Screen from "../utils/Screen"; 5 | import Color from '../utils/Color'; 6 | 7 | export default class ResRectangle extends Rectangle { 8 | constructor(pos: Point, size: Size, color: Color) { 9 | super(pos, size, color); 10 | } 11 | 12 | public Draw(): void; 13 | public Draw(offset: any): void; 14 | public Draw(pos: Point | Size, size: Size, color: Color): void; 15 | 16 | public Draw(pos?: Point | Size, size?: Size, color?: Color) { 17 | if (!pos) pos = new Size(); 18 | if (pos && !size && !color) { 19 | pos = new Point(this.Pos.X + (pos as Size).Width, this.Pos.Y + (pos as Size).Height); 20 | size = this.Size; 21 | color = this.Color; 22 | } 23 | 24 | const screenw = Screen.Width; 25 | const screenh = Screen.Height; 26 | const height = 1080.0; 27 | const ratio = screenw / screenh; 28 | const width = height * ratio; 29 | 30 | const w = size.Width / width; 31 | const h = size.Height / height; 32 | const x = (pos as Point).X / width + w * 0.5; 33 | const y = (pos as Point).Y / height + h * 0.5; 34 | 35 | DrawRect(x, y, w, h, color.R, color.G, color.B, color.A); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/modules/Container.ts: -------------------------------------------------------------------------------- 1 | import Size from "../utils/Size"; 2 | import Rectangle from "./Rectangle"; 3 | import Screen from "../utils/Screen"; 4 | import Point from '../utils/Point'; 5 | import Color from '../utils/Color'; 6 | 7 | export default class Container extends Rectangle { 8 | public Items: any[]; 9 | 10 | constructor(pos: Point, size: Size, color: Color) { 11 | super(pos, size, color); 12 | this.Items = []; 13 | } 14 | 15 | addItem(item: any) { 16 | this.Items.push(item); 17 | } 18 | 19 | Draw(offset?: Size) { 20 | if (!this.Enabled) return; 21 | offset = offset || new Size(); 22 | const screenw = Screen.Width; 23 | const screenh = Screen.Height; 24 | const height = 1080.0; 25 | const ratio = screenw / screenh; 26 | const width = height * ratio; 27 | 28 | const w = this.Size.Width / width; 29 | const h = this.Size.Height / height; 30 | const x = (this.Pos.X + offset.Width) / width + w * 0.5; 31 | const y = (this.Pos.Y + offset.Height) / height + h * 0.5; 32 | 33 | DrawRect(x, y, w, h, this.Color.R, this.Color.G, this.Color.B, this.Color.A); 34 | 35 | for (var item of this.Items) 36 | item.Draw(new Size(this.Pos.X + offset.Width, this.Pos.Y + offset.Height)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/items/UIMenuListItem.d.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import ItemsCollection from "../modules/ItemsCollection"; 3 | import ListItem from "../modules/ListItem"; 4 | import ResText from "../modules/ResText"; 5 | import Sprite from "../modules/Sprite"; 6 | import UIMenuItem from "./UIMenuItem"; 7 | export default class UIMenuListItem extends UIMenuItem { 8 | ScrollingEnabled: boolean; 9 | HoldTimeBeforeScroll: number; 10 | protected _itemText: ResText; 11 | protected _arrowLeft: Sprite; 12 | protected _arrowRight: Sprite; 13 | private _currentOffset; 14 | private _itemsCollection; 15 | get Collection(): ListItem[]; 16 | set Collection(v: ListItem[]); 17 | set SelectedItem(v: ListItem); 18 | get SelectedItem(): ListItem; 19 | get SelectedValue(): any; 20 | protected _index: number; 21 | get Index(): number; 22 | set Index(value: number); 23 | constructor(text: string, description?: string, collection?: ItemsCollection, startIndex?: number, data?: any); 24 | setCollection(collection: ItemsCollection): void; 25 | setCollectionItem(index: number, item: ListItem | string, resetSelection?: boolean): void; 26 | SetVerticalPosition(y: number): void; 27 | SetRightLabel(text: string): this; 28 | SetRightBadge(badge: BadgeStyle): this; 29 | Draw(): void; 30 | } 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FiveM-NativeUI 2 | This project is a (fully TypeScript compatible) port of RageMP-NativeUI [Kar](https://github.com/karscopsandrobbers/RAGEMP-NativeUI) for FiveM. It provides a simple way to use NativeUI menus in your clientside scripts. A lot of credits to [datWeazel](https://github.com/datWeazel/alt-V-NativeUI) who made the initial port of the RageMP-NativeUI. 3 | 4 | ## Usage: 5 | ### With bundler: 6 | 1. Create in your `package.json` location a file named `.npmrc` and add this line: 7 | ``` 8 | @pichotm:registry=https://npm.pkg.github.com 9 | ``` 10 | 2. Install by run `npm install --save @pichotm/fivem-nativeui`. 11 | 3. Add this line to top of file where you want to use NativeUI. 12 | ```typescript 13 | import * as NativeUI from "@pichotm/fivem-nativeui"; 14 | ``` 15 | ### Without bundler: 16 | 1. Download `.zip` archive you want from [releases page](https://github.com/PichotM/FiveM-NativeUI/releases). 17 | 2. Unpack archive in client's folder, and import like any other file: 18 | ```javascript 19 | # nativeui-min 20 | import * as NativeUI from "nativeui/nativeui.min.js"; 21 | # nativeui 22 | import * as NativeUi from "nativeui/nativeui.js"; 23 | ``` 24 | - __Don't forget include nativeui folder in `client_scripts` section of your `fxmanifest.lua`__ 25 | 26 | 27 | ## Example Menu 28 | ``` 29 | examples\nativeUI-example 30 | ``` 31 | **Result:** 32 | ![Result](http://i.pichotm.fr/batman/don/pasta/987e3530-0f2b-40d6-be04-c860ddb5c33a.png) -------------------------------------------------------------------------------- /src/modules/MidsizedMessage.ts: -------------------------------------------------------------------------------- 1 | import HudColor from '../enums/HudColor'; 2 | import Message from './Message'; 3 | 4 | export default class MidsizedMessage extends Message { 5 | public static Initialize(scaleForm: string, transitionOutAnimName: string) { 6 | super.Initialize(scaleForm, transitionOutAnimName); 7 | setTick(() => this.Render()); 8 | } 9 | 10 | public static ShowMidsizedMessage(title: string, message: string = "", time: number = 5000): void { 11 | this.ShowCustomShard("SHOW_MIDSIZED_MESSAGE", time, title, message); 12 | } 13 | 14 | public static ShowBridgesKnivesProgress(title: string, totalToDo: number, message: string, info: string, completed: number, time: number = 5000): void { 15 | this.ShowCustomShard("SHOW_BRIDGES_KNIVES_PROGRESS", time, title, totalToDo, message, info, completed); 16 | } 17 | 18 | public static ShowCondensedShardMessage(title: string, message: string, bgColor: HudColor, useDarkerShard: boolean, time: number = 5000): void { 19 | this.ShowCustomShard("SHOW_COND_SHARD_MESSAGE", time, title, message, bgColor, useDarkerShard); 20 | } 21 | 22 | public static ShowMidsizedShardMessage(title: string, message: string, bgColor: HudColor, useDarkerShard: boolean, useCondensedShard: boolean, time: number = 5000): void { 23 | this.ShowCustomShard("SHOW_SHARD_MIDSIZED_MESSAGE", time, title, message, bgColor, useDarkerShard, useCondensedShard); 24 | } 25 | } 26 | MidsizedMessage.Initialize("MIDSIZED_MESSAGE", "SHARD_ANIM_OUT"); -------------------------------------------------------------------------------- /src/modules/InstructionalButton.ts: -------------------------------------------------------------------------------- 1 | import UIMenuItem from "../items/UIMenuItem"; 2 | import Control from '../enums/Control'; 3 | 4 | export default class InstructionalButton { 5 | public Text: string; 6 | public get ItemBind(): UIMenuItem { return this._itemBind; } 7 | 8 | private _itemBind: UIMenuItem = null; 9 | private readonly _buttonString: string; 10 | private readonly _buttonControl: Control; 11 | private readonly _usingControls: boolean; 12 | 13 | /* 14 | * Add a dynamic button to the instructional buttons array. 15 | * Changes whether the controller is being used and changes depending on keybinds. 16 | * @param control GTA.Control that gets converted into a button. 17 | * @param keystring Custom keyboard button, like "I", or "O", or "F5". 18 | * @param text Help text that goes with the button. 19 | */ 20 | constructor(text: string, control: Control, buttonString: string = null) { 21 | this.Text = text; 22 | this._buttonControl = control; 23 | this._usingControls = buttonString == null; 24 | this._buttonString = buttonString; 25 | } 26 | 27 | /* 28 | * Bind this button to an item, so it's only shown when that item is selected. 29 | * @param item Item to bind to. 30 | */ 31 | public BindToItem(item: UIMenuItem): void { 32 | this._itemBind = item; 33 | } 34 | 35 | public GetButtonId(): string { 36 | return this._usingControls ? GetControlInstructionalButton(2, this._buttonControl as number, 0) : "t_" + this._buttonString; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/items/UIMenuAutoListItem.d.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import ResText from "../modules/ResText"; 3 | import Sprite from "../modules/Sprite"; 4 | import UIMenuItem from "./UIMenuItem"; 5 | export default class UIMenuAutoListItem extends UIMenuItem { 6 | protected _itemText: ResText; 7 | protected _arrowLeft: Sprite; 8 | protected _arrowRight: Sprite; 9 | private _currentOffset; 10 | private _leftMoveThreshold; 11 | private _rightMoveThreshold; 12 | private _lowerThreshold; 13 | private _upperThreshold; 14 | private _preCaptionText; 15 | private _postCaptionText; 16 | private _selectedValue; 17 | get PreCaptionText(): string; 18 | set PreCaptionText(text: string); 19 | get PostCaptionText(): string; 20 | set PostCaptionText(text: string); 21 | get LeftMoveThreshold(): number; 22 | set LeftMoveThreshold(value: number); 23 | get RightMoveThreshold(): number; 24 | set RightMoveThreshold(value: number); 25 | get LowerThreshold(): number; 26 | set LowerThreshold(value: number); 27 | get UpperThreshold(): number; 28 | set UpperThreshold(value: number); 29 | get SelectedValue(): number; 30 | set SelectedValue(value: number); 31 | constructor(text: string, description?: string, lowerThreshold?: number, upperThreshold?: number, startValue?: number, data?: any); 32 | SetVerticalPosition(y: number): void; 33 | SetRightLabel(text: string): this; 34 | SetRightBadge(badge: BadgeStyle): this; 35 | Draw(): void; 36 | } 37 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/items/UIMenuDynamicListItem.d.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import ChangeDirection from "../enums/ChangeDirection"; 3 | import ResText from "../modules/ResText"; 4 | import Sprite from "../modules/Sprite"; 5 | import UIMenuItem from "./UIMenuItem"; 6 | interface SelectionChangeHandler { 7 | (item: UIMenuDynamicListItem, selectedValue: string, changeDirection: ChangeDirection): string; 8 | } 9 | export default class UIMenuDynamicListItem extends UIMenuItem { 10 | protected _itemText: ResText; 11 | protected _arrowLeft: Sprite; 12 | protected _arrowRight: Sprite; 13 | private _currentOffset; 14 | private _precaptionText; 15 | private _selectedValue; 16 | private readonly _selectedStartValueHandler; 17 | readonly SelectionChangeHandler: SelectionChangeHandler; 18 | SelectionChangeHandlerPromise(item: UIMenuDynamicListItem, selectedValue: string, changeDirection: ChangeDirection): Promise; 19 | get PreCaptionText(): string; 20 | set PreCaptionText(text: string); 21 | get SelectedValue(): string; 22 | set SelectedValue(value: string); 23 | constructor(text: string, selectionChangeHandler: { 24 | (item: UIMenuDynamicListItem, selectedValue: string, changeDirection: ChangeDirection): string; 25 | }, description?: string, selectedStartValueHandler?: { 26 | (): string; 27 | }, data?: any); 28 | SetVerticalPosition(y: number): void; 29 | SetRightLabel(text: string): this; 30 | SetRightBadge(badge: BadgeStyle): this; 31 | Draw(): void; 32 | private isVariableFunction; 33 | } 34 | export {}; 35 | -------------------------------------------------------------------------------- /src/enums/BadgeStyle.js: -------------------------------------------------------------------------------- 1 | var BadgeStyle; 2 | (function (BadgeStyle) { 3 | BadgeStyle[BadgeStyle["None"] = 0] = "None"; 4 | BadgeStyle[BadgeStyle["BronzeMedal"] = 1] = "BronzeMedal"; 5 | BadgeStyle[BadgeStyle["GoldMedal"] = 2] = "GoldMedal"; 6 | BadgeStyle[BadgeStyle["SilverMedal"] = 3] = "SilverMedal"; 7 | BadgeStyle[BadgeStyle["Alert"] = 4] = "Alert"; 8 | BadgeStyle[BadgeStyle["Crown"] = 5] = "Crown"; 9 | BadgeStyle[BadgeStyle["Ammo"] = 6] = "Ammo"; 10 | BadgeStyle[BadgeStyle["Armour"] = 7] = "Armour"; 11 | BadgeStyle[BadgeStyle["Barber"] = 8] = "Barber"; 12 | BadgeStyle[BadgeStyle["Clothes"] = 9] = "Clothes"; 13 | BadgeStyle[BadgeStyle["Franklin"] = 10] = "Franklin"; 14 | BadgeStyle[BadgeStyle["Bike"] = 11] = "Bike"; 15 | BadgeStyle[BadgeStyle["Car"] = 12] = "Car"; 16 | BadgeStyle[BadgeStyle["Gun"] = 13] = "Gun"; 17 | BadgeStyle[BadgeStyle["Heart"] = 14] = "Heart"; 18 | BadgeStyle[BadgeStyle["Makeup"] = 15] = "Makeup"; 19 | BadgeStyle[BadgeStyle["Mask"] = 16] = "Mask"; 20 | BadgeStyle[BadgeStyle["Michael"] = 17] = "Michael"; 21 | BadgeStyle[BadgeStyle["Star"] = 18] = "Star"; 22 | BadgeStyle[BadgeStyle["Tattoo"] = 19] = "Tattoo"; 23 | BadgeStyle[BadgeStyle["Trevor"] = 20] = "Trevor"; 24 | BadgeStyle[BadgeStyle["Lock"] = 21] = "Lock"; 25 | BadgeStyle[BadgeStyle["Tick"] = 22] = "Tick"; 26 | BadgeStyle[BadgeStyle["Sale"] = 23] = "Sale"; 27 | BadgeStyle[BadgeStyle["ArrowLeft"] = 24] = "ArrowLeft"; 28 | BadgeStyle[BadgeStyle["ArrowRight"] = 25] = "ArrowRight"; 29 | BadgeStyle[BadgeStyle["Audio1"] = 26] = "Audio1"; 30 | BadgeStyle[BadgeStyle["Audio2"] = 27] = "Audio2"; 31 | BadgeStyle[BadgeStyle["Audio3"] = 28] = "Audio3"; 32 | BadgeStyle[BadgeStyle["AudioInactive"] = 29] = "AudioInactive"; 33 | BadgeStyle[BadgeStyle["AudioMute"] = 30] = "AudioMute"; 34 | })(BadgeStyle || (BadgeStyle = {})); 35 | export default BadgeStyle; 36 | -------------------------------------------------------------------------------- /src/items/UIMenuCheckboxItem.js: -------------------------------------------------------------------------------- 1 | import Sprite from "../modules/Sprite"; 2 | import Color from "../utils/Color"; 3 | import Point from "../utils/Point"; 4 | import Size from "../utils/Size"; 5 | import UIMenuItem from "./UIMenuItem"; 6 | export default class UIMenuCheckboxItem extends UIMenuItem { 7 | constructor(text, check = false, description = "") { 8 | super(text, description); 9 | this.Checked = false; 10 | const y = 0; 11 | this._checkedSprite = new Sprite("commonmenu", "shop_box_blank", new Point(410, y + 95), new Size(50, 50)); 12 | this.Checked = check; 13 | } 14 | SetVerticalPosition(y) { 15 | super.SetVerticalPosition(y); 16 | this._checkedSprite.Pos = new Point(380 + this.Offset.X + this.Parent.WidthOffset, y + 138 + this.Offset.Y); 17 | } 18 | Draw() { 19 | super.Draw(); 20 | this._checkedSprite.Pos = this._checkedSprite.Pos = new Point(380 + this.Offset.X + this.Parent.WidthOffset, this._checkedSprite.Pos.Y); 21 | const isDefaultHightlitedForeColor = this.HighlightedForeColor == UIMenuItem.DefaultHighlightedForeColor; 22 | if (this.Selected && isDefaultHightlitedForeColor) { 23 | this._checkedSprite.TextureName = this.Checked 24 | ? "shop_box_tickb" 25 | : "shop_box_blankb"; 26 | } 27 | else { 28 | this._checkedSprite.TextureName = this.Checked 29 | ? "shop_box_tick" 30 | : "shop_box_blank"; 31 | } 32 | this._checkedSprite.Color = this.Enabled 33 | ? this.Selected && !isDefaultHightlitedForeColor 34 | ? this.HighlightedForeColor 35 | : this.ForeColor 36 | : new Color(163, 159, 148); 37 | this._checkedSprite.Draw(); 38 | } 39 | SetRightBadge(badge) { 40 | return this; 41 | } 42 | SetRightLabel(text) { 43 | return this; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/modules/Text.js: -------------------------------------------------------------------------------- 1 | import game from 'natives'; 2 | import Color from "../utils/Color"; 3 | import Point from "../utils/Point"; 4 | import IElement from "./IElement"; 5 | export default class Text extends IElement { 6 | constructor(caption, pos, scale, color, font, centered) { 7 | super(); 8 | this.Caption = caption; 9 | this.Pos = pos; 10 | this.Scale = scale; 11 | this.Color = color || new Color(255, 255, 255, 255); 12 | this.Font = font || 0; 13 | this.Centered = centered || false; 14 | } 15 | Draw(caption, pos, scale, color, font, centered) { 16 | if (caption && !pos && !scale && !color && !font && !centered) { 17 | pos = new Point(this.Pos.X + caption.Width, this.Pos.Y + caption.Height); 18 | scale = this.Scale; 19 | color = this.Color; 20 | font = this.Font; 21 | centered = this.Centered; 22 | } 23 | const x = pos.X / 1280.0; 24 | const y = pos.Y / 720.0; 25 | SetTextFont(parseInt(font)); 26 | SetTextScale(scale, scale); 27 | SetTextColour(color.R, color.G, color.B, color.A); 28 | SetTextCentre(centered); 29 | BeginTextCommandDisplayText("STRING"); 30 | Text.AddLongString(caption); 31 | EndTextCommandDisplayText(x, y, 0); 32 | } 33 | static AddLongString(text) { 34 | if (!text.length) 35 | return; 36 | const maxStringLength = 99; 37 | for (let i = 0, position; i < text.length; i += maxStringLength) { 38 | let currentText = text.substr(i, i + maxStringLength); 39 | let currentIndex = i; 40 | if ((currentText.match(/~/g) || []).length % 2 !== 0) { 41 | position = currentText.lastIndexOf('~'); 42 | i -= (maxStringLength - position); 43 | } 44 | else { 45 | position = Math.min(maxStringLength, text.length - currentIndex); 46 | } 47 | AddTextComponentSubstringPlayerName(text.substr(currentIndex, position)); 48 | } 49 | } 50 | } 51 | export { Text }; 52 | -------------------------------------------------------------------------------- /src/modules/BigMessage.js: -------------------------------------------------------------------------------- 1 | import Message from './Message'; 2 | export default class BigMessage extends Message { 3 | static Initialize(scaleForm, transitionOutAnimName) { 4 | super.Initialize(scaleForm, transitionOutAnimName); 5 | setTick(() => this.Render()); 6 | } 7 | static ShowMissionPassedMessage(msg, subtitle = "", time = 5000) { 8 | this.ShowCustomShard("SHOW_MISSION_PASSED_MESSAGE", time, msg, subtitle, 100, true, 0, true); 9 | } 10 | static ShowColoredShard(msg, desc, textColor, bgColor, time = 5000) { 11 | this.ShowCustomShard("SHOW_SHARD_CENTERED_MP_MESSAGE", time, msg, desc, bgColor, textColor); 12 | } 13 | static ShowOldMessage(msg, time = 5000) { 14 | this.ShowCustomShard("SHOW_MISSION_PASSED_MESSAGE", time, msg); 15 | } 16 | static ShowSimpleShard(title, subtitle = "", time = 5000) { 17 | this.ShowCustomShard("SHOW_SHARD_CREW_RANKUP_MP_MESSAGE", time, title, subtitle); 18 | } 19 | static ShowRankupMessage(msg, subtitle, rank, time = 5000) { 20 | this.ShowCustomShard("SHOW_BIG_MP_MESSAGE", time, msg, subtitle, rank, "", ""); 21 | } 22 | static ShowPlaneMessage(title, planeName, planeHash, time = 5000) { 23 | this.ShowCustomShard("SHOW_PLANE_MESSAGE", time, title, planeName, planeHash, "", ""); 24 | } 25 | static ShowWeaponPurchasedMessage(bigMessage, weaponName, weaponHash, time = 5000) { 26 | this.ShowCustomShard("SHOW_WEAPON_PURCHASED", time, bigMessage, weaponName, weaponHash, "", 100); 27 | } 28 | static ShowWastedMessage(title, message, color, darkenBackground, time = 5000) { 29 | this.ShowCustomShard("SHOW_SHARD_WASTED_MP_MESSAGE", time, title, message, color, darkenBackground); 30 | } 31 | static ShowMpMessageLarge(msg, subtitle = "", time = 5000) { 32 | this.ShowComplexCustomShard(() => { 33 | this.Scaleform.callFunction("SHOW_CENTERED_MP_MESSAGE_LARGE", msg, subtitle, 100, true, 100); 34 | this.Scaleform.callFunction("TRANSITION_IN"); 35 | }, time); 36 | } 37 | } 38 | BigMessage.Initialize("MP_BIG_MESSAGE_FREEMODE", "TRANSITION_OUT"); 39 | -------------------------------------------------------------------------------- /src/items/UIMenuCheckboxItem.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import Sprite from "../modules/Sprite"; 3 | import Color from "../utils/Color"; 4 | import Point from "../utils/Point"; 5 | import Size from "../utils/Size"; 6 | import UIMenuItem from "./UIMenuItem"; 7 | 8 | export default class UIMenuCheckboxItem extends UIMenuItem { 9 | private readonly _checkedSprite: Sprite; 10 | 11 | public Checked: boolean = false; 12 | 13 | constructor(text: string, check: boolean = false, description: string = "") { 14 | super(text, description); 15 | 16 | const y = 0; 17 | this._checkedSprite = new Sprite("commonmenu", "shop_box_blank", new Point(410, y + 95), new Size(50, 50)); 18 | this.Checked = check; 19 | } 20 | 21 | public SetVerticalPosition(y: number) { 22 | super.SetVerticalPosition(y); 23 | this._checkedSprite.Pos = new Point(380 + this.Offset.X + this.Parent.WidthOffset, y + 138 + this.Offset.Y); 24 | } 25 | 26 | public Draw() { 27 | super.Draw(); 28 | 29 | this._checkedSprite.Pos = this._checkedSprite.Pos = new Point(380 + this.Offset.X + this.Parent.WidthOffset, this._checkedSprite.Pos.Y); 30 | const isDefaultHightlitedForeColor = this.HighlightedForeColor == UIMenuItem.DefaultHighlightedForeColor; 31 | 32 | if (this.Selected && isDefaultHightlitedForeColor) { 33 | this._checkedSprite.TextureName = this.Checked 34 | ? "shop_box_tickb" 35 | : "shop_box_blankb"; 36 | } else { 37 | this._checkedSprite.TextureName = this.Checked 38 | ? "shop_box_tick" 39 | : "shop_box_blank"; 40 | } 41 | 42 | this._checkedSprite.Color = this.Enabled 43 | ? this.Selected && !isDefaultHightlitedForeColor 44 | ? this.HighlightedForeColor 45 | : this.ForeColor 46 | : new Color(163, 159, 148); 47 | this._checkedSprite.Draw(); 48 | } 49 | 50 | public SetRightBadge(badge: BadgeStyle) { 51 | return this; 52 | } 53 | 54 | public SetRightLabel(text: string) { 55 | return this; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/utils/Screen.js: -------------------------------------------------------------------------------- 1 | import game from 'natives'; 2 | import Size from "./Size"; 3 | import Text from '../modules/Text'; 4 | const gameScreen = GetActiveScreenResolution(0, 0); 5 | export default class Screen { 6 | static get ResolutionMaintainRatio() { 7 | const ratio = Screen.Width / Screen.Height; 8 | const width = 1080.0 * ratio; 9 | return new Size(width, 1080.0); 10 | } 11 | static MousePosition(relative = false) { 12 | const res = Screen.ResolutionMaintainRatio; 13 | const cursor = GetNuiCursorPosition(); 14 | let [mouseX, mouseY] = [cursor.x, cursor.y]; 15 | if (relative) 16 | [mouseX, mouseY] = [cursor.x / res.Width, cursor.y / res.Height]; 17 | return { 18 | X: mouseX, 19 | Y: mouseY 20 | }; 21 | } 22 | static IsMouseInBounds(topLeft, boxSize) { 23 | const mousePosition = Screen.MousePosition(); 24 | return (mousePosition.X >= topLeft.X && 25 | mousePosition.X <= topLeft.X + boxSize.Width && 26 | (mousePosition.Y > topLeft.Y && mousePosition.Y < topLeft.Y + boxSize.Height)); 27 | } 28 | static GetTextWidth(text, font, scale) { 29 | BeginTextCommandGetWidth("CELL_EMAIL_BCON"); 30 | Text.AddLongString(text); 31 | SetTextFont(font); 32 | SetTextScale(1.0, scale); 33 | const width = EndTextCommandGetWidth(true); 34 | const res = Screen.ResolutionMaintainRatio; 35 | return res.Width * width; 36 | } 37 | static GetLineCount(text, position, font, scale, wrap) { 38 | BeginTextCommandLineCount("CELL_EMAIL_BCON"); 39 | Text.AddLongString(text); 40 | const res = Screen.ResolutionMaintainRatio; 41 | const x = position.X / res.Width; 42 | const y = position.Y / res.Height; 43 | SetTextFont(font); 44 | SetTextScale(1.0, scale); 45 | if (wrap > 0) { 46 | const start = position.X / res.Width; 47 | const end = start + (wrap / res.Width); 48 | SetTextWrap(x, end); 49 | } 50 | let lineCount = EndTextCommandLineCount(x, y); 51 | return lineCount; 52 | } 53 | } 54 | Screen.Width = gameScreen[1]; 55 | Screen.Height = gameScreen[2]; 56 | -------------------------------------------------------------------------------- /src/modules/Sprite.js: -------------------------------------------------------------------------------- 1 | import Color from "../utils/Color"; 2 | import Screen from "../utils/Screen"; 3 | export default class Sprite { 4 | constructor(textureDict, textureName, pos, size, heading = 0, color = new Color(255, 255, 255)) { 5 | this.TextureDict = textureDict; 6 | this.TextureName = textureName; 7 | this.Pos = pos; 8 | this.Size = size; 9 | this.Heading = heading; 10 | this.Color = color; 11 | this.Visible = true; 12 | } 13 | LoadTextureDictionary() { 14 | this.requestTextureDictPromise(this._textureDict).then((succ) => { }); 15 | } 16 | requestTextureDictPromise(textureDict) { 17 | return new Promise((resolve, reject) => { 18 | RequestStreamedTextureDict(textureDict, true); 19 | let inter = setInterval(() => { 20 | if (HasStreamedTextureDictLoaded(textureDict)) { 21 | clearInterval(inter); 22 | return resolve(true); 23 | } 24 | }, 10); 25 | }); 26 | } 27 | set TextureDict(v) { 28 | this._textureDict = v; 29 | if (!this.IsTextureDictionaryLoaded) 30 | this.LoadTextureDictionary(); 31 | } 32 | get TextureDict() { 33 | return this._textureDict; 34 | } 35 | get IsTextureDictionaryLoaded() { 36 | return HasStreamedTextureDictLoaded(this._textureDict); 37 | } 38 | Draw(textureDictionary, textureName, pos, size, heading, color, loadTexture) { 39 | textureDictionary = textureDictionary || this.TextureDict; 40 | textureName = textureName || this.TextureName; 41 | pos = pos || this.Pos; 42 | size = size || this.Size; 43 | heading = heading || this.Heading; 44 | color = color || this.Color; 45 | loadTexture = loadTexture || true; 46 | if (loadTexture) { 47 | if (!HasStreamedTextureDictLoaded(textureDictionary)) 48 | RequestStreamedTextureDict(textureDictionary, true); 49 | } 50 | const screenw = Screen.Width; 51 | const screenh = Screen.Height; 52 | const height = 1080.0; 53 | const ratio = screenw / screenh; 54 | const width = height * ratio; 55 | const w = this.Size.Width / width; 56 | const h = this.Size.Height / height; 57 | const x = this.Pos.X / width + w * 0.5; 58 | const y = this.Pos.Y / height + h * 0.5; 59 | DrawSprite(textureDictionary, textureName, x, y, w, h, heading, color.R, color.G, color.B, color.A, true); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/modules/BigMessage.ts: -------------------------------------------------------------------------------- 1 | import HudColor from '../enums/HudColor'; 2 | import Message from './Message'; 3 | 4 | export default class BigMessage extends Message { 5 | public static Initialize(scaleForm: string, transitionOutAnimName: string) { 6 | super.Initialize(scaleForm, transitionOutAnimName); 7 | setTick(() => this.Render()); 8 | } 9 | 10 | public static ShowMissionPassedMessage(msg: string, subtitle: string = "", time: number = 5000): void { 11 | this.ShowCustomShard("SHOW_MISSION_PASSED_MESSAGE", time, msg, subtitle, 100, true, 0, true); 12 | } 13 | 14 | public static ShowColoredShard(msg: string, desc: string, textColor: HudColor, bgColor: HudColor, time: number = 5000): void { 15 | this.ShowCustomShard("SHOW_SHARD_CENTERED_MP_MESSAGE", time, msg, desc, bgColor as number, textColor as number); 16 | } 17 | 18 | public static ShowOldMessage(msg: string, time: number = 5000): void { 19 | this.ShowCustomShard("SHOW_MISSION_PASSED_MESSAGE", time, msg); 20 | } 21 | 22 | public static ShowSimpleShard(title: string, subtitle: string = "", time: number = 5000): void { 23 | this.ShowCustomShard("SHOW_SHARD_CREW_RANKUP_MP_MESSAGE", time, title, subtitle); 24 | } 25 | 26 | public static ShowRankupMessage(msg: string, subtitle: string, rank: number, time: number = 5000): void { 27 | this.ShowCustomShard("SHOW_BIG_MP_MESSAGE", time, msg, subtitle, rank, "", ""); 28 | } 29 | 30 | public static ShowPlaneMessage(title: string, planeName: string, planeHash: number, time: number = 5000): void { 31 | this.ShowCustomShard("SHOW_PLANE_MESSAGE", time, title, planeName, planeHash, "", ""); 32 | } 33 | 34 | public static ShowWeaponPurchasedMessage(bigMessage: string, weaponName: string, weaponHash: number, time: number = 5000): void { 35 | this.ShowCustomShard("SHOW_WEAPON_PURCHASED", time, bigMessage, weaponName, weaponHash, "", 100); 36 | } 37 | 38 | public static ShowWastedMessage(title: string, message: string, color: HudColor, darkenBackground: boolean, time: number = 5000): void { 39 | this.ShowCustomShard("SHOW_SHARD_WASTED_MP_MESSAGE", time, title, message, color as number, darkenBackground); 40 | } 41 | 42 | public static ShowMpMessageLarge(msg: string, subtitle: string = "", time: number = 5000): void { 43 | this.ShowComplexCustomShard(() => { 44 | this.Scaleform.callFunction("SHOW_CENTERED_MP_MESSAGE_LARGE", msg, subtitle, 100, true, 100); 45 | this.Scaleform.callFunction("TRANSITION_IN"); 46 | }, time); 47 | } 48 | } 49 | BigMessage.Initialize("MP_BIG_MESSAGE_FREEMODE", "TRANSITION_OUT"); -------------------------------------------------------------------------------- /src/modules/Text.ts: -------------------------------------------------------------------------------- 1 | import Color from "../utils/Color"; 2 | import Point from "../utils/Point"; 3 | import IElement from "./IElement"; 4 | import Size from '../utils/Size'; 5 | 6 | export default class Text extends IElement { 7 | public Caption: string; 8 | public Pos: Point; 9 | public Scale: number; 10 | public Color: Color; 11 | public Font: number; 12 | public Centered: boolean; 13 | 14 | constructor(caption: string, pos: Point, scale: number, color: Color, font: number, centered: boolean) { 15 | super(); 16 | this.Caption = caption; 17 | this.Pos = pos; 18 | this.Scale = scale; 19 | this.Color = color || new Color(255, 255, 255, 255); 20 | this.Font = font || 0; 21 | this.Centered = centered || false; 22 | } 23 | 24 | public Draw(caption: Size, pos: Point, scale: number, color: Color, font: string | number, centered: boolean) { 25 | if (caption && !pos && !scale && !color && !font && !centered) { 26 | pos = new Point(this.Pos.X + caption.Width, this.Pos.Y + caption.Height); 27 | scale = this.Scale; 28 | color = this.Color; 29 | font = this.Font; 30 | centered = this.Centered; 31 | } 32 | const x = pos.X / 1280.0; 33 | const y = pos.Y / 720.0; 34 | 35 | 36 | SetTextFont(parseInt(font as string)); 37 | SetTextScale(scale, scale); 38 | SetTextColour(color.R, color.G, color.B, color.A); 39 | SetTextCentre(centered); 40 | BeginTextCommandDisplayText("STRING"); 41 | Text.AddLongString(caption as any); 42 | EndTextCommandDisplayText(x, y); 43 | } 44 | 45 | public static AddLongString(text: string) { 46 | if (!text.length) 47 | return; 48 | 49 | const maxStringLength = 99; 50 | 51 | for (let i = 0, position; i < text.length; i += maxStringLength) { 52 | let currentText = text.substr(i, i + maxStringLength); 53 | let currentIndex = i; 54 | if ((currentText.match(/~/g) || []).length % 2 !== 0) { 55 | position = currentText.lastIndexOf('~'); 56 | //if(position > 0 && currentText[position - 1] === ' ') { // Doesn't the substring auto add a space? 57 | // position--; 58 | //} 59 | i -= (maxStringLength - position); 60 | } else { 61 | position = Math.min(maxStringLength, text.length - currentIndex); 62 | } 63 | AddTextComponentSubstringPlayerName(text.substr(currentIndex, position)); 64 | } 65 | } 66 | } 67 | 68 | export { 69 | Text 70 | } 71 | -------------------------------------------------------------------------------- /src/utils/Scaleform.js: -------------------------------------------------------------------------------- 1 | export default class Scaleform { 2 | constructor(scaleForm) { 3 | this._handle = 0; 4 | this.scaleForm = scaleForm; 5 | this._handle = RequestScaleformMovie(this.scaleForm); 6 | } 7 | get handle() { 8 | return this._handle; 9 | } 10 | get isValid() { 11 | return this._handle != 0; 12 | } 13 | get isLoaded() { 14 | return HasScaleformMovieLoaded(this._handle); 15 | } 16 | callFunctionHead(funcName, ...args) { 17 | if (!this.isValid || !this.isLoaded) 18 | return; 19 | BeginScaleformMovieMethod(this._handle, funcName); 20 | args.forEach((arg) => { 21 | switch (typeof arg) { 22 | case "number": 23 | { 24 | if (Number(arg) === arg && arg % 1 !== 0) { 25 | ScaleformMovieMethodAddParamFloat(arg); 26 | } 27 | else { 28 | ScaleformMovieMethodAddParamInt(arg); 29 | } 30 | } 31 | case "string": 32 | { 33 | ScaleformMovieMethodAddParamPlayerNameString(arg); 34 | break; 35 | } 36 | case "boolean": 37 | { 38 | ScaleformMovieMethodAddParamBool(arg); 39 | break; 40 | } 41 | default: 42 | { 43 | console.log(`Unknown argument type ${typeof arg} = ${arg.toString()} passed to scaleform with handle ${this._handle}`); 44 | } 45 | } 46 | }); 47 | } 48 | callFunction(funcName, ...args) { 49 | this.callFunctionHead(funcName, ...args); 50 | EndScaleformMovieMethod(); 51 | } 52 | callFunctionReturn(funcName, ...args) { 53 | this.callFunctionHead(funcName, ...args); 54 | return EndScaleformMovieMethodReturnValue(); 55 | } 56 | render2D() { 57 | if (!this.isValid || !this.isLoaded) 58 | return; 59 | DrawScaleformMovieFullscreen(this._handle, 255, 255, 255, 255, 0); 60 | } 61 | recreate() { 62 | if (!this.isValid || !this.isLoaded) 63 | return; 64 | SetScaleformMovieAsNoLongerNeeded(this._handle); 65 | this._handle = RequestScaleformMovie(this.scaleForm); 66 | } 67 | destroy() { 68 | if (!this.isValid) 69 | return; 70 | SetScaleformMovieAsNoLongerNeeded(this._handle); 71 | this._handle = 0; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/utils/Scaleform.ts: -------------------------------------------------------------------------------- 1 | export default class Scaleform { 2 | private _handle: number = 0; 3 | private scaleForm: string; 4 | 5 | public constructor(scaleForm: string) { 6 | this.scaleForm = scaleForm; 7 | this._handle = RequestScaleformMovie(this.scaleForm); 8 | } 9 | 10 | public get handle(): number { 11 | return this._handle; 12 | } 13 | 14 | public get isValid(): boolean { 15 | return this._handle != 0; 16 | } 17 | 18 | public get isLoaded(): boolean { 19 | return HasScaleformMovieLoaded(this._handle) === 1; 20 | } 21 | 22 | private callFunctionHead(funcName: string, ...args: any[]): void { 23 | if (!this.isValid || !this.isLoaded) 24 | return; 25 | 26 | BeginScaleformMovieMethod(this._handle, funcName); 27 | 28 | args.forEach((arg: any) => { 29 | switch (typeof arg) { 30 | case "number": 31 | { 32 | if (Number(arg) === arg && arg % 1 !== 0) { 33 | ScaleformMovieMethodAddParamFloat(arg); 34 | } 35 | else { 36 | ScaleformMovieMethodAddParamInt(arg); 37 | } 38 | } 39 | case "string": 40 | { 41 | ScaleformMovieMethodAddParamPlayerNameString(arg as string); 42 | break; 43 | } 44 | case "boolean": 45 | { 46 | ScaleformMovieMethodAddParamBool(arg); 47 | break; 48 | } 49 | default: 50 | { 51 | console.log(`Unknown argument type ${typeof arg} = ${arg.toString()} passed to scaleform with handle ${this._handle}`); 52 | } 53 | } 54 | }); 55 | } 56 | 57 | public callFunction(funcName: string, ...args: any[]): void { 58 | this.callFunctionHead(funcName, ...args); 59 | EndScaleformMovieMethod(); 60 | } 61 | 62 | public callFunctionReturn(funcName: string, ...args: any[]): number { 63 | this.callFunctionHead(funcName, ...args); 64 | return EndScaleformMovieMethodReturnValue(); 65 | } 66 | 67 | public render2D(): void { 68 | if (!this.isValid || !this.isLoaded) 69 | return; 70 | DrawScaleformMovieFullscreen(this._handle, 255, 255, 255, 255, 0); 71 | } 72 | 73 | public recreate(): void { 74 | if (!this.isValid || !this.isLoaded) 75 | return; 76 | SetScaleformMovieAsNoLongerNeeded(this._handle); 77 | this._handle = RequestScaleformMovie(this.scaleForm); 78 | } 79 | 80 | public destroy(): void { 81 | if (!this.isValid) 82 | return; 83 | SetScaleformMovieAsNoLongerNeeded(this._handle); 84 | this._handle = 0; 85 | } 86 | } -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/items/UIMenuItem.d.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import NativeUI from "../NativeUi"; 3 | import ResRectangle from "../modules/ResRectangle"; 4 | import ResText from "../modules/ResText"; 5 | import Sprite from "../modules/Sprite"; 6 | import Color from "../utils/Color"; 7 | import Point from "../utils/Point"; 8 | export default class UIMenuItem { 9 | readonly Id: string; 10 | static readonly DefaultBackColor: Color; 11 | static readonly DefaultHighlightedBackColor: Color; 12 | static readonly DefaultForeColor: Color; 13 | static readonly DefaultHighlightedForeColor: Color; 14 | private _event; 15 | protected _rectangle: ResRectangle; 16 | protected _text: ResText; 17 | protected _description: string; 18 | protected _selectedSprite: Sprite; 19 | protected _badgeLeft: Sprite; 20 | protected _badgeRight: Sprite; 21 | protected _labelText: ResText; 22 | BackColor: Color; 23 | HighlightedBackColor: Color; 24 | ForeColor: Color; 25 | HighlightedForeColor: Color; 26 | Enabled: boolean; 27 | Selected: boolean; 28 | Hovered: boolean; 29 | Data: any; 30 | Offset: Point; 31 | Parent: NativeUI; 32 | get Text(): string; 33 | set Text(text: string); 34 | get Description(): string; 35 | set Description(text: string); 36 | RightLabel: string; 37 | LeftBadge: BadgeStyle; 38 | RightBadge: BadgeStyle; 39 | constructor(text: string, description?: string, data?: any); 40 | SetVerticalPosition(y: number): void; 41 | addEvent(event: string, ...args: any[]): void; 42 | fireEvent(): void; 43 | Draw(): void; 44 | SetLeftBadge(badge: BadgeStyle): void; 45 | SetRightBadge(badge: BadgeStyle): void; 46 | SetRightLabel(text: string): void; 47 | BadgeToSpriteLib(badge: BadgeStyle): "commonmenu" | "mpshopsale" | "mpleaderboard"; 48 | BadgeToSpriteName(badge: BadgeStyle, selected: boolean): "" | "mp_medal_bronze" | "mp_medal_gold" | "medal_silver" | "mp_alerttriangle" | "mp_hostcrown" | "shop_ammo_icon_b" | "shop_ammo_icon_a" | "shop_armour_icon_b" | "shop_armour_icon_a" | "shop_barber_icon_b" | "shop_barber_icon_a" | "shop_clothing_icon_b" | "shop_clothing_icon_a" | "shop_franklin_icon_b" | "shop_franklin_icon_a" | "shop_garage_bike_icon_b" | "shop_garage_bike_icon_a" | "shop_garage_icon_b" | "shop_garage_icon_a" | "shop_gunclub_icon_b" | "shop_gunclub_icon_a" | "shop_health_icon_b" | "shop_health_icon_a" | "shop_lock" | "shop_makeup_icon_b" | "shop_makeup_icon_a" | "shop_mask_icon_b" | "shop_mask_icon_a" | "shop_michael_icon_b" | "shop_michael_icon_a" | "shop_new_star" | "shop_tattoos_icon_b" | "shop_tattoos_icon_a" | "shop_tick_icon" | "shop_trevor_icon_b" | "shop_trevor_icon_a" | "saleicon" | "arrowleft" | "arrowright" | "leaderboard_audio_1" | "leaderboard_audio_2" | "leaderboard_audio_3" | "leaderboard_audio_inactive" | "leaderboard_audio_mute"; 49 | IsBagdeWhiteSprite(badge: BadgeStyle): boolean; 50 | BadgeToColor(badge: BadgeStyle, selected: boolean): Color; 51 | } 52 | -------------------------------------------------------------------------------- /src/modules/ResText.js: -------------------------------------------------------------------------------- 1 | import Alignment from "../enums/Alignment"; 2 | import game from 'natives'; 3 | import Color from "../utils/Color"; 4 | import Point from "../utils/Point"; 5 | import Size from "../utils/Size"; 6 | import Text from "./Text"; 7 | import Screen from "../utils/Screen"; 8 | export default class ResText extends Text { 9 | constructor(caption, pos, scale, color, font, centered) { 10 | super(caption, pos, scale, color || new Color(255, 255, 255), font || 0, false); 11 | this.TextAlignment = Alignment.Left; 12 | this.Wrap = 0; 13 | if (centered) 14 | this.TextAlignment = centered; 15 | } 16 | get WordWrap() { 17 | return new Size(this.Wrap, 0); 18 | } 19 | set WordWrap(value) { 20 | this.Wrap = value.Width; 21 | } 22 | Draw(arg1, pos, scale, color, font, arg2, dropShadow, outline, wordWrap) { 23 | let caption = arg1; 24 | let centered = arg2; 25 | let textAlignment = arg2; 26 | if (!arg1) 27 | arg1 = new Size(0, 0); 28 | if (arg1 && !pos) { 29 | textAlignment = this.TextAlignment; 30 | caption = this.Caption; 31 | pos = new Point(this.Pos.X + arg1.Width, this.Pos.Y + arg1.Height); 32 | scale = this.Scale; 33 | color = this.Color; 34 | font = this.Font; 35 | if (centered == true || centered == false) { 36 | centered = this.Centered; 37 | } 38 | else { 39 | centered = undefined; 40 | dropShadow = this.DropShadow; 41 | outline = this.Outline; 42 | wordWrap = this.WordWrap; 43 | } 44 | } 45 | const screenw = Screen.Width; 46 | const screenh = Screen.Height; 47 | const height = 1080.0; 48 | const ratio = screenw / screenh; 49 | const width = height * ratio; 50 | const x = this.Pos.X / width; 51 | const y = this.Pos.Y / height; 52 | SetTextFont(parseInt(font)); 53 | SetTextScale(1.0, scale); 54 | SetTextColour(color.R, color.G, color.B, color.A); 55 | if (centered !== undefined) { 56 | SetTextCentre(centered); 57 | } 58 | else { 59 | if (dropShadow) 60 | SetTextDropshadow(2, 0, 0, 0, 0); 61 | switch (textAlignment) { 62 | case Alignment.Centered: 63 | SetTextCentre(true); 64 | break; 65 | case Alignment.Right: 66 | SetTextRightJustify(true); 67 | SetTextWrap(0.0, x); 68 | break; 69 | } 70 | if (this.Wrap) { 71 | const xsize = (this.Pos.X + this.Wrap) / width; 72 | SetTextWrap(x, xsize); 73 | } 74 | } 75 | BeginTextCommandDisplayText("CELL_EMAIL_BCON"); 76 | Text.AddLongString(caption); 77 | EndTextCommandDisplayText(x, y, 0); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/modules/Sprite.ts: -------------------------------------------------------------------------------- 1 | import Color from "../utils/Color"; 2 | import Point from "../utils/Point"; 3 | import Size from "../utils/Size"; 4 | import Screen from "../utils/Screen"; 5 | 6 | export default class Sprite { 7 | public TextureName: string; 8 | public Pos: Point; 9 | public Size: Size; 10 | public Heading: number; 11 | public Color: Color; 12 | public Visible: boolean; 13 | 14 | private _textureDict: string; 15 | 16 | constructor(textureDict: string, textureName: string, pos: Point, size: Size, heading = 0, color = new Color(255, 255, 255)) { 17 | this.TextureDict = textureDict; 18 | this.TextureName = textureName; 19 | this.Pos = pos; 20 | this.Size = size; 21 | this.Heading = heading; 22 | this.Color = color; 23 | this.Visible = true; 24 | } 25 | 26 | public LoadTextureDictionary() { 27 | this.requestTextureDictPromise(this._textureDict).then((succ) => { }); 28 | } 29 | private requestTextureDictPromise(textureDict: string) { 30 | return new Promise((resolve, reject) => { 31 | RequestStreamedTextureDict(textureDict, true); 32 | let inter = setInterval(() => { 33 | if (HasStreamedTextureDictLoaded(textureDict)) { 34 | clearInterval(inter); 35 | return resolve(true); 36 | } 37 | }, 10); 38 | }); 39 | } 40 | 41 | public set TextureDict(v) { 42 | this._textureDict = v; 43 | if (!this.IsTextureDictionaryLoaded) this.LoadTextureDictionary(); 44 | } 45 | public get TextureDict(): string { 46 | return this._textureDict; 47 | } 48 | 49 | public get IsTextureDictionaryLoaded() { 50 | return HasStreamedTextureDictLoaded(this._textureDict); 51 | } 52 | 53 | public Draw(textureDictionary?: string, textureName?: string, pos?: Point, size?: Size, heading?: number, color?: Color, loadTexture?: boolean) { 54 | textureDictionary = textureDictionary || this.TextureDict; 55 | textureName = textureName || this.TextureName; 56 | pos = pos || this.Pos; 57 | size = size || this.Size; 58 | heading = heading || this.Heading; 59 | color = color || this.Color; 60 | loadTexture = loadTexture || true; 61 | 62 | if (loadTexture) { 63 | if (!HasStreamedTextureDictLoaded(textureDictionary)) 64 | RequestStreamedTextureDict(textureDictionary, true); 65 | } 66 | 67 | const screenw = Screen.Width; 68 | const screenh = Screen.Height; 69 | const height = 1080.0; 70 | const ratio = screenw / screenh; 71 | const width = height * ratio; 72 | 73 | const w = this.Size.Width / width; 74 | const h = this.Size.Height / height; 75 | const x = this.Pos.X / width + w * 0.5; 76 | const y = this.Pos.Y / height + h * 0.5; 77 | 78 | DrawSprite(textureDictionary, textureName, x, y, w, h, heading, color.R, color.G, color.B, color.A); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/modules/Message.js: -------------------------------------------------------------------------------- 1 | import Scaleform from '../utils/Scaleform'; 2 | export default class Message { 3 | static Initialize(scaleForm, transitionOutAnimName) { 4 | this._transitionOutAnimName = transitionOutAnimName; 5 | this._scaleform = new Scaleform(scaleForm); 6 | } 7 | static get IsVisible() { 8 | return this._messageVisible; 9 | } 10 | static get Scaleform() { 11 | return this._scaleform; 12 | } 13 | static Load() { 14 | if (this._delayedTransitionInTimeout != null) { 15 | clearTimeout(this._delayedTransitionInTimeout); 16 | this._delayedTransitionInTimeout = null; 17 | } 18 | } 19 | static SetDelayedTransition(messageHandler, time) { 20 | this._delayedTransitionInTimeout = setTimeout(() => { 21 | this._delayedTransitionInTimeout = null; 22 | this.TransitionIn(messageHandler, time); 23 | }, this._transitionOutTimeMs); 24 | } 25 | static ShowCustomShard(funcName, time = 5000, ...funcArgs) { 26 | this.ShowComplexCustomShard(() => { 27 | this._scaleform.callFunction(funcName, ...funcArgs); 28 | }, time); 29 | } 30 | static ShowComplexCustomShard(messageHandler, time = 5000) { 31 | this.Load(); 32 | if (this._messageVisible) { 33 | this.TransitionOut(); 34 | this.SetDelayedTransition(() => messageHandler(), time); 35 | } 36 | else { 37 | this.TransitionIn(messageHandler, time); 38 | } 39 | } 40 | static TransitionOut() { 41 | if (!this._messageVisible) 42 | return; 43 | if (this._transitionOutTimeout != null) { 44 | clearTimeout(this._transitionOutTimeout); 45 | this._transitionOutTimeout = null; 46 | } 47 | if (this._transitionOutFinishedTimeout != null) { 48 | clearTimeout(this._transitionOutFinishedTimeout); 49 | this._transitionOutFinishedTimeout = null; 50 | } 51 | this._scaleform.callFunction(this._transitionOutAnimName); 52 | this._transitionOutFinishedTimeout = setTimeout(() => { 53 | this._messageVisible = false; 54 | this._scaleform.recreate(); 55 | }, this._transitionOutTimeMs); 56 | } 57 | static TransitionIn(messageHandler, transitionOutTime = 500) { 58 | this._messageVisible = true; 59 | messageHandler(); 60 | this.SetTransitionOutTimer(transitionOutTime); 61 | } 62 | static SetTransitionOutTimer(time) { 63 | this._transitionOutTimeout = setTimeout(() => { 64 | this._transitionOutTimeout = null; 65 | this.TransitionOut(); 66 | }, time); 67 | } 68 | static Render() { 69 | if (this._messageVisible) { 70 | this._scaleform.render2D(); 71 | } 72 | } 73 | } 74 | Message._messageVisible = false; 75 | Message._transitionOutTimeout = null; 76 | Message._transitionOutFinishedTimeout = null; 77 | Message._delayedTransitionInTimeout = null; 78 | Message._scaleform = null; 79 | Message._transitionOutTimeMs = 500; 80 | Message._transitionOutAnimName = null; 81 | -------------------------------------------------------------------------------- /src/utils/Screen.ts: -------------------------------------------------------------------------------- 1 | import Font from "../enums/Font"; 2 | import Point from "./Point"; 3 | import Size from "./Size"; 4 | import Text from '../modules/Text'; 5 | 6 | const gameScreen: number[] = GetActiveScreenResolution(); 7 | 8 | export default class Screen { 9 | public static Width: number = gameScreen[0]; 10 | public static Height: number = gameScreen[1]; 11 | 12 | public static get ResolutionMaintainRatio(): Size { 13 | const ratio = Screen.Width / Screen.Height; 14 | const width = 1080.0 * ratio; 15 | 16 | return new Size(width, 1080.0); 17 | } 18 | 19 | public static MousePosition(relative: boolean = false): { X: number; Y: number } { 20 | const res = Screen.ResolutionMaintainRatio; 21 | let [mouseX, mouseY] = GetNuiCursorPosition(); 22 | if (relative) 23 | [mouseX, mouseY] = [mouseX / res.Width, mouseY / res.Height]; 24 | return { 25 | X: mouseX, 26 | Y: mouseY 27 | }; 28 | } 29 | 30 | public static IsMouseInBounds(topLeft: Point, boxSize: Size) { 31 | const mousePosition = Screen.MousePosition(); 32 | return ( 33 | mousePosition.X >= topLeft.X && 34 | mousePosition.X <= topLeft.X + boxSize.Width && 35 | (mousePosition.Y > topLeft.Y && mousePosition.Y < topLeft.Y + boxSize.Height) 36 | ); 37 | } 38 | 39 | public static GetTextWidth(text: string, font: Font, scale: number): number { 40 | // Start by requesting the game to start processing a width measurement 41 | BeginTextCommandWidth("CELL_EMAIL_BCON"); 42 | // Add the text string 43 | Text.AddLongString(text); 44 | 45 | // Set the properties for the text 46 | SetTextFont(font); 47 | SetTextScale(1.0, scale); 48 | 49 | // Ask the game for the relative string width 50 | const width: number = EndTextCommandGetWidth(true); 51 | // And return the literal result 52 | const res = Screen.ResolutionMaintainRatio; 53 | return res.Width * width; 54 | } 55 | 56 | public static GetLineCount(text: string, position: Point, font: Font, scale: number, wrap: number): number { 57 | // Tell the game that we are going to request the number of lines 58 | BeginTextCommandLineCount("CELL_EMAIL_BCON"); 59 | // Add the text that has been sent to us 60 | Text.AddLongString(text); 61 | 62 | // Get the resolution with the correct aspect ratio 63 | const res: Size = Screen.ResolutionMaintainRatio; 64 | // Calculate the x and y positions 65 | const x: number = position.X / res.Width; 66 | const y: number = position.Y / res.Height; 67 | 68 | // Set the properties for the text 69 | SetTextFont(font); 70 | SetTextScale(1.0, scale); 71 | 72 | // If there is some text wrap to add 73 | if (wrap > 0) { 74 | // Calculate the wrap size 75 | const start: number = position.X / res.Width; 76 | const end: number = start + (wrap / res.Width); 77 | // And apply it 78 | SetTextWrap(x, end); 79 | } 80 | 81 | // Finally, return the number of lines being made by the string 82 | let lineCount = EndTextCommandGetLineCount(x, y); 83 | return lineCount; 84 | } 85 | } -------------------------------------------------------------------------------- /src/items/UIMenuSliderItem.js: -------------------------------------------------------------------------------- 1 | import ResRectangle from "../modules/ResRectangle"; 2 | import Sprite from "../modules/Sprite"; 3 | import Color from "../utils/Color"; 4 | import Point from "../utils/Point"; 5 | import Size from "../utils/Size"; 6 | import UIMenuItem from "./UIMenuItem"; 7 | export default class UIMenuSliderItem extends UIMenuItem { 8 | constructor(text, items, index, description = "", divider = false, data = null) { 9 | super(text, description, data); 10 | const y = 0; 11 | this._items = items; 12 | this._arrowLeft = new Sprite("commonmenutu", "arrowleft", new Point(0, 105 + y), new Size(15, 15)); 13 | this._arrowRight = new Sprite("commonmenutu", "arrowright", new Point(0, 105 + y), new Size(15, 15)); 14 | this._rectangleBackground = new ResRectangle(new Point(0, 0), new Size(150, 9), new Color(4, 32, 57, 255)); 15 | this._rectangleSlider = new ResRectangle(new Point(0, 0), new Size(75, 9), new Color(57, 116, 200, 255)); 16 | if (divider) { 17 | this._rectangleDivider = new ResRectangle(new Point(0, 0), new Size(2.5, 20), Color.WhiteSmoke); 18 | } 19 | else { 20 | this._rectangleDivider = new ResRectangle(new Point(0, 0), new Size(2.5, 20), Color.Transparent); 21 | } 22 | this.Index = index; 23 | } 24 | get Index() { 25 | return this._index % this._items.length; 26 | } 27 | set Index(value) { 28 | this._index = 100000000 - (100000000 % this._items.length) + value; 29 | } 30 | SetVerticalPosition(y) { 31 | this._rectangleBackground.Pos = new Point(250 + this.Offset.X + this.Parent.WidthOffset, y + 158.5 + this.Offset.Y); 32 | this._rectangleSlider.Pos = new Point(250 + this.Offset.X + this.Parent.WidthOffset, y + 158.5 + this.Offset.Y); 33 | this._rectangleDivider.Pos = new Point(323.5 + this.Offset.X + this.Parent.WidthOffset, y + 153 + this.Offset.Y); 34 | this._arrowLeft.Pos = new Point(235 + this.Offset.X + this.Parent.WidthOffset, 155.5 + y + this.Offset.Y); 35 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 155.5 + y + this.Offset.Y); 36 | super.SetVerticalPosition(y); 37 | } 38 | IndexToItem(index) { 39 | return this._items[index]; 40 | } 41 | Draw() { 42 | super.Draw(); 43 | this._arrowLeft.Color = this.Enabled 44 | ? this.Selected 45 | ? Color.Black 46 | : Color.WhiteSmoke 47 | : new Color(163, 159, 148); 48 | this._arrowRight.Color = this.Enabled 49 | ? this.Selected 50 | ? Color.Black 51 | : Color.WhiteSmoke 52 | : new Color(163, 159, 148); 53 | let offset = ((this._rectangleBackground.Size.Width - this._rectangleSlider.Size.Width) / (this._items.length - 1)) * this.Index; 54 | this._rectangleSlider.Pos = new Point(250 + this.Offset.X + offset + +this.Parent.WidthOffset, this._rectangleSlider.Pos.Y); 55 | if (this.Selected) { 56 | this._arrowLeft.Draw(); 57 | this._arrowRight.Draw(); 58 | } 59 | this._rectangleBackground.Draw(); 60 | this._rectangleSlider.Draw(); 61 | this._rectangleDivider.Draw(); 62 | } 63 | SetRightBadge(badge) { } 64 | SetRightLabel(text) { } 65 | } 66 | -------------------------------------------------------------------------------- /src/modules/ResText.ts: -------------------------------------------------------------------------------- 1 | import Alignment from "../enums/Alignment"; 2 | import Color from "../utils/Color"; 3 | import Point from "../utils/Point"; 4 | import Size from "../utils/Size"; 5 | import Text from "./Text"; 6 | import Screen from "../utils/Screen"; 7 | 8 | export default class ResText extends Text { 9 | public TextAlignment: Alignment = Alignment.Left; 10 | public DropShadow: boolean; 11 | public Outline: boolean; 12 | public Wrap: number = 0; 13 | 14 | public get WordWrap() { 15 | return new Size(this.Wrap, 0); 16 | } 17 | public set WordWrap(value) { 18 | this.Wrap = value.Width; 19 | } 20 | 21 | constructor(caption: string, pos: Point, scale: number, color?: Color, font?: number, centered?: Alignment) { 22 | super(caption, pos, scale, color || new Color(255, 255, 255), font || 0, false); 23 | if (centered) this.TextAlignment = centered; 24 | } 25 | 26 | public Draw(): void; 27 | public Draw(offset: Size): void; 28 | public Draw(caption: Size, pos: Point, scale: number, color: Color, font: string | number, arg2: any): void; 29 | 30 | public Draw(arg1?: any, pos?: Point, scale?: number, color?: Color, font?: string | number, arg2?: any, dropShadow?: boolean, outline?: boolean, wordWrap?: Size) { 31 | let caption = arg1; 32 | let centered = arg2; 33 | let textAlignment = arg2; 34 | if (!arg1) arg1 = new Size(0, 0); 35 | 36 | if (arg1 && !pos) { 37 | textAlignment = this.TextAlignment; 38 | caption = this.Caption; 39 | pos = new Point(this.Pos.X + arg1.Width, this.Pos.Y + arg1.Height); 40 | scale = this.Scale; 41 | color = this.Color; 42 | font = this.Font; 43 | if (centered == true || centered == false) { 44 | centered = this.Centered; 45 | } else { 46 | centered = undefined; 47 | dropShadow = this.DropShadow; 48 | outline = this.Outline; 49 | wordWrap = this.WordWrap; 50 | } 51 | } 52 | 53 | const screenw = Screen.Width; 54 | const screenh = Screen.Height; 55 | 56 | const height = 1080.0; 57 | const ratio = screenw / screenh; 58 | const width = height * ratio; 59 | 60 | const x = this.Pos.X / width; 61 | const y = this.Pos.Y / height; 62 | 63 | SetTextFont(parseInt(font as string)); 64 | SetTextScale(1.0, scale); 65 | SetTextColour(color.R, color.G, color.B, color.A); 66 | 67 | if (centered !== undefined) { 68 | SetTextCentre(centered); 69 | } else { 70 | if (dropShadow) SetTextDropshadow(2, 0, 0, 0, 0); 71 | 72 | switch (textAlignment) { 73 | case Alignment.Centered: 74 | SetTextCentre(true); 75 | break; 76 | case Alignment.Right: 77 | SetTextRightJustify(true); 78 | SetTextWrap(0.0, x); 79 | break; 80 | } 81 | 82 | if (this.Wrap) { 83 | const xsize = (this.Pos.X + this.Wrap) / width; 84 | SetTextWrap(x, xsize); 85 | } 86 | } 87 | 88 | BeginTextCommandDisplayText("CELL_EMAIL_BCON"); 89 | Text.AddLongString(caption as string); 90 | EndTextCommandDisplayText(x, y); 91 | } 92 | } -------------------------------------------------------------------------------- /src/modules/Message.ts: -------------------------------------------------------------------------------- 1 | import Scaleform from '../utils/Scaleform'; 2 | 3 | export default class Message { 4 | private static _messageVisible: boolean = false; 5 | private static _transitionOutTimeout: NodeJS.Timeout = null; 6 | private static _transitionOutFinishedTimeout: NodeJS.Timeout = null; 7 | private static _delayedTransitionInTimeout: NodeJS.Timeout = null; 8 | private static _scaleform: Scaleform = null; 9 | private static _transitionOutTimeMs: number = 500; 10 | private static _transitionOutAnimName: string = null; 11 | 12 | protected static Initialize(scaleForm: string, transitionOutAnimName: string) { 13 | this._transitionOutAnimName = transitionOutAnimName; 14 | this._scaleform = new Scaleform(scaleForm); 15 | } 16 | 17 | public static get IsVisible(): boolean { 18 | return this._messageVisible; 19 | } 20 | 21 | protected static get Scaleform(): Scaleform { 22 | return this._scaleform; 23 | } 24 | 25 | private static Load() { 26 | //Make sure there is no delayed transition existing 27 | if (this._delayedTransitionInTimeout != null) { 28 | clearTimeout(this._delayedTransitionInTimeout); 29 | this._delayedTransitionInTimeout = null; 30 | } 31 | } 32 | 33 | //Delayed transition is needed when transition out got played before, this is the case when bigmessage is called before other one is finished showing. 34 | private static SetDelayedTransition(messageHandler: { (): void }, time: number) { 35 | this._delayedTransitionInTimeout = setTimeout(() => { 36 | this._delayedTransitionInTimeout = null; 37 | this.TransitionIn(messageHandler, time); 38 | }, this._transitionOutTimeMs); 39 | } 40 | 41 | public static ShowCustomShard(funcName: string, time: number = 5000, ...funcArgs: any[]): void { 42 | this.ShowComplexCustomShard(() => { 43 | this._scaleform.callFunction(funcName, ...funcArgs); 44 | }, time); 45 | } 46 | 47 | public static ShowComplexCustomShard(messageHandler: { (): void }, time: number = 5000): void { 48 | this.Load(); 49 | if (this._messageVisible) { //When a shard is already shown 50 | this.TransitionOut(); 51 | this.SetDelayedTransition(() => messageHandler(), time); 52 | } 53 | else { 54 | this.TransitionIn(messageHandler, time); 55 | } 56 | } 57 | 58 | protected static TransitionOut() { 59 | if (!this._messageVisible) 60 | return; 61 | if (this._transitionOutTimeout != null) { 62 | clearTimeout(this._transitionOutTimeout); 63 | this._transitionOutTimeout = null; 64 | } 65 | if (this._transitionOutFinishedTimeout != null) { 66 | clearTimeout(this._transitionOutFinishedTimeout); 67 | this._transitionOutFinishedTimeout = null; 68 | } 69 | this._scaleform.callFunction(this._transitionOutAnimName); 70 | this._transitionOutFinishedTimeout = setTimeout(() => { 71 | this._messageVisible = false; 72 | this._scaleform.recreate(); 73 | }, this._transitionOutTimeMs); 74 | } 75 | 76 | private static TransitionIn(messageHandler: { (): void }, transitionOutTime: number = 500) { 77 | this._messageVisible = true; 78 | messageHandler(); 79 | this.SetTransitionOutTimer(transitionOutTime); 80 | } 81 | 82 | private static SetTransitionOutTimer(time: number) { 83 | this._transitionOutTimeout = setTimeout(() => { 84 | this._transitionOutTimeout = null; 85 | this.TransitionOut(); 86 | }, time); 87 | } 88 | 89 | protected static Render() { 90 | if (this._messageVisible) { 91 | this._scaleform.render2D(); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/items/UIMenuSliderItem.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import ResRectangle from "../modules/ResRectangle"; 3 | import Sprite from "../modules/Sprite"; 4 | import Color from "../utils/Color"; 5 | import Point from "../utils/Point"; 6 | import Size from "../utils/Size"; 7 | import UIMenuItem from "./UIMenuItem"; 8 | 9 | export default class UIMenuSliderItem extends UIMenuItem { 10 | private _arrowLeft: Sprite; 11 | private _arrowRight: Sprite; 12 | private _rectangleBackground: ResRectangle; 13 | private _rectangleSlider: ResRectangle; 14 | private _rectangleDivider: ResRectangle; 15 | private _items: any[]; 16 | private _index: number; 17 | 18 | public get Index() { 19 | return this._index % this._items.length; 20 | } 21 | public set Index(value) { 22 | this._index = 100000000 - (100000000 % this._items.length) + value; 23 | } 24 | 25 | constructor(text: string, items: any[], index: number, description: string = "", divider: boolean = false, data: any = null) { 26 | super(text, description, data); 27 | 28 | const y: number = 0; 29 | this._items = items; 30 | this._arrowLeft = new Sprite("commonmenutu", "arrowleft", new Point(0, 105 + y), new Size(15, 15)); 31 | this._arrowRight = new Sprite("commonmenutu", "arrowright", new Point(0, 105 + y), new Size(15, 15)); 32 | this._rectangleBackground = new ResRectangle(new Point(0, 0), new Size(150, 9), new Color(4, 32, 57, 255)); 33 | this._rectangleSlider = new ResRectangle(new Point(0, 0), new Size(75, 9), new Color(57, 116, 200, 255)); 34 | if (divider) { 35 | this._rectangleDivider = new ResRectangle(new Point(0, 0), new Size(2.5, 20), Color.WhiteSmoke); 36 | } else { 37 | this._rectangleDivider = new ResRectangle(new Point(0, 0), new Size(2.5, 20), Color.Transparent); 38 | } 39 | this.Index = index; 40 | } 41 | 42 | public SetVerticalPosition(y: number) { 43 | this._rectangleBackground.Pos = new Point(250 + this.Offset.X + this.Parent.WidthOffset, y + 158.5 + this.Offset.Y); 44 | this._rectangleSlider.Pos = new Point(250 + this.Offset.X + this.Parent.WidthOffset, y + 158.5 + this.Offset.Y); 45 | this._rectangleDivider.Pos = new Point(323.5 + this.Offset.X + this.Parent.WidthOffset, y + 153 + this.Offset.Y); 46 | this._arrowLeft.Pos = new Point(235 + this.Offset.X + this.Parent.WidthOffset, 155.5 + y + this.Offset.Y); 47 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 155.5 + y + this.Offset.Y); 48 | 49 | super.SetVerticalPosition(y); 50 | } 51 | 52 | public IndexToItem(index: number) { 53 | return this._items[index]; 54 | } 55 | 56 | public Draw() { 57 | super.Draw(); 58 | this._arrowLeft.Color = this.Enabled 59 | ? this.Selected 60 | ? Color.Black 61 | : Color.WhiteSmoke 62 | : new Color(163, 159, 148); 63 | this._arrowRight.Color = this.Enabled 64 | ? this.Selected 65 | ? Color.Black 66 | : Color.WhiteSmoke 67 | : new Color(163, 159, 148); 68 | let offset = ((this._rectangleBackground.Size.Width - this._rectangleSlider.Size.Width) / (this._items.length - 1)) * this.Index; 69 | this._rectangleSlider.Pos = new Point(250 + this.Offset.X + offset + +this.Parent.WidthOffset, this._rectangleSlider.Pos.Y); 70 | if (this.Selected) { 71 | this._arrowLeft.Draw(); 72 | this._arrowRight.Draw(); 73 | } 74 | this._rectangleBackground.Draw(); 75 | this._rectangleSlider.Draw(); 76 | this._rectangleDivider.Draw(); 77 | } 78 | 79 | public SetRightBadge(badge: BadgeStyle) { } 80 | 81 | public SetRightLabel(text: string) { } 82 | } 83 | -------------------------------------------------------------------------------- /src/items/UIMenuDynamicListItem.js: -------------------------------------------------------------------------------- 1 | import Font from "../enums/Font"; 2 | import Alignment from "../enums/Alignment"; 3 | import ResText from "../modules/ResText"; 4 | import Sprite from "../modules/Sprite"; 5 | import Color from "../utils/Color"; 6 | import Point from "../utils/Point"; 7 | import Size from "../utils/Size"; 8 | import Screen from "../utils/Screen"; 9 | import UIMenuItem from "./UIMenuItem"; 10 | export default class UIMenuDynamicListItem extends UIMenuItem { 11 | constructor(text, selectionChangeHandler, description = "", selectedStartValueHandler = null, data = null) { 12 | super(text, description, data); 13 | this._currentOffset = 0; 14 | this._precaptionText = ''; 15 | this._selectedStartValueHandler = null; 16 | this.SelectionChangeHandler = null; 17 | if (!this.isVariableFunction(selectionChangeHandler)) { 18 | console.log(`[UIMenuDynamicListItem] ${text} is not created with a valid selectionChangeHandler, needs to be function. Please see docs.`); 19 | } 20 | if (!this.isVariableFunction(selectedStartValueHandler)) { 21 | console.log(`[UIMenuDynamicListItem] ${text} is not created with a valid selectedStartValueHandler, needs to be function. Please see docs.`); 22 | } 23 | this.SelectionChangeHandler = selectionChangeHandler; 24 | this._selectedStartValueHandler = selectedStartValueHandler; 25 | let y = 0; 26 | this._arrowLeft = new Sprite("commonmenu", "arrowleft", new Point(110, 105 + y), new Size(30, 30)); 27 | this._arrowRight = new Sprite("commonmenu", "arrowright", new Point(280, 105 + y), new Size(30, 30)); 28 | this._itemText = new ResText("", new Point(290, y + 104), 0.35, Color.White, Font.ChaletLondon, Alignment.Right); 29 | } 30 | SelectionChangeHandlerPromise(item, selectedValue, changeDirection) { 31 | return new Promise((resolve, reject) => { 32 | let newSelectedValue = this.SelectionChangeHandler(item, selectedValue, changeDirection); 33 | resolve(newSelectedValue); 34 | }); 35 | } 36 | get PreCaptionText() { 37 | return this._precaptionText; 38 | } 39 | set PreCaptionText(text) { 40 | if (!text) 41 | throw new Error("The pre caption text can't be null"); 42 | if (typeof text !== 'string') 43 | throw new Error("The pre caption text must be a string"); 44 | this._precaptionText = text; 45 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); 46 | } 47 | get SelectedValue() { 48 | return this._selectedValue; 49 | } 50 | set SelectedValue(value) { 51 | this._selectedValue = value; 52 | if (value == undefined) 53 | return; 54 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue, this._itemText && this._itemText.Font ? this._itemText.Font : 0, this._itemText && this._itemText.Scale ? this._itemText.Scale : 0.35); 55 | } 56 | SetVerticalPosition(y) { 57 | this._arrowLeft.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 58 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 59 | this._itemText.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, y + 147 + this.Offset.Y); 60 | super.SetVerticalPosition(y); 61 | } 62 | SetRightLabel(text) { 63 | return this; 64 | } 65 | SetRightBadge(badge) { 66 | return this; 67 | } 68 | Draw() { 69 | super.Draw(); 70 | if (this._selectedValue == undefined) { 71 | if (this._selectedStartValueHandler != null) { 72 | this.SelectedValue = this._selectedStartValueHandler(); 73 | } 74 | else { 75 | this._selectedValue = ""; 76 | } 77 | } 78 | const offset = this._currentOffset; 79 | this._itemText.Color = this.Enabled 80 | ? this.Selected 81 | ? this.HighlightedForeColor 82 | : this.ForeColor 83 | : new Color(163, 159, 148); 84 | this._itemText.Caption = this.PreCaptionText + this._selectedValue; 85 | this._arrowLeft.Color = this.Enabled 86 | ? this.Selected 87 | ? this.HighlightedForeColor 88 | : this.ForeColor 89 | : new Color(163, 159, 148); 90 | this._arrowRight.Color = this.Enabled 91 | ? this.Selected 92 | ? this.HighlightedForeColor 93 | : this.ForeColor 94 | : new Color(163, 159, 148); 95 | this._arrowLeft.Pos = new Point(380 - offset + this.Offset.X + this.Parent.WidthOffset, this._arrowLeft.Pos.Y); 96 | if (this.Selected) { 97 | this._arrowLeft.Draw(); 98 | this._arrowRight.Draw(); 99 | this._itemText.Pos = new Point(405 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 100 | } 101 | else { 102 | this._itemText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 103 | } 104 | this._itemText.Draw(); 105 | } 106 | isVariableFunction(functionToCheck) { 107 | return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]'; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/items/UIMenuListItem.js: -------------------------------------------------------------------------------- 1 | import Font from "../enums/Font"; 2 | import Alignment from "../enums/Alignment"; 3 | import ItemsCollection from "../modules/ItemsCollection"; 4 | import ListItem from "../modules/ListItem"; 5 | import ResText from "../modules/ResText"; 6 | import Sprite from "../modules/Sprite"; 7 | import Color from "../utils/Color"; 8 | import Point from "../utils/Point"; 9 | import Size from "../utils/Size"; 10 | import Screen from "../utils/Screen"; 11 | import UIMenuItem from "./UIMenuItem"; 12 | export default class UIMenuListItem extends UIMenuItem { 13 | constructor(text, description = "", collection = new ItemsCollection([]), startIndex = 0, data = null) { 14 | super(text, description, data); 15 | this.ScrollingEnabled = true; 16 | this.HoldTimeBeforeScroll = 200; 17 | this._currentOffset = 0; 18 | this._itemsCollection = []; 19 | this._index = 0; 20 | let y = 0; 21 | this.Collection = collection.getListItems(); 22 | this.Index = startIndex; 23 | this._arrowLeft = new Sprite("commonmenu", "arrowleft", new Point(110, 105 + y), new Size(30, 30)); 24 | this._arrowRight = new Sprite("commonmenu", "arrowright", new Point(280, 105 + y), new Size(30, 30)); 25 | this._itemText = new ResText("", new Point(290, y + 104), 0.35, Color.White, Font.ChaletLondon, Alignment.Right); 26 | } 27 | get Collection() { 28 | return this._itemsCollection; 29 | } 30 | set Collection(v) { 31 | if (!v) 32 | throw new Error("The collection can't be null"); 33 | this._itemsCollection = v; 34 | } 35 | set SelectedItem(v) { 36 | const idx = this.Collection.findIndex(li => li.Id === v.Id); 37 | if (idx > 0) 38 | this.Index = idx; 39 | else 40 | this.Index = 0; 41 | } 42 | get SelectedItem() { 43 | return this.Collection.length > 0 ? this.Collection[this.Index] : null; 44 | } 45 | get SelectedValue() { 46 | return this.SelectedItem == null 47 | ? null 48 | : this.SelectedItem.Data == null 49 | ? this.SelectedItem.DisplayText 50 | : this.SelectedItem.Data; 51 | } 52 | get Index() { 53 | if (this.Collection == null) 54 | return -1; 55 | if (this.Collection != null && this.Collection.length == 0) 56 | return -1; 57 | return this._index % this.Collection.length; 58 | } 59 | set Index(value) { 60 | if (this.Collection == null) 61 | return; 62 | if (this.Collection != null && this.Collection.length == 0) 63 | return; 64 | this._index = 100000000 - (100000000 % this.Collection.length) + value; 65 | const caption = this.Collection.length >= this.Index 66 | ? this.Collection[this.Index].DisplayText 67 | : " "; 68 | this._currentOffset = Screen.GetTextWidth(caption, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); 69 | } 70 | setCollection(collection) { 71 | this.Collection = collection.getListItems(); 72 | } 73 | setCollectionItem(index, item, resetSelection = true) { 74 | if (index > this.Collection.length) 75 | throw new Error("Index out of bounds"); 76 | if (typeof item === "string") 77 | item = new ListItem(item); 78 | this.Collection.splice(index, 1, item); 79 | if (resetSelection) 80 | this.Index = 0; 81 | } 82 | SetVerticalPosition(y) { 83 | this._arrowLeft.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 84 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 85 | this._itemText.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, y + 147 + this.Offset.Y); 86 | super.SetVerticalPosition(y); 87 | } 88 | SetRightLabel(text) { 89 | return this; 90 | } 91 | SetRightBadge(badge) { 92 | return this; 93 | } 94 | Draw() { 95 | super.Draw(); 96 | const caption = this.Collection.length >= this.Index 97 | ? this.Collection[this.Index].DisplayText 98 | : " "; 99 | const offset = this._currentOffset; 100 | this._itemText.Color = this.Enabled 101 | ? this.Selected 102 | ? this.HighlightedForeColor 103 | : this.ForeColor 104 | : new Color(163, 159, 148); 105 | this._itemText.Caption = caption; 106 | this._arrowLeft.Color = this.Enabled 107 | ? this.Selected 108 | ? this.HighlightedForeColor 109 | : this.ForeColor 110 | : new Color(163, 159, 148); 111 | this._arrowRight.Color = this.Enabled 112 | ? this.Selected 113 | ? this.HighlightedForeColor 114 | : this.ForeColor 115 | : new Color(163, 159, 148); 116 | this._arrowLeft.Pos = new Point(380 - offset + this.Offset.X + this.Parent.WidthOffset, this._arrowLeft.Pos.Y); 117 | if (this.Selected) { 118 | this._arrowLeft.Draw(); 119 | this._arrowRight.Draw(); 120 | this._itemText.Pos = new Point(405 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 121 | } 122 | else { 123 | this._itemText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 124 | } 125 | this._itemText.Draw(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/NativeUi.d.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "./enums/BadgeStyle"; 2 | import Font from "./enums/Font"; 3 | import Alignment from './enums/Alignment'; 4 | import Control from './enums/Control'; 5 | import HudColor from './enums/HudColor'; 6 | import ChangeDirection from './enums/ChangeDirection'; 7 | import UIMenuCheckboxItem from "./items/UIMenuCheckboxItem"; 8 | import UIMenuItem from "./items/UIMenuItem"; 9 | import UIMenuListItem from "./items/UIMenuListItem"; 10 | import UIMenuAutoListItem from "./items/UIMenuAutoListItem"; 11 | import UIMenuSliderItem from "./items/UIMenuSliderItem"; 12 | import ItemsCollection from "./modules/ItemsCollection"; 13 | import ListItem from "./modules/ListItem"; 14 | import ResRectangle from "./modules/ResRectangle"; 15 | import ResText from "./modules/ResText"; 16 | import Sprite from "./modules/Sprite"; 17 | import Color from "./utils/Color"; 18 | import LiteEvent from "./utils/LiteEvent"; 19 | import Point from "./utils/Point"; 20 | import Size from "./utils/Size"; 21 | import InstructionalButton from './modules/InstructionalButton'; 22 | import BigMessage from './modules/BigMessage'; 23 | import MidsizedMessage from './modules/MidsizedMessage'; 24 | import UIMenuDynamicListItem from './items/UIMenuDynamicListItem'; 25 | export default class NativeUI { 26 | private _visible; 27 | private _counterPretext; 28 | private _counterOverride; 29 | private _spriteLibrary; 30 | private _spriteName; 31 | private _offset; 32 | private _lastUpDownNavigation; 33 | private _lastLeftRightNavigation; 34 | private _extraOffset; 35 | private _buttonsEnabled; 36 | private _justOpened; 37 | private _justOpenedFromPool; 38 | private _justClosedFromPool; 39 | private _poolOpening; 40 | private _safezoneOffset; 41 | private _activeItem; 42 | private _maxItemsOnScreen; 43 | private _minItem; 44 | private _maxItem; 45 | private _mouseEdgeEnabled; 46 | private _bannerSprite; 47 | private _bannerRectangle; 48 | private _recalculateDescriptionNextFrame; 49 | private readonly _instructionalButtons; 50 | private readonly _instructionalButtonsScaleform; 51 | private readonly _defaultTitleScale; 52 | private readonly _maxMenuItems; 53 | private readonly _mainMenu; 54 | private readonly _upAndDownSprite; 55 | private readonly _titleResText; 56 | private readonly _subtitleResText; 57 | private readonly _extraRectangleUp; 58 | private readonly _extraRectangleDown; 59 | private readonly _descriptionBar; 60 | private readonly _descriptionRectangle; 61 | private readonly _descriptionText; 62 | private readonly _counterText; 63 | private readonly _background; 64 | readonly Id: string; 65 | readonly SelectTextLocalized: string; 66 | readonly BackTextLocalized: string; 67 | WidthOffset: number; 68 | ParentMenu: NativeUI; 69 | ParentItem: UIMenuItem; 70 | Children: Map; 71 | MouseControlsEnabled: boolean; 72 | CloseableByUser: boolean; 73 | AUDIO_LIBRARY: string; 74 | AUDIO_UPDOWN: string; 75 | AUDIO_LEFTRIGHT: string; 76 | AUDIO_SELECT: string; 77 | AUDIO_BACK: string; 78 | AUDIO_ERROR: string; 79 | MenuItems: (UIMenuItem | UIMenuListItem | UIMenuAutoListItem | UIMenuDynamicListItem | UIMenuSliderItem | UIMenuCheckboxItem)[]; 80 | readonly IndexChange: LiteEvent; 81 | readonly ListChange: LiteEvent; 82 | readonly AutoListChange: LiteEvent; 83 | readonly DynamicListChange: LiteEvent; 84 | readonly SliderChange: LiteEvent; 85 | readonly CheckboxChange: LiteEvent; 86 | readonly ItemSelect: LiteEvent; 87 | readonly MenuOpen: LiteEvent; 88 | readonly MenuClose: LiteEvent; 89 | readonly MenuChange: LiteEvent; 90 | GetSpriteBanner(): Sprite; 91 | GetRectangleBanner(): ResRectangle; 92 | GetTitle(): ResText; 93 | get MaxItemsVisible(): number; 94 | set MaxItemsVisible(value: number); 95 | get Title(): string; 96 | set Title(text: string); 97 | get GetSubTitle(): ResText; 98 | get SubTitle(): string; 99 | set SubTitle(text: string); 100 | get Visible(): boolean; 101 | set Visible(toggle: boolean); 102 | get CurrentSelection(): number; 103 | set CurrentSelection(v: number); 104 | constructor(title: string, subtitle: string, offset: Point, spriteLibrary?: string, spriteName?: string); 105 | DisableInstructionalButtons(disable: boolean): void; 106 | AddInstructionalButton(button: InstructionalButton): void; 107 | SetSpriteBannerType(spriteBanner: Sprite): void; 108 | SetRectangleBannerType(rectangle: ResRectangle): void; 109 | AddSpriteBannerType(spriteBanner: Sprite): void; 110 | SetNoBannerType(): void; 111 | RemoveInstructionalButton(button: InstructionalButton): void; 112 | private RecalculateDescriptionPosition; 113 | SetMenuWidthOffset(widthOffset: number): void; 114 | AddItem(item: UIMenuItem): void; 115 | RemoveItem(item: UIMenuItem): void; 116 | RefreshIndex(): void; 117 | Clear(): void; 118 | Open(): void; 119 | private CleanUp; 120 | Close(closeChildren?: boolean): void; 121 | GoLeft(): void; 122 | GoRight(): void; 123 | SelectItem(): void; 124 | HasCurrentSelectionChildren(): boolean; 125 | IsMouseInListItemArrows(item: UIMenuItem, topLeft: Point, safezone: any): 0 | 1 | 2; 126 | ProcessMouse(): void; 127 | ProcessControl(): void; 128 | GoUpOverflow(): void; 129 | GoUp(): void; 130 | GoDownOverflow(): void; 131 | GoDown(): void; 132 | GoBack(): void; 133 | BindMenuToItem(menuToBind: NativeUI, itemToBindTo: UIMenuItem): void; 134 | AddSubMenu(subMenu: NativeUI, itemToBindTo: UIMenuItem): void; 135 | ReleaseMenuFromItem(releaseFrom: UIMenuItem): boolean; 136 | UpdateDescriptionCaption(): void; 137 | CalculateDescription(): void; 138 | UpdateScaleform(): void; 139 | private render; 140 | } 141 | export { NativeUI as Menu, UIMenuItem, UIMenuListItem, UIMenuAutoListItem, UIMenuDynamicListItem, UIMenuCheckboxItem, UIMenuSliderItem, BadgeStyle, ChangeDirection, Font, Alignment, Control, HudColor, Sprite, ResRectangle, InstructionalButton, Point, Size, Color, ItemsCollection, ListItem, BigMessage, MidsizedMessage }; 142 | -------------------------------------------------------------------------------- /src/items/UIMenuListItem.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import Font from "../enums/Font"; 3 | import Alignment from "../enums/Alignment"; 4 | import ItemsCollection from "../modules/ItemsCollection"; 5 | import ListItem from "../modules/ListItem"; 6 | import ResText from "../modules/ResText"; 7 | import Sprite from "../modules/Sprite"; 8 | import Color from "../utils/Color"; 9 | import Point from "../utils/Point"; 10 | import Size from "../utils/Size"; 11 | import Screen from "../utils/Screen"; 12 | import UIMenuItem from "./UIMenuItem"; 13 | 14 | export default class UIMenuListItem extends UIMenuItem { 15 | public ScrollingEnabled: boolean = true; 16 | public HoldTimeBeforeScroll: number = 200; 17 | 18 | protected _itemText: ResText; 19 | protected _arrowLeft: Sprite; 20 | protected _arrowRight: Sprite; 21 | 22 | private _currentOffset: number = 0; 23 | private _itemsCollection: Array = []; 24 | 25 | public get Collection() { 26 | return this._itemsCollection; 27 | } 28 | public set Collection(v) { 29 | if (!v) throw new Error("The collection can't be null"); 30 | this._itemsCollection = v; 31 | } 32 | 33 | public set SelectedItem(v: ListItem) { 34 | const idx = this.Collection.findIndex(li => li.Id === v.Id); 35 | if (idx > 0) 36 | this.Index = idx; 37 | else 38 | this.Index = 0; 39 | } 40 | 41 | public get SelectedItem() { 42 | return this.Collection.length > 0 ? this.Collection[this.Index] : null; 43 | } 44 | 45 | public get SelectedValue() { 46 | return this.SelectedItem == null 47 | ? null 48 | : this.SelectedItem.Data == null 49 | ? this.SelectedItem.DisplayText 50 | : this.SelectedItem.Data; 51 | } 52 | 53 | protected _index: number = 0; 54 | 55 | public get Index() { 56 | if (this.Collection == null) 57 | return -1; 58 | if (this.Collection != null && this.Collection.length == 0) 59 | return -1; 60 | 61 | return this._index % this.Collection.length; 62 | } 63 | public set Index(value) { 64 | if (this.Collection == null) 65 | return; 66 | if (this.Collection != null && this.Collection.length == 0) 67 | return; 68 | 69 | this._index = 100000000 - (100000000 % this.Collection.length) + value; 70 | 71 | const caption = this.Collection.length >= this.Index 72 | ? this.Collection[this.Index].DisplayText 73 | : " "; 74 | this._currentOffset = Screen.GetTextWidth(caption, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); // this._itemText && this._itemText.font ? this._itemText.font : 0, this._itemText && this._itemText.scale ? this._itemText.scale : 0.35 75 | } 76 | 77 | constructor(text: string, description: string = "", collection: ItemsCollection = new ItemsCollection([]), startIndex: number = 0, data: any = null) { 78 | super(text, description, data); 79 | 80 | let y = 0; 81 | this.Collection = collection.getListItems(); 82 | this.Index = startIndex; 83 | this._arrowLeft = new Sprite("commonmenu", "arrowleft", new Point(110, 105 + y), new Size(30, 30)); 84 | this._arrowRight = new Sprite("commonmenu", "arrowright", new Point(280, 105 + y), new Size(30, 30)); 85 | this._itemText = new ResText("", new Point(290, y + 104), 0.35, Color.White, Font.ChaletLondon, Alignment.Right); 86 | } 87 | 88 | public setCollection(collection: ItemsCollection) { 89 | this.Collection = collection.getListItems(); 90 | } 91 | 92 | public setCollectionItem(index: number, item: ListItem | string, resetSelection: boolean = true) { 93 | if (index > this.Collection.length) 94 | // Placeholder for formatting 95 | throw new Error("Index out of bounds"); 96 | if (typeof item === "string") 97 | // Placeholder for formatting 98 | item = new ListItem(item); 99 | 100 | this.Collection.splice(index, 1, item); 101 | 102 | if (resetSelection) 103 | // Placeholder for formatting 104 | this.Index = 0; 105 | } 106 | 107 | public SetVerticalPosition(y: number) { 108 | this._arrowLeft.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 109 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 110 | this._itemText.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, y + 147 + this.Offset.Y); 111 | super.SetVerticalPosition(y); 112 | } 113 | 114 | public SetRightLabel(text: string) { 115 | return this; 116 | } 117 | 118 | public SetRightBadge(badge: BadgeStyle) { 119 | return this; 120 | } 121 | 122 | public Draw() { 123 | super.Draw(); 124 | const caption = this.Collection.length >= this.Index 125 | ? this.Collection[this.Index].DisplayText 126 | : " "; 127 | const offset = this._currentOffset; 128 | 129 | this._itemText.Color = this.Enabled 130 | ? this.Selected 131 | ? this.HighlightedForeColor 132 | : this.ForeColor 133 | : new Color(163, 159, 148); 134 | 135 | this._itemText.Caption = caption; 136 | 137 | this._arrowLeft.Color = this.Enabled 138 | ? this.Selected 139 | ? this.HighlightedForeColor 140 | : this.ForeColor 141 | : new Color(163, 159, 148); 142 | this._arrowRight.Color = this.Enabled 143 | ? this.Selected 144 | ? this.HighlightedForeColor 145 | : this.ForeColor 146 | : new Color(163, 159, 148); 147 | 148 | this._arrowLeft.Pos = new Point(380 - offset + this.Offset.X + this.Parent.WidthOffset, this._arrowLeft.Pos.Y); 149 | 150 | if (this.Selected) { 151 | this._arrowLeft.Draw(); 152 | this._arrowRight.Draw(); 153 | this._itemText.Pos = new Point(405 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 154 | } else { 155 | this._itemText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 156 | } 157 | this._itemText.Draw(); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/items/UIMenuDynamicListItem.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import Font from "../enums/Font"; 3 | import Alignment from "../enums/Alignment"; 4 | import ChangeDirection from "../enums/ChangeDirection"; 5 | import ResText from "../modules/ResText"; 6 | import Sprite from "../modules/Sprite"; 7 | import Color from "../utils/Color"; 8 | import Point from "../utils/Point"; 9 | import Size from "../utils/Size"; 10 | import Screen from "../utils/Screen"; 11 | import UIMenuItem from "./UIMenuItem"; 12 | 13 | interface SelectionChangeHandler { 14 | (item: UIMenuDynamicListItem, selectedValue: string, changeDirection: ChangeDirection): string 15 | } 16 | 17 | interface SelectedStartValueHandler { 18 | (): string 19 | } 20 | 21 | export default class UIMenuDynamicListItem extends UIMenuItem { 22 | protected _itemText: ResText; 23 | protected _arrowLeft: Sprite; 24 | protected _arrowRight: Sprite; 25 | 26 | private _currentOffset: number = 0; 27 | private _precaptionText: string = ''; 28 | private _selectedValue: string; 29 | private readonly _selectedStartValueHandler: SelectedStartValueHandler = null; 30 | 31 | public readonly SelectionChangeHandler: SelectionChangeHandler = null; 32 | public SelectionChangeHandlerPromise(item: UIMenuDynamicListItem, selectedValue: string, changeDirection: ChangeDirection): Promise { 33 | return new Promise((resolve, reject) => { 34 | let newSelectedValue: string = this.SelectionChangeHandler(item, selectedValue, changeDirection); 35 | resolve(newSelectedValue); 36 | }); 37 | } 38 | 39 | public get PreCaptionText() { 40 | return this._precaptionText; 41 | } 42 | public set PreCaptionText(text) { 43 | if (!text) throw new Error("The pre caption text can't be null"); 44 | if (typeof text !== 'string') throw new Error("The pre caption text must be a string"); 45 | this._precaptionText = text; 46 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); 47 | } 48 | 49 | public get SelectedValue(): string { 50 | return this._selectedValue; 51 | } 52 | public set SelectedValue(value: string) { 53 | this._selectedValue = value; 54 | if (value == undefined) 55 | return; 56 | 57 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue, this._itemText && this._itemText.Font ? this._itemText.Font : 0, this._itemText && this._itemText.Scale ? this._itemText.Scale : 0.35); 58 | } 59 | 60 | constructor(text: string, selectionChangeHandler: { (item: UIMenuDynamicListItem, selectedValue: string, changeDirection: ChangeDirection): string }, description: string = "", selectedStartValueHandler: { (): string } = null, data: any = null) { 61 | super(text, description, data); 62 | 63 | if (!this.isVariableFunction(selectionChangeHandler)) { 64 | console.log(`[UIMenuDynamicListItem] ${text} is not created with a valid selectionChangeHandler, needs to be function. Please see docs.`); 65 | } 66 | if (!this.isVariableFunction(selectedStartValueHandler)) { 67 | console.log(`[UIMenuDynamicListItem] ${text} is not created with a valid selectedStartValueHandler, needs to be function. Please see docs.`); 68 | } 69 | 70 | this.SelectionChangeHandler = selectionChangeHandler; 71 | this._selectedStartValueHandler = selectedStartValueHandler; 72 | let y = 0; 73 | 74 | this._arrowLeft = new Sprite("commonmenu", "arrowleft", new Point(110, 105 + y), new Size(30, 30)); 75 | this._arrowRight = new Sprite("commonmenu", "arrowright", new Point(280, 105 + y), new Size(30, 30)); 76 | this._itemText = new ResText("", new Point(290, y + 104), 0.35, Color.White, Font.ChaletLondon, Alignment.Right); 77 | } 78 | 79 | public SetVerticalPosition(y: number) { 80 | this._arrowLeft.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 81 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 82 | this._itemText.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, y + 147 + this.Offset.Y); 83 | super.SetVerticalPosition(y); 84 | } 85 | 86 | public SetRightLabel(text: string) { 87 | return this; 88 | } 89 | 90 | public SetRightBadge(badge: BadgeStyle) { 91 | return this; 92 | } 93 | 94 | public Draw() { 95 | super.Draw(); 96 | if (this._selectedValue == undefined) { 97 | if (this._selectedStartValueHandler != null) { 98 | this.SelectedValue = this._selectedStartValueHandler(); 99 | } 100 | else { 101 | this._selectedValue = ""; 102 | } 103 | } 104 | 105 | const offset = this._currentOffset; 106 | 107 | this._itemText.Color = this.Enabled 108 | ? this.Selected 109 | ? this.HighlightedForeColor 110 | : this.ForeColor 111 | : new Color(163, 159, 148); 112 | 113 | this._itemText.Caption = this.PreCaptionText + this._selectedValue; 114 | 115 | this._arrowLeft.Color = this.Enabled 116 | ? this.Selected 117 | ? this.HighlightedForeColor 118 | : this.ForeColor 119 | : new Color(163, 159, 148); 120 | this._arrowRight.Color = this.Enabled 121 | ? this.Selected 122 | ? this.HighlightedForeColor 123 | : this.ForeColor 124 | : new Color(163, 159, 148); 125 | 126 | this._arrowLeft.Pos = new Point(380 - offset + this.Offset.X + this.Parent.WidthOffset, this._arrowLeft.Pos.Y); 127 | 128 | if (this.Selected) { 129 | this._arrowLeft.Draw(); 130 | this._arrowRight.Draw(); 131 | this._itemText.Pos = new Point(405 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 132 | } else { 133 | this._itemText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 134 | } 135 | this._itemText.Draw(); 136 | } 137 | 138 | private isVariableFunction(functionToCheck: any): boolean { 139 | return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]'; 140 | } 141 | } -------------------------------------------------------------------------------- /src/items/UIMenuAutoListItem.js: -------------------------------------------------------------------------------- 1 | import Font from "../enums/Font"; 2 | import Alignment from "../enums/Alignment"; 3 | import ResText from "../modules/ResText"; 4 | import Sprite from "../modules/Sprite"; 5 | import Color from "../utils/Color"; 6 | import Point from "../utils/Point"; 7 | import Size from "../utils/Size"; 8 | import Screen from "../utils/Screen"; 9 | import UIMenuItem from "./UIMenuItem"; 10 | import { fixFloat } from "../utils/Number"; 11 | export default class UIMenuAutoListItem extends UIMenuItem { 12 | constructor(text, description = "", lowerThreshold = 0, upperThreshold = 10, startValue = 0, data = null) { 13 | super(text, description, data); 14 | this._currentOffset = 0; 15 | this._leftMoveThreshold = 1; 16 | this._rightMoveThreshold = 1; 17 | this._lowerThreshold = 0; 18 | this._upperThreshold = 10; 19 | this._preCaptionText = ''; 20 | this._postCaptionText = ''; 21 | let y = 0; 22 | this.LowerThreshold = lowerThreshold; 23 | this.UpperThreshold = lowerThreshold > upperThreshold ? lowerThreshold : upperThreshold; 24 | this.SelectedValue = (startValue < lowerThreshold || startValue > upperThreshold) ? lowerThreshold : startValue; 25 | this._arrowLeft = new Sprite("commonmenu", "arrowleft", new Point(110, 105 + y), new Size(30, 30)); 26 | this._arrowRight = new Sprite("commonmenu", "arrowright", new Point(280, 105 + y), new Size(30, 30)); 27 | this._itemText = new ResText("", new Point(290, y + 104), 0.35, Color.White, Font.ChaletLondon, Alignment.Right); 28 | } 29 | get PreCaptionText() { 30 | return this._preCaptionText; 31 | } 32 | set PreCaptionText(text) { 33 | if (!text) 34 | throw new Error("The pre caption text can't be null"); 35 | if (typeof text !== 'string') 36 | throw new Error("The pre caption text must be a string"); 37 | this._preCaptionText = text; 38 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue.toString() + this.PostCaptionText, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); 39 | } 40 | get PostCaptionText() { 41 | return this._postCaptionText; 42 | } 43 | set PostCaptionText(text) { 44 | if (!text) 45 | throw new Error("The post caption text can't be null"); 46 | if (typeof text !== 'string') 47 | throw new Error("The post caption text must be a string"); 48 | this._postCaptionText = text; 49 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue.toString() + this.PostCaptionText, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); 50 | } 51 | get LeftMoveThreshold() { 52 | return this._leftMoveThreshold; 53 | } 54 | set LeftMoveThreshold(value) { 55 | if (!value) 56 | throw new Error("The left threshold can't be null"); 57 | this._leftMoveThreshold = value; 58 | } 59 | get RightMoveThreshold() { 60 | return this._rightMoveThreshold; 61 | } 62 | set RightMoveThreshold(value) { 63 | if (!value) 64 | throw new Error("The right threshold can't be null"); 65 | this._rightMoveThreshold = value; 66 | } 67 | get LowerThreshold() { 68 | return this._lowerThreshold; 69 | } 70 | set LowerThreshold(value) { 71 | if (typeof value !== 'number' && !value) 72 | throw new Error("The lower threshold can't be null"); 73 | this._lowerThreshold = value; 74 | if (this.SelectedValue < value) { 75 | this.SelectedValue = value; 76 | } 77 | } 78 | get UpperThreshold() { 79 | return this._upperThreshold; 80 | } 81 | set UpperThreshold(value) { 82 | if (typeof value !== 'number' && !value) 83 | throw new Error("The upper threshold can't be null"); 84 | this._upperThreshold = value; 85 | if (this.SelectedValue > value) { 86 | this.SelectedValue = value; 87 | } 88 | } 89 | get SelectedValue() { 90 | return this._selectedValue; 91 | } 92 | set SelectedValue(value) { 93 | if (value < this._lowerThreshold || value > this._upperThreshold) 94 | throw new Error("The value can not be outside the lower or upper limits"); 95 | this._selectedValue = fixFloat(value); 96 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue.toString() + this.PostCaptionText, this._itemText && this._itemText.Font ? this._itemText.Font : 0, this._itemText && this._itemText.Scale ? this._itemText.Scale : 0.35); 97 | } 98 | SetVerticalPosition(y) { 99 | this._arrowLeft.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 100 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 101 | this._itemText.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, y + 147 + this.Offset.Y); 102 | super.SetVerticalPosition(y); 103 | } 104 | SetRightLabel(text) { 105 | return this; 106 | } 107 | SetRightBadge(badge) { 108 | return this; 109 | } 110 | Draw() { 111 | super.Draw(); 112 | const offset = this._currentOffset; 113 | this._itemText.Color = this.Enabled 114 | ? this.Selected 115 | ? this.HighlightedForeColor 116 | : this.ForeColor 117 | : new Color(163, 159, 148); 118 | this._itemText.Caption = this.PreCaptionText + this._selectedValue + this.PostCaptionText; 119 | this._arrowLeft.Color = this.Enabled 120 | ? this.Selected 121 | ? this.HighlightedForeColor 122 | : this.ForeColor 123 | : new Color(163, 159, 148); 124 | this._arrowRight.Color = this.Enabled 125 | ? this.Selected 126 | ? this.HighlightedForeColor 127 | : this.ForeColor 128 | : new Color(163, 159, 148); 129 | this._arrowLeft.Pos = new Point(380 - offset + this.Offset.X + this.Parent.WidthOffset, this._arrowLeft.Pos.Y); 130 | if (this.Selected) { 131 | this._arrowLeft.Draw(); 132 | this._arrowRight.Draw(); 133 | this._itemText.Pos = new Point(405 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 134 | } 135 | else { 136 | this._itemText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 137 | } 138 | this._itemText.Draw(); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/enums/HudColor.ts: -------------------------------------------------------------------------------- 1 | enum HudColor { 2 | HUD_COLOUR_PURE_WHITE = 0, 3 | HUD_COLOUR_WHITE = 1, 4 | HUD_COLOUR_BLACK = 2, 5 | HUD_COLOUR_GREY = 3, 6 | HUD_COLOUR_GREYLIGHT = 4, 7 | HUD_COLOUR_GREYDARK = 5, 8 | HUD_COLOUR_RED = 6, 9 | HUD_COLOUR_REDLIGHT = 7, 10 | HUD_COLOUR_REDDARK = 8, 11 | HUD_COLOUR_BLUE = 9, 12 | HUD_COLOUR_BLUELIGHT = 10, 13 | HUD_COLOUR_BLUEDARK = 11, 14 | HUD_COLOUR_YELLOW = 12, 15 | HUD_COLOUR_YELLOWLIGHT = 13, 16 | HUD_COLOUR_YELLOWDARK = 14, 17 | HUD_COLOUR_ORANGE = 15, 18 | HUD_COLOUR_ORANGELIGHT = 16, 19 | HUD_COLOUR_ORANGEDARK = 17, 20 | HUD_COLOUR_GREEN = 18, 21 | HUD_COLOUR_GREENLIGHT = 19, 22 | HUD_COLOUR_GREENDARK = 20, 23 | HUD_COLOUR_PURPLE = 21, 24 | HUD_COLOUR_PURPLELIGHT = 22, 25 | HUD_COLOUR_PURPLEDARK = 23, 26 | HUD_COLOUR_PINK = 24, 27 | HUD_COLOUR_RADAR_HEALTH = 25, 28 | HUD_COLOUR_RADAR_ARMOUR = 26, 29 | HUD_COLOUR_RADAR_DAMAGE = 27, 30 | HUD_COLOUR_NET_PLAYER1 = 28, 31 | HUD_COLOUR_NET_PLAYER2 = 29, 32 | HUD_COLOUR_NET_PLAYER3 = 30, 33 | HUD_COLOUR_NET_PLAYER4 = 31, 34 | HUD_COLOUR_NET_PLAYER5 = 32, 35 | HUD_COLOUR_NET_PLAYER6 = 33, 36 | HUD_COLOUR_NET_PLAYER7 = 34, 37 | HUD_COLOUR_NET_PLAYER8 = 35, 38 | HUD_COLOUR_NET_PLAYER9 = 36, 39 | HUD_COLOUR_NET_PLAYER10 = 37, 40 | HUD_COLOUR_NET_PLAYER11 = 38, 41 | HUD_COLOUR_NET_PLAYER12 = 39, 42 | HUD_COLOUR_NET_PLAYER13 = 40, 43 | HUD_COLOUR_NET_PLAYER14 = 41, 44 | HUD_COLOUR_NET_PLAYER15 = 42, 45 | HUD_COLOUR_NET_PLAYER16 = 43, 46 | HUD_COLOUR_NET_PLAYER17 = 44, 47 | HUD_COLOUR_NET_PLAYER18 = 45, 48 | HUD_COLOUR_NET_PLAYER19 = 46, 49 | HUD_COLOUR_NET_PLAYER20 = 47, 50 | HUD_COLOUR_NET_PLAYER21 = 48, 51 | HUD_COLOUR_NET_PLAYER22 = 49, 52 | HUD_COLOUR_NET_PLAYER23 = 50, 53 | HUD_COLOUR_NET_PLAYER24 = 51, 54 | HUD_COLOUR_NET_PLAYER25 = 52, 55 | HUD_COLOUR_NET_PLAYER26 = 53, 56 | HUD_COLOUR_NET_PLAYER27 = 54, 57 | HUD_COLOUR_NET_PLAYER28 = 55, 58 | HUD_COLOUR_NET_PLAYER29 = 56, 59 | HUD_COLOUR_NET_PLAYER30 = 57, 60 | HUD_COLOUR_NET_PLAYER31 = 58, 61 | HUD_COLOUR_NET_PLAYER32 = 59, 62 | HUD_COLOUR_SIMPLEBLIP_DEFAULT = 60, 63 | HUD_COLOUR_MENU_BLUE = 61, 64 | HUD_COLOUR_MENU_GREY_LIGHT = 62, 65 | HUD_COLOUR_MENU_BLUE_EXTRA_DARK = 63, 66 | HUD_COLOUR_MENU_YELLOW = 64, 67 | HUD_COLOUR_MENU_YELLOW_DARK = 65, 68 | HUD_COLOUR_MENU_GREEN = 66, 69 | HUD_COLOUR_MENU_GREY = 67, 70 | HUD_COLOUR_MENU_GREY_DARK = 68, 71 | HUD_COLOUR_MENU_HIGHLIGHT = 69, 72 | HUD_COLOUR_MENU_STANDARD = 70, 73 | HUD_COLOUR_MENU_DIMMED = 71, 74 | HUD_COLOUR_MENU_EXTRA_DIMMED = 72, 75 | HUD_COLOUR_BRIEF_TITLE = 73, 76 | HUD_COLOUR_MID_GREY_MP = 74, 77 | HUD_COLOUR_NET_PLAYER1_DARK = 75, 78 | HUD_COLOUR_NET_PLAYER2_DARK = 76, 79 | HUD_COLOUR_NET_PLAYER3_DARK = 77, 80 | HUD_COLOUR_NET_PLAYER4_DARK = 78, 81 | HUD_COLOUR_NET_PLAYER5_DARK = 79, 82 | HUD_COLOUR_NET_PLAYER6_DARK = 80, 83 | HUD_COLOUR_NET_PLAYER7_DARK = 81, 84 | HUD_COLOUR_NET_PLAYER8_DARK = 82, 85 | HUD_COLOUR_NET_PLAYER9_DARK = 83, 86 | HUD_COLOUR_NET_PLAYER10_DARK = 84, 87 | HUD_COLOUR_NET_PLAYER11_DARK = 85, 88 | HUD_COLOUR_NET_PLAYER12_DARK = 86, 89 | HUD_COLOUR_NET_PLAYER13_DARK = 87, 90 | HUD_COLOUR_NET_PLAYER14_DARK = 88, 91 | HUD_COLOUR_NET_PLAYER15_DARK = 89, 92 | HUD_COLOUR_NET_PLAYER16_DARK = 90, 93 | HUD_COLOUR_NET_PLAYER17_DARK = 91, 94 | HUD_COLOUR_NET_PLAYER18_DARK = 92, 95 | HUD_COLOUR_NET_PLAYER19_DARK = 93, 96 | HUD_COLOUR_NET_PLAYER20_DARK = 94, 97 | HUD_COLOUR_NET_PLAYER21_DARK = 95, 98 | HUD_COLOUR_NET_PLAYER22_DARK = 96, 99 | HUD_COLOUR_NET_PLAYER23_DARK = 97, 100 | HUD_COLOUR_NET_PLAYER24_DARK = 98, 101 | HUD_COLOUR_NET_PLAYER25_DARK = 99, 102 | HUD_COLOUR_NET_PLAYER26_DARK = 100, 103 | HUD_COLOUR_NET_PLAYER27_DARK = 101, 104 | HUD_COLOUR_NET_PLAYER28_DARK = 102, 105 | HUD_COLOUR_NET_PLAYER29_DARK = 103, 106 | HUD_COLOUR_NET_PLAYER30_DARK = 104, 107 | HUD_COLOUR_NET_PLAYER31_DARK = 105, 108 | HUD_COLOUR_NET_PLAYER32_DARK = 106, 109 | HUD_COLOUR_BRONZE = 107, 110 | HUD_COLOUR_SILVER = 108, 111 | HUD_COLOUR_GOLD = 109, 112 | HUD_COLOUR_PLATINUM = 110, 113 | HUD_COLOUR_GANG1 = 111, 114 | HUD_COLOUR_GANG2 = 112, 115 | HUD_COLOUR_GANG3 = 113, 116 | HUD_COLOUR_GANG4 = 114, 117 | HUD_COLOUR_SAME_CREW = 115, 118 | HUD_COLOUR_FREEMODE = 116, 119 | HUD_COLOUR_PAUSE_BG = 117, 120 | HUD_COLOUR_FRIENDLY = 118, 121 | HUD_COLOUR_ENEMY = 119, 122 | HUD_COLOUR_LOCATION = 120, 123 | HUD_COLOUR_PICKUP = 121, 124 | HUD_COLOUR_PAUSE_SINGLEPLAYER = 122, 125 | HUD_COLOUR_FREEMODE_DARK = 123, 126 | HUD_COLOUR_INACTIVE_MISSION = 124, 127 | HUD_COLOUR_DAMAGE = 125, 128 | HUD_COLOUR_PINKLIGHT = 126, 129 | HUD_COLOUR_PM_MITEM_HIGHLIGHT = 127, 130 | HUD_COLOUR_SCRIPT_VARIABLE = 128, 131 | HUD_COLOUR_YOGA = 129, 132 | HUD_COLOUR_TENNIS = 130, 133 | HUD_COLOUR_GOLF = 131, 134 | HUD_COLOUR_SHOOTING_RANGE = 132, 135 | HUD_COLOUR_FLIGHT_SCHOOL = 133, 136 | HUD_COLOUR_NORTH_BLUE = 134, 137 | HUD_COLOUR_SOCIAL_CLUB = 135, 138 | HUD_COLOUR_PLATFORM_BLUE = 136, 139 | HUD_COLOUR_PLATFORM_GREEN = 137, 140 | HUD_COLOUR_PLATFORM_GREY = 138, 141 | HUD_COLOUR_FACEBOOK_BLUE = 139, 142 | HUD_COLOUR_INGAME_BG = 140, 143 | HUD_COLOUR_DARTS = 141, 144 | HUD_COLOUR_WAYPOINT = 142, 145 | HUD_COLOUR_MICHAEL = 143, 146 | HUD_COLOUR_FRANKLIN = 144, 147 | HUD_COLOUR_TREVOR = 145, 148 | HUD_COLOUR_GOLF_P1 = 146, 149 | HUD_COLOUR_GOLF_P2 = 147, 150 | HUD_COLOUR_GOLF_P3 = 148, 151 | HUD_COLOUR_GOLF_P4 = 149, 152 | HUD_COLOUR_WAYPOINTLIGHT = 150, 153 | HUD_COLOUR_WAYPOINTDARK = 151, 154 | HUD_COLOUR_PANEL_LIGHT = 152, 155 | HUD_COLOUR_MICHAEL_DARK = 153, 156 | HUD_COLOUR_FRANKLIN_DARK = 154, 157 | HUD_COLOUR_TREVOR_DARK = 155, 158 | HUD_COLOUR_OBJECTIVE_ROUTE = 156, 159 | HUD_COLOUR_PAUSEMAP_TINT = 157, 160 | HUD_COLOUR_PAUSE_DESELECT = 158, 161 | HUD_COLOUR_PM_WEAPONS_PURCHASABLE = 159, 162 | HUD_COLOUR_PM_WEAPONS_LOCKED = 160, 163 | HUD_COLOUR_END_SCREEN_BG = 161, 164 | HUD_COLOUR_CHOP = 162, 165 | HUD_COLOUR_PAUSEMAP_TINT_HALF = 163, 166 | HUD_COLOUR_NORTH_BLUE_OFFICIAL = 164, 167 | HUD_COLOUR_SCRIPT_VARIABLE_2 = 165, 168 | HUD_COLOUR_H = 166, 169 | HUD_COLOUR_HDARK = 167, 170 | HUD_COLOUR_T = 168, 171 | HUD_COLOUR_TDARK = 169, 172 | HUD_COLOUR_HSHARD = 170, 173 | HUD_COLOUR_CONTROLLER_MICHAEL = 171, 174 | HUD_COLOUR_CONTROLLER_FRANKLIN = 172, 175 | HUD_COLOUR_CONTROLLER_TREVOR = 173, 176 | HUD_COLOUR_CONTROLLER_CHOP = 174, 177 | HUD_COLOUR_VIDEO_EDITOR_VIDEO = 175, 178 | HUD_COLOUR_VIDEO_EDITOR_AUDIO = 176, 179 | HUD_COLOUR_VIDEO_EDITOR_TEXT = 177, 180 | HUD_COLOUR_HB_BLUE = 178, 181 | HUD_COLOUR_HB_YELLOW = 179, 182 | } 183 | 184 | export default HudColor; -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/enums/HudColor.d.ts: -------------------------------------------------------------------------------- 1 | declare enum HudColor { 2 | HUD_COLOUR_PURE_WHITE = 0, 3 | HUD_COLOUR_WHITE = 1, 4 | HUD_COLOUR_BLACK = 2, 5 | HUD_COLOUR_GREY = 3, 6 | HUD_COLOUR_GREYLIGHT = 4, 7 | HUD_COLOUR_GREYDARK = 5, 8 | HUD_COLOUR_RED = 6, 9 | HUD_COLOUR_REDLIGHT = 7, 10 | HUD_COLOUR_REDDARK = 8, 11 | HUD_COLOUR_BLUE = 9, 12 | HUD_COLOUR_BLUELIGHT = 10, 13 | HUD_COLOUR_BLUEDARK = 11, 14 | HUD_COLOUR_YELLOW = 12, 15 | HUD_COLOUR_YELLOWLIGHT = 13, 16 | HUD_COLOUR_YELLOWDARK = 14, 17 | HUD_COLOUR_ORANGE = 15, 18 | HUD_COLOUR_ORANGELIGHT = 16, 19 | HUD_COLOUR_ORANGEDARK = 17, 20 | HUD_COLOUR_GREEN = 18, 21 | HUD_COLOUR_GREENLIGHT = 19, 22 | HUD_COLOUR_GREENDARK = 20, 23 | HUD_COLOUR_PURPLE = 21, 24 | HUD_COLOUR_PURPLELIGHT = 22, 25 | HUD_COLOUR_PURPLEDARK = 23, 26 | HUD_COLOUR_PINK = 24, 27 | HUD_COLOUR_RADAR_HEALTH = 25, 28 | HUD_COLOUR_RADAR_ARMOUR = 26, 29 | HUD_COLOUR_RADAR_DAMAGE = 27, 30 | HUD_COLOUR_NET_PLAYER1 = 28, 31 | HUD_COLOUR_NET_PLAYER2 = 29, 32 | HUD_COLOUR_NET_PLAYER3 = 30, 33 | HUD_COLOUR_NET_PLAYER4 = 31, 34 | HUD_COLOUR_NET_PLAYER5 = 32, 35 | HUD_COLOUR_NET_PLAYER6 = 33, 36 | HUD_COLOUR_NET_PLAYER7 = 34, 37 | HUD_COLOUR_NET_PLAYER8 = 35, 38 | HUD_COLOUR_NET_PLAYER9 = 36, 39 | HUD_COLOUR_NET_PLAYER10 = 37, 40 | HUD_COLOUR_NET_PLAYER11 = 38, 41 | HUD_COLOUR_NET_PLAYER12 = 39, 42 | HUD_COLOUR_NET_PLAYER13 = 40, 43 | HUD_COLOUR_NET_PLAYER14 = 41, 44 | HUD_COLOUR_NET_PLAYER15 = 42, 45 | HUD_COLOUR_NET_PLAYER16 = 43, 46 | HUD_COLOUR_NET_PLAYER17 = 44, 47 | HUD_COLOUR_NET_PLAYER18 = 45, 48 | HUD_COLOUR_NET_PLAYER19 = 46, 49 | HUD_COLOUR_NET_PLAYER20 = 47, 50 | HUD_COLOUR_NET_PLAYER21 = 48, 51 | HUD_COLOUR_NET_PLAYER22 = 49, 52 | HUD_COLOUR_NET_PLAYER23 = 50, 53 | HUD_COLOUR_NET_PLAYER24 = 51, 54 | HUD_COLOUR_NET_PLAYER25 = 52, 55 | HUD_COLOUR_NET_PLAYER26 = 53, 56 | HUD_COLOUR_NET_PLAYER27 = 54, 57 | HUD_COLOUR_NET_PLAYER28 = 55, 58 | HUD_COLOUR_NET_PLAYER29 = 56, 59 | HUD_COLOUR_NET_PLAYER30 = 57, 60 | HUD_COLOUR_NET_PLAYER31 = 58, 61 | HUD_COLOUR_NET_PLAYER32 = 59, 62 | HUD_COLOUR_SIMPLEBLIP_DEFAULT = 60, 63 | HUD_COLOUR_MENU_BLUE = 61, 64 | HUD_COLOUR_MENU_GREY_LIGHT = 62, 65 | HUD_COLOUR_MENU_BLUE_EXTRA_DARK = 63, 66 | HUD_COLOUR_MENU_YELLOW = 64, 67 | HUD_COLOUR_MENU_YELLOW_DARK = 65, 68 | HUD_COLOUR_MENU_GREEN = 66, 69 | HUD_COLOUR_MENU_GREY = 67, 70 | HUD_COLOUR_MENU_GREY_DARK = 68, 71 | HUD_COLOUR_MENU_HIGHLIGHT = 69, 72 | HUD_COLOUR_MENU_STANDARD = 70, 73 | HUD_COLOUR_MENU_DIMMED = 71, 74 | HUD_COLOUR_MENU_EXTRA_DIMMED = 72, 75 | HUD_COLOUR_BRIEF_TITLE = 73, 76 | HUD_COLOUR_MID_GREY_MP = 74, 77 | HUD_COLOUR_NET_PLAYER1_DARK = 75, 78 | HUD_COLOUR_NET_PLAYER2_DARK = 76, 79 | HUD_COLOUR_NET_PLAYER3_DARK = 77, 80 | HUD_COLOUR_NET_PLAYER4_DARK = 78, 81 | HUD_COLOUR_NET_PLAYER5_DARK = 79, 82 | HUD_COLOUR_NET_PLAYER6_DARK = 80, 83 | HUD_COLOUR_NET_PLAYER7_DARK = 81, 84 | HUD_COLOUR_NET_PLAYER8_DARK = 82, 85 | HUD_COLOUR_NET_PLAYER9_DARK = 83, 86 | HUD_COLOUR_NET_PLAYER10_DARK = 84, 87 | HUD_COLOUR_NET_PLAYER11_DARK = 85, 88 | HUD_COLOUR_NET_PLAYER12_DARK = 86, 89 | HUD_COLOUR_NET_PLAYER13_DARK = 87, 90 | HUD_COLOUR_NET_PLAYER14_DARK = 88, 91 | HUD_COLOUR_NET_PLAYER15_DARK = 89, 92 | HUD_COLOUR_NET_PLAYER16_DARK = 90, 93 | HUD_COLOUR_NET_PLAYER17_DARK = 91, 94 | HUD_COLOUR_NET_PLAYER18_DARK = 92, 95 | HUD_COLOUR_NET_PLAYER19_DARK = 93, 96 | HUD_COLOUR_NET_PLAYER20_DARK = 94, 97 | HUD_COLOUR_NET_PLAYER21_DARK = 95, 98 | HUD_COLOUR_NET_PLAYER22_DARK = 96, 99 | HUD_COLOUR_NET_PLAYER23_DARK = 97, 100 | HUD_COLOUR_NET_PLAYER24_DARK = 98, 101 | HUD_COLOUR_NET_PLAYER25_DARK = 99, 102 | HUD_COLOUR_NET_PLAYER26_DARK = 100, 103 | HUD_COLOUR_NET_PLAYER27_DARK = 101, 104 | HUD_COLOUR_NET_PLAYER28_DARK = 102, 105 | HUD_COLOUR_NET_PLAYER29_DARK = 103, 106 | HUD_COLOUR_NET_PLAYER30_DARK = 104, 107 | HUD_COLOUR_NET_PLAYER31_DARK = 105, 108 | HUD_COLOUR_NET_PLAYER32_DARK = 106, 109 | HUD_COLOUR_BRONZE = 107, 110 | HUD_COLOUR_SILVER = 108, 111 | HUD_COLOUR_GOLD = 109, 112 | HUD_COLOUR_PLATINUM = 110, 113 | HUD_COLOUR_GANG1 = 111, 114 | HUD_COLOUR_GANG2 = 112, 115 | HUD_COLOUR_GANG3 = 113, 116 | HUD_COLOUR_GANG4 = 114, 117 | HUD_COLOUR_SAME_CREW = 115, 118 | HUD_COLOUR_FREEMODE = 116, 119 | HUD_COLOUR_PAUSE_BG = 117, 120 | HUD_COLOUR_FRIENDLY = 118, 121 | HUD_COLOUR_ENEMY = 119, 122 | HUD_COLOUR_LOCATION = 120, 123 | HUD_COLOUR_PICKUP = 121, 124 | HUD_COLOUR_PAUSE_SINGLEPLAYER = 122, 125 | HUD_COLOUR_FREEMODE_DARK = 123, 126 | HUD_COLOUR_INACTIVE_MISSION = 124, 127 | HUD_COLOUR_DAMAGE = 125, 128 | HUD_COLOUR_PINKLIGHT = 126, 129 | HUD_COLOUR_PM_MITEM_HIGHLIGHT = 127, 130 | HUD_COLOUR_SCRIPT_VARIABLE = 128, 131 | HUD_COLOUR_YOGA = 129, 132 | HUD_COLOUR_TENNIS = 130, 133 | HUD_COLOUR_GOLF = 131, 134 | HUD_COLOUR_SHOOTING_RANGE = 132, 135 | HUD_COLOUR_FLIGHT_SCHOOL = 133, 136 | HUD_COLOUR_NORTH_BLUE = 134, 137 | HUD_COLOUR_SOCIAL_CLUB = 135, 138 | HUD_COLOUR_PLATFORM_BLUE = 136, 139 | HUD_COLOUR_PLATFORM_GREEN = 137, 140 | HUD_COLOUR_PLATFORM_GREY = 138, 141 | HUD_COLOUR_FACEBOOK_BLUE = 139, 142 | HUD_COLOUR_INGAME_BG = 140, 143 | HUD_COLOUR_DARTS = 141, 144 | HUD_COLOUR_WAYPOINT = 142, 145 | HUD_COLOUR_MICHAEL = 143, 146 | HUD_COLOUR_FRANKLIN = 144, 147 | HUD_COLOUR_TREVOR = 145, 148 | HUD_COLOUR_GOLF_P1 = 146, 149 | HUD_COLOUR_GOLF_P2 = 147, 150 | HUD_COLOUR_GOLF_P3 = 148, 151 | HUD_COLOUR_GOLF_P4 = 149, 152 | HUD_COLOUR_WAYPOINTLIGHT = 150, 153 | HUD_COLOUR_WAYPOINTDARK = 151, 154 | HUD_COLOUR_PANEL_LIGHT = 152, 155 | HUD_COLOUR_MICHAEL_DARK = 153, 156 | HUD_COLOUR_FRANKLIN_DARK = 154, 157 | HUD_COLOUR_TREVOR_DARK = 155, 158 | HUD_COLOUR_OBJECTIVE_ROUTE = 156, 159 | HUD_COLOUR_PAUSEMAP_TINT = 157, 160 | HUD_COLOUR_PAUSE_DESELECT = 158, 161 | HUD_COLOUR_PM_WEAPONS_PURCHASABLE = 159, 162 | HUD_COLOUR_PM_WEAPONS_LOCKED = 160, 163 | HUD_COLOUR_END_SCREEN_BG = 161, 164 | HUD_COLOUR_CHOP = 162, 165 | HUD_COLOUR_PAUSEMAP_TINT_HALF = 163, 166 | HUD_COLOUR_NORTH_BLUE_OFFICIAL = 164, 167 | HUD_COLOUR_SCRIPT_VARIABLE_2 = 165, 168 | HUD_COLOUR_H = 166, 169 | HUD_COLOUR_HDARK = 167, 170 | HUD_COLOUR_T = 168, 171 | HUD_COLOUR_TDARK = 169, 172 | HUD_COLOUR_HSHARD = 170, 173 | HUD_COLOUR_CONTROLLER_MICHAEL = 171, 174 | HUD_COLOUR_CONTROLLER_FRANKLIN = 172, 175 | HUD_COLOUR_CONTROLLER_TREVOR = 173, 176 | HUD_COLOUR_CONTROLLER_CHOP = 174, 177 | HUD_COLOUR_VIDEO_EDITOR_VIDEO = 175, 178 | HUD_COLOUR_VIDEO_EDITOR_AUDIO = 176, 179 | HUD_COLOUR_VIDEO_EDITOR_TEXT = 177, 180 | HUD_COLOUR_HB_BLUE = 178, 181 | HUD_COLOUR_HB_YELLOW = 179 182 | } 183 | export default HudColor; 184 | -------------------------------------------------------------------------------- /src/items/UIMenuAutoListItem.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import Font from "../enums/Font"; 3 | import Alignment from "../enums/Alignment"; 4 | import ResText from "../modules/ResText"; 5 | import Sprite from "../modules/Sprite"; 6 | import Color from "../utils/Color"; 7 | import Point from "../utils/Point"; 8 | import Size from "../utils/Size"; 9 | import Screen from "../utils/Screen"; 10 | import UIMenuItem from "./UIMenuItem"; 11 | import { fixFloat } from "../utils/Number"; 12 | 13 | export default class UIMenuAutoListItem extends UIMenuItem { 14 | protected _itemText: ResText; 15 | protected _arrowLeft: Sprite; 16 | protected _arrowRight: Sprite; 17 | 18 | private _currentOffset: number = 0; 19 | private _leftMoveThreshold: number = 1; 20 | private _rightMoveThreshold: number = 1; 21 | private _lowerThreshold: number = 0; 22 | private _upperThreshold: number = 10; 23 | private _preCaptionText: string = ''; 24 | private _postCaptionText: string = ''; 25 | private _selectedValue: number; 26 | 27 | public get PreCaptionText() { 28 | return this._preCaptionText; 29 | } 30 | public set PreCaptionText(text: string) { 31 | if (!text) throw new Error("The pre caption text can't be null"); 32 | if (typeof text !== 'string') throw new Error("The pre caption text must be a string"); 33 | this._preCaptionText = text; 34 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue.toString() + this.PostCaptionText, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); // this._itemText && this._itemText.scale ? this._itemText.scale : 0.35 35 | } 36 | 37 | public get PostCaptionText() { 38 | return this._postCaptionText; 39 | } 40 | public set PostCaptionText(text: string) { 41 | if (!text) throw new Error("The post caption text can't be null"); 42 | if (typeof text !== 'string') throw new Error("The post caption text must be a string"); 43 | this._postCaptionText = text; 44 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue.toString() + this.PostCaptionText, this._itemText && this._itemText.Font ? this._itemText.Font : 0, 0.35); // this._itemText && this._itemText.scale ? this._itemText.scale : 0.35 45 | } 46 | 47 | public get LeftMoveThreshold() { 48 | return this._leftMoveThreshold; 49 | } 50 | public set LeftMoveThreshold(value: number) { 51 | if (!value) throw new Error("The left threshold can't be null"); 52 | 53 | this._leftMoveThreshold = value; 54 | } 55 | 56 | public get RightMoveThreshold() { 57 | return this._rightMoveThreshold; 58 | } 59 | public set RightMoveThreshold(value: number) { 60 | if (!value) throw new Error("The right threshold can't be null"); 61 | 62 | this._rightMoveThreshold = value; 63 | } 64 | 65 | public get LowerThreshold() { 66 | return this._lowerThreshold; 67 | } 68 | public set LowerThreshold(value: number) { 69 | if (typeof value !== 'number' && !value) throw new Error("The lower threshold can't be null"); 70 | 71 | this._lowerThreshold = value; 72 | if (this.SelectedValue < value) { 73 | this.SelectedValue = value; 74 | } 75 | } 76 | 77 | public get UpperThreshold() { 78 | return this._upperThreshold; 79 | } 80 | public set UpperThreshold(value: number) { 81 | if (typeof value !== 'number' && !value) throw new Error("The upper threshold can't be null"); 82 | 83 | this._upperThreshold = value; 84 | if (this.SelectedValue > value) { 85 | this.SelectedValue = value; 86 | } 87 | } 88 | 89 | public get SelectedValue() { 90 | return this._selectedValue; 91 | } 92 | public set SelectedValue(value: number) { 93 | if (value < this._lowerThreshold || value > this._upperThreshold) throw new Error("The value can not be outside the lower or upper limits"); 94 | 95 | this._selectedValue = fixFloat(value); 96 | this._currentOffset = Screen.GetTextWidth(this.PreCaptionText + this._selectedValue.toString() + this.PostCaptionText, this._itemText && this._itemText.Font ? this._itemText.Font : 0, this._itemText && this._itemText.Scale ? this._itemText.Scale : 0.35); 97 | } 98 | 99 | constructor(text: string, description: string = "", lowerThreshold: number = 0, upperThreshold: number = 10, startValue: number = 0, data: any = null) { 100 | super(text, description, data); 101 | 102 | let y = 0; 103 | this.LowerThreshold = lowerThreshold; 104 | this.UpperThreshold = lowerThreshold > upperThreshold ? lowerThreshold : upperThreshold; 105 | this.SelectedValue = (startValue < lowerThreshold || startValue > upperThreshold) ? lowerThreshold : startValue; 106 | this._arrowLeft = new Sprite("commonmenu", "arrowleft", new Point(110, 105 + y), new Size(30, 30)); 107 | this._arrowRight = new Sprite("commonmenu", "arrowright", new Point(280, 105 + y), new Size(30, 30)); 108 | this._itemText = new ResText("", new Point(290, y + 104), 0.35, Color.White, Font.ChaletLondon, Alignment.Right); 109 | } 110 | 111 | public SetVerticalPosition(y: number) { 112 | this._arrowLeft.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 113 | this._arrowRight.Pos = new Point(400 + this.Offset.X + this.Parent.WidthOffset, 147 + y + this.Offset.Y); 114 | this._itemText.Pos = new Point(300 + this.Offset.X + this.Parent.WidthOffset, y + 147 + this.Offset.Y); 115 | super.SetVerticalPosition(y); 116 | } 117 | 118 | public SetRightLabel(text: string) { 119 | return this; 120 | } 121 | 122 | public SetRightBadge(badge: BadgeStyle) { 123 | return this; 124 | } 125 | 126 | public Draw() { 127 | super.Draw(); 128 | const offset = this._currentOffset; 129 | 130 | this._itemText.Color = this.Enabled 131 | ? this.Selected 132 | ? this.HighlightedForeColor 133 | : this.ForeColor 134 | : new Color(163, 159, 148); 135 | 136 | this._itemText.Caption = this.PreCaptionText + this._selectedValue + this.PostCaptionText; 137 | 138 | this._arrowLeft.Color = this.Enabled 139 | ? this.Selected 140 | ? this.HighlightedForeColor 141 | : this.ForeColor 142 | : new Color(163, 159, 148); 143 | this._arrowRight.Color = this.Enabled 144 | ? this.Selected 145 | ? this.HighlightedForeColor 146 | : this.ForeColor 147 | : new Color(163, 159, 148); 148 | 149 | this._arrowLeft.Pos = new Point(380 - offset + this.Offset.X + this.Parent.WidthOffset, this._arrowLeft.Pos.Y); 150 | 151 | if (this.Selected) { 152 | this._arrowLeft.Draw(); 153 | this._arrowRight.Draw(); 154 | this._itemText.Pos = new Point(405 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 155 | } else { 156 | this._itemText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._itemText.Pos.Y); 157 | } 158 | this._itemText.Draw(); 159 | } 160 | } -------------------------------------------------------------------------------- /src/enums/Control.ts: -------------------------------------------------------------------------------- 1 | enum Control { 2 | NextCamera, 3 | LookLeftRight, 4 | LookUpDown, 5 | LookUpOnly, 6 | LookDownOnly, 7 | LookLeftOnly, 8 | LookRightOnly, 9 | CinematicSlowMo, 10 | FlyUpDown, 11 | FlyLeftRight, 12 | ScriptedFlyZUp, 13 | ScriptedFlyZDown, 14 | WeaponWheelUpDown, 15 | WeaponWheelLeftRight, 16 | WeaponWheelNext, 17 | WeaponWheelPrev, 18 | SelectNextWeapon, 19 | SelectPrevWeapon, 20 | SkipCutscene, 21 | CharacterWheel, 22 | MultiplayerInfo, 23 | Sprint, 24 | Jump, 25 | Enter, 26 | Attack, 27 | Aim, 28 | LookBehind, 29 | Phone, 30 | SpecialAbility, 31 | SpecialAbilitySecondary, 32 | MoveLeftRight, 33 | MoveUpDown, 34 | MoveUpOnly, 35 | MoveDownOnly, 36 | MoveLeftOnly, 37 | MoveRightOnly, 38 | Duck, 39 | SelectWeapon, 40 | Pickup, 41 | SniperZoom, 42 | SniperZoomInOnly, 43 | SniperZoomOutOnly, 44 | SniperZoomInSecondary, 45 | SniperZoomOutSecondary, 46 | Cover, 47 | Reload, 48 | Talk, 49 | Detonate, 50 | HUDSpecial, 51 | Arrest, 52 | AccurateAim, 53 | Context, 54 | ContextSecondary, 55 | WeaponSpecial, 56 | WeaponSpecial2, 57 | Dive, 58 | DropWeapon, 59 | DropAmmo, 60 | ThrowGrenade, 61 | VehicleMoveLeftRight, 62 | VehicleMoveUpDown, 63 | VehicleMoveUpOnly, 64 | VehicleMoveDownOnly, 65 | VehicleMoveLeftOnly, 66 | VehicleMoveRightOnly, 67 | VehicleSpecial, 68 | VehicleGunLeftRight, 69 | VehicleGunUpDown, 70 | VehicleAim, 71 | VehicleAttack, 72 | VehicleAttack2, 73 | VehicleAccelerate, 74 | VehicleBrake, 75 | VehicleDuck, 76 | VehicleHeadlight, 77 | VehicleExit, 78 | VehicleHandbrake, 79 | VehicleHotwireLeft, 80 | VehicleHotwireRight, 81 | VehicleLookBehind, 82 | VehicleCinCam, 83 | VehicleNextRadio, 84 | VehiclePrevRadio, 85 | VehicleNextRadioTrack, 86 | VehiclePrevRadioTrack, 87 | VehicleRadioWheel, 88 | VehicleHorn, 89 | VehicleFlyThrottleUp, 90 | VehicleFlyThrottleDown, 91 | VehicleFlyYawLeft, 92 | VehicleFlyYawRight, 93 | VehiclePassengerAim, 94 | VehiclePassengerAttack, 95 | VehicleSpecialAbilityFranklin, 96 | VehicleStuntUpDown, 97 | VehicleCinematicUpDown, 98 | VehicleCinematicUpOnly, 99 | VehicleCinematicDownOnly, 100 | VehicleCinematicLeftRight, 101 | VehicleSelectNextWeapon, 102 | VehicleSelectPrevWeapon, 103 | VehicleRoof, 104 | VehicleJump, 105 | VehicleGrapplingHook, 106 | VehicleShuffle, 107 | VehicleDropProjectile, 108 | VehicleMouseControlOverride, 109 | VehicleFlyRollLeftRight, 110 | VehicleFlyRollLeftOnly, 111 | VehicleFlyRollRightOnly, 112 | VehicleFlyPitchUpDown, 113 | VehicleFlyPitchUpOnly, 114 | VehicleFlyPitchDownOnly, 115 | VehicleFlyUnderCarriage, 116 | VehicleFlyAttack, 117 | VehicleFlySelectNextWeapon, 118 | VehicleFlySelectPrevWeapon, 119 | VehicleFlySelectTargetLeft, 120 | VehicleFlySelectTargetRight, 121 | VehicleFlyVerticalFlightMode, 122 | VehicleFlyDuck, 123 | VehicleFlyAttackCamera, 124 | VehicleFlyMouseControlOverride, 125 | VehicleSubTurnLeftRight, 126 | VehicleSubTurnLeftOnly, 127 | VehicleSubTurnRightOnly, 128 | VehicleSubPitchUpDown, 129 | VehicleSubPitchUpOnly, 130 | VehicleSubPitchDownOnly, 131 | VehicleSubThrottleUp, 132 | VehicleSubThrottleDown, 133 | VehicleSubAscend, 134 | VehicleSubDescend, 135 | VehicleSubTurnHardLeft, 136 | VehicleSubTurnHardRight, 137 | VehicleSubMouseControlOverride, 138 | VehiclePushbikePedal, 139 | VehiclePushbikeSprint, 140 | VehiclePushbikeFrontBrake, 141 | VehiclePushbikeRearBrake, 142 | MeleeAttackLight, 143 | MeleeAttackHeavy, 144 | MeleeAttackAlternate, 145 | MeleeBlock, 146 | ParachuteDeploy, 147 | ParachuteDetach, 148 | ParachuteTurnLeftRight, 149 | ParachuteTurnLeftOnly, 150 | ParachuteTurnRightOnly, 151 | ParachutePitchUpDown, 152 | ParachutePitchUpOnly, 153 | ParachutePitchDownOnly, 154 | ParachuteBrakeLeft, 155 | ParachuteBrakeRight, 156 | ParachuteSmoke, 157 | ParachutePrecisionLanding, 158 | Map, 159 | SelectWeaponUnarmed, 160 | SelectWeaponMelee, 161 | SelectWeaponHandgun, 162 | SelectWeaponShotgun, 163 | SelectWeaponSmg, 164 | SelectWeaponAutoRifle, 165 | SelectWeaponSniper, 166 | SelectWeaponHeavy, 167 | SelectWeaponSpecial, 168 | SelectCharacterMichael, 169 | SelectCharacterFranklin, 170 | SelectCharacterTrevor, 171 | SelectCharacterMultiplayer, 172 | SaveReplayClip, 173 | SpecialAbilityPC, 174 | PhoneUp, 175 | PhoneDown, 176 | PhoneLeft, 177 | PhoneRight, 178 | PhoneSelect, 179 | PhoneCancel, 180 | PhoneOption, 181 | PhoneExtraOption, 182 | PhoneScrollForward, 183 | PhoneScrollBackward, 184 | PhoneCameraFocusLock, 185 | PhoneCameraGrid, 186 | PhoneCameraSelfie, 187 | PhoneCameraDOF, 188 | PhoneCameraExpression, 189 | FrontendDown, 190 | FrontendUp, 191 | FrontendLeft, 192 | FrontendRight, 193 | FrontendRdown, 194 | FrontendRup, 195 | FrontendRleft, 196 | FrontendRright, 197 | FrontendAxisX, 198 | FrontendAxisY, 199 | FrontendRightAxisX, 200 | FrontendRightAxisY, 201 | FrontendPause, 202 | FrontendPauseAlternate, 203 | FrontendAccept, 204 | FrontendCancel, 205 | FrontendX, 206 | FrontendY, 207 | FrontendLb, 208 | FrontendRb, 209 | FrontendLt, 210 | FrontendRt, 211 | FrontendLs, 212 | FrontendRs, 213 | FrontendLeaderboard, 214 | FrontendSocialClub, 215 | FrontendSocialClubSecondary, 216 | FrontendDelete, 217 | FrontendEndscreenAccept, 218 | FrontendEndscreenExpand, 219 | FrontendSelect, 220 | ScriptLeftAxisX, 221 | ScriptLeftAxisY, 222 | ScriptRightAxisX, 223 | ScriptRightAxisY, 224 | ScriptRUp, 225 | ScriptRDown, 226 | ScriptRLeft, 227 | ScriptRRight, 228 | ScriptLB, 229 | ScriptRB, 230 | ScriptLT, 231 | ScriptRT, 232 | ScriptLS, 233 | ScriptRS, 234 | ScriptPadUp, 235 | ScriptPadDown, 236 | ScriptPadLeft, 237 | ScriptPadRight, 238 | ScriptSelect, 239 | CursorAccept, 240 | CursorCancel, 241 | CursorX, 242 | CursorY, 243 | CursorScrollUp, 244 | CursorScrollDown, 245 | EnterCheatCode, 246 | InteractionMenu, 247 | MpTextChatAll, 248 | MpTextChatTeam, 249 | MpTextChatFriends, 250 | MpTextChatCrew, 251 | PushToTalk, 252 | CreatorLS, 253 | CreatorRS, 254 | CreatorLT, 255 | CreatorRT, 256 | CreatorMenuToggle, 257 | CreatorAccept, 258 | CreatorDelete, 259 | Attack2, 260 | RappelJump, 261 | RappelLongJump, 262 | RappelSmashWindow, 263 | PrevWeapon, 264 | NextWeapon, 265 | MeleeAttack1, 266 | MeleeAttack2, 267 | Whistle, 268 | MoveLeft, 269 | MoveRight, 270 | MoveUp, 271 | MoveDown, 272 | LookLeft, 273 | LookRight, 274 | LookUp, 275 | LookDown, 276 | SniperZoomIn, 277 | SniperZoomOut, 278 | SniperZoomInAlternate, 279 | SniperZoomOutAlternate, 280 | VehicleMoveLeft, 281 | VehicleMoveRight, 282 | VehicleMoveUp, 283 | VehicleMoveDown, 284 | VehicleGunLeft, 285 | VehicleGunRight, 286 | VehicleGunUp, 287 | VehicleGunDown, 288 | VehicleLookLeft, 289 | VehicleLookRight, 290 | ReplayStartStopRecording, 291 | ReplayStartStopRecordingSecondary, 292 | ScaledLookLeftRight, 293 | ScaledLookUpDown, 294 | ScaledLookUpOnly, 295 | ScaledLookDownOnly, 296 | ScaledLookLeftOnly, 297 | ScaledLookRightOnly, 298 | ReplayMarkerDelete, 299 | ReplayClipDelete, 300 | ReplayPause, 301 | ReplayRewind, 302 | ReplayFfwd, 303 | ReplayNewmarker, 304 | ReplayRecord, 305 | ReplayScreenshot, 306 | ReplayHidehud, 307 | ReplayStartpoint, 308 | ReplayEndpoint, 309 | ReplayAdvance, 310 | ReplayBack, 311 | ReplayTools, 312 | ReplayRestart, 313 | ReplayShowhotkey, 314 | ReplayCycleMarkerLeft, 315 | ReplayCycleMarkerRight, 316 | ReplayFOVIncrease, 317 | ReplayFOVDecrease, 318 | ReplayCameraUp, 319 | ReplayCameraDown, 320 | ReplaySave, 321 | ReplayToggletime, 322 | ReplayToggletips, 323 | ReplayPreview, 324 | ReplayToggleTimeline, 325 | ReplayTimelinePickupClip, 326 | ReplayTimelineDuplicateClip, 327 | ReplayTimelinePlaceClip, 328 | ReplayCtrl, 329 | ReplayTimelineSave, 330 | ReplayPreviewAudio, 331 | VehicleDriveLook, 332 | VehicleDriveLook2, 333 | VehicleFlyAttack2, 334 | RadioWheelUpDown, 335 | RadioWheelLeftRight, 336 | VehicleSlowMoUpDown, 337 | VehicleSlowMoUpOnly, 338 | VehicleSlowMoDownOnly, 339 | MapPointOfInterest, 340 | ReplaySnapmaticPhoto, 341 | VehicleCarJump, 342 | VehicleRocketBoost, 343 | VehicleParachute, 344 | VehicleBikeWings, 345 | VehicleFlyBombBay, 346 | VehicleFlyCounter, 347 | VehicleFlyTransform, 348 | } 349 | 350 | export default Control; -------------------------------------------------------------------------------- /src/items/UIMenuItem.js: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import Font from "../enums/Font"; 3 | import Alignment from "../enums/Alignment"; 4 | import ResRectangle from "../modules/ResRectangle"; 5 | import ResText from "../modules/ResText"; 6 | import Sprite from "../modules/Sprite"; 7 | import Color from "../utils/Color"; 8 | import Point from "../utils/Point"; 9 | import Size from "../utils/Size"; 10 | import UUIDV4 from "../utils/UUIDV4"; 11 | export default class UIMenuItem { 12 | constructor(text, description = "", data = null) { 13 | this.Id = UUIDV4(); 14 | this.BackColor = UIMenuItem.DefaultBackColor; 15 | this.HighlightedBackColor = UIMenuItem.DefaultHighlightedBackColor; 16 | this.ForeColor = UIMenuItem.DefaultForeColor; 17 | this.HighlightedForeColor = UIMenuItem.DefaultHighlightedForeColor; 18 | this.RightLabel = ""; 19 | this.LeftBadge = BadgeStyle.None; 20 | this.RightBadge = BadgeStyle.None; 21 | this.Enabled = true; 22 | this.Data = data; 23 | this._rectangle = new ResRectangle(new Point(0, 0), new Size(431, 38), new Color(150, 0, 0, 0)); 24 | this._text = new ResText(text, new Point(8, 0), 0.33, Color.WhiteSmoke, Font.ChaletLondon, Alignment.Left); 25 | this.Description = description; 26 | this._selectedSprite = new Sprite("commonmenu", "gradient_nav", new Point(0, 0), new Size(431, 38)); 27 | this._badgeLeft = new Sprite("commonmenu", "", new Point(0, 0), new Size(40, 40)); 28 | this._badgeRight = new Sprite("commonmenu", "", new Point(0, 0), new Size(40, 40)); 29 | this._labelText = new ResText("", new Point(0, 0), 0.35, Color.White, 0, Alignment.Right); 30 | } 31 | get Text() { 32 | return this._text.Caption; 33 | } 34 | set Text(text) { 35 | this._text.Caption = text; 36 | } 37 | get Description() { 38 | return this._description; 39 | } 40 | set Description(text) { 41 | this._description = text; 42 | if (this.hasOwnProperty('Parent')) { 43 | this.Parent.UpdateDescriptionCaption(); 44 | } 45 | } 46 | SetVerticalPosition(y) { 47 | this._rectangle.Pos = new Point(this.Offset.X, y + 144 + this.Offset.Y); 48 | this._selectedSprite.Pos = new Point(0 + this.Offset.X, y + 144 + this.Offset.Y); 49 | this._text.Pos = new Point(8 + this.Offset.X, y + 147 + this.Offset.Y); 50 | this._badgeLeft.Pos = new Point(0 + this.Offset.X, y + 142 + this.Offset.Y); 51 | this._badgeRight.Pos = new Point(385 + this.Offset.X, y + 142 + this.Offset.Y); 52 | this._labelText.Pos = new Point(420 + this.Offset.X, y + 148 + this.Offset.Y); 53 | } 54 | addEvent(event, ...args) { 55 | this._event = { event: event, args: args }; 56 | } 57 | fireEvent() { 58 | if (this._event) { 59 | // alt.emit(this._event.event, ...this._event.args); 60 | } 61 | } 62 | Draw() { 63 | this._rectangle.Size = new Size(431 + this.Parent.WidthOffset, 38); 64 | this._selectedSprite.Size = new Size(431 + this.Parent.WidthOffset, 38); 65 | if (this.Hovered && !this.Selected) { 66 | this._rectangle.Color = new Color(255, 255, 255, 20); 67 | this._rectangle.Draw(); 68 | } 69 | this._selectedSprite.Color = this.Selected 70 | ? this.HighlightedBackColor 71 | : this.BackColor; 72 | this._selectedSprite.Draw(); 73 | this._text.Color = this.Enabled 74 | ? this.Selected 75 | ? this.HighlightedForeColor 76 | : this.ForeColor 77 | : new Color(163, 159, 148); 78 | if (this.LeftBadge != BadgeStyle.None) { 79 | this._text.Pos = new Point(35 + this.Offset.X, this._text.Pos.Y); 80 | this._badgeLeft.TextureDict = this.BadgeToSpriteLib(this.LeftBadge); 81 | this._badgeLeft.TextureName = this.BadgeToSpriteName(this.LeftBadge, this.Selected); 82 | this._badgeLeft.Color = this.IsBagdeWhiteSprite(this.LeftBadge) 83 | ? this.Enabled 84 | ? this.Selected 85 | ? this.HighlightedForeColor 86 | : this.ForeColor 87 | : new Color(163, 159, 148) 88 | : Color.White; 89 | this._badgeLeft.Draw(); 90 | } 91 | else { 92 | this._text.Pos = new Point(8 + this.Offset.X, this._text.Pos.Y); 93 | } 94 | if (this.RightBadge != BadgeStyle.None) { 95 | this._badgeRight.Pos = new Point(385 + this.Offset.X + this.Parent.WidthOffset, this._badgeRight.Pos.Y); 96 | this._badgeRight.TextureDict = this.BadgeToSpriteLib(this.RightBadge); 97 | this._badgeRight.TextureName = this.BadgeToSpriteName(this.RightBadge, this.Selected); 98 | this._badgeRight.Color = this.IsBagdeWhiteSprite(this.RightBadge) 99 | ? this.Enabled 100 | ? this.Selected 101 | ? this.HighlightedForeColor 102 | : this.ForeColor 103 | : new Color(163, 159, 148) 104 | : Color.White; 105 | this._badgeRight.Draw(); 106 | } 107 | if (this.RightLabel && this.RightLabel !== "") { 108 | this._labelText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._labelText.Pos.Y); 109 | this._labelText.Caption = this.RightLabel; 110 | this._labelText.Color = this._text.Color = this.Enabled 111 | ? this.Selected 112 | ? this.HighlightedForeColor 113 | : this.ForeColor 114 | : new Color(163, 159, 148); 115 | this._labelText.Draw(); 116 | } 117 | this._text.Draw(); 118 | } 119 | SetLeftBadge(badge) { 120 | this.LeftBadge = badge; 121 | } 122 | SetRightBadge(badge) { 123 | this.RightBadge = badge; 124 | } 125 | SetRightLabel(text) { 126 | this.RightLabel = text; 127 | } 128 | BadgeToSpriteLib(badge) { 129 | switch (badge) { 130 | case BadgeStyle.Sale: 131 | return "mpshopsale"; 132 | case BadgeStyle.Audio1: 133 | case BadgeStyle.Audio2: 134 | case BadgeStyle.Audio3: 135 | case BadgeStyle.AudioInactive: 136 | case BadgeStyle.AudioMute: 137 | return "mpleaderboard"; 138 | default: 139 | return "commonmenu"; 140 | } 141 | } 142 | BadgeToSpriteName(badge, selected) { 143 | switch (badge) { 144 | case BadgeStyle.None: 145 | return ""; 146 | case BadgeStyle.BronzeMedal: 147 | return "mp_medal_bronze"; 148 | case BadgeStyle.GoldMedal: 149 | return "mp_medal_gold"; 150 | case BadgeStyle.SilverMedal: 151 | return "medal_silver"; 152 | case BadgeStyle.Alert: 153 | return "mp_alerttriangle"; 154 | case BadgeStyle.Crown: 155 | return "mp_hostcrown"; 156 | case BadgeStyle.Ammo: 157 | return selected ? "shop_ammo_icon_b" : "shop_ammo_icon_a"; 158 | case BadgeStyle.Armour: 159 | return selected ? "shop_armour_icon_b" : "shop_armour_icon_a"; 160 | case BadgeStyle.Barber: 161 | return selected ? "shop_barber_icon_b" : "shop_barber_icon_a"; 162 | case BadgeStyle.Clothes: 163 | return selected ? "shop_clothing_icon_b" : "shop_clothing_icon_a"; 164 | case BadgeStyle.Franklin: 165 | return selected ? "shop_franklin_icon_b" : "shop_franklin_icon_a"; 166 | case BadgeStyle.Bike: 167 | return selected ? "shop_garage_bike_icon_b" : "shop_garage_bike_icon_a"; 168 | case BadgeStyle.Car: 169 | return selected ? "shop_garage_icon_b" : "shop_garage_icon_a"; 170 | case BadgeStyle.Gun: 171 | return selected ? "shop_gunclub_icon_b" : "shop_gunclub_icon_a"; 172 | case BadgeStyle.Heart: 173 | return selected ? "shop_health_icon_b" : "shop_health_icon_a"; 174 | case BadgeStyle.Lock: 175 | return "shop_lock"; 176 | case BadgeStyle.Makeup: 177 | return selected ? "shop_makeup_icon_b" : "shop_makeup_icon_a"; 178 | case BadgeStyle.Mask: 179 | return selected ? "shop_mask_icon_b" : "shop_mask_icon_a"; 180 | case BadgeStyle.Michael: 181 | return selected ? "shop_michael_icon_b" : "shop_michael_icon_a"; 182 | case BadgeStyle.Star: 183 | return "shop_new_star"; 184 | case BadgeStyle.Tattoo: 185 | return selected ? "shop_tattoos_icon_b" : "shop_tattoos_icon_a"; 186 | case BadgeStyle.Tick: 187 | return "shop_tick_icon"; 188 | case BadgeStyle.Trevor: 189 | return selected ? "shop_trevor_icon_b" : "shop_trevor_icon_a"; 190 | case BadgeStyle.Sale: 191 | return "saleicon"; 192 | case BadgeStyle.ArrowLeft: 193 | return "arrowleft"; 194 | case BadgeStyle.ArrowRight: 195 | return "arrowright"; 196 | case BadgeStyle.Audio1: 197 | return "leaderboard_audio_1"; 198 | case BadgeStyle.Audio2: 199 | return "leaderboard_audio_2"; 200 | case BadgeStyle.Audio3: 201 | return "leaderboard_audio_3"; 202 | case BadgeStyle.AudioInactive: 203 | return "leaderboard_audio_inactive"; 204 | case BadgeStyle.AudioMute: 205 | return "leaderboard_audio_mute"; 206 | default: 207 | return ""; 208 | } 209 | } 210 | IsBagdeWhiteSprite(badge) { 211 | switch (badge) { 212 | case BadgeStyle.Lock: 213 | case BadgeStyle.Tick: 214 | case BadgeStyle.Crown: 215 | return true; 216 | default: 217 | return false; 218 | } 219 | } 220 | BadgeToColor(badge, selected) { 221 | switch (badge) { 222 | case BadgeStyle.Lock: 223 | case BadgeStyle.Tick: 224 | case BadgeStyle.Crown: 225 | return selected 226 | ? new Color(255, 0, 0, 0) 227 | : new Color(255, 255, 255, 255); 228 | default: 229 | return new Color(255, 255, 255, 255); 230 | } 231 | } 232 | } 233 | UIMenuItem.DefaultBackColor = Color.Empty; 234 | UIMenuItem.DefaultHighlightedBackColor = Color.White; 235 | UIMenuItem.DefaultForeColor = Color.WhiteSmoke; 236 | UIMenuItem.DefaultHighlightedForeColor = Color.Black; 237 | -------------------------------------------------------------------------------- /examples/nativeUI-example/src/include/nativeui/enums/Control.d.ts: -------------------------------------------------------------------------------- 1 | declare enum Control { 2 | NextCamera = 0, 3 | LookLeftRight = 1, 4 | LookUpDown = 2, 5 | LookUpOnly = 3, 6 | LookDownOnly = 4, 7 | LookLeftOnly = 5, 8 | LookRightOnly = 6, 9 | CinematicSlowMo = 7, 10 | FlyUpDown = 8, 11 | FlyLeftRight = 9, 12 | ScriptedFlyZUp = 10, 13 | ScriptedFlyZDown = 11, 14 | WeaponWheelUpDown = 12, 15 | WeaponWheelLeftRight = 13, 16 | WeaponWheelNext = 14, 17 | WeaponWheelPrev = 15, 18 | SelectNextWeapon = 16, 19 | SelectPrevWeapon = 17, 20 | SkipCutscene = 18, 21 | CharacterWheel = 19, 22 | MultiplayerInfo = 20, 23 | Sprint = 21, 24 | Jump = 22, 25 | Enter = 23, 26 | Attack = 24, 27 | Aim = 25, 28 | LookBehind = 26, 29 | Phone = 27, 30 | SpecialAbility = 28, 31 | SpecialAbilitySecondary = 29, 32 | MoveLeftRight = 30, 33 | MoveUpDown = 31, 34 | MoveUpOnly = 32, 35 | MoveDownOnly = 33, 36 | MoveLeftOnly = 34, 37 | MoveRightOnly = 35, 38 | Duck = 36, 39 | SelectWeapon = 37, 40 | Pickup = 38, 41 | SniperZoom = 39, 42 | SniperZoomInOnly = 40, 43 | SniperZoomOutOnly = 41, 44 | SniperZoomInSecondary = 42, 45 | SniperZoomOutSecondary = 43, 46 | Cover = 44, 47 | Reload = 45, 48 | Talk = 46, 49 | Detonate = 47, 50 | HUDSpecial = 48, 51 | Arrest = 49, 52 | AccurateAim = 50, 53 | Context = 51, 54 | ContextSecondary = 52, 55 | WeaponSpecial = 53, 56 | WeaponSpecial2 = 54, 57 | Dive = 55, 58 | DropWeapon = 56, 59 | DropAmmo = 57, 60 | ThrowGrenade = 58, 61 | VehicleMoveLeftRight = 59, 62 | VehicleMoveUpDown = 60, 63 | VehicleMoveUpOnly = 61, 64 | VehicleMoveDownOnly = 62, 65 | VehicleMoveLeftOnly = 63, 66 | VehicleMoveRightOnly = 64, 67 | VehicleSpecial = 65, 68 | VehicleGunLeftRight = 66, 69 | VehicleGunUpDown = 67, 70 | VehicleAim = 68, 71 | VehicleAttack = 69, 72 | VehicleAttack2 = 70, 73 | VehicleAccelerate = 71, 74 | VehicleBrake = 72, 75 | VehicleDuck = 73, 76 | VehicleHeadlight = 74, 77 | VehicleExit = 75, 78 | VehicleHandbrake = 76, 79 | VehicleHotwireLeft = 77, 80 | VehicleHotwireRight = 78, 81 | VehicleLookBehind = 79, 82 | VehicleCinCam = 80, 83 | VehicleNextRadio = 81, 84 | VehiclePrevRadio = 82, 85 | VehicleNextRadioTrack = 83, 86 | VehiclePrevRadioTrack = 84, 87 | VehicleRadioWheel = 85, 88 | VehicleHorn = 86, 89 | VehicleFlyThrottleUp = 87, 90 | VehicleFlyThrottleDown = 88, 91 | VehicleFlyYawLeft = 89, 92 | VehicleFlyYawRight = 90, 93 | VehiclePassengerAim = 91, 94 | VehiclePassengerAttack = 92, 95 | VehicleSpecialAbilityFranklin = 93, 96 | VehicleStuntUpDown = 94, 97 | VehicleCinematicUpDown = 95, 98 | VehicleCinematicUpOnly = 96, 99 | VehicleCinematicDownOnly = 97, 100 | VehicleCinematicLeftRight = 98, 101 | VehicleSelectNextWeapon = 99, 102 | VehicleSelectPrevWeapon = 100, 103 | VehicleRoof = 101, 104 | VehicleJump = 102, 105 | VehicleGrapplingHook = 103, 106 | VehicleShuffle = 104, 107 | VehicleDropProjectile = 105, 108 | VehicleMouseControlOverride = 106, 109 | VehicleFlyRollLeftRight = 107, 110 | VehicleFlyRollLeftOnly = 108, 111 | VehicleFlyRollRightOnly = 109, 112 | VehicleFlyPitchUpDown = 110, 113 | VehicleFlyPitchUpOnly = 111, 114 | VehicleFlyPitchDownOnly = 112, 115 | VehicleFlyUnderCarriage = 113, 116 | VehicleFlyAttack = 114, 117 | VehicleFlySelectNextWeapon = 115, 118 | VehicleFlySelectPrevWeapon = 116, 119 | VehicleFlySelectTargetLeft = 117, 120 | VehicleFlySelectTargetRight = 118, 121 | VehicleFlyVerticalFlightMode = 119, 122 | VehicleFlyDuck = 120, 123 | VehicleFlyAttackCamera = 121, 124 | VehicleFlyMouseControlOverride = 122, 125 | VehicleSubTurnLeftRight = 123, 126 | VehicleSubTurnLeftOnly = 124, 127 | VehicleSubTurnRightOnly = 125, 128 | VehicleSubPitchUpDown = 126, 129 | VehicleSubPitchUpOnly = 127, 130 | VehicleSubPitchDownOnly = 128, 131 | VehicleSubThrottleUp = 129, 132 | VehicleSubThrottleDown = 130, 133 | VehicleSubAscend = 131, 134 | VehicleSubDescend = 132, 135 | VehicleSubTurnHardLeft = 133, 136 | VehicleSubTurnHardRight = 134, 137 | VehicleSubMouseControlOverride = 135, 138 | VehiclePushbikePedal = 136, 139 | VehiclePushbikeSprint = 137, 140 | VehiclePushbikeFrontBrake = 138, 141 | VehiclePushbikeRearBrake = 139, 142 | MeleeAttackLight = 140, 143 | MeleeAttackHeavy = 141, 144 | MeleeAttackAlternate = 142, 145 | MeleeBlock = 143, 146 | ParachuteDeploy = 144, 147 | ParachuteDetach = 145, 148 | ParachuteTurnLeftRight = 146, 149 | ParachuteTurnLeftOnly = 147, 150 | ParachuteTurnRightOnly = 148, 151 | ParachutePitchUpDown = 149, 152 | ParachutePitchUpOnly = 150, 153 | ParachutePitchDownOnly = 151, 154 | ParachuteBrakeLeft = 152, 155 | ParachuteBrakeRight = 153, 156 | ParachuteSmoke = 154, 157 | ParachutePrecisionLanding = 155, 158 | Map = 156, 159 | SelectWeaponUnarmed = 157, 160 | SelectWeaponMelee = 158, 161 | SelectWeaponHandgun = 159, 162 | SelectWeaponShotgun = 160, 163 | SelectWeaponSmg = 161, 164 | SelectWeaponAutoRifle = 162, 165 | SelectWeaponSniper = 163, 166 | SelectWeaponHeavy = 164, 167 | SelectWeaponSpecial = 165, 168 | SelectCharacterMichael = 166, 169 | SelectCharacterFranklin = 167, 170 | SelectCharacterTrevor = 168, 171 | SelectCharacterMultiplayer = 169, 172 | SaveReplayClip = 170, 173 | SpecialAbilityPC = 171, 174 | PhoneUp = 172, 175 | PhoneDown = 173, 176 | PhoneLeft = 174, 177 | PhoneRight = 175, 178 | PhoneSelect = 176, 179 | PhoneCancel = 177, 180 | PhoneOption = 178, 181 | PhoneExtraOption = 179, 182 | PhoneScrollForward = 180, 183 | PhoneScrollBackward = 181, 184 | PhoneCameraFocusLock = 182, 185 | PhoneCameraGrid = 183, 186 | PhoneCameraSelfie = 184, 187 | PhoneCameraDOF = 185, 188 | PhoneCameraExpression = 186, 189 | FrontendDown = 187, 190 | FrontendUp = 188, 191 | FrontendLeft = 189, 192 | FrontendRight = 190, 193 | FrontendRdown = 191, 194 | FrontendRup = 192, 195 | FrontendRleft = 193, 196 | FrontendRright = 194, 197 | FrontendAxisX = 195, 198 | FrontendAxisY = 196, 199 | FrontendRightAxisX = 197, 200 | FrontendRightAxisY = 198, 201 | FrontendPause = 199, 202 | FrontendPauseAlternate = 200, 203 | FrontendAccept = 201, 204 | FrontendCancel = 202, 205 | FrontendX = 203, 206 | FrontendY = 204, 207 | FrontendLb = 205, 208 | FrontendRb = 206, 209 | FrontendLt = 207, 210 | FrontendRt = 208, 211 | FrontendLs = 209, 212 | FrontendRs = 210, 213 | FrontendLeaderboard = 211, 214 | FrontendSocialClub = 212, 215 | FrontendSocialClubSecondary = 213, 216 | FrontendDelete = 214, 217 | FrontendEndscreenAccept = 215, 218 | FrontendEndscreenExpand = 216, 219 | FrontendSelect = 217, 220 | ScriptLeftAxisX = 218, 221 | ScriptLeftAxisY = 219, 222 | ScriptRightAxisX = 220, 223 | ScriptRightAxisY = 221, 224 | ScriptRUp = 222, 225 | ScriptRDown = 223, 226 | ScriptRLeft = 224, 227 | ScriptRRight = 225, 228 | ScriptLB = 226, 229 | ScriptRB = 227, 230 | ScriptLT = 228, 231 | ScriptRT = 229, 232 | ScriptLS = 230, 233 | ScriptRS = 231, 234 | ScriptPadUp = 232, 235 | ScriptPadDown = 233, 236 | ScriptPadLeft = 234, 237 | ScriptPadRight = 235, 238 | ScriptSelect = 236, 239 | CursorAccept = 237, 240 | CursorCancel = 238, 241 | CursorX = 239, 242 | CursorY = 240, 243 | CursorScrollUp = 241, 244 | CursorScrollDown = 242, 245 | EnterCheatCode = 243, 246 | InteractionMenu = 244, 247 | MpTextChatAll = 245, 248 | MpTextChatTeam = 246, 249 | MpTextChatFriends = 247, 250 | MpTextChatCrew = 248, 251 | PushToTalk = 249, 252 | CreatorLS = 250, 253 | CreatorRS = 251, 254 | CreatorLT = 252, 255 | CreatorRT = 253, 256 | CreatorMenuToggle = 254, 257 | CreatorAccept = 255, 258 | CreatorDelete = 256, 259 | Attack2 = 257, 260 | RappelJump = 258, 261 | RappelLongJump = 259, 262 | RappelSmashWindow = 260, 263 | PrevWeapon = 261, 264 | NextWeapon = 262, 265 | MeleeAttack1 = 263, 266 | MeleeAttack2 = 264, 267 | Whistle = 265, 268 | MoveLeft = 266, 269 | MoveRight = 267, 270 | MoveUp = 268, 271 | MoveDown = 269, 272 | LookLeft = 270, 273 | LookRight = 271, 274 | LookUp = 272, 275 | LookDown = 273, 276 | SniperZoomIn = 274, 277 | SniperZoomOut = 275, 278 | SniperZoomInAlternate = 276, 279 | SniperZoomOutAlternate = 277, 280 | VehicleMoveLeft = 278, 281 | VehicleMoveRight = 279, 282 | VehicleMoveUp = 280, 283 | VehicleMoveDown = 281, 284 | VehicleGunLeft = 282, 285 | VehicleGunRight = 283, 286 | VehicleGunUp = 284, 287 | VehicleGunDown = 285, 288 | VehicleLookLeft = 286, 289 | VehicleLookRight = 287, 290 | ReplayStartStopRecording = 288, 291 | ReplayStartStopRecordingSecondary = 289, 292 | ScaledLookLeftRight = 290, 293 | ScaledLookUpDown = 291, 294 | ScaledLookUpOnly = 292, 295 | ScaledLookDownOnly = 293, 296 | ScaledLookLeftOnly = 294, 297 | ScaledLookRightOnly = 295, 298 | ReplayMarkerDelete = 296, 299 | ReplayClipDelete = 297, 300 | ReplayPause = 298, 301 | ReplayRewind = 299, 302 | ReplayFfwd = 300, 303 | ReplayNewmarker = 301, 304 | ReplayRecord = 302, 305 | ReplayScreenshot = 303, 306 | ReplayHidehud = 304, 307 | ReplayStartpoint = 305, 308 | ReplayEndpoint = 306, 309 | ReplayAdvance = 307, 310 | ReplayBack = 308, 311 | ReplayTools = 309, 312 | ReplayRestart = 310, 313 | ReplayShowhotkey = 311, 314 | ReplayCycleMarkerLeft = 312, 315 | ReplayCycleMarkerRight = 313, 316 | ReplayFOVIncrease = 314, 317 | ReplayFOVDecrease = 315, 318 | ReplayCameraUp = 316, 319 | ReplayCameraDown = 317, 320 | ReplaySave = 318, 321 | ReplayToggletime = 319, 322 | ReplayToggletips = 320, 323 | ReplayPreview = 321, 324 | ReplayToggleTimeline = 322, 325 | ReplayTimelinePickupClip = 323, 326 | ReplayTimelineDuplicateClip = 324, 327 | ReplayTimelinePlaceClip = 325, 328 | ReplayCtrl = 326, 329 | ReplayTimelineSave = 327, 330 | ReplayPreviewAudio = 328, 331 | VehicleDriveLook = 329, 332 | VehicleDriveLook2 = 330, 333 | VehicleFlyAttack2 = 331, 334 | RadioWheelUpDown = 332, 335 | RadioWheelLeftRight = 333, 336 | VehicleSlowMoUpDown = 334, 337 | VehicleSlowMoUpOnly = 335, 338 | VehicleSlowMoDownOnly = 336, 339 | MapPointOfInterest = 337, 340 | ReplaySnapmaticPhoto = 338, 341 | VehicleCarJump = 339, 342 | VehicleRocketBoost = 340, 343 | VehicleParachute = 341, 344 | VehicleBikeWings = 342, 345 | VehicleFlyBombBay = 343, 346 | VehicleFlyCounter = 344, 347 | VehicleFlyTransform = 345 348 | } 349 | export default Control; 350 | -------------------------------------------------------------------------------- /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 [yyyy] [name of copyright owner] 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 | -------------------------------------------------------------------------------- /src/items/UIMenuItem.ts: -------------------------------------------------------------------------------- 1 | import BadgeStyle from "../enums/BadgeStyle"; 2 | import Font from "../enums/Font"; 3 | import Alignment from "../enums/Alignment"; 4 | import NativeUI from "../NativeUi"; 5 | import ResRectangle from "../modules/ResRectangle"; 6 | import ResText from "../modules/ResText"; 7 | import Sprite from "../modules/Sprite"; 8 | import Color from "../utils/Color"; 9 | import Point from "../utils/Point"; 10 | import Size from "../utils/Size"; 11 | import UUIDV4 from "../utils/UUIDV4"; 12 | 13 | export default class UIMenuItem { 14 | public readonly Id: string = UUIDV4(); 15 | 16 | public static readonly DefaultBackColor: Color = Color.Empty; 17 | public static readonly DefaultHighlightedBackColor: Color = Color.White; 18 | public static readonly DefaultForeColor: Color = Color.WhiteSmoke; 19 | public static readonly DefaultHighlightedForeColor: Color = Color.Black; 20 | 21 | private _event: { event: string; args: any[] }; 22 | 23 | protected _rectangle: ResRectangle; 24 | protected _text: ResText; 25 | protected _description: string; 26 | protected _selectedSprite: Sprite; 27 | protected _badgeLeft: Sprite; 28 | protected _badgeRight: Sprite; 29 | protected _labelText: ResText; 30 | 31 | public BackColor: Color = UIMenuItem.DefaultBackColor; 32 | public HighlightedBackColor: Color = UIMenuItem.DefaultHighlightedBackColor; 33 | 34 | public ForeColor: Color = UIMenuItem.DefaultForeColor; 35 | public HighlightedForeColor: Color = UIMenuItem.DefaultHighlightedForeColor; 36 | 37 | public Enabled: boolean; 38 | public Selected: boolean; 39 | public Hovered: boolean; 40 | public Data: any; 41 | 42 | public Offset: Point; 43 | public Parent: NativeUI; 44 | 45 | public get Text() { 46 | return this._text.Caption; 47 | } 48 | public set Text(text) { 49 | this._text.Caption = text; 50 | } 51 | 52 | public get Description() { 53 | return this._description; 54 | } 55 | public set Description(text) { 56 | this._description = text; 57 | if (this.hasOwnProperty('Parent')) { 58 | this.Parent.UpdateDescriptionCaption(); 59 | } 60 | } 61 | 62 | public RightLabel: string = ""; 63 | public LeftBadge: BadgeStyle = BadgeStyle.None; 64 | public RightBadge: BadgeStyle = BadgeStyle.None; 65 | 66 | constructor(text: string, description = "", data: any = null) { 67 | this.Enabled = true; 68 | this.Data = data; 69 | 70 | this._rectangle = new ResRectangle(new Point(0, 0), new Size(431, 38), new Color(150, 0, 0, 0)); 71 | this._text = new ResText(text, new Point(8, 0), 0.33, Color.WhiteSmoke, Font.ChaletLondon, Alignment.Left); 72 | this.Description = description; 73 | this._selectedSprite = new Sprite("commonmenu", "gradient_nav", new Point(0, 0), new Size(431, 38)); 74 | 75 | this._badgeLeft = new Sprite("commonmenu", "", new Point(0, 0), new Size(40, 40)); 76 | this._badgeRight = new Sprite("commonmenu", "", new Point(0, 0), new Size(40, 40)); 77 | 78 | this._labelText = new ResText("", new Point(0, 0), 0.35, Color.White, 0, Alignment.Right); 79 | } 80 | 81 | public SetVerticalPosition(y: number) { 82 | this._rectangle.Pos = new Point(this.Offset.X, y + 144 + this.Offset.Y); 83 | this._selectedSprite.Pos = new Point(0 + this.Offset.X, y + 144 + this.Offset.Y); 84 | this._text.Pos = new Point(8 + this.Offset.X, y + 147 + this.Offset.Y); 85 | 86 | this._badgeLeft.Pos = new Point(0 + this.Offset.X, y + 142 + this.Offset.Y); 87 | this._badgeRight.Pos = new Point(385 + this.Offset.X, y + 142 + this.Offset.Y); 88 | 89 | this._labelText.Pos = new Point(420 + this.Offset.X, y + 148 + this.Offset.Y); 90 | } 91 | 92 | public addEvent(event: string, ...args: any[]) { 93 | this._event = { event: event, args: args }; 94 | } 95 | 96 | public fireEvent() { 97 | if (this._event) { 98 | //alt.emit(this._event.event, ...this._event.args); 99 | } 100 | } 101 | 102 | public Draw() { 103 | this._rectangle.Size = new Size(431 + this.Parent.WidthOffset, 38); 104 | this._selectedSprite.Size = new Size(431 + this.Parent.WidthOffset, 38); 105 | 106 | if (this.Hovered && !this.Selected) { 107 | this._rectangle.Color = new Color(255, 255, 255, 20); 108 | this._rectangle.Draw(); 109 | } 110 | 111 | this._selectedSprite.Color = this.Selected 112 | ? this.HighlightedBackColor 113 | : this.BackColor; 114 | this._selectedSprite.Draw(); 115 | 116 | this._text.Color = this.Enabled 117 | ? this.Selected 118 | ? this.HighlightedForeColor 119 | : this.ForeColor 120 | : new Color(163, 159, 148); 121 | 122 | if (this.LeftBadge != BadgeStyle.None) { 123 | this._text.Pos = new Point(35 + this.Offset.X, this._text.Pos.Y); 124 | this._badgeLeft.TextureDict = this.BadgeToSpriteLib(this.LeftBadge); 125 | this._badgeLeft.TextureName = this.BadgeToSpriteName(this.LeftBadge, this.Selected); 126 | this._badgeLeft.Color = this.IsBagdeWhiteSprite(this.LeftBadge) 127 | ? this.Enabled 128 | ? this.Selected 129 | ? this.HighlightedForeColor 130 | : this.ForeColor 131 | : new Color(163, 159, 148) 132 | : Color.White; 133 | this._badgeLeft.Draw(); 134 | } else { 135 | this._text.Pos = new Point(8 + this.Offset.X, this._text.Pos.Y); 136 | } 137 | 138 | if (this.RightBadge != BadgeStyle.None) { 139 | this._badgeRight.Pos = new Point(385 + this.Offset.X + this.Parent.WidthOffset, this._badgeRight.Pos.Y); 140 | this._badgeRight.TextureDict = this.BadgeToSpriteLib(this.RightBadge); 141 | this._badgeRight.TextureName = this.BadgeToSpriteName(this.RightBadge, this.Selected); 142 | this._badgeRight.Color = this.IsBagdeWhiteSprite(this.RightBadge) 143 | ? this.Enabled 144 | ? this.Selected 145 | ? this.HighlightedForeColor 146 | : this.ForeColor 147 | : new Color(163, 159, 148) 148 | : Color.White; 149 | this._badgeRight.Draw(); 150 | } 151 | 152 | if (this.RightLabel && this.RightLabel !== "") { 153 | this._labelText.Pos = new Point(420 + this.Offset.X + this.Parent.WidthOffset, this._labelText.Pos.Y); 154 | this._labelText.Caption = this.RightLabel; 155 | this._labelText.Color = this._text.Color = this.Enabled 156 | ? this.Selected 157 | ? this.HighlightedForeColor 158 | : this.ForeColor 159 | : new Color(163, 159, 148); 160 | this._labelText.Draw(); 161 | } 162 | this._text.Draw(); 163 | } 164 | 165 | public SetLeftBadge(badge: BadgeStyle) { 166 | this.LeftBadge = badge; 167 | } 168 | 169 | public SetRightBadge(badge: BadgeStyle) { 170 | this.RightBadge = badge; 171 | } 172 | 173 | public SetRightLabel(text: string) { 174 | this.RightLabel = text; 175 | } 176 | 177 | public BadgeToSpriteLib(badge: BadgeStyle) { 178 | switch (badge) { 179 | case BadgeStyle.Sale: 180 | return "mpshopsale"; 181 | case BadgeStyle.Audio1: 182 | case BadgeStyle.Audio2: 183 | case BadgeStyle.Audio3: 184 | case BadgeStyle.AudioInactive: 185 | case BadgeStyle.AudioMute: 186 | return "mpleaderboard"; 187 | default: 188 | return "commonmenu"; 189 | } 190 | } 191 | 192 | public BadgeToSpriteName(badge: BadgeStyle, selected: boolean) { 193 | switch (badge) { 194 | case BadgeStyle.None: 195 | return ""; 196 | case BadgeStyle.BronzeMedal: 197 | return "mp_medal_bronze"; 198 | case BadgeStyle.GoldMedal: 199 | return "mp_medal_gold"; 200 | case BadgeStyle.SilverMedal: 201 | return "medal_silver"; 202 | case BadgeStyle.Alert: 203 | return "mp_alerttriangle"; 204 | case BadgeStyle.Crown: 205 | return "mp_hostcrown"; 206 | case BadgeStyle.Ammo: 207 | return selected ? "shop_ammo_icon_b" : "shop_ammo_icon_a"; 208 | case BadgeStyle.Armour: 209 | return selected ? "shop_armour_icon_b" : "shop_armour_icon_a"; 210 | case BadgeStyle.Barber: 211 | return selected ? "shop_barber_icon_b" : "shop_barber_icon_a"; 212 | case BadgeStyle.Clothes: 213 | return selected ? "shop_clothing_icon_b" : "shop_clothing_icon_a"; 214 | case BadgeStyle.Franklin: 215 | return selected ? "shop_franklin_icon_b" : "shop_franklin_icon_a"; 216 | case BadgeStyle.Bike: 217 | return selected ? "shop_garage_bike_icon_b" : "shop_garage_bike_icon_a"; 218 | case BadgeStyle.Car: 219 | return selected ? "shop_garage_icon_b" : "shop_garage_icon_a"; 220 | case BadgeStyle.Gun: 221 | return selected ? "shop_gunclub_icon_b" : "shop_gunclub_icon_a"; 222 | case BadgeStyle.Heart: 223 | return selected ? "shop_health_icon_b" : "shop_health_icon_a"; 224 | case BadgeStyle.Lock: 225 | return "shop_lock"; 226 | case BadgeStyle.Makeup: 227 | return selected ? "shop_makeup_icon_b" : "shop_makeup_icon_a"; 228 | case BadgeStyle.Mask: 229 | return selected ? "shop_mask_icon_b" : "shop_mask_icon_a"; 230 | case BadgeStyle.Michael: 231 | return selected ? "shop_michael_icon_b" : "shop_michael_icon_a"; 232 | case BadgeStyle.Star: 233 | return "shop_new_star"; 234 | case BadgeStyle.Tattoo: 235 | return selected ? "shop_tattoos_icon_b" : "shop_tattoos_icon_a"; 236 | case BadgeStyle.Tick: 237 | return "shop_tick_icon"; 238 | case BadgeStyle.Trevor: 239 | return selected ? "shop_trevor_icon_b" : "shop_trevor_icon_a"; 240 | case BadgeStyle.Sale: 241 | return "saleicon"; 242 | case BadgeStyle.ArrowLeft: 243 | return "arrowleft"; 244 | case BadgeStyle.ArrowRight: 245 | return "arrowright"; 246 | case BadgeStyle.Audio1: 247 | return "leaderboard_audio_1"; 248 | case BadgeStyle.Audio2: 249 | return "leaderboard_audio_2"; 250 | case BadgeStyle.Audio3: 251 | return "leaderboard_audio_3"; 252 | case BadgeStyle.AudioInactive: 253 | return "leaderboard_audio_inactive"; 254 | case BadgeStyle.AudioMute: 255 | return "leaderboard_audio_mute"; 256 | default: 257 | return ""; 258 | } 259 | } 260 | 261 | public IsBagdeWhiteSprite(badge: BadgeStyle) { 262 | switch (badge) { 263 | case BadgeStyle.Lock: 264 | case BadgeStyle.Tick: 265 | case BadgeStyle.Crown: 266 | return true; 267 | default: 268 | return false; 269 | } 270 | } 271 | 272 | public BadgeToColor(badge: BadgeStyle, selected: boolean): Color { 273 | switch (badge) { 274 | case BadgeStyle.Lock: 275 | case BadgeStyle.Tick: 276 | case BadgeStyle.Crown: 277 | return selected 278 | ? new Color(255, 0, 0, 0) 279 | : new Color(255, 255, 255, 255); 280 | default: 281 | return new Color(255, 255, 255, 255); 282 | } 283 | } 284 | } --------------------------------------------------------------------------------