3082 lines
92 KiB
Plaintext
3082 lines
92 KiB
Plaintext
%13%
|
|
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 then syncFunc() end
|
|
end
|
|
else
|
|
--Probably leaving the world, so disconnect for now
|
|
if eventConnection then
|
|
eventConnection:disconnect()
|
|
if removeFunc then removeFunc() end
|
|
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 function getScreenGuiAncestor(instance)
|
|
local localInstance = instance
|
|
while localInstance and not localInstance:IsA("ScreenGui") do
|
|
localInstance = localInstance.Parent
|
|
end
|
|
return localInstance
|
|
end
|
|
|
|
local function CreateButtons(frame, buttons, yPos, ySize)
|
|
local buttonNum = 1
|
|
local buttonObjs = {}
|
|
for i, obj in ipairs(buttons) do
|
|
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(.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(.8/3,0, ySize.Scale, ySize.Offset)
|
|
|
|
frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
|
|
frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
|
|
elseif numButtons >= 3 then
|
|
local spacing = .1 / numButtons
|
|
local buttonSize = .9 / numButtons
|
|
|
|
buttonNum = 1
|
|
while buttonNum <= numButtons do
|
|
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 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 --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)
|
|
end
|
|
|
|
end
|
|
|
|
local function cancelSlide(areaSoak)
|
|
areaSoak.Visible = false
|
|
if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
|
|
end
|
|
|
|
t.CreateStyledMessageDialog = function(title, message, style, buttons)
|
|
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 = "https://youtube.pengin.xyz/asset/?id=42565285"
|
|
elseif style == "notify" or style == "Notify" then
|
|
styleImage.Size = UDim2.new(0, 71, 0, 71)
|
|
styleImage.Image = "https://youtube.pengin.xyz/asset/?id=42604978"
|
|
elseif style == "confirm" or style == "Confirm" then
|
|
styleImage.Size = UDim2.new(0, 74, 0, 76)
|
|
styleImage.Image = "https://youtube.pengin.xyz/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.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.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 = 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, .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 xPos = 0.055
|
|
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.youtube.pengin.xyz/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 = #items
|
|
local useScrollButtons = false
|
|
if dropDownItemCount > 6 then
|
|
useScrollButtons = true
|
|
dropDownItemCount = 6
|
|
end
|
|
|
|
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)*.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, .8/((dropDownItemCount + 1)*.8),0)
|
|
else
|
|
choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
|
|
end
|
|
choiceButton.TextWrap = true
|
|
choiceButton.ZIndex = 2
|
|
|
|
local dropDownSelected = false
|
|
|
|
local scrollUpButton
|
|
local scrollDownButton
|
|
local scrollMouseCount = 0
|
|
|
|
local setZIndex = function(baseZIndex)
|
|
droppedDownMenu.ZIndex = baseZIndex +1
|
|
if scrollUpButton then
|
|
scrollUpButton.ZIndex = baseZIndex + 3
|
|
end
|
|
if scrollDownButton then
|
|
scrollDownButton.ZIndex = baseZIndex + 3
|
|
end
|
|
|
|
local children = droppedDownMenu:GetChildren()
|
|
if children then
|
|
for i, child in ipairs(children) do
|
|
if child.Name == "ChoiceButton" then
|
|
child.ZIndex = baseZIndex + 2
|
|
elseif child.Name == "ClickCaptureButton" then
|
|
child.ZIndex = baseZIndex
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local scrollBarPosition = 1
|
|
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 i, 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)*.8)/((dropDownItemCount+1)*.8),0)
|
|
obj.Visible = true
|
|
end
|
|
obj.TextColor3 = Color3.new(1,1,1)
|
|
obj.BackgroundTransparency = 1
|
|
|
|
childNum = childNum + 1
|
|
end
|
|
end
|
|
end
|
|
local toggleVisibility = function()
|
|
dropDownSelected = not dropDownSelected
|
|
|
|
dropDownMenu.Visible = not dropDownSelected
|
|
droppedDownMenu.Visible = dropDownSelected
|
|
if dropDownSelected then
|
|
setZIndex(4)
|
|
else
|
|
setZIndex(2)
|
|
end
|
|
if useScrollButtons then
|
|
updateScroll()
|
|
end
|
|
end
|
|
droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
|
|
|
|
local updateSelection = function(text)
|
|
local foundItem = false
|
|
local children = droppedDownMenu:GetChildren()
|
|
local childNum = 1
|
|
if children then
|
|
for i, obj in ipairs(children) do
|
|
if obj.Name == "ChoiceButton" then
|
|
if obj.Text == text then
|
|
obj.Font = Enum.Font.ArialBold
|
|
foundItem = true
|
|
scrollBarPosition = childNum
|
|
else
|
|
obj.Font = Enum.Font.Arial
|
|
end
|
|
childNum = childNum + 1
|
|
end
|
|
end
|
|
end
|
|
if not text then
|
|
dropDownMenu.Text = "Choose One"
|
|
scrollBarPosition = 1
|
|
else
|
|
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 function scrollDown()
|
|
if scrollBarPosition + dropDownItemCount <= itemCount then
|
|
scrollBarPosition = scrollBarPosition + 1
|
|
updateScroll()
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
local function scrollUp()
|
|
if scrollBarPosition > 1 then
|
|
scrollBarPosition = scrollBarPosition - 1
|
|
updateScroll()
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
if useScrollButtons then
|
|
--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*.8)/((dropDownItemCount+1)*.8),0)
|
|
scrollUpButton.MouseButton1Click:connect(
|
|
function()
|
|
scrollMouseCount = scrollMouseCount + 1
|
|
end)
|
|
scrollUpButton.MouseLeave:connect(
|
|
function()
|
|
scrollMouseCount = scrollMouseCount + 1
|
|
end)
|
|
scrollUpButton.MouseButton1Down:connect(
|
|
function()
|
|
scrollMouseCount = scrollMouseCount + 1
|
|
|
|
scrollUp()
|
|
local val = scrollMouseCount
|
|
wait(0.5)
|
|
while val == scrollMouseCount do
|
|
if scrollUp() == false then
|
|
break
|
|
end
|
|
wait(0.1)
|
|
end
|
|
end)
|
|
|
|
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)
|
|
while val == scrollMouseCount do
|
|
if scrollDown() == false then
|
|
break
|
|
end
|
|
wait(0.1)
|
|
end
|
|
end)
|
|
|
|
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*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
|
|
scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
|
|
scrollbar.Parent = droppedDownMenu
|
|
end
|
|
|
|
for i,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
|
|
end
|
|
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)
|
|
|
|
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()
|
|
|
|
local bigFakeButton = Instance.new("TextButton")
|
|
bigFakeButton.BackgroundTransparency = 1
|
|
bigFakeButton.Name = "ClickCaptureButton"
|
|
bigFakeButton.Size = UDim2.new(0, 4000, 0, 3000)
|
|
bigFakeButton.Position = UDim2.new(0, -2000, 0, -1500)
|
|
bigFakeButton.ZIndex = 1
|
|
bigFakeButton.Text = ""
|
|
bigFakeButton.Parent = droppedDownMenu
|
|
bigFakeButton.MouseButton1Click:connect(toggleVisibility)
|
|
|
|
dropDownMenu.MouseButton1Click:connect(toggleVisibility)
|
|
return frame, updateSelection
|
|
end
|
|
|
|
t.CreatePropertyDropDownMenu = function(instance, property, enum)
|
|
|
|
local items = enum:GetEnumItems()
|
|
local names = {}
|
|
local nameToItem = {}
|
|
for i,obj in ipairs(items) do
|
|
names[i] = obj.Name
|
|
nameToItem[obj.Name] = obj
|
|
end
|
|
|
|
local frame
|
|
local updateSelection
|
|
frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
|
|
|
|
ScopedConnect(frame, instance, "Changed",
|
|
function(prop)
|
|
if prop == property then
|
|
updateSelection(instance[property].Name)
|
|
end
|
|
end,
|
|
function()
|
|
updateSelection(instance[property].Name)
|
|
end)
|
|
|
|
return frame
|
|
end
|
|
|
|
t.GetFontHeight = function(font, fontSize)
|
|
if font == nil or fontSize == nil then
|
|
error("Font and FontSize must be non-nil")
|
|
end
|
|
|
|
if font == Enum.Font.Legacy then
|
|
if fontSize == Enum.FontSize.Size8 then
|
|
return 12
|
|
elseif fontSize == Enum.FontSize.Size9 then
|
|
return 14
|
|
elseif fontSize == Enum.FontSize.Size10 then
|
|
return 15
|
|
elseif fontSize == Enum.FontSize.Size11 then
|
|
return 17
|
|
elseif fontSize == Enum.FontSize.Size12 then
|
|
return 18
|
|
elseif fontSize == Enum.FontSize.Size14 then
|
|
return 21
|
|
elseif fontSize == Enum.FontSize.Size18 then
|
|
return 27
|
|
elseif fontSize == Enum.FontSize.Size24 then
|
|
return 36
|
|
elseif fontSize == Enum.FontSize.Size36 then
|
|
return 54
|
|
elseif fontSize == Enum.FontSize.Size48 then
|
|
return 72
|
|
else
|
|
error("Unknown FontSize")
|
|
end
|
|
elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
|
|
if fontSize == Enum.FontSize.Size8 then
|
|
return 8
|
|
elseif fontSize == Enum.FontSize.Size9 then
|
|
return 9
|
|
elseif fontSize == Enum.FontSize.Size10 then
|
|
return 10
|
|
elseif fontSize == Enum.FontSize.Size11 then
|
|
return 11
|
|
elseif fontSize == Enum.FontSize.Size12 then
|
|
return 12
|
|
elseif fontSize == Enum.FontSize.Size14 then
|
|
return 14
|
|
elseif fontSize == Enum.FontSize.Size18 then
|
|
return 18
|
|
elseif fontSize == Enum.FontSize.Size24 then
|
|
return 24
|
|
elseif fontSize == Enum.FontSize.Size36 then
|
|
return 36
|
|
elseif fontSize == Enum.FontSize.Size48 then
|
|
return 48
|
|
else
|
|
error("Unknown FontSize")
|
|
end
|
|
else
|
|
error("Unknown Font " .. font)
|
|
end
|
|
end
|
|
|
|
local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
|
|
local totalPixels = frame.AbsoluteSize.Y
|
|
local pixelsRemaining = frame.AbsoluteSize.Y
|
|
for i, child in ipairs(guiObjects) do
|
|
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
|
|
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
|
|
|
|
if isLabel then
|
|
pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
|
|
else
|
|
pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
|
|
end
|
|
else
|
|
child.Visible = false
|
|
pixelsRemaining = -1
|
|
end
|
|
|
|
else
|
|
--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)
|
|
end
|
|
end
|
|
end
|
|
|
|
t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
|
|
if not frame:IsA("GuiObject") then
|
|
error("Frame must be a GuiObject")
|
|
end
|
|
for i, child in ipairs(guiObjects) do
|
|
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 = {}
|
|
end
|
|
|
|
if not settingsTable["TextLabelSizePadY"] then
|
|
settingsTable["TextLabelSizePadY"] = 0
|
|
end
|
|
if not settingsTable["TextLabelPositionPadY"] then
|
|
settingsTable["TextLabelPositionPadY"] = 0
|
|
end
|
|
if not settingsTable["TextButtonSizePadY"] then
|
|
settingsTable["TextButtonSizePadY"] = 12
|
|
end
|
|
if not settingsTable["TextButtonPositionPadY"] then
|
|
settingsTable["TextButtonPositionPadY"] = 2
|
|
end
|
|
|
|
--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 i, child in ipairs(guiObjects) do
|
|
child.Parent = wrapperFrame
|
|
end
|
|
|
|
local recalculate = function()
|
|
wait()
|
|
layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
|
|
end
|
|
|
|
frame.Changed:connect(
|
|
function(prop)
|
|
if prop == "AbsoluteSize" then
|
|
--Wait a heartbeat for it to sync in
|
|
recalculate(nil)
|
|
end
|
|
end)
|
|
frame.AncestryChanged:connect(recalculate)
|
|
|
|
layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
|
|
end
|
|
|
|
|
|
t.CreateSlider = function(steps,width,position)
|
|
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(child,parent)
|
|
if parent == nil then
|
|
areaSoak.Parent = nil
|
|
else
|
|
areaSoak.Parent = getScreenGuiAncestor(sliderGui)
|
|
end
|
|
end)
|
|
|
|
local sliderPosition = Instance.new("IntValue")
|
|
sliderPosition.Name = "SliderPosition"
|
|
sliderPosition.Value = 0
|
|
sliderPosition.Parent = sliderGui
|
|
|
|
local id = math.random(1,100)
|
|
|
|
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 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
|
|
cancelSlide(areaSoak)
|
|
end
|
|
end)
|
|
areaSoak.MouseButton1Up:connect(function()
|
|
if areaSoak.Visible then
|
|
cancelSlide(areaSoak)
|
|
end
|
|
end)
|
|
|
|
slider.MouseButton1Down:connect(function()
|
|
areaSoak.Visible = true
|
|
if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
|
|
areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
|
|
setSliderPos(x,slider,sliderPosition,bar,steps)
|
|
end)
|
|
end)
|
|
|
|
slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
|
|
|
|
sliderPosition.Changed:connect(function(prop)
|
|
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)
|
|
end)
|
|
|
|
bar.MouseButton1Down:connect(function(x,y)
|
|
setSliderPos(x,slider,sliderPosition,bar,steps)
|
|
end)
|
|
|
|
return sliderGui, sliderPosition, sliderSteps
|
|
|
|
end
|
|
|
|
t.CreateTrueScrollingFrame = function()
|
|
local lowY = nil
|
|
local highY = nil
|
|
|
|
local dragCon = nil
|
|
local upCon = nil
|
|
|
|
local fixScrollingAreaCon = nil
|
|
|
|
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
|
|
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
|
|
local upChildren = scrollUpButton:GetChildren()
|
|
for i = 1, #upChildren do
|
|
upChildren[i].BackgroundTransparency = 0.1
|
|
end
|
|
end)
|
|
scrollUpButton.MouseLeave:connect(function()
|
|
scrollUpButton.BackgroundTransparency = 0.5
|
|
local upChildren = scrollUpButton:GetChildren()
|
|
for i = 1, #upChildren do
|
|
upChildren[i].BackgroundTransparency = 0.5
|
|
end
|
|
end)
|
|
|
|
local scrollDownButton = scrollUpButton:clone()
|
|
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].BackgroundTransparency = 0.1
|
|
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
|
|
newNub.BackgroundTransparency = 0.1
|
|
lastNub.BackgroundTransparency = 0.1
|
|
end)
|
|
scrollbar.MouseLeave:connect(function()
|
|
scrollbar.BackgroundTransparency = 0.5
|
|
scrollNub.BackgroundTransparency = 0.5
|
|
newNub.BackgroundTransparency = 0.5
|
|
lastNub.BackgroundTransparency = 0.5
|
|
end)
|
|
|
|
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(x,y,offset)
|
|
if y < scrollTrack.AbsolutePosition.y then
|
|
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
|
|
return false
|
|
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 false
|
|
end
|
|
local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
|
|
if newScaleYPos + relativeSize > 1 then
|
|
newScaleYPos = 1 - relativeSize
|
|
scrollBottom.Value = true
|
|
scrollUp.Value = false
|
|
elseif newScaleYPos <= 0 then
|
|
newScaleYPos = 0
|
|
scrollUp.Value = true
|
|
scrollBottom.Value = false
|
|
else
|
|
scrollUp.Value = false
|
|
scrollBottom.Value = false
|
|
end
|
|
local oldPos = scrollbar.Position
|
|
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
|
|
|
|
return (oldPos ~= scrollbar.Position)
|
|
end
|
|
|
|
local function drillDownSetHighLow(instance)
|
|
if not instance or not instance:IsA("GuiObject") then return end
|
|
if instance == controlFrame then return end
|
|
|
|
if lowY and lowY > instance.AbsolutePosition.Y then
|
|
lowY = instance.AbsolutePosition.Y
|
|
elseif not lowY then
|
|
lowY = instance.AbsolutePosition.Y
|
|
end
|
|
if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
|
|
highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
|
|
elseif not highY then
|
|
highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
|
|
end
|
|
local children = instance:GetChildren()
|
|
for i = 1, #children do
|
|
drillDownSetHighLow(children[i])
|
|
end
|
|
end
|
|
|
|
local function resetHighLow()
|
|
local firstChildren = scrollingFrame:GetChildren()
|
|
|
|
for i = 1, #firstChildren do
|
|
drillDownSetHighLow(firstChildren[i])
|
|
end
|
|
end
|
|
|
|
local function setSliderSizeAndPosition()
|
|
if highY and lowY then
|
|
local totalYSpan = math.abs(highY - lowY)
|
|
if totalYSpan == 0 then
|
|
scrollbar.Visible = false
|
|
scrollDownButton.Visible = false
|
|
scrollUpButton.Visible = false
|
|
|
|
if dragCon then dragCon:disconnect() dragCon = nil end
|
|
if upCon then upCon:disconnect() upCon = nil end
|
|
return
|
|
end
|
|
|
|
if fixScrollingAreaCon then fixScrollingAreaCon:disconnect() fixScrollingAreaCon = nil end
|
|
|
|
local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
|
|
if percentShown >= 1 then
|
|
scrollbar.Visible = false
|
|
scrollDownButton.Visible = false
|
|
scrollUpButton.Visible = false
|
|
else
|
|
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)
|
|
if scrollbar.Position.Y.Offset < 0 then
|
|
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function recalculate()
|
|
local percentFrame = 0
|
|
if scrollbar.Position.Y.Scale > 0 then
|
|
percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
|
|
end
|
|
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.floor((guiChildren[i].AbsolutePosition.Y - lowY) + hiddenYAmount))
|
|
end
|
|
end
|
|
|
|
lowY = nil
|
|
highY = nil
|
|
resetHighLow()
|
|
end
|
|
|
|
local buttonScrollAmountPixels = 7
|
|
local reentrancyGuardScrollUp = false
|
|
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 function doScrollDown()
|
|
if reentrancyGuardScrollDown then return end
|
|
|
|
reentrancyGuardScrollDown = true
|
|
if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
|
|
recalculate()
|
|
end
|
|
reentrancyGuardScrollDown = false
|
|
end
|
|
|
|
local function scrollUp(mouseYPos)
|
|
if scrollUpButton.Active then
|
|
scrollStamp = tick()
|
|
local current = scrollStamp
|
|
local upCon
|
|
upCon = mouseDrag.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
mouseDrag.Parent = nil
|
|
upCon:disconnect()
|
|
end)
|
|
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
|
|
doScrollUp()
|
|
wait(0.2)
|
|
local t = tick()
|
|
local w = 0.1
|
|
while scrollStamp == current do
|
|
doScrollUp()
|
|
if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then
|
|
break
|
|
end
|
|
if not scrollUpButton.Active then break end
|
|
if tick()-t > 5 then
|
|
w = 0
|
|
elseif tick()-t > 2 then
|
|
w = 0.06
|
|
end
|
|
wait(w)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function scrollDown(mouseYPos)
|
|
if scrollDownButton.Active then
|
|
scrollStamp = tick()
|
|
local current = scrollStamp
|
|
local downCon
|
|
downCon = mouseDrag.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
mouseDrag.Parent = nil
|
|
downCon:disconnect()
|
|
end)
|
|
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
|
|
doScrollDown()
|
|
wait(0.2)
|
|
local t = tick()
|
|
local w = 0.1
|
|
while scrollStamp == current do
|
|
doScrollDown()
|
|
if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
|
|
break
|
|
end
|
|
if not scrollDownButton.Active then break end
|
|
if tick()-t > 5 then
|
|
w = 0
|
|
elseif tick()-t > 2 then
|
|
w = 0.06
|
|
end
|
|
wait(w)
|
|
end
|
|
end
|
|
end
|
|
|
|
scrollbar.MouseButton1Down:connect(function(x,y)
|
|
if scrollbar.Active then
|
|
scrollStamp = tick()
|
|
local mouseOffset = y - scrollbar.AbsolutePosition.y
|
|
if dragCon then dragCon:disconnect() dragCon = nil end
|
|
if upCon then upCon:disconnect() upCon = nil end
|
|
local prevY = y
|
|
local reentrancyGuardMouseScroll = false
|
|
dragCon = mouseDrag.MouseMoved:connect(function(x,y)
|
|
if reentrancyGuardMouseScroll then return end
|
|
|
|
reentrancyGuardMouseScroll = true
|
|
if positionScrollBar(x,y,mouseOffset) then
|
|
recalculate()
|
|
end
|
|
reentrancyGuardMouseScroll = false
|
|
|
|
end)
|
|
upCon = mouseDrag.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
mouseDrag.Parent = nil
|
|
dragCon:disconnect(); dragCon = nil
|
|
upCon:disconnect(); drag = nil
|
|
end)
|
|
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
|
|
end
|
|
end)
|
|
|
|
local scrollMouseCount = 0
|
|
|
|
scrollUpButton.MouseButton1Down:connect(function()
|
|
if not fixScrollingAreaCon then scrollUp() end
|
|
end)
|
|
scrollUpButton.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
end)
|
|
|
|
|
|
scrollDownButton.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
end)
|
|
scrollDownButton.MouseButton1Down:connect(function()
|
|
if not fixScrollingAreaCon then scrollDown() end
|
|
end)
|
|
|
|
scrollbar.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
end)
|
|
|
|
local function heightCheck(instance)
|
|
if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then
|
|
highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
|
|
elseif not highY then
|
|
highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
|
|
end
|
|
setSliderSizeAndPosition()
|
|
end
|
|
|
|
local function highLowRecheck()
|
|
lowY = nil
|
|
highY = nil
|
|
resetHighLow()
|
|
setSliderSizeAndPosition()
|
|
end
|
|
|
|
scrollingFrame.DescendantAdded:connect(function(instance)
|
|
if not instance:IsA("GuiObject") then return end
|
|
wait() -- wait a heartbeat for sizes to reconfig
|
|
setSliderSizeAndPosition()
|
|
highLowRecheck()
|
|
|
|
if instance.Visible then
|
|
heightCheck(instance)
|
|
end
|
|
end)
|
|
|
|
scrollingFrame.DescendantRemoving:connect(function(instance)
|
|
if not instance:IsA("GuiObject") then return end
|
|
wait() -- wait a heartbeat for sizes to reconfig
|
|
highLowRecheck()
|
|
end)
|
|
|
|
scrollingFrame.Changed:connect(function(prop)
|
|
if prop == "AbsoluteSize" then
|
|
wait()
|
|
setSliderSizeAndPosition()
|
|
highLowRecheck()
|
|
end
|
|
end)
|
|
|
|
return scrollingFrame, controlFrame
|
|
end
|
|
|
|
t.CreateScrollingFrame = function(orderList,scrollStyle)
|
|
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.youtube.pengin.xyz/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 = function()
|
|
howManyDisplayed = 0
|
|
local guiObjects = {}
|
|
if orderList then
|
|
for i, child in ipairs(orderList) do
|
|
if child.Parent == frame then
|
|
table.insert(guiObjects, child)
|
|
end
|
|
end
|
|
else
|
|
local children = frame:GetChildren()
|
|
if children then
|
|
for i, child in ipairs(children) do
|
|
if child:IsA("GuiObject") then
|
|
table.insert(guiObjects, child)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if #guiObjects == 0 then
|
|
scrollUpButton.Active = false
|
|
scrollDownButton.Active = false
|
|
scrollDrag.Active = false
|
|
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
|
|
xCounter = guiObjects[pos].AbsoluteSize.X
|
|
end
|
|
if guiObjects[pos].AbsoluteSize.Y > currentRowY then
|
|
currentRowY = guiObjects[pos].AbsoluteSize.Y
|
|
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
|
|
if xCounter >= totalPixelsX then
|
|
rowSize = rowSizeCounter - 1
|
|
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
|
|
break
|
|
else
|
|
scrollPosition = scrollPosition - rowSize
|
|
end
|
|
currentRowY = 0
|
|
else
|
|
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,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
|
|
if xCounter + child.AbsoluteSize.X >= totalPixelsX then
|
|
if setRowSize then
|
|
rowSize = rowSizeCounter - 1
|
|
setRowSize = false
|
|
end
|
|
xCounter = 0
|
|
pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
|
|
end
|
|
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
|
|
howManyDisplayed = howManyDisplayed + 1
|
|
end
|
|
lastChildSize = child.AbsoluteSize
|
|
end
|
|
end
|
|
end
|
|
|
|
scrollUpButton.Active = (scrollPosition > 1)
|
|
if lastChildSize == 0 then
|
|
scrollDownButton.Active = false
|
|
else
|
|
scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0)
|
|
end
|
|
scrollDrag.Active = #guiObjects > howManyDisplayed
|
|
scrollDrag.Visible = scrollDrag.Active
|
|
end
|
|
|
|
|
|
|
|
local layoutSimpleScrollBar = function()
|
|
local guiObjects = {}
|
|
howManyDisplayed = 0
|
|
|
|
if orderList then
|
|
for i, child in ipairs(orderList) do
|
|
if child.Parent == frame then
|
|
table.insert(guiObjects, child)
|
|
end
|
|
end
|
|
else
|
|
local children = frame:GetChildren()
|
|
if children then
|
|
for i, child in ipairs(children) do
|
|
if child:IsA("GuiObject") then
|
|
table.insert(guiObjects, child)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if #guiObjects == 0 then
|
|
scrollUpButton.Active = false
|
|
scrollDownButton.Active = false
|
|
scrollDrag.Active = false
|
|
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
|
|
if pos >= scrollPosition then
|
|
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
|
|
--print("Backing up ScrollPosition from -- " ..scrollPosition)
|
|
scrollPosition = scrollPosition - 1
|
|
end
|
|
else
|
|
break
|
|
end
|
|
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
|
|
--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
|
|
howManyDisplayed = howManyDisplayed + 1
|
|
else
|
|
child.Visible = false
|
|
end
|
|
end
|
|
end
|
|
end
|
|
scrollUpButton.Active = (scrollPosition > 1)
|
|
scrollDownButton.Active = (pixelsRemaining < 0)
|
|
scrollDrag.Active = #guiObjects > howManyDisplayed
|
|
scrollDrag.Visible = scrollDrag.Active
|
|
end
|
|
|
|
|
|
local moveDragger = function()
|
|
local guiObjects = 0
|
|
local children = frame:GetChildren()
|
|
if children then
|
|
for i, child in ipairs(children) do
|
|
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)
|
|
|
|
local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
|
|
if relativeYPos > 1 then relativeYPos = 1
|
|
elseif relativeYPos < 0 then 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)
|
|
end
|
|
|
|
local reentrancyGuard = false
|
|
local recalculate = function()
|
|
if reentrancyGuard then
|
|
return
|
|
end
|
|
reentrancyGuard = true
|
|
wait()
|
|
local success, err = nil
|
|
if style == "grid" then
|
|
success, err = pcall(function() layoutGridScrollBar() end)
|
|
elseif style == "simple" then
|
|
success, err = pcall(function() layoutSimpleScrollBar() end)
|
|
end
|
|
if not success then print(err) end
|
|
moveDragger()
|
|
reentrancyGuard = false
|
|
end
|
|
|
|
local doScrollUp = function()
|
|
scrollPosition = (scrollPosition) - rowSize
|
|
if scrollPosition < 1 then scrollPosition = 1 end
|
|
recalculate(nil)
|
|
end
|
|
|
|
local doScrollDown = function()
|
|
scrollPosition = (scrollPosition) + rowSize
|
|
recalculate(nil)
|
|
end
|
|
|
|
local scrollUp = function(mouseYPos)
|
|
if scrollUpButton.Active then
|
|
scrollStamp = tick()
|
|
local current = scrollStamp
|
|
local upCon
|
|
upCon = mouseDrag.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
mouseDrag.Parent = nil
|
|
upCon:disconnect()
|
|
end)
|
|
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
|
|
doScrollUp()
|
|
wait(0.2)
|
|
local t = tick()
|
|
local w = 0.1
|
|
while scrollStamp == current do
|
|
doScrollUp()
|
|
if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then
|
|
break
|
|
end
|
|
if not scrollUpButton.Active then break end
|
|
if tick()-t > 5 then
|
|
w = 0
|
|
elseif tick()-t > 2 then
|
|
w = 0.06
|
|
end
|
|
wait(w)
|
|
end
|
|
end
|
|
end
|
|
|
|
local scrollDown = function(mouseYPos)
|
|
if scrollDownButton.Active then
|
|
scrollStamp = tick()
|
|
local current = scrollStamp
|
|
local downCon
|
|
downCon = mouseDrag.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
mouseDrag.Parent = nil
|
|
downCon:disconnect()
|
|
end)
|
|
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
|
|
doScrollDown()
|
|
wait(0.2)
|
|
local t = tick()
|
|
local w = 0.1
|
|
while scrollStamp == current do
|
|
doScrollDown()
|
|
if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
|
|
break
|
|
end
|
|
if not scrollDownButton.Active then break end
|
|
if tick()-t > 5 then
|
|
w = 0
|
|
elseif tick()-t > 2 then
|
|
w = 0.06
|
|
end
|
|
wait(w)
|
|
end
|
|
end
|
|
end
|
|
|
|
local y = 0
|
|
scrollDrag.MouseButton1Down:connect(function(x,y)
|
|
if scrollDrag.Active then
|
|
scrollStamp = tick()
|
|
local mouseOffset = y - scrollDrag.AbsolutePosition.y
|
|
local dragCon
|
|
local upCon
|
|
dragCon = mouseDrag.MouseMoved:connect(function(x,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 i, child in ipairs(children) do
|
|
if child:IsA("GuiObject") then
|
|
guiObjects = guiObjects + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
local doublePercent = y/(barAbsSize-dragAbsSize)
|
|
local rowDiff = rowSize
|
|
local totalScrollCount = guiObjects - (howManyDisplayed - 1)
|
|
local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
|
|
if newScrollPosition < scrollPosition then
|
|
rowDiff = -rowDiff
|
|
end
|
|
|
|
if newScrollPosition < 1 then
|
|
newScrollPosition = 1
|
|
end
|
|
|
|
scrollPosition = newScrollPosition
|
|
recalculate(nil)
|
|
end)
|
|
upCon = mouseDrag.MouseButton1Up:connect(function()
|
|
scrollStamp = tick()
|
|
mouseDrag.Parent = nil
|
|
dragCon:disconnect(); dragCon = nil
|
|
upCon:disconnect(); drag = nil
|
|
end)
|
|
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
|
|
end
|
|
end)
|
|
|
|
local scrollMouseCount = 0
|
|
|
|
scrollUpButton.MouseButton1Down:connect(
|
|
function()
|
|
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(x,y)
|
|
if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
|
|
scrollDown(y)
|
|
elseif y < (scrollDrag.AbsolutePosition.y) then
|
|
scrollUp(y)
|
|
end
|
|
end)
|
|
|
|
|
|
frame.ChildAdded:connect(function()
|
|
recalculate(nil)
|
|
end)
|
|
|
|
frame.ChildRemoved:connect(function()
|
|
recalculate(nil)
|
|
end)
|
|
|
|
frame.Changed:connect(
|
|
function(prop)
|
|
if prop == "AbsoluteSize" then
|
|
--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 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 (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 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 (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 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" .. textLabel.Name
|
|
fullLabel.BorderSizePixel = 0
|
|
fullLabel.BackgroundTransparency = 0
|
|
fullLabel.Text = text
|
|
fullLabel.TextXAlignment = Enum.TextXAlignment.Center
|
|
fullLabel.Position = UDim2.new(0,-3,0,0)
|
|
fullLabel.Size = UDim2.new(0,100,1,0)
|
|
fullLabel.Visible = false
|
|
fullLabel.Parent = textLabel
|
|
|
|
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
|
|
--Tear down the rollover if it is active
|
|
if mouseEnterConnection then
|
|
mouseEnterConnection:disconnect()
|
|
mouseEnterConnection = nil
|
|
end
|
|
if mouseLeaveConnection then
|
|
mouseLeaveConnection:disconnect()
|
|
mouseLeaveConnection = nil
|
|
end
|
|
else
|
|
local len = string.len(text)
|
|
textLabel.Text = text .. "~"
|
|
|
|
--Shrink the text
|
|
local textSize = binaryGrow(0, len,
|
|
function(pos)
|
|
if pos == 0 then
|
|
textLabel.Text = "~"
|
|
else
|
|
textLabel.Text = string.sub(text, 1, pos) .. "~"
|
|
end
|
|
return textLabel.TextFits
|
|
end)
|
|
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)
|
|
|
|
--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 mouseLeaveConnection == nil then
|
|
mouseLeaveConnection = textLabel.MouseLeave:connect(
|
|
function()
|
|
fullLabel.Visible = false
|
|
--textLabel.Text = shortText
|
|
end)
|
|
end
|
|
end
|
|
end
|
|
textLabel.AncestryChanged:connect(checkForResize)
|
|
textLabel.Changed:connect(
|
|
function(prop)
|
|
if prop == "AbsoluteSize" then
|
|
checkForResize()
|
|
end
|
|
end)
|
|
|
|
checkForResize()
|
|
|
|
local function changeText(newText)
|
|
text = newText
|
|
fullLabel.Text = text
|
|
checkForResize()
|
|
end
|
|
|
|
return textLabel, changeText
|
|
end
|
|
|
|
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
|
|
else
|
|
if transitionFrame.Visible == false then
|
|
transitionFrame.Size = UDim2.new(0.0,50,0.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.0,50,0.0,50)
|
|
newPosition = UDim2.new(0.5,-25,0.5,-25)
|
|
end
|
|
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
|
|
|
|
t.CreateTutorial = function(name, tutorialKey, createButtons)
|
|
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 i,child in ipairs(children) do
|
|
if child.Visible then
|
|
if visiblePage then
|
|
child.Visible = false
|
|
else
|
|
visiblePage = child
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return visiblePage
|
|
end
|
|
|
|
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")
|
|
if firstPage then
|
|
TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)
|
|
else
|
|
error("Could not find TutorialPage1")
|
|
end
|
|
end
|
|
end
|
|
|
|
local dismissTutorial = function()
|
|
local currentTutorialPage = getVisiblePageAndHideOthers()
|
|
|
|
if currentTutorialPage then
|
|
TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
|
|
end
|
|
|
|
UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
|
|
end
|
|
|
|
local gotoPage = function(pageNum)
|
|
local page = pages:FindFirstChild("TutorialPage" .. pageNum)
|
|
local currentTutorialPage = getVisiblePageAndHideOthers()
|
|
TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
|
|
end
|
|
|
|
return frame, showTutorial, dismissTutorial, gotoPage
|
|
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 = 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() 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 = nil
|
|
|
|
local function basicHandleResize()
|
|
if frame.Visible and frame.Parent then
|
|
local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
|
|
handleResize(200,maxSize)
|
|
end
|
|
end
|
|
|
|
frame.Changed:connect(
|
|
function(prop)
|
|
if prop == "Parent" then
|
|
if parentConnection ~= nil then
|
|
parentConnection:disconnect()
|
|
parentConnection = nil
|
|
end
|
|
if frame.Parent and frame.Parent:IsA("GuiObject") then
|
|
parentConnection = frame.Parent.Changed:connect(
|
|
function(parentProp)
|
|
if parentProp == "AbsoluteSize" then
|
|
wait()
|
|
basicHandleResize()
|
|
end
|
|
end)
|
|
basicHandleResize()
|
|
end
|
|
end
|
|
|
|
if prop == "Visible" then
|
|
basicHandleResize()
|
|
end
|
|
end)
|
|
|
|
return frame, innerFrame
|
|
end
|
|
|
|
t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
|
|
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)
|
|
size = binaryShrink(minSize, maxSize,
|
|
function(size)
|
|
frame.Size = UDim2.new(0, size, 0, size)
|
|
return textLabel.TextFits
|
|
end)
|
|
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)
|
|
textLabel.Parent = contentFrame
|
|
|
|
return frame
|
|
end
|
|
|
|
t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
|
|
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)
|
|
size = binaryShrink(minSize, maxSize,
|
|
function(size)
|
|
return size >= x and size >= y
|
|
end)
|
|
if size >= x and size >= y then
|
|
imageLabel.Size = UDim2.new(0,x, 0,y)
|
|
imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
|
|
else
|
|
if x > y then
|
|
--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
|
|
--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" .. (#children+1)
|
|
local previousPage = children[#children]
|
|
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")
|
|
end
|
|
previousPage.NextButton.MouseButton1Click:connect(
|
|
function()
|
|
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")
|
|
end
|
|
tutorialPage.PrevButton.MouseButton1Click:connect(
|
|
function()
|
|
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)
|
|
|
|
if not userIdsForSets then
|
|
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 " ..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!")
|
|
end
|
|
if type(objectSelected) ~= "function" then
|
|
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 " .. type(dialogClosed) .. ", should be of type function!")
|
|
end
|
|
|
|
if showAdminCategories == nil then -- by default, don't show beta sets
|
|
showAdminCategories = false
|
|
end
|
|
|
|
local arrayPosition = 1
|
|
local insertButtons = {}
|
|
local insertButtonCons = {}
|
|
local contents = nil
|
|
local setGui = nil
|
|
|
|
local Data = {}
|
|
Data.CurrentCategory = nil
|
|
Data.Category = {}
|
|
local SetCache = {}
|
|
|
|
local userCategoryButtons = nil
|
|
|
|
local buttonWidth = 64
|
|
local buttonHeight = buttonWidth
|
|
|
|
local SmallThumbnailUrl = nil
|
|
local LargeThumbnailUrl = nil
|
|
local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
|
|
|
|
if useAssetVersionId then
|
|
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 = 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 function drillDownSetZIndex(parent, index)
|
|
local children = parent:GetChildren()
|
|
for i = 1, #children do
|
|
if children[i]:IsA("GuiObject") then
|
|
children[i].ZIndex = index
|
|
end
|
|
drillDownSetZIndex(children[i], index)
|
|
end
|
|
end
|
|
|
|
-- 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
|
|
|
|
-- Helper Function that contructs gui elements
|
|
local function createSetGui()
|
|
|
|
local setGui = Instance.new("ScreenGui")
|
|
setGui.Name = "SetGui"
|
|
|
|
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 = 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 = "https://youtube.pengin.xyz/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 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 function buildSetButton(name, setId, setImageId, i, count)
|
|
local button = createSetButton(name)
|
|
button.Text = name
|
|
button.Name = "SetButton"
|
|
button.Visible = true
|
|
|
|
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 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)
|
|
end
|
|
end
|
|
return setButtons
|
|
end
|
|
|
|
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 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 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)
|
|
end)
|
|
end
|
|
if insertButton:FindFirstChild("AssetName") then
|
|
setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
|
|
end
|
|
end
|
|
|
|
local function selectTerrainShape(shape)
|
|
if currTerrainDropDownFrame then
|
|
objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
|
|
end
|
|
end
|
|
|
|
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
|
|
dropDownTextButton.Parent.Visible = false
|
|
end
|
|
selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
|
|
end)
|
|
|
|
return dropDownTextButton
|
|
end
|
|
|
|
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
|
|
|
|
dropDown.MouseLeave:connect(function()
|
|
dropDown.Visible = false
|
|
end)
|
|
end
|
|
|
|
|
|
local function createDropDownMenuButton(parent)
|
|
local dropDownButton = Instance.new("ImageButton")
|
|
dropDownButton.Name = "DropDownButton"
|
|
dropDownButton.Image = "http://www.youtube.pengin.xyz/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
|
|
|
|
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 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
|
|
delay(0.1,function()
|
|
if lastEnter == insertButton then
|
|
showLargePreview(insertButton)
|
|
end
|
|
end)
|
|
end)
|
|
return insertButton, mouseEnterCon
|
|
end
|
|
|
|
local function realignButtonGrid(columns)
|
|
local x = 0
|
|
local y = 0
|
|
for i = 1, #insertButtons do
|
|
insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
|
|
x = x + 1
|
|
if x >= columns then
|
|
x = 0
|
|
y = y + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
|
|
if visible then
|
|
insertFrame.AssetName.Value = name
|
|
insertFrame.AssetId.Value = assetId
|
|
local newImageUrl = SmallThumbnailUrl .. assetId
|
|
if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
|
|
delay(0,function()
|
|
game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId)
|
|
insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
|
|
end)
|
|
end
|
|
table.insert(insertButtonCons,
|
|
insertFrame.Button.MouseButton1Click:connect(function()
|
|
objectSelected(name, tonumber(assetId))
|
|
end)
|
|
)
|
|
insertFrame.Visible = true
|
|
else
|
|
insertFrame.Visible = false
|
|
end
|
|
end
|
|
|
|
local function loadSectionOfItems(setGui, rows, columns)
|
|
local pageSize = rows * columns
|
|
|
|
if arrayPosition > #contents then return end
|
|
|
|
local origArrayPos = arrayPosition
|
|
|
|
local yCopy = 0
|
|
for i = 1, pageSize + 1 do
|
|
if arrayPosition >= #contents + 1 then
|
|
break
|
|
end
|
|
|
|
local buttonCon
|
|
insertButtons[arrayPosition], buttonCon = buildInsertButton()
|
|
table.insert(insertButtonCons,buttonCon)
|
|
insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
|
|
arrayPosition = arrayPosition + 1
|
|
end
|
|
realignButtonGrid(columns)
|
|
|
|
local indexCopy = origArrayPos
|
|
for index = origArrayPos, arrayPosition do
|
|
if insertButtons[index] then
|
|
if contents[index] then
|
|
local assetId
|
|
if useAssetVersionId then
|
|
assetId = contents[index].AssetVersionId
|
|
else
|
|
assetId = contents[index].AssetId
|
|
end
|
|
setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
|
|
else
|
|
break
|
|
end
|
|
else
|
|
break
|
|
end
|
|
indexCopy = index
|
|
end
|
|
end
|
|
|
|
local function setSetIndex()
|
|
Data.Category[Data.CurrentCategory].Index = 0
|
|
|
|
rows = 7
|
|
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
|
|
for i = 1, #insertButtonCons do
|
|
if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
|
|
end
|
|
insertButtonCons = {}
|
|
insertButtons = {}
|
|
|
|
arrayPosition = 1
|
|
loadSectionOfItems(setGui, rows, columns)
|
|
end
|
|
end
|
|
|
|
local function selectSet(button, setName, setId, setIndex)
|
|
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
|
|
setSetIndex()
|
|
end
|
|
end
|
|
|
|
local function selectCategoryPage(buttons, page)
|
|
if buttons ~= Data.CurrentCategory then
|
|
if Data.CurrentCategory then
|
|
for key, button in pairs(Data.CurrentCategory) do
|
|
button.Visible = false
|
|
end
|
|
end
|
|
|
|
Data.CurrentCategory = buttons
|
|
if Data.Category[Data.CurrentCategory] == nil then
|
|
Data.Category[Data.CurrentCategory] = {}
|
|
if #buttons > 0 then
|
|
selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
|
|
end
|
|
else
|
|
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 function selectCategory(category)
|
|
selectCategoryPage(category, 0)
|
|
end
|
|
|
|
local function resetAllSetButtonSelection()
|
|
local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
|
|
for i = 1, #setButtons do
|
|
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 function populateSetsFrame()
|
|
local currRow = 0
|
|
for i = 1, #userCategoryButtons 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 -- 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
|
|
selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
|
|
selectCategory(userCategoryButtons)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
setGui = createSetGui()
|
|
setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
|
|
if prop == "AbsoluteSize" then
|
|
handleResize()
|
|
setSetIndex()
|
|
end
|
|
end)
|
|
|
|
local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
|
|
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
|
|
controlFrame.ScrollBottom.Changed:connect(function(prop)
|
|
if controlFrame.ScrollBottom.Value == true then
|
|
if debounce then return end
|
|
debounce = true
|
|
loadSectionOfItems(setGui, rows, columns)
|
|
debounce = false
|
|
end
|
|
end)
|
|
|
|
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
|
|
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()
|
|
|
|
insertPanelCloseCon = setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
|
|
setGui.SetPanel.Visible = false
|
|
if dialogClosed then dialogClosed() end
|
|
end)
|
|
|
|
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
|
|
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 == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then
|
|
|
|
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
|
|
end
|
|
|
|
return t |