2013/yue/45284430.lua

1195 lines
35 KiB
Lua

local t = { }
local New
New = function(className, name, props)
if not (props ~= nil) then
props = name
name = nil
end
local obj = Instance.new(className)
if name then
obj.Name = name
end
local parent
for k, v in pairs(props) do
if type(k) == "string" then
if k == "Parent" then
parent = v
else
obj[k] = v
end
elseif type(k) == "number" and type(v) == "userdata" then
v.Parent = obj
end
end
obj.Parent = parent
return obj
end
local ScopedConnect
ScopedConnect = function(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
local eventConnection
local tryConnect
tryConnect = function()
if game:IsAncestorOf(parentInstance) then
if not eventConnection then
eventConnection = instance[event]:connect(signalFunc)
if syncFunc then
syncFunc()
end
end
if eventConnection then
eventConnection:disconnect()
if removeFunc then
return removeFunc()
end
end
end
end
local connection = parentInstance.AncestryChanged:connect(tryConnect)
tryConnect()
return connection
end
local getScreenGuiAncestor
getScreenGuiAncestor = function(instance)
local localInstance = instance
while localInstance and not localInstance:IsA("ScreenGui") do
localInstance = localInstance.Parent
end
return localInstance
end
local CreateButtons
CreateButtons = function(frame, buttons, yPos, ySize)
local buttonNum = 1
local buttonObjs = { }
for _, obj in ipairs(buttons) do
local button = New("TextButton", "Button" .. tostring(buttonNum), {
Font = Enum.Font.Arial,
FontSize = Enum.FontSize.Size18,
AutoButtonColor = true,
Modal = true,
Style = (function()
if obj["Style"] then
return obj.Style
else
return Enum.ButtonStyle.RobloxButton
end
end)(),
Text = obj.Text,
TextColor3 = Color3.new(1, 1, 1),
Parent = frame
})
button.MouseButton1Click:connect(obj.Function)
buttonObjs[buttonNum] = button
buttonNum = buttonNum + 1
end
local numButtons = buttonNum - 1
if numButtons == 1 then
frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
frame.Button1.Size = UDim2.new(0.4, 0, ySize.Scale, ySize.Offset)
elseif numButtons == 2 then
frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
frame.Button1.Size = UDim2.new(0.8 / 3, 0, ySize.Scale, ySize.Offset)
frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
frame.Button2.Size = UDim2.new(0.35, 0, ySize.Scale, ySize.Offset)
elseif numButtons >= 3 then
local spacing = 0.1 / numButtons
local buttonSize = 0.9 / numButtons
buttonNum = 1
while buttonNum <= numButtons do
buttonObjs[buttonNum].Position = UDim2.new(spacing * buttonNum + buttonSize * (buttonNum - 1), 0, yPos.Scale, yPos.Offset)
buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
buttonNum = buttonNum + 1
end
end
end
local setSliderPos
setSliderPos = function(newAbsPosX, slider, sliderPosition, bar, steps)
local newStep = steps - 1
local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X))
local wholeNum, remainder = math.modf(relativePosX * newStep)
if remainder > 0.5 then
wholeNum = wholeNum + 1
end
relativePosX = wholeNum / newStep
local result = math.ceil(relativePosX * newStep)
if sliderPosition.Value ~= result + 1 then
sliderPosition.Value = result + 1
slider.Position = UDim2.new(relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset)
end
end
local cancelSlide
cancelSlide = function(areaSoak)
areaSoak.Visible = false
if areaSoakMouseMoveCon then
return areaSoakMouseMoveCon:disconnect()
end
end
t.CreateStyledMessageDialog = function(title, message, style, buttons)
local frame = New("Frame", "MessageDialog", {
Size = UDim2.new(0.5, 0, 0, 165),
Position = UDim2.new(0.25, 0, 0.5, -72.5),
Active = true,
Style = Enum.FrameStyle.RobloxRound,
New("ImageLabel", "StyleImage", {
BackgroundTransparency = 1,
Position = UDim2.new(0, 5, 0, 15)
}),
New("TextLabel", "Title", {
Text = title,
TextStrokeTransparency = 0,
BackgroundTransparency = 1,
TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255),
Position = UDim2.new(0, 80, 0, 0),
Size = UDim2.new(1, -80, 0, 40),
Font = Enum.Font.ArialBold,
FontSize = Enum.FontSize.Size36,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Center
}),
New("TextLabel", "Message", {
Text = message,
TextStrokeTransparency = 0,
TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255),
Position = UDim2.new(0.025, 80, 0, 45),
Size = UDim2.new(0.95, -80, 0, 55),
BackgroundTransparency = 1,
Font = Enum.Font.Arial,
FontSize = Enum.FontSize.Size18,
TextWrap = true,
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Top
})
})
local StyleImage = frame.StyleImage
if style == "error" or style == "Error" then
StyleImage.Size = UDim2.new(0, 71, 0, 71)
StyleImage.Image = "http://www.roblox.com/asset?id=42565285"
elseif style == "notify" or style == "Notify" then
StyleImage.Size = UDim2.new(0, 71, 0, 71)
StyleImage.Image = "http://www.roblox.com/asset?id=42604978"
elseif style == "confirm" or style == "Confirm" then
StyleImage.Size = UDim2.new(0, 74, 0, 76)
StyleImage.Image = "http://www.roblox.com/asset?id=42557901"
else
return t.CreateMessageDialog(title, message, buttons)
end
CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40))
return frame
end
t.CreateMessageDialog = function(title, message, buttons)
local frame = New("Frame", "MessageDialog", {
Size = UDim2.new(0.5, 0, 0.5, 0),
Position = UDim2.new(0.25, 0, 0.25, 0),
Active = true,
Style = Enum.FrameStyle.RobloxRound,
Parent = script.Parent,
New("TextLabel", "Title", {
Text = title,
BackgroundTransparency = 1,
TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255),
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, 0.15, 0),
Font = Enum.Font.ArialBold,
FontSize = Enum.FontSize.Size36,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Center
}),
New("TextLabel", "Message", {
Text = message,
TextColor3 = Color3.new(221 / 255, 221 / 255, 221 / 255),
Position = UDim2.new(0.025, 0, 0.175, 0),
Size = UDim2.new(0.95, 0, 0.55, 0),
BackgroundTransparency = 1,
Font = Enum.Font.Arial,
FontSize = Enum.FontSize.Size18,
TextWrap = true,
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Top
})
})
CreateButtons(frame, buttons, UDim.new(0.8, 0), UDim.new(0.15, 0))
return frame
end
t.CreateDropDownMenu = function(items, onSelect, forRoblox)
local width = UDim.new(0, 100)
local height = UDim.new(0, 32)
local frame = New("Frame", "DropDownMenu", {
BackgroundTransparency = 1,
Size = UDim2.new(width, height),
New("TextButton", "DropDownMenuButton", {
TextWrap = true,
TextColor3 = Color3.new(1, 1, 1),
Text = "Choose One",
Font = Enum.Font.ArialBold,
FontSize = Enum.FontSize.Size18,
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Center,
BackgroundTransparency = 1,
AutoButtonColor = true,
Style = Enum.ButtonStyle.RobloxButton,
Size = UDim2.new(1, 0, 1, 0),
ZIndex = 2,
New("ImageLabel", "Icon", {
Active = false,
Image = "http://www.roblox.com/asset/?id=45732894",
BackgroundTransparency = 1,
Size = UDim2.new(0, 11, 0, 6),
Position = UDim2.new(1, -11, 0.5, -2),
ZIndex = 2
})
})
})
local dropDownMenu = frame.DropDownMenuButton
local itemCount = #items
local dropDownItemCount = #items
local useScrollButtons = false
if dropDownItemCount > 6 then
useScrollButtons = true
dropDownItemCount = 6
end
local droppedDownMenu = New("TextButton", "List", {
Text = "",
BackgroundTransparency = 1,
Style = Enum.ButtonStyle.RobloxButton,
Visible = false,
Active = true,
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(1, 0, (1 + dropDownItemCount) * 0.8, 0),
Parent = frame,
ZIndex = 2
})
local choiceButton = New("TextButton", "ChoiceButton", {
BackgroundTransparency = 1,
BorderSizePixel = 0,
Text = "ReplaceMe",
TextColor3 = Color3.new(1, 1, 1),
TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Center,
BackgroundColor3 = Color3.new(1, 1, 1),
Font = Enum.Font.Arial,
FontSize = Enum.FontSize.Size18,
Size = (function()
if useScrollButtons then
return UDim2.new(1, -13, 0.8 / ((dropDownItemCount + 1) * 0.8), 0)
else
return UDim2.new(1, 0, 0.8 / ((dropDownItemCount + 1) * 0.8), 0)
end
end)(),
TextWrap = true,
ZIndex = 2
})
local areaSoak = New("TextButton", "AreaSoak", {
Text = "",
BackgroundTransparency = 1,
Active = true,
Size = UDim2.new(1, 0, 1, 0),
Visible = false,
ZIndex = 3
})
local dropDownSelected = false
local scrollUpButton
local scrollDownButton
local scrollMouseCount = 0
local setZIndex
setZIndex = function(baseZIndex)
droppedDownMenu.ZIndex = baseZIndex + 1
if scrollUpButton then
scrollUpButton.ZIndex = baseZIndex + 3
end
if scrollDownButton then
scrollDownButton.ZIndex = baseZIndex + 3
end
local children = droppedDownMenu:GetChildren()
if children then
for _, child in ipairs(children) do
if child.Name == "ChoiceButton" then
child.ZIndex = baseZIndex + 2
elseif child.Name == "ClickCaptureButton" then
child.ZIndex = baseZIndex
end
end
end
end
local scrollBarPosition = 1
local updateScroll
updateScroll = function()
if scrollUpButton then
scrollUpButton.Active = scrollBarPosition > 1
end
if scrollDownButton then
scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount
end
local children = droppedDownMenu:GetChildren()
if not children then
return
end
local childNum = 1
for _, obj in ipairs(children) do
if obj.Name == "ChoiceButton" then
if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then
obj.Visible = false
else
obj.Position = UDim2.new(0, 0, ((childNum - scrollBarPosition + 1) * 0.8) / ((dropDownItemCount + 1) * 0.8), 0)
obj.Visible = true
end
obj.TextColor3 = Color3.new(1, 1, 1)
obj.BackgroundTransparency = 1
childNum = childNum + 1
end
end
end
local toggleVisibility
toggleVisibility = function()
dropDownSelected = not dropDownSelected
areaSoak.Visible = not areaSoak.Visible
dropDownMenu.Visible = not dropDownSelected
droppedDownMenu.Visible = dropDownSelected
if dropDownSelected then
setZIndex(4)
else
setZIndex(2)
end
if useScrollButtons then
return updateScroll()
end
end
droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
local updateSelection
updateSelection = function(text)
local foundItem = false
local children = droppedDownMenu:GetChildren()
local childNum = 1
if children then
for _, obj in ipairs(children) do
if obj.Name == "ChoiceButton" then
if obj.Text == text then
obj.Font = Enum.Font.ArialBold
foundItem = true
scrollBarPosition = childNum
else
obj.Font = Enum.Font.Arial
end
childNum = childNum + 1
end
end
end
if not text then
dropDownMenu.Text = "Choose One"
scrollBarPosition = 1
else
if not foundItem then
error("Invalid Selection Update -- " .. text)
end
if scrollBarPosition + dropDownItemCount > itemCount + 1 then
scrollBarPosition = itemCount - dropDownItemCount + 1
end
dropDownMenu.Text = text
end
end
local scrollDown
scrollDown = function()
if scrollBarPosition + dropDownItemCount <= itemCount then
scrollBarPosition = scrollBarPosition + 1
updateScroll()
return true
end
return false
end
local scrollUp
scrollUp = function()
if scrollBarPosition > 1 then
scrollBarPosition = scrollBarPosition - 1
updateScroll()
return true
end
return false
end
if useScrollButtons then
scrollUpButton = New("ImageButton", "ScrollUpButton", {
BackgroundTransparency = 1,
Image = "rbxasset://textures/ui/scrollbuttonUp.png",
Size = UDim2.new(0, 17, 0, 17),
Position = UDim2.new(1, -11, (1 * 0.8) / ((dropDownItemCount + 1) * 0.8), 0),
Parent = droppedDownMenu
})
local incScrollMouseCount
incScrollMouseCount = function()
scrollMouseCount = scrollMouseCount + 1
end
scrollUpButton.MouseButton1Click:connect(incScrollMouseCount)
scrollUpButton.MouseLeave:connect(incScrollMouseCount)
scrollUpButton.MouseButton1Down:connect(function()
scrollMouseCount = scrollMouseCount + 1
scrollUp()
local val = scrollMouseCount
wait(0.5)
while val == scrollMouseCount do
if scrollUp() == false then
break
end
wait(0.1)
end
end)
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(function()
scrollMouseCount = scrollMouseCount + 1
scrollDown()
local val = scrollMouseCount
wait(0.5)
while val == scrollMouseCount do
if scrollDown() == false then
break
end
wait(0.1)
end
end)
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
})
end
for _, item in ipairs(items) do
local button = choiceButton:clone()
if forRoblox then
button.RobloxLocked = true
end
button.Text = item
button.Parent = droppedDownMenu
button.MouseButton1Click:connect(function()
button.TextColor3 = Color3.new(1, 1, 1)
button.BackgroundTransparency = 1
updateSelection(item)
onSelect(item)
return toggleVisibility()
end)
button.MouseEnter:connect(function()
button.TextColor3 = Color3.new(0, 0, 0)
button.BackgroundTransparency = 0
end)
button.MouseLeave:connect(function()
button.TextColor3 = Color3.new(1, 1, 1)
button.BackgroundTransparency = 1
end)
end
updateScroll()
frame.AncestryChanged:connect(function(_, parent)
if not (parent ~= nil) then
areaSoak.Parent = nil
else
areaSoak.Parent = getScreenGuiAncestor(frame)
end
end)
dropDownMenu.MouseButton1Click:connect(toggleVisibility)
areaSoak.MouseButton1Click:connect(toggleVisibility)
return frame, updateSelection
end
t.CreatePropertyDropDownMenu = function(instance, property, enum)
local items = enum:GetEnumItems()
local names = { }
local nameToItem = { }
for i, obj in ipairs(items) do
names[i] = obj.Name
nameToItem[obj.Name] = obj
end
local frame, updateSelection
frame, updateSelection = t.CreateDropDownMenu(names, function(text)
instance[property] = nameToItem[text]
end)
local t1
t1 = function(prop)
if prop == property then
return updateSelection(instance[property].Name)
end
end
local t2
t2 = function()
return updateSelection(instance[property].Name)
end
ScopedConnect(frame, instance, "Changed", t1, t2)
return frame
end
t.GetFontHeight = function(font, fontSize)
if not ((font ~= nil) and (fontSize ~= nil)) then
error("Font and FontSize must be non-nil")
end
if font == Enum.Font.Legacy then
if Enum.FontSize.Size8 == fontSize then
return 12
elseif Enum.FontSize.Size9 == fontSize then
return 14
elseif Enum.FontSize.Size10 == fontSize then
return 15
elseif Enum.FontSize.Size11 == fontSize then
return 17
elseif Enum.FontSize.Size12 == fontSize then
return 18
elseif Enum.FontSize.Size14 == fontSize then
return 21
elseif Enum.FontSize.Size18 == fontSize then
return 27
elseif Enum.FontSize.Size24 == fontSize then
return 36
elseif Enum.FontSize.Size36 == fontSize then
return 54
elseif Enum.FontSize.Size48 == fontSize then
return 72
else
return error("Unknown FontSize")
end
elseif font == Enum.Font.Arial or font == Enum.Font.ArialBold then
if Enum.FontSize.Size8 == fontSize then
return 8
elseif Enum.FontSize.Size9 == fontSize then
return 9
elseif Enum.FontSize.Size10 == fontSize then
return 10
elseif Enum.FontSize.Size11 == fontSize then
return 11
elseif Enum.FontSize.Size12 == fontSize then
return 12
elseif Enum.FontSize.Size14 == fontSize then
return 14
elseif Enum.FontSize.Size18 == fontSize then
return 18
elseif Enum.FontSize.Size24 == fontSize then
return 24
elseif Enum.FontSize.Size36 == fontSize then
return 36
elseif Enum.FontSize.Size48 == fontSize then
return 48
else
return error("Unknown FontSize")
end
else
return error("Unknown Font " .. tostring(font))
end
end
local layoutGuiObjectsHelper
layoutGuiObjectsHelper = function(frame, guiObjects, settingsTable)
local totalPixels = frame.AbsoluteSize.Y
local pixelsRemaining = frame.AbsoluteSize.Y
for _, child in ipairs(guiObjects) do
if child:IsA("TextLabel" or child:IsA("TextButton")) then
local isLabel = child:IsA("TextLabel")
local settingsTableIndex = "Text" .. tostring((function()
if isLabel then
return "Label"
else
return "Button"
end
end)()) .. "PositionPadY"
pixelsRemaining = pixelsRemaining - settingsTable[settingsTableIndex]
child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
if child.TextFits and child.TextBounds.Y < pixelsRemaining then
child.Visible = true
child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable[settingsTableIndex])
while not child.TextFits do
child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
end
pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
pixelsRemaining = pixelsRemaining - settingsTable[settingsTableIndex]
else
child.Visible = false
pixelsRemaining = -1
end
else
child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
child.Visible = pixelsRemaining >= 0
end
end
end
t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
if not frame:IsA("GuiObject") then
error("Frame must be a GuiObject")
end
for _, child in ipairs(guiObjects) do
if not child:IsA("GuiObject") then
error("All elements that are layed out must be of type GuiObject")
end
end
if not settingsTable then
settingsTable = { }
end
if not settingsTable["TextLabelSizePadY"] then
settingsTable["TextLabelSizePadY"] = 0
end
if not settingsTable["TextLabelPositionPadY"] then
settingsTable["TextLabelPositionPadY"] = 0
end
if not settingsTable["TextButtonSizePadY"] then
settingsTable["TextButtonSizePadY"] = 12
end
if not settingsTable["TextButtonPositionPadY"] then
settingsTable["TextButtonPositionPadY"] = 2
end
local wrapperFrame = New("Frame", "WrapperFrame", {
BackgroundTransparency = 1,
Size = UDim2.new(1, 0, 1, 0),
Parent = frame
})
for _, child in ipairs(guiObjects) do
child.Parent = wrapperFrame
end
local recalculate
recalculate = function()
wait()
return layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
end
frame.Changed:connect(function(prop)
if prop == "AbsoluteSize" then
return recalculate(nil)
end
end)
frame.AncestryChanged:connect(recalculate)
return layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
end
t.CreateSlider = function(steps, width, position)
local sliderGui = New("Frame", "SliderGui", {
Size = UDim2.new(1, 0, 1, 0),
BackgroundTransparency = 1,
New("IntValue", "SliderSteps", {
Value = steps
}),
New("IntValue", "SliderPosition", {
Value = 0
}),
New("TextButton", "Bar", {
Text = "",
AutoButtonColor = false,
BackgroundColor3 = Color3.new(0, 0, 0),
Size = UDim2.new(0, (function()
if type(width) == "number" then
return width
else
return 200
end
end)(), 0, 5),
BorderColor3 = Color3.new(95 / 255, 95 / 255, 95 / 255),
ZIndex = 2,
New("ImageButton", "Slider", {
BackgroundTransparency = 1,
Image = "rbxasset://textures/ui/Slider.png",
Position = UDim2.new(0, 0, 0.5, -10),
Size = UDim2.new(0, 20, 0, 20),
ZIndex = 3
})
})
})
local areaSoak = New("TextButton", "AreaSoak", {
Text = "",
BackgroundTransparency = 1,
Active = false,
Size = UDim2.new(1, 0, 1, 0),
Visible = false,
ZIndex = 4
})
local sliderPosition, sliderSteps, slider, bar = sliderGui.SliderPosition, sliderGui.SliderSteps, sliderGui.Bar.Slider, sliderGui.Bar
sliderGui.AncestryChanged:connect(function(_, parent)
if not (parent ~= nil) then
areaSoak.Parent = nil
else
areaSoak.Parent = getScreenGuiAncestor(sliderGui)
end
end)
if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
bar.Position = position
end
local areaSoakMouseMoveCon
areaSoak.MouseLeave:connect(function()
if areaSoak.Visible then
return cancelSlide(areaSoak)
end
end)
areaSoak.MouseButton1Up:connect(function()
if areaSoak.Visible then
return cancelSlide(areaSoak)
end
end)
slider.MouseButton1Down:connect(function()
areaSoak.Visible = true
if areaSoakMouseMoveCon then
areaSoakMouseMoveCon:disconnect()
end
areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x, _)
return setSliderPos(x, slider, sliderPosition, bar, steps)
end)
end)
slider.MouseButton1Up:connect(function()
return cancelSlide(areaSoak)
end)
sliderPosition.Changed:connect(function(_)
sliderPosition.Value = math.min(steps, math.max(1, sliderPosition.Value))
local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
slider.Position = UDim2.new(relativePosX, -slider.AbsoluteSize.X / 2, slider.Position.Y.Scale, slider.Position.Y.Offset)
end)
bar.MouseButton1Down:connect(function(x, _)
return setSliderPos(x, slider, sliderPosition, bar, steps)
end)
return sliderGui, sliderPosition, sliderSteps
end
t.CreateTrueScrollingFrame = function()
local lowY, highY
local dragCon, upCon
local internalChange = false
local descendantsChangeConMap = { }
local scrollingFrame = New("Frame", "ScrollingFrame", {
Active = true,
Size = UDim2.new(1, 0, 1, 0),
ClipsDescendants = true,
New("Frame", "ControlFrame", {
BackgroundTransparency = 1,
Size = UDim2.new(0, 18, 1, 0),
Position = UDim2.new(1, -20, 0, 0),
New("BoolValue", "ScrollBottom", {
Value = false
}),
New("BoolValue", "scrollUp", {
Value = false
}),
New("TextButton", "ScrollUpButton", {
Text = "",
AutoButtonColor = false,
BackgroundColor3 = Color3.new(0, 0, 0),
BorderColor3 = Color3.new(1, 1, 1),
BackgroundTransparency = 0.5,
Size = UDim2.new(0, 18, 0, 18),
ZIndex = 2
}),
New("Frame", "ScrollTrack", {
BackgroundTransparency = 1,
Size = UDim2.new(0, 18, 1, -38),
Position = UDim2.new(0, 0, 0, 19),
New("TextButton", "ScrollBar", {
BackgroundColor3 = Color3.new(0, 0, 0),
BorderColor3 = Color3.new(1, 1, 1),
BackgroundTransparency = 0.5,
AutoButtonColor = false,
Text = "",
Active = true,
ZIndex = 2,
Size = UDim2.new(0, 18, 0.1, 0),
Position = UDim2.new(0, 0, 0, 0),
New("Frame", "ScrollNub", {
BorderColor3 = Color3.new(1, 1, 1),
Size = UDim2.new(0, 10, 0, 0),
Position = UDim2.new(0.5, -5, 0.5, 0),
ZIndex = 2,
BackgroundTransparency = 0.5
})
})
})
})
})
local controlFrame, scrollBottom, scrollUp, scrollUpButton, scrollTrack, scrollbar, scrollNub = scrollingFrame.ControlFrame, scrollingFrame.ControlFrame.ScrollBottom, scrollingFrame.ControlFrame.ScrollUp, scrollingFrame.ControlFrame.ScrollUpButton, scrollingFrame.ControlFrame.ScrollTrack, scrollingFrame.ControlFrame.ScrollTrack.ScrollBar, scrollingFrame.ControlFrame.ScrollTrack.ScrollBar.ScrollNub
for i = 1, 6 do
New("Frame", "tri" .. tostring(i), {
BorderColor3 = Color3.new(1, 1, 1),
ZIndex = 3,
BackgroundTransparency = 0.5,
Size = UDim2.new(0, 12 - ((i - 1) * 2), 0, 0),
Position = UDim2.new(0, 3 + (i - 1), 0.5, 2 - (i - 1)),
Parent = scrollUpButton
})
end
scrollUpButton.MouseEnter:connect(function()
scrollUpButton.BackgroundTransparency = 0.1
local upChildren = scrollUpButton:GetChildren()
for i = 1, #upChildren do
upChildren[i].BackgroundTransparency = 0.1
end
end)
scrollUpButton.MouseLeave:connect(function()
scrollUpButton.BackgroundTransparency = 0.5
local upChildren = scrollUpButton:GetChildren()
for i = 1, #upChildren do
upChildren[i].BackgroundTransparency = 0.5
end
end)
local scrollDownButton = scrollUpButton:clone()
do
scrollDownButton.Name = "ScrollDownButton"
scrollDownButton.Position = UDim2.new(0, 0, 1, -18)
local downChildren = scrollDownButton:GetChildren()
for i = 1, #downChildren do
downChildren[i].Position = UDim2.new(0, 3 + (i - 1), 0.5, -2 + (i - 1))
end
scrollDownButton.MouseEnter:connect(function()
scrollDownButton.BackgroundTransparency = 0.1
downChildren = scrollDownButton:GetChildren()
for i = 1, #downChildren do
downChildren[i].BackgroundTransparency = 0.1
end
end)
scrollDownButton.MouseLeave:connect(function()
scrollDownButton.BackgroundTransparency = 0.5
downChildren = scrollDownButton:GetChildren()
for i = 1, #downChildren do
downChildren[i].BackgroundTransparency = 0.5
end
end)
scrollDownButton.Parent = controlFrame
end
local newNub = scrollNub:clone()
newNub.Position = UDim2.new(0.5, -5, 0.5, -2)
newNub.Parent = scrollbar
local lastNub = scrollNub:clone()
lastNub.Position = UDim2.new(0.5, -5, 0.5, 2)
lastNub.Parent = scrollbar
scrollbar.MouseEnter:connect(function()
scrollbar.BackgroundTransparency = 0.1
scrollNub.BackgroundTransparency = 0.1
newNub.BackgroundTransparency = 0.1
lastNub.BackgroundTransparency = 0.1
end)
scrollbar.MouseLeave:connect(function()
scrollbar.BackgroundTransparency = 0.5
scrollNub.BackgroundTransparency = 0.5
newNub.BackgroundTransparency = 0.5
lastNub.BackgroundTransparency = 0.5
end)
local mouseDrag = New("ImageButton", {
Active = false,
Size = UDim2.new(1.5, 0, 1.5, 0),
AutoButtonColor = false,
BackgroundTransparency = 1,
Name = "mouseDrag",
Position = UDim2.new(-0.25, 0, -0.25, 0),
ZIndex = 10
})
local positionScrollBar
positionScrollBar = function(_, y, offset)
local oldPos = scrollbar.Position
if y < scrollTrack.AbsolutePosition.y then
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0)
return (oldPos ~= scrollbar.Position)
end
local relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y
if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0)
return (oldPos ~= scrollbar.Position)
end
local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset) / scrollTrack.AbsoluteSize.y
if newScaleYPos + relativeSize > 1 then
newScaleYPos = 1 - relativeSize
scrollBottom.Value = true
scrollUp.Value = false
elseif newScaleYPos <= 0 then
newScaleYPos = 0
scrollUp.Value = true
scrollBottom.Value = false
else
scrollUp.Value = false
scrollBottom.Value = false
end
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, newScaleYPos, 0)
return (oldPos ~= scrollbar.Position)
end
local drillDownSetHighLow
drillDownSetHighLow = function(instance)
if not instance or not instance:IsA("GuiObject") then
return
end
if instance == controlFrame then
return
end
if instance:IsDescendantOf(controlFrame) then
return
end
if not instance.Visible then
return
end
if (lowY and lowY > instance.AbsolutePosition.Y) or not lowY then
lowY = instance.AbsolutePosition.Y
end
if (highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y)) or not highY then
highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
end
local children = instance:GetChildren()
for i = 1, #children do
drillDownSetHighLow(children[i])
end
end
local resetHighLow
resetHighLow = function()
local firstChildren = scrollingFrame:GetChildren()
for i = 1, #firstChildren do
drillDownSetHighLow(firstChildren[i])
end
end
local recalculate
recalculate = function()
internalChange = true
local percentFrame = 0
if scrollbar.Position.Y.Scale > 0 then
if scrollbar.Visible then
percentFrame = scrollbar.Position.Y.Scale / ((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y) / scrollTrack.AbsoluteSize.Y)
else
percentFrame = 0
end
end
if percentFrame > 0.99 then
percentFrame = 1
end
local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
local guiChildren = scrollingFrame:GetChildren()
for i = 1, #guiChildren do
if guiChildren[i] ~= controlFrame then
guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale, guiChildren[i].Position.X.Offset, 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
end
end
lowY = nil
highY = nil
resetHighLow()
internalChange = false
end
local setSliderSizeAndPosition
setSliderSizeAndPosition = function()
if not highY or not lowY then
return
end
local totalYSpan = math.abs(highY - lowY)
if totalYSpan == 0 then
scrollbar.Visible = false
scrollDownButton.Visible = false
scrollUpButton.Visible = false
if dragCon then
dragCon:disconnect()
dragCon = nil
end
if upCon then
upCon:disconnect()
upCon = nil
end
return
end
local percentShown = scrollingFrame.AbsoluteSize.Y / totalYSpan
if percentShown >= 1 then
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)
end
local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY) / totalYSpan
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, percentPosition, -scrollbar.AbsoluteSize.X / 2)
if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 0, 0)
end
if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
local relativeSize = scrollbar.AbsoluteSize.Y / scrollTrack.AbsoluteSize.Y
scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale, scrollbar.Position.X.Offset, 1 - relativeSize, 0)
end
end
local buttonScrollAmountPixels = 7
local reentrancyGuardScrollUp = false
local doScrollUp
doScrollUp = function()
if reentrancyGuardScrollUp then
return
end
reentrancyGuardScrollUp = true
if positionScrollBar(0, scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels, 0) then
recalculate()
end
reentrancyGuardScrollUp = false
end
local reentrancyGuardScrollDown = false
local doScrollDown
doScrollDown = function()
if reentrancyGuardScrollDown then
return
end
reentrancyGuardScrollDown = true
if positionScrollBar(0, scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels, 0) then
recalculate()
end
reentrancyGuardScrollDown = false
end
scrollUp = function(mouseYPos)
if scrollUpButton.Active then
local scrollStamp = tick()
local current = scrollStamp
local upCon
upCon = mouseDrag.MouseButton1Up:connect(function()
scrollStamp = tick()
mouseDrag.Parent = nil
return upCon:disconnect()
end)
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
doScrollUp()
wait(0.2)
t = tick()
local w = 0.1
while scrollStamp == current do
doScrollUp()
if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then
break
end
if not scrollUpButton.Active then
break
end
if tick() - t > 5 then
w = 0
elseif tick() - t > 2 then
w = 0.06
end
wait(w)
end
end
end
local scrollDown
scrollDown = function(mouseYPos)
if scrollDownButton.Active then
local scrollStamp = tick()
local current = scrollStamp
local downCon
downCon = mouseDrag.MouseButton1Up:connect(function()
scrollStamp = tick()
mouseDrag.Parent = nil
return downCon:disconnect()
end)
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
doScrollDown()
wait(0.2)
t = tick()
local w = 0.1
while scrollStamp == current do
doScrollDown()
if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
break
end
if not scrollDownButton.Active then
break
end
if tick() - t > 5 then
w = 0
elseif tick() - t > 2 then
w = 0.06
end
wait(w)
end
end
end
scrollbar.MouseButton1Down:connect(function(x, y)
if scrollbar.Active then
local scrollStamp = tick()
local mouseOffset = y - scrollbar.AbsolutePosition.y
if dragCon then
dragCon:disconnect()
dragCon = nil
end
if upCon then
upCon:disconnect()
upCon = nil
end
local reentrancyGuardMouseScroll = false
dragCon = mouseDrag.MouseMoved:connect(function(x, y)
if reentrancyGuardMouseScroll then
return
end
reentrancyGuardMouseScroll = true
if positionScrollBar(x, y, mouseOffset) then
recalculate()
end
reentrancyGuardMouseScroll = false
end)
upCon = mouseDrag.MouseButton1Up:connect(function()
scrollStamp = tick()
mouseDrag.Parent = nil
dragCon:disconnect()
dragCon = nil
upCon:disconnect()
local drag = nil
end)
mouseDrag.Parent = getScreenGuiAncestor(scrollbar)
end
end)
local scrollMouseCount = 0
scrollUpButton.MouseButton1Down:connect(function()
return scrollUp()
end)
scrollDownButton.MouseButton1Down:connect(function()
return scrollDown()
end)
local scrollTick
scrollTick = function()
scrollStamp = tick()
end
scrollUpButton.MouseButton1Up:connect(scrollTick)
scrollDownButton.MouseButton1Up:connect(scrollTick)
scrollbar.MouseButton1Up:connect(scrollTick)
local highLowRecheck
highLowRecheck = function()
local oldLowY = lowY
local oldHighY = highY
lowY = nil
highY = nil
resetHighLow()
if (lowY ~= oldLowY) or (highY ~= oldHighY) then
return setSliderSizeAndPosition()
end
end
local descendantChanged
descendantChanged = function(this, prop)
if internalChange then
return
end
if not this.Visible then
return
end
if prop == "Size" or prop == "Position" then
wait()
return highLowRecheck()
end
end
scrollingFrame.DescendantAdded:connect(function(instance)
if not instance:IsA("GuiObject") then
return
end
if instance.Visible then
wait()
highLowRecheck()
end
descendantsChangeConMap[instance] = instance.Changed:connect(function(prop)
return descendantChanged(instance, prop)
end)
end)
scrollingFrame.DescendantRemoving:connect(function(instance)
if not instance:IsA("GuiObject") then
return
end
if descendantsChangeConMap[instance] then
descendantsChangeConMap[instance]:disconnect()
descendantsChangeConMap[instance] = nil
end
wait()
return highLowRecheck()
end)
scrollingFrame.Changed:connect(function(prop)
if prop == "AbsoluteSize" then
if not highY or not lowY then
return
end
highLowRecheck()
return setSliderSizeAndPosition()
end
end)
return scrollingFrame, controlFrame
end