3428 lines
96 KiB
Plaintext
3428 lines
96 KiB
Plaintext
t = {}
|
|
|
|
-- Heliodex's basic New function (basically a simplified version of melt)
|
|
New = (className, name, props) ->
|
|
if not props? -- no name was provided
|
|
props = name
|
|
name = nil
|
|
|
|
obj = Instance.new className
|
|
obj.Name = name if name
|
|
local parent
|
|
|
|
for k, v in pairs props
|
|
if type(k) == "string"
|
|
if k == "Parent"
|
|
parent = v
|
|
else
|
|
obj[k] = v
|
|
|
|
elseif type(k) == "number" and type(v) == "userdata"
|
|
v.Parent = obj
|
|
|
|
obj.Parent = parent
|
|
obj
|
|
--
|
|
|
|
ScopedConnect = (parentInstance, instance, event, signalFunc, syncFunc, removeFunc) ->
|
|
local eventConnection
|
|
|
|
--Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
|
|
tryConnect = ->
|
|
if game\IsAncestorOf parentInstance
|
|
--Entering the world, make sure we are connected/synced
|
|
if not eventConnection
|
|
eventConnection = instance[event]\connect signalFunc
|
|
syncFunc?!
|
|
|
|
--Probably leaving the world, so disconnect for now
|
|
if eventConnection
|
|
eventConnection\disconnect!
|
|
removeFunc?!
|
|
|
|
--Hook it up to ancestryChanged signal
|
|
connection = parentInstance.AncestryChanged\connect tryConnect
|
|
|
|
--Now connect us if we're already in the world
|
|
tryConnect!
|
|
|
|
connection
|
|
|
|
getScreenGuiAncestor = (instance) ->
|
|
localInstance = instance
|
|
while localInstance and not localInstance\IsA "ScreenGui"
|
|
localInstance = localInstance.Parent
|
|
localInstance
|
|
|
|
CreateButtons = (frame, buttons, yPos, ySize) ->
|
|
buttonNum = 1
|
|
buttonObjs = {}
|
|
for _, obj in ipairs buttons
|
|
button = New "TextButton", "Button#{buttonNum}"
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
AutoButtonColor: true
|
|
Modal: true
|
|
Style: if obj["Style"]
|
|
obj.Style
|
|
else
|
|
Enum.ButtonStyle.RobloxButton
|
|
|
|
Text: obj.Text
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Parent: frame
|
|
|
|
button.MouseButton1Click\connect obj.Function
|
|
buttonObjs[buttonNum] = button
|
|
buttonNum += 1
|
|
|
|
numButtons = buttonNum - 1
|
|
|
|
if numButtons == 1
|
|
frame.Button1.Position = UDim2.new 0.35, 0, yPos.Scale, yPos.Offset
|
|
frame.Button1.Size = UDim2.new 0.4, 0, ySize.Scale, ySize.Offset
|
|
elseif numButtons == 2
|
|
frame.Button1.Position = UDim2.new 0.1, 0, yPos.Scale, yPos.Offset
|
|
frame.Button1.Size = UDim2.new 0.8 / 3, 0, ySize.Scale, ySize.Offset
|
|
|
|
frame.Button2.Position = UDim2.new 0.55, 0, yPos.Scale, yPos.Offset
|
|
frame.Button2.Size = UDim2.new 0.35, 0, ySize.Scale, ySize.Offset
|
|
|
|
elseif numButtons >= 3
|
|
spacing = 0.1 / numButtons
|
|
buttonSize = 0.9 / numButtons
|
|
|
|
buttonNum = 1
|
|
while buttonNum <= numButtons
|
|
buttonObjs[buttonNum].Position = UDim2.new(
|
|
spacing * buttonNum + buttonSize * (buttonNum - 1),
|
|
0,
|
|
yPos.Scale,
|
|
yPos.Offset
|
|
)
|
|
|
|
buttonObjs[buttonNum].Size = UDim2.new buttonSize, 0, ySize.Scale, ySize.Offset
|
|
buttonNum += 1
|
|
|
|
setSliderPos = (newAbsPosX, slider, sliderPosition, bar, steps) ->
|
|
newStep = steps - 1 --otherwise we really get one more step than we want
|
|
relativePosX = math.min 1, math.max 0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X
|
|
wholeNum, remainder = math.modf relativePosX * newStep
|
|
if remainder > 0.5
|
|
wholeNum += 1
|
|
|
|
relativePosX = wholeNum / newStep
|
|
|
|
result = math.ceil relativePosX * newStep
|
|
if sliderPosition.Value ~= result + 1 --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
|
|
)
|
|
|
|
cancelSlide = (areaSoak) ->
|
|
areaSoak.Visible = false
|
|
areaSoakMouseMoveCon?\disconnect!
|
|
|
|
t.CreateStyledMessageDialog = (title, message, style, buttons) ->
|
|
frame = New "Frame", "MessageDialog"
|
|
Size: UDim2.new 0.5, 0, 0, 165
|
|
Position: UDim2.new 0.25, 0, 0.5, -72.5
|
|
Active: true
|
|
Style: Enum.FrameStyle.RobloxRound
|
|
|
|
* New "ImageLabel", "StyleImage"
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new 0, 5, 0, 15
|
|
|
|
* New "TextLabel", "Title"
|
|
Text: title
|
|
TextStrokeTransparency: 0
|
|
BackgroundTransparency: 1
|
|
TextColor3: Color3.new 221 / 255, 221 / 255, 221 / 255
|
|
Position: UDim2.new 0, 80, 0, 0
|
|
Size: UDim2.new 1, -80, 0, 40
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size36
|
|
TextXAlignment: Enum.TextXAlignment.Center
|
|
TextYAlignment: Enum.TextYAlignment.Center
|
|
|
|
* New "TextLabel", "Message"
|
|
Text: message
|
|
TextStrokeTransparency: 0
|
|
TextColor3: Color3.new 221 / 255, 221 / 255, 221 / 255
|
|
Position: UDim2.new 0.025, 80, 0, 45
|
|
Size: UDim2.new 0.95, -80, 0, 55
|
|
BackgroundTransparency: 1
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
TextWrap: true
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Top
|
|
|
|
:StyleImage = frame
|
|
|
|
if style == "error" or style == "Error"
|
|
StyleImage.Size = UDim2.new 0, 71, 0, 71
|
|
StyleImage.Image = "http://www.roblox.com/asset?id=42565285"
|
|
elseif style == "notify" or style == "Notify"
|
|
StyleImage.Size = UDim2.new 0, 71, 0, 71
|
|
StyleImage.Image = "http://www.roblox.com/asset?id=42604978"
|
|
elseif style == "confirm" or style == "Confirm"
|
|
StyleImage.Size = UDim2.new 0, 74, 0, 76
|
|
StyleImage.Image = "http://www.roblox.com/asset?id=42557901"
|
|
else
|
|
return t.CreateMessageDialog title, message, buttons
|
|
|
|
CreateButtons frame, buttons, UDim.new(0, 105), UDim.new 0, 40
|
|
|
|
frame
|
|
|
|
t.CreateMessageDialog = (title, message, buttons) ->
|
|
frame = New "Frame", "MessageDialog"
|
|
Size: UDim2.new 0.5, 0, 0.5, 0
|
|
Position: UDim2.new 0.25, 0, 0.25, 0
|
|
Active: true
|
|
Style: Enum.FrameStyle.RobloxRound
|
|
Parent: script.Parent
|
|
|
|
* New "TextLabel", "Title"
|
|
Text: title
|
|
BackgroundTransparency: 1
|
|
TextColor3: Color3.new 221 / 255, 221 / 255, 221 / 255
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
Size: UDim2.new 1, 0, 0.15, 0
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size36
|
|
TextXAlignment: Enum.TextXAlignment.Center
|
|
TextYAlignment: Enum.TextYAlignment.Center
|
|
|
|
* New "TextLabel", "Message"
|
|
Text: message
|
|
TextColor3: Color3.new 221 / 255, 221 / 255, 221 / 255
|
|
Position: UDim2.new 0.025, 0, 0.175, 0
|
|
Size: UDim2.new 0.95, 0, 0.55, 0
|
|
BackgroundTransparency: 1
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
TextWrap: true
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Top
|
|
|
|
CreateButtons frame, buttons, UDim.new(0.8, 0), UDim.new 0.15, 0
|
|
|
|
frame
|
|
|
|
t.CreateDropDownMenu = (items, onSelect, forRoblox) ->
|
|
width = UDim.new 0, 100
|
|
height = UDim.new 0, 32
|
|
|
|
itemCount = dropDownItemCount = #items
|
|
useScrollButtons = false
|
|
if dropDownItemCount > 6
|
|
useScrollButtons = true
|
|
dropDownItemCount = 6
|
|
|
|
frame = New "Frame", "DropDownMenu"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new width, height
|
|
|
|
* New "TextButton", "List"
|
|
Text: ""
|
|
BackgroundTransparency: 1
|
|
--AutoButtonColor: true
|
|
Style: Enum.ButtonStyle.RobloxButton
|
|
Visible: false
|
|
Active: true --Blocks clicks
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
Size: UDim2.new 1, 0, (1 + dropDownItemCount) * 0.8, 0
|
|
ZIndex: 2
|
|
|
|
* New "TextButton", "DropDownMenuButton"
|
|
TextWrap: true
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Text: "Choose One"
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size18
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Center
|
|
BackgroundTransparency: 1
|
|
AutoButtonColor: true
|
|
Style: Enum.ButtonStyle.RobloxButton
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
ZIndex: 2
|
|
|
|
* New "ImageLabel", "Icon"
|
|
Active: false
|
|
Image: "http://www.roblox.com/asset/?id=45732894"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 11, 0, 6
|
|
Position: UDim2.new 1, -11, 0.5, -2
|
|
ZIndex: 2
|
|
|
|
{ -- Destructure
|
|
DropDownMenuButton: dropDownMenu
|
|
List: droppedDownMenu
|
|
} = frame
|
|
|
|
choiceButton = New "TextButton", "ChoiceButton"
|
|
BackgroundTransparency: 1
|
|
BorderSizePixel: 0
|
|
Text: "ReplaceMe"
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Center
|
|
BackgroundColor3: Color3.new 1, 1, 1
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
Size: UDim2.new if useScrollButtons
|
|
1, -13, 0.8 / ((dropDownItemCount + 1) * 0.8), 0
|
|
else
|
|
1, 0, 0.8 / ((dropDownItemCount + 1) * 0.8), 0
|
|
TextWrap: true
|
|
ZIndex: 2
|
|
|
|
areaSoak = New "TextButton", "AreaSoak"
|
|
Text: ""
|
|
BackgroundTransparency: 1
|
|
Active: true
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
Visible: false
|
|
ZIndex: 3
|
|
|
|
dropDownSelected = false
|
|
|
|
local scrollUpButton, scrollDownButton
|
|
scrollMouseCount = 0
|
|
|
|
setZIndex = (baseZIndex) ->
|
|
droppedDownMenu.ZIndex = baseZIndex + 1
|
|
if scrollUpButton
|
|
scrollUpButton.ZIndex = baseZIndex + 3
|
|
|
|
if scrollDownButton
|
|
scrollDownButton.ZIndex = baseZIndex + 3
|
|
|
|
|
|
children = droppedDownMenu\GetChildren!
|
|
if children
|
|
for _, child in ipairs children
|
|
if child.Name == "ChoiceButton"
|
|
child.ZIndex = baseZIndex + 2
|
|
elseif child.Name == "ClickCaptureButton"
|
|
child.ZIndex = baseZIndex
|
|
|
|
|
|
scrollBarPosition = 1
|
|
updateScroll = ->
|
|
if scrollUpButton
|
|
scrollUpButton.Active = scrollBarPosition > 1
|
|
|
|
if scrollDownButton
|
|
scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount
|
|
|
|
children = droppedDownMenu\GetChildren!
|
|
return if not children
|
|
|
|
childNum = 1
|
|
for _, obj in ipairs(children)
|
|
if obj.Name == "ChoiceButton"
|
|
if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount
|
|
obj.Visible = false
|
|
else
|
|
obj.Position = UDim2.new(
|
|
0,
|
|
0,
|
|
((childNum - scrollBarPosition + 1) * 0.8) / ((dropDownItemCount + 1) * 0.8),
|
|
0
|
|
)
|
|
obj.Visible = true
|
|
obj.TextColor3 = Color3.new 1, 1, 1
|
|
obj.BackgroundTransparency = 1
|
|
|
|
childNum += 1
|
|
|
|
toggleVisibility = ->
|
|
dropDownSelected = not dropDownSelected
|
|
|
|
areaSoak.Visible = not areaSoak.Visible
|
|
dropDownMenu.Visible = not dropDownSelected
|
|
droppedDownMenu.Visible = dropDownSelected
|
|
if dropDownSelected
|
|
setZIndex 4
|
|
else
|
|
setZIndex 2
|
|
if useScrollButtons
|
|
updateScroll!
|
|
|
|
droppedDownMenu.MouseButton1Click\connect toggleVisibility
|
|
|
|
updateSelection = (text) ->
|
|
foundItem = false
|
|
children = droppedDownMenu\GetChildren!
|
|
childNum = 1
|
|
if children
|
|
for _, obj in ipairs children
|
|
if obj.Name == "ChoiceButton"
|
|
if obj.Text == text
|
|
obj.Font = Enum.Font.ArialBold
|
|
foundItem = true
|
|
scrollBarPosition = childNum
|
|
else
|
|
obj.Font = Enum.Font.Arial
|
|
|
|
childNum += 1
|
|
|
|
if not text
|
|
dropDownMenu.Text = "Choose One"
|
|
scrollBarPosition = 1
|
|
else
|
|
if not foundItem
|
|
error("Invalid Selection Update -- " .. text)
|
|
|
|
if scrollBarPosition + dropDownItemCount > itemCount + 1
|
|
scrollBarPosition = itemCount - dropDownItemCount + 1
|
|
|
|
dropDownMenu.Text = text
|
|
|
|
scrollDown = ->
|
|
if scrollBarPosition + dropDownItemCount <= itemCount
|
|
scrollBarPosition += 1
|
|
updateScroll!
|
|
return true
|
|
false
|
|
|
|
scrollUp = ->
|
|
if scrollBarPosition > 1
|
|
scrollBarPosition -= 1
|
|
updateScroll!
|
|
return true
|
|
false
|
|
|
|
if useScrollButtons
|
|
--Make some scroll buttons
|
|
scrollUpButton = New "ImageButton", "ScrollUpButton"
|
|
BackgroundTransparency: 1
|
|
Image: "rbxasset://textures/ui/scrollbuttonUp.png"
|
|
Size: UDim2.new 0, 17, 0, 17
|
|
Position: UDim2.new 1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 0
|
|
Parent: droppedDownMenu
|
|
|
|
incScrollMouseCount = -> scrollMouseCount += 1
|
|
|
|
scrollUpButton.MouseButton1Click\connect incScrollMouseCount
|
|
scrollUpButton.MouseLeave\connect incScrollMouseCount
|
|
scrollUpButton.MouseButton1Down\connect ->
|
|
scrollMouseCount += 1
|
|
|
|
scrollUp!
|
|
val = scrollMouseCount
|
|
wait 0.5
|
|
while val == scrollMouseCount
|
|
break if scrollUp! == false
|
|
wait 0.1
|
|
|
|
scrollDownButton = New "ImageButton", "ScrollDownButton"
|
|
BackgroundTransparency: 1
|
|
Image: "rbxasset://textures/ui/scrollbuttonDown.png"
|
|
Size: UDim2.new 0, 17, 0, 17
|
|
Position: UDim2.new 1, -11, 1, -11
|
|
Parent: droppedDownMenu
|
|
|
|
scrollDownButton.MouseButton1Click\connect incScrollMouseCount
|
|
scrollDownButton.MouseLeave\connect incScrollMouseCount
|
|
scrollDownButton.MouseButton1Down\connect ->
|
|
scrollMouseCount += 1
|
|
|
|
scrollDown!
|
|
val = scrollMouseCount
|
|
wait 0.5
|
|
while val == scrollMouseCount
|
|
break if scrollDown! == false
|
|
wait 0.1
|
|
|
|
New "ImageLabel", "ScrollBar"
|
|
Image: "rbxasset://textures/ui/scrollbar.png"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 18, (dropDownItemCount * 0.8) / ((dropDownItemCount + 1) * 0.8), -17 - 11 - 4
|
|
Position: UDim2.new 1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 17 + 2
|
|
Parent: droppedDownMenu
|
|
|
|
for _, item in ipairs items
|
|
-- needed to maintain local scope for items in event listeners below
|
|
button = choiceButton\clone!
|
|
if forRoblox
|
|
button.RobloxLocked = true
|
|
|
|
button.Text = item
|
|
button.Parent = droppedDownMenu
|
|
button.MouseButton1Click\connect ->
|
|
--Remove Highlight
|
|
button.TextColor3 = Color3.new 1, 1, 1
|
|
button.BackgroundTransparency = 1
|
|
|
|
updateSelection item
|
|
onSelect item
|
|
|
|
toggleVisibility!
|
|
|
|
button.MouseEnter\connect ->
|
|
--Add Highlight
|
|
button.TextColor3 = Color3.new 0, 0, 0
|
|
button.BackgroundTransparency = 0
|
|
|
|
button.MouseLeave\connect ->
|
|
--Remove Highlight
|
|
button.TextColor3 = Color3.new 1, 1, 1
|
|
button.BackgroundTransparency = 1
|
|
|
|
--This does the initial layout of the buttons
|
|
updateScroll!
|
|
|
|
frame.AncestryChanged\connect (_, parent) ->
|
|
if not parent?
|
|
areaSoak.Parent = nil
|
|
else
|
|
areaSoak.Parent = getScreenGuiAncestor frame
|
|
|
|
dropDownMenu.MouseButton1Click\connect toggleVisibility
|
|
areaSoak.MouseButton1Click\connect toggleVisibility
|
|
|
|
frame, updateSelection
|
|
|
|
t.CreatePropertyDropDownMenu = (instance, property, enum) ->
|
|
items = enum\GetEnumItems!
|
|
names = {}
|
|
nameToItem = {}
|
|
for i, obj in ipairs items
|
|
names[i] = obj.Name
|
|
nameToItem[obj.Name] = obj
|
|
|
|
frame, updateSelection = t.CreateDropDownMenu names, (text) ->
|
|
instance[property] = nameToItem[text]
|
|
|
|
t1 = (prop) ->
|
|
if prop == property
|
|
updateSelection instance[property].Name
|
|
|
|
t2 = -> updateSelection instance[property].Name
|
|
|
|
ScopedConnect frame, instance, "Changed", t1, t2
|
|
|
|
frame
|
|
|
|
t.GetFontHeight = (font, fontSize) ->
|
|
if not (font? and fontSize?)
|
|
error "Font and FontSize must be non-nil"
|
|
|
|
if font == Enum.Font.Legacy
|
|
return switch fontSize
|
|
when Enum.FontSize.Size8 then 12
|
|
when Enum.FontSize.Size9 then 14
|
|
when Enum.FontSize.Size10 then 15
|
|
when Enum.FontSize.Size11 then 17
|
|
when Enum.FontSize.Size12 then 18
|
|
when Enum.FontSize.Size14 then 21
|
|
when Enum.FontSize.Size18 then 27
|
|
when Enum.FontSize.Size24 then 36
|
|
when Enum.FontSize.Size36 then 54
|
|
when Enum.FontSize.Size48 then 72
|
|
else error "Unknown FontSize"
|
|
|
|
elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold
|
|
return switch fontSize
|
|
when Enum.FontSize.Size8 then 8
|
|
when Enum.FontSize.Size9 then 9
|
|
when Enum.FontSize.Size10 then 10
|
|
when Enum.FontSize.Size11 then 11
|
|
when Enum.FontSize.Size12 then 12
|
|
when Enum.FontSize.Size14 then 14
|
|
when Enum.FontSize.Size18 then 18
|
|
when Enum.FontSize.Size24 then 24
|
|
when Enum.FontSize.Size36 then 36
|
|
when Enum.FontSize.Size48 then 48
|
|
else error "Unknown FontSize"
|
|
|
|
else error "Unknown Font #{font}"
|
|
|
|
layoutGuiObjectsHelper = (frame, guiObjects, settingsTable) ->
|
|
totalPixels = pixelsRemaining = frame.AbsoluteSize.Y
|
|
|
|
for _, child in ipairs guiObjects
|
|
if child\IsA"TextLabel" or child\IsA "TextButton"
|
|
isLabel = child\IsA "TextLabel"
|
|
settingsTableIndex = "Text#{if isLabel then "Label" else "Button"}PositionPadY"
|
|
pixelsRemaining -= settingsTable[settingsTableIndex]
|
|
|
|
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
|
|
child.Visible = true
|
|
child.Size = UDim2.new(
|
|
child.Size.X.Scale,
|
|
child.Size.X.Offset,
|
|
0,
|
|
child.TextBounds.Y + settingsTable[settingsTableIndex]
|
|
)
|
|
|
|
until child.TextFits
|
|
child.Size = UDim2.new child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1
|
|
|
|
pixelsRemaining -= child.AbsoluteSize.Y
|
|
pixelsRemaining -= settingsTable[settingsTableIndex]
|
|
else
|
|
child.Visible = false
|
|
pixelsRemaining = -1
|
|
else
|
|
--GuiObject
|
|
child.Position = UDim2.new child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining
|
|
pixelsRemaining -= child.AbsoluteSize.Y
|
|
child.Visible = pixelsRemaining >= 0
|
|
|
|
t.LayoutGuiObjects = (frame, guiObjects, settingsTable) ->
|
|
if not frame\IsA "GuiObject"
|
|
error "Frame must be a GuiObject"
|
|
|
|
for _, child in ipairs guiObjects
|
|
if not child\IsA "GuiObject"
|
|
error "All elements that are layed out must be of type GuiObject"
|
|
|
|
if not settingsTable
|
|
settingsTable = {}
|
|
|
|
if not settingsTable["TextLabelSizePadY"]
|
|
settingsTable["TextLabelSizePadY"] = 0
|
|
|
|
if not settingsTable["TextLabelPositionPadY"]
|
|
settingsTable["TextLabelPositionPadY"] = 0
|
|
|
|
if not settingsTable["TextButtonSizePadY"]
|
|
settingsTable["TextButtonSizePadY"] = 12
|
|
|
|
if not settingsTable["TextButtonPositionPadY"]
|
|
settingsTable["TextButtonPositionPadY"] = 2
|
|
|
|
--Wrapper frame takes care of styled objects
|
|
wrapperFrame = New "Frame", "WrapperFrame"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
Parent: frame
|
|
|
|
for _, child in ipairs guiObjects
|
|
child.Parent = wrapperFrame
|
|
|
|
recalculate = ->
|
|
wait!
|
|
layoutGuiObjectsHelper wrapperFrame, guiObjects, settingsTable
|
|
|
|
frame.Changed\connect (prop) ->
|
|
if prop == "AbsoluteSize"
|
|
--Wait a heartbeat for it to sync in
|
|
recalculate nil
|
|
|
|
frame.AncestryChanged\connect recalculate
|
|
|
|
layoutGuiObjectsHelper wrapperFrame, guiObjects, settingsTable
|
|
|
|
t.CreateSlider = (steps, width, position) ->
|
|
sliderGui = New "Frame", "SliderGui"
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
BackgroundTransparency: 1
|
|
|
|
* New "IntValue", "SliderSteps"
|
|
Value: steps
|
|
|
|
* New "IntValue", "SliderPosition"
|
|
Value: 0
|
|
|
|
* New "TextButton", "Bar"
|
|
Text: ""
|
|
AutoButtonColor: false
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
Size: UDim2.new(
|
|
0,
|
|
if type(width) == "number" then width else 200,
|
|
0,
|
|
5
|
|
)
|
|
BorderColor3: Color3.new 95 / 255, 95 / 255, 95 / 255
|
|
ZIndex: 2
|
|
|
|
* New "ImageButton", "Slider"
|
|
BackgroundTransparency: 1
|
|
Image: "rbxasset://textures/ui/Slider.png"
|
|
Position: UDim2.new 0, 0, 0.5, -10
|
|
Size: UDim2.new 0, 20, 0, 20
|
|
ZIndex: 3
|
|
|
|
areaSoak = New "TextButton", "AreaSoak"
|
|
Text: ""
|
|
BackgroundTransparency: 1
|
|
Active: false
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
Visible: false
|
|
ZIndex: 4
|
|
|
|
{ -- Destructure
|
|
Bar:
|
|
Slider: slider
|
|
Bar: bar
|
|
SliderPosition: sliderPosition
|
|
SliderSteps: sliderSteps
|
|
} = sliderGui
|
|
|
|
sliderGui.AncestryChanged\connect (_, parent) ->
|
|
areaSoak.Parent = if not parent?
|
|
nil
|
|
else
|
|
getScreenGuiAncestor sliderGui
|
|
|
|
if position["X"] and
|
|
position["X"]["Scale"] and
|
|
position["X"]["Offset"] and
|
|
position["Y"] and
|
|
position["Y"]["Scale"] and
|
|
position["Y"]["Offset"]
|
|
|
|
bar.Position = position
|
|
|
|
local areaSoakMouseMoveCon
|
|
|
|
areaSoak.MouseLeave\connect ->
|
|
if areaSoak.Visible
|
|
cancelSlide areaSoak
|
|
|
|
areaSoak.MouseButton1Up\connect ->
|
|
if areaSoak.Visible
|
|
cancelSlide areaSoak
|
|
|
|
slider.MouseButton1Down\connect ->
|
|
areaSoak.Visible = true
|
|
areaSoakMouseMoveCon?\disconnect!
|
|
areaSoakMouseMoveCon = areaSoak.MouseMoved\connect (x, _) ->
|
|
setSliderPos x, slider, sliderPosition, bar, steps
|
|
|
|
slider.MouseButton1Up\connect ->
|
|
cancelSlide areaSoak
|
|
|
|
sliderPosition.Changed\connect (_) ->
|
|
sliderPosition.Value = math.min steps, math.max 1, sliderPosition.Value
|
|
relativePosX = (sliderPosition.Value - 1) / (steps - 1)
|
|
slider.Position = UDim2.new relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset
|
|
|
|
|
|
bar.MouseButton1Down\connect (x, _) ->
|
|
setSliderPos x, slider, sliderPosition, bar, steps
|
|
|
|
sliderGui, sliderPosition, sliderSteps
|
|
|
|
t.CreateTrueScrollingFrame = ->
|
|
local lowY, highY
|
|
local dragCon, upCon
|
|
|
|
internalChange = false
|
|
desantsChangeConMap = {}
|
|
|
|
scrollingFrame = New "Frame", "ScrollingFrame"
|
|
Active: true
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
ClipsDesants: true
|
|
|
|
* New "Frame", "ControlFrame"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 18, 1, 0
|
|
Position: UDim2.new 1, -20, 0, 0
|
|
|
|
* New "BoolValue", "ScrollBottom"
|
|
Value: false
|
|
|
|
* New "BoolValue", "scrollUp"
|
|
Value: false
|
|
|
|
* New "TextButton", "ScrollUpButton"
|
|
Text: ""
|
|
AutoButtonColor: false
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
BorderColor3: Color3.new 1, 1, 1
|
|
BackgroundTransparency: 0.5
|
|
Size: UDim2.new 0, 18, 0, 18
|
|
ZIndex: 2
|
|
|
|
* New "Frame", "ScrollTrack"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 18, 1, -38
|
|
Position: UDim2.new 0, 0, 0, 19
|
|
|
|
* New "TextButton", "ScrollBar"
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
BorderColor3: Color3.new 1, 1, 1
|
|
BackgroundTransparency: 0.5
|
|
AutoButtonColor: false
|
|
Text: ""
|
|
Active: true
|
|
ZIndex: 2
|
|
Size: UDim2.new 0, 18, 0.1, 0
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
|
|
* New "Frame", "ScrollNub"
|
|
BorderColor3: Color3.new 1, 1, 1
|
|
Size: UDim2.new 0, 10, 0, 0
|
|
Position: UDim2.new 0.5, -5, 0.5, 0
|
|
ZIndex: 2
|
|
BackgroundTransparency: 0.5
|
|
|
|
{ -- Destructure
|
|
ControlFrame: controlFrame
|
|
ControlFrame:
|
|
ScrollBottom: scrollBottom
|
|
ScrollUp: scrollUp
|
|
ScrollUpButton: scrollUpButton
|
|
ScrollTrack: scrollTrack
|
|
ScrollTrack:
|
|
ScrollBar: scrollbar
|
|
ScrollBar:
|
|
ScrollNub: scrollNub
|
|
} = scrollingFrame
|
|
|
|
for i = 1, 6
|
|
New "Frame", "tri#{i}"
|
|
BorderColor3: Color3.new 1, 1, 1
|
|
ZIndex: 3
|
|
BackgroundTransparency: 0.5
|
|
Size: UDim2.new 0, 12 - ((i - 1) * 2), 0, 0
|
|
Position: UDim2.new 0, 3 + (i - 1), 0.5, 2 - (i - 1)
|
|
Parent: scrollUpButton
|
|
|
|
scrollUpButton.MouseEnter\connect ->
|
|
scrollUpButton.BackgroundTransparency = 0.1
|
|
upChildren = scrollUpButton\GetChildren!
|
|
for i = 1, #upChildren
|
|
upChildren[i].BackgroundTransparency = 0.1
|
|
|
|
scrollUpButton.MouseLeave\connect ->
|
|
scrollUpButton.BackgroundTransparency = 0.5
|
|
upChildren = scrollUpButton\GetChildren!
|
|
for i = 1, #upChildren
|
|
upChildren[i].BackgroundTransparency = 0.5
|
|
|
|
scrollDownButton = scrollUpButton\clone!
|
|
|
|
with scrollDownButton
|
|
.Name = "ScrollDownButton"
|
|
.Position = UDim2.new 0, 0, 1, -18
|
|
downChildren = \GetChildren!
|
|
for i = 1, #downChildren
|
|
downChildren[i].Position = UDim2.new 0, 3 + (i - 1), 0.5, -2 + (i - 1)
|
|
|
|
.MouseEnter\connect ->
|
|
.BackgroundTransparency = 0.1
|
|
downChildren = \GetChildren!
|
|
for i = 1, #downChildren
|
|
downChildren[i].BackgroundTransparency = 0.1
|
|
|
|
.MouseLeave\connect ->
|
|
.BackgroundTransparency = 0.5
|
|
downChildren = \GetChildren!
|
|
for i = 1, #downChildren
|
|
downChildren[i].BackgroundTransparency = 0.5
|
|
|
|
.Parent = controlFrame
|
|
|
|
newNub = scrollNub\clone!
|
|
newNub.Position = UDim2.new 0.5, -5, 0.5, -2
|
|
newNub.Parent = scrollbar
|
|
|
|
lastNub = scrollNub\clone!
|
|
lastNub.Position = UDim2.new 0.5, -5, 0.5, 2
|
|
lastNub.Parent = scrollbar
|
|
|
|
scrollbar.MouseEnter\connect ->
|
|
scrollbar.BackgroundTransparency = 0.1
|
|
scrollNub.BackgroundTransparency = 0.1
|
|
newNub.BackgroundTransparency = 0.1
|
|
lastNub.BackgroundTransparency = 0.1
|
|
|
|
scrollbar.MouseLeave\connect ->
|
|
scrollbar.BackgroundTransparency = 0.5
|
|
scrollNub.BackgroundTransparency = 0.5
|
|
newNub.BackgroundTransparency = 0.5
|
|
lastNub.BackgroundTransparency = 0.5
|
|
|
|
mouseDrag = New "ImageButton"
|
|
Active: false
|
|
Size: UDim2.new 1.5, 0, 1.5, 0
|
|
AutoButtonColor: false
|
|
BackgroundTransparency: 1
|
|
Name: "mouseDrag"
|
|
Position: UDim2.new -0.25, 0, -0.25, 0
|
|
ZIndex: 10
|
|
|
|
positionScrollBar = (_, y, offset) ->
|
|
oldPos = scrollbar.Position
|
|
|
|
if y < scrollTrack.AbsolutePosition.y
|
|
scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0
|
|
return (oldPos ~= scrollbar.Position)
|
|
|
|
relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y
|
|
|
|
if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y)
|
|
scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0
|
|
return (oldPos ~= scrollbar.Position)
|
|
|
|
newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset) / scrollTrack.AbsoluteSize.y
|
|
if newScaleYPos + relativeSize > 1
|
|
newScaleYPos = 1 - relativeSize
|
|
scrollBottom.Value = true
|
|
scrollUp.Value = false
|
|
elseif newScaleYPos <= 0
|
|
newScaleYPos = 0
|
|
scrollUp.Value = true
|
|
scrollBottom.Value = false
|
|
else
|
|
scrollUp.Value = false
|
|
scrollBottom.Value = false
|
|
|
|
scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, newScaleYPos, 0
|
|
|
|
return (oldPos ~= scrollbar.Position)
|
|
|
|
drillDownSetHighLow = (instance) ->
|
|
return if not instance or not instance\IsA "GuiObject"
|
|
return if instance == controlFrame
|
|
return if instance\IsDesantOf controlFrame
|
|
return if not instance.Visible
|
|
|
|
if (lowY and lowY > instance.AbsolutePosition.Y) or not lowY
|
|
lowY = instance.AbsolutePosition.Y
|
|
|
|
if (highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y)) or not highY
|
|
highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
|
|
|
|
children = instance\GetChildren!
|
|
for i = 1, #children
|
|
drillDownSetHighLow children[i]
|
|
|
|
resetHighLow = ->
|
|
firstChildren = scrollingFrame\GetChildren!
|
|
|
|
for i = 1, #firstChildren
|
|
drillDownSetHighLow firstChildren[i]
|
|
|
|
recalculate = ->
|
|
internalChange = true
|
|
|
|
percentFrame = 0
|
|
if scrollbar.Position.Y.Scale > 0
|
|
if scrollbar.Visible
|
|
percentFrame = scrollbar.Position.Y.Scale /
|
|
((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y) / scrollTrack.AbsoluteSize.Y)
|
|
else
|
|
percentFrame = 0
|
|
|
|
if percentFrame > 0.99
|
|
percentFrame = 1
|
|
|
|
hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
|
|
|
|
guiChildren = scrollingFrame\GetChildren!
|
|
for i = 1, #guiChildren
|
|
if guiChildren[i] ~= controlFrame
|
|
guiChildren[i].Position = UDim2.new(
|
|
guiChildren[i].Position.X.Scale,
|
|
guiChildren[i].Position.X.Offset,
|
|
0,
|
|
math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount
|
|
)
|
|
|
|
lowY = nil
|
|
highY = nil
|
|
resetHighLow!
|
|
internalChange = false
|
|
|
|
setSliderSizeAndPosition = ->
|
|
return if not highY or not lowY
|
|
|
|
totalYSpan = math.abs highY - lowY
|
|
if totalYSpan == 0
|
|
scrollbar.Visible = false
|
|
scrollDownButton.Visible = false
|
|
scrollUpButton.Visible = false
|
|
|
|
dragCon?\disconnect!
|
|
dragCon = nil
|
|
|
|
upCon?\disconnect!
|
|
upCon = nil
|
|
|
|
percentShown = scrollingFrame.AbsoluteSize.Y / totalYSpan
|
|
if percentShown >= 1
|
|
scrollbar.Visible = false
|
|
scrollDownButton.Visible = false
|
|
scrollUpButton.Visible = false
|
|
recalculate!
|
|
else
|
|
scrollbar.Visible = true
|
|
scrollDownButton.Visible = true
|
|
scrollUpButton.Visible = true
|
|
|
|
scrollbar.Size = UDim2.new scrollbar.Size.X.Scale, scrollbar.Size.X.Offset, percentShown, 0
|
|
|
|
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.AbsolutePosition.y < scrollTrack.AbsolutePosition.y
|
|
scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0
|
|
|
|
if scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y >
|
|
scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y
|
|
|
|
relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y
|
|
scrollbar.Position = UDim2.new scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0
|
|
|
|
buttonScrollAmountPixels = 7
|
|
reentrancyGuardScrollUp = false
|
|
doScrollUp = ->
|
|
return if reentrancyGuardScrollUp
|
|
|
|
reentrancyGuardScrollUp = true
|
|
if positionScrollBar 0, scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels, 0
|
|
recalculate!
|
|
|
|
reentrancyGuardScrollUp = false
|
|
|
|
reentrancyGuardScrollDown = false
|
|
|
|
doScrollDown = ->
|
|
return if reentrancyGuardScrollDown
|
|
|
|
reentrancyGuardScrollDown = true
|
|
if positionScrollBar 0, scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels, 0
|
|
recalculate!
|
|
|
|
reentrancyGuardScrollDown = false
|
|
|
|
scrollUp = (mouseYPos) ->
|
|
if scrollUpButton.Active
|
|
scrollStamp = tick!
|
|
current = scrollStamp
|
|
local upCon
|
|
upCon = mouseDrag.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
mouseDrag.Parent = nil
|
|
upCon\disconnect!
|
|
|
|
mouseDrag.Parent = getScreenGuiAncestor scrollbar
|
|
doScrollUp!
|
|
wait 0.2
|
|
t = tick!
|
|
w = 0.1
|
|
while scrollStamp == current
|
|
doScrollUp!
|
|
break if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y
|
|
break if not scrollUpButton.Active
|
|
|
|
w = if tick! - t > 5
|
|
0
|
|
elseif tick! - t > 2
|
|
0.06
|
|
|
|
wait w
|
|
|
|
scrollDown = (mouseYPos) ->
|
|
if scrollDownButton.Active
|
|
scrollStamp = tick!
|
|
current = scrollStamp
|
|
local downCon
|
|
downCon = mouseDrag.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
mouseDrag.Parent = nil
|
|
downCon\disconnect!
|
|
|
|
mouseDrag.Parent = getScreenGuiAncestor scrollbar
|
|
doScrollDown!
|
|
wait 0.2
|
|
t = tick!
|
|
w = 0.1
|
|
while scrollStamp == current
|
|
doScrollDown!
|
|
break if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x)
|
|
break if not scrollDownButton.Active
|
|
|
|
w = if tick! - t > 5
|
|
0
|
|
elseif tick! - t > 2
|
|
0.06
|
|
|
|
wait w
|
|
|
|
global scrollStamp
|
|
scrollbar.MouseButton1Down\connect (_, y) ->
|
|
if scrollbar.Active
|
|
scrollStamp = tick!
|
|
mouseOffset = y - scrollbar.AbsolutePosition.y
|
|
|
|
dragCon?\disconnect!
|
|
dragCon = nil
|
|
|
|
upCon?\disconnect!
|
|
upCon = nil
|
|
|
|
reentrancyGuardMouseScroll = false
|
|
dragCon = mouseDrag.MouseMoved\connect (x, y) ->
|
|
return if reentrancyGuardMouseScroll
|
|
|
|
reentrancyGuardMouseScroll = true
|
|
if positionScrollBar x, y, mouseOffset
|
|
recalculate!
|
|
|
|
reentrancyGuardMouseScroll = false
|
|
|
|
upCon = mouseDrag.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
mouseDrag.Parent = nil
|
|
dragCon\disconnect!
|
|
dragCon = nil
|
|
upCon\disconnect!
|
|
drag = nil
|
|
|
|
mouseDrag.Parent = getScreenGuiAncestor scrollbar
|
|
|
|
scrollMouseCount = 0
|
|
|
|
scrollUpButton.MouseButton1Down\connect ->
|
|
scrollUp!
|
|
|
|
scrollDownButton.MouseButton1Down\connect ->
|
|
scrollDown!
|
|
|
|
scrollTick = ->
|
|
scrollStamp = tick!
|
|
|
|
scrollUpButton.MouseButton1Up\connect scrollTick
|
|
scrollDownButton.MouseButton1Up\connect scrollTick
|
|
scrollbar.MouseButton1Up\connect scrollTick
|
|
|
|
-- heightCheck = (instance) ->
|
|
-- if (highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY) or not highY
|
|
-- highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
|
|
|
|
-- setSliderSizeAndPosition!
|
|
|
|
highLowRecheck = ->
|
|
oldLowY = lowY
|
|
oldHighY = highY
|
|
lowY = nil
|
|
highY = nil
|
|
resetHighLow!
|
|
|
|
if (lowY ~= oldLowY) or (highY ~= oldHighY)
|
|
setSliderSizeAndPosition!
|
|
|
|
desantChanged = (this, prop) ->
|
|
return if internalChange
|
|
return if not this.Visible
|
|
|
|
if prop == "Size" or prop == "Position"
|
|
wait!
|
|
highLowRecheck!
|
|
|
|
scrollingFrame.DesantAdded\connect (instance) ->
|
|
return if not instance\IsA "GuiObject"
|
|
|
|
if instance.Visible
|
|
wait! -- wait a heartbeat for sizes to reconfig
|
|
highLowRecheck!
|
|
|
|
desantsChangeConMap[instance] = instance.Changed\connect (prop) ->
|
|
desantChanged instance, prop
|
|
|
|
scrollingFrame.DesantRemoving\connect (instance) ->
|
|
return if not instance\IsA "GuiObject"
|
|
|
|
if desantsChangeConMap[instance]
|
|
desantsChangeConMap[instance]\disconnect!
|
|
desantsChangeConMap[instance] = nil
|
|
|
|
wait! -- wait a heartbeat for sizes to reconfig
|
|
highLowRecheck!
|
|
|
|
scrollingFrame.Changed\connect (prop) ->
|
|
if prop == "AbsoluteSize"
|
|
return if not highY or not lowY
|
|
|
|
highLowRecheck!
|
|
setSliderSizeAndPosition!
|
|
|
|
scrollingFrame, controlFrame
|
|
|
|
t.CreateScrollingFrame = (orderList, scrollStyle) ->
|
|
frame = New "Frame", "ScrollingFrame"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
|
|
scrollUpButton = New "ImageButton", "ScrollUpButton"
|
|
BackgroundTransparency: 1
|
|
Image: "rbxasset://textures/ui/scrollbuttonUp.png"
|
|
Size: UDim2.new 0, 17, 0, 17
|
|
|
|
scrollDownButton = New "ImageButton", "ScrollDownButton"
|
|
BackgroundTransparency: 1
|
|
Image: "rbxasset://textures/ui/scrollbuttonDown.png"
|
|
Size: UDim2.new 0, 17, 0, 17
|
|
|
|
scrollbar = New "ImageButton", "ScrollBar"
|
|
Image: "rbxasset://textures/ui/scrollbar.png"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 18, 0, 150
|
|
|
|
* New "ImageButton", "ScrollDrag"
|
|
Image: "http://www.roblox.com/asset/?id=61367186"
|
|
Size: UDim2.new 1, 0, 0, 16
|
|
BackgroundTransparency: 1
|
|
Active: true
|
|
|
|
:scrollDrag = scrollbar
|
|
|
|
mouseDrag = New "ImageButton", "mouseDrag"
|
|
Active: false
|
|
Size: UDim2.new 1.5, 0, 1.5, 0
|
|
AutoButtonColor: false
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new -0.25, 0, -0.25, 0
|
|
ZIndex: 10
|
|
|
|
scrollStamp = 0
|
|
|
|
style = "simple"
|
|
if scrollStyle and tostring scrollStyle
|
|
style = scrollStyle
|
|
|
|
scrollPosition = 1
|
|
rowSize = 0
|
|
howManyDisplayed = 0
|
|
|
|
layoutGridScrollBar = ->
|
|
howManyDisplayed = 0
|
|
guiObjects = {}
|
|
if orderList
|
|
for _, child in ipairs orderList
|
|
if child.Parent == frame
|
|
table.insert guiObjects, child
|
|
|
|
else
|
|
children = frame\GetChildren!
|
|
if children
|
|
for _, child in ipairs children
|
|
if child\IsA "GuiObject"
|
|
table.insert guiObjects, child
|
|
|
|
if #guiObjects == 0
|
|
scrollUpButton.Active = false
|
|
scrollDownButton.Active = false
|
|
scrollDrag.Active = false
|
|
scrollPosition = 1
|
|
return
|
|
|
|
if scrollPosition > #guiObjects
|
|
scrollPosition = #guiObjects
|
|
|
|
if scrollPosition < 1
|
|
scrollPosition = 1
|
|
|
|
totalPixelsY = frame.AbsoluteSize.Y
|
|
pixelsRemainingY = frame.AbsoluteSize.Y
|
|
|
|
totalPixelsX = frame.AbsoluteSize.X
|
|
|
|
xCounter = 0
|
|
rowSizeCounter = 0
|
|
setRowSize = true
|
|
|
|
pixelsBelowScrollbar = 0
|
|
pos = #guiObjects
|
|
|
|
currentRowY = 0
|
|
|
|
pos = scrollPosition
|
|
--count up from current scroll position to fill out grid
|
|
while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY
|
|
xCounter += guiObjects[pos].AbsoluteSize.X
|
|
--previous pos was the of a row
|
|
if xCounter >= totalPixelsX
|
|
pixelsBelowScrollbar += currentRowY
|
|
currentRowY = 0
|
|
xCounter = guiObjects[pos].AbsoluteSize.X
|
|
|
|
if guiObjects[pos].AbsoluteSize.Y > currentRowY
|
|
currentRowY = guiObjects[pos].AbsoluteSize.Y
|
|
|
|
pos += 1
|
|
|
|
--Count wherever current row left off
|
|
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
|
|
xCounter += guiObjects[pos].AbsoluteSize.X
|
|
rowSizeCounter += 1
|
|
if xCounter >= totalPixelsX
|
|
rowSize = rowSizeCounter - 1
|
|
rowSizeCounter = 0
|
|
xCounter = guiObjects[pos].AbsoluteSize.X
|
|
if pixelsBelowScrollbar + currentRowY <= totalPixelsY
|
|
--It fits, so back up our scroll position
|
|
pixelsBelowScrollbar += currentRowY
|
|
if scrollPosition <= rowSize
|
|
scrollPosition = 1
|
|
break
|
|
else
|
|
scrollPosition -= rowSize
|
|
|
|
currentRowY = 0
|
|
else
|
|
break
|
|
|
|
if guiObjects[pos].AbsoluteSize.Y > currentRowY
|
|
currentRowY = guiObjects[pos].AbsoluteSize.Y
|
|
|
|
pos -= 1
|
|
|
|
--Do check last time if pos = 0
|
|
if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY)
|
|
scrollPosition = 1
|
|
|
|
xCounter = 0
|
|
--pos = scrollPosition
|
|
rowSizeCounter = 0
|
|
setRowSize = true
|
|
lastChildSize = 0
|
|
|
|
xOffset = yOffset = 0
|
|
if guiObjects[1]
|
|
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
|
|
|
|
for i, child in ipairs guiObjects
|
|
if i < scrollPosition
|
|
--print "Hiding #{child.Name}"
|
|
child.Visible = false
|
|
else
|
|
if pixelsRemainingY < 0
|
|
--print "Out of Space #{child.Name}"
|
|
child.Visible = false
|
|
else
|
|
--print "Laying out #{child.Name}"
|
|
--GuiObject
|
|
if setRowSize
|
|
rowSizeCounter += 1
|
|
|
|
if xCounter + child.AbsoluteSize.X >= totalPixelsX
|
|
if setRowSize
|
|
rowSize = rowSizeCounter - 1
|
|
setRowSize = false
|
|
|
|
xCounter = 0
|
|
pixelsRemainingY -= child.AbsoluteSize.Y
|
|
|
|
child.Position = UDim2.new(
|
|
child.Position.X.Scale,
|
|
xCounter + xOffset,
|
|
0,
|
|
totalPixelsY - pixelsRemainingY + yOffset
|
|
)
|
|
xCounter += child.AbsoluteSize.X
|
|
child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0)
|
|
if child.Visible
|
|
howManyDisplayed += 1
|
|
|
|
lastChildSize = child.AbsoluteSize
|
|
|
|
scrollUpButton.Active = (scrollPosition > 1)
|
|
|
|
scrollDownButton.Active = if lastChildSize == 0
|
|
false
|
|
else
|
|
(pixelsRemainingY - lastChildSize.Y) < 0
|
|
|
|
scrollDrag.Active = #guiObjects > howManyDisplayed
|
|
scrollDrag.Visible = scrollDrag.Active
|
|
|
|
|
|
layoutSimpleScrollBar = ->
|
|
guiObjects = {}
|
|
howManyDisplayed = 0
|
|
|
|
if orderList
|
|
for _, child in ipairs orderList
|
|
if child.Parent == frame
|
|
table.insert guiObjects, child
|
|
|
|
else
|
|
children = frame\GetChildren!
|
|
if children
|
|
for _, child in ipairs children
|
|
if child\IsA "GuiObject"
|
|
table.insert guiObjects, child
|
|
|
|
if #guiObjects == 0
|
|
scrollUpButton.Active = false
|
|
scrollDownButton.Active = false
|
|
scrollDrag.Active = false
|
|
scrollPosition = 1
|
|
return
|
|
|
|
if scrollPosition > #guiObjects
|
|
scrollPosition = #guiObjects
|
|
|
|
totalPixels = frame.AbsoluteSize.Y
|
|
pixelsRemaining = frame.AbsoluteSize.Y
|
|
|
|
pixelsBelowScrollbar = 0
|
|
pos = #guiObjects
|
|
while pixelsBelowScrollbar < totalPixels and pos >= 1
|
|
if pos >= scrollPosition
|
|
pixelsBelowScrollbar += guiObjects[pos].AbsoluteSize.Y
|
|
else
|
|
if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels
|
|
--It fits, so back up our scroll position
|
|
pixelsBelowScrollbar += guiObjects[pos].AbsoluteSize.Y
|
|
if scrollPosition <= 1
|
|
scrollPosition = 1
|
|
break
|
|
else
|
|
--local ("Backing up ScrollPosition from -- " ..scrollPosition)
|
|
scrollPosition -= 1
|
|
else break
|
|
|
|
pos -= 1
|
|
|
|
|
|
pos = scrollPosition
|
|
for i, child in ipairs guiObjects
|
|
if i < scrollPosition
|
|
-- print "Hiding #{child.Name}"
|
|
child.Visible = false
|
|
else
|
|
if pixelsRemaining < 0
|
|
--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 -= child.AbsoluteSize.Y
|
|
if pixelsRemaining >= 0
|
|
child.Visible = true
|
|
howManyDisplayed += 1
|
|
else
|
|
child.Visible = false
|
|
|
|
scrollUpButton.Active = (scrollPosition > 1)
|
|
scrollDownButton.Active = (pixelsRemaining < 0)
|
|
scrollDrag.Active = #guiObjects > howManyDisplayed
|
|
scrollDrag.Visible = scrollDrag.Active
|
|
|
|
moveDragger = ->
|
|
guiObjects = 0
|
|
children = frame\GetChildren!
|
|
if children
|
|
for _, child in ipairs children
|
|
if child\IsA "GuiObject"
|
|
guiObjects += 1
|
|
|
|
return if not scrollDrag.Parent
|
|
|
|
dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1 / (guiObjects - howManyDisplayed + 1))
|
|
if dragSizeY < 16
|
|
dragSizeY = 16
|
|
|
|
scrollDrag.Size = UDim2.new(
|
|
scrollDrag.Size.X.Scale,
|
|
scrollDrag.Size.X.Offset,
|
|
scrollDrag.Size.Y.Scale,
|
|
dragSizeY
|
|
)
|
|
|
|
relativeYPos = (scrollPosition - 1) / (guiObjects - howManyDisplayed)
|
|
if relativeYPos > 1
|
|
relativeYPos = 1
|
|
elseif relativeYPos < 0
|
|
relativeYPos = 0
|
|
|
|
absYPos = 0
|
|
|
|
if relativeYPos ~= 0
|
|
absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
|
|
|
|
|
|
scrollDrag.Position = UDim2.new(
|
|
scrollDrag.Position.X.Scale,
|
|
scrollDrag.Position.X.Offset,
|
|
scrollDrag.Position.Y.Scale,
|
|
absYPos
|
|
)
|
|
|
|
|
|
reentrancyGuard = false
|
|
recalculate = ->
|
|
return if reentrancyGuard
|
|
|
|
reentrancyGuard = true
|
|
wait!
|
|
local success, err
|
|
if style == "grid"
|
|
success, err = pcall ->
|
|
layoutGridScrollBar!
|
|
|
|
elseif style == "simple"
|
|
success, err = pcall ->
|
|
layoutSimpleScrollBar!
|
|
|
|
if not success
|
|
print err
|
|
|
|
moveDragger!
|
|
reentrancyGuard = false
|
|
|
|
|
|
doScrollUp = ->
|
|
scrollPosition -= rowSize
|
|
if scrollPosition < 1
|
|
scrollPosition = 1
|
|
|
|
recalculate nil
|
|
|
|
doScrollDown = ->
|
|
scrollPosition += rowSize
|
|
recalculate nil
|
|
|
|
scrollUp = (mouseYPos) ->
|
|
if scrollUpButton.Active
|
|
scrollStamp = tick!
|
|
current = scrollStamp
|
|
upCon = mouseDrag.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
mouseDrag.Parent = nil
|
|
upCon\disconnect!
|
|
|
|
mouseDrag.Parent = getScreenGuiAncestor scrollbar
|
|
doScrollUp!
|
|
wait 0.2
|
|
t = tick!
|
|
w = 0.1
|
|
while scrollStamp == current
|
|
doScrollUp!
|
|
break if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y
|
|
break if not scrollUpButton.Active
|
|
|
|
w = if tick! - t > 5
|
|
0
|
|
elseif tick! - t > 2
|
|
0.06
|
|
|
|
wait w
|
|
|
|
scrollDown = (mouseYPos) ->
|
|
if scrollDownButton.Active
|
|
scrollStamp = tick!
|
|
current = scrollStamp
|
|
downCon = mouseDrag.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
mouseDrag.Parent = nil
|
|
downCon\disconnect!
|
|
|
|
mouseDrag.Parent = getScreenGuiAncestor scrollbar
|
|
doScrollDown!
|
|
wait 0.2
|
|
t = tick!
|
|
w = 0.1
|
|
while scrollStamp == current
|
|
doScrollDown!
|
|
break if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x)
|
|
break if not scrollDownButton.Active
|
|
|
|
w = if tick! - t > 5
|
|
0
|
|
elseif tick! - t > 2
|
|
0.06
|
|
|
|
wait w
|
|
|
|
-- y = 0
|
|
scrollDrag.MouseButton1Down\connect (_, y) ->
|
|
if scrollDrag.Active
|
|
scrollStamp = tick!
|
|
mouseOffset = y - scrollDrag.AbsolutePosition.y
|
|
local dragCon, upCon
|
|
dragCon = mouseDrag.MouseMoved\connect (_, y) ->
|
|
barAbsPos = scrollbar.AbsolutePosition.y
|
|
barAbsSize = scrollbar.AbsoluteSize.y
|
|
|
|
dragAbsSize = scrollDrag.AbsoluteSize.y
|
|
barAbsOne = barAbsPos + barAbsSize - dragAbsSize
|
|
y -= mouseOffset
|
|
y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y
|
|
y -= barAbsPos
|
|
|
|
guiObjects = 0
|
|
children = frame\GetChildren!
|
|
if children
|
|
for _, child in ipairs children
|
|
if child\IsA "GuiObject"
|
|
guiObjects += 1
|
|
|
|
doublePercent = y / (barAbsSize - dragAbsSize)
|
|
rowDiff = rowSize
|
|
totalScrollCount = guiObjects - (howManyDisplayed - 1)
|
|
newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
|
|
if newScrollPosition < scrollPosition
|
|
rowDiff = -rowDiff
|
|
|
|
if newScrollPosition < 1
|
|
newScrollPosition = 1
|
|
|
|
scrollPosition = newScrollPosition
|
|
recalculate nil
|
|
|
|
upCon = mouseDrag.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
mouseDrag.Parent = nil
|
|
dragCon\disconnect!
|
|
dragCon = nil
|
|
upCon\disconnect!
|
|
drag = nil
|
|
|
|
mouseDrag.Parent = getScreenGuiAncestor scrollbar
|
|
|
|
scrollMouseCount = 0
|
|
|
|
scrollUpButton.MouseButton1Down\connect ->
|
|
scrollUp!
|
|
scrollDownButton.MouseButton1Down\connect ->
|
|
scrollDown!
|
|
|
|
scrollUpButton.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
scrollDownButton.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
|
|
scrollbar.MouseButton1Up\connect ->
|
|
scrollStamp = tick!
|
|
scrollbar.MouseButton1Down\connect (_, y) ->
|
|
if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y)
|
|
scrollDown y
|
|
elseif y < scrollDrag.AbsolutePosition.y
|
|
scrollUp y
|
|
|
|
frame.ChildAdded\connect -> recalculate nil
|
|
frame.ChildRemoved\connect -> recalculate nil
|
|
frame.AncestryChanged\connect -> recalculate nil
|
|
|
|
frame.Changed\connect (prop) ->
|
|
if prop == "AbsoluteSize"
|
|
--Wait a heartbeat for it to sync in
|
|
recalculate nil
|
|
|
|
|
|
frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
|
|
|
|
binaryGrow = (min, max, fits) ->
|
|
if min > max
|
|
return min
|
|
|
|
biggestLegal = min
|
|
|
|
while min <= max
|
|
mid = min + math.floor (max - min) / 2
|
|
if fits(mid) and (not biggestLegal? or biggestLegal < mid)
|
|
biggestLegal = mid
|
|
--Try growing
|
|
min = mid + 1
|
|
else
|
|
--Doesn't fit, shrink
|
|
max = mid - 1
|
|
|
|
biggestLegal
|
|
|
|
binaryShrink = (min, max, fits) ->
|
|
if min > max
|
|
return min
|
|
|
|
smallestLegal = max
|
|
|
|
while min <= max
|
|
mid = min + math.floor (max - min) / 2
|
|
if fits(mid) and (not smallestLegal? or smallestLegal > mid)
|
|
smallestLegal = mid
|
|
--It fits, shrink
|
|
max = mid - 1
|
|
else
|
|
--Doesn't fit, grow
|
|
min = mid + 1
|
|
|
|
smallestLegal
|
|
|
|
getGuiOwner = (instance) ->
|
|
while instance?
|
|
if instance\IsA"ScreenGui" or instance\IsA"BillboardGui"
|
|
return instance
|
|
|
|
instance = instance.Parent
|
|
|
|
t.AutoTruncateTextObject = (textLabel) ->
|
|
text = textLabel.Text
|
|
|
|
fullLabel = textLabel\Clone!
|
|
with fullLabel
|
|
.Name = "Full#{textLabel.Name}"
|
|
.BorderSizePixel = 0
|
|
.BackgroundTransparency = 0
|
|
.Text = text
|
|
.TextXAlignment = Enum.TextXAlignment.Center
|
|
.Position = UDim2.new 0, -3, 0, 0
|
|
.Size = UDim2.new 0, 100, 1, 0
|
|
.Visible = false
|
|
.Parent = textLabel
|
|
|
|
local shortText
|
|
local mouseEnterConnection
|
|
local mouseLeaveConnection
|
|
|
|
checkForResize = ->
|
|
return if not getGuiOwner(textLabel)?
|
|
|
|
textLabel.Text = text
|
|
if textLabel.TextFits
|
|
--Tear down the rollover if it is active
|
|
|
|
mouseEnterConnection?\disconnect!
|
|
mouseEnterConnection = nil
|
|
|
|
mouseLeaveConnection?\disconnect!
|
|
mouseLeaveConnection = nil
|
|
|
|
else
|
|
len = string.len text
|
|
textLabel.Text = "#{text}~"
|
|
|
|
--Shrink the text
|
|
textSize = binaryGrow 0, len, (pos) ->
|
|
textLabel.Text = if pos == 0
|
|
"~"
|
|
else
|
|
"#{string.sub text, 1, pos}~"
|
|
|
|
textLabel.TextFits
|
|
|
|
shortText = "#{string.sub text, 1, textSize}~"
|
|
textLabel.Text = shortText
|
|
|
|
--Make sure the fullLabel fits
|
|
if not fullLabel.TextFits
|
|
--Already too small, grow it really bit to start
|
|
fullLabel.Size = UDim2.new 0, 10000, 1, 0
|
|
|
|
--Okay, now try to binary shrink it back down
|
|
fullLabelSize = binaryShrink textLabel.AbsoluteSize.X, fullLabel.AbsoluteSize.X, (size) ->
|
|
fullLabel.Size = UDim2.new 0, size, 1, 0
|
|
fullLabel.TextFits
|
|
|
|
fullLabel.Size = UDim2.new 0, fullLabelSize + 6, 1, 0
|
|
|
|
--Now setup the rollover effects, if they are currently off
|
|
if not mouseEnterConnection?
|
|
mouseEnterConnection = textLabel.MouseEnter\connect ->
|
|
fullLabel.ZIndex = textLabel.ZIndex + 1
|
|
fullLabel.Visible = true
|
|
--textLabel.Text = ""
|
|
|
|
if not mouseLeaveConnection?
|
|
mouseLeaveConnection = textLabel.MouseLeave\connect ->
|
|
fullLabel.Visible = false
|
|
--textLabel.Text = shortText
|
|
|
|
textLabel.AncestryChanged\connect checkForResize
|
|
textLabel.Changed\connect (prop) ->
|
|
if prop == "AbsoluteSize"
|
|
checkForResize!
|
|
|
|
checkForResize!
|
|
|
|
changeText = (newText) ->
|
|
text = newText
|
|
fullLabel.Text = text
|
|
checkForResize!
|
|
|
|
textLabel, changeText
|
|
|
|
TransitionTutorialPages = (fromPage, toPage, transitionFrame, currentPageValue) ->
|
|
if fromPage
|
|
fromPage.Visible = false
|
|
if transitionFrame.Visible == false
|
|
transitionFrame.Size = fromPage.Size
|
|
transitionFrame.Position = fromPage.Position
|
|
|
|
elseif transitionFrame.Visible == false
|
|
transitionFrame.Size = UDim2.new 0, 50, 0, 50
|
|
transitionFrame.Position = UDim2.new 0.5, -25, 0.5, -25
|
|
|
|
transitionFrame.Visible = true
|
|
currentPageValue.Value = nil
|
|
|
|
local newSize, newPosition
|
|
if toPage
|
|
--Make it visible so it resizes
|
|
toPage.Visible = true
|
|
|
|
newSize = toPage.Size
|
|
newPosition = toPage.Position
|
|
|
|
toPage.Visible = false
|
|
else
|
|
newSize = UDim2.new 0, 50, 0, 50
|
|
newPosition = UDim2.new 0.5, -25, 0.5, -25
|
|
|
|
transitionFrame\TweenSizeAndPosition(
|
|
newSize,
|
|
newPosition,
|
|
Enum.EasingDirection.InOut,
|
|
Enum.EasingStyle.Quad,
|
|
0.3,
|
|
true,
|
|
(state) ->
|
|
if state == Enum.TweenStatus.Completed
|
|
transitionFrame.Visible = false
|
|
if toPage
|
|
toPage.Visible = true
|
|
currentPageValue.Value = toPage
|
|
)
|
|
|
|
t.CreateTutorial = (name, tutorialKey, createButtons) ->
|
|
frame = New "Frame", "Tutorial-#{name}"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0.6, 0, 0.6, 0
|
|
Position: UDim2.new 0.2, 0, 0.2, 0
|
|
|
|
* New "Frame", "TransitionFrame"
|
|
Style: Enum.FrameStyle.RobloxRound
|
|
Size: UDim2.new 0.6, 0, 0.6, 0
|
|
Position: UDim2.new 0.2, 0, 0.2, 0
|
|
Visible: false
|
|
|
|
* New "ObjectValue", "CurrentTutorialPage"
|
|
Value: nil
|
|
|
|
* New "BoolValue", "Buttons"
|
|
Value: createButtons
|
|
|
|
* New "Frame", "Pages"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
|
|
{ -- Destructure
|
|
TransitionFrame: transitionFrame
|
|
CurrentTutorialPage: currentPageValue
|
|
Pages: pages
|
|
} = frame
|
|
|
|
getVisiblePageAndHideOthers = ->
|
|
local visiblePage
|
|
children = pages\GetChildren!
|
|
if children
|
|
for _, child in ipairs children
|
|
if child.Visible
|
|
if visiblePage
|
|
child.Visible = false
|
|
else
|
|
visiblePage = child
|
|
|
|
visiblePage
|
|
|
|
showTutorial = (alwaysShow) ->
|
|
if alwaysShow or UserSettings!.GameSettings\GetTutorialState(tutorialKey) == false
|
|
print "Showing tutorial-", tutorialKey
|
|
currentTutorialPage = getVisiblePageAndHideOthers!
|
|
|
|
firstPage = pages\FindFirstChild "TutorialPage1"
|
|
if firstPage
|
|
TransitionTutorialPages currentTutorialPage, firstPage, transitionFrame, currentPageValue
|
|
else
|
|
error "Could not find TutorialPage1"
|
|
|
|
|
|
dismissTutorial = ->
|
|
currentTutorialPage = getVisiblePageAndHideOthers!
|
|
|
|
if currentTutorialPage
|
|
TransitionTutorialPages currentTutorialPage, nil, transitionFrame, currentPageValue
|
|
|
|
UserSettings!.GameSettings\SetTutorialState tutorialKey, true
|
|
|
|
|
|
gotoPage = (pageNum) ->
|
|
page = pages\FindFirstChild "TutorialPage#{pageNum}"
|
|
currentTutorialPage = getVisiblePageAndHideOthers!
|
|
TransitionTutorialPages currentTutorialPage, page, transitionFrame, currentPageValue
|
|
|
|
frame, showTutorial, dismissTutorial, gotoPage
|
|
|
|
CreateBasicTutorialPage = (name, handleResize, skipTutorial, giveDoneButton) ->
|
|
frame = New "Frame", "TutorialPage"
|
|
Style: Enum.FrameStyle.RobloxRound
|
|
Size: UDim2.new 0.6, 0, 0.6, 0
|
|
Position: UDim2.new 0.2, 0, 0.2, 0
|
|
Visible: false
|
|
|
|
* New "TextLabel", "Header"
|
|
Text: name
|
|
BackgroundTransparency: 1
|
|
FontSize: Enum.FontSize.Size24
|
|
Font: Enum.Font.ArialBold
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextXAlignment: Enum.TextXAlignment.Center
|
|
TextWrap: true
|
|
Size: UDim2.new 1, -55, 0, 22
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
|
|
* New "ImageButton", "SkipButton"
|
|
AutoButtonColor: false
|
|
BackgroundTransparency: 1
|
|
Image: "rbxasset://textures/ui/closeButton.png"
|
|
Size: UDim2.new 0, 25, 0, 25
|
|
Position: UDim2.new 1, -25, 0, 0
|
|
|
|
* New "TextButton", "NextButton"
|
|
Text: "Next"
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
Style: Enum.ButtonStyle.RobloxButtonDefault
|
|
Size: UDim2.new 0, 80, 0, 32
|
|
Position: UDim2.new 0.5, 5, 1, -32
|
|
Active: false
|
|
Visible: false
|
|
|
|
* New "TextButton", "PrevButton"
|
|
Text: "Previous"
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
Style: Enum.ButtonStyle.RobloxButton
|
|
Size: UDim2.new 0, 80, 0, 32
|
|
Position: UDim2.new 0.5, -85, 1, -32
|
|
Active: false
|
|
Visible: false
|
|
|
|
* New "Frame", "ContentFrame"
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new 0, 0, 0, 25
|
|
|
|
innerFrame = frame.ContentFrame
|
|
|
|
with frame.SkipButton
|
|
.MouseButton1Click\connect ->
|
|
skipTutorial!
|
|
.MouseEnter\connect ->
|
|
.Image = "rbxasset://textures/ui/closeButton_dn.png"
|
|
.MouseLeave\connect ->
|
|
.Image = "rbxasset://textures/ui/closeButton.png"
|
|
|
|
if giveDoneButton
|
|
doneButton = New "TextButton", "DoneButton"
|
|
Style: Enum.ButtonStyle.RobloxButtonDefault
|
|
Text: "Done"
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size18
|
|
Size: UDim2.new 0, 100, 0, 50
|
|
Position: UDim2.new 0.5, -50, 1, -50
|
|
Parent: frame
|
|
|
|
if skipTutorial
|
|
doneButton.MouseButton1Click\connect ->
|
|
skipTutorial!
|
|
|
|
innerFrame.Size = if giveDoneButton
|
|
UDim2.new 1, 0, 1, -75
|
|
else
|
|
UDim2.new 1, 0, 1, -22
|
|
|
|
local parentConnection
|
|
|
|
basicHandleResize = ->
|
|
if frame.Visible and frame.Parent
|
|
maxSize = math.min frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y
|
|
handleResize 200, maxSize
|
|
|
|
frame.Changed\connect (prop) ->
|
|
if prop == "Parent"
|
|
|
|
parentConnection?\disconnect!
|
|
parentConnection = nil
|
|
|
|
if frame.Parent and frame.Parent\IsA "GuiObject"
|
|
parentConnection = frame.Parent.Changed\connect (parentProp) ->
|
|
if parentProp == "AbsoluteSize"
|
|
wait!
|
|
basicHandleResize!
|
|
basicHandleResize!
|
|
|
|
if prop == "Visible"
|
|
basicHandleResize!
|
|
|
|
frame, innerFrame
|
|
|
|
t.CreateTextTutorialPage = (name, text, skipTutorialFunc) ->
|
|
local frame
|
|
|
|
textLabel = New "TextLabel"
|
|
BackgroundTransparency: 1
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Text: text
|
|
TextWrap: true
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Center
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size14
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
|
|
handleResize = (minSize, maxSize) ->
|
|
size = binaryShrink minSize, maxSize, (size) ->
|
|
frame.Size = UDim2.new 0, size, 0, size
|
|
textLabel.TextFits
|
|
|
|
frame.Size = UDim2.new 0, size, 0, size
|
|
frame.Position = UDim2.new 0.5, -size / 2, 0.5, -size / 2
|
|
|
|
frame, contentFrame = CreateBasicTutorialPage name, handleResize, skipTutorialFunc
|
|
textLabel.Parent = contentFrame
|
|
|
|
frame
|
|
|
|
t.CreateImageTutorialPage = (name, imageAsset, x, y, skipTutorialFunc, giveDoneButton) ->
|
|
local frame, contentFrame
|
|
|
|
imageLabel = New "ImageLabel"
|
|
BackgroundTransparency: 1
|
|
Image: imageAsset
|
|
Size: UDim2.new 0, x, 0, y
|
|
Position: UDim2.new 0.5, -x / 2, 0.5, -y / 2
|
|
|
|
handleResize = (minSize, maxSize) ->
|
|
size = binaryShrink minSize, maxSize, (size) ->
|
|
size >= x and size >= y
|
|
|
|
if size >= x and size >= y
|
|
imageLabel.Size = UDim2.new 0, x, 0, y
|
|
imageLabel.Position = UDim2.new 0.5, -x / 2, 0.5, -y / 2
|
|
else
|
|
imageLabel.Size, imageLabel.Position = if x > y
|
|
--X is limiter, so
|
|
UDim2.new(1, 0, y / x, 0), UDim2.new(0, 0, 0.5 - (y / x) / 2, 0)
|
|
else
|
|
--Y is limiter
|
|
UDim2.new(x / y, 0, 1, 0), UDim2.new(0.5 - (x / y) / 2, 0, 0, 0)
|
|
|
|
|
|
size += 50
|
|
frame.Size = UDim2.new 0, size, 0, size
|
|
frame.Position = UDim2.new 0.5, -size / 2, 0.5, -size / 2
|
|
|
|
frame, contentFrame = CreateBasicTutorialPage name, handleResize, skipTutorialFunc, giveDoneButton
|
|
imageLabel.Parent = contentFrame
|
|
|
|
frame
|
|
|
|
t.AddTutorialPage = (tutorial, tutorialPage) ->
|
|
transitionFrame = tutorial.TransitionFrame
|
|
currentPageValue = tutorial.CurrentTutorialPage
|
|
|
|
if not tutorial.Buttons.Value
|
|
tutorialPage.NextButton.Parent = tutorialPage.PrevButton.Parent = nil
|
|
|
|
children = tutorial.Pages\GetChildren!
|
|
if children and #children > 0
|
|
tutorialPage.Name = "TutorialPage#{#children + 1}"
|
|
previousPage = children[#children]
|
|
if not previousPage\IsA "GuiObject"
|
|
error "All elements under Pages must be GuiObjects"
|
|
|
|
if tutorial.Buttons.Value
|
|
if previousPage.NextButton.Active
|
|
error "NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function"
|
|
|
|
previousPage.NextButton.MouseButton1Click\connect ->
|
|
TransitionTutorialPages previousPage, tutorialPage, transitionFrame, currentPageValue
|
|
|
|
previousPage.NextButton.Active = previousPage.NextButton.Visible = true
|
|
|
|
if tutorialPage.PrevButton.Active
|
|
error "PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function"
|
|
|
|
tutorialPage.PrevButton.MouseButton1Click\connect ->
|
|
TransitionTutorialPages tutorialPage, previousPage, transitionFrame, currentPageValue
|
|
|
|
tutorialPage.PrevButton.Active = tutorialPage.PrevButton.Visible = true
|
|
|
|
|
|
tutorialPage.Parent = tutorial.Pages
|
|
else
|
|
--First child
|
|
tutorialPage.Name = "TutorialPage1"
|
|
tutorialPage.Parent = tutorial.Pages
|
|
|
|
t.CreateSetPanel = (userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId) ->
|
|
if not userIdsForSets
|
|
error "CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids"
|
|
|
|
if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata"
|
|
error "CreateSetPanel: userIdsForSets (first arg) is of type #{type userIdsForSets}, should be of type table or userdata"
|
|
|
|
if not objectSelected
|
|
error "CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!"
|
|
|
|
if type(objectSelected) ~= "function"
|
|
error "CreateSetPanel: objectSelected (second arg) is of type #{type objectSelected}, should be of type function!"
|
|
|
|
if dialogClosed and type(dialogClosed) ~= "function"
|
|
error "CreateSetPanel: dialogClosed (third arg) is of type #{type dialogClosed}, should be of type function!"
|
|
|
|
if not showAdminCategories? -- by default, don't show beta sets
|
|
showAdminCategories = false
|
|
|
|
arrayPosition = 1
|
|
insertButtons = {}
|
|
insertButtonCons = {}
|
|
local contents, setGui
|
|
|
|
-- used for water selections
|
|
waterForceDirection = "NegX"
|
|
waterForce = "None"
|
|
local waterGui, waterTypeChangedEvent
|
|
|
|
Data = {}
|
|
Data.CurrentCategory = nil
|
|
Data.Category = {}
|
|
SetCache = {}
|
|
|
|
local userCategoryButtons
|
|
|
|
buttonWidth = 64
|
|
buttonHeight = buttonWidth
|
|
|
|
local SmallThumbnailUrl, LargeThumbnailUrl
|
|
BaseUrl = game\GetService"ContentProvider".BaseUrl\lower!
|
|
|
|
LargeThumbnailUrl, SmallThumbnailUrl = if useAssetVersionId
|
|
"#{BaseUrl}Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid=", "#{BaseUrl}Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid="
|
|
else
|
|
"#{BaseUrl}Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid=", "#{BaseUrl}Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
|
|
|
|
|
|
drillDownSetZIndex = (parent, index) ->
|
|
children = parent\GetChildren!
|
|
for i = 1, #children
|
|
if children[i]\IsA "GuiObject"
|
|
children[i].ZIndex = index
|
|
|
|
drillDownSetZIndex children[i], index
|
|
|
|
-- for terrain stamping
|
|
local currTerrainDropDownFrame
|
|
terrainShapes =
|
|
* "Block"
|
|
* "Vertical Ramp"
|
|
* "Corner Wedge"
|
|
* "Inverse Corner Wedge"
|
|
* "Horizontal Ramp"
|
|
* "Auto-Wedge"
|
|
terrainShapeMap = {}
|
|
|
|
for i = 1, #terrainShapes
|
|
terrainShapeMap[terrainShapes[i]] = i - 1
|
|
|
|
terrainShapeMap[terrainShapes[#terrainShapes]] = 6
|
|
|
|
createWaterGui = ->
|
|
waterForceDirections = { "NegX", "X", "NegY", "Y", "NegZ", "Z" }
|
|
waterForces = { "None", "Small", "Medium", "Strong", "Max" }
|
|
|
|
waterFrame = New "Frame", "WaterFrame"
|
|
Style: Enum.FrameStyle.RobloxSquare
|
|
Size: UDim2.new 0, 150, 0, 110
|
|
Visible: false
|
|
|
|
waterForceLabel = New "TextLabel", "WaterForceLabel"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 1, 0, 0, 12
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size12
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
Text: "Water Force"
|
|
Parent: waterFrame
|
|
|
|
waterForceDirLabel = waterForceLabel\Clone!
|
|
with waterForceDirLabel
|
|
.Name = "WaterForceDirectionLabel"
|
|
.Text = "Water Force Direction"
|
|
.Position = UDim2.new 0, 0, 0, 50
|
|
.Parent = waterFrame
|
|
|
|
waterTypeChangedEvent = New "BindableEvent", "WaterTypeChangedEvent"
|
|
Parent: waterFrame
|
|
|
|
waterForceDirectionSelectedFunc = (newForceDirection) ->
|
|
waterForceDirection = newForceDirection
|
|
waterTypeChangedEvent\Fire { waterForce, waterForceDirection }
|
|
|
|
waterForceSelectedFunc = (newForce) ->
|
|
waterForce = newForce
|
|
waterTypeChangedEvent\Fire { waterForce, waterForceDirection }
|
|
|
|
|
|
waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu waterForceDirections, waterForceDirectionSelectedFunc
|
|
waterForceDirectionDropDown.Size = UDim2.new 1, 0, 0, 25
|
|
waterForceDirectionDropDown.Position = UDim2.new 0, 0, 1, 3
|
|
forceWaterDirectionSelection "NegX"
|
|
waterForceDirectionDropDown.Parent = waterForceDirLabel
|
|
|
|
waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu waterForces, waterForceSelectedFunc
|
|
forceWaterForceSelection "None"
|
|
waterForceDropDown.Size = UDim2.new 1, 0, 0, 25
|
|
waterForceDropDown.Position = UDim2.new 0, 0, 1, 3
|
|
waterForceDropDown.Parent = waterForceLabel
|
|
|
|
waterFrame, waterTypeChangedEvent
|
|
|
|
|
|
-- Helper Function that contructs gui elements
|
|
createSetGui = ->
|
|
setGui = Instance.new "ScreenGui"
|
|
setGui.Name = "SetGui"
|
|
|
|
setPanel = New "Frame", "SetPanel"
|
|
Active: true
|
|
BackgroundTransparency: 1
|
|
Position: position or UDim2.new 0.2, 29, 0.1, 24
|
|
Size: size or UDim2.new 0.6, -58, 0.64, 0
|
|
Style: Enum.FrameStyle.RobloxRound
|
|
ZIndex: 6
|
|
Parent: setGui
|
|
|
|
* New "TextButton", "CancelButton"
|
|
Position: UDim2.new 1, -32, 0, -2
|
|
Size: UDim2.new 0, 34, 0, 34
|
|
Style: Enum.ButtonStyle.RobloxButtonDefault
|
|
ZIndex: 6
|
|
Text: ""
|
|
Modal: true
|
|
|
|
* New "ImageLabel", "CancelImage"
|
|
BackgroundTransparency: 1
|
|
Image: "http://www.roblox.com/asset?id=54135717"
|
|
Position: UDim2.new 0, -2, 0, -2
|
|
Size: UDim2.new 0, 16, 0, 16
|
|
ZIndex: 6
|
|
|
|
* New "Frame", "ItemPreview"
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new 0.8, 5, 0.085, 0
|
|
Size: UDim2.new 0.21, 0, 0.9, 0
|
|
ZIndex: 6
|
|
|
|
* New "ImageLabel", "LargePreview"
|
|
BackgroundTransparency: 1
|
|
Image: ""
|
|
Size: UDim2.new 1, 0, 0, 170
|
|
ZIndex: 6
|
|
|
|
* New "Frame", "TextPanel"
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new 0, 0, 0.45, 0
|
|
Size: UDim2.new 1, 0, 0.55, 0
|
|
ZIndex: 6
|
|
|
|
* New "TextLabel", "RolloverText"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 1, 0, 0, 48
|
|
ZIndex: 6
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size24
|
|
Text: ""
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextWrap: true
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Top
|
|
|
|
* New "Frame", "Sets"
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new 0, 0, 0, 5
|
|
Size: UDim2.new 0.23, 0, 1, -5
|
|
ZIndex: 6
|
|
|
|
* New "Frame", "Line"
|
|
BackgroundColor3: Color3.new 1, 1, 1
|
|
BackgroundTransparency: 0.7
|
|
BorderSizePixel: 0
|
|
Position: UDim2.new 1, -3, 0.06, 0
|
|
Size: UDim2.new 0, 3, 0.9, 0
|
|
ZIndex: 6
|
|
|
|
* New "TextLabel", "SetsHeader"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 47, 0, 24
|
|
ZIndex: 6
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size24
|
|
Text: "Sets"
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
TextYAlignment: Enum.TextYAlignment.Top
|
|
|
|
setsLists, controlFrame = t.CreateTrueScrollingFrame!
|
|
with setsLists
|
|
.Size = UDim2.new 1, -6, 0.94, 0
|
|
.Position = UDim2.new 0, 0, 0.06, 0
|
|
.BackgroundTransparency = 1
|
|
.Name = "SetsLists"
|
|
.ZIndex = 6
|
|
.Parent = setPanel.Sets
|
|
drillDownSetZIndex controlFrame, 7
|
|
|
|
setGui
|
|
|
|
createSetButton = (text) ->
|
|
setButton = New "TextButton"
|
|
Text: text or ""
|
|
AutoButtonColor: false
|
|
BackgroundTransparency: 1
|
|
BackgroundColor3: Color3.new 1, 1, 1
|
|
BorderSizePixel: 0
|
|
Size: UDim2.new 1, -5, 0, 18
|
|
ZIndex: 6
|
|
Visible: false
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
|
|
setButton
|
|
|
|
buildSetButton = (name, setId, _, _, _) ->
|
|
button = createSetButton name
|
|
with button
|
|
.Text = name
|
|
.Name = "SetButton"
|
|
.Visible = true
|
|
|
|
New "IntValue", "SetId"
|
|
Value: setId
|
|
Parent: button
|
|
|
|
New "StringValue", "SetName"
|
|
Value: name
|
|
Parent: button
|
|
|
|
button
|
|
|
|
processCategory = (sets) ->
|
|
setButtons = {}
|
|
numSkipped = 0
|
|
for i = 1, #sets
|
|
if not showAdminCategories and sets[i].Name == "Beta"
|
|
numSkipped += 1
|
|
else
|
|
setButtons[i - numSkipped] = buildSetButton sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets
|
|
|
|
setButtons
|
|
|
|
handleResize = ->
|
|
wait! -- neccessary to insure heartbeat happened
|
|
|
|
with setGui.SetPanel.ItemPreview
|
|
.LargePreview.Size = UDim2.new 1, 0, 0, .AbsoluteSize.X
|
|
.LargePreview.Position = UDim2.new 0.5, -.LargePreview.AbsoluteSize.X / 2, 0, 0
|
|
.TextPanel.Position = UDim2.new 0, 0, 0, .LargePreview.AbsoluteSize.Y
|
|
.TextPanel.Size = UDim2.new 1, 0, 0, .AbsoluteSize.Y - .LargePreview.AbsoluteSize.Y
|
|
|
|
makeInsertAssetButton = ->
|
|
insertAssetButtonExample = New "Frame", "InsertAssetButtonExample"
|
|
Position: UDim2.new 0, 128, 0, 64
|
|
Size: UDim2.new 0, 64, 0, 64
|
|
BackgroundTransparency: 1
|
|
ZIndex: 6
|
|
Visible: false
|
|
|
|
* New "IntValue", "AssetId"
|
|
Value: 0
|
|
|
|
* New "StringValue", "AssetName"
|
|
Value: ""
|
|
|
|
* New "TextButton", "Button"
|
|
Text: ""
|
|
Style: Enum.ButtonStyle.RobloxButton
|
|
Position: UDim2.new 0.025, 0, 0.025, 0
|
|
Size: UDim2.new 0.95, 0, 0.95, 0
|
|
ZIndex: 6
|
|
|
|
* New "ImageLabel", "ButtonImage"
|
|
Image: ""
|
|
Position: UDim2.new 0, -7, 0, -7
|
|
Size: UDim2.new 1, 14, 1, 14
|
|
BackgroundTransparency: 1
|
|
ZIndex: 7
|
|
|
|
with insertAssetButtonExample.button.ButtonImage\clone!
|
|
.Name = "ConfigIcon"
|
|
.Visible = false
|
|
.Position = UDim2.new 1, -23, 1, -24
|
|
.Size = UDim2.new 0, 16, 0, 16
|
|
.Image = ""
|
|
.ZIndex = 6
|
|
.Parent = insertAssetButtonExample
|
|
|
|
insertAssetButtonExample
|
|
|
|
showLargePreview = (insertButton) ->
|
|
if insertButton\FindFirstChild "AssetId"
|
|
delay 0, ->
|
|
game\GetService"ContentProvider"\Preload LargeThumbnailUrl .. "#{insertButton.AssetId.Value}"
|
|
setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. "#{insertButton.AssetId.Value}"
|
|
|
|
if insertButton\FindFirstChild "AssetName"
|
|
setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
|
|
|
|
selectTerrainShape = (shape) ->
|
|
if currTerrainDropDownFrame
|
|
objectSelected(
|
|
tostring(currTerrainDropDownFrame.AssetName.Value),
|
|
tonumber(currTerrainDropDownFrame.AssetId.Value),
|
|
shape
|
|
)
|
|
|
|
createTerrainTypeButton = (name, parent) ->
|
|
dropDownTextButton = New "TextButton", "#{name}Button"
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size14
|
|
BorderSizePixel: 0
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Text: name
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
BackgroundTransparency: 1
|
|
ZIndex: parent.ZIndex + 1
|
|
Size: UDim2.new 0, parent.Size.X.Offset - 2, 0, 16
|
|
Position: UDim2.new 0, 1, 0, 0
|
|
|
|
with dropDownTextButton
|
|
.MouseEnter\connect ->
|
|
.BackgroundTransparency = 0
|
|
.TextColor3 = Color3.new 0, 0, 0
|
|
|
|
.MouseLeave\connect ->
|
|
.BackgroundTransparency = 1
|
|
.TextColor3 = Color3.new 1, 1, 1
|
|
|
|
.MouseButton1Click\connect ->
|
|
.BackgroundTransparency = 1
|
|
.TextColor3 = Color3.new 1, 1, 1
|
|
if .Parent and .Parent\IsA "GuiObject"
|
|
.Parent.Visible = false
|
|
|
|
selectTerrainShape terrainShapeMap[.Text]
|
|
|
|
dropDownTextButton
|
|
|
|
createTerrainDropDownMenu = (zIndex) ->
|
|
dropDown = New "Frame", "TerrainDropDown"
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
BorderColor3: Color3.new 1, 0, 0
|
|
Size: UDim2.new 0, 200, 0, 0
|
|
Visible: false
|
|
ZIndex: zIndex
|
|
Parent: setGui
|
|
|
|
for i = 1, #terrainShapes
|
|
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
|
|
|
|
dropDown.MouseLeave\connect ->
|
|
dropDown.Visible = false
|
|
|
|
createDropDownMenuButton = (parent) ->
|
|
dropDownButton = New "ImageButton"
|
|
Name: "DropDownButton"
|
|
Image: "http://www.roblox.com/asset/?id=67581509"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 16, 0, 16
|
|
Position: UDim2.new 1, -24, 0, 6
|
|
ZIndex: parent.ZIndex + 2
|
|
Parent: parent
|
|
|
|
if not setGui\FindFirstChild "TerrainDropDown"
|
|
createTerrainDropDownMenu 8
|
|
|
|
dropDownButton.MouseButton1Click\connect ->
|
|
setGui.TerrainDropDown.Visible = true
|
|
setGui.TerrainDropDown.Position = UDim2.new 0, parent.AbsolutePosition.X, 0, parent.AbsolutePosition.Y
|
|
currTerrainDropDownFrame = parent
|
|
|
|
buildInsertButton = ->
|
|
insertButton = makeInsertAssetButton!
|
|
insertButton.Name = "InsertAssetButton"
|
|
insertButton.Visible = true
|
|
|
|
if Data.Category[Data.CurrentCategory].SetName == "High Scalability"
|
|
createDropDownMenuButton insertButton
|
|
|
|
lastEnter = nil
|
|
mouseEnterCon = insertButton.MouseEnter\connect ->
|
|
lastEnter = insertButton
|
|
delay 0.1, ->
|
|
if lastEnter == insertButton
|
|
showLargePreview insertButton
|
|
|
|
insertButton, mouseEnterCon
|
|
|
|
realignButtonGrid = (columns) ->
|
|
x = 0
|
|
y = 0
|
|
for i = 1, #insertButtons
|
|
insertButtons[i].Position = UDim2.new 0, buttonWidth * x, 0, buttonHeight * y
|
|
x += 1
|
|
if x >= columns
|
|
x = 0
|
|
y += 1
|
|
|
|
setInsertButtonImageBehavior = (insertFrame, visible, name, assetId) ->
|
|
if visible
|
|
insertFrame.AssetName.Value = name
|
|
insertFrame.AssetId.Value = assetId
|
|
newImageUrl = SmallThumbnailUrl .. assetId
|
|
if newImageUrl ~= insertFrame.Button.ButtonImage.Image
|
|
delay 0, ->
|
|
game\GetService"ContentProvider"\Preload(SmallThumbnailUrl .. assetId)
|
|
insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
|
|
|
|
table.insert(
|
|
insertButtonCons,
|
|
insertFrame.Button.MouseButton1Click\connect ->
|
|
-- special case for water, show water selection gui
|
|
isWaterSelected = name == "Water" and
|
|
(Data.Category[Data.CurrentCategory].SetName == "High Scalability")
|
|
waterGui.Visible = isWaterSelected
|
|
objectSelected name, if isWaterSelected
|
|
tonumber(assetId), nil
|
|
else
|
|
tonumber assetId
|
|
|
|
)
|
|
|
|
insertFrame.Visible = true
|
|
else
|
|
insertFrame.Visible = false
|
|
|
|
loadSectionOfItems = (setGui, rows, columns) ->
|
|
pageSize = rows * columns
|
|
|
|
return if arrayPosition > #contents
|
|
|
|
origArrayPos = arrayPosition
|
|
|
|
for _ = 1, pageSize + 1
|
|
break if arrayPosition >= #contents + 1
|
|
|
|
local buttonCon
|
|
insertButtons[arrayPosition], buttonCon = buildInsertButton!
|
|
table.insert insertButtonCons, buttonCon
|
|
insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
|
|
arrayPosition += 1
|
|
|
|
realignButtonGrid columns
|
|
|
|
-- indexCopy = origArrayPos
|
|
for index = origArrayPos, arrayPosition
|
|
if insertButtons[index]
|
|
if contents[index]
|
|
-- we don't want water to have a drop down button
|
|
if contents[index].Name == "Water" and
|
|
Data.Category[Data.CurrentCategory].SetName == "High Scalability"
|
|
insertButtons[index]\FindFirstChild("DropDownButton", true)\Destroy!
|
|
|
|
local assetId
|
|
assetId = if useAssetVersionId
|
|
contents[index].AssetVersionId
|
|
else
|
|
contents[index].AssetId
|
|
|
|
setInsertButtonImageBehavior insertButtons[index], true, contents[index].Name, assetId
|
|
else break
|
|
else break
|
|
|
|
-- indexCopy = index
|
|
|
|
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
|
|
-- remove our buttons and their connections
|
|
for i = 1, #insertButtons
|
|
insertButtons[i]\remove!
|
|
|
|
for i = 1, #insertButtonCons
|
|
if insertButtonCons[i]
|
|
insertButtonCons[i]\disconnect!
|
|
|
|
|
|
insertButtonCons = {}
|
|
insertButtons = {}
|
|
|
|
arrayPosition = 1
|
|
loadSectionOfItems setGui, rows, columns
|
|
|
|
selectSet = (button, setName, setId, _) ->
|
|
if button and Data.Category[Data.CurrentCategory]?
|
|
with Data.Category[Data.CurrentCategory]
|
|
if button ~= .Button
|
|
.Button = button
|
|
|
|
if not SetCache[setId]?
|
|
SetCache[setId] = game\GetService"InsertService"\GetCollection setId
|
|
|
|
.Contents = SetCache[setId]
|
|
.SetName = setName
|
|
.SetId = setId
|
|
|
|
setSetIndex!
|
|
|
|
selectCategoryPage = (buttons, _) ->
|
|
if buttons ~= Data.CurrentCategory
|
|
if Data.CurrentCategory
|
|
for _, button in pairs Data.CurrentCategory
|
|
button.Visible = false
|
|
|
|
Data.CurrentCategory = buttons
|
|
if not Data.Category[Data.CurrentCategory]?
|
|
Data.Category[Data.CurrentCategory] = {}
|
|
if #buttons > 0
|
|
selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
|
|
|
|
else with Data.Category[Data.CurrentCategory]
|
|
.Button = nil
|
|
selectSet(
|
|
.ButtonFrame,
|
|
.SetName,
|
|
.SetId,
|
|
.Index
|
|
)
|
|
|
|
selectCategory = (category) ->
|
|
selectCategoryPage category, 0
|
|
|
|
resetAllSetButtonSelection = ->
|
|
setButtons = setGui.SetPanel.Sets.SetsLists\GetChildren!
|
|
for i = 1, #setButtons
|
|
with setButtons[i] do if \IsA "TextButton"
|
|
.Selected = false
|
|
.BackgroundTransparency = 1
|
|
.TextColor3 = Color3.new 1, 1, 1
|
|
.BackgroundColor3 = Color3.new 1, 1, 1
|
|
|
|
populateSetsFrame = ->
|
|
currRow = 0
|
|
|
|
for i = 1, #userCategoryButtons do with button = userCategoryButtons[i]
|
|
.Visible = true
|
|
.Position = UDim2.new 0, 5, 0, currRow * .Size.Y.Offset
|
|
.Parent = setGui.SetPanel.Sets.SetsLists
|
|
|
|
if i == 1 -- we will have this selected by default, so show it
|
|
.Selected = true
|
|
.BackgroundColor3 = Color3.new 0, 204 / 255, 0
|
|
.TextColor3 = Color3.new 0, 0, 0
|
|
.BackgroundTransparency = 0
|
|
|
|
.MouseEnter\connect ->
|
|
if not .Selected
|
|
.BackgroundTransparency = 0
|
|
.TextColor3 = Color3.new 0, 0, 0
|
|
|
|
.MouseLeave\connect ->
|
|
if not .Selected
|
|
.BackgroundTransparency = 1
|
|
.TextColor3 = Color3.new 1, 1, 1
|
|
|
|
.MouseButton1Click\connect ->
|
|
resetAllSetButtonSelection!
|
|
.Selected = not .Selected
|
|
.BackgroundColor3 = Color3.new 0, 204 / 255, 0
|
|
.TextColor3 = Color3.new 0, 0, 0
|
|
.BackgroundTransparency = 0
|
|
selectSet button, .Text, userCategoryButtons[i].SetId.Value, 0
|
|
|
|
currRow += 1
|
|
|
|
buttons = setGui.SetPanel.Sets.SetsLists\GetChildren!
|
|
|
|
-- set first category as loaded for default
|
|
if buttons
|
|
for i = 1, #buttons
|
|
if buttons[i]\IsA "TextButton"
|
|
selectSet buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0
|
|
selectCategory userCategoryButtons
|
|
break
|
|
|
|
setGui = createSetGui!
|
|
waterGui, waterTypeChangedEvent = createWaterGui!
|
|
waterGui.Position = UDim2.new 0, 55, 0, 0
|
|
waterGui.Parent = setGui
|
|
setGui.Changed\connect (prop) -> -- this resizes the preview image to always be the right size
|
|
if prop == "AbsoluteSize"
|
|
handleResize!
|
|
setSetIndex!
|
|
|
|
scrollFrame, controlFrame = t.CreateTrueScrollingFrame!
|
|
with scrollFrame
|
|
.Name = "ItemsFrame"
|
|
.Size = UDim2.new 0.54, 0, 0.85, 0
|
|
.Position = UDim2.new 0.24, 0, 0.085, 0
|
|
.ZIndex = 6
|
|
.Parent = setGui.SetPanel
|
|
.BackgroundTransparency = 1
|
|
|
|
drillDownSetZIndex controlFrame, 7
|
|
|
|
controlFrame.Parent = setGui.SetPanel
|
|
controlFrame.Position = UDim2.new 0.76, 5, 0, 0
|
|
|
|
debounce = false
|
|
|
|
rows = math.floor setGui.SetPanel.ItemsFrame.AbsoluteSize.Y / buttonHeight
|
|
columns = math.floor setGui.SetPanel.ItemsFrame.AbsoluteSize.X / buttonWidth
|
|
|
|
controlFrame.ScrollBottom.Changed\connect (_) ->
|
|
if controlFrame.ScrollBottom.Value == true
|
|
return if debounce
|
|
|
|
debounce = true
|
|
loadSectionOfItems setGui, rows, columns
|
|
debounce = false
|
|
|
|
userData = {}
|
|
for id = 1, #userIdsForSets
|
|
newUserData = game\GetService"InsertService"\GetUserSets userIdsForSets[id]
|
|
if newUserData and #newUserData > 2
|
|
-- start at #3 to skip over My Decals and My Models for each account
|
|
for category = 3, #newUserData
|
|
table.insert userData, if newUserData[category].Name == "High Scalability" -- we want high scalability parts to show first
|
|
1, newUserData[category]
|
|
else
|
|
newUserData[category]
|
|
|
|
if userData
|
|
userCategoryButtons = processCategory userData
|
|
|
|
populateSetsFrame!
|
|
|
|
--[[insertPanelCloseCon = ]]
|
|
setGui.SetPanel.CancelButton.MouseButton1Click\connect ->
|
|
setGui.SetPanel.Visible = false
|
|
dialogClosed?!
|
|
|
|
setVisibilityFunction = (visible) ->
|
|
setGui.SetPanel.Visible = not not visible
|
|
|
|
getVisibilityFunction = ->
|
|
if setGui?\FindFirstChild "SetPanel"
|
|
return setGui.SetPanel.Visible
|
|
false
|
|
|
|
setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
|
|
|
|
t.CreateTerrainMaterialSelector = (size, position) ->
|
|
terrainMaterialSelectionChanged = Instance.new "BindableEvent"
|
|
terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged"
|
|
|
|
local selectedButton
|
|
|
|
frame = New "Frame", "TerrainMaterialSelector"
|
|
Size: size or UDim2.new 0, 245, 0, 230
|
|
BorderSizePixel: 0
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
Active: true
|
|
|
|
if position
|
|
frame.Position = position
|
|
|
|
terrainMaterialSelectionChanged.Parent = frame
|
|
|
|
-- waterEnabled = true -- todo: turn this on when water is ready
|
|
|
|
materialToImageMap = {}
|
|
materialNames =
|
|
* "Grass"
|
|
* "Sand"
|
|
* "Brick"
|
|
* "Granite"
|
|
* "Asphalt"
|
|
* "Iron"
|
|
* "Aluminum"
|
|
* "Gold"
|
|
* "Plank"
|
|
* "Log"
|
|
* "Gravel"
|
|
* "Cinder Block"
|
|
* "Stone Wall"
|
|
* "Concrete"
|
|
* "Plastic (red)"
|
|
* "Plastic (blue)"
|
|
* "Water"
|
|
-- if waterEnabled
|
|
-- table.insert materialNames, "Water"
|
|
|
|
currentMaterial = 1
|
|
|
|
getEnumFromName = (choice) ->
|
|
for i, v in ipairs materialNames
|
|
return i if v == choice
|
|
|
|
getNameFromEnum = (choice) ->
|
|
switch choice
|
|
when Enum.CellMaterial.Grass, 1 then "Grass"
|
|
when Enum.CellMaterial.Sand, 2 then "Sand"
|
|
when Enum.CellMaterial.Empty, 0 then "Erase"
|
|
when Enum.CellMaterial.Brick, 3 then "Brick"
|
|
when Enum.CellMaterial.Granite, 4 then "Granite"
|
|
when Enum.CellMaterial.Asphalt, 5 then "Asphalt"
|
|
when Enum.CellMaterial.Iron, 6 then "Iron"
|
|
when Enum.CellMaterial.Aluminum, 7 then "Aluminum"
|
|
when Enum.CellMaterial.Gold, 8 then "Gold"
|
|
when Enum.CellMaterial.WoodPlank, 9 then "Plank"
|
|
when Enum.CellMaterial.WoodLog, 10 then "Log"
|
|
when Enum.CellMaterial.Gravel, 11 then "Gravel"
|
|
when Enum.CellMaterial.CinderBlock, 12 then "Cinder Block"
|
|
when Enum.CellMaterial.MossyStone, 13 then "Stone Wall"
|
|
when Enum.CellMaterial.Cement, 14 then "Concrete"
|
|
when Enum.CellMaterial.RedPlastic, 15 then "Plastic (red)"
|
|
when Enum.CellMaterial.BluePlastic, 16 then "Plastic (blue)"
|
|
when Enum.CellMaterial.Water, 17 then "Water"
|
|
|
|
updateMaterialChoice = (choice) ->
|
|
currentMaterial = getEnumFromName choice
|
|
terrainMaterialSelectionChanged\Fire currentMaterial
|
|
|
|
-- we so need a better way to do this
|
|
for _, v in pairs materialNames
|
|
materialToImageMap[v] = {}
|
|
materialToImageMap[v].Regular = "http://www.roblox.com/asset/?id=#{switch v
|
|
when "Grass" then 56563112
|
|
when "Sand" then 62356652
|
|
when "Brick" then 65961537
|
|
when "Granite" then 67532153
|
|
when "Asphalt" then 67532038
|
|
when "Iron" then 67532093
|
|
when "Aluminum" then 67531995
|
|
when "Gold" then 67532118
|
|
when "Plastic (red)" then 67531848
|
|
when "Plastic (blue)" then 67531924
|
|
when "Plank" then 67532015
|
|
when "Log" then 67532051
|
|
when "Gravel" then 67532206
|
|
when "Cinder Block" then 67532103
|
|
when "Stone Wall" then 67531804
|
|
when "Concrete" then 67532059
|
|
when "Water" then 81407474
|
|
else 66887593}"
|
|
|
|
-- fill in the rest here!!
|
|
|
|
scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame nil, "grid"
|
|
|
|
with scrollFrame
|
|
.Size = UDim2.new 0.85, 0, 1, 0
|
|
.Position = UDim2.new 0, 0, 0, 0
|
|
.Parent = frame
|
|
|
|
with scrollUp
|
|
.Parent = frame
|
|
.Visible = true
|
|
.Position = UDim2.new 1, -19, 0, 0
|
|
|
|
with scrollDown
|
|
.Parent = frame
|
|
.Visible = true
|
|
.Position = UDim2.new 1, -19, 1, -17
|
|
|
|
goToNewMaterial = (buttonWrap, materialName) ->
|
|
updateMaterialChoice materialName
|
|
buttonWrap.BackgroundTransparency = 0
|
|
selectedButton.BackgroundTransparency = 1
|
|
selectedButton = buttonWrap
|
|
|
|
createMaterialButton = (name) ->
|
|
buttonWrap = New "TextButton", "#{name}"
|
|
Text: ""
|
|
Size: UDim2.new 0, 32, 0, 32
|
|
BackgroundColor3: Color3.new 1, 1, 1
|
|
BorderSizePixel: 0
|
|
BackgroundTransparency: 1
|
|
AutoButtonColor: false
|
|
|
|
* New "ImageButton", "#{name}"
|
|
AutoButtonColor: false
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 0, 30, 0, 30
|
|
Position: UDim2.new 0, 1, 0, 1
|
|
Image: materialToImageMap[name].Regular
|
|
|
|
* New "NumberValue", "EnumType"
|
|
Value: 0
|
|
|
|
with buttonWrap.ImageButton
|
|
.MouseEnter\connect ->
|
|
buttonWrap.BackgroundTransparency = 0
|
|
.MouseLeave\connect ->
|
|
if selectedButton ~= buttonWrap
|
|
buttonWrap.BackgroundTransparency = 1
|
|
.MouseButton1Click\connect ->
|
|
if selectedButton ~= buttonWrap
|
|
goToNewMaterial buttonWrap, tostring name
|
|
|
|
buttonWrap
|
|
|
|
for i = 1, #materialNames
|
|
imageButton = createMaterialButton materialNames[i]
|
|
|
|
if materialNames[i] == "Grass" then -- always start with grass as the default
|
|
selectedButton = imageButton
|
|
imageButton.BackgroundTransparency = 0
|
|
|
|
imageButton.Parent = scrollFrame
|
|
|
|
forceTerrainMaterialSelection = (newMaterialType) ->
|
|
return if not newMaterialType
|
|
return if currentMaterial == newMaterialType
|
|
|
|
matName = getNameFromEnum newMaterialType
|
|
buttons = scrollFrame\GetChildren!
|
|
for i = 1, #buttons
|
|
if (buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)") or
|
|
(buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)") or
|
|
(string.find buttons[i].Name, matName)
|
|
goToNewMaterial buttons[i], matName
|
|
return
|
|
|
|
frame.Changed\connect (prop) ->
|
|
if prop == "AbsoluteSize"
|
|
recalculateScroll!
|
|
|
|
recalculateScroll!
|
|
frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
|
|
|
|
t.CreateLoadingFrame = (name, size, position) ->
|
|
game\GetService"ContentProvider"\Preload "http://www.roblox.com/asset/?id=35238053"
|
|
|
|
loadingFrame = New "Frame", "LoadingFrame"
|
|
Style: Enum.FrameStyle.RobloxRound
|
|
Size: size or UDim2.new 0, 300, 0, 160
|
|
Position: position or UDim2.new 0.5, -150, 0.5, -80
|
|
|
|
* New "TextLabel", "loadingName"
|
|
BackgroundTransparency: 1
|
|
Size: UDim2.new 1, 0, 0, 18
|
|
Position: UDim2.new 0, 0, 0, 2
|
|
Font: Enum.Font.Arial
|
|
Text: name
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextStrokeTransparency: 1
|
|
FontSize: Enum.FontSize.Size18
|
|
|
|
* New "TextButton", "CancelButton"
|
|
Position: UDim2.new 0.5, -60, 1, -40
|
|
Size: UDim2.new 0, 120, 0, 40
|
|
Font: Enum.Font.Arial
|
|
FontSize: Enum.FontSize.Size18
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Text: "Cancel"
|
|
Style: Enum.ButtonStyle.RobloxButton
|
|
|
|
* New "Frame", "LoadingBar"
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
BorderColor3: Color3.new 79 / 255, 79 / 255, 79 / 255
|
|
Position: UDim2.new 0, 0, 0, 41
|
|
Size: UDim2.new 1, 0, 0, 30
|
|
|
|
* New "ImageLabel", "LoadingGreenBar"
|
|
Image: "http://www.roblox.com/asset/?id=35238053"
|
|
Position: UDim2.new 0, 0, 0, 0
|
|
Size: UDim2.new 0, 0, 1, 0
|
|
Visible: false
|
|
|
|
* New "TextLabel", "LoadingPercent"
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new 0, 0, 1, 0
|
|
Size: UDim2.new 1, 0, 0, 14
|
|
Font: Enum.Font.Arial
|
|
Text: "0%"
|
|
FontSize: Enum.FontSize.Size14
|
|
TextColor3: Color3.new 1, 1, 1
|
|
|
|
{ -- Destructure
|
|
CancelButton: cancelButton
|
|
LoadingBar:
|
|
LoadingGreenBar: loadingGreenBar
|
|
LoadingPercent: loadingPercent
|
|
} = loadingFrame
|
|
|
|
cancelButtonClicked = New "BindableEvent", "CancelButtonClicked"
|
|
Parent: cancelButton
|
|
|
|
cancelButton.MouseButton1Click\connect ->
|
|
cancelButtonClicked\Fire!
|
|
|
|
updateLoadingGuiPercent = (percent, tweenAction, tweenLength) ->
|
|
if percent and type(percent) ~= "number"
|
|
error "updateLoadingGuiPercent expects number as argument, got", type(percent), "instead"
|
|
|
|
newSize = UDim2.new if percent < 0
|
|
0, 0, 1, 0
|
|
elseif percent > 1
|
|
1, 0, 1, 0
|
|
else
|
|
percent, 0, 1, 0
|
|
|
|
if tweenAction
|
|
if not tweenLength
|
|
error "updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument"
|
|
|
|
loadingGreenBar\TweenSize newSize, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, tweenLength,
|
|
if newSize.X.Scale > 0
|
|
loadingGreenBar.Visible = true
|
|
true
|
|
else
|
|
true, ->
|
|
if newSize.X.Scale < 0
|
|
loadingGreenBar.Visible = false
|
|
|
|
else
|
|
loadingGreenBar.Size = newSize
|
|
loadingGreenBar.Visible = newSize.X.Scale > 0
|
|
|
|
|
|
loadingGreenBar.Changed\connect (prop) ->
|
|
if prop == "Size"
|
|
loadingPercent.Text = "#{math.ceil loadingGreenBar.Size.X.Scale * 100}%"
|
|
|
|
loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
|
|
|
|
t.CreatePluginFrame = (name, size, position, scrollable, parent) ->
|
|
createMenuButton = (size, position, text, fontsize, name, parent) ->
|
|
with New "TextButton", name,
|
|
AutoButtonColor: false
|
|
BackgroundTransparency: 1
|
|
Position: position
|
|
Size: size
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: fontsize
|
|
Text: text
|
|
TextColor3: Color3.new 1, 1, 1
|
|
BorderSizePixel: 0
|
|
BackgroundColor3: Color3.new 20 / 255, 20 / 255, 20 / 255
|
|
|
|
.MouseEnter\connect ->
|
|
return if .Selected
|
|
.BackgroundTransparency = 0
|
|
|
|
.MouseLeave\connect ->
|
|
return if .Selected
|
|
.BackgroundTransparency = 1
|
|
|
|
.Parent = parent
|
|
|
|
dragBar = New "Frame", "#{name}DragBar"
|
|
BackgroundColor3: Color3.new 39 / 255, 39 / 255, 39 / 255
|
|
BorderColor3: Color3.new 0, 0, 0
|
|
Size: if size
|
|
UDim2.new(size.X.Scale, size.X.Offset, 0, 20) + UDim2.new 0, 20, 0, 0
|
|
else
|
|
UDim2.new 0, 183, 0, 20
|
|
Active: true
|
|
Draggable: true
|
|
|
|
-- plugin name label
|
|
* New "TextLabel", "BarNameLabel"
|
|
Text: " #{name}"
|
|
TextColor3: Color3.new 1, 1, 1
|
|
TextStrokeTransparency: 0
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size18
|
|
TextXAlignment: Enum.TextXAlignment.Left
|
|
BackgroundTransparency: 1
|
|
|
|
* New "Frame", "HelpFrame"
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
Size: UDim2.new 0, 300, 0, 552
|
|
Position: UDim2.new 1, 5, 0, 0
|
|
Active: true
|
|
BorderSizePixel: 0
|
|
Visible: false
|
|
|
|
* New "Frame", "SeparatingLine"
|
|
BackgroundColor3: Color3.new 115 / 255, 115 / 255, 115 / 255
|
|
BorderSizePixel: 0
|
|
Position: UDim2.new 1, -18, 0.5, -7
|
|
Size: UDim2.new 0, 1, 0, 14
|
|
|
|
* New "Frame", "MinimizeFrame"
|
|
BackgroundColor3: Color3.new 73 / 255, 73 / 255, 73 / 255
|
|
BorderColor3: Color3.new 0, 0, 0
|
|
Position: UDim2.new 0, 0, 1, 0
|
|
Size: if size
|
|
UDim2.new(size.X.Scale, size.X.Offset, 0, 50) + UDim2.new 0, 20, 0, 0
|
|
else
|
|
UDim2.new 0, 183, 0, 50
|
|
Visible: false
|
|
|
|
* New "TextButton", "MinimizeButton"
|
|
Position: UDim2.new 0.5, -50, 0.5, -20
|
|
Size: UDim2.new 0, 100, 0, 40
|
|
Style: Enum.ButtonStyle.RobloxButton
|
|
Font: Enum.Font.ArialBold
|
|
FontSize: Enum.FontSize.Size18
|
|
TextColor3: Color3.new 1, 1, 1
|
|
Text: "Show"
|
|
|
|
with dragBar
|
|
if position
|
|
.Position = position
|
|
|
|
--.Visible = false
|
|
.MouseEnter\connect ->
|
|
.BackgroundColor3 = Color3.new 49 / 255, 49 / 255, 49 / 255
|
|
|
|
.MouseLeave\connect ->
|
|
.BackgroundColor3 = Color3.new 39 / 255, 39 / 255, 39 / 255
|
|
|
|
.Parent = parent
|
|
|
|
-- close button
|
|
closeButton = createMenuButton(
|
|
UDim2.new(0, 15, 0, 17),
|
|
UDim2.new(1, -16, 0.5, -8),
|
|
"X",
|
|
Enum.FontSize.Size14,
|
|
"CloseButton",
|
|
dragBar
|
|
)
|
|
closeEvent = New "BindableEvent", "CloseEvent"
|
|
Parent: closeButton
|
|
|
|
closeButton.MouseButton1Click\connect ->
|
|
closeEvent\Fire!
|
|
closeButton.BackgroundTransparency = 1
|
|
|
|
-- help button
|
|
helpButton = createMenuButton(
|
|
UDim2.new(0, 15, 0, 17),
|
|
UDim2.new(1, -51, 0.5, -8),
|
|
"?",
|
|
Enum.FontSize.Size14,
|
|
"HelpButton",
|
|
dragBar
|
|
)
|
|
|
|
{ -- Destructure
|
|
HelpFrame: helpFrame
|
|
SeparatingLine: separatingLine
|
|
MinimizeFrame: minimizeFrame
|
|
MinimizeFrame:
|
|
MinimizeBigButton: minimizeBigButton
|
|
} = dragBar
|
|
|
|
helpButton.MouseButton1Click\connect ->
|
|
helpFrame.Visible = not helpFrame.Visible
|
|
if helpFrame.Visible
|
|
helpButton.Selected = true
|
|
helpButton.BackgroundTransparency = 0
|
|
screenGui = getScreenGuiAncestor helpFrame
|
|
if screenGui
|
|
if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X --position on left hand side
|
|
helpFrame.Position = UDim2.new 0, -5 - helpFrame.AbsoluteSize.X, 0, 0
|
|
else -- position on right hand side
|
|
helpFrame.Position = UDim2.new 1, 5, 0, 0
|
|
|
|
else
|
|
helpFrame.Position = UDim2.new 1, 5, 0, 0
|
|
else
|
|
helpButton.Selected = false
|
|
helpButton.BackgroundTransparency = 1
|
|
|
|
minimizeButton = createMenuButton(
|
|
UDim2.new(0, 16, 0, 17),
|
|
UDim2.new(1, -34, 0.5, -8),
|
|
"-",
|
|
Enum.FontSize.Size14,
|
|
"MinimizeButton",
|
|
dragBar
|
|
)
|
|
minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
|
|
|
|
with separatingLine\clone!
|
|
.Position = UDim2.new 1, -35, 0.5, -7
|
|
.Parent = dragBar
|
|
|
|
widgetContainer = New "Frame", "WidgetContainer"
|
|
BackgroundTransparency: 1
|
|
Position: UDim2.new 0, 0, 1, 0
|
|
BorderColor3: Color3.new 0, 0, 0
|
|
|
|
* New "TextButton", "VerticalDragger"
|
|
ZIndex: 2
|
|
AutoButtonColor: false
|
|
BackgroundColor3: Color3.new 50 / 255, 50 / 255, 50 / 255
|
|
BorderColor3: Color3.new 0, 0, 0
|
|
Size: UDim2.new 1, 20, 0, 20
|
|
Position: UDim2.new 0, 0, 1, 0
|
|
Active: true
|
|
Text: ""
|
|
|
|
* New "Frame", "ScrubFrame"
|
|
BackgroundColor3: Color3.new 1, 1, 1
|
|
BorderSizePixel: 0
|
|
Position: UDim2.new 0.5, -5, 0.5, 0
|
|
Size: UDim2.new 0, 10, 0, 1
|
|
ZIndex: 5
|
|
|
|
{ -- Destructure
|
|
VerticalDragger: verticalDragger
|
|
VerticalDragger:
|
|
ScrubFrame: scrubFrame
|
|
} = widgetContainer
|
|
|
|
if not scrollable
|
|
widgetContainer.BackgroundTransparency = 0
|
|
widgetContainer.BackgroundColor3 = Color3.new 72 / 255, 72 / 255, 72 / 255
|
|
|
|
widgetContainer.Parent = dragBar
|
|
|
|
if size
|
|
widgetContainer.Size = if scrollable
|
|
size
|
|
else
|
|
UDim2.new 0, dragBar.AbsoluteSize.X, size.Y.Scale, size.Y.Offset
|
|
|
|
else
|
|
widgetContainer.Size = UDim2.new if scrollable
|
|
0, 163, 0, 400
|
|
else
|
|
0, dragBar.AbsoluteSize.X, 0, 400
|
|
|
|
if position
|
|
widgetContainer.Position = position + UDim2.new 0, 0, 0, 20
|
|
|
|
local frame, control
|
|
if scrollable
|
|
--frame for widgets
|
|
frame, control = t.CreateTrueScrollingFrame!
|
|
|
|
with frame
|
|
.Size = UDim2.new 1, 0, 1, 0
|
|
.BackgroundColor3 = Color3.new 72 / 255, 72 / 255, 72 / 255
|
|
.BorderColor3 = Color3.new 0, 0, 0
|
|
.Active = true
|
|
.Parent = widgetContainer
|
|
with control
|
|
.BackgroundColor3 = Color3.new 72 / 255, 72 / 255, 72 / 255
|
|
.BorderSizePixel = 0
|
|
.BackgroundTransparency = 0
|
|
.Position = UDim2.new 1, -21, 1, 1
|
|
.Size = UDim2.new 0, 21, if size
|
|
size.Y.Scale, size.Y.Offset
|
|
else
|
|
0, 400
|
|
\FindFirstChild"ScrollDownButton".Position = UDim2.new 0, 0, 1, -20
|
|
|
|
.Parent = dragBar
|
|
|
|
New "Frame", "FakeLine"
|
|
BorderSizePixel: 0
|
|
BackgroundColor3: Color3.new 0, 0, 0
|
|
Size: UDim2.new 0, 1, 1, 1
|
|
Position: UDim2.new 1, 0, 0, 0
|
|
Parent: control
|
|
|
|
for _ = 1, 2
|
|
with scrubFrame\clone!
|
|
.Position = UDim2.new 0.5, -5, 0.5, 2
|
|
.Parent = verticalDragger
|
|
|
|
areaSoak = New "TextButton", "AreaSoak"
|
|
Size: UDim2.new 1, 0, 1, 0
|
|
BackgroundTransparency: 1
|
|
BorderSizePixel: 0
|
|
Text: ""
|
|
ZIndex: 10
|
|
Visible: false
|
|
Active: true
|
|
Parent: getScreenGuiAncestor parent
|
|
|
|
draggingVertical = false
|
|
local startYPos
|
|
|
|
with verticalDragger
|
|
.MouseEnter\connect ->
|
|
.BackgroundColor3 = Color3.new 60 / 255, 60 / 255, 60 / 255
|
|
.MouseLeave\connect ->
|
|
.BackgroundColor3 = Color3.new 50 / 255, 50 / 255, 50 / 255
|
|
.MouseButton1Down\connect (_, y) ->
|
|
draggingVertical = true
|
|
areaSoak.Visible = true
|
|
startYPos = y
|
|
|
|
areaSoak.MouseButton1Up\connect ->
|
|
draggingVertical = false
|
|
areaSoak.Visible = false
|
|
areaSoak.MouseMoved\connect (_, y) ->
|
|
return if not draggingVertical
|
|
|
|
yDelta = y - startYPos
|
|
return if not control.ScrollDownButton.Visible and yDelta > 0
|
|
|
|
|
|
if (widgetContainer.Size.Y.Offset + yDelta) < 150
|
|
widgetContainer.Size = UDim2.new(
|
|
widgetContainer.Size.X.Scale,
|
|
widgetContainer.Size.X.Offset,
|
|
widgetContainer.Size.Y.Scale,
|
|
150
|
|
)
|
|
control.Size = UDim2.new 0, 21, 0, 150
|
|
return
|
|
|
|
startYPos = y
|
|
|
|
if widgetContainer.Size.Y.Offset + yDelta >= 0
|
|
widgetContainer.Size = UDim2.new(
|
|
widgetContainer.Size.X.Scale,
|
|
widgetContainer.Size.X.Offset,
|
|
widgetContainer.Size.Y.Scale,
|
|
widgetContainer.Size.Y.Offset + yDelta
|
|
)
|
|
control.Size = UDim2.new 0, 21, 0, control.Size.Y.Offset + yDelta
|
|
|
|
switchMinimize = ->
|
|
minimizeFrame.Visible = not minimizeFrame.Visible
|
|
if scrollable
|
|
frame.Visible = not frame.Visible
|
|
verticalDragger.Visible = not verticalDragger.Visible
|
|
control.Visible = not control.Visible
|
|
else
|
|
widgetContainer.Visible = not widgetContainer.Visible
|
|
|
|
minimizeButton.Text = if minimizeFrame.Visible
|
|
"+"
|
|
else
|
|
"-"
|
|
|
|
minimizeBigButton.MouseButton1Click\connect switchMinimize
|
|
minimizeButton.MouseButton1Click\connect switchMinimize
|
|
|
|
return dragBar, if scrollable
|
|
frame, helpFrame, closeEvent
|
|
else
|
|
widgetContainer, helpFrame, closeEvent
|
|
|
|
t.Help = (funcNameOrFunc) ->
|
|
--input argument can be a string or a function. Should return a description (of arguments and expected side effects)
|
|
switch funcNameOrFunc
|
|
when 'CreatePropertyDropDownMenu', t.CreatePropertyDropDownMenu
|
|
'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"'
|
|
|
|
when 'CreateDropDownMenu', t.CreateDropDownMenu
|
|
'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'
|
|
|
|
when 'CreateMessageDialog', t.CreateMessageDialog
|
|
'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'
|
|
|
|
when 'CreateStyledMessageDialog', t.CreateStyledMessageDialog
|
|
'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'
|
|
|
|
when 'GetFontHeight', t.GetFontHeight
|
|
'Function GetFontHeight. ' ..
|
|
'Arguments: (font, fontSize). ' ..
|
|
'Side effect: returns the size in pixels of the given font + fontSize'
|
|
|
|
when 'CreateScrollingFrame', t.CreateScrollingFrame
|
|
'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)'
|
|
|
|
when 'CreateTrueScrollingFrame', t.CreateTrueScrollingFrame
|
|
'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.'
|
|
|
|
when 'AutoTruncateTextObject', t.AutoTruncateTextObject
|
|
'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'
|
|
|
|
when 'CreateSlider', t.CreateSlider
|
|
'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.'
|
|
|
|
when 'CreateLoadingFrame', t.CreateLoadingFrame
|
|
'Function CreateLoadingFrame. ' ..
|
|
'Arguments: (name, size, position) ' ..
|
|
'Side effect: Creates a gui that can be manipulated to show progress for a particular action. Name appears above the loading bar, and size and position are udim2 values (both size and position are optional arguments). Returns 3 arguments, the first being the gui created. The second being updateLoadingGuiPercent, which is a bindable function. This function takes one argument (two optionally), which should be a number between 0 and 1, representing the percentage the loading gui should be at. The second argument to this function is a boolean value that if set to true will tween the current percentage value to the new percentage value, therefore our third argument is how long this tween should take. Our third returned argument is a BindableEvent, that
|
|
when fired means that someone clicked the cancel button on the dialog.'
|
|
|
|
when 'CreateTerrainMaterialSelector', t.CreateTerrainMaterialSelector
|
|
'Function CreateTerrainMaterialSelector. ' ..
|
|
'Arguments: (size, position) ' ..
|
|
'Side effect: Size and position are UDim2 values that specifies the selector"s size and position. Both size and position are optional arguments. This method returns 3 objects (terrainSelectorGui, terrainSelected, forceTerrainSelection). terrainSelectorGui is just the gui object that we generate with this function, parent it as you like. TerrainSelected is a BindableEvent that is fired whenever a new terrain type is selected in the gui. ForceTerrainSelection is a function that takes an argument of Enum.CellMaterial and will force the gui to show that material as currently selected.'
|
|
|
|
-- Thanks RbxGui, that was unbelievably tedious to port
|
|
-- Heliodex
|