From 139ce9b30c08ece54ed6124c7ecf90d3ea018170 Mon Sep 17 00:00:00 2001 From: Lewin Kelly Date: Mon, 24 Apr 2023 07:14:43 +0100 Subject: [PATCH] Re-revert compiled RbxUtil corescript --- processed/45284430.lua | 3913 +++++++++++++++++++++++----------------- 1 file changed, 2294 insertions(+), 1619 deletions(-) diff --git a/processed/45284430.lua b/processed/45284430.lua index f095785..7312973 100644 --- a/processed/45284430.lua +++ b/processed/45284430.lua @@ -1,298 +1,309 @@ -print("[Mercury]: Loaded corescript 45284430") -local t = { } -local New -New = function(className, name, props) - if not (props ~= nil) then - props = name - name = nil - end - local obj = Instance.new(className) - if name then - obj.Name = name - end - local parent - for k, v in pairs(props) do - if type(k) == "string" then - if k == "Parent" then - parent = v - else - obj[k] = v - end - elseif type(k) == "number" and type(v) == "userdata" then - v.Parent = obj - end - end - obj.Parent = parent - return obj -end -local ScopedConnect -ScopedConnect = function(parentInstance, instance, event, signalFunc, syncFunc, removeFunc) - local eventConnection - local tryConnect - tryConnect = function() +local t = {} + +local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc) + local eventConnection = nil + + --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away) + local tryConnect = function() if game:IsAncestorOf(parentInstance) then + --Entering the world, make sure we are connected/synced if not eventConnection then eventConnection = instance[event]:connect(signalFunc) - if syncFunc ~= nil then + if syncFunc then syncFunc() end end + else + --Probably leaving the world, so disconnect for now if eventConnection then eventConnection:disconnect() - if removeFunc ~= nil then - return removeFunc() + if removeFunc then + removeFunc() end - return nil end end end + + --Hook it up to ancestryChanged signal local connection = parentInstance.AncestryChanged:connect(tryConnect) + + --Now connect us if we're already in the world tryConnect() + return connection end -local getScreenGuiAncestor -getScreenGuiAncestor = function(instance) + +local function getScreenGuiAncestor(instance) local localInstance = instance - while localInstance and not localInstance:IsA("ScreenGui") do + while localInstance and not localInstance:IsA "ScreenGui" do localInstance = localInstance.Parent end return localInstance end -local CreateButtons -CreateButtons = function(frame, buttons, yPos, ySize) + +local function CreateButtons(frame, buttons, yPos, ySize) local buttonNum = 1 - local buttonObjs = { } + local buttonObjs = {} for _, obj in ipairs(buttons) do - local button = New("TextButton", "Button" .. tostring(buttonNum), { - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - AutoButtonColor = true, - Modal = true, - Style = (function() - if obj["Style"] then - return obj.Style - else - return Enum.ButtonStyle.RobloxButton - end - end)(), - Text = obj.Text, - TextColor3 = Color3.new(1, 1, 1), - Parent = frame - }) + local button = Instance.new "TextButton" + button.Name = "Button" .. buttonNum + button.Font = Enum.Font.Arial + button.FontSize = Enum.FontSize.Size18 + button.AutoButtonColor = true + button.Modal = true + if obj["Style"] then + button.Style = obj.Style + else + button.Style = Enum.ButtonStyle.RobloxButton + end + button.Text = obj.Text + button.TextColor3 = Color3.new(1, 1, 1) button.MouseButton1Click:connect(obj.Function) + button.Parent = frame buttonObjs[buttonNum] = button + buttonNum = buttonNum + 1 end local numButtons = buttonNum - 1 + if numButtons == 1 then frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(0.4, 0, ySize.Scale, ySize.Offset) elseif numButtons == 2 then frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset) frame.Button1.Size = UDim2.new(0.8 / 3, 0, ySize.Scale, ySize.Offset) + frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset) frame.Button2.Size = UDim2.new(0.35, 0, ySize.Scale, ySize.Offset) elseif numButtons >= 3 then local spacing = 0.1 / numButtons local buttonSize = 0.9 / numButtons + buttonNum = 1 while buttonNum <= numButtons do - buttonObjs[buttonNum].Position = UDim2.new(spacing * buttonNum + buttonSize * (buttonNum - 1), 0, yPos.Scale, yPos.Offset) + buttonObjs[buttonNum].Position = + UDim2.new(spacing * buttonNum + (buttonNum - 1) * buttonSize, 0, yPos.Scale, yPos.Offset) buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset) buttonNum = buttonNum + 1 end end end -local setSliderPos -setSliderPos = function(newAbsPosX, slider, sliderPosition, bar, steps) - local newStep = steps - 1 + +local function setSliderPos(newAbsPosX, slider, sliderPosition, bar, steps) + local newStep = steps - 1 --otherwise we really get one more step than we want local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X)) local wholeNum, remainder = math.modf(relativePosX * newStep) if remainder > 0.5 then wholeNum = wholeNum + 1 end relativePosX = wholeNum / newStep + local result = math.ceil(relativePosX * newStep) - if sliderPosition.Value ~= result + 1 then + if sliderPosition.Value ~= (result + 1) then --only update if we moved a step sliderPosition.Value = result + 1 - slider.Position = UDim2.new(relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset) + slider.Position = + UDim2.new(relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset) end end -local cancelSlide -cancelSlide = function(areaSoak) + +local function cancelSlide(areaSoak) areaSoak.Visible = false - local _obj_0 = areaSoakMouseMoveCon - if _obj_0 ~= nil then - return _obj_0:disconnect() + if areaSoakMouseMoveCon then + areaSoakMouseMoveCon:disconnect() end - return nil end + t.CreateStyledMessageDialog = function(title, message, style, buttons) - local frame = New("Frame", "MessageDialog", { - Size = UDim2.new(0.5, 0, 0, 165), - Position = UDim2.new(0.25, 0, 0.5, -72.5), - Active = true, - Style = Enum.FrameStyle.RobloxRound, - New("ImageLabel", "StyleImage", { - BackgroundTransparency = 1, - Position = UDim2.new(0, 5, 0, 15) - }), - New("TextLabel", "Title", { - Text = title, - TextStrokeTransparency = 0, - BackgroundTransparency = 1, - TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255), - Position = UDim2.new(0, 80, 0, 0), - Size = UDim2.new(1, -80, 0, 40), - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size36, - TextXAlignment = Enum.TextXAlignment.Center, - TextYAlignment = Enum.TextYAlignment.Center - }), - New("TextLabel", "Message", { - Text = message, - TextStrokeTransparency = 0, - TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255), - Position = UDim2.new(0.025, 80, 0, 45), - Size = UDim2.new(0.95, -80, 0, 55), - BackgroundTransparency = 1, - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - TextWrap = true, - TextXAlignment = Enum.TextXAlignment.Left, - TextYAlignment = Enum.TextYAlignment.Top - }) - }) - local StyleImage = frame.StyleImage + local frame = Instance.new "Frame" + frame.Size = UDim2.new(0.5, 0, 0, 165) + frame.Position = UDim2.new(0.25, 0, 0.5, -72.5) + frame.Name = "MessageDialog" + frame.Active = true + frame.Style = Enum.FrameStyle.RobloxRound + + local styleImage = Instance.new "ImageLabel" + styleImage.Name = "StyleImage" + styleImage.BackgroundTransparency = 1 + styleImage.Position = UDim2.new(0, 5, 0, 15) if style == "error" or style == "Error" then - StyleImage.Size = UDim2.new(0, 71, 0, 71) - StyleImage.Image = "http://www.roblox.com/asset?id=42565285" + styleImage.Size = UDim2.new(0, 71, 0, 71) + styleImage.Image = "http://www.roblox.com/asset?id=42565285" elseif style == "notify" or style == "Notify" then - StyleImage.Size = UDim2.new(0, 71, 0, 71) - StyleImage.Image = "http://www.roblox.com/asset?id=42604978" + styleImage.Size = UDim2.new(0, 71, 0, 71) + styleImage.Image = "http://www.roblox.com/asset?id=42604978" elseif style == "confirm" or style == "Confirm" then - StyleImage.Size = UDim2.new(0, 74, 0, 76) - StyleImage.Image = "http://www.roblox.com/asset?id=42557901" + styleImage.Size = UDim2.new(0, 74, 0, 76) + styleImage.Image = "http://www.roblox.com/asset?id=42557901" else return t.CreateMessageDialog(title, message, buttons) end + styleImage.Parent = frame + + local titleLabel = Instance.new "TextLabel" + titleLabel.Name = "Title" + titleLabel.Text = title + titleLabel.TextStrokeTransparency = 0 + titleLabel.BackgroundTransparency = 1 + titleLabel.TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255) + titleLabel.Position = UDim2.new(0, 80, 0, 0) + titleLabel.Size = UDim2.new(1, -80, 0, 40) + titleLabel.Font = Enum.Font.ArialBold + titleLabel.FontSize = Enum.FontSize.Size36 + titleLabel.TextXAlignment = Enum.TextXAlignment.Center + titleLabel.TextYAlignment = Enum.TextYAlignment.Center + titleLabel.Parent = frame + + local messageLabel = Instance.new "TextLabel" + messageLabel.Name = "Message" + messageLabel.Text = message + messageLabel.TextStrokeTransparency = 0 + messageLabel.TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255) + messageLabel.Position = UDim2.new(0.025, 80, 0, 45) + messageLabel.Size = UDim2.new(0.95, -80, 0, 55) + messageLabel.BackgroundTransparency = 1 + messageLabel.Font = Enum.Font.Arial + messageLabel.FontSize = Enum.FontSize.Size18 + messageLabel.TextWrap = true + messageLabel.TextXAlignment = Enum.TextXAlignment.Left + messageLabel.TextYAlignment = Enum.TextYAlignment.Top + messageLabel.Parent = frame + CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40)) + return frame end + t.CreateMessageDialog = function(title, message, buttons) - local frame = New("Frame", "MessageDialog", { - Size = UDim2.new(0.5, 0, 0.5, 0), - Position = UDim2.new(0.25, 0, 0.25, 0), - Active = true, - Style = Enum.FrameStyle.RobloxRound, - Parent = script.Parent, - New("TextLabel", "Title", { - Text = title, - BackgroundTransparency = 1, - TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255), - Position = UDim2.new(0, 0, 0, 0), - Size = UDim2.new(1, 0, 0.15, 0), - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size36, - TextXAlignment = Enum.TextXAlignment.Center, - TextYAlignment = Enum.TextYAlignment.Center - }), - New("TextLabel", "Message", { - Text = message, - TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255), - Position = UDim2.new(0.025, 0, 0.175, 0), - Size = UDim2.new(0.95, 0, 0.55, 0), - BackgroundTransparency = 1, - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - TextWrap = true, - TextXAlignment = Enum.TextXAlignment.Left, - TextYAlignment = Enum.TextYAlignment.Top - }) - }) + local frame = Instance.new "Frame" + frame.Size = UDim2.new(0.5, 0, 0.5, 0) + frame.Position = UDim2.new(0.25, 0, 0.25, 0) + frame.Name = "MessageDialog" + frame.Active = true + frame.Style = Enum.FrameStyle.RobloxRound + + local titleLabel = Instance.new "TextLabel" + titleLabel.Name = "Title" + titleLabel.Text = title + titleLabel.BackgroundTransparency = 1 + titleLabel.TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255) + titleLabel.Position = UDim2.new(0, 0, 0, 0) + titleLabel.Size = UDim2.new(1, 0, 0.15, 0) + titleLabel.Font = Enum.Font.ArialBold + titleLabel.FontSize = Enum.FontSize.Size36 + titleLabel.TextXAlignment = Enum.TextXAlignment.Center + titleLabel.TextYAlignment = Enum.TextYAlignment.Center + titleLabel.Parent = frame + + local messageLabel = Instance.new "TextLabel" + messageLabel.Name = "Message" + messageLabel.Text = message + messageLabel.TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255) + messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0) + messageLabel.Size = UDim2.new(0.95, 0, 0.55, 0) + messageLabel.BackgroundTransparency = 1 + messageLabel.Font = Enum.Font.Arial + messageLabel.FontSize = Enum.FontSize.Size18 + messageLabel.TextWrap = true + messageLabel.TextXAlignment = Enum.TextXAlignment.Left + messageLabel.TextYAlignment = Enum.TextYAlignment.Top + messageLabel.Parent = frame + CreateButtons(frame, buttons, UDim.new(0.8, 0), UDim.new(0.15, 0)) + return frame end + t.CreateDropDownMenu = function(items, onSelect, forRoblox) local width = UDim.new(0, 100) local height = UDim.new(0, 32) + + local frame = Instance.new "Frame" + frame.Name = "DropDownMenu" + frame.BackgroundTransparency = 1 + frame.Size = UDim2.new(width, height) + + local dropDownMenu = Instance.new "TextButton" + dropDownMenu.Name = "DropDownMenuButton" + dropDownMenu.TextWrap = true + dropDownMenu.TextColor3 = Color3.new(1, 1, 1) + dropDownMenu.Text = "Choose One" + dropDownMenu.Font = Enum.Font.ArialBold + dropDownMenu.FontSize = Enum.FontSize.Size18 + dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left + dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center + dropDownMenu.BackgroundTransparency = 1 + dropDownMenu.AutoButtonColor = true + dropDownMenu.Style = Enum.ButtonStyle.RobloxButton + dropDownMenu.Size = UDim2.new(1, 0, 1, 0) + dropDownMenu.Parent = frame + dropDownMenu.ZIndex = 2 + + local dropDownIcon = Instance.new "ImageLabel" + dropDownIcon.Name = "Icon" + dropDownIcon.Active = false + dropDownIcon.Image = "http://www.roblox.com/asset/?id=45732894" + dropDownIcon.BackgroundTransparency = 1 + dropDownIcon.Size = UDim2.new(0, 11, 0, 6) + dropDownIcon.Position = UDim2.new(1, -11, 0.5, -2) + dropDownIcon.Parent = dropDownMenu + dropDownIcon.ZIndex = 2 + local itemCount = #items - local dropDownItemCount = itemCount + local dropDownItemCount = #items local useScrollButtons = false if dropDownItemCount > 6 then useScrollButtons = true dropDownItemCount = 6 end - local frame = New("Frame", "DropDownMenu", { - BackgroundTransparency = 1, - Size = UDim2.new(width, height), - New("TextButton", "List", { - Text = "", - BackgroundTransparency = 1, - Style = Enum.ButtonStyle.RobloxButton, - Visible = false, - Active = true, - Position = UDim2.new(0, 0, 0, 0), - Size = UDim2.new(1, 0, (1 + dropDownItemCount) * 0.8, 0), - ZIndex = 2 - }), - New("TextButton", "DropDownMenuButton", { - TextWrap = true, - TextColor3 = Color3.new(1, 1, 1), - Text = "Choose One", - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size18, - TextXAlignment = Enum.TextXAlignment.Left, - TextYAlignment = Enum.TextYAlignment.Center, - BackgroundTransparency = 1, - AutoButtonColor = true, - Style = Enum.ButtonStyle.RobloxButton, - Size = UDim2.new(1, 0, 1, 0), - ZIndex = 2, - New("ImageLabel", "Icon", { - Active = false, - Image = "http://www.roblox.com/asset/?id=45732894", - BackgroundTransparency = 1, - Size = UDim2.new(0, 11, 0, 6), - Position = UDim2.new(1, -11, 0.5, -2), - ZIndex = 2 - }) - }) - }) - local dropDownMenu, droppedDownMenu = frame.DropDownMenuButton, frame.List - local choiceButton = New("TextButton", "ChoiceButton", { - BackgroundTransparency = 1, - BorderSizePixel = 0, - Text = "ReplaceMe", - TextColor3 = Color3.new(1, 1, 1), - TextXAlignment = Enum.TextXAlignment.Left, - TextYAlignment = Enum.TextYAlignment.Center, - BackgroundColor3 = Color3.new(1, 1, 1), - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - Size = UDim2.new((function() - if useScrollButtons then - return 1, -13, 0.8 / ((dropDownItemCount + 1) * 0.8), 0 - else - return 1, 0, 0.8 / ((dropDownItemCount + 1) * 0.8), 0 - end - end)()), - TextWrap = true, - ZIndex = 2 - }) - local areaSoak = New("TextButton", "AreaSoak", { - Text = "", - BackgroundTransparency = 1, - Active = true, - Size = UDim2.new(1, 0, 1, 0), - Visible = false, - ZIndex = 3 - }) + + local droppedDownMenu = Instance.new "TextButton" + droppedDownMenu.Name = "List" + droppedDownMenu.Text = "" + droppedDownMenu.BackgroundTransparency = 1 + --droppedDownMenu.AutoButtonColor = true + droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton + droppedDownMenu.Visible = false + droppedDownMenu.Active = true --Blocks clicks + droppedDownMenu.Position = UDim2.new(0, 0, 0, 0) + droppedDownMenu.Size = UDim2.new(1, 0, (1 + dropDownItemCount) * 0.8, 0) + droppedDownMenu.Parent = frame + droppedDownMenu.ZIndex = 2 + + local choiceButton = Instance.new "TextButton" + choiceButton.Name = "ChoiceButton" + choiceButton.BackgroundTransparency = 1 + choiceButton.BorderSizePixel = 0 + choiceButton.Text = "ReplaceMe" + choiceButton.TextColor3 = Color3.new(1, 1, 1) + choiceButton.TextXAlignment = Enum.TextXAlignment.Left + choiceButton.TextYAlignment = Enum.TextYAlignment.Center + choiceButton.BackgroundColor3 = Color3.new(1, 1, 1) + choiceButton.Font = Enum.Font.Arial + choiceButton.FontSize = Enum.FontSize.Size18 + if useScrollButtons then + choiceButton.Size = UDim2.new(1, -13, 0.8 / ((dropDownItemCount + 1) * 0.8), 0) + else + choiceButton.Size = UDim2.new(1, 0, 0.8 / ((dropDownItemCount + 1) * 0.8), 0) + end + choiceButton.TextWrap = true + choiceButton.ZIndex = 2 + + local areaSoak = Instance.new "TextButton" + areaSoak.Name = "AreaSoak" + areaSoak.Text = "" + areaSoak.BackgroundTransparency = 1 + areaSoak.Active = true + areaSoak.Size = UDim2.new(1, 0, 1, 0) + areaSoak.Visible = false + areaSoak.ZIndex = 3 + local dropDownSelected = false - local scrollUpButton, scrollDownButton + + local scrollUpButton + local scrollDownButton local scrollMouseCount = 0 - local setZIndex - setZIndex = function(baseZIndex) + + local setZIndex = function(baseZIndex) droppedDownMenu.ZIndex = baseZIndex + 1 if scrollUpButton then scrollUpButton.ZIndex = baseZIndex + 3 @@ -300,6 +311,7 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) if scrollDownButton then scrollDownButton.ZIndex = baseZIndex + 3 end + local children = droppedDownMenu:GetChildren() if children then for _, child in ipairs(children) do @@ -311,37 +323,41 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) end end end + local scrollBarPosition = 1 - local updateScroll - updateScroll = function() + local updateScroll = function() if scrollUpButton then scrollUpButton.Active = scrollBarPosition > 1 end if scrollDownButton then scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount end + local children = droppedDownMenu:GetChildren() if not children then return end + local childNum = 1 for _, obj in ipairs(children) do if obj.Name == "ChoiceButton" then if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then obj.Visible = false else - obj.Position = UDim2.new(0, 0, ((childNum - scrollBarPosition + 1) * 0.8) / ((dropDownItemCount + 1) * 0.8), 0) + obj.Position = + UDim2.new(0, 0, ((childNum - scrollBarPosition + 1) * 0.8) / ((dropDownItemCount + 1) * 0.8), 0) obj.Visible = true end obj.TextColor3 = Color3.new(1, 1, 1) obj.BackgroundTransparency = 1 + childNum = childNum + 1 end end end - local toggleVisibility - toggleVisibility = function() + local toggleVisibility = function() dropDownSelected = not dropDownSelected + areaSoak.Visible = not areaSoak.Visible dropDownMenu.Visible = not dropDownSelected droppedDownMenu.Visible = dropDownSelected @@ -351,12 +367,12 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) setZIndex(2) end if useScrollButtons then - return updateScroll() + updateScroll() end end droppedDownMenu.MouseButton1Click:connect(toggleVisibility) - local updateSelection - updateSelection = function(text) + + local updateSelection = function(text) local foundItem = false local children = droppedDownMenu:GetChildren() local childNum = 1 @@ -381,14 +397,16 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) if not foundItem then error("Invalid Selection Update -- " .. text) end + if scrollBarPosition + dropDownItemCount > itemCount + 1 then scrollBarPosition = itemCount - dropDownItemCount + 1 end + dropDownMenu.Text = text end end - local scrollDown - scrollDown = function() + + local function scrollDown() if scrollBarPosition + dropDownItemCount <= itemCount then scrollBarPosition = scrollBarPosition + 1 updateScroll() @@ -396,8 +414,7 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) end return false end - local scrollUp - scrollUp = function() + local function scrollUp() if scrollBarPosition > 1 then scrollBarPosition = scrollBarPosition - 1 updateScroll() @@ -405,22 +422,24 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) end return false end + if useScrollButtons then - scrollUpButton = New("ImageButton", "ScrollUpButton", { - BackgroundTransparency = 1, - Image = "rbxasset://textures/ui/scrollbuttonUp.png", - Size = UDim2.new(0, 17, 0, 17), - Position = UDim2.new(1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 0), - Parent = droppedDownMenu - }) - local incScrollMouseCount - incScrollMouseCount = function() + --Make some scroll buttons + scrollUpButton = Instance.new "ImageButton" + scrollUpButton.Name = "ScrollUpButton" + scrollUpButton.BackgroundTransparency = 1 + scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" + scrollUpButton.Size = UDim2.new(0, 17, 0, 17) + scrollUpButton.Position = UDim2.new(1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 0) + scrollUpButton.MouseButton1Click:connect(function() scrollMouseCount = scrollMouseCount + 1 - end - scrollUpButton.MouseButton1Click:connect(incScrollMouseCount) - scrollUpButton.MouseLeave:connect(incScrollMouseCount) + end) + scrollUpButton.MouseLeave:connect(function() + scrollMouseCount = scrollMouseCount + 1 + end) scrollUpButton.MouseButton1Down:connect(function() scrollMouseCount = scrollMouseCount + 1 + scrollUp() local val = scrollMouseCount wait(0.5) @@ -431,17 +450,25 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) wait(0.1) end end) - scrollDownButton = New("ImageButton", "ScrollDownButton", { - BackgroundTransparency = 1, - Image = "rbxasset://textures/ui/scrollbuttonDown.png", - Size = UDim2.new(0, 17, 0, 17), - Position = UDim2.new(1, -11, 1, -11), - Parent = droppedDownMenu - }) - scrollDownButton.MouseButton1Click:connect(incScrollMouseCount) - scrollDownButton.MouseLeave:connect(incScrollMouseCount) + + scrollUpButton.Parent = droppedDownMenu + + scrollDownButton = Instance.new "ImageButton" + scrollDownButton.Name = "ScrollDownButton" + scrollDownButton.BackgroundTransparency = 1 + scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" + scrollDownButton.Size = UDim2.new(0, 17, 0, 17) + scrollDownButton.Position = UDim2.new(1, -11, 1, -11) + scrollDownButton.Parent = droppedDownMenu + scrollDownButton.MouseButton1Click:connect(function() + scrollMouseCount = scrollMouseCount + 1 + end) + scrollDownButton.MouseLeave:connect(function() + scrollMouseCount = scrollMouseCount + 1 + end) scrollDownButton.MouseButton1Down:connect(function() scrollMouseCount = scrollMouseCount + 1 + scrollDown() local val = scrollMouseCount wait(0.5) @@ -452,15 +479,18 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) wait(0.1) end end) - New("ImageLabel", "ScrollBar", { - Image = "rbxasset://textures/ui/scrollbar.png", - BackgroundTransparency = 1, - Size = UDim2.new(0, 18, (dropDownItemCount * 0.8) / ((dropDownItemCount + 1) * 0.8), -17 - 11 - 4), - Position = UDim2.new(1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 17 + 2), - Parent = droppedDownMenu - }) + + local scrollbar = Instance.new "ImageLabel" + scrollbar.Name = "ScrollBar" + scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" + scrollbar.BackgroundTransparency = 1 + scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount * 0.8) / ((dropDownItemCount + 1) * 0.8), -17 - 11 - 4) + scrollbar.Position = UDim2.new(1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 17 + 2) + scrollbar.Parent = droppedDownMenu end + for _, item in ipairs(items) do + -- needed to maintain local scope for items in event listeners below local button = choiceButton:clone() if forRoblox then button.RobloxLocked = true @@ -468,161 +498,199 @@ t.CreateDropDownMenu = function(items, onSelect, forRoblox) button.Text = item button.Parent = droppedDownMenu button.MouseButton1Click:connect(function() + --Remove Highlight button.TextColor3 = Color3.new(1, 1, 1) button.BackgroundTransparency = 1 + updateSelection(item) onSelect(item) - return toggleVisibility() + + toggleVisibility() end) button.MouseEnter:connect(function() + --Add Highlight button.TextColor3 = Color3.new(0, 0, 0) button.BackgroundTransparency = 0 end) + button.MouseLeave:connect(function() + --Remove Highlight button.TextColor3 = Color3.new(1, 1, 1) button.BackgroundTransparency = 1 end) end + + --This does the initial layout of the buttons updateScroll() + frame.AncestryChanged:connect(function(_, parent) - if not (parent ~= nil) then + if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(frame) end end) + dropDownMenu.MouseButton1Click:connect(toggleVisibility) areaSoak.MouseButton1Click:connect(toggleVisibility) return frame, updateSelection end + t.CreatePropertyDropDownMenu = function(instance, property, enum) local items = enum:GetEnumItems() - local names = { } - local nameToItem = { } + local names = {} + local nameToItem = {} for i, obj in ipairs(items) do names[i] = obj.Name nameToItem[obj.Name] = obj end - local frame, updateSelection = t.CreateDropDownMenu(names, function(text) + + local frame + local updateSelection + frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end) - local t1 - t1 = function(prop) + + ScopedConnect(frame, instance, "Changed", function(prop) if prop == property then - return updateSelection(instance[property].Name) + updateSelection(instance[property].Name) end - end - local t2 - t2 = function() - return updateSelection(instance[property].Name) - end - ScopedConnect(frame, instance, "Changed", t1, t2) + end, function() + updateSelection(instance[property].Name) + end) + return frame end + t.GetFontHeight = function(font, fontSize) - if not ((font ~= nil) and (fontSize ~= nil)) then - error("Font and FontSize must be non-nil") + if font == nil or fontSize == nil then + error "Font and FontSize must be non-nil" end + if font == Enum.Font.Legacy then - if Enum.FontSize.Size8 == fontSize then + if fontSize == Enum.FontSize.Size8 then return 12 - elseif Enum.FontSize.Size9 == fontSize then + elseif fontSize == Enum.FontSize.Size9 then return 14 - elseif Enum.FontSize.Size10 == fontSize then + elseif fontSize == Enum.FontSize.Size10 then return 15 - elseif Enum.FontSize.Size11 == fontSize then + elseif fontSize == Enum.FontSize.Size11 then return 17 - elseif Enum.FontSize.Size12 == fontSize then + elseif fontSize == Enum.FontSize.Size12 then return 18 - elseif Enum.FontSize.Size14 == fontSize then + elseif fontSize == Enum.FontSize.Size14 then return 21 - elseif Enum.FontSize.Size18 == fontSize then + elseif fontSize == Enum.FontSize.Size18 then return 27 - elseif Enum.FontSize.Size24 == fontSize then + elseif fontSize == Enum.FontSize.Size24 then return 36 - elseif Enum.FontSize.Size36 == fontSize then + elseif fontSize == Enum.FontSize.Size36 then return 54 - elseif Enum.FontSize.Size48 == fontSize then + elseif fontSize == Enum.FontSize.Size48 then return 72 else - return error("Unknown FontSize") + error "Unknown FontSize" end elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then - if Enum.FontSize.Size8 == fontSize then + if fontSize == Enum.FontSize.Size8 then return 8 - elseif Enum.FontSize.Size9 == fontSize then + elseif fontSize == Enum.FontSize.Size9 then return 9 - elseif Enum.FontSize.Size10 == fontSize then + elseif fontSize == Enum.FontSize.Size10 then return 10 - elseif Enum.FontSize.Size11 == fontSize then + elseif fontSize == Enum.FontSize.Size11 then return 11 - elseif Enum.FontSize.Size12 == fontSize then + elseif fontSize == Enum.FontSize.Size12 then return 12 - elseif Enum.FontSize.Size14 == fontSize then + elseif fontSize == Enum.FontSize.Size14 then return 14 - elseif Enum.FontSize.Size18 == fontSize then + elseif fontSize == Enum.FontSize.Size18 then return 18 - elseif Enum.FontSize.Size24 == fontSize then + elseif fontSize == Enum.FontSize.Size24 then return 24 - elseif Enum.FontSize.Size36 == fontSize then + elseif fontSize == Enum.FontSize.Size36 then return 36 - elseif Enum.FontSize.Size48 == fontSize then + elseif fontSize == Enum.FontSize.Size48 then return 48 else - return error("Unknown FontSize") + error "Unknown FontSize" end else - return error("Unknown Font " .. tostring(font)) + error("Unknown Font " .. font) end end -local layoutGuiObjectsHelper -layoutGuiObjectsHelper = function(frame, guiObjects, settingsTable) + +local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable) local totalPixels = frame.AbsoluteSize.Y - local pixelsRemaining = totalPixels + local pixelsRemaining = frame.AbsoluteSize.Y for _, child in ipairs(guiObjects) do - if child:IsA("TextLabel") or child:IsA("TextButton") then - local isLabel = child:IsA("TextLabel") - local settingsTableIndex = "Text" .. tostring((function() - if isLabel then - return "Label" - else - return "Button" - end - end)()) .. "PositionPadY" - pixelsRemaining = pixelsRemaining - settingsTable[settingsTableIndex] - child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) + if child:IsA "TextLabel" or child:IsA "TextButton" then + local isLabel = child:IsA "TextLabel" + if isLabel then + pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] + else + pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] + end + child.Position = + UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining) + if child.TextFits and child.TextBounds.Y < pixelsRemaining then child.Visible = true - child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[settingsTableIndex]) + if isLabel then + child.Size = UDim2.new( + child.Size.X.Scale, + child.Size.X.Offset, + 0, + child.TextBounds.Y + settingsTable["TextLabelSizePadY"] + ) + else + child.Size = UDim2.new( + child.Size.X.Scale, + child.Size.X.Offset, + 0, + child.TextBounds.Y + settingsTable["TextButtonSizePadY"] + ) + end + while not child.TextFits do child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1) end pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y - pixelsRemaining = pixelsRemaining - settingsTable[settingsTableIndex] + + if isLabel then + pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"] + else + pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"] + end else child.Visible = false pixelsRemaining = -1 end else - child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) + --GuiObject + child.Position = + UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y - child.Visible = pixelsRemaining >= 0 + child.Visible = (pixelsRemaining >= 0) end end end + t.LayoutGuiObjects = function(frame, guiObjects, settingsTable) - if not frame:IsA("GuiObject") then - error("Frame must be a GuiObject") + if not frame:IsA "GuiObject" then + error "Frame must be a GuiObject" end for _, child in ipairs(guiObjects) do - if not child:IsA("GuiObject") then - error("All elements that are layed out must be of type GuiObject") + if not child:IsA "GuiObject" then + error "All elements that are layed out must be of type GuiObject" end end + if not settingsTable then - settingsTable = { } + settingsTable = {} end + if not settingsTable["TextLabelSizePadY"] then settingsTable["TextLabelSizePadY"] = 0 end @@ -635,174 +703,195 @@ t.LayoutGuiObjects = function(frame, guiObjects, settingsTable) if not settingsTable["TextButtonPositionPadY"] then settingsTable["TextButtonPositionPadY"] = 2 end - local wrapperFrame = New("Frame", "WrapperFrame", { - BackgroundTransparency = 1, - Size = UDim2.new(1, 0, 1, 0), - Parent = frame - }) + + --Wrapper frame takes care of styled objects + local wrapperFrame = Instance.new "Frame" + wrapperFrame.Name = "WrapperFrame" + wrapperFrame.BackgroundTransparency = 1 + wrapperFrame.Size = UDim2.new(1, 0, 1, 0) + wrapperFrame.Parent = frame + for _, child in ipairs(guiObjects) do child.Parent = wrapperFrame end - local recalculate - recalculate = function() + + local recalculate = function() wait() - return layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) + layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) end + frame.Changed:connect(function(prop) if prop == "AbsoluteSize" then - return recalculate(nil) + --Wait a heartbeat for it to sync in + recalculate(nil) end end) frame.AncestryChanged:connect(recalculate) - return layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) + + layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable) end + t.CreateSlider = function(steps, width, position) - local sliderGui = New("Frame", "SliderGui", { - Size = UDim2.new(1, 0, 1, 0), - BackgroundTransparency = 1, - New("IntValue", "SliderSteps", { - Value = steps - }), - New("IntValue", "SliderPosition", { - Value = 0 - }), - New("TextButton", "Bar", { - Text = "", - AutoButtonColor = false, - BackgroundColor3 = Color3.new(0, 0, 0), - Size = UDim2.new(0, (function() - if type(width) == "number" then - return width - else - return 200 - end - end)(), 0, 5), - BorderColor3 = Color3.new(95 / 255, 95 / 255, 95 / 255), - ZIndex = 2, - New("ImageButton", "Slider", { - BackgroundTransparency = 1, - Image = "rbxasset://textures/ui/Slider.png", - Position = UDim2.new(0, 0, 0.5, -10), - Size = UDim2.new(0, 20, 0, 20), - ZIndex = 3 - }) - }) - }) - local areaSoak = New("TextButton", "AreaSoak", { - Text = "", - BackgroundTransparency = 1, - Active = false, - Size = UDim2.new(1, 0, 1, 0), - Visible = false, - ZIndex = 4 - }) - local slider, bar, sliderPosition, sliderSteps = sliderGui.Bar.Slider, sliderGui.Bar, sliderGui.SliderPosition, sliderGui.SliderSteps + local sliderGui = Instance.new "Frame" + sliderGui.Size = UDim2.new(1, 0, 1, 0) + sliderGui.BackgroundTransparency = 1 + sliderGui.Name = "SliderGui" + + local sliderSteps = Instance.new "IntValue" + sliderSteps.Name = "SliderSteps" + sliderSteps.Value = steps + sliderSteps.Parent = sliderGui + + local areaSoak = Instance.new "TextButton" + areaSoak.Name = "AreaSoak" + areaSoak.Text = "" + areaSoak.BackgroundTransparency = 1 + areaSoak.Active = false + areaSoak.Size = UDim2.new(1, 0, 1, 0) + areaSoak.Visible = false + areaSoak.ZIndex = 4 + sliderGui.AncestryChanged:connect(function(_, parent) - if not (parent ~= nil) then + if parent == nil then areaSoak.Parent = nil else areaSoak.Parent = getScreenGuiAncestor(sliderGui) end end) - if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then + + local sliderPosition = Instance.new "IntValue" + sliderPosition.Name = "SliderPosition" + sliderPosition.Value = 0 + sliderPosition.Parent = sliderGui + + local bar = Instance.new "TextButton" + bar.Text = "" + bar.AutoButtonColor = false + bar.Name = "Bar" + bar.BackgroundColor3 = Color3.new(0, 0, 0) + if type(width) == "number" then + bar.Size = UDim2.new(0, width, 0, 5) + else + bar.Size = UDim2.new(0, 200, 0, 5) + end + bar.BorderColor3 = Color3.new(95 / 255, 95 / 255, 95 / 255) + bar.ZIndex = 2 + bar.Parent = sliderGui + + if + position["X"] + and position["X"]["Scale"] + and position["X"]["Offset"] + and position["Y"] + and position["Y"]["Scale"] + and position["Y"]["Offset"] + then bar.Position = position end - local areaSoakMouseMoveCon + + local slider = Instance.new "ImageButton" + slider.Name = "Slider" + slider.BackgroundTransparency = 1 + slider.Image = "rbxasset://textures/ui/Slider.png" + slider.Position = UDim2.new(0, 0, 0.5, -10) + slider.Size = UDim2.new(0, 20, 0, 20) + slider.ZIndex = 3 + slider.Parent = bar + + local areaSoakMouseMoveCon = nil + areaSoak.MouseLeave:connect(function() if areaSoak.Visible then - return cancelSlide(areaSoak) + cancelSlide(areaSoak) end end) areaSoak.MouseButton1Up:connect(function() if areaSoak.Visible then - return cancelSlide(areaSoak) + cancelSlide(areaSoak) end end) + slider.MouseButton1Down:connect(function() areaSoak.Visible = true - if areaSoakMouseMoveCon ~= nil then + if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x, _) - return setSliderPos(x, slider, sliderPosition, bar, steps) + setSliderPos(x, slider, sliderPosition, bar, steps) end) end) + slider.MouseButton1Up:connect(function() - return cancelSlide(areaSoak) + cancelSlide(areaSoak) end) + sliderPosition.Changed:connect(function(_) sliderPosition.Value = math.min(steps, math.max(1, sliderPosition.Value)) local relativePosX = (sliderPosition.Value - 1) / (steps - 1) - slider.Position = UDim2.new(relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset) + slider.Position = + UDim2.new(relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset) end) + bar.MouseButton1Down:connect(function(x, _) - return setSliderPos(x, slider, sliderPosition, bar, steps) + setSliderPos(x, slider, sliderPosition, bar, steps) end) + return sliderGui, sliderPosition, sliderSteps end + t.CreateTrueScrollingFrame = function() - local lowY, highY - local dragCon, upCon + local lowY = nil + local highY = nil + + local dragCon = nil + local upCon = nil + local internalChange = false - local desantsChangeConMap = { } - local scrollingFrame = New("Frame", "ScrollingFrame", { - Active = true, - Size = UDim2.new(1, 0, 1, 0), - ClipsDesants = true, - New("Frame", "ControlFrame", { - BackgroundTransparency = 1, - Size = UDim2.new(0, 18, 1, 0), - Position = UDim2.new(1, -20, 0, 0), - New("BoolValue", "ScrollBottom", { - Value = false - }), - New("BoolValue", "scrollUp", { - Value = false - }), - New("TextButton", "ScrollUpButton", { - Text = "", - AutoButtonColor = false, - BackgroundColor3 = Color3.new(0, 0, 0), - BorderColor3 = Color3.new(1, 1, 1), - BackgroundTransparency = 0.5, - Size = UDim2.new(0, 18, 0, 18), - ZIndex = 2 - }), - New("Frame", "ScrollTrack", { - BackgroundTransparency = 1, - Size = UDim2.new(0, 18, 1, -38), - Position = UDim2.new(0, 0, 0, 19), - New("TextButton", "ScrollBar", { - BackgroundColor3 = Color3.new(0, 0, 0), - BorderColor3 = Color3.new(1, 1, 1), - BackgroundTransparency = 0.5, - AutoButtonColor = false, - Text = "", - Active = true, - ZIndex = 2, - Size = UDim2.new(0, 18, 0.1, 0), - Position = UDim2.new(0, 0, 0, 0), - New("Frame", "ScrollNub", { - BorderColor3 = Color3.new(1, 1, 1), - Size = UDim2.new(0, 10, 0, 0), - Position = UDim2.new(0.5, -5, 0.5, 0), - ZIndex = 2, - BackgroundTransparency = 0.5 - }) - }) - }) - }) - }) - local controlFrame, scrollBottom, scrollUp, scrollUpButton, scrollTrack, scrollbar, scrollNub = scrollingFrame.ControlFrame, scrollingFrame.ControlFrame.ScrollBottom, scrollingFrame.ControlFrame.ScrollUp, scrollingFrame.ControlFrame.ScrollUpButton, scrollingFrame.ControlFrame.ScrollTrack, scrollingFrame.ControlFrame.ScrollTrack.ScrollBar, scrollingFrame.ControlFrame.ScrollTrack.ScrollBar.ScrollNub + + local descendantsChangeConMap = {} + + local scrollingFrame = Instance.new "Frame" + scrollingFrame.Name = "ScrollingFrame" + scrollingFrame.Active = true + scrollingFrame.Size = UDim2.new(1, 0, 1, 0) + scrollingFrame.ClipsDescendants = true + + local controlFrame = Instance.new "Frame" + controlFrame.Name = "ControlFrame" + controlFrame.BackgroundTransparency = 1 + controlFrame.Size = UDim2.new(0, 18, 1, 0) + controlFrame.Position = UDim2.new(1, -20, 0, 0) + controlFrame.Parent = scrollingFrame + + local scrollBottom = Instance.new "BoolValue" + scrollBottom.Value = false + scrollBottom.Name = "ScrollBottom" + scrollBottom.Parent = controlFrame + + local scrollUp = Instance.new "BoolValue" + scrollUp.Value = false + scrollUp.Name = "scrollUp" + scrollUp.Parent = controlFrame + + local scrollUpButton = Instance.new "TextButton" + scrollUpButton.Name = "ScrollUpButton" + scrollUpButton.Text = "" + scrollUpButton.AutoButtonColor = false + scrollUpButton.BackgroundColor3 = Color3.new(0, 0, 0) + scrollUpButton.BorderColor3 = Color3.new(1, 1, 1) + scrollUpButton.BackgroundTransparency = 0.5 + scrollUpButton.Size = UDim2.new(0, 18, 0, 18) + scrollUpButton.ZIndex = 2 + scrollUpButton.Parent = controlFrame for i = 1, 6 do - New("Frame", "tri" .. tostring(i), { - BorderColor3 = Color3.new(1, 1, 1), - ZIndex = 3, - BackgroundTransparency = 0.5, - Size = UDim2.new(0, 12 - ((i - 1) * 2), 0, 0), - Position = UDim2.new(0, 3 + (i - 1), 0.5, 2 - (i - 1)), - Parent = scrollUpButton - }) + local triFrame = Instance.new "Frame" + triFrame.BorderColor3 = Color3.new(1, 1, 1) + triFrame.Name = "tri" .. tostring(i) + triFrame.ZIndex = 3 + triFrame.BackgroundTransparency = 0.5 + triFrame.Size = UDim2.new(0, 12 - ((i - 1) * 2), 0, 0) + triFrame.Position = UDim2.new(0, 3 + (i - 1), 0.5, 2 - (i - 1)) + triFrame.Parent = scrollUpButton end scrollUpButton.MouseEnter:connect(function() scrollUpButton.BackgroundTransparency = 0.1 @@ -818,36 +907,68 @@ t.CreateTrueScrollingFrame = function() upChildren[i].BackgroundTransparency = 0.5 end end) + local scrollDownButton = scrollUpButton:clone() - do - scrollDownButton.Name = "ScrollDownButton" - scrollDownButton.Position = UDim2.new(0, 0, 1, -18) + scrollDownButton.Name = "ScrollDownButton" + scrollDownButton.Position = UDim2.new(0, 0, 1, -18) + local downChildren = scrollDownButton:GetChildren() + for i = 1, #downChildren do + downChildren[i].Position = UDim2.new(0, 3 + (i - 1), 0.5, -2 + (i - 1)) + end + scrollDownButton.MouseEnter:connect(function() + scrollDownButton.BackgroundTransparency = 0.1 local downChildren = scrollDownButton:GetChildren() for i = 1, #downChildren do - downChildren[i].Position = UDim2.new(0, 3 + (i - 1), 0.5, -2 + (i - 1)) + downChildren[i].BackgroundTransparency = 0.1 end - scrollDownButton.MouseEnter:connect(function() - scrollDownButton.BackgroundTransparency = 0.1 - downChildren = scrollDownButton:GetChildren() - for i = 1, #downChildren do - downChildren[i].BackgroundTransparency = 0.1 - end - end) - scrollDownButton.MouseLeave:connect(function() - scrollDownButton.BackgroundTransparency = 0.5 - downChildren = scrollDownButton:GetChildren() - for i = 1, #downChildren do - downChildren[i].BackgroundTransparency = 0.5 - end - end) - scrollDownButton.Parent = controlFrame - end + end) + scrollDownButton.MouseLeave:connect(function() + scrollDownButton.BackgroundTransparency = 0.5 + local downChildren = scrollDownButton:GetChildren() + for i = 1, #downChildren do + downChildren[i].BackgroundTransparency = 0.5 + end + end) + scrollDownButton.Parent = controlFrame + + local scrollTrack = Instance.new "Frame" + scrollTrack.Name = "ScrollTrack" + scrollTrack.BackgroundTransparency = 1 + scrollTrack.Size = UDim2.new(0, 18, 1, -38) + scrollTrack.Position = UDim2.new(0, 0, 0, 19) + scrollTrack.Parent = controlFrame + + local scrollbar = Instance.new "TextButton" + scrollbar.BackgroundColor3 = Color3.new(0, 0, 0) + scrollbar.BorderColor3 = Color3.new(1, 1, 1) + scrollbar.BackgroundTransparency = 0.5 + scrollbar.AutoButtonColor = false + scrollbar.Text = "" + scrollbar.Active = true + scrollbar.Name = "ScrollBar" + scrollbar.ZIndex = 2 + scrollbar.BackgroundTransparency = 0.5 + scrollbar.Size = UDim2.new(0, 18, 0.1, 0) + scrollbar.Position = UDim2.new(0, 0, 0, 0) + scrollbar.Parent = scrollTrack + + local scrollNub = Instance.new "Frame" + scrollNub.Name = "ScrollNub" + scrollNub.BorderColor3 = Color3.new(1, 1, 1) + scrollNub.Size = UDim2.new(0, 10, 0, 0) + scrollNub.Position = UDim2.new(0.5, -5, 0.5, 0) + scrollNub.ZIndex = 2 + scrollNub.BackgroundTransparency = 0.5 + scrollNub.Parent = scrollbar + local newNub = scrollNub:clone() newNub.Position = UDim2.new(0.5, -5, 0.5, -2) newNub.Parent = scrollbar + local lastNub = scrollNub:clone() lastNub.Position = UDim2.new(0.5, -5, 0.5, 2) lastNub.Parent = scrollbar + scrollbar.MouseEnter:connect(function() scrollbar.BackgroundTransparency = 0.1 scrollNub.BackgroundTransparency = 0.1 @@ -860,23 +981,26 @@ t.CreateTrueScrollingFrame = function() newNub.BackgroundTransparency = 0.5 lastNub.BackgroundTransparency = 0.5 end) - local mouseDrag = New("ImageButton", { - Active = false, - Size = UDim2.new(1.5, 0, 1.5, 0), - AutoButtonColor = false, - BackgroundTransparency = 1, - Name = "mouseDrag", - Position = UDim2.new(-0.25, 0, -0.25, 0), - ZIndex = 10 - }) - local positionScrollBar - positionScrollBar = function(_, y, offset) + + local mouseDrag = Instance.new "ImageButton" + mouseDrag.Active = false + mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) + mouseDrag.AutoButtonColor = false + mouseDrag.BackgroundTransparency = 1 + mouseDrag.Name = "mouseDrag" + mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) + mouseDrag.ZIndex = 10 + + local function positionScrollBar(_, y, offset) local oldPos = scrollbar.Position + if y < scrollTrack.AbsolutePosition.y then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0) return (oldPos ~= scrollbar.Position) end + local relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y + if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0) return (oldPos ~= scrollbar.Position) @@ -895,22 +1019,24 @@ t.CreateTrueScrollingFrame = function() scrollBottom.Value = false end scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, newScaleYPos, 0) + return (oldPos ~= scrollbar.Position) end - local drillDownSetHighLow - drillDownSetHighLow = function(instance) - if not instance or not instance:IsA("GuiObject") then + + local function drillDownSetHighLow(instance) + if not instance or not instance:IsA "GuiObject" then return end if instance == controlFrame then return end - if instance:IsDesantOf(controlFrame) then + if instance:IsDescendantOf(controlFrame) then return end if not instance.Visible then return end + if (lowY and lowY > instance.AbsolutePosition.Y) or not lowY then lowY = instance.AbsolutePosition.Y end @@ -922,20 +1048,23 @@ t.CreateTrueScrollingFrame = function() drillDownSetHighLow(children[i]) end end - local resetHighLow - resetHighLow = function() + + local function resetHighLow() local firstChildren = scrollingFrame:GetChildren() + for i = 1, #firstChildren do drillDownSetHighLow(firstChildren[i]) end end - local recalculate - recalculate = function() + + local function recalculate() internalChange = true + local percentFrame = 0 if scrollbar.Position.Y.Scale > 0 then if scrollbar.Visible then - percentFrame = scrollbar.Position.Y.Scale / ((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y) / scrollTrack.AbsoluteSize.Y) + percentFrame = scrollbar.Position.Y.Scale + / ((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y) / scrollTrack.AbsoluteSize.Y) else percentFrame = 0 end @@ -943,37 +1072,49 @@ t.CreateTrueScrollingFrame = function() if percentFrame > 0.99 then percentFrame = 1 end + local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame + local guiChildren = scrollingFrame:GetChildren() for i = 1, #guiChildren do if guiChildren[i] ~= controlFrame then - guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale, guiChildren[i].Position.X.Offset, 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount) + guiChildren[i].Position = UDim2.new( + guiChildren[i].Position.X.Scale, + guiChildren[i].Position.X.Offset, + 0, + math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount + ) end end + lowY = nil highY = nil resetHighLow() internalChange = false end - local setSliderSizeAndPosition - setSliderSizeAndPosition = function() + + local function setSliderSizeAndPosition() if not highY or not lowY then return end + local totalYSpan = math.abs(highY - lowY) if totalYSpan == 0 then scrollbar.Visible = false scrollDownButton.Visible = false scrollUpButton.Visible = false - if dragCon ~= nil then + + if dragCon then dragCon:disconnect() + dragCon = nil end - dragCon = nil - if upCon ~= nil then + if upCon then upCon:disconnect() + upCon = nil end - upCon = nil + return end + local percentShown = scrollingFrame.AbsoluteSize.Y / totalYSpan if percentShown >= 1 then scrollbar.Visible = false @@ -984,44 +1125,59 @@ t.CreateTrueScrollingFrame = function() scrollbar.Visible = true scrollDownButton.Visible = true scrollUpButton.Visible = true + scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale, scrollbar.Size.X.Offset, percentShown, 0) end + local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY) / totalYSpan - scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, percentPosition, -scrollbar.AbsoluteSize.X / 2) + scrollbar.Position = UDim2.new( + scrollbar.Position.X.Scale, + scrollbar.Position.X.Offset, + percentPosition, + -scrollbar.AbsoluteSize.X / 2 + ) + if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0) end - if scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y > scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y then + + if + (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) + > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) + then local relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0) end end + local buttonScrollAmountPixels = 7 local reentrancyGuardScrollUp = false - local doScrollUp - doScrollUp = function() + local function doScrollUp() if reentrancyGuardScrollUp then return end + reentrancyGuardScrollUp = true if positionScrollBar(0, scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels, 0) then recalculate() end reentrancyGuardScrollUp = false end + local reentrancyGuardScrollDown = false - local doScrollDown - doScrollDown = function() + local function doScrollDown() if reentrancyGuardScrollDown then return end + reentrancyGuardScrollDown = true if positionScrollBar(0, scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels, 0) then recalculate() end reentrancyGuardScrollDown = false end - scrollUp = function(mouseYPos) + + local function scrollUp(mouseYPos) if scrollUpButton.Active then local scrollStamp = tick() local current = scrollStamp @@ -1029,12 +1185,12 @@ t.CreateTrueScrollingFrame = function() upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil - return upCon:disconnect() + upCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollUp() wait(0.2) - t = tick() + local t = tick() local w = 0.1 while scrollStamp == current do doScrollUp() @@ -1053,8 +1209,8 @@ t.CreateTrueScrollingFrame = function() end end end - local scrollDown - scrollDown = function(mouseYPos) + + local function scrollDown(mouseYPos) if scrollDownButton.Active then local scrollStamp = tick() local current = scrollStamp @@ -1062,12 +1218,12 @@ t.CreateTrueScrollingFrame = function() downCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil - return downCon:disconnect() + downCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollDown() wait(0.2) - t = tick() + local t = tick() local w = 0.1 while scrollStamp == current do doScrollDown() @@ -1086,23 +1242,25 @@ t.CreateTrueScrollingFrame = function() end end end + scrollbar.MouseButton1Down:connect(function(_, y) if scrollbar.Active then - scrollStamp = tick() + local scrollStamp = tick() local mouseOffset = y - scrollbar.AbsolutePosition.y - if dragCon ~= nil then + if dragCon then dragCon:disconnect() + dragCon = nil end - dragCon = nil - if upCon ~= nil then + if upCon then upCon:disconnect() + upCon = nil end - upCon = nil local reentrancyGuardMouseScroll = false dragCon = mouseDrag.MouseMoved:connect(function(x, y) if reentrancyGuardMouseScroll then return end + reentrancyGuardMouseScroll = true if positionScrollBar(x, y, mouseOffset) then recalculate() @@ -1115,130 +1273,158 @@ t.CreateTrueScrollingFrame = function() dragCon:disconnect() dragCon = nil upCon:disconnect() - local drag = nil + drag = nil end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) end end) + local scrollMouseCount = 0 + scrollUpButton.MouseButton1Down:connect(function() - return scrollUp() + scrollUp() end) scrollDownButton.MouseButton1Down:connect(function() - return scrollDown() + scrollDown() end) - local scrollTick - scrollTick = function() + + local function scrollTick() scrollStamp = tick() end + scrollUpButton.MouseButton1Up:connect(scrollTick) scrollDownButton.MouseButton1Up:connect(scrollTick) scrollbar.MouseButton1Up:connect(scrollTick) - local highLowRecheck - highLowRecheck = function() + + -- local function heightCheck(instance) + -- if (highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY) or not highY then + -- highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y + -- end + -- setSliderSizeAndPosition() + -- end + + local function highLowRecheck() local oldLowY = lowY local oldHighY = highY lowY = nil highY = nil resetHighLow() + if (lowY ~= oldLowY) or (highY ~= oldHighY) then - return setSliderSizeAndPosition() + setSliderSizeAndPosition() end end - local desantChanged - desantChanged = function(this, prop) + + local function descendantChanged(this, prop) if internalChange then return end if not this.Visible then return end + if prop == "Size" or prop == "Position" then - wait() - return highLowRecheck() - end - end - scrollingFrame.DesantAdded:connect(function(instance) - if not instance:IsA("GuiObject") then - return - end - if instance.Visible then wait() highLowRecheck() end - desantsChangeConMap[instance] = instance.Changed:connect(function(prop) - return desantChanged(instance, prop) - end) - end) - scrollingFrame.DesantRemoving:connect(function(instance) - if not instance:IsA("GuiObject") then + end + + scrollingFrame.DescendantAdded:connect(function(instance) + if not instance:IsA "GuiObject" then return end - if desantsChangeConMap[instance] then - desantsChangeConMap[instance]:disconnect() - desantsChangeConMap[instance] = nil + + if instance.Visible then + wait() -- wait a heartbeat for sizes to reconfig + highLowRecheck() end - wait() - return highLowRecheck() + + descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) + descendantChanged(instance, prop) + end) end) + + scrollingFrame.DescendantRemoving:connect(function(instance) + if not instance:IsA "GuiObject" then + return + end + if descendantsChangeConMap[instance] then + descendantsChangeConMap[instance]:disconnect() + descendantsChangeConMap[instance] = nil + end + wait() -- wait a heartbeat for sizes to reconfig + highLowRecheck() + end) + scrollingFrame.Changed:connect(function(prop) if prop == "AbsoluteSize" then if not highY or not lowY then return end + highLowRecheck() - return setSliderSizeAndPosition() + setSliderSizeAndPosition() end end) + return scrollingFrame, controlFrame end + t.CreateScrollingFrame = function(orderList, scrollStyle) - local frame = New("Frame", "ScrollingFrame", { - BackgroundTransparency = 1, - Size = UDim2.new(1, 0, 1, 0) - }) - local scrollUpButton = New("ImageButton", "ScrollUpButton", { - BackgroundTransparency = 1, - Image = "rbxasset://textures/ui/scrollbuttonUp.png", - Size = UDim2.new(0, 17, 0, 17) - }) - local scrollDownButton = New("ImageButton", "ScrollDownButton", { - BackgroundTransparency = 1, - Image = "rbxasset://textures/ui/scrollbuttonDown.png", - Size = UDim2.new(0, 17, 0, 17) - }) - local scrollbar = New("ImageButton", "ScrollBar", { - Image = "rbxasset://textures/ui/scrollbar.png", - BackgroundTransparency = 1, - Size = UDim2.new(0, 18, 0, 150), - New("ImageButton", "ScrollDrag", { - Image = "http://www.roblox.com/asset/?id=61367186", - Size = UDim2.new(1, 0, 0, 16), - BackgroundTransparency = 1, - Active = true - }) - }) - local scrollDrag = scrollbar.scrollDrag - local mouseDrag = New("ImageButton", "mouseDrag", { - Active = false, - Size = UDim2.new(1.5, 0, 1.5, 0), - AutoButtonColor = false, - BackgroundTransparency = 1, - Position = UDim2.new(-0.25, 0, -0.25, 0), - ZIndex = 10 - }) + local frame = Instance.new "Frame" + frame.Name = "ScrollingFrame" + frame.BackgroundTransparency = 1 + frame.Size = UDim2.new(1, 0, 1, 0) + + local scrollUpButton = Instance.new "ImageButton" + scrollUpButton.Name = "ScrollUpButton" + scrollUpButton.BackgroundTransparency = 1 + scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png" + scrollUpButton.Size = UDim2.new(0, 17, 0, 17) + + local scrollDownButton = Instance.new "ImageButton" + scrollDownButton.Name = "ScrollDownButton" + scrollDownButton.BackgroundTransparency = 1 + scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png" + scrollDownButton.Size = UDim2.new(0, 17, 0, 17) + + local scrollbar = Instance.new "ImageButton" + scrollbar.Name = "ScrollBar" + scrollbar.Image = "rbxasset://textures/ui/scrollbar.png" + scrollbar.BackgroundTransparency = 1 + scrollbar.Size = UDim2.new(0, 18, 0, 150) + local scrollStamp = 0 + + local scrollDrag = Instance.new "ImageButton" + scrollDrag.Image = "http://www.roblox.com/asset/?id=61367186" + scrollDrag.Size = UDim2.new(1, 0, 0, 16) + scrollDrag.BackgroundTransparency = 1 + scrollDrag.Name = "ScrollDrag" + scrollDrag.Active = true + scrollDrag.Parent = scrollbar + + local mouseDrag = Instance.new "ImageButton" + mouseDrag.Active = false + mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0) + mouseDrag.AutoButtonColor = false + mouseDrag.BackgroundTransparency = 1 + mouseDrag.Name = "mouseDrag" + mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0) + mouseDrag.ZIndex = 10 + local style = "simple" if scrollStyle and tostring(scrollStyle) then style = scrollStyle end + local scrollPosition = 1 local rowSize = 0 local howManyDisplayed = 0 - local layoutGridScrollBar - layoutGridScrollBar = function() + + local layoutGridScrollBar = function() howManyDisplayed = 0 - local guiObjects = { } + local guiObjects = {} if orderList then for _, child in ipairs(orderList) do if child.Parent == frame then @@ -1249,7 +1435,7 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) local children = frame:GetChildren() if children then for _, child in ipairs(children) do - if child:IsA("GuiObject") then + if child:IsA "GuiObject" then table.insert(guiObjects, child) end end @@ -1262,24 +1448,34 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) scrollPosition = 1 return end + if scrollPosition > #guiObjects then scrollPosition = #guiObjects end + if scrollPosition < 1 then scrollPosition = 1 end + local totalPixelsY = frame.AbsoluteSize.Y local pixelsRemainingY = frame.AbsoluteSize.Y + local totalPixelsX = frame.AbsoluteSize.X + local xCounter = 0 local rowSizeCounter = 0 local setRowSize = true + local pixelsBelowScrollbar = 0 local pos = #guiObjects + local currentRowY = 0 + pos = scrollPosition + --count up from current scroll position to fill out grid while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do xCounter = xCounter + guiObjects[pos].AbsoluteSize.X + --previous pos was the end of a row if xCounter >= totalPixelsX then pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY currentRowY = 0 @@ -1290,10 +1486,17 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) end pos = pos + 1 end + --Count wherever current row left off pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY currentRowY = 0 + pos = scrollPosition - 1 xCounter = 0 + + --objects with varying X,Y dimensions can rarely cause minor errors + --rechecking every new scrollPosition is necessary to avoid 100% of errors + + --count backwards from current scrollPosition to see if we can add more rows while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do xCounter = xCounter + guiObjects[pos].AbsoluteSize.X rowSizeCounter = rowSizeCounter + 1 @@ -1302,6 +1505,7 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) rowSizeCounter = 0 xCounter = guiObjects[pos].AbsoluteSize.X if pixelsBelowScrollbar + currentRowY <= totalPixelsY then + --It fits, so back up our scroll position pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY if scrollPosition <= rowSize then scrollPosition = 1 @@ -1314,31 +1518,42 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) break end end + if guiObjects[pos].AbsoluteSize.Y > currentRowY then currentRowY = guiObjects[pos].AbsoluteSize.Y end + pos = pos - 1 end + + --Do check last time if pos = 0 if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then scrollPosition = 1 end + xCounter = 0 + --pos = scrollPosition rowSizeCounter = 0 setRowSize = true local lastChildSize = 0 - local xOffset = 0 - local yOffset = 0 + + local xOffset, yOffset = 0 if guiObjects[1] then yOffset = math.ceil(math.floor(math.fmod(totalPixelsY, guiObjects[1].AbsoluteSize.X)) / 2) xOffset = math.ceil(math.floor(math.fmod(totalPixelsX, guiObjects[1].AbsoluteSize.Y)) / 2) end + for i, child in ipairs(guiObjects) do if i < scrollPosition then + --print("Hiding " .. child.Name) child.Visible = false else if pixelsRemainingY < 0 then + --print("Out of Space " .. child.Name) child.Visible = false else + --print("Laying out " .. child.Name) + --GuiObject if setRowSize then rowSizeCounter = rowSizeCounter + 1 end @@ -1350,7 +1565,12 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) xCounter = 0 pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y end - child.Position = UDim2.new(child.Position.X.Scale, xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset) + child.Position = UDim2.new( + child.Position.X.Scale, + xCounter + xOffset, + 0, + totalPixelsY - pixelsRemainingY + yOffset + ) xCounter = xCounter + child.AbsoluteSize.X child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0) if child.Visible then @@ -1360,19 +1580,21 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) end end end + scrollUpButton.Active = (scrollPosition > 1) if lastChildSize == 0 then scrollDownButton.Active = false else - scrollDownButton.Active = (pixelsRemainingY - lastChildSize.Y) < 0 + scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0) end scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active end - local layoutSimpleScrollBar - layoutSimpleScrollBar = function() - local guiObjects = { } + + local layoutSimpleScrollBar = function() + local guiObjects = {} howManyDisplayed = 0 + if orderList then for _, child in ipairs(orderList) do if child.Parent == frame then @@ -1383,7 +1605,7 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) local children = frame:GetChildren() if children then for _, child in ipairs(children) do - if child:IsA("GuiObject") then + if child:IsA "GuiObject" then table.insert(guiObjects, child) end end @@ -1396,11 +1618,14 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) scrollPosition = 1 return end + if scrollPosition > #guiObjects then scrollPosition = #guiObjects end + local totalPixels = frame.AbsoluteSize.Y local pixelsRemaining = frame.AbsoluteSize.Y + local pixelsBelowScrollbar = 0 local pos = #guiObjects while pixelsBelowScrollbar < totalPixels and pos >= 1 do @@ -1408,11 +1633,13 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y else if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then + --It fits, so back up our scroll position pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y if scrollPosition <= 1 then scrollPosition = 1 break else + --local ("Backing up ScrollPosition from -- " ..scrollPosition) scrollPosition = scrollPosition - 1 end else @@ -1421,15 +1648,21 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) end pos = pos - 1 end + pos = scrollPosition for i, child in ipairs(guiObjects) do if i < scrollPosition then + --print("Hiding " .. child.Name) child.Visible = false else if pixelsRemaining < 0 then + --print("Out of Space " .. child.Name) child.Visible = false else - child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) + --print("Laying out " .. child.Name) + --GuiObject + child.Position = + UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining) pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y if pixelsRemaining >= 0 then child.Visible = true @@ -1445,25 +1678,29 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) scrollDrag.Active = #guiObjects > howManyDisplayed scrollDrag.Visible = scrollDrag.Active end - local moveDragger - moveDragger = function() + + local moveDragger = function() local guiObjects = 0 local children = frame:GetChildren() if children then for _, child in ipairs(children) do - if child:IsA("GuiObject") then + if child:IsA "GuiObject" then guiObjects = guiObjects + 1 end end end + if not scrollDrag.Parent then return end + local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1 / (guiObjects - howManyDisplayed + 1)) if dragSizeY < 16 then dragSizeY = 16 end - scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale, scrollDrag.Size.X.Offset, scrollDrag.Size.Y.Scale, dragSizeY) + scrollDrag.Size = + UDim2.new(scrollDrag.Size.X.Scale, scrollDrag.Size.X.Offset, scrollDrag.Size.Y.Scale, dragSizeY) + local relativeYPos = (scrollPosition - 1) / (guiObjects - howManyDisplayed) if relativeYPos > 1 then relativeYPos = 1 @@ -1471,27 +1708,30 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) relativeYPos = 0 end local absYPos = 0 + if relativeYPos ~= 0 then absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y) end - scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale, scrollDrag.Position.X.Offset, scrollDrag.Position.Y.Scale, absYPos) + + scrollDrag.Position = + UDim2.new(scrollDrag.Position.X.Scale, scrollDrag.Position.X.Offset, scrollDrag.Position.Y.Scale, absYPos) end + local reentrancyGuard = false - local recalculate - recalculate = function() + local recalculate = function() if reentrancyGuard then return end reentrancyGuard = true wait() - local success, err + local success, err = nil if style == "grid" then success, err = pcall(function() - return layoutGridScrollBar() + layoutGridScrollBar() end) elseif style == "simple" then success, err = pcall(function() - return layoutSimpleScrollBar() + layoutSimpleScrollBar() end) end if not success then @@ -1500,33 +1740,34 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) moveDragger() reentrancyGuard = false end - local doScrollUp - doScrollUp = function() + + local doScrollUp = function() scrollPosition = scrollPosition - rowSize if scrollPosition < 1 then scrollPosition = 1 end - return recalculate(nil) + recalculate(nil) end - local doScrollDown - doScrollDown = function() + + local doScrollDown = function() scrollPosition = scrollPosition + rowSize - return recalculate(nil) + recalculate(nil) end - local scrollUp - scrollUp = function(mouseYPos) + + local scrollUp = function(mouseYPos) if scrollUpButton.Active then scrollStamp = tick() local current = scrollStamp - local upCon = mouseDrag.MouseButton1Up:connect(function() + local upCon + upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil - return upCon:disconnect() + upCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollUp() wait(0.2) - t = tick() + local t = tick() local w = 0.1 while scrollStamp == current do doScrollUp() @@ -1545,20 +1786,21 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) end end end - local scrollDown - scrollDown = function(mouseYPos) + + local scrollDown = function(mouseYPos) if scrollDownButton.Active then scrollStamp = tick() local current = scrollStamp - local downCon = mouseDrag.MouseButton1Up:connect(function() + local downCon + downCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() mouseDrag.Parent = nil - return downCon:disconnect() + downCon:disconnect() end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) doScrollDown() wait(0.2) - t = tick() + local t = tick() local w = 0.1 while scrollStamp == current do doScrollDown() @@ -1577,28 +1819,34 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) end end end + + -- local y = 0 scrollDrag.MouseButton1Down:connect(function(_, y) if scrollDrag.Active then scrollStamp = tick() local mouseOffset = y - scrollDrag.AbsolutePosition.y - local dragCon, upCon + local dragCon + local upCon dragCon = mouseDrag.MouseMoved:connect(function(_, y) local barAbsPos = scrollbar.AbsolutePosition.y local barAbsSize = scrollbar.AbsoluteSize.y + local dragAbsSize = scrollDrag.AbsoluteSize.y local barAbsOne = barAbsPos + barAbsSize - dragAbsSize y = y - mouseOffset y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y y = y - barAbsPos + local guiObjects = 0 local children = frame:GetChildren() if children then for _, child in ipairs(children) do - if child:IsA("GuiObject") then + if child:IsA "GuiObject" then guiObjects = guiObjects + 1 end end end + local doublePercent = y / (barAbsSize - dragAbsSize) local rowDiff = rowSize local totalScrollCount = guiObjects - (howManyDisplayed - 1) @@ -1606,11 +1854,13 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) if newScrollPosition < scrollPosition then rowDiff = -rowDiff end + if newScrollPosition < 1 then newScrollPosition = 1 end + scrollPosition = newScrollPosition - return recalculate(nil) + recalculate(nil) end) upCon = mouseDrag.MouseButton1Up:connect(function() scrollStamp = tick() @@ -1618,97 +1868,116 @@ t.CreateScrollingFrame = function(orderList, scrollStyle) dragCon:disconnect() dragCon = nil upCon:disconnect() - local drag = nil + drag = nil end) mouseDrag.Parent = getScreenGuiAncestor(scrollbar) end end) + local scrollMouseCount = 0 + scrollUpButton.MouseButton1Down:connect(function() - return scrollUp() - end) - scrollDownButton.MouseButton1Down:connect(function() - return scrollDown() + scrollUp() end) scrollUpButton.MouseButton1Up:connect(function() scrollStamp = tick() end) + scrollDownButton.MouseButton1Up:connect(function() scrollStamp = tick() end) + scrollDownButton.MouseButton1Down:connect(function() + scrollDown() + end) + scrollbar.MouseButton1Up:connect(function() scrollStamp = tick() end) scrollbar.MouseButton1Down:connect(function(_, y) if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then - return scrollDown(y) + scrollDown(y) elseif y < scrollDrag.AbsolutePosition.y then - return scrollUp(y) + scrollUp(y) end end) + frame.ChildAdded:connect(function() - return recalculate(nil) + recalculate(nil) end) + frame.ChildRemoved:connect(function() - return recalculate(nil) - end) - frame.AncestryChanged:connect(function() - return recalculate(nil) + recalculate(nil) end) + frame.Changed:connect(function(prop) if prop == "AbsoluteSize" then - return recalculate(nil) + --Wait a heartbeat for it to sync in + recalculate(nil) end end) + frame.AncestryChanged:connect(function() + recalculate(nil) + end) + return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar end -local binaryGrow -binaryGrow = function(min, max, fits) +local function binaryGrow(min, max, fits) if min > max then return min end local biggestLegal = min + while min <= max do local mid = min + math.floor((max - min) / 2) - if fits(mid) and (not (biggestLegal ~= nil) or biggestLegal < mid) then + if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then biggestLegal = mid + + --Try growing min = mid + 1 else + --Doesn't fit, shrink max = mid - 1 end end return biggestLegal end -local binaryShrink -binaryShrink = function(min, max, fits) + +local function binaryShrink(min, max, fits) if min > max then return min end local smallestLegal = max + while min <= max do local mid = min + math.floor((max - min) / 2) - if fits(mid) and (not (smallestLegal ~= nil) or smallestLegal > mid) then + if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then smallestLegal = mid + + --It fits, shrink max = mid - 1 else + --Doesn't fit, grow min = mid + 1 end end return smallestLegal end -local getGuiOwner -getGuiOwner = function(instance) - while (instance ~= nil) do - if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then + +local function getGuiOwner(instance) + while instance ~= nil do + if instance:IsA "ScreenGui" or instance:IsA "BillboardGui" then return instance end instance = instance.Parent end + return nil end + t.AutoTruncateTextObject = function(textLabel) local text = textLabel.Text + local fullLabel = textLabel:Clone() - fullLabel.Name = "Full" .. tostring(textLabel.Name) + fullLabel.Name = "Full" .. textLabel.Name fullLabel.BorderSizePixel = 0 fullLabel.BackgroundTransparency = 0 fullLabel.Text = text @@ -1717,54 +1986,67 @@ t.AutoTruncateTextObject = function(textLabel) fullLabel.Size = UDim2.new(0, 100, 1, 0) fullLabel.Visible = false fullLabel.Parent = textLabel - local shortText - local mouseEnterConnection - local mouseLeaveConnection - local checkForResize - checkForResize = function() - if not (getGuiOwner(textLabel) ~= nil) then + + local shortText = nil + local mouseEnterConnection = nil + local mouseLeaveConnection = nil + + local checkForResize = function() + if getGuiOwner(textLabel) == nil then return end textLabel.Text = text if textLabel.TextFits then - if mouseEnterConnection ~= nil then + --Tear down the rollover if it is active + if mouseEnterConnection then mouseEnterConnection:disconnect() + mouseEnterConnection = nil end - mouseEnterConnection = nil - if mouseLeaveConnection ~= nil then + if mouseLeaveConnection then mouseLeaveConnection:disconnect() + mouseLeaveConnection = nil end - mouseLeaveConnection = nil else local len = string.len(text) - textLabel.Text = tostring(text) .. "~" + textLabel.Text = text .. "~" + + --Shrink the text local textSize = binaryGrow(0, len, function(pos) if pos == 0 then textLabel.Text = "~" else - textLabel.Text = tostring(string.sub(text, 1, pos)) .. "~" + textLabel.Text = string.sub(text, 1, pos) .. "~" end return textLabel.TextFits end) - shortText = tostring(string.sub(text, 1, textSize)) .. "~" + shortText = string.sub(text, 1, textSize) .. "~" textLabel.Text = shortText + + --Make sure the fullLabel fits if not fullLabel.TextFits then + --Already too small, grow it really bit to start fullLabel.Size = UDim2.new(0, 10000, 1, 0) end + + --Okay, now try to binary shrink it back down local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X, fullLabel.AbsoluteSize.X, function(size) fullLabel.Size = UDim2.new(0, size, 1, 0) return fullLabel.TextFits end) fullLabel.Size = UDim2.new(0, fullLabelSize + 6, 1, 0) - if not (mouseEnterConnection ~= nil) then + + --Now setup the rollover effects, if they are currently off + if mouseEnterConnection == nil then mouseEnterConnection = textLabel.MouseEnter:connect(function() fullLabel.ZIndex = textLabel.ZIndex + 1 fullLabel.Visible = true + --textLabel.Text = "" end) end - if not (mouseLeaveConnection ~= nil) then + if mouseLeaveConnection == nil then mouseLeaveConnection = textLabel.MouseLeave:connect(function() fullLabel.Visible = false + --textLabel.Text = shortText end) end end @@ -1772,78 +2054,102 @@ t.AutoTruncateTextObject = function(textLabel) textLabel.AncestryChanged:connect(checkForResize) textLabel.Changed:connect(function(prop) if prop == "AbsoluteSize" then - return checkForResize() + checkForResize() end end) + checkForResize() - local changeText - changeText = function(newText) + + local function changeText(newText) text = newText fullLabel.Text = text - return checkForResize() + checkForResize() end + return textLabel, changeText end -local TransitionTutorialPages -TransitionTutorialPages = function(fromPage, toPage, transitionFrame, currentPageValue) + +local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue) if fromPage then fromPage.Visible = false if transitionFrame.Visible == false then transitionFrame.Size = fromPage.Size transitionFrame.Position = fromPage.Position end - elseif transitionFrame.Visible == false then - transitionFrame.Size = UDim2.new(0, 50, 0, 50) - transitionFrame.Position = UDim2.new(0.5, -25, 0.5, -25) + else + if transitionFrame.Visible == false then + transitionFrame.Size = UDim2.new(0, 50, 0, 50) + transitionFrame.Position = UDim2.new(0.5, -25, 0.5, -25) + end end transitionFrame.Visible = true currentPageValue.Value = nil + local newSize, newPosition if toPage then + --Make it visible so it resizes toPage.Visible = true + newSize = toPage.Size newPosition = toPage.Position + toPage.Visible = false else newSize = UDim2.new(0, 50, 0, 50) newPosition = UDim2.new(0.5, -25, 0.5, -25) end - return transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true, function(state) - if state == Enum.TweenStatus.Completed then - transitionFrame.Visible = false - if toPage then - toPage.Visible = true - currentPageValue.Value = toPage + transitionFrame:TweenSizeAndPosition( + newSize, + newPosition, + Enum.EasingDirection.InOut, + Enum.EasingStyle.Quad, + 0.3, + true, + function(state) + if state == Enum.TweenStatus.Completed then + transitionFrame.Visible = false + if toPage then + toPage.Visible = true + currentPageValue.Value = toPage + end end end - end) + ) end + t.CreateTutorial = function(name, tutorialKey, createButtons) - local frame = New("Frame", "Tutorial-" .. tostring(name), { - BackgroundTransparency = 1, - Size = UDim2.new(0.6, 0, 0.6, 0), - Position = UDim2.new(0.2, 0, 0.2, 0), - New("Frame", "TransitionFrame", { - Style = Enum.FrameStyle.RobloxRound, - Size = UDim2.new(0.6, 0, 0.6, 0), - Position = UDim2.new(0.2, 0, 0.2, 0), - Visible = false - }), - New("ObjectValue", "CurrentTutorialPage", { - Value = nil - }), - New("BoolValue", "Buttons", { - Value = createButtons - }), - New("Frame", "Pages", { - BackgroundTransparency = 1, - Size = UDim2.new(1, 0, 1, 0) - }) - }) - local transitionFrame, currentPageValue, pages = frame.TransitionFrame, frame.CurrentTutorialPage, frame.Pages - local getVisiblePageAndHideOthers - getVisiblePageAndHideOthers = function() - local visiblePage + local frame = Instance.new "Frame" + frame.Name = "Tutorial-" .. name + frame.BackgroundTransparency = 1 + frame.Size = UDim2.new(0.6, 0, 0.6, 0) + frame.Position = UDim2.new(0.2, 0, 0.2, 0) + + local transitionFrame = Instance.new "Frame" + transitionFrame.Name = "TransitionFrame" + transitionFrame.Style = Enum.FrameStyle.RobloxRound + transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0) + transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0) + transitionFrame.Visible = false + transitionFrame.Parent = frame + + local currentPageValue = Instance.new "ObjectValue" + currentPageValue.Name = "CurrentTutorialPage" + currentPageValue.Value = nil + currentPageValue.Parent = frame + + local boolValue = Instance.new "BoolValue" + boolValue.Name = "Buttons" + boolValue.Value = createButtons + boolValue.Parent = frame + + local pages = Instance.new "Frame" + pages.Name = "Pages" + pages.BackgroundTransparency = 1 + pages.Size = UDim2.new(1, 0, 1, 0) + pages.Parent = frame + + local function getVisiblePageAndHideOthers() + local visiblePage = nil local children = pages:GetChildren() if children then for _, child in ipairs(children) do @@ -1858,167 +2164,187 @@ t.CreateTutorial = function(name, tutorialKey, createButtons) end return visiblePage end - local showTutorial - showTutorial = function(alwaysShow) + + local showTutorial = function(alwaysShow) if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then print("Showing tutorial-", tutorialKey) local currentTutorialPage = getVisiblePageAndHideOthers() - local firstPage = pages:FindFirstChild("TutorialPage1") + + local firstPage = pages:FindFirstChild "TutorialPage1" if firstPage then - return TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue) + TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue) else - return error("Could not find TutorialPage1") + error "Could not find TutorialPage1" end end end - local dismissTutorial - dismissTutorial = function() + + local dismissTutorial = function() local currentTutorialPage = getVisiblePageAndHideOthers() + if currentTutorialPage then TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue) end - return UserSettings().GameSettings:SetTutorialState(tutorialKey, true) + + UserSettings().GameSettings:SetTutorialState(tutorialKey, true) end - local gotoPage - gotoPage = function(pageNum) - local page = pages:FindFirstChild("TutorialPage" .. tostring(pageNum)) + + local gotoPage = function(pageNum) + local page = pages:FindFirstChild("TutorialPage" .. pageNum) local currentTutorialPage = getVisiblePageAndHideOthers() - return TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue) + TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue) end + return frame, showTutorial, dismissTutorial, gotoPage end -local CreateBasicTutorialPage -CreateBasicTutorialPage = function(name, handleResize, skipTutorial, giveDoneButton) - local frame = New("Frame", "TutorialPage", { - Style = Enum.FrameStyle.RobloxRound, - Size = UDim2.new(0.6, 0, 0.6, 0), - Position = UDim2.new(0.2, 0, 0.2, 0), - Visible = false, - New("TextLabel", "Header", { - Text = name, - BackgroundTransparency = 1, - FontSize = Enum.FontSize.Size24, - Font = Enum.Font.ArialBold, - TextColor3 = Color3.new(1, 1, 1), - TextXAlignment = Enum.TextXAlignment.Center, - TextWrap = true, - Size = UDim2.new(1, -55, 0, 22), - Position = UDim2.new(0, 0, 0, 0) - }), - New("ImageButton", "SkipButton", { - AutoButtonColor = false, - BackgroundTransparency = 1, - Image = "rbxasset://textures/ui/closeButton.png", - Size = UDim2.new(0, 25, 0, 25), - Position = UDim2.new(1, -25, 0, 0) - }), - New("TextButton", "NextButton", { - Text = "Next", - TextColor3 = Color3.new(1, 1, 1), - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - Style = Enum.ButtonStyle.RobloxButtonDefault, - Size = UDim2.new(0, 80, 0, 32), - Position = UDim2.new(0.5, 5, 1, -32), - Active = false, - Visible = false - }), - New("TextButton", "PrevButton", { - Text = "Previous", - TextColor3 = Color3.new(1, 1, 1), - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - Style = Enum.ButtonStyle.RobloxButton, - Size = UDim2.new(0, 80, 0, 32), - Position = UDim2.new(0.5, -85, 1, -32), - Active = false, - Visible = false - }), - New("Frame", "ContentFrame", { - BackgroundTransparency = 1, - Position = UDim2.new(0, 0, 0, 25) - }) - }) - local innerFrame = frame.ContentFrame - do - local _with_0 = frame.SkipButton - _with_0.MouseButton1Click:connect(function() - return skipTutorial() - end) - _with_0.MouseEnter:connect(function() - _with_0.Image = "rbxasset://textures/ui/closeButton_dn.png" - end) - _with_0.MouseLeave:connect(function() - _with_0.Image = "rbxasset://textures/ui/closeButton.png" - end) - end + +local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton) + local frame = Instance.new "Frame" + frame.Name = "TutorialPage" + frame.Style = Enum.FrameStyle.RobloxRound + frame.Size = UDim2.new(0.6, 0, 0.6, 0) + frame.Position = UDim2.new(0.2, 0, 0.2, 0) + frame.Visible = false + + local frameHeader = Instance.new "TextLabel" + frameHeader.Name = "Header" + frameHeader.Text = name + frameHeader.BackgroundTransparency = 1 + frameHeader.FontSize = Enum.FontSize.Size24 + frameHeader.Font = Enum.Font.ArialBold + frameHeader.TextColor3 = Color3.new(1, 1, 1) + frameHeader.TextXAlignment = Enum.TextXAlignment.Center + frameHeader.TextWrap = true + frameHeader.Size = UDim2.new(1, -55, 0, 22) + frameHeader.Position = UDim2.new(0, 0, 0, 0) + frameHeader.Parent = frame + + local skipButton = Instance.new "ImageButton" + skipButton.Name = "SkipButton" + skipButton.AutoButtonColor = false + skipButton.BackgroundTransparency = 1 + skipButton.Image = "rbxasset://textures/ui/closeButton.png" + skipButton.MouseButton1Click:connect(function() + skipTutorial() + end) + skipButton.MouseEnter:connect(function() + skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png" + end) + skipButton.MouseLeave:connect(function() + skipButton.Image = "rbxasset://textures/ui/closeButton.png" + end) + skipButton.Size = UDim2.new(0, 25, 0, 25) + skipButton.Position = UDim2.new(1, -25, 0, 0) + skipButton.Parent = frame + if giveDoneButton then - local doneButton = New("TextButton", "DoneButton", { - Style = Enum.ButtonStyle.RobloxButtonDefault, - Text = "Done", - TextColor3 = Color3.new(1, 1, 1), - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size18, - Size = UDim2.new(0, 100, 0, 50), - Position = UDim2.new(0.5, -50, 1, -50), - Parent = frame - }) + local doneButton = Instance.new "TextButton" + doneButton.Name = "DoneButton" + doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault + doneButton.Text = "Done" + doneButton.TextColor3 = Color3.new(1, 1, 1) + doneButton.Font = Enum.Font.ArialBold + doneButton.FontSize = Enum.FontSize.Size18 + doneButton.Size = UDim2.new(0, 100, 0, 50) + doneButton.Position = UDim2.new(0.5, -50, 1, -50) + if skipTutorial then doneButton.MouseButton1Click:connect(function() - return skipTutorial() + skipTutorial() end) end + + doneButton.Parent = frame end + + local innerFrame = Instance.new "Frame" + innerFrame.Name = "ContentFrame" + innerFrame.BackgroundTransparency = 1 + innerFrame.Position = UDim2.new(0, 0, 0, 25) + innerFrame.Parent = frame + + local nextButton = Instance.new "TextButton" + nextButton.Name = "NextButton" + nextButton.Text = "Next" + nextButton.TextColor3 = Color3.new(1, 1, 1) + nextButton.Font = Enum.Font.Arial + nextButton.FontSize = Enum.FontSize.Size18 + nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault + nextButton.Size = UDim2.new(0, 80, 0, 32) + nextButton.Position = UDim2.new(0.5, 5, 1, -32) + nextButton.Active = false + nextButton.Visible = false + nextButton.Parent = frame + + local prevButton = Instance.new "TextButton" + prevButton.Name = "PrevButton" + prevButton.Text = "Previous" + prevButton.TextColor3 = Color3.new(1, 1, 1) + prevButton.Font = Enum.Font.Arial + prevButton.FontSize = Enum.FontSize.Size18 + prevButton.Style = Enum.ButtonStyle.RobloxButton + prevButton.Size = UDim2.new(0, 80, 0, 32) + prevButton.Position = UDim2.new(0.5, -85, 1, -32) + prevButton.Active = false + prevButton.Visible = false + prevButton.Parent = frame + if giveDoneButton then innerFrame.Size = UDim2.new(1, 0, 1, -75) else innerFrame.Size = UDim2.new(1, 0, 1, -22) end - local parentConnection - local basicHandleResize - basicHandleResize = function() + + local parentConnection = nil + + local function basicHandleResize() if frame.Visible and frame.Parent then local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y) - return handleResize(200, maxSize) + handleResize(200, maxSize) end end + frame.Changed:connect(function(prop) if prop == "Parent" then if parentConnection ~= nil then parentConnection:disconnect() + parentConnection = nil end - parentConnection = nil - if frame.Parent and frame.Parent:IsA("GuiObject") then + if frame.Parent and frame.Parent:IsA "GuiObject" then parentConnection = frame.Parent.Changed:connect(function(parentProp) if parentProp == "AbsoluteSize" then wait() - return basicHandleResize() + basicHandleResize() end end) basicHandleResize() end end + if prop == "Visible" then - return basicHandleResize() + basicHandleResize() end end) + return frame, innerFrame end + t.CreateTextTutorialPage = function(name, text, skipTutorialFunc) - local frame - local textLabel = New("TextLabel", { - BackgroundTransparency = 1, - TextColor3 = Color3.new(1, 1, 1), - Text = text, - TextWrap = true, - TextXAlignment = Enum.TextXAlignment.Left, - TextYAlignment = Enum.TextYAlignment.Center, - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size14, - Size = UDim2.new(1, 0, 1, 0) - }) - local handleResize - handleResize = function(minSize, maxSize) + local frame = nil + local contentFrame = nil + + local textLabel = Instance.new "TextLabel" + textLabel.BackgroundTransparency = 1 + textLabel.TextColor3 = Color3.new(1, 1, 1) + textLabel.Text = text + textLabel.TextWrap = true + textLabel.TextXAlignment = Enum.TextXAlignment.Left + textLabel.TextYAlignment = Enum.TextYAlignment.Center + textLabel.Font = Enum.Font.Arial + textLabel.FontSize = Enum.FontSize.Size14 + textLabel.Size = UDim2.new(1, 0, 1, 0) + + local function handleResize(minSize, maxSize) local size = binaryShrink(minSize, maxSize, function(size) frame.Size = UDim2.new(0, size, 0, size) return textLabel.TextFits @@ -2026,21 +2352,24 @@ t.CreateTextTutorialPage = function(name, text, skipTutorialFunc) frame.Size = UDim2.new(0, size, 0, size) frame.Position = UDim2.new(0.5, -size / 2, 0.5, -size / 2) end - local contentFrame + frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc) textLabel.Parent = contentFrame + return frame end + t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton) - local frame, contentFrame - local imageLabel = New("ImageLabel", { - BackgroundTransparency = 1, - Image = imageAsset, - Size = UDim2.new(0, x, 0, y), - Position = UDim2.new(0.5, -x / 2, 0.5, -y / 2) - }) - local handleResize - handleResize = function(minSize, maxSize) + local frame = nil + local contentFrame = nil + + local imageLabel = Instance.new "ImageLabel" + imageLabel.BackgroundTransparency = 1 + imageLabel.Image = imageAsset + imageLabel.Size = UDim2.new(0, x, 0, y) + imageLabel.Position = UDim2.new(0.5, -x / 2, 0.5, -y / 2) + + local function handleResize(minSize, maxSize) local size = binaryShrink(minSize, maxSize, function(size) return size >= x and size >= y end) @@ -2049,491 +2378,591 @@ t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, g imageLabel.Position = UDim2.new(0.5, -x / 2, 0.5, -y / 2) else if x > y then - imageLabel.Size, imageLabel.Position = UDim2.new(1, 0, y / x, 0), UDim2.new(0, 0, 0.5 - (y / x) / 2, 0) + --X is limiter, so + imageLabel.Size = UDim2.new(1, 0, y / x, 0) + imageLabel.Position = UDim2.new(0, 0, 0.5 - (y / x) / 2, 0) else - imageLabel.Size, imageLabel.Position = UDim2.new(x / y, 0, 1, 0), UDim2.new(0.5 - (x / y) / 2, 0, 0, 0) + --Y is limiter + imageLabel.Size = UDim2.new(x / y, 0, 1, 0) + imageLabel.Position = UDim2.new(0.5 - (x / y) / 2, 0, 0, 0) end end size = size + 50 frame.Size = UDim2.new(0, size, 0, size) frame.Position = UDim2.new(0.5, -size / 2, 0.5, -size / 2) end + frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton) imageLabel.Parent = contentFrame + return frame end + t.AddTutorialPage = function(tutorial, tutorialPage) local transitionFrame = tutorial.TransitionFrame local currentPageValue = tutorial.CurrentTutorialPage + if not tutorial.Buttons.Value then tutorialPage.NextButton.Parent = nil tutorialPage.PrevButton.Parent = nil end + local children = tutorial.Pages:GetChildren() if children and #children > 0 then - tutorialPage.Name = "TutorialPage" .. tostring(#children + 1) + tutorialPage.Name = "TutorialPage" .. (#children + 1) local previousPage = children[#children] - if not previousPage:IsA("GuiObject") then - error("All elements under Pages must be GuiObjects") + if not previousPage:IsA "GuiObject" then + error "All elements under Pages must be GuiObjects" end + if tutorial.Buttons.Value then if previousPage.NextButton.Active then - error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function") + error "NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function" end previousPage.NextButton.MouseButton1Click:connect(function() - return TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue) + TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue) end) previousPage.NextButton.Active = true previousPage.NextButton.Visible = true + if tutorialPage.PrevButton.Active then - error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function") + error "PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function" end tutorialPage.PrevButton.MouseButton1Click:connect(function() - return TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue) + TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue) end) tutorialPage.PrevButton.Active = true tutorialPage.PrevButton.Visible = true end + tutorialPage.Parent = tutorial.Pages else + --First child tutorialPage.Name = "TutorialPage1" tutorialPage.Parent = tutorial.Pages end end -t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId) + +t.CreateSetPanel = function( + userIdsForSets, + objectSelected, + dialogClosed, + size, + position, + showAdminCategories, + useAssetVersionId +) if not userIdsForSets then - error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids") + error "CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids" end if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then - error("CreateSetPanel: userIdsForSets (first arg) is of type " .. tostring(type(userIdsForSets)) .. ", should be of type table or userdata") + error( + "CreateSetPanel: userIdsForSets (first arg) is of type " + .. type(userIdsForSets) + .. ", should be of type table or userdata" + ) end if not objectSelected then - error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!") + error "CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!" end if type(objectSelected) ~= "function" then - error("CreateSetPanel: objectSelected (second arg) is of type " .. tostring(type(objectSelected)) .. ", should be of type function!") + error( + "CreateSetPanel: objectSelected (second arg) is of type " + .. type(objectSelected) + .. ", should be of type function!" + ) end if dialogClosed and type(dialogClosed) ~= "function" then - error("CreateSetPanel: dialogClosed (third arg) is of type " .. tostring(type(dialogClosed)) .. ", should be of type function!") + error( + "CreateSetPanel: dialogClosed (third arg) is of type " + .. type(dialogClosed) + .. ", should be of type function!" + ) end - if not (showAdminCategories ~= nil) then + + if showAdminCategories == nil then -- by default, don't show beta sets showAdminCategories = false end + local arrayPosition = 1 - local insertButtons = { } - local insertButtonCons = { } - local contents, setGui + local insertButtons = {} + local insertButtonCons = {} + local contents = nil + local setGui = nil + + -- used for water selections local waterForceDirection = "NegX" local waterForce = "None" - local waterGui, waterTypeChangedEvent - local Data = { } + local waterGui, waterTypeChangedEvent = nil + + local Data = {} Data.CurrentCategory = nil - Data.Category = { } - local SetCache = { } - local userCategoryButtons + Data.Category = {} + local SetCache = {} + + local userCategoryButtons = nil + local buttonWidth = 64 local buttonHeight = buttonWidth - local SmallThumbnailUrl, LargeThumbnailUrl + + local SmallThumbnailUrl = nil + local LargeThumbnailUrl = nil local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower() + if useAssetVersionId then - LargeThumbnailUrl, SmallThumbnailUrl = tostring(BaseUrl) .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid=", tostring(BaseUrl) .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid=" + LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid=" + SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid=" else - LargeThumbnailUrl, SmallThumbnailUrl = tostring(BaseUrl) .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=", tostring(BaseUrl) .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid=" + LargeThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=" + SmallThumbnailUrl = BaseUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid=" end - local drillDownSetZIndex - drillDownSetZIndex = function(parent, index) + + local function drillDownSetZIndex(parent, index) local children = parent:GetChildren() for i = 1, #children do - if children[i]:IsA("GuiObject") then + if children[i]:IsA "GuiObject" then children[i].ZIndex = index end drillDownSetZIndex(children[i], index) end end - local currTerrainDropDownFrame - local terrainShapes = { - "Block", - "Vertical Ramp", - "Corner Wedge", - "Inverse Corner Wedge", - "Horizontal Ramp", - "Auto-Wedge" - } - local terrainShapeMap = { } + + -- for terrain stamping + local currTerrainDropDownFrame = nil + local terrainShapes = + { "Block", "Vertical Ramp", "Corner Wedge", "Inverse Corner Wedge", "Horizontal Ramp", "Auto-Wedge" } + local terrainShapeMap = {} for i = 1, #terrainShapes do terrainShapeMap[terrainShapes[i]] = i - 1 end terrainShapeMap[terrainShapes[#terrainShapes]] = 6 - local createWaterGui - createWaterGui = function() - local waterForceDirections = { - "NegX", - "X", - "NegY", - "Y", - "NegZ", - "Z" - } - local waterForces = { - "None", - "Small", - "Medium", - "Strong", - "Max" - } - local waterFrame = New("Frame", "WaterFrame", { - Style = Enum.FrameStyle.RobloxSquare, - Size = UDim2.new(0, 150, 0, 110), - Visible = false - }) - local waterForceLabel = New("TextLabel", "WaterForceLabel", { - BackgroundTransparency = 1, - Size = UDim2.new(1, 0, 0, 12), - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size12, - TextColor3 = Color3.new(1, 1, 1), - TextXAlignment = Enum.TextXAlignment.Left, - Text = "Water Force", - Parent = waterFrame - }) + + local function createWaterGui() + local waterForceDirections = { "NegX", "X", "NegY", "Y", "NegZ", "Z" } + local waterForces = { "None", "Small", "Medium", "Strong", "Max" } + + local waterFrame = Instance.new "Frame" + waterFrame.Name = "WaterFrame" + waterFrame.Style = Enum.FrameStyle.RobloxSquare + waterFrame.Size = UDim2.new(0, 150, 0, 110) + waterFrame.Visible = false + + local waterForceLabel = Instance.new "TextLabel" + waterForceLabel.Name = "WaterForceLabel" + waterForceLabel.BackgroundTransparency = 1 + waterForceLabel.Size = UDim2.new(1, 0, 0, 12) + waterForceLabel.Font = Enum.Font.ArialBold + waterForceLabel.FontSize = Enum.FontSize.Size12 + waterForceLabel.TextColor3 = Color3.new(1, 1, 1) + waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left + waterForceLabel.Text = "Water Force" + waterForceLabel.Parent = waterFrame + local waterForceDirLabel = waterForceLabel:Clone() waterForceDirLabel.Name = "WaterForceDirectionLabel" waterForceDirLabel.Text = "Water Force Direction" waterForceDirLabel.Position = UDim2.new(0, 0, 0, 50) waterForceDirLabel.Parent = waterFrame - waterTypeChangedEvent = New("BindableEvent", "WaterTypeChangedEvent", { - Parent = waterFrame - }) - local waterForceDirectionSelectedFunc - waterForceDirectionSelectedFunc = function(newForceDirection) + + local waterTypeChangedEvent = Instance.new "BindableEvent" + waterTypeChangedEvent.Name = "WaterTypeChangedEvent" + waterTypeChangedEvent.Parent = waterFrame + + local waterForceDirectionSelectedFunc = function(newForceDirection) waterForceDirection = newForceDirection - return waterTypeChangedEvent:Fire({ - waterForce, - waterForceDirection - }) + waterTypeChangedEvent:Fire { waterForce, waterForceDirection } end - local waterForceSelectedFunc - waterForceSelectedFunc = function(newForce) + local waterForceSelectedFunc = function(newForce) waterForce = newForce - return waterTypeChangedEvent:Fire({ - waterForce, - waterForceDirection - }) + waterTypeChangedEvent:Fire { waterForce, waterForceDirection } end - local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc) + + local waterForceDirectionDropDown, forceWaterDirectionSelection = + t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc) waterForceDirectionDropDown.Size = UDim2.new(1, 0, 0, 25) waterForceDirectionDropDown.Position = UDim2.new(0, 0, 1, 3) - forceWaterDirectionSelection("NegX") + forceWaterDirectionSelection "NegX" waterForceDirectionDropDown.Parent = waterForceDirLabel + local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc) - forceWaterForceSelection("None") + forceWaterForceSelection "None" waterForceDropDown.Size = UDim2.new(1, 0, 0, 25) waterForceDropDown.Position = UDim2.new(0, 0, 1, 3) waterForceDropDown.Parent = waterForceLabel + return waterFrame, waterTypeChangedEvent end - local createSetGui - createSetGui = function() - setGui = Instance.new("ScreenGui") + + -- Helper Function that contructs gui elements + local function createSetGui() + local setGui = Instance.new "ScreenGui" setGui.Name = "SetGui" - local setPanel = New("Frame", "SetPanel", { - Active = true, - BackgroundTransparency = 1, - Position = position or UDim2.new(0.2, 29, 0.1, 24), - Size = size or UDim2.new(0.6, -58, 0.64, 0), - Style = Enum.FrameStyle.RobloxRound, - ZIndex = 6, - Parent = setGui, - New("TextButton", "CancelButton", { - Position = UDim2.new(1, -32, 0, -2), - Size = UDim2.new(0, 34, 0, 34), - Style = Enum.ButtonStyle.RobloxButtonDefault, - ZIndex = 6, - Text = "", - Modal = true, - New("ImageLabel", "CancelImage", { - BackgroundTransparency = 1, - Image = "http://www.roblox.com/asset?id=54135717", - Position = UDim2.new(0, -2, 0, -2), - Size = UDim2.new(0, 16, 0, 16), - ZIndex = 6 - }) - }), - New("Frame", "ItemPreview", { - BackgroundTransparency = 1, - Position = UDim2.new(0.8, 5, 0.085, 0), - Size = UDim2.new(0.21, 0, 0.9, 0), - ZIndex = 6, - New("ImageLabel", "LargePreview", { - BackgroundTransparency = 1, - Image = "", - Size = UDim2.new(1, 0, 0, 170), - ZIndex = 6 - }), - New("Frame", "TextPanel", { - BackgroundTransparency = 1, - Position = UDim2.new(0, 0, 0.45, 0), - Size = UDim2.new(1, 0, 0.55, 0), - ZIndex = 6, - New("TextLabel", "RolloverText", { - BackgroundTransparency = 1, - Size = UDim2.new(1, 0, 0, 48), - ZIndex = 6, - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size24, - Text = "", - TextColor3 = Color3.new(1, 1, 1), - TextWrap = true, - TextXAlignment = Enum.TextXAlignment.Left, - TextYAlignment = Enum.TextYAlignment.Top - }) - }) - }), - New("Frame", "Sets", { - BackgroundTransparency = 1, - Position = UDim2.new(0, 0, 0, 5), - Size = UDim2.new(0.23, 0, 1, -5), - ZIndex = 6, - New("Frame", "Line", { - BackgroundColor3 = Color3.new(1, 1, 1), - BackgroundTransparency = 0.7, - BorderSizePixel = 0, - Position = UDim2.new(1, -3, 0.06, 0), - Size = UDim2.new(0, 3, 0.9, 0), - ZIndex = 6 - }), - New("TextLabel", "SetsHeader", { - BackgroundTransparency = 1, - Size = UDim2.new(0, 47, 0, 24), - ZIndex = 6, - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size24, - Text = "Sets", - TextColor3 = Color3.new(1, 1, 1), - TextXAlignment = Enum.TextXAlignment.Left, - TextYAlignment = Enum.TextYAlignment.Top - }) - }) - }) + + local setPanel = Instance.new "Frame" + setPanel.Name = "SetPanel" + setPanel.Active = true + setPanel.BackgroundTransparency = 1 + if position then + setPanel.Position = position + else + setPanel.Position = UDim2.new(0.2, 29, 0.1, 24) + end + if size then + setPanel.Size = size + else + setPanel.Size = UDim2.new(0.6, -58, 0.64, 0) + end + setPanel.Style = Enum.FrameStyle.RobloxRound + setPanel.ZIndex = 6 + setPanel.Parent = setGui + + -- Children of SetPanel + local itemPreview = Instance.new "Frame" + itemPreview.Name = "ItemPreview" + itemPreview.BackgroundTransparency = 1 + itemPreview.Position = UDim2.new(0.8, 5, 0.085, 0) + itemPreview.Size = UDim2.new(0.21, 0, 0.9, 0) + itemPreview.ZIndex = 6 + itemPreview.Parent = setPanel + + -- Children of ItemPreview + local textPanel = Instance.new "Frame" + textPanel.Name = "TextPanel" + textPanel.BackgroundTransparency = 1 + textPanel.Position = UDim2.new(0, 0, 0.45, 0) + textPanel.Size = UDim2.new(1, 0, 0.55, 0) + textPanel.ZIndex = 6 + textPanel.Parent = itemPreview + + -- Children of TextPanel + local rolloverText = Instance.new "TextLabel" + rolloverText.Name = "RolloverText" + rolloverText.BackgroundTransparency = 1 + rolloverText.Size = UDim2.new(1, 0, 0, 48) + rolloverText.ZIndex = 6 + rolloverText.Font = Enum.Font.ArialBold + rolloverText.FontSize = Enum.FontSize.Size24 + rolloverText.Text = "" + rolloverText.TextColor3 = Color3.new(1, 1, 1) + rolloverText.TextWrap = true + rolloverText.TextXAlignment = Enum.TextXAlignment.Left + rolloverText.TextYAlignment = Enum.TextYAlignment.Top + rolloverText.Parent = textPanel + + local largePreview = Instance.new "ImageLabel" + largePreview.Name = "LargePreview" + largePreview.BackgroundTransparency = 1 + largePreview.Image = "" + largePreview.Size = UDim2.new(1, 0, 0, 170) + largePreview.ZIndex = 6 + largePreview.Parent = itemPreview + + local sets = Instance.new "Frame" + sets.Name = "Sets" + sets.BackgroundTransparency = 1 + sets.Position = UDim2.new(0, 0, 0, 5) + sets.Size = UDim2.new(0.23, 0, 1, -5) + sets.ZIndex = 6 + sets.Parent = setPanel + + -- Children of Sets + local line = Instance.new "Frame" + line.Name = "Line" + line.BackgroundColor3 = Color3.new(1, 1, 1) + line.BackgroundTransparency = 0.7 + line.BorderSizePixel = 0 + line.Position = UDim2.new(1, -3, 0.06, 0) + line.Size = UDim2.new(0, 3, 0.9, 0) + line.ZIndex = 6 + line.Parent = sets + local setsLists, controlFrame = t.CreateTrueScrollingFrame() setsLists.Size = UDim2.new(1, -6, 0.94, 0) setsLists.Position = UDim2.new(0, 0, 0.06, 0) setsLists.BackgroundTransparency = 1 setsLists.Name = "SetsLists" setsLists.ZIndex = 6 - setsLists.Parent = setPanel.Sets + setsLists.Parent = sets drillDownSetZIndex(controlFrame, 7) + + local setsHeader = Instance.new "TextLabel" + setsHeader.Name = "SetsHeader" + setsHeader.BackgroundTransparency = 1 + setsHeader.Size = UDim2.new(0, 47, 0, 24) + setsHeader.ZIndex = 6 + setsHeader.Font = Enum.Font.ArialBold + setsHeader.FontSize = Enum.FontSize.Size24 + setsHeader.Text = "Sets" + setsHeader.TextColor3 = Color3.new(1, 1, 1) + setsHeader.TextXAlignment = Enum.TextXAlignment.Left + setsHeader.TextYAlignment = Enum.TextYAlignment.Top + setsHeader.Parent = sets + + local cancelButton = Instance.new "TextButton" + cancelButton.Name = "CancelButton" + cancelButton.Position = UDim2.new(1, -32, 0, -2) + cancelButton.Size = UDim2.new(0, 34, 0, 34) + cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault + cancelButton.ZIndex = 6 + cancelButton.Text = "" + cancelButton.Modal = true + cancelButton.Parent = setPanel + + -- Children of Cancel Button + local cancelImage = Instance.new "ImageLabel" + cancelImage.Name = "CancelImage" + cancelImage.BackgroundTransparency = 1 + cancelImage.Image = "http://www.roblox.com/asset?id=54135717" + cancelImage.Position = UDim2.new(0, -2, 0, -2) + cancelImage.Size = UDim2.new(0, 16, 0, 16) + cancelImage.ZIndex = 6 + cancelImage.Parent = cancelButton + return setGui end - local createSetButton - createSetButton = function(text) - local setButton = New("TextButton", { - Text = text or "", - AutoButtonColor = false, - BackgroundTransparency = 1, - BackgroundColor3 = Color3.new(1, 1, 1), - BorderSizePixel = 0, - Size = UDim2.new(1, -5, 0, 18), - ZIndex = 6, - Visible = false, - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - TextColor3 = Color3.new(1, 1, 1), - TextXAlignment = Enum.TextXAlignment.Left - }) + + local function createSetButton(text) + local setButton = Instance.new "TextButton" + + if text then + setButton.Text = text + else + setButton.Text = "" + end + + setButton.AutoButtonColor = false + setButton.BackgroundTransparency = 1 + setButton.BackgroundColor3 = Color3.new(1, 1, 1) + setButton.BorderSizePixel = 0 + setButton.Size = UDim2.new(1, -5, 0, 18) + setButton.ZIndex = 6 + setButton.Visible = false + setButton.Font = Enum.Font.Arial + setButton.FontSize = Enum.FontSize.Size18 + setButton.TextColor3 = Color3.new(1, 1, 1) + setButton.TextXAlignment = Enum.TextXAlignment.Left + return setButton end - local buildSetButton - buildSetButton = function(name, setId, _, _, _) + + local function buildSetButton(name, setId, _, _, _) local button = createSetButton(name) button.Text = name button.Name = "SetButton" button.Visible = true - New("IntValue", "SetId", { - Value = setId, - Parent = button - }) - New("StringValue", "SetName", { - Value = name, - Parent = button - }) + + local setValue = Instance.new "IntValue" + setValue.Name = "SetId" + setValue.Value = setId + setValue.Parent = button + + local setName = Instance.new "StringValue" + setName.Name = "SetName" + setName.Value = name + setName.Parent = button + return button end - local processCategory - processCategory = function(sets) - local setButtons = { } + + local function processCategory(sets) + local setButtons = {} local numSkipped = 0 for i = 1, #sets do if not showAdminCategories and sets[i].Name == "Beta" then numSkipped = numSkipped + 1 else - setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets) + setButtons[i - numSkipped] = + buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets) end end return setButtons end - local handleResize - handleResize = function() - wait() - local _with_0 = setGui.SetPanel.ItemPreview - _with_0.LargePreview.Size = UDim2.new(1, 0, 0, _with_0.AbsoluteSize.X) - _with_0.LargePreview.Position = UDim2.new(0.5, -_with_0.LargePreview.AbsoluteSize.X / 2, 0, 0) - _with_0.TextPanel.Position = UDim2.new(0, 0, 0, _with_0.LargePreview.AbsoluteSize.Y) - _with_0.TextPanel.Size = UDim2.new(1, 0, 0, _with_0.AbsoluteSize.Y - _with_0.LargePreview.AbsoluteSize.Y) - return _with_0 + + local function handleResize() + wait() -- neccessary to insure heartbeat happened + + local itemPreview = setGui.SetPanel.ItemPreview + + itemPreview.LargePreview.Size = UDim2.new(1, 0, 0, itemPreview.AbsoluteSize.X) + itemPreview.LargePreview.Position = UDim2.new(0.5, -itemPreview.LargePreview.AbsoluteSize.X / 2, 0, 0) + itemPreview.TextPanel.Position = UDim2.new(0, 0, 0, itemPreview.LargePreview.AbsoluteSize.Y) + itemPreview.TextPanel.Size = + UDim2.new(1, 0, 0, itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y) end - local makeInsertAssetButton - makeInsertAssetButton = function() - local insertAssetButtonExample = New("Frame", "InsertAssetButtonExample", { - Position = UDim2.new(0, 128, 0, 64), - Size = UDim2.new(0, 64, 0, 64), - BackgroundTransparency = 1, - ZIndex = 6, - Visible = false, - New("IntValue", "AssetId", { - Value = 0 - }), - New("StringValue", "AssetName", { - Value = "" - }), - New("TextButton", "Button", { - Text = "", - Style = Enum.ButtonStyle.RobloxButton, - Position = UDim2.new(0.025, 0, 0.025, 0), - Size = UDim2.new(0.95, 0, 0.95, 0), - ZIndex = 6, - New("ImageLabel", "ButtonImage", { - Image = "", - Position = UDim2.new(0, -7, 0, -7), - Size = UDim2.new(1, 14, 1, 14), - BackgroundTransparency = 1, - ZIndex = 7 - }) - }) - }) - do - local _with_0 = insertAssetButtonExample.button.ButtonImage:clone() - _with_0.Name = "ConfigIcon" - _with_0.Visible = false - _with_0.Position = UDim2.new(1, -23, 1, -24) - _with_0.Size = UDim2.new(0, 16, 0, 16) - _with_0.Image = "" - _with_0.ZIndex = 6 - _with_0.Parent = insertAssetButtonExample - end + + local function makeInsertAssetButton() + local insertAssetButtonExample = Instance.new "Frame" + insertAssetButtonExample.Name = "InsertAssetButtonExample" + insertAssetButtonExample.Position = UDim2.new(0, 128, 0, 64) + insertAssetButtonExample.Size = UDim2.new(0, 64, 0, 64) + insertAssetButtonExample.BackgroundTransparency = 1 + insertAssetButtonExample.ZIndex = 6 + insertAssetButtonExample.Visible = false + + local assetId = Instance.new "IntValue" + assetId.Name = "AssetId" + assetId.Value = 0 + assetId.Parent = insertAssetButtonExample + + local assetName = Instance.new "StringValue" + assetName.Name = "AssetName" + assetName.Value = "" + assetName.Parent = insertAssetButtonExample + + local button = Instance.new "TextButton" + button.Name = "Button" + button.Text = "" + button.Style = Enum.ButtonStyle.RobloxButton + button.Position = UDim2.new(0.025, 0, 0.025, 0) + button.Size = UDim2.new(0.95, 0, 0.95, 0) + button.ZIndex = 6 + button.Parent = insertAssetButtonExample + + local buttonImage = Instance.new "ImageLabel" + buttonImage.Name = "ButtonImage" + buttonImage.Image = "" + buttonImage.Position = UDim2.new(0, -7, 0, -7) + buttonImage.Size = UDim2.new(1, 14, 1, 14) + buttonImage.BackgroundTransparency = 1 + buttonImage.ZIndex = 7 + buttonImage.Parent = button + + local configIcon = buttonImage:clone() + configIcon.Name = "ConfigIcon" + configIcon.Visible = false + configIcon.Position = UDim2.new(1, -23, 1, -24) + configIcon.Size = UDim2.new(0, 16, 0, 16) + configIcon.Image = "" + configIcon.ZIndex = 6 + configIcon.Parent = insertAssetButtonExample + return insertAssetButtonExample end - local showLargePreview - showLargePreview = function(insertButton) - if insertButton:FindFirstChild("AssetId") then + + local function showLargePreview(insertButton) + if insertButton:FindFirstChild "AssetId" then delay(0, function() game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)) - setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value) + setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl + .. tostring(insertButton.AssetId.Value) end) end - if insertButton:FindFirstChild("AssetName") then + if insertButton:FindFirstChild "AssetName" then setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value end end - local selectTerrainShape - selectTerrainShape = function(shape) + + local function selectTerrainShape(shape) if currTerrainDropDownFrame then - return objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape) + objectSelected( + tostring(currTerrainDropDownFrame.AssetName.Value), + tonumber(currTerrainDropDownFrame.AssetId.Value), + shape + ) end end - local createTerrainTypeButton - createTerrainTypeButton = function(name, parent) - local dropDownTextButton = New("TextButton", tostring(name) .. "Button", { - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size14, - BorderSizePixel = 0, - TextColor3 = Color3.new(1, 1, 1), - Text = name, - TextXAlignment = Enum.TextXAlignment.Left, - BackgroundTransparency = 1, - ZIndex = parent.ZIndex + 1, - Size = UDim2.new(0, parent.Size.X.Offset - 2, 0, 16), - Position = UDim2.new(0, 1, 0, 0) - }) + + local function createTerrainTypeButton(name, parent) + local dropDownTextButton = Instance.new "TextButton" + dropDownTextButton.Name = name .. "Button" + dropDownTextButton.Font = Enum.Font.ArialBold + dropDownTextButton.FontSize = Enum.FontSize.Size14 + dropDownTextButton.BorderSizePixel = 0 + dropDownTextButton.TextColor3 = Color3.new(1, 1, 1) + dropDownTextButton.Text = name + dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left + dropDownTextButton.BackgroundTransparency = 1 + dropDownTextButton.ZIndex = parent.ZIndex + 1 + dropDownTextButton.Size = UDim2.new(0, parent.Size.X.Offset - 2, 0, 16) + dropDownTextButton.Position = UDim2.new(0, 1, 0, 0) + dropDownTextButton.MouseEnter:connect(function() dropDownTextButton.BackgroundTransparency = 0 dropDownTextButton.TextColor3 = Color3.new(0, 0, 0) end) + dropDownTextButton.MouseLeave:connect(function() dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new(1, 1, 1) end) + dropDownTextButton.MouseButton1Click:connect(function() dropDownTextButton.BackgroundTransparency = 1 dropDownTextButton.TextColor3 = Color3.new(1, 1, 1) - if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then + if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA "GuiObject" then dropDownTextButton.Parent.Visible = false end - return selectTerrainShape(terrainShapeMap[dropDownTextButton.Text]) + selectTerrainShape(terrainShapeMap[dropDownTextButton.Text]) end) + return dropDownTextButton end - local createTerrainDropDownMenu - createTerrainDropDownMenu = function(zIndex) - local dropDown = New("Frame", "TerrainDropDown", { - BackgroundColor3 = Color3.new(0, 0, 0), - BorderColor3 = Color3.new(1, 0, 0), - Size = UDim2.new(0, 200, 0, 0), - Visible = false, - ZIndex = zIndex, - Parent = setGui - }) + + local function createTerrainDropDownMenu(zIndex) + local dropDown = Instance.new "Frame" + dropDown.Name = "TerrainDropDown" + dropDown.BackgroundColor3 = Color3.new(0, 0, 0) + dropDown.BorderColor3 = Color3.new(1, 0, 0) + dropDown.Size = UDim2.new(0, 200, 0, 0) + dropDown.Visible = false + dropDown.ZIndex = zIndex + dropDown.Parent = setGui + for i = 1, #terrainShapes do local shapeButton = createTerrainTypeButton(terrainShapes[i], dropDown) shapeButton.Position = UDim2.new(0, 1, 0, (i - 1) * shapeButton.Size.Y.Offset) shapeButton.Parent = dropDown dropDown.Size = UDim2.new(0, 200, 0, dropDown.Size.Y.Offset + shapeButton.Size.Y.Offset) end - return dropDown.MouseLeave:connect(function() + + dropDown.MouseLeave:connect(function() dropDown.Visible = false end) end - local createDropDownMenuButton - createDropDownMenuButton = function(parent) - local dropDownButton = New("ImageButton", { - Name = "DropDownButton", - Image = "http://www.roblox.com/asset/?id=67581509", - BackgroundTransparency = 1, - Size = UDim2.new(0, 16, 0, 16), - Position = UDim2.new(1, -24, 0, 6), - ZIndex = parent.ZIndex + 2, - Parent = parent - }) - if not setGui:FindFirstChild("TerrainDropDown") then + + local function createDropDownMenuButton(parent) + local dropDownButton = Instance.new "ImageButton" + dropDownButton.Name = "DropDownButton" + dropDownButton.Image = "http://www.roblox.com/asset/?id=67581509" + dropDownButton.BackgroundTransparency = 1 + dropDownButton.Size = UDim2.new(0, 16, 0, 16) + dropDownButton.Position = UDim2.new(1, -24, 0, 6) + dropDownButton.ZIndex = parent.ZIndex + 2 + dropDownButton.Parent = parent + + if not setGui:FindFirstChild "TerrainDropDown" then createTerrainDropDownMenu(8) end - return dropDownButton.MouseButton1Click:connect(function() + + dropDownButton.MouseButton1Click:connect(function() setGui.TerrainDropDown.Visible = true setGui.TerrainDropDown.Position = UDim2.new(0, parent.AbsolutePosition.X, 0, parent.AbsolutePosition.Y) currTerrainDropDownFrame = parent end) end - local buildInsertButton - buildInsertButton = function() + + local function buildInsertButton() local insertButton = makeInsertAssetButton() insertButton.Name = "InsertAssetButton" insertButton.Visible = true + if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then createDropDownMenuButton(insertButton) end + local lastEnter = nil local mouseEnterCon = insertButton.MouseEnter:connect(function() lastEnter = insertButton - return delay(0.1, function() + delay(0.1, function() if lastEnter == insertButton then - return showLargePreview(insertButton) + showLargePreview(insertButton) end end) end) return insertButton, mouseEnterCon end - local realignButtonGrid - realignButtonGrid = function(columns) + + local function realignButtonGrid(columns) local x = 0 local y = 0 for i = 1, #insertButtons do @@ -2545,8 +2974,8 @@ t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, end end end - local setInsertButtonImageBehavior - setInsertButtonImageBehavior = function(insertFrame, visible, name, assetId) + + local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId) if visible then insertFrame.AssetName.Value = name insertFrame.AssetId.Value = assetId @@ -2557,33 +2986,40 @@ t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId end) end - table.insert(insertButtonCons, insertFrame.Button.MouseButton1Click:connect(function() - local isWaterSelected = name == "Water" and (Data.Category[Data.CurrentCategory].SetName == "High Scalability") - waterGui.Visible = isWaterSelected - return objectSelected(name, (function() + table.insert( + insertButtonCons, + insertFrame.Button.MouseButton1Click:connect(function() + -- special case for water, show water selection gui + local isWaterSelected = (name == "Water") + and (Data.Category[Data.CurrentCategory].SetName == "High Scalability") + waterGui.Visible = isWaterSelected if isWaterSelected then - return tonumber(assetId), nil + objectSelected(name, tonumber(assetId), nil) else - return tonumber(assetId) + objectSelected(name, tonumber(assetId)) end - end)()) - end)) + end) + ) insertFrame.Visible = true else insertFrame.Visible = false end end - local loadSectionOfItems - loadSectionOfItems = function(setGui, rows, columns) + + local function loadSectionOfItems(setGui, rows, columns) local pageSize = rows * columns + if arrayPosition > #contents then return end + local origArrayPos = arrayPosition + for _ = 1, pageSize + 1 do if arrayPosition >= #contents + 1 then break end + local buttonCon insertButtons[arrayPosition], buttonCon = buildInsertButton() table.insert(insertButtonCons, buttonCon) @@ -2591,12 +3027,18 @@ t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, arrayPosition = arrayPosition + 1 end realignButtonGrid(columns) + + -- local indexCopy = origArrayPos for index = origArrayPos, arrayPosition do if insertButtons[index] then if contents[index] then - if contents[index].Name == "Water" and Data.Category[Data.CurrentCategory].SetName == "High Scalability" then - insertButtons[index]:FindFirstChild("DropDownButton", true):Destroy() + -- we don't want water to have a drop down button + if contents[index].Name == "Water" then + if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then + insertButtons[index]:FindFirstChild("DropDownButton", true):Destroy() + end end + local assetId if useAssetVersionId then assetId = contents[index].AssetVersionId @@ -2610,15 +3052,19 @@ t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, else break end + -- indexCopy = index end end - local setSetIndex - setSetIndex = function() + + local function setSetIndex() Data.Category[Data.CurrentCategory].Index = 0 + local rows = 7 local columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X / buttonWidth) + contents = Data.Category[Data.CurrentCategory].Contents if contents then + -- remove our buttons and their connections for i = 1, #insertButtons do insertButtons[i]:remove() end @@ -2627,113 +3073,118 @@ t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, insertButtonCons[i]:disconnect() end end - insertButtonCons = { } - insertButtons = { } + insertButtonCons = {} + insertButtons = {} + arrayPosition = 1 - return loadSectionOfItems(setGui, rows, columns) + loadSectionOfItems(setGui, rows, columns) end end - local selectSet - selectSet = function(button, setName, setId, _) - if button and (Data.Category[Data.CurrentCategory] ~= nil) then - do - local _with_0 = Data.Category[Data.CurrentCategory] - if button ~= _with_0.Button then - _with_0.Button = button - if not (SetCache[setId] ~= nil) then - SetCache[setId] = game:GetService("InsertService"):GetCollection(setId) - end - _with_0.Contents = SetCache[setId] - _with_0.SetName = setName - _with_0.SetId = setId + + local function selectSet(button, setName, setId, _) + if button and Data.Category[Data.CurrentCategory] ~= nil then + if button ~= Data.Category[Data.CurrentCategory].Button then + Data.Category[Data.CurrentCategory].Button = button + + if SetCache[setId] == nil then + SetCache[setId] = game:GetService("InsertService"):GetCollection(setId) end + Data.Category[Data.CurrentCategory].Contents = SetCache[setId] + + Data.Category[Data.CurrentCategory].SetName = setName + Data.Category[Data.CurrentCategory].SetId = setId end - return setSetIndex() + setSetIndex() end end - local selectCategoryPage - selectCategoryPage = function(buttons, _) + + local function selectCategoryPage(buttons, _) if buttons ~= Data.CurrentCategory then if Data.CurrentCategory then for _, button in pairs(Data.CurrentCategory) do button.Visible = false end end + Data.CurrentCategory = buttons - if not (Data.Category[Data.CurrentCategory] ~= nil) then - Data.Category[Data.CurrentCategory] = { } + if Data.Category[Data.CurrentCategory] == nil then + Data.Category[Data.CurrentCategory] = {} if #buttons > 0 then - return selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0) + selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0) end else - local _with_0 = Data.Category[Data.CurrentCategory] - _with_0.Button = nil - selectSet(_with_0.ButtonFrame, _with_0.SetName, _with_0.SetId, _with_0.Index) - return _with_0 + Data.Category[Data.CurrentCategory].Button = nil + selectSet( + Data.Category[Data.CurrentCategory].ButtonFrame, + Data.Category[Data.CurrentCategory].SetName, + Data.Category[Data.CurrentCategory].SetId, + Data.Category[Data.CurrentCategory].Index + ) end end end - local selectCategory - selectCategory = function(category) - return selectCategoryPage(category, 0) + + local function selectCategory(category) + selectCategoryPage(category, 0) end - local resetAllSetButtonSelection - resetAllSetButtonSelection = function() + + local function resetAllSetButtonSelection() local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren() for i = 1, #setButtons do - do - local _with_0 = setButtons[i] - if _with_0:IsA("TextButton") then - _with_0.Selected = false - _with_0.BackgroundTransparency = 1 - _with_0.TextColor3 = Color3.new(1, 1, 1) - _with_0.BackgroundColor3 = Color3.new(1, 1, 1) - end + if setButtons[i]:IsA "TextButton" then + setButtons[i].Selected = false + setButtons[i].BackgroundTransparency = 1 + setButtons[i].TextColor3 = Color3.new(1, 1, 1) + setButtons[i].BackgroundColor3 = Color3.new(1, 1, 1) end end end - local populateSetsFrame - populateSetsFrame = function() + + local function populateSetsFrame() local currRow = 0 for i = 1, #userCategoryButtons do - do - local button = userCategoryButtons[i] - button.Visible = true - button.Position = UDim2.new(0, 5, 0, currRow * button.Size.Y.Offset) - button.Parent = setGui.SetPanel.Sets.SetsLists - if i == 1 then - button.Selected = true - button.BackgroundColor3 = Color3.new(0, 204 / 255, 0) - button.TextColor3 = Color3.new(0, 0, 0) - button.BackgroundTransparency = 0 - end - button.MouseEnter:connect(function() - if not button.Selected then - button.BackgroundTransparency = 0 - button.TextColor3 = Color3.new(0, 0, 0) - end - end) - button.MouseLeave:connect(function() - if not button.Selected then - button.BackgroundTransparency = 1 - button.TextColor3 = Color3.new(1, 1, 1) - end - end) - button.MouseButton1Click:connect(function() - resetAllSetButtonSelection() - button.Selected = not button.Selected - button.BackgroundColor3 = Color3.new(0, 204 / 255, 0) - button.TextColor3 = Color3.new(0, 0, 0) - button.BackgroundTransparency = 0 - return selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0) - end) - currRow = currRow + 1 + local button = userCategoryButtons[i] + button.Visible = true + button.Position = UDim2.new(0, 5, 0, currRow * button.Size.Y.Offset) + button.Parent = setGui.SetPanel.Sets.SetsLists + + if i == 1 then -- we will have this selected by default, so show it + button.Selected = true + button.BackgroundColor3 = Color3.new(0, 204 / 255, 0) + button.TextColor3 = Color3.new(0, 0, 0) + button.BackgroundTransparency = 0 end + + button.MouseEnter:connect(function() + if not button.Selected then + button.BackgroundTransparency = 0 + button.TextColor3 = Color3.new(0, 0, 0) + end + end) + button.MouseLeave:connect(function() + if not button.Selected then + button.BackgroundTransparency = 1 + button.TextColor3 = Color3.new(1, 1, 1) + end + end) + button.MouseButton1Click:connect(function() + resetAllSetButtonSelection() + button.Selected = not button.Selected + button.BackgroundColor3 = Color3.new(0, 204 / 255, 0) + button.TextColor3 = Color3.new(0, 0, 0) + button.BackgroundTransparency = 0 + selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0) + end) + + currRow = currRow + 1 end + local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren() + + -- set first category as loaded for default if buttons then for i = 1, #buttons do - if buttons[i]:IsA("TextButton") then + if buttons[i]:IsA "TextButton" then selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0) selectCategory(userCategoryButtons) break @@ -2741,29 +3192,32 @@ t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, end end end + setGui = createSetGui() waterGui, waterTypeChangedEvent = createWaterGui() waterGui.Position = UDim2.new(0, 55, 0, 0) waterGui.Parent = setGui - setGui.Changed:connect(function(prop) + setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size if prop == "AbsoluteSize" then handleResize() - return setSetIndex() + setSetIndex() end end) + local scrollFrame, controlFrame = t.CreateTrueScrollingFrame() - scrollFrame.Name = "ItemsFrame" scrollFrame.Size = UDim2.new(0.54, 0, 0.85, 0) scrollFrame.Position = UDim2.new(0.24, 0, 0.085, 0) + scrollFrame.Name = "ItemsFrame" scrollFrame.ZIndex = 6 scrollFrame.Parent = setGui.SetPanel scrollFrame.BackgroundTransparency = 1 + drillDownSetZIndex(controlFrame, 7) + controlFrame.Parent = setGui.SetPanel controlFrame.Position = UDim2.new(0.76, 5, 0, 0) + local debounce = false - local rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y / buttonHeight) - local columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X / buttonWidth) controlFrame.ScrollBottom.Changed:connect(function(_) if controlFrame.ScrollBottom.Value == true then if debounce then @@ -2774,65 +3228,84 @@ t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, debounce = false end end) - local userData = { } + + local userData = {} for id = 1, #userIdsForSets do local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id]) if newUserData and #newUserData > 2 then + -- start at #3 to skip over My Decals and My Models for each account for category = 3, #newUserData do - table.insert(userData, (function() - if newUserData[category].Name == "High Scalability" then - return 1, newUserData[category] - else - return newUserData[category] - end - end)()) + if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first + table.insert(userData, 1, newUserData[category]) + else + table.insert(userData, newUserData[category]) + end end end end if userData then userCategoryButtons = processCategory(userData) end + + rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y / buttonHeight) + columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X / buttonWidth) + populateSetsFrame() + + --[[local insertPanelCloseCon = ]] setGui.SetPanel.CancelButton.MouseButton1Click:connect(function() setGui.SetPanel.Visible = false - if dialogClosed ~= nil then - return dialogClosed() + if dialogClosed then + dialogClosed() end - return nil end) - local setVisibilityFunction - setVisibilityFunction = function(visible) - setGui.SetPanel.Visible = not not visible - end - local getVisibilityFunction - getVisibilityFunction = function() - if (function() - if setGui ~= nil then - return setGui:FindFirstChild("SetPanel") - end - return nil - end)() then - return setGui.SetPanel.Visible + + local setVisibilityFunction = function(visible) + if visible then + setGui.SetPanel.Visible = true + else + setGui.SetPanel.Visible = false end + end + + local getVisibilityFunction = function() + if setGui then + if setGui:FindFirstChild "SetPanel" then + return setGui.SetPanel.Visible + end + end + return false end + return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent end + t.CreateTerrainMaterialSelector = function(size, position) - local terrainMaterialSelectionChanged = Instance.new("BindableEvent") + local terrainMaterialSelectionChanged = Instance.new "BindableEvent" terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged" - local selectedButton - local frame = New("Frame", "TerrainMaterialSelector", { - Size = size or UDim2.new(0, 245, 0, 230), - BorderSizePixel = 0, - BackgroundColor3 = Color3.new(0, 0, 0), - Active = true - }) + + local selectedButton = nil + + local frame = Instance.new "Frame" + frame.Name = "TerrainMaterialSelector" + if size then + frame.Size = size + else + frame.Size = UDim2.new(0, 245, 0, 230) + end if position then frame.Position = position end + frame.BorderSizePixel = 0 + frame.BackgroundColor3 = Color3.new(0, 0, 0) + frame.Active = true + terrainMaterialSelectionChanged.Parent = frame - local materialToImageMap = { } + + local waterEnabled = true -- todo: turn this on when water is ready + + local materialToImageMap = {} local materialNames = { "Grass", "Sand", @@ -2850,380 +3323,442 @@ t.CreateTerrainMaterialSelector = function(size, position) "Concrete", "Plastic (red)", "Plastic (blue)", - "Water" } + if waterEnabled then + table.insert(materialNames, "Water") + end local currentMaterial = 1 - local getEnumFromName - getEnumFromName = function(choice) - for i, v in ipairs(materialNames) do - if v == choice then - return i - end + + function getEnumFromName(choice) + if choice == "Grass" then + return 1 + end + if choice == "Sand" then + return 2 + end + if choice == "Erase" then + return 0 + end + if choice == "Brick" then + return 3 + end + if choice == "Granite" then + return 4 + end + if choice == "Asphalt" then + return 5 + end + if choice == "Iron" then + return 6 + end + if choice == "Aluminum" then + return 7 + end + if choice == "Gold" then + return 8 + end + if choice == "Plank" then + return 9 + end + if choice == "Log" then + return 10 + end + if choice == "Gravel" then + return 11 + end + if choice == "Cinder Block" then + return 12 + end + if choice == "Stone Wall" then + return 13 + end + if choice == "Concrete" then + return 14 + end + if choice == "Plastic (red)" then + return 15 + end + if choice == "Plastic (blue)" then + return 16 + end + if choice == "Water" then + return 17 end end - local getNameFromEnum - getNameFromEnum = function(choice) - if Enum.CellMaterial.Grass == choice or 1 == choice then + + function getNameFromEnum(choice) + if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass" - elseif Enum.CellMaterial.Sand == choice or 2 == choice then + elseif choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" - elseif Enum.CellMaterial.Empty == choice or 0 == choice then + elseif choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" - elseif Enum.CellMaterial.Brick == choice or 3 == choice then + elseif choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" - elseif Enum.CellMaterial.Granite == choice or 4 == choice then + elseif choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" - elseif Enum.CellMaterial.Asphalt == choice or 5 == choice then + elseif choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" - elseif Enum.CellMaterial.Iron == choice or 6 == choice then + elseif choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" - elseif Enum.CellMaterial.Aluminum == choice or 7 == choice then + elseif choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" - elseif Enum.CellMaterial.Gold == choice or 8 == choice then + elseif choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" - elseif Enum.CellMaterial.WoodPlank == choice or 9 == choice then + elseif choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" - elseif Enum.CellMaterial.WoodLog == choice or 10 == choice then + elseif choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" - elseif Enum.CellMaterial.Gravel == choice or 11 == choice then + elseif choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" - elseif Enum.CellMaterial.CinderBlock == choice or 12 == choice then + elseif choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" - elseif Enum.CellMaterial.MossyStone == choice or 13 == choice then + elseif choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" - elseif Enum.CellMaterial.Cement == choice or 14 == choice then + elseif choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" - elseif Enum.CellMaterial.RedPlastic == choice or 15 == choice then + elseif choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" - elseif Enum.CellMaterial.BluePlastic == choice or 16 == choice then + elseif choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" - elseif Enum.CellMaterial.Water == choice or 17 == choice then - return "Water" + end + + if waterEnabled then + if choice == Enum.CellMaterial.Water or choice == 17 then + return "Water" + end end end - local updateMaterialChoice - updateMaterialChoice = function(choice) + + local function updateMaterialChoice(choice) currentMaterial = getEnumFromName(choice) - return terrainMaterialSelectionChanged:Fire(currentMaterial) + terrainMaterialSelectionChanged:Fire(currentMaterial) end + + -- we so need a better way to do this for _, v in pairs(materialNames) do - materialToImageMap[v] = { } - materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=" .. tostring((function() - if "Grass" == v then - return 56563112 - elseif "Sand" == v then - return 62356652 - elseif "Brick" == v then - return 65961537 - elseif "Granite" == v then - return 67532153 - elseif "Asphalt" == v then - return 67532038 - elseif "Iron" == v then - return 67532093 - elseif "Aluminum" == v then - return 67531995 - elseif "Gold" == v then - return 67532118 - elseif "Plastic (red)" == v then - return 67531848 - elseif "Plastic (blue)" == v then - return 67531924 - elseif "Plank" == v then - return 67532015 - elseif "Log" == v then - return 67532051 - elseif "Gravel" == v then - return 67532206 - elseif "Cinder Block" == v then - return 67532103 - elseif "Stone Wall" == v then - return 67531804 - elseif "Concrete" == v then - return 67532059 - elseif "Water" == v then - return 81407474 - else - return 66887593 - end - end)()) + materialToImageMap[v] = {} + if v == "Grass" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=56563112" + elseif v == "Sand" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=62356652" + elseif v == "Brick" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=65961537" + elseif v == "Granite" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532153" + elseif v == "Asphalt" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532038" + elseif v == "Iron" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532093" + elseif v == "Aluminum" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531995" + elseif v == "Gold" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532118" + elseif v == "Plastic (red)" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531848" + elseif v == "Plastic (blue)" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531924" + elseif v == "Plank" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532015" + elseif v == "Log" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532051" + elseif v == "Gravel" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532206" + elseif v == "Cinder Block" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532103" + elseif v == "Stone Wall" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67531804" + elseif v == "Concrete" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=67532059" + elseif v == "Water" then + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=81407474" + else + materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=66887593" -- fill in the rest here!! + end end + local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil, "grid") scrollFrame.Size = UDim2.new(0.85, 0, 1, 0) scrollFrame.Position = UDim2.new(0, 0, 0, 0) scrollFrame.Parent = frame + scrollUp.Parent = frame scrollUp.Visible = true scrollUp.Position = UDim2.new(1, -19, 0, 0) + scrollDown.Parent = frame scrollDown.Visible = true scrollDown.Position = UDim2.new(1, -19, 1, -17) - local goToNewMaterial - goToNewMaterial = function(buttonWrap, materialName) + + local function goToNewMaterial(buttonWrap, materialName) updateMaterialChoice(materialName) buttonWrap.BackgroundTransparency = 0 selectedButton.BackgroundTransparency = 1 selectedButton = buttonWrap end - local createMaterialButton - createMaterialButton = function(name) - local buttonWrap = New("TextButton", tostring(name), { - Text = "", - Size = UDim2.new(0, 32, 0, 32), - BackgroundColor3 = Color3.new(1, 1, 1), - BorderSizePixel = 0, - BackgroundTransparency = 1, - AutoButtonColor = false, - New("ImageButton", tostring(name), { - AutoButtonColor = false, - BackgroundTransparency = 1, - Size = UDim2.new(0, 30, 0, 30), - Position = UDim2.new(0, 1, 0, 1), - Image = materialToImageMap[name].Regular - }), - New("NumberValue", "EnumType", { - Value = 0 - }) - }) - do - local _with_0 = buttonWrap.ImageButton - _with_0.MouseEnter:connect(function() - buttonWrap.BackgroundTransparency = 0 - end) - _with_0.MouseLeave:connect(function() - if selectedButton ~= buttonWrap then - buttonWrap.BackgroundTransparency = 1 - end - end) - _with_0.MouseButton1Click:connect(function() - if selectedButton ~= buttonWrap then - return goToNewMaterial(buttonWrap, tostring(name)) - end - end) - end + + local function createMaterialButton(name) + local buttonWrap = Instance.new "TextButton" + buttonWrap.Text = "" + buttonWrap.Size = UDim2.new(0, 32, 0, 32) + buttonWrap.BackgroundColor3 = Color3.new(1, 1, 1) + buttonWrap.BorderSizePixel = 0 + buttonWrap.BackgroundTransparency = 1 + buttonWrap.AutoButtonColor = false + buttonWrap.Name = tostring(name) + + local imageButton = Instance.new "ImageButton" + imageButton.AutoButtonColor = false + imageButton.BackgroundTransparency = 1 + imageButton.Size = UDim2.new(0, 30, 0, 30) + imageButton.Position = UDim2.new(0, 1, 0, 1) + imageButton.Name = tostring(name) + imageButton.Parent = buttonWrap + imageButton.Image = materialToImageMap[name].Regular + + local enumType = Instance.new "NumberValue" + enumType.Name = "EnumType" + enumType.Parent = buttonWrap + enumType.Value = 0 + + imageButton.MouseEnter:connect(function() + buttonWrap.BackgroundTransparency = 0 + end) + imageButton.MouseLeave:connect(function() + if selectedButton ~= buttonWrap then + buttonWrap.BackgroundTransparency = 1 + end + end) + imageButton.MouseButton1Click:connect(function() + if selectedButton ~= buttonWrap then + goToNewMaterial(buttonWrap, tostring(name)) + end + end) + return buttonWrap end + for i = 1, #materialNames do local imageButton = createMaterialButton(materialNames[i]) - if materialNames[i] == "Grass" then + + if materialNames[i] == "Grass" then -- always start with grass as the default selectedButton = imageButton imageButton.BackgroundTransparency = 0 end + imageButton.Parent = scrollFrame end - local forceTerrainMaterialSelection - forceTerrainMaterialSelection = function(newMaterialType) + + local forceTerrainMaterialSelection = function(newMaterialType) if not newMaterialType then return end if currentMaterial == newMaterialType then return end + local matName = getNameFromEnum(newMaterialType) local buttons = scrollFrame:GetChildren() for i = 1, #buttons do - if (buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)") or (buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)") or (string.find(buttons[i].Name, matName)) then + if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then + goToNewMaterial(buttons[i], matName) + return + end + if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then + goToNewMaterial(buttons[i], matName) + return + end + if string.find(buttons[i].Name, matName) then goToNewMaterial(buttons[i], matName) return end end end + frame.Changed:connect(function(prop) if prop == "AbsoluteSize" then - return recalculateScroll() + recalculateScroll() end end) + recalculateScroll() return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection end + t.CreateLoadingFrame = function(name, size, position) - game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=35238053") - local loadingFrame = New("Frame", "LoadingFrame", { - Style = Enum.FrameStyle.RobloxRound, - Size = size or UDim2.new(0, 300, 0, 160), - Position = position or UDim2.new(0.5, -150, 0.5, -80), - New("TextLabel", "loadingName", { - BackgroundTransparency = 1, - Size = UDim2.new(1, 0, 0, 18), - Position = UDim2.new(0, 0, 0, 2), - Font = Enum.Font.Arial, - Text = name, - TextColor3 = Color3.new(1, 1, 1), - TextStrokeTransparency = 1, - FontSize = Enum.FontSize.Size18 - }), - New("TextButton", "CancelButton", { - Position = UDim2.new(0.5, -60, 1, -40), - Size = UDim2.new(0, 120, 0, 40), - Font = Enum.Font.Arial, - FontSize = Enum.FontSize.Size18, - TextColor3 = Color3.new(1, 1, 1), - Text = "Cancel", - Style = Enum.ButtonStyle.RobloxButton - }), - New("Frame", "LoadingBar", { - BackgroundColor3 = Color3.new(0, 0, 0), - BorderColor3 = Color3.new(79 / 255, 79 / 255, 79 / 255), - Position = UDim2.new(0, 0, 0, 41), - Size = UDim2.new(1, 0, 0, 30), - New("ImageLabel", "LoadingGreenBar", { - Image = "http://www.roblox.com/asset/?id=35238053", - Position = UDim2.new(0, 0, 0, 0), - Size = UDim2.new(0, 0, 1, 0), - Visible = false - }), - New("TextLabel", "LoadingPercent", { - BackgroundTransparency = 1, - Position = UDim2.new(0, 0, 1, 0), - Size = UDim2.new(1, 0, 0, 14), - Font = Enum.Font.Arial, - Text = "0%", - FontSize = Enum.FontSize.Size14, - TextColor3 = Color3.new(1, 1, 1) - }) - }) - }) - local cancelButton, loadingGreenBar, loadingPercent = loadingFrame.CancelButton, loadingFrame.LoadingBar.LoadingGreenBar, loadingFrame.LoadingBar.LoadingPercent - local cancelButtonClicked = New("BindableEvent", "CancelButtonClicked", { - Parent = cancelButton - }) + game:GetService("ContentProvider"):Preload "http://www.roblox.com/asset/?id=35238053" + + local loadingFrame = Instance.new "Frame" + loadingFrame.Name = "LoadingFrame" + loadingFrame.Style = Enum.FrameStyle.RobloxRound + + if size then + loadingFrame.Size = size + else + loadingFrame.Size = UDim2.new(0, 300, 0, 160) + end + if position then + loadingFrame.Position = position + else + loadingFrame.Position = UDim2.new(0.5, -150, 0.5, -80) + end + + local loadingBar = Instance.new "Frame" + loadingBar.Name = "LoadingBar" + loadingBar.BackgroundColor3 = Color3.new(0, 0, 0) + loadingBar.BorderColor3 = Color3.new(79 / 255, 79 / 255, 79 / 255) + loadingBar.Position = UDim2.new(0, 0, 0, 41) + loadingBar.Size = UDim2.new(1, 0, 0, 30) + loadingBar.Parent = loadingFrame + + local loadingGreenBar = Instance.new "ImageLabel" + loadingGreenBar.Name = "LoadingGreenBar" + loadingGreenBar.Image = "http://www.roblox.com/asset/?id=35238053" + loadingGreenBar.Position = UDim2.new(0, 0, 0, 0) + loadingGreenBar.Size = UDim2.new(0, 0, 1, 0) + loadingGreenBar.Visible = false + loadingGreenBar.Parent = loadingBar + + local loadingPercent = Instance.new "TextLabel" + loadingPercent.Name = "LoadingPercent" + loadingPercent.BackgroundTransparency = 1 + loadingPercent.Position = UDim2.new(0, 0, 1, 0) + loadingPercent.Size = UDim2.new(1, 0, 0, 14) + loadingPercent.Font = Enum.Font.Arial + loadingPercent.Text = "0%" + loadingPercent.FontSize = Enum.FontSize.Size14 + loadingPercent.TextColor3 = Color3.new(1, 1, 1) + loadingPercent.Parent = loadingBar + + local cancelButton = Instance.new "TextButton" + cancelButton.Name = "CancelButton" + cancelButton.Position = UDim2.new(0.5, -60, 1, -40) + cancelButton.Size = UDim2.new(0, 120, 0, 40) + cancelButton.Font = Enum.Font.Arial + cancelButton.FontSize = Enum.FontSize.Size18 + cancelButton.TextColor3 = Color3.new(1, 1, 1) + cancelButton.Text = "Cancel" + cancelButton.Style = Enum.ButtonStyle.RobloxButton + cancelButton.Parent = loadingFrame + + local loadingName = Instance.new "TextLabel" + loadingName.Name = "loadingName" + loadingName.BackgroundTransparency = 1 + loadingName.Size = UDim2.new(1, 0, 0, 18) + loadingName.Position = UDim2.new(0, 0, 0, 2) + loadingName.Font = Enum.Font.Arial + loadingName.Text = name + loadingName.TextColor3 = Color3.new(1, 1, 1) + loadingName.TextStrokeTransparency = 1 + loadingName.FontSize = Enum.FontSize.Size18 + loadingName.Parent = loadingFrame + + local cancelButtonClicked = Instance.new "BindableEvent" + cancelButtonClicked.Name = "CancelButtonClicked" + cancelButtonClicked.Parent = cancelButton cancelButton.MouseButton1Click:connect(function() - return cancelButtonClicked:Fire() + cancelButtonClicked:Fire() end) - local updateLoadingGuiPercent - updateLoadingGuiPercent = function(percent, tweenAction, tweenLength) + + local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength) if percent and type(percent) ~= "number" then error("updateLoadingGuiPercent expects number as argument, got", type(percent), "instead") end - local newSize = UDim2.new((function() - if percent < 0 then - return 0, 0, 1, 0 - elseif percent > 1 then - return 1, 0, 1, 0 - else - return percent, 0, 1, 0 - end - end)()) + + local newSize = nil + if percent < 0 then + newSize = UDim2.new(0, 0, 1, 0) + elseif percent > 1 then + newSize = UDim2.new(1, 0, 1, 0) + else + newSize = UDim2.new(percent, 0, 1, 0) + end + if tweenAction then if not tweenLength then - error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument") + error "updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument" end - return loadingGreenBar:TweenSize(newSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenLength, (function() - if newSize.X.Scale > 0 then - loadingGreenBar.Visible = true - return true - else - return true, function() + + if newSize.X.Scale > 0 then + loadingGreenBar.Visible = true + loadingGreenBar:TweenSize(newSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenLength, true) + else + loadingGreenBar:TweenSize( + newSize, + Enum.EasingDirection.Out, + Enum.EasingStyle.Quad, + tweenLength, + true, + function() if newSize.X.Scale < 0 then loadingGreenBar.Visible = false end end - end - end)()) + ) + end else loadingGreenBar.Size = newSize - loadingGreenBar.Visible = newSize.X.Scale > 0 + loadingGreenBar.Visible = (newSize.X.Scale > 0) end end + loadingGreenBar.Changed:connect(function(prop) if prop == "Size" then loadingPercent.Text = tostring(math.ceil(loadingGreenBar.Size.X.Scale * 100)) .. "%" end end) + return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked end + t.CreatePluginFrame = function(name, size, position, scrollable, parent) - local createMenuButton - createMenuButton = function(size, position, text, fontsize, name, parent) - local _with_0 = New("TextButton", name, { - AutoButtonColor = false, - BackgroundTransparency = 1, - Position = position, - Size = size, - Font = Enum.Font.ArialBold, - FontSize = fontsize, - Text = text, - TextColor3 = Color3.new(1, 1, 1), - BorderSizePixel = 0, - BackgroundColor3 = Color3.new(20 / 255, 20 / 255, 20 / 255) - }) - _with_0.MouseEnter:connect(function() - if _with_0.Selected then + function createMenuButton(size, position, text, fontsize, name, parent) + local button = Instance.new "TextButton" + button.AutoButtonColor = false + button.Name = name + button.BackgroundTransparency = 1 + button.Position = position + button.Size = size + button.Font = Enum.Font.ArialBold + button.FontSize = fontsize + button.Text = text + button.TextColor3 = Color3.new(1, 1, 1) + button.BorderSizePixel = 0 + button.BackgroundColor3 = Color3.new(20 / 255, 20 / 255, 20 / 255) + + button.MouseEnter:connect(function() + if button.Selected then return end - _with_0.BackgroundTransparency = 0 + button.BackgroundTransparency = 0 end) - _with_0.MouseLeave:connect(function() - if _with_0.Selected then + button.MouseLeave:connect(function() + if button.Selected then return end - _with_0.BackgroundTransparency = 1 + button.BackgroundTransparency = 1 end) - _with_0.Parent = parent - return _with_0 + + button.Parent = parent + + return button + end + + local dragBar = Instance.new "Frame" + dragBar.Name = tostring(name) .. "DragBar" + dragBar.BackgroundColor3 = Color3.new(39 / 255, 39 / 255, 39 / 255) + dragBar.BorderColor3 = Color3.new(0, 0, 0) + if size then + dragBar.Size = UDim2.new(size.X.Scale, size.X.Offset, 0, 20) + UDim2.new(0, 20, 0, 0) + else + dragBar.Size = UDim2.new(0, 183, 0, 20) end - local dragBar = New("Frame", tostring(name) .. "DragBar", { - BackgroundColor3 = Color3.new(39 / 255, 39 / 255, 39 / 255), - BorderColor3 = Color3.new(0, 0, 0), - Size = (function() - if size then - return UDim2.new(size.X.Scale, size.X.Offset, 0, 20) + UDim2.new(0, 20, 0, 0) - else - return UDim2.new(0, 183, 0, 20) - end - end)(), - Active = true, - Draggable = true, - New("TextLabel", "BarNameLabel", { - Text = " " .. tostring(name), - TextColor3 = Color3.new(1, 1, 1), - TextStrokeTransparency = 0, - Size = UDim2.new(1, 0, 1, 0), - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size18, - TextXAlignment = Enum.TextXAlignment.Left, - BackgroundTransparency = 1 - }), - New("Frame", "HelpFrame", { - BackgroundColor3 = Color3.new(0, 0, 0), - Size = UDim2.new(0, 300, 0, 552), - Position = UDim2.new(1, 5, 0, 0), - Active = true, - BorderSizePixel = 0, - Visible = false - }), - New("Frame", "SeparatingLine", { - BackgroundColor3 = Color3.new(115 / 255, 115 / 255, 115 / 255), - BorderSizePixel = 0, - Position = UDim2.new(1, -18, 0.5, -7), - Size = UDim2.new(0, 1, 0, 14) - }), - New("Frame", "MinimizeFrame", { - BackgroundColor3 = Color3.new(73 / 255, 73 / 255, 73 / 255), - BorderColor3 = Color3.new(0, 0, 0), - Position = UDim2.new(0, 0, 1, 0), - Size = (function() - if size then - return UDim2.new(size.X.Scale, size.X.Offset, 0, 50) + UDim2.new(0, 20, 0, 0) - else - return UDim2.new(0, 183, 0, 50) - end - end)(), - Visible = false, - New("TextButton", "MinimizeButton", { - Position = UDim2.new(0.5, -50, 0.5, -20), - Size = UDim2.new(0, 100, 0, 40), - Style = Enum.ButtonStyle.RobloxButton, - Font = Enum.Font.ArialBold, - FontSize = Enum.FontSize.Size18, - TextColor3 = Color3.new(1, 1, 1), - Text = "Show" - }) - }) - }) if position then dragBar.Position = position end + dragBar.Active = true + dragBar.Draggable = true + --dragBar.Visible = false dragBar.MouseEnter:connect(function() dragBar.BackgroundColor3 = Color3.new(49 / 255, 49 / 255, 49 / 255) end) @@ -3231,16 +3766,56 @@ t.CreatePluginFrame = function(name, size, position, scrollable, parent) dragBar.BackgroundColor3 = Color3.new(39 / 255, 39 / 255, 39 / 255) end) dragBar.Parent = parent - local closeButton = createMenuButton(UDim2.new(0, 15, 0, 17), UDim2.new(1, -16, 0.5, -8), "X", Enum.FontSize.Size14, "CloseButton", dragBar) - local closeEvent = New("BindableEvent", "CloseEvent", { - Parent = closeButton - }) + + -- plugin name label + local pluginNameLabel = Instance.new "TextLabel" + pluginNameLabel.Name = "BarNameLabel" + pluginNameLabel.Text = " " .. tostring(name) + pluginNameLabel.TextColor3 = Color3.new(1, 1, 1) + pluginNameLabel.TextStrokeTransparency = 0 + pluginNameLabel.Size = UDim2.new(1, 0, 1, 0) + pluginNameLabel.Font = Enum.Font.ArialBold + pluginNameLabel.FontSize = Enum.FontSize.Size18 + pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left + pluginNameLabel.BackgroundTransparency = 1 + pluginNameLabel.Parent = dragBar + + -- close button + local closeButton = createMenuButton( + UDim2.new(0, 15, 0, 17), + UDim2.new(1, -16, 0.5, -8), + "X", + Enum.FontSize.Size14, + "CloseButton", + dragBar + ) + local closeEvent = Instance.new "BindableEvent" + closeEvent.Name = "CloseEvent" + closeEvent.Parent = closeButton closeButton.MouseButton1Click:connect(function() closeEvent:Fire() closeButton.BackgroundTransparency = 1 end) - local helpButton = createMenuButton(UDim2.new(0, 15, 0, 17), UDim2.new(1, -51, 0.5, -8), "?", Enum.FontSize.Size14, "HelpButton", dragBar) - local helpFrame, separatingLine, minimizeFrame, minimizeBigButton = dragBar.HelpFrame, dragBar.SeparatingLine, dragBar.MinimizeFrame, dragBar.MinimizeFrame.MinimizeBigButton + + -- help button + local helpButton = createMenuButton( + UDim2.new(0, 15, 0, 17), + UDim2.new(1, -51, 0.5, -8), + "?", + Enum.FontSize.Size14, + "HelpButton", + dragBar + ) + local helpFrame = Instance.new "Frame" + helpFrame.Name = "HelpFrame" + helpFrame.BackgroundColor3 = Color3.new(0, 0, 0) + helpFrame.Size = UDim2.new(0, 300, 0, 552) + helpFrame.Position = UDim2.new(1, 5, 0, 0) + helpFrame.Active = true + helpFrame.BorderSizePixel = 0 + helpFrame.Visible = false + helpFrame.Parent = dragBar + helpButton.MouseButton1Click:connect(function() helpFrame.Visible = not helpFrame.Visible if helpFrame.Visible then @@ -3248,9 +3823,9 @@ t.CreatePluginFrame = function(name, size, position, scrollable, parent) helpButton.BackgroundTransparency = 0 local screenGui = getScreenGuiAncestor(helpFrame) if screenGui then - if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then + if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side helpFrame.Position = UDim2.new(0, -5 - helpFrame.AbsoluteSize.X, 0, 0) - else + else -- position on right hand side helpFrame.Position = UDim2.new(1, 5, 0, 0) end else @@ -3261,41 +3836,64 @@ t.CreatePluginFrame = function(name, size, position, scrollable, parent) helpButton.BackgroundTransparency = 1 end end) - local minimizeButton = createMenuButton(UDim2.new(0, 16, 0, 17), UDim2.new(1, -34, 0.5, -8), "-", Enum.FontSize.Size14, "MinimizeButton", dragBar) + + local minimizeButton = createMenuButton( + UDim2.new(0, 16, 0, 17), + UDim2.new(1, -34, 0.5, -8), + "-", + Enum.FontSize.Size14, + "MinimizeButton", + dragBar + ) minimizeButton.TextYAlignment = Enum.TextYAlignment.Top - do - local _with_0 = separatingLine:clone() - _with_0.Position = UDim2.new(1, -35, 0.5, -7) - _with_0.Parent = dragBar + + local minimizeFrame = Instance.new "Frame" + minimizeFrame.Name = "MinimizeFrame" + minimizeFrame.BackgroundColor3 = Color3.new(73 / 255, 73 / 255, 73 / 255) + minimizeFrame.BorderColor3 = Color3.new(0, 0, 0) + minimizeFrame.Position = UDim2.new(0, 0, 1, 0) + if size then + minimizeFrame.Size = UDim2.new(size.X.Scale, size.X.Offset, 0, 50) + UDim2.new(0, 20, 0, 0) + else + minimizeFrame.Size = UDim2.new(0, 183, 0, 50) end - local widgetContainer = New("Frame", "WidgetContainer", { - BackgroundTransparency = 1, - Position = UDim2.new(0, 0, 1, 0), - BorderColor3 = Color3.new(0, 0, 0), - New("TextButton", "VerticalDragger", { - ZIndex = 2, - AutoButtonColor = false, - BackgroundColor3 = Color3.new(50 / 255, 50 / 255, 50 / 255), - BorderColor3 = Color3.new(0, 0, 0), - Size = UDim2.new(1, 20, 0, 20), - Position = UDim2.new(0, 0, 1, 0), - Active = true, - Text = "", - New("Frame", "ScrubFrame", { - BackgroundColor3 = Color3.new(1, 1, 1), - BorderSizePixel = 0, - Position = UDim2.new(0.5, -5, 0.5, 0), - Size = UDim2.new(0, 10, 0, 1), - ZIndex = 5 - }) - }) - }) - local verticalDragger, scrubFrame = widgetContainer.VerticalDragger, widgetContainer.VerticalDragger.ScrubFrame + minimizeFrame.Visible = false + minimizeFrame.Parent = dragBar + + local minimizeBigButton = Instance.new "TextButton" + minimizeBigButton.Position = UDim2.new(0.5, -50, 0.5, -20) + minimizeBigButton.Name = "MinimizeButton" + minimizeBigButton.Size = UDim2.new(0, 100, 0, 40) + minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton + minimizeBigButton.Font = Enum.Font.ArialBold + minimizeBigButton.FontSize = Enum.FontSize.Size18 + minimizeBigButton.TextColor3 = Color3.new(1, 1, 1) + minimizeBigButton.Text = "Show" + minimizeBigButton.Parent = minimizeFrame + + local separatingLine = Instance.new "Frame" + separatingLine.Name = "SeparatingLine" + separatingLine.BackgroundColor3 = Color3.new(115 / 255, 115 / 255, 115 / 255) + separatingLine.BorderSizePixel = 0 + separatingLine.Position = UDim2.new(1, -18, 0.5, -7) + separatingLine.Size = UDim2.new(0, 1, 0, 14) + separatingLine.Parent = dragBar + + local otherSeparatingLine = separatingLine:clone() + otherSeparatingLine.Position = UDim2.new(1, -35, 0.5, -7) + otherSeparatingLine.Parent = dragBar + + local widgetContainer = Instance.new "Frame" + widgetContainer.Name = "WidgetContainer" + widgetContainer.BackgroundTransparency = 1 + widgetContainer.Position = UDim2.new(0, 0, 1, 0) + widgetContainer.BorderColor3 = Color3.new(0, 0, 0) if not scrollable then widgetContainer.BackgroundTransparency = 0 widgetContainer.BackgroundColor3 = Color3.new(72 / 255, 72 / 255, 72 / 255) end widgetContainer.Parent = dragBar + if size then if scrollable then widgetContainer.Size = size @@ -3303,64 +3901,85 @@ t.CreatePluginFrame = function(name, size, position, scrollable, parent) widgetContainer.Size = UDim2.new(0, dragBar.AbsoluteSize.X, size.Y.Scale, size.Y.Offset) end else - widgetContainer.Size = UDim2.new((function() - if scrollable then - return 0, 163, 0, 400 - else - return 0, dragBar.AbsoluteSize.X, 0, 400 - end - end)()) + if scrollable then + widgetContainer.Size = UDim2.new(0, 163, 0, 400) + else + widgetContainer.Size = UDim2.new(0, dragBar.AbsoluteSize.X, 0, 400) + end end if position then widgetContainer.Position = position + UDim2.new(0, 0, 0, 20) end - local frame, control + + local frame, control, verticalDragger = nil if scrollable then + --frame for widgets frame, control = t.CreateTrueScrollingFrame() frame.Size = UDim2.new(1, 0, 1, 0) frame.BackgroundColor3 = Color3.new(72 / 255, 72 / 255, 72 / 255) frame.BorderColor3 = Color3.new(0, 0, 0) frame.Active = true frame.Parent = widgetContainer + control.Parent = dragBar control.BackgroundColor3 = Color3.new(72 / 255, 72 / 255, 72 / 255) control.BorderSizePixel = 0 control.BackgroundTransparency = 0 control.Position = UDim2.new(1, -21, 1, 1) - control.Size = UDim2.new(0, 21, (function() - if size then - return size.Y.Scale, size.Y.Offset - else - return 0, 400 - end - end)()) - control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0, 0, 1, -20) - control.Parent = dragBar - New("Frame", "FakeLine", { - BorderSizePixel = 0, - BackgroundColor3 = Color3.new(0, 0, 0), - Size = UDim2.new(0, 1, 1, 1), - Position = UDim2.new(1, 0, 0, 0), - Parent = control - }) - for _ = 1, 2 do - do - local _with_0 = scrubFrame:clone() - _with_0.Position = UDim2.new(0.5, -5, 0.5, 2) - _with_0.Parent = verticalDragger - end + if size then + control.Size = UDim2.new(0, 21, size.Y.Scale, size.Y.Offset) + else + control.Size = UDim2.new(0, 21, 0, 400) end - local areaSoak = New("TextButton", "AreaSoak", { - Size = UDim2.new(1, 0, 1, 0), - BackgroundTransparency = 1, - BorderSizePixel = 0, - Text = "", - ZIndex = 10, - Visible = false, - Active = true, - Parent = getScreenGuiAncestor(parent) - }) + control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0, 0, 1, -20) + + local fakeLine = Instance.new "Frame" + fakeLine.Name = "FakeLine" + fakeLine.BorderSizePixel = 0 + fakeLine.BackgroundColor3 = Color3.new(0, 0, 0) + fakeLine.Size = UDim2.new(0, 1, 1, 1) + fakeLine.Position = UDim2.new(1, 0, 0, 0) + fakeLine.Parent = control + + verticalDragger = Instance.new "TextButton" + verticalDragger.ZIndex = 2 + verticalDragger.AutoButtonColor = false + verticalDragger.Name = "VerticalDragger" + verticalDragger.BackgroundColor3 = Color3.new(50 / 255, 50 / 255, 50 / 255) + verticalDragger.BorderColor3 = Color3.new(0, 0, 0) + verticalDragger.Size = UDim2.new(1, 20, 0, 20) + verticalDragger.Position = UDim2.new(0, 0, 1, 0) + verticalDragger.Active = true + verticalDragger.Text = "" + verticalDragger.Parent = widgetContainer + + local scrubFrame = Instance.new "Frame" + scrubFrame.Name = "ScrubFrame" + scrubFrame.BackgroundColor3 = Color3.new(1, 1, 1) + scrubFrame.BorderSizePixel = 0 + scrubFrame.Position = UDim2.new(0.5, -5, 0.5, 0) + scrubFrame.Size = UDim2.new(0, 10, 0, 1) + scrubFrame.ZIndex = 5 + scrubFrame.Parent = verticalDragger + local scrubTwo = scrubFrame:clone() + scrubTwo.Position = UDim2.new(0.5, -5, 0.5, -2) + scrubTwo.Parent = verticalDragger + local scrubThree = scrubFrame:clone() + scrubThree.Position = UDim2.new(0.5, -5, 0.5, 2) + scrubThree.Parent = verticalDragger + + local areaSoak = Instance.new "TextButton" + areaSoak.Name = "AreaSoak" + areaSoak.Size = UDim2.new(1, 0, 1, 0) + areaSoak.BackgroundTransparency = 1 + areaSoak.BorderSizePixel = 0 + areaSoak.Text = "" + areaSoak.ZIndex = 10 + areaSoak.Visible = false + areaSoak.Active = true + areaSoak.Parent = getScreenGuiAncestor(parent) + local draggingVertical = false - local startYPos + local startYPos = nil verticalDragger.MouseEnter:connect(function() verticalDragger.BackgroundColor3 = Color3.new(60 / 255, 60 / 255, 60 / 255) end) @@ -3380,24 +3999,38 @@ t.CreatePluginFrame = function(name, size, position, scrollable, parent) if not draggingVertical then return end + local yDelta = y - startYPos if not control.ScrollDownButton.Visible and yDelta > 0 then return end + if (widgetContainer.Size.Y.Offset + yDelta) < 150 then - widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset, widgetContainer.Size.Y.Scale, 150) + widgetContainer.Size = UDim2.new( + widgetContainer.Size.X.Scale, + widgetContainer.Size.X.Offset, + widgetContainer.Size.Y.Scale, + 150 + ) control.Size = UDim2.new(0, 21, 0, 150) return end + startYPos = y + if widgetContainer.Size.Y.Offset + yDelta >= 0 then - widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset, widgetContainer.Size.Y.Scale, widgetContainer.Size.Y.Offset + yDelta) + widgetContainer.Size = UDim2.new( + widgetContainer.Size.X.Scale, + widgetContainer.Size.X.Offset, + widgetContainer.Size.Y.Scale, + widgetContainer.Size.Y.Offset + yDelta + ) control.Size = UDim2.new(0, 21, 0, control.Size.Y.Offset + yDelta) end end) end - local switchMinimize - switchMinimize = function() + + local function switchMinimize() minimizeFrame.Visible = not minimizeFrame.Visible if scrollable then frame.Visible = not frame.Visible @@ -3406,44 +4039,86 @@ t.CreatePluginFrame = function(name, size, position, scrollable, parent) else widgetContainer.Visible = not widgetContainer.Visible end + if minimizeFrame.Visible then minimizeButton.Text = "+" else minimizeButton.Text = "-" end end - minimizeBigButton.MouseButton1Click:connect(switchMinimize) - minimizeButton.MouseButton1Click:connect(switchMinimize) - return dragBar, (function() - if scrollable then - return frame, helpFrame, closeEvent - else - return widgetContainer, helpFrame, closeEvent - end - end)() -end -t.Help = function(funcNameOrFunc) - if 'CreatePropertyDropDownMenu' == funcNameOrFunc or t.CreatePropertyDropDownMenu == funcNameOrFunc then - return 'Function CreatePropertyDropDownMenu. ' .. 'Arguments: (instance, propertyName, enumType). ' .. 'Side effect: returns a container with a drop-down-box that is linked to the "property" field of "instance" which is of type "enumType"' - elseif 'CreateDropDownMenu' == funcNameOrFunc or t.CreateDropDownMenu == funcNameOrFunc then - return 'Function CreateDropDownMenu. ' .. 'Arguments: (items, onItemSelected). ' .. 'Side effect: Returns 2 results, a container to the gui object and a "updateSelection" function for external updating. The container is a drop-down-box created around a list of items' - elseif 'CreateMessageDialog' == funcNameOrFunc or t.CreateMessageDialog == funcNameOrFunc then - return 'Function CreateMessageDialog. ' .. 'Arguments: (title, message, buttons). ' .. 'Side effect: Returns a gui object of a message box with "title" and "message" as passed in. "buttons" input is an array of Tables contains a "Text" and "Function" field for the text/callback of each button' - elseif 'CreateStyledMessageDialog' == funcNameOrFunc or t.CreateStyledMessageDialog == funcNameOrFunc then - return 'Function CreateStyledMessageDialog. ' .. 'Arguments: (title, message, style, buttons). ' .. 'Side effect: Returns a gui object of a message box with "title" and "message" as passed in. "buttons" input is an array of Tables contains a "Text" and "Function" field for the text/callback of each button, "style" is a string, either Error, Notify or Confirm' - elseif 'GetFontHeight' == funcNameOrFunc or t.GetFontHeight == funcNameOrFunc then - return 'Function GetFontHeight. ' .. 'Arguments: (font, fontSize). ' .. 'Side effect: returns the size in pixels of the given font + fontSize' - elseif 'CreateScrollingFrame' == funcNameOrFunc or t.CreateScrollingFrame == funcNameOrFunc then - return 'Function CreateScrollingFrame. ' .. 'Arguments: (orderList, style) ' .. 'Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). "scrollFrame" can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a "grid" styling if style is passed "grid" as a string. recalculateFunction can be called\n when a relayout is needed (\n when orderList changes)' - elseif 'CreateTrueScrollingFrame' == funcNameOrFunc or t.CreateTrueScrollingFrame == funcNameOrFunc then - return 'Function CreateTrueScrollingFrame. ' .. 'Arguments: (nil) ' .. 'Side effect: returns 2 objects, (scrollFrame, controlFrame). "scrollFrame" can be filled with GuiObjects, and they will be clipped if not inside the frame"s bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit.' - elseif 'AutoTruncateTextObject' == funcNameOrFunc or t.AutoTruncateTextObject == funcNameOrFunc then - return 'Function AutoTruncateTextObject. ' .. 'Arguments: (textLabel) ' .. 'Side effect: returns 2 objects, (textLabel, changeText). The "textLabel" input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. "changeText" is a function that can be used to change the text, it takes 1 string as an argument' - elseif 'CreateSlider' == funcNameOrFunc or t.CreateSlider == funcNameOrFunc then - return 'Function CreateSlider. ' .. 'Arguments: (steps, width, position) ' .. 'Side effect: returns 2 objects, (sliderGui, sliderPosition). The "steps" argument specifies how many different positions the slider can hold along the bar. "width" specifies in pixels how wide the bar should be (modifiable afterwards if desired). "position" argument should be a UDim2 for slider positioning. "sliderPosition" is an IntValue whose current .Value specifies the specific step the slider is currently on.' - elseif 'CreateLoadingFrame' == funcNameOrFunc or t.CreateLoadingFrame == funcNameOrFunc then - return 'Function CreateLoadingFrame. ' .. 'Arguments: (name, size, position) ' .. 'Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that\n when fired means that someone clicked the cancel button on the dialog.' - elseif 'CreateTerrainMaterialSelector' == funcNameOrFunc or t.CreateTerrainMaterialSelector == funcNameOrFunc then - return 'Function CreateTerrainMaterialSelector. ' .. 'Arguments: (size, position) ' .. 'Side effect: Size and position are UDim2 values that specifies the selector"s size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected.' + + minimizeBigButton.MouseButton1Click:connect(function() + switchMinimize() + end) + + minimizeButton.MouseButton1Click:connect(function() + switchMinimize() + end) + + if scrollable then + return dragBar, frame, helpFrame, closeEvent + else + return dragBar, widgetContainer, helpFrame, closeEvent end end + +t.Help = function(funcNameOrFunc) + --input argument can be a string or a function. Should return a description (of arguments and expected side effects) + if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then + return "Function CreatePropertyDropDownMenu. " + .. "Arguments: (instance, propertyName, enumType). " + .. "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'" + end + if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then + return "Function CreateDropDownMenu. " + .. "Arguments: (items, onItemSelected). " + .. "Side effect: Returns 2 results, a container to the gui object and a 'updateSelection' function for external updating. The container is a drop-down-box created around a list of items" + end + if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then + return "Function CreateMessageDialog. " + .. "Arguments: (title, message, buttons). " + .. "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button" + end + if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then + return "Function CreateStyledMessageDialog. " + .. "Arguments: (title, message, style, buttons). " + .. "Side effect: Returns a gui object of a message box with 'title' and 'message' as passed in. 'buttons' input is an array of Tables contains a 'Text' and 'Function' field for the text/callback of each button, 'style' is a string, either Error, Notify or Confirm" + end + if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then + return "Function GetFontHeight. " + .. "Arguments: (font, fontSize). " + .. "Side effect: returns the size in pixels of the given font + fontSize" + end + if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then + return "Function CreateScrollingFrame. " + .. "Arguments: (orderList, style) " + .. "Side effect: returns 4 objects, (scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction). 'scrollFrame' can be filled with GuiObjects. It will lay them out and allow scrollUpButton/scrollDownButton to interact with them. Orderlist is optional (and specifies the order to layout the children. Without orderlist, it uses the children order. style is also optional, and allows for a 'grid' styling if style is passed 'grid' as a string. recalculateFunction can be called when a relayout is needed (when orderList changes)" + end + if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then + return "Function CreateTrueScrollingFrame. " + .. "Arguments: (nil) " + .. "Side effect: returns 2 objects, (scrollFrame, controlFrame). 'scrollFrame' can be filled with GuiObjects, and they will be clipped if not inside the frame's bounds. controlFrame has children scrollup and scrolldown, as well as a slider. controlFrame can be parented to any guiobject and it will readjust itself to fit." + end + if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then + return "Function AutoTruncateTextObject. " + .. "Arguments: (textLabel) " + .. "Side effect: returns 2 objects, (textLabel, changeText). The 'textLabel' input is modified to automatically truncate text (with ellipsis), if it gets too small to fit. 'changeText' is a function that can be used to change the text, it takes 1 string as an argument" + end + if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then + return "Function CreateSlider. " + .. "Arguments: (steps, width, position) " + .. "Side effect: returns 2 objects, (sliderGui, sliderPosition). The 'steps' argument specifies how many different positions the slider can hold along the bar. 'width' specifies in pixels how wide the bar should be (modifiable afterwards if desired). 'position' argument should be a UDim2 for slider positioning. 'sliderPosition' is an IntValue whose current .Value specifies the specific step the slider is currently on." + end + if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then + return "Function CreateLoadingFrame. " + .. "Arguments: (name, size, position) " + .. "Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that when fired means that someone clicked the cancel button on the dialog." + end + if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then + return "Function CreateTerrainMaterialSelector. " + .. "Arguments: (size, position) " + .. "Side effect: Size and position are UDim2 values that specifies the selector's size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected." + end +end + +return t