
KeylessUniversal

local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local GuiService = game:GetService("GuiService")
local BACKGROUND_IMAGE_URL = "https://raw.gatinero.xyz/bggatinero.jpg"
local BACKGROUND_IMAGE_FALLBACK = "rbxassetid://18665679839"
local BACKGROUND_IMAGE_TRANSPARENCY = 0.80
local SIDEBAR_BACKGROUND_IMAGE_URL = "http://raw.gatinero.xyz/sidebar.jpg"
local OVERLAY_TRANSPARENCY = 1
local IconLibraryURL = "https://raw.githubusercontent.com/Footagesus/Icons/main/Main-v2.lua"
local IconLibrary = loadstring(game:HttpGet(IconLibraryURL))()
IconLibrary.SetIconsType("lucide")
local Library = {}
Library.__index = Library
function LoadLucideIcon(iconName, parent, color)
if not iconName or not parent then
warn("LoadLucideIcon: Invalid parameters")
return nil
end
local success, iconData = pcall(function()
return IconLibrary.Icon(iconName, nil, true)
end)
if not success or not iconData then
warn("✗ Failed to load Lucide icon: " .. iconName)
return nil
end
local iconLabel = Instance.new("ImageLabel")
iconLabel.Name = "Icon"
iconLabel.Size = UDim2.new(1, 0, 1, 0)
iconLabel.BackgroundTransparency = 1
iconLabel.Image = iconData[1]
iconLabel.ImageRectSize = iconData[2].ImageRectSize
iconLabel.ImageRectOffset = iconData[2].ImageRectPosition
iconLabel.ImageColor3 = color or Color3.fromRGB(255, 255, 255)
iconLabel.ScaleType = Enum.ScaleType.Fit
iconLabel.Parent = parent
return iconLabel
end
_G.LoadLucideIcon = LoadLucideIcon
_G.IconLibrary = IconLibrary
_G.HideUsernameEnabled = false
local function IsMobileDevice()
local hasTouchNoKeyboard = UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled
local viewportSize = workspace.CurrentCamera.ViewportSize
local isSmallScreen = (viewportSize.X < 1000 and viewportSize.Y < 1000)
local aspectRatio = viewportSize.Y / viewportSize.X
local isMobileAspectRatio = (aspectRatio > 1.5) or (aspectRatio < 0.7 and aspectRatio > 0.4)
local isSmallDisplay = GuiService.ViewportDisplaySize == Enum.DisplaySize.Small
local isTenFoot = GuiService:IsTenFootInterface()
if isTenFoot then
return false
end
if hasTouchNoKeyboard then
return true
end
if UserInputService.TouchEnabled and (isSmallScreen or isMobileAspectRatio or isSmallDisplay) then
return true
end
return false
end
local function GetMobileScale()
if not IsMobileDevice() then
return 1
end
local viewportSize = workspace.CurrentCamera.ViewportSize
local baseWidth = 700
local baseHeight = 450
local scaleX = viewportSize.X / baseWidth
local scaleY = viewportSize.Y / baseHeight
local scale = math.min(scaleX, scaleY)
if viewportSize.Y > viewportSize.X then
scale = scale * 0.75
else
scale = scale * 0.85
end
return math.clamp(scale, 0.4, 1)
end
local function CalculateResponsiveSize(baseSize, minSize, maxSize)
local viewportSize = workspace.CurrentCamera.ViewportSize
local isMobile = IsMobileDevice()
local baseWidth = baseSize.X.Offset
local baseHeight = baseSize.Y.Offset
local targetWidth, targetHeight
if isMobile then
local isPortrait = viewportSize.Y > viewportSize.X
if isPortrait then
targetWidth = viewportSize.X * 0.92
targetHeight = viewportSize.Y * 0.70
else
targetWidth = viewportSize.X * 0.85
targetHeight = viewportSize.Y * 0.80
end
else
targetWidth = math.min(baseWidth, viewportSize.X * 0.75)
targetHeight = math.min(baseHeight, viewportSize.Y * 0.80)
if baseWidth < viewportSize.X * 0.6 and baseHeight < viewportSize.Y * 0.7 then
targetWidth = baseWidth
targetHeight = baseHeight
end
end
targetWidth = math.max(targetWidth, minSize.X)
targetHeight = math.max(targetHeight, minSize.Y)
targetWidth = math.min(targetWidth, maxSize.X)
targetHeight = math.min(targetHeight, maxSize.Y)
local marginX = isMobile and 20 or 40
local marginY = isMobile and 20 or 40
targetWidth = math.min(targetWidth, viewportSize.X - marginX)
targetHeight = math.min(targetHeight, viewportSize.Y - marginY)
targetWidth = math.floor(targetWidth)
targetHeight = math.floor(targetHeight)
return UDim2.new(0, targetWidth, 0, targetHeight)
end
local Theme = {
MainBackground = Color3.fromRGB(25, 25, 40),
SidebarBackground = Color3.fromRGB(20, 20, 35),
AccentColor = Color3.fromRGB(74, 46, 221),
AccentHover = Color3.fromRGB(94, 66, 241),
TextColor = Color3.fromRGB(255, 255, 255),
TextSecondary = Color3.fromRGB(180, 180, 200),
SeparatorColor = Color3.fromRGB(60, 60, 80),
ToggleOn = Color3.fromRGB(74, 46, 221),
ToggleOff = Color3.fromRGB(40, 40, 55),
SuccessColor = Color3.fromRGB(46, 204, 113),
ErrorColor = Color3.fromRGB(231, 76, 60),
WarningColor = Color3.fromRGB(241, 196, 15),
}
local TweenPresets = {
Fast = TweenInfo.new(0.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
Medium = TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
Smooth = TweenInfo.new(0.4, Enum.EasingStyle.Sine, Enum.EasingDirection.Out),
}
local function CreateTween(instance, properties, tweenInfo)
tweenInfo = tweenInfo or TweenPresets.Fast
local tween = TweenService:Create(instance, tweenInfo, properties)
tween:Play()
return tween
end
local function ApplyGlassmorphism(frame)
frame.BackgroundTransparency = 0.3
local blur = Instance.new("ImageLabel")
blur.Name = "GlassBlur"
blur.Size = UDim2.new(1, 0, 1, 0)
blur.Position = UDim2.new(0, 0, 0, 0)
blur.BackgroundTransparency = 1
blur.Image = "rbxasset://textures/ui/GuiImagePlaceholder.png"
blur.ImageTransparency = 0.95
blur.ScaleType = Enum.ScaleType.Tile
blur.TileSize = UDim2.new(0, 100, 0, 100)
blur.ZIndex = frame.ZIndex - 1
blur.Parent = frame
return blur
end
local NotificationContainer = nil
local ActiveNotifications = {}
function Library:Notify(config)
config = config or {}
local title = config.Title or "Notification"
local content = config.Content or ""
local duration = config.Duration or 5
local icon = config.Icon
local iconThemed = config.IconThemed or false
if not NotificationContainer or not NotificationContainer.Parent then
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "GAeroUI_Notifications"
screenGui.ResetOnSpawn = false
screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
screenGui.DisplayOrder = 100
screenGui.Parent = game:GetService("CoreGui")
NotificationContainer = Instance.new("Frame")
NotificationContainer.Name = "NotificationContainer"
NotificationContainer.Size = UDim2.new(0, 320, 1, -80)
NotificationContainer.Position = UDim2.new(1, -340, 0, 70)
NotificationContainer.BackgroundTransparency = 1
NotificationContainer.Parent = screenGui
local listLayout = Instance.new("UIListLayout")
listLayout.SortOrder = Enum.SortOrder.LayoutOrder
listLayout.Padding = UDim.new(0, 10)
listLayout.VerticalAlignment = Enum.VerticalAlignment.Top
listLayout.Parent = NotificationContainer
end
local notifFrame = Instance.new("Frame")
notifFrame.Name = "Notification"
notifFrame.Size = UDim2.new(1, 0, 0, 0)
notifFrame.BackgroundColor3 = Theme.SidebarBackground
notifFrame.BackgroundTransparency = 0.3
notifFrame.BorderSizePixel = 0
notifFrame.ClipsDescendants = true
notifFrame.LayoutOrder = #ActiveNotifications + 1
notifFrame.Parent = NotificationContainer
local notifCorner = Instance.new("UICorner")
notifCorner.CornerRadius = UDim.new(0, 12)
notifCorner.Parent = notifFrame
local notifStroke = Instance.new("UIStroke")
notifStroke.Color = Theme.SeparatorColor
notifStroke.Transparency = 0.5
notifStroke.Thickness = 1
notifStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
notifStroke.Parent = notifFrame
ApplyGlassmorphism(notifFrame)
local contentContainer = Instance.new("Frame")
contentContainer.Name = "Content"
contentContainer.Size = UDim2.new(1, -24, 1, -24)
contentContainer.Position = UDim2.new(0, 12, 0, 12)
contentContainer.BackgroundTransparency = 1
contentContainer.Parent = notifFrame
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 6)
contentLayout.FillDirection = Enum.FillDirection.Vertical
contentLayout.Parent = contentContainer
local headerFrame = Instance.new("Frame")
headerFrame.Name = "Header"
headerFrame.Size = UDim2.new(1, 0, 0, 20)
headerFrame.BackgroundTransparency = 1
headerFrame.LayoutOrder = 1
headerFrame.Parent = contentContainer
if icon then
local iconContainer = Instance.new("Frame")
iconContainer.Name = "IconContainer"
iconContainer.Size = UDim2.new(0, 20, 0, 20)
iconContainer.Position = UDim2.new(0, 0, 0, 0)
iconContainer.BackgroundTransparency = 1
iconContainer.Parent = headerFrame
if icon:match("^lucide%-") then
local iconName = icon:gsub("^lucide%-", "")
LoadLucideIcon(iconName, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
elseif icon:match("^rbxassetid://") or icon:match("^http") then
local iconImage = Instance.new("ImageLabel")
iconImage.Size = UDim2.new(1, 0, 1, 0)
iconImage.BackgroundTransparency = 1
iconImage.Image = icon
iconImage.ImageColor3 = iconThemed and Theme.AccentColor or Theme.TextColor
iconImage.Parent = iconContainer
else
LoadLucideIcon(icon, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
end
end
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, icon and -28 or 0, 1, 0)
titleLabel.Position = UDim2.new(0, icon and 28 or 0, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.TextColor
titleLabel.TextSize = 14
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.TextTruncate = Enum.TextTruncate.AtEnd
titleLabel.Parent = headerFrame
if content and content ~= "" then
local contentLabel = Instance.new("TextLabel")
contentLabel.Name = "ContentText"
contentLabel.Size = UDim2.new(1, 0, 0, 0)
contentLabel.BackgroundTransparency = 1
contentLabel.Text = content
contentLabel.TextColor3 = Theme.TextSecondary
contentLabel.TextSize = 12
contentLabel.Font = Enum.Font.Gotham
contentLabel.TextXAlignment = Enum.TextXAlignment.Left
contentLabel.TextYAlignment = Enum.TextYAlignment.Top
contentLabel.TextWrapped = true
contentLabel.AutomaticSize = Enum.AutomaticSize.Y
contentLabel.LayoutOrder = 2
contentLabel.Parent = contentContainer
end
task.wait()
local finalHeight = contentLayout.AbsoluteContentSize.Y + 24
notifFrame.Size = UDim2.new(1, 0, 0, 0)
notifFrame.Position = UDim2.new(0, 20, 0, 0)
CreateTween(notifFrame, {
Size = UDim2.new(1, 0, 0, finalHeight),
Position = UDim2.new(0, 0, 0, 0)
}, TweenPresets.Smooth)
table.insert(ActiveNotifications, notifFrame)
task.delay(duration, function()
if notifFrame and notifFrame.Parent then
CreateTween(notifFrame, {
Size = UDim2.new(1, 0, 0, 0),
Position = UDim2.new(0, 20, 0, 0)
}, TweenPresets.Fast)
CreateTween(notifStroke, {Transparency = 1}, TweenPresets.Fast)
task.wait(0.2)
if notifFrame and notifFrame.Parent then
notifFrame:Destroy()
end
for i, notif in ipairs(ActiveNotifications) do
if notif == notifFrame then
table.remove(ActiveNotifications, i)
break
end
end
end
end)
return notifFrame
end
function Library:Popup(config)
config = config or {}
local title = config.Title or "Popup"
local content = config.Content or ""
local icon = config.Icon
local iconThemed = config.IconThemed or false
local buttons = config.Buttons or {{Title = "OK", Variant = "Primary"}}
local popupScreenGui = Instance.new("ScreenGui")
popupScreenGui.Name = "GAeroUI_Popup"
popupScreenGui.ResetOnSpawn = false
popupScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
popupScreenGui.DisplayOrder = 200
popupScreenGui.Parent = game:GetService("CoreGui")
local popupOverlay = Instance.new("Frame")
popupOverlay.Name = "PopupOverlay"
popupOverlay.Size = UDim2.new(1, 0, 1, 0)
popupOverlay.Position = UDim2.new(0, 0, 0, 0)
popupOverlay.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
popupOverlay.BackgroundTransparency = 1
popupOverlay.BorderSizePixel = 0
popupOverlay.Parent = popupScreenGui
local popupContainer = Instance.new("Frame")
popupContainer.Name = "PopupContainer"
popupContainer.Size = UDim2.new(0, 420, 0, 0)
popupContainer.Position = UDim2.new(0.5, -210, 0.5, 0)
popupContainer.AnchorPoint = Vector2.new(0.5, 0.5)
popupContainer.BackgroundColor3 = Theme.MainBackground
popupContainer.BackgroundTransparency = 0.3
popupContainer.BorderSizePixel = 0
popupContainer.ClipsDescendants = true
popupContainer.Parent = popupOverlay
local popupCorner = Instance.new("UICorner")
popupCorner.CornerRadius = UDim.new(0, 16)
popupCorner.Parent = popupContainer
local popupStroke = Instance.new("UIStroke")
popupStroke.Color = Theme.SeparatorColor
popupStroke.Transparency = 0.3
popupStroke.Thickness = 1
popupStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
popupStroke.Parent = popupContainer
ApplyGlassmorphism(popupContainer)
local contentArea = Instance.new("Frame")
contentArea.Name = "ContentArea"
contentArea.Size = UDim2.new(1, -40, 1, -40)
contentArea.Position = UDim2.new(0, 20, 0, 20)
contentArea.BackgroundTransparency = 1
contentArea.Parent = popupContainer
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 10)
contentLayout.FillDirection = Enum.FillDirection.Vertical
contentLayout.Parent = contentArea
local headerFrame = Instance.new("Frame")
headerFrame.Name = "Header"
headerFrame.Size = UDim2.new(1, 0, 0, 24)
headerFrame.BackgroundTransparency = 1
headerFrame.LayoutOrder = 1
headerFrame.Parent = contentArea
if icon then
local iconContainer = Instance.new("Frame")
iconContainer.Name = "IconContainer"
iconContainer.Size = UDim2.new(0, 20, 0, 20)
iconContainer.Position = UDim2.new(0, 0, 0, 2)
iconContainer.BackgroundTransparency = 1
iconContainer.Parent = headerFrame
if icon:match("^lucide%-") then
local iconName = icon:gsub("^lucide%-", "")
LoadLucideIcon(iconName, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
elseif icon:match("^rbxassetid://") or icon:match("^http") then
local iconImage = Instance.new("ImageLabel")
iconImage.Size = UDim2.new(1, 0, 1, 0)
iconImage.BackgroundTransparency = 1
iconImage.Image = icon
iconImage.ImageColor3 = iconThemed and Theme.AccentColor or Theme.TextColor
iconImage.Parent = iconContainer
else
LoadLucideIcon(icon, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
end
end
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, icon and -28 or 0, 1, 0)
titleLabel.Position = UDim2.new(0, icon and 28 or 0, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.TextColor
titleLabel.TextSize = 18
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.TextYAlignment = Enum.TextYAlignment.Center
titleLabel.TextTruncate = Enum.TextTruncate.AtEnd
titleLabel.Parent = headerFrame
local contentLabel = Instance.new("TextLabel")
contentLabel.Name = "ContentText"
contentLabel.Size = UDim2.new(1, 0, 0, 0)
contentLabel.BackgroundTransparency = 1
contentLabel.Text = content
contentLabel.TextColor3 = Theme.TextSecondary
contentLabel.TextSize = 14
contentLabel.Font = Enum.Font.Gotham
contentLabel.TextXAlignment = Enum.TextXAlignment.Left
contentLabel.TextYAlignment = Enum.TextYAlignment.Top
contentLabel.TextWrapped = true
contentLabel.AutomaticSize = Enum.AutomaticSize.Y
contentLabel.LayoutOrder = 2
contentLabel.Parent = contentArea
local buttonsFrame = Instance.new("Frame")
buttonsFrame.Name = "Buttons"
buttonsFrame.Size = UDim2.new(1, 0, 0, 44)
buttonsFrame.BackgroundTransparency = 1
buttonsFrame.LayoutOrder = 3
buttonsFrame.Parent = contentArea
local buttonsLayout = Instance.new("UIListLayout")
buttonsLayout.SortOrder = Enum.SortOrder.LayoutOrder
buttonsLayout.Padding = UDim.new(0, 10)
buttonsLayout.FillDirection = Enum.FillDirection.Horizontal
buttonsLayout.HorizontalAlignment = Enum.HorizontalAlignment.Right
buttonsLayout.Parent = buttonsFrame
local function closePopup()
CreateTween(popupOverlay, {BackgroundTransparency = 1}, TweenPresets.Fast)
CreateTween(popupContainer, {
Size = UDim2.new(0, 420, 0, 0),
Position = UDim2.new(0.5, -210, 0.5, 0)
}, TweenPresets.Fast)
task.wait(0.2)
if popupScreenGui and popupScreenGui.Parent then
popupScreenGui:Destroy()
end
end
for i, buttonConfig in ipairs(buttons) do
local btnTitle = buttonConfig.Title or "Button"
local btnIcon = buttonConfig.Icon
local btnVariant = buttonConfig.Variant or "Primary"
local btnCallback = buttonConfig.Callback
-- Calculate equal button width based on number of buttons
local totalButtons = #buttons
local totalPadding = (totalButtons - 1) * 10
local buttonWidth = (buttonsFrame.AbsoluteSize.X - totalPadding) / totalButtons
local button = Instance.new("TextButton")
button.Name = "PopupButton_" .. i
button.Size = UDim2.new(0, buttonWidth, 1, 0)
button.BackgroundColor3 = btnVariant == "Primary" and Theme.AccentColor or
btnVariant == "Secondary" and Theme.SidebarBackground or
Theme.MainBackground
button.BackgroundTransparency = btnVariant == "Tertiary" and 0.5 or 0
button.BorderSizePixel = 0
button.Text = ""
button.AutoButtonColor = false
button.LayoutOrder = i
button.Parent = buttonsFrame
local btnCorner = Instance.new("UICorner")
btnCorner.CornerRadius = UDim.new(0, 10)
btnCorner.Parent = button
local contentContainer = Instance.new("Frame")
contentContainer.Size = UDim2.new(1, -16, 1, 0)
contentContainer.Position = UDim2.new(0, 8, 0, 0)
contentContainer.BackgroundTransparency = 1
contentContainer.Parent = button
local contentContainerLayout = Instance.new("UIListLayout")
contentContainerLayout.FillDirection = Enum.FillDirection.Horizontal
contentContainerLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
contentContainerLayout.VerticalAlignment = Enum.VerticalAlignment.Center
contentContainerLayout.Padding = UDim.new(0, 6)
contentContainerLayout.Parent = contentContainer
if btnIcon then
local btnIconContainer = Instance.new("Frame")
btnIconContainer.Name = "IconContainer"
btnIconContainer.Size = UDim2.new(0, 18, 0, 18)
btnIconContainer.BackgroundTransparency = 1
btnIconContainer.LayoutOrder = 1
btnIconContainer.Parent = contentContainer
LoadLucideIcon(btnIcon, btnIconContainer, Theme.TextColor)
end
local btnLabel = Instance.new("TextLabel")
btnLabel.Size = UDim2.new(0, 0, 0, 0)
btnLabel.AutomaticSize = Enum.AutomaticSize.XY
btnLabel.BackgroundTransparency = 1
btnLabel.Text = btnTitle
btnLabel.TextColor3 = Theme.TextColor
btnLabel.TextSize = 14
btnLabel.Font = Enum.Font.GothamSemibold
btnLabel.LayoutOrder = 2
btnLabel.Parent = contentContainer
button.MouseButton1Click:Connect(function()
if btnCallback then
local success, err = pcall(btnCallback)
if not success then
warn("GAeroUI Popup Button Error:", err)
end
end
closePopup()
end)
button.MouseEnter:Connect(function()
CreateTween(button, {
BackgroundColor3 = btnVariant == "Primary" and Theme.AccentHover or Theme.AccentColor
})
end)
button.MouseLeave:Connect(function()
CreateTween(button, {
BackgroundColor3 = btnVariant == "Primary" and Theme.AccentColor or
btnVariant == "Secondary" and Theme.SidebarBackground or
Theme.MainBackground
})
end)
end
task.wait()
local finalHeight = contentLayout.AbsoluteContentSize.Y + 40
popupContainer.Size = UDim2.new(0, 420, 0, 0)
CreateTween(popupOverlay, {BackgroundTransparency = 0.5}, TweenPresets.Medium)
CreateTween(popupContainer, {
Size = UDim2.new(0, 420, 0, finalHeight)
}, TweenPresets.Smooth)
return {
Close = closePopup
}
end
function Library:HideUsername(config)
config = config or {}
local line1 = config.Line1 or "Gatinero_Hub"
local line2 = config.Line2 or "dsc.gg/gatinero"
local nameColor = config.NameColor or Color3.fromRGB(255, 255, 255)
local discordColor = config.DiscordColor or Color3.fromRGB(255, 255, 255)
local outlineColor = config.OutlineColor or Color3.fromRGB(0, 0, 0)
local Players = game:GetService("Players")
local localPlayer = Players.LocalPlayer
local isHidden = false
local characterConnection = nil
local currentBillboard = nil
local function createCustomNameTag(character)
if not character then return end
local head = character:WaitForChild("Head", 5)
local humanoid = character:WaitForChild("Humanoid", 5)
if not head or not humanoid then return end
for _, child in ipairs(head:GetChildren()) do
if child:IsA("BillboardGui") then
child:Destroy()
end
end
humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None
local billboard = Instance.new("BillboardGui")
billboard.Name = "CustomNameTag"
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.StudsOffset = Vector3.new(0, 2, 0)
billboard.AlwaysOnTop = true
billboard.Parent = head
local nameLabel1 = Instance.new("TextLabel")
nameLabel1.Name = "NameLabel1"
nameLabel1.Size = UDim2.new(1, 0, 0.4, 0)
nameLabel1.Position = UDim2.new(0, 0, 0, 0)
nameLabel1.BackgroundTransparency = 1
nameLabel1.Text = line1
nameLabel1.TextColor3 = nameColor
nameLabel1.TextStrokeTransparency = 0
nameLabel1.TextStrokeColor3 = outlineColor
nameLabel1.Font = Enum.Font.GothamBold
nameLabel1.TextSize = 18
nameLabel1.TextScaled = false
nameLabel1.Parent = billboard
local stroke1 = Instance.new("UIStroke")
stroke1.Color = outlineColor
stroke1.Thickness = 3
stroke1.Parent = nameLabel1
local nameLabel2 = Instance.new("TextLabel")
nameLabel2.Name = "NameLabel2"
nameLabel2.Size = UDim2.new(1, 0, 0.35, 0)
nameLabel2.Position = UDim2.new(0, 0, 0.4, 0)
nameLabel2.BackgroundTransparency = 1
nameLabel2.Text = line2
nameLabel2.TextColor3 = discordColor
nameLabel2.TextStrokeTransparency = 0
nameLabel2.TextStrokeColor3 = outlineColor
nameLabel2.Font = Enum.Font.GothamBold
nameLabel2.TextSize = 16
nameLabel2.TextScaled = false
nameLabel2.Parent = billboard
local stroke2 = Instance.new("UIStroke")
stroke2.Color = outlineColor
stroke2.Thickness = 3
stroke2.Parent = nameLabel2
currentBillboard = billboard
end
local function restoreDefaultNameTag(character)
if not character then return end
local head = character:FindFirstChild("Head")
local humanoid = character:FindFirstChild("Humanoid")
if not head or not humanoid then return end
for _, child in ipairs(head:GetChildren()) do
if child:IsA("BillboardGui") and child.Name == "CustomNameTag" then
child:Destroy()
end
end
humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.Viewer
currentBillboard = nil
end
local function setupCharacter(character)
task.wait(0.1)
if isHidden then
createCustomNameTag(character)
else
restoreDefaultNameTag(character)
end
end
local function toggle(state)
isHidden = state
if localPlayer.Character then
if isHidden then
createCustomNameTag(localPlayer.Character)
else
restoreDefaultNameTag(localPlayer.Character)
end
end
end
if characterConnection then
characterConnection:Disconnect()
end
characterConnection = localPlayer.CharacterAdded:Connect(setupCharacter)
return {
Toggle = toggle,
IsHidden = function() return isHidden end,
Disconnect = function()
if characterConnection then
characterConnection:Disconnect()
end
if localPlayer.Character then
restoreDefaultNameTag(localPlayer.Character)
end
end
}
end
local Window = {}
Window.__index = Window
function Library:CreateWindow(config)
config = config or {}
local windowTitle = config.Title or "GAeroUI"
if type(windowTitle) ~= "string" then
warn("GAeroUI: Title must be a string, using default")
windowTitle = "GAeroUI"
end
local baseSize = config.Size or UDim2.new(0, 700, 0, 450)
local minSize = config.MinSize or Vector2.new(500, 350)
local maxSize = config.MaxSize or Vector2.new(1200, 800)
if minSize.X < 300 or minSize.Y < 200 then
warn("GAeroUI: MinSize too small, using minimum 300x200")
minSize = Vector2.new(math.max(300, minSize.X), math.max(200, minSize.Y))
end
if maxSize.X < minSize.X or maxSize.Y < minSize.Y then
warn("GAeroUI: MaxSize must be larger than MinSize, adjusting")
maxSize = Vector2.new(math.max(maxSize.X, minSize.X + 100), math.max(maxSize.Y, minSize.Y + 100))
end
local windowSize = CalculateResponsiveSize(baseSize, minSize, maxSize)
local self = setmetatable({}, Window)
self.Tabs = {}
self.CurrentTab = nil
self.InProfileView = false
self.BaseSize = baseSize
self.MinSize = minSize
self.MaxSize = maxSize
self.IsMinimized = false
self.MinimizedPosition = nil
self.MinimizedIconPosition = nil
self.OriginalSize = windowSize
self.Connections = {}
self.IsDestroyed = false
self.IsMobile = IsMobileDevice()
self.MobileScale = GetMobileScale()
self.ScreenGui = Instance.new("ScreenGui")
self.ScreenGui.Name = "GAeroUI"
self.ScreenGui.ResetOnSpawn = false
self.ScreenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
self.ScreenGui.Parent = game:GetService("CoreGui")
self.MainFrame = Instance.new("Frame")
self.MainFrame.Name = "MainWindow"
self.MainFrame.Size = windowSize
self.MainFrame.Position = UDim2.new(0.5, -windowSize.X.Offset/2, 0.5, -windowSize.Y.Offset/2)
self.MainFrame.BackgroundColor3 = Theme.MainBackground
self.MainFrame.BackgroundTransparency = 1
self.MainFrame.BorderSizePixel = 0
self.MainFrame.ClipsDescendants = false
self.MainFrame.Parent = self.ScreenGui
if self.IsMobile then
local uiScale = Instance.new("UIScale")
uiScale.Name = "MobileScale"
uiScale.Scale = self.MobileScale
uiScale.Parent = self.MainFrame
self.MainFrame.Position = UDim2.new(0.5, 0, 0.5, 0)
self.MainFrame.AnchorPoint = Vector2.new(0.5, 0.5)
end
local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0, 16)
mainCorner.Parent = self.MainFrame
local backgroundImage = Instance.new("ImageLabel")
backgroundImage.Name = "BackgroundImage"
backgroundImage.Size = UDim2.new(1, 0, 1, 0)
backgroundImage.Position = UDim2.new(0, 0, 0, 0)
backgroundImage.BackgroundTransparency = 1
backgroundImage.ImageTransparency = BACKGROUND_IMAGE_TRANSPARENCY
backgroundImage.ScaleType = Enum.ScaleType.Crop
backgroundImage.ZIndex = 1
backgroundImage.Parent = self.MainFrame
local function LoadBackgroundImage()
local success = false
pcall(function()
local imageData = game:HttpGet(BACKGROUND_IMAGE_URL)
if imageData and #imageData > 0 then
local base64Data = game:GetService("HttpService"):Base64Encode(imageData)
local mimeType = "image/jpeg"
if BACKGROUND_IMAGE_URL:lower():match("%.png") then
mimeType = "image/png"
elseif BACKGROUND_IMAGE_URL:lower():match("%.gif") then
mimeType = "image/gif"
end
backgroundImage.Image = "data:" .. mimeType .. ";base64," .. base64Data
success = true
end
end)
if not success and (getcustomasset and writefile and readfile) then
pcall(function()
local imageData = game:HttpGet(BACKGROUND_IMAGE_URL)
if writefile and readfile and getcustomasset then
local fileName = "gatinero_bg.jpg"
writefile(fileName, imageData)
backgroundImage.Image = getcustomasset(fileName)
success = true
end
end)
end
if not success then
backgroundImage.Image = BACKGROUND_IMAGE_FALLBACK
end
pcall(function()
if game:GetService("ContentProvider") then
game:GetService("ContentProvider"):PreloadAsync({backgroundImage})
end
end)
end
task.spawn(LoadBackgroundImage)
local bgCorner = Instance.new("UICorner")
bgCorner.CornerRadius = UDim.new(0, 16)
bgCorner.Parent = backgroundImage
local overlay = Instance.new("Frame")
overlay.Name = "DarkOverlay"
overlay.Size = UDim2.new(1, 0, 1, 0)
overlay.Position = UDim2.new(0, 0, 0, 0)
overlay.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
overlay.BackgroundTransparency = OVERLAY_TRANSPARENCY
overlay.BorderSizePixel = 0
overlay.ZIndex = 1
overlay.Parent = self.MainFrame
local overlayCorner = Instance.new("UICorner")
overlayCorner.CornerRadius = UDim.new(0, 16)
overlayCorner.Parent = overlay
local gradient = Instance.new("UIGradient")
gradient.Color = ColorSequence.new{
ColorSequenceKeypoint.new(0, Color3.fromRGB(74, 46, 221)),
ColorSequenceKeypoint.new(0.5, Color3.fromRGB(25, 25, 40)),
ColorSequenceKeypoint.new(1, Color3.fromRGB(20, 20, 35))
}
gradient.Transparency = NumberSequence.new{
NumberSequenceKeypoint.new(0, 0.7),
NumberSequenceKeypoint.new(0.5, 0.85),
NumberSequenceKeypoint.new(1, 0.6)
}
gradient.Rotation = 135
gradient.Parent = overlay
ApplyGlassmorphism(self.MainFrame)
local contentClipper = Instance.new("Frame")
contentClipper.Name = "ContentClipper"
contentClipper.Size = UDim2.new(1, 0, 1, 0)
contentClipper.Position = UDim2.new(0, 0, 0, 0)
contentClipper.BackgroundTransparency = 1
contentClipper.ClipsDescendants = true
contentClipper.ZIndex = 1
contentClipper.Parent = self.MainFrame
self.Sidebar = Instance.new("Frame")
self.Sidebar.Name = "Sidebar"
self.Sidebar.Size = UDim2.new(0, 200, 1, 0)
self.Sidebar.Position = UDim2.new(0, 0, 0, 0)
self.Sidebar.BackgroundColor3 = Theme.SidebarBackground
self.Sidebar.BackgroundTransparency = 1
self.Sidebar.BorderSizePixel = 0
self.Sidebar.ClipsDescendants = true
self.Sidebar.ZIndex = 2
self.Sidebar.Parent = self.MainFrame
local sidebarCorner = Instance.new("UICorner")
sidebarCorner.CornerRadius = UDim.new(0, 16)
sidebarCorner.Parent = self.Sidebar
local topRightPatch = Instance.new("Frame")
topRightPatch.Size = UDim2.new(0, 16, 0, 16)
topRightPatch.Position = UDim2.new(1, -16, 0, 0)
topRightPatch.BackgroundColor3 = Theme.SidebarBackground
topRightPatch.BackgroundTransparency = 1
topRightPatch.BorderSizePixel = 0
topRightPatch.Parent = self.Sidebar
local bottomRightPatch = Instance.new("Frame")
bottomRightPatch.Size = UDim2.new(0, 16, 0, 16)
bottomRightPatch.Position = UDim2.new(1, -16, 1, -16)
bottomRightPatch.BackgroundColor3 = Theme.SidebarBackground
bottomRightPatch.BorderSizePixel = 0
bottomRightPatch.Parent = self.Sidebar
-- Sidebar background image
local sidebarBackgroundImage = Instance.new("ImageLabel")
sidebarBackgroundImage.Name = "SidebarBackgroundImage"
sidebarBackgroundImage.Size = UDim2.new(1, 0, 1, 0)
sidebarBackgroundImage.Position = UDim2.new(0, 0, 0, 0)
sidebarBackgroundImage.BackgroundTransparency = 1
sidebarBackgroundImage.ImageTransparency = 0.5
sidebarBackgroundImage.ScaleType = Enum.ScaleType.Crop
sidebarBackgroundImage.ZIndex = 1
sidebarBackgroundImage.Parent = self.Sidebar
local function LoadSidebarBackgroundImage()
local success = false
pcall(function()
local imageData = game:HttpGet(SIDEBAR_BACKGROUND_IMAGE_URL)
if imageData and #imageData > 0 then
local base64Data = game:GetService("HttpService"):Base64Encode(imageData)
local mimeType = "image/jpeg"
if SIDEBAR_BACKGROUND_IMAGE_URL:lower():match("%.png") then
mimeType = "image/png"
elseif SIDEBAR_BACKGROUND_IMAGE_URL:lower():match("%.gif") then
mimeType = "image/gif"
end
sidebarBackgroundImage.Image = "data:" .. mimeType .. ";base64," .. base64Data
success = true
end
end)
if not success and (getcustomasset and writefile and readfile) then
pcall(function()
local imageData = game:HttpGet(SIDEBAR_BACKGROUND_IMAGE_URL)
if writefile and readfile and getcustomasset then
local fileName = "gatinero_sidebar_bg.jpg"
writefile(fileName, imageData)
sidebarBackgroundImage.Image = getcustomasset(fileName)
success = true
end
end)
end
if not success then
sidebarBackgroundImage.Image = BACKGROUND_IMAGE_FALLBACK
end
pcall(function()
if game:GetService("ContentProvider") then
game:GetService("ContentProvider"):PreloadAsync({sidebarBackgroundImage})
end
end)
end
task.spawn(LoadSidebarBackgroundImage)
local sidebarBgCorner = Instance.new("UICorner")
sidebarBgCorner.CornerRadius = UDim.new(0, 16)
sidebarBgCorner.Parent = sidebarBackgroundImage
-- Dark overlay for better text visibility
local sidebarOverlay = Instance.new("Frame")
sidebarOverlay.Name = "SidebarOverlay"
sidebarOverlay.Size = UDim2.new(1, 0, 1, 0)
sidebarOverlay.Position = UDim2.new(0, 0, 0, 0)
sidebarOverlay.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
sidebarOverlay.BackgroundTransparency = 0.5
sidebarOverlay.BorderSizePixel = 0
sidebarOverlay.ZIndex = 1
sidebarOverlay.Parent = self.Sidebar
local sidebarOverlayCorner = Instance.new("UICorner")
sidebarOverlayCorner.CornerRadius = UDim.new(0, 16)
sidebarOverlayCorner.Parent = sidebarOverlay
local titleBar = Instance.new("Frame")
titleBar.Name = "TitleBar"
titleBar.Size = UDim2.new(1, -200, 0, 40)
titleBar.Position = UDim2.new(0, 200, 0, 0)
titleBar.BackgroundTransparency = 1
titleBar.BorderSizePixel = 0
titleBar.ZIndex = 10
titleBar.Parent = self.MainFrame
local controlsFrame = Instance.new("Frame")
controlsFrame.Name = "Controls"
controlsFrame.Size = UDim2.new(0, 60, 0, 24)
controlsFrame.Position = UDim2.new(1, -70, 0.5, -12)
controlsFrame.BackgroundTransparency = 1
controlsFrame.Parent = titleBar
local minimizeBtn = Instance.new("TextButton")
minimizeBtn.Name = "MinimizeButton"
minimizeBtn.Size = UDim2.new(0, 24, 0, 24)
minimizeBtn.Position = UDim2.new(0, 0, 0, 0)
minimizeBtn.BackgroundColor3 = Theme.SidebarBackground
minimizeBtn.BackgroundTransparency = 0.3
minimizeBtn.BorderSizePixel = 0
minimizeBtn.Text = "—"
minimizeBtn.TextColor3 = Theme.TextColor
minimizeBtn.TextSize = 16
minimizeBtn.Font = Enum.Font.GothamBold
minimizeBtn.AutoButtonColor = false
minimizeBtn.Parent = controlsFrame
local minCorner = Instance.new("UICorner")
minCorner.CornerRadius = UDim.new(0, 6)
minCorner.Parent = minimizeBtn
self.Connections.MinimizeButton = minimizeBtn.MouseButton1Click:Connect(function()
self:ToggleMinimize()
end)
minimizeBtn.MouseEnter:Connect(function()
CreateTween(minimizeBtn, {BackgroundTransparency = 0})
end)
minimizeBtn.MouseLeave:Connect(function()
CreateTween(minimizeBtn, {BackgroundTransparency = 0.3})
end)
local closeBtn = Instance.new("TextButton")
closeBtn.Name = "CloseButton"
closeBtn.Size = UDim2.new(0, 24, 0, 24)
closeBtn.Position = UDim2.new(0, 32, 0, 0)
closeBtn.BackgroundColor3 = Color3.fromRGB(220, 50, 50)
closeBtn.BackgroundTransparency = 0.3
closeBtn.BorderSizePixel = 0
closeBtn.Text = ""
closeBtn.AutoButtonColor = false
closeBtn.Parent = controlsFrame
local closeIcon = Instance.new("ImageLabel")
closeIcon.Size = UDim2.new(0, 16, 0, 16)
closeIcon.Position = UDim2.new(0.5, -8, 0.5, -8)
closeIcon.BackgroundTransparency = 1
closeIcon.ImageColor3 = Theme.TextColor
closeIcon.Parent = closeBtn
LoadLucideIcon("x", closeIcon, Theme.TextColor)
local closeCorner = Instance.new("UICorner")
closeCorner.CornerRadius = UDim.new(0, 6)
closeCorner.Parent = closeBtn
self.Connections.CloseButton = closeBtn.MouseButton1Click:Connect(function()
self:Close()
end)
closeBtn.MouseEnter:Connect(function()
CreateTween(closeBtn, {BackgroundTransparency = 0, BackgroundColor3 = Color3.fromRGB(255, 60, 60)})
end)
closeBtn.MouseLeave:Connect(function()
CreateTween(closeBtn, {BackgroundTransparency = 0.3, BackgroundColor3 = Color3.fromRGB(220, 50, 50)})
end)
local header = Instance.new("Frame")
header.Name = "Header"
header.Size = UDim2.new(1, 0, 0, 70)
header.BackgroundTransparency = 1
header.Parent = self.Sidebar
local logoIcon = Instance.new("ImageLabel")
logoIcon.Name = "Logo"
logoIcon.Size = UDim2.new(0, 28, 0, 28)
logoIcon.Position = UDim2.new(0, 12, 0, 12)
logoIcon.BackgroundTransparency = 1
logoIcon.Image = "rbxassetid://88183417608118"
logoIcon.ImageColor3 = Theme.AccentColor
logoIcon.Parent = header
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, -50, 0, 18)
titleLabel.Position = UDim2.new(0, 46, 0, 12)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = "GATINERO HUB"
titleLabel.TextColor3 = Theme.TextColor
titleLabel.TextSize = 16
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.Parent = header
local subtitle = Instance.new("TextLabel")
subtitle.Name = "Subtitle"
subtitle.Size = UDim2.new(1, -50, 0, 12)
subtitle.Position = UDim2.new(0, 46, 0, 30)
subtitle.BackgroundTransparency = 1
subtitle.Text = "Mount Menu"
subtitle.TextColor3 = Theme.TextSecondary
subtitle.TextSize = 10
subtitle.Font = Enum.Font.Gotham
subtitle.TextXAlignment = Enum.TextXAlignment.Left
subtitle.Parent = header
local headerSeparator = Instance.new("Frame")
headerSeparator.Name = "HeaderSeparator"
headerSeparator.Size = UDim2.new(1, -20, 0, 1)
headerSeparator.Position = UDim2.new(0, 10, 0, 60)
headerSeparator.BackgroundColor3 = Theme.SeparatorColor
headerSeparator.BorderSizePixel = 0
headerSeparator.Parent = header
local profileCard = Instance.new("TextButton")
profileCard.Name = "ProfileCard"
profileCard.Size = UDim2.new(1, -20, 0, 60)
profileCard.Position = UDim2.new(0, 10, 0, 75)
profileCard.BackgroundColor3 = Theme.SidebarBackground
profileCard.BackgroundTransparency = 0.5
profileCard.BorderSizePixel = 0
profileCard.Text = ""
profileCard.AutoButtonColor = false
profileCard.Parent = self.Sidebar
local profileCorner = Instance.new("UICorner")
profileCorner.CornerRadius = UDim.new(0, 10)
profileCorner.Parent = profileCard
local profileStroke = Instance.new("UIStroke")
profileStroke.Color = Theme.SeparatorColor
profileStroke.Transparency = 0.5
profileStroke.Thickness = 1
profileStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
profileStroke.Parent = profileCard
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local avatarImage = Instance.new("ImageLabel")
avatarImage.Name = "Avatar"
avatarImage.Size = UDim2.new(0, 44, 0, 44)
avatarImage.Position = UDim2.new(0, 8, 0.5, -22)
avatarImage.BackgroundColor3 = Theme.ToggleOff
avatarImage.BorderSizePixel = 0
avatarImage.Image = Players:GetUserThumbnailAsync(LocalPlayer.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size150x150)
avatarImage.Parent = profileCard
local avatarCorner = Instance.new("UICorner")
avatarCorner.CornerRadius = UDim.new(1, 0)
avatarCorner.Parent = avatarImage
local usernameLabel = Instance.new("TextLabel")
usernameLabel.Name = "Username"
usernameLabel.Size = UDim2.new(1, -68, 0, 18)
usernameLabel.Position = UDim2.new(0, 60, 0, 14)
usernameLabel.BackgroundTransparency = 1
usernameLabel.Text = _G.HideUsernameEnabled and "Gatinero_Hub" or LocalPlayer.Name
usernameLabel.TextColor3 = Theme.TextColor
usernameLabel.TextSize = 14
usernameLabel.Font = Enum.Font.GothamBold
usernameLabel.TextXAlignment = Enum.TextXAlignment.Left
usernameLabel.TextTruncate = Enum.TextTruncate.AtEnd
usernameLabel.Parent = profileCard
local displayNameLabel = Instance.new("TextLabel")
displayNameLabel.Name = "DisplayName"
displayNameLabel.Size = UDim2.new(1, -68, 0, 14)
displayNameLabel.Position = UDim2.new(0, 60, 0, 32)
displayNameLabel.BackgroundTransparency = 1
displayNameLabel.Text = _G.HideUsernameEnabled and "dsc.gg/gatinero" or ("@" .. LocalPlayer.Name)
displayNameLabel.TextColor3 = Theme.TextSecondary
displayNameLabel.TextSize = 11
displayNameLabel.Font = Enum.Font.Gotham
displayNameLabel.TextXAlignment = Enum.TextXAlignment.Left
displayNameLabel.TextTruncate = Enum.TextTruncate.AtEnd
displayNameLabel.Parent = profileCard
if not _G.HideUsernameEnabled and LocalPlayer.DisplayName ~= LocalPlayer.Name then
usernameLabel.Text = LocalPlayer.DisplayName
displayNameLabel.Text = "@" .. LocalPlayer.Name
end
self.ProfileUsernameLabel = usernameLabel
self.ProfileDisplayNameLabel = displayNameLabel
profileCard.MouseEnter:Connect(function()
CreateTween(profileCard, {BackgroundTransparency = 0.3})
CreateTween(profileStroke, {Transparency = 0.2})
end)
profileCard.MouseLeave:Connect(function()
CreateTween(profileCard, {BackgroundTransparency = 0.5})
CreateTween(profileStroke, {Transparency = 0.5})
end)
self.ProfileCard = profileCard
profileCard.MouseButton1Click:Connect(function()
self:ShowProfileInfo()
end)
local profileSeparator = Instance.new("Frame")
profileSeparator.Name = "ProfileSeparator"
profileSeparator.Size = UDim2.new(1, -20, 0, 1)
profileSeparator.Position = UDim2.new(0, 10, 0, 145)
profileSeparator.BackgroundColor3 = Theme.SeparatorColor
profileSeparator.BorderSizePixel = 0
profileSeparator.Parent = self.Sidebar
self.TabContainer = Instance.new("ScrollingFrame")
self.TabContainer.Name = "TabContainer"
self.TabContainer.Size = UDim2.new(1, -10, 1, -155)
self.TabContainer.Position = UDim2.new(0, 5, 0, 150)
self.TabContainer.BackgroundTransparency = 1
self.TabContainer.BorderSizePixel = 0
self.TabContainer.ScrollBarThickness = self.IsMobile and 8 or 6
self.TabContainer.ScrollBarImageColor3 = Theme.AccentColor
self.TabContainer.ScrollBarImageTransparency = self.IsMobile and 0.2 or 0.3
self.TabContainer.CanvasSize = UDim2.new(0, 0, 0, 0)
self.TabContainer.ScrollingDirection = Enum.ScrollingDirection.Y
self.TabContainer.VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar
self.TabContainer.ElasticBehavior = Enum.ElasticBehavior.WhenScrollable
self.TabContainer.ScrollingEnabled = true
self.TabContainer.Active = true
self.TabContainer.Selectable = true
self.TabContainer.AutomaticCanvasSize = Enum.AutomaticSize.Y
self.TabContainer.Parent = self.Sidebar
local tabLayout = Instance.new("UIListLayout")
tabLayout.SortOrder = Enum.SortOrder.LayoutOrder
tabLayout.Padding = UDim.new(0, 6)
tabLayout.Parent = self.TabContainer
-- Function to update canvas size
local function updateCanvasSize()
local contentHeight = tabLayout.AbsoluteContentSize.Y
local padding = self.IsMobile and 30 or 20
self.TabContainer.CanvasSize = UDim2.new(0, 0, 0, contentHeight + padding)
end
-- Update canvas size when content changes
self.Connections.TabLayoutChanged = tabLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(updateCanvasSize)
-- Initial canvas size update (delayed to ensure layout is calculated)
task.spawn(function()
task.wait(0.1)
updateCanvasSize()
-- Force another update after a short delay for mobile devices
if self.IsMobile then
task.wait(0.2)
updateCanvasSize()
end
end)
local tabPadding = Instance.new("UIPadding")
tabPadding.PaddingLeft = UDim.new(0, 5)
tabPadding.PaddingRight = UDim.new(0, 5)
tabPadding.Parent = self.TabContainer
local contentBackground = Instance.new("Frame")
contentBackground.Name = "ContentBackground"
contentBackground.Size = UDim2.new(1, -220, 1, -60)
contentBackground.Position = UDim2.new(0, 210, 0, 50)
contentBackground.BackgroundColor3 = Theme.SidebarBackground
contentBackground.BackgroundTransparency = 0.5
contentBackground.BorderSizePixel = 0
contentBackground.ZIndex = 1
contentBackground.Parent = contentClipper
local contentBgCorner = Instance.new("UICorner")
contentBgCorner.CornerRadius = UDim.new(0, 12)
contentBgCorner.Parent = contentBackground
self.ContentArea = Instance.new("Frame")
self.ContentArea.Name = "ContentArea"
self.ContentArea.Size = UDim2.new(1, 0, 1, 0)
self.ContentArea.Position = UDim2.new(0, 0, 0, 0)
self.ContentArea.BackgroundTransparency = 1
self.ContentArea.ZIndex = 2
self.ContentArea.Parent = contentBackground
self.ContentScroll = Instance.new("ScrollingFrame")
self.ContentScroll.Name = "ContentScroll"
self.ContentScroll.Size = UDim2.new(1, -6, 1, 0)
self.ContentScroll.Position = UDim2.new(0, 0, 0, 0)
self.ContentScroll.BackgroundTransparency = 1
self.ContentScroll.BorderSizePixel = 0
self.ContentScroll.ScrollBarThickness = 5
self.ContentScroll.ScrollBarImageColor3 = Theme.AccentColor
self.ContentScroll.ScrollBarImageTransparency = 0.3
self.ContentScroll.CanvasSize = UDim2.new(0, 0, 0, 0)
self.ContentScroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
self.ContentScroll.Parent = self.ContentArea
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 10)
contentLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
contentLayout.Parent = self.ContentScroll
local contentPadding = Instance.new("UIPadding")
contentPadding.PaddingLeft = UDim.new(0, 16)
contentPadding.PaddingRight = UDim.new(0, 16)
contentPadding.PaddingTop = UDim.new(0, 16)
contentPadding.PaddingBottom = UDim.new(0, 16)
contentPadding.Parent = self.ContentScroll
self:MakeDraggable()
self:MakeResizable()
if self.IsMobile then
self:SetupMobileViewportMonitoring()
end
self.MainFrame.Size = UDim2.new(0, 0, 0, 0)
CreateTween(self.MainFrame, {Size = windowSize}, TweenPresets.Smooth)
return self
end
function Window:Close()
if self.IsDestroyed then return end
if self.IsMinimized then
self.IsMinimized = false
self.Sidebar.Visible = true
local titleBar = self.MainFrame:FindFirstChild("TitleBar")
if titleBar then titleBar.Visible = true end
local contentClipper = self.MainFrame:FindFirstChild("ContentClipper")
if contentClipper then contentClipper.Visible = true end
local minimizeIcon = self.MainFrame:FindFirstChild("MinimizeIcon")
if minimizeIcon then minimizeIcon:Destroy() end
end
if self.MainFrame and self.MainFrame.Parent then
local closeTween = CreateTween(self.MainFrame, {
Size = UDim2.new(0, 0, 0, 0),
Position = UDim2.new(0.5, 0, 0.5, 0)
}, TweenPresets.Smooth)
if closeTween then
closeTween.Completed:Wait()
else
task.wait(0.4)
end
end
self:Destroy()
end
function Window:Destroy()
if self.IsDestroyed then return end
self.IsDestroyed = true
for name, connection in pairs(self.Connections) do
if connection and typeof(connection) == "RBXScriptConnection" then
connection:Disconnect()
end
end
self.Connections = {}
self.Tabs = {}
self.CurrentTab = nil
if self.ScreenGui then
pcall(function()
self.ScreenGui:Destroy()
end)
end
self.ScreenGui = nil
self.MainFrame = nil
self.Sidebar = nil
self.TabContainer = nil
self.ContentArea = nil
self.ContentScroll = nil
end
function Window:MakeDraggable()
local dragging = false
local dragInput, mousePos, framePos
local function update(input)
local delta = input.Position - mousePos
CreateTween(self.MainFrame, {
Position = UDim2.new(framePos.X.Scale, framePos.X.Offset + delta.X, framePos.Y.Scale, framePos.Y.Offset + delta.Y)
}, TweenPresets.Fast)
end
local function setupDragging(element)
element.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
mousePos = input.Position
framePos = self.MainFrame.Position
input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
dragging = false
end
end)
end
end)
element.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
end
local titleBar = self.MainFrame:FindFirstChild("TitleBar")
local sidebarHeader = self.Sidebar:FindFirstChild("Header")
if titleBar then
setupDragging(titleBar)
end
if sidebarHeader then
setupDragging(sidebarHeader)
end
self.Connections.DragInputChanged = UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging then
update(input)
end
end)
end
function Window:Minimize()
if self.IsDestroyed then return end
if not self.IsMinimized then
self:ToggleMinimize()
end
end
function Window:Restore()
if self.IsDestroyed then return end
if self.IsMinimized then
self:ToggleMinimize()
end
end
function Window:ToggleMinimize()
if self.IsDestroyed then return end
-- Close any open dropdowns when minimizing
for _, child in ipairs(self.ScreenGui:GetChildren()) do
if child:IsA("ScrollingFrame") and child.Name:match("^OptionsList_") then
child.Visible = false
child.Size = UDim2.new(0, child.AbsoluteSize.X, 0, 0)
end
end
if self.IsMinimized then
self.IsMinimized = false
self.MinimizedIconPosition = self.MainFrame.Position
if self.Connections.MinimizeIconDrag then
self.Connections.MinimizeIconDrag:Disconnect()
self.Connections.MinimizeIconDrag = nil
end
local restorePosition = self.MinimizedPosition or UDim2.new(0.5, 0, 0.5, 0)
self.Sidebar.Visible = true
local titleBar = self.MainFrame:FindFirstChild("TitleBar")
if titleBar then
titleBar.Visible = true
end
local contentClipper = self.MainFrame:FindFirstChild("ContentClipper")
if contentClipper then
contentClipper.Visible = true
end
local resizeHandle = self.MainFrame:FindFirstChild("ResizeHandle")
if resizeHandle then
resizeHandle.Visible = true
end
CreateTween(self.MainFrame, {
Size = self.OriginalSize,
Position = restorePosition
}, TweenPresets.Medium)
local minimizeIcon = self.MainFrame:FindFirstChild("MinimizeIcon")
if minimizeIcon then
minimizeIcon:Destroy()
end
else
self.IsMinimized = true
self.MinimizedPosition = self.MainFrame.Position
self.OriginalSize = self.MainFrame.Size
self.Sidebar.Visible = false
local titleBar = self.MainFrame:FindFirstChild("TitleBar")
if titleBar then
titleBar.Visible = false
end
local contentClipper = self.MainFrame:FindFirstChild("ContentClipper")
if contentClipper then
contentClipper.Visible = false
end
local resizeHandle = self.MainFrame:FindFirstChild("ResizeHandle")
if resizeHandle then
resizeHandle.Visible = false
end
local iconPosition = self.MinimizedIconPosition or self.MainFrame.Position
local minimizeIcon = Instance.new("ImageButton")
minimizeIcon.Name = "MinimizeIcon"
minimizeIcon.Size = UDim2.new(1, 0, 1, 0)
minimizeIcon.Position = UDim2.new(0, 0, 0, 0)
minimizeIcon.BackgroundTransparency = 1
minimizeIcon.Image = "rbxassetid://88183417608118"
minimizeIcon.ImageColor3 = Theme.AccentColor
minimizeIcon.ZIndex = 100
minimizeIcon.Parent = self.MainFrame
local isDragging = false
local dragStart = nil
local startPos = nil
minimizeIcon.MouseButton1Down:Connect(function()
dragStart = UserInputService:GetMouseLocation()
startPos = self.MainFrame.Position
isDragging = false
end)
minimizeIcon.MouseButton1Up:Connect(function()
if not isDragging then
self:ToggleMinimize()
end
dragStart = nil
end)
self.Connections.MinimizeIconDrag = UserInputService.InputChanged:Connect(function(input)
if dragStart and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
local currentPos = UserInputService:GetMouseLocation()
local delta = currentPos - dragStart
if math.abs(delta.X) > 5 or math.abs(delta.Y) > 5 then
isDragging = true
if self.MainFrame and self.MainFrame.Parent then
self.MainFrame.Position = UDim2.new(
startPos.X.Scale,
startPos.X.Offset + delta.X,
startPos.Y.Scale,
startPos.Y.Offset + delta.Y
)
end
end
end
end)
minimizeIcon.MouseEnter:Connect(function()
CreateTween(minimizeIcon, {ImageColor3 = Theme.AccentHover})
end)
minimizeIcon.MouseLeave:Connect(function()
CreateTween(minimizeIcon, {ImageColor3 = Theme.AccentColor})
end)
CreateTween(self.MainFrame, {
Size = UDim2.new(0, 60, 0, 60),
Position = iconPosition
}, TweenPresets.Medium)
end
end
function Window:MakeResizable()
if self.IsMobile then
return
end
local resizeHandle = Instance.new("ImageButton")
resizeHandle.Name = "ResizeHandle"
resizeHandle.Size = UDim2.new(0, 20, 0, 20)
resizeHandle.Position = UDim2.new(1, -20, 1, -20)
resizeHandle.BackgroundColor3 = Theme.AccentColor
resizeHandle.BackgroundTransparency = 0.3
resizeHandle.BorderSizePixel = 0
resizeHandle.Image = ""
resizeHandle.ZIndex = 10
resizeHandle.Parent = self.MainFrame
local handleCorner = Instance.new("UICorner")
handleCorner.CornerRadius = UDim.new(0, 6)
handleCorner.Parent = resizeHandle
local resizeIconContainer = Instance.new("Frame")
resizeIconContainer.Name = "IconContainer"
resizeIconContainer.Size = UDim2.new(0, 14, 0, 14)
resizeIconContainer.Position = UDim2.new(0.5, -7, 0.5, -7)
resizeIconContainer.BackgroundTransparency = 1
resizeIconContainer.ZIndex = 11
resizeIconContainer.Parent = resizeHandle
LoadLucideIcon("maximize-2", resizeIconContainer, Theme.TextColor)
local resizing = false
local startPos, startSize
resizeHandle.MouseButton1Down:Connect(function()
resizing = true
startPos = UserInputService:GetMouseLocation()
startSize = self.MainFrame.AbsoluteSize
end)
self.Connections.ResizeInputEnded = UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
resizing = false
end
end)
self.Connections.ResizeRenderStepped = RunService.RenderStepped:Connect(function()
if resizing and self.MainFrame and self.MainFrame.Parent then
local mousePos = UserInputService:GetMouseLocation()
local delta = mousePos - startPos
local newWidth = math.max(self.MinSize.X, startSize.X + delta.X)
local newHeight = math.max(self.MinSize.Y, startSize.Y + delta.Y)
self.MainFrame.Size = UDim2.new(0, newWidth, 0, newHeight)
end
end)
resizeHandle.MouseEnter:Connect(function()
CreateTween(resizeHandle, {BackgroundTransparency = 0.1})
end)
resizeHandle.MouseLeave:Connect(function()
CreateTween(resizeHandle, {BackgroundTransparency = 0.3})
end)
end
function Window:SetupMobileViewportMonitoring()
if self.IsDestroyed or not self.IsMobile then return end
local camera = workspace.CurrentCamera
local lastViewportSize = camera.ViewportSize
local lastOrientation = lastViewportSize.Y > lastViewportSize.X and "Portrait" or "Landscape"
self.Connections.ViewportMonitor = RunService.RenderStepped:Connect(function()
if self.IsDestroyed or not self.MainFrame or not self.MainFrame.Parent then
if self.Connections.ViewportMonitor then
self.Connections.ViewportMonitor:Disconnect()
self.Connections.ViewportMonitor = nil
end
return
end
local currentViewportSize = camera.ViewportSize
local currentOrientation = currentViewportSize.Y > currentViewportSize.X and "Portrait" or "Landscape"
local viewportChanged = (currentViewportSize - lastViewportSize).Magnitude > 10
local orientationChanged = currentOrientation ~= lastOrientation
if viewportChanged or orientationChanged then
lastViewportSize = currentViewportSize
lastOrientation = currentOrientation
self.IsMobile = IsMobileDevice()
local newScale = GetMobileScale()
self.MobileScale = newScale
local uiScale = self.MainFrame:FindFirstChild("MobileScale")
if self.IsMobile then
if not uiScale then
uiScale = Instance.new("UIScale")
uiScale.Name = "MobileScale"
uiScale.Parent = self.MainFrame
end
CreateTween(uiScale, {Scale = newScale}, TweenPresets.Medium)
elseif uiScale then
uiScale:Destroy()
end
if not self.IsMinimized then
local newSize = CalculateResponsiveSize(self.BaseSize, self.MinSize, self.MaxSize)
local currentSize = self.MainFrame.Size
local sizeDiffX = math.abs(newSize.X.Offset - currentSize.X.Offset)
local sizeDiffY = math.abs(newSize.Y.Offset - currentSize.Y.Offset)
if sizeDiffX > 20 or sizeDiffY > 20 then
CreateTween(self.MainFrame, {Size = newSize}, TweenPresets.Medium)
local newPosition = UDim2.new(0.5, -newSize.X.Offset/2, 0.5, -newSize.Y.Offset/2)
if self.IsMobile then
newPosition = UDim2.new(0.5, 0, 0.5, 0)
end
CreateTween(self.MainFrame, {Position = newPosition}, TweenPresets.Medium)
end
end
end
end)
end
function Window:AddSidebarSeparator()
if self.IsDestroyed then
warn("GAeroUI: Cannot add separator to destroyed window")
return nil
end
local separator = Instance.new("Frame")
separator.Name = "SidebarSeparator"
separator.Size = UDim2.new(1, 0, 0, 1)
separator.BackgroundColor3 = Theme.SeparatorColor
separator.BorderSizePixel = 0
separator.Parent = self.TabContainer
local separatorPadding = Instance.new("UIPadding")
separatorPadding.PaddingTop = UDim.new(0, 8)
separatorPadding.PaddingBottom = UDim.new(0, 8)
separatorPadding.Parent = separator
return separator
end
function Window:ShowProfileInfo()
if self.IsDestroyed then return end
for _, tab in ipairs(self.Tabs) do
if tab.Button then
CreateTween(tab.Button, {BackgroundTransparency = 1})
CreateTween(tab.Icon, {ImageColor3 = Theme.TextSecondary})
CreateTween(tab.Label, {TextColor3 = Theme.TextSecondary})
end
for _, element in ipairs(tab.Elements) do
if element.Instance then
element.Instance.Visible = false
end
end
end
self.CurrentTab = nil
self.InProfileView = true
self:BuildProfileContent()
end
function Window:UpdateProfileCard()
if self.IsDestroyed then return end
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
if self.ProfileUsernameLabel then
if _G.HideUsernameEnabled then
self.ProfileUsernameLabel.Text = "Gatinero_Hub"
else
self.ProfileUsernameLabel.Text = LocalPlayer.DisplayName ~= LocalPlayer.Name and LocalPlayer.DisplayName or LocalPlayer.Name
end
end
if self.ProfileDisplayNameLabel then
if _G.HideUsernameEnabled then
self.ProfileDisplayNameLabel.Text = "dsc.gg/gatinero"
else
self.ProfileDisplayNameLabel.Text = "@" .. LocalPlayer.Name
end
end
end
function Window:BuildProfileContent()
if self.IsDestroyed then return end
for _, child in ipairs(self.ContentScroll:GetChildren()) do
if child:IsA("Frame") and child.Name:match("Profile") then
child:Destroy()
end
end
local userData = _G.GatineroUserData or {}
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local function createInfoSection(title, items, layoutOrder)
local section = Instance.new("Frame")
section.Name = "ProfileSection_" .. title
section.Size = UDim2.new(1, 0, 0, 0)
section.BackgroundColor3 = Theme.SidebarBackground
section.BackgroundTransparency = 0.3
section.BorderSizePixel = 0
section.LayoutOrder = layoutOrder
section.AutomaticSize = Enum.AutomaticSize.Y
section.Parent = self.ContentScroll
local sectionCorner = Instance.new("UICorner")
sectionCorner.CornerRadius = UDim.new(0, 10)
sectionCorner.Parent = section
local sectionLayout = Instance.new("UIListLayout")
sectionLayout.SortOrder = Enum.SortOrder.LayoutOrder
sectionLayout.Padding = UDim.new(0, 8)
sectionLayout.Parent = section
local sectionPadding = Instance.new("UIPadding")
sectionPadding.PaddingLeft = UDim.new(0, 16)
sectionPadding.PaddingRight = UDim.new(0, 16)
sectionPadding.PaddingTop = UDim.new(0, 16)
sectionPadding.PaddingBottom = UDim.new(0, 16)
sectionPadding.Parent = section
local titleLabel = Instance.new("TextLabel")
titleLabel.Size = UDim2.new(1, 0, 0, 24)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.AccentColor
titleLabel.TextSize = 18
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.LayoutOrder = 0
titleLabel.Parent = section
for i, item in ipairs(items) do
local itemFrame = Instance.new("Frame")
itemFrame.Size = UDim2.new(1, 0, 0, 0)
itemFrame.BackgroundTransparency = 1
itemFrame.LayoutOrder = i
itemFrame.AutomaticSize = Enum.AutomaticSize.Y
itemFrame.Parent = section
local itemLabel = Instance.new("TextLabel")
itemLabel.Size = UDim2.new(1, 0, 0, 16)
itemLabel.BackgroundTransparency = 1
itemLabel.Text = item.label
itemLabel.TextColor3 = Theme.TextSecondary
itemLabel.TextSize = 12
itemLabel.Font = Enum.Font.Gotham
itemLabel.TextXAlignment = Enum.TextXAlignment.Left
itemLabel.TextYAlignment = Enum.TextYAlignment.Top
itemLabel.Parent = itemFrame
local itemValue = Instance.new("TextLabel")
itemValue.Size = UDim2.new(1, 0, 0, 0)
itemValue.Position = UDim2.new(0, 0, 0, 16)
itemValue.BackgroundTransparency = 1
itemValue.Text = item.value
itemValue.TextColor3 = item.color or Theme.TextColor
itemValue.TextSize = 15
itemValue.Font = Enum.Font.GothamBold
itemValue.TextXAlignment = Enum.TextXAlignment.Left
itemValue.TextYAlignment = Enum.TextYAlignment.Top
itemValue.TextWrapped = true
itemValue.AutomaticSize = Enum.AutomaticSize.Y
itemValue.Parent = itemFrame
end
return section
end
-- Use Junkie runtime variables with fallback support
local isPremium = false
local expiresAt = nil
local discordId = nil
local createdAt = nil
local serviceName = nil
local isInvalidated = false
local isHwidBanned = false
pcall(function()
-- Try modern Junkie runtime variables (JD_*) first
if JD_IS_PREMIUM ~= nil then
isPremium = JD_IS_PREMIUM or false
end
if JD_EXPIRES_AT ~= nil then
expiresAt = JD_EXPIRES_AT
end
if JD_DISCORD_ID ~= nil then
discordId = JD_DISCORD_ID
end
if JD_CREATED_AT ~= nil then
createdAt = JD_CREATED_AT
end
if JD_SERVICE_NAME ~= nil then
serviceName = JD_SERVICE_NAME
end
if JD_IS_INVALIDATED ~= nil then
isInvalidated = JD_IS_INVALIDATED or false
end
if JD_IS_HWID_BANNED ~= nil then
isHwidBanned = JD_IS_HWID_BANNED or false
end
-- Fallback to JunkieCore if JD_* variables are not set
if not isPremium and not expiresAt and JunkieCore then
isPremium = JunkieCore.GetIsPremium() or false
expiresAt = JunkieCore.GetExpiresAt()
discordId = JunkieCore.GetDiscordId()
createdAt = JunkieCore.GetCreatedAt()
serviceName = JunkieCore.GetServiceName()
isInvalidated = JunkieCore.GetIsInvalidated() or false
isHwidBanned = JunkieCore.GetIsHwidBanned() or false
end
end)
if not isPremium and userData.isVIP then
isPremium = userData.isVIP
end
if (not expiresAt or expiresAt == 0) and userData.expiresAt then
expiresAt = userData.expiresAt
end
if not discordId and userData.discordId then
discordId = userData.discordId
end
if not createdAt and userData.createdAt then
createdAt = userData.createdAt
end
if not serviceName and userData.serviceId then
serviceName = userData.serviceId
end
if expiresAt and (expiresAt <= 0 or type(expiresAt) ~= "number") then
expiresAt = nil
end
-- Detect if timestamp is in seconds or milliseconds
-- Timestamps after year 2000 in seconds: > 946684800
-- Timestamps after year 2000 in milliseconds: > 946684800000
local function normalizeTimestamp(timestamp)
if not timestamp or type(timestamp) ~= "number" or timestamp <= 0 then
return nil
end
-- If timestamp is less than 10 billion, it's in seconds (before year 2286)
-- If timestamp is greater, it's in milliseconds
if timestamp < 10000000000 then
return timestamp * 1000 -- Convert seconds to milliseconds
else
return timestamp -- Already in milliseconds
end
end
expiresAt = normalizeTimestamp(expiresAt)
createdAt = normalizeTimestamp(createdAt)
local expirationText = "Never"
local daysLeft = "Permanent"
if expiresAt and type(expiresAt) == "number" and expiresAt > 0 then
local currentTime = os.time() * 1000
local timeLeft = (expiresAt - currentTime) / 1000
if timeLeft > 0 then
local days = math.floor(timeLeft / 86400)
local hours = math.floor((timeLeft % 86400) / 3600)
local minutes = math.floor((timeLeft % 3600) / 60)
if days > 0 then
daysLeft = string.format("%d days, %d hours", days, hours)
elseif hours > 0 then
daysLeft = string.format("%d hours, %d minutes", hours, minutes)
else
daysLeft = string.format("%d minutes", minutes)
end
expirationText = os.date("%Y-%m-%d %H:%M", expiresAt / 1000)
else
expirationText = "Expired"
daysLeft = "Expired"
end
else
expirationText = "Never"
daysLeft = "Permanent"
end
local createdText = "Unknown"
if createdAt and type(createdAt) == "number" and createdAt > 0 then
createdText = os.date("%Y-%m-%d %H:%M", createdAt / 1000)
end
local aboutSection = Instance.new("Frame")
aboutSection.Name = "ProfileSection_About"
aboutSection.Size = UDim2.new(1, 0, 0, 0)
aboutSection.BackgroundColor3 = Theme.SidebarBackground
aboutSection.BackgroundTransparency = 0.3
aboutSection.BorderSizePixel = 0
aboutSection.LayoutOrder = 1
aboutSection.AutomaticSize = Enum.AutomaticSize.Y
aboutSection.Parent = self.ContentScroll
local aboutCorner = Instance.new("UICorner")
aboutCorner.CornerRadius = UDim.new(0, 10)
aboutCorner.Parent = aboutSection
local aboutPadding = Instance.new("UIPadding")
aboutPadding.PaddingLeft = UDim.new(0, 20)
aboutPadding.PaddingRight = UDim.new(0, 20)
aboutPadding.PaddingTop = UDim.new(0, 20)
aboutPadding.PaddingBottom = UDim.new(0, 20)
aboutPadding.Parent = aboutSection
local headerContainer = Instance.new("Frame")
headerContainer.Size = UDim2.new(1, 0, 0, 80)
headerContainer.BackgroundTransparency = 1
headerContainer.Parent = aboutSection
local logo = Instance.new("ImageLabel")
logo.Name = "Logo"
logo.Size = UDim2.new(0, 80, 0, 80)
logo.Position = UDim2.new(0, 0, 0, 0)
logo.BackgroundTransparency = 1
logo.Image = "rbxassetid://88183417608118"
logo.ImageColor3 = Theme.AccentColor
logo.Parent = headerContainer
local textContainer = Instance.new("Frame")
textContainer.Size = UDim2.new(1, -90, 1, 0)
textContainer.Position = UDim2.new(0, 90, 0, 0)
textContainer.BackgroundTransparency = 1
textContainer.Parent = headerContainer
local titleLabel = Instance.new("TextLabel")
titleLabel.Size = UDim2.new(1, 0, 0, 32)
titleLabel.Position = UDim2.new(0, 0, 0, 8)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = "Gatinero Hub"
titleLabel.TextColor3 = Theme.TextColor
titleLabel.TextSize = 28
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.Parent = textContainer
local subtitleLabel = Instance.new("TextLabel")
subtitleLabel.Size = UDim2.new(1, 0, 0, 18)
subtitleLabel.Position = UDim2.new(0, 0, 0, 42)
subtitleLabel.BackgroundTransparency = 1
subtitleLabel.Text = "Mount Menu • V2.4.0 • 090126"
subtitleLabel.TextColor3 = Theme.TextSecondary
subtitleLabel.TextSize = 14
subtitleLabel.Font = Enum.Font.Gotham
subtitleLabel.TextXAlignment = Enum.TextXAlignment.Left
subtitleLabel.Parent = textContainer
local authorLabel = Instance.new("TextLabel")
authorLabel.Size = UDim2.new(1, 0, 0, 16)
authorLabel.Position = UDim2.new(0, 0, 0, 62)
authorLabel.BackgroundTransparency = 1
authorLabel.Text = "Author: Bousterd"
authorLabel.TextColor3 = Theme.TextSecondary
authorLabel.TextSize = 13
authorLabel.Font = Enum.Font.Gotham
authorLabel.TextXAlignment = Enum.TextXAlignment.Left
authorLabel.Parent = textContainer
local keyStatusColor = isPremium and Theme.SuccessColor or Theme.WarningColor
local statusItems = {
{label = "Status", value = isPremium and "VIP" or "FREE", color = keyStatusColor},
{label = "Expires", value = expirationText},
{label = "Time Remaining", value = daysLeft},
{label = "Key Created", value = createdText},
}
if isInvalidated then
table.insert(statusItems, {label = "Warning", value = "⚠️ KEY INVALIDATED", color = Theme.ErrorColor})
end
if isHwidBanned then
table.insert(statusItems, {label = "Warning", value = "🚫 HWID BANNED", color = Theme.ErrorColor})
end
-- Create separate buttons section (LayoutOrder 1.5 to appear between header and status)
local buttonsSection = Instance.new("Frame")
buttonsSection.Name = "ProfileSection_SocialButtons"
buttonsSection.Size = UDim2.new(1, 0, 0, 44)
buttonsSection.BackgroundTransparency = 1
buttonsSection.BorderSizePixel = 0
buttonsSection.LayoutOrder = 1.5
buttonsSection.Parent = self.ContentScroll
-- Join Discord Button
local discordButton = Instance.new("TextButton")
discordButton.Name = "DiscordButton"
discordButton.Size = UDim2.new(0.5, -4, 1, 0)
discordButton.Position = UDim2.new(0, 0, 0, 0)
discordButton.BackgroundColor3 = Theme.SidebarBackground
discordButton.BorderSizePixel = 0
discordButton.Text = ""
discordButton.AutoButtonColor = false
discordButton.Parent = buttonsSection
local discordCorner = Instance.new("UICorner")
discordCorner.CornerRadius = UDim.new(0, 10)
discordCorner.Parent = discordButton
local discordIconContainer = Instance.new("Frame")
discordIconContainer.Name = "IconContainer"
discordIconContainer.Size = UDim2.new(0, 18, 0, 18)
discordIconContainer.Position = UDim2.new(0, 12, 0.5, -9)
discordIconContainer.BackgroundTransparency = 1
discordIconContainer.Parent = discordButton
LoadLucideIcon("message-circle", discordIconContainer, Theme.TextColor)
local discordLabel = Instance.new("TextLabel")
discordLabel.Size = UDim2.new(1, -40, 1, 0)
discordLabel.Position = UDim2.new(0, 35, 0, 0)
discordLabel.BackgroundTransparency = 1
discordLabel.Text = "Join Discord"
discordLabel.TextColor3 = Theme.TextColor
discordLabel.TextSize = 14
discordLabel.Font = Enum.Font.GothamSemibold
discordLabel.TextXAlignment = Enum.TextXAlignment.Left
discordLabel.Parent = discordButton
-- Website Button
local websiteButton = Instance.new("TextButton")
websiteButton.Name = "WebsiteButton"
websiteButton.Size = UDim2.new(0.5, -4, 1, 0)
websiteButton.Position = UDim2.new(0.5, 4, 0, 0)
websiteButton.BackgroundColor3 = Theme.SidebarBackground
websiteButton.BorderSizePixel = 0
websiteButton.Text = ""
websiteButton.AutoButtonColor = false
websiteButton.Parent = buttonsSection
local websiteCorner = Instance.new("UICorner")
websiteCorner.CornerRadius = UDim.new(0, 10)
websiteCorner.Parent = websiteButton
local websiteIconContainer = Instance.new("Frame")
websiteIconContainer.Name = "IconContainer"
websiteIconContainer.Size = UDim2.new(0, 18, 0, 18)
websiteIconContainer.Position = UDim2.new(0, 12, 0.5, -9)
websiteIconContainer.BackgroundTransparency = 1
websiteIconContainer.Parent = websiteButton
LoadLucideIcon("globe", websiteIconContainer, Theme.TextColor)
local websiteLabel = Instance.new("TextLabel")
websiteLabel.Size = UDim2.new(1, -40, 1, 0)
websiteLabel.Position = UDim2.new(0, 35, 0, 0)
websiteLabel.BackgroundTransparency = 1
websiteLabel.Text = "Website"
websiteLabel.TextColor3 = Theme.TextColor
websiteLabel.TextSize = 14
websiteLabel.Font = Enum.Font.GothamSemibold
websiteLabel.TextXAlignment = Enum.TextXAlignment.Left
websiteLabel.Parent = websiteButton
-- Button hover and click effects (matching regular buttons)
discordButton.MouseEnter:Connect(function()
CreateTween(discordButton, {BackgroundColor3 = Theme.AccentHover})
CreateTween(discordLabel, {TextColor3 = Color3.fromRGB(255, 255, 255)})
if discordIconContainer:FindFirstChildOfClass("ImageLabel") then
CreateTween(discordIconContainer:FindFirstChildOfClass("ImageLabel"), {ImageColor3 = Color3.fromRGB(255, 255, 255)})
end
end)
discordButton.MouseLeave:Connect(function()
CreateTween(discordButton, {BackgroundColor3 = Theme.SidebarBackground})
CreateTween(discordLabel, {TextColor3 = Theme.TextColor})
if discordIconContainer:FindFirstChildOfClass("ImageLabel") then
CreateTween(discordIconContainer:FindFirstChildOfClass("ImageLabel"), {ImageColor3 = Theme.TextColor})
end
end)
discordButton.MouseButton1Click:Connect(function()
CreateTween(discordButton, {BackgroundColor3 = Theme.AccentColor}, TweenPresets.Fast)
CreateTween(discordLabel, {TextColor3 = Color3.fromRGB(255, 255, 255)}, TweenPresets.Fast)
task.wait(0.15)
if discordButton and discordButton.Parent then
CreateTween(discordButton, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
CreateTween(discordLabel, {TextColor3 = Theme.TextColor}, TweenPresets.Fast)
end
local discordInvite = "discord.gg/z2jpWZ4nwx"
if setclipboard then
setclipboard("https://" .. discordInvite)
Library:Notify({
Title = "Discord Link Copied!",
Description = "Discord invite link copied to clipboard: " .. discordInvite,
Duration = 3
})
else
Library:Notify({
Title = "Join Discord",
Description = "Discord: " .. discordInvite,
Duration = 5
})
end
end)
websiteButton.MouseEnter:Connect(function()
CreateTween(websiteButton, {BackgroundColor3 = Theme.AccentHover})
CreateTween(websiteLabel, {TextColor3 = Color3.fromRGB(255, 255, 255)})
if websiteIconContainer:FindFirstChildOfClass("ImageLabel") then
CreateTween(websiteIconContainer:FindFirstChildOfClass("ImageLabel"), {ImageColor3 = Color3.fromRGB(255, 255, 255)})
end
end)
websiteButton.MouseLeave:Connect(function()
CreateTween(websiteButton, {BackgroundColor3 = Theme.SidebarBackground})
CreateTween(websiteLabel, {TextColor3 = Theme.TextColor})
if websiteIconContainer:FindFirstChildOfClass("ImageLabel") then
CreateTween(websiteIconContainer:FindFirstChildOfClass("ImageLabel"), {ImageColor3 = Theme.TextColor})
end
end)
websiteButton.MouseButton1Click:Connect(function()
CreateTween(websiteButton, {BackgroundColor3 = Theme.AccentColor}, TweenPresets.Fast)
CreateTween(websiteLabel, {TextColor3 = Color3.fromRGB(255, 255, 255)}, TweenPresets.Fast)
task.wait(0.15)
if websiteButton and websiteButton.Parent then
CreateTween(websiteButton, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
CreateTween(websiteLabel, {TextColor3 = Theme.TextColor}, TweenPresets.Fast)
end
local websiteUrl = "raw.gatinero.xyz"
if setclipboard then
setclipboard("https://" .. websiteUrl)
Library:Notify({
Title = "Website Link Copied!",
Description = "Website link copied to clipboard: " .. websiteUrl,
Duration = 3
})
else
Library:Notify({
Title = "Visit Website",
Description = "Website: " .. websiteUrl,
Duration = 5
})
end
end)
createInfoSection("Status", statusItems, 2)
createInfoSection("User Information", {
{label = "Display Name", value = _G.HideUsernameEnabled and "Gatinero_Hub" or LocalPlayer.DisplayName},
{label = "Username", value = _G.HideUsernameEnabled and "dsc.gg/gatinero" or ("@" .. LocalPlayer.Name)},
{label = "Account Age", value = LocalPlayer.AccountAge .. " days"},
{label = "User ID", value = tostring(LocalPlayer.UserId)},
{label = "Discord ID", value = discordId or "Not Linked"},
}, 3)
-- Get map/place information
local placeId = game.PlaceId
local placeName = "Loading..."
local mapInfoSection = createInfoSection("Map Information", {
{label = "Place Name", value = placeName},
{label = "Place ID", value = tostring(placeId)},
}, 4)
-- Try to get place name asynchronously and update the label
task.spawn(function()
pcall(function()
local MarketplaceService = game:GetService("MarketplaceService")
local productInfo = MarketplaceService:GetProductInfo(placeId)
placeName = productInfo.Name
-- Find and update the Place Name value label
for _, child in ipairs(mapInfoSection:GetChildren()) do
if child:IsA("Frame") then
for _, subChild in ipairs(child:GetChildren()) do
if subChild:IsA("TextLabel") and subChild.Text == "Loading..." then
subChild.Text = placeName
break
end
end
end
end
end)
end)
end
function Window:AddTab(name, iconId)
if self.IsDestroyed then
warn("GAeroUI: Cannot add tab to destroyed window")
return nil
end
if not name or type(name) ~= "string" or name == "" then
warn("GAeroUI: Tab name must be a non-empty string")
return nil
end
local tab = {}
tab.Name = name
tab.Elements = {}
tab.Window = self
local tabButton = Instance.new("TextButton")
tabButton.Name = name
tabButton.Size = UDim2.new(1, 0, 0, 38)
tabButton.BackgroundColor3 = Theme.SidebarBackground
tabButton.BackgroundTransparency = 1
tabButton.BorderSizePixel = 0
tabButton.Text = ""
tabButton.AutoButtonColor = false
tabButton.Parent = self.TabContainer
local tabCorner = Instance.new("UICorner")
tabCorner.CornerRadius = UDim.new(0, 8)
tabCorner.Parent = tabButton
local icon = Instance.new("ImageLabel")
if iconId and iconId:match("^lucide%-") then
local iconName = iconId:gsub("^lucide%-", "")
local iconContainer = Instance.new("Frame")
iconContainer.Name = "IconContainer"
iconContainer.Size = UDim2.new(0, 20, 0, 20)
iconContainer.Position = UDim2.new(0, 10, 0.5, -10)
iconContainer.BackgroundTransparency = 1
iconContainer.Parent = tabButton
LoadLucideIcon(iconName, iconContainer, Theme.TextSecondary)
else
icon.Name = "Icon"
icon.Size = UDim2.new(0, 20, 0, 20)
icon.Position = UDim2.new(0, 10, 0.5, -10)
icon.BackgroundTransparency = 1
icon.ImageColor3 = Theme.TextSecondary
icon.Image = iconId or "rbxassetid://7733960981"
icon.Parent = tabButton
end
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(1, -45, 1, 0)
label.Position = UDim2.new(0, 38, 0, 0)
label.BackgroundTransparency = 1
label.Text = name
label.TextColor3 = Theme.TextSecondary
label.TextSize = 14
label.Font = Enum.Font.GothamMedium
label.TextXAlignment = Enum.TextXAlignment.Left
label.Parent = tabButton
tab.Button = tabButton
tab.Icon = icon
tab.Label = label
tabButton.MouseButton1Click:Connect(function()
self:SelectTab(tab)
end)
tabButton.MouseEnter:Connect(function()
if self.CurrentTab ~= tab then
CreateTween(tabButton, {BackgroundTransparency = 0.9})
CreateTween(icon, {ImageColor3 = Theme.TextColor})
CreateTween(label, {TextColor3 = Theme.TextColor})
end
end)
tabButton.MouseLeave:Connect(function()
if self.CurrentTab ~= tab then
CreateTween(tabButton, {BackgroundTransparency = 1})
CreateTween(icon, {ImageColor3 = Theme.TextSecondary})
CreateTween(label, {TextColor3 = Theme.TextSecondary})
end
end)
table.insert(self.Tabs, tab)
if #self.Tabs == 1 then
self:SelectTab(tab)
end
-- Update canvas size after adding tab (important for mobile scrolling)
task.spawn(function()
task.wait(0.05)
if self.TabContainer then
local tabLayout = self.TabContainer:FindFirstChildOfClass("UIListLayout")
if tabLayout then
local contentHeight = tabLayout.AbsoluteContentSize.Y
local padding = self.IsMobile and 30 or 20
self.TabContainer.CanvasSize = UDim2.new(0, 0, 0, contentHeight + padding)
end
end
end)
return setmetatable(tab, {__index = self:GetTabMethods()})
end
function Window:SelectTab(tab)
if self.InProfileView then
for _, child in ipairs(self.ContentScroll:GetChildren()) do
if child:IsA("Frame") and child.Name:match("ProfileSection_") then
child:Destroy()
end
end
self.InProfileView = false
end
-- Close any open dropdowns when switching tabs
for _, child in ipairs(self.ScreenGui:GetChildren()) do
if child:IsA("ScrollingFrame") and child.Name:match("^OptionsList_") then
child.Visible = false
child.Size = UDim2.new(0, child.AbsoluteSize.X, 0, 0)
end
end
if self.CurrentTab then
CreateTween(self.CurrentTab.Button, {BackgroundTransparency = 1})
CreateTween(self.CurrentTab.Icon, {ImageColor3 = Theme.TextSecondary})
CreateTween(self.CurrentTab.Label, {TextColor3 = Theme.TextSecondary})
for _, element in ipairs(self.CurrentTab.Elements) do
if element.Instance then
element.Instance.Visible = false
end
end
end
self.CurrentTab = tab
CreateTween(tab.Button, {BackgroundTransparency = 0.85, BackgroundColor3 = Theme.AccentColor})
CreateTween(tab.Icon, {ImageColor3 = Theme.TextColor})
CreateTween(tab.Label, {TextColor3 = Theme.TextColor})
for _, element in ipairs(tab.Elements) do
if element.Instance then
local manuallyHidden = element.Instance:GetAttribute("ManuallyHidden")
if not manuallyHidden then
element.Instance.Visible = true
end
end
end
end
function Window:Tag(config)
if self.IsDestroyed then
warn("GAeroUI: Cannot create tag on destroyed window")
return nil
end
config = config or {}
local title = config.Title or "Tag"
local icon = config.Icon
local color = config.Color or Theme.AccentColor
local radius = config.Radius or 13
local titleBar = self.MainFrame:FindFirstChild("TitleBar")
if not titleBar then
warn("GAeroUI: TitleBar not found")
return nil
end
local tagFrame = Instance.new("Frame")
tagFrame.Name = "Tag_" .. title
tagFrame.Size = UDim2.new(0, 0, 0, 24)
tagFrame.Position = UDim2.new(0, 10, 0.5, -12)
tagFrame.BackgroundColor3 = color
tagFrame.BackgroundTransparency = 0.2
tagFrame.BorderSizePixel = 0
tagFrame.AutomaticSize = Enum.AutomaticSize.X
tagFrame.ZIndex = 11
tagFrame.Parent = titleBar
local tagCorner = Instance.new("UICorner")
tagCorner.CornerRadius = UDim.new(0, radius)
tagCorner.Parent = tagFrame
local tagLayout = Instance.new("UIListLayout")
tagLayout.FillDirection = Enum.FillDirection.Horizontal
tagLayout.VerticalAlignment = Enum.VerticalAlignment.Center
tagLayout.Padding = UDim.new(0, 6)
tagLayout.Parent = tagFrame
local tagPadding = Instance.new("UIPadding")
tagPadding.PaddingLeft = UDim.new(0, 10)
tagPadding.PaddingRight = UDim.new(0, 10)
tagPadding.Parent = tagFrame
if icon then
local iconContainer = Instance.new("Frame")
iconContainer.Name = "IconContainer"
iconContainer.Size = UDim2.new(0, 16, 0, 16)
iconContainer.BackgroundTransparency = 1
iconContainer.LayoutOrder = 1
iconContainer.Parent = tagFrame
LoadLucideIcon(icon, iconContainer, Theme.TextColor)
end
local tagLabel = Instance.new("TextLabel")
tagLabel.Name = "Label"
tagLabel.Size = UDim2.new(0, 0, 0, 0)
tagLabel.AutomaticSize = Enum.AutomaticSize.XY
tagLabel.BackgroundTransparency = 1
tagLabel.Text = title
tagLabel.TextColor3 = Theme.TextColor
tagLabel.TextSize = 12
tagLabel.Font = Enum.Font.GothamBold
tagLabel.LayoutOrder = 2
tagLabel.Parent = tagFrame
return {
Frame = tagFrame,
SetTitle = function(newTitle)
tagLabel.Text = newTitle
end,
SetColor = function(newColor)
tagFrame.BackgroundColor3 = newColor
end,
Destroy = function()
if tagFrame and tagFrame.Parent then
tagFrame:Destroy()
end
end
}
end
function Window:Divider()
if self.IsDestroyed then
warn("GAeroUI: Cannot add divider to destroyed window")
return nil
end
local divider = Instance.new("Frame")
divider.Name = "Divider"
divider.Size = UDim2.new(1, -10, 0, 1)
divider.BackgroundColor3 = Theme.SeparatorColor
divider.BorderSizePixel = 0
divider.Parent = self.TabContainer
local dividerPadding = Instance.new("UIPadding")
dividerPadding.PaddingLeft = UDim.new(0, 5)
dividerPadding.PaddingRight = UDim.new(0, 5)
dividerPadding.PaddingTop = UDim.new(0, 4)
dividerPadding.PaddingBottom = UDim.new(0, 4)
dividerPadding.Parent = divider
return divider
end
function Window:Space(height)
if self.IsDestroyed then
warn("GAeroUI: Cannot add space to destroyed window")
return nil
end
height = height or 10
local space = Instance.new("Frame")
space.Name = "Space"
space.Size = UDim2.new(1, 0, 0, height)
space.BackgroundTransparency = 1
space.Parent = self.TabContainer
return space
end
function Window:Section(config)
if self.IsDestroyed then
warn("GAeroUI: Cannot add tab section to destroyed window")
return nil
end
config = config or {}
local title = config.Title or "Section"
local icon = config.Icon
local iconThemed = config.IconThemed or false
local opened = config.Opened ~= false
local sectionContainer = Instance.new("Frame")
sectionContainer.Name = "TabSection_" .. title
sectionContainer.Size = UDim2.new(1, 0, 0, 0)
sectionContainer.BackgroundTransparency = 1
sectionContainer.AutomaticSize = Enum.AutomaticSize.Y
sectionContainer.Parent = self.TabContainer
local sectionLayout = Instance.new("UIListLayout")
sectionLayout.SortOrder = Enum.SortOrder.LayoutOrder
sectionLayout.Padding = UDim.new(0, 6)
sectionLayout.Parent = sectionContainer
local headerButton = Instance.new("TextButton")
headerButton.Name = "SectionHeader"
headerButton.Size = UDim2.new(1, 0, 0, 32)
headerButton.BackgroundColor3 = Theme.SidebarBackground
headerButton.BackgroundTransparency = 0.7
headerButton.BorderSizePixel = 0
headerButton.Text = ""
headerButton.AutoButtonColor = false
headerButton.LayoutOrder = 1
headerButton.Parent = sectionContainer
local headerCorner = Instance.new("UICorner")
headerCorner.CornerRadius = UDim.new(0, 8)
headerCorner.Parent = headerButton
if icon then
local iconContainer = Instance.new("Frame")
iconContainer.Name = "IconContainer"
iconContainer.Size = UDim2.new(0, 18, 0, 18)
iconContainer.Position = UDim2.new(0, 10, 0.5, -9)
iconContainer.BackgroundTransparency = 1
iconContainer.Parent = headerButton
if icon:match("^lucide%-") then
local iconName = icon:gsub("^lucide%-", "")
LoadLucideIcon(iconName, iconContainer, iconThemed and Theme.AccentColor or Theme.TextSecondary)
elseif icon:match("^rbxassetid://") or icon:match("^http") then
local iconImage = Instance.new("ImageLabel")
iconImage.Size = UDim2.new(1, 0, 1, 0)
iconImage.BackgroundTransparency = 1
iconImage.Image = icon
iconImage.ImageColor3 = iconThemed and Theme.AccentColor or Theme.TextSecondary
iconImage.Parent = iconContainer
else
LoadLucideIcon(icon, iconContainer, iconThemed and Theme.AccentColor or Theme.TextSecondary)
end
end
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, icon and -60 or -36, 1, 0)
titleLabel.Position = UDim2.new(0, icon and 36 or 10, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.TextSecondary
titleLabel.TextSize = 12
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.TextTruncate = Enum.TextTruncate.AtEnd
titleLabel.Parent = headerButton
local arrowContainer = Instance.new("Frame")
arrowContainer.Name = "ArrowContainer"
arrowContainer.Size = UDim2.new(0, 14, 0, 14)
arrowContainer.Position = UDim2.new(1, -24, 0.5, -7)
arrowContainer.BackgroundTransparency = 1
arrowContainer.Rotation = opened and 0 or -90
arrowContainer.Parent = headerButton
LoadLucideIcon("chevron-down", arrowContainer, Theme.TextSecondary)
local contentContainer = Instance.new("Frame")
contentContainer.Name = "SectionContent"
contentContainer.Size = UDim2.new(1, 0, 0, 0)
contentContainer.BackgroundTransparency = 1
contentContainer.Visible = opened
contentContainer.AutomaticSize = Enum.AutomaticSize.Y
contentContainer.LayoutOrder = 2
contentContainer.Parent = sectionContainer
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 6)
contentLayout.Parent = contentContainer
headerButton.MouseButton1Click:Connect(function()
opened = not opened
contentContainer.Visible = opened
CreateTween(arrowContainer, {
Rotation = opened and 0 or -90
}, TweenPresets.Fast)
end)
headerButton.MouseEnter:Connect(function()
CreateTween(headerButton, {BackgroundTransparency = 0.5}, TweenPresets.Fast)
end)
headerButton.MouseLeave:Connect(function()
CreateTween(headerButton, {BackgroundTransparency = 0.7}, TweenPresets.Fast)
end)
return {
Container = sectionContainer,
ContentContainer = contentContainer,
AddTab = function(name, iconId)
return self:AddTab(name, iconId)
end
}
end
function Window:Dialog(config)
if self.IsDestroyed then
warn("GAeroUI: Cannot create dialog on destroyed window")
return nil
end
config = config or {}
local title = config.Title or "Dialog"
local content = config.Content or ""
local icon = config.Icon
local iconThemed = config.IconThemed or false
local buttons = config.Buttons or {{Title = "OK"}}
local dialogOverlay = Instance.new("Frame")
dialogOverlay.Name = "DialogOverlay"
dialogOverlay.Size = UDim2.new(1, 0, 1, 0)
dialogOverlay.Position = UDim2.new(0, 0, 0, 0)
dialogOverlay.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
dialogOverlay.BackgroundTransparency = 1
dialogOverlay.BorderSizePixel = 0
dialogOverlay.ZIndex = 1000
dialogOverlay.Parent = self.ScreenGui
local dialogContainer = Instance.new("Frame")
dialogContainer.Name = "DialogContainer"
dialogContainer.Size = UDim2.new(0, 400, 0, 0)
dialogContainer.Position = UDim2.new(0.5, -200, 0.5, 0)
dialogContainer.AnchorPoint = Vector2.new(0.5, 0.5)
dialogContainer.BackgroundColor3 = Theme.MainBackground
dialogContainer.BackgroundTransparency = 0.1
dialogContainer.BorderSizePixel = 0
dialogContainer.ClipsDescendants = true
dialogContainer.ZIndex = 1001
dialogContainer.Parent = dialogOverlay
local dialogCorner = Instance.new("UICorner")
dialogCorner.CornerRadius = UDim.new(0, 16)
dialogCorner.Parent = dialogContainer
local dialogStroke = Instance.new("UIStroke")
dialogStroke.Color = Theme.SeparatorColor
dialogStroke.Transparency = 0.3
dialogStroke.Thickness = 1
dialogStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
dialogStroke.Parent = dialogContainer
ApplyGlassmorphism(dialogContainer)
local contentArea = Instance.new("Frame")
contentArea.Name = "ContentArea"
contentArea.Size = UDim2.new(1, -48, 1, -48)
contentArea.Position = UDim2.new(0, 24, 0, 24)
contentArea.BackgroundTransparency = 1
contentArea.ZIndex = 1002
contentArea.Parent = dialogContainer
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 16)
contentLayout.FillDirection = Enum.FillDirection.Vertical
contentLayout.Parent = contentArea
local headerFrame = Instance.new("Frame")
headerFrame.Name = "Header"
headerFrame.Size = UDim2.new(1, 0, 0, 32)
headerFrame.BackgroundTransparency = 1
headerFrame.LayoutOrder = 1
headerFrame.Parent = contentArea
if icon then
local iconContainer = Instance.new("Frame")
iconContainer.Name = "IconContainer"
iconContainer.Size = UDim2.new(0, 32, 0, 32)
iconContainer.Position = UDim2.new(0, 0, 0, 0)
iconContainer.BackgroundTransparency = 1
iconContainer.Parent = headerFrame
if icon:match("^lucide%-") then
local iconName = icon:gsub("^lucide%-", "")
LoadLucideIcon(iconName, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
elseif icon:match("^rbxassetid://") or icon:match("^http") then
local iconImage = Instance.new("ImageLabel")
iconImage.Size = UDim2.new(1, 0, 1, 0)
iconImage.BackgroundTransparency = 1
iconImage.Image = icon
iconImage.ImageColor3 = iconThemed and Theme.AccentColor or Theme.TextColor
iconImage.Parent = iconContainer
else
LoadLucideIcon(icon, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
end
end
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, icon and -40 or 0, 1, 0)
titleLabel.Position = UDim2.new(0, icon and 40 or 0, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.TextColor
titleLabel.TextSize = 18
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.TextTruncate = Enum.TextTruncate.AtEnd
titleLabel.Parent = headerFrame
local contentLabel = Instance.new("TextLabel")
contentLabel.Name = "ContentText"
contentLabel.Size = UDim2.new(1, 0, 0, 0)
contentLabel.BackgroundTransparency = 1
contentLabel.Text = content
contentLabel.TextColor3 = Theme.TextSecondary
contentLabel.TextSize = 14
contentLabel.Font = Enum.Font.Gotham
contentLabel.TextXAlignment = Enum.TextXAlignment.Left
contentLabel.TextYAlignment = Enum.TextYAlignment.Top
contentLabel.TextWrapped = true
contentLabel.AutomaticSize = Enum.AutomaticSize.Y
contentLabel.LayoutOrder = 2
contentLabel.Parent = contentArea
local buttonsFrame = Instance.new("Frame")
buttonsFrame.Name = "Buttons"
buttonsFrame.Size = UDim2.new(1, 0, 0, 44)
buttonsFrame.BackgroundTransparency = 1
buttonsFrame.LayoutOrder = 3
buttonsFrame.Parent = contentArea
local buttonsLayout = Instance.new("UIListLayout")
buttonsLayout.SortOrder = Enum.SortOrder.LayoutOrder
buttonsLayout.Padding = UDim.new(0, 8)
buttonsLayout.FillDirection = Enum.FillDirection.Horizontal
buttonsLayout.HorizontalAlignment = Enum.HorizontalAlignment.Right
buttonsLayout.Parent = buttonsFrame
local function closeDialog()
CreateTween(dialogOverlay, {BackgroundTransparency = 1}, TweenPresets.Fast)
CreateTween(dialogContainer, {
Size = UDim2.new(0, 400, 0, 0),
Position = UDim2.new(0.5, -200, 0.5, 0)
}, TweenPresets.Fast)
task.wait(0.2)
if dialogOverlay and dialogOverlay.Parent then
dialogOverlay:Destroy()
end
end
for i, buttonConfig in ipairs(buttons) do
local btnTitle = buttonConfig.Title or "Button"
local btnIcon = buttonConfig.Icon
local btnVariant = buttonConfig.Variant or "Primary"
local btnCallback = buttonConfig.Callback
local button = Instance.new("TextButton")
button.Name = "DialogButton_" .. i
button.Size = UDim2.new(0, 100, 1, 0)
button.BackgroundColor3 = btnVariant == "Primary" and Theme.AccentColor or
btnVariant == "Secondary" and Theme.SidebarBackground or
Theme.MainBackground
button.BackgroundTransparency = btnVariant == "Tertiary" and 0.5 or 0
button.BorderSizePixel = 0
button.Text = ""
button.AutoButtonColor = false
button.LayoutOrder = i
button.Parent = buttonsFrame
local btnCorner = Instance.new("UICorner")
btnCorner.CornerRadius = UDim.new(0, 10)
btnCorner.Parent = button
if btnIcon then
local btnIconContainer = Instance.new("Frame")
btnIconContainer.Name = "IconContainer"
btnIconContainer.Size = UDim2.new(0, 16, 0, 16)
btnIconContainer.Position = UDim2.new(0, 8, 0.5, -8)
btnIconContainer.BackgroundTransparency = 1
btnIconContainer.Parent = button
LoadLucideIcon(btnIcon, btnIconContainer, Theme.TextColor)
end
local btnLabel = Instance.new("TextLabel")
btnLabel.Size = UDim2.new(1, btnIcon and -32 or -16, 1, 0)
btnLabel.Position = UDim2.new(0, btnIcon and 28 or 8, 0, 0)
btnLabel.BackgroundTransparency = 1
btnLabel.Text = btnTitle
btnLabel.TextColor3 = Theme.TextColor
btnLabel.TextSize = 13
btnLabel.Font = Enum.Font.GothamSemibold
btnLabel.TextXAlignment = Enum.TextXAlignment.Center
btnLabel.Parent = button
button.MouseButton1Click:Connect(function()
if btnCallback then
local success, err = pcall(btnCallback)
if not success then
warn("GAeroUI Dialog Button Error:", err)
end
end
closeDialog()
end)
button.MouseEnter:Connect(function()
CreateTween(button, {
BackgroundColor3 = btnVariant == "Primary" and Theme.AccentHover or Theme.AccentColor
})
end)
button.MouseLeave:Connect(function()
CreateTween(button, {
BackgroundColor3 = btnVariant == "Primary" and Theme.AccentColor or
btnVariant == "Secondary" and Theme.SidebarBackground or
Theme.MainBackground
})
end)
end
task.wait()
local finalHeight = contentLayout.AbsoluteContentSize.Y + 48
dialogContainer.Size = UDim2.new(0, 400, 0, 0)
CreateTween(dialogOverlay, {BackgroundTransparency = 0.5}, TweenPresets.Medium)
CreateTween(dialogContainer, {
Size = UDim2.new(0, 400, 0, finalHeight)
}, TweenPresets.Smooth)
return {
Close = closeDialog,
Show = function()
dialogOverlay.Visible = true
end
}
end
function Window:GetTabMethods()
local TabMethods = {}
function TabMethods:AddButton(text, callback)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add button to destroyed window")
return nil
end
if not text or type(text) ~= "string" or text == "" then
warn("GAeroUI: Button text must be a non-empty string")
return nil
end
if callback and type(callback) ~= "function" then
warn("GAeroUI: Button callback must be a function")
return nil
end
local buttonContainer = Instance.new("Frame")
buttonContainer.Name = "ButtonContainer_" .. text
buttonContainer.Size = UDim2.new(1, 0, 0, 44)
buttonContainer.BackgroundTransparency = 1
buttonContainer.Visible = (self.Window.CurrentTab == self)
buttonContainer.Parent = self.Window.ContentScroll
local button = Instance.new("TextButton")
button.Name = "Button"
button.Size = UDim2.new(1, 0, 1, 0)
button.BackgroundColor3 = Theme.SidebarBackground
button.BorderSizePixel = 0
button.Text = ""
button.AutoButtonColor = false
button.Parent = buttonContainer
local btnCorner = Instance.new("UICorner")
btnCorner.CornerRadius = UDim.new(0, 10)
btnCorner.Parent = button
local buttonLabel = Instance.new("TextLabel")
buttonLabel.Name = "Label"
buttonLabel.Size = UDim2.new(1, -24, 1, 0)
buttonLabel.Position = UDim2.new(0, 12, 0, 0)
buttonLabel.BackgroundTransparency = 1
buttonLabel.Text = text
buttonLabel.TextColor3 = Theme.TextColor
buttonLabel.TextSize = 14
buttonLabel.Font = Enum.Font.GothamSemibold
buttonLabel.TextXAlignment = Enum.TextXAlignment.Left
buttonLabel.TextTruncate = Enum.TextTruncate.AtEnd
buttonLabel.Parent = button
button.MouseButton1Click:Connect(function()
CreateTween(button, {BackgroundColor3 = Theme.AccentColor}, TweenPresets.Fast)
CreateTween(buttonLabel, {TextColor3 = Color3.fromRGB(255, 255, 255)}, TweenPresets.Fast)
task.wait(0.15)
if button and button.Parent then
CreateTween(button, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
CreateTween(buttonLabel, {TextColor3 = Theme.TextColor}, TweenPresets.Fast)
end
if callback then
local success, err = pcall(callback)
if not success then
warn("GAeroUI Button Error:", err)
end
end
end)
button.MouseEnter:Connect(function()
CreateTween(button, {BackgroundColor3 = Theme.AccentHover})
CreateTween(buttonLabel, {TextColor3 = Color3.fromRGB(255, 255, 255)})
end)
button.MouseLeave:Connect(function()
CreateTween(button, {BackgroundColor3 = Theme.SidebarBackground})
CreateTween(buttonLabel, {TextColor3 = Theme.TextColor})
end)
table.insert(self.Elements, {Instance = buttonContainer, Type = "Button"})
return buttonContainer
end
function TabMethods:AddToggle(text, defaultState, callback)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add toggle to destroyed window")
return nil
end
if not text or type(text) ~= "string" or text == "" then
warn("GAeroUI: Toggle text must be a non-empty string")
return nil
end
if callback and type(callback) ~= "function" then
warn("GAeroUI: Toggle callback must be a function")
return nil
end
defaultState = defaultState or false
if type(defaultState) ~= "boolean" then
warn("GAeroUI: Toggle defaultState must be a boolean, using false")
defaultState = false
end
local toggleContainer = Instance.new("Frame")
toggleContainer.Name = "ToggleContainer_" .. text
toggleContainer.Size = UDim2.new(1, 0, 0, 44)
toggleContainer.BackgroundTransparency = 1
toggleContainer.Visible = (self.Window.CurrentTab == self)
toggleContainer.Parent = self.Window.ContentScroll
local toggleFrame = Instance.new("Frame")
toggleFrame.Name = "ToggleFrame"
toggleFrame.Size = UDim2.new(1, 0, 1, 0)
toggleFrame.BackgroundColor3 = Theme.SidebarBackground
toggleFrame.BorderSizePixel = 0
toggleFrame.Parent = toggleContainer
local toggleCorner = Instance.new("UICorner")
toggleCorner.CornerRadius = UDim.new(0, 10)
toggleCorner.Parent = toggleFrame
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(1, -80, 1, 0)
label.Position = UDim2.new(0, 12, 0, 0)
label.BackgroundTransparency = 1
label.Text = text
label.TextColor3 = Theme.TextColor
label.TextSize = 14
label.Font = Enum.Font.GothamSemibold
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextTruncate = Enum.TextTruncate.AtEnd
label.Parent = toggleFrame
local toggleButton = Instance.new("TextButton")
toggleButton.Name = "ToggleButton"
toggleButton.Size = UDim2.new(0, 52, 0, 26)
toggleButton.Position = UDim2.new(1, -64, 0.5, -13)
toggleButton.BackgroundColor3 = defaultState and Theme.ToggleOn or Theme.ToggleOff
toggleButton.BorderSizePixel = 0
toggleButton.Text = ""
toggleButton.AutoButtonColor = false
toggleButton.Parent = toggleFrame
local toggleBtnCorner = Instance.new("UICorner")
toggleBtnCorner.CornerRadius = UDim.new(1, 0)
toggleBtnCorner.Parent = toggleButton
local toggleDot = Instance.new("Frame")
toggleDot.Name = "Dot"
toggleDot.Size = UDim2.new(0, 20, 0, 20)
toggleDot.Position = defaultState and UDim2.new(1, -23, 0.5, -10) or UDim2.new(0, 3, 0.5, -10)
toggleDot.BackgroundColor3 = Theme.TextColor
toggleDot.BorderSizePixel = 0
toggleDot.Parent = toggleButton
local dotCorner = Instance.new("UICorner")
dotCorner.CornerRadius = UDim.new(1, 0)
dotCorner.Parent = toggleDot
local toggled = defaultState
toggleButton.MouseButton1Click:Connect(function()
toggled = not toggled
CreateTween(toggleButton, {BackgroundColor3 = toggled and Theme.ToggleOn or Theme.ToggleOff}, TweenPresets.Medium)
CreateTween(toggleDot, {Position = toggled and UDim2.new(1, -23, 0.5, -10) or UDim2.new(0, 3, 0.5, -10)}, TweenPresets.Medium)
if callback then
local success, err = pcall(callback, toggled)
if not success then
warn("GAeroUI Toggle Error:", err)
end
end
end)
toggleFrame.MouseEnter:Connect(function()
CreateTween(toggleFrame, {BackgroundColor3 = Color3.fromRGB(30, 30, 45)})
end)
toggleFrame.MouseLeave:Connect(function()
CreateTween(toggleFrame, {BackgroundColor3 = Theme.SidebarBackground})
end)
table.insert(self.Elements, {Instance = toggleContainer, Type = "Toggle"})
return toggleContainer
end
function TabMethods:AddSeparator()
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add separator to destroyed window")
return nil
end
local separatorContainer = Instance.new("Frame")
separatorContainer.Name = "SeparatorContainer"
separatorContainer.Size = UDim2.new(1, 0, 0, 12)
separatorContainer.BackgroundTransparency = 1
separatorContainer.Visible = (self.Window.CurrentTab == self)
separatorContainer.Parent = self.Window.ContentScroll
local separator = Instance.new("Frame")
separator.Name = "Separator"
separator.Size = UDim2.new(1, 0, 0, 1)
separator.Position = UDim2.new(0, 0, 0.5, 0)
separator.BackgroundColor3 = Theme.SeparatorColor
separator.BorderSizePixel = 0
separator.Parent = separatorContainer
table.insert(self.Elements, {Instance = separatorContainer, Type = "Separator"})
return separatorContainer
end
function TabMethods:AddLabel(text)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add label to destroyed window")
return nil
end
local labelContainer = Instance.new("Frame")
labelContainer.Name = "LabelContainer"
labelContainer.Size = UDim2.new(1, 0, 0, 28)
labelContainer.BackgroundTransparency = 1
labelContainer.Visible = (self.Window.CurrentTab == self)
labelContainer.Parent = self.Window.ContentScroll
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(1, 0, 1, 0)
label.BackgroundTransparency = 1
label.Text = text or ""
label.TextColor3 = Theme.TextSecondary
label.TextSize = 13
label.Font = Enum.Font.Gotham
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextWrapped = true
label.Parent = labelContainer
table.insert(self.Elements, {Instance = labelContainer, Type = "Label"})
return {
UpdateText = function(newText)
label.Text = newText or ""
end,
SetColor = function(color)
label.TextColor3 = color
end,
Instance = labelContainer
}
end
function TabMethods:AddLabeledSeparator(text)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add labeled separator to destroyed window")
return nil
end
local separatorContainer = Instance.new("Frame")
separatorContainer.Name = "LabeledSeparatorContainer"
separatorContainer.Size = UDim2.new(1, 0, 0, 28)
separatorContainer.BackgroundTransparency = 1
separatorContainer.Visible = (self.Window.CurrentTab == self)
separatorContainer.Parent = self.Window.ContentScroll
local label = Instance.new("TextLabel")
label.Name = "SeparatorLabel"
label.Size = UDim2.new(0, 0, 1, 0)
label.Position = UDim2.new(0, 0, 0, 0)
label.BackgroundTransparency = 1
label.Text = text or ""
label.TextColor3 = Theme.TextSecondary
label.TextSize = 12
label.Font = Enum.Font.GothamBold
label.TextXAlignment = Enum.TextXAlignment.Left
label.AutomaticSize = Enum.AutomaticSize.X
label.Parent = separatorContainer
local leftSeparator = Instance.new("Frame")
leftSeparator.Name = "LeftSeparator"
leftSeparator.Size = UDim2.new(0, 0, 0, 1)
leftSeparator.Position = UDim2.new(0, 0, 0.5, 0)
leftSeparator.BackgroundColor3 = Theme.SeparatorColor
leftSeparator.BorderSizePixel = 0
leftSeparator.Visible = false
leftSeparator.Parent = separatorContainer
local rightSeparator = Instance.new("Frame")
rightSeparator.Name = "RightSeparator"
rightSeparator.Size = UDim2.new(1, -10, 0, 1)
rightSeparator.Position = UDim2.new(0, 0, 0.5, 0)
rightSeparator.BackgroundColor3 = Theme.SeparatorColor
rightSeparator.BorderSizePixel = 0
rightSeparator.Parent = separatorContainer
label:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
local labelWidth = label.AbsoluteSize.X
if labelWidth > 0 then
leftSeparator.Visible = false
rightSeparator.Size = UDim2.new(1, -(labelWidth + 10), 0, 1)
rightSeparator.Position = UDim2.new(0, labelWidth + 10, 0.5, 0)
else
leftSeparator.Visible = false
rightSeparator.Size = UDim2.new(1, 0, 0, 1)
rightSeparator.Position = UDim2.new(0, 0, 0.5, 0)
end
end)
table.insert(self.Elements, {Instance = separatorContainer, Type = "LabeledSeparator"})
return {
UpdateText = function(newText)
label.Text = newText or ""
end,
SetColor = function(color)
label.TextColor3 = color
end,
Instance = separatorContainer
}
end
function TabMethods:AddDropdown(text, options, defaultOption, callback)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add dropdown to destroyed window")
return nil
end
if not text or type(text) ~= "string" or text == "" then
warn("GAeroUI: Dropdown text must be a non-empty string")
return nil
end
if not options or type(options) ~= "table" or #options == 0 then
warn("GAeroUI: Dropdown options must be a non-empty table")
return nil
end
if callback and type(callback) ~= "function" then
warn("GAeroUI: Dropdown callback must be a function")
return nil
end
defaultOption = defaultOption or options[1]
local selectedValue = defaultOption
local isOpen = false
local dropdownContainer = Instance.new("Frame")
dropdownContainer.Name = "DropdownContainer_" .. text
dropdownContainer.Size = UDim2.new(1, 0, 0, 50)
dropdownContainer.BackgroundTransparency = 1
dropdownContainer.Visible = (self.Window.CurrentTab == self)
dropdownContainer.Parent = self.Window.ContentScroll
local dropdownFrame = Instance.new("Frame")
dropdownFrame.Name = "DropdownFrame"
dropdownFrame.Size = UDim2.new(1, 0, 1, 0)
dropdownFrame.BackgroundColor3 = Theme.SidebarBackground
dropdownFrame.BorderSizePixel = 0
dropdownFrame.Parent = dropdownContainer
local dropdownCorner = Instance.new("UICorner")
dropdownCorner.CornerRadius = UDim.new(0, 10)
dropdownCorner.Parent = dropdownFrame
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(0, 180, 1, 0)
label.Position = UDim2.new(0, 16, 0, 0)
label.BackgroundTransparency = 1
label.Text = text
label.TextColor3 = Theme.TextColor
label.TextSize = 14
label.Font = Enum.Font.GothamSemibold
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextYAlignment = Enum.TextYAlignment.Center
label.TextTruncate = Enum.TextTruncate.AtEnd
label.Parent = dropdownFrame
local dropdownButton = Instance.new("TextButton")
dropdownButton.Name = "DropdownButton"
dropdownButton.Size = UDim2.new(1, -212, 0, 36)
dropdownButton.Position = UDim2.new(0, 200, 0.5, -18)
dropdownButton.BackgroundColor3 = Theme.ToggleOff
dropdownButton.BorderSizePixel = 0
dropdownButton.Text = ""
dropdownButton.AutoButtonColor = false
dropdownButton.Parent = dropdownFrame
local buttonCorner = Instance.new("UICorner")
buttonCorner.CornerRadius = UDim.new(0, 8)
buttonCorner.Parent = dropdownButton
local selectedLabel = Instance.new("TextLabel")
selectedLabel.Name = "SelectedLabel"
selectedLabel.Size = UDim2.new(1, -44, 1, 0)
selectedLabel.Position = UDim2.new(0, 14, 0, 0)
selectedLabel.BackgroundTransparency = 1
selectedLabel.Text = tostring(selectedValue)
selectedLabel.TextColor3 = Theme.TextColor
selectedLabel.TextSize = 13
selectedLabel.Font = Enum.Font.GothamMedium
selectedLabel.TextXAlignment = Enum.TextXAlignment.Left
selectedLabel.TextYAlignment = Enum.TextYAlignment.Center
selectedLabel.TextTruncate = Enum.TextTruncate.AtEnd
selectedLabel.Parent = dropdownButton
local arrowIcon = Instance.new("TextLabel")
arrowIcon.Name = "ArrowIcon"
arrowIcon.Size = UDim2.new(0, 24, 1, 0)
arrowIcon.Position = UDim2.new(1, -28, 0, 0)
arrowIcon.BackgroundTransparency = 1
arrowIcon.Text = "▼"
arrowIcon.TextColor3 = Theme.TextSecondary
arrowIcon.TextSize = 10
arrowIcon.Font = Enum.Font.GothamBold
arrowIcon.TextYAlignment = Enum.TextYAlignment.Center
arrowIcon.Parent = dropdownButton
local optionsList = Instance.new("ScrollingFrame")
optionsList.Name = "OptionsList_" .. text
optionsList.Size = UDim2.new(0, 0, 0, 0)
optionsList.Position = UDim2.new(0, 0, 0, 0)
optionsList.BackgroundColor3 = Color3.fromRGB(16, 16, 24)
optionsList.BorderSizePixel = 0
optionsList.ScrollBarThickness = 5
optionsList.ScrollBarImageColor3 = Theme.AccentColor
optionsList.ScrollBarImageTransparency = 0.2
optionsList.Visible = false
optionsList.ZIndex = 10000
optionsList.Active = true
optionsList.ClipsDescendants = true
optionsList.Parent = self.Window.ScreenGui
local listStroke = Instance.new("UIStroke")
listStroke.Color = Theme.AccentColor
listStroke.Transparency = 0.6
listStroke.Thickness = 1.5
listStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
listStroke.Parent = optionsList
local listCorner = Instance.new("UICorner")
listCorner.CornerRadius = UDim.new(0, 10)
listCorner.Parent = optionsList
local listLayout = Instance.new("UIListLayout")
listLayout.SortOrder = Enum.SortOrder.LayoutOrder
listLayout.Padding = UDim.new(0, 4)
listLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
listLayout.Parent = optionsList
local listPadding = Instance.new("UIPadding")
listPadding.PaddingLeft = UDim.new(0, 8)
listPadding.PaddingRight = UDim.new(0, 8)
listPadding.PaddingTop = UDim.new(0, 8)
listPadding.PaddingBottom = UDim.new(0, 8)
listPadding.Parent = optionsList
-- Track scroll connection for cleanup
local scrollConnection = nil
-- Declare closeDropdown as a variable first so it can be referenced in updateOptions
local closeDropdown
local function updateOptions(newOptions)
for _, child in pairs(optionsList:GetChildren()) do
if child:IsA("TextButton") then
child:Destroy()
end
end
for i, option in ipairs(newOptions) do
local optionButton = Instance.new("TextButton")
optionButton.Name = "Option_" .. i
optionButton.Size = UDim2.new(1, 0, 0, 36)
optionButton.BackgroundColor3 = Color3.fromRGB(22, 22, 34)
optionButton.BackgroundTransparency = 0
optionButton.BorderSizePixel = 0
optionButton.Text = ""
optionButton.AutoButtonColor = false
optionButton.ZIndex = 1001
optionButton.Parent = optionsList
local optionCorner = Instance.new("UICorner")
optionCorner.CornerRadius = UDim.new(0, 8)
optionCorner.Parent = optionButton
local optionText = Instance.new("TextLabel")
optionText.Name = "OptionText"
optionText.Size = UDim2.new(1, -24, 1, 0)
optionText.Position = UDim2.new(0, 14, 0, 0)
optionText.BackgroundTransparency = 1
optionText.Text = tostring(option)
optionText.TextColor3 = Theme.TextColor
optionText.TextSize = 13
optionText.Font = Enum.Font.GothamMedium
optionText.TextXAlignment = Enum.TextXAlignment.Left
optionText.TextYAlignment = Enum.TextYAlignment.Center
optionText.TextTruncate = Enum.TextTruncate.AtEnd
optionText.ZIndex = 1002
optionText.Parent = optionButton
local selectionIndicator = Instance.new("Frame")
selectionIndicator.Name = "SelectionIndicator"
selectionIndicator.Size = UDim2.new(0, 3, 0, 20)
selectionIndicator.Position = UDim2.new(0, 4, 0.5, -10)
selectionIndicator.BackgroundColor3 = Theme.AccentColor
selectionIndicator.BorderSizePixel = 0
selectionIndicator.Visible = (tostring(option) == tostring(selectedValue))
selectionIndicator.ZIndex = 1002
selectionIndicator.Parent = optionButton
local indicatorCorner = Instance.new("UICorner")
indicatorCorner.CornerRadius = UDim.new(1, 0)
indicatorCorner.Parent = selectionIndicator
optionButton.MouseButton1Click:Connect(function()
selectedValue = option
selectedLabel.Text = tostring(option)
for _, child in pairs(optionsList:GetChildren()) do
if child:IsA("TextButton") then
local indicator = child:FindFirstChild("SelectionIndicator")
if indicator then
indicator.Visible = false
end
end
end
selectionIndicator.Visible = true
closeDropdown()
if callback then
task.spawn(function()
local success, err = pcall(callback, option)
if not success then
warn("GAeroUI Dropdown Error:", err)
end
end)
end
end)
optionButton.MouseEnter:Connect(function()
CreateTween(optionButton, {BackgroundColor3 = Theme.AccentColor}, TweenPresets.Fast)
CreateTween(optionText, {TextColor3 = Color3.fromRGB(255, 255, 255)}, TweenPresets.Fast)
end)
optionButton.MouseLeave:Connect(function()
CreateTween(optionButton, {BackgroundColor3 = Color3.fromRGB(22, 22, 34)}, TweenPresets.Fast)
CreateTween(optionText, {TextColor3 = Theme.TextColor}, TweenPresets.Fast)
end)
end
optionsList.CanvasSize = UDim2.new(0, 0, 0, listLayout.AbsoluteContentSize.Y + 16)
end
-- Define closeDropdown function (now that it's declared above, it can be used in updateOptions)
closeDropdown = function()
isOpen = false
CreateTween(optionsList, {Size = UDim2.new(0, optionsList.AbsoluteSize.X, 0, 0)}, TweenPresets.Medium)
CreateTween(arrowIcon, {Rotation = 0}, TweenPresets.Medium)
CreateTween(dropdownButton, {BackgroundColor3 = Theme.ToggleOff}, TweenPresets.Fast)
task.wait(0.3)
optionsList.Visible = false
-- Disconnect scroll listener
if scrollConnection then
scrollConnection:Disconnect()
scrollConnection = nil
end
end
updateOptions(options)
dropdownButton.MouseButton1Click:Connect(function()
isOpen = not isOpen
if isOpen then
-- Calculate available space below dropdown for mobile compatibility
local viewportSize = workspace.CurrentCamera.ViewportSize
local containerAbsPos = dropdownContainer.AbsolutePosition
local containerAbsSize = dropdownContainer.AbsoluteSize
local dropdownBottomY = containerAbsPos.Y + containerAbsSize.Y
-- Account for mobile scaling if applicable
local availableSpaceBelow = viewportSize.Y - dropdownBottomY - 40 -- 40px margin for safety
local maxHeight = math.min(280, math.max(120, availableSpaceBelow))
local optionHeight = 40
local totalHeight = (#options * optionHeight) + 16
local contentHeight = math.min(totalHeight, maxHeight)
-- Calculate position in absolute screen coordinates
local dropdownX = containerAbsPos.X + 16
local dropdownY = containerAbsPos.Y + containerAbsSize.Y + 4
local dropdownWidth = containerAbsSize.X - 32
optionsList.Position = UDim2.new(0, dropdownX, 0, dropdownY)
optionsList.Size = UDim2.new(0, dropdownWidth, 0, 0)
optionsList.Visible = true
CreateTween(optionsList, {Size = UDim2.new(0, dropdownWidth, 0, contentHeight)}, TweenPresets.Medium)
CreateTween(arrowIcon, {Rotation = 180}, TweenPresets.Medium)
CreateTween(dropdownButton, {BackgroundColor3 = Color3.fromRGB(50, 50, 70)}, TweenPresets.Fast)
-- Monitor ContentScroll for scrolling and close dropdown when user scrolls
if scrollConnection then
scrollConnection:Disconnect()
end
scrollConnection = self.Window.ContentScroll:GetPropertyChangedSignal("CanvasPosition"):Connect(function()
closeDropdown()
end)
else
closeDropdown()
end
end)
dropdownFrame.MouseEnter:Connect(function()
if not isOpen then
CreateTween(dropdownFrame, {BackgroundColor3 = Color3.fromRGB(28, 28, 42)}, TweenPresets.Fast)
end
end)
dropdownFrame.MouseLeave:Connect(function()
if not isOpen then
CreateTween(dropdownFrame, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
end
end)
dropdownButton.MouseEnter:Connect(function()
if not isOpen then
CreateTween(dropdownButton, {BackgroundColor3 = Color3.fromRGB(50, 50, 70)}, TweenPresets.Fast)
end
end)
dropdownButton.MouseLeave:Connect(function()
if not isOpen then
CreateTween(dropdownButton, {BackgroundColor3 = Theme.ToggleOff}, TweenPresets.Fast)
end
end)
table.insert(self.Elements, {Instance = dropdownContainer, Type = "Dropdown"})
-- Cleanup when dropdown container is destroyed
dropdownContainer.Destroying:Connect(function()
if scrollConnection then
scrollConnection:Disconnect()
scrollConnection = nil
end
if optionsList and optionsList.Parent then
optionsList:Destroy()
end
end)
return {
Container = dropdownContainer,
SetValue = function(value)
selectedValue = value
selectedLabel.Text = tostring(value)
end,
GetValue = function()
return selectedValue
end,
UpdateOptions = function(newOptions)
options = newOptions
updateOptions(newOptions)
end,
Refresh = function()
updateOptions(options)
end,
Close = function()
closeDropdown()
end
}
end
function TabMethods:AddSlider(text, min, max, defaultValue, callback)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add slider to destroyed window")
return nil
end
if not text or type(text) ~= "string" or text == "" then
warn("GAeroUI: Slider text must be a non-empty string")
return nil
end
if callback and type(callback) ~= "function" then
warn("GAeroUI: Slider callback must be a function")
return nil
end
min = min or 0
max = max or 100
defaultValue = defaultValue or min
if type(min) ~= "number" or type(max) ~= "number" or type(defaultValue) ~= "number" then
warn("GAeroUI: Slider min, max, and defaultValue must be numbers")
return nil
end
if min >= max then
warn("GAeroUI: Slider min must be less than max")
return nil
end
defaultValue = math.clamp(defaultValue, min, max)
local sliderContainer = Instance.new("Frame")
sliderContainer.Name = "SliderContainer_" .. text
sliderContainer.Size = UDim2.new(1, 0, 0, 54)
sliderContainer.BackgroundTransparency = 1
sliderContainer.Visible = (self.Window.CurrentTab == self)
sliderContainer.Parent = self.Window.ContentScroll
local sliderFrame = Instance.new("Frame")
sliderFrame.Name = "SliderFrame"
sliderFrame.Size = UDim2.new(1, 0, 1, 0)
sliderFrame.BackgroundColor3 = Theme.SidebarBackground
sliderFrame.BorderSizePixel = 0
sliderFrame.Parent = sliderContainer
local sliderCorner = Instance.new("UICorner")
sliderCorner.CornerRadius = UDim.new(0, 10)
sliderCorner.Parent = sliderFrame
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(1, -24, 0, 18)
label.Position = UDim2.new(0, 12, 0, 8)
label.BackgroundTransparency = 1
label.Text = text
label.TextColor3 = Theme.TextColor
label.TextSize = 14
label.Font = Enum.Font.GothamSemibold
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextTruncate = Enum.TextTruncate.AtEnd
label.Parent = sliderFrame
local valueLabel = Instance.new("TextLabel")
valueLabel.Name = "ValueLabel"
valueLabel.Size = UDim2.new(0, 60, 0, 18)
valueLabel.Position = UDim2.new(1, -72, 0, 8)
valueLabel.BackgroundTransparency = 1
valueLabel.Text = tostring(math.floor(defaultValue))
valueLabel.TextColor3 = Theme.AccentColor
valueLabel.TextSize = 14
valueLabel.Font = Enum.Font.GothamBold
valueLabel.TextXAlignment = Enum.TextXAlignment.Right
valueLabel.Parent = sliderFrame
local sliderTrack = Instance.new("Frame")
sliderTrack.Name = "SliderTrack"
sliderTrack.Size = UDim2.new(1, -24, 0, 6)
sliderTrack.Position = UDim2.new(0, 12, 1, -16)
sliderTrack.BackgroundColor3 = Theme.ToggleOff
sliderTrack.BorderSizePixel = 0
sliderTrack.Parent = sliderFrame
local trackCorner = Instance.new("UICorner")
trackCorner.CornerRadius = UDim.new(1, 0)
trackCorner.Parent = sliderTrack
local sliderFill = Instance.new("Frame")
sliderFill.Name = "SliderFill"
sliderFill.Size = UDim2.new((defaultValue - min) / (max - min), 0, 1, 0)
sliderFill.BackgroundColor3 = Theme.AccentColor
sliderFill.BorderSizePixel = 0
sliderFill.Parent = sliderTrack
local fillCorner = Instance.new("UICorner")
fillCorner.CornerRadius = UDim.new(1, 0)
fillCorner.Parent = sliderFill
local sliderThumb = Instance.new("Frame")
sliderThumb.Name = "SliderThumb"
sliderThumb.Size = UDim2.new(0, 16, 0, 16)
sliderThumb.Position = UDim2.new((defaultValue - min) / (max - min), -8, 0.5, -8)
sliderThumb.BackgroundColor3 = Theme.TextColor
sliderThumb.BorderSizePixel = 0
sliderThumb.Parent = sliderTrack
local thumbCorner = Instance.new("UICorner")
thumbCorner.CornerRadius = UDim.new(1, 0)
thumbCorner.Parent = sliderThumb
local currentValue = defaultValue
local dragging = false
local function updateSlider(value)
value = math.clamp(value, min, max)
currentValue = value
local percentage = (value - min) / (max - min)
CreateTween(sliderFill, {Size = UDim2.new(percentage, 0, 1, 0)}, TweenPresets.Fast)
CreateTween(sliderThumb, {Position = UDim2.new(percentage, -8, 0.5, -8)}, TweenPresets.Fast)
-- Display decimal values with 1 decimal place if value has decimals
local displayValue = value
if math.abs(value - math.floor(value)) > 0.001 then
valueLabel.Text = string.format("%.1f", value)
else
valueLabel.Text = tostring(math.floor(value))
end
if callback then
local success, err = pcall(callback, value)
if not success then
warn("GAeroUI Slider Error:", err)
end
end
end
local function getValueFromPosition(inputPosition)
local trackPosition = sliderTrack.AbsolutePosition.X
local trackSize = sliderTrack.AbsoluteSize.X
local relativePosition = math.clamp(inputPosition.X - trackPosition, 0, trackSize)
local percentage = relativePosition / trackSize
return min + (percentage * (max - min))
end
sliderTrack.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
local value = getValueFromPosition(input.Position)
updateSlider(value)
end
end)
sliderTrack.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
end
end)
sliderThumb.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
end
end)
sliderThumb.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = false
end
end)
UserInputService.InputChanged:Connect(function(input)
if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
local value = getValueFromPosition(input.Position)
updateSlider(value)
end
end)
sliderFrame.MouseEnter:Connect(function()
CreateTween(sliderFrame, {BackgroundColor3 = Color3.fromRGB(30, 30, 45)})
CreateTween(sliderThumb, {Size = UDim2.new(0, 18, 0, 18), Position = UDim2.new((currentValue - min) / (max - min), -9, 0.5, -9)}, TweenPresets.Fast)
end)
sliderFrame.MouseLeave:Connect(function()
if not dragging then
CreateTween(sliderFrame, {BackgroundColor3 = Theme.SidebarBackground})
CreateTween(sliderThumb, {Size = UDim2.new(0, 16, 0, 16), Position = UDim2.new((currentValue - min) / (max - min), -8, 0.5, -8)}, TweenPresets.Fast)
end
end)
table.insert(self.Elements, {Instance = sliderContainer, Type = "Slider"})
return {
Container = sliderContainer,
SetValue = function(value)
updateSlider(value)
end,
GetValue = function()
return currentValue
end,
SetMin = function(newMin)
min = newMin
if currentValue < min then
updateSlider(min)
end
end,
SetMax = function(newMax)
max = newMax
if currentValue > max then
updateSlider(max)
end
end
}
end
function TabMethods:AddStepperButtons(decreaseText, increaseText, onDecrease, onIncrease)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add stepper buttons to destroyed window")
return nil
end
decreaseText = decreaseText or "- Decrease"
increaseText = increaseText or "+ Increase"
if onDecrease and type(onDecrease) ~= "function" then
warn("GAeroUI: onDecrease must be a function")
return nil
end
if onIncrease and type(onIncrease) ~= "function" then
warn("GAeroUI: onIncrease must be a function")
return nil
end
local stepperContainer = Instance.new("Frame")
stepperContainer.Name = "StepperContainer"
stepperContainer.Size = UDim2.new(1, 0, 0, 40)
stepperContainer.BackgroundTransparency = 1
stepperContainer.Visible = (self.Window.CurrentTab == self)
stepperContainer.Parent = self.Window.ContentScroll
local decreaseButton = Instance.new("TextButton")
decreaseButton.Name = "DecreaseButton"
decreaseButton.Size = UDim2.new(0.48, -4, 1, 0)
decreaseButton.Position = UDim2.new(0, 0, 0, 0)
decreaseButton.BackgroundColor3 = Theme.SidebarBackground
decreaseButton.BorderSizePixel = 0
decreaseButton.Text = decreaseText
decreaseButton.TextColor3 = Theme.TextColor
decreaseButton.TextSize = 14
decreaseButton.Font = Enum.Font.GothamSemibold
decreaseButton.AutoButtonColor = false
decreaseButton.Parent = stepperContainer
local decreaseCorner = Instance.new("UICorner")
decreaseCorner.CornerRadius = UDim.new(0, 10)
decreaseCorner.Parent = decreaseButton
local increaseButton = Instance.new("TextButton")
increaseButton.Name = "IncreaseButton"
increaseButton.Size = UDim2.new(0.48, -4, 1, 0)
increaseButton.Position = UDim2.new(0.52, 4, 0, 0)
increaseButton.BackgroundColor3 = Theme.SidebarBackground
increaseButton.BorderSizePixel = 0
increaseButton.Text = increaseText
increaseButton.TextColor3 = Theme.TextColor
increaseButton.TextSize = 14
increaseButton.Font = Enum.Font.GothamSemibold
increaseButton.AutoButtonColor = false
increaseButton.Parent = stepperContainer
local increaseCorner = Instance.new("UICorner")
increaseCorner.CornerRadius = UDim.new(0, 10)
increaseCorner.Parent = increaseButton
decreaseButton.MouseEnter:Connect(function()
CreateTween(decreaseButton, {BackgroundColor3 = Color3.fromRGB(30, 30, 45)}, TweenPresets.Fast)
end)
decreaseButton.MouseLeave:Connect(function()
CreateTween(decreaseButton, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
end)
increaseButton.MouseEnter:Connect(function()
CreateTween(increaseButton, {BackgroundColor3 = Color3.fromRGB(30, 30, 45)}, TweenPresets.Fast)
end)
increaseButton.MouseLeave:Connect(function()
CreateTween(increaseButton, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
end)
decreaseButton.MouseButton1Click:Connect(function()
if onDecrease then
local success, err = pcall(onDecrease)
if not success then
warn("GAeroUI StepperButtons Decrease Error:", err)
end
end
end)
increaseButton.MouseButton1Click:Connect(function()
if onIncrease then
local success, err = pcall(onIncrease)
if not success then
warn("GAeroUI StepperButtons Increase Error:", err)
end
end
end)
table.insert(self.Elements, {Instance = stepperContainer, Type = "StepperButtons"})
return {
Container = stepperContainer,
SetDecreaseText = function(text)
decreaseButton.Text = text
end,
SetIncreaseText = function(text)
increaseButton.Text = text
end,
SetEnabled = function(enabled)
decreaseButton.Active = enabled
increaseButton.Active = enabled
decreaseButton.TextTransparency = enabled and 0 or 0.5
increaseButton.TextTransparency = enabled and 0 or 0.5
end
}
end
function TabMethods:AddTextBox(text, placeholder, defaultValue, callback)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add textbox to destroyed window")
return nil
end
if not text or type(text) ~= "string" or text == "" then
warn("GAeroUI: TextBox text must be a non-empty string")
return nil
end
if callback and type(callback) ~= "function" then
warn("GAeroUI: TextBox callback must be a function")
return nil
end
placeholder = placeholder or "Enter text..."
defaultValue = defaultValue or ""
local textBoxContainer = Instance.new("Frame")
textBoxContainer.Name = "TextBoxContainer_" .. text
textBoxContainer.Size = UDim2.new(1, 0, 0, 50)
textBoxContainer.BackgroundTransparency = 1
textBoxContainer.Visible = (self.Window.CurrentTab == self)
textBoxContainer.Parent = self.Window.ContentScroll
local textBoxFrame = Instance.new("Frame")
textBoxFrame.Name = "TextBoxFrame"
textBoxFrame.Size = UDim2.new(1, 0, 1, 0)
textBoxFrame.BackgroundColor3 = Theme.SidebarBackground
textBoxFrame.BorderSizePixel = 0
textBoxFrame.Parent = textBoxContainer
local textBoxCorner = Instance.new("UICorner")
textBoxCorner.CornerRadius = UDim.new(0, 10)
textBoxCorner.Parent = textBoxFrame
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(0, 180, 1, 0)
label.Position = UDim2.new(0, 16, 0, 0)
label.BackgroundTransparency = 1
label.Text = text
label.TextColor3 = Theme.TextColor
label.TextSize = 14
label.Font = Enum.Font.GothamSemibold
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextYAlignment = Enum.TextYAlignment.Center
label.TextTruncate = Enum.TextTruncate.AtEnd
label.Parent = textBoxFrame
local textBoxInput = Instance.new("TextBox")
textBoxInput.Name = "TextBoxInput"
textBoxInput.Size = UDim2.new(1, -212, 0, 36)
textBoxInput.Position = UDim2.new(0, 200, 0.5, -18)
textBoxInput.BackgroundColor3 = Theme.ToggleOff
textBoxInput.BorderSizePixel = 0
textBoxInput.Text = defaultValue
textBoxInput.PlaceholderText = placeholder
textBoxInput.TextColor3 = Theme.TextColor
textBoxInput.PlaceholderColor3 = Theme.TextSecondary
textBoxInput.TextSize = 13
textBoxInput.Font = Enum.Font.GothamMedium
textBoxInput.TextXAlignment = Enum.TextXAlignment.Left
textBoxInput.ClearTextOnFocus = false
textBoxInput.Parent = textBoxFrame
local inputCorner = Instance.new("UICorner")
inputCorner.CornerRadius = UDim.new(0, 8)
inputCorner.Parent = textBoxInput
local inputPadding = Instance.new("UIPadding")
inputPadding.PaddingLeft = UDim.new(0, 14)
inputPadding.PaddingRight = UDim.new(0, 14)
inputPadding.Parent = textBoxInput
local onChangeCallback = nil
textBoxInput:GetPropertyChangedSignal("Text"):Connect(function()
if onChangeCallback then
local success, err = pcall(onChangeCallback, textBoxInput.Text)
if not success then
warn("GAeroUI TextBox OnChange Error:", err)
end
end
end)
textBoxInput.FocusLost:Connect(function(enterPressed)
if callback then
local success, err = pcall(callback, textBoxInput.Text, enterPressed)
if not success then
warn("GAeroUI TextBox Error:", err)
end
end
end)
textBoxInput.Focused:Connect(function()
CreateTween(textBoxInput, {BackgroundColor3 = Color3.fromRGB(50, 50, 70)}, TweenPresets.Fast)
end)
textBoxInput.FocusLost:Connect(function()
CreateTween(textBoxInput, {BackgroundColor3 = Theme.ToggleOff}, TweenPresets.Fast)
end)
textBoxFrame.MouseEnter:Connect(function()
CreateTween(textBoxFrame, {BackgroundColor3 = Color3.fromRGB(28, 28, 42)}, TweenPresets.Fast)
end)
textBoxFrame.MouseLeave:Connect(function()
CreateTween(textBoxFrame, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
end)
table.insert(self.Elements, {Instance = textBoxContainer, Type = "TextBox"})
return {
Container = textBoxContainer,
SetValue = function(value)
textBoxInput.Text = tostring(value)
end,
GetValue = function()
return textBoxInput.Text
end,
Clear = function()
textBoxInput.Text = ""
end,
SetPlaceholder = function(newPlaceholder)
textBoxInput.PlaceholderText = newPlaceholder
end,
OnChange = function(changeCallback)
onChangeCallback = changeCallback
end
}
end
function TabMethods:AddLoadingBar(text)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add loading bar to destroyed window")
return nil
end
text = text or "Loading..."
local loadingContainer = Instance.new("Frame")
loadingContainer.Name = "LoadingBarContainer"
loadingContainer.Size = UDim2.new(1, 0, 0, 70)
loadingContainer.BackgroundTransparency = 1
loadingContainer.Visible = (self.Window.CurrentTab == self)
loadingContainer.Parent = self.Window.ContentScroll
local loadingFrame = Instance.new("Frame")
loadingFrame.Name = "LoadingFrame"
loadingFrame.Size = UDim2.new(1, 0, 1, 0)
loadingFrame.BackgroundColor3 = Theme.SidebarBackground
loadingFrame.BorderSizePixel = 0
loadingFrame.Parent = loadingContainer
local loadingCorner = Instance.new("UICorner")
loadingCorner.CornerRadius = UDim.new(0, 10)
loadingCorner.Parent = loadingFrame
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(1, -24, 0, 18)
label.Position = UDim2.new(0, 12, 0, 8)
label.BackgroundTransparency = 1
label.Text = text
label.TextColor3 = Theme.TextColor
label.TextSize = 14
label.Font = Enum.Font.GothamSemibold
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextTruncate = Enum.TextTruncate.AtEnd
label.Parent = loadingFrame
local progressTrack = Instance.new("Frame")
progressTrack.Name = "ProgressTrack"
progressTrack.Size = UDim2.new(1, -24, 0, 8)
progressTrack.Position = UDim2.new(0, 12, 1, -20)
progressTrack.BackgroundColor3 = Theme.ToggleOff
progressTrack.BorderSizePixel = 0
progressTrack.Parent = loadingFrame
local trackCorner = Instance.new("UICorner")
trackCorner.CornerRadius = UDim.new(1, 0)
trackCorner.Parent = progressTrack
local progressFill = Instance.new("Frame")
progressFill.Name = "ProgressFill"
progressFill.Size = UDim2.new(0, 0, 1, 0)
progressFill.BackgroundColor3 = Theme.AccentColor
progressFill.BorderSizePixel = 0
progressFill.Parent = progressTrack
local fillCorner = Instance.new("UICorner")
fillCorner.CornerRadius = UDim.new(1, 0)
fillCorner.Parent = progressFill
local progressGlow = Instance.new("Frame")
progressGlow.Name = "ProgressGlow"
progressGlow.Size = UDim2.new(0, 40, 1, 4)
progressGlow.Position = UDim2.new(1, -20, 0, -2)
progressGlow.BackgroundColor3 = Theme.AccentHover
progressGlow.BackgroundTransparency = 0.3
progressGlow.BorderSizePixel = 0
progressGlow.Parent = progressFill
local glowCorner = Instance.new("UICorner")
glowCorner.CornerRadius = UDim.new(1, 0)
glowCorner.Parent = progressGlow
local glowGradient = Instance.new("UIGradient")
glowGradient.Transparency = NumberSequence.new({
NumberSequenceKeypoint.new(0, 1),
NumberSequenceKeypoint.new(0.5, 0.3),
NumberSequenceKeypoint.new(1, 1)
})
glowGradient.Rotation = 0
glowGradient.Parent = progressGlow
local percentLabel = Instance.new("TextLabel")
percentLabel.Name = "PercentLabel"
percentLabel.Size = UDim2.new(0, 60, 0, 18)
percentLabel.Position = UDim2.new(1, -72, 0, 8)
percentLabel.BackgroundTransparency = 1
percentLabel.Text = "0%"
percentLabel.TextColor3 = Theme.AccentColor
percentLabel.TextSize = 13
percentLabel.Font = Enum.Font.GothamBold
percentLabel.TextXAlignment = Enum.TextXAlignment.Right
percentLabel.Parent = loadingFrame
local animationConnection = nil
local isIndeterminate = true
local function startIndeterminateAnimation()
if animationConnection then
animationConnection:Disconnect()
end
isIndeterminate = true
local animationTime = 0
animationConnection = RunService.Heartbeat:Connect(function(deltaTime)
if not isIndeterminate or not progressFill or not progressFill.Parent then
if animationConnection then
animationConnection:Disconnect()
animationConnection = nil
end
return
end
animationTime = animationTime + deltaTime
local progress = (math.sin(animationTime * 2) + 1) / 2
progressFill.Size = UDim2.new(0.3 + (progress * 0.4), 0, 1, 0)
percentLabel.Text = "..."
end)
end
startIndeterminateAnimation()
table.insert(self.Elements, {Instance = loadingContainer, Type = "LoadingBar"})
return {
Container = loadingContainer,
SetProgress = function(percent)
if not progressFill or not progressFill.Parent then return end
isIndeterminate = false
if animationConnection then
animationConnection:Disconnect()
animationConnection = nil
end
percent = math.clamp(percent, 0, 100)
local scale = percent / 100
CreateTween(progressFill, {Size = UDim2.new(scale, 0, 1, 0)}, TweenPresets.Fast)
percentLabel.Text = string.format("%d%%", math.floor(percent))
if percent >= 100 and progressGlow and progressGlow.Parent then
CreateTween(progressGlow, {BackgroundTransparency = 1}, TweenPresets.Fast)
end
end,
SetText = function(newText)
if label and label.Parent then
label.Text = newText
end
end,
Complete = function()
if not progressFill or not progressFill.Parent then return end
isIndeterminate = false
if animationConnection then
animationConnection:Disconnect()
animationConnection = nil
end
CreateTween(progressFill, {Size = UDim2.new(1, 0, 1, 0)}, TweenPresets.Medium)
percentLabel.Text = "100%"
task.wait(0.5)
if loadingContainer and loadingContainer.Parent then
CreateTween(loadingContainer, {
Size = UDim2.new(1, 0, 0, 0),
BackgroundTransparency = 1
}, TweenPresets.Fast)
task.wait(0.2)
if loadingContainer and loadingContainer.Parent then
loadingContainer:Destroy()
end
end
end,
Destroy = function()
isIndeterminate = false
if animationConnection then
animationConnection:Disconnect()
animationConnection = nil
end
if loadingContainer and loadingContainer.Parent then
loadingContainer:Destroy()
end
end
}
end
function TabMethods:AddColorpicker(text, defaultColor, transparency, callback)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add colorpicker to destroyed window")
return nil
end
if not text or type(text) ~= "string" or text == "" then
warn("GAeroUI: Colorpicker text must be a non-empty string")
return nil
end
defaultColor = defaultColor or Color3.fromRGB(255, 255, 255)
local hasTransparency = transparency ~= nil
local currentTransparency = transparency or 0
local colorpickerContainer = Instance.new("Frame")
colorpickerContainer.Name = "ColorpickerContainer_" .. text
colorpickerContainer.Size = UDim2.new(1, 0, 0, 44)
colorpickerContainer.BackgroundTransparency = 1
colorpickerContainer.Visible = (self.Window.CurrentTab == self)
colorpickerContainer.Parent = self.Window.ContentScroll
local colorpickerFrame = Instance.new("Frame")
colorpickerFrame.Name = "ColorpickerFrame"
colorpickerFrame.Size = UDim2.new(1, 0, 1, 0)
colorpickerFrame.BackgroundColor3 = Theme.SidebarBackground
colorpickerFrame.BorderSizePixel = 0
colorpickerFrame.Parent = colorpickerContainer
local colorpickerCorner = Instance.new("UICorner")
colorpickerCorner.CornerRadius = UDim.new(0, 10)
colorpickerCorner.Parent = colorpickerFrame
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(1, -100, 1, 0)
label.Position = UDim2.new(0, 12, 0, 0)
label.BackgroundTransparency = 1
label.Text = text
label.TextColor3 = Theme.TextColor
label.TextSize = 14
label.Font = Enum.Font.GothamSemibold
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextTruncate = Enum.TextTruncate.AtEnd
label.Parent = colorpickerFrame
local currentColor = defaultColor
local colorPreview = Instance.new("TextButton")
colorPreview.Name = "ColorPreview"
colorPreview.Size = UDim2.new(0, 80, 0, 32)
colorPreview.Position = UDim2.new(1, -92, 0.5, -16)
colorPreview.BackgroundColor3 = currentColor
colorPreview.BackgroundTransparency = hasTransparency and currentTransparency or 0
colorPreview.BorderSizePixel = 0
colorPreview.Text = ""
colorPreview.AutoButtonColor = false
colorPreview.Parent = colorpickerFrame
local previewCorner = Instance.new("UICorner")
previewCorner.CornerRadius = UDim.new(0, 8)
previewCorner.Parent = colorPreview
local previewStroke = Instance.new("UIStroke")
previewStroke.Color = Theme.SeparatorColor
previewStroke.Transparency = 0.5
previewStroke.Thickness = 1
previewStroke.Parent = colorPreview
local pickerOpen = false
colorPreview.MouseButton1Click:Connect(function()
if pickerOpen then return end
pickerOpen = true
local pickerOverlay = Instance.new("Frame")
pickerOverlay.Name = "ColorPickerOverlay"
pickerOverlay.Size = UDim2.new(1, 0, 1, 0)
pickerOverlay.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
pickerOverlay.BackgroundTransparency = 0.5
pickerOverlay.BorderSizePixel = 0
pickerOverlay.ZIndex = 500
pickerOverlay.Parent = self.Window.ScreenGui
local pickerFrame = Instance.new("Frame")
pickerFrame.Name = "ColorPicker"
pickerFrame.Size = UDim2.new(0, 280, 0, hasTransparency and 340 or 300)
pickerFrame.Position = UDim2.new(0.5, -140, 0.5, hasTransparency and -170 or -150)
pickerFrame.BackgroundColor3 = Theme.MainBackground
pickerFrame.BackgroundTransparency = 0.1
pickerFrame.BorderSizePixel = 0
pickerFrame.ZIndex = 501
pickerFrame.Parent = pickerOverlay
local pickerCorner = Instance.new("UICorner")
pickerCorner.CornerRadius = UDim.new(0, 12)
pickerCorner.Parent = pickerFrame
ApplyGlassmorphism(pickerFrame)
local function createSlider(name, yPos, defaultValue)
local sliderLabel = Instance.new("TextLabel")
sliderLabel.Size = UDim2.new(0, 30, 0, 20)
sliderLabel.Position = UDim2.new(0, 20, 0, yPos)
sliderLabel.BackgroundTransparency = 1
sliderLabel.Text = name
sliderLabel.TextColor3 = Theme.TextColor
sliderLabel.TextSize = 13
sliderLabel.Font = Enum.Font.GothamBold
sliderLabel.TextXAlignment = Enum.TextXAlignment.Left
sliderLabel.ZIndex = 502
sliderLabel.Parent = pickerFrame
local sliderTrack = Instance.new("Frame")
sliderTrack.Size = UDim2.new(0, 180, 0, 6)
sliderTrack.Position = UDim2.new(0, 60, 0, yPos + 7)
sliderTrack.BackgroundColor3 = Theme.ToggleOff
sliderTrack.BorderSizePixel = 0
sliderTrack.ZIndex = 502
sliderTrack.Parent = pickerFrame
local trackCorner = Instance.new("UICorner")
trackCorner.CornerRadius = UDim.new(1, 0)
trackCorner.Parent = sliderTrack
local sliderFill = Instance.new("Frame")
sliderFill.Size = UDim2.new(defaultValue / 255, 0, 1, 0)
sliderFill.BackgroundColor3 = name == "R" and Color3.fromRGB(231, 76, 60) or
name == "G" and Color3.fromRGB(46, 204, 113) or
Color3.fromRGB(52, 152, 219)
sliderFill.BorderSizePixel = 0
sliderFill.ZIndex = 503
sliderFill.Parent = sliderTrack
local fillCorner = Instance.new("UICorner")
fillCorner.CornerRadius = UDim.new(1, 0)
fillCorner.Parent = sliderFill
local valueLabel = Instance.new("TextLabel")
valueLabel.Size = UDim2.new(0, 30, 0, 20)
valueLabel.Position = UDim2.new(0, 245, 0, yPos)
valueLabel.BackgroundTransparency = 1
valueLabel.Text = tostring(math.floor(defaultValue))
valueLabel.TextColor3 = Theme.TextSecondary
valueLabel.TextSize = 12
valueLabel.Font = Enum.Font.Gotham
valueLabel.TextXAlignment = Enum.TextXAlignment.Right
valueLabel.ZIndex = 502
valueLabel.Parent = pickerFrame
local dragging = false
local sliderButton = Instance.new("TextButton")
sliderButton.Size = UDim2.new(1, 0, 1, 0)
sliderButton.BackgroundTransparency = 1
sliderButton.Text = ""
sliderButton.ZIndex = 504
sliderButton.Parent = sliderTrack
sliderButton.MouseButton1Down:Connect(function()
dragging = true
end)
UserInputService.InputEnded:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 then
dragging = false
end
end)
UserInputService.InputChanged:Connect(function(input)
if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
local mousePos = UserInputService:GetMouseLocation()
local relativePos = mousePos.X - sliderTrack.AbsolutePosition.X
local percentage = math.clamp(relativePos / sliderTrack.AbsoluteSize.X, 0, 1)
local value = math.floor(percentage * 255)
sliderFill.Size = UDim2.new(percentage, 0, 1, 0)
valueLabel.Text = tostring(value)
return value
end
end)
return {
GetValue = function()
return math.floor((sliderFill.Size.X.Scale) * 255)
end,
SetValue = function(value)
sliderFill.Size = UDim2.new(value / 255, 0, 1, 0)
valueLabel.Text = tostring(math.floor(value))
end
}
end
local rSlider = createSlider("R", 30, currentColor.R * 255)
local gSlider = createSlider("G", 70, currentColor.G * 255)
local bSlider = createSlider("B", 110, currentColor.B * 255)
local alphaSlider
if hasTransparency then
alphaSlider = createSlider("A", 150, (1 - currentTransparency) * 255)
end
local applyButton = Instance.new("TextButton")
applyButton.Size = UDim2.new(0, 120, 0, 36)
applyButton.Position = UDim2.new(0.5, -60, 1, hasTransparency and -50 or -50)
applyButton.BackgroundColor3 = Theme.AccentColor
applyButton.BorderSizePixel = 0
applyButton.Text = "Apply"
applyButton.TextColor3 = Theme.TextColor
applyButton.TextSize = 14
applyButton.Font = Enum.Font.GothamBold
applyButton.AutoButtonColor = false
applyButton.ZIndex = 502
applyButton.Parent = pickerFrame
local applyCorner = Instance.new("UICorner")
applyCorner.CornerRadius = UDim.new(0, 10)
applyCorner.Parent = applyButton
applyButton.MouseButton1Click:Connect(function()
local r = rSlider.GetValue()
local g = gSlider.GetValue()
local b = bSlider.GetValue()
currentColor = Color3.fromRGB(r, g, b)
if hasTransparency and alphaSlider then
currentTransparency = 1 - (alphaSlider.GetValue() / 255)
colorPreview.BackgroundTransparency = currentTransparency
end
colorPreview.BackgroundColor3 = currentColor
if callback then
pcall(callback, currentColor, currentTransparency)
end
pickerOverlay:Destroy()
pickerOpen = false
end)
applyButton.MouseEnter:Connect(function()
CreateTween(applyButton, {BackgroundColor3 = Theme.AccentHover})
end)
applyButton.MouseLeave:Connect(function()
CreateTween(applyButton, {BackgroundColor3 = Theme.AccentColor})
end)
pickerOverlay.MouseButton1Click:Connect(function()
pickerOverlay:Destroy()
pickerOpen = false
end)
end)
colorpickerFrame.MouseEnter:Connect(function()
CreateTween(colorpickerFrame, {BackgroundColor3 = Color3.fromRGB(28, 28, 42)}, TweenPresets.Fast)
end)
colorpickerFrame.MouseLeave:Connect(function()
CreateTween(colorpickerFrame, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
end)
table.insert(self.Elements, {Instance = colorpickerContainer, Type = "Colorpicker"})
return {
Container = colorpickerContainer,
SetColor = function(color, alpha)
currentColor = color
colorPreview.BackgroundColor3 = color
if hasTransparency and alpha then
currentTransparency = alpha
colorPreview.BackgroundTransparency = alpha
end
if callback then
pcall(callback, color, alpha or currentTransparency)
end
end,
GetColor = function()
return currentColor, currentTransparency
end
}
end
function TabMethods:AddCode(config)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add code to destroyed window")
return nil
end
config = config or {}
local title = config.Title or "Code"
local code = config.Code or ""
local codeContainer = Instance.new("Frame")
codeContainer.Name = "CodeContainer_" .. title
codeContainer.Size = UDim2.new(1, 0, 0, 0)
codeContainer.BackgroundTransparency = 1
codeContainer.Visible = (self.Window.CurrentTab == self)
codeContainer.AutomaticSize = Enum.AutomaticSize.Y
codeContainer.Parent = self.Window.ContentScroll
local codeFrame = Instance.new("Frame")
codeFrame.Name = "CodeFrame"
codeFrame.Size = UDim2.new(1, 0, 0, 0)
codeFrame.BackgroundColor3 = Theme.SidebarBackground
codeFrame.BackgroundTransparency = 0.3
codeFrame.BorderSizePixel = 0
codeFrame.AutomaticSize = Enum.AutomaticSize.Y
codeFrame.Parent = codeContainer
local codeCorner = Instance.new("UICorner")
codeCorner.CornerRadius = UDim.new(0, 10)
codeCorner.Parent = codeFrame
local contentArea = Instance.new("Frame")
contentArea.Name = "ContentArea"
contentArea.Size = UDim2.new(1, -24, 0, 0)
contentArea.Position = UDim2.new(0, 12, 0, 12)
contentArea.BackgroundTransparency = 1
contentArea.AutomaticSize = Enum.AutomaticSize.Y
contentArea.Parent = codeFrame
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 8)
contentLayout.Parent = contentArea
local headerFrame = Instance.new("Frame")
headerFrame.Name = "Header"
headerFrame.Size = UDim2.new(1, 0, 0, 24)
headerFrame.BackgroundTransparency = 1
headerFrame.LayoutOrder = 1
headerFrame.Parent = contentArea
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, -80, 1, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.AccentColor
titleLabel.TextSize = 14
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.Parent = headerFrame
local copyButton = Instance.new("TextButton")
copyButton.Name = "CopyButton"
copyButton.Size = UDim2.new(0, 70, 0, 24)
copyButton.Position = UDim2.new(1, -70, 0, 0)
copyButton.BackgroundColor3 = Theme.AccentColor
copyButton.BackgroundTransparency = 0.2
copyButton.BorderSizePixel = 0
copyButton.Text = ""
copyButton.AutoButtonColor = false
copyButton.Parent = headerFrame
local copyCorner = Instance.new("UICorner")
copyCorner.CornerRadius = UDim.new(0, 6)
copyCorner.Parent = copyButton
local copyIconContainer = Instance.new("Frame")
copyIconContainer.Name = "IconContainer"
copyIconContainer.Size = UDim2.new(0, 14, 0, 14)
copyIconContainer.Position = UDim2.new(0, 8, 0.5, -7)
copyIconContainer.BackgroundTransparency = 1
copyIconContainer.Parent = copyButton
LoadLucideIcon("copy", copyIconContainer, Theme.TextColor)
local copyLabel = Instance.new("TextLabel")
copyLabel.Size = UDim2.new(1, -26, 1, 0)
copyLabel.Position = UDim2.new(0, 26, 0, 0)
copyLabel.BackgroundTransparency = 1
copyLabel.Text = "Copy"
copyLabel.TextColor3 = Theme.TextColor
copyLabel.TextSize = 12
copyLabel.Font = Enum.Font.GothamSemibold
copyLabel.TextXAlignment = Enum.TextXAlignment.Left
copyLabel.Parent = copyButton
local codeBox = Instance.new("Frame")
codeBox.Name = "CodeBox"
codeBox.Size = UDim2.new(1, 0, 0, 0)
codeBox.BackgroundColor3 = Theme.ToggleOff
codeBox.BorderSizePixel = 0
codeBox.AutomaticSize = Enum.AutomaticSize.Y
codeBox.LayoutOrder = 2
codeBox.Parent = contentArea
local codeBoxCorner = Instance.new("UICorner")
codeBoxCorner.CornerRadius = UDim.new(0, 8)
codeBoxCorner.Parent = codeBox
local codeLabel = Instance.new("TextLabel")
codeLabel.Name = "CodeText"
codeLabel.Size = UDim2.new(1, -16, 0, 0)
codeLabel.Position = UDim2.new(0, 8, 0, 8)
codeLabel.BackgroundTransparency = 1
codeLabel.Text = code
codeLabel.TextColor3 = Theme.TextColor
codeLabel.TextSize = 12
codeLabel.Font = Enum.Font.Code
codeLabel.TextXAlignment = Enum.TextXAlignment.Left
codeLabel.TextYAlignment = Enum.TextYAlignment.Top
codeLabel.TextWrapped = true
codeLabel.AutomaticSize = Enum.AutomaticSize.Y
codeLabel.Parent = codeBox
local codePadding = Instance.new("UIPadding")
codePadding.PaddingBottom = UDim.new(0, 8)
codePadding.Parent = codeBox
local bottomPadding = Instance.new("Frame")
bottomPadding.Size = UDim2.new(1, 0, 0, 12)
bottomPadding.BackgroundTransparency = 1
bottomPadding.LayoutOrder = 999
bottomPadding.Parent = contentArea
local onCopyCallback = nil
copyButton.MouseButton1Click:Connect(function()
if setclipboard then
setclipboard(code)
copyLabel.Text = "Copied!"
CreateTween(copyButton, {BackgroundColor3 = Theme.SuccessColor})
task.wait(1.5)
copyLabel.Text = "Copy"
CreateTween(copyButton, {BackgroundColor3 = Theme.AccentColor})
if onCopyCallback then
pcall(onCopyCallback)
end
else
copyLabel.Text = "Failed"
CreateTween(copyButton, {BackgroundColor3 = Theme.ErrorColor})
task.wait(1.5)
copyLabel.Text = "Copy"
CreateTween(copyButton, {BackgroundColor3 = Theme.AccentColor})
end
end)
copyButton.MouseEnter:Connect(function()
if copyLabel.Text == "Copy" then
CreateTween(copyButton, {BackgroundTransparency = 0})
end
end)
copyButton.MouseLeave:Connect(function()
if copyLabel.Text == "Copy" then
CreateTween(copyButton, {BackgroundTransparency = 0.2})
end
end)
table.insert(self.Elements, {Instance = codeContainer, Type = "Code"})
return {
Container = codeContainer,
SetCode = function(newCode)
code = newCode
codeLabel.Text = newCode
end,
OnCopy = function(callback)
onCopyCallback = callback
end
}
end
function TabMethods:AddImage(config)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add image to destroyed window")
return nil
end
config = config or {}
local image = config.Image or ""
local aspectRatio = config.AspectRatio or "16:9"
local radius = config.Radius or 12
local ratioWidth, ratioHeight = aspectRatio:match("(%d+):(%d+)")
ratioWidth = tonumber(ratioWidth) or 16
ratioHeight = tonumber(ratioHeight) or 9
local heightScale = ratioHeight / ratioWidth
local imageContainer = Instance.new("Frame")
imageContainer.Name = "ImageContainer"
imageContainer.Size = UDim2.new(1, 0, 0, 0)
imageContainer.BackgroundTransparency = 1
imageContainer.Visible = (self.Window.CurrentTab == self)
imageContainer.Parent = self.Window.ContentScroll
local imageFrame = Instance.new("Frame")
imageFrame.Name = "ImageFrame"
imageFrame.Size = UDim2.new(1, 0, 0, 0)
imageFrame.BackgroundColor3 = Theme.ToggleOff
imageFrame.BorderSizePixel = 0
imageFrame.Parent = imageContainer
local imageCorner = Instance.new("UICorner")
imageCorner.CornerRadius = UDim.new(0, radius)
imageCorner.Parent = imageFrame
local imageLabel = Instance.new("ImageLabel")
imageLabel.Name = "Image"
imageLabel.Size = UDim2.new(1, 0, 1, 0)
imageLabel.BackgroundTransparency = 1
imageLabel.Image = image
imageLabel.ScaleType = Enum.ScaleType.Crop
imageLabel.Parent = imageFrame
local imageLabelCorner = Instance.new("UICorner")
imageLabelCorner.CornerRadius = UDim.new(0, radius)
imageLabelCorner.Parent = imageLabel
task.wait()
local containerWidth = imageContainer.AbsoluteSize.X
local calculatedHeight = containerWidth * heightScale
imageContainer.Size = UDim2.new(1, 0, 0, calculatedHeight)
imageFrame.Size = UDim2.new(1, 0, 1, 0)
table.insert(self.Elements, {Instance = imageContainer, Type = "Image"})
return {
Container = imageContainer,
SetImage = function(newImage)
imageLabel.Image = newImage
end
}
end
function TabMethods:AddParagraph(config)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add paragraph to destroyed window")
return nil
end
config = config or {}
local title = config.Title or "Paragraph"
local desc = config.Desc or ""
local image = config.Image
local imageSize = config.ImageSize or 22
local iconThemed = config.IconThemed or false
local thumbnail = config.Thumbnail
local thumbnailSize = config.ThumbnailSize or 80
local buttons = config.Buttons or {}
local paragraphContainer = Instance.new("Frame")
paragraphContainer.Name = "ParagraphContainer_" .. title
paragraphContainer.Size = UDim2.new(1, 0, 0, 0)
paragraphContainer.BackgroundTransparency = 1
paragraphContainer.Visible = (self.Window.CurrentTab == self)
paragraphContainer.AutomaticSize = Enum.AutomaticSize.Y
paragraphContainer.Parent = self.Window.ContentScroll
local paragraphFrame = Instance.new("Frame")
paragraphFrame.Name = "ParagraphFrame"
paragraphFrame.Size = UDim2.new(1, 0, 0, 0)
paragraphFrame.BackgroundColor3 = Theme.SidebarBackground
paragraphFrame.BackgroundTransparency = 0.3
paragraphFrame.BorderSizePixel = 0
paragraphFrame.AutomaticSize = Enum.AutomaticSize.Y
paragraphFrame.Parent = paragraphContainer
local paragraphCorner = Instance.new("UICorner")
paragraphCorner.CornerRadius = UDim.new(0, 10)
paragraphCorner.Parent = paragraphFrame
local contentArea = Instance.new("Frame")
contentArea.Name = "ContentArea"
contentArea.Size = UDim2.new(1, -24, 0, 0)
contentArea.Position = UDim2.new(0, 12, 0, 12)
contentArea.BackgroundTransparency = 1
contentArea.AutomaticSize = Enum.AutomaticSize.Y
contentArea.Parent = paragraphFrame
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 10)
contentLayout.Parent = contentArea
if thumbnail then
local thumbnailFrame = Instance.new("Frame")
thumbnailFrame.Name = "Thumbnail"
thumbnailFrame.Size = UDim2.new(1, 0, 0, thumbnailSize)
thumbnailFrame.BackgroundTransparency = 1
thumbnailFrame.LayoutOrder = 1
thumbnailFrame.Parent = contentArea
local thumbnailImage = Instance.new("ImageLabel")
thumbnailImage.Size = UDim2.new(1, 0, 1, 0)
thumbnailImage.BackgroundColor3 = Theme.ToggleOff
thumbnailImage.BorderSizePixel = 0
thumbnailImage.Image = thumbnail
thumbnailImage.ScaleType = Enum.ScaleType.Crop
thumbnailImage.Parent = thumbnailFrame
local thumbnailCorner = Instance.new("UICorner")
thumbnailCorner.CornerRadius = UDim.new(0, 8)
thumbnailCorner.Parent = thumbnailImage
end
local headerFrame = Instance.new("Frame")
headerFrame.Name = "Header"
headerFrame.Size = UDim2.new(1, 0, 0, 24)
headerFrame.BackgroundTransparency = 1
headerFrame.LayoutOrder = 2
headerFrame.Parent = contentArea
if image then
local iconContainer = Instance.new("Frame")
iconContainer.Name = "IconContainer"
iconContainer.Size = UDim2.new(0, imageSize, 0, imageSize)
iconContainer.Position = UDim2.new(0, 0, 0, 0)
iconContainer.BackgroundTransparency = 1
iconContainer.Parent = headerFrame
if image:match("^lucide%-") then
local iconName = image:gsub("^lucide%-", "")
LoadLucideIcon(iconName, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
elseif image:match("^rbxassetid://") or image:match("^http") then
local iconImage = Instance.new("ImageLabel")
iconImage.Size = UDim2.new(1, 0, 1, 0)
iconImage.BackgroundTransparency = 1
iconImage.Image = image
iconImage.ImageColor3 = iconThemed and Theme.AccentColor or Theme.TextColor
iconImage.Parent = iconContainer
else
LoadLucideIcon(image, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
end
end
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, image and -(imageSize + 8) or 0, 1, 0)
titleLabel.Position = UDim2.new(0, image and (imageSize + 8) or 0, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.TextColor
titleLabel.TextSize = 16
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.TextTruncate = Enum.TextTruncate.AtEnd
titleLabel.Parent = headerFrame
if desc and desc ~= "" then
local descLabel = Instance.new("TextLabel")
descLabel.Name = "Description"
descLabel.Size = UDim2.new(1, 0, 0, 0)
descLabel.BackgroundTransparency = 1
descLabel.Text = desc
descLabel.TextColor3 = Theme.TextSecondary
descLabel.TextSize = 13
descLabel.Font = Enum.Font.Gotham
descLabel.TextXAlignment = Enum.TextXAlignment.Left
descLabel.TextYAlignment = Enum.TextYAlignment.Top
descLabel.TextWrapped = true
descLabel.AutomaticSize = Enum.AutomaticSize.Y
descLabel.LayoutOrder = 3
descLabel.Parent = contentArea
end
if #buttons > 0 then
local buttonsFrame = Instance.new("Frame")
buttonsFrame.Name = "Buttons"
buttonsFrame.Size = UDim2.new(1, 0, 0, 0)
buttonsFrame.BackgroundTransparency = 1
buttonsFrame.AutomaticSize = Enum.AutomaticSize.Y
buttonsFrame.LayoutOrder = 4
buttonsFrame.Parent = contentArea
local buttonsLayout = Instance.new("UIListLayout")
buttonsLayout.SortOrder = Enum.SortOrder.LayoutOrder
buttonsLayout.Padding = UDim.new(0, 6)
buttonsLayout.Parent = buttonsFrame
for i, buttonConfig in ipairs(buttons) do
local btnTitle = buttonConfig.Title or "Button"
local btnIcon = buttonConfig.Icon
local btnCallback = buttonConfig.Callback
local button = Instance.new("TextButton")
button.Name = "ParagraphButton_" .. i
button.Size = UDim2.new(1, 0, 0, 36)
button.BackgroundColor3 = Theme.AccentColor
button.BackgroundTransparency = 0.1
button.BorderSizePixel = 0
button.Text = ""
button.AutoButtonColor = false
button.LayoutOrder = i
button.Parent = buttonsFrame
local btnCorner = Instance.new("UICorner")
btnCorner.CornerRadius = UDim.new(0, 8)
btnCorner.Parent = button
if btnIcon then
local btnIconContainer = Instance.new("Frame")
btnIconContainer.Name = "IconContainer"
btnIconContainer.Size = UDim2.new(0, 18, 0, 18)
btnIconContainer.Position = UDim2.new(0, 10, 0.5, -9)
btnIconContainer.BackgroundTransparency = 1
btnIconContainer.Parent = button
LoadLucideIcon(btnIcon, btnIconContainer, Theme.TextColor)
end
local btnLabel = Instance.new("TextLabel")
btnLabel.Size = UDim2.new(1, btnIcon and -40 or -20, 1, 0)
btnLabel.Position = UDim2.new(0, btnIcon and 36 or 10, 0, 0)
btnLabel.BackgroundTransparency = 1
btnLabel.Text = btnTitle
btnLabel.TextColor3 = Theme.TextColor
btnLabel.TextSize = 13
btnLabel.Font = Enum.Font.GothamSemibold
btnLabel.TextXAlignment = Enum.TextXAlignment.Left
btnLabel.Parent = button
button.MouseButton1Click:Connect(function()
if btnCallback then
local success, err = pcall(btnCallback)
if not success then
warn("GAeroUI Paragraph Button Error:", err)
end
end
end)
button.MouseEnter:Connect(function()
CreateTween(button, {BackgroundTransparency = 0, BackgroundColor3 = Theme.AccentHover})
end)
button.MouseLeave:Connect(function()
CreateTween(button, {BackgroundTransparency = 0.1, BackgroundColor3 = Theme.AccentColor})
end)
end
end
local bottomPadding = Instance.new("Frame")
bottomPadding.Size = UDim2.new(1, 0, 0, 12)
bottomPadding.BackgroundTransparency = 1
bottomPadding.LayoutOrder = 999
bottomPadding.Parent = contentArea
table.insert(self.Elements, {Instance = paragraphContainer, Type = "Paragraph"})
return {
Container = paragraphContainer,
SetTitle = function(newTitle)
titleLabel.Text = newTitle
end,
SetDesc = function(newDesc)
if desc and desc ~= "" then
local descLabel = contentArea:FindFirstChild("Description")
if descLabel then
descLabel.Text = newDesc
end
end
end,
SetImage = function(newImage, size)
if image then
local iconContainer = headerFrame:FindFirstChild("IconContainer")
if iconContainer then
iconContainer:ClearAllChildren()
if newImage:match("^lucide%-") then
local iconName = newImage:gsub("^lucide%-", "")
LoadLucideIcon(iconName, iconContainer, iconThemed and Theme.AccentColor or Theme.TextColor)
else
local iconImage = Instance.new("ImageLabel")
iconImage.Size = UDim2.new(1, 0, 1, 0)
iconImage.BackgroundTransparency = 1
iconImage.Image = newImage
iconImage.ImageColor3 = iconThemed and Theme.AccentColor or Theme.TextColor
iconImage.Parent = iconContainer
end
if size then
iconContainer.Size = UDim2.new(0, size, 0, size)
end
end
end
end,
SetThumbnail = function(newThumbnail, size)
local thumbnailFrame = contentArea:FindFirstChild("Thumbnail")
if thumbnailFrame then
local thumbnailImage = thumbnailFrame:FindFirstChildOfClass("ImageLabel")
if thumbnailImage then
thumbnailImage.Image = newThumbnail
if size then
thumbnailFrame.Size = UDim2.new(1, 0, 0, size)
end
end
end
end
}
end
function TabMethods:AddSection(config)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add section to destroyed window")
return nil
end
config = config or {}
local title = config.Title or "Section"
local opened = config.Opened ~= false
local sectionContainer = Instance.new("Frame")
sectionContainer.Name = "SectionContainer_" .. title
sectionContainer.Size = UDim2.new(1, 0, 0, 0)
sectionContainer.BackgroundTransparency = 1
sectionContainer.Visible = (self.Window.CurrentTab == self)
sectionContainer.AutomaticSize = Enum.AutomaticSize.Y
sectionContainer.Parent = self.Window.ContentScroll
local sectionLayout = Instance.new("UIListLayout")
sectionLayout.SortOrder = Enum.SortOrder.LayoutOrder
sectionLayout.Padding = UDim.new(0, 8)
sectionLayout.Parent = sectionContainer
local headerButton = Instance.new("TextButton")
headerButton.Name = "SectionHeader"
headerButton.Size = UDim2.new(1, 0, 0, 36)
headerButton.BackgroundColor3 = Theme.SidebarBackground
headerButton.BackgroundTransparency = 0.5
headerButton.BorderSizePixel = 0
headerButton.Text = ""
headerButton.AutoButtonColor = false
headerButton.LayoutOrder = 1
headerButton.Parent = sectionContainer
local headerCorner = Instance.new("UICorner")
headerCorner.CornerRadius = UDim.new(0, 10)
headerCorner.Parent = headerButton
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "Title"
titleLabel.Size = UDim2.new(1, -40, 1, 0)
titleLabel.Position = UDim2.new(0, 12, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = title
titleLabel.TextColor3 = Theme.AccentColor
titleLabel.TextSize = 15
titleLabel.Font = Enum.Font.GothamBold
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.Parent = headerButton
local arrowContainer = Instance.new("Frame")
arrowContainer.Name = "ArrowContainer"
arrowContainer.Size = UDim2.new(0, 16, 0, 16)
arrowContainer.Position = UDim2.new(1, -28, 0.5, -8)
arrowContainer.BackgroundTransparency = 1
arrowContainer.Rotation = opened and 0 or -90
arrowContainer.Parent = headerButton
LoadLucideIcon("chevron-down", arrowContainer, Theme.TextSecondary)
local contentContainer = Instance.new("Frame")
contentContainer.Name = "SectionContent"
contentContainer.Size = UDim2.new(1, 0, 0, 0)
contentContainer.BackgroundTransparency = 1
contentContainer.Visible = opened
contentContainer.AutomaticSize = Enum.AutomaticSize.Y
contentContainer.LayoutOrder = 2
contentContainer.Parent = sectionContainer
local contentLayout = Instance.new("UIListLayout")
contentLayout.SortOrder = Enum.SortOrder.LayoutOrder
contentLayout.Padding = UDim.new(0, 8)
contentLayout.Parent = contentContainer
local contentPadding = Instance.new("UIPadding")
contentPadding.PaddingLeft = UDim.new(0, 8)
contentPadding.PaddingRight = UDim.new(0, 8)
contentPadding.Parent = contentContainer
headerButton.MouseButton1Click:Connect(function()
opened = not opened
contentContainer.Visible = opened
CreateTween(arrowContainer, {
Rotation = opened and 0 or -90
}, TweenPresets.Fast)
end)
headerButton.MouseEnter:Connect(function()
CreateTween(headerButton, {BackgroundTransparency = 0.3}, TweenPresets.Fast)
end)
headerButton.MouseLeave:Connect(function()
CreateTween(headerButton, {BackgroundTransparency = 0.5}, TweenPresets.Fast)
end)
table.insert(self.Elements, {Instance = sectionContainer, Type = "Section"})
local SectionMethods = setmetatable({}, {__index = self})
SectionMethods.Window = self.Window
SectionMethods.Elements = {}
SectionMethods.ContentContainer = contentContainer
SectionMethods.OriginalContentScroll = self.Window.ContentScroll
local sectionProxy = setmetatable({}, {
__index = function(t, k)
if k == "ContentScroll" then
return contentContainer
else
return self.Window[k]
end
end
})
SectionMethods.Window = sectionProxy
return SectionMethods
end
function TabMethods:AddKeybind(text, defaultKey, callback)
if self.Window.IsDestroyed then
warn("GAeroUI: Cannot add keybind to destroyed window")
return nil
end
if not text or type(text) ~= "string" or text == "" then
warn("GAeroUI: Keybind text must be a non-empty string")
return nil
end
defaultKey = defaultKey or "F"
if type(defaultKey) ~= "string" then
warn("GAeroUI: Keybind defaultKey must be a string, using 'F'")
defaultKey = "F"
end
local keybindContainer = Instance.new("Frame")
keybindContainer.Name = "KeybindContainer_" .. text
keybindContainer.Size = UDim2.new(1, 0, 0, 44)
keybindContainer.BackgroundTransparency = 1
keybindContainer.Visible = (self.Window.CurrentTab == self)
keybindContainer.Parent = self.Window.ContentScroll
local keybindFrame = Instance.new("Frame")
keybindFrame.Name = "KeybindFrame"
keybindFrame.Size = UDim2.new(1, 0, 1, 0)
keybindFrame.BackgroundColor3 = Theme.SidebarBackground
keybindFrame.BorderSizePixel = 0
keybindFrame.Parent = keybindContainer
local keybindCorner = Instance.new("UICorner")
keybindCorner.CornerRadius = UDim.new(0, 10)
keybindCorner.Parent = keybindFrame
local label = Instance.new("TextLabel")
label.Name = "Label"
label.Size = UDim2.new(1, -100, 1, 0)
label.Position = UDim2.new(0, 12, 0, 0)
label.BackgroundTransparency = 1
label.Text = text
label.TextColor3 = Theme.TextColor
label.TextSize = 14
label.Font = Enum.Font.GothamSemibold
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextTruncate = Enum.TextTruncate.AtEnd
label.Parent = keybindFrame
local currentKey = defaultKey
local isBinding = false
local keybindButton = Instance.new("TextButton")
keybindButton.Name = "KeybindButton"
keybindButton.Size = UDim2.new(0, 80, 0, 32)
keybindButton.Position = UDim2.new(1, -92, 0.5, -16)
keybindButton.BackgroundColor3 = Theme.ToggleOff
keybindButton.BorderSizePixel = 0
keybindButton.Text = ""
keybindButton.AutoButtonColor = false
keybindButton.Parent = keybindFrame
local keybindBtnCorner = Instance.new("UICorner")
keybindBtnCorner.CornerRadius = UDim.new(0, 8)
keybindBtnCorner.Parent = keybindButton
local keyLabel = Instance.new("TextLabel")
keyLabel.Name = "KeyLabel"
keyLabel.Size = UDim2.new(1, -16, 1, 0)
keyLabel.Position = UDim2.new(0, 8, 0, 0)
keyLabel.BackgroundTransparency = 1
keyLabel.Text = currentKey
keyLabel.TextColor3 = Theme.TextColor
keyLabel.TextSize = 13
keyLabel.Font = Enum.Font.GothamBold
keyLabel.TextXAlignment = Enum.TextXAlignment.Center
keyLabel.Parent = keybindButton
local inputConnection = nil
local function stopBinding()
isBinding = false
keyLabel.Text = currentKey
CreateTween(keybindButton, {BackgroundColor3 = Theme.ToggleOff}, TweenPresets.Fast)
if inputConnection then
inputConnection:Disconnect()
inputConnection = nil
end
end
local function startBinding()
isBinding = true
keyLabel.Text = "..."
CreateTween(keybindButton, {BackgroundColor3 = Theme.AccentColor}, TweenPresets.Fast)
inputConnection = UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.Keyboard then
local keyCode = input.KeyCode
local keyName = keyCode.Name
if keyName == "LeftShift" or keyName == "RightShift" or
keyName == "LeftControl" or keyName == "RightControl" or
keyName == "LeftAlt" or keyName == "RightAlt" then
return
end
currentKey = keyName
stopBinding()
if callback then
local success, err = pcall(callback, keyName)
if not success then
warn("GAeroUI Keybind Error:", err)
end
end
elseif input.UserInputType == Enum.UserInputType.MouseButton1 or
input.UserInputType == Enum.UserInputType.MouseButton2 then
stopBinding()
end
end)
end
keybindButton.MouseButton1Click:Connect(function()
if isBinding then
stopBinding()
else
startBinding()
end
end)
keybindButton.MouseEnter:Connect(function()
if not isBinding then
CreateTween(keybindButton, {BackgroundColor3 = Color3.fromRGB(50, 50, 70)}, TweenPresets.Fast)
end
end)
keybindButton.MouseLeave:Connect(function()
if not isBinding then
CreateTween(keybindButton, {BackgroundColor3 = Theme.ToggleOff}, TweenPresets.Fast)
end
end)
keybindFrame.MouseEnter:Connect(function()
CreateTween(keybindFrame, {BackgroundColor3 = Color3.fromRGB(28, 28, 42)}, TweenPresets.Fast)
end)
keybindFrame.MouseLeave:Connect(function()
CreateTween(keybindFrame, {BackgroundColor3 = Theme.SidebarBackground}, TweenPresets.Fast)
end)
table.insert(self.Elements, {Instance = keybindContainer, Type = "Keybind"})
return {
Container = keybindContainer,
SetKey = function(key)
currentKey = key
keyLabel.Text = key
if callback then
pcall(callback, key)
end
end,
GetKey = function()
return currentKey
end
}
end
return TabMethods
end
-- ============================================
-- NAVIGATION SHORTCUT COMPONENT
-- ============================================
function Window:CreateNavigationShortcut(config)
if self.IsDestroyed then
warn("GAeroUI: Cannot create navigation shortcut on destroyed window")
return nil
end
config = config or {}
local onStart = config.OnStart
local onPause = config.OnPause
local onStop = config.OnStop
local initialPosition = config.Position or UDim2.new(0.5, 0, 0.85, 0)
local shortcut = {}
shortcut.Enabled = false
shortcut.ScreenGui = nil
shortcut.Frame = nil
shortcut.StartButton = nil
shortcut.PauseButton = nil
shortcut.StopButton = nil
shortcut.PauseLabel = nil
shortcut.Connections = {}
function shortcut:Create()
if self.ScreenGui then
return
end
local isMobile = IsMobileDevice()
local mobileScale = GetMobileScale()
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "GAeroUI_NavigationShortcut"
screenGui.ResetOnSpawn = false
screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
screenGui.DisplayOrder = 50
screenGui.Parent = game:GetService("CoreGui")
self.ScreenGui = screenGui
-- Main Frame (compact, icon-only design)
local frame = Instance.new("Frame")
frame.Name = "NavigationFrame"
frame.Size = UDim2.new(0, isMobile and 160 or 180, 0, isMobile and 50 or 56)
frame.Position = initialPosition
frame.AnchorPoint = Vector2.new(0.5, 0.5)
frame.BackgroundColor3 = Theme.SidebarBackground
frame.BackgroundTransparency = 0.5
frame.BorderSizePixel = 0
frame.Parent = screenGui
if isMobile then
local uiScale = Instance.new("UIScale")
uiScale.Scale = mobileScale
uiScale.Parent = frame
end
local frameCorner = Instance.new("UICorner")
frameCorner.CornerRadius = UDim.new(0, 12)
frameCorner.Parent = frame
self.Frame = frame
-- Buttons Container (horizontal layout)
local buttonsContainer = Instance.new("Frame")
buttonsContainer.Name = "ButtonsContainer"
buttonsContainer.Size = UDim2.new(1, -16, 1, -16)
buttonsContainer.Position = UDim2.new(0, 8, 0, 8)
buttonsContainer.BackgroundTransparency = 1
buttonsContainer.Parent = frame
local buttonLayout = Instance.new("UIListLayout")
buttonLayout.SortOrder = Enum.SortOrder.LayoutOrder
buttonLayout.Padding = UDim.new(0, 8)
buttonLayout.FillDirection = Enum.FillDirection.Horizontal
buttonLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
buttonLayout.VerticalAlignment = Enum.VerticalAlignment.Center
buttonLayout.Parent = buttonsContainer
local buttonSize = isMobile and 40 or 44
-- Start Button (icon only with improved styling)
local startButton = Instance.new("TextButton")
startButton.Name = "StartButton"
startButton.Size = UDim2.new(0, buttonSize, 0, buttonSize)
startButton.BackgroundColor3 = Color3.fromRGB(35, 35, 50)
startButton.BackgroundTransparency = 0.3
startButton.BorderSizePixel = 0
startButton.Text = ""
startButton.AutoButtonColor = false
startButton.LayoutOrder = 1
startButton.Parent = buttonsContainer
local startCorner = Instance.new("UICorner")
startCorner.CornerRadius = UDim.new(0, 10)
startCorner.Parent = startButton
local startStroke = Instance.new("UIStroke")
startStroke.Color = Theme.SuccessColor
startStroke.Transparency = 0.7
startStroke.Thickness = 1.5
startStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
startStroke.Parent = startButton
local startIconContainer = Instance.new("Frame")
startIconContainer.Name = "IconContainer"
startIconContainer.Size = UDim2.new(0, 22, 0, 22)
startIconContainer.Position = UDim2.new(0.5, -11, 0.5, -11)
startIconContainer.BackgroundTransparency = 1
startIconContainer.Parent = startButton
LoadLucideIcon("play", startIconContainer, Theme.SuccessColor)
self.StartButton = startButton
self.StartIcon = startIconContainer
self.StartStroke = startStroke
-- Pause Button (icon only with improved styling)
local pauseButton = Instance.new("TextButton")
pauseButton.Name = "PauseButton"
pauseButton.Size = UDim2.new(0, buttonSize, 0, buttonSize)
pauseButton.BackgroundColor3 = Color3.fromRGB(35, 35, 50)
pauseButton.BackgroundTransparency = 0.3
pauseButton.BorderSizePixel = 0
pauseButton.Text = ""
pauseButton.AutoButtonColor = false
pauseButton.LayoutOrder = 2
pauseButton.Parent = buttonsContainer
local pauseCorner = Instance.new("UICorner")
pauseCorner.CornerRadius = UDim.new(0, 10)
pauseCorner.Parent = pauseButton
local pauseStroke = Instance.new("UIStroke")
pauseStroke.Color = Theme.WarningColor
pauseStroke.Transparency = 0.7
pauseStroke.Thickness = 1.5
pauseStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
pauseStroke.Parent = pauseButton
local pauseIconContainer = Instance.new("Frame")
pauseIconContainer.Name = "IconContainer"
pauseIconContainer.Size = UDim2.new(0, 22, 0, 22)
pauseIconContainer.Position = UDim2.new(0.5, -11, 0.5, -11)
pauseIconContainer.BackgroundTransparency = 1
pauseIconContainer.Parent = pauseButton
LoadLucideIcon("pause", pauseIconContainer, Theme.WarningColor)
self.PauseButton = pauseButton
self.PauseIcon = pauseIconContainer
self.PauseStroke = pauseStroke
-- Stop Button (icon only with improved styling)
local stopButton = Instance.new("TextButton")
stopButton.Name = "StopButton"
stopButton.Size = UDim2.new(0, buttonSize, 0, buttonSize)
stopButton.BackgroundColor3 = Color3.fromRGB(35, 35, 50)
stopButton.BackgroundTransparency = 0.3
stopButton.BorderSizePixel = 0
stopButton.Text = ""
stopButton.AutoButtonColor = false
stopButton.LayoutOrder = 3
stopButton.Parent = buttonsContainer
local stopCorner = Instance.new("UICorner")
stopCorner.CornerRadius = UDim.new(0, 10)
stopCorner.Parent = stopButton
local stopStroke = Instance.new("UIStroke")
stopStroke.Color = Theme.ErrorColor
stopStroke.Transparency = 0.7
stopStroke.Thickness = 1.5
stopStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
stopStroke.Parent = stopButton
local stopIconContainer = Instance.new("Frame")
stopIconContainer.Name = "IconContainer"
stopIconContainer.Size = UDim2.new(0, 22, 0, 22)
stopIconContainer.Position = UDim2.new(0.5, -11, 0.5, -11)
stopIconContainer.BackgroundTransparency = 1
stopIconContainer.Parent = stopButton
LoadLucideIcon("square", stopIconContainer, Theme.ErrorColor)
self.StopButton = stopButton
self.StopIcon = stopIconContainer
self.StopStroke = stopStroke
-- Button Click Events and Hover Effects (enhanced with glow effects)
startButton.MouseButton1Click:Connect(function()
if onStart then
local success, err = pcall(onStart)
if not success then
warn("GAeroUI Navigation Shortcut Start Error:", err)
end
end
end)
startButton.MouseEnter:Connect(function()
CreateTween(startButton, {BackgroundColor3 = Color3.fromRGB(46, 204, 113), BackgroundTransparency = 0.1}, TweenPresets.Fast)
CreateTween(startStroke, {Transparency = 0.3}, TweenPresets.Fast)
end)
startButton.MouseLeave:Connect(function()
CreateTween(startButton, {BackgroundColor3 = Color3.fromRGB(35, 35, 50), BackgroundTransparency = 0.3}, TweenPresets.Fast)
CreateTween(startStroke, {Transparency = 0.7}, TweenPresets.Fast)
end)
pauseButton.MouseButton1Click:Connect(function()
if onPause then
local success, err = pcall(onPause)
if not success then
warn("GAeroUI Navigation Shortcut Pause Error:", err)
end
end
end)
pauseButton.MouseEnter:Connect(function()
CreateTween(pauseButton, {BackgroundColor3 = Color3.fromRGB(241, 196, 15), BackgroundTransparency = 0.1}, TweenPresets.Fast)
CreateTween(pauseStroke, {Transparency = 0.3}, TweenPresets.Fast)
end)
pauseButton.MouseLeave:Connect(function()
CreateTween(pauseButton, {BackgroundColor3 = Color3.fromRGB(35, 35, 50), BackgroundTransparency = 0.3}, TweenPresets.Fast)
CreateTween(pauseStroke, {Transparency = 0.7}, TweenPresets.Fast)
end)
stopButton.MouseButton1Click:Connect(function()
if onStop then
local success, err = pcall(onStop)
if not success then
warn("GAeroUI Navigation Shortcut Stop Error:", err)
end
end
end)
stopButton.MouseEnter:Connect(function()
CreateTween(stopButton, {BackgroundColor3 = Color3.fromRGB(231, 76, 60), BackgroundTransparency = 0.1}, TweenPresets.Fast)
CreateTween(stopStroke, {Transparency = 0.3}, TweenPresets.Fast)
end)
stopButton.MouseLeave:Connect(function()
CreateTween(stopButton, {BackgroundColor3 = Color3.fromRGB(35, 35, 50), BackgroundTransparency = 0.3}, TweenPresets.Fast)
CreateTween(stopStroke, {Transparency = 0.7}, TweenPresets.Fast)
end)
-- Make Draggable
local dragging = false
local dragInput
local dragStart
local startPos
local function update(input)
local delta = input.Position - dragStart
local newPosition = UDim2.new(
startPos.X.Scale,
startPos.X.Offset + delta.X,
startPos.Y.Scale,
startPos.Y.Offset + delta.Y
)
CreateTween(frame, {Position = newPosition}, TweenPresets.Fast)
end
frame.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPos = frame.Position
input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
dragging = false
end
end)
end
end)
frame.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
self.Connections.DragInput = UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging then
update(input)
end
end)
-- Fade in animation with proper transparency handling
frame.BackgroundTransparency = 1
startButton.BackgroundTransparency = 1
pauseButton.BackgroundTransparency = 1
stopButton.BackgroundTransparency = 1
startStroke.Transparency = 1
pauseStroke.Transparency = 1
stopStroke.Transparency = 1
for _, child in ipairs(frame:GetDescendants()) do
if child:IsA("ImageLabel") then
child.ImageTransparency = 1
end
end
task.wait(0.1)
CreateTween(frame, {BackgroundTransparency = 0.1}, TweenPresets.Medium)
CreateTween(startButton, {BackgroundTransparency = 0.3}, TweenPresets.Medium)
CreateTween(pauseButton, {BackgroundTransparency = 0.3}, TweenPresets.Medium)
CreateTween(stopButton, {BackgroundTransparency = 0.3}, TweenPresets.Medium)
CreateTween(startStroke, {Transparency = 0.7}, TweenPresets.Medium)
CreateTween(pauseStroke, {Transparency = 0.7}, TweenPresets.Medium)
CreateTween(stopStroke, {Transparency = 0.7}, TweenPresets.Medium)
for _, child in ipairs(frame:GetDescendants()) do
if child:IsA("ImageLabel") then
CreateTween(child, {ImageTransparency = 0}, TweenPresets.Medium)
end
end
self.Enabled = true
end
function shortcut:Destroy()
for _, connection in pairs(self.Connections) do
if connection and typeof(connection) == "RBXScriptConnection" then
connection:Disconnect()
end
end
self.Connections = {}
if self.ScreenGui then
self.ScreenGui:Destroy()
self.ScreenGui = nil
end
self.Frame = nil
self.StartButton = nil
self.PauseButton = nil
self.StopButton = nil
self.StartIcon = nil
self.PauseIcon = nil
self.StopIcon = nil
self.StartStroke = nil
self.PauseStroke = nil
self.StopStroke = nil
self.Enabled = false
end
function shortcut:Show()
if not self.Enabled then
self:Create()
elseif self.ScreenGui then
self.ScreenGui.Enabled = true
end
end
function shortcut:Hide()
if self.ScreenGui then
self.ScreenGui.Enabled = false
end
end
function shortcut:SetPauseText(text)
if self.PauseIcon then
-- Clear existing icon
for _, child in ipairs(self.PauseIcon:GetChildren()) do
child:Destroy()
end
-- Load appropriate icon based on state
-- When text is "Resume", show play icon (to resume playback)
-- When text is "Pause", show pause icon (to pause playback)
if text == "Resume" then
LoadLucideIcon("play", self.PauseIcon, Theme.WarningColor)
else
-- Default to pause icon for "Pause" or any other state
LoadLucideIcon("pause", self.PauseIcon, Theme.WarningColor)
end
end
end
function shortcut:UpdateCallbacks(newConfig)
if newConfig.OnStart then
onStart = newConfig.OnStart
end
if newConfig.OnPause then
onPause = newConfig.OnPause
end
if newConfig.OnStop then
onStop = newConfig.OnStop
end
end
return shortcut
end
return LibraryNo comments yet for this script.

![[KEYLESS] Moondiety Script | 17+ supported Games](https://scriptblox.com/images/sb/0-1753093706828.png)

