├── assets └── rblxguibanner.png ├── default.project.json ├── src ├── rblxgui │ ├── lib │ │ ├── PluginGlobalVariables.lua │ │ ├── GUIElement.lua │ │ ├── Template.lua │ │ ├── Managers │ │ │ ├── EventManager.lua │ │ │ ├── InputManager.lua │ │ │ ├── LayoutManager.lua │ │ │ ├── ThemeManager.lua │ │ │ └── KeybindManager.lua │ │ ├── Objects │ │ │ ├── ObjectTemplate.lua │ │ │ ├── GUIObject.lua │ │ │ ├── InstanceInputField.lua │ │ │ ├── Textbox.lua │ │ │ ├── ProgressBar.lua │ │ │ ├── ToggleableButton.lua │ │ │ ├── TitlebarButton.lua │ │ │ ├── Labeled.lua │ │ │ ├── Checkbox.lua │ │ │ ├── KeybindInputField.lua │ │ │ ├── Slider.lua │ │ │ ├── ColorInput.lua │ │ │ ├── Button.lua │ │ │ ├── ViewButton.lua │ │ │ └── InputField.lua │ │ ├── Frames │ │ │ ├── GUIFrame.lua │ │ │ ├── BackgroundFrame.lua │ │ │ ├── ListFrame.lua │ │ │ ├── ScrollingFrame.lua │ │ │ ├── Section.lua │ │ │ ├── PluginWidget.lua │ │ │ ├── Page.lua │ │ │ └── TitlebarMenu.lua │ │ ├── Prompts │ │ │ ├── InputPrompt.lua │ │ │ ├── Prompt.lua │ │ │ ├── TextPrompt.lua │ │ │ └── ColorPrompt.lua │ │ └── Misc │ │ │ └── GUIUtil.lua │ └── initialize.lua └── Example.client.lua ├── README.md └── LICENSE /assets/rblxguibanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arch4ic/rblxguilib/HEAD/assets/rblxguibanner.png -------------------------------------------------------------------------------- /default.project.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rblxguilib", 3 | "tree": { 4 | "$path": "src" 5 | } 6 | } -------------------------------------------------------------------------------- /src/rblxgui/lib/PluginGlobalVariables.lua: -------------------------------------------------------------------------------- 1 | local m = {} 2 | m.LibraryDir = script.Parent 3 | m.FramesDir = m.LibraryDir.Frames 4 | m.ObjectsDir = m.LibraryDir.Objects 5 | m.ManagersDir = m.LibraryDir.Managers 6 | m.PromptsDir = m.LibraryDir.Prompts 7 | m.MiscDir = m.LibraryDir.Misc 8 | 9 | return m -------------------------------------------------------------------------------- /src/rblxgui/lib/GUIElement.lua: -------------------------------------------------------------------------------- 1 | local GUIElement = {} 2 | GUIElement.__index = GUIElement 3 | 4 | local GV = require(script.Parent.PluginGlobalVariables) 5 | 6 | function GUIElement.new(Arguments, Parent) 7 | local self = {} 8 | setmetatable(self,GUIElement) 9 | self.Arguments = Arguments or {} 10 | self.Parent = Parent 11 | return self 12 | end 13 | 14 | return GUIElement -------------------------------------------------------------------------------- /src/rblxgui/lib/Template.lua: -------------------------------------------------------------------------------- 1 | -- template for classes 2 | 3 | --inheritance 4 | --local GUIElement = require(GV.LibraryDir.GUIElement) 5 | --setmetatable(,GUIElement) 6 | 7 | local temp = {} 8 | temp.__index = temp 9 | 10 | 11 | function temp.new() 12 | --self = GUIElement.new() 13 | local self = {} 14 | setmetatable(self,temp) 15 | return self 16 | end 17 | 18 | return temp -------------------------------------------------------------------------------- /src/rblxgui/lib/Managers/EventManager.lua: -------------------------------------------------------------------------------- 1 | local m = {} 2 | 3 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 4 | m.EventList = {} 5 | 6 | function m.AddConnection(Connection, func) 7 | m.EventList[#m.EventList+1] = Connection:Connect(func) 8 | end 9 | 10 | GV.PluginObject.Unloading:Connect(function() 11 | for _, v in pairs(m.EventList) do 12 | v:Disconnect() 13 | end 14 | end) 15 | 16 | return m -------------------------------------------------------------------------------- /src/rblxgui/initialize.lua: -------------------------------------------------------------------------------- 1 | local GV = require(script.Parent.lib.PluginGlobalVariables) 2 | local function requireall(p,id) 3 | GV.PluginObject = p 4 | local library = {} 5 | if id then require(script.Parent.lib.PluginGlobalVariables).PluginID = id end 6 | for _, i in pairs(script.Parent.lib:GetDescendants()) do 7 | if i:IsA("ModuleScript") then 8 | library[i.Name] = require(i) 9 | end 10 | end 11 | return library 12 | end 13 | return requireall -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/ObjectTemplate.lua: -------------------------------------------------------------------------------- 1 | local temp = {} 2 | temp.__index = temp 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIObject = require(GV.ObjectsDir.GUIObject) 7 | setmetatable(temp,GUIObject) 8 | 9 | function temp.new(Arguments, Parent) 10 | local self = GUIObject.new(Arguments, Parent) 11 | setmetatable(self,temp) 12 | self.Object = nil 13 | self.MainMovable = nil 14 | return self 15 | end 16 | 17 | return temp -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/GUIFrame.lua: -------------------------------------------------------------------------------- 1 | local GUIFrame = {} 2 | GUIFrame.__index = GUIFrame 3 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 4 | local GUIElement = require(GV.LibraryDir.GUIElement) 5 | setmetatable(GUIFrame,GUIElement) 6 | 7 | GV.MainGUI = nil 8 | 9 | function GUIFrame.new(Arguments, Parent) 10 | local self = GUIElement.new(Arguments, Parent or GV.MainGUI) 11 | setmetatable(self,GUIFrame) 12 | self.Content = nil 13 | return self 14 | end 15 | 16 | function GUIFrame:SetMain() 17 | GV.MainGUI = self.Content 18 | end 19 | 20 | return GUIFrame -------------------------------------------------------------------------------- /src/rblxgui/lib/Managers/InputManager.lua: -------------------------------------------------------------------------------- 1 | local m = {} 2 | 3 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 4 | local EventManager = require(GV.ManagersDir.EventManager) 5 | 6 | m.InputFieldEvents = {} 7 | m.InputFrames = {} 8 | function m.AddInputEvent(Event, func) 9 | m.InputFieldEvents[#m.InputFieldEvents+1] = {Event, func} 10 | for _, v in pairs(m.InputFrames) do 11 | EventManager.AddConnection(v[Event], func) 12 | end 13 | end 14 | 15 | function m.AddInput(Frame) 16 | m.InputFrames[#m.InputFrames + 1] = Frame 17 | for _, v in pairs(m.InputFieldEvents) do 18 | EventManager.AddConnection(Frame[v[1]], v[2]) 19 | end 20 | end 21 | 22 | return m -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/BackgroundFrame.lua: -------------------------------------------------------------------------------- 1 | local BackgroundFrame = {} 2 | BackgroundFrame.__index = BackgroundFrame 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIFrame = require(GV.FramesDir.GUIFrame) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(BackgroundFrame,GUIFrame) 9 | 10 | 11 | function BackgroundFrame.new(Arguments, Parent) 12 | local self = GUIFrame.new(Arguments, Parent) 13 | setmetatable(self,BackgroundFrame) 14 | -- generate background frame 15 | self.Content = Instance.new("Frame", self.Parent) 16 | ThemeManager.ColorSync(self.Content, "BackgroundColor3", Enum.StudioStyleGuideColor.MainBackground) 17 | self.Content.Size = UDim2.new(1,0,1,0) 18 | self.Content.Name = "Background" 19 | self.Content.ZIndex = 0 20 | return self 21 | end 22 | 23 | return BackgroundFrame -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/GUIObject.lua: -------------------------------------------------------------------------------- 1 | local GUIObject = {} 2 | GUIObject.__index = GUIObject 3 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 4 | local GUIElement = require(GV.LibraryDir.GUIElement) 5 | local ListFrame = require(GV.FramesDir.ListFrame) 6 | setmetatable(GUIObject,GUIElement) 7 | GV.ObjectList = {} 8 | 9 | function GUIObject.new(Arguments, Parent) 10 | local self = GUIElement.new(Arguments, Parent or ListFrame.new().Content) 11 | setmetatable(self,GUIObject) 12 | self.Object = nil 13 | self.MainMovable = nil 14 | GV.ObjectList[#GV.ObjectList+1] = self 15 | return self 16 | end 17 | 18 | function GUIObject:Move(NewFrame, WithFrame) 19 | local PreviousParent = self.Parent 20 | self.MainMovable.Parent = NewFrame 21 | self.Parent = NewFrame 22 | if PreviousParent:IsA("Frame") and WithFrame then 23 | for _, i in pairs(PreviousParent:GetChildren()) do 24 | if i:IsA("Frame") then 25 | return self.Object 26 | end 27 | end 28 | PreviousParent:Destroy() 29 | end 30 | end 31 | 32 | 33 | 34 | return GUIObject -------------------------------------------------------------------------------- /src/rblxgui/lib/Prompts/InputPrompt.lua: -------------------------------------------------------------------------------- 1 | local InputPrompt = {} 2 | InputPrompt.__index = InputPrompt 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local TextPrompt = require(GV.PromptsDir.TextPrompt) 7 | local InputFieldMod = require(GV.ObjectsDir.InputField) 8 | 9 | setmetatable(InputPrompt, TextPrompt) 10 | 11 | -- Title, Textbox, Buttons, InputField 12 | function InputPrompt.new(Arguments) 13 | local self = TextPrompt.new(Arguments) 14 | setmetatable(self,InputPrompt) 15 | local InputField = self.Arguments.InputField or self.Arguments.Input 16 | if type(InputField) == "string" then 17 | self.InputField = InputFieldMod.new({Placeholder = InputField, InputSize = UDim.new(1,-30), NoDropdown = true, Unpausable = true}) 18 | else 19 | self.InputField = InputField 20 | end 21 | self.InputField.Arguments.Unpausable = true 22 | self.InputField.InputFieldContainer.Size = UDim2.new(1,0,0,25) 23 | self.InputField.DropdownMaxY = 30 24 | self.ButtonsFrame.Parent = nil 25 | self.InputField:Move(self.TextPromptContainer, true) 26 | self.ButtonsFrame.Parent = self.TextPromptContainer 27 | self.Input = self.InputField.Input 28 | return self 29 | end 30 | 31 | return InputPrompt -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/InstanceInputField.lua: -------------------------------------------------------------------------------- 1 | local InstanceInputField = {} 2 | InstanceInputField.__index = InstanceInputField 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local InputField = require(GV.ObjectsDir.InputField) 7 | local Selection = game:GetService("Selection") 8 | setmetatable(InstanceInputField,InputField) 9 | 10 | function InstanceInputField.new(Arguments, Parent) 11 | Arguments = Arguments or {} 12 | Arguments.Placeholder = Arguments.Placeholder or "Select object(s)" 13 | Arguments.DisableEditing = true 14 | local self = InputField.new(Arguments, Parent) 15 | setmetatable(self,InstanceInputField) 16 | self.IgnoreText = true 17 | self.DefaultEmpty = {} 18 | self.Focusable = true 19 | self.TextEditable = true 20 | self.Input.Focused:Connect(function() 21 | if self.Disabled then return end 22 | local CurrentSelection = Selection:Get() 23 | if #CurrentSelection > 0 then self:SetValue(CurrentSelection) end 24 | end) 25 | Selection.SelectionChanged:Connect(function() 26 | if self.Disabled then return end 27 | if self.Input:IsFocused() then 28 | local CurrentSelection = Selection:Get() 29 | if #CurrentSelection > 0 then self:SetValue(CurrentSelection) end 30 | end 31 | end) 32 | return self 33 | end 34 | 35 | return InstanceInputField -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/Textbox.lua: -------------------------------------------------------------------------------- 1 | local Textbox = {} 2 | Textbox.__index = Textbox 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIObject = require(GV.ObjectsDir.GUIObject) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(Textbox,GUIObject) 9 | 10 | function Textbox:SetDisabled(State) 11 | self.Disabled = State 12 | if self.Disabled then 13 | self.Textbox.TextTransparency = 0.5 14 | else 15 | self.Textbox.TextTransparency = 0 16 | end 17 | end 18 | 19 | function Textbox:ToggleDisable() 20 | self:SetDisabled(not self.Disabled) 21 | end 22 | 23 | -- Text, Font, Alignment, TextSize 24 | function Textbox.new(Arguments, Parent) 25 | local self = GUIObject.new(Arguments, Parent) 26 | setmetatable(self,Textbox) 27 | local Alignment = self.Arguments.Alignment or Enum.TextXAlignment.Center 28 | local Font = self.Arguments.Font or Enum.Font.SourceSans 29 | local TextSize = self.Arguments.TextSize or self.Arguments.FontSize or 15 30 | self.Textbox = Instance.new("TextLabel", self.Parent) 31 | self.Textbox.BackgroundTransparency = 1 32 | self.Textbox.Size = UDim2.new(1,0,1,0) 33 | self.Textbox.TextXAlignment = Alignment 34 | self.Textbox.TextSize = TextSize 35 | self.Textbox.Font = Font 36 | self.Textbox.Text = self.Arguments.Text 37 | ThemeManager.ColorSync(self.Textbox, "TextColor3", Enum.StudioStyleGuideColor.MainText) 38 | self.Object = self.Textbox 39 | self.MainMovable = self.Textbox 40 | return self 41 | end 42 | 43 | return Textbox -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/ListFrame.lua: -------------------------------------------------------------------------------- 1 | local ListFrame = {} 2 | ListFrame.__index = ListFrame 3 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 4 | local GUIFrame = require(GV.FramesDir.GUIFrame) 5 | setmetatable(ListFrame,GUIFrame) 6 | local Count = 0 7 | 8 | 9 | -- Name, Height 10 | function ListFrame.new(Arguments, Parent) 11 | local self = GUIFrame.new(Arguments, Parent) 12 | setmetatable(self,ListFrame) 13 | Count = Count + 1; 14 | self.Arguments.Height = self.Arguments.Height or 28 15 | self.Content = Instance.new("Frame", self.Parent) 16 | self.Content.BackgroundTransparency = 1 17 | self.Content.Size = UDim2.new(1,0,0,self.Arguments.Height) 18 | self.Content.Name = Count 19 | if self.Arguments.Name then self.Content.Name = self.Content.Name .. ": " .. self.Arguments.Name end 20 | -- layout (used for stacking multiple elements in one row) 21 | self.Layout = Instance.new("UIGridLayout", self.Content) 22 | self.Layout.SortOrder = Enum.SortOrder.LayoutOrder 23 | self.Layout.FillDirection = Enum.FillDirection.Vertical 24 | self.Layout.HorizontalAlignment = Enum.HorizontalAlignment.Center 25 | self.Layout.Changed:Connect(function(p) 26 | if p == "AbsoluteCellCount" and self.Layout.AbsoluteCellCount.X > 0 then 27 | self.Layout.CellSize = UDim2.new(1/self.Layout.AbsoluteCellCount.X,0,1,0) 28 | end 29 | end) 30 | -- self.Padding for elements in frame 31 | self.Padding = Instance.new("UIPadding", self.Content) 32 | self.Padding.PaddingBottom, self.Padding.PaddingLeft, self.Padding.PaddingRight, self.Padding.PaddingTop = UDim.new(0,2), UDim.new(0,2), UDim.new(0,2), UDim.new(0,2) 33 | return self 34 | end 35 | 36 | return ListFrame -------------------------------------------------------------------------------- /src/rblxgui/lib/Prompts/Prompt.lua: -------------------------------------------------------------------------------- 1 | local Prompt = {} 2 | Prompt.__index = Prompt 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local BackgroundFrame = require(GV.FramesDir.BackgroundFrame) 7 | local GUIElement = require(GV.LibraryDir.GUIElement) 8 | local ResetThreshold = 5 9 | setmetatable(Prompt,GUIElement) 10 | 11 | function Prompt:Destroy() 12 | if not self.Arguments.NoPause then util.UnpauseAll() end 13 | self.Widget:Destroy() 14 | end 15 | 16 | function Prompt:OnWindowClose(func) 17 | self.CloseAction = func 18 | end 19 | 20 | function Prompt:Reset(Title, Width, Height) 21 | if self.Resetting then return end 22 | self.Resetting = true 23 | Title = Title or "Prompt" 24 | if not Width or Width < 1 then Width = 260 end 25 | if not Height or Height < 1 then Height = 75 end 26 | local NewWidget = GV.PluginObject:CreateDockWidgetPluginGui(game:GetService("HttpService"):GenerateGUID(false), DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, true, true, Width+2, Height+24,1,1)) 27 | if self.Widget then for _,v in pairs(self.Widget:GetChildren())do 28 | v.Parent = NewWidget 29 | end self.Widget:Destroy() end 30 | NewWidget.Title = Title 31 | NewWidget.Changed:Connect(function(p) 32 | if p == "AbsoluteSize" then 33 | if NewWidget.AbsoluteSize.X ~= Width or NewWidget.AbsoluteSize.Y ~= Height then 34 | if not self.ResetCounter or self.ResetCounter < ResetThreshold then 35 | self.ResetCounter = (self.ResetCounter or 0) + 1 36 | self:Reset(Title, Width, Height) 37 | end 38 | end 39 | elseif p == "Enabled" then 40 | NewWidget.Enabled = true 41 | if self.CloseAction then self.CloseAction() end 42 | end 43 | end) 44 | self.Widget = NewWidget 45 | self.Resetting = false 46 | end 47 | 48 | -- Title, Width, Height, NoPause 49 | function Prompt.new(Arguments) 50 | local self = GUIElement.new(Arguments) 51 | setmetatable(self,Prompt) 52 | self:Reset(self.Arguments.Title, self.Arguments.Width, self.Arguments.Height) 53 | if not self.Arguments.NoPause then util.PauseAll() end 54 | local BackgroundFrame = BackgroundFrame.new(nil, self.Widget) 55 | self.Parent = BackgroundFrame.Content 56 | return self 57 | end 58 | 59 | return Prompt -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/ProgressBar.lua: -------------------------------------------------------------------------------- 1 | local ProgressBar = {} 2 | ProgressBar.__index = ProgressBar 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIObject = require(GV.ObjectsDir.GUIObject) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(ProgressBar,GUIObject) 9 | 10 | function ProgressBar:SetDisabled(State) 11 | self.Disabled = State 12 | if self.Disabled then 13 | self.ProgressBar.BackgroundTransparency, self.ProgressIndicator.BackgroundTransparency = 0.5, 0.5 14 | else 15 | self.ProgressBar.BackgroundTransparency, self.ProgressIndicator.BackgroundTransparency = 0, 0 16 | end 17 | end 18 | 19 | function ProgressBar:ToggleDisable() 20 | self:SetDisabled(not self.Disabled) 21 | end 22 | 23 | function ProgressBar:SetValue(Value) 24 | self.Value = Value 25 | self.ProgressIndicator.Size = UDim2.new(self.Value,0,1,0) 26 | end 27 | 28 | -- BarSize, Value, Disabled 29 | function ProgressBar.new(Arguments, Parent) 30 | local self = GUIObject.new(Arguments, Parent) 31 | setmetatable(self,ProgressBar) 32 | self.ProgressBarContainer = Instance.new("Frame", self.Parent) 33 | self.ProgressBarContainer.Name = "ProgressBarContainer" 34 | self.ProgressBarContainer.BackgroundTransparency = 1 35 | self.ProgressBarContainer.Size = UDim2.new(1,0,1,0) 36 | self.ProgressBar = Instance.new("Frame", self.ProgressBarContainer) 37 | self.ProgressBar.Name = "ProgressBar" 38 | self.ProgressBar.AnchorPoint = Vector2.new(0.5,0.5) 39 | local Size = util.GetScale(self.Arguments.BarSize) or UDim.new(1,-12) 40 | self.ProgressBar.Size = UDim2.new(Size.Scale,Size.Offset,0,16) 41 | self.ProgressBar.Position = UDim2.new(0.5,0,0.5,0) 42 | ThemeManager.ColorSync(self.ProgressBar, "BackgroundColor3", Enum.StudioStyleGuideColor.InputFieldBackground) 43 | ThemeManager.ColorSync(self.ProgressBar, "BorderColor3", Enum.StudioStyleGuideColor.InputFieldBorder) 44 | self.ProgressIndicator = Instance.new("Frame", self.ProgressBar) 45 | self.ProgressIndicator.Name = "Indicator" 46 | self:SetValue(self.Arguments.Value) 47 | self.ProgressIndicator.BorderSizePixel = 0 48 | ThemeManager.ColorSync(self.ProgressIndicator, "BackgroundColor3", Enum.StudioStyleGuideColor.LinkText, nil, true) 49 | self:SetDisabled(self.Arguments.Disabled) 50 | self.Object = self.ProgressIndicator 51 | self.MainMovable = self.ProgressBarContainer 52 | return self 53 | end 54 | 55 | return ProgressBar -------------------------------------------------------------------------------- /src/rblxgui/lib/Managers/LayoutManager.lua: -------------------------------------------------------------------------------- 1 | local m = {} 2 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 3 | local util = require(GV.MiscDir.GUIUtil) 4 | 5 | function m.SearchForID(ID, Table) 6 | for i,v in pairs(Table) do 7 | if v.ID == ID then return {i,v} end 8 | end 9 | return {nil,nil} 10 | end 11 | 12 | function m.GetLayout() 13 | local layout = {Widgets = {}, Pages = {}} 14 | for _, Widget in pairs(GV.PluginWidgets) do 15 | local WidgetDesc = { 16 | ID = Widget.ID, 17 | Title = Widget.WidgetObject.Title 18 | } 19 | layout.Widgets[#layout.Widgets+1] = WidgetDesc 20 | end 21 | for _, Page in pairs(GV.PluginPages) do 22 | local PageDesc = { 23 | ID = Page.ID, 24 | MenuID = Page.TitlebarMenu.ID 25 | } 26 | layout.Pages[#layout.Pages+1] = PageDesc 27 | end 28 | return layout 29 | end 30 | 31 | function m.RecallLayout(layout) 32 | for _, Widget in pairs(layout.Widgets) do 33 | local WidgetTable = m.SearchForID(Widget.ID, GV.PluginWidgets)[2] 34 | if not WidgetTable then 35 | WidgetTable = require(GV.FramesDir.PluginWidget).new({ID = Widget.ID, Title = Widget.Title, Enabled = true}) 36 | end 37 | WidgetTable.WidgetObject.Title = Widget.Title 38 | end 39 | for _, Page in pairs(layout.Pages) do 40 | local PageTable = m.SearchForID(Page.ID, GV.PluginPages)[2] 41 | if PageTable then 42 | if PageTable.TitlebarMenu.ID ~= Page.MenuID then 43 | local NewMenu = m.SearchForID(Page.MenuID, GV.PluginWidgets)[2] 44 | if NewMenu then 45 | PageTable.TitlebarMenu:RemovePage(PageTable) 46 | NewMenu.TitlebarMenu:RecievePage(PageTable) 47 | end 48 | end 49 | end 50 | end 51 | for i, Widget in pairs(GV.PluginWidgets) do 52 | if not m.SearchForID(Widget.ID, layout.Widgets)[2] then 53 | Widget.WidgetObject:Destroy() 54 | Widget = nil 55 | GV.PluginWidgets[i] = nil 56 | end 57 | end 58 | end 59 | 60 | function m.SaveLayout(layout) 61 | layout = layout or m.GetLayout() 62 | GV.PluginObject:SetSetting(GV.PluginID.."PreviousGUIState", layout) 63 | end 64 | 65 | function m.RecallSave() 66 | m.DefaultLayout = m.GetLayout() 67 | m.RecallLayout(GV.PluginObject:GetSetting(GV.PluginID.."PreviousGUIState")) 68 | end 69 | 70 | function m.ResetLayout() 71 | m.RecallLayout(m.DefaultLayout) 72 | end 73 | 74 | GV.PluginObject.Unloading:Connect(function() 75 | m.SaveLayout() 76 | end) 77 | 78 | return m -------------------------------------------------------------------------------- /src/rblxgui/lib/Managers/ThemeManager.lua: -------------------------------------------------------------------------------- 1 | local m = {} 2 | 3 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 4 | local EventManager = require(GV.ManagersDir.EventManager) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | 7 | -- syncs colors with studio theme 8 | local syncedelements = {} 9 | m.DefaultAccentColor = Color3.fromRGB(53, 181, 255) 10 | m.DefaultThemeColor = Color3.new(0.5,0.5,0.5) 11 | 12 | m.PreinstalledThemes = {{Name = "Default Theme", Theme = util.Color3ToTable(m.DefaultThemeColor), Accent = util.Color3ToTable(m.DefaultAccentColor)}} 13 | 14 | function m.ColorSync(element, property, enum, enum2, accent, accenttheme, ignoretheme) 15 | syncedelements[#syncedelements + 1] = {element, property, enum, enum2, accent, accenttheme, ignoretheme} 16 | m.MatchColor(element, property, enum, enum2, accent, accenttheme, ignoretheme) 17 | end 18 | 19 | function m.MatchColor(element, property, enum, enum2, useaccent, accenttheme, ignoretheme) 20 | local Theme = settings().Studio.Theme 21 | if useaccent and (((accenttheme) and accenttheme == tostring(Theme)) or not accenttheme) then 22 | element[property] = m.CurrentAccent 23 | else 24 | local ThemeColor = Theme:GetColor(enum, enum2) 25 | if not ignoretheme then 26 | element[property] = util.AddColor(util.MulitplyColor(util.SubColor(Color3.new(1,1,1), util.MulitplyColor(m.CurrentTheme, Color3.new(2,2,2))), util.MulitplyColor(ThemeColor, ThemeColor)), util.MulitplyColor(util.MulitplyColor(ThemeColor, m.CurrentTheme), Color3.new(2,2,2))) 27 | else 28 | element[property] = ThemeColor 29 | end 30 | end 31 | end 32 | 33 | function m.ReloadTheme(theme, accent) 34 | m.CurrentTheme = theme or m.CurrentTheme 35 | m.CurrentAccent = accent or m.CurrentAccent 36 | for _, v in pairs(syncedelements) do 37 | m.MatchColor(v[1], v[2], v[3], v[4], v[5], v[6], v[7]) 38 | end 39 | end 40 | 41 | function m.UpdateTheme(theme,accent) 42 | m.ThemeColor = theme or m.CurrentTheme 43 | m.AccentColor = accent or m.CurrentAccent 44 | m.ReloadTheme(m.ThemeColor, m.AccentColor) 45 | end 46 | 47 | EventManager.AddConnection(settings().Studio.ThemeChanged, function() 48 | m.ReloadTheme(m.CurrentTheme, m.CurrentAccent) 49 | end) 50 | 51 | local LatestThemeSave = GV.PluginObject:GetSetting(GV.PluginID.."PreviousPluginGUITheme") or {Theme = util.Color3ToTable(m.DefaultThemeColor), Accent = util.Color3ToTable(m.DefaultAccentColor)} 52 | m.AccentColor = util.TableToColor3(LatestThemeSave.Accent) 53 | m.ThemeColor = util.TableToColor3(LatestThemeSave.Theme) 54 | m.CurrentTheme = m.ThemeColor 55 | m.CurrentAccent = m.AccentColor 56 | 57 | GV.PluginObject.Unloading:Connect(function() 58 | GV.PluginObject:SetSetting(GV.PluginID.."PreviousPluginGUITheme", {Theme = util.Color3ToTable(m.ThemeColor), Accent = util.Color3ToTable(m.AccentColor)}) 59 | end) 60 | 61 | return m -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/ScrollingFrame.lua: -------------------------------------------------------------------------------- 1 | local ScrollingFrame = {} 2 | ScrollingFrame.__index = ScrollingFrame 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIFrame = require(GV.FramesDir.GUIFrame) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(ScrollingFrame,GUIFrame) 9 | 10 | ScrollingFrame.Images = { 11 | bottom = "http://www.roblox.com/asset/?id=9599518795", 12 | mid = "http://www.roblox.com/asset/?id=9599545837", 13 | top = "http://www.roblox.com/asset/?id=9599519108" 14 | } 15 | 16 | -- updaing the scrolling frame to fit window size based on element size 17 | function ScrollingFrame:UpdateFrameSize() 18 | local ScrollbarVisibility = self.Content.AbsoluteWindowSize.Y < self.Content.AbsoluteCanvasSize.Y 19 | self.Content.CanvasSize = UDim2.new(0,0,0,self.Layout.AbsoluteContentSize.Y) 20 | self.ScrollbarBackground.Visible = ScrollbarVisibility 21 | end 22 | 23 | -- BarSize 24 | function ScrollingFrame.new(Arguments, Parent) 25 | local self = GUIFrame.new(Arguments, Parent) 26 | setmetatable(self, ScrollingFrame) 27 | -- scroll bar background 28 | self.ScrollbarBackground = Instance.new("Frame", self.Parent) 29 | self.ScrollbarBackground.Size = UDim2.new(0,self.Arguments.BarSize or 15,1,0) 30 | self.ScrollbarBackground.Position = UDim2.new(1,-(self.Arguments.BarSize or 15),0,0) 31 | self.ScrollbarBackground.Name = "ScrollbarBackground" 32 | ThemeManager.ColorSync(self.ScrollbarBackground, "BackgroundColor3", Enum.StudioStyleGuideColor.ScrollBarBackground) 33 | 34 | -- scrolling frame 35 | self.Content = Instance.new("ScrollingFrame", self.Parent) 36 | self.Content.BackgroundTransparency = 1 37 | self.Content.Size = UDim2.new(1,0,1,0) 38 | self.Content.ScrollBarThickness = self.Arguments.BarSize or 15 39 | self.Content.BottomImage, self.Content.MidImage, self.Content.TopImage = self.Images.bottom, self.Images.mid, self.Images.top 40 | self.Content.ScrollingDirection = Enum.ScrollingDirection.Y 41 | self.Content.VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar 42 | self.Content.Name = "ScrollingFrame" 43 | self.Content.ZIndex = 2 44 | ThemeManager.ColorSync(self.Content, "ScrollBarImageColor3", Enum.StudioStyleGuideColor.ScrollBar) 45 | ThemeManager.ColorSync(self.Content, "BorderColor3", Enum.StudioStyleGuideColor.Border) 46 | 47 | -- list layout for later elements 48 | self.Layout = Instance.new("UIListLayout", self.Content) 49 | self.Layout.SortOrder = Enum.SortOrder.LayoutOrder 50 | self.Layout.HorizontalAlignment = Enum.HorizontalAlignment.Center 51 | 52 | -- updating the scrollingframe whenever things are added or the size of the widow is changed 53 | self.Layout.Changed:Connect(function(p) 54 | if p == "AbsoluteContentSize" then self:UpdateFrameSize() end 55 | end) 56 | self.Parent.Changed:Connect(function(p) 57 | if p == "AbsoluteSize" then self:UpdateFrameSize() end 58 | end) 59 | return self 60 | end 61 | 62 | return ScrollingFrame -------------------------------------------------------------------------------- /src/rblxgui/lib/Misc/GUIUtil.lua: -------------------------------------------------------------------------------- 1 | local m = {} 2 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 3 | 4 | -- dumps the gui into workspace for debugging 5 | function m.DumpGUI(parent) 6 | local StarterGUI = game:GetService("StarterGui") 7 | local temp = Instance.new("ScreenGui", StarterGUI) 8 | if StarterGUI:FindFirstChild("Dump") then 9 | StarterGUI.Dump.Parent = nil 10 | end 11 | temp.Name = "Dump" 12 | for _, i in pairs(parent:GetChildren()) do 13 | i:Clone().Parent = temp 14 | end 15 | end 16 | 17 | function m.AppendTable(table,newtable) 18 | local fulltable = table 19 | for i, v in pairs(newtable) do fulltable[i] = v end 20 | return fulltable 21 | end 22 | 23 | function m.DumpTable(Table, Step) 24 | Step = Step or 1 25 | if type(Table) == "table"then 26 | local result = "{\n" .. string.rep(":", Step) 27 | for i, v in pairs(Table) do 28 | result = result .. i .." = " .. m.DumpTable(v, Step+1) .. "," 29 | end 30 | return result .. "\n".. string.rep(":", Step-1) .. "}" 31 | else 32 | return tostring(Table) 33 | end 34 | end 35 | 36 | function m.HoverIcon(element, icon) 37 | icon = icon or "rbxasset://SystemCursors/PointingHand" 38 | element.MouseMoved:Connect(function() 39 | GV.PluginObject:GetMouse().Icon = icon 40 | end) 41 | element.MouseLeave:Connect(function() 42 | task.wait(0) 43 | GV.PluginObject:GetMouse().Icon = "rbxasset://SystemCursors/Arrow" 44 | end) 45 | end 46 | 47 | function m.CopyTable(t) 48 | local newt = {} 49 | for i,v in pairs(t) do 50 | newt[i] = v 51 | end 52 | return newt 53 | end 54 | 55 | function m.GetScale(Scale) 56 | if typeof(Scale) == "UDim" then 57 | return Scale 58 | elseif typeof(Scale) == "number" then 59 | return UDim.new(Scale,0) 60 | else 61 | return nil 62 | end 63 | end 64 | 65 | function m.RoundNumber(number, factor) 66 | if factor == 0 then return number else return math.floor(number/factor+0.5)*factor end 67 | end 68 | 69 | local UnpauseList = {} 70 | function m.PauseAll() 71 | if #UnpauseList > 0 then return end 72 | for _,v in pairs(GV.ObjectList) do 73 | if v and v.SetDisabled and not v.Disabled and not v.Arguments.Unpausable then 74 | v:SetDisabled(true) 75 | UnpauseList[#UnpauseList+1] = v 76 | end 77 | end 78 | end 79 | 80 | function m.UnpauseAll() 81 | for _,v in pairs(UnpauseList) do 82 | v:SetDisabled(false) 83 | end 84 | UnpauseList = {} 85 | end 86 | 87 | function m.AddColor(c1, c2) 88 | return Color3.new(c1.R + c2.R, c1.G + c2.G, c1.B + c2.B) 89 | end 90 | function m.SubColor(c1, c2) 91 | return Color3.new(c1.R - c2.R, c1.G - c2.G, c1.B - c2.B) 92 | end 93 | function m.MulitplyColor(c1,c2) 94 | return Color3.new(c1.R * c2.R, c1.G * c2.G, c1.B * c2.B) 95 | end 96 | 97 | function m.Color3ToText(color) 98 | return "[" .. m.RoundNumber(color.R*255, 1) .. ", " .. m.RoundNumber(color.G*255, 1) .. ", " .. m.RoundNumber(color.B*255, 1) .. "]" 99 | end 100 | 101 | function m.TextToColor3(text) 102 | local numbers = {} 103 | for i in text:gmatch("[%.%d]+") do 104 | numbers[#numbers+1] = tonumber(i) 105 | if #numbers == 3 then break end 106 | end 107 | return Color3.fromRGB(numbers[1] or 0, numbers[2] or 0, numbers[3] or 0) 108 | end 109 | 110 | function m.Color3ToTable(color) 111 | return {R = color.R, G = color.G, B = color.B} 112 | end 113 | 114 | function m.TableToColor3(table) 115 | return Color3.new(table.R, table.G, table.B) 116 | end 117 | 118 | return m -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/ToggleableButton.lua: -------------------------------------------------------------------------------- 1 | local ToggleableButton = {} 2 | ToggleableButton.__index = ToggleableButton 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local Button = require(GV.ObjectsDir.Button) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(ToggleableButton,Button) 9 | 10 | function ToggleableButton:Update() 11 | if not self.Value then 12 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder) 13 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button) 14 | else 15 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder, Enum.StudioStyleGuideModifier.Pressed) 16 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Pressed) 17 | end 18 | end 19 | 20 | function ToggleableButton:Toggle() 21 | self:SetValue(not self.Value) 22 | return self.Value 23 | end 24 | 25 | function ToggleableButton:SetValue(Value) 26 | self.Value = Value 27 | self:Update() 28 | end 29 | 30 | -- Textbox, Size, Value, Disabled 31 | function ToggleableButton.new(Arguments, Parent) 32 | local self = Button.new(Arguments, Parent) 33 | setmetatable(self,ToggleableButton) 34 | self.Toggleable = true 35 | local Pressed = false 36 | self.Button.MouseMoved:Connect(function() 37 | if self.Disabled or Pressed then return end 38 | if not self.Value then 39 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder, Enum.StudioStyleGuideModifier.Hover) 40 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Hover) 41 | else 42 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.InputFieldBorder) 43 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.InputFieldBackground) 44 | end 45 | end) 46 | self.Button.MouseLeave:Connect(function() 47 | if self.Disabled then return end 48 | Pressed = false 49 | self:Update() 50 | end) 51 | self.Button.MouseButton1Down:Connect(function() 52 | if self.Disabled then return end 53 | Pressed = true 54 | if not self.Value then 55 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.InputFieldBorder) 56 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.InputFieldBackground) 57 | else 58 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder, Enum.StudioStyleGuideModifier.Pressed) 59 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Pressed) 60 | end 61 | end) 62 | 63 | self.Button.MouseButton1Up:Connect(function() 64 | if self.Disabled then return end 65 | Pressed = false 66 | if not self.Value then 67 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder, Enum.StudioStyleGuideModifier.Hover) 68 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Hover) 69 | end 70 | end) 71 | 72 | self.Button.MouseButton1Click:Connect(function() 73 | if not self.Disabled then 74 | self:Toggle() 75 | end 76 | end) 77 | 78 | self:SetValue(self.Arguments.Value) 79 | return self 80 | end 81 | 82 | return ToggleableButton -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/TitlebarButton.lua: -------------------------------------------------------------------------------- 1 | local TitlebarButton = {} 2 | TitlebarButton.__index = TitlebarButton 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIObject = require(GV.ObjectsDir.GUIObject) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(TitlebarButton,GUIObject) 9 | 10 | GV.TitleBarButtons = {} 11 | 12 | function TitlebarButton:SetDisabled(State) 13 | self.Disabled = State 14 | if self.Disabled then 15 | self.CursorIcon = "rbxasset://SystemCursors/Forbidden" 16 | for _,v in pairs(self.Buttons) do 17 | v.Transparency = 0.5 18 | end 19 | else 20 | self.CursorIcon = "rbxasset://SystemCursors/PointingHand" 21 | for _,v in pairs(self.Buttons) do 22 | v.Transparency = 0 23 | end 24 | end 25 | end 26 | 27 | function TitlebarButton:ToggleDisable() 28 | self:SetDisabled(not self.Disabled) 29 | end 30 | 31 | function TitlebarButton:Clicked(func) 32 | self.Action = func 33 | end 34 | 35 | function TitlebarButton:SelectedAction(func) 36 | self.TitlebarMenuSelectedAction = func 37 | end 38 | 39 | function TitlebarButton:CreateCopy(TitlebarMenu) 40 | local Button = Instance.new("TextButton", TitlebarMenu.ButtonContainer) 41 | Button = Instance.new("TextButton", TitlebarMenu.ButtonContainer) 42 | Button.Name = self.Name 43 | Button.Position = UDim2.new(0,TitlebarMenu.ButtonContainer.Size.X.Offset,1,0) 44 | ThemeManager.ColorSync(Button, "BackgroundColor3", Enum.StudioStyleGuideColor.Titlebar,nil,nil,nil,true) 45 | Button.ZIndex = 4 46 | Button.BorderSizePixel = 0 47 | Button.Font = Enum.Font.SourceSans 48 | Button.TextSize = 14 49 | ThemeManager.ColorSync(Button, "TextColor3", Enum.StudioStyleGuideColor.MainText,nil,nil,nil,true) 50 | Button.Text = self.Name 51 | if not self.TabSize then 52 | local function sync() 53 | Button.Size = UDim2.new(0,Button.TextBounds.X+1.5*Button.TextSize, 0, 24) 54 | end 55 | Button.Changed:Connect(function(p) 56 | if p == "TextBounds" then sync() end 57 | end) 58 | else 59 | Button.Size = UDim2.new(0,self.TabSize,1,0) 60 | end 61 | Button.MouseMoved:Connect(function() 62 | GV.PluginObject:GetMouse().Icon = self.CursorIcon 63 | end) 64 | Button.MouseLeave:Connect(function() 65 | task.wait(0) 66 | GV.PluginObject:GetMouse().Icon = "rbxasset://SystemCursors/Arrow" 67 | end) 68 | Button.MouseButton1Click:Connect(function() 69 | if self.Disabled then return end 70 | if self.Action then self.Action() end 71 | if self.PluginMenu then 72 | -- ???? what 73 | task.wait() 74 | task.wait() 75 | -- i have no idea how this works but it does 76 | local SelectedAction = self.PluginMenu:ShowAsync() 77 | if self.TitlebarMenuSelectedAction then self.TitlebarMenuSelectedAction(SelectedAction) end 78 | end 79 | end) 80 | self.Buttons[#self.Buttons+1] = Button 81 | end 82 | 83 | -- Name, TabSize, Disabled, PluginMenu 84 | function TitlebarButton.new(Arguments) 85 | local self = GUIObject.new(Arguments) 86 | setmetatable(self,TitlebarButton) 87 | self.Buttons = {} 88 | self.Name = self.Arguments.Name 89 | self.PluginMenu = self.Arguments.PluginMenu 90 | self.TabSize = self.Arguments.TabSize 91 | for _, v in pairs(GV.PluginWidgets) do 92 | self:CreateCopy(v.TitlebarMenu) 93 | end 94 | self:SetDisabled(self.Arguments.Disabled) 95 | self.Object = self.Buttons 96 | GV.TitleBarButtons[#GV.TitleBarButtons+1] = self 97 | return self 98 | end 99 | 100 | return TitlebarButton -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/Labeled.lua: -------------------------------------------------------------------------------- 1 | local LabeledObject = {} 2 | LabeledObject.__index = LabeledObject 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local TextboxMod = require(GV.ObjectsDir.Textbox) 7 | local GUIObject = require(GV.ObjectsDir.GUIObject) 8 | setmetatable(LabeledObject,GUIObject) 9 | 10 | function LabeledObject:SetDisabled(State) 11 | self.Disabled = State 12 | for _, v in pairs(self.Objects) do v:SetDisabled(State) end 13 | if self.Disabled then 14 | self.Label.TextTransparency = 0.5 15 | else 16 | self.Label.TextTransparency = 0 17 | end 18 | end 19 | 20 | function LabeledObject:ToggleDisable() 21 | self:SetDisabled(not self.Disabled) 22 | end 23 | 24 | function LabeledObject:AddObject(Object, Name, Size) 25 | Object:Move(self.Content, true) 26 | Size = util.GetScale(Size) 27 | if not Size then Size = UDim.new(1-self.TotalUsedScale, -self.TotalUsedOffset) end 28 | Object.MainMovable.Size = UDim2.new(Size.Scale,Size.Offset,1,0) 29 | Object.MainMovable.Position = UDim2.new(self.TotalUsedScale,self.TotalUsedOffset,0,0) 30 | self.TotalUsedScale += Size.Scale 31 | self.TotalUsedOffset += Size.Offset 32 | self[Name] = Object 33 | self.Objects[#self.Objects+1] = Object 34 | end 35 | 36 | -- Textbox, LabelSize, Objects 37 | function LabeledObject.new(Arguments, Parent) 38 | local self = GUIObject.new(Arguments, Parent) 39 | setmetatable(self,LabeledObject) 40 | self.Objects = {} 41 | self.TotalUsedScale = 0 42 | self.TotalUsedOffset = 0 43 | self.MainFrame = Instance.new("Frame", self.Parent) 44 | self.MainFrame.BackgroundTransparency = 1 45 | self.MainFrame.Name = "MainFrame" 46 | self.MainLayout = Instance.new("UIListLayout", self.MainFrame) 47 | self.MainLayout.HorizontalAlignment = Enum.HorizontalAlignment.Left 48 | self.MainLayout.SortOrder = Enum.SortOrder.LayoutOrder 49 | self.MainLayout.FillDirection = Enum.FillDirection.Horizontal 50 | self.MainPadding = Instance.new("UIPadding", self.MainFrame) 51 | self.MainPadding.PaddingBottom, self.MainPadding.PaddingLeft, self.MainPadding.PaddingRight, self.MainPadding.PaddingTop = UDim.new(0,2), UDim.new(0,6), UDim.new(0,0), UDim.new(0,2) 52 | local Textbox = self.Arguments.Textbox or self.Arguments.Text 53 | if type(Textbox) == "string" then 54 | self.TextboxTable = TextboxMod.new({Text = Textbox, Alignment = Enum.TextXAlignment.Left, TextSize = 14}, self.MainFrame) 55 | else 56 | self.TextboxTable = Textbox 57 | Textbox:Move(self.MainFrame, true) 58 | end 59 | self.Label = self.TextboxTable.Textbox 60 | self.Content = Instance.new("Frame", self.MainFrame) 61 | self.Content.Name = "Content" 62 | self.Content.BackgroundTransparency = 1 63 | local LabelSize = util.GetScale(self.Arguments.LabelSize) 64 | if LabelSize then 65 | self.Label.Size = UDim2.new(LabelSize.Scale, LabelSize.Offset, 0, 20) 66 | self.Content.Size = UDim2.new(1-LabelSize.Scale, -LabelSize.Offset, 0, 20) 67 | else 68 | local function sync() 69 | self.Label.Size = UDim2.new(0,self.Label.TextBounds.X+self.Label.TextSize, 1, 0) 70 | self.Content.Size = UDim2.new(1,-(self.Label.TextBounds.X+self.Label.TextSize), 0, 20) 71 | end 72 | self.Label.Changed:Connect(function(p) 73 | if p == "TextBounds" then sync() end 74 | end) 75 | end 76 | self.TotalUsedScale = 0 77 | local Objects = self.Arguments.Objects or self.Arguments.Object 78 | if type(Objects) == "table" and Objects[1] and type(Objects[1] == "table") then 79 | for _, v in pairs(Objects) do 80 | self:AddObject(v.Object, v.Name, v.Size) 81 | end 82 | else 83 | self:AddObject(Objects, "Object") 84 | end 85 | self:SetDisabled(self.Arguments.Disabled) 86 | self.MainMovable = self.MainFrame 87 | return self 88 | end 89 | 90 | return LabeledObject -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/Checkbox.lua: -------------------------------------------------------------------------------- 1 | local Checkbox = {} 2 | Checkbox.__index = Checkbox 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIObject = require(GV.ObjectsDir.GUIObject) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(Checkbox,GUIObject) 9 | 10 | Checkbox.Images = { 11 | check = "http://www.roblox.com/asset/?id=10278675078" 12 | } 13 | 14 | function Checkbox:SetDisabled(State) 15 | self.Disabled = State 16 | if self.Disabled then 17 | self.CursorIcon = "rbxasset://SystemCursors/Forbidden" 18 | self.Checkbox.Transparency, self.CheckImage.ImageTransparency = 0.5, 0.5 19 | else 20 | self.CursorIcon = "rbxasset://SystemCursors/PointingHand" 21 | self.Checkbox.Transparency, self.CheckImage.ImageTransparency = 0, 0 22 | end 23 | end 24 | 25 | function Checkbox:ToggleDisable() 26 | self:SetDisabled(not self.Disabled) 27 | end 28 | 29 | function Checkbox:Toggle() 30 | self:SetValue(not self.Value) 31 | return self.Value 32 | end 33 | 34 | function Checkbox:SetValue(Toggle) 35 | self.Value = Toggle 36 | self.CheckImage.Visible = Toggle 37 | if Toggle then 38 | ThemeManager.ColorSync(self.Checkbox, "BackgroundColor3", Enum.StudioStyleGuideColor.CheckedFieldBackground, Enum.StudioStyleGuideModifier.Selected, true, "Light") 39 | else 40 | ThemeManager.ColorSync(self.Checkbox, "BackgroundColor3", Enum.StudioStyleGuideColor.CheckedFieldBackground) 41 | end 42 | end 43 | 44 | function Checkbox:Clicked(func) 45 | self.Action = func 46 | end 47 | -- Value, Disabled 48 | function Checkbox.new(Arguments, Parent) 49 | local self = GUIObject.new(Arguments, Parent) 50 | setmetatable(self,Checkbox) 51 | self.Value = self.Arguments.Value 52 | self.Disabled = self.Arguments.Disabled 53 | self.CheckboxFrame = Instance.new("Frame", self.Parent) 54 | self.CheckboxFrame.BackgroundTransparency = 1 55 | self.CheckboxFrame.Name = "CheckboxFrame" 56 | self.Checkbox = Instance.new("TextButton", self.CheckboxFrame) 57 | self.Checkbox.BackgroundTransparency = 1 58 | self.Checkbox.AnchorPoint = Vector2.new(0.5,0.5) 59 | self.Checkbox.Position = UDim2.new(0.5,0,0.5,0) 60 | self.Checkbox.Size = UDim2.new(0,16,0,16) 61 | self.Checkbox.Name = "Checkbox" 62 | self.Checkbox.Text = "" 63 | ThemeManager.ColorSync(self.Checkbox, "BorderColor3", Enum.StudioStyleGuideColor.CheckedFieldBorder) 64 | ThemeManager.ColorSync(self.Checkbox, "BackgroundColor3", Enum.StudioStyleGuideColor.CheckedFieldBackground) 65 | self.CheckImage = Instance.new("ImageLabel", self.Checkbox) 66 | self.CheckImage.AnchorPoint = Vector2.new(0.5,0.5) 67 | self.CheckImage.Position = UDim2.new(0.5,0,0.5,0) 68 | self.CheckImage.Size = UDim2.new(0,16,0,16) 69 | self.CheckImage.Image = self.Images.check 70 | self.CheckImage.BackgroundTransparency = 1 71 | self.CheckImage.Name = "CheckIndicator" 72 | ThemeManager.ColorSync(self.CheckImage, "ImageColor3", Enum.StudioStyleGuideColor.CheckedFieldIndicator, nil, true, "Dark") 73 | self.Checkbox.MouseMoved:Connect(function() 74 | GV.PluginObject:GetMouse().Icon = self.CursorIcon 75 | if not self.Disabled then 76 | ThemeManager.ColorSync(self.Checkbox, "BorderColor3", Enum.StudioStyleGuideColor.CheckedFieldBorder, Enum.StudioStyleGuideModifier.Hover) 77 | end 78 | end) 79 | self.Checkbox.MouseLeave:Connect(function() 80 | task.wait(0) 81 | GV.PluginObject:GetMouse().Icon = "rbxasset://SystemCursors/Arrow" 82 | ThemeManager.ColorSync(self.Checkbox, "BorderColor3", Enum.StudioStyleGuideColor.CheckedFieldBorder) 83 | end) 84 | self.Checkbox.MouseButton1Click:Connect(function() 85 | if not self.Disabled then 86 | self:Toggle() 87 | if self.Action then self.Action(self.Value) end 88 | end 89 | end) 90 | self:SetValue(self.Value) 91 | self:SetDisabled(self.Disabled) 92 | self.Object = self.Checkbox 93 | self.MainMovable = self.CheckboxFrame 94 | return self 95 | end 96 | 97 | return Checkbox -------------------------------------------------------------------------------- /src/rblxgui/lib/Prompts/TextPrompt.lua: -------------------------------------------------------------------------------- 1 | local TextPrompt = {} 2 | TextPrompt.__index = TextPrompt 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local Prompt = require(GV.PromptsDir.Prompt) 7 | local TextboxMod = require(GV.ObjectsDir.Textbox) 8 | local Button = require(GV.ObjectsDir.Button) 9 | setmetatable(TextPrompt, Prompt) 10 | 11 | function TextPrompt:Clicked(func) 12 | self.Action = func 13 | end 14 | 15 | -- Title, Textbox/Text, Buttons 16 | function TextPrompt.new(Arguments) 17 | local self = Prompt.new(Arguments) 18 | setmetatable(self,TextPrompt) 19 | local Buttons = self.Arguments.Buttons or {"OK"} 20 | self.TextPromptContainer = Instance.new("Frame", self.Parent) 21 | self.TextPromptContainer.BackgroundTransparency = 1 22 | self.TextPromptContainer.BorderSizePixel = 0 23 | self.TextPromptContainer.Size = UDim2.new(0,self.Parent.AbsoluteSize.X,0,self.Parent.AbsoluteSize.Y) 24 | self.TextPromptContainer.Name = "TextPromptContainer" 25 | self.TextPromptLayout = Instance.new("UIListLayout", self.TextPromptContainer) 26 | self.TextPromptLayout.SortOrder = Enum.SortOrder.LayoutOrder 27 | self.TextFrame = Instance.new("Frame", self.TextPromptContainer) 28 | self.TextFrame.Name = "TextFrame" 29 | self.TextFrame.Size = UDim2.new(0,0,0,35) 30 | self.TextFrame.BackgroundTransparency = 1 31 | self.TextFrame.BorderSizePixel = 0 32 | self.TextboxTable = self.Arguments.Textbox or self.Arguments.Text 33 | if type(self.TextboxTable) == "string" or not self.TextboxTable then 34 | self.TextboxTable = TextboxMod.new({Text = self.TextboxTable or ""}, self.TextFrame) 35 | else 36 | self.TextboxTable:Move(self.TextFrame, true) 37 | end 38 | self.TextboxTable.Arguments.Unpausable = true 39 | self.Textbox = self.TextboxTable.Textbox 40 | self.Textbox.ZIndex = 1 41 | self.Textbox.TextXAlignment = Enum.TextXAlignment.Left 42 | self.Textbox.AnchorPoint = Vector2.new(0.5,0.5) 43 | self.Textbox.Position = UDim2.new(0.5,0,0.6,0) 44 | self.Textbox.Size = UDim2.new(1,-24,0,14) 45 | self.ButtonsFrame = Instance.new("Frame", self.TextPromptContainer) 46 | self.ButtonsFrame.Name = "ButtonsFrame" 47 | self.ButtonsFrame.Size = UDim2.new(1,0,0,40) 48 | self.ButtonsFrame.BackgroundTransparency = 1 49 | self.ButtonsFrame.BorderSizePixel = 0 50 | local ButtonsFramePadding = Instance.new("UIPadding", self.ButtonsFrame) 51 | ButtonsFramePadding.PaddingBottom, ButtonsFramePadding.PaddingLeft, ButtonsFramePadding.PaddingRight, ButtonsFramePadding.PaddingTop = UDim.new(0,7), UDim.new(0,7), UDim.new(0,7), UDim.new(0,7) 52 | self.ButtonsFrameLayout = Instance.new("UIListLayout", self.ButtonsFrame) 53 | self.ButtonsFrameLayout.FillDirection = Enum.FillDirection.Horizontal 54 | self.ButtonsFrameLayout.HorizontalAlignment = Enum.HorizontalAlignment.Right 55 | self.ButtonsFrameLayout.SortOrder = Enum.SortOrder.LayoutOrder 56 | self:OnWindowClose(function() 57 | self:Destroy() 58 | if self.Action then self.Action(0) end 59 | end) 60 | if (#Buttons*82)+14 > 260 then 61 | self.ButtonsFrame.Size = UDim2.new(0,(#Buttons*82)+14,0,40) 62 | end 63 | for i,v in pairs(Buttons) do 64 | local NewButton = v 65 | if type(v) == "string" then 66 | NewButton = Button.new({Text = v, ButtonSize = 0.95}, self.ButtonsFrame) 67 | else 68 | NewButton:Move(self.ButtonsFrame, true) 69 | end 70 | NewButton.Arguments.Unpausable = true 71 | NewButton.ButtonFrame.Size = UDim2.new(0,82,1,0) 72 | NewButton:Clicked(function() 73 | self:Destroy() 74 | if self.Action then self.Action(i) end 75 | end) 76 | end 77 | local function syncTextFrame() 78 | self.TextFrame.Size = UDim2.new(0,self.Textbox.TextBounds.X+24,0,self.Textbox.TextBounds.Y+21) 79 | end 80 | syncTextFrame() 81 | self.Textbox.Changed:Connect(function(p) 82 | if p == "TextBounds" then 83 | syncTextFrame() 84 | end 85 | end) 86 | local function syncTextPromptSize() 87 | self:Reset(self.Arguments.Title, self.TextPromptLayout.AbsoluteContentSize.X, self.TextPromptLayout.AbsoluteContentSize.Y) 88 | self.TextPromptContainer.Size = UDim2.fromOffset(self.TextPromptLayout.AbsoluteContentSize.X, self.TextPromptLayout.AbsoluteContentSize.Y) 89 | self.TextPromptContainer.Parent = self.Parent 90 | end 91 | syncTextPromptSize() 92 | self.TextPromptLayout.Changed:Connect(function(p) 93 | if p == "AbsoluteContentSize" then 94 | syncTextPromptSize() 95 | end 96 | end) 97 | return self 98 | end 99 | 100 | return TextPrompt -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/Section.lua: -------------------------------------------------------------------------------- 1 | local Section = {} 2 | Section.__index = Section 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIFrame = require(GV.FramesDir.GUIFrame) 7 | local TextboxMod = require(GV.ObjectsDir.Textbox) 8 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 9 | setmetatable(Section,GUIFrame) 10 | 11 | Section.Images = { 12 | Open = "http://www.roblox.com/asset/?id=9666389442", 13 | Closed = "http://www.roblox.com/asset/?id=9666389853" 14 | } 15 | 16 | function Section:SetState(State) 17 | self.Open = State 18 | self.Content.Visible = self.Open 19 | if self.Open then self.CollapseImage.Image = self.Images.Open else self.CollapseImage.Image = self.Images.Closed end 20 | end 21 | 22 | function Section:Toggle() 23 | self:SetState(not self.Open) 24 | end 25 | 26 | -- Text, Open 27 | function Section.new(Arguments, Parent) 28 | local self = GUIFrame.new(Arguments, Parent) 29 | setmetatable(self, Section) 30 | self.Open = self.Arguments.Open 31 | 32 | self.Collapse = Instance.new("Frame", self.Parent) 33 | self.Collapse.BackgroundTransparency = 1 34 | self.Collapse.Size = UDim2.new(1,0,0,0) 35 | self.Collapse.AutomaticSize = Enum.AutomaticSize.Y 36 | 37 | self.CollapseLayout = Instance.new("UIListLayout", self.Collapse) 38 | self.CollapseLayout.SortOrder = Enum.SortOrder.LayoutOrder 39 | self.CollapseLayout.FillDirection = Enum.FillDirection.Vertical 40 | self.CollapseLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center 41 | --self.CollapseLayout.Padding = UDim.new(0,5) 42 | 43 | self.Label = Instance.new("TextButton", self.Collapse) 44 | self.Label.Text = "" 45 | self.Label.Name = "Section Label" 46 | self.Label.Size = UDim2.new(2,0,0,25) 47 | self.Label.BorderSizePixel = 0 48 | ThemeManager.ColorSync(self.Label, "BackgroundColor3", Enum.StudioStyleGuideColor.Titlebar) 49 | self.Label.MouseButton1Click:Connect(function() self:Toggle() end) 50 | util.HoverIcon(self.Label, "rbxasset://SystemCursors/PointingHand") 51 | 52 | self.LabelFrame = Instance.new("Frame", self.Label) 53 | self.LabelFrame.AnchorPoint = Vector2.new(0.5,0) 54 | self.LabelFrame.Position = UDim2.new(0.5,0,0,0) 55 | self.LabelFrame.Size = UDim2.new(0.5,0,0,25) 56 | self.LabelFrame.BackgroundTransparency = 1 57 | 58 | self.LabelLayout = Instance.new("UIListLayout", self.LabelFrame) 59 | self.LabelLayout.SortOrder = Enum.SortOrder.LayoutOrder 60 | self.LabelLayout.FillDirection = Enum.FillDirection.Horizontal 61 | 62 | self.CollapseImageFrame = Instance.new("Frame", self.LabelFrame) 63 | self.CollapseImageFrame.Size = UDim2.new(0,25,0,25) 64 | self.CollapseImageFrame.BackgroundTransparency = 1 65 | 66 | self.CollapseTextboxFrame = Instance.new("Frame", self.LabelFrame) 67 | self.CollapseTextboxFrame.Size = UDim2.new(1,-25,0,25) 68 | self.CollapseTextboxFrame.BackgroundTransparency = 1 69 | 70 | self.CollapseImage = Instance.new("ImageLabel", self.CollapseImageFrame) 71 | self.CollapseImage.BackgroundTransparency = 1 72 | self.CollapseImage.AnchorPoint = Vector2.new(0.5,0.5) 73 | self.CollapseImage.Position = UDim2.new(0.5,0,0.5,0) 74 | self.CollapseImage.Size = UDim2.new(0,15,0,15) 75 | ThemeManager.ColorSync(self.CollapseImage, "ImageColor3", Enum.StudioStyleGuideColor.MainText) 76 | 77 | local Textbox = self.Arguments.Textbox or self.Arguments.Text 78 | if type(Textbox) == "string" then 79 | self.TextboxTable = TextboxMod.new({Text = Textbox, Font = Enum.Font.SourceSansBold, Alignment = Enum.TextXAlignment.Left, TextSize = 15}, self.CollapseTextboxFrame) 80 | else 81 | self.TextboxTable = Textbox 82 | Textbox:Move(self.CollapseTextboxFrame, true) 83 | end 84 | self.TextboxTable.Arguments.Unpausable = true 85 | self.Textbox = self.TextboxTable.Textbox 86 | self.Collapse.Name = "Section - " .. self.Textbox.Text 87 | self.Textbox.AnchorPoint = Vector2.new(0,0.5) 88 | self.Textbox.Position = UDim2.new(0,0,0.5,0) 89 | 90 | self.Content = Instance.new("Frame", self.Collapse) 91 | self.Content.Size = UDim2.new(1,-15,0,0) 92 | self.Content.BackgroundTransparency = 1 93 | self.Content.Visible = self.Open 94 | self.Content.Name = "Contents" 95 | 96 | self.Layout = Instance.new("UIListLayout", self.Content) 97 | self.Layout.SortOrder = Enum.SortOrder.LayoutOrder 98 | self.Layout.HorizontalAlignment = Enum.HorizontalAlignment.Center 99 | self:SetState(self.Arguments.Open) 100 | 101 | local function syncContentSize() 102 | self.Content.Size = UDim2.new(1, -15, 0, self.Layout.AbsoluteContentSize.Y); 103 | end 104 | syncContentSize() 105 | self.Layout.Changed:Connect(function(p) 106 | if p == "AbsoluteContentSize" then 107 | syncContentSize() 108 | end 109 | end) 110 | 111 | return self 112 | end 113 | 114 | return Section -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/KeybindInputField.lua: -------------------------------------------------------------------------------- 1 | local KeybindInputField = {} 2 | KeybindInputField.__index = KeybindInputField 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local KeybindManager = require(GV.ManagersDir.KeybindManager) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | local InputField = require(GV.ObjectsDir.InputField) 9 | local KeybindNum = 0 10 | setmetatable(KeybindInputField,InputField) 11 | 12 | --[[ 13 | How to make keybinds in code 14 | Always use Left if its control alt or shift 15 | ex: 16 | {{LeftControl, LeftAlt, Zero},{P}} 17 | {{"Keybind Preset",{{LeftControl, LeftAlt, Zero},{P}}}} 18 | ]]-- 19 | 20 | function KeybindInputField:UpdateValues(Value) 21 | Value = Value or self.Value 22 | KeybindManager.UpdateKeybinds(self.ID, {Keybinds = Value, Holdable = self.Holdable, PressedAction = self.PressedAction, ReleasedAction = self.ReleasedAction}) 23 | end 24 | 25 | function KeybindInputField:UpdateBind(Value) 26 | if not Value then return end 27 | if #Value[1]>0 and #Value[#Value]>0 then Value[#Value + 1] = {} end 28 | self:UpdateValues(Value) 29 | end 30 | 31 | function KeybindInputField:SetBind(Bind) 32 | Bind = Bind or {Value = {{}}} 33 | local BindInfo = self.GetItemInfo(Bind) 34 | local Value = BindInfo.Value 35 | self:UpdateBind(Value) 36 | self:SetValue({Name = BindInfo.Name or KeybindManager.GenerateKeybindList(Value), ["Value"] = Value}) 37 | end 38 | 39 | function KeybindInputField:AddBind(Bind) 40 | local BindInfo = self.GetItemInfo(Bind) 41 | if #BindInfo.Value[1]>0 and #BindInfo.Value[#BindInfo.Value]>0 then BindInfo.Value[#BindInfo.Value+1] = {} end 42 | self:AddItem({Name = BindInfo.Name or KeybindManager.GenerateKeybindList(BindInfo.Value), Value = BindInfo.Value}, function() self:UpdateBind(BindInfo.Value) end) 43 | end 44 | 45 | function KeybindInputField:AddBinds(Binds) 46 | for _, Bind in pairs(Binds) do 47 | self:AddBind(Bind) 48 | end 49 | end 50 | 51 | function KeybindInputField:EditKeybind(Keybind, Complete) 52 | local Value = util.CopyTable(self.Value) 53 | Value[#Value] = Keybind 54 | if Complete then 55 | Value[#Value+1] = {} 56 | end 57 | self:UpdateValues(Value) 58 | self:SetValue({Name = KeybindManager.GenerateKeybindList(Value), ["Value"] = Value}) 59 | end 60 | 61 | function KeybindInputField:RemoveKeybind(Index) 62 | local Value = util.CopyTable(self.Value) 63 | Index = Index or #Value - 1 64 | table.remove(Value, Index) 65 | self:SetValue({Name = KeybindManager.GenerateKeybindList(Value), ["Value"] = Value}) 66 | end 67 | 68 | function KeybindInputField:UnfocusInputField(ForceUnfocus) 69 | if not ForceUnfocus and self.MouseInInput then return false 70 | else 71 | ThemeManager.ColorSync(self.InputFieldFrame, "BorderColor3", Enum.StudioStyleGuideColor.InputFieldBorder) 72 | self.Focused = false 73 | end 74 | return true 75 | end 76 | 77 | function KeybindInputField:Pressed(func) 78 | function self.PressedAction() 79 | if not self.Disabled and func then func() end 80 | end 81 | self:UpdateValues() 82 | end 83 | 84 | function KeybindInputField:Released(func) 85 | function self.ReleasedAction() 86 | if not self.Disabled and func then func() end 87 | end 88 | self:UpdateValues() 89 | end 90 | 91 | -- PressedAction, ReleasedAction, Holdable, Unrestricted, Bind/CurrentBind, Items/Binds 92 | function KeybindInputField.new(Arguments, Parent) 93 | Arguments = Arguments or {} 94 | KeybindNum += 1 95 | Arguments.Placeholder = Arguments.Placeholder or "Set Keybind" 96 | Arguments.DisableEditing = true 97 | local self = InputField.new(Arguments, Parent) 98 | setmetatable(self,KeybindInputField) 99 | self.IgnoreText = true 100 | self.Holdable = self.Arguments.Holdable 101 | self.Unrestricted = self.Arguments.Unrestricted 102 | if not self.Holdable then self.Holdable = false end 103 | if not self.Unrestricted then self.Unrestricted = false end 104 | self.DefaultEmpty = {{}} 105 | self.TextEditable = true 106 | self.ID = KeybindNum 107 | self:Pressed(self.Arguments.PressedAction) 108 | self:Released(self.Arguments.ReleasedAction) 109 | self.Value = {{}} 110 | self.Arguments.Binds = self.Arguments.Items or self.Arguments.Binds 111 | self.Input.Focused:Connect(function() 112 | if self.Disabled then return end 113 | self.Focused = true 114 | ThemeManager.ColorSync(self.InputFieldFrame, "BorderColor3", Enum.StudioStyleGuideColor.InputFieldBorder, Enum.StudioStyleGuideModifier.Selected, true) 115 | task.wait() 116 | KeybindManager.FocusInputField(self.ID, self, self.EditKeybind, self.RemoveKeybind, self.UnfocusInputField) 117 | end) 118 | if self.Arguments.Binds then self:AddBinds(self.Arguments.Binds) end 119 | self:SetBind(self.Arguments.Bind or self.Arguments.CurrentBind) 120 | return self 121 | end 122 | 123 | return KeybindInputField -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/Slider.lua: -------------------------------------------------------------------------------- 1 | local Slider = {} 2 | Slider.__index = Slider 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIObject = require(GV.ObjectsDir.GUIObject) 7 | local InputManager = require(GV.ManagersDir.InputManager) 8 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 9 | setmetatable(Slider,GUIObject) 10 | 11 | function Slider:SetDisabled(State) 12 | self.Disabled = State 13 | self.SliderSelected = false 14 | if self.Disabled then 15 | self.CursorIcon = "rbxasset://SystemCursors/Forbidden" 16 | self.SlideBar.BackgroundTransparency, self.SlideButton.BackgroundTransparency = 0.5, 0.5 17 | else 18 | self.CursorIcon = "rbxasset://SystemCursors/PointingHand" 19 | self.SlideBar.BackgroundTransparency, self.SlideButton.BackgroundTransparency = 0, 0 20 | end 21 | end 22 | 23 | function Slider:SetValue(Value) 24 | self.Value = Value 25 | self:UpdatePosition() 26 | end 27 | 28 | function Slider:SetRange(Min, Max) 29 | self.Min = Min 30 | self.Max = Max 31 | self:UpdatePosition() 32 | end 33 | 34 | function Slider:UpdatePosition() 35 | self.SlideButton.Position = UDim2.new((self.Value-self.Min)/(self.Max - self.Min), 0, 0.5, 0) 36 | if self.Value ~= self.PreviousValue then 37 | self.PreviousValue = self.Value 38 | if self.Action then self.Action(self.Value) end 39 | end 40 | end 41 | 42 | function Slider:ToggleDisable() 43 | self:SetDisabled(not self.Disabled) 44 | end 45 | 46 | function Slider:Changed(func) 47 | self.Action = func 48 | end 49 | 50 | function Slider:Pressed(func) 51 | self.PressedAction = func 52 | end 53 | 54 | function Slider:Released(func) 55 | self.ReleasedAction = func 56 | end 57 | 58 | -- Min, Max, Value, Increment, SliderSize, Disabled 59 | function Slider.new(Arguments, Parent) 60 | local self = GUIObject.new(Arguments, Parent) 61 | setmetatable(self,Slider) 62 | self.Increment = self.Arguments.Increment or 0 63 | self.Value = self.Arguments.Value or self.Arguments.Min 64 | self.Min = self.Arguments.Min 65 | self.Max = self.Arguments.Max 66 | self.SliderFrame = Instance.new("Frame", self.Parent) 67 | self.SliderFrame.BackgroundTransparency = 1 68 | self.SlideBar = Instance.new("Frame", self.SliderFrame) 69 | self.SlideBar.AnchorPoint = Vector2.new(0.5,0.5) 70 | self.SlideBar.Position = UDim2.new(0.5,0,0.5,0) 71 | local Size = util.GetScale(self.Arguments.SliderSize) or UDim.new(1,-12) 72 | self.SlideBar.Size = UDim2.new(Size.Scale, Size.Offset, 0, 5) 73 | ThemeManager.ColorSync(self.SlideBar, "BackgroundColor3", Enum.StudioStyleGuideColor.FilterButtonAccent) 74 | self.SlideButton = Instance.new("TextButton", self.SlideBar) 75 | self.SlideButton.Text = "" 76 | self.SlideButton.BorderSizePixel = 1 77 | self.SlideButton.AnchorPoint = Vector2.new(0.5,0.5) 78 | self:UpdatePosition() 79 | self.SlideButton.Size = UDim2.new(0,7,0,18) 80 | ThemeManager.ColorSync(self.SlideButton, "BackgroundColor3", Enum.StudioStyleGuideColor.InputFieldBackground) 81 | ThemeManager.ColorSync(self.SlideButton, "BorderColor3", Enum.StudioStyleGuideColor.InputFieldBorder) 82 | self.SlideBar.BorderSizePixel = 0 83 | self.SliderSelected = false 84 | self.InitialX = 0 85 | self.SlideButton.MouseButton1Down:Connect(function(x) 86 | if self.PressedAction then self.PressedAction() end 87 | if self.Disabled then return end 88 | self.SliderSelected = true 89 | self.InitialX = self.SlideButton.AbsolutePosition.X - x 90 | end) 91 | self.SlideButton.MouseButton1Up:Connect(function() 92 | if self.ReleasedAction then self.ReleasedAction() end 93 | end) 94 | self.PreviousValue = self.Value 95 | InputManager.AddInputEvent("MouseMoved", function(x) 96 | if not self.SliderSelected then return end 97 | self.Value = util.RoundNumber(math.clamp((x + self.InitialX - self.SlideBar.AbsolutePosition.X + self.SlideButton.Size.X.Offset / 2)/self.SlideBar.AbsoluteSize.X, 0, 1) * (self.Max - self.Min) + self.Min, self.Increment) 98 | self:UpdatePosition() 99 | end) 100 | InputManager.AddInputEvent("InputEnded", function(p) 101 | if self.SliderSelected and p.UserInputType == Enum.UserInputType.MouseButton1 then 102 | self.SliderSelected = false 103 | if self.ReleasedAction then self.ReleasedAction() end 104 | end 105 | end) 106 | InputManager.AddInputEvent("MouseLeave", function() 107 | if self.SliderSelected and self.ReleasedAction then self.ReleasedAction() end 108 | self.SliderSelected = false 109 | end) 110 | self.SlideButton.MouseMoved:Connect(function() 111 | GV.PluginObject:GetMouse().Icon = self.CursorIcon 112 | end) 113 | self.SlideButton.MouseLeave:Connect(function() 114 | task.wait(0) 115 | GV.PluginObject:GetMouse().Icon = "rbxasset://SystemCursors/Arrow" 116 | end) 117 | self:SetDisabled(self.Arguments.Disabled) 118 | self.Object = self.SlideButton 119 | self.MainMovable = self.SliderFrame 120 | return self 121 | end 122 | 123 | return Slider -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/ColorInput.lua: -------------------------------------------------------------------------------- 1 | local ColorInput = {} 2 | ColorInput.__index = ColorInput 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local GUIObject = require(GV.ObjectsDir.GUIObject) 7 | local InputField = require(GV.ObjectsDir.InputField) 8 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 9 | local ColorPrompt = require(GV.PromptsDir.ColorPrompt) 10 | setmetatable(ColorInput,GUIObject) 11 | 12 | local RightClickMenu = GV.PluginObject:CreatePluginMenu(game:GetService("HttpService"):GenerateGUID(false), "RightClickMenu - ColorInput") 13 | RightClickMenu.Name = "ColorInput Right-Click Menu" 14 | RightClickMenu:AddNewAction("Reset", "Reset") 15 | 16 | function ColorInput:SetDisabled(State) 17 | self.Disabled = State 18 | self.ColorInput:SetDisabled(State) 19 | if self.Disabled then 20 | self.CursorIcon = "rbxasset://SystemCursors/Forbidden" 21 | self.ColorButton.BackgroundTransparency = 0.5 22 | else 23 | self.CursorIcon = "rbxasset://SystemCursors/PointingHand" 24 | self.ColorButton.BackgroundTransparency = 0 25 | end 26 | end 27 | 28 | function ColorInput:ToggleDisable() 29 | self:SetDisabled(not self.Disabled) 30 | end 31 | 32 | function ColorInput:SetValue(Value, IgnoreText) 33 | self.Value = Value 34 | self.ColorButton.BackgroundColor3 = self.Value 35 | if not IgnoreText then self.ColorInput.Input.Text = util.Color3ToText(self.Value) end 36 | if self.Action then self.Action(self.Value) end 37 | end 38 | 39 | function ColorInput:Changed(func) 40 | self.Action = func 41 | end 42 | 43 | -- Color/Value/DefaultColor, NoPause, Disabled 44 | function ColorInput.new(Arguments, Parent) 45 | local self = GUIObject.new(Arguments, Parent) 46 | setmetatable(self,ColorInput) 47 | self.IgnoreText = true 48 | self.Disabled = self.Arguments.Disabled 49 | self.ColorInputContainer = Instance.new("Frame", self.Parent) 50 | self.ColorInputContainer.BackgroundTransparency = 1 51 | self.ColorInputContainer.Name = "ColorInputContainer" 52 | self.ColorInputFrame = Instance.new("Frame", self.ColorInputContainer) 53 | self.ColorInputFrame.Name = "ColorInputFrame" 54 | self.ColorInputFrame.AnchorPoint = Vector2.new(0.5,0.5) 55 | self.ColorInputFrame.BackgroundTransparency = 1 56 | self.ColorInputFrame.Position = UDim2.new(0.5,0,0.5,0) 57 | self.ColorInputFrame.Size = UDim2.new(0,130,1,0) 58 | self.ColorInputLayout = Instance.new("UIListLayout", self.ColorInputFrame) 59 | self.ColorInputLayout.Padding = UDim.new(0,10) 60 | self.ColorInputLayout.FillDirection = Enum.FillDirection.Horizontal 61 | self.ColorInputLayout.SortOrder = Enum.SortOrder.LayoutOrder 62 | self.ColorInputLayout.VerticalAlignment = Enum.VerticalAlignment.Center 63 | self.ColorButton = Instance.new("TextButton", self.ColorInputFrame) 64 | self.ColorButton.Name = "ColorButton" 65 | self.ColorButton.Size = UDim2.new(0,18,0,18) 66 | ThemeManager.ColorSync(self.ColorButton, "BorderColor3", Enum.StudioStyleGuideColor.InputFieldBorder) 67 | self.ColorButton.Text = "" 68 | self.ColorButton.MouseButton1Click:Connect(function() 69 | if self.Disabled then return end 70 | local prompt = ColorPrompt.new({Value = self.Value, NoPause = self.Arguments.NoPause}) 71 | prompt:Done(function(p) 72 | self:SetValue(p) 73 | end) 74 | prompt:Changed(function(p) 75 | self:SetValue(p) 76 | end) 77 | end) 78 | self.ColorButton.MouseButton2Click:Connect(function() 79 | if self.Disabled then return end 80 | local Response = RightClickMenu:ShowAsync() 81 | if Response then 82 | if Response.Text == "Reset" then self:SetValue(self.DefaultValue) end 83 | end 84 | end) 85 | self.ColorInput = InputField.new({NoDropdown = true, ClearBackground = true}, self.ColorInputFrame) 86 | self.ColorInput.Name = "ColorInput" 87 | self.ColorInput.InputFieldContainer.Size = UDim2.new(0,100,0,20) 88 | self.ColorInput.InputFieldFrame.Size = UDim2.new(1,0,1,0) 89 | self.ColorInput.Input.TextXAlignment = Enum.TextXAlignment.Center 90 | self.ColorInput:Changed(function(p) 91 | self:SetValue(util.TextToColor3(p), true) 92 | end) 93 | self.ColorInput:LostFocus(function(p) 94 | self:SetValue(util.TextToColor3(p)) 95 | self.ColorInput.Input.TextXAlignment = Enum.TextXAlignment.Center 96 | end) 97 | self.ColorInput:GainedFocus(function() 98 | self.ColorInput.Input.TextXAlignment = Enum.TextXAlignment.Left 99 | end) 100 | self.ColorButton.MouseMoved:Connect(function() 101 | GV.PluginObject:GetMouse().Icon = self.CursorIcon 102 | end) 103 | self.ColorButton.MouseLeave:Connect(function() 104 | task.wait(0) 105 | GV.PluginObject:GetMouse().Icon = "rbxasset://SystemCursors/Arrow" 106 | end) 107 | self.DefaultValue = self.Arguments.Color or self.Arguments.Value or Color3.new(1,1,1) 108 | self:SetValue(self.DefaultValue) 109 | self:SetDisabled(self.Disabled) 110 | self.Object = self.ColorButton 111 | self.MainMovable = self.ColorInputContainer 112 | return self 113 | end 114 | 115 | return ColorInput -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/PluginWidget.lua: -------------------------------------------------------------------------------- 1 | local GuiService = game:GetService("GuiService") 2 | local Widget = {} 3 | Widget.__index = Widget 4 | 5 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 6 | local plugin = GV.PluginObject 7 | local util = require(GV.MiscDir.GUIUtil) 8 | local InputManager = require(GV.ManagersDir.InputManager) 9 | local GUIFrame = require(GV.FramesDir.GUIFrame) 10 | local TitlebarMenu = require(GV.FramesDir.TitlebarMenu) 11 | local InputField = require(GV.ObjectsDir.InputField) 12 | local TextPrompt = require(GV.PromptsDir.TextPrompt) 13 | local InputPrompt = require(GV.PromptsDir.InputPrompt) 14 | local BackgroundFrame = require(GV.FramesDir.BackgroundFrame) 15 | setmetatable(Widget,GUIFrame) 16 | GV.PluginWidgets = {} 17 | local Unnamed = 0 18 | 19 | function Widget:Delete() 20 | local WidgetTitle = self.WidgetObject.Title 21 | local DeletePrompt = TextPrompt.new({Title = "Delete " .. WidgetTitle, Text = 'Are you sure you want to delete "' .. WidgetTitle .. '"?', Buttons = {"Yes", "No"}}) 22 | DeletePrompt:Clicked(function(p) 23 | if p == 2 or p == 0 then return end 24 | if self.TitlebarMenu and #self.TitlebarMenu.Pages > 0 then 25 | local AvailibleWidgets = {} 26 | for _,v in pairs(GV.PluginWidgets)do 27 | if v.TitlebarMenu and v.WidgetObject.Title ~= WidgetTitle then AvailibleWidgets[#AvailibleWidgets+1] = {Name = v.WidgetObject.Title, Value = v} end 28 | end 29 | if #AvailibleWidgets < 1 then return end 30 | local TransferPrompt = InputPrompt.new({Title = "Transfer Pages", Text = "Where would you like to move the pages?", Buttons = {"OK", "Cancel"}, InputField = InputField.new({Value = AvailibleWidgets[1], Items = AvailibleWidgets, DisableEditing = true, NoFiltering = true, Unpausable = true})}) 31 | TransferPrompt:Clicked(function(p2) 32 | if p2 == 2 then return end 33 | local NewWidget = TransferPrompt.InputField.Value 34 | if NewWidget == "" then return end 35 | for _, v in pairs(self.TitlebarMenu.Pages) do 36 | NewWidget.TitlebarMenu:RecievePage(v) 37 | end 38 | self.WidgetObject:Destroy() 39 | table.remove(GV.PluginWidgets, self.Index) 40 | self = nil 41 | end) 42 | util.DumpGUI(TransferPrompt.Widget) 43 | else 44 | self.WidgetObject:Destroy() 45 | table.remove(GV.PluginWidgets, self.Index) 46 | self = nil 47 | end 48 | end) 49 | end 50 | 51 | function Widget:Rename() 52 | local NewTitlePrompt = InputPrompt.new({Title = "Rename " .. self.WidgetObject.Title, Text = "Type in a new name:", Buttons = {"OK", "Cancel"}, InputField = InputField.new({Placeholder = "New name", Text = self.WidgetObject.Title, NoDropdown = true, Unpausable = true})}) 53 | NewTitlePrompt:Clicked(function(p) 54 | if p == 2 then return end 55 | self.WidgetObject.Title = NewTitlePrompt.Input.Text 56 | end) 57 | end 58 | 59 | -- ID, Title, Enabled, NoTitlebarMenu, DockState, OverrideRestore 60 | function Widget.new(Arguments) 61 | local self = GUIFrame.new(Arguments) 62 | setmetatable(self, Widget) 63 | self.ID = self.Arguments.ID or game:GetService("HttpService"):GenerateGUID(false) 64 | local title = self.Arguments.Title 65 | if not title then 66 | title = self.Arguments.ID 67 | if not title then 68 | Unnamed += 1 69 | title = "Unnamed #" .. tostring(Unnamed) 70 | end 71 | end 72 | self.Arguments.DockState = self.Arguments.DockState or Enum.InitialDockState.Float 73 | -- really dumb but its gotta be a boolean 74 | if not self.Arguments.Enabled then self.Arguments.Enabled = false end 75 | if not self.Arguments.OverrideRestore then self.Arguments.OverrideRestore = false end 76 | self.WidgetObject = plugin:CreateDockWidgetPluginGui(self.ID, DockWidgetPluginGuiInfo.new(self.Arguments.DockState, self.Arguments.Enabled, self.Arguments.OverrideRestore, 300, 500, 50, 50)) 77 | self.WidgetObject.Title = title 78 | self.BackgroundFrame = BackgroundFrame.new(nil, self.WidgetObject) 79 | self.InputFrame = Instance.new("Frame", self.WidgetObject) 80 | self.InputFrame.BackgroundTransparency = 1 81 | self.InputFrame.Size = UDim2.new(1,0,1,0) 82 | self.InputFrame.ZIndex = 100 83 | self.InputFrame.Name = "InputFrame" 84 | local FixPosition = false 85 | local FixPage = nil 86 | self.InputFrame.MouseMoved:Connect(function() 87 | if not FixPosition then return end 88 | FixPosition = false 89 | local MousePos = self.WidgetObject:GetRelativeMousePosition() 90 | FixPage.TabFrame.Position = UDim2.new(0,MousePos.X + FixPage.InitialX + self.TitlebarMenu.ScrollingMenu.CanvasPosition.X, 0,0) 91 | self.TitlebarMenu:BeingDragged(FixPage.ID) 92 | self.TitlebarMenu:FixPageLayout() 93 | end) 94 | InputManager.AddInput(self.InputFrame) 95 | if not self.Arguments.NoTitlebarMenu then self.TitlebarMenu = TitlebarMenu.new({ID = self.ID}, self.WidgetObject) end 96 | self.WidgetObject.PluginDragDropped:Connect(function() 97 | if(GV.SelectedPage and self.TitlebarMenu) then 98 | self.TitlebarMenu:RecievePage(GV.SelectedPage) 99 | FixPosition = true 100 | FixPage = GV.SelectedPage 101 | self.TitlebarMenu:SetActive(GV.SelectedPage.ID) 102 | GV.SelectedPage = nil 103 | end 104 | end) 105 | for _, v in pairs(GV.TitleBarButtons) do 106 | v:CreateCopy(self.TitlebarMenu) 107 | end 108 | self.Parent = self.WidgetObject 109 | self.Content = self.WidgetObject 110 | self.Index = #GV.PluginWidgets+1 111 | GV.PluginWidgets[self.Index] = self 112 | return self 113 | end 114 | 115 | return Widget -------------------------------------------------------------------------------- /src/rblxgui/lib/Objects/Button.lua: -------------------------------------------------------------------------------- 1 | local Button = {} 2 | Button.__index = Button 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 7 | local TextboxMod = require(GV.ObjectsDir.Textbox) 8 | local GUIObject = require(GV.ObjectsDir.GUIObject) 9 | setmetatable(Button,GUIObject) 10 | 11 | Button.Images = { 12 | border = "http://www.roblox.com/asset/?id=10460485555", 13 | bg = "http://www.roblox.com/asset/?id=10460051857", 14 | selected = "http://www.roblox.com/asset/?id=10460676787" 15 | } 16 | 17 | function Button:SetDisabled(State) 18 | self.Disabled = State 19 | if self.Disabled then 20 | self.CursorIcon = "rbxasset://SystemCursors/Forbidden" 21 | self.Button.ImageTransparency, self.Textbox.TextTransparency = 0.5, 0.5 22 | else 23 | self.CursorIcon = "rbxasset://SystemCursors/PointingHand" 24 | self.Button.ImageTransparency, self.Textbox.TextTransparency = 0, 0 25 | end 26 | end 27 | 28 | function Button:ToggleDisable() 29 | self:SetDisabled(not self.Disabled) 30 | end 31 | 32 | function Button:Clicked(func) 33 | self.Action = func 34 | end 35 | 36 | function Button:Pressed(func) 37 | self.PressedAction = func 38 | end 39 | 40 | function Button:Released(func) 41 | self.ReleasedAction = func 42 | end 43 | 44 | -- Text/Textbox, ButtonSize, Disabled 45 | function Button.new(Arguments, Parent) 46 | local self = GUIObject.new(Arguments, Parent) 47 | setmetatable(self,Button) 48 | self.TextboxTable = nil 49 | -- creating a frame to hold the button 50 | self.ButtonFrame = Instance.new("Frame", self.Parent) 51 | self.ButtonFrame.BackgroundTransparency = 1 52 | self.ButtonFrame.Name = "ButtonFrame" 53 | self.ButtonFrame.Size = UDim2.new(1,0,1,0) 54 | 55 | self.Button = Instance.new("ImageButton", self.ButtonFrame) 56 | 57 | -- set up a textbox for the button 58 | local Textbox = self.Arguments.Textbox or self.Arguments.Text 59 | if type(Textbox) == "string" then 60 | self.TextboxTable = TextboxMod.new({Text = Textbox}, self.Button) 61 | else 62 | self.TextboxTable = Textbox 63 | Textbox:Move(self.Button, true) 64 | end 65 | self.Textbox = self.TextboxTable.Textbox 66 | self.Textbox.ZIndex = 1 67 | 68 | local Size = util.GetScale(self.Arguments.ButtonSize) 69 | if Size then self.Button.Size = UDim2.new(Size.Scale,Size.Offset,1,0) 70 | else 71 | local function sync() 72 | self.Button.Size = UDim2.new(0,self.Textbox.TextBounds.X+1.5*self.Textbox.TextSize, 1, 0) 73 | end 74 | self.Textbox.Changed:Connect(function(p) 75 | if p == "TextBounds" then sync() end 76 | end) 77 | end 78 | self.Button.Position = UDim2.new(0.5, 0, 0, 0) 79 | self.Button.AnchorPoint = Vector2.new(0.5,0) 80 | self.Button.BackgroundTransparency = 1 81 | self.Button.Image = self.Images.border 82 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.DialogButtonBorder) 83 | self.Button.ScaleType = Enum.ScaleType.Slice 84 | self.Button.SliceCenter = Rect.new(7,7,156,36) 85 | self.Button.Name = "Button" 86 | 87 | self.ButtonBackground = Instance.new("ImageLabel", self.Button) 88 | self.ButtonBackground.Name = "ButtonBackground" 89 | self.ButtonBackground.BackgroundTransparency = 1 90 | self.ButtonBackground.Size = UDim2.new(1,0,1,0) 91 | self.ButtonBackground.Image = self.Images.bg 92 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button) 93 | self.ButtonBackground.ScaleType = Enum.ScaleType.Slice 94 | self.ButtonBackground.SliceCenter = Rect.new(7,7,156,36) 95 | self.ButtonBackground.ZIndex = 0 96 | 97 | self.Toggleable = false 98 | local Pressed = false 99 | self.Button.MouseMoved:Connect(function() 100 | GV.PluginObject:GetMouse().Icon = self.CursorIcon 101 | if self.Disabled or Pressed or self.Toggleable then return end 102 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder, Enum.StudioStyleGuideModifier.Hover) 103 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Hover) 104 | end) 105 | self.Button.MouseLeave:Connect(function() 106 | task.wait(0) 107 | GV.PluginObject:GetMouse().Icon = "rbxasset://SystemCursors/Arrow" 108 | if self.Disabled or self.Toggleable then return end 109 | if Pressed and self.ReleasedAction then self.ReleasedAction() end 110 | Pressed = false 111 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder) 112 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button) 113 | end) 114 | 115 | self.Button.MouseButton1Down:Connect(function() 116 | if self.Disabled or self.Toggleable then return end 117 | if self.PressedAction then self.PressedAction() end 118 | Pressed = true 119 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder, Enum.StudioStyleGuideModifier.Pressed) 120 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button, Enum.StudioStyleGuideModifier.Pressed) 121 | end) 122 | 123 | self.Button.MouseButton1Up:Connect(function() 124 | if self.Disabled or self.Toggleable then return end 125 | if self.ReleasedAction then self.ReleasedAction() end 126 | Pressed = false 127 | ThemeManager.ColorSync(self.Button, "ImageColor3", Enum.StudioStyleGuideColor.ButtonBorder) 128 | ThemeManager.ColorSync(self.ButtonBackground, "ImageColor3", Enum.StudioStyleGuideColor.Button) 129 | end) 130 | 131 | self.Button.MouseButton1Click:Connect(function() 132 | if not self.Disabled then 133 | if self.Action then self.Action(self.Value) end 134 | end 135 | end) 136 | 137 | self:SetDisabled(self.Arguments.Disabled) 138 | self.Object = self.Button 139 | self.MainMovable = self.ButtonFrame 140 | return self 141 | end 142 | 143 | return Button -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/Page.lua: -------------------------------------------------------------------------------- 1 | local Page = {} 2 | Page.__index = Page 3 | 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local util = require(GV.MiscDir.GUIUtil) 6 | local InputManager = require(GV.ManagersDir.InputManager) 7 | local GUIFrame = require(GV.FramesDir.GUIFrame) 8 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 9 | setmetatable(Page,GUIFrame) 10 | local PageNum = 0 11 | GV.PluginPages = {} 12 | 13 | function Page:SetState(State) 14 | self.Open = State 15 | self.Content.Visible = State 16 | local Transparency = 1 17 | local OppositeTransparency = 0 18 | if State then Transparency, OppositeTransparency = 0, 1 end 19 | self.TabFrame.BackgroundTransparency, self.TopBorder.BackgroundTransparency, self.LeftBorder.BackgroundTransparency, self.RightBorder.BackgroundTransparency = Transparency, Transparency, Transparency, Transparency 20 | self.Tab.BackgroundTransparency = OppositeTransparency 21 | self.TabFrame.ZIndex, self.Tab.ZIndex, self.TopBorder.ZIndex, self.LeftBorder.ZIndex, self.RightBorder.ZIndex = OppositeTransparency + 2, OppositeTransparency + 2, OppositeTransparency + 2, OppositeTransparency + 2, OppositeTransparency + 2 22 | if State then 23 | ThemeManager.ColorSync(self.Tab, "TextColor3", Enum.StudioStyleGuideColor.MainText) 24 | else 25 | ThemeManager.ColorSync(self.Tab, "TextColor3", Enum.StudioStyleGuideColor.TitlebarText,nil,nil,nil,true) 26 | end 27 | end 28 | 29 | -- Name, TitlebarMenu, Open, TabSize, ID 30 | function Page.new(Arguments, Parent) 31 | local self = GUIFrame.new(Arguments, Parent) 32 | self.TitlebarMenu = self.Arguments.TitlebarMenu or self.Parent.TitlebarMenu 33 | setmetatable(self,Page) 34 | PageNum += 1 35 | self.ID = self.Arguments.ID or self.Arguments.Name 36 | self.TabFrame = Instance.new("Frame", self.TitlebarMenu.TabContainer) 37 | self.TabFrame.Name = PageNum 38 | self.TabFrame.BorderSizePixel = 0 39 | ThemeManager.ColorSync(self.TabFrame, "BackgroundColor3", Enum.StudioStyleGuideColor.MainBackground) 40 | self.Tab = Instance.new("TextButton", self.TabFrame) 41 | self.Tab.Size = UDim2.new(1, 0, 0, 24) 42 | ThemeManager.ColorSync(self.Tab, "BackgroundColor3", Enum.StudioStyleGuideColor.Titlebar,nil,nil,nil,true) 43 | self.Tab.BorderSizePixel = 0 44 | self.Tab.Font = Enum.Font.SourceSans 45 | self.Tab.Text = self.Arguments.Name 46 | self.Tab.TextSize = 14 47 | self.Tab.Name = "Tab" 48 | self.InsideWidget = true 49 | if not self.Arguments.TabSize then 50 | local function sync() 51 | self.TabFrame.Size = UDim2.new(0,self.Tab.TextBounds.X+1.5*self.Tab.TextSize, 0, 24) 52 | end 53 | self.Tab.Changed:Connect(function(p) 54 | if p == "TextBounds" then sync() end 55 | end) 56 | sync() 57 | else 58 | self.TabFrame.Size = UDim2.new(0,self.Arguments.TabSize,0,30) 59 | end 60 | self.Tab.MouseButton1Down:Connect(function(x) 61 | if self.TabDragging then return end 62 | GV.SelectedPage = self 63 | self.TitlebarMenu:SetActive(self.ID) 64 | self.TabDragging = true 65 | self.InitialX = self.TabFrame.Position.X.Offset - x - self.TitlebarMenu.ScrollingMenu.CanvasPosition.X 66 | end) 67 | InputManager.AddInputEvent("InputEnded", function(p) 68 | if not self.TabDragging or p.UserInputType ~= Enum.UserInputType.MouseButton1 then return end 69 | GV.SelectedPage = nil 70 | self.TabDragging = false 71 | self.TitlebarMenu:FixPageLayout() 72 | end) 73 | InputManager.AddInputEvent("MouseEnter", function() 74 | if not self.TabDragging and self.InsideWidget then return end 75 | self.TitlebarMenu:AddPage(self) 76 | self.InsideWidget = true 77 | GV.SelectedPage = nil 78 | self.TabDragging = false 79 | self.TitlebarMenu:FixPageLayout() 80 | end) 81 | local PreviousMouseX = 0 82 | InputManager.AddInputEvent("MouseMoved", function(x) 83 | PreviousMouseX = x 84 | if not self.TabDragging then return end 85 | self.TabFrame.Position = UDim2.new(0,x + self.InitialX + self.TitlebarMenu.ScrollingMenu.CanvasPosition.X,0,0) 86 | if self.InsideWidget then self.TitlebarMenu:BeingDragged(self.ID) end 87 | end) 88 | self.TitlebarMenu.ScrollingMenu.Changed:Connect(function(p) 89 | if not p == "CanvasPosition" or not self.TabDragging then return end 90 | self.TabFrame.Position = UDim2.new(0,PreviousMouseX + self.InitialX + self.TitlebarMenu.ScrollingMenu.CanvasPosition.X,0,0) 91 | if self.InsideWidget then self.TitlebarMenu:BeingDragged(self.ID) end 92 | end) 93 | InputManager.AddInputEvent("MouseLeave", function() 94 | if not self.TabDragging then return end 95 | self.TabDragging = false 96 | self.InsideWidget = false 97 | GV.PluginObject:StartDrag({}) 98 | self.TitlebarMenu:RemovePage(self) 99 | end) 100 | ThemeManager.ColorSync(self.Tab, "TextColor3", Enum.StudioStyleGuideColor.TitlebarText,nil,nil,nil,true) 101 | self.TopBorder = Instance.new("Frame", self.TabFrame) 102 | self.TopBorder.Size = UDim2.new(1,0,0,1) 103 | self.TopBorder.BorderSizePixel = 0 104 | self.TopBorder.Name = "TopBorder" 105 | ThemeManager.ColorSync(self.TopBorder, "BackgroundColor3", Enum.StudioStyleGuideColor.RibbonTabTopBar, nil, true, nil, true) 106 | self.LeftBorder = Instance.new("Frame", self.TabFrame) 107 | self.LeftBorder.Size = UDim2.new(0,1,0,24) 108 | self.LeftBorder.BorderSizePixel = 0 109 | self.LeftBorder.Name = "LeftBorder" 110 | ThemeManager.ColorSync(self.LeftBorder, "BackgroundColor3", Enum.StudioStyleGuideColor.Border) 111 | self.RightBorder = Instance.new("Frame", self.TabFrame) 112 | self.RightBorder.Size = UDim2.new(0,1,0,24) 113 | self.RightBorder.Position = UDim2.new(1,0,0,0) 114 | self.RightBorder.BorderSizePixel = 0 115 | self.RightBorder.Name = "RightBorder" 116 | ThemeManager.ColorSync(self.RightBorder, "BackgroundColor3", Enum.StudioStyleGuideColor.Border) 117 | self.Content = Instance.new("Frame", self.TitlebarMenu.ContentContainers) 118 | self.Content.BackgroundTransparency = 1 119 | self.Content.Size = UDim2.new(1,0,1,0) 120 | self.Content.Name = self.ID 121 | self.TitlebarMenu:AddPage(self) 122 | if self.Arguments.Open then self.TitlebarMenu:SetActive(self.ID) else self:SetState(false) end 123 | GV.PluginPages[#GV.PluginPages+1] = self 124 | return self 125 | end 126 | 127 | return Page -------------------------------------------------------------------------------- /src/rblxgui/lib/Frames/TitlebarMenu.lua: -------------------------------------------------------------------------------- 1 | local StarterPlayer = game:GetService("StarterPlayer") 2 | local TitlebarMenu = {} 3 | TitlebarMenu.__index = TitlebarMenu 4 | local GV = require(script.Parent.Parent.PluginGlobalVariables) 5 | local GUIFrame = require(GV.FramesDir.GUIFrame) 6 | local util = require(GV.MiscDir.GUIUtil) 7 | local ThemeManager = require(GV.ManagersDir.ThemeManager) 8 | setmetatable(TitlebarMenu,GUIFrame) 9 | GV.PluginTitlebarMenus = {} 10 | 11 | function TitlebarMenu:RecievePage(Page) 12 | Page.TabFrame.Parent = self.TabContainer 13 | Page.Content.Parent = self.ContentContainers 14 | Page.TitlebarMenu = self 15 | Page.InsideWidget = true 16 | Page.Parent = self.TitlebarMenu 17 | self:AddPage(Page) 18 | end 19 | 20 | function TitlebarMenu:GetIDIndex(ID) 21 | for i,v in pairs(self.Pages) do if v.ID == ID then return i end end 22 | end 23 | 24 | function TitlebarMenu:GetIDTab(ID) 25 | return self.Pages[self:GetIDIndex(ID)] 26 | end 27 | 28 | function TitlebarMenu:AddPage(Page) 29 | self:FixPageLayout() 30 | if #self.Pages > 0 then 31 | local LatestPage = self.Pages[#self.Pages] 32 | Page.TabFrame.Position = UDim2.new(0,LatestPage.TabFrame.Position.X.Offset + LatestPage.TabFrame.Size.X.Offset,0,0) 33 | else 34 | Page.TabFrame.Position = UDim2.new(0,0,0,0) 35 | end 36 | self.ScrollingMenu.CanvasSize = UDim2.new(0,Page.TabFrame.Position.X.Offset + Page.TabFrame.Size.X.Offset,0,0) 37 | self.Pages[#self.Pages+1] = Page 38 | end 39 | 40 | function TitlebarMenu:RemovePage(Page) 41 | table.remove(self.Pages, self:GetIDIndex(Page.ID)) 42 | self.ScrollingMenu.CanvasSize = UDim2.new(0,self.ScrollingMenu.CanvasSize.Width.Offset - Page.TabFrame.Size.X.Offset,0,0) 43 | self:FixPageLayout() 44 | end 45 | 46 | function TitlebarMenu:SetActive(ID) 47 | for _, v in pairs(self.Pages) do 48 | v:SetState(v.ID == ID) 49 | end 50 | end 51 | 52 | function TitlebarMenu:FixPageLayout(IgnoreID) 53 | local PreviousPageSize = 0 54 | for _, v in pairs(self.Pages) do 55 | if IgnoreID ~= v.ID then 56 | v.TabFrame.Position = UDim2.new(0,PreviousPageSize,0,0) 57 | end 58 | PreviousPageSize += v.TabFrame.Size.X.Offset 59 | end 60 | end 61 | 62 | function TitlebarMenu:MovePage(ID, Index, IgnoreID) 63 | local PageIndex = self:GetIDIndex(ID) 64 | if PageIndex == Index then return end 65 | local Page = self.Pages[PageIndex] 66 | table.remove(self.Pages, PageIndex) 67 | table.insert(self.Pages, Index, Page) 68 | if IgnoreID then self:FixPageLayout(ID) end 69 | end 70 | 71 | function TitlebarMenu:BeingDragged(ID) 72 | local tab = self:GetIDTab(ID) 73 | local xpos = tab.TabFrame.Position.X.Offset + tab.TabFrame.Size.X.Offset / 2 74 | for i, v in pairs(self.Pages) do 75 | if v.ID ~=ID and xpos >= v.TabFrame.Position.X.Offset and xpos < v.TabFrame.Position.X.Offset + v.TabFrame.Size.X.Offset then 76 | self:MovePage(ID, i, true) 77 | end 78 | end 79 | end 80 | -- ID 81 | function TitlebarMenu.new(Arguments, Parent) 82 | local self = GUIFrame.new(Arguments, Parent) 83 | self.ID = self.Arguments.ID or game:GetService("HttpService"):GenerateGUID(false) 84 | setmetatable(self,TitlebarMenu) 85 | self.TitlebarMenu = Instance.new("Frame", self.Parent) 86 | self.TitlebarMenu.Name = "TitlebarMenu" 87 | self.TitlebarMenu.Size = UDim2.new(1,0,0,24) 88 | ThemeManager.ColorSync(self.TitlebarMenu, "BackgroundColor3", Enum.StudioStyleGuideColor.Titlebar,nil,nil,nil,true) 89 | self.TitlebarMenu.BorderSizePixel = 0 90 | self.ButtonsFrame = Instance.new("Frame", self.TitlebarMenu) 91 | self.ButtonsFrame.Size = UDim2.new(0,0,0,24) 92 | self.ButtonsFrame.ZIndex = 3 93 | ThemeManager.ColorSync(self.ButtonsFrame, "BackgroundColor3", Enum.StudioStyleGuideColor.Titlebar,nil,nil,nil,true) 94 | self.ButtonsFrame.BorderSizePixel = 0 95 | self.ButtonsFrame.Name = "ButtonsFrame" 96 | local ButtonsFrameBorder = Instance.new("Frame", self.ButtonsFrame) 97 | ButtonsFrameBorder.Position = UDim2.new(0,0,1,-1) 98 | ButtonsFrameBorder.Size = UDim2.new(1,0,0,1) 99 | ButtonsFrameBorder.BorderSizePixel = 0 100 | ThemeManager.ColorSync(ButtonsFrameBorder, "BackgroundColor3", Enum.StudioStyleGuideColor.Border,nil,nil,nil,true) 101 | ButtonsFrameBorder.Name = "Border" 102 | ButtonsFrameBorder.ZIndex = 5 103 | self.ButtonContainer = Instance.new("Frame", self.ButtonsFrame) 104 | self.ButtonContainer.BackgroundTransparency = 1 105 | self.ButtonContainer.BorderSizePixel = 0 106 | self.ButtonContainer.Size = UDim2.new(1,0,1,0) 107 | self.ButtonContainer.Name = "ButtonContainer" 108 | local ButtonContainerLayout = Instance.new("UIListLayout", self.ButtonContainer) 109 | ButtonContainerLayout.FillDirection = Enum.FillDirection.Horizontal 110 | ButtonContainerLayout.SortOrder = Enum.SortOrder.LayoutOrder 111 | self.ScrollingMenu = Instance.new("ScrollingFrame", self.TitlebarMenu) 112 | self.ScrollingMenu.BackgroundTransparency = 1 113 | self.ScrollingMenu.Position = UDim2.new(1,0,0,0) 114 | self.ScrollingMenu.AnchorPoint = Vector2.new(1,0) 115 | self.ScrollingMenu.Size = UDim2.new(1,0,1,0) 116 | self.ScrollingMenu.CanvasSize = UDim2.new(0,0,0,0) 117 | self.ScrollingMenu.ScrollBarThickness = 0 118 | self.ScrollingMenu.ScrollingDirection = Enum.ScrollingDirection.X 119 | self.ScrollingMenu.ZIndex = 2 120 | self.ScrollingMenu.ClipsDescendants = false 121 | ButtonContainerLayout.Changed:Connect(function(p) 122 | if p ~= "AbsoluteContentSize" then return end 123 | self.ButtonsFrame.Size = UDim2.new(0,ButtonContainerLayout.AbsoluteContentSize.X, 1,0) 124 | self.ScrollingMenu.Size = UDim2.new(1,-ButtonContainerLayout.AbsoluteContentSize.X,1,0) 125 | end) 126 | self.TabContainer = Instance.new("Frame", self.ScrollingMenu) 127 | self.TabContainer.BackgroundTransparency = 1 128 | self.TabContainer.Size = UDim2.new(1,0,1,0) 129 | self.TabContainer.ZIndex = 2 130 | self.TabContainer.Name = "TabContainer" 131 | --local TabContainerPadding = Instance.new("UIPadding", self.TabContainer) 132 | --TabContainerPadding.PaddingLeft, TabContainerPadding.PaddingRight = UDim.new(0,5), UDim.new(0,5) 133 | local TabContainerBorder = Instance.new("Frame", self.TitlebarMenu) 134 | TabContainerBorder.Name = "Border" 135 | TabContainerBorder.Position = UDim2.new(0,0,1,-1) 136 | TabContainerBorder.Size = UDim2.new(1,0,0,1) 137 | TabContainerBorder.BorderSizePixel = 0 138 | TabContainerBorder.ZIndex = 2 139 | ThemeManager.ColorSync(TabContainerBorder, "BackgroundColor3", Enum.StudioStyleGuideColor.Border) 140 | self.ContentContainers = Instance.new("Frame", self.Parent) 141 | self.ContentContainers.Name = "Content" 142 | self.ContentContainers.BackgroundTransparency = 1 143 | self.ContentContainers.Position = UDim2.new(0,0,0,24) 144 | self.ContentContainers.Size = UDim2.new(1,0,1,-24) 145 | self.Pages = {} 146 | self.Content = self.Parent 147 | GV.PluginTitlebarMenus[#GV.PluginTitlebarMenus+1] = self 148 | return self 149 | end 150 | 151 | return TitlebarMenu -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://github.com/xa1on/rblxguilib) 2 |
5 | 6 | 7 |