--[[ ECHELON UI LIBRARY v1.0 Premium Dark / Cyber Glass UI Library for Roblox Usage: local EchelonUI = loadstring(game:HttpGet("URL"))() ]] local EchelonUI = {} EchelonUI.__index = EchelonUI EchelonUI.Version = "1.0" EchelonUI.Name = "EchelonUI" -- Services local Players = game:GetService("Players") local TweenService = game:GetService("TweenService") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local HttpService = game:GetService("HttpService") local CoreGui = game:GetService("CoreGui") local GuiService = game:GetService("GuiService") local LocalPlayer = Players.LocalPlayer local Mouse = LocalPlayer:GetMouse() -- Utilities local function isMobile() return UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled end local function deepCopy(t) if type(t) ~= "table" then return t end local n = {} for k, v in pairs(t) do n[k] = deepCopy(v) end return n end local function clamp(v, min, max) return math.max(min, math.min(max, v)) end local function round(n, step) if not step or step == 0 then return n end return math.floor(n / step + 0.5) * step end local function create(class, props) local inst = Instance.new(class) for k, v in pairs(props or {}) do if k ~= "Parent" then inst[k] = v end end if props and props.Parent then inst.Parent = props.Parent end return inst end local function tween(obj, props, duration, style, dir) local t = TweenService:Create( obj, TweenInfo.new(duration or 0.25, style or Enum.EasingStyle.Quint, dir or Enum.EasingDirection.Out), props ) t:Play() return t end local function makeCorner(parent, radius) return create("UICorner", { CornerRadius = UDim.new(0, radius or 8), Parent = parent }) end local function makeStroke(parent, color, thickness, transparency) return create("UIStroke", { Color = color or Color3.fromRGB(60, 60, 80), Thickness = thickness or 1, Transparency = transparency or 0.4, ApplyStrokeMode = Enum.ApplyStrokeMode.Border, Parent = parent }) end local function makePadding(parent, t, b, l, r) return create("UIPadding", { PaddingTop = UDim.new(0, t or 0), PaddingBottom = UDim.new(0, b or 0), PaddingLeft = UDim.new(0, l or 0), PaddingRight = UDim.new(0, r or 0), Parent = parent }) end local function makeList(parent, pad, dir, hAlign, vAlign) return create("UIListLayout", { Padding = UDim.new(0, pad or 6), FillDirection = dir or Enum.FillDirection.Vertical, HorizontalAlignment = hAlign or Enum.HorizontalAlignment.Left, VerticalAlignment = vAlign or Enum.VerticalAlignment.Top, SortOrder = Enum.SortOrder.LayoutOrder, Parent = parent }) end -- ============================================================ -- THEME SYSTEM -- ============================================================ local ThemeRegistry = {} -- elements that react to theme changes local DefaultThemes = { Aqua = { bg = Color3.fromRGB(12, 14, 22), bg2 = Color3.fromRGB(18, 22, 34), bg3 = Color3.fromRGB(24, 30, 46), bg4 = Color3.fromRGB(32, 40, 58), accent = Color3.fromRGB(0, 210, 200), accent2 = Color3.fromRGB(0, 160, 180), accent3 = Color3.fromRGB(40, 240, 220), accentGlow = Color3.fromRGB(0, 255, 240), text = Color3.fromRGB(235, 240, 250), text2 = Color3.fromRGB(160, 175, 200), text3 = Color3.fromRGB(100, 115, 140), border = Color3.fromRGB(45, 55, 80), borderSoft = Color3.fromRGB(30, 38, 55), red = Color3.fromRGB(255, 70, 90), green = Color3.fromRGB(60, 220, 140), gold = Color3.fromRGB(255, 200, 60), }, Purple = { bg = Color3.fromRGB(14, 12, 22), bg2 = Color3.fromRGB(22, 18, 34), bg3 = Color3.fromRGB(30, 24, 46), bg4 = Color3.fromRGB(40, 32, 58), accent = Color3.fromRGB(170, 90, 255), accent2 = Color3.fromRGB(130, 60, 220), accent3 = Color3.fromRGB(200, 130, 255), accentGlow = Color3.fromRGB(190, 110, 255), text = Color3.fromRGB(235, 235, 250), text2 = Color3.fromRGB(170, 160, 200), text3 = Color3.fromRGB(110, 100, 140), border = Color3.fromRGB(55, 45, 80), borderSoft = Color3.fromRGB(38, 30, 55), red = Color3.fromRGB(255, 70, 90), green = Color3.fromRGB(60, 220, 140), gold = Color3.fromRGB(255, 200, 60), }, Red = { bg = Color3.fromRGB(16, 12, 14), bg2 = Color3.fromRGB(26, 16, 20), bg3 = Color3.fromRGB(36, 22, 26), bg4 = Color3.fromRGB(48, 28, 34), accent = Color3.fromRGB(255, 70, 90), accent2 = Color3.fromRGB(200, 40, 60), accent3 = Color3.fromRGB(255, 120, 130), accentGlow = Color3.fromRGB(255, 90, 110), text = Color3.fromRGB(245, 235, 235), text2 = Color3.fromRGB(190, 160, 165), text3 = Color3.fromRGB(130, 100, 105), border = Color3.fromRGB(70, 40, 48), borderSoft = Color3.fromRGB(48, 28, 34), red = Color3.fromRGB(255, 70, 90), green = Color3.fromRGB(60, 220, 140), gold = Color3.fromRGB(255, 200, 60), }, Blue = { bg = Color3.fromRGB(10, 14, 24), bg2 = Color3.fromRGB(14, 20, 36), bg3 = Color3.fromRGB(20, 28, 48), bg4 = Color3.fromRGB(28, 38, 62), accent = Color3.fromRGB(60, 140, 255), accent2 = Color3.fromRGB(40, 100, 220), accent3 = Color3.fromRGB(100, 180, 255), accentGlow = Color3.fromRGB(80, 160, 255), text = Color3.fromRGB(230, 240, 255), text2 = Color3.fromRGB(150, 175, 210), text3 = Color3.fromRGB(90, 115, 150), border = Color3.fromRGB(40, 55, 90), borderSoft = Color3.fromRGB(28, 38, 60), red = Color3.fromRGB(255, 70, 90), green = Color3.fromRGB(60, 220, 140), gold = Color3.fromRGB(255, 200, 60), }, } local CurrentTheme = deepCopy(DefaultThemes.Aqua) local CustomThemes = {} function EchelonUI:AddTheme(name, data) CustomThemes[name] = data end function EchelonUI:GetTheme(name) return CustomThemes[name] or DefaultThemes[name] or CurrentTheme end local function applyThemeToRegistry() for _, entry in ipairs(ThemeRegistry) do if entry and entry.Update then pcall(entry.Update, CurrentTheme) end end end local function registerTheme(updateFn) local entry = { Update = updateFn } table.insert(ThemeRegistry, entry) return entry end -- ============================================================ -- ICON SYSTEM -- ============================================================ local IconPack = "lucide" local IconCache = {} local IconsModule = nil local function loadIcons() if IconsModule then return IconsModule end local sources = { "https://raw.githubusercontent.com/Footagesus/Icons/main/Main-v2.lua", "https://raw.githubusercontent.com/Footagesus/Icons/main/Main.lua", } for _, url in ipairs(sources) do local ok, result = pcall(function() return loadstring(game:HttpGet(url))() end) if ok and result then IconsModule = result return IconsModule end end return nil end function EchelonUI:SetIconPack(pack) IconPack = pack or "lucide" IconCache = {} end function EchelonUI:GetIcon(name) if not name or name == "" then return nil end if typeof(name) == "string" and name:find("rbxassetid://") then return { Image = name, ImageRectSize = Vector2.new(0, 0), ImageRectOffset = Vector2.new(0, 0) } end if IconCache[name] then return IconCache[name] end local mod = loadIcons() if mod and mod.GetIcon then local ok, data = pcall(mod.GetIcon, name, IconPack) if ok and data then IconCache[name] = data return data end end -- fallback empty return { Image = "rbxassetid://0", ImageRectSize = Vector2.new(0, 0), ImageRectOffset = Vector2.new(0, 0) } end local function applyIcon(imageLabel, iconName, color) local data = EchelonUI:GetIcon(iconName) if not data then return end imageLabel.Image = data.Image or data if data.ImageRectSize and data.ImageRectSize.X > 0 then imageLabel.ImageRectSize = data.ImageRectSize imageLabel.ImageRectOffset = data.ImageRectOffset or Vector2.new(0, 0) end if color then imageLabel.ImageColor3 = color end end -- ============================================================ -- CONFIG SYSTEM -- ============================================================ local ConfigFolder = "EchelonUI_Configs" local ConfigData = {} -- in-memory + file if possible local FlagMap = {} -- Flag -> {Set, Get} local function ensureFolder() if not isfolder then return false end if not isfolder(ConfigFolder) then pcall(makefolder, ConfigFolder) end return true end function EchelonUI:SaveConfig(name) name = name or "default" local data = {} for flag, handlers in pairs(FlagMap) do if handlers.Get then data[flag] = handlers.Get() end end ConfigData[name] = data if ensureFolder() and writefile then pcall(writefile, ConfigFolder .. "/" .. name .. ".json", HttpService:JSONEncode(data)) end return true end function EchelonUI:LoadConfig(name) name = name or "default" local data = ConfigData[name] if not data and ensureFolder() and readfile and isfile then local path = ConfigFolder .. "/" .. name .. ".json" if isfile(path) then local ok, decoded = pcall(function() return HttpService:JSONDecode(readfile(path)) end) if ok and decoded then data = decoded ConfigData[name] = data end end end if not data then return false end for flag, value in pairs(data) do local handlers = FlagMap[flag] if handlers and handlers.Set then pcall(handlers.Set, value) end end return true end function EchelonUI:DeleteConfig(name) name = name or "default" ConfigData[name] = nil if ensureFolder() and isfile and delfile then local path = ConfigFolder .. "/" .. name .. ".json" if isfile(path) then pcall(delfile, path) end end end function EchelonUI:GetConfigs() local list = {} for k in pairs(ConfigData) do table.insert(list, k) end if ensureFolder() and listfiles then local ok, files = pcall(listfiles, ConfigFolder) if ok and files then for _, f in ipairs(files) do local n = f:match("([^/\\]+)%.json$") if n and not table.find(list, n) then table.insert(list, n) end end end end return list end local function registerFlag(flag, getFn, setFn) if not flag or flag == "" then return end FlagMap[flag] = { Get = getFn, Set = setFn } end -- ============================================================ -- PLATFORM HELPERS -- ============================================================ function EchelonUI:GetPlatform() if isMobile() then return "Mobile" end return "PC" end function EchelonUI:GetExecutor() local names = { "Synapse", "Script-Ware", "Krnl", "Fluxus", "Oxygen", "Electron", "Delta", "Codex", "Solara", "Wave" } for _, n in ipairs(names) do if identifyexecutor and identifyexecutor():lower():find(n:lower()) then return n end end if identifyexecutor then return identifyexecutor() end return "Unknown" end -- ============================================================ -- NOTIFICATION SYSTEM -- ============================================================ local NotifyContainer = nil local ActiveNotifies = {} local function ensureNotifyContainer() if NotifyContainer and NotifyContainer.Parent then return NotifyContainer end local gui = create("ScreenGui", { Name = "EchelonUI_Notifications", ResetOnSpawn = false, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 9999, Parent = (gethui and gethui()) or CoreGui }) NotifyContainer = create("Frame", { Name = "Container", BackgroundTransparency = 1, Size = UDim2.new(0, 320, 1, -40), Position = UDim2.new(1, -340, 0, 20), Parent = gui }) makeList(NotifyContainer, 8, Enum.FillDirection.Vertical, Enum.HorizontalAlignment.Right, Enum.VerticalAlignment.Top) return NotifyContainer end local TypeColors = { Success = function(t) return t.green end, Error = function(t) return t.red end, Warning = function(t) return t.gold end, Info = function(t) return t.accent end, } function EchelonUI:Notify(opts) opts = opts or {} local title = opts.Title or "Notification" local content = opts.Content or "" local nType = opts.Type or "Info" local duration = opts.Duration or 4 local theme = CurrentTheme local container = ensureNotifyContainer() local accent = (TypeColors[nType] or TypeColors.Info)(theme) local card = create("Frame", { Name = "Notify", BackgroundColor3 = theme.bg2, BackgroundTransparency = 0.1, Size = UDim2.new(1, 0, 0, 0), ClipsDescendants = true, Parent = container }) makeCorner(card, 10) local stroke = makeStroke(card, accent, 1.2, 0.3) local accentBar = create("Frame", { BackgroundColor3 = accent, BorderSizePixel = 0, Size = UDim2.new(0, 3, 1, 0), Parent = card }) makeCorner(accentBar, 2) local titleL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 14, 0, 8), Size = UDim2.new(1, -40, 0, 18), Font = Enum.Font.GothamBold, Text = title, TextColor3 = theme.text, TextSize = 14, TextXAlignment = Enum.TextXAlignment.Left, Parent = card }) local contentL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 14, 0, 28), Size = UDim2.new(1, -24, 0, 0), Font = Enum.Font.Gotham, Text = content, TextColor3 = theme.text2, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, TextWrapped = true, Parent = card }) contentL.Size = UDim2.new(1, -24, 0, contentL.TextBounds.Y + 4) card.Size = UDim2.new(1, 0, 0, 40 + contentL.TextBounds.Y) local closeBtn = create("TextButton", { BackgroundTransparency = 1, Position = UDim2.new(1, -28, 0, 6), Size = UDim2.new(0, 22, 0, 22), Text = "×", Font = Enum.Font.GothamBold, TextSize = 16, TextColor3 = theme.text3, Parent = card }) local progress = create("Frame", { BackgroundColor3 = accent, BorderSizePixel = 0, Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(1, 0, 0, 2), Parent = card }) card.Position = UDim2.new(1, 40, 0, 0) tween(card, { Position = UDim2.new(0, 0, 0, 0) }, 0.35) local closed = false local function close() if closed then return end closed = true tween(card, { Position = UDim2.new(1, 40, 0, 0), BackgroundTransparency = 1 }, 0.3) task.delay(0.35, function() if card then card:Destroy() end end) end closeBtn.MouseButton1Click:Connect(close) tween(progress, { Size = UDim2.new(0, 0, 0, 2) }, duration, Enum.EasingStyle.Linear) task.delay(duration, close) registerTheme(function(t) if not card or not card.Parent then return end card.BackgroundColor3 = t.bg2 titleL.TextColor3 = t.text contentL.TextColor3 = t.text2 local a = (TypeColors[nType] or TypeColors.Info)(t) accentBar.BackgroundColor3 = a progress.BackgroundColor3 = a stroke.Color = a end) end -- ============================================================ -- WINDOW -- ============================================================ local Windows = {} function EchelonUI:CreateWindow(opts) opts = opts or {} local title = opts.Title or "ECHELON UI" local subTitle = opts.SubTitle or opts.Version or "1.0" local logoId = opts.Logo local size = opts.Size or UDim2.fromOffset(500, 580) local mobileSize = opts.MobileSize or UDim2.fromOffset(340, 420) local themeName = opts.Theme or "Aqua" local bgTrans = opts.BackgroundTransparency or 0.05 local titleAnim = opts.TitleAnimation ~= false local draggable = opts.Draggable ~= false local minimizable = opts.Minimizable ~= false local closable = opts.Closable ~= false local keybind = opts.Keybind or Enum.KeyCode.RightShift local cornerR = opts.CornerRadius or 12 local strokeT = opts.StrokeThickness or 1.2 local showStatus = opts.ShowStatusBar ~= false local loadingScreen = opts.LoadingScreen ~= false local accentOverride = opts.AccentColor local fontTitle = opts.FontTitle or Enum.Font.GothamBold local fontBody = opts.FontBody or Enum.Font.Gotham -- Apply theme local themeData = EchelonUI:GetTheme(themeName) CurrentTheme = deepCopy(themeData) if accentOverride then CurrentTheme.accent = accentOverride CurrentTheme.accent2 = accentOverride CurrentTheme.accent3 = accentOverride CurrentTheme.accentGlow = accentOverride end local finalSize = isMobile() and mobileSize or size local guiParent = (gethui and gethui()) or CoreGui local screenGui = create("ScreenGui", { Name = "EchelonUI_" .. HttpService:GenerateGUID(false):sub(1, 8), ResetOnSpawn = false, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 100, Parent = guiParent }) -- Loading Screen local loadingFrame = nil if loadingScreen then loadingFrame = create("Frame", { Name = "Loading", BackgroundColor3 = CurrentTheme.bg, Size = UDim2.fromScale(1, 1), ZIndex = 50, Parent = screenGui }) local loadLogo = create("ImageLabel", { BackgroundTransparency = 1, AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.38), Size = UDim2.fromOffset(64, 64), Image = logoId or "rbxassetid://0", ImageColor3 = CurrentTheme.accent, Parent = loadingFrame }) makeCorner(loadLogo, 12) local loadTitle = create("TextLabel", { BackgroundTransparency = 1, AnchorPoint = Vector2.new(0.5, 0), Position = UDim2.new(0.5, 0, 0.38, 80), Size = UDim2.new(0, 300, 0, 28), Font = fontTitle, Text = title, TextColor3 = CurrentTheme.text, TextSize = 22, Parent = loadingFrame }) local loadVer = create("TextLabel", { BackgroundTransparency = 1, AnchorPoint = Vector2.new(0.5, 0), Position = UDim2.new(0.5, 0, 0.38, 110), Size = UDim2.new(0, 200, 0, 18), Font = fontBody, Text = "v" .. subTitle, TextColor3 = CurrentTheme.text2, TextSize = 13, Parent = loadingFrame }) local progressBg = create("Frame", { BackgroundColor3 = CurrentTheme.bg3, AnchorPoint = Vector2.new(0.5, 0), Position = UDim2.new(0.5, 0, 0.38, 150), Size = UDim2.new(0, 200, 0, 4), Parent = loadingFrame }) makeCorner(progressBg, 2) local progressFill = create("Frame", { BackgroundColor3 = CurrentTheme.accent, Size = UDim2.new(0, 0, 1, 0), Parent = progressBg }) makeCorner(progressFill, 2) local statusText = create("TextLabel", { BackgroundTransparency = 1, AnchorPoint = Vector2.new(0.5, 0), Position = UDim2.new(0.5, 0, 0.38, 165), Size = UDim2.new(0, 250, 0, 16), Font = fontBody, Text = "Initializing...", TextColor3 = CurrentTheme.text3, TextSize = 11, Parent = loadingFrame }) task.spawn(function() local steps = { "Loading assets", "Building interface", "Applying theme", "Ready" } for i, s in ipairs(steps) do statusText.Text = s tween(progressFill, { Size = UDim2.new(i / #steps, 0, 1, 0) }, 0.25) task.wait(0.22) end tween(loadingFrame, { BackgroundTransparency = 1 }, 0.4) for _, c in ipairs(loadingFrame:GetDescendants()) do if c:IsA("TextLabel") or c:IsA("ImageLabel") then tween(c, { TextTransparency = 1, ImageTransparency = 1 }, 0.35) elseif c:IsA("Frame") then tween(c, { BackgroundTransparency = 1 }, 0.35) end end task.wait(0.45) if loadingFrame then loadingFrame:Destroy() end end) end -- Main Window local main = create("Frame", { Name = "Main", BackgroundColor3 = CurrentTheme.bg, BackgroundTransparency = bgTrans, Size = finalSize, Position = UDim2.fromScale(0.5, 0.5), AnchorPoint = Vector2.new(0.5, 0.5), ClipsDescendants = true, Visible = not loadingScreen, Parent = screenGui }) makeCorner(main, cornerR) local mainStroke = makeStroke(main, CurrentTheme.border, strokeT, 0.35) -- Top gradient line local topLine = create("Frame", { Name = "TopLine", BackgroundColor3 = CurrentTheme.accent, BorderSizePixel = 0, Size = UDim2.new(1, 0, 0, 2), Position = UDim2.new(0, 0, 0, 0), ZIndex = 5, Parent = main }) local topGrad = create("UIGradient", { Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, CurrentTheme.accent), ColorSequenceKeypoint.new(0.5, CurrentTheme.accent3), ColorSequenceKeypoint.new(1, CurrentTheme.accent2), }), Parent = topLine }) if titleAnim then task.spawn(function() while topLine and topLine.Parent do tween(topGrad, { Offset = Vector2.new(1, 0) }, 2.5, Enum.EasingStyle.Linear) task.wait(2.5) topGrad.Offset = Vector2.new(-1, 0) end end) end -- Title Bar local titleBar = create("Frame", { Name = "TitleBar", BackgroundColor3 = CurrentTheme.bg2, BackgroundTransparency = 0.3, Size = UDim2.new(1, 0, 0, 48), Parent = main }) -- only bottom corners avoided by clipping local logoImg = nil if logoId then logoImg = create("ImageLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(28, 28), Image = logoId, Parent = titleBar }) makeCorner(logoImg, 6) end local titleLabel = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, logoId and 48 or 14, 0, 6), Size = UDim2.new(1, -140, 0, 20), Font = fontTitle, Text = title, TextColor3 = CurrentTheme.text, TextSize = 15, TextXAlignment = Enum.TextXAlignment.Left, Parent = titleBar }) local subLabel = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, logoId and 48 or 14, 0, 26), Size = UDim2.new(1, -140, 0, 14), Font = fontBody, Text = subTitle, TextColor3 = CurrentTheme.text3, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, Parent = titleBar }) -- Window controls local controls = create("Frame", { BackgroundTransparency = 1, Position = UDim2.new(1, -90, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(80, 28), Parent = titleBar }) makeList(controls, 4, Enum.FillDirection.Horizontal, Enum.HorizontalAlignment.Right) local function makeControlBtn(txt, color) local b = create("TextButton", { BackgroundColor3 = CurrentTheme.bg3, Size = UDim2.fromOffset(24, 24), Text = txt, Font = Enum.Font.GothamBold, TextSize = 12, TextColor3 = color or CurrentTheme.text2, AutoButtonColor = false, Parent = controls }) makeCorner(b, 6) b.MouseEnter:Connect(function() tween(b, { BackgroundColor3 = CurrentTheme.bg4 }, 0.15) end) b.MouseLeave:Connect(function() tween(b, { BackgroundColor3 = CurrentTheme.bg3 }, 0.15) end) return b end local minimized = false local minBtn, closeBtn if minimizable then minBtn = makeControlBtn("–") end if closable then closeBtn = makeControlBtn("×", CurrentTheme.red) end -- Tab bar (left) local tabBarWidth = 58 local tabBar = create("Frame", { Name = "TabBar", BackgroundColor3 = CurrentTheme.bg2, BackgroundTransparency = 0.25, Position = UDim2.new(0, 0, 0, 48), Size = UDim2.new(0, tabBarWidth, 1, showStatus and -70 or -48), Parent = main }) local tabList = create("ScrollingFrame", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), CanvasSize = UDim2.new(0, 0, 0, 0), ScrollBarThickness = 0, BorderSizePixel = 0, Parent = tabBar }) makeList(tabList, 4, Enum.FillDirection.Vertical, Enum.HorizontalAlignment.Center) makePadding(tabList, 8, 8, 6, 6) -- Content area local contentArea = create("Frame", { Name = "Content", BackgroundTransparency = 1, Position = UDim2.new(0, tabBarWidth, 0, 48), Size = UDim2.new(1, -tabBarWidth, 1, showStatus and -70 or -48), ClipsDescendants = true, Parent = main }) -- Status bar local statusBar = nil if showStatus then statusBar = create("Frame", { Name = "StatusBar", BackgroundColor3 = CurrentTheme.bg2, BackgroundTransparency = 0.3, Position = UDim2.new(0, 0, 1, -22), Size = UDim2.new(1, 0, 0, 22), Parent = main }) local statusL = create("TextLabel", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Font = fontBody, Text = " " .. EchelonUI:GetPlatform() .. " | " .. EchelonUI:GetExecutor() .. " | EchelonUI " .. EchelonUI.Version, TextColor3 = CurrentTheme.text3, TextSize = 10, TextXAlignment = Enum.TextXAlignment.Left, Parent = statusBar }) end -- Dragging if draggable then local dragging, dragStart, startPos titleBar.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = main.Position end end) titleBar.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 delta = input.Position - dragStart main.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) end end) end -- Minimize local originalSize = finalSize if minBtn then minBtn.MouseButton1Click:Connect(function() minimized = not minimized if minimized then tween(main, { Size = UDim2.fromOffset(finalSize.X.Offset, 48) }, 0.3) contentArea.Visible = false tabBar.Visible = false if statusBar then statusBar.Visible = false end else tween(main, { Size = originalSize }, 0.3) contentArea.Visible = true tabBar.Visible = true if statusBar then statusBar.Visible = true end end end) end -- Close if closeBtn then closeBtn.MouseButton1Click:Connect(function() tween(main, { Size = UDim2.fromOffset(0, 0), BackgroundTransparency = 1 }, 0.25) task.delay(0.3, function() screenGui:Destroy() end) end) end -- Keybind toggle local visible = true UserInputService.InputBegan:Connect(function(input, gpe) if gpe then return end if input.KeyCode == keybind then visible = not visible main.Visible = visible end end) -- Theme live update registration registerTheme(function(t) main.BackgroundColor3 = t.bg mainStroke.Color = t.border titleBar.BackgroundColor3 = t.bg2 titleLabel.TextColor3 = t.text subLabel.TextColor3 = t.text3 tabBar.BackgroundColor3 = t.bg2 topLine.BackgroundColor3 = t.accent topGrad.Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, t.accent), ColorSequenceKeypoint.new(0.5, t.accent3), ColorSequenceKeypoint.new(1, t.accent2), }) if statusBar then statusBar.BackgroundColor3 = t.bg2 end end) -- Window object local Window = {} Window._gui = screenGui Window._main = main Window._tabs = {} Window._currentTab = nil Window._theme = CurrentTheme function Window:SetTheme(name) local t = EchelonUI:GetTheme(name) if not t then return end CurrentTheme = deepCopy(t) applyThemeToRegistry() end function Window:SetBackgroundTransparency(v) bgTrans = clamp(v, 0, 0.6) main.BackgroundTransparency = bgTrans end function Window:SetTitleAnimation(enabled) titleAnim = enabled end function Window:Notify(opts) EchelonUI:Notify(opts) end function Window:Destroy() screenGui:Destroy() end -- ======================================================== -- TAB -- ======================================================== function Window:CreateTab(tabOpts) tabOpts = tabOpts or {} local tabName = tabOpts.Name or "Tab" local tabIcon = tabOpts.Icon or "circle" local order = tabOpts.Order or (#Window._tabs + 1) local tabBtn = create("TextButton", { BackgroundColor3 = CurrentTheme.bg3, BackgroundTransparency = 0.4, Size = UDim2.fromOffset(44, 44), Text = "", AutoButtonColor = false, LayoutOrder = order, Parent = tabList }) makeCorner(tabBtn, 10) local iconImg = create("ImageLabel", { BackgroundTransparency = 1, AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(20, 20), Parent = tabBtn }) applyIcon(iconImg, tabIcon, CurrentTheme.text2) local indicator = create("Frame", { BackgroundColor3 = CurrentTheme.accent, Size = UDim2.new(0, 3, 0, 0), Position = UDim2.new(0, 0, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Visible = false, Parent = tabBtn }) makeCorner(indicator, 2) local page = create("ScrollingFrame", { Name = tabName, BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), CanvasSize = UDim2.new(0, 0, 0, 0), ScrollBarThickness = 3, ScrollBarImageColor3 = CurrentTheme.accent, BorderSizePixel = 0, Visible = false, Parent = contentArea }) makePadding(page, 10, 10, 12, 12) local pageLayout = makeList(page, 8) pageLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() page.CanvasSize = UDim2.new(0, 0, 0, pageLayout.AbsoluteContentSize.Y + 20) end) local Tab = { _btn = tabBtn, _page = page, _name = tabName, } local function selectTab() for _, t in ipairs(Window._tabs) do t._page.Visible = false t._btn.BackgroundTransparency = 0.4 t._btn.BackgroundColor3 = CurrentTheme.bg3 local ind = t._btn:FindFirstChild("Frame") if ind then ind.Visible = false; ind.Size = UDim2.new(0, 3, 0, 0) end local ic = t._btn:FindFirstChildOfClass("ImageLabel") if ic then ic.ImageColor3 = CurrentTheme.text2 end end page.Visible = true tabBtn.BackgroundTransparency = 0.1 tabBtn.BackgroundColor3 = CurrentTheme.bg4 indicator.Visible = true tween(indicator, { Size = UDim2.new(0, 3, 0.6, 0) }, 0.2) iconImg.ImageColor3 = CurrentTheme.accent Window._currentTab = Tab end tabBtn.MouseButton1Click:Connect(selectTab) tabBtn.MouseEnter:Connect(function() if Window._currentTab ~= Tab then tween(tabBtn, { BackgroundTransparency = 0.2 }, 0.15) end end) tabBtn.MouseLeave:Connect(function() if Window._currentTab ~= Tab then tween(tabBtn, { BackgroundTransparency = 0.4 }, 0.15) end end) registerTheme(function(t) tabBtn.BackgroundColor3 = (Window._currentTab == Tab) and t.bg4 or t.bg3 iconImg.ImageColor3 = (Window._currentTab == Tab) and t.accent or t.text2 indicator.BackgroundColor3 = t.accent page.ScrollBarImageColor3 = t.accent end) table.insert(Window._tabs, Tab) if #Window._tabs == 1 then selectTab() end -- Auto canvas tabList.CanvasSize = UDim2.new(0, 0, 0, (#Window._tabs) * 48 + 16) -- ==================================================== -- SECTION -- ==================================================== function Tab:CreateSection(secOpts) secOpts = secOpts or {} local secTitle = secOpts.Title or "Section" local secIcon = secOpts.Icon local sec = create("Frame", { BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 28), Parent = page }) local bar = create("Frame", { BackgroundColor3 = CurrentTheme.accent, Size = UDim2.new(0, 3, 0, 14), Position = UDim2.new(0, 0, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Parent = sec }) makeCorner(bar, 2) local iconS = nil if secIcon then iconS = create("ImageLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 10, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(14, 14), Parent = sec }) applyIcon(iconS, secIcon, CurrentTheme.accent) end local titleS = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, secIcon and 28 or 10, 0, 0), Size = UDim2.new(1, -30, 1, 0), Font = Enum.Font.GothamBold, Text = secTitle:upper(), TextColor3 = CurrentTheme.accent, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, Parent = sec }) registerTheme(function(t) bar.BackgroundColor3 = t.accent titleS.TextColor3 = t.accent if iconS then iconS.ImageColor3 = t.accent end end) return sec end -- ==================================================== -- ELEMENT CONTAINER HELPER -- ==================================================== local function makeElementContainer(height) local frame = create("Frame", { BackgroundColor3 = CurrentTheme.bg3, BackgroundTransparency = 0.35, Size = UDim2.new(1, 0, 0, height or 42), Parent = page }) makeCorner(frame, 8) makeStroke(frame, CurrentTheme.borderSoft, 1, 0.5) return frame end -- ==================================================== -- TOGGLE -- ==================================================== function Tab:CreateToggle(tOpts) tOpts = tOpts or {} local name = tOpts.Name or "Toggle" local desc = tOpts.Description local default = tOpts.Default or false local flag = tOpts.Flag local callback = tOpts.Callback or function() end local h = desc and 52 or 40 local frame = makeElementContainer(h) local value = default local nameL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0, desc and 6 or 0), Size = UDim2.new(1, -70, 0, 18), Font = Enum.Font.GothamMedium, Text = name, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) if desc then create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0, 26), Size = UDim2.new(1, -70, 0, 16), Font = fontBody, Text = desc, TextColor3 = CurrentTheme.text3, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) end local track = create("Frame", { BackgroundColor3 = value and CurrentTheme.accent or CurrentTheme.bg4, Position = UDim2.new(1, -48, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(36, 20), Parent = frame }) makeCorner(track, 10) local thumb = create("Frame", { BackgroundColor3 = Color3.fromRGB(255, 255, 255), Position = value and UDim2.new(1, -18, 0.5, 0) or UDim2.new(0, 2, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(16, 16), Parent = track }) makeCorner(thumb, 8) local function set(v, silent) value = v tween(track, { BackgroundColor3 = value and CurrentTheme.accent or CurrentTheme.bg4 }, 0.2) tween(thumb, { Position = value and UDim2.new(1, -18, 0.5, 0) or UDim2.new(0, 2, 0.5, 0) }, 0.2) if not silent then pcall(callback, value) end end local btn = create("TextButton", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Text = "", Parent = frame }) btn.MouseButton1Click:Connect(function() set(not value) end) registerFlag(flag, function() return value end, function(v) set(v, true) end) registerTheme(function(t) nameL.TextColor3 = t.text track.BackgroundColor3 = value and t.accent or t.bg4 frame.BackgroundColor3 = t.bg3 end) local obj = { SetValue = function(_, v) set(v) end, GetValue = function() return value end, SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } return obj end -- ==================================================== -- BUTTON -- ==================================================== function Tab:CreateButton(bOpts) bOpts = bOpts or {} local name = bOpts.Name or "Button" local desc = bOpts.Description local icon = bOpts.Icon local image = bOpts.Image local color = bOpts.Color local callback = bOpts.Callback or function() end local h = desc and 52 or 40 local frame = makeElementContainer(h) if color then frame.BackgroundColor3 = color end if image then create("ImageLabel", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Image = image, ImageTransparency = 0.7, ScaleType = Enum.ScaleType.Crop, Parent = frame }) end local iconImgB = nil if icon then iconImgB = create("ImageLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(16, 16), Parent = frame }) applyIcon(iconImgB, icon, color and Color3.new(1,1,1) or CurrentTheme.accent) end local nameL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, icon and 34 or 12, 0, desc and 6 or 0), Size = UDim2.new(1, -20, 0, 18), Font = Enum.Font.GothamMedium, Text = name, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) if desc then create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, icon and 34 or 12, 0, 26), Size = UDim2.new(1, -20, 0, 16), Font = fontBody, Text = desc, TextColor3 = CurrentTheme.text3, TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) end local btn = create("TextButton", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Text = "", Parent = frame }) btn.MouseEnter:Connect(function() tween(frame, { BackgroundTransparency = 0.15 }, 0.15) end) btn.MouseLeave:Connect(function() tween(frame, { BackgroundTransparency = 0.35 }, 0.15) end) btn.MouseButton1Down:Connect(function() tween(frame, { Size = UDim2.new(1, -4, 0, h - 2) }, 0.08) end) btn.MouseButton1Up:Connect(function() tween(frame, { Size = UDim2.new(1, 0, 0, h) }, 0.1) end) btn.MouseButton1Click:Connect(function() pcall(callback) end) registerTheme(function(t) if not color then frame.BackgroundColor3 = t.bg3 end nameL.TextColor3 = t.text if iconImgB then iconImgB.ImageColor3 = t.accent end end) return { SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end -- ==================================================== -- SLIDER -- ==================================================== function Tab:CreateSlider(sOpts) sOpts = sOpts or {} local name = sOpts.Name or "Slider" local min = sOpts.Min or 0 local max = sOpts.Max or 100 local default = sOpts.Default or min local increment = sOpts.Increment or 1 local suffix = sOpts.Suffix or "" local flag = sOpts.Flag local callback = sOpts.Callback or function() end local frame = makeElementContainer(56) local value = clamp(default, min, max) local nameL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0, 6), Size = UDim2.new(0.6, 0, 0, 16), Font = Enum.Font.GothamMedium, Text = name, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) local valueL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0.6, 0, 0, 6), Size = UDim2.new(0.4, -12, 0, 16), Font = Enum.Font.Gotham, Text = tostring(value) .. suffix, TextColor3 = CurrentTheme.accent, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Right, Parent = frame }) local track = create("Frame", { BackgroundColor3 = CurrentTheme.bg4, Position = UDim2.new(0, 12, 0, 32), Size = UDim2.new(1, -24, 0, 6), Parent = frame }) makeCorner(track, 3) local fill = create("Frame", { BackgroundColor3 = CurrentTheme.accent, Size = UDim2.new((value - min) / (max - min), 0, 1, 0), Parent = track }) makeCorner(fill, 3) local knob = create("Frame", { BackgroundColor3 = Color3.fromRGB(255, 255, 255), Size = UDim2.fromOffset(14, 14), Position = UDim2.new((value - min) / (max - min), 0, 0.5, 0), AnchorPoint = Vector2.new(0.5, 0.5), Parent = track }) makeCorner(knob, 7) local function set(v, silent) value = clamp(round(v, increment), min, max) local pct = (value - min) / math.max(max - min, 0.001) fill.Size = UDim2.new(pct, 0, 1, 0) knob.Position = UDim2.new(pct, 0, 0.5, 0) valueL.Text = tostring(value) .. suffix if not silent then pcall(callback, value) end end local sliding = false local function updateFromInput(input) local rel = (input.Position.X - track.AbsolutePosition.X) / track.AbsoluteSize.X set(min + rel * (max - min)) end track.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then sliding = true updateFromInput(input) end end) UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then sliding = false end end) UserInputService.InputChanged:Connect(function(input) if sliding and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then updateFromInput(input) end end) registerFlag(flag, function() return value end, function(v) set(v, true) end) registerTheme(function(t) nameL.TextColor3 = t.text valueL.TextColor3 = t.accent fill.BackgroundColor3 = t.accent frame.BackgroundColor3 = t.bg3 track.BackgroundColor3 = t.bg4 end) return { SetValue = function(_, v) set(v) end, GetValue = function() return value end, SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end -- ==================================================== -- DROPDOWN -- ==================================================== function Tab:CreateDropdown(dOpts) dOpts = dOpts or {} local name = dOpts.Name or "Dropdown" local options = dOpts.Options or {} local default = dOpts.Default or 1 local multi = dOpts.Multi or false local flag = dOpts.Flag local callback = dOpts.Callback or function() end local search = dOpts.Search local frame = makeElementContainer(40) local selected = multi and {} or (options[default] or options[1]) if multi and type(default) == "table" then selected = default end local nameL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0, 0), Size = UDim2.new(0.45, 0, 1, 0), Font = Enum.Font.GothamMedium, Text = name, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) local display = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0.45, 0, 0, 0), Size = UDim2.new(0.45, 0, 1, 0), Font = fontBody, Text = multi and (table.concat(selected, ", ") or "None") or tostring(selected), TextColor3 = CurrentTheme.text2, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Right, TextTruncate = Enum.TextTruncate.AtEnd, Parent = frame }) local arrow = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(1, -24, 0, 0), Size = UDim2.fromOffset(20, 40), Font = Enum.Font.GothamBold, Text = "▾", TextColor3 = CurrentTheme.text3, TextSize = 12, Parent = frame }) local dropFrame = create("Frame", { BackgroundColor3 = CurrentTheme.bg2, Size = UDim2.new(1, 0, 0, 0), Position = UDim2.new(0, 0, 1, 4), Visible = false, ClipsDescendants = true, ZIndex = 20, Parent = frame }) makeCorner(dropFrame, 8) makeStroke(dropFrame, CurrentTheme.border, 1, 0.4) local dropList = create("ScrollingFrame", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), CanvasSize = UDim2.new(0, 0, 0, 0), ScrollBarThickness = 3, BorderSizePixel = 0, ZIndex = 21, Parent = dropFrame }) makeList(dropList, 2) makePadding(dropList, 4, 4, 4, 4) local open = false local function refreshDisplay() if multi then display.Text = #selected > 0 and table.concat(selected, ", ") or "None" else display.Text = tostring(selected) end end local function toggleDrop() open = not open dropFrame.Visible = open if open then local h = math.min(#options * 28 + 8, 160) tween(dropFrame, { Size = UDim2.new(1, 0, 0, h) }, 0.2) frame.ZIndex = 10 else tween(dropFrame, { Size = UDim2.new(1, 0, 0, 0) }, 0.15) task.delay(0.15, function() if not open then dropFrame.Visible = false; frame.ZIndex = 1 end end) end end local function buildOptions() for _, c in ipairs(dropList:GetChildren()) do if c:IsA("TextButton") then c:Destroy() end end for i, opt in ipairs(options) do local optBtn = create("TextButton", { BackgroundColor3 = CurrentTheme.bg3, BackgroundTransparency = 0.5, Size = UDim2.new(1, -8, 0, 26), Text = " " .. tostring(opt), Font = fontBody, TextSize = 12, TextColor3 = CurrentTheme.text, TextXAlignment = Enum.TextXAlignment.Left, AutoButtonColor = false, ZIndex = 22, Parent = dropList }) makeCorner(optBtn, 5) optBtn.MouseEnter:Connect(function() tween(optBtn, { BackgroundTransparency = 0.2 }, 0.1) end) optBtn.MouseLeave:Connect(function() tween(optBtn, { BackgroundTransparency = 0.5 }, 0.1) end) optBtn.MouseButton1Click:Connect(function() if multi then local idx = table.find(selected, opt) if idx then table.remove(selected, idx) else table.insert(selected, opt) end refreshDisplay() pcall(callback, selected) else selected = opt refreshDisplay() toggleDrop() pcall(callback, selected) end end) end dropList.CanvasSize = UDim2.new(0, 0, 0, #options * 28 + 8) end buildOptions() local clickBtn = create("TextButton", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Text = "", ZIndex = 5, Parent = frame }) clickBtn.MouseButton1Click:Connect(toggleDrop) registerFlag(flag, function() return selected end, function(v) selected = v refreshDisplay() end) registerTheme(function(t) nameL.TextColor3 = t.text display.TextColor3 = t.text2 frame.BackgroundColor3 = t.bg3 dropFrame.BackgroundColor3 = t.bg2 end) return { SetValue = function(_, v) selected = v; refreshDisplay() end, GetValue = function() return selected end, SetOptions = function(_, opts) options = opts; buildOptions() end, SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end -- ==================================================== -- INPUT -- ==================================================== function Tab:CreateInput(iOpts) iOpts = iOpts or {} local name = iOpts.Name or "Input" local placeholder = iOpts.Placeholder or "" local default = iOpts.Default or "" local numeric = iOpts.Numeric local flag = iOpts.Flag local callback = iOpts.Callback or function() end local frame = makeElementContainer(40) create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0, 0), Size = UDim2.new(0.35, 0, 1, 0), Font = Enum.Font.GothamMedium, Text = name, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) local box = create("TextBox", { BackgroundColor3 = CurrentTheme.bg4, Position = UDim2.new(0.38, 0, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.new(0.58, 0, 0, 26), Font = fontBody, Text = default, PlaceholderText = placeholder, PlaceholderColor3 = CurrentTheme.text3, TextColor3 = CurrentTheme.text, TextSize = 12, ClearTextOnFocus = false, Parent = frame }) makeCorner(box, 6) makePadding(box, 0, 0, 8, 8) box.FocusLost:Connect(function(enter) local txt = box.Text if numeric then txt = tonumber(txt) or 0 box.Text = tostring(txt) end pcall(callback, txt) end) registerFlag(flag, function() return box.Text end, function(v) box.Text = tostring(v) end) registerTheme(function(t) box.BackgroundColor3 = t.bg4 box.TextColor3 = t.text box.PlaceholderColor3 = t.text3 frame.BackgroundColor3 = t.bg3 end) return { SetValue = function(_, v) box.Text = tostring(v) end, GetValue = function() return box.Text end, SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end -- ==================================================== -- KEYBIND -- ==================================================== function Tab:CreateKeybind(kOpts) kOpts = kOpts or {} local name = kOpts.Name or "Keybind" local default = kOpts.Default or Enum.KeyCode.E local flag = kOpts.Flag local callback = kOpts.Callback or function() end local frame = makeElementContainer(40) local current = default local listening = false create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0, 0), Size = UDim2.new(0.5, 0, 1, 0), Font = Enum.Font.GothamMedium, Text = name, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) local keyBtn = create("TextButton", { BackgroundColor3 = CurrentTheme.bg4, Position = UDim2.new(1, -100, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(88, 26), Font = fontBody, Text = current.Name, TextColor3 = CurrentTheme.accent, TextSize = 12, AutoButtonColor = false, Parent = frame }) makeCorner(keyBtn, 6) keyBtn.MouseButton1Click:Connect(function() listening = true keyBtn.Text = "..." end) UserInputService.InputBegan:Connect(function(input, gpe) if not listening then return end if input.UserInputType == Enum.UserInputType.Keyboard then current = input.KeyCode keyBtn.Text = current.Name listening = false pcall(callback, current) end end) registerFlag(flag, function() return current end, function(v) current = v keyBtn.Text = current.Name end) registerTheme(function(t) keyBtn.BackgroundColor3 = t.bg4 keyBtn.TextColor3 = t.accent frame.BackgroundColor3 = t.bg3 end) return { SetValue = function(_, v) current = v; keyBtn.Text = v.Name end, GetValue = function() return current end, SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end -- ==================================================== -- PARAGRAPH / LABEL -- ==================================================== function Tab:CreateParagraph(pOpts) pOpts = pOpts or {} local title = pOpts.Title or "" local content = pOpts.Content or "" local frame = create("Frame", { BackgroundColor3 = CurrentTheme.bg3, BackgroundTransparency = 0.4, Size = UDim2.new(1, 0, 0, 0), Parent = page }) makeCorner(frame, 8) makePadding(frame, 10, 10, 12, 12) local tL = create("TextLabel", { BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 16), Font = Enum.Font.GothamBold, Text = title, TextColor3 = CurrentTheme.accent, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) local cL = create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 0, 0, 20), Size = UDim2.new(1, 0, 0, 0), Font = fontBody, Text = content, TextColor3 = CurrentTheme.text2, TextSize = 12, TextXAlignment = Enum.TextXAlignment.Left, TextWrapped = true, Parent = frame }) cL.Size = UDim2.new(1, 0, 0, cL.TextBounds.Y + 4) frame.Size = UDim2.new(1, 0, 0, 36 + cL.TextBounds.Y) registerTheme(function(t) tL.TextColor3 = t.accent cL.TextColor3 = t.text2 frame.BackgroundColor3 = t.bg3 end) return { SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end function Tab:CreateLabel(lOpts) lOpts = lOpts or {} local text = lOpts.Text or "Label" local gradient = lOpts.Gradient local frame = create("Frame", { BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 22), Parent = page }) local lbl = create("TextLabel", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Font = Enum.Font.GothamMedium, Text = text, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) if gradient then local g = create("UIGradient", { Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, CurrentTheme.accent), ColorSequenceKeypoint.new(1, CurrentTheme.accent3), }), Parent = lbl }) registerTheme(function(t) g.Color = ColorSequence.new({ ColorSequenceKeypoint.new(0, t.accent), ColorSequenceKeypoint.new(1, t.accent3), }) end) else registerTheme(function(t) lbl.TextColor3 = t.text end) end return { SetText = function(_, t) lbl.Text = t end, SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end -- ==================================================== -- DIVIDER -- ==================================================== function Tab:CreateDivider() local frame = create("Frame", { BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 12), Parent = page }) local line = create("Frame", { BackgroundColor3 = CurrentTheme.borderSoft, AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.new(1, 0, 0, 1), Parent = frame }) registerTheme(function(t) line.BackgroundColor3 = t.borderSoft end) return frame end -- ==================================================== -- COLOR PICKER (simple) -- ==================================================== function Tab:CreateColorPicker(cOpts) cOpts = cOpts or {} local name = cOpts.Name or "Color" local default = cOpts.Default or Color3.fromRGB(255, 255, 255) local flag = cOpts.Flag local callback = cOpts.Callback or function() end local frame = makeElementContainer(40) local value = default create("TextLabel", { BackgroundTransparency = 1, Position = UDim2.new(0, 12, 0, 0), Size = UDim2.new(0.6, 0, 1, 0), Font = Enum.Font.GothamMedium, Text = name, TextColor3 = CurrentTheme.text, TextSize = 13, TextXAlignment = Enum.TextXAlignment.Left, Parent = frame }) local preview = create("Frame", { BackgroundColor3 = value, Position = UDim2.new(1, -40, 0.5, 0), AnchorPoint = Vector2.new(0, 0.5), Size = UDim2.fromOffset(28, 28), Parent = frame }) makeCorner(preview, 6) makeStroke(preview, CurrentTheme.border, 1, 0.3) -- Simple cycle / click to open is complex; provide SetValue primarily -- For full picker would need HSV wheel — keep lightweight local btn = create("TextButton", { BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Text = "", Parent = frame }) -- Basic: user can SetValue externally; click does nothing heavy registerFlag(flag, function() return value end, function(v) value = v preview.BackgroundColor3 = v end) registerTheme(function(t) frame.BackgroundColor3 = t.bg3 end) return { SetValue = function(_, v) value = v; preview.BackgroundColor3 = v; pcall(callback, v) end, GetValue = function() return value end, SetVisible = function(_, v) frame.Visible = v end, Destroy = function() frame:Destroy() end, } end -- ==================================================== -- PLAYER SELECTOR -- ==================================================== function Tab:CreatePlayerSelector(pOpts) pOpts = pOpts or {} local name = pOpts.Name or "Player" local multi = pOpts.Multi or false local flag = pOpts.Flag local callback = pOpts.Callback or function() end local options = {} for _, p in ipairs(Players:GetPlayers()) do if p ~= LocalPlayer then table.insert(options, p.Name) end end local dd = Tab:CreateDropdown({ Name = name, Options = options, Multi = multi, Flag = flag, Callback = callback, }) -- Refresh button via small extra return dd end return Tab end table.insert(Windows, Window) -- Reveal after loading if loadingScreen then task.delay(1.2, function() main.Visible = true main.Size = UDim2.fromOffset(0, 0) tween(main, { Size = finalSize }, 0.4, Enum.EasingStyle.Back) end) end return Window end -- Global notify alias EchelonUI.Notify = function(_, opts) EchelonUI:Notify(opts) end --[[ ============================================================ EXAMPLE USAGE (remove or comment in production) ============================================================ local Lib = EchelonUI local Win = Lib:CreateWindow({ Title = "ECHELON HUB", SubTitle = "1.0", Theme = "Aqua", Logo = nil, }) local T = Win:CreateTab({ Name = "Main", Icon = "house" }) T:CreateSection({ Title = "General", Icon = "settings" }) T:CreateToggle({ Name = "Enabled", Description = "Turn on feature", Default = false, Flag = "Enabled", Callback = function(v) print("Toggle:", v) end, }) T:CreateButton({ Name = "Click Me", Icon = "mouse-pointer-click", Callback = function() Win:Notify({ Title = "OK", Content = "Clicked successfully", Type = "Success" }) end, }) T:CreateSlider({ Name = "WalkSpeed", Min = 16, Max = 100, Default = 16, Flag = "WS", Callback = function(v) print(v) end, }) T:CreateDropdown({ Name = "Mode", Options = {"Safe", "Normal", "Rage"}, Default = 2, Flag = "Mode", Callback = print, }) T:CreateInput({ Name = "Config", Placeholder = "name", Flag = "Cfg" }) T:CreateKeybind({ Name = "Key", Default = Enum.KeyCode.Q, Flag = "Key" }) T:CreateLabel({ Text = "Status: Ready", Gradient = true }) T:CreateParagraph({ Title = "Info", Content = "EchelonUI v1.0 — Premium dark cyber library." }) T:CreateDivider() ]] return EchelonUI