· 4 years ago · Jun 21, 2021, 12:50 AM
1local t = {}
2
3local function ScopedConnect(parentInstance, instance, event, signalFunc, syncFunc, removeFunc)
4 local eventConnection = nil
5
6 --Connection on parentInstance is scoped by parentInstance (when destroyed, it goes away)
7 local tryConnect = function()
8 if game:IsAncestorOf(parentInstance) then
9 --Entering the world, make sure we are connected/synced
10 if not eventConnection then
11 eventConnection = instance[event]:connect(signalFunc)
12 if syncFunc then syncFunc() end
13 end
14 else
15 --Probably leaving the world, so disconnect for now
16 if eventConnection then
17 eventConnection:disconnect()
18 if removeFunc then removeFunc() end
19 end
20 end
21 end
22
23 --Hook it up to ancestryChanged signal
24 local connection = parentInstance.AncestryChanged:connect(tryConnect)
25
26 --Now connect us if we're already in the world
27 tryConnect()
28
29 return connection
30end
31
32local function getLayerCollectorAncestor(instance)
33 local localInstance = instance
34 while localInstance and not localInstance:IsA("LayerCollector") do
35 localInstance = localInstance.Parent
36 end
37 return localInstance
38end
39
40local function CreateButtons(frame, buttons, yPos, ySize)
41 local buttonNum = 1
42 local buttonObjs = {}
43 for i, obj in ipairs(buttons) do
44 local button = Instance.new("TextButton")
45 button.Name = "Button" .. buttonNum
46 button.Font = Enum.Font.Arial
47 button.FontSize = Enum.FontSize.Size18
48 button.AutoButtonColor = true
49 button.Modal = true
50 if obj["Style"] then
51 button.Style = obj.Style
52 else
53 button.Style = Enum.ButtonStyle.RobloxButton
54 end
55 if obj["ZIndex"] then
56 button.ZIndex = obj.ZIndex
57 end
58 button.Text = obj.Text
59 button.TextColor3 = Color3.new(1,1,1)
60 button.MouseButton1Click:connect(obj.Function)
61 button.Parent = frame
62 buttonObjs[buttonNum] = button
63
64 buttonNum = buttonNum + 1
65 end
66 local numButtons = buttonNum-1
67
68 if numButtons == 1 then
69 frame.Button1.Position = UDim2.new(0.35, 0, yPos.Scale, yPos.Offset)
70 frame.Button1.Size = UDim2.new(.4,0,ySize.Scale, ySize.Offset)
71 elseif numButtons == 2 then
72 frame.Button1.Position = UDim2.new(0.1, 0, yPos.Scale, yPos.Offset)
73 frame.Button1.Size = UDim2.new(.8/3,0, ySize.Scale, ySize.Offset)
74
75 frame.Button2.Position = UDim2.new(0.55, 0, yPos.Scale, yPos.Offset)
76 frame.Button2.Size = UDim2.new(.35,0, ySize.Scale, ySize.Offset)
77 elseif numButtons >= 3 then
78 local spacing = .1 / numButtons
79 local buttonSize = .9 / numButtons
80
81 buttonNum = 1
82 while buttonNum <= numButtons do
83 buttonObjs[buttonNum].Position = UDim2.new(spacing*buttonNum + (buttonNum-1) * buttonSize, 0, yPos.Scale, yPos.Offset)
84 buttonObjs[buttonNum].Size = UDim2.new(buttonSize, 0, ySize.Scale, ySize.Offset)
85 buttonNum = buttonNum + 1
86 end
87 end
88end
89
90local function setSliderPos(newAbsPosX,slider,sliderPosition,bar,steps)
91
92 local newStep = steps - 1 --otherwise we really get one more step than we want
93 local relativePosX = math.min(1, math.max(0, (newAbsPosX - bar.AbsolutePosition.X) / bar.AbsoluteSize.X ))
94 local wholeNum, remainder = math.modf(relativePosX * newStep)
95 if remainder > 0.5 then
96 wholeNum = wholeNum + 1
97 end
98 relativePosX = wholeNum/newStep
99
100 local result = math.ceil(relativePosX * newStep)
101 if sliderPosition.Value ~= (result + 1) then --only update if we moved a step
102 sliderPosition.Value = result + 1
103 slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
104 end
105
106end
107
108local function cancelSlide(areaSoak)
109 areaSoak.Visible = false
110end
111
112t.CreateStyledMessageDialog = function(title, message, style, buttons)
113 local frame = Instance.new("Frame")
114 frame.Size = UDim2.new(0.5, 0, 0, 165)
115 frame.Position = UDim2.new(0.25, 0, 0.5, -72.5)
116 frame.Name = "MessageDialog"
117 frame.Active = true
118 frame.Style = Enum.FrameStyle.RobloxRound
119
120 local styleImage = Instance.new("ImageLabel")
121 styleImage.Name = "StyleImage"
122 styleImage.BackgroundTransparency = 1
123 styleImage.Position = UDim2.new(0,5,0,15)
124 if style == "error" or style == "Error" then
125 styleImage.Size = UDim2.new(0, 71, 0, 71)
126 styleImage.Image = "https://www.roblox.com/asset/?id=42565285"
127 elseif style == "notify" or style == "Notify" then
128 styleImage.Size = UDim2.new(0, 71, 0, 71)
129 styleImage.Image = "https://www.roblox.com/asset/?id=42604978"
130 elseif style == "confirm" or style == "Confirm" then
131 styleImage.Size = UDim2.new(0, 74, 0, 76)
132 styleImage.Image = "https://www.roblox.com/asset/?id=42557901"
133 else
134 return t.CreateMessageDialog(title,message,buttons)
135 end
136 styleImage.Parent = frame
137
138 local titleLabel = Instance.new("TextLabel")
139 titleLabel.Name = "Title"
140 titleLabel.Text = title
141 titleLabel.TextStrokeTransparency = 0
142 titleLabel.BackgroundTransparency = 1
143 titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
144 titleLabel.Position = UDim2.new(0, 80, 0, 0)
145 titleLabel.Size = UDim2.new(1, -80, 0, 40)
146 titleLabel.Font = Enum.Font.ArialBold
147 titleLabel.FontSize = Enum.FontSize.Size36
148 titleLabel.TextXAlignment = Enum.TextXAlignment.Center
149 titleLabel.TextYAlignment = Enum.TextYAlignment.Center
150 titleLabel.Parent = frame
151
152 local messageLabel = Instance.new("TextLabel")
153 messageLabel.Name = "Message"
154 messageLabel.Text = message
155 messageLabel.TextStrokeTransparency = 0
156 messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
157 messageLabel.Position = UDim2.new(0.025, 80, 0, 45)
158 messageLabel.Size = UDim2.new(0.95, -80, 0, 55)
159 messageLabel.BackgroundTransparency = 1
160 messageLabel.Font = Enum.Font.Arial
161 messageLabel.FontSize = Enum.FontSize.Size18
162 messageLabel.TextWrap = true
163 messageLabel.TextXAlignment = Enum.TextXAlignment.Left
164 messageLabel.TextYAlignment = Enum.TextYAlignment.Top
165 messageLabel.Parent = frame
166
167 CreateButtons(frame, buttons, UDim.new(0, 105), UDim.new(0, 40) )
168
169 return frame
170end
171
172t.CreateMessageDialog = function(title, message, buttons)
173 local frame = Instance.new("Frame")
174 frame.Size = UDim2.new(0.5, 0, 0.5, 0)
175 frame.Position = UDim2.new(0.25, 0, 0.25, 0)
176 frame.Name = "MessageDialog"
177 frame.Active = true
178 frame.Style = Enum.FrameStyle.RobloxRound
179
180 local titleLabel = Instance.new("TextLabel")
181 titleLabel.Name = "Title"
182 titleLabel.Text = title
183 titleLabel.BackgroundTransparency = 1
184 titleLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
185 titleLabel.Position = UDim2.new(0, 0, 0, 0)
186 titleLabel.Size = UDim2.new(1, 0, 0.15, 0)
187 titleLabel.Font = Enum.Font.ArialBold
188 titleLabel.FontSize = Enum.FontSize.Size36
189 titleLabel.TextXAlignment = Enum.TextXAlignment.Center
190 titleLabel.TextYAlignment = Enum.TextYAlignment.Center
191 titleLabel.Parent = frame
192
193 local messageLabel = Instance.new("TextLabel")
194 messageLabel.Name = "Message"
195 messageLabel.Text = message
196 messageLabel.TextColor3 = Color3.new(221/255,221/255,221/255)
197 messageLabel.Position = UDim2.new(0.025, 0, 0.175, 0)
198 messageLabel.Size = UDim2.new(0.95, 0, .55, 0)
199 messageLabel.BackgroundTransparency = 1
200 messageLabel.Font = Enum.Font.Arial
201 messageLabel.FontSize = Enum.FontSize.Size18
202 messageLabel.TextWrap = true
203 messageLabel.TextXAlignment = Enum.TextXAlignment.Left
204 messageLabel.TextYAlignment = Enum.TextYAlignment.Top
205 messageLabel.Parent = frame
206
207 CreateButtons(frame, buttons, UDim.new(0.8,0), UDim.new(0.15, 0))
208
209 return frame
210end
211
212-- written by jmargh
213-- to be used for the new settings menu
214t.CreateScrollingDropDownMenu = function(onSelectedCallback, size, position, baseZ)
215 local maxVisibleList = 6
216 local baseZIndex = 0
217 if type(baseZ) == 'number' then
218 baseZIndex = baseZ
219 end
220
221 local dropDownMenu = {}
222 local currentList = nil
223
224 local updateFunc = nil
225 local frame = Instance.new('Frame')
226 frame.Name = "DropDownMenuFrame"
227 frame.Size = size
228 frame.Position = position
229 frame.BackgroundTransparency = 1
230 dropDownMenu.Frame = frame
231
232 local currentSelectionName = Instance.new('TextButton')
233 currentSelectionName.Name = "CurrentSelectionName"
234 currentSelectionName.Size = UDim2.new(1, 0, 1, 0)
235 currentSelectionName.BackgroundTransparency = 1
236 currentSelectionName.Font = Enum.Font.SourceSansBold
237 currentSelectionName.FontSize = Enum.FontSize.Size18
238 currentSelectionName.TextXAlignment = Enum.TextXAlignment.Left
239 currentSelectionName.TextYAlignment = Enum.TextYAlignment.Center
240 currentSelectionName.TextColor3 = Color3.new(0.5, 0.5, 0.5)
241 currentSelectionName.TextWrap = true
242 currentSelectionName.ZIndex = baseZIndex
243 currentSelectionName.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
244 currentSelectionName.Text = "Choose One"
245 currentSelectionName.Parent = frame
246 dropDownMenu.CurrentSelectionButton = currentSelectionName
247
248 local icon = Instance.new('ImageLabel')
249 icon.Name = "DropDownIcon"
250 icon.Size = UDim2.new(0, 16, 0, 12)
251 icon.Position = UDim2.new(1, -17, 0.5, -6)
252 icon.Image = 'rbxasset://textures/ui/dropdown_arrow.png'
253 icon.BackgroundTransparency = 1
254 icon.ZIndex = baseZIndex
255 icon.Parent = currentSelectionName
256
257 local listMenu = nil
258 local scrollingBackground = nil
259 local visibleCount = 0
260 local isOpen = false
261
262 local function onEntrySelected()
263 icon.Rotation = 0
264 scrollingBackground:TweenSize(UDim2.new(1, 0, 0, currentSelectionName.AbsoluteSize.y), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 0.15, true)
265 --
266 listMenu.ScrollBarThickness = 0
267 listMenu:TweenSize(UDim2.new(1, -16, 0, 24), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 0.15, true, function()
268 if not isOpen then
269 listMenu.Visible = false
270 scrollingBackground.Visible = false
271 end
272 end)
273 isOpen = false
274 end
275
276 currentSelectionName.MouseButton1Click:connect(function()
277 if not currentSelectionName.Active or #currentList == 0 then return end
278 if isOpen then
279 onEntrySelected()
280 return
281 end
282 --
283 isOpen = true
284 icon.Rotation = 180
285 if listMenu then listMenu.Visible = true end
286 if scrollingBackground then scrollingBackground.Visible = true end
287 --
288 if scrollingBackground then
289 scrollingBackground:TweenSize(UDim2.new(1, 0, 0, visibleCount * 24 + 8), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 0.15, true)
290 end
291 if listMenu then
292 listMenu:TweenSize(UDim2.new(1, -16, 0, visibleCount * 24), Enum.EasingDirection.InOut, Enum.EasingStyle.Sine, 0.15, true, function()
293 listMenu.ScrollBarThickness = 6
294 end)
295 end
296 end)
297
298 --[[ Public API ]]--
299 dropDownMenu.IsOpen = function()
300 return isOpen
301 end
302
303 dropDownMenu.Close = function()
304 onEntrySelected()
305 end
306
307 dropDownMenu.Reset = function()
308 isOpen = false
309 icon.Rotation = 0
310 listMenu.ScrollBarThickness = 0
311 listMenu.Size = UDim2.new(1, -16, 0, 24)
312 listMenu.Visible = false
313 scrollingBackground.Visible = false
314 end
315
316 dropDownMenu.SetVisible = function(isVisible)
317 if frame then
318 frame.Visible = isVisible
319 end
320 end
321
322 dropDownMenu.UpdateZIndex = function(newZIndexBase)
323 currentSelectionName.ZIndex = newZIndexBase
324 icon.ZIndex = newZIndexBase
325 if scrollingBackground then scrollingBackground.ZIndex = newZIndexBase + 1 end
326 if listMenu then
327 listMenu.ZIndex = newZIndexBase + 2
328 for _,child in pairs(listMenu:GetChildren()) do
329 child.ZIndex = newZIndexBase + 4
330 end
331 end
332 end
333
334 dropDownMenu.SetActive = function(isActive)
335 currentSelectionName.Active = isActive
336 end
337
338 dropDownMenu.SetSelectionText = function(text)
339 currentSelectionName.Text = text
340 end
341
342 dropDownMenu.CreateList = function(list)
343 currentSelectionName.Text = "Choose One"
344 if listMenu then listMenu:Destroy() end
345 if scrollingBackground then scrollingBackground:Destroy() end
346 --
347 currentList = list
348 local length = #list
349 visibleCount = math.min(maxVisibleList, length)
350 local listMenuOffset = visibleCount * 24
351
352 listMenu = Instance.new('ScrollingFrame')
353 listMenu.Name = "ListMenu"
354 listMenu.Size = UDim2.new(1, -16, 0, 24)
355 listMenu.Position = UDim2.new(0, 12, 0, 32)
356 listMenu.CanvasSize = UDim2.new(0, 0, 0, length * 24)
357 listMenu.BackgroundTransparency = 1
358 listMenu.BorderSizePixel = 0
359 listMenu.ZIndex = baseZIndex + 2
360 listMenu.Visible = false
361 listMenu.Active = true
362 listMenu.BottomImage = 'rbxasset://textures/ui/scroll-bottom.png'
363 listMenu.MidImage = 'rbxasset://textures/ui/scroll-middle.png'
364 listMenu.TopImage = 'rbxasset://textures/ui/scroll-top.png'
365 listMenu.ScrollBarThickness = 0
366 listMenu.Parent = frame
367
368 scrollingBackground = Instance.new('TextButton')
369 scrollingBackground.Name = "ScrollingBackground"
370 scrollingBackground.Size = UDim2.new(1, 0, 0, currentSelectionName.AbsoluteSize.y)
371 scrollingBackground.Position = UDim2.new(0, 0, 0, 28)
372 scrollingBackground.BackgroundColor3 = Color3.new(1, 1, 1)
373 scrollingBackground.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
374 scrollingBackground.ZIndex = baseZIndex + 1
375 scrollingBackground.Text = ""
376 scrollingBackground.Visible = false
377 scrollingBackground.AutoButtonColor = false
378 scrollingBackground.Parent = frame
379
380 for i = 1, length do
381 local entry = list[i]
382 local btn = Instance.new('TextButton')
383 btn.Name = entry
384 btn.Size = UDim2.new(1, 0, 0, 24)
385 btn.Position = UDim2.new(0, 0, 0, (i - 1) * 24)
386 btn.BackgroundTransparency = 0
387 btn.BackgroundColor3 = Color3.new(1, 1, 1)
388 btn.BorderSizePixel = 0
389 btn.Font = Enum.Font.SourceSans
390 btn.FontSize = Enum.FontSize.Size18
391 btn.TextColor3 = Color3.new(0.5, 0.5, 0.5)
392 btn.TextXAlignment = Enum.TextXAlignment.Left
393 btn.TextYAlignment = Enum.TextYAlignment.Center
394 btn.Text = entry
395 btn.ZIndex = baseZIndex + 4
396 btn.AutoButtonColor = false
397 btn.Parent = listMenu
398
399 btn.MouseButton1Click:connect(function()
400 currentSelectionName.Text = btn.Text
401 onEntrySelected()
402 btn.Font = Enum.Font.SourceSans
403 btn.TextColor3 = Color3.new(0.5, 0.5, 0.5)
404 btn.BackgroundColor3 = Color3.new(1, 1, 1)
405 onSelectedCallback(btn.Text)
406 end)
407
408 btn.MouseEnter:connect(function()
409 btn.TextColor3 = Color3.new(1, 1, 1)
410 btn.BackgroundColor3 = Color3.new(0.75, 0.75, 0.75)
411 end)
412 btn.MouseLeave:connect(function()
413 btn.TextColor3 = Color3.new(0.5, 0.5, 0.5)
414 btn.BackgroundColor3 = Color3.new(1, 1, 1)
415 end)
416 end
417 end
418
419 return dropDownMenu
420end
421
422t.CreateDropDownMenu = function(items, onSelect, forRoblox, whiteSkin, baseZ)
423 local baseZIndex = 0
424 if (type(baseZ) == "number") then
425 baseZIndex = baseZ
426 end
427 local width = UDim.new(0, 100)
428 local height = UDim.new(0, 32)
429
430 local xPos = 0.055
431 local frame = Instance.new("Frame")
432 local textColor = Color3.new(1,1,1)
433 if (whiteSkin) then
434 textColor = Color3.new(0.5, 0.5, 0.5)
435 end
436 frame.Name = "DropDownMenu"
437 frame.BackgroundTransparency = 1
438 frame.Size = UDim2.new(width, height)
439
440 local dropDownMenu = Instance.new("TextButton")
441 dropDownMenu.Name = "DropDownMenuButton"
442 dropDownMenu.TextWrap = true
443 dropDownMenu.TextColor3 = textColor
444 dropDownMenu.Text = "Choose One"
445 dropDownMenu.Font = Enum.Font.ArialBold
446 dropDownMenu.FontSize = Enum.FontSize.Size18
447 dropDownMenu.TextXAlignment = Enum.TextXAlignment.Left
448 dropDownMenu.TextYAlignment = Enum.TextYAlignment.Center
449 dropDownMenu.BackgroundTransparency = 1
450 dropDownMenu.AutoButtonColor = true
451 if (whiteSkin) then
452 dropDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
453 else
454 dropDownMenu.Style = Enum.ButtonStyle.RobloxButton
455 end
456 dropDownMenu.Size = UDim2.new(1,0,1,0)
457 dropDownMenu.Parent = frame
458 dropDownMenu.ZIndex = 2 + baseZIndex
459
460 local dropDownIcon = Instance.new("ImageLabel")
461 dropDownIcon.Name = "Icon"
462 dropDownIcon.Active = false
463 if (whiteSkin) then
464 dropDownIcon.Image = "rbxasset://textures/ui/dropdown_arrow.png"
465 dropDownIcon.Size = UDim2.new(0,16,0,12)
466 dropDownIcon.Position = UDim2.new(1,-17,0.5, -6)
467 else
468 dropDownIcon.Image = "https://www.roblox.com/asset/?id=45732894"
469 dropDownIcon.Size = UDim2.new(0,11,0,6)
470 dropDownIcon.Position = UDim2.new(1,-11,0.5, -2)
471 end
472 dropDownIcon.BackgroundTransparency = 1
473 dropDownIcon.Parent = dropDownMenu
474 dropDownIcon.ZIndex = 2 + baseZIndex
475
476 local itemCount = #items
477 local dropDownItemCount = #items
478 local useScrollButtons = false
479 if dropDownItemCount > 6 then
480 useScrollButtons = true
481 dropDownItemCount = 6
482 end
483
484 local droppedDownMenu = Instance.new("TextButton")
485 droppedDownMenu.Name = "List"
486 droppedDownMenu.Text = ""
487 droppedDownMenu.BackgroundTransparency = 1
488 --droppedDownMenu.AutoButtonColor = true
489 if (whiteSkin) then
490 droppedDownMenu.Style = Enum.ButtonStyle.RobloxRoundDropdownButton
491 else
492 droppedDownMenu.Style = Enum.ButtonStyle.RobloxButton
493 end
494 droppedDownMenu.Visible = false
495 droppedDownMenu.Active = true --Blocks clicks
496 droppedDownMenu.Position = UDim2.new(0,0,0,0)
497 droppedDownMenu.Size = UDim2.new(1,0, (1 + dropDownItemCount)*.8, 0)
498 droppedDownMenu.Parent = frame
499 droppedDownMenu.ZIndex = 4 + baseZIndex
500
501 local choiceButton = Instance.new("TextButton")
502 choiceButton.Name = "ChoiceButton"
503 choiceButton.BackgroundTransparency = 1
504 choiceButton.BorderSizePixel = 0
505 choiceButton.Text = "ReplaceMe"
506 choiceButton.TextColor3 = textColor
507 choiceButton.TextXAlignment = Enum.TextXAlignment.Left
508 choiceButton.TextYAlignment = Enum.TextYAlignment.Center
509 choiceButton.BackgroundColor3 = Color3.new(1, 1, 1)
510 choiceButton.Font = Enum.Font.Arial
511 choiceButton.FontSize = Enum.FontSize.Size18
512 if useScrollButtons then
513 choiceButton.Size = UDim2.new(1,-13, .8/((dropDownItemCount + 1)*.8),0)
514 else
515 choiceButton.Size = UDim2.new(1, 0, .8/((dropDownItemCount + 1)*.8),0)
516 end
517 choiceButton.TextWrap = true
518 choiceButton.ZIndex = 2 + baseZIndex
519
520 local areaSoak = Instance.new("TextButton")
521 areaSoak.Name = "AreaSoak"
522 areaSoak.Text = ""
523 areaSoak.BackgroundTransparency = 1
524 areaSoak.Active = true
525 areaSoak.Size = UDim2.new(1,0,1,0)
526 areaSoak.Visible = false
527 areaSoak.ZIndex = 3 + baseZIndex
528
529 local dropDownSelected = false
530
531 local scrollUpButton
532 local scrollDownButton
533 local scrollMouseCount = 0
534
535 local setZIndex = function(baseZIndex)
536 droppedDownMenu.ZIndex = baseZIndex +1
537 if scrollUpButton then
538 scrollUpButton.ZIndex = baseZIndex + 3
539 end
540 if scrollDownButton then
541 scrollDownButton.ZIndex = baseZIndex + 3
542 end
543
544 local children = droppedDownMenu:GetChildren()
545 if children then
546 for i, child in ipairs(children) do
547 if child.Name == "ChoiceButton" then
548 child.ZIndex = baseZIndex + 4
549 elseif child.Name == "ClickCaptureButton" then
550 child.ZIndex = baseZIndex
551 end
552 end
553 end
554 end
555
556 local scrollBarPosition = 1
557 local updateScroll = function()
558 if scrollUpButton then
559 scrollUpButton.Active = scrollBarPosition > 1
560 end
561 if scrollDownButton then
562 scrollDownButton.Active = scrollBarPosition + dropDownItemCount <= itemCount
563 end
564
565 local children = droppedDownMenu:GetChildren()
566 if not children then return end
567
568 local childNum = 1
569 for i, obj in ipairs(children) do
570 if obj.Name == "ChoiceButton" then
571 if childNum < scrollBarPosition or childNum >= scrollBarPosition + dropDownItemCount then
572 obj.Visible = false
573 else
574 obj.Position = UDim2.new(0,0,((childNum-scrollBarPosition+1)*.8)/((dropDownItemCount+1)*.8),0)
575 obj.Visible = true
576 end
577 obj.TextColor3 = textColor
578 obj.BackgroundTransparency = 1
579
580 childNum = childNum + 1
581 end
582 end
583 end
584 local toggleVisibility = function()
585 dropDownSelected = not dropDownSelected
586
587 areaSoak.Visible = not areaSoak.Visible
588 dropDownMenu.Visible = not dropDownSelected
589 droppedDownMenu.Visible = dropDownSelected
590 if dropDownSelected then
591 setZIndex(4 + baseZIndex)
592 else
593 setZIndex(2 + baseZIndex)
594 end
595 if useScrollButtons then
596 updateScroll()
597 end
598 end
599 droppedDownMenu.MouseButton1Click:connect(toggleVisibility)
600
601 local updateSelection = function(text)
602 local foundItem = false
603 local children = droppedDownMenu:GetChildren()
604 local childNum = 1
605 if children then
606 for i, obj in ipairs(children) do
607 if obj.Name == "ChoiceButton" then
608 if obj.Text == text then
609 obj.Font = Enum.Font.ArialBold
610 foundItem = true
611 scrollBarPosition = childNum
612 if (whiteSkin) then
613 obj.TextColor3 = Color3.new(90/255,142/255,233/255)
614 end
615 else
616 obj.Font = Enum.Font.Arial
617 if (whiteSkin) then
618 obj.TextColor3 = textColor
619 end
620 end
621 childNum = childNum + 1
622 end
623 end
624 end
625 if not text then
626 dropDownMenu.Text = "Choose One"
627 scrollBarPosition = 1
628 else
629 if not foundItem then
630 error("Invalid Selection Update -- " .. text)
631 end
632
633 if scrollBarPosition + dropDownItemCount > itemCount + 1 then
634 scrollBarPosition = itemCount - dropDownItemCount + 1
635 end
636
637 dropDownMenu.Text = text
638 end
639 end
640
641 local function scrollDown()
642 if scrollBarPosition + dropDownItemCount <= itemCount then
643 scrollBarPosition = scrollBarPosition + 1
644 updateScroll()
645 return true
646 end
647 return false
648 end
649 local function scrollUp()
650 if scrollBarPosition > 1 then
651 scrollBarPosition = scrollBarPosition - 1
652 updateScroll()
653 return true
654 end
655 return false
656 end
657
658 if useScrollButtons then
659 --Make some scroll buttons
660 scrollUpButton = Instance.new("ImageButton")
661 scrollUpButton.Name = "ScrollUpButton"
662 scrollUpButton.BackgroundTransparency = 1
663 scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
664 scrollUpButton.Size = UDim2.new(0,17,0,17)
665 scrollUpButton.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),0)
666 scrollUpButton.MouseButton1Click:connect(
667 function()
668 scrollMouseCount = scrollMouseCount + 1
669 end)
670 scrollUpButton.MouseLeave:connect(
671 function()
672 scrollMouseCount = scrollMouseCount + 1
673 end)
674 scrollUpButton.MouseButton1Down:connect(
675 function()
676 scrollMouseCount = scrollMouseCount + 1
677
678 scrollUp()
679 local val = scrollMouseCount
680 wait(0.5)
681 while val == scrollMouseCount do
682 if scrollUp() == false then
683 break
684 end
685 wait(0.1)
686 end
687 end)
688
689 scrollUpButton.Parent = droppedDownMenu
690
691 scrollDownButton = Instance.new("ImageButton")
692 scrollDownButton.Name = "ScrollDownButton"
693 scrollDownButton.BackgroundTransparency = 1
694 scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
695 scrollDownButton.Size = UDim2.new(0,17,0,17)
696 scrollDownButton.Position = UDim2.new(1,-11,1,-11)
697 scrollDownButton.Parent = droppedDownMenu
698 scrollDownButton.MouseButton1Click:connect(
699 function()
700 scrollMouseCount = scrollMouseCount + 1
701 end)
702 scrollDownButton.MouseLeave:connect(
703 function()
704 scrollMouseCount = scrollMouseCount + 1
705 end)
706 scrollDownButton.MouseButton1Down:connect(
707 function()
708 scrollMouseCount = scrollMouseCount + 1
709
710 scrollDown()
711 local val = scrollMouseCount
712 wait(0.5)
713 while val == scrollMouseCount do
714 if scrollDown() == false then
715 break
716 end
717 wait(0.1)
718 end
719 end)
720
721 local scrollbar = Instance.new("ImageLabel")
722 scrollbar.Name = "ScrollBar"
723 scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
724 scrollbar.BackgroundTransparency = 1
725 scrollbar.Size = UDim2.new(0, 18, (dropDownItemCount*.8)/((dropDownItemCount+1)*.8), -(17) - 11 - 4)
726 scrollbar.Position = UDim2.new(1,-11,(1*.8)/((dropDownItemCount+1)*.8),17+2)
727 scrollbar.Parent = droppedDownMenu
728 end
729
730 for i,item in ipairs(items) do
731 -- needed to maintain local scope for items in event listeners below
732 local button = choiceButton:clone()
733 if forRoblox then
734 --button.RobloxLocked = true
735 end
736 button.Text = item
737 button.Parent = droppedDownMenu
738 if (whiteSkin) then
739 button.TextColor3 = textColor
740 end
741
742 button.MouseButton1Click:connect(function()
743 --Remove Highlight
744 if (not whiteSkin) then
745 button.TextColor3 = Color3.new(1,1,1)
746 end
747 button.BackgroundTransparency = 1
748
749 updateSelection(item)
750 onSelect(item)
751
752 toggleVisibility()
753 end)
754 button.MouseEnter:connect(function()
755 --Add Highlight
756 if (not whiteSkin) then
757 button.TextColor3 = Color3.new(0,0,0)
758 end
759 button.BackgroundTransparency = 0
760 end)
761
762 button.MouseLeave:connect(function()
763 --Remove Highlight
764 if (not whiteSkin) then
765 button.TextColor3 = Color3.new(1,1,1)
766 end
767 button.BackgroundTransparency = 1
768 end)
769 end
770
771 --This does the initial layout of the buttons
772 updateScroll()
773
774 frame.AncestryChanged:connect(function(child,parent)
775 if parent == nil then
776 areaSoak.Parent = nil
777 else
778 areaSoak.Parent = getLayerCollectorAncestor(frame)
779 end
780 end)
781
782 dropDownMenu.MouseButton1Click:connect(toggleVisibility)
783 areaSoak.MouseButton1Click:connect(toggleVisibility)
784 return frame, updateSelection
785end
786
787t.CreatePropertyDropDownMenu = function(instance, property, enum)
788
789 local items = enum:GetEnumItems()
790 local names = {}
791 local nameToItem = {}
792 for i,obj in ipairs(items) do
793 names[i] = obj.Name
794 nameToItem[obj.Name] = obj
795 end
796
797 local frame
798 local updateSelection
799 frame, updateSelection = t.CreateDropDownMenu(names, function(text) instance[property] = nameToItem[text] end)
800
801 ScopedConnect(frame, instance, "Changed",
802 function(prop)
803 if prop == property then
804 updateSelection(instance[property].Name)
805 end
806 end,
807 function()
808 updateSelection(instance[property].Name)
809 end)
810
811 return frame
812end
813
814t.GetFontHeight = function(font, fontSize)
815 if font == nil or fontSize == nil then
816 error("Font and FontSize must be non-nil")
817 end
818
819 local fontSizeInt = tonumber(fontSize.Name:match("%d+")) -- Clever hack to extract the size from the enum itself.
820
821 if font == Enum.Font.Legacy then -- Legacy has a 50% bigger size.
822 return math.ceil(fontSizeInt*1.5)
823 else -- Size is literally just the fontSizeInt
824 return fontSizeInt
825 end
826end
827
828local function layoutGuiObjectsHelper(frame, guiObjects, settingsTable)
829 local totalPixels = frame.AbsoluteSize.Y
830 local pixelsRemaining = frame.AbsoluteSize.Y
831 for i, child in ipairs(guiObjects) do
832 if child:IsA("TextLabel") or child:IsA("TextButton") then
833 local isLabel = child:IsA("TextLabel")
834 if isLabel then
835 pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
836 else
837 pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
838 end
839 child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
840 child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, pixelsRemaining)
841
842 if child.TextFits and child.TextBounds.Y < pixelsRemaining then
843 child.Visible = true
844 if isLabel then
845 child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextLabelSizePadY"])
846 else
847 child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.TextBounds.Y + settingsTable["TextButtonSizePadY"])
848 end
849
850 while not child.TextFits do
851 child.Size = UDim2.new(child.Size.X.Scale, child.Size.X.Offset, 0, child.AbsoluteSize.Y + 1)
852 end
853 pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
854
855 if isLabel then
856 pixelsRemaining = pixelsRemaining - settingsTable["TextLabelPositionPadY"]
857 else
858 pixelsRemaining = pixelsRemaining - settingsTable["TextButtonPositionPadY"]
859 end
860 else
861 child.Visible = false
862 pixelsRemaining = -1
863 end
864
865 else
866 --GuiObject
867 child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
868 pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
869 child.Visible = (pixelsRemaining >= 0)
870 end
871 end
872end
873
874t.LayoutGuiObjects = function(frame, guiObjects, settingsTable)
875 if not frame:IsA("GuiObject") then
876 error("Frame must be a GuiObject")
877 end
878 for i, child in ipairs(guiObjects) do
879 if not child:IsA("GuiObject") then
880 error("All elements that are layed out must be of type GuiObject")
881 end
882 end
883
884 if not settingsTable then
885 settingsTable = {}
886 end
887
888 if not settingsTable["TextLabelSizePadY"] then
889 settingsTable["TextLabelSizePadY"] = 0
890 end
891 if not settingsTable["TextLabelPositionPadY"] then
892 settingsTable["TextLabelPositionPadY"] = 0
893 end
894 if not settingsTable["TextButtonSizePadY"] then
895 settingsTable["TextButtonSizePadY"] = 12
896 end
897 if not settingsTable["TextButtonPositionPadY"] then
898 settingsTable["TextButtonPositionPadY"] = 2
899 end
900
901 --Wrapper frame takes care of styled objects
902 local wrapperFrame = Instance.new("Frame")
903 wrapperFrame.Name = "WrapperFrame"
904 wrapperFrame.BackgroundTransparency = 1
905 wrapperFrame.Size = UDim2.new(1,0,1,0)
906 wrapperFrame.Parent = frame
907
908 for i, child in ipairs(guiObjects) do
909 child.Parent = wrapperFrame
910 end
911
912 local recalculate = function()
913 wait()
914 layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
915 end
916
917 frame.Changed:connect(
918 function(prop)
919 if prop == "AbsoluteSize" then
920 --Wait a heartbeat for it to sync in
921 recalculate(nil)
922 end
923 end)
924 frame.AncestryChanged:connect(recalculate)
925
926 layoutGuiObjectsHelper(wrapperFrame, guiObjects, settingsTable)
927end
928
929
930t.CreateSlider = function(steps,width,position)
931 local sliderGui = Instance.new("Frame")
932 sliderGui.Size = UDim2.new(1,0,1,0)
933 sliderGui.BackgroundTransparency = 1
934 sliderGui.Name = "SliderGui"
935
936 local sliderSteps = Instance.new("IntValue")
937 sliderSteps.Name = "SliderSteps"
938 sliderSteps.Value = steps
939 sliderSteps.Parent = sliderGui
940
941 local areaSoak = Instance.new("TextButton")
942 areaSoak.Name = "AreaSoak"
943 areaSoak.Text = ""
944 areaSoak.BackgroundTransparency = 1
945 areaSoak.Active = false
946 areaSoak.Size = UDim2.new(1,0,1,0)
947 areaSoak.Visible = false
948 areaSoak.ZIndex = 4
949
950 sliderGui.AncestryChanged:connect(function(child,parent)
951 if parent == nil then
952 areaSoak.Parent = nil
953 else
954 areaSoak.Parent = getLayerCollectorAncestor(sliderGui)
955 end
956 end)
957
958 local sliderPosition = Instance.new("IntValue")
959 sliderPosition.Name = "SliderPosition"
960 sliderPosition.Value = 0
961 sliderPosition.Parent = sliderGui
962
963 local id = math.random(1,100)
964
965 local bar = Instance.new("TextButton")
966 bar.Text = ""
967 bar.AutoButtonColor = false
968 bar.Name = "Bar"
969 bar.BackgroundColor3 = Color3.new(0,0,0)
970 if type(width) == "number" then
971 bar.Size = UDim2.new(0,width,0,5)
972 else
973 bar.Size = UDim2.new(0,200,0,5)
974 end
975 bar.BorderColor3 = Color3.new(95/255,95/255,95/255)
976 bar.ZIndex = 2
977 bar.Parent = sliderGui
978
979 if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
980 bar.Position = position
981 end
982
983 local slider = Instance.new("ImageButton")
984 slider.Name = "Slider"
985 slider.BackgroundTransparency = 1
986 slider.Image = "rbxasset://textures/ui/Slider.png"
987 slider.Position = UDim2.new(0,0,0.5,-10)
988 slider.Size = UDim2.new(0,20,0,20)
989 slider.ZIndex = 3
990 slider.Parent = bar
991
992 local areaSoakMouseMoveCon = nil
993
994 areaSoak.MouseLeave:connect(function()
995 if areaSoak.Visible then
996 cancelSlide(areaSoak)
997 end
998 end)
999 areaSoak.MouseButton1Up:connect(function()
1000 if areaSoak.Visible then
1001 cancelSlide(areaSoak)
1002 end
1003 end)
1004
1005 slider.MouseButton1Down:connect(function()
1006 areaSoak.Visible = true
1007 if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
1008 areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
1009 setSliderPos(x,slider,sliderPosition,bar,steps)
1010 end)
1011 end)
1012
1013 slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
1014
1015 sliderPosition.Changed:connect(function(prop)
1016 sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
1017 local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
1018 slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
1019 end)
1020
1021 bar.MouseButton1Down:connect(function(x,y)
1022 setSliderPos(x,slider,sliderPosition,bar,steps)
1023 end)
1024
1025 return sliderGui, sliderPosition, sliderSteps
1026
1027end
1028
1029
1030
1031t.CreateSliderNew = function(steps,width,position)
1032 local sliderGui = Instance.new("Frame")
1033 sliderGui.Size = UDim2.new(1,0,1,0)
1034 sliderGui.BackgroundTransparency = 1
1035 sliderGui.Name = "SliderGui"
1036
1037 local sliderSteps = Instance.new("IntValue")
1038 sliderSteps.Name = "SliderSteps"
1039 sliderSteps.Value = steps
1040 sliderSteps.Parent = sliderGui
1041
1042 local areaSoak = Instance.new("TextButton")
1043 areaSoak.Name = "AreaSoak"
1044 areaSoak.Text = ""
1045 areaSoak.BackgroundTransparency = 1
1046 areaSoak.Active = false
1047 areaSoak.Size = UDim2.new(1,0,1,0)
1048 areaSoak.Visible = false
1049 areaSoak.ZIndex = 6
1050
1051 sliderGui.AncestryChanged:connect(function(child,parent)
1052 if parent == nil then
1053 areaSoak.Parent = nil
1054 else
1055 areaSoak.Parent = getLayerCollectorAncestor(sliderGui)
1056 end
1057 end)
1058
1059 local sliderPosition = Instance.new("IntValue")
1060 sliderPosition.Name = "SliderPosition"
1061 sliderPosition.Value = 0
1062 sliderPosition.Parent = sliderGui
1063
1064 local id = math.random(1,100)
1065
1066 local sliderBarImgHeight = 7
1067 local sliderBarCapImgWidth = 4
1068
1069 local bar = Instance.new("ImageButton")
1070 bar.BackgroundColor3 = Color3.fromRGB(1,1,1)
1071 bar.BorderColor3 = Color3.fromRGB(95, 95, 95)
1072 bar.Name = "Bar"
1073 local displayWidth = 200
1074 if type(width) == "number" then
1075 bar.Size = UDim2.new(0,width - (sliderBarCapImgWidth * 2),0,sliderBarImgHeight)
1076 displayWidth = width - (sliderBarCapImgWidth * 2)
1077 else
1078 bar.Size = UDim2.new(0,200,0, 5)
1079 end
1080 bar.ZIndex = 3
1081 bar.Parent = sliderGui
1082 if position["X"] and position["X"]["Scale"] and position["X"]["Offset"] and position["Y"] and position["Y"]["Scale"] and position["Y"]["Offset"] then
1083 bar.Position = position
1084 end
1085
1086--[[
1087 local barLeft = bar:clone()
1088 barLeft.Name = "BarLeft"
1089 barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png"
1090 barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
1091 barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
1092 barLeft.Parent = sliderGui
1093 barLeft.ZIndex = 3
1094
1095 local barRight = barLeft:clone()
1096 barRight.Name = "BarRight"
1097 barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png"
1098 barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
1099 barRight.Parent = sliderGui
1100
1101 local fillLeft = barLeft:clone()
1102 fillLeft.Name = "FillLeft"
1103 fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png"
1104 fillLeft.Parent = sliderGui
1105 fillLeft.ZIndex = 4
1106
1107 local fill = fillLeft:clone()
1108 fill.Name = "Fill"
1109 fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png"
1110 fill.Parent = bar
1111 fill.ZIndex = 4
1112 fill.Position = UDim2.new(0, 0, 0, 0)
1113 fill.Size = UDim2.new(0.5, 0, 1, 0)
1114]]
1115
1116 -- bar.Visible = false
1117
1118 local slider = Instance.new("ImageButton")
1119 slider.Name = "Slider"
1120 slider.BackgroundTransparency = 1
1121 slider.Image = "rbxassetid://6958886440"
1122 slider.Position = UDim2.new(0,0,0.5,-14)
1123 slider.Size = UDim2.new(0,28,0,28)
1124 slider.ZIndex = 5
1125 slider.Parent = bar
1126
1127 local areaSoakMouseMoveCon = nil
1128
1129 areaSoak.MouseLeave:connect(function()
1130 if areaSoak.Visible then
1131 cancelSlide(areaSoak)
1132 end
1133 end)
1134 areaSoak.MouseButton1Up:connect(function()
1135 if areaSoak.Visible then
1136 cancelSlide(areaSoak)
1137 end
1138 end)
1139
1140 slider.MouseButton1Down:connect(function()
1141 areaSoak.Visible = true
1142 if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
1143 areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
1144 setSliderPos(x,slider,sliderPosition,bar,steps)
1145 end)
1146 end)
1147
1148 slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
1149
1150 sliderPosition.Changed:connect(function(prop)
1151 sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
1152 local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
1153 slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
1154 --fill.Size = UDim2.new(relativePosX, 0, 1, 0)
1155 end)
1156
1157 bar.MouseButton1Down:connect(function(x,y)
1158 setSliderPos(x,slider,sliderPosition,bar,steps)
1159 end)
1160
1161
1162 return sliderGui, sliderPosition, sliderSteps
1163
1164end
1165
1166
1167
1168
1169
1170t.CreateTrueScrollingFrame = function()
1171 local lowY = nil
1172 local highY = nil
1173
1174 local dragCon = nil
1175 local upCon = nil
1176
1177 local internalChange = false
1178
1179 local descendantsChangeConMap = {}
1180
1181 local scrollingFrame = Instance.new("Frame")
1182 scrollingFrame.Name = "ScrollingFrame"
1183 scrollingFrame.Active = true
1184 scrollingFrame.Size = UDim2.new(1,0,1,0)
1185 scrollingFrame.ClipsDescendants = true
1186
1187 local controlFrame = Instance.new("Frame")
1188 controlFrame.Name = "ControlFrame"
1189 controlFrame.BackgroundTransparency = 1
1190 controlFrame.Size = UDim2.new(0,18,1,0)
1191 controlFrame.Position = UDim2.new(1,-20,0,0)
1192 controlFrame.Parent = scrollingFrame
1193
1194 local scrollBottom = Instance.new("BoolValue")
1195 scrollBottom.Value = false
1196 scrollBottom.Name = "ScrollBottom"
1197 scrollBottom.Parent = controlFrame
1198
1199 local scrollUp = Instance.new("BoolValue")
1200 scrollUp.Value = false
1201 scrollUp.Name = "scrollUp"
1202 scrollUp.Parent = controlFrame
1203
1204 local scrollUpButton = Instance.new("TextButton")
1205 scrollUpButton.Name = "ScrollUpButton"
1206 scrollUpButton.Text = ""
1207 scrollUpButton.AutoButtonColor = false
1208 scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
1209 scrollUpButton.BorderColor3 = Color3.new(1,1,1)
1210 scrollUpButton.BackgroundTransparency = 0.5
1211 scrollUpButton.Size = UDim2.new(0,18,0,18)
1212 scrollUpButton.ZIndex = 2
1213 scrollUpButton.Parent = controlFrame
1214 for i = 1, 6 do
1215 local triFrame = Instance.new("Frame")
1216 triFrame.BorderColor3 = Color3.new(1,1,1)
1217 triFrame.Name = "tri" .. tostring(i)
1218 triFrame.ZIndex = 3
1219 triFrame.BackgroundTransparency = 0.5
1220 triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
1221 triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
1222 triFrame.Parent = scrollUpButton
1223 end
1224 scrollUpButton.MouseEnter:connect(function()
1225 scrollUpButton.BackgroundTransparency = 0.1
1226 local upChildren = scrollUpButton:GetChildren()
1227 for i = 1, #upChildren do
1228 upChildren[i].BackgroundTransparency = 0.1
1229 end
1230 end)
1231 scrollUpButton.MouseLeave:connect(function()
1232 scrollUpButton.BackgroundTransparency = 0.5
1233 local upChildren = scrollUpButton:GetChildren()
1234 for i = 1, #upChildren do
1235 upChildren[i].BackgroundTransparency = 0.5
1236 end
1237 end)
1238
1239 local scrollDownButton = scrollUpButton:clone()
1240 scrollDownButton.Name = "ScrollDownButton"
1241 scrollDownButton.Position = UDim2.new(0,0,1,-18)
1242 local downChildren = scrollDownButton:GetChildren()
1243 for i = 1, #downChildren do
1244 downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
1245 end
1246 scrollDownButton.MouseEnter:connect(function()
1247 scrollDownButton.BackgroundTransparency = 0.1
1248 local downChildren = scrollDownButton:GetChildren()
1249 for i = 1, #downChildren do
1250 downChildren[i].BackgroundTransparency = 0.1
1251 end
1252 end)
1253 scrollDownButton.MouseLeave:connect(function()
1254 scrollDownButton.BackgroundTransparency = 0.5
1255 local downChildren = scrollDownButton:GetChildren()
1256 for i = 1, #downChildren do
1257 downChildren[i].BackgroundTransparency = 0.5
1258 end
1259 end)
1260 scrollDownButton.Parent = controlFrame
1261
1262 local scrollTrack = Instance.new("Frame")
1263 scrollTrack.Name = "ScrollTrack"
1264 scrollTrack.BackgroundTransparency = 1
1265 scrollTrack.Size = UDim2.new(0,18,1,-38)
1266 scrollTrack.Position = UDim2.new(0,0,0,19)
1267 scrollTrack.Parent = controlFrame
1268
1269 local scrollbar = Instance.new("TextButton")
1270 scrollbar.BackgroundColor3 = Color3.new(0,0,0)
1271 scrollbar.BorderColor3 = Color3.new(1,1,1)
1272 scrollbar.BackgroundTransparency = 0.5
1273 scrollbar.AutoButtonColor = false
1274 scrollbar.Text = ""
1275 scrollbar.Active = true
1276 scrollbar.Name = "ScrollBar"
1277 scrollbar.ZIndex = 2
1278 scrollbar.BackgroundTransparency = 0.5
1279 scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
1280 scrollbar.Position = UDim2.new(0,0,0,0)
1281 scrollbar.Parent = scrollTrack
1282
1283 local scrollNub = Instance.new("Frame")
1284 scrollNub.Name = "ScrollNub"
1285 scrollNub.BorderColor3 = Color3.new(1,1,1)
1286 scrollNub.Size = UDim2.new(0,10,0,0)
1287 scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
1288 scrollNub.ZIndex = 2
1289 scrollNub.BackgroundTransparency = 0.5
1290 scrollNub.Parent = scrollbar
1291
1292 local newNub = scrollNub:clone()
1293 newNub.Position = UDim2.new(0.5,-5,0.5,-2)
1294 newNub.Parent = scrollbar
1295
1296 local lastNub = scrollNub:clone()
1297 lastNub.Position = UDim2.new(0.5,-5,0.5,2)
1298 lastNub.Parent = scrollbar
1299
1300 scrollbar.MouseEnter:connect(function()
1301 scrollbar.BackgroundTransparency = 0.1
1302 scrollNub.BackgroundTransparency = 0.1
1303 newNub.BackgroundTransparency = 0.1
1304 lastNub.BackgroundTransparency = 0.1
1305 end)
1306 scrollbar.MouseLeave:connect(function()
1307 scrollbar.BackgroundTransparency = 0.5
1308 scrollNub.BackgroundTransparency = 0.5
1309 newNub.BackgroundTransparency = 0.5
1310 lastNub.BackgroundTransparency = 0.5
1311 end)
1312
1313 local mouseDrag = Instance.new("ImageButton")
1314 mouseDrag.Active = false
1315 mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
1316 mouseDrag.AutoButtonColor = false
1317 mouseDrag.BackgroundTransparency = 1
1318 mouseDrag.Name = "mouseDrag"
1319 mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
1320 mouseDrag.ZIndex = 10
1321
1322 local function positionScrollBar(x,y,offset)
1323 local oldPos = scrollbar.Position
1324
1325 if y < scrollTrack.AbsolutePosition.y then
1326 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
1327 return (oldPos ~= scrollbar.Position)
1328 end
1329
1330 local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
1331
1332 if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
1333 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
1334 return (oldPos ~= scrollbar.Position)
1335 end
1336 local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
1337 if newScaleYPos + relativeSize > 1 then
1338 newScaleYPos = 1 - relativeSize
1339 scrollBottom.Value = true
1340 scrollUp.Value = false
1341 elseif newScaleYPos <= 0 then
1342 newScaleYPos = 0
1343 scrollUp.Value = true
1344 scrollBottom.Value = false
1345 else
1346 scrollUp.Value = false
1347 scrollBottom.Value = false
1348 end
1349 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
1350
1351 return (oldPos ~= scrollbar.Position)
1352 end
1353
1354 local function drillDownSetHighLow(instance)
1355 if not instance or not instance:IsA("GuiObject") then return end
1356 if instance == controlFrame then return end
1357 if instance:IsDescendantOf(controlFrame) then return end
1358 if not instance.Visible then return end
1359
1360 if lowY and lowY > instance.AbsolutePosition.Y then
1361 lowY = instance.AbsolutePosition.Y
1362 elseif not lowY then
1363 lowY = instance.AbsolutePosition.Y
1364 end
1365 if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
1366 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1367 elseif not highY then
1368 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1369 end
1370 local children = instance:GetChildren()
1371 for i = 1, #children do
1372 drillDownSetHighLow(children[i])
1373 end
1374 end
1375
1376 local function resetHighLow()
1377 local firstChildren = scrollingFrame:GetChildren()
1378
1379 for i = 1, #firstChildren do
1380 drillDownSetHighLow(firstChildren[i])
1381 end
1382 end
1383
1384 local function recalculate()
1385 internalChange = true
1386
1387 local percentFrame = 0
1388 if scrollbar.Position.Y.Scale > 0 then
1389 if scrollbar.Visible then
1390 percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
1391 else
1392 percentFrame = 0
1393 end
1394 end
1395 if percentFrame > 0.99 then percentFrame = 1 end
1396
1397 local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
1398
1399 local guiChildren = scrollingFrame:GetChildren()
1400 for i = 1, #guiChildren do
1401 if guiChildren[i] ~= controlFrame then
1402 guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
1403 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
1404 end
1405 end
1406
1407 lowY = nil
1408 highY = nil
1409 resetHighLow()
1410 internalChange = false
1411 end
1412
1413 local function setSliderSizeAndPosition()
1414 if not highY or not lowY then return end
1415
1416 local totalYSpan = math.abs(highY - lowY)
1417 if totalYSpan == 0 then
1418 scrollbar.Visible = false
1419 scrollDownButton.Visible = false
1420 scrollUpButton.Visible = false
1421
1422 if dragCon then dragCon:disconnect() dragCon = nil end
1423 if upCon then upCon:disconnect() upCon = nil end
1424 return
1425 end
1426
1427 local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
1428 if percentShown >= 1 then
1429 scrollbar.Visible = false
1430 scrollDownButton.Visible = false
1431 scrollUpButton.Visible = false
1432 recalculate()
1433 else
1434 scrollbar.Visible = true
1435 scrollDownButton.Visible = true
1436 scrollUpButton.Visible = true
1437
1438 scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
1439 end
1440
1441 local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
1442 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
1443
1444 if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then
1445 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
1446 end
1447
1448 if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
1449 local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
1450 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
1451 end
1452 end
1453
1454 local buttonScrollAmountPixels = 7
1455 local reentrancyGuardScrollUp = false
1456 local function doScrollUp()
1457 if reentrancyGuardScrollUp then return end
1458
1459 reentrancyGuardScrollUp = true
1460 if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
1461 recalculate()
1462 end
1463 reentrancyGuardScrollUp = false
1464 end
1465
1466 local reentrancyGuardScrollDown = false
1467 local function doScrollDown()
1468 if reentrancyGuardScrollDown then return end
1469
1470 reentrancyGuardScrollDown = true
1471 if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
1472 recalculate()
1473 end
1474 reentrancyGuardScrollDown = false
1475 end
1476
1477 local function scrollUp(mouseYPos)
1478 if scrollUpButton.Active then
1479 scrollStamp = tick()
1480 local current = scrollStamp
1481 local upCon
1482 upCon = mouseDrag.MouseButton1Up:connect(function()
1483 scrollStamp = tick()
1484 mouseDrag.Parent = nil
1485 upCon:disconnect()
1486 end)
1487 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
1488 doScrollUp()
1489 wait(0.2)
1490 local t = tick()
1491 local w = 0.1
1492 while scrollStamp == current do
1493 doScrollUp()
1494 if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then
1495 break
1496 end
1497 if not scrollUpButton.Active then break end
1498 if tick()-t > 5 then
1499 w = 0
1500 elseif tick()-t > 2 then
1501 w = 0.06
1502 end
1503 wait(w)
1504 end
1505 end
1506 end
1507
1508 local function scrollDown(mouseYPos)
1509 if scrollDownButton.Active then
1510 scrollStamp = tick()
1511 local current = scrollStamp
1512 local downCon
1513 downCon = mouseDrag.MouseButton1Up:connect(function()
1514 scrollStamp = tick()
1515 mouseDrag.Parent = nil
1516 downCon:disconnect()
1517 end)
1518 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
1519 doScrollDown()
1520 wait(0.2)
1521 local t = tick()
1522 local w = 0.1
1523 while scrollStamp == current do
1524 doScrollDown()
1525 if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
1526 break
1527 end
1528 if not scrollDownButton.Active then break end
1529 if tick()-t > 5 then
1530 w = 0
1531 elseif tick()-t > 2 then
1532 w = 0.06
1533 end
1534 wait(w)
1535 end
1536 end
1537 end
1538
1539 scrollbar.MouseButton1Down:connect(function(x,y)
1540 if scrollbar.Active then
1541 scrollStamp = tick()
1542 local mouseOffset = y - scrollbar.AbsolutePosition.y
1543 if dragCon then dragCon:disconnect() dragCon = nil end
1544 if upCon then upCon:disconnect() upCon = nil end
1545 local prevY = y
1546 local reentrancyGuardMouseScroll = false
1547 dragCon = mouseDrag.MouseMoved:connect(function(x,y)
1548 if reentrancyGuardMouseScroll then return end
1549
1550 reentrancyGuardMouseScroll = true
1551 if positionScrollBar(x,y,mouseOffset) then
1552 recalculate()
1553 end
1554 reentrancyGuardMouseScroll = false
1555
1556 end)
1557 upCon = mouseDrag.MouseButton1Up:connect(function()
1558 scrollStamp = tick()
1559 mouseDrag.Parent = nil
1560 dragCon:disconnect(); dragCon = nil
1561 upCon:disconnect(); drag = nil
1562 end)
1563 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
1564 end
1565 end)
1566
1567 local scrollMouseCount = 0
1568
1569 scrollUpButton.MouseButton1Down:connect(function()
1570 scrollUp()
1571 end)
1572 scrollUpButton.MouseButton1Up:connect(function()
1573 scrollStamp = tick()
1574 end)
1575
1576 scrollDownButton.MouseButton1Up:connect(function()
1577 scrollStamp = tick()
1578 end)
1579 scrollDownButton.MouseButton1Down:connect(function()
1580 scrollDown()
1581 end)
1582
1583 scrollbar.MouseButton1Up:connect(function()
1584 scrollStamp = tick()
1585 end)
1586
1587 local function heightCheck(instance)
1588 if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then
1589 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1590 elseif not highY then
1591 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1592 end
1593 setSliderSizeAndPosition()
1594 end
1595
1596 local function highLowRecheck()
1597 local oldLowY = lowY
1598 local oldHighY = highY
1599 lowY = nil
1600 highY = nil
1601 resetHighLow()
1602
1603 if (lowY ~= oldLowY) or (highY ~= oldHighY) then
1604 setSliderSizeAndPosition()
1605 end
1606 end
1607
1608 local function descendantChanged(this, prop)
1609 if internalChange then return end
1610 if not this.Visible then return end
1611
1612 if prop == "Size" or prop == "Position" then
1613 wait()
1614 highLowRecheck()
1615 end
1616 end
1617
1618 scrollingFrame.DescendantAdded:connect(function(instance)
1619 if not instance:IsA("GuiObject") then return end
1620
1621 if instance.Visible then
1622 wait() -- wait a heartbeat for sizes to reconfig
1623 highLowRecheck()
1624 end
1625
1626 descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
1627 end)
1628
1629 scrollingFrame.DescendantRemoving:connect(function(instance)
1630 if not instance:IsA("GuiObject") then return end
1631 if descendantsChangeConMap[instance] then
1632 descendantsChangeConMap[instance]:disconnect()
1633 descendantsChangeConMap[instance] = nil
1634 end
1635 wait() -- wait a heartbeat for sizes to reconfig
1636 highLowRecheck()
1637 end)
1638
1639 scrollingFrame.Changed:connect(function(prop)
1640 if prop == "AbsoluteSize" then
1641 if not highY or not lowY then return end
1642
1643 highLowRecheck()
1644 setSliderSizeAndPosition()
1645 end
1646 end)
1647
1648 return scrollingFrame, controlFrame
1649end
1650
1651t.CreateScrollingFrame = function(orderList,scrollStyle)
1652 local frame = Instance.new("Frame")
1653 frame.Name = "ScrollingFrame"
1654 frame.BackgroundTransparency = 1
1655 frame.Size = UDim2.new(1,0,1,0)
1656
1657 local scrollUpButton = Instance.new("ImageButton")
1658 scrollUpButton.Name = "ScrollUpButton"
1659 scrollUpButton.BackgroundTransparency = 1
1660 scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
1661 scrollUpButton.Size = UDim2.new(0,17,0,17)
1662
1663
1664 local scrollDownButton = Instance.new("ImageButton")
1665 scrollDownButton.Name = "ScrollDownButton"
1666 scrollDownButton.BackgroundTransparency = 1
1667 scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
1668 scrollDownButton.Size = UDim2.new(0,17,0,17)
1669
1670 local scrollbar = Instance.new("ImageButton")
1671 scrollbar.Name = "ScrollBar"
1672 scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
1673 scrollbar.BackgroundTransparency = 1
1674 scrollbar.Size = UDim2.new(0, 18, 0, 150)
1675
1676 local scrollStamp = 0
1677
1678 local scrollDrag = Instance.new("ImageButton")
1679 scrollDrag.Image = "https://www.roblox.com/asset/?id=61367186"
1680 scrollDrag.Size = UDim2.new(1, 0, 0, 16)
1681 scrollDrag.BackgroundTransparency = 1
1682 scrollDrag.Name = "ScrollDrag"
1683 scrollDrag.Active = true
1684 scrollDrag.Parent = scrollbar
1685
1686 local mouseDrag = Instance.new("ImageButton")
1687 mouseDrag.Active = false
1688 mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
1689 mouseDrag.AutoButtonColor = false
1690 mouseDrag.BackgroundTransparency = 1
1691 mouseDrag.Name = "mouseDrag"
1692 mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
1693 mouseDrag.ZIndex = 10
1694
1695 local style = "simple"
1696 if scrollStyle and tostring(scrollStyle) then
1697 style = scrollStyle
1698 end
1699
1700 local scrollPosition = 1
1701 local rowSize = 0
1702 local howManyDisplayed = 0
1703
1704 local layoutGridScrollBar = function()
1705 howManyDisplayed = 0
1706 local guiObjects = {}
1707 if orderList then
1708 for i, child in ipairs(orderList) do
1709 if child.Parent == frame then
1710 table.insert(guiObjects, child)
1711 end
1712 end
1713 else
1714 local children = frame:GetChildren()
1715 if children then
1716 for i, child in ipairs(children) do
1717 if child:IsA("GuiObject") then
1718 table.insert(guiObjects, child)
1719 end
1720 end
1721 end
1722 end
1723 if #guiObjects == 0 then
1724 scrollUpButton.Active = false
1725 scrollDownButton.Active = false
1726 scrollDrag.Active = false
1727 scrollPosition = 1
1728 return
1729 end
1730
1731 if scrollPosition > #guiObjects then
1732 scrollPosition = #guiObjects
1733 end
1734
1735 if scrollPosition < 1 then scrollPosition = 1 end
1736
1737 local totalPixelsY = frame.AbsoluteSize.Y
1738 local pixelsRemainingY = frame.AbsoluteSize.Y
1739
1740 local totalPixelsX = frame.AbsoluteSize.X
1741
1742 local xCounter = 0
1743 local rowSizeCounter = 0
1744 local setRowSize = true
1745
1746 local pixelsBelowScrollbar = 0
1747 local pos = #guiObjects
1748
1749 local currentRowY = 0
1750
1751 pos = scrollPosition
1752 --count up from current scroll position to fill out grid
1753 while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do
1754 xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
1755 --previous pos was the end of a row
1756 if xCounter >= totalPixelsX then
1757 pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
1758 currentRowY = 0
1759 xCounter = guiObjects[pos].AbsoluteSize.X
1760 end
1761 if guiObjects[pos].AbsoluteSize.Y > currentRowY then
1762 currentRowY = guiObjects[pos].AbsoluteSize.Y
1763 end
1764 pos = pos + 1
1765 end
1766 --Count wherever current row left off
1767 pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
1768 currentRowY = 0
1769
1770 pos = scrollPosition - 1
1771 xCounter = 0
1772
1773 --objects with varying X,Y dimensions can rarely cause minor errors
1774 --rechecking every new scrollPosition is necessary to avoid 100% of errors
1775
1776 --count backwards from current scrollPosition to see if we can add more rows
1777 while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do
1778 xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
1779 rowSizeCounter = rowSizeCounter + 1
1780 if xCounter >= totalPixelsX then
1781 rowSize = rowSizeCounter - 1
1782 rowSizeCounter = 0
1783 xCounter = guiObjects[pos].AbsoluteSize.X
1784 if pixelsBelowScrollbar + currentRowY <= totalPixelsY then
1785 --It fits, so back up our scroll position
1786 pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
1787 if scrollPosition <= rowSize then
1788 scrollPosition = 1
1789 break
1790 else
1791 scrollPosition = scrollPosition - rowSize
1792 end
1793 currentRowY = 0
1794 else
1795 break
1796 end
1797 end
1798
1799 if guiObjects[pos].AbsoluteSize.Y > currentRowY then
1800 currentRowY = guiObjects[pos].AbsoluteSize.Y
1801 end
1802
1803 pos = pos - 1
1804 end
1805
1806 --Do check last time if pos = 0
1807 if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then
1808 scrollPosition = 1
1809 end
1810
1811 xCounter = 0
1812 --pos = scrollPosition
1813 rowSizeCounter = 0
1814 setRowSize = true
1815 local lastChildSize = 0
1816
1817 local xOffset,yOffset = 0
1818 if guiObjects[1] then
1819 yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
1820 xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
1821 end
1822
1823 for i, child in ipairs(guiObjects) do
1824 if i < scrollPosition then
1825 --print("Hiding " .. child.Name)
1826 child.Visible = false
1827 else
1828 if pixelsRemainingY < 0 then
1829 --print("Out of Space " .. child.Name)
1830 child.Visible = false
1831 else
1832 --print("Laying out " .. child.Name)
1833 --GuiObject
1834 if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
1835 if xCounter + child.AbsoluteSize.X >= totalPixelsX then
1836 if setRowSize then
1837 rowSize = rowSizeCounter - 1
1838 setRowSize = false
1839 end
1840 xCounter = 0
1841 pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
1842 end
1843 child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
1844 xCounter = xCounter + child.AbsoluteSize.X
1845 child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0)
1846 if child.Visible then
1847 howManyDisplayed = howManyDisplayed + 1
1848 end
1849 lastChildSize = child.AbsoluteSize
1850 end
1851 end
1852 end
1853
1854 scrollUpButton.Active = (scrollPosition > 1)
1855 if lastChildSize == 0 then
1856 scrollDownButton.Active = false
1857 else
1858 scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0)
1859 end
1860 scrollDrag.Active = #guiObjects > howManyDisplayed
1861 scrollDrag.Visible = scrollDrag.Active
1862 end
1863
1864
1865
1866 local layoutSimpleScrollBar = function()
1867 local guiObjects = {}
1868 howManyDisplayed = 0
1869
1870 if orderList then
1871 for i, child in ipairs(orderList) do
1872 if child.Parent == frame then
1873 table.insert(guiObjects, child)
1874 end
1875 end
1876 else
1877 local children = frame:GetChildren()
1878 if children then
1879 for i, child in ipairs(children) do
1880 if child:IsA("GuiObject") then
1881 table.insert(guiObjects, child)
1882 end
1883 end
1884 end
1885 end
1886 if #guiObjects == 0 then
1887 scrollUpButton.Active = false
1888 scrollDownButton.Active = false
1889 scrollDrag.Active = false
1890 scrollPosition = 1
1891 return
1892 end
1893
1894 if scrollPosition > #guiObjects then
1895 scrollPosition = #guiObjects
1896 end
1897
1898 local totalPixels = frame.AbsoluteSize.Y
1899 local pixelsRemaining = frame.AbsoluteSize.Y
1900
1901 local pixelsBelowScrollbar = 0
1902 local pos = #guiObjects
1903 while pixelsBelowScrollbar < totalPixels and pos >= 1 do
1904 if pos >= scrollPosition then
1905 pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
1906 else
1907 if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then
1908 --It fits, so back up our scroll position
1909 pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
1910 if scrollPosition <= 1 then
1911 scrollPosition = 1
1912 break
1913 else
1914 --local ("Backing up ScrollPosition from -- " ..scrollPosition)
1915 scrollPosition = scrollPosition - 1
1916 end
1917 else
1918 break
1919 end
1920 end
1921 pos = pos - 1
1922 end
1923
1924 pos = scrollPosition
1925 for i, child in ipairs(guiObjects) do
1926 if i < scrollPosition then
1927 --print("Hiding " .. child.Name)
1928 child.Visible = false
1929 else
1930 if pixelsRemaining < 0 then
1931 --print("Out of Space " .. child.Name)
1932 child.Visible = false
1933 else
1934 --print("Laying out " .. child.Name)
1935 --GuiObject
1936 child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
1937 pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
1938 if (pixelsRemaining >= 0) then
1939 child.Visible = true
1940 howManyDisplayed = howManyDisplayed + 1
1941 else
1942 child.Visible = false
1943 end
1944 end
1945 end
1946 end
1947 scrollUpButton.Active = (scrollPosition > 1)
1948 scrollDownButton.Active = (pixelsRemaining < 0)
1949 scrollDrag.Active = #guiObjects > howManyDisplayed
1950 scrollDrag.Visible = scrollDrag.Active
1951 end
1952
1953
1954 local moveDragger = function()
1955 local guiObjects = 0
1956 local children = frame:GetChildren()
1957 if children then
1958 for i, child in ipairs(children) do
1959 if child:IsA("GuiObject") then
1960 guiObjects = guiObjects + 1
1961 end
1962 end
1963 end
1964
1965 if not scrollDrag.Parent then return end
1966
1967 local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
1968 if dragSizeY < 16 then dragSizeY = 16 end
1969 scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
1970
1971 local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
1972 if relativeYPos > 1 then relativeYPos = 1
1973 elseif relativeYPos < 0 then relativeYPos = 0 end
1974 local absYPos = 0
1975
1976 if relativeYPos ~= 0 then
1977 absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
1978 end
1979
1980 scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
1981 end
1982
1983 local reentrancyGuard = false
1984 local recalculate = function()
1985 if reentrancyGuard then
1986 return
1987 end
1988 reentrancyGuard = true
1989 wait()
1990 local success, err = nil
1991 if style == "grid" then
1992 success, err = pcall(function() layoutGridScrollBar() end)
1993 elseif style == "simple" then
1994 success, err = pcall(function() layoutSimpleScrollBar() end)
1995 end
1996 if not success then print(err) end
1997 moveDragger()
1998 reentrancyGuard = false
1999 end
2000
2001 local doScrollUp = function()
2002 scrollPosition = (scrollPosition) - rowSize
2003 if scrollPosition < 1 then scrollPosition = 1 end
2004 recalculate(nil)
2005 end
2006
2007 local doScrollDown = function()
2008 scrollPosition = (scrollPosition) + rowSize
2009 recalculate(nil)
2010 end
2011
2012 local scrollUp = function(mouseYPos)
2013 if scrollUpButton.Active then
2014 scrollStamp = tick()
2015 local current = scrollStamp
2016 local upCon
2017 upCon = mouseDrag.MouseButton1Up:connect(function()
2018 scrollStamp = tick()
2019 mouseDrag.Parent = nil
2020 upCon:disconnect()
2021 end)
2022 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
2023 doScrollUp()
2024 wait(0.2)
2025 local t = tick()
2026 local w = 0.1
2027 while scrollStamp == current do
2028 doScrollUp()
2029 if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then
2030 break
2031 end
2032 if not scrollUpButton.Active then break end
2033 if tick()-t > 5 then
2034 w = 0
2035 elseif tick()-t > 2 then
2036 w = 0.06
2037 end
2038 wait(w)
2039 end
2040 end
2041 end
2042
2043 local scrollDown = function(mouseYPos)
2044 if scrollDownButton.Active then
2045 scrollStamp = tick()
2046 local current = scrollStamp
2047 local downCon
2048 downCon = mouseDrag.MouseButton1Up:connect(function()
2049 scrollStamp = tick()
2050 mouseDrag.Parent = nil
2051 downCon:disconnect()
2052 end)
2053 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
2054 doScrollDown()
2055 wait(0.2)
2056 local t = tick()
2057 local w = 0.1
2058 while scrollStamp == current do
2059 doScrollDown()
2060 if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
2061 break
2062 end
2063 if not scrollDownButton.Active then break end
2064 if tick()-t > 5 then
2065 w = 0
2066 elseif tick()-t > 2 then
2067 w = 0.06
2068 end
2069 wait(w)
2070 end
2071 end
2072 end
2073
2074 local y = 0
2075 scrollDrag.MouseButton1Down:connect(function(x,y)
2076 if scrollDrag.Active then
2077 scrollStamp = tick()
2078 local mouseOffset = y - scrollDrag.AbsolutePosition.y
2079 local dragCon
2080 local upCon
2081 dragCon = mouseDrag.MouseMoved:connect(function(x,y)
2082 local barAbsPos = scrollbar.AbsolutePosition.y
2083 local barAbsSize = scrollbar.AbsoluteSize.y
2084
2085 local dragAbsSize = scrollDrag.AbsoluteSize.y
2086 local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
2087 y = y - mouseOffset
2088 y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y
2089 y = y - barAbsPos
2090
2091 local guiObjects = 0
2092 local children = frame:GetChildren()
2093 if children then
2094 for i, child in ipairs(children) do
2095 if child:IsA("GuiObject") then
2096 guiObjects = guiObjects + 1
2097 end
2098 end
2099 end
2100
2101 local doublePercent = y/(barAbsSize-dragAbsSize)
2102 local rowDiff = rowSize
2103 local totalScrollCount = guiObjects - (howManyDisplayed - 1)
2104 local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
2105 if newScrollPosition < scrollPosition then
2106 rowDiff = -rowDiff
2107 end
2108
2109 if newScrollPosition < 1 then
2110 newScrollPosition = 1
2111 end
2112
2113 scrollPosition = newScrollPosition
2114 recalculate(nil)
2115 end)
2116 upCon = mouseDrag.MouseButton1Up:connect(function()
2117 scrollStamp = tick()
2118 mouseDrag.Parent = nil
2119 dragCon:disconnect(); dragCon = nil
2120 upCon:disconnect(); drag = nil
2121 end)
2122 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
2123 end
2124 end)
2125
2126 local scrollMouseCount = 0
2127
2128 scrollUpButton.MouseButton1Down:connect(
2129 function()
2130 scrollUp()
2131 end)
2132 scrollUpButton.MouseButton1Up:connect(function()
2133 scrollStamp = tick()
2134 end)
2135
2136
2137 scrollDownButton.MouseButton1Up:connect(function()
2138 scrollStamp = tick()
2139 end)
2140 scrollDownButton.MouseButton1Down:connect(
2141 function()
2142 scrollDown()
2143 end)
2144
2145 scrollbar.MouseButton1Up:connect(function()
2146 scrollStamp = tick()
2147 end)
2148 scrollbar.MouseButton1Down:connect(
2149 function(x,y)
2150 if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
2151 scrollDown(y)
2152 elseif y < (scrollDrag.AbsolutePosition.y) then
2153 scrollUp(y)
2154 end
2155 end)
2156
2157
2158 frame.ChildAdded:connect(function()
2159 recalculate(nil)
2160 end)
2161
2162 frame.ChildRemoved:connect(function()
2163 recalculate(nil)
2164 end)
2165
2166 frame.Changed:connect(
2167 function(prop)
2168 if prop == "AbsoluteSize" then
2169 --Wait a heartbeat for it to sync in
2170 recalculate(nil)
2171 end
2172 end)
2173 frame.AncestryChanged:connect(function() recalculate(nil) end)
2174
2175 return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
2176end
2177local function binaryGrow(min, max, fits)
2178 if min > max then
2179 return min
2180 end
2181 local biggestLegal = min
2182
2183 while min <= max do
2184 local mid = min + math.floor((max - min) / 2)
2185 if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then
2186 biggestLegal = mid
2187
2188 --Try growing
2189 min = mid + 1
2190 else
2191 --Doesn't fit, shrink
2192 max = mid - 1
2193 end
2194 end
2195 return biggestLegal
2196end
2197
2198
2199local function binaryShrink(min, max, fits)
2200 if min > max then
2201 return min
2202 end
2203 local smallestLegal = max
2204
2205 while min <= max do
2206 local mid = min + math.floor((max - min) / 2)
2207 if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then
2208 smallestLegal = mid
2209
2210 --It fits, shrink
2211 max = mid - 1
2212 else
2213 --Doesn't fit, grow
2214 min = mid + 1
2215 end
2216 end
2217 return smallestLegal
2218end
2219
2220
2221local function getGuiOwner(instance)
2222 while instance ~= nil do
2223 if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then
2224 return instance
2225 end
2226 instance = instance.Parent
2227 end
2228 return nil
2229end
2230
2231t.AutoTruncateTextObject = function(textLabel)
2232 local text = textLabel.Text
2233
2234 local fullLabel = textLabel:Clone()
2235 fullLabel.Name = "Full" .. textLabel.Name
2236 fullLabel.BorderSizePixel = 0
2237 fullLabel.BackgroundTransparency = 0
2238 fullLabel.Text = text
2239 fullLabel.TextXAlignment = Enum.TextXAlignment.Center
2240 fullLabel.Position = UDim2.new(0,-3,0,0)
2241 fullLabel.Size = UDim2.new(0,100,1,0)
2242 fullLabel.Visible = false
2243 fullLabel.Parent = textLabel
2244
2245 local shortText = nil
2246 local mouseEnterConnection = nil
2247 local mouseLeaveConnection= nil
2248
2249 local checkForResize = function()
2250 if getGuiOwner(textLabel) == nil then
2251 return
2252 end
2253 textLabel.Text = text
2254 if textLabel.TextFits then
2255 --Tear down the rollover if it is active
2256 if mouseEnterConnection then
2257 mouseEnterConnection:disconnect()
2258 mouseEnterConnection = nil
2259 end
2260 if mouseLeaveConnection then
2261 mouseLeaveConnection:disconnect()
2262 mouseLeaveConnection = nil
2263 end
2264 else
2265 local len = string.len(text)
2266 textLabel.Text = text .. "~"
2267
2268 --Shrink the text
2269 local textSize = binaryGrow(0, len,
2270 function(pos)
2271 if pos == 0 then
2272 textLabel.Text = "~"
2273 else
2274 textLabel.Text = string.sub(text, 1, pos) .. "~"
2275 end
2276 return textLabel.TextFits
2277 end)
2278 shortText = string.sub(text, 1, textSize) .. "~"
2279 textLabel.Text = shortText
2280
2281 --Make sure the fullLabel fits
2282 if not fullLabel.TextFits then
2283 --Already too small, grow it really bit to start
2284 fullLabel.Size = UDim2.new(0, 10000, 1, 0)
2285 end
2286
2287 --Okay, now try to binary shrink it back down
2288 local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
2289 function(size)
2290 fullLabel.Size = UDim2.new(0, size, 1, 0)
2291 return fullLabel.TextFits
2292 end)
2293 fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
2294
2295 --Now setup the rollover effects, if they are currently off
2296 if mouseEnterConnection == nil then
2297 mouseEnterConnection = textLabel.MouseEnter:connect(
2298 function()
2299 fullLabel.ZIndex = textLabel.ZIndex + 1
2300 fullLabel.Visible = true
2301 --textLabel.Text = ""
2302 end)
2303 end
2304 if mouseLeaveConnection == nil then
2305 mouseLeaveConnection = textLabel.MouseLeave:connect(
2306 function()
2307 fullLabel.Visible = false
2308 --textLabel.Text = shortText
2309 end)
2310 end
2311 end
2312 end
2313 textLabel.AncestryChanged:connect(checkForResize)
2314 textLabel.Changed:connect(
2315 function(prop)
2316 if prop == "AbsoluteSize" then
2317 checkForResize()
2318 end
2319 end)
2320
2321 checkForResize()
2322
2323 local function changeText(newText)
2324 text = newText
2325 fullLabel.Text = text
2326 checkForResize()
2327 end
2328
2329 return textLabel, changeText
2330end
2331
2332local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)
2333 if fromPage then
2334 fromPage.Visible = false
2335 if transitionFrame.Visible == false then
2336 transitionFrame.Size = fromPage.Size
2337 transitionFrame.Position = fromPage.Position
2338 end
2339 else
2340 if transitionFrame.Visible == false then
2341 transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
2342 transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
2343 end
2344 end
2345 transitionFrame.Visible = true
2346 currentPageValue.Value = nil
2347
2348 local newSize, newPosition
2349 if toPage then
2350 --Make it visible so it resizes
2351 toPage.Visible = true
2352
2353 newSize = toPage.Size
2354 newPosition = toPage.Position
2355
2356 toPage.Visible = false
2357 else
2358 newSize = UDim2.new(0.0,50,0.0,50)
2359 newPosition = UDim2.new(0.5,-25,0.5,-25)
2360 end
2361 transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
2362 function(state)
2363 if state == Enum.TweenStatus.Completed then
2364 transitionFrame.Visible = false
2365 if toPage then
2366 toPage.Visible = true
2367 currentPageValue.Value = toPage
2368 end
2369 end
2370 end)
2371end
2372
2373t.CreateTutorial = function(name, tutorialKey, createButtons)
2374 local frame = Instance.new("Frame")
2375 frame.Name = "Tutorial-" .. name
2376 frame.BackgroundTransparency = 1
2377 frame.Size = UDim2.new(0.6, 0, 0.6, 0)
2378 frame.Position = UDim2.new(0.2, 0, 0.2, 0)
2379
2380 local transitionFrame = Instance.new("Frame")
2381 transitionFrame.Name = "TransitionFrame"
2382 transitionFrame.Style = Enum.FrameStyle.RobloxRound
2383 transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
2384 transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
2385 transitionFrame.Visible = false
2386 transitionFrame.Parent = frame
2387
2388 local currentPageValue = Instance.new("ObjectValue")
2389 currentPageValue.Name = "CurrentTutorialPage"
2390 currentPageValue.Value = nil
2391 currentPageValue.Parent = frame
2392
2393 local boolValue = Instance.new("BoolValue")
2394 boolValue.Name = "Buttons"
2395 boolValue.Value = createButtons
2396 boolValue.Parent = frame
2397
2398 local pages = Instance.new("Frame")
2399 pages.Name = "Pages"
2400 pages.BackgroundTransparency = 1
2401 pages.Size = UDim2.new(1,0,1,0)
2402 pages.Parent = frame
2403
2404 local function getVisiblePageAndHideOthers()
2405 local visiblePage = nil
2406 local children = pages:GetChildren()
2407 if children then
2408 for i,child in ipairs(children) do
2409 if child.Visible then
2410 if visiblePage then
2411 child.Visible = false
2412 else
2413 visiblePage = child
2414 end
2415 end
2416 end
2417 end
2418 return visiblePage
2419 end
2420
2421 local showTutorial = function(alwaysShow)
2422 if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
2423 print("Showing tutorial-",tutorialKey)
2424 local currentTutorialPage = getVisiblePageAndHideOthers()
2425
2426 local firstPage = pages:FindFirstChild("TutorialPage1")
2427 if firstPage then
2428 TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)
2429 else
2430 error("Could not find TutorialPage1")
2431 end
2432 end
2433 end
2434
2435 local dismissTutorial = function()
2436 local currentTutorialPage = getVisiblePageAndHideOthers()
2437
2438 if currentTutorialPage then
2439 TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
2440 end
2441
2442 UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
2443 end
2444
2445 local gotoPage = function(pageNum)
2446 local page = pages:FindFirstChild("TutorialPage" .. pageNum)
2447 local currentTutorialPage = getVisiblePageAndHideOthers()
2448 TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
2449 end
2450
2451 return frame, showTutorial, dismissTutorial, gotoPage
2452end
2453
2454local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
2455 local frame = Instance.new("Frame")
2456 frame.Name = "TutorialPage"
2457 frame.Style = Enum.FrameStyle.RobloxRound
2458 frame.Size = UDim2.new(0.6, 0, 0.6, 0)
2459 frame.Position = UDim2.new(0.2, 0, 0.2, 0)
2460 frame.Visible = false
2461
2462 local frameHeader = Instance.new("TextLabel")
2463 frameHeader.Name = "Header"
2464 frameHeader.Text = name
2465 frameHeader.BackgroundTransparency = 1
2466 frameHeader.FontSize = Enum.FontSize.Size24
2467 frameHeader.Font = Enum.Font.ArialBold
2468 frameHeader.TextColor3 = Color3.new(1,1,1)
2469 frameHeader.TextXAlignment = Enum.TextXAlignment.Center
2470 frameHeader.TextWrap = true
2471 frameHeader.Size = UDim2.new(1,-55, 0, 22)
2472 frameHeader.Position = UDim2.new(0,0,0,0)
2473 frameHeader.Parent = frame
2474
2475 local skipButton = Instance.new("ImageButton")
2476 skipButton.Name = "SkipButton"
2477 skipButton.AutoButtonColor = false
2478 skipButton.BackgroundTransparency = 1
2479 skipButton.Image = "rbxasset://textures/ui/closeButton.png"
2480 skipButton.MouseButton1Click:connect(function()
2481 skipTutorial()
2482 end)
2483 skipButton.MouseEnter:connect(function()
2484 skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png"
2485 end)
2486 skipButton.MouseLeave:connect(function()
2487 skipButton.Image = "rbxasset://textures/ui/closeButton.png"
2488 end)
2489 skipButton.Size = UDim2.new(0, 25, 0, 25)
2490 skipButton.Position = UDim2.new(1, -25, 0, 0)
2491 skipButton.Parent = frame
2492
2493
2494 if giveDoneButton then
2495 local doneButton = Instance.new("TextButton")
2496 doneButton.Name = "DoneButton"
2497 doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
2498 doneButton.Text = "Done"
2499 doneButton.TextColor3 = Color3.new(1,1,1)
2500 doneButton.Font = Enum.Font.ArialBold
2501 doneButton.FontSize = Enum.FontSize.Size18
2502 doneButton.Size = UDim2.new(0,100,0,50)
2503 doneButton.Position = UDim2.new(0.5,-50,1,-50)
2504
2505 if skipTutorial then
2506 doneButton.MouseButton1Click:connect(function() skipTutorial() end)
2507 end
2508
2509 doneButton.Parent = frame
2510 end
2511
2512 local innerFrame = Instance.new("Frame")
2513 innerFrame.Name = "ContentFrame"
2514 innerFrame.BackgroundTransparency = 1
2515 innerFrame.Position = UDim2.new(0,0,0,25)
2516 innerFrame.Parent = frame
2517
2518 local nextButton = Instance.new("TextButton")
2519 nextButton.Name = "NextButton"
2520 nextButton.Text = "Next"
2521 nextButton.TextColor3 = Color3.new(1,1,1)
2522 nextButton.Font = Enum.Font.Arial
2523 nextButton.FontSize = Enum.FontSize.Size18
2524 nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
2525 nextButton.Size = UDim2.new(0,80, 0, 32)
2526 nextButton.Position = UDim2.new(0.5, 5, 1, -32)
2527 nextButton.Active = false
2528 nextButton.Visible = false
2529 nextButton.Parent = frame
2530
2531 local prevButton = Instance.new("TextButton")
2532 prevButton.Name = "PrevButton"
2533 prevButton.Text = "Previous"
2534 prevButton.TextColor3 = Color3.new(1,1,1)
2535 prevButton.Font = Enum.Font.Arial
2536 prevButton.FontSize = Enum.FontSize.Size18
2537 prevButton.Style = Enum.ButtonStyle.RobloxButton
2538 prevButton.Size = UDim2.new(0,80, 0, 32)
2539 prevButton.Position = UDim2.new(0.5, -85, 1, -32)
2540 prevButton.Active = false
2541 prevButton.Visible = false
2542 prevButton.Parent = frame
2543
2544 if giveDoneButton then
2545 innerFrame.Size = UDim2.new(1,0,1,-75)
2546 else
2547 innerFrame.Size = UDim2.new(1,0,1,-22)
2548 end
2549
2550 local parentConnection = nil
2551
2552 local function basicHandleResize()
2553 if frame.Visible and frame.Parent then
2554 local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
2555 handleResize(200,maxSize)
2556 end
2557 end
2558
2559 frame.Changed:connect(
2560 function(prop)
2561 if prop == "Parent" then
2562 if parentConnection ~= nil then
2563 parentConnection:disconnect()
2564 parentConnection = nil
2565 end
2566 if frame.Parent and frame.Parent:IsA("GuiObject") then
2567 parentConnection = frame.Parent.Changed:connect(
2568 function(parentProp)
2569 if parentProp == "AbsoluteSize" then
2570 wait()
2571 basicHandleResize()
2572 end
2573 end)
2574 basicHandleResize()
2575 end
2576 end
2577
2578 if prop == "Visible" then
2579 basicHandleResize()
2580 end
2581 end)
2582
2583 return frame, innerFrame
2584end
2585
2586t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
2587 local frame = nil
2588 local contentFrame = nil
2589
2590 local textLabel = Instance.new("TextLabel")
2591 textLabel.BackgroundTransparency = 1
2592 textLabel.TextColor3 = Color3.new(1,1,1)
2593 textLabel.Text = text
2594 textLabel.TextWrap = true
2595 textLabel.TextXAlignment = Enum.TextXAlignment.Left
2596 textLabel.TextYAlignment = Enum.TextYAlignment.Center
2597 textLabel.Font = Enum.Font.Arial
2598 textLabel.FontSize = Enum.FontSize.Size14
2599 textLabel.Size = UDim2.new(1,0,1,0)
2600
2601 local function handleResize(minSize, maxSize)
2602 size = binaryShrink(minSize, maxSize,
2603 function(size)
2604 frame.Size = UDim2.new(0, size, 0, size)
2605 return textLabel.TextFits
2606 end)
2607 frame.Size = UDim2.new(0, size, 0, size)
2608 frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
2609 end
2610
2611 frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
2612 textLabel.Parent = contentFrame
2613
2614 return frame
2615end
2616
2617t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
2618 local frame = nil
2619 local contentFrame = nil
2620
2621 local imageLabel = Instance.new("ImageLabel")
2622 imageLabel.BackgroundTransparency = 1
2623 imageLabel.Image = imageAsset
2624 imageLabel.Size = UDim2.new(0,x,0,y)
2625 imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
2626
2627 local function handleResize(minSize, maxSize)
2628 size = binaryShrink(minSize, maxSize,
2629 function(size)
2630 return size >= x and size >= y
2631 end)
2632 if size >= x and size >= y then
2633 imageLabel.Size = UDim2.new(0,x, 0,y)
2634 imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
2635 else
2636 if x > y then
2637 --X is limiter, so
2638 imageLabel.Size = UDim2.new(1,0,y/x,0)
2639 imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
2640 else
2641 --Y is limiter
2642 imageLabel.Size = UDim2.new(x/y,0,1, 0)
2643 imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
2644 end
2645 end
2646 size = size + 50
2647 frame.Size = UDim2.new(0, size, 0, size)
2648 frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
2649 end
2650
2651 frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
2652 imageLabel.Parent = contentFrame
2653
2654 return frame
2655end
2656
2657t.AddTutorialPage = function(tutorial, tutorialPage)
2658 local transitionFrame = tutorial.TransitionFrame
2659 local currentPageValue = tutorial.CurrentTutorialPage
2660
2661 if not tutorial.Buttons.Value then
2662 tutorialPage.NextButton.Parent = nil
2663 tutorialPage.PrevButton.Parent = nil
2664 end
2665
2666 local children = tutorial.Pages:GetChildren()
2667 if children and #children > 0 then
2668 tutorialPage.Name = "TutorialPage" .. (#children+1)
2669 local previousPage = children[#children]
2670 if not previousPage:IsA("GuiObject") then
2671 error("All elements under Pages must be GuiObjects")
2672 end
2673
2674 if tutorial.Buttons.Value then
2675 if previousPage.NextButton.Active then
2676 error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function")
2677 end
2678 previousPage.NextButton.MouseButton1Click:connect(
2679 function()
2680 TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
2681 end)
2682 previousPage.NextButton.Active = true
2683 previousPage.NextButton.Visible = true
2684
2685 if tutorialPage.PrevButton.Active then
2686 error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function")
2687 end
2688 tutorialPage.PrevButton.MouseButton1Click:connect(
2689 function()
2690 TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
2691 end)
2692 tutorialPage.PrevButton.Active = true
2693 tutorialPage.PrevButton.Visible = true
2694 end
2695
2696 tutorialPage.Parent = tutorial.Pages
2697 else
2698 --First child
2699 tutorialPage.Name = "TutorialPage1"
2700 tutorialPage.Parent = tutorial.Pages
2701 end
2702end
2703
2704t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
2705
2706 if not userIdsForSets then
2707 error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids")
2708 end
2709 if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then
2710 error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata")
2711 end
2712 if not objectSelected then
2713 error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!")
2714 end
2715 if type(objectSelected) ~= "function" then
2716 error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!")
2717 end
2718 if dialogClosed and type(dialogClosed) ~= "function" then
2719 error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!")
2720 end
2721
2722 if showAdminCategories == nil then -- by default, don't show beta sets
2723 showAdminCategories = false
2724 end
2725
2726 local arrayPosition = 1
2727 local insertButtons = {}
2728 local insertButtonCons = {}
2729 local contents = nil
2730 local setGui = nil
2731
2732 -- used for water selections
2733 local waterForceDirection = "NegX"
2734 local waterForce = "None"
2735 local waterGui, waterTypeChangedEvent = nil
2736
2737 local Data = {}
2738 Data.CurrentCategory = nil
2739 Data.Category = {}
2740 local SetCache = {}
2741
2742 local userCategoryButtons = nil
2743
2744 local buttonWidth = 64
2745 local buttonHeight = buttonWidth
2746
2747 local SmallThumbnailUrl = nil
2748 local LargeThumbnailUrl = nil
2749 local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
2750 local AssetGameUrl = string.gsub(BaseUrl, "www", "assetgame")
2751
2752 if useAssetVersionId then
2753 LargeThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid="
2754 SmallThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid="
2755 else
2756 LargeThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid="
2757 SmallThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
2758 end
2759
2760 local function drillDownSetZIndex(parent, index)
2761 local children = parent:GetChildren()
2762 for i = 1, #children do
2763 if children[i]:IsA("GuiObject") then
2764 children[i].ZIndex = index
2765 end
2766 drillDownSetZIndex(children[i], index)
2767 end
2768 end
2769
2770 -- for terrain stamping
2771 local currTerrainDropDownFrame = nil
2772 local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"}
2773 local terrainShapeMap = {}
2774 for i = 1, #terrainShapes do
2775 terrainShapeMap[terrainShapes[i]] = i - 1
2776 end
2777 terrainShapeMap[terrainShapes[#terrainShapes]] = 6
2778
2779 local function createWaterGui()
2780 local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"}
2781 local waterForces = {"None", "Small", "Medium", "Strong", "Max"}
2782
2783 local waterFrame = Instance.new("Frame")
2784 waterFrame.Name = "WaterFrame"
2785 waterFrame.Style = Enum.FrameStyle.RobloxSquare
2786 waterFrame.Size = UDim2.new(0,150,0,110)
2787 waterFrame.Visible = false
2788
2789 local waterForceLabel = Instance.new("TextLabel")
2790 waterForceLabel.Name = "WaterForceLabel"
2791 waterForceLabel.BackgroundTransparency = 1
2792 waterForceLabel.Size = UDim2.new(1,0,0,12)
2793 waterForceLabel.Font = Enum.Font.ArialBold
2794 waterForceLabel.FontSize = Enum.FontSize.Size12
2795 waterForceLabel.TextColor3 = Color3.new(1,1,1)
2796 waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
2797 waterForceLabel.Text = "Water Force"
2798 waterForceLabel.Parent = waterFrame
2799
2800 local waterForceDirLabel = waterForceLabel:Clone()
2801 waterForceDirLabel.Name = "WaterForceDirectionLabel"
2802 waterForceDirLabel.Text = "Water Force Direction"
2803 waterForceDirLabel.Position = UDim2.new(0,0,0,50)
2804 waterForceDirLabel.Parent = waterFrame
2805
2806 local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame)
2807 waterTypeChangedEvent.Name = "WaterTypeChangedEvent"
2808
2809 local waterForceDirectionSelectedFunc = function(newForceDirection)
2810 waterForceDirection = newForceDirection
2811 waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
2812 end
2813 local waterForceSelectedFunc = function(newForce)
2814 waterForce = newForce
2815 waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
2816 end
2817
2818 local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
2819 waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
2820 waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
2821 forceWaterDirectionSelection("NegX")
2822 waterForceDirectionDropDown.Parent = waterForceDirLabel
2823
2824 local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
2825 forceWaterForceSelection("None")
2826 waterForceDropDown.Size = UDim2.new(1,0,0,25)
2827 waterForceDropDown.Position = UDim2.new(0,0,1,3)
2828 waterForceDropDown.Parent = waterForceLabel
2829
2830 return waterFrame, waterTypeChangedEvent
2831 end
2832
2833 -- Helper Function that contructs gui elements
2834 local function createSetGui()
2835
2836 local setGui = Instance.new("ScreenGui")
2837 setGui.Name = "SetGui"
2838
2839 local setPanel = Instance.new("Frame")
2840 setPanel.Name = "SetPanel"
2841 setPanel.Active = true
2842 setPanel.BackgroundTransparency = 1
2843 if position then
2844 setPanel.Position = position
2845 else
2846 setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
2847 end
2848 if size then
2849 setPanel.Size = size
2850 else
2851 setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
2852 end
2853 setPanel.Style = Enum.FrameStyle.RobloxRound
2854 setPanel.ZIndex = 6
2855 setPanel.Parent = setGui
2856
2857 -- Children of SetPanel
2858 local itemPreview = Instance.new("Frame")
2859 itemPreview.Name = "ItemPreview"
2860 itemPreview.BackgroundTransparency = 1
2861 itemPreview.Position = UDim2.new(0.8,5,0.085,0)
2862 itemPreview.Size = UDim2.new(0.21,0,0.9,0)
2863 itemPreview.ZIndex = 6
2864 itemPreview.Parent = setPanel
2865
2866 -- Children of ItemPreview
2867 local textPanel = Instance.new("Frame")
2868 textPanel.Name = "TextPanel"
2869 textPanel.BackgroundTransparency = 1
2870 textPanel.Position = UDim2.new(0,0,0.45,0)
2871 textPanel.Size = UDim2.new(1,0,0.55,0)
2872 textPanel.ZIndex = 6
2873 textPanel.Parent = itemPreview
2874
2875 -- Children of TextPanel
2876 local rolloverText = Instance.new("TextLabel")
2877 rolloverText.Name = "RolloverText"
2878 rolloverText.BackgroundTransparency = 1
2879 rolloverText.Size = UDim2.new(1,0,0,48)
2880 rolloverText.ZIndex = 6
2881 rolloverText.Font = Enum.Font.ArialBold
2882 rolloverText.FontSize = Enum.FontSize.Size24
2883 rolloverText.Text = ""
2884 rolloverText.TextColor3 = Color3.new(1,1,1)
2885 rolloverText.TextWrap = true
2886 rolloverText.TextXAlignment = Enum.TextXAlignment.Left
2887 rolloverText.TextYAlignment = Enum.TextYAlignment.Top
2888 rolloverText.Parent = textPanel
2889
2890 local largePreview = Instance.new("ImageLabel")
2891 largePreview.Name = "LargePreview"
2892 largePreview.BackgroundTransparency = 1
2893 largePreview.Image = ""
2894 largePreview.Size = UDim2.new(1,0,0,170)
2895 largePreview.ZIndex = 6
2896 largePreview.Parent = itemPreview
2897
2898 local sets = Instance.new("Frame")
2899 sets.Name = "Sets"
2900 sets.BackgroundTransparency = 1
2901 sets.Position = UDim2.new(0,0,0,5)
2902 sets.Size = UDim2.new(0.23,0,1,-5)
2903 sets.ZIndex = 6
2904 sets.Parent = setPanel
2905
2906 -- Children of Sets
2907 local line = Instance.new("Frame")
2908 line.Name = "Line"
2909 line.BackgroundColor3 = Color3.new(1,1,1)
2910 line.BackgroundTransparency = 0.7
2911 line.BorderSizePixel = 0
2912 line.Position = UDim2.new(1,-3,0.06,0)
2913 line.Size = UDim2.new(0,3,0.9,0)
2914 line.ZIndex = 6
2915 line.Parent = sets
2916
2917 local setsLists, controlFrame = t.CreateTrueScrollingFrame()
2918 setsLists.Size = UDim2.new(1,-6,0.94,0)
2919 setsLists.Position = UDim2.new(0,0,0.06,0)
2920 setsLists.BackgroundTransparency = 1
2921 setsLists.Name = "SetsLists"
2922 setsLists.ZIndex = 6
2923 setsLists.Parent = sets
2924 drillDownSetZIndex(controlFrame, 7)
2925
2926 local setsHeader = Instance.new("TextLabel")
2927 setsHeader.Name = "SetsHeader"
2928 setsHeader.BackgroundTransparency = 1
2929 setsHeader.Size = UDim2.new(0,47,0,24)
2930 setsHeader.ZIndex = 6
2931 setsHeader.Font = Enum.Font.ArialBold
2932 setsHeader.FontSize = Enum.FontSize.Size24
2933 setsHeader.Text = "Sets"
2934 setsHeader.TextColor3 = Color3.new(1,1,1)
2935 setsHeader.TextXAlignment = Enum.TextXAlignment.Left
2936 setsHeader.TextYAlignment = Enum.TextYAlignment.Top
2937 setsHeader.Parent = sets
2938
2939 local cancelButton = Instance.new("TextButton")
2940 cancelButton.Name = "CancelButton"
2941 cancelButton.Position = UDim2.new(1,-32,0,-2)
2942 cancelButton.Size = UDim2.new(0,34,0,34)
2943 cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
2944 cancelButton.ZIndex = 6
2945 cancelButton.Text = ""
2946 cancelButton.Modal = true
2947 cancelButton.Parent = setPanel
2948
2949 -- Children of Cancel Button
2950 local cancelImage = Instance.new("ImageLabel")
2951 cancelImage.Name = "CancelImage"
2952 cancelImage.BackgroundTransparency = 1
2953 cancelImage.Image = "https://www.roblox.com/asset/?id=54135717"
2954 cancelImage.Position = UDim2.new(0,-2,0,-2)
2955 cancelImage.Size = UDim2.new(0,16,0,16)
2956 cancelImage.ZIndex = 6
2957 cancelImage.Parent = cancelButton
2958
2959 return setGui
2960 end
2961
2962 local function createSetButton(text)
2963 local setButton = Instance.new("TextButton")
2964
2965 if text then setButton.Text = text
2966 else setButton.Text = "" end
2967
2968 setButton.AutoButtonColor = false
2969 setButton.BackgroundTransparency = 1
2970 setButton.BackgroundColor3 = Color3.new(1,1,1)
2971 setButton.BorderSizePixel = 0
2972 setButton.Size = UDim2.new(1,-5,0,18)
2973 setButton.ZIndex = 6
2974 setButton.Visible = false
2975 setButton.Font = Enum.Font.Arial
2976 setButton.FontSize = Enum.FontSize.Size18
2977 setButton.TextColor3 = Color3.new(1,1,1)
2978 setButton.TextXAlignment = Enum.TextXAlignment.Left
2979
2980 return setButton
2981 end
2982
2983 local function buildSetButton(name, setId, setImageId, i, count)
2984 local button = createSetButton(name)
2985 button.Text = name
2986 button.Name = "SetButton"
2987 button.Visible = true
2988
2989 local setValue = Instance.new("IntValue")
2990 setValue.Name = "SetId"
2991 setValue.Value = setId
2992 setValue.Parent = button
2993
2994 local setName = Instance.new("StringValue")
2995 setName.Name = "SetName"
2996 setName.Value = name
2997 setName.Parent = button
2998
2999 return button
3000 end
3001
3002 local function processCategory(sets)
3003 local setButtons = {}
3004 local numSkipped = 0
3005 for i = 1, #sets do
3006 if not showAdminCategories and sets[i].Name == "Beta" then
3007 numSkipped = numSkipped + 1
3008 else
3009 setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
3010 end
3011 end
3012 return setButtons
3013 end
3014
3015 local function handleResize()
3016 wait() -- neccessary to insure heartbeat happened
3017
3018 local itemPreview = setGui.SetPanel.ItemPreview
3019
3020 itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
3021 itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
3022 itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
3023 itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
3024 end
3025
3026 local function makeInsertAssetButton()
3027 local insertAssetButtonExample = Instance.new("Frame")
3028 insertAssetButtonExample.Name = "InsertAssetButtonExample"
3029 insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
3030 insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
3031 insertAssetButtonExample.BackgroundTransparency = 1
3032 insertAssetButtonExample.ZIndex = 6
3033 insertAssetButtonExample.Visible = false
3034
3035 local assetId = Instance.new("IntValue")
3036 assetId.Name = "AssetId"
3037 assetId.Value = 0
3038 assetId.Parent = insertAssetButtonExample
3039
3040 local assetName = Instance.new("StringValue")
3041 assetName.Name = "AssetName"
3042 assetName.Value = ""
3043 assetName.Parent = insertAssetButtonExample
3044
3045 local button = Instance.new("TextButton")
3046 button.Name = "Button"
3047 button.Text = ""
3048 button.Style = Enum.ButtonStyle.RobloxButton
3049 button.Position = UDim2.new(0.025,0,0.025,0)
3050 button.Size = UDim2.new(0.95,0,0.95,0)
3051 button.ZIndex = 6
3052 button.Parent = insertAssetButtonExample
3053
3054 local buttonImage = Instance.new("ImageLabel")
3055 buttonImage.Name = "ButtonImage"
3056 buttonImage.Image = ""
3057 buttonImage.Position = UDim2.new(0,-7,0,-7)
3058 buttonImage.Size = UDim2.new(1,14,1,14)
3059 buttonImage.BackgroundTransparency = 1
3060 buttonImage.ZIndex = 7
3061 buttonImage.Parent = button
3062
3063 local configIcon = buttonImage:clone()
3064 configIcon.Name = "ConfigIcon"
3065 configIcon.Visible = false
3066 configIcon.Position = UDim2.new(1,-23,1,-24)
3067 configIcon.Size = UDim2.new(0,16,0,16)
3068 configIcon.Image = ""
3069 configIcon.ZIndex = 6
3070 configIcon.Parent = insertAssetButtonExample
3071
3072 return insertAssetButtonExample
3073 end
3074
3075 local function showLargePreview(insertButton)
3076 if insertButton:FindFirstChild("AssetId") then
3077 delay(0,function()
3078 game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
3079 setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
3080 end)
3081 end
3082 if insertButton:FindFirstChild("AssetName") then
3083 setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
3084 end
3085 end
3086
3087 local function selectTerrainShape(shape)
3088 if currTerrainDropDownFrame then
3089 objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
3090 end
3091 end
3092
3093 local function createTerrainTypeButton(name, parent)
3094 local dropDownTextButton = Instance.new("TextButton")
3095 dropDownTextButton.Name = name .. "Button"
3096 dropDownTextButton.Font = Enum.Font.ArialBold
3097 dropDownTextButton.FontSize = Enum.FontSize.Size14
3098 dropDownTextButton.BorderSizePixel = 0
3099 dropDownTextButton.TextColor3 = Color3.new(1,1,1)
3100 dropDownTextButton.Text = name
3101 dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
3102 dropDownTextButton.BackgroundTransparency = 1
3103 dropDownTextButton.ZIndex = parent.ZIndex + 1
3104 dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
3105 dropDownTextButton.Position = UDim2.new(0,1,0,0)
3106
3107 dropDownTextButton.MouseEnter:connect(function()
3108 dropDownTextButton.BackgroundTransparency = 0
3109 dropDownTextButton.TextColor3 = Color3.new(0,0,0)
3110 end)
3111
3112 dropDownTextButton.MouseLeave:connect(function()
3113 dropDownTextButton.BackgroundTransparency = 1
3114 dropDownTextButton.TextColor3 = Color3.new(1,1,1)
3115 end)
3116
3117 dropDownTextButton.MouseButton1Click:connect(function()
3118 dropDownTextButton.BackgroundTransparency = 1
3119 dropDownTextButton.TextColor3 = Color3.new(1,1,1)
3120 if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then
3121 dropDownTextButton.Parent.Visible = false
3122 end
3123 selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
3124 end)
3125
3126 return dropDownTextButton
3127 end
3128
3129 local function createTerrainDropDownMenu(zIndex)
3130 local dropDown = Instance.new("Frame")
3131 dropDown.Name = "TerrainDropDown"
3132 dropDown.BackgroundColor3 = Color3.new(0,0,0)
3133 dropDown.BorderColor3 = Color3.new(1,0,0)
3134 dropDown.Size = UDim2.new(0,200,0,0)
3135 dropDown.Visible = false
3136 dropDown.ZIndex = zIndex
3137 dropDown.Parent = setGui
3138
3139 for i = 1, #terrainShapes do
3140 local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
3141 shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
3142 shapeButton.Parent = dropDown
3143 dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
3144 end
3145
3146 dropDown.MouseLeave:connect(function()
3147 dropDown.Visible = false
3148 end)
3149 end
3150
3151
3152 local function createDropDownMenuButton(parent)
3153 local dropDownButton = Instance.new("ImageButton")
3154 dropDownButton.Name = "DropDownButton"
3155 dropDownButton.Image = "https://www.roblox.com/asset/?id=67581509"
3156 dropDownButton.BackgroundTransparency = 1
3157 dropDownButton.Size = UDim2.new(0,16,0,16)
3158 dropDownButton.Position = UDim2.new(1,-24,0,6)
3159 dropDownButton.ZIndex = parent.ZIndex + 2
3160 dropDownButton.Parent = parent
3161
3162 if not setGui:FindFirstChild("TerrainDropDown") then
3163 createTerrainDropDownMenu(8)
3164 end
3165
3166 dropDownButton.MouseButton1Click:connect(function()
3167 setGui.TerrainDropDown.Visible = true
3168 setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
3169 currTerrainDropDownFrame = parent
3170 end)
3171 end
3172
3173 local function buildInsertButton()
3174 local insertButton = makeInsertAssetButton()
3175 insertButton.Name = "InsertAssetButton"
3176 insertButton.Visible = true
3177
3178 if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
3179 createDropDownMenuButton(insertButton)
3180 end
3181
3182 local lastEnter = nil
3183 local mouseEnterCon = insertButton.MouseEnter:connect(function()
3184 lastEnter = insertButton
3185 delay(0.1,function()
3186 if lastEnter == insertButton then
3187 showLargePreview(insertButton)
3188 end
3189 end)
3190 end)
3191 return insertButton, mouseEnterCon
3192 end
3193
3194 local function realignButtonGrid(columns)
3195 local x = 0
3196 local y = 0
3197 for i = 1, #insertButtons do
3198 insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
3199 x = x + 1
3200 if x >= columns then
3201 x = 0
3202 y = y + 1
3203 end
3204 end
3205 end
3206
3207 local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
3208 if visible then
3209 insertFrame.AssetName.Value = name
3210 insertFrame.AssetId.Value = assetId
3211 local newImageUrl = SmallThumbnailUrl .. assetId
3212 if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
3213 delay(0,function()
3214 game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId)
3215 if insertFrame:findFirstChild("Button") then
3216 insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
3217 end
3218 end)
3219 end
3220 table.insert(insertButtonCons,
3221 insertFrame.Button.MouseButton1Click:connect(function()
3222 -- special case for water, show water selection gui
3223 local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability")
3224 waterGui.Visible = isWaterSelected
3225 if isWaterSelected then
3226 objectSelected(name, tonumber(assetId), nil)
3227 else
3228 objectSelected(name, tonumber(assetId))
3229 end
3230 end)
3231 )
3232 insertFrame.Visible = true
3233 else
3234 insertFrame.Visible = false
3235 end
3236 end
3237
3238 local function loadSectionOfItems(setGui, rows, columns)
3239 local pageSize = rows * columns
3240
3241 if arrayPosition > #contents then return end
3242
3243 local origArrayPos = arrayPosition
3244
3245 local yCopy = 0
3246 for i = 1, pageSize + 1 do
3247 if arrayPosition >= #contents + 1 then
3248 break
3249 end
3250
3251 local buttonCon
3252 insertButtons[arrayPosition], buttonCon = buildInsertButton()
3253 table.insert(insertButtonCons,buttonCon)
3254 insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
3255 arrayPosition = arrayPosition + 1
3256 end
3257 realignButtonGrid(columns)
3258
3259 local indexCopy = origArrayPos
3260 for index = origArrayPos, arrayPosition do
3261 if insertButtons[index] then
3262 if contents[index] then
3263
3264 -- we don't want water to have a drop down button
3265 if contents[index].Name == "Water" then
3266 if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
3267 insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy()
3268 end
3269 end
3270
3271 local assetId
3272 if useAssetVersionId then
3273 assetId = contents[index].AssetVersionId
3274 else
3275 assetId = contents[index].AssetId
3276 end
3277 setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
3278 else
3279 break
3280 end
3281 else
3282 break
3283 end
3284 indexCopy = index
3285 end
3286 end
3287
3288 local function setSetIndex()
3289 Data.Category[Data.CurrentCategory].Index = 0
3290
3291 rows = 7
3292 columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
3293
3294 contents = Data.Category[Data.CurrentCategory].Contents
3295 if contents then
3296 -- remove our buttons and their connections
3297 for i = 1, #insertButtons do
3298 insertButtons[i]:remove()
3299 end
3300 for i = 1, #insertButtonCons do
3301 if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
3302 end
3303 insertButtonCons = {}
3304 insertButtons = {}
3305
3306 arrayPosition = 1
3307 loadSectionOfItems(setGui, rows, columns)
3308 end
3309 end
3310
3311 local function selectSet(button, setName, setId, setIndex)
3312 if button and Data.Category[Data.CurrentCategory] ~= nil then
3313 if button ~= Data.Category[Data.CurrentCategory].Button then
3314 Data.Category[Data.CurrentCategory].Button = button
3315
3316 if SetCache[setId] == nil then
3317 SetCache[setId] = game:GetService("InsertService"):GetCollection(setId)
3318 end
3319 Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
3320
3321 Data.Category[Data.CurrentCategory].SetName = setName
3322 Data.Category[Data.CurrentCategory].SetId = setId
3323 end
3324 setSetIndex()
3325 end
3326 end
3327
3328 local function selectCategoryPage(buttons, page)
3329 if buttons ~= Data.CurrentCategory then
3330 if Data.CurrentCategory then
3331 for key, button in pairs(Data.CurrentCategory) do
3332 button.Visible = false
3333 end
3334 end
3335
3336 Data.CurrentCategory = buttons
3337 if Data.Category[Data.CurrentCategory] == nil then
3338 Data.Category[Data.CurrentCategory] = {}
3339 if #buttons > 0 then
3340 selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
3341 end
3342 else
3343 Data.Category[Data.CurrentCategory].Button = nil
3344 selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
3345 end
3346 end
3347 end
3348
3349 local function selectCategory(category)
3350 selectCategoryPage(category, 0)
3351 end
3352
3353 local function resetAllSetButtonSelection()
3354 local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
3355 for i = 1, #setButtons do
3356 if setButtons[i]:IsA("TextButton") then
3357 setButtons[i].Selected = false
3358 setButtons[i].BackgroundTransparency = 1
3359 setButtons[i].TextColor3 = Color3.new(1,1,1)
3360 setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
3361 end
3362 end
3363 end
3364
3365 local function populateSetsFrame()
3366 local currRow = 0
3367 for i = 1, #userCategoryButtons do
3368 local button = userCategoryButtons[i]
3369 button.Visible = true
3370 button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
3371 button.Parent = setGui.SetPanel.Sets.SetsLists
3372
3373 if i == 1 then -- we will have this selected by default, so show it
3374 button.Selected = true
3375 button.BackgroundColor3 = Color3.new(0,204/255,0)
3376 button.TextColor3 = Color3.new(0,0,0)
3377 button.BackgroundTransparency = 0
3378 end
3379
3380 button.MouseEnter:connect(function()
3381 if not button.Selected then
3382 button.BackgroundTransparency = 0
3383 button.TextColor3 = Color3.new(0,0,0)
3384 end
3385 end)
3386 button.MouseLeave:connect(function()
3387 if not button.Selected then
3388 button.BackgroundTransparency = 1
3389 button.TextColor3 = Color3.new(1,1,1)
3390 end
3391 end)
3392 button.MouseButton1Click:connect(function()
3393 resetAllSetButtonSelection()
3394 button.Selected = not button.Selected
3395 button.BackgroundColor3 = Color3.new(0,204/255,0)
3396 button.TextColor3 = Color3.new(0,0,0)
3397 button.BackgroundTransparency = 0
3398 selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
3399 end)
3400
3401 currRow = currRow + 1
3402 end
3403
3404 local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
3405
3406 -- set first category as loaded for default
3407 if buttons then
3408 for i = 1, #buttons do
3409 if buttons[i]:IsA("TextButton") then
3410 selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
3411 selectCategory(userCategoryButtons)
3412 break
3413 end
3414 end
3415 end
3416 end
3417
3418 setGui = createSetGui()
3419 waterGui, waterTypeChangedEvent = createWaterGui()
3420 waterGui.Position = UDim2.new(0,55,0,0)
3421 waterGui.Parent = setGui
3422 setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
3423 if prop == "AbsoluteSize" then
3424 handleResize()
3425 setSetIndex()
3426 end
3427 end)
3428
3429 local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
3430 scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
3431 scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
3432 scrollFrame.Name = "ItemsFrame"
3433 scrollFrame.ZIndex = 6
3434 scrollFrame.Parent = setGui.SetPanel
3435 scrollFrame.BackgroundTransparency = 1
3436
3437 drillDownSetZIndex(controlFrame,7)
3438
3439 controlFrame.Parent = setGui.SetPanel
3440 controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
3441
3442 local debounce = false
3443 controlFrame.ScrollBottom.Changed:connect(function(prop)
3444 if controlFrame.ScrollBottom.Value == true then
3445 if debounce then return end
3446 debounce = true
3447 loadSectionOfItems(setGui, rows, columns)
3448 debounce = false
3449 end
3450 end)
3451
3452 local userData = {}
3453 for id = 1, #userIdsForSets do
3454 local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id])
3455 if newUserData and #newUserData > 2 then
3456 -- start at #3 to skip over My Decals and My Models for each account
3457 for category = 3, #newUserData do
3458 if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first
3459 table.insert(userData,1,newUserData[category])
3460 else
3461 table.insert(userData, newUserData[category])
3462 end
3463 end
3464 end
3465
3466 end
3467 if userData then
3468 userCategoryButtons = processCategory(userData)
3469 end
3470
3471 rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
3472 columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
3473
3474 populateSetsFrame()
3475
3476 setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
3477 setGui.SetPanel.Visible = false
3478 if dialogClosed then dialogClosed() end
3479 end)
3480
3481 local setVisibilityFunction = function(visible)
3482 if visible then
3483 setGui.SetPanel.Visible = true
3484 else
3485 setGui.SetPanel.Visible = false
3486 end
3487 end
3488
3489 local getVisibilityFunction = function()
3490 if setGui then
3491 if setGui:FindFirstChild("SetPanel") then
3492 return setGui.SetPanel.Visible
3493 end
3494 end
3495
3496 return false
3497 end
3498
3499 return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
3500end
3501
3502t.CreateTerrainMaterialSelector = function(size,position)
3503 local terrainMaterialSelectionChanged = Instance.new("BindableEvent")
3504 terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged"
3505
3506 local selectedButton = nil
3507
3508 local frame = Instance.new("Frame")
3509 frame.Name = "TerrainMaterialSelector"
3510 if size then
3511 frame.Size = size
3512 else
3513 frame.Size = UDim2.new(0, 245, 0, 230)
3514 end
3515 if position then
3516 frame.Position = position
3517 end
3518 frame.BorderSizePixel = 0
3519 frame.BackgroundColor3 = Color3.new(0,0,0)
3520 frame.Active = true
3521
3522 terrainMaterialSelectionChanged.Parent = frame
3523
3524 local waterEnabled = true -- todo: turn this on when water is ready
3525
3526 local materialToImageMap = {}
3527 local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"}
3528 if waterEnabled then
3529 table.insert(materialNames,"Water")
3530 end
3531 local currentMaterial = 1
3532
3533 function getEnumFromName(choice)
3534 if choice == "Grass" then return 1 end
3535 if choice == "Sand" then return 2 end
3536 if choice == "Erase" then return 0 end
3537 if choice == "Brick" then return 3 end
3538 if choice == "Granite" then return 4 end
3539 if choice == "Asphalt" then return 5 end
3540 if choice == "Iron" then return 6 end
3541 if choice == "Aluminum" then return 7 end
3542 if choice == "Gold" then return 8 end
3543 if choice == "Plank" then return 9 end
3544 if choice == "Log" then return 10 end
3545 if choice == "Gravel" then return 11 end
3546 if choice == "Cinder Block" then return 12 end
3547 if choice == "Stone Wall" then return 13 end
3548 if choice == "Concrete" then return 14 end
3549 if choice == "Plastic (red)" then return 15 end
3550 if choice == "Plastic (blue)" then return 16 end
3551 if choice == "Water" then return 17 end
3552 end
3553
3554 function getNameFromEnum(choice)
3555 if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end
3556 if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end
3557 if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end
3558 if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end
3559 if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end
3560 if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end
3561 if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end
3562 if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end
3563 if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end
3564 if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end
3565 if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end
3566 if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end
3567 if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end
3568 if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end
3569 if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end
3570 if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end
3571 if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end
3572
3573 if waterEnabled then
3574 if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end
3575 end
3576 end
3577
3578
3579 local function updateMaterialChoice(choice)
3580 currentMaterial = getEnumFromName(choice)
3581 terrainMaterialSelectionChanged:Fire(currentMaterial)
3582 end
3583
3584 -- we so need a better way to do this
3585 for i,v in pairs(materialNames) do
3586 materialToImageMap[v] = {}
3587 if v == "Grass" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=56563112"
3588 elseif v == "Sand" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=62356652"
3589 elseif v == "Brick" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=65961537"
3590 elseif v == "Granite" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532153"
3591 elseif v == "Asphalt" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532038"
3592 elseif v == "Iron" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532093"
3593 elseif v == "Aluminum" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531995"
3594 elseif v == "Gold" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532118"
3595 elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531848"
3596 elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531924"
3597 elseif v == "Plank" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532015"
3598 elseif v == "Log" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532051"
3599 elseif v == "Gravel" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532206"
3600 elseif v == "Cinder Block" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532103"
3601 elseif v == "Stone Wall" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531804"
3602 elseif v == "Concrete" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532059"
3603 elseif v == "Water" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=81407474"
3604 else materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=66887593" -- fill in the rest here!!
3605 end
3606 end
3607
3608 local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid")
3609 scrollFrame.Size = UDim2.new(0.85,0,1,0)
3610 scrollFrame.Position = UDim2.new(0,0,0,0)
3611 scrollFrame.Parent = frame
3612
3613 scrollUp.Parent = frame
3614 scrollUp.Visible = true
3615 scrollUp.Position = UDim2.new(1,-19,0,0)
3616
3617 scrollDown.Parent = frame
3618 scrollDown.Visible = true
3619 scrollDown.Position = UDim2.new(1,-19,1,-17)
3620
3621 local function goToNewMaterial(buttonWrap, materialName)
3622 updateMaterialChoice(materialName)
3623 buttonWrap.BackgroundTransparency = 0
3624 selectedButton.BackgroundTransparency = 1
3625 selectedButton = buttonWrap
3626 end
3627
3628 local function createMaterialButton(name)
3629 local buttonWrap = Instance.new("TextButton")
3630 buttonWrap.Text = ""
3631 buttonWrap.Size = UDim2.new(0,32,0,32)
3632 buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
3633 buttonWrap.BorderSizePixel = 0
3634 buttonWrap.BackgroundTransparency = 1
3635 buttonWrap.AutoButtonColor = false
3636 buttonWrap.Name = tostring(name)
3637
3638 local imageButton = Instance.new("ImageButton")
3639 imageButton.AutoButtonColor = false
3640 imageButton.BackgroundTransparency = 1
3641 imageButton.Size = UDim2.new(0,30,0,30)
3642 imageButton.Position = UDim2.new(0,1,0,1)
3643 imageButton.Name = tostring(name)
3644 imageButton.Parent = buttonWrap
3645 imageButton.Image = materialToImageMap[name].Regular
3646
3647 local enumType = Instance.new("NumberValue")
3648 enumType.Name = "EnumType"
3649 enumType.Parent = buttonWrap
3650 enumType.Value = 0
3651
3652 imageButton.MouseEnter:connect(function()
3653 buttonWrap.BackgroundTransparency = 0
3654 end)
3655 imageButton.MouseLeave:connect(function()
3656 if selectedButton ~= buttonWrap then
3657 buttonWrap.BackgroundTransparency = 1
3658 end
3659 end)
3660 imageButton.MouseButton1Click:connect(function()
3661 if selectedButton ~= buttonWrap then
3662 goToNewMaterial(buttonWrap, tostring(name))
3663 end
3664 end)
3665
3666 return buttonWrap
3667 end
3668
3669 for i = 1, #materialNames do
3670 local imageButton = createMaterialButton(materialNames[i])
3671
3672 if materialNames[i] == "Grass" then -- always start with grass as the default
3673 selectedButton = imageButton
3674 imageButton.BackgroundTransparency = 0
3675 end
3676
3677 imageButton.Parent = scrollFrame
3678 end
3679
3680 local forceTerrainMaterialSelection = function(newMaterialType)
3681 if not newMaterialType then return end
3682 if currentMaterial == newMaterialType then return end
3683
3684 local matName = getNameFromEnum(newMaterialType)
3685 local buttons = scrollFrame:GetChildren()
3686 for i = 1, #buttons do
3687 if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end
3688 if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end
3689 if string.find(buttons[i].Name, matName) then
3690 goToNewMaterial(buttons[i],matName)
3691 return
3692 end
3693 end
3694 end
3695
3696 frame.Changed:connect(function ( prop )
3697 if prop == "AbsoluteSize" then
3698 recalculateScroll()
3699 end
3700 end)
3701
3702 recalculateScroll()
3703 return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
3704end
3705
3706t.CreateLoadingFrame = function(name,size,position)
3707 game:GetService("ContentProvider"):Preload("https://www.roblox.com/asset/?id=35238053")
3708
3709 local loadingFrame = Instance.new("Frame")
3710 loadingFrame.Name = "LoadingFrame"
3711 loadingFrame.Style = Enum.FrameStyle.RobloxRound
3712
3713 if size then loadingFrame.Size = size
3714 else loadingFrame.Size = UDim2.new(0,300,0,160) end
3715 if position then loadingFrame.Position = position
3716 else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
3717
3718 local loadingBar = Instance.new("Frame")
3719 loadingBar.Name = "LoadingBar"
3720 loadingBar.BackgroundColor3 = Color3.new(0,0,0)
3721 loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
3722 loadingBar.Position = UDim2.new(0,0,0,41)
3723 loadingBar.Size = UDim2.new(1,0,0,30)
3724 loadingBar.Parent = loadingFrame
3725
3726 local loadingGreenBar = Instance.new("ImageLabel")
3727 loadingGreenBar.Name = "LoadingGreenBar"
3728 loadingGreenBar.Image = "https://www.roblox.com/asset/?id=35238053"
3729 loadingGreenBar.Position = UDim2.new(0,0,0,0)
3730 loadingGreenBar.Size = UDim2.new(0,0,1,0)
3731 loadingGreenBar.Visible = false
3732 loadingGreenBar.Parent = loadingBar
3733
3734 local loadingPercent = Instance.new("TextLabel")
3735 loadingPercent.Name = "LoadingPercent"
3736 loadingPercent.BackgroundTransparency = 1
3737 loadingPercent.Position = UDim2.new(0,0,1,0)
3738 loadingPercent.Size = UDim2.new(1,0,0,14)
3739 loadingPercent.Font = Enum.Font.Arial
3740 loadingPercent.Text = "0%"
3741 loadingPercent.FontSize = Enum.FontSize.Size14
3742 loadingPercent.TextColor3 = Color3.new(1,1,1)
3743 loadingPercent.Parent = loadingBar
3744
3745 local cancelButton = Instance.new("TextButton")
3746 cancelButton.Name = "CancelButton"
3747 cancelButton.Position = UDim2.new(0.5,-60,1,-40)
3748 cancelButton.Size = UDim2.new(0,120,0,40)
3749 cancelButton.Font = Enum.Font.Arial
3750 cancelButton.FontSize = Enum.FontSize.Size18
3751 cancelButton.TextColor3 = Color3.new(1,1,1)
3752 cancelButton.Text = "Cancel"
3753 cancelButton.Style = Enum.ButtonStyle.RobloxButton
3754 cancelButton.Parent = loadingFrame
3755
3756 local loadingName = Instance.new("TextLabel")
3757 loadingName.Name = "loadingName"
3758 loadingName.BackgroundTransparency = 1
3759 loadingName.Size = UDim2.new(1,0,0,18)
3760 loadingName.Position = UDim2.new(0,0,0,2)
3761 loadingName.Font = Enum.Font.Arial
3762 loadingName.Text = name
3763 loadingName.TextColor3 = Color3.new(1,1,1)
3764 loadingName.TextStrokeTransparency = 1
3765 loadingName.FontSize = Enum.FontSize.Size18
3766 loadingName.Parent = loadingFrame
3767
3768 local cancelButtonClicked = Instance.new("BindableEvent")
3769 cancelButtonClicked.Name = "CancelButtonClicked"
3770 cancelButtonClicked.Parent = cancelButton
3771 cancelButton.MouseButton1Click:connect(function()
3772 cancelButtonClicked:Fire()
3773 end)
3774
3775 local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
3776 if percent and type(percent) ~= "number" then
3777 error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead")
3778 end
3779
3780 local newSize = nil
3781 if percent < 0 then
3782 newSize = UDim2.new(0,0,1,0)
3783 elseif percent > 1 then
3784 newSize = UDim2.new(1,0,1,0)
3785 else
3786 newSize = UDim2.new(percent,0,1,0)
3787 end
3788
3789 if tweenAction then
3790 if not tweenLength then
3791 error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument")
3792 end
3793
3794 if (newSize.X.Scale > 0) then
3795 loadingGreenBar.Visible = true
3796 loadingGreenBar:TweenSize( newSize,
3797 Enum.EasingDirection.Out,
3798 Enum.EasingStyle.Quad,
3799 tweenLength,
3800 true)
3801 else
3802 loadingGreenBar:TweenSize( newSize,
3803 Enum.EasingDirection.Out,
3804 Enum.EasingStyle.Quad,
3805 tweenLength,
3806 true,
3807 function()
3808 if (newSize.X.Scale < 0) then
3809 loadingGreenBar.Visible = false
3810 end
3811 end)
3812 end
3813
3814 else
3815 loadingGreenBar.Size = newSize
3816 loadingGreenBar.Visible = (newSize.X.Scale > 0)
3817 end
3818 end
3819
3820 loadingGreenBar.Changed:connect(function(prop)
3821 if prop == "Size" then
3822 loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%"
3823 end
3824 end)
3825
3826 return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
3827end
3828
3829t.CreatePluginFrame = function (name,size,position,scrollable,parent)
3830 local function createMenuButton(size,position,text,fontsize,name,parent)
3831 local button = Instance.new("TextButton",parent)
3832 button.AutoButtonColor = false
3833 button.Name = name
3834 button.BackgroundTransparency = 1
3835 button.Position = position
3836 button.Size = size
3837 button.Font = Enum.Font.ArialBold
3838 button.FontSize = fontsize
3839 button.Text = text
3840 button.TextColor3 = Color3.new(1,1,1)
3841 button.BorderSizePixel = 0
3842 button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
3843
3844 button.MouseEnter:connect(function ( )
3845 if button.Selected then return end
3846 button.BackgroundTransparency = 0
3847 end)
3848 button.MouseLeave:connect(function ( )
3849 if button.Selected then return end
3850 button.BackgroundTransparency = 1
3851 end)
3852
3853 return button
3854
3855 end
3856
3857 local dragBar = Instance.new("Frame",parent)
3858 dragBar.Name = tostring(name) .. "DragBar"
3859 dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
3860 dragBar.BorderColor3 = Color3.new(0,0,0)
3861 if size then
3862 dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
3863 else
3864 dragBar.Size = UDim2.new(0,183,0,20)
3865 end
3866 if position then
3867 dragBar.Position = position
3868 end
3869 dragBar.Active = true
3870 dragBar.Draggable = true
3871 --dragBar.Visible = false
3872 dragBar.MouseEnter:connect(function ( )
3873 dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
3874 end)
3875 dragBar.MouseLeave:connect(function ( )
3876 dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
3877 end)
3878
3879 -- plugin name label
3880 local pluginNameLabel = Instance.new("TextLabel",dragBar)
3881 pluginNameLabel.Name = "BarNameLabel"
3882 pluginNameLabel.Text = " " .. tostring(name)
3883 pluginNameLabel.TextColor3 = Color3.new(1,1,1)
3884 pluginNameLabel.TextStrokeTransparency = 0
3885 pluginNameLabel.Size = UDim2.new(1,0,1,0)
3886 pluginNameLabel.Font = Enum.Font.ArialBold
3887 pluginNameLabel.FontSize = Enum.FontSize.Size18
3888 pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
3889 pluginNameLabel.BackgroundTransparency = 1
3890
3891 -- close button
3892 local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar)
3893 local closeEvent = Instance.new("BindableEvent")
3894 closeEvent.Name = "CloseEvent"
3895 closeEvent.Parent = closeButton
3896 closeButton.MouseButton1Click:connect(function ()
3897 closeEvent:Fire()
3898 closeButton.BackgroundTransparency = 1
3899 end)
3900
3901 -- help button
3902 local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar)
3903 local helpFrame = Instance.new("Frame",dragBar)
3904 helpFrame.Name = "HelpFrame"
3905 helpFrame.BackgroundColor3 = Color3.new(0,0,0)
3906 helpFrame.Size = UDim2.new(0,300,0,552)
3907 helpFrame.Position = UDim2.new(1,5,0,0)
3908 helpFrame.Active = true
3909 helpFrame.BorderSizePixel = 0
3910 helpFrame.Visible = false
3911
3912 helpButton.MouseButton1Click:connect(function( )
3913 helpFrame.Visible = not helpFrame.Visible
3914 if helpFrame.Visible then
3915 helpButton.Selected = true
3916 helpButton.BackgroundTransparency = 0
3917 local screenGui = getLayerCollectorAncestor(helpFrame)
3918 if screenGui then
3919 if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side
3920 helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
3921 else -- position on right hand side
3922 helpFrame.Position = UDim2.new(1,5,0,0)
3923 end
3924 else
3925 helpFrame.Position = UDim2.new(1,5,0,0)
3926 end
3927 else
3928 helpButton.Selected = false
3929 helpButton.BackgroundTransparency = 1
3930 end
3931 end)
3932
3933 local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar)
3934 minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
3935
3936 local minimizeFrame = Instance.new("Frame",dragBar)
3937 minimizeFrame.Name = "MinimizeFrame"
3938 minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
3939 minimizeFrame.BorderColor3 = Color3.new(0,0,0)
3940 minimizeFrame.Position = UDim2.new(0,0,1,0)
3941 if size then
3942 minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
3943 else
3944 minimizeFrame.Size = UDim2.new(0,183,0,50)
3945 end
3946 minimizeFrame.Visible = false
3947
3948 local minimizeBigButton = Instance.new("TextButton",minimizeFrame)
3949 minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
3950 minimizeBigButton.Name = "MinimizeButton"
3951 minimizeBigButton.Size = UDim2.new(0,100,0,40)
3952 minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
3953 minimizeBigButton.Font = Enum.Font.ArialBold
3954 minimizeBigButton.FontSize = Enum.FontSize.Size18
3955 minimizeBigButton.TextColor3 = Color3.new(1,1,1)
3956 minimizeBigButton.Text = "Show"
3957
3958 local separatingLine = Instance.new("Frame",dragBar)
3959 separatingLine.Name = "SeparatingLine"
3960 separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
3961 separatingLine.BorderSizePixel = 0
3962 separatingLine.Position = UDim2.new(1,-18,0.5,-7)
3963 separatingLine.Size = UDim2.new(0,1,0,14)
3964
3965 local otherSeparatingLine = separatingLine:clone()
3966 otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
3967 otherSeparatingLine.Parent = dragBar
3968
3969 local widgetContainer = Instance.new("Frame",dragBar)
3970 widgetContainer.Name = "WidgetContainer"
3971 widgetContainer.BackgroundTransparency = 1
3972 widgetContainer.Position = UDim2.new(0,0,1,0)
3973 widgetContainer.BorderColor3 = Color3.new(0,0,0)
3974 if not scrollable then
3975 widgetContainer.BackgroundTransparency = 0
3976 widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
3977 end
3978
3979 if size then
3980 if scrollable then
3981 widgetContainer.Size = size
3982 else
3983 widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
3984 end
3985 else
3986 if scrollable then
3987 widgetContainer.Size = UDim2.new(0,163,0,400)
3988 else
3989 widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
3990 end
3991 end
3992 if position then
3993 widgetContainer.Position = position + UDim2.new(0,0,0,20)
3994 end
3995
3996 local frame,control,verticalDragger = nil
3997 if scrollable then
3998 --frame for widgets
3999 frame,control = t.CreateTrueScrollingFrame()
4000 frame.Size = UDim2.new(1, 0, 1, 0)
4001 frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
4002 frame.BorderColor3 = Color3.new(0,0,0)
4003 frame.Active = true
4004 frame.Parent = widgetContainer
4005 control.Parent = dragBar
4006 control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
4007 control.BorderSizePixel = 0
4008 control.BackgroundTransparency = 0
4009 control.Position = UDim2.new(1,-21,1,1)
4010 if size then
4011 control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
4012 else
4013 control.Size = UDim2.new(0,21,0,400)
4014 end
4015 control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20)
4016
4017 local fakeLine = Instance.new("Frame",control)
4018 fakeLine.Name = "FakeLine"
4019 fakeLine.BorderSizePixel = 0
4020 fakeLine.BackgroundColor3 = Color3.new(0,0,0)
4021 fakeLine.Size = UDim2.new(0,1,1,1)
4022 fakeLine.Position = UDim2.new(1,0,0,0)
4023
4024 verticalDragger = Instance.new("TextButton",widgetContainer)
4025 verticalDragger.ZIndex = 2
4026 verticalDragger.AutoButtonColor = false
4027 verticalDragger.Name = "VerticalDragger"
4028 verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
4029 verticalDragger.BorderColor3 = Color3.new(0,0,0)
4030 verticalDragger.Size = UDim2.new(1,20,0,20)
4031 verticalDragger.Position = UDim2.new(0,0,1,0)
4032 verticalDragger.Active = true
4033 verticalDragger.Text = ""
4034
4035 local scrubFrame = Instance.new("Frame",verticalDragger)
4036 scrubFrame.Name = "ScrubFrame"
4037 scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
4038 scrubFrame.BorderSizePixel = 0
4039 scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
4040 scrubFrame.Size = UDim2.new(0,10,0,1)
4041 scrubFrame.ZIndex = 5
4042 local scrubTwo = scrubFrame:clone()
4043 scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
4044 scrubTwo.Parent = verticalDragger
4045 local scrubThree = scrubFrame:clone()
4046 scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
4047 scrubThree.Parent = verticalDragger
4048
4049 local areaSoak = Instance.new("TextButton",getLayerCollectorAncestor(parent))
4050 areaSoak.Name = "AreaSoak"
4051 areaSoak.Size = UDim2.new(1,0,1,0)
4052 areaSoak.BackgroundTransparency = 1
4053 areaSoak.BorderSizePixel = 0
4054 areaSoak.Text = ""
4055 areaSoak.ZIndex = 10
4056 areaSoak.Visible = false
4057 areaSoak.Active = true
4058
4059 local draggingVertical = false
4060 local startYPos = nil
4061 verticalDragger.MouseEnter:connect(function ()
4062 verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
4063 end)
4064 verticalDragger.MouseLeave:connect(function ()
4065 verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
4066 end)
4067 verticalDragger.MouseButton1Down:connect(function(x,y)
4068 draggingVertical = true
4069 areaSoak.Visible = true
4070 startYPos = y
4071 end)
4072 areaSoak.MouseButton1Up:connect(function ( )
4073 draggingVertical = false
4074 areaSoak.Visible = false
4075 end)
4076 areaSoak.MouseMoved:connect(function(x,y)
4077 if not draggingVertical then return end
4078
4079 local yDelta = y - startYPos
4080 if not control.ScrollDownButton.Visible and yDelta > 0 then
4081 return
4082 end
4083
4084 if (widgetContainer.Size.Y.Offset + yDelta) < 150 then
4085 widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
4086 control.Size = UDim2.new (0,21,0,150)
4087 return
4088 end
4089
4090 startYPos = y
4091
4092 if widgetContainer.Size.Y.Offset + yDelta >= 0 then
4093 widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
4094 control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
4095 end
4096 end)
4097 end
4098
4099 local function switchMinimize()
4100 minimizeFrame.Visible = not minimizeFrame.Visible
4101 if scrollable then
4102 frame.Visible = not frame.Visible
4103 verticalDragger.Visible = not verticalDragger.Visible
4104 control.Visible = not control.Visible
4105 else
4106 widgetContainer.Visible = not widgetContainer.Visible
4107 end
4108
4109 if minimizeFrame.Visible then
4110 minimizeButton.Text = "+"
4111 else
4112 minimizeButton.Text = "-"
4113 end
4114 end
4115
4116 minimizeBigButton.MouseButton1Click:connect(function ( )
4117 switchMinimize()
4118 end)
4119
4120 minimizeButton.MouseButton1Click:connect(function( )
4121 switchMinimize()
4122 end)
4123
4124 if scrollable then
4125 return dragBar, frame, helpFrame, closeEvent
4126 else
4127 return dragBar, widgetContainer, helpFrame, closeEvent
4128 end
4129end
4130
4131t.Help =
4132 function(funcNameOrFunc)
4133 --input argument can be a string or a function. Should return a description (of arguments and expected side effects)
4134 if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then
4135 return "Function CreatePropertyDropDownMenu. " ..
4136 "Arguments: (instance, propertyName, enumType). " ..
4137 "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'"
4138 end
4139 if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then
4140 return "Function CreateDropDownMenu. " ..
4141 "Arguments: (items, onItemSelected). " ..
4142 "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"
4143 end
4144 if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then
4145 return "Function CreateMessageDialog. " ..
4146 "Arguments: (title, message, buttons). " ..
4147 "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"
4148 end
4149 if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then
4150 return "Function CreateStyledMessageDialog. " ..
4151 "Arguments: (title, message, style, buttons). " ..
4152 "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"
4153 end
4154 if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then
4155 return "Function GetFontHeight. " ..
4156 "Arguments: (font, fontSize). " ..
4157 "Side effect: returns the size in pixels of the given font + fontSize"
4158 end
4159 if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then
4160
4161 end
4162 if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then
4163 return "Function CreateScrollingFrame. " ..
4164 "Arguments: (orderList, style) " ..
4165 "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)"
4166 end
4167 if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then
4168 return "Function CreateTrueScrollingFrame. " ..
4169 "Arguments: (nil) " ..
4170 "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."
4171 end
4172 if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then
4173 return "Function AutoTruncateTextObject. " ..
4174 "Arguments: (textLabel) " ..
4175 "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"
4176 end
4177 if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then
4178 return "Function CreateSlider. " ..
4179 "Arguments: (steps, width, position) " ..
4180 "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."
4181 end
4182 if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then
4183 return "Function CreateSliderNew. " ..
4184 "Arguments: (steps, width, position) " ..
4185 "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."
4186 end
4187 if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then
4188 return "Function CreateLoadingFrame. " ..
4189 "Arguments: (name, size, position) " ..
4190 "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."
4191 end
4192 if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then
4193 return "Function CreateTerrainMaterialSelector. " ..
4194 "Arguments: (size, position) " ..
4195 "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."
4196 end
4197end
4198
4199return t
4200