1203 lines
		
	
	
	
		
			43 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			1203 lines
		
	
	
	
		
			43 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| UIMenu = setmetatable({}, UIMenu)
 | |
| UIMenu.__index = UIMenu
 | |
| UIMenu.__call = function() return "UIMenu" end
 | |
| 
 | |
| function UIMenu.New(Title, Subtitle, X, Y, TxtDictionary, TxtName)
 | |
| 	local X, Y = tonumber(X) or 0, tonumber(Y) or 0
 | |
| 	if Title ~= nil then Title = tostring(Title) or "" else Title = "" end
 | |
| 	if Subtitle ~= nil then Subtitle = tostring(Subtitle) or "" else Subtitle = "" end
 | |
| 	if TxtDictionary ~= nil then TxtDictionary = tostring(TxtDictionary) or "commonmenu" else TxtDictionary = "commonmenu" end
 | |
| 	if TxtName ~= nil then TxtName = tostring(TxtName) or "interaction_bgd" else TxtName = "interaction_bgd" end
 | |
| 	local _UIMenu = {
 | |
| 		Logo = Sprite.New(TxtDictionary, TxtName, 0 + X, 0 + Y, 431, 107),
 | |
| 		Banner = nil,
 | |
| 		Title = UIResText.New(Title, 215 + X, 20 + Y, 1.15, 255, 255, 255, 255, 1, 1),
 | |
| 		Subtitle = {ExtraY = 0},
 | |
| 		WidthOffset = 0,
 | |
| 		Position = {X = X, Y = Y},
 | |
| 		Pagination = {Min = 0, Max = 9, Total = 9},
 | |
| 		PageCounter = {PreText = ""},
 | |
| 		Extra = {},
 | |
| 		Description = {},
 | |
| 		Items = {},
 | |
| 		Windows = {},
 | |
| 		Children = {},
 | |
| 		Controls = {
 | |
| 			Back = {
 | |
| 				Enabled = true,
 | |
| 			},
 | |
| 			Select = {
 | |
| 				Enabled = true,
 | |
| 			},
 | |
| 			Left = {
 | |
| 				Enabled = true,
 | |
| 			},
 | |
| 			Right = {
 | |
| 				Enabled = true,
 | |
| 			},
 | |
| 			Up = {
 | |
| 				Enabled = true,
 | |
| 			},
 | |
| 			Down = {
 | |
| 				Enabled = true,
 | |
| 			},
 | |
| 		},
 | |
| 		ParentMenu = nil,
 | |
| 		ParentItem = nil,
 | |
| 		_Visible = false,
 | |
| 		ActiveItem = 1000,
 | |
| 		Dirty = false;
 | |
| 		ReDraw = true,
 | |
| 		InstructionalScaleform = RequestScaleformMovie("INSTRUCTIONAL_BUTTONS"),
 | |
| 		InstructionalButtons = {},
 | |
| 		OnIndexChange = function(menu, newindex) end,
 | |
| 		OnListChange = function(menu, list, newindex) end,
 | |
| 		OnSliderChange = function(menu, slider, newindex) end,
 | |
| 		OnProgressChange = function(menu, progress, newindex) end,
 | |
| 		OnCheckboxChange = function(menu, item, checked) end,
 | |
| 		OnListSelect = function(menu, list, index) end,
 | |
| 		OnSliderSelect = function(menu, slider, index) end,
 | |
| 		OnProgressSelect = function(menu, progress, index) end,
 | |
| 		OnItemSelect = function(menu, item, index) end,
 | |
| 		OnMenuChanged = function(menu, newmenu, forward) end,
 | |
| 		OnMenuClosed = function(menu) end,
 | |
| 		Settings = {
 | |
| 			InstructionalButtons = true,
 | |
| 			MultilineFormats = true,
 | |
| 			ScaleWithSafezone = true,
 | |
| 			ResetCursorOnOpen = true,
 | |
| 			MouseControlsEnabled = true,
 | |
| 			MouseEdgeEnabled = true,
 | |
| 			ControlDisablingEnabled = true,
 | |
| 			Audio = {
 | |
| 				Library = "HUD_FRONTEND_DEFAULT_SOUNDSET",
 | |
| 				UpDown = "NAV_UP_DOWN",
 | |
| 				LeftRight = "NAV_LEFT_RIGHT",
 | |
| 				Select = "SELECT",
 | |
| 				Back = "BACK",
 | |
| 				Error = "ERROR",
 | |
| 			},
 | |
|             EnabledControls = {
 | |
|                 Controller = {
 | |
|                     {0, 2}, -- Look Up and Down
 | |
|                     {0, 1}, -- Look Left and Right
 | |
|                     {0, 25}, -- Aim
 | |
|                     {0, 24}, -- Attack
 | |
|                 },
 | |
|                 Keyboard = {
 | |
|                     {0, 201}, -- Select
 | |
|                     {0, 195}, -- X axis
 | |
|                     {0, 196}, -- Y axis
 | |
|                     {0, 187}, -- Down
 | |
|                     {0, 188}, -- Up
 | |
|                     {0, 189}, -- Left
 | |
|                     {0, 190}, -- Right
 | |
|                     {0, 202}, -- Back
 | |
|                     {0, 217}, -- Select
 | |
|                     {0, 242}, -- Scroll down
 | |
|                     {0, 241}, -- Scroll up
 | |
|                     {0, 239}, -- Cursor X
 | |
|                     {0, 240}, -- Cursor Y
 | |
|                     {0, 31}, -- Move Up and Down
 | |
|                     {0, 30}, -- Move Left and Right
 | |
|                     {0, 21}, -- Sprint
 | |
|                     {0, 22}, -- Jump
 | |
|                     {0, 23}, -- Enter
 | |
|                     {0, 75}, -- Exit Vehicle
 | |
|                     {0, 71}, -- Accelerate Vehicle
 | |
|                     {0, 72}, -- Vehicle Brake
 | |
|                     {0, 59}, -- Move Vehicle Left and Right
 | |
|                     {0, 89}, -- Fly Yaw Left
 | |
|                     {0, 9}, -- Fly Left and Right
 | |
|                     {0, 8}, -- Fly Up and Down
 | |
|                     {0, 90}, -- Fly Yaw Right
 | |
|                     {0, 76}, -- Vehicle Handbrake
 | |
|                 },
 | |
|             },
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if Subtitle ~= "" and Subtitle ~= nil then
 | |
| 		_UIMenu.Subtitle.Rectangle = UIResRectangle.New(0 + _UIMenu.Position.X, 107 + _UIMenu.Position.Y, 431, 37, 0, 0, 0, 255)
 | |
| 		_UIMenu.Subtitle.Text = UIResText.New(Subtitle, 8 + _UIMenu.Position.X, 110 + _UIMenu.Position.Y, 0.35, 245, 245, 245, 255, 0)
 | |
| 		_UIMenu.Subtitle.BackupText = Subtitle
 | |
| 		_UIMenu.Subtitle.Formatted = false
 | |
| 		if string.starts(Subtitle, "~") then
 | |
| 			_UIMenu.PageCounter.PreText = string.sub(Subtitle, 1, 3)
 | |
| 		end
 | |
| 		_UIMenu.PageCounter.Text = UIResText.New("", 425 + _UIMenu.Position.X, 110 + _UIMenu.Position.Y, 0.35, 245, 245, 245, 255, 0, "Right")
 | |
| 		_UIMenu.Subtitle.ExtraY = 37
 | |
| 	end
 | |
| 	
 | |
| 	_UIMenu.ArrowSprite = Sprite.New("commonmenu", "shop_arrows_upanddown", 190 + _UIMenu.Position.X, 147 + 37 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 50, 50)
 | |
| 	_UIMenu.Extra.Up = UIResRectangle.New(0 + _UIMenu.Position.X, 144 + 38 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 431, 18, 0, 0, 0, 200)
 | |
| 	_UIMenu.Extra.Down = UIResRectangle.New(0 + _UIMenu.Position.X, 144 + 18 + 38 * (_UIMenu.Pagination.Total + 1) + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 431, 18, 0, 0, 0, 200)
 | |
| 
 | |
| 	_UIMenu.Description.Bar = UIResRectangle.New(_UIMenu.Position.X, 123, 431, 4, 0, 0, 0, 255)
 | |
| 	_UIMenu.Description.Rectangle = Sprite.New("commonmenu", "gradient_bgd", _UIMenu.Position.X, 127, 431, 30)
 | |
| 	_UIMenu.Description.Text = UIResText.New("Description", _UIMenu.Position.X + 5, 125, 0.35)
 | |
| 
 | |
| 	_UIMenu.Background = Sprite.New("commonmenu", "gradient_bgd", _UIMenu.Position.X, 144 + _UIMenu.Position.Y - 37 + _UIMenu.Subtitle.ExtraY, 290, 25)
 | |
| 
 | |
| 	Citizen.CreateThread(function()
 | |
| 		if not HasScaleformMovieLoaded(_UIMenu.InstructionalScaleform) then
 | |
| 			_UIMenu.InstructionalScaleform = RequestScaleformMovie("INSTRUCTIONAL_BUTTONS")
 | |
| 			while not HasScaleformMovieLoaded(_UIMenu.InstructionalScaleform) do
 | |
| 				Citizen.Wait(0)
 | |
| 			end
 | |
| 		end
 | |
| 	end)
 | |
| 	return setmetatable(_UIMenu, UIMenu)
 | |
| end
 | |
| 
 | |
| function UIMenu:SetMenuWidthOffset(Offset)
 | |
|     if tonumber(Offset) then
 | |
|         self.WidthOffset = math.floor(tonumber(Offset))
 | |
|         self.Logo:Size(431 + self.WidthOffset, 107)
 | |
|         self.Title:Position(((self.WidthOffset + 431)/2) + self.Position.X, 20 + self.Position.Y)
 | |
|         if self.Subtitle.Rectangle ~= nil then
 | |
|             self.Subtitle.Rectangle:Size(431 + self.WidthOffset + 100, 37)            
 | |
|             self.PageCounter.Text:Position(425 + self.Position.X + self.WidthOffset, 110 + self.Position.Y)
 | |
|         end
 | |
|         if self.Banner ~= nil then
 | |
|             self.Banner:Size(431 + self.WidthOffset, 107)
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| function UIMenu:DisEnableControls(bool)
 | |
| 	if bool then
 | |
| 		EnableAllControlActions(2)
 | |
| 	else
 | |
| 		DisableAllControlActions(2)
 | |
| 	end
 | |
| 
 | |
| 	if bool then
 | |
| 		return
 | |
| 	else
 | |
|         if Controller() then
 | |
|             for Index = 1, #self.Settings.EnabledControls.Controller do
 | |
|                 EnableControlAction(self.Settings.EnabledControls.Controller[Index][1], self.Settings.EnabledControls.Controller[Index][2], true)
 | |
|             end
 | |
|         else
 | |
|             for Index = 1, #self.Settings.EnabledControls.Keyboard do
 | |
|                 EnableControlAction(self.Settings.EnabledControls.Keyboard[Index][1], self.Settings.EnabledControls.Keyboard[Index][2], true)
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| function UIMenu:InstructionalButtons(bool)
 | |
| 	if bool ~= nil then
 | |
| 		self.Settings.InstrucitonalButtons = tobool(bool)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:SetBannerSprite(Sprite, IncludeChildren)
 | |
|     if Sprite() == "Sprite" then
 | |
|         self.Logo = Sprite
 | |
|         self.Logo:Size(431 + self.WidthOffset, 107)
 | |
|         self.Logo:Position(self.Position.X, self.Position.Y)
 | |
|         self.Banner = nil
 | |
|         if IncludeChildren then
 | |
|             for Item, Menu in pairs(self.Children) do
 | |
|                 Menu.Logo = Sprite
 | |
|                 Menu.Logo:Size(431 + self.WidthOffset, 107)
 | |
|                 Menu.Logo:Position(self.Position.X, self.Position.Y)
 | |
|                 Menu.Banner = nil
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| function UIMenu:SetBannerRectangle(Rectangle, IncludeChildren)
 | |
|     if Rectangle() == "Rectangle" then
 | |
|         self.Banner = Rectangle
 | |
|         self.Banner:Size(431 + self.WidthOffset, 107)
 | |
|         self.Banner:Position(self.Position.X, self.Position.Y)
 | |
|         self.Logo = nil
 | |
|         if IncludeChildren then
 | |
|             for Item, Menu in pairs(self.Children) do
 | |
|                 Menu.Banner = Rectangle
 | |
|                 Menu.Banner:Size(431 + self.WidthOffset, 107)
 | |
|                 Menu:Position(self.Position.X, self.Position.Y)
 | |
|                 Menu.Logo = nil
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| function UIMenu:CurrentSelection(value)
 | |
| 	if tonumber(value) then
 | |
| 		if #self.Items == 0 then
 | |
| 			self.ActiveItem = 0
 | |
| 		end
 | |
| 
 | |
| 		self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 		self.ActiveItem = 1000000 - (1000000 % #self.Items) + tonumber(value)
 | |
| 
 | |
| 		if self:CurrentSelection() > self.Pagination.Max then
 | |
| 			self.Pagination.Min = self:CurrentSelection() - self.Pagination.Total
 | |
| 			self.Pagination.Max = self:CurrentSelection()
 | |
| 		elseif self:CurrentSelection() < self.Pagination.Min then
 | |
| 			self.Pagination.Min = self:CurrentSelection()
 | |
| 			self.Pagination.Max = self:CurrentSelection() + self.Pagination.Total
 | |
| 		end 
 | |
| 	else
 | |
| 		if #self.Items == 0 then
 | |
| 			return 1
 | |
| 		else
 | |
| 			if self.ActiveItem % #self.Items == 0 then
 | |
| 				return 1
 | |
| 			else
 | |
| 				return self.ActiveItem % #self.Items + 1
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:CalculateWindowHeight()
 | |
| 	local Height = 0
 | |
| 	for i = 1, #self.Windows do
 | |
| 		Height = Height + self.Windows[i].Background:Size().Height
 | |
| 	end
 | |
| 	return Height
 | |
| end
 | |
| 
 | |
| function UIMenu:CalculateItemHeightOffset(Item)
 | |
| 	if Item.Base then
 | |
| 		return Item.Base.Rectangle.Height
 | |
| 	else
 | |
| 		return Item.Rectangle.Height
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:CalculateItemHeight()
 | |
| 	local ItemOffset = 0 + self.Subtitle.ExtraY - 37
 | |
| 	for i = self.Pagination.Min + 1, self.Pagination.Max do
 | |
| 		local Item = self.Items[i]
 | |
| 		if Item ~= nil then
 | |
| 			ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
 | |
| 		end
 | |
| 	end
 | |
| 	return ItemOffset
 | |
| end
 | |
| 
 | |
| function UIMenu:RecalculateDescriptionPosition()
 | |
| 	local WindowHeight = self:CalculateWindowHeight()
 | |
|     self.Description.Bar:Position(self.Position.X, 149 + self.Position.Y + WindowHeight)
 | |
|     self.Description.Rectangle:Position(self.Position.X, 149 + self.Position.Y + WindowHeight)
 | |
|     self.Description.Text:Position(self.Position.X + 8, 155 + self.Position.Y + WindowHeight)
 | |
| 
 | |
| 	self.Description.Bar:Size(431 + self.WidthOffset, 4)
 | |
| 	self.Description.Rectangle:Size(431 + self.WidthOffset, 30)
 | |
| 
 | |
| 	self.Description.Bar:Position(self.Position.X, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Bar:Position().Y)
 | |
| 	self.Description.Rectangle:Position(self.Position.X, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Rectangle:Position().Y)
 | |
| 	self.Description.Text:Position(self.Position.X + 8, self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + self.Description.Text:Position().Y)
 | |
| end
 | |
| 
 | |
| function UIMenu:CaclulatePanelPosition(HasDescription)
 | |
| 	local Height = self:CalculateWindowHeight() + 149 + self.Position.Y
 | |
| 
 | |
| 	if HasDescription then
 | |
| 		Height = Height + self.Description.Rectangle:Size().Height + 5
 | |
| 	end
 | |
| 
 | |
| 	return self:CalculateItemHeight() + ((#self.Items > (self.Pagination.Total + 1)) and 37 or 0) + Height
 | |
| end
 | |
| 
 | |
| function UIMenu:AddWindow(Window)
 | |
| 	if Window() == "UIMenuWindow" then
 | |
| 		Window:SetParentMenu(self)
 | |
| 		Window:Offset(self.Position.X, self.Position.Y)
 | |
| 		table.insert(self.Windows, Window)
 | |
| 		self.ReDraw = true
 | |
| 		self:RecalculateDescriptionPosition()
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:RemoveWindowAt(Index)
 | |
| 	if tonumber(Index) then
 | |
| 		if self.Windows[Index] then
 | |
| 			table.remove(self.Windows, Index)
 | |
| 			self.ReDraw = true
 | |
| 			self:RecalculateDescriptionPosition()
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:AddItem(Item)
 | |
| 	if Item() == "UIMenuItem" then
 | |
| 		local SelectedItem = self:CurrentSelection()
 | |
| 		Item:SetParentMenu(self)
 | |
| 		Item:Offset(self.Position.X, self.Position.Y)
 | |
| 		Item:Position((#self.Items * 25) - 37 + self.Subtitle.ExtraY)
 | |
| 		table.insert(self.Items, Item)
 | |
| 		self:RecalculateDescriptionPosition()
 | |
| 		self:CurrentSelection(SelectedItem)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:RemoveItemAt(Index)
 | |
| 	if tonumber(Index) then
 | |
| 		if self.Items[Index] then
 | |
| 			local SelectedItem = self:CurrentSelection()
 | |
| 			if #self.Items > self.Pagination.Total and self.Pagination.Max == #self.Items - 1 then
 | |
| 				self.Pagination.Min = self.Pagination.Min - 1
 | |
| 				self.Pagination.Max = self.Pagination.Max + 1
 | |
| 			end
 | |
| 			table.remove(self.Items, tonumber(Index))
 | |
| 			self:RecalculateDescriptionPosition()
 | |
| 			self:CurrentSelection(SelectedItem)
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:RefreshIndex()
 | |
| 	if #self.Items == 0 then
 | |
| 		self.ActiveItem = 1000
 | |
| 		self.Pagination.Max = self.Pagination.Total + 1
 | |
| 		self.Pagination.Min = 0
 | |
| 		return
 | |
| 	end
 | |
| 	self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 	self.ActiveItem = 1000 - (1000 % #self.Items)
 | |
| 	self.Pagination.Max = self.Pagination.Total + 1
 | |
| 	self.Pagination.Min = 0
 | |
| 	self.ReDraw = true
 | |
| end
 | |
| 
 | |
| function UIMenu:Clear()
 | |
| 	self.Items = {}
 | |
|     self.ReDraw = true
 | |
| 	self:RecalculateDescriptionPosition()
 | |
| end
 | |
| 
 | |
| function UIMenu:MultilineFormat(str)
 | |
| 	if tostring(str) then
 | |
| 
 | |
| 		local PixelPerLine = 425 + self.WidthOffset
 | |
| 		local AggregatePixels = 0
 | |
| 		local output = ""
 | |
| 		local words = string.split(tostring(str), " ")
 | |
| 
 | |
| 		for i = 1, #words do
 | |
| 			local offset = MeasureStringWidth(words[i], 0, 0.35)
 | |
| 			AggregatePixels = AggregatePixels + offset
 | |
| 			if AggregatePixels > PixelPerLine then
 | |
| 				output = output .. "\n" .. words[i] .. " "
 | |
| 				AggregatePixels = offset + MeasureString(" ")
 | |
| 			else
 | |
| 				output = output .. words[i] .. " "
 | |
| 				AggregatePixels = AggregatePixels + MeasureString(" ")
 | |
| 			end
 | |
| 		end
 | |
| 		return output
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:DrawCalculations()
 | |
| 	local WindowHeight = self:CalculateWindowHeight()
 | |
| 
 | |
| 	if self.Settings.MultilineFormats then
 | |
| 		if self.Subtitle.Rectangle and not self.Subtitle.Formatted then
 | |
| 			self.Subtitle.Formatted = true
 | |
| 			self.Subtitle.Text:Text(self:MultilineFormat(self.Subtitle.Text:Text()))
 | |
| 
 | |
| 			local Linecount = #string.split(self.Subtitle.Text:Text(), "\n")
 | |
| 			self.Subtitle.ExtraY = ((Linecount == 1) and 37 or ((Linecount + 1) * 22))
 | |
| 			self.Subtitle.Rectangle:Size(431 + self.WidthOffset, self.Subtitle.ExtraY)
 | |
| 		end
 | |
| 	elseif self.Subtitle.Formatted then
 | |
| 		self.Subtitle.Formatted = false
 | |
| 		self.Subtitle.ExtraY = 37
 | |
| 		self.Subtitle.Rectangle:Size(431 + self.WidthOffset, self.Subtitle.ExtraY)
 | |
| 		self.Subtitle.Text:Text(self.Subtitle.BackupText)
 | |
| 	end
 | |
| 
 | |
|     self.Background:Size(431 + self.WidthOffset, self:CalculateItemHeight() + WindowHeight + ((self.Subtitle.ExtraY > 0) and 0 or 37))
 | |
| 
 | |
| 	self.Extra.Up:Size(431 + self.WidthOffset, 18)
 | |
| 	self.Extra.Down:Size(431 + self.WidthOffset, 18)
 | |
| 
 | |
|     self.Extra.Up:Position(self.Position.X, 144 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
 | |
|     self.Extra.Down:Position(self.Position.X, 144 + 18 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
 | |
| 
 | |
|     if self.WidthOffset > 0 then
 | |
|         self.ArrowSprite:Position(190 + self.Position.X + (self.WidthOffset / 2), 137 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
 | |
|     else
 | |
|         self.ArrowSprite:Position(190 + self.Position.X + self.WidthOffset, 137 + self:CalculateItemHeight() + self.Position.Y + WindowHeight)
 | |
|     end
 | |
| 
 | |
| 	self.ReDraw = false
 | |
| 
 | |
| 	if #self.Items ~= 0 and self.Items[self:CurrentSelection()]:Description() ~= "" then
 | |
| 		self:RecalculateDescriptionPosition()
 | |
| 
 | |
| 		local description = self.Items[self:CurrentSelection()]:Description()
 | |
| 		if self.Settings.MultilineFormats then
 | |
| 			self.Description.Text:Text(self:MultilineFormat(description))
 | |
| 		else
 | |
| 			self.Description.Text:Text(description)
 | |
| 		end
 | |
| 
 | |
| 		local Linecount = #string.split(self.Description.Text:Text(), "\n")
 | |
| 		self.Description.Rectangle:Size(431 + self.WidthOffset, ((Linecount == 1) and 37 or ((Linecount + 1) * 22)))
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:Visible(bool)
 | |
| 	if bool ~= nil then
 | |
| 		self._Visible = tobool(bool)
 | |
| 		self.JustOpened = tobool(bool)
 | |
| 		self.Dirty = tobool(bool)
 | |
| 		self:UpdateScaleform()
 | |
| 		if self.ParentMenu ~= nil or tobool(bool) == false then
 | |
| 			return
 | |
| 		end
 | |
| 		if self.Settings.ResetCursorOnOpen then
 | |
| 			local W, H = GetScreenResolution()
 | |
| 			SetCursorLocation(W / 2, H / 2)
 | |
| 			SetCursorSprite(1)
 | |
| 		end
 | |
| 	else
 | |
| 		return self._Visible
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:ProcessControl()
 | |
| 	if not self._Visible then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if self.JustOpened then
 | |
| 		self.JustOpened = false
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if self.Controls.Back.Enabled and (IsDisabledControlJustReleased(0, 177) or IsDisabledControlJustReleased(1, 177) or IsDisabledControlJustReleased(2, 177) or IsDisabledControlJustReleased(0, 199) or IsDisabledControlJustReleased(1, 199) or IsDisabledControlJustReleased(2, 199)) then
 | |
| 		self:GoBack()
 | |
| 	end
 | |
| 	
 | |
| 	if #self.Items == 0 then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if not self.UpPressed then
 | |
| 		if self.Controls.Up.Enabled and (IsDisabledControlJustPressed(0, 172) or IsDisabledControlJustPressed(1, 172) or IsDisabledControlJustPressed(2, 172) or IsDisabledControlJustPressed(0, 241) or IsDisabledControlJustPressed(1, 241) or IsDisabledControlJustPressed(2, 241) or IsDisabledControlJustPressed(2, 241)) then
 | |
| 			Citizen.CreateThread(function()
 | |
| 				self.UpPressed = true
 | |
| 				if #self.Items > self.Pagination.Total + 1 then
 | |
| 					self:GoUpOverflow()
 | |
| 				else
 | |
| 					self:GoUp()
 | |
| 				end
 | |
| 				self:UpdateScaleform()
 | |
| 				Citizen.Wait(175)
 | |
| 				while self.Controls.Up.Enabled and (IsDisabledControlPressed(0, 172) or IsDisabledControlPressed(1, 172) or IsDisabledControlPressed(2, 172) or IsDisabledControlPressed(0, 241) or IsDisabledControlPressed(1, 241) or IsDisabledControlPressed(2, 241) or IsDisabledControlPressed(2, 241)) do
 | |
| 					if #self.Items > self.Pagination.Total + 1 then
 | |
| 						self:GoUpOverflow()
 | |
| 					else
 | |
| 						self:GoUp()
 | |
| 					end
 | |
| 					self:UpdateScaleform()
 | |
| 					Citizen.Wait(125)
 | |
| 				end
 | |
| 				self.UpPressed = false
 | |
| 			end)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if not self.DownPressed then
 | |
| 		if self.Controls.Down.Enabled and (IsDisabledControlJustPressed(0, 173) or IsDisabledControlJustPressed(1, 173) or IsDisabledControlJustPressed(2, 173) or IsDisabledControlJustPressed(0, 242) or IsDisabledControlJustPressed(1, 242) or IsDisabledControlJustPressed(2, 242)) then
 | |
| 			Citizen.CreateThread(function()
 | |
| 				self.DownPressed = true
 | |
| 				if #self.Items > self.Pagination.Total + 1 then
 | |
| 					self:GoDownOverflow()
 | |
| 				else
 | |
| 					self:GoDown()
 | |
| 				end
 | |
| 				self:UpdateScaleform()
 | |
| 				Citizen.Wait(175)
 | |
| 				while self.Controls.Down.Enabled and (IsDisabledControlPressed(0, 173) or IsDisabledControlPressed(1, 173) or IsDisabledControlPressed(2, 173) or IsDisabledControlPressed(0, 242) or IsDisabledControlPressed(1, 242) or IsDisabledControlPressed(2, 242)) do
 | |
| 					if #self.Items > self.Pagination.Total + 1 then
 | |
| 						self:GoDownOverflow()
 | |
| 					else
 | |
| 						self:GoDown()
 | |
| 					end
 | |
| 					self:UpdateScaleform()
 | |
| 					Citizen.Wait(125)
 | |
| 				end
 | |
| 				self.DownPressed = false
 | |
| 			end)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if not self.LeftPressed then
 | |
| 		if self.Controls.Left.Enabled and (IsDisabledControlPressed(0, 174) or IsDisabledControlPressed(1, 174) or IsDisabledControlPressed(2, 174)) then
 | |
| 			Citizen.CreateThread(function()
 | |
| 				self.LeftPressed = true
 | |
| 				self:GoLeft()
 | |
| 				Citizen.Wait(175)
 | |
| 				while self.Controls.Left.Enabled and (IsDisabledControlPressed(0, 174) or IsDisabledControlPressed(1, 174) or IsDisabledControlPressed(2, 174)) do
 | |
| 					self:GoLeft()
 | |
| 					Citizen.Wait(125)
 | |
| 				end
 | |
| 				self.LeftPressed = false
 | |
| 			end)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if not self.RightPressed then
 | |
| 		if self.Controls.Right.Enabled and (IsDisabledControlPressed(0, 175) or IsDisabledControlPressed(1, 175) or IsDisabledControlPressed(2, 175)) then
 | |
| 			Citizen.CreateThread(function()
 | |
| 				self.RightPressed = true
 | |
| 				self:GoRight()
 | |
| 				Citizen.Wait(175)
 | |
| 				while self.Controls.Right.Enabled and (IsDisabledControlPressed(0, 175) or IsDisabledControlPressed(1, 175) or IsDisabledControlPressed(2, 175)) do
 | |
| 					self:GoRight()
 | |
| 					Citizen.Wait(125)
 | |
| 				end
 | |
| 				self.RightPressed = false
 | |
| 			end)
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if self.Controls.Select.Enabled and (IsDisabledControlJustPressed(0, 201) or IsDisabledControlJustPressed(1, 201) or IsDisabledControlJustPressed(2, 201)) then
 | |
| 		self:SelectItem()
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:GoUpOverflow()
 | |
| 	if #self.Items <= self.Pagination.Total + 1 then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if self:CurrentSelection() <= self.Pagination.Min + 1 then
 | |
| 		if self:CurrentSelection() == 1 then
 | |
| 			self.Pagination.Min = #self.Items - (self.Pagination.Total + 1)
 | |
| 			self.Pagination.Max = #self.Items
 | |
| 			self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 			self.ActiveItem = 1000 - (1000 % #self.Items)
 | |
| 			self.ActiveItem = self.ActiveItem + (#self.Items - 1)
 | |
| 			self.Items[self:CurrentSelection()]:Selected(true)
 | |
| 		else
 | |
| 			self.Pagination.Min = self.Pagination.Min - 1
 | |
| 			self.Pagination.Max = self.Pagination.Max - 1
 | |
| 			self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 			self.ActiveItem = self.ActiveItem - 1
 | |
| 			self.Items[self:CurrentSelection()]:Selected(true)
 | |
| 		end
 | |
| 	else
 | |
| 		self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 		self.ActiveItem = self.ActiveItem - 1
 | |
| 		self.Items[self:CurrentSelection()]:Selected(true)
 | |
| 	end
 | |
| 	PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
 | |
| 	self.OnIndexChange(self, self:CurrentSelection())
 | |
| 	self.ReDraw = true
 | |
| end
 | |
| 
 | |
| function UIMenu:GoUp()
 | |
| 	if #self.Items > self.Pagination.Total + 1 then
 | |
| 		return
 | |
| 	end
 | |
| 	self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 	self.ActiveItem = self.ActiveItem - 1
 | |
| 	self.Items[self:CurrentSelection()]:Selected(true)
 | |
| 	PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
 | |
| 	self.OnIndexChange(self, self:CurrentSelection())
 | |
| 	self.ReDraw = true
 | |
| end
 | |
| 
 | |
| function UIMenu:GoDownOverflow()
 | |
| 	if #self.Items <= self.Pagination.Total + 1 then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if self:CurrentSelection() >= self.Pagination.Max then
 | |
| 		if self:CurrentSelection() == #self.Items then
 | |
| 			self.Pagination.Min = 0
 | |
| 			self.Pagination.Max = self.Pagination.Total + 1
 | |
| 			self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 			self.ActiveItem = 1000 - (1000 % #self.Items)
 | |
| 			self.Items[self:CurrentSelection()]:Selected(true)
 | |
| 		else
 | |
| 			self.Pagination.Max = self.Pagination.Max + 1
 | |
| 			self.Pagination.Min = self.Pagination.Max - (self.Pagination.Total + 1)
 | |
| 			self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 			self.ActiveItem = self.ActiveItem + 1
 | |
| 			self.Items[self:CurrentSelection()]:Selected(true)            
 | |
| 		end
 | |
| 	else
 | |
| 		self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 		self.ActiveItem = self.ActiveItem + 1
 | |
| 		self.Items[self:CurrentSelection()]:Selected(true)
 | |
| 	end
 | |
| 	PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
 | |
| 	self.OnIndexChange(self, self:CurrentSelection())
 | |
| 	self.ReDraw = true
 | |
| end
 | |
| 
 | |
| function UIMenu:GoDown()
 | |
| 	if #self.Items > self.Pagination.Total + 1 then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	self.Items[self:CurrentSelection()]:Selected(false)
 | |
| 	self.ActiveItem = self.ActiveItem + 1
 | |
| 	self.Items[self:CurrentSelection()]:Selected(true) 
 | |
| 	PlaySoundFrontend(-1, self.Settings.Audio.UpDown, self.Settings.Audio.Library, true)
 | |
| 	self.OnIndexChange(self, self:CurrentSelection())
 | |
| 	self.ReDraw = true
 | |
| end
 | |
| 
 | |
| function UIMenu:GoLeft()
 | |
| 	local type, subtype = self.Items[self:CurrentSelection()]()
 | |
| 	if subtype ~= "UIMenuListItem" and subtype ~= "UIMenuSliderItem" and subtype ~= "UIMenuProgressItem" then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if not self.Items[self:CurrentSelection()]:Enabled() then
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
 | |
| 		return
 | |
| 	end
 | |
| 	
 | |
| 	if subtype == "UIMenuListItem" then
 | |
| 		local Item = self.Items[self:CurrentSelection()]
 | |
| 		Item:Index(Item._Index - 1)
 | |
| 		self.OnListChange(self, Item, Item._Index)
 | |
| 		Item.OnListChanged(self, Item, Item._Index)
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
 | |
| 	elseif subtype == "UIMenuSliderItem" then
 | |
| 		local Item = self.Items[self:CurrentSelection()]
 | |
| 		Item:Index(Item._Index - 1)
 | |
| 		self.OnSliderChange(self, Item, Item:Index())
 | |
| 		Item.OnSliderChanged(self, Item, Item._Index)
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
 | |
| 	elseif subtype == "UIMenuProgressItem" then
 | |
| 		local Item = self.Items[self:CurrentSelection()]
 | |
| 		Item:Index(Item.Data.Index - 1)
 | |
| 		self.OnProgressChange(self, Item, Item.Data.Index)
 | |
| 		Item.OnProgressChanged(self, Item, Item.Data.Index)
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:GoRight()
 | |
| 	local type, subtype = self.Items[self:CurrentSelection()]()
 | |
| 	if subtype ~= "UIMenuListItem" and subtype ~= "UIMenuSliderItem" and subtype ~= "UIMenuProgressItem" then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if not self.Items[self:CurrentSelection()]:Enabled() then
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	if subtype == "UIMenuListItem" then
 | |
| 		local Item = self.Items[self:CurrentSelection()]
 | |
| 		Item:Index(Item._Index + 1)
 | |
| 		self.OnListChange(self, Item, Item._Index)
 | |
| 		Item.OnListChanged(self, Item, Item._Index)
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
 | |
| 	elseif subtype == "UIMenuSliderItem" then
 | |
| 		local Item = self.Items[self:CurrentSelection()]
 | |
| 		Item:Index(Item._Index + 1)
 | |
| 		self.OnSliderChange(self, Item, Item:Index())
 | |
| 		Item.OnSliderChanged(self, Item, Item._Index)
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
 | |
| 	elseif subtype == "UIMenuProgressItem" then
 | |
| 		local Item = self.Items[self:CurrentSelection()]
 | |
| 		Item:Index(Item.Data.Index + 1)
 | |
| 		self.OnProgressChange(self, Item, Item.Data.Index)
 | |
| 		Item.OnProgressChanged(self, Item, Item.Data.Index)
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.LeftRight, self.Settings.Audio.Library, true)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:SelectItem()
 | |
| 	if not self.Items[self:CurrentSelection()]:Enabled() then
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
 | |
| 		return
 | |
| 	end
 | |
| 	local Item = self.Items[self:CurrentSelection()]
 | |
| 	local type, subtype = Item()
 | |
| 	if subtype == "UIMenuCheckboxItem" then
 | |
| 		Item.Checked = not Item.Checked
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
 | |
| 		self.OnCheckboxChange(self, Item, Item.Checked)
 | |
| 		Item.CheckboxEvent(self, Item, Item.Checked)
 | |
| 	elseif subtype == "UIMenuListItem" then
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
 | |
| 		self.OnListSelect(self, Item, Item._Index)
 | |
| 		Item.OnListSelected(self, Item, Item._Index)
 | |
| 	elseif subtype == "UIMenuSliderItem" then
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
 | |
| 		self.OnSliderSelect(self, Item, Item._Index)
 | |
| 		Item.OnSliderSelected(Item._Index)
 | |
| 	elseif subtype == "UIMenuProgressItem" then
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
 | |
| 		self.OnProgressSelect(self, Item, Item.Data.Index)
 | |
| 		Item.OnProgressSelected(Item.Data.Index)		
 | |
| 	else
 | |
| 		PlaySoundFrontend(-1, self.Settings.Audio.Select, self.Settings.Audio.Library, true)
 | |
| 		self.OnItemSelect(self, Item, self:CurrentSelection())
 | |
| 		Item.Activated(self, Item)
 | |
| 		if not self.Children[Item] then
 | |
| 			return
 | |
| 		end
 | |
| 		self:Visible(false)
 | |
| 		self.Children[Item]:Visible(true)
 | |
| 		self.OnMenuChanged(self, self.Children[self.Items[self:CurrentSelection()]], true)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:GoBack()
 | |
| 	PlaySoundFrontend(-1, self.Settings.Audio.Back, self.Settings.Audio.Library, true)
 | |
| 	self:Visible(false)
 | |
| 	if self.ParentMenu ~= nil then
 | |
| 		self.ParentMenu:Visible(true)
 | |
| 		self.OnMenuChanged(self, self.ParentMenu, false)
 | |
| 		if self.Settings.ResetCursorOnOpen then
 | |
| 			local W, H = GetActiveScreenResolution()
 | |
| 			SetCursorLocation(W / 2, H / 2)
 | |
| 		end
 | |
| 	end
 | |
| 	self.OnMenuClosed(self)
 | |
| end
 | |
| 
 | |
| function UIMenu:BindMenuToItem(Menu, Item)
 | |
| 	if Menu() == "UIMenu" and Item() == "UIMenuItem" then
 | |
| 		Menu.ParentMenu = self
 | |
| 		Menu.ParentItem = Item
 | |
| 		self.Children[Item] = Menu
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:ReleaseMenuFromItem(Item)
 | |
| 	if Item() == "UIMenuItem" then
 | |
| 		if not self.Children[Item] then
 | |
| 			return false
 | |
| 		end
 | |
| 		self.Children[Item].ParentMenu = nil
 | |
| 		self.Children[Item].ParentItem = nil
 | |
| 		self.Children[Item] = nil
 | |
| 		return true
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:Draw()
 | |
| 	if not self._Visible then
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	HideHudComponentThisFrame(19)
 | |
| 
 | |
| 	if self.Settings.ControlDisablingEnabled then
 | |
| 		self:DisEnableControls(false)
 | |
| 	end
 | |
| 
 | |
| 	if self.Settings.InstructionalButtons then
 | |
| 		DrawScaleformMovieFullscreen(self.InstructionalScaleform, 255, 255, 255, 255, 0)
 | |
| 	end
 | |
| 
 | |
| 	if self.Settings.ScaleWithSafezone then
 | |
| 		ScreenDrawPositionBegin(76, 84)
 | |
| 		ScreenDrawPositionRatio(0, 0, 0, 0)
 | |
| 	end
 | |
| 
 | |
| 	if self.ReDraw then
 | |
| 		self:DrawCalculations()
 | |
| 	end
 | |
| 
 | |
| 	if self.Logo then
 | |
| 		self.Logo:Draw()
 | |
| 	elseif self.Banner then
 | |
| 		self.Banner:Draw()
 | |
| 	end
 | |
| 
 | |
| 	self.Title:Draw()
 | |
| 
 | |
| 	if self.Subtitle.Rectangle then
 | |
| 		self.Subtitle.Rectangle:Draw()
 | |
| 		self.Subtitle.Text:Draw()
 | |
| 	end
 | |
| 
 | |
| 	if #self.Items ~= 0 or #self.Windows ~= 0 then
 | |
| 		self.Background:Draw()
 | |
| 	end
 | |
| 
 | |
| 	if #self.Windows ~= 0 then
 | |
| 		local WindowOffset = 0
 | |
| 		for index = 1, #self.Windows do
 | |
| 			if self.Windows[index - 1] then 
 | |
| 				WindowOffset = WindowOffset + self.Windows[index - 1].Background:Size().Height 
 | |
| 			end
 | |
| 			local Window = self.Windows[index]
 | |
| 			Window:Position(WindowOffset + self.Subtitle.ExtraY - 37)
 | |
| 			Window:Draw()
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if #self.Items == 0 then
 | |
| 		if self.Settings.ScaleWithSafezone then
 | |
| 			ScreenDrawPositionEnd()
 | |
| 		end
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	local CurrentSelection = self:CurrentSelection()
 | |
| 	self.Items[CurrentSelection]:Selected(true)
 | |
| 
 | |
| 	if self.Items[CurrentSelection]:Description() ~= "" then
 | |
| 		self.Description.Bar:Draw()
 | |
| 		self.Description.Rectangle:Draw()
 | |
| 		self.Description.Text:Draw()
 | |
| 	end
 | |
| 
 | |
| 	if self.Items[CurrentSelection].Panels ~= nil then
 | |
| 		if #self.Items[CurrentSelection].Panels ~= 0 then
 | |
| 			local PanelOffset = self:CaclulatePanelPosition(self.Items[CurrentSelection]:Description() ~= "")
 | |
| 			for index = 1, #self.Items[CurrentSelection].Panels do
 | |
| 				if self.Items[CurrentSelection].Panels[index - 1] then 
 | |
| 					PanelOffset = PanelOffset + self.Items[CurrentSelection].Panels[index - 1].Background:Size().Height + 5
 | |
| 				end
 | |
| 				self.Items[CurrentSelection].Panels[index]:Position(PanelOffset)
 | |
| 				self.Items[CurrentSelection].Panels[index]:Draw()
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	local WindowHeight = self:CalculateWindowHeight()
 | |
| 
 | |
| 	if #self.Items <= self.Pagination.Total + 1 then
 | |
| 		local ItemOffset = self.Subtitle.ExtraY - 37 + WindowHeight
 | |
| 		for index = 1, #self.Items do
 | |
| 			Item = self.Items[index]
 | |
| 			Item:Position(ItemOffset)
 | |
| 			Item:Draw()
 | |
| 			ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
 | |
| 		end
 | |
| 	else
 | |
| 		local ItemOffset = self.Subtitle.ExtraY - 37 + WindowHeight
 | |
| 		for index = self.Pagination.Min + 1, self.Pagination.Max, 1 do
 | |
| 			if self.Items[index] then
 | |
| 				Item = self.Items[index]
 | |
| 				Item:Position(ItemOffset)
 | |
| 				Item:Draw()
 | |
| 				ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 		self.Extra.Up:Draw()
 | |
| 		self.Extra.Down:Draw()
 | |
| 		self.ArrowSprite:Draw()
 | |
| 
 | |
| 		if self.PageCounter.Text ~= nil then
 | |
| 			local Caption = self.PageCounter.PreText .. CurrentSelection .. " / " .. #self.Items
 | |
| 			self.PageCounter.Text:Text(Caption)
 | |
| 			self.PageCounter.Text:Draw()
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	if self.Settings.ScaleWithSafezone then
 | |
| 		ScreenDrawPositionEnd()
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:ProcessMouse()
 | |
| 	if not self._Visible or self.JustOpened or #self.Items == 0 or tobool(Controller()) or not self.Settings.MouseControlsEnabled then
 | |
| 		EnableControlAction(0, 2, true)
 | |
| 		EnableControlAction(0, 1, true)
 | |
| 		EnableControlAction(0, 25, true)
 | |
| 		EnableControlAction(0, 24, true)
 | |
| 		if self.Dirty then
 | |
| 			for _, Item in pairs(self.Items) do
 | |
| 				if Item:Hovered() then
 | |
| 					Item:Hovered(false)
 | |
| 				end
 | |
| 			end
 | |
| 		end
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
|     local SafeZone = {X = 0, Y = 0}
 | |
|     local WindowHeight = self:CalculateWindowHeight()
 | |
|     if self.Settings.ScaleWithSafezone then
 | |
| 	   SafeZone = GetSafeZoneBounds()
 | |
|     end
 | |
| 
 | |
| 	local Limit = #self.Items
 | |
| 	local ItemOffset = 0
 | |
| 
 | |
| 	ShowCursorThisFrame()
 | |
| 
 | |
| 	if #self.Items > self.Pagination.Total + 1 then
 | |
| 		Limit = self.Pagination.Max
 | |
| 	end
 | |
| 
 | |
| 	if IsMouseInBounds(0, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then
 | |
| 		SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() + 5)
 | |
| 		SetCursorSprite(6)
 | |
| 	elseif IsMouseInBounds(1920 - 30, 0, 30, 1080) and self.Settings.MouseEdgeEnabled then
 | |
| 		SetGameplayCamRelativeHeading(GetGameplayCamRelativeHeading() - 5)
 | |
| 		SetCursorSprite(7)	
 | |
| 	elseif self.Settings.MouseEdgeEnabled then
 | |
| 		SetCursorSprite(1)
 | |
| 	end
 | |
| 
 | |
| 	for i = self.Pagination.Min + 1, Limit, 1 do
 | |
| 		local X, Y = self.Position.X + SafeZone.X, self.Position.Y + 144 - 37 + self.Subtitle.ExtraY + ItemOffset + SafeZone.Y + WindowHeight
 | |
| 		local Item = self.Items[i]
 | |
| 		local Type, SubType = Item()
 | |
| 		local Width, Height = 431 + self.WidthOffset, self:CalculateItemHeightOffset(Item)
 | |
| 
 | |
| 		if IsMouseInBounds(X, Y, Width, Height) then
 | |
| 			Item:Hovered(true)
 | |
| 			if not self.Controls.MousePressed then
 | |
| 				if IsDisabledControlJustPressed(0, 24) then
 | |
| 					Citizen.CreateThread(function()
 | |
| 						local _X, _Y, _Width, _Height = X, Y, Width, Height
 | |
| 						self.Controls.MousePressed = true
 | |
| 						if Item:Selected() and Item:Enabled() then
 | |
| 							if SubType == "UIMenuListItem" then
 | |
| 								if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
 | |
| 									self:GoLeft()
 | |
| 								elseif not IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
 | |
| 									self:SelectItem()
 | |
| 								end
 | |
| 								if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
 | |
| 									self:GoRight()
 | |
| 								elseif not IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
 | |
| 									self:SelectItem()
 | |
| 								end
 | |
| 							elseif SubType == "UIMenuSliderItem" then
 | |
| 								if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
 | |
| 									self:GoLeft()
 | |
| 								elseif not IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
 | |
| 									self:SelectItem()
 | |
| 								end
 | |
| 								if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
 | |
| 									self:GoRight()
 | |
| 								elseif not IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
 | |
| 									self:SelectItem()
 | |
| 								end
 | |
| 							elseif SubType == "UIMenuProgressItem" then
 | |
| 								if IsMouseInBounds(Item.Bar.X + SafeZone.X, Item.Bar.Y + SafeZone.Y - 12, Item.Data.Max, Item.Bar.Height + 24) then
 | |
| 									Item:CalculateProgress(math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X)
 | |
|                                     self.OnProgressChange(self, Item, Item.Data.Index)
 | |
|                                     Item.OnProgressChanged(self, Item, Item.Data.Index)
 | |
| 								else
 | |
| 									self:SelectItem()
 | |
| 								end
 | |
| 							else
 | |
| 								self:SelectItem()
 | |
| 							end
 | |
| 						elseif not Item:Selected() then
 | |
| 							self:CurrentSelection(i-1)
 | |
| 							PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
 | |
| 							self.OnIndexChange(self, self:CurrentSelection())
 | |
| 							self.ReDraw = true
 | |
| 							self:UpdateScaleform()
 | |
| 						elseif not Item:Enabled() and Item:Selected() then
 | |
| 							PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
 | |
| 						end
 | |
| 						Citizen.Wait(175)
 | |
| 						while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_X, _Y, _Width, _Height) do
 | |
| 							if Item:Selected() and Item:Enabled() then
 | |
| 								if SubType == "UIMenuListItem" then
 | |
| 									if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
 | |
| 										self:GoLeft()
 | |
| 									end
 | |
| 									if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
 | |
| 										self:GoRight()
 | |
| 									end
 | |
| 								elseif SubType == "UIMenuSliderItem" then
 | |
| 									if IsMouseInBounds(Item.LeftArrow.X + SafeZone.X, Item.LeftArrow.Y + SafeZone.Y, Item.LeftArrow.Width, Item.LeftArrow.Height) then
 | |
| 										self:GoLeft()
 | |
| 									end
 | |
| 									if IsMouseInBounds(Item.RightArrow.X + SafeZone.X, Item.RightArrow.Y + SafeZone.Y, Item.RightArrow.Width, Item.RightArrow.Height) then
 | |
| 										self:GoRight()
 | |
| 									end
 | |
| 								elseif SubType == "UIMenuProgressItem" then
 | |
| 									if IsMouseInBounds(Item.Bar.X + SafeZone.X, Item.Bar.Y + SafeZone.Y - 12, Item.Data.Max, Item.Bar.Height + 24) then
 | |
| 										Item:CalculateProgress(math.round(GetControlNormal(0, 239) * 1920) - SafeZone.X)
 | |
|                                         self.OnProgressChange(self, Item, Item.Data.Index)
 | |
|                                         Item.OnProgressChanged(self, Item, Item.Data.Index)
 | |
| 									else
 | |
| 										self:SelectItem()
 | |
| 									end
 | |
| 								end
 | |
| 							elseif not Item:Selected() then
 | |
| 								self:CurrentSelection(i-1)
 | |
| 								PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
 | |
| 								self.OnIndexChange(self, self:CurrentSelection())
 | |
| 								self.ReDraw = true
 | |
| 								self:UpdateScaleform()
 | |
| 							elseif not Item:Enabled() and Item:Selected() then
 | |
| 								PlaySoundFrontend(-1, self.Settings.Audio.Error, self.Settings.Audio.Library, true)
 | |
| 							end
 | |
| 							Citizen.Wait(125)						
 | |
| 						end
 | |
| 						self.Controls.MousePressed = false
 | |
| 					end)
 | |
| 				end
 | |
| 			end
 | |
| 		else
 | |
| 			Item:Hovered(false)
 | |
| 		end
 | |
| 		ItemOffset = ItemOffset + self:CalculateItemHeightOffset(Item)
 | |
| 	end
 | |
| 
 | |
| 	local ExtraX, ExtraY = self.Position.X + SafeZone.X, 144 + self:CalculateItemHeight() + self.Position.Y + SafeZone.Y + WindowHeight
 | |
| 
 | |
| 	if #self.Items <= self.Pagination.Total + 1 then return end
 | |
| 
 | |
| 	if IsMouseInBounds(ExtraX, ExtraY, 431 + self.WidthOffset, 18) then
 | |
| 		self.Extra.Up:Colour(30, 30, 30, 255)
 | |
| 		if not self.Controls.MousePressed then
 | |
| 			if IsDisabledControlJustPressed(0, 24) then
 | |
| 				Citizen.CreateThread(function()
 | |
| 					local _ExtraX, _ExtraY = ExtraX, ExtraY
 | |
| 					self.Controls.MousePressed = true
 | |
| 					if #self.Items > self.Pagination.Total + 1 then
 | |
| 						self:GoUpOverflow()
 | |
| 					else
 | |
| 						self:GoUp()
 | |
| 					end
 | |
| 					Citizen.Wait(175)
 | |
| 					while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_ExtraX, _ExtraY, 431 + self.WidthOffset, 18) do
 | |
| 						if #self.Items > self.Pagination.Total + 1 then
 | |
| 							self:GoUpOverflow()
 | |
| 						else
 | |
| 							self:GoUp()
 | |
| 						end
 | |
| 						Citizen.Wait(125)
 | |
| 					end
 | |
| 					self.Controls.MousePressed = false				
 | |
| 				end)
 | |
| 			end
 | |
| 		end
 | |
| 	else
 | |
| 		self.Extra.Up:Colour(0, 0, 0, 200)
 | |
| 	end
 | |
| 
 | |
| 	if IsMouseInBounds(ExtraX, ExtraY + 18, 431 + self.WidthOffset, 18) then
 | |
| 		self.Extra.Down:Colour(30, 30, 30, 255)
 | |
| 		if not self.Controls.MousePressed then
 | |
| 			if IsDisabledControlJustPressed(0, 24) then
 | |
| 				Citizen.CreateThread(function()
 | |
| 					local _ExtraX, _ExtraY = ExtraX, ExtraY
 | |
| 					self.Controls.MousePressed = true
 | |
| 					if #self.Items > self.Pagination.Total + 1 then
 | |
| 						self:GoDownOverflow()
 | |
| 					else
 | |
| 						self:GoDown()
 | |
| 					end
 | |
| 					Citizen.Wait(175)
 | |
| 					while IsDisabledControlPressed(0, 24) and IsMouseInBounds(_ExtraX, _ExtraY + 18, 431 + self.WidthOffset, 18) do
 | |
| 						if #self.Items > self.Pagination.Total + 1 then
 | |
| 							self:GoDownOverflow()
 | |
| 						else
 | |
| 							self:GoDown()
 | |
| 						end
 | |
| 						Citizen.Wait(125)
 | |
| 					end
 | |
| 					self.Controls.MousePressed = false				
 | |
| 				end)
 | |
| 			end
 | |
| 		end
 | |
| 	else
 | |
| 		self.Extra.Down:Colour(0, 0, 0, 200)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:AddInstructionButton(button)
 | |
| 	if type(button) == "table" and #button == 2 then
 | |
| 		table.insert(self.InstructionalButtons, button)
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:RemoveInstructionButton(button)
 | |
| 	if type(button) == "table" then
 | |
| 		for i = 1, #self.InstructionalButtons do
 | |
| 			if button == self.InstructionalButtons[i] then
 | |
| 				table.remove(self.InstructionalButtons, i)
 | |
| 				break
 | |
| 			end
 | |
| 		end
 | |
| 	else
 | |
| 		if tonumber(button) then
 | |
| 			if self.InstructionalButtons[tonumber(button)] then
 | |
| 				table.remove(self.InstructionalButtons, tonumber(button))
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| end
 | |
| 
 | |
| function UIMenu:AddEnabledControl(Inputgroup, Control, Controller)
 | |
|     if tonumber(Inputgroup) and tonumber(Control) then
 | |
|         table.insert(self.Settings.EnabledControls[(Controller and "Controller" or "Keyboard")], {Inputgroup, Control})
 | |
|     end
 | |
| end
 | |
| 
 | |
| function UIMenu:RemoveEnabledControl(Inputgroup, Control, Controller)
 | |
|     local Type = (Controller and "Controller" or "Keyboard")
 | |
|     for Index = 1, #self.Settings.EnabledControls[Type] do
 | |
|         if Inputgroup == self.Settings.EnabledControls[Type][Index][1] and Control == self.Settings.EnabledControls[Type][Index][2] then
 | |
|             table.remove(self.Settings.EnabledControls[Type], Index)
 | |
|             break
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| function UIMenu:UpdateScaleform()
 | |
| 	if not self._Visible or not self.Settings.InstructionalButtons then
 | |
| 		return
 | |
| 	end
 | |
| 	
 | |
| 	PushScaleformMovieFunction(self.InstructionalScaleform, "CLEAR_ALL")
 | |
| 	PopScaleformMovieFunction()
 | |
| 
 | |
| 	PushScaleformMovieFunction(self.InstructionalScaleform, "TOGGLE_MOUSE_BUTTONS")
 | |
| 	PushScaleformMovieFunctionParameterInt(0)
 | |
| 	PopScaleformMovieFunction()
 | |
| 
 | |
| 	PushScaleformMovieFunction(self.InstructionalScaleform, "CREATE_CONTAINER")
 | |
| 	PopScaleformMovieFunction()
 | |
| 
 | |
| 	PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT")
 | |
| 	PushScaleformMovieFunctionParameterInt(0)
 | |
| 	PushScaleformMovieFunctionParameterString(GetControlInstructionalButton(2, 176, 0))
 | |
| 	PushScaleformMovieFunctionParameterString("Select")
 | |
| 	PopScaleformMovieFunction()
 | |
| 
 | |
| 	if self.Controls.Back.Enabled then
 | |
| 		PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT")
 | |
| 		PushScaleformMovieFunctionParameterInt(1)
 | |
| 		PushScaleformMovieFunctionParameterString(GetControlInstructionalButton(2, 177, 0))
 | |
| 		PushScaleformMovieFunctionParameterString("Back")
 | |
| 		PopScaleformMovieFunction()
 | |
|     	end
 | |
| 
 | |
| 	local count = 2
 | |
| 
 | |
| 	for i = 1, #self.InstructionalButtons do
 | |
| 		if self.InstructionalButtons[i] then
 | |
| 			if #self.InstructionalButtons[i] == 2 then
 | |
| 				PushScaleformMovieFunction(self.InstructionalScaleform, "SET_DATA_SLOT")
 | |
| 				PushScaleformMovieFunctionParameterInt(count)
 | |
| 				PushScaleformMovieFunctionParameterString(self.InstructionalButtons[i][1])
 | |
| 				PushScaleformMovieFunctionParameterString(self.InstructionalButtons[i][2])
 | |
| 				PopScaleformMovieFunction()
 | |
| 				count = count + 1
 | |
| 			end
 | |
| 		end
 | |
| 	end
 | |
| 
 | |
| 	PushScaleformMovieFunction(self.InstructionalScaleform, "DRAW_INSTRUCTIONAL_BUTTONS")
 | |
| 	PushScaleformMovieFunctionParameterInt(-1)
 | |
| 	PopScaleformMovieFunction()
 | |
| end
 | 
