diff --git a/Library/testing2.lua b/Library/testing2.lua new file mode 100644 index 0000000..dfa1fa9 --- /dev/null +++ b/Library/testing2.lua @@ -0,0 +1,855 @@ +local TweenService = game:GetService("TweenService") +local UserInputService = game:GetService("UserInputService") +local RunService = game:GetService("RunService") +local HttpService = game:GetService("HttpService") +local Players = game:GetService("Players") +local StarterGui = game:GetService("StarterGui") + +local JustHub = {} + +-- DEFINISI THEME +JustHub.Themes = { + Darker = { + ["Color Hub 1"] = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.fromRGB(25,25,25)), + ColorSequenceKeypoint.new(0.5, Color3.fromRGB(32,32,32)), + ColorSequenceKeypoint.new(1, Color3.fromRGB(25,25,25)) + }), + ["Color Hub 2"] = Color3.fromRGB(30,30,30), + ["Color Stroke"] = Color3.fromRGB(40,40,40), + ["Color Theme"] = Color3.fromRGB(88,101,242), + ["Color Text"] = Color3.fromRGB(243,243,243), + ["Color Dark Text"] = Color3.fromRGB(180,180,180) + }, + Dark = { + ["Color Hub 1"] = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.fromRGB(40,40,40)), + ColorSequenceKeypoint.new(0.5, Color3.fromRGB(47,47,47)), + ColorSequenceKeypoint.new(1, Color3.fromRGB(40,40,40)) + }), + ["Color Hub 2"] = Color3.fromRGB(45,45,45), + ["Color Stroke"] = Color3.fromRGB(65,65,65), + ["Color Theme"] = Color3.fromRGB(65,150,255), + ["Color Text"] = Color3.fromRGB(245,245,245), + ["Color Dark Text"] = Color3.fromRGB(190,190,190) + }, + Purple = { + ["Color Hub 1"] = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.fromRGB(28,25,30)), + ColorSequenceKeypoint.new(0.5, Color3.fromRGB(32,32,32)), + ColorSequenceKeypoint.new(1, Color3.fromRGB(28,25,30)) + }), + ["Color Hub 2"] = Color3.fromRGB(30,30,30), + ["Color Stroke"] = Color3.fromRGB(40,40,40), + ["Color Theme"] = Color3.fromRGB(150,0,255), + ["Color Text"] = Color3.fromRGB(240,240,240), + ["Color Dark Text"] = Color3.fromRGB(180,180,180) + }, + Light = { + ["Color Hub 1"] = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.fromRGB(230,230,230)), + ColorSequenceKeypoint.new(0.5, Color3.fromRGB(245,245,245)), + ColorSequenceKeypoint.new(1, Color3.fromRGB(230,230,230)) + }), + ["Color Hub 2"] = Color3.fromRGB(240,240,240), + ["Color Stroke"] = Color3.fromRGB(200,200,200), + ["Color Theme"] = Color3.fromRGB(0,120,255), + ["Color Text"] = Color3.fromRGB(30,30,30), + ["Color Dark Text"] = Color3.fromRGB(80,80,80) + }, + Neon = { + ["Color Hub 1"] = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.fromRGB(10,10,10)), + ColorSequenceKeypoint.new(0.5, Color3.fromRGB(0,200,200)), + ColorSequenceKeypoint.new(1, Color3.fromRGB(10,10,10)) + }), + ["Color Hub 2"] = Color3.fromRGB(15,15,15), + ["Color Stroke"] = Color3.fromRGB(0,255,255), + ["Color Theme"] = Color3.fromRGB(0,255,0), + ["Color Text"] = Color3.fromRGB(255,255,255), + ["Color Dark Text"] = Color3.fromRGB(200,200,200) + }, + Forest = { + ["Color Hub 1"] = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.fromRGB(0,50,0)), + ColorSequenceKeypoint.new(0.5, Color3.fromRGB(0,80,0)), + ColorSequenceKeypoint.new(1, Color3.fromRGB(0,50,0)) + }), + ["Color Hub 2"] = Color3.fromRGB(0,60,0), + ["Color Stroke"] = Color3.fromRGB(0,80,0), + ["Color Theme"] = Color3.fromRGB(0,120,0), + ["Color Text"] = Color3.fromRGB(220,220,220), + ["Color Dark Text"] = Color3.fromRGB(160,160,160) + }, + Aqua = { + ["Color Hub 1"] = ColorSequence.new({ + ColorSequenceKeypoint.new(0, Color3.fromRGB(0,100,100)), + ColorSequenceKeypoint.new(0.5, Color3.fromRGB(0,150,150)), + ColorSequenceKeypoint.new(1, Color3.fromRGB(0,100,100)) + }), + ["Color Hub 2"] = Color3.fromRGB(0,110,110), + ["Color Stroke"] = Color3.fromRGB(0,180,180), + ["Color Theme"] = Color3.fromRGB(0,220,220), + ["Color Text"] = Color3.fromRGB(255,255,255), + ["Color Dark Text"] = Color3.fromRGB(200,200,200) + } +} + +JustHub.Info = {Version = "1.1.0"} +JustHub.Save = {UISize = {550,380}, TabSize = 160, Theme = "Darker"} +JustHub.ConfigData = {} +JustHub.ControlRegistry = {} + +-- Fungsi pembuat instance +local function createInstance(className, properties, parent) + local inst = Instance.new(className) + if properties then + for k, v in pairs(properties) do + inst[k] = v + end + end + if parent then inst.Parent = parent end + return inst +end + +-- Fungsi tween +local function tweenProperty(object, propertyTable, duration) + local ti = TweenInfo.new(duration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out) + local tw = TweenService:Create(object, ti, propertyTable) + tw:Play() + return tw +end + +local function getCurrentTheme(themeChoice) + if type(themeChoice) == "table" then + return themeChoice + else + return JustHub.Themes[themeChoice or JustHub.Save.Theme] + end +end + +local function clampPosition(pos, screenSize) + local x = math.clamp(pos.X.Offset, 0, screenSize.X) + local y = math.clamp(pos.Y.Offset, 0, screenSize.Y) + return UDim2.new(pos.X.Scale, x, pos.Y.Scale, y) +end + +local function addBorder(obj, color, thickness) + return createInstance("UIStroke", {Color = color, Thickness = thickness}, obj) +end + +-- Fungsi untuk mendaftarkan kontrol ke ControlRegistry agar dapat disimpan/diload +function JustHub:RegisterControl(key, updateFunction) + JustHub.ControlRegistry[key] = updateFunction +end + +function JustHub:ApplyConfig(config) + for key, savedValue in pairs(config) do + if JustHub.ControlRegistry[key] then + JustHub.ControlRegistry[key](savedValue) + end + end +end + +-- Metode untuk section (menggunakan metatable agar setiap section mendapatkan method-method berikut) +local SectionMethods = {} + +function SectionMethods:addMenu(menuName) + menuName = menuName or "Menu" + local menuFrame = createInstance("Frame", { + Name = menuName, + Size = UDim2.new(1,0,0,40), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], + BackgroundTransparency = 0.3, + }, self.Content) + createInstance("UICorner", {CornerRadius = UDim.new(0,6)}, menuFrame) + createInstance("TextLabel", { + Name = "MenuLabel", + Text = menuName, + Size = UDim2.new(1,0,1,0), + BackgroundTransparency = 1, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.GothamBold, + TextSize = 16, + }, menuFrame) + return menuFrame +end + +function SectionMethods:addToggle(options) + options = options or {} + local toggleTitle = options.Name or "Toggle" + local default = options.Default or false + local callback = options.Callback or function(state) end + local toggleFrame = createInstance("Frame", { + Name = toggleTitle.."Toggle", + Size = UDim2.new(1,0,0,20), + BackgroundColor3 = Color3.fromRGB(40,40,40) + }, self.Content) + createInstance("UICorner", {CornerRadius = UDim.new(0,20)}, toggleFrame) + addBorder(toggleFrame, getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], 1) + local label = createInstance("TextLabel", { + Size = UDim2.new(0.7,0,1,0), + Position = UDim2.new(0,0,0,0), + BackgroundTransparency = 1, + Text = toggleTitle, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.Gotham, + TextSize = 12, + TextXAlignment = Enum.TextXAlignment.Left + }, toggleFrame) + local separator = createInstance("Frame", { + Size = UDim2.new(0,2,1,0), + Position = UDim2.new(0.7,0,0,0), + BackgroundColor3 = Color3.fromRGB(255,255,255) + }, toggleFrame) + createInstance("UICorner", {CornerRadius = UDim.new(0,1)}, separator) + local toggleContainer = createInstance("Frame", { + Size = UDim2.new(0.3,0,1,0), + Position = UDim2.new(0.7,0,0,0), + BackgroundTransparency = 1 + }, toggleFrame) + local toggleSwitch = createInstance("Frame", { + Size = UDim2.new(0,35,0,15), + Position = UDim2.new(1,-35,0.5,-7.5), + BackgroundColor3 = default and Color3.fromRGB(0,200,0) or Color3.fromRGB(100,100,100), + BorderSizePixel = 0 + }, toggleContainer) + toggleSwitch.Active = true + toggleSwitch.Selectable = true + createInstance("UICorner", {CornerRadius = UDim.new(0,15)}, toggleSwitch) + local toggleCircle = createInstance("Frame", { + Size = UDim2.new(0,13,0,13), + Position = default and UDim2.new(0,20,0.5,-6.5) or UDim2.new(0,2,0.5,-6.5), + BackgroundColor3 = Color3.new(1,1,1), + BorderSizePixel = 0 + }, toggleSwitch) + createInstance("UICorner", {CornerRadius = UDim.new(1,0)}, toggleCircle) + local state = default + if default then callback(true) else callback(false) end + JustHub.ConfigData[toggleTitle] = state + JustHub:RegisterControl(toggleTitle, function(savedValue) + state = savedValue + if state then + toggleCircle.Position = UDim2.new(0,20,0.5,-6.5) + toggleSwitch.BackgroundColor3 = Color3.fromRGB(0,200,0) + label.TextColor3 = Color3.fromRGB(0,255,0) + else + toggleCircle.Position = UDim2.new(0,2,0.5,-6.5) + toggleSwitch.BackgroundColor3 = Color3.fromRGB(100,100,100) + label.TextColor3 = Color3.fromRGB(255,255,255) + end + end) + toggleSwitch.InputBegan:Connect(function(input) + if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then + if not state then + tweenProperty(toggleCircle, {Position = UDim2.new(0,20,0.5,-6.5)}, 0.3) + tweenProperty(toggleSwitch, {BackgroundColor3 = Color3.fromRGB(0,200,0)}, 0.3) + tweenProperty(label, {TextColor3 = Color3.fromRGB(0,255,0)}, 0.3) + else + tweenProperty(toggleCircle, {Position = UDim2.new(0,2,0.5,-6.5)}, 0.3) + tweenProperty(toggleSwitch, {BackgroundColor3 = Color3.fromRGB(100,100,100)}, 0.3) + tweenProperty(label, {TextColor3 = Color3.fromRGB(255,255,255)}, 0.3) + end + state = not state + JustHub.ConfigData[toggleTitle] = state + callback(state) + end + end) + return toggleFrame +end + +function SectionMethods:addSlider(options) + options = options or {} + local sliderName = options.Name or "Slider" + local min = options.Min or 0 + local max = options.Max or 100 + local default = options.Default or min + local callback = options.Callback or function(value) end + local sliderFrame = createInstance("Frame", {Name = sliderName.."Slider", Size = UDim2.new(1,0,0,25), BackgroundTransparency = 1}, self.Content) + addBorder(sliderFrame, getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], 1) + local label = createInstance("TextLabel", { + Name = "Label", + Text = sliderName, + Size = UDim2.new(0.7,0,1,0), + Position = UDim2.new(0,0,0,0), + BackgroundTransparency = 1, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.Gotham, + TextSize = 10 + }, sliderFrame) + local separator = createInstance("Frame", { + Size = UDim2.new(0,2,1,0), + Position = UDim2.new(0.7,0,0,0), + BackgroundColor3 = Color3.fromRGB(255,255,255) + }, sliderFrame) + createInstance("UICorner", {CornerRadius = UDim.new(0,1)}, separator) + local sliderContainer = createInstance("Frame", { + Name = "SliderContainer", + Size = UDim2.new(0.3,0,1,0), + Position = UDim2.new(0.7,0,0,0), + BackgroundTransparency = 1 + }, sliderFrame) + local sliderBar = createInstance("Frame", { + Name = "SliderBar", + Size = UDim2.new(1,-20,0,4), + Position = UDim2.new(0,10,0.5,-2), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Stroke"] + }, sliderContainer) + createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, sliderBar) + local sliderHandle = createInstance("Frame", { + Name = "SliderHandle", + Size = UDim2.new(0,12,0,12), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Theme"], + Position = UDim2.new((default - min)/(max - min), -6, 0.5,-6) + }, sliderBar) + createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, sliderHandle) + local dragging = false + sliderHandle.InputBegan:Connect(function(input) + if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true end + end) + sliderHandle.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 barAbsPos = sliderBar.AbsolutePosition.X + local barWidth = sliderBar.AbsoluteSize.X + local relativePos = math.clamp((input.Position.X - barAbsPos) / barWidth, 0, 1) + sliderHandle.Position = UDim2.new(relativePos, -6, sliderHandle.Position.Y.Scale, sliderHandle.Position.Y.Offset) + local value = min + relativePos*(max - min) + JustHub.ConfigData[sliderName] = value + callback(value) + end + end) + JustHub:RegisterControl(sliderName, function(savedValue) + local newRel = (savedValue - min)/(max - min) + sliderHandle.Position = UDim2.new(newRel, -6, 0.5, -6) + end) + return sliderFrame +end + +function SectionMethods:addTextBox(options) + options = options or {} + local textBoxName = options.Name or "TextBox" + local defaultText = options.Default or "" + local callback = options.Callback or function(text) end + local textBoxFrame = createInstance("Frame", {Name = textBoxName.."TextBox", Size = UDim2.new(1,0,0,20), BackgroundTransparency = 1}, self.Content) + addBorder(textBoxFrame, getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], 1) + local label = createInstance("TextLabel", { + Name = "Label", + Text = textBoxName, + Size = UDim2.new(0.7,0,1,0), + Position = UDim2.new(0,0,0,0), + BackgroundTransparency = 1, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.Gotham, + TextSize = 10 + }, textBoxFrame) + local textbox = createInstance("TextBox", { + Name = "Input", + Text = defaultText, + Size = UDim2.new(0.3,0,1,0), + Position = UDim2.new(0.7,0,0,0), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.Gotham, + TextSize = 10 + }, textBoxFrame) + textbox.FocusLost:Connect(function(enterPressed) + JustHub.ConfigData[textBoxName] = textbox.Text + callback(textbox.Text) + end) + JustHub:RegisterControl(textBoxName, function(savedText) + textbox.Text = savedText + end) + return textBoxFrame +end + +function SectionMethods:addDropdown(options) + options = options or {} + local dropdownTile = options.Name or "Dropdown" + local default = options.Default or "" + local list = options.Items or {} + local callback = options.Callback or function(selected) end + local dropdownFrame = createInstance("Frame", {Name = dropdownTile.."Dropdown", BackgroundTransparency = 1}, self.Content) + dropdownFrame.Size = UDim2.new(1,0,0,20) + addBorder(dropdownFrame, getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], 1) + local label = createInstance("TextLabel", { + Name = "Label", + Text = dropdownTile, + Size = UDim2.new(0.7,0,1,0), + Position = UDim2.new(0,0,0,0), + BackgroundTransparency = 1, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.Gotham, + TextSize = 10 + }, dropdownFrame) + local dropdownButton = createInstance("TextButton", { + Name = "DropdownButton", + Text = (default ~= "" and (default .. " ▼") or "Select ▼"), + Size = UDim2.new(0.3,0,1,0), + Position = UDim2.new(0.7,0,0,0), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], + Font = Enum.Font.GothamBold, + TextSize = 10 + }, dropdownFrame) + local listFrame = createInstance("Frame", { + Name = "DropdownList", + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Hub 2"], + Visible = false, + Position = UDim2.new(0,0,1,0) + }, dropdownFrame) + listFrame.Size = UDim2.new(1,0,0,#list*20 + ((#list-1)*2)) + createInstance("UIListLayout", {Padding = UDim.new(0,2), SortOrder = Enum.SortOrder.LayoutOrder}, listFrame) + local dropdown_toggle = false + dropdownButton.MouseButton1Click:Connect(function() + if dropdown_toggle then + tweenProperty(listFrame, {Size = UDim2.new(1,0,0,0)}, 0.15) + tweenProperty(dropdownButton, {TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"]}, 0.15) + wait(0.15) + listFrame.Visible = false + else + listFrame.Visible = true + tweenProperty(listFrame, {Size = UDim2.new(1,0,0,#list*20 + ((#list-1)*2))}, 0.15) + tweenProperty(dropdownButton, {TextColor3 = Color3.fromRGB(0,255,0)}, 0.15) + end + dropdown_toggle = not dropdown_toggle + end) + for _, option in ipairs(list) do + local btn = createInstance("TextButton", { + Size = UDim2.new(1,0,0,20), + Text = option, + TextColor3 = Color3.fromRGB(255,255,255), + BackgroundTransparency = 1, + Font = Enum.Font.Gotham, + TextSize = 10 + }, listFrame) + btn.MouseButton1Click:Connect(function() + label.Text = dropdownTile .. " - " .. option + JustHub.ConfigData[dropdownTile] = option + pcall(callback, option) + tweenProperty(listFrame, {Size = UDim2.new(1,0,0,0)}, 0.15) + dropdown_toggle = false + wait(0.15) + listFrame.Visible = false + end) + end + JustHub.ConfigData[dropdownTile] = default + JustHub:RegisterControl(dropdownTile, function(savedValue) + label.Text = dropdownTile .. " - " .. savedValue + end) + return dropdownFrame +end + +function SectionMethods:addButton(options) + options = options or {} + local labelText = options.Name or "Button" + local buttonText = options.ButtonText or "Click" + local callback = options.Callback or function() end + local container = createInstance("Frame", {Name = labelText.."ButtonControl", Size = UDim2.new(1,0,0,30), BackgroundTransparency = 1}, self.Content) + addBorder(container, getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], 1) + local label = createInstance("TextLabel", { + Name = "Label", + Text = labelText, + Size = UDim2.new(0.7,0,1,0), + Position = UDim2.new(0,0,0,0), + BackgroundTransparency = 1, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.Gotham, + TextSize = 10, + TextXAlignment = Enum.TextXAlignment.Left + }, container) + local button = createInstance("TextButton", { + Name = "ActionButton", + Text = buttonText, + Size = UDim2.new(0.3,0,0.8,0), + Position = UDim2.new(0.7,0,0.1,0), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Theme"], + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.GothamBold, + TextSize = 10 + }, container) + createInstance("UICorner", {CornerRadius = UDim.new(0,6)}, button) + button.MouseButton1Click:Connect(function() pcall(callback) end) + return container +end + +-- Fungsi untuk membuat Section, yang akan menjadi container untuk kontrol-kontrol. +function JustHub:addSection(sectionName, sectionHeight) + sectionName = sectionName or "Section" + sectionHeight = sectionHeight or 100 + local sectionFrame = createInstance("Frame", { + Name = sectionName, + Size = UDim2.new(1,0,0,sectionHeight), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Hub 2"], + BackgroundTransparency = 0.2, + }, nil) -- Belum diparent; nantinya akan dipasang di dalam tab. + createInstance("UICorner", {CornerRadius = UDim.new(0,8)}, sectionFrame) + local sectionTitle = createInstance("TextLabel", { + Name = "SectionTitle", + Text = sectionName, + Size = UDim2.new(1,0,0,30), + BackgroundTransparency = 1, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + Font = Enum.Font.GothamBold, + TextSize = 16, + TextXAlignment = Enum.TextXAlignment.Left, + }, sectionFrame) + local sectionContent = createInstance("Frame", { + Name = "SectionContent", + Size = UDim2.new(1,0,1,-30), + Position = UDim2.new(0,0,0,30), + BackgroundTransparency = 1, + }, sectionFrame) + createInstance("UIListLayout", { + FillDirection = Enum.FillDirection.Vertical, + Padding = UDim.new(0,5), + SortOrder = Enum.SortOrder.LayoutOrder, + }, sectionContent) + local sectionObj = {Frame = sectionFrame, Title = sectionTitle, Content = sectionContent} + setmetatable(sectionObj, {__index = SectionMethods}) + return sectionObj +end + +-- Fungsi pembuatan Window +function JustHub:CreateWindow(options) + options = options or {} + local windowName = options.Name or "JustHub Window" + local currentTheme = getCurrentTheme(options.Theme) + local windowGUID = HttpService:GenerateGUID(false) + local finalTitle = windowName .. " [" .. windowGUID .. "]" + local player = Players.LocalPlayer + local playerGui = player:WaitForChild("PlayerGui") + local screenGui = createInstance("ScreenGui", {Name = "JustHub", ResetOnSpawn = false}, playerGui) + self.ScreenGui = screenGui + local uiWidth = JustHub.Save.UISize[1] + local uiHeight = JustHub.Save.UISize[2] + local mainFrame = createInstance("Frame", { + Name = "MainFrame", + AnchorPoint = Vector2.new(0.5,0.5), + Position = UDim2.new(0.5,0,-0.5,0), + Size = UDim2.new(0,uiWidth,0,uiHeight), + BackgroundColor3 = currentTheme["Color Hub 2"], + }, screenGui) + createInstance("UICorner", {CornerRadius = UDim.new(0,12)}, mainFrame) + addBorder(mainFrame, currentTheme["Color Stroke"], 2) + createInstance("UIGradient", {Color = currentTheme["Color Hub 1"]}, mainFrame) + local topBar = createInstance("Frame", {Name = "TopBar", Size = UDim2.new(1,0,0,60), BackgroundColor3 = currentTheme["Color Hub 2"]}, mainFrame) + createInstance("UICorner", {CornerRadius = UDim.new(0,12)}, topBar) + local titleLabel = createInstance("TextLabel", { + Name = "TitleLabel", + Size = UDim2.new(1,-180,1,0), + Position = UDim2.new(0,10,0,0), + BackgroundTransparency = 1, + Text = finalTitle, + TextColor3 = currentTheme["Color Text"], + Font = Enum.Font.GothamBold, + TextSize = 18, + TextXAlignment = Enum.TextXAlignment.Left, + }, topBar) + local usernameLabel = createInstance("TextLabel", { + Name = "UsernameLabel", + Size = UDim2.new(0,150,1,0), + Position = UDim2.new(1,-160,0,0), + BackgroundTransparency = 1, + Text = "Welcome, " .. player.Name, + TextColor3 = currentTheme["Color Text"], + Font = Enum.Font.GothamBold, + TextSize = 16, + TextXAlignment = Enum.TextXAlignment.Right, + }, topBar) + local function createControlButton(name, image, pos) + return createInstance("ImageButton", { + Name = name, + Size = UDim2.new(0,40,0,40), + Position = pos, + BackgroundTransparency = 1, + Image = image, + ImageColor3 = currentTheme["Color Theme"], + }, topBar) + end + local hideButton = createControlButton("HideButton", "rbxassetid://1307617803", UDim2.new(1,-110,0,10)) + local maxButton = createControlButton("MaxButton", "rbxassetid://1307617941", UDim2.new(1,-70,0,10)) + local closeButton = createControlButton("CloseButton", "rbxassetid://3926305904", UDim2.new(1,-30,0,10)) + local sidebarWidth = JustHub.Save.TabSize + local sidebar = createInstance("Frame", { + Name = "Sidebar", + Size = UDim2.new(0,sidebarWidth,1,-60), + Position = UDim2.new(0,0,0,60), + BackgroundColor3 = currentTheme["Color Hub 2"], + }, mainFrame) + createInstance("UICorner", {CornerRadius = UDim.new(0,10)}, sidebar) + createInstance("UIListLayout", { + FillDirection = Enum.FillDirection.Vertical, + Padding = UDim.new(0,10), + HorizontalAlignment = Enum.HorizontalAlignment.Center, + VerticalAlignment = Enum.VerticalAlignment.Top, + }, sidebar) + local contentContainer = createInstance("Frame", { + Name = "ContentContainer", + Size = UDim2.new(1,-sidebarWidth,1,-60), + Position = UDim2.new(0,sidebarWidth,0,60), + BackgroundColor3 = currentTheme["Color Hub 2"], + }, mainFrame) + createInstance("UICorner", {CornerRadius = UDim.new(0,10)}, contentContainer) + local scrollingFrame = createInstance("ScrollingFrame", { + Size = UDim2.new(1,0,1,0), + BackgroundTransparency = 1, + ScrollBarThickness = 8, + BorderSizePixel = 0, + }, contentContainer) + createInstance("UIListLayout", { + SortOrder = Enum.SortOrder.LayoutOrder, + Padding = UDim.new(0,10), + }, scrollingFrame) + local fpsLabel = createInstance("TextLabel", { + Name = "FPSLabel", + Size = UDim2.new(0,100,0,20), + Position = UDim2.new(1,-110,1,-30), + BackgroundTransparency = 1, + TextColor3 = currentTheme["Color Text"], + Font = Enum.Font.Gotham, + TextSize = 14, + Text = "FPS: Calculating...", + }, mainFrame) + RunService.Heartbeat:Connect(function(delta) + local fps = math.floor(1/delta) + fpsLabel.Text = "FPS: " .. fps + end) + local tweenInfoIn = TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.Out) + local tweenIn = TweenService:Create(mainFrame, tweenInfoIn, {Position = UDim2.new(0.5,0,0.5,0)}) + tweenIn:Play() + closeButton.MouseButton1Click:Connect(function() + local tweenInfoOut = TweenInfo.new(0.5, Enum.EasingStyle.Back, Enum.EasingDirection.In) + local tweenOut = TweenService:Create(mainFrame, tweenInfoOut, {Position = UDim2.new(0.5,0,-0.5,0)}) + tweenOut:Play() + tweenOut.Completed:Connect(function() screenGui:Destroy() end) + end) + local dragging = false + local dragStart, startPos + topBar.InputBegan:Connect(function(input) + if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then + dragging = true + dragStart = input.Position + startPos = mainFrame.Position + end + end) + topBar.InputChanged:Connect(function(input) + if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then + local delta = input.Position - dragStart + local newPos = UDim2.new(startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y) + newPos = clampPosition(newPos, Vector2.new(screenGui.AbsoluteSize.X, screenGui.AbsoluteSize.Y)) + mainFrame.Position = newPos + end + end) + UserInputService.InputEnded:Connect(function(input) + if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end + end) + print("JustHub Window dibuat.") + local windowObject = {ScreenGui = screenGui, MainFrame = mainFrame, TopBar = topBar, Sidebar = sidebar, ContentContainer = contentContainer, Tabs = {}} + function windowObject:addTab(tabName) + tabName = tabName or "Tab" + local tabButton = createInstance("TextButton", { + Name = tabName.."Button", + Text = tabName, + Size = UDim2.new(1,0,0,30), + BackgroundColor3 = currentTheme["Color Stroke"], + TextColor3 = currentTheme["Color Text"], + Font = Enum.Font.GothamBold, + TextSize = 16, + }, self.Sidebar) + local tabContent = createInstance("Frame", { + Name = tabName.."Content", + Size = UDim2.new(1,0,1,0), + BackgroundTransparency = 1, + Visible = false, + }, scrollingFrame) + local tabObject = {Name = tabName, Button = tabButton, Content = tabContent, Sections = {}} + table.insert(self.Tabs, tabObject) + tabButton.MouseButton1Click:Connect(function() + for _, t in ipairs(self.Tabs) do t.Content.Visible = false end + tabObject.Content.Visible = true + end) + if #self.Tabs == 1 then tabObject.Content.Visible = true end + function tabObject:addSection(sectionName, sectionHeight) + sectionName = sectionName or "Section" + sectionHeight = sectionHeight or 100 + local sectionFrame = createInstance("Frame", { + Name = sectionName, + Size = UDim2.new(1,0,0,sectionHeight), + BackgroundColor3 = currentTheme["Color Hub 2"], + BackgroundTransparency = 0.2, + }, self.Content) + createInstance("UICorner", {CornerRadius = UDim.new(0,8)}, sectionFrame) + local sectionTitle = createInstance("TextLabel", { + Name = "SectionTitle", + Text = sectionName, + Size = UDim2.new(1,0,0,30), + BackgroundTransparency = 1, + TextColor3 = currentTheme["Color Text"], + Font = Enum.Font.GothamBold, + TextSize = 16, + TextXAlignment = Enum.TextXAlignment.Left, + }, sectionFrame) + local sectionContent = createInstance("Frame", { + Name = "SectionContent", + Size = UDim2.new(1,0,1,-30), + Position = UDim2.new(0,0,0,30), + BackgroundTransparency = 1, + }, sectionFrame) + createInstance("UIListLayout", { + FillDirection = Enum.FillDirection.Vertical, + Padding = UDim.new(0,5), + SortOrder = Enum.SortOrder.LayoutOrder, + }, sectionContent) + local sectionObj = {Frame = sectionFrame, Title = sectionTitle, Content = sectionContent} + table.insert(self.Sections, sectionObj) + -- Pasangkan metatable agar section memiliki method-method tambahan + setmetatable(sectionObj, {__index = SectionMethods}) + return sectionObj + end + return tabObject + end + return windowObject +end + +-- Fungsi Loading Screen: tampilkan loading screen (dengan judul dan welcome) selama durasi tertentu +function JustHub:ShowLoadingScreen(duration, callback) + duration = duration or 5 + callback = callback or function() end + local player = Players.LocalPlayer + local playerGui = player:WaitForChild("PlayerGui") + local loadingGui = createInstance("ScreenGui", {Name = "LoadingScreen", ResetOnSpawn = false, IgnoreGuiInset = true}, playerGui) + local background = createInstance("Frame", { + Size = UDim2.new(1,0,1,0), + Position = UDim2.new(0,0,0,0), + BackgroundColor3 = Color3.new(0,0,0), + BackgroundTransparency = 0.5, + BorderSizePixel = 0, + }, loadingGui) + local titleLabel = createInstance("TextLabel", { + Text = "JustHub Library", + Font = Enum.Font.SourceSansSemibold, + TextSize = 20, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + BackgroundTransparency = 1, + Size = UDim2.new(0,200,0,50), + AnchorPoint = Vector2.new(0.5,0.5), + Position = UDim2.new(0.5,0,0.5,-50), + }, loadingGui) + local welcomeLabel = createInstance("TextLabel", { + Text = "Welcome, " .. player.Name, + Font = Enum.Font.SourceSansSemibold, + TextSize = 16, + TextColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Text"], + BackgroundTransparency = 1, + Size = UDim2.new(0,200,0,30), + AnchorPoint = Vector2.new(0.5,0), + Position = UDim2.new(0.5,0,0.5,10), + }, loadingGui) + local progressBarContainer = createInstance("Frame", { + Size = UDim2.new(0.5,0,0,20), + Position = UDim2.new(0.5,0,0.5,50), + AnchorPoint = Vector2.new(0.5,0.5), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Stroke"], + BackgroundTransparency = 0.5, + BorderSizePixel = 0, + }, loadingGui) + createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, progressBarContainer) + local progressBarFill = createInstance("Frame", { + Size = UDim2.new(0,0,1,0), + BackgroundColor3 = getCurrentTheme(JustHub.Save.Theme)["Color Theme"], + BorderSizePixel = 0, + }, progressBarContainer) + createInstance("UICorner", {CornerRadius = UDim.new(0,4)}, progressBarFill) + local tweenInfo = TweenInfo.new(duration, Enum.EasingStyle.Quad, Enum.EasingDirection.Out) + local progressTween = TweenService:Create(progressBarFill, tweenInfo, {Size = UDim2.new(1,0,1,0)}) + progressTween:Play() + spawn(function() + while progressTween.PlaybackState == Enum.PlaybackState.Playing do + tweenProperty(titleLabel, {TextTransparency = 0.5}, 0.5) + wait(0.5) + tweenProperty(titleLabel, {TextTransparency = 0}, 0.5) + wait(0.5) + end + end) + progressTween.Completed:Connect(function() + wait(0.5) + loadingGui:Destroy() + callback() + end) +end + +-- Fungsi InitializeUI: tampilkan loading screen terlebih dahulu, kemudian buat window dan simpan ke JustHub.Window +function JustHub:InitializeUI(options) + self:ShowLoadingScreen(5, function() + local window = self:CreateWindow(options) + self.Window = window + print("Window dibuat setelah loading screen.") + end) +end + +function JustHub:SaveConfig(fileName) + fileName = fileName or "JustHub_Config.json" + if writefile then + local json = HttpService:JSONEncode(JustHub.ConfigData) + writefile(fileName, json) + StarterGui:SetCore("SendNotification", { + Title = "Save Config"; + Text = "Config berhasil disimpan ke " .. fileName; + Duration = 5; + }) + else + warn("Saving config is not supported in this environment.") + end +end + +function JustHub:LoadConfig(fileName) + fileName = fileName or "JustHub_Config.json" + if readfile then + local data = readfile(fileName) + local config = HttpService:JSONDecode(data) + JustHub.ConfigData = config + JustHub:ApplyConfig(config) + StarterGui:SetCore("SendNotification", { + Title = "Load Config"; + Text = "Config berhasil dimuat dari " .. fileName; + Duration = 5; + }) + return config + else + warn("Loading config is not supported in this environment.") + return {} + end +end + +function JustHub:ToggleUIVisibility() + if self.ScreenGui and self.ScreenGui.Parent then + self.ScreenGui.Enabled = not self.ScreenGui.Enabled + end +end + +UserInputService.InputBegan:Connect(function(input, gameProcessed) + if not gameProcessed and input.KeyCode and input.KeyCode == Enum.KeyCode.RightShift then + JustHub:ToggleUIVisibility() + end +end) + +function JustHub:Notify(options) + options = options or {} + local title = options.Title or "" + local text = options.Message or "" + local duration = options.Duration or 5 + local success, errorMessage = pcall(function() + StarterGui:SetCore("SendNotification", { + Title = title; + Text = text; + Duration = duration; + }) + end) + if not success then + warn("Gagal mengirim notifikasi: " .. errorMessage) + end +end + +return JustHub