· 5 years ago · Jul 13, 2020, 12:54 PM
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 = 2 + 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 + 2
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.BackgroundTransparency = 1
1071 bar.Image = "rbxasset://textures/ui/Slider-BKG-Center.png"
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,sliderBarImgHeight)
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 local barLeft = bar:clone()
1087 barLeft.Name = "BarLeft"
1088 barLeft.Image = "rbxasset://textures/ui/Slider-BKG-Left-Cap.png"
1089 barLeft.Size = UDim2.new(0, sliderBarCapImgWidth, 0, sliderBarImgHeight)
1090 barLeft.Position = UDim2.new(position.X.Scale, position.X.Offset - sliderBarCapImgWidth, position.Y.Scale, position.Y.Offset)
1091 barLeft.Parent = sliderGui
1092 barLeft.ZIndex = 3
1093
1094 local barRight = barLeft:clone()
1095 barRight.Name = "BarRight"
1096 barRight.Image = "rbxasset://textures/ui/Slider-BKG-Right-Cap.png"
1097 barRight.Position = UDim2.new(position.X.Scale, position.X.Offset + displayWidth, position.Y.Scale, position.Y.Offset)
1098 barRight.Parent = sliderGui
1099
1100 local fillLeft = barLeft:clone()
1101 fillLeft.Name = "FillLeft"
1102 fillLeft.Image = "rbxasset://textures/ui/Slider-Fill-Left-Cap.png"
1103 fillLeft.Parent = sliderGui
1104 fillLeft.ZIndex = 4
1105
1106 local fill = fillLeft:clone()
1107 fill.Name = "Fill"
1108 fill.Image = "rbxasset://textures/ui/Slider-Fill-Center.png"
1109 fill.Parent = bar
1110 fill.ZIndex = 4
1111 fill.Position = UDim2.new(0, 0, 0, 0)
1112 fill.Size = UDim2.new(0.5, 0, 1, 0)
1113
1114
1115-- bar.Visible = false
1116
1117 local slider = Instance.new("ImageButton")
1118 slider.Name = "Slider"
1119 slider.BackgroundTransparency = 1
1120 slider.Image = "rbxasset://textures/ui/slider_new_tab.png"
1121 slider.Position = UDim2.new(0,0,0.5,-14)
1122 slider.Size = UDim2.new(0,28,0,28)
1123 slider.ZIndex = 5
1124 slider.Parent = bar
1125
1126 local areaSoakMouseMoveCon = nil
1127
1128 areaSoak.MouseLeave:connect(function()
1129 if areaSoak.Visible then
1130 cancelSlide(areaSoak)
1131 end
1132 end)
1133 areaSoak.MouseButton1Up:connect(function()
1134 if areaSoak.Visible then
1135 cancelSlide(areaSoak)
1136 end
1137 end)
1138
1139 slider.MouseButton1Down:connect(function()
1140 areaSoak.Visible = true
1141 if areaSoakMouseMoveCon then areaSoakMouseMoveCon:disconnect() end
1142 areaSoakMouseMoveCon = areaSoak.MouseMoved:connect(function(x,y)
1143 setSliderPos(x,slider,sliderPosition,bar,steps)
1144 end)
1145 end)
1146
1147 slider.MouseButton1Up:connect(function() cancelSlide(areaSoak) end)
1148
1149 sliderPosition.Changed:connect(function(prop)
1150 sliderPosition.Value = math.min(steps, math.max(1,sliderPosition.Value))
1151 local relativePosX = (sliderPosition.Value - 1) / (steps - 1)
1152 slider.Position = UDim2.new(relativePosX,-slider.AbsoluteSize.X/2,slider.Position.Y.Scale,slider.Position.Y.Offset)
1153 fill.Size = UDim2.new(relativePosX, 0, 1, 0)
1154 end)
1155
1156 bar.MouseButton1Down:connect(function(x,y)
1157 setSliderPos(x,slider,sliderPosition,bar,steps)
1158 end)
1159
1160 fill.MouseButton1Down:connect(function(x,y)
1161 setSliderPos(x,slider,sliderPosition,bar,steps)
1162 end)
1163
1164 fillLeft.MouseButton1Down:connect(function(x,y)
1165 setSliderPos(x,slider,sliderPosition,bar,steps)
1166 end)
1167
1168
1169 return sliderGui, sliderPosition, sliderSteps
1170
1171end
1172
1173
1174
1175
1176
1177t.CreateTrueScrollingFrame = function()
1178 local lowY = nil
1179 local highY = nil
1180
1181 local dragCon = nil
1182 local upCon = nil
1183
1184 local internalChange = false
1185
1186 local descendantsChangeConMap = {}
1187
1188 local scrollingFrame = Instance.new("Frame")
1189 scrollingFrame.Name = "ScrollingFrame"
1190 scrollingFrame.Active = true
1191 scrollingFrame.Size = UDim2.new(1,0,1,0)
1192 scrollingFrame.ClipsDescendants = true
1193
1194 local controlFrame = Instance.new("Frame")
1195 controlFrame.Name = "ControlFrame"
1196 controlFrame.BackgroundTransparency = 1
1197 controlFrame.Size = UDim2.new(0,18,1,0)
1198 controlFrame.Position = UDim2.new(1,-20,0,0)
1199 controlFrame.Parent = scrollingFrame
1200
1201 local scrollBottom = Instance.new("BoolValue")
1202 scrollBottom.Value = false
1203 scrollBottom.Name = "ScrollBottom"
1204 scrollBottom.Parent = controlFrame
1205
1206 local scrollUp = Instance.new("BoolValue")
1207 scrollUp.Value = false
1208 scrollUp.Name = "scrollUp"
1209 scrollUp.Parent = controlFrame
1210
1211 local scrollUpButton = Instance.new("TextButton")
1212 scrollUpButton.Name = "ScrollUpButton"
1213 scrollUpButton.Text = ""
1214 scrollUpButton.AutoButtonColor = false
1215 scrollUpButton.BackgroundColor3 = Color3.new(0,0,0)
1216 scrollUpButton.BorderColor3 = Color3.new(1,1,1)
1217 scrollUpButton.BackgroundTransparency = 0.5
1218 scrollUpButton.Size = UDim2.new(0,18,0,18)
1219 scrollUpButton.ZIndex = 2
1220 scrollUpButton.Parent = controlFrame
1221 for i = 1, 6 do
1222 local triFrame = Instance.new("Frame")
1223 triFrame.BorderColor3 = Color3.new(1,1,1)
1224 triFrame.Name = "tri" .. tostring(i)
1225 triFrame.ZIndex = 3
1226 triFrame.BackgroundTransparency = 0.5
1227 triFrame.Size = UDim2.new(0,12 - ((i -1) * 2),0,0)
1228 triFrame.Position = UDim2.new(0,3 + (i -1),0.5,2 - (i -1))
1229 triFrame.Parent = scrollUpButton
1230 end
1231 scrollUpButton.MouseEnter:connect(function()
1232 scrollUpButton.BackgroundTransparency = 0.1
1233 local upChildren = scrollUpButton:GetChildren()
1234 for i = 1, #upChildren do
1235 upChildren[i].BackgroundTransparency = 0.1
1236 end
1237 end)
1238 scrollUpButton.MouseLeave:connect(function()
1239 scrollUpButton.BackgroundTransparency = 0.5
1240 local upChildren = scrollUpButton:GetChildren()
1241 for i = 1, #upChildren do
1242 upChildren[i].BackgroundTransparency = 0.5
1243 end
1244 end)
1245
1246 local scrollDownButton = scrollUpButton:clone()
1247 scrollDownButton.Name = "ScrollDownButton"
1248 scrollDownButton.Position = UDim2.new(0,0,1,-18)
1249 local downChildren = scrollDownButton:GetChildren()
1250 for i = 1, #downChildren do
1251 downChildren[i].Position = UDim2.new(0,3 + (i -1),0.5,-2 + (i - 1))
1252 end
1253 scrollDownButton.MouseEnter:connect(function()
1254 scrollDownButton.BackgroundTransparency = 0.1
1255 local downChildren = scrollDownButton:GetChildren()
1256 for i = 1, #downChildren do
1257 downChildren[i].BackgroundTransparency = 0.1
1258 end
1259 end)
1260 scrollDownButton.MouseLeave:connect(function()
1261 scrollDownButton.BackgroundTransparency = 0.5
1262 local downChildren = scrollDownButton:GetChildren()
1263 for i = 1, #downChildren do
1264 downChildren[i].BackgroundTransparency = 0.5
1265 end
1266 end)
1267 scrollDownButton.Parent = controlFrame
1268
1269 local scrollTrack = Instance.new("Frame")
1270 scrollTrack.Name = "ScrollTrack"
1271 scrollTrack.BackgroundTransparency = 1
1272 scrollTrack.Size = UDim2.new(0,18,1,-38)
1273 scrollTrack.Position = UDim2.new(0,0,0,19)
1274 scrollTrack.Parent = controlFrame
1275
1276 local scrollbar = Instance.new("TextButton")
1277 scrollbar.BackgroundColor3 = Color3.new(0,0,0)
1278 scrollbar.BorderColor3 = Color3.new(1,1,1)
1279 scrollbar.BackgroundTransparency = 0.5
1280 scrollbar.AutoButtonColor = false
1281 scrollbar.Text = ""
1282 scrollbar.Active = true
1283 scrollbar.Name = "ScrollBar"
1284 scrollbar.ZIndex = 2
1285 scrollbar.BackgroundTransparency = 0.5
1286 scrollbar.Size = UDim2.new(0, 18, 0.1, 0)
1287 scrollbar.Position = UDim2.new(0,0,0,0)
1288 scrollbar.Parent = scrollTrack
1289
1290 local scrollNub = Instance.new("Frame")
1291 scrollNub.Name = "ScrollNub"
1292 scrollNub.BorderColor3 = Color3.new(1,1,1)
1293 scrollNub.Size = UDim2.new(0,10,0,0)
1294 scrollNub.Position = UDim2.new(0.5,-5,0.5,0)
1295 scrollNub.ZIndex = 2
1296 scrollNub.BackgroundTransparency = 0.5
1297 scrollNub.Parent = scrollbar
1298
1299 local newNub = scrollNub:clone()
1300 newNub.Position = UDim2.new(0.5,-5,0.5,-2)
1301 newNub.Parent = scrollbar
1302
1303 local lastNub = scrollNub:clone()
1304 lastNub.Position = UDim2.new(0.5,-5,0.5,2)
1305 lastNub.Parent = scrollbar
1306
1307 scrollbar.MouseEnter:connect(function()
1308 scrollbar.BackgroundTransparency = 0.1
1309 scrollNub.BackgroundTransparency = 0.1
1310 newNub.BackgroundTransparency = 0.1
1311 lastNub.BackgroundTransparency = 0.1
1312 end)
1313 scrollbar.MouseLeave:connect(function()
1314 scrollbar.BackgroundTransparency = 0.5
1315 scrollNub.BackgroundTransparency = 0.5
1316 newNub.BackgroundTransparency = 0.5
1317 lastNub.BackgroundTransparency = 0.5
1318 end)
1319
1320 local mouseDrag = Instance.new("ImageButton")
1321 mouseDrag.Active = false
1322 mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
1323 mouseDrag.AutoButtonColor = false
1324 mouseDrag.BackgroundTransparency = 1
1325 mouseDrag.Name = "mouseDrag"
1326 mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
1327 mouseDrag.ZIndex = 10
1328
1329 local function positionScrollBar(x,y,offset)
1330 local oldPos = scrollbar.Position
1331
1332 if y < scrollTrack.AbsolutePosition.y then
1333 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
1334 return (oldPos ~= scrollbar.Position)
1335 end
1336
1337 local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
1338
1339 if y > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
1340 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
1341 return (oldPos ~= scrollbar.Position)
1342 end
1343 local newScaleYPos = (y - scrollTrack.AbsolutePosition.y - offset)/scrollTrack.AbsoluteSize.y
1344 if newScaleYPos + relativeSize > 1 then
1345 newScaleYPos = 1 - relativeSize
1346 scrollBottom.Value = true
1347 scrollUp.Value = false
1348 elseif newScaleYPos <= 0 then
1349 newScaleYPos = 0
1350 scrollUp.Value = true
1351 scrollBottom.Value = false
1352 else
1353 scrollUp.Value = false
1354 scrollBottom.Value = false
1355 end
1356 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,newScaleYPos,0)
1357
1358 return (oldPos ~= scrollbar.Position)
1359 end
1360
1361 local function drillDownSetHighLow(instance)
1362 if not instance or not instance:IsA("GuiObject") then return end
1363 if instance == controlFrame then return end
1364 if instance:IsDescendantOf(controlFrame) then return end
1365 if not instance.Visible then return end
1366
1367 if lowY and lowY > instance.AbsolutePosition.Y then
1368 lowY = instance.AbsolutePosition.Y
1369 elseif not lowY then
1370 lowY = instance.AbsolutePosition.Y
1371 end
1372 if highY and highY < (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) then
1373 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1374 elseif not highY then
1375 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1376 end
1377 local children = instance:GetChildren()
1378 for i = 1, #children do
1379 drillDownSetHighLow(children[i])
1380 end
1381 end
1382
1383 local function resetHighLow()
1384 local firstChildren = scrollingFrame:GetChildren()
1385
1386 for i = 1, #firstChildren do
1387 drillDownSetHighLow(firstChildren[i])
1388 end
1389 end
1390
1391 local function recalculate()
1392 internalChange = true
1393
1394 local percentFrame = 0
1395 if scrollbar.Position.Y.Scale > 0 then
1396 if scrollbar.Visible then
1397 percentFrame = scrollbar.Position.Y.Scale/((scrollTrack.AbsoluteSize.Y - scrollbar.AbsoluteSize.Y)/scrollTrack.AbsoluteSize.Y)
1398 else
1399 percentFrame = 0
1400 end
1401 end
1402 if percentFrame > 0.99 then percentFrame = 1 end
1403
1404 local hiddenYAmount = (scrollingFrame.AbsoluteSize.Y - (highY - lowY)) * percentFrame
1405
1406 local guiChildren = scrollingFrame:GetChildren()
1407 for i = 1, #guiChildren do
1408 if guiChildren[i] ~= controlFrame then
1409 guiChildren[i].Position = UDim2.new(guiChildren[i].Position.X.Scale,guiChildren[i].Position.X.Offset,
1410 0, math.ceil(guiChildren[i].AbsolutePosition.Y) - math.ceil(lowY) + hiddenYAmount)
1411 end
1412 end
1413
1414 lowY = nil
1415 highY = nil
1416 resetHighLow()
1417 internalChange = false
1418 end
1419
1420 local function setSliderSizeAndPosition()
1421 if not highY or not lowY then return end
1422
1423 local totalYSpan = math.abs(highY - lowY)
1424 if totalYSpan == 0 then
1425 scrollbar.Visible = false
1426 scrollDownButton.Visible = false
1427 scrollUpButton.Visible = false
1428
1429 if dragCon then dragCon:disconnect() dragCon = nil end
1430 if upCon then upCon:disconnect() upCon = nil end
1431 return
1432 end
1433
1434 local percentShown = scrollingFrame.AbsoluteSize.Y/totalYSpan
1435 if percentShown >= 1 then
1436 scrollbar.Visible = false
1437 scrollDownButton.Visible = false
1438 scrollUpButton.Visible = false
1439 recalculate()
1440 else
1441 scrollbar.Visible = true
1442 scrollDownButton.Visible = true
1443 scrollUpButton.Visible = true
1444
1445 scrollbar.Size = UDim2.new(scrollbar.Size.X.Scale,scrollbar.Size.X.Offset,percentShown,0)
1446 end
1447
1448 local percentPosition = (scrollingFrame.AbsolutePosition.Y - lowY)/totalYSpan
1449 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,percentPosition,-scrollbar.AbsoluteSize.X/2)
1450
1451 if scrollbar.AbsolutePosition.y < scrollTrack.AbsolutePosition.y then
1452 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,0,0)
1453 end
1454
1455 if (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.Y) > (scrollTrack.AbsolutePosition.y + scrollTrack.AbsoluteSize.y) then
1456 local relativeSize = scrollbar.AbsoluteSize.Y/scrollTrack.AbsoluteSize.Y
1457 scrollbar.Position = UDim2.new(scrollbar.Position.X.Scale,scrollbar.Position.X.Offset,1 - relativeSize,0)
1458 end
1459 end
1460
1461 local buttonScrollAmountPixels = 7
1462 local reentrancyGuardScrollUp = false
1463 local function doScrollUp()
1464 if reentrancyGuardScrollUp then return end
1465
1466 reentrancyGuardScrollUp = true
1467 if positionScrollBar(0,scrollbar.AbsolutePosition.Y - buttonScrollAmountPixels,0) then
1468 recalculate()
1469 end
1470 reentrancyGuardScrollUp = false
1471 end
1472
1473 local reentrancyGuardScrollDown = false
1474 local function doScrollDown()
1475 if reentrancyGuardScrollDown then return end
1476
1477 reentrancyGuardScrollDown = true
1478 if positionScrollBar(0,scrollbar.AbsolutePosition.Y + buttonScrollAmountPixels,0) then
1479 recalculate()
1480 end
1481 reentrancyGuardScrollDown = false
1482 end
1483
1484 local function scrollUp(mouseYPos)
1485 if scrollUpButton.Active then
1486 scrollStamp = tick()
1487 local current = scrollStamp
1488 local upCon
1489 upCon = mouseDrag.MouseButton1Up:connect(function()
1490 scrollStamp = tick()
1491 mouseDrag.Parent = nil
1492 upCon:disconnect()
1493 end)
1494 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
1495 doScrollUp()
1496 wait(0.2)
1497 local t = tick()
1498 local w = 0.1
1499 while scrollStamp == current do
1500 doScrollUp()
1501 if mouseYPos and mouseYPos > scrollbar.AbsolutePosition.y then
1502 break
1503 end
1504 if not scrollUpButton.Active then break end
1505 if tick()-t > 5 then
1506 w = 0
1507 elseif tick()-t > 2 then
1508 w = 0.06
1509 end
1510 wait(w)
1511 end
1512 end
1513 end
1514
1515 local function scrollDown(mouseYPos)
1516 if scrollDownButton.Active then
1517 scrollStamp = tick()
1518 local current = scrollStamp
1519 local downCon
1520 downCon = mouseDrag.MouseButton1Up:connect(function()
1521 scrollStamp = tick()
1522 mouseDrag.Parent = nil
1523 downCon:disconnect()
1524 end)
1525 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
1526 doScrollDown()
1527 wait(0.2)
1528 local t = tick()
1529 local w = 0.1
1530 while scrollStamp == current do
1531 doScrollDown()
1532 if mouseYPos and mouseYPos < (scrollbar.AbsolutePosition.y + scrollbar.AbsoluteSize.x) then
1533 break
1534 end
1535 if not scrollDownButton.Active then break end
1536 if tick()-t > 5 then
1537 w = 0
1538 elseif tick()-t > 2 then
1539 w = 0.06
1540 end
1541 wait(w)
1542 end
1543 end
1544 end
1545
1546 scrollbar.MouseButton1Down:connect(function(x,y)
1547 if scrollbar.Active then
1548 scrollStamp = tick()
1549 local mouseOffset = y - scrollbar.AbsolutePosition.y
1550 if dragCon then dragCon:disconnect() dragCon = nil end
1551 if upCon then upCon:disconnect() upCon = nil end
1552 local prevY = y
1553 local reentrancyGuardMouseScroll = false
1554 dragCon = mouseDrag.MouseMoved:connect(function(x,y)
1555 if reentrancyGuardMouseScroll then return end
1556
1557 reentrancyGuardMouseScroll = true
1558 if positionScrollBar(x,y,mouseOffset) then
1559 recalculate()
1560 end
1561 reentrancyGuardMouseScroll = false
1562
1563 end)
1564 upCon = mouseDrag.MouseButton1Up:connect(function()
1565 scrollStamp = tick()
1566 mouseDrag.Parent = nil
1567 dragCon:disconnect(); dragCon = nil
1568 upCon:disconnect(); drag = nil
1569 end)
1570 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
1571 end
1572 end)
1573
1574 local scrollMouseCount = 0
1575
1576 scrollUpButton.MouseButton1Down:connect(function()
1577 scrollUp()
1578 end)
1579 scrollUpButton.MouseButton1Up:connect(function()
1580 scrollStamp = tick()
1581 end)
1582
1583 scrollDownButton.MouseButton1Up:connect(function()
1584 scrollStamp = tick()
1585 end)
1586 scrollDownButton.MouseButton1Down:connect(function()
1587 scrollDown()
1588 end)
1589
1590 scrollbar.MouseButton1Up:connect(function()
1591 scrollStamp = tick()
1592 end)
1593
1594 local function heightCheck(instance)
1595 if highY and (instance.AbsolutePosition.Y + instance.AbsoluteSize.Y) > highY then
1596 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1597 elseif not highY then
1598 highY = instance.AbsolutePosition.Y + instance.AbsoluteSize.Y
1599 end
1600 setSliderSizeAndPosition()
1601 end
1602
1603 local function highLowRecheck()
1604 local oldLowY = lowY
1605 local oldHighY = highY
1606 lowY = nil
1607 highY = nil
1608 resetHighLow()
1609
1610 if (lowY ~= oldLowY) or (highY ~= oldHighY) then
1611 setSliderSizeAndPosition()
1612 end
1613 end
1614
1615 local function descendantChanged(this, prop)
1616 if internalChange then return end
1617 if not this.Visible then return end
1618
1619 if prop == "Size" or prop == "Position" then
1620 wait()
1621 highLowRecheck()
1622 end
1623 end
1624
1625 scrollingFrame.DescendantAdded:connect(function(instance)
1626 if not instance:IsA("GuiObject") then return end
1627
1628 if instance.Visible then
1629 wait() -- wait a heartbeat for sizes to reconfig
1630 highLowRecheck()
1631 end
1632
1633 descendantsChangeConMap[instance] = instance.Changed:connect(function(prop) descendantChanged(instance, prop) end)
1634 end)
1635
1636 scrollingFrame.DescendantRemoving:connect(function(instance)
1637 if not instance:IsA("GuiObject") then return end
1638 if descendantsChangeConMap[instance] then
1639 descendantsChangeConMap[instance]:disconnect()
1640 descendantsChangeConMap[instance] = nil
1641 end
1642 wait() -- wait a heartbeat for sizes to reconfig
1643 highLowRecheck()
1644 end)
1645
1646 scrollingFrame.Changed:connect(function(prop)
1647 if prop == "AbsoluteSize" then
1648 if not highY or not lowY then return end
1649
1650 highLowRecheck()
1651 setSliderSizeAndPosition()
1652 end
1653 end)
1654
1655 return scrollingFrame, controlFrame
1656end
1657
1658t.CreateScrollingFrame = function(orderList,scrollStyle)
1659 local frame = Instance.new("Frame")
1660 frame.Name = "ScrollingFrame"
1661 frame.BackgroundTransparency = 1
1662 frame.Size = UDim2.new(1,0,1,0)
1663
1664 local scrollUpButton = Instance.new("ImageButton")
1665 scrollUpButton.Name = "ScrollUpButton"
1666 scrollUpButton.BackgroundTransparency = 1
1667 scrollUpButton.Image = "rbxasset://textures/ui/scrollbuttonUp.png"
1668 scrollUpButton.Size = UDim2.new(0,17,0,17)
1669
1670
1671 local scrollDownButton = Instance.new("ImageButton")
1672 scrollDownButton.Name = "ScrollDownButton"
1673 scrollDownButton.BackgroundTransparency = 1
1674 scrollDownButton.Image = "rbxasset://textures/ui/scrollbuttonDown.png"
1675 scrollDownButton.Size = UDim2.new(0,17,0,17)
1676
1677 local scrollbar = Instance.new("ImageButton")
1678 scrollbar.Name = "ScrollBar"
1679 scrollbar.Image = "rbxasset://textures/ui/scrollbar.png"
1680 scrollbar.BackgroundTransparency = 1
1681 scrollbar.Size = UDim2.new(0, 18, 0, 150)
1682
1683 local scrollStamp = 0
1684
1685 local scrollDrag = Instance.new("ImageButton")
1686 scrollDrag.Image = "https://www.roblox.com/asset/?id=61367186"
1687 scrollDrag.Size = UDim2.new(1, 0, 0, 16)
1688 scrollDrag.BackgroundTransparency = 1
1689 scrollDrag.Name = "ScrollDrag"
1690 scrollDrag.Active = true
1691 scrollDrag.Parent = scrollbar
1692
1693 local mouseDrag = Instance.new("ImageButton")
1694 mouseDrag.Active = false
1695 mouseDrag.Size = UDim2.new(1.5, 0, 1.5, 0)
1696 mouseDrag.AutoButtonColor = false
1697 mouseDrag.BackgroundTransparency = 1
1698 mouseDrag.Name = "mouseDrag"
1699 mouseDrag.Position = UDim2.new(-0.25, 0, -0.25, 0)
1700 mouseDrag.ZIndex = 10
1701
1702 local style = "simple"
1703 if scrollStyle and tostring(scrollStyle) then
1704 style = scrollStyle
1705 end
1706
1707 local scrollPosition = 1
1708 local rowSize = 0
1709 local howManyDisplayed = 0
1710
1711 local layoutGridScrollBar = function()
1712 howManyDisplayed = 0
1713 local guiObjects = {}
1714 if orderList then
1715 for i, child in ipairs(orderList) do
1716 if child.Parent == frame then
1717 table.insert(guiObjects, child)
1718 end
1719 end
1720 else
1721 local children = frame:GetChildren()
1722 if children then
1723 for i, child in ipairs(children) do
1724 if child:IsA("GuiObject") then
1725 table.insert(guiObjects, child)
1726 end
1727 end
1728 end
1729 end
1730 if #guiObjects == 0 then
1731 scrollUpButton.Active = false
1732 scrollDownButton.Active = false
1733 scrollDrag.Active = false
1734 scrollPosition = 1
1735 return
1736 end
1737
1738 if scrollPosition > #guiObjects then
1739 scrollPosition = #guiObjects
1740 end
1741
1742 if scrollPosition < 1 then scrollPosition = 1 end
1743
1744 local totalPixelsY = frame.AbsoluteSize.Y
1745 local pixelsRemainingY = frame.AbsoluteSize.Y
1746
1747 local totalPixelsX = frame.AbsoluteSize.X
1748
1749 local xCounter = 0
1750 local rowSizeCounter = 0
1751 local setRowSize = true
1752
1753 local pixelsBelowScrollbar = 0
1754 local pos = #guiObjects
1755
1756 local currentRowY = 0
1757
1758 pos = scrollPosition
1759 --count up from current scroll position to fill out grid
1760 while pos <= #guiObjects and pixelsBelowScrollbar < totalPixelsY do
1761 xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
1762 --previous pos was the end of a row
1763 if xCounter >= totalPixelsX then
1764 pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
1765 currentRowY = 0
1766 xCounter = guiObjects[pos].AbsoluteSize.X
1767 end
1768 if guiObjects[pos].AbsoluteSize.Y > currentRowY then
1769 currentRowY = guiObjects[pos].AbsoluteSize.Y
1770 end
1771 pos = pos + 1
1772 end
1773 --Count wherever current row left off
1774 pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
1775 currentRowY = 0
1776
1777 pos = scrollPosition - 1
1778 xCounter = 0
1779
1780 --objects with varying X,Y dimensions can rarely cause minor errors
1781 --rechecking every new scrollPosition is necessary to avoid 100% of errors
1782
1783 --count backwards from current scrollPosition to see if we can add more rows
1784 while pixelsBelowScrollbar + currentRowY < totalPixelsY and pos >= 1 do
1785 xCounter = xCounter + guiObjects[pos].AbsoluteSize.X
1786 rowSizeCounter = rowSizeCounter + 1
1787 if xCounter >= totalPixelsX then
1788 rowSize = rowSizeCounter - 1
1789 rowSizeCounter = 0
1790 xCounter = guiObjects[pos].AbsoluteSize.X
1791 if pixelsBelowScrollbar + currentRowY <= totalPixelsY then
1792 --It fits, so back up our scroll position
1793 pixelsBelowScrollbar = pixelsBelowScrollbar + currentRowY
1794 if scrollPosition <= rowSize then
1795 scrollPosition = 1
1796 break
1797 else
1798 scrollPosition = scrollPosition - rowSize
1799 end
1800 currentRowY = 0
1801 else
1802 break
1803 end
1804 end
1805
1806 if guiObjects[pos].AbsoluteSize.Y > currentRowY then
1807 currentRowY = guiObjects[pos].AbsoluteSize.Y
1808 end
1809
1810 pos = pos - 1
1811 end
1812
1813 --Do check last time if pos = 0
1814 if (pos == 0) and (pixelsBelowScrollbar + currentRowY <= totalPixelsY) then
1815 scrollPosition = 1
1816 end
1817
1818 xCounter = 0
1819 --pos = scrollPosition
1820 rowSizeCounter = 0
1821 setRowSize = true
1822 local lastChildSize = 0
1823
1824 local xOffset,yOffset = 0
1825 if guiObjects[1] then
1826 yOffset = math.ceil(math.floor(math.fmod(totalPixelsY,guiObjects[1].AbsoluteSize.X))/2)
1827 xOffset = math.ceil(math.floor(math.fmod(totalPixelsX,guiObjects[1].AbsoluteSize.Y))/2)
1828 end
1829
1830 for i, child in ipairs(guiObjects) do
1831 if i < scrollPosition then
1832 --print("Hiding " .. child.Name)
1833 child.Visible = false
1834 else
1835 if pixelsRemainingY < 0 then
1836 --print("Out of Space " .. child.Name)
1837 child.Visible = false
1838 else
1839 --print("Laying out " .. child.Name)
1840 --GuiObject
1841 if setRowSize then rowSizeCounter = rowSizeCounter + 1 end
1842 if xCounter + child.AbsoluteSize.X >= totalPixelsX then
1843 if setRowSize then
1844 rowSize = rowSizeCounter - 1
1845 setRowSize = false
1846 end
1847 xCounter = 0
1848 pixelsRemainingY = pixelsRemainingY - child.AbsoluteSize.Y
1849 end
1850 child.Position = UDim2.new(child.Position.X.Scale,xCounter + xOffset, 0, totalPixelsY - pixelsRemainingY + yOffset)
1851 xCounter = xCounter + child.AbsoluteSize.X
1852 child.Visible = ((pixelsRemainingY - child.AbsoluteSize.Y) >= 0)
1853 if child.Visible then
1854 howManyDisplayed = howManyDisplayed + 1
1855 end
1856 lastChildSize = child.AbsoluteSize
1857 end
1858 end
1859 end
1860
1861 scrollUpButton.Active = (scrollPosition > 1)
1862 if lastChildSize == 0 then
1863 scrollDownButton.Active = false
1864 else
1865 scrollDownButton.Active = ((pixelsRemainingY - lastChildSize.Y) < 0)
1866 end
1867 scrollDrag.Active = #guiObjects > howManyDisplayed
1868 scrollDrag.Visible = scrollDrag.Active
1869 end
1870
1871
1872
1873 local layoutSimpleScrollBar = function()
1874 local guiObjects = {}
1875 howManyDisplayed = 0
1876
1877 if orderList then
1878 for i, child in ipairs(orderList) do
1879 if child.Parent == frame then
1880 table.insert(guiObjects, child)
1881 end
1882 end
1883 else
1884 local children = frame:GetChildren()
1885 if children then
1886 for i, child in ipairs(children) do
1887 if child:IsA("GuiObject") then
1888 table.insert(guiObjects, child)
1889 end
1890 end
1891 end
1892 end
1893 if #guiObjects == 0 then
1894 scrollUpButton.Active = false
1895 scrollDownButton.Active = false
1896 scrollDrag.Active = false
1897 scrollPosition = 1
1898 return
1899 end
1900
1901 if scrollPosition > #guiObjects then
1902 scrollPosition = #guiObjects
1903 end
1904
1905 local totalPixels = frame.AbsoluteSize.Y
1906 local pixelsRemaining = frame.AbsoluteSize.Y
1907
1908 local pixelsBelowScrollbar = 0
1909 local pos = #guiObjects
1910 while pixelsBelowScrollbar < totalPixels and pos >= 1 do
1911 if pos >= scrollPosition then
1912 pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
1913 else
1914 if pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y <= totalPixels then
1915 --It fits, so back up our scroll position
1916 pixelsBelowScrollbar = pixelsBelowScrollbar + guiObjects[pos].AbsoluteSize.Y
1917 if scrollPosition <= 1 then
1918 scrollPosition = 1
1919 break
1920 else
1921 --local ("Backing up ScrollPosition from -- " ..scrollPosition)
1922 scrollPosition = scrollPosition - 1
1923 end
1924 else
1925 break
1926 end
1927 end
1928 pos = pos - 1
1929 end
1930
1931 pos = scrollPosition
1932 for i, child in ipairs(guiObjects) do
1933 if i < scrollPosition then
1934 --print("Hiding " .. child.Name)
1935 child.Visible = false
1936 else
1937 if pixelsRemaining < 0 then
1938 --print("Out of Space " .. child.Name)
1939 child.Visible = false
1940 else
1941 --print("Laying out " .. child.Name)
1942 --GuiObject
1943 child.Position = UDim2.new(child.Position.X.Scale, child.Position.X.Offset, 0, totalPixels - pixelsRemaining)
1944 pixelsRemaining = pixelsRemaining - child.AbsoluteSize.Y
1945 if (pixelsRemaining >= 0) then
1946 child.Visible = true
1947 howManyDisplayed = howManyDisplayed + 1
1948 else
1949 child.Visible = false
1950 end
1951 end
1952 end
1953 end
1954 scrollUpButton.Active = (scrollPosition > 1)
1955 scrollDownButton.Active = (pixelsRemaining < 0)
1956 scrollDrag.Active = #guiObjects > howManyDisplayed
1957 scrollDrag.Visible = scrollDrag.Active
1958 end
1959
1960
1961 local moveDragger = function()
1962 local guiObjects = 0
1963 local children = frame:GetChildren()
1964 if children then
1965 for i, child in ipairs(children) do
1966 if child:IsA("GuiObject") then
1967 guiObjects = guiObjects + 1
1968 end
1969 end
1970 end
1971
1972 if not scrollDrag.Parent then return end
1973
1974 local dragSizeY = scrollDrag.Parent.AbsoluteSize.y * (1/(guiObjects - howManyDisplayed + 1))
1975 if dragSizeY < 16 then dragSizeY = 16 end
1976 scrollDrag.Size = UDim2.new(scrollDrag.Size.X.Scale,scrollDrag.Size.X.Offset,scrollDrag.Size.Y.Scale,dragSizeY)
1977
1978 local relativeYPos = (scrollPosition - 1)/(guiObjects - (howManyDisplayed))
1979 if relativeYPos > 1 then relativeYPos = 1
1980 elseif relativeYPos < 0 then relativeYPos = 0 end
1981 local absYPos = 0
1982
1983 if relativeYPos ~= 0 then
1984 absYPos = (relativeYPos * scrollbar.AbsoluteSize.y) - (relativeYPos * scrollDrag.AbsoluteSize.y)
1985 end
1986
1987 scrollDrag.Position = UDim2.new(scrollDrag.Position.X.Scale,scrollDrag.Position.X.Offset,scrollDrag.Position.Y.Scale,absYPos)
1988 end
1989
1990 local reentrancyGuard = false
1991 local recalculate = function()
1992 if reentrancyGuard then
1993 return
1994 end
1995 reentrancyGuard = true
1996 wait()
1997 local success, err = nil
1998 if style == "grid" then
1999 success, err = pcall(function() layoutGridScrollBar() end)
2000 elseif style == "simple" then
2001 success, err = pcall(function() layoutSimpleScrollBar() end)
2002 end
2003 if not success then print(err) end
2004 moveDragger()
2005 reentrancyGuard = false
2006 end
2007
2008 local doScrollUp = function()
2009 scrollPosition = (scrollPosition) - rowSize
2010 if scrollPosition < 1 then scrollPosition = 1 end
2011 recalculate(nil)
2012 end
2013
2014 local doScrollDown = function()
2015 scrollPosition = (scrollPosition) + rowSize
2016 recalculate(nil)
2017 end
2018
2019 local scrollUp = function(mouseYPos)
2020 if scrollUpButton.Active then
2021 scrollStamp = tick()
2022 local current = scrollStamp
2023 local upCon
2024 upCon = mouseDrag.MouseButton1Up:connect(function()
2025 scrollStamp = tick()
2026 mouseDrag.Parent = nil
2027 upCon:disconnect()
2028 end)
2029 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
2030 doScrollUp()
2031 wait(0.2)
2032 local t = tick()
2033 local w = 0.1
2034 while scrollStamp == current do
2035 doScrollUp()
2036 if mouseYPos and mouseYPos > scrollDrag.AbsolutePosition.y then
2037 break
2038 end
2039 if not scrollUpButton.Active then break end
2040 if tick()-t > 5 then
2041 w = 0
2042 elseif tick()-t > 2 then
2043 w = 0.06
2044 end
2045 wait(w)
2046 end
2047 end
2048 end
2049
2050 local scrollDown = function(mouseYPos)
2051 if scrollDownButton.Active then
2052 scrollStamp = tick()
2053 local current = scrollStamp
2054 local downCon
2055 downCon = mouseDrag.MouseButton1Up:connect(function()
2056 scrollStamp = tick()
2057 mouseDrag.Parent = nil
2058 downCon:disconnect()
2059 end)
2060 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
2061 doScrollDown()
2062 wait(0.2)
2063 local t = tick()
2064 local w = 0.1
2065 while scrollStamp == current do
2066 doScrollDown()
2067 if mouseYPos and mouseYPos < (scrollDrag.AbsolutePosition.y + scrollDrag.AbsoluteSize.x) then
2068 break
2069 end
2070 if not scrollDownButton.Active then break end
2071 if tick()-t > 5 then
2072 w = 0
2073 elseif tick()-t > 2 then
2074 w = 0.06
2075 end
2076 wait(w)
2077 end
2078 end
2079 end
2080
2081 local y = 0
2082 scrollDrag.MouseButton1Down:connect(function(x,y)
2083 if scrollDrag.Active then
2084 scrollStamp = tick()
2085 local mouseOffset = y - scrollDrag.AbsolutePosition.y
2086 local dragCon
2087 local upCon
2088 dragCon = mouseDrag.MouseMoved:connect(function(x,y)
2089 local barAbsPos = scrollbar.AbsolutePosition.y
2090 local barAbsSize = scrollbar.AbsoluteSize.y
2091
2092 local dragAbsSize = scrollDrag.AbsoluteSize.y
2093 local barAbsOne = barAbsPos + barAbsSize - dragAbsSize
2094 y = y - mouseOffset
2095 y = y < barAbsPos and barAbsPos or y > barAbsOne and barAbsOne or y
2096 y = y - barAbsPos
2097
2098 local guiObjects = 0
2099 local children = frame:GetChildren()
2100 if children then
2101 for i, child in ipairs(children) do
2102 if child:IsA("GuiObject") then
2103 guiObjects = guiObjects + 1
2104 end
2105 end
2106 end
2107
2108 local doublePercent = y/(barAbsSize-dragAbsSize)
2109 local rowDiff = rowSize
2110 local totalScrollCount = guiObjects - (howManyDisplayed - 1)
2111 local newScrollPosition = math.floor((doublePercent * totalScrollCount) + 0.5) + rowDiff
2112 if newScrollPosition < scrollPosition then
2113 rowDiff = -rowDiff
2114 end
2115
2116 if newScrollPosition < 1 then
2117 newScrollPosition = 1
2118 end
2119
2120 scrollPosition = newScrollPosition
2121 recalculate(nil)
2122 end)
2123 upCon = mouseDrag.MouseButton1Up:connect(function()
2124 scrollStamp = tick()
2125 mouseDrag.Parent = nil
2126 dragCon:disconnect(); dragCon = nil
2127 upCon:disconnect(); drag = nil
2128 end)
2129 mouseDrag.Parent = getLayerCollectorAncestor(scrollbar)
2130 end
2131 end)
2132
2133 local scrollMouseCount = 0
2134
2135 scrollUpButton.MouseButton1Down:connect(
2136 function()
2137 scrollUp()
2138 end)
2139 scrollUpButton.MouseButton1Up:connect(function()
2140 scrollStamp = tick()
2141 end)
2142
2143
2144 scrollDownButton.MouseButton1Up:connect(function()
2145 scrollStamp = tick()
2146 end)
2147 scrollDownButton.MouseButton1Down:connect(
2148 function()
2149 scrollDown()
2150 end)
2151
2152 scrollbar.MouseButton1Up:connect(function()
2153 scrollStamp = tick()
2154 end)
2155 scrollbar.MouseButton1Down:connect(
2156 function(x,y)
2157 if y > (scrollDrag.AbsoluteSize.y + scrollDrag.AbsolutePosition.y) then
2158 scrollDown(y)
2159 elseif y < (scrollDrag.AbsolutePosition.y) then
2160 scrollUp(y)
2161 end
2162 end)
2163
2164
2165 frame.ChildAdded:connect(function()
2166 recalculate(nil)
2167 end)
2168
2169 frame.ChildRemoved:connect(function()
2170 recalculate(nil)
2171 end)
2172
2173 frame.Changed:connect(
2174 function(prop)
2175 if prop == "AbsoluteSize" then
2176 --Wait a heartbeat for it to sync in
2177 recalculate(nil)
2178 end
2179 end)
2180 frame.AncestryChanged:connect(function() recalculate(nil) end)
2181
2182 return frame, scrollUpButton, scrollDownButton, recalculate, scrollbar
2183end
2184local function binaryGrow(min, max, fits)
2185 if min > max then
2186 return min
2187 end
2188 local biggestLegal = min
2189
2190 while min <= max do
2191 local mid = min + math.floor((max - min) / 2)
2192 if fits(mid) and (biggestLegal == nil or biggestLegal < mid) then
2193 biggestLegal = mid
2194
2195 --Try growing
2196 min = mid + 1
2197 else
2198 --Doesn't fit, shrink
2199 max = mid - 1
2200 end
2201 end
2202 return biggestLegal
2203end
2204
2205
2206local function binaryShrink(min, max, fits)
2207 if min > max then
2208 return min
2209 end
2210 local smallestLegal = max
2211
2212 while min <= max do
2213 local mid = min + math.floor((max - min) / 2)
2214 if fits(mid) and (smallestLegal == nil or smallestLegal > mid) then
2215 smallestLegal = mid
2216
2217 --It fits, shrink
2218 max = mid - 1
2219 else
2220 --Doesn't fit, grow
2221 min = mid + 1
2222 end
2223 end
2224 return smallestLegal
2225end
2226
2227
2228local function getGuiOwner(instance)
2229 while instance ~= nil do
2230 if instance:IsA("ScreenGui") or instance:IsA("BillboardGui") then
2231 return instance
2232 end
2233 instance = instance.Parent
2234 end
2235 return nil
2236end
2237
2238t.AutoTruncateTextObject = function(textLabel)
2239 local text = textLabel.Text
2240
2241 local fullLabel = textLabel:Clone()
2242 fullLabel.Name = "Full" .. textLabel.Name
2243 fullLabel.BorderSizePixel = 0
2244 fullLabel.BackgroundTransparency = 0
2245 fullLabel.Text = text
2246 fullLabel.TextXAlignment = Enum.TextXAlignment.Center
2247 fullLabel.Position = UDim2.new(0,-3,0,0)
2248 fullLabel.Size = UDim2.new(0,100,1,0)
2249 fullLabel.Visible = false
2250 fullLabel.Parent = textLabel
2251
2252 local shortText = nil
2253 local mouseEnterConnection = nil
2254 local mouseLeaveConnection= nil
2255
2256 local checkForResize = function()
2257 if getGuiOwner(textLabel) == nil then
2258 return
2259 end
2260 textLabel.Text = text
2261 if textLabel.TextFits then
2262 --Tear down the rollover if it is active
2263 if mouseEnterConnection then
2264 mouseEnterConnection:disconnect()
2265 mouseEnterConnection = nil
2266 end
2267 if mouseLeaveConnection then
2268 mouseLeaveConnection:disconnect()
2269 mouseLeaveConnection = nil
2270 end
2271 else
2272 local len = string.len(text)
2273 textLabel.Text = text .. "~"
2274
2275 --Shrink the text
2276 local textSize = binaryGrow(0, len,
2277 function(pos)
2278 if pos == 0 then
2279 textLabel.Text = "~"
2280 else
2281 textLabel.Text = string.sub(text, 1, pos) .. "~"
2282 end
2283 return textLabel.TextFits
2284 end)
2285 shortText = string.sub(text, 1, textSize) .. "~"
2286 textLabel.Text = shortText
2287
2288 --Make sure the fullLabel fits
2289 if not fullLabel.TextFits then
2290 --Already too small, grow it really bit to start
2291 fullLabel.Size = UDim2.new(0, 10000, 1, 0)
2292 end
2293
2294 --Okay, now try to binary shrink it back down
2295 local fullLabelSize = binaryShrink(textLabel.AbsoluteSize.X,fullLabel.AbsoluteSize.X,
2296 function(size)
2297 fullLabel.Size = UDim2.new(0, size, 1, 0)
2298 return fullLabel.TextFits
2299 end)
2300 fullLabel.Size = UDim2.new(0,fullLabelSize+6,1,0)
2301
2302 --Now setup the rollover effects, if they are currently off
2303 if mouseEnterConnection == nil then
2304 mouseEnterConnection = textLabel.MouseEnter:connect(
2305 function()
2306 fullLabel.ZIndex = textLabel.ZIndex + 1
2307 fullLabel.Visible = true
2308 --textLabel.Text = ""
2309 end)
2310 end
2311 if mouseLeaveConnection == nil then
2312 mouseLeaveConnection = textLabel.MouseLeave:connect(
2313 function()
2314 fullLabel.Visible = false
2315 --textLabel.Text = shortText
2316 end)
2317 end
2318 end
2319 end
2320 textLabel.AncestryChanged:connect(checkForResize)
2321 textLabel.Changed:connect(
2322 function(prop)
2323 if prop == "AbsoluteSize" then
2324 checkForResize()
2325 end
2326 end)
2327
2328 checkForResize()
2329
2330 local function changeText(newText)
2331 text = newText
2332 fullLabel.Text = text
2333 checkForResize()
2334 end
2335
2336 return textLabel, changeText
2337end
2338
2339local function TransitionTutorialPages(fromPage, toPage, transitionFrame, currentPageValue)
2340 if fromPage then
2341 fromPage.Visible = false
2342 if transitionFrame.Visible == false then
2343 transitionFrame.Size = fromPage.Size
2344 transitionFrame.Position = fromPage.Position
2345 end
2346 else
2347 if transitionFrame.Visible == false then
2348 transitionFrame.Size = UDim2.new(0.0,50,0.0,50)
2349 transitionFrame.Position = UDim2.new(0.5,-25,0.5,-25)
2350 end
2351 end
2352 transitionFrame.Visible = true
2353 currentPageValue.Value = nil
2354
2355 local newSize, newPosition
2356 if toPage then
2357 --Make it visible so it resizes
2358 toPage.Visible = true
2359
2360 newSize = toPage.Size
2361 newPosition = toPage.Position
2362
2363 toPage.Visible = false
2364 else
2365 newSize = UDim2.new(0.0,50,0.0,50)
2366 newPosition = UDim2.new(0.5,-25,0.5,-25)
2367 end
2368 transitionFrame:TweenSizeAndPosition(newSize, newPosition, Enum.EasingDirection.InOut, Enum.EasingStyle.Quad, 0.3, true,
2369 function(state)
2370 if state == Enum.TweenStatus.Completed then
2371 transitionFrame.Visible = false
2372 if toPage then
2373 toPage.Visible = true
2374 currentPageValue.Value = toPage
2375 end
2376 end
2377 end)
2378end
2379
2380t.CreateTutorial = function(name, tutorialKey, createButtons)
2381 local frame = Instance.new("Frame")
2382 frame.Name = "Tutorial-" .. name
2383 frame.BackgroundTransparency = 1
2384 frame.Size = UDim2.new(0.6, 0, 0.6, 0)
2385 frame.Position = UDim2.new(0.2, 0, 0.2, 0)
2386
2387 local transitionFrame = Instance.new("Frame")
2388 transitionFrame.Name = "TransitionFrame"
2389 transitionFrame.Style = Enum.FrameStyle.RobloxRound
2390 transitionFrame.Size = UDim2.new(0.6, 0, 0.6, 0)
2391 transitionFrame.Position = UDim2.new(0.2, 0, 0.2, 0)
2392 transitionFrame.Visible = false
2393 transitionFrame.Parent = frame
2394
2395 local currentPageValue = Instance.new("ObjectValue")
2396 currentPageValue.Name = "CurrentTutorialPage"
2397 currentPageValue.Value = nil
2398 currentPageValue.Parent = frame
2399
2400 local boolValue = Instance.new("BoolValue")
2401 boolValue.Name = "Buttons"
2402 boolValue.Value = createButtons
2403 boolValue.Parent = frame
2404
2405 local pages = Instance.new("Frame")
2406 pages.Name = "Pages"
2407 pages.BackgroundTransparency = 1
2408 pages.Size = UDim2.new(1,0,1,0)
2409 pages.Parent = frame
2410
2411 local function getVisiblePageAndHideOthers()
2412 local visiblePage = nil
2413 local children = pages:GetChildren()
2414 if children then
2415 for i,child in ipairs(children) do
2416 if child.Visible then
2417 if visiblePage then
2418 child.Visible = false
2419 else
2420 visiblePage = child
2421 end
2422 end
2423 end
2424 end
2425 return visiblePage
2426 end
2427
2428 local showTutorial = function(alwaysShow)
2429 if alwaysShow or UserSettings().GameSettings:GetTutorialState(tutorialKey) == false then
2430 print("Showing tutorial-",tutorialKey)
2431 local currentTutorialPage = getVisiblePageAndHideOthers()
2432
2433 local firstPage = pages:FindFirstChild("TutorialPage1")
2434 if firstPage then
2435 TransitionTutorialPages(currentTutorialPage, firstPage, transitionFrame, currentPageValue)
2436 else
2437 error("Could not find TutorialPage1")
2438 end
2439 end
2440 end
2441
2442 local dismissTutorial = function()
2443 local currentTutorialPage = getVisiblePageAndHideOthers()
2444
2445 if currentTutorialPage then
2446 TransitionTutorialPages(currentTutorialPage, nil, transitionFrame, currentPageValue)
2447 end
2448
2449 UserSettings().GameSettings:SetTutorialState(tutorialKey, true)
2450 end
2451
2452 local gotoPage = function(pageNum)
2453 local page = pages:FindFirstChild("TutorialPage" .. pageNum)
2454 local currentTutorialPage = getVisiblePageAndHideOthers()
2455 TransitionTutorialPages(currentTutorialPage, page, transitionFrame, currentPageValue)
2456 end
2457
2458 return frame, showTutorial, dismissTutorial, gotoPage
2459end
2460
2461local function CreateBasicTutorialPage(name, handleResize, skipTutorial, giveDoneButton)
2462 local frame = Instance.new("Frame")
2463 frame.Name = "TutorialPage"
2464 frame.Style = Enum.FrameStyle.RobloxRound
2465 frame.Size = UDim2.new(0.6, 0, 0.6, 0)
2466 frame.Position = UDim2.new(0.2, 0, 0.2, 0)
2467 frame.Visible = false
2468
2469 local frameHeader = Instance.new("TextLabel")
2470 frameHeader.Name = "Header"
2471 frameHeader.Text = name
2472 frameHeader.BackgroundTransparency = 1
2473 frameHeader.FontSize = Enum.FontSize.Size24
2474 frameHeader.Font = Enum.Font.ArialBold
2475 frameHeader.TextColor3 = Color3.new(1,1,1)
2476 frameHeader.TextXAlignment = Enum.TextXAlignment.Center
2477 frameHeader.TextWrap = true
2478 frameHeader.Size = UDim2.new(1,-55, 0, 22)
2479 frameHeader.Position = UDim2.new(0,0,0,0)
2480 frameHeader.Parent = frame
2481
2482 local skipButton = Instance.new("ImageButton")
2483 skipButton.Name = "SkipButton"
2484 skipButton.AutoButtonColor = false
2485 skipButton.BackgroundTransparency = 1
2486 skipButton.Image = "rbxasset://textures/ui/closeButton.png"
2487 skipButton.MouseButton1Click:connect(function()
2488 skipTutorial()
2489 end)
2490 skipButton.MouseEnter:connect(function()
2491 skipButton.Image = "rbxasset://textures/ui/closeButton_dn.png"
2492 end)
2493 skipButton.MouseLeave:connect(function()
2494 skipButton.Image = "rbxasset://textures/ui/closeButton.png"
2495 end)
2496 skipButton.Size = UDim2.new(0, 25, 0, 25)
2497 skipButton.Position = UDim2.new(1, -25, 0, 0)
2498 skipButton.Parent = frame
2499
2500
2501 if giveDoneButton then
2502 local doneButton = Instance.new("TextButton")
2503 doneButton.Name = "DoneButton"
2504 doneButton.Style = Enum.ButtonStyle.RobloxButtonDefault
2505 doneButton.Text = "Done"
2506 doneButton.TextColor3 = Color3.new(1,1,1)
2507 doneButton.Font = Enum.Font.ArialBold
2508 doneButton.FontSize = Enum.FontSize.Size18
2509 doneButton.Size = UDim2.new(0,100,0,50)
2510 doneButton.Position = UDim2.new(0.5,-50,1,-50)
2511
2512 if skipTutorial then
2513 doneButton.MouseButton1Click:connect(function() skipTutorial() end)
2514 end
2515
2516 doneButton.Parent = frame
2517 end
2518
2519 local innerFrame = Instance.new("Frame")
2520 innerFrame.Name = "ContentFrame"
2521 innerFrame.BackgroundTransparency = 1
2522 innerFrame.Position = UDim2.new(0,0,0,25)
2523 innerFrame.Parent = frame
2524
2525 local nextButton = Instance.new("TextButton")
2526 nextButton.Name = "NextButton"
2527 nextButton.Text = "Next"
2528 nextButton.TextColor3 = Color3.new(1,1,1)
2529 nextButton.Font = Enum.Font.Arial
2530 nextButton.FontSize = Enum.FontSize.Size18
2531 nextButton.Style = Enum.ButtonStyle.RobloxButtonDefault
2532 nextButton.Size = UDim2.new(0,80, 0, 32)
2533 nextButton.Position = UDim2.new(0.5, 5, 1, -32)
2534 nextButton.Active = false
2535 nextButton.Visible = false
2536 nextButton.Parent = frame
2537
2538 local prevButton = Instance.new("TextButton")
2539 prevButton.Name = "PrevButton"
2540 prevButton.Text = "Previous"
2541 prevButton.TextColor3 = Color3.new(1,1,1)
2542 prevButton.Font = Enum.Font.Arial
2543 prevButton.FontSize = Enum.FontSize.Size18
2544 prevButton.Style = Enum.ButtonStyle.RobloxButton
2545 prevButton.Size = UDim2.new(0,80, 0, 32)
2546 prevButton.Position = UDim2.new(0.5, -85, 1, -32)
2547 prevButton.Active = false
2548 prevButton.Visible = false
2549 prevButton.Parent = frame
2550
2551 if giveDoneButton then
2552 innerFrame.Size = UDim2.new(1,0,1,-75)
2553 else
2554 innerFrame.Size = UDim2.new(1,0,1,-22)
2555 end
2556
2557 local parentConnection = nil
2558
2559 local function basicHandleResize()
2560 if frame.Visible and frame.Parent then
2561 local maxSize = math.min(frame.Parent.AbsoluteSize.X, frame.Parent.AbsoluteSize.Y)
2562 handleResize(200,maxSize)
2563 end
2564 end
2565
2566 frame.Changed:connect(
2567 function(prop)
2568 if prop == "Parent" then
2569 if parentConnection ~= nil then
2570 parentConnection:disconnect()
2571 parentConnection = nil
2572 end
2573 if frame.Parent and frame.Parent:IsA("GuiObject") then
2574 parentConnection = frame.Parent.Changed:connect(
2575 function(parentProp)
2576 if parentProp == "AbsoluteSize" then
2577 wait()
2578 basicHandleResize()
2579 end
2580 end)
2581 basicHandleResize()
2582 end
2583 end
2584
2585 if prop == "Visible" then
2586 basicHandleResize()
2587 end
2588 end)
2589
2590 return frame, innerFrame
2591end
2592
2593t.CreateTextTutorialPage = function(name, text, skipTutorialFunc)
2594 local frame = nil
2595 local contentFrame = nil
2596
2597 local textLabel = Instance.new("TextLabel")
2598 textLabel.BackgroundTransparency = 1
2599 textLabel.TextColor3 = Color3.new(1,1,1)
2600 textLabel.Text = text
2601 textLabel.TextWrap = true
2602 textLabel.TextXAlignment = Enum.TextXAlignment.Left
2603 textLabel.TextYAlignment = Enum.TextYAlignment.Center
2604 textLabel.Font = Enum.Font.Arial
2605 textLabel.FontSize = Enum.FontSize.Size14
2606 textLabel.Size = UDim2.new(1,0,1,0)
2607
2608 local function handleResize(minSize, maxSize)
2609 size = binaryShrink(minSize, maxSize,
2610 function(size)
2611 frame.Size = UDim2.new(0, size, 0, size)
2612 return textLabel.TextFits
2613 end)
2614 frame.Size = UDim2.new(0, size, 0, size)
2615 frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
2616 end
2617
2618 frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc)
2619 textLabel.Parent = contentFrame
2620
2621 return frame
2622end
2623
2624t.CreateImageTutorialPage = function(name, imageAsset, x, y, skipTutorialFunc, giveDoneButton)
2625 local frame = nil
2626 local contentFrame = nil
2627
2628 local imageLabel = Instance.new("ImageLabel")
2629 imageLabel.BackgroundTransparency = 1
2630 imageLabel.Image = imageAsset
2631 imageLabel.Size = UDim2.new(0,x,0,y)
2632 imageLabel.Position = UDim2.new(0.5,-x/2,0.5,-y/2)
2633
2634 local function handleResize(minSize, maxSize)
2635 size = binaryShrink(minSize, maxSize,
2636 function(size)
2637 return size >= x and size >= y
2638 end)
2639 if size >= x and size >= y then
2640 imageLabel.Size = UDim2.new(0,x, 0,y)
2641 imageLabel.Position = UDim2.new(0.5,-x/2, 0.5, -y/2)
2642 else
2643 if x > y then
2644 --X is limiter, so
2645 imageLabel.Size = UDim2.new(1,0,y/x,0)
2646 imageLabel.Position = UDim2.new(0,0, 0.5 - (y/x)/2, 0)
2647 else
2648 --Y is limiter
2649 imageLabel.Size = UDim2.new(x/y,0,1, 0)
2650 imageLabel.Position = UDim2.new(0.5-(x/y)/2, 0, 0, 0)
2651 end
2652 end
2653 size = size + 50
2654 frame.Size = UDim2.new(0, size, 0, size)
2655 frame.Position = UDim2.new(0.5, -size/2, 0.5, -size/2)
2656 end
2657
2658 frame, contentFrame = CreateBasicTutorialPage(name, handleResize, skipTutorialFunc, giveDoneButton)
2659 imageLabel.Parent = contentFrame
2660
2661 return frame
2662end
2663
2664t.AddTutorialPage = function(tutorial, tutorialPage)
2665 local transitionFrame = tutorial.TransitionFrame
2666 local currentPageValue = tutorial.CurrentTutorialPage
2667
2668 if not tutorial.Buttons.Value then
2669 tutorialPage.NextButton.Parent = nil
2670 tutorialPage.PrevButton.Parent = nil
2671 end
2672
2673 local children = tutorial.Pages:GetChildren()
2674 if children and #children > 0 then
2675 tutorialPage.Name = "TutorialPage" .. (#children+1)
2676 local previousPage = children[#children]
2677 if not previousPage:IsA("GuiObject") then
2678 error("All elements under Pages must be GuiObjects")
2679 end
2680
2681 if tutorial.Buttons.Value then
2682 if previousPage.NextButton.Active then
2683 error("NextButton already Active on previousPage, please only add pages with RbxGui.AddTutorialPage function")
2684 end
2685 previousPage.NextButton.MouseButton1Click:connect(
2686 function()
2687 TransitionTutorialPages(previousPage, tutorialPage, transitionFrame, currentPageValue)
2688 end)
2689 previousPage.NextButton.Active = true
2690 previousPage.NextButton.Visible = true
2691
2692 if tutorialPage.PrevButton.Active then
2693 error("PrevButton already Active on tutorialPage, please only add pages with RbxGui.AddTutorialPage function")
2694 end
2695 tutorialPage.PrevButton.MouseButton1Click:connect(
2696 function()
2697 TransitionTutorialPages(tutorialPage, previousPage, transitionFrame, currentPageValue)
2698 end)
2699 tutorialPage.PrevButton.Active = true
2700 tutorialPage.PrevButton.Visible = true
2701 end
2702
2703 tutorialPage.Parent = tutorial.Pages
2704 else
2705 --First child
2706 tutorialPage.Name = "TutorialPage1"
2707 tutorialPage.Parent = tutorial.Pages
2708 end
2709end
2710
2711t.CreateSetPanel = function(userIdsForSets, objectSelected, dialogClosed, size, position, showAdminCategories, useAssetVersionId)
2712
2713 if not userIdsForSets then
2714 error("CreateSetPanel: userIdsForSets (first arg) is nil, should be a table of number ids")
2715 end
2716 if type(userIdsForSets) ~= "table" and type(userIdsForSets) ~= "userdata" then
2717 error("CreateSetPanel: userIdsForSets (first arg) is of type " ..type(userIdsForSets) .. ", should be of type table or userdata")
2718 end
2719 if not objectSelected then
2720 error("CreateSetPanel: objectSelected (second arg) is nil, should be a callback function!")
2721 end
2722 if type(objectSelected) ~= "function" then
2723 error("CreateSetPanel: objectSelected (second arg) is of type " .. type(objectSelected) .. ", should be of type function!")
2724 end
2725 if dialogClosed and type(dialogClosed) ~= "function" then
2726 error("CreateSetPanel: dialogClosed (third arg) is of type " .. type(dialogClosed) .. ", should be of type function!")
2727 end
2728
2729 if showAdminCategories == nil then -- by default, don't show beta sets
2730 showAdminCategories = false
2731 end
2732
2733 local arrayPosition = 1
2734 local insertButtons = {}
2735 local insertButtonCons = {}
2736 local contents = nil
2737 local setGui = nil
2738
2739 -- used for water selections
2740 local waterForceDirection = "NegX"
2741 local waterForce = "None"
2742 local waterGui, waterTypeChangedEvent = nil
2743
2744 local Data = {}
2745 Data.CurrentCategory = nil
2746 Data.Category = {}
2747 local SetCache = {}
2748
2749 local userCategoryButtons = nil
2750
2751 local buttonWidth = 64
2752 local buttonHeight = buttonWidth
2753
2754 local SmallThumbnailUrl = nil
2755 local LargeThumbnailUrl = nil
2756 local BaseUrl = game:GetService("ContentProvider").BaseUrl:lower()
2757 local AssetGameUrl = string.gsub(BaseUrl, "www", "assetgame")
2758
2759 if useAssetVersionId then
2760 LargeThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&assetversionid="
2761 SmallThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&assetversionid="
2762 else
2763 LargeThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=420&ht=420&aid="
2764 SmallThumbnailUrl = AssetGameUrl .. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
2765 end
2766
2767 local function drillDownSetZIndex(parent, index)
2768 local children = parent:GetChildren()
2769 for i = 1, #children do
2770 if children[i]:IsA("GuiObject") then
2771 children[i].ZIndex = index
2772 end
2773 drillDownSetZIndex(children[i], index)
2774 end
2775 end
2776
2777 -- for terrain stamping
2778 local currTerrainDropDownFrame = nil
2779 local terrainShapes = {"Block","Vertical Ramp","Corner Wedge","Inverse Corner Wedge","Horizontal Ramp","Auto-Wedge"}
2780 local terrainShapeMap = {}
2781 for i = 1, #terrainShapes do
2782 terrainShapeMap[terrainShapes[i]] = i - 1
2783 end
2784 terrainShapeMap[terrainShapes[#terrainShapes]] = 6
2785
2786 local function createWaterGui()
2787 local waterForceDirections = {"NegX","X","NegY","Y","NegZ","Z"}
2788 local waterForces = {"None", "Small", "Medium", "Strong", "Max"}
2789
2790 local waterFrame = Instance.new("Frame")
2791 waterFrame.Name = "WaterFrame"
2792 waterFrame.Style = Enum.FrameStyle.RobloxSquare
2793 waterFrame.Size = UDim2.new(0,150,0,110)
2794 waterFrame.Visible = false
2795
2796 local waterForceLabel = Instance.new("TextLabel")
2797 waterForceLabel.Name = "WaterForceLabel"
2798 waterForceLabel.BackgroundTransparency = 1
2799 waterForceLabel.Size = UDim2.new(1,0,0,12)
2800 waterForceLabel.Font = Enum.Font.ArialBold
2801 waterForceLabel.FontSize = Enum.FontSize.Size12
2802 waterForceLabel.TextColor3 = Color3.new(1,1,1)
2803 waterForceLabel.TextXAlignment = Enum.TextXAlignment.Left
2804 waterForceLabel.Text = "Water Force"
2805 waterForceLabel.Parent = waterFrame
2806
2807 local waterForceDirLabel = waterForceLabel:Clone()
2808 waterForceDirLabel.Name = "WaterForceDirectionLabel"
2809 waterForceDirLabel.Text = "Water Force Direction"
2810 waterForceDirLabel.Position = UDim2.new(0,0,0,50)
2811 waterForceDirLabel.Parent = waterFrame
2812
2813 local waterTypeChangedEvent = Instance.new("BindableEvent",waterFrame)
2814 waterTypeChangedEvent.Name = "WaterTypeChangedEvent"
2815
2816 local waterForceDirectionSelectedFunc = function(newForceDirection)
2817 waterForceDirection = newForceDirection
2818 waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
2819 end
2820 local waterForceSelectedFunc = function(newForce)
2821 waterForce = newForce
2822 waterTypeChangedEvent:Fire({waterForce, waterForceDirection})
2823 end
2824
2825 local waterForceDirectionDropDown, forceWaterDirectionSelection = t.CreateDropDownMenu(waterForceDirections, waterForceDirectionSelectedFunc)
2826 waterForceDirectionDropDown.Size = UDim2.new(1,0,0,25)
2827 waterForceDirectionDropDown.Position = UDim2.new(0,0,1,3)
2828 forceWaterDirectionSelection("NegX")
2829 waterForceDirectionDropDown.Parent = waterForceDirLabel
2830
2831 local waterForceDropDown, forceWaterForceSelection = t.CreateDropDownMenu(waterForces, waterForceSelectedFunc)
2832 forceWaterForceSelection("None")
2833 waterForceDropDown.Size = UDim2.new(1,0,0,25)
2834 waterForceDropDown.Position = UDim2.new(0,0,1,3)
2835 waterForceDropDown.Parent = waterForceLabel
2836
2837 return waterFrame, waterTypeChangedEvent
2838 end
2839
2840 -- Helper Function that contructs gui elements
2841 local function createSetGui()
2842
2843 local setGui = Instance.new("ScreenGui")
2844 setGui.Name = "SetGui"
2845
2846 local setPanel = Instance.new("Frame")
2847 setPanel.Name = "SetPanel"
2848 setPanel.Active = true
2849 setPanel.BackgroundTransparency = 1
2850 if position then
2851 setPanel.Position = position
2852 else
2853 setPanel.Position = UDim2.new(0.2, 29, 0.1, 24)
2854 end
2855 if size then
2856 setPanel.Size = size
2857 else
2858 setPanel.Size = UDim2.new(0.6, -58, 0.64, 0)
2859 end
2860 setPanel.Style = Enum.FrameStyle.RobloxRound
2861 setPanel.ZIndex = 6
2862 setPanel.Parent = setGui
2863
2864 -- Children of SetPanel
2865 local itemPreview = Instance.new("Frame")
2866 itemPreview.Name = "ItemPreview"
2867 itemPreview.BackgroundTransparency = 1
2868 itemPreview.Position = UDim2.new(0.8,5,0.085,0)
2869 itemPreview.Size = UDim2.new(0.21,0,0.9,0)
2870 itemPreview.ZIndex = 6
2871 itemPreview.Parent = setPanel
2872
2873 -- Children of ItemPreview
2874 local textPanel = Instance.new("Frame")
2875 textPanel.Name = "TextPanel"
2876 textPanel.BackgroundTransparency = 1
2877 textPanel.Position = UDim2.new(0,0,0.45,0)
2878 textPanel.Size = UDim2.new(1,0,0.55,0)
2879 textPanel.ZIndex = 6
2880 textPanel.Parent = itemPreview
2881
2882 -- Children of TextPanel
2883 local rolloverText = Instance.new("TextLabel")
2884 rolloverText.Name = "RolloverText"
2885 rolloverText.BackgroundTransparency = 1
2886 rolloverText.Size = UDim2.new(1,0,0,48)
2887 rolloverText.ZIndex = 6
2888 rolloverText.Font = Enum.Font.ArialBold
2889 rolloverText.FontSize = Enum.FontSize.Size24
2890 rolloverText.Text = ""
2891 rolloverText.TextColor3 = Color3.new(1,1,1)
2892 rolloverText.TextWrap = true
2893 rolloverText.TextXAlignment = Enum.TextXAlignment.Left
2894 rolloverText.TextYAlignment = Enum.TextYAlignment.Top
2895 rolloverText.Parent = textPanel
2896
2897 local largePreview = Instance.new("ImageLabel")
2898 largePreview.Name = "LargePreview"
2899 largePreview.BackgroundTransparency = 1
2900 largePreview.Image = ""
2901 largePreview.Size = UDim2.new(1,0,0,170)
2902 largePreview.ZIndex = 6
2903 largePreview.Parent = itemPreview
2904
2905 local sets = Instance.new("Frame")
2906 sets.Name = "Sets"
2907 sets.BackgroundTransparency = 1
2908 sets.Position = UDim2.new(0,0,0,5)
2909 sets.Size = UDim2.new(0.23,0,1,-5)
2910 sets.ZIndex = 6
2911 sets.Parent = setPanel
2912
2913 -- Children of Sets
2914 local line = Instance.new("Frame")
2915 line.Name = "Line"
2916 line.BackgroundColor3 = Color3.new(1,1,1)
2917 line.BackgroundTransparency = 0.7
2918 line.BorderSizePixel = 0
2919 line.Position = UDim2.new(1,-3,0.06,0)
2920 line.Size = UDim2.new(0,3,0.9,0)
2921 line.ZIndex = 6
2922 line.Parent = sets
2923
2924 local setsLists, controlFrame = t.CreateTrueScrollingFrame()
2925 setsLists.Size = UDim2.new(1,-6,0.94,0)
2926 setsLists.Position = UDim2.new(0,0,0.06,0)
2927 setsLists.BackgroundTransparency = 1
2928 setsLists.Name = "SetsLists"
2929 setsLists.ZIndex = 6
2930 setsLists.Parent = sets
2931 drillDownSetZIndex(controlFrame, 7)
2932
2933 local setsHeader = Instance.new("TextLabel")
2934 setsHeader.Name = "SetsHeader"
2935 setsHeader.BackgroundTransparency = 1
2936 setsHeader.Size = UDim2.new(0,47,0,24)
2937 setsHeader.ZIndex = 6
2938 setsHeader.Font = Enum.Font.ArialBold
2939 setsHeader.FontSize = Enum.FontSize.Size24
2940 setsHeader.Text = "Sets"
2941 setsHeader.TextColor3 = Color3.new(1,1,1)
2942 setsHeader.TextXAlignment = Enum.TextXAlignment.Left
2943 setsHeader.TextYAlignment = Enum.TextYAlignment.Top
2944 setsHeader.Parent = sets
2945
2946 local cancelButton = Instance.new("TextButton")
2947 cancelButton.Name = "CancelButton"
2948 cancelButton.Position = UDim2.new(1,-32,0,-2)
2949 cancelButton.Size = UDim2.new(0,34,0,34)
2950 cancelButton.Style = Enum.ButtonStyle.RobloxButtonDefault
2951 cancelButton.ZIndex = 6
2952 cancelButton.Text = ""
2953 cancelButton.Modal = true
2954 cancelButton.Parent = setPanel
2955
2956 -- Children of Cancel Button
2957 local cancelImage = Instance.new("ImageLabel")
2958 cancelImage.Name = "CancelImage"
2959 cancelImage.BackgroundTransparency = 1
2960 cancelImage.Image = "https://www.roblox.com/asset/?id=54135717"
2961 cancelImage.Position = UDim2.new(0,-2,0,-2)
2962 cancelImage.Size = UDim2.new(0,16,0,16)
2963 cancelImage.ZIndex = 6
2964 cancelImage.Parent = cancelButton
2965
2966 return setGui
2967 end
2968
2969 local function createSetButton(text)
2970 local setButton = Instance.new("TextButton")
2971
2972 if text then setButton.Text = text
2973 else setButton.Text = "" end
2974
2975 setButton.AutoButtonColor = false
2976 setButton.BackgroundTransparency = 1
2977 setButton.BackgroundColor3 = Color3.new(1,1,1)
2978 setButton.BorderSizePixel = 0
2979 setButton.Size = UDim2.new(1,-5,0,18)
2980 setButton.ZIndex = 6
2981 setButton.Visible = false
2982 setButton.Font = Enum.Font.Arial
2983 setButton.FontSize = Enum.FontSize.Size18
2984 setButton.TextColor3 = Color3.new(1,1,1)
2985 setButton.TextXAlignment = Enum.TextXAlignment.Left
2986
2987 return setButton
2988 end
2989
2990 local function buildSetButton(name, setId, setImageId, i, count)
2991 local button = createSetButton(name)
2992 button.Text = name
2993 button.Name = "SetButton"
2994 button.Visible = true
2995
2996 local setValue = Instance.new("IntValue")
2997 setValue.Name = "SetId"
2998 setValue.Value = setId
2999 setValue.Parent = button
3000
3001 local setName = Instance.new("StringValue")
3002 setName.Name = "SetName"
3003 setName.Value = name
3004 setName.Parent = button
3005
3006 return button
3007 end
3008
3009 local function processCategory(sets)
3010 local setButtons = {}
3011 local numSkipped = 0
3012 for i = 1, #sets do
3013 if not showAdminCategories and sets[i].Name == "Beta" then
3014 numSkipped = numSkipped + 1
3015 else
3016 setButtons[i - numSkipped] = buildSetButton(sets[i].Name, sets[i].CategoryId, sets[i].ImageAssetId, i - numSkipped, #sets)
3017 end
3018 end
3019 return setButtons
3020 end
3021
3022 local function handleResize()
3023 wait() -- neccessary to insure heartbeat happened
3024
3025 local itemPreview = setGui.SetPanel.ItemPreview
3026
3027 itemPreview.LargePreview.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.X)
3028 itemPreview.LargePreview.Position = UDim2.new(0.5,-itemPreview.LargePreview.AbsoluteSize.X/2,0,0)
3029 itemPreview.TextPanel.Position = UDim2.new(0,0,0,itemPreview.LargePreview.AbsoluteSize.Y)
3030 itemPreview.TextPanel.Size = UDim2.new(1,0,0,itemPreview.AbsoluteSize.Y - itemPreview.LargePreview.AbsoluteSize.Y)
3031 end
3032
3033 local function makeInsertAssetButton()
3034 local insertAssetButtonExample = Instance.new("Frame")
3035 insertAssetButtonExample.Name = "InsertAssetButtonExample"
3036 insertAssetButtonExample.Position = UDim2.new(0,128,0,64)
3037 insertAssetButtonExample.Size = UDim2.new(0,64,0,64)
3038 insertAssetButtonExample.BackgroundTransparency = 1
3039 insertAssetButtonExample.ZIndex = 6
3040 insertAssetButtonExample.Visible = false
3041
3042 local assetId = Instance.new("IntValue")
3043 assetId.Name = "AssetId"
3044 assetId.Value = 0
3045 assetId.Parent = insertAssetButtonExample
3046
3047 local assetName = Instance.new("StringValue")
3048 assetName.Name = "AssetName"
3049 assetName.Value = ""
3050 assetName.Parent = insertAssetButtonExample
3051
3052 local button = Instance.new("TextButton")
3053 button.Name = "Button"
3054 button.Text = ""
3055 button.Style = Enum.ButtonStyle.RobloxButton
3056 button.Position = UDim2.new(0.025,0,0.025,0)
3057 button.Size = UDim2.new(0.95,0,0.95,0)
3058 button.ZIndex = 6
3059 button.Parent = insertAssetButtonExample
3060
3061 local buttonImage = Instance.new("ImageLabel")
3062 buttonImage.Name = "ButtonImage"
3063 buttonImage.Image = ""
3064 buttonImage.Position = UDim2.new(0,-7,0,-7)
3065 buttonImage.Size = UDim2.new(1,14,1,14)
3066 buttonImage.BackgroundTransparency = 1
3067 buttonImage.ZIndex = 7
3068 buttonImage.Parent = button
3069
3070 local configIcon = buttonImage:clone()
3071 configIcon.Name = "ConfigIcon"
3072 configIcon.Visible = false
3073 configIcon.Position = UDim2.new(1,-23,1,-24)
3074 configIcon.Size = UDim2.new(0,16,0,16)
3075 configIcon.Image = ""
3076 configIcon.ZIndex = 6
3077 configIcon.Parent = insertAssetButtonExample
3078
3079 return insertAssetButtonExample
3080 end
3081
3082 local function showLargePreview(insertButton)
3083 if insertButton:FindFirstChild("AssetId") then
3084 delay(0,function()
3085 game:GetService("ContentProvider"):Preload(LargeThumbnailUrl .. tostring(insertButton.AssetId.Value))
3086 setGui.SetPanel.ItemPreview.LargePreview.Image = LargeThumbnailUrl .. tostring(insertButton.AssetId.Value)
3087 end)
3088 end
3089 if insertButton:FindFirstChild("AssetName") then
3090 setGui.SetPanel.ItemPreview.TextPanel.RolloverText.Text = insertButton.AssetName.Value
3091 end
3092 end
3093
3094 local function selectTerrainShape(shape)
3095 if currTerrainDropDownFrame then
3096 objectSelected(tostring(currTerrainDropDownFrame.AssetName.Value), tonumber(currTerrainDropDownFrame.AssetId.Value), shape)
3097 end
3098 end
3099
3100 local function createTerrainTypeButton(name, parent)
3101 local dropDownTextButton = Instance.new("TextButton")
3102 dropDownTextButton.Name = name .. "Button"
3103 dropDownTextButton.Font = Enum.Font.ArialBold
3104 dropDownTextButton.FontSize = Enum.FontSize.Size14
3105 dropDownTextButton.BorderSizePixel = 0
3106 dropDownTextButton.TextColor3 = Color3.new(1,1,1)
3107 dropDownTextButton.Text = name
3108 dropDownTextButton.TextXAlignment = Enum.TextXAlignment.Left
3109 dropDownTextButton.BackgroundTransparency = 1
3110 dropDownTextButton.ZIndex = parent.ZIndex + 1
3111 dropDownTextButton.Size = UDim2.new(0,parent.Size.X.Offset - 2,0,16)
3112 dropDownTextButton.Position = UDim2.new(0,1,0,0)
3113
3114 dropDownTextButton.MouseEnter:connect(function()
3115 dropDownTextButton.BackgroundTransparency = 0
3116 dropDownTextButton.TextColor3 = Color3.new(0,0,0)
3117 end)
3118
3119 dropDownTextButton.MouseLeave:connect(function()
3120 dropDownTextButton.BackgroundTransparency = 1
3121 dropDownTextButton.TextColor3 = Color3.new(1,1,1)
3122 end)
3123
3124 dropDownTextButton.MouseButton1Click:connect(function()
3125 dropDownTextButton.BackgroundTransparency = 1
3126 dropDownTextButton.TextColor3 = Color3.new(1,1,1)
3127 if dropDownTextButton.Parent and dropDownTextButton.Parent:IsA("GuiObject") then
3128 dropDownTextButton.Parent.Visible = false
3129 end
3130 selectTerrainShape(terrainShapeMap[dropDownTextButton.Text])
3131 end)
3132
3133 return dropDownTextButton
3134 end
3135
3136 local function createTerrainDropDownMenu(zIndex)
3137 local dropDown = Instance.new("Frame")
3138 dropDown.Name = "TerrainDropDown"
3139 dropDown.BackgroundColor3 = Color3.new(0,0,0)
3140 dropDown.BorderColor3 = Color3.new(1,0,0)
3141 dropDown.Size = UDim2.new(0,200,0,0)
3142 dropDown.Visible = false
3143 dropDown.ZIndex = zIndex
3144 dropDown.Parent = setGui
3145
3146 for i = 1, #terrainShapes do
3147 local shapeButton = createTerrainTypeButton(terrainShapes[i],dropDown)
3148 shapeButton.Position = UDim2.new(0,1,0,(i - 1) * (shapeButton.Size.Y.Offset))
3149 shapeButton.Parent = dropDown
3150 dropDown.Size = UDim2.new(0,200,0,dropDown.Size.Y.Offset + (shapeButton.Size.Y.Offset))
3151 end
3152
3153 dropDown.MouseLeave:connect(function()
3154 dropDown.Visible = false
3155 end)
3156 end
3157
3158
3159 local function createDropDownMenuButton(parent)
3160 local dropDownButton = Instance.new("ImageButton")
3161 dropDownButton.Name = "DropDownButton"
3162 dropDownButton.Image = "https://www.roblox.com/asset/?id=67581509"
3163 dropDownButton.BackgroundTransparency = 1
3164 dropDownButton.Size = UDim2.new(0,16,0,16)
3165 dropDownButton.Position = UDim2.new(1,-24,0,6)
3166 dropDownButton.ZIndex = parent.ZIndex + 2
3167 dropDownButton.Parent = parent
3168
3169 if not setGui:FindFirstChild("TerrainDropDown") then
3170 createTerrainDropDownMenu(8)
3171 end
3172
3173 dropDownButton.MouseButton1Click:connect(function()
3174 setGui.TerrainDropDown.Visible = true
3175 setGui.TerrainDropDown.Position = UDim2.new(0,parent.AbsolutePosition.X,0,parent.AbsolutePosition.Y)
3176 currTerrainDropDownFrame = parent
3177 end)
3178 end
3179
3180 local function buildInsertButton()
3181 local insertButton = makeInsertAssetButton()
3182 insertButton.Name = "InsertAssetButton"
3183 insertButton.Visible = true
3184
3185 if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
3186 createDropDownMenuButton(insertButton)
3187 end
3188
3189 local lastEnter = nil
3190 local mouseEnterCon = insertButton.MouseEnter:connect(function()
3191 lastEnter = insertButton
3192 delay(0.1,function()
3193 if lastEnter == insertButton then
3194 showLargePreview(insertButton)
3195 end
3196 end)
3197 end)
3198 return insertButton, mouseEnterCon
3199 end
3200
3201 local function realignButtonGrid(columns)
3202 local x = 0
3203 local y = 0
3204 for i = 1, #insertButtons do
3205 insertButtons[i].Position = UDim2.new(0, buttonWidth * x, 0, buttonHeight * y)
3206 x = x + 1
3207 if x >= columns then
3208 x = 0
3209 y = y + 1
3210 end
3211 end
3212 end
3213
3214 local function setInsertButtonImageBehavior(insertFrame, visible, name, assetId)
3215 if visible then
3216 insertFrame.AssetName.Value = name
3217 insertFrame.AssetId.Value = assetId
3218 local newImageUrl = SmallThumbnailUrl .. assetId
3219 if newImageUrl ~= insertFrame.Button.ButtonImage.Image then
3220 delay(0,function()
3221 game:GetService("ContentProvider"):Preload(SmallThumbnailUrl .. assetId)
3222 if insertFrame:findFirstChild("Button") then
3223 insertFrame.Button.ButtonImage.Image = SmallThumbnailUrl .. assetId
3224 end
3225 end)
3226 end
3227 table.insert(insertButtonCons,
3228 insertFrame.Button.MouseButton1Click:connect(function()
3229 -- special case for water, show water selection gui
3230 local isWaterSelected = (name == "Water") and (Data.Category[Data.CurrentCategory].SetName == "High Scalability")
3231 waterGui.Visible = isWaterSelected
3232 if isWaterSelected then
3233 objectSelected(name, tonumber(assetId), nil)
3234 else
3235 objectSelected(name, tonumber(assetId))
3236 end
3237 end)
3238 )
3239 insertFrame.Visible = true
3240 else
3241 insertFrame.Visible = false
3242 end
3243 end
3244
3245 local function loadSectionOfItems(setGui, rows, columns)
3246 local pageSize = rows * columns
3247
3248 if arrayPosition > #contents then return end
3249
3250 local origArrayPos = arrayPosition
3251
3252 local yCopy = 0
3253 for i = 1, pageSize + 1 do
3254 if arrayPosition >= #contents + 1 then
3255 break
3256 end
3257
3258 local buttonCon
3259 insertButtons[arrayPosition], buttonCon = buildInsertButton()
3260 table.insert(insertButtonCons,buttonCon)
3261 insertButtons[arrayPosition].Parent = setGui.SetPanel.ItemsFrame
3262 arrayPosition = arrayPosition + 1
3263 end
3264 realignButtonGrid(columns)
3265
3266 local indexCopy = origArrayPos
3267 for index = origArrayPos, arrayPosition do
3268 if insertButtons[index] then
3269 if contents[index] then
3270
3271 -- we don't want water to have a drop down button
3272 if contents[index].Name == "Water" then
3273 if Data.Category[Data.CurrentCategory].SetName == "High Scalability" then
3274 insertButtons[index]:FindFirstChild("DropDownButton",true):Destroy()
3275 end
3276 end
3277
3278 local assetId
3279 if useAssetVersionId then
3280 assetId = contents[index].AssetVersionId
3281 else
3282 assetId = contents[index].AssetId
3283 end
3284 setInsertButtonImageBehavior(insertButtons[index], true, contents[index].Name, assetId)
3285 else
3286 break
3287 end
3288 else
3289 break
3290 end
3291 indexCopy = index
3292 end
3293 end
3294
3295 local function setSetIndex()
3296 Data.Category[Data.CurrentCategory].Index = 0
3297
3298 rows = 7
3299 columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
3300
3301 contents = Data.Category[Data.CurrentCategory].Contents
3302 if contents then
3303 -- remove our buttons and their connections
3304 for i = 1, #insertButtons do
3305 insertButtons[i]:remove()
3306 end
3307 for i = 1, #insertButtonCons do
3308 if insertButtonCons[i] then insertButtonCons[i]:disconnect() end
3309 end
3310 insertButtonCons = {}
3311 insertButtons = {}
3312
3313 arrayPosition = 1
3314 loadSectionOfItems(setGui, rows, columns)
3315 end
3316 end
3317
3318 local function selectSet(button, setName, setId, setIndex)
3319 if button and Data.Category[Data.CurrentCategory] ~= nil then
3320 if button ~= Data.Category[Data.CurrentCategory].Button then
3321 Data.Category[Data.CurrentCategory].Button = button
3322
3323 if SetCache[setId] == nil then
3324 SetCache[setId] = game:GetService("InsertService"):GetCollection(setId)
3325 end
3326 Data.Category[Data.CurrentCategory].Contents = SetCache[setId]
3327
3328 Data.Category[Data.CurrentCategory].SetName = setName
3329 Data.Category[Data.CurrentCategory].SetId = setId
3330 end
3331 setSetIndex()
3332 end
3333 end
3334
3335 local function selectCategoryPage(buttons, page)
3336 if buttons ~= Data.CurrentCategory then
3337 if Data.CurrentCategory then
3338 for key, button in pairs(Data.CurrentCategory) do
3339 button.Visible = false
3340 end
3341 end
3342
3343 Data.CurrentCategory = buttons
3344 if Data.Category[Data.CurrentCategory] == nil then
3345 Data.Category[Data.CurrentCategory] = {}
3346 if #buttons > 0 then
3347 selectSet(buttons[1], buttons[1].SetName.Value, buttons[1].SetId.Value, 0)
3348 end
3349 else
3350 Data.Category[Data.CurrentCategory].Button = nil
3351 selectSet(Data.Category[Data.CurrentCategory].ButtonFrame, Data.Category[Data.CurrentCategory].SetName, Data.Category[Data.CurrentCategory].SetId, Data.Category[Data.CurrentCategory].Index)
3352 end
3353 end
3354 end
3355
3356 local function selectCategory(category)
3357 selectCategoryPage(category, 0)
3358 end
3359
3360 local function resetAllSetButtonSelection()
3361 local setButtons = setGui.SetPanel.Sets.SetsLists:GetChildren()
3362 for i = 1, #setButtons do
3363 if setButtons[i]:IsA("TextButton") then
3364 setButtons[i].Selected = false
3365 setButtons[i].BackgroundTransparency = 1
3366 setButtons[i].TextColor3 = Color3.new(1,1,1)
3367 setButtons[i].BackgroundColor3 = Color3.new(1,1,1)
3368 end
3369 end
3370 end
3371
3372 local function populateSetsFrame()
3373 local currRow = 0
3374 for i = 1, #userCategoryButtons do
3375 local button = userCategoryButtons[i]
3376 button.Visible = true
3377 button.Position = UDim2.new(0,5,0,currRow * button.Size.Y.Offset)
3378 button.Parent = setGui.SetPanel.Sets.SetsLists
3379
3380 if i == 1 then -- we will have this selected by default, so show it
3381 button.Selected = true
3382 button.BackgroundColor3 = Color3.new(0,204/255,0)
3383 button.TextColor3 = Color3.new(0,0,0)
3384 button.BackgroundTransparency = 0
3385 end
3386
3387 button.MouseEnter:connect(function()
3388 if not button.Selected then
3389 button.BackgroundTransparency = 0
3390 button.TextColor3 = Color3.new(0,0,0)
3391 end
3392 end)
3393 button.MouseLeave:connect(function()
3394 if not button.Selected then
3395 button.BackgroundTransparency = 1
3396 button.TextColor3 = Color3.new(1,1,1)
3397 end
3398 end)
3399 button.MouseButton1Click:connect(function()
3400 resetAllSetButtonSelection()
3401 button.Selected = not button.Selected
3402 button.BackgroundColor3 = Color3.new(0,204/255,0)
3403 button.TextColor3 = Color3.new(0,0,0)
3404 button.BackgroundTransparency = 0
3405 selectSet(button, button.Text, userCategoryButtons[i].SetId.Value, 0)
3406 end)
3407
3408 currRow = currRow + 1
3409 end
3410
3411 local buttons = setGui.SetPanel.Sets.SetsLists:GetChildren()
3412
3413 -- set first category as loaded for default
3414 if buttons then
3415 for i = 1, #buttons do
3416 if buttons[i]:IsA("TextButton") then
3417 selectSet(buttons[i], buttons[i].Text, userCategoryButtons[i].SetId.Value, 0)
3418 selectCategory(userCategoryButtons)
3419 break
3420 end
3421 end
3422 end
3423 end
3424
3425 setGui = createSetGui()
3426 waterGui, waterTypeChangedEvent = createWaterGui()
3427 waterGui.Position = UDim2.new(0,55,0,0)
3428 waterGui.Parent = setGui
3429 setGui.Changed:connect(function(prop) -- this resizes the preview image to always be the right size
3430 if prop == "AbsoluteSize" then
3431 handleResize()
3432 setSetIndex()
3433 end
3434 end)
3435
3436 local scrollFrame, controlFrame = t.CreateTrueScrollingFrame()
3437 scrollFrame.Size = UDim2.new(0.54,0,0.85,0)
3438 scrollFrame.Position = UDim2.new(0.24,0,0.085,0)
3439 scrollFrame.Name = "ItemsFrame"
3440 scrollFrame.ZIndex = 6
3441 scrollFrame.Parent = setGui.SetPanel
3442 scrollFrame.BackgroundTransparency = 1
3443
3444 drillDownSetZIndex(controlFrame,7)
3445
3446 controlFrame.Parent = setGui.SetPanel
3447 controlFrame.Position = UDim2.new(0.76, 5, 0, 0)
3448
3449 local debounce = false
3450 controlFrame.ScrollBottom.Changed:connect(function(prop)
3451 if controlFrame.ScrollBottom.Value == true then
3452 if debounce then return end
3453 debounce = true
3454 loadSectionOfItems(setGui, rows, columns)
3455 debounce = false
3456 end
3457 end)
3458
3459 local userData = {}
3460 for id = 1, #userIdsForSets do
3461 local newUserData = game:GetService("InsertService"):GetUserSets(userIdsForSets[id])
3462 if newUserData and #newUserData > 2 then
3463 -- start at #3 to skip over My Decals and My Models for each account
3464 for category = 3, #newUserData do
3465 if newUserData[category].Name == "High Scalability" then -- we want high scalability parts to show first
3466 table.insert(userData,1,newUserData[category])
3467 else
3468 table.insert(userData, newUserData[category])
3469 end
3470 end
3471 end
3472
3473 end
3474 if userData then
3475 userCategoryButtons = processCategory(userData)
3476 end
3477
3478 rows = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.Y/buttonHeight)
3479 columns = math.floor(setGui.SetPanel.ItemsFrame.AbsoluteSize.X/buttonWidth)
3480
3481 populateSetsFrame()
3482
3483 setGui.SetPanel.CancelButton.MouseButton1Click:connect(function()
3484 setGui.SetPanel.Visible = false
3485 if dialogClosed then dialogClosed() end
3486 end)
3487
3488 local setVisibilityFunction = function(visible)
3489 if visible then
3490 setGui.SetPanel.Visible = true
3491 else
3492 setGui.SetPanel.Visible = false
3493 end
3494 end
3495
3496 local getVisibilityFunction = function()
3497 if setGui then
3498 if setGui:FindFirstChild("SetPanel") then
3499 return setGui.SetPanel.Visible
3500 end
3501 end
3502
3503 return false
3504 end
3505
3506 return setGui, setVisibilityFunction, getVisibilityFunction, waterTypeChangedEvent
3507end
3508
3509t.CreateTerrainMaterialSelector = function(size,position)
3510 local terrainMaterialSelectionChanged = Instance.new("BindableEvent")
3511 terrainMaterialSelectionChanged.Name = "TerrainMaterialSelectionChanged"
3512
3513 local selectedButton = nil
3514
3515 local frame = Instance.new("Frame")
3516 frame.Name = "TerrainMaterialSelector"
3517 if size then
3518 frame.Size = size
3519 else
3520 frame.Size = UDim2.new(0, 245, 0, 230)
3521 end
3522 if position then
3523 frame.Position = position
3524 end
3525 frame.BorderSizePixel = 0
3526 frame.BackgroundColor3 = Color3.new(0,0,0)
3527 frame.Active = true
3528
3529 terrainMaterialSelectionChanged.Parent = frame
3530
3531 local waterEnabled = true -- todo: turn this on when water is ready
3532
3533 local materialToImageMap = {}
3534 local materialNames = {"Grass", "Sand", "Brick", "Granite", "Asphalt", "Iron", "Aluminum", "Gold", "Plank", "Log", "Gravel", "Cinder Block", "Stone Wall", "Concrete", "Plastic (red)", "Plastic (blue)"}
3535 if waterEnabled then
3536 table.insert(materialNames,"Water")
3537 end
3538 local currentMaterial = 1
3539
3540 function getEnumFromName(choice)
3541 if choice == "Grass" then return 1 end
3542 if choice == "Sand" then return 2 end
3543 if choice == "Erase" then return 0 end
3544 if choice == "Brick" then return 3 end
3545 if choice == "Granite" then return 4 end
3546 if choice == "Asphalt" then return 5 end
3547 if choice == "Iron" then return 6 end
3548 if choice == "Aluminum" then return 7 end
3549 if choice == "Gold" then return 8 end
3550 if choice == "Plank" then return 9 end
3551 if choice == "Log" then return 10 end
3552 if choice == "Gravel" then return 11 end
3553 if choice == "Cinder Block" then return 12 end
3554 if choice == "Stone Wall" then return 13 end
3555 if choice == "Concrete" then return 14 end
3556 if choice == "Plastic (red)" then return 15 end
3557 if choice == "Plastic (blue)" then return 16 end
3558 if choice == "Water" then return 17 end
3559 end
3560
3561 function getNameFromEnum(choice)
3562 if choice == Enum.CellMaterial.Grass or choice == 1 then return "Grass"end
3563 if choice == Enum.CellMaterial.Sand or choice == 2 then return "Sand" end
3564 if choice == Enum.CellMaterial.Empty or choice == 0 then return "Erase" end
3565 if choice == Enum.CellMaterial.Brick or choice == 3 then return "Brick" end
3566 if choice == Enum.CellMaterial.Granite or choice == 4 then return "Granite" end
3567 if choice == Enum.CellMaterial.Asphalt or choice == 5 then return "Asphalt" end
3568 if choice == Enum.CellMaterial.Iron or choice == 6 then return "Iron" end
3569 if choice == Enum.CellMaterial.Aluminum or choice == 7 then return "Aluminum" end
3570 if choice == Enum.CellMaterial.Gold or choice == 8 then return "Gold" end
3571 if choice == Enum.CellMaterial.WoodPlank or choice == 9 then return "Plank" end
3572 if choice == Enum.CellMaterial.WoodLog or choice == 10 then return "Log" end
3573 if choice == Enum.CellMaterial.Gravel or choice == 11 then return "Gravel" end
3574 if choice == Enum.CellMaterial.CinderBlock or choice == 12 then return "Cinder Block" end
3575 if choice == Enum.CellMaterial.MossyStone or choice == 13 then return "Stone Wall" end
3576 if choice == Enum.CellMaterial.Cement or choice == 14 then return "Concrete" end
3577 if choice == Enum.CellMaterial.RedPlastic or choice == 15 then return "Plastic (red)" end
3578 if choice == Enum.CellMaterial.BluePlastic or choice == 16 then return "Plastic (blue)" end
3579
3580 if waterEnabled then
3581 if choice == Enum.CellMaterial.Water or choice == 17 then return "Water" end
3582 end
3583 end
3584
3585
3586 local function updateMaterialChoice(choice)
3587 currentMaterial = getEnumFromName(choice)
3588 terrainMaterialSelectionChanged:Fire(currentMaterial)
3589 end
3590
3591 -- we so need a better way to do this
3592 for i,v in pairs(materialNames) do
3593 materialToImageMap[v] = {}
3594 if v == "Grass" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=56563112"
3595 elseif v == "Sand" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=62356652"
3596 elseif v == "Brick" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=65961537"
3597 elseif v == "Granite" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532153"
3598 elseif v == "Asphalt" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532038"
3599 elseif v == "Iron" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532093"
3600 elseif v == "Aluminum" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531995"
3601 elseif v == "Gold" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532118"
3602 elseif v == "Plastic (red)" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531848"
3603 elseif v == "Plastic (blue)" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531924"
3604 elseif v == "Plank" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532015"
3605 elseif v == "Log" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532051"
3606 elseif v == "Gravel" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532206"
3607 elseif v == "Cinder Block" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532103"
3608 elseif v == "Stone Wall" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67531804"
3609 elseif v == "Concrete" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=67532059"
3610 elseif v == "Water" then materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=81407474"
3611 else materialToImageMap[v].Regular = "https://www.roblox.com/asset/?id=66887593" -- fill in the rest here!!
3612 end
3613 end
3614
3615 local scrollFrame, scrollUp, scrollDown, recalculateScroll = t.CreateScrollingFrame(nil,"grid")
3616 scrollFrame.Size = UDim2.new(0.85,0,1,0)
3617 scrollFrame.Position = UDim2.new(0,0,0,0)
3618 scrollFrame.Parent = frame
3619
3620 scrollUp.Parent = frame
3621 scrollUp.Visible = true
3622 scrollUp.Position = UDim2.new(1,-19,0,0)
3623
3624 scrollDown.Parent = frame
3625 scrollDown.Visible = true
3626 scrollDown.Position = UDim2.new(1,-19,1,-17)
3627
3628 local function goToNewMaterial(buttonWrap, materialName)
3629 updateMaterialChoice(materialName)
3630 buttonWrap.BackgroundTransparency = 0
3631 selectedButton.BackgroundTransparency = 1
3632 selectedButton = buttonWrap
3633 end
3634
3635 local function createMaterialButton(name)
3636 local buttonWrap = Instance.new("TextButton")
3637 buttonWrap.Text = ""
3638 buttonWrap.Size = UDim2.new(0,32,0,32)
3639 buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
3640 buttonWrap.BorderSizePixel = 0
3641 buttonWrap.BackgroundTransparency = 1
3642 buttonWrap.AutoButtonColor = false
3643 buttonWrap.Name = tostring(name)
3644
3645 local imageButton = Instance.new("ImageButton")
3646 imageButton.AutoButtonColor = false
3647 imageButton.BackgroundTransparency = 1
3648 imageButton.Size = UDim2.new(0,30,0,30)
3649 imageButton.Position = UDim2.new(0,1,0,1)
3650 imageButton.Name = tostring(name)
3651 imageButton.Parent = buttonWrap
3652 imageButton.Image = materialToImageMap[name].Regular
3653
3654 local enumType = Instance.new("NumberValue")
3655 enumType.Name = "EnumType"
3656 enumType.Parent = buttonWrap
3657 enumType.Value = 0
3658
3659 imageButton.MouseEnter:connect(function()
3660 buttonWrap.BackgroundTransparency = 0
3661 end)
3662 imageButton.MouseLeave:connect(function()
3663 if selectedButton ~= buttonWrap then
3664 buttonWrap.BackgroundTransparency = 1
3665 end
3666 end)
3667 imageButton.MouseButton1Click:connect(function()
3668 if selectedButton ~= buttonWrap then
3669 goToNewMaterial(buttonWrap, tostring(name))
3670 end
3671 end)
3672
3673 return buttonWrap
3674 end
3675
3676 for i = 1, #materialNames do
3677 local imageButton = createMaterialButton(materialNames[i])
3678
3679 if materialNames[i] == "Grass" then -- always start with grass as the default
3680 selectedButton = imageButton
3681 imageButton.BackgroundTransparency = 0
3682 end
3683
3684 imageButton.Parent = scrollFrame
3685 end
3686
3687 local forceTerrainMaterialSelection = function(newMaterialType)
3688 if not newMaterialType then return end
3689 if currentMaterial == newMaterialType then return end
3690
3691 local matName = getNameFromEnum(newMaterialType)
3692 local buttons = scrollFrame:GetChildren()
3693 for i = 1, #buttons do
3694 if buttons[i].Name == "Plastic (blue)" and matName == "Plastic (blue)" then goToNewMaterial(buttons[i],matName) return end
3695 if buttons[i].Name == "Plastic (red)" and matName == "Plastic (red)" then goToNewMaterial(buttons[i],matName) return end
3696 if string.find(buttons[i].Name, matName) then
3697 goToNewMaterial(buttons[i],matName)
3698 return
3699 end
3700 end
3701 end
3702
3703 frame.Changed:connect(function ( prop )
3704 if prop == "AbsoluteSize" then
3705 recalculateScroll()
3706 end
3707 end)
3708
3709 recalculateScroll()
3710 return frame, terrainMaterialSelectionChanged, forceTerrainMaterialSelection
3711end
3712
3713t.CreateLoadingFrame = function(name,size,position)
3714 game:GetService("ContentProvider"):Preload("https://www.roblox.com/asset/?id=35238053")
3715
3716 local loadingFrame = Instance.new("Frame")
3717 loadingFrame.Name = "LoadingFrame"
3718 loadingFrame.Style = Enum.FrameStyle.RobloxRound
3719
3720 if size then loadingFrame.Size = size
3721 else loadingFrame.Size = UDim2.new(0,300,0,160) end
3722 if position then loadingFrame.Position = position
3723 else loadingFrame.Position = UDim2.new(0.5, -150, 0.5,-80) end
3724
3725 local loadingBar = Instance.new("Frame")
3726 loadingBar.Name = "LoadingBar"
3727 loadingBar.BackgroundColor3 = Color3.new(0,0,0)
3728 loadingBar.BorderColor3 = Color3.new(79/255,79/255,79/255)
3729 loadingBar.Position = UDim2.new(0,0,0,41)
3730 loadingBar.Size = UDim2.new(1,0,0,30)
3731 loadingBar.Parent = loadingFrame
3732
3733 local loadingGreenBar = Instance.new("ImageLabel")
3734 loadingGreenBar.Name = "LoadingGreenBar"
3735 loadingGreenBar.Image = "https://www.roblox.com/asset/?id=35238053"
3736 loadingGreenBar.Position = UDim2.new(0,0,0,0)
3737 loadingGreenBar.Size = UDim2.new(0,0,1,0)
3738 loadingGreenBar.Visible = false
3739 loadingGreenBar.Parent = loadingBar
3740
3741 local loadingPercent = Instance.new("TextLabel")
3742 loadingPercent.Name = "LoadingPercent"
3743 loadingPercent.BackgroundTransparency = 1
3744 loadingPercent.Position = UDim2.new(0,0,1,0)
3745 loadingPercent.Size = UDim2.new(1,0,0,14)
3746 loadingPercent.Font = Enum.Font.Arial
3747 loadingPercent.Text = "0%"
3748 loadingPercent.FontSize = Enum.FontSize.Size14
3749 loadingPercent.TextColor3 = Color3.new(1,1,1)
3750 loadingPercent.Parent = loadingBar
3751
3752 local cancelButton = Instance.new("TextButton")
3753 cancelButton.Name = "CancelButton"
3754 cancelButton.Position = UDim2.new(0.5,-60,1,-40)
3755 cancelButton.Size = UDim2.new(0,120,0,40)
3756 cancelButton.Font = Enum.Font.Arial
3757 cancelButton.FontSize = Enum.FontSize.Size18
3758 cancelButton.TextColor3 = Color3.new(1,1,1)
3759 cancelButton.Text = "Cancel"
3760 cancelButton.Style = Enum.ButtonStyle.RobloxButton
3761 cancelButton.Parent = loadingFrame
3762
3763 local loadingName = Instance.new("TextLabel")
3764 loadingName.Name = "loadingName"
3765 loadingName.BackgroundTransparency = 1
3766 loadingName.Size = UDim2.new(1,0,0,18)
3767 loadingName.Position = UDim2.new(0,0,0,2)
3768 loadingName.Font = Enum.Font.Arial
3769 loadingName.Text = name
3770 loadingName.TextColor3 = Color3.new(1,1,1)
3771 loadingName.TextStrokeTransparency = 1
3772 loadingName.FontSize = Enum.FontSize.Size18
3773 loadingName.Parent = loadingFrame
3774
3775 local cancelButtonClicked = Instance.new("BindableEvent")
3776 cancelButtonClicked.Name = "CancelButtonClicked"
3777 cancelButtonClicked.Parent = cancelButton
3778 cancelButton.MouseButton1Click:connect(function()
3779 cancelButtonClicked:Fire()
3780 end)
3781
3782 local updateLoadingGuiPercent = function(percent, tweenAction, tweenLength)
3783 if percent and type(percent) ~= "number" then
3784 error("updateLoadingGuiPercent expects number as argument, got",type(percent),"instead")
3785 end
3786
3787 local newSize = nil
3788 if percent < 0 then
3789 newSize = UDim2.new(0,0,1,0)
3790 elseif percent > 1 then
3791 newSize = UDim2.new(1,0,1,0)
3792 else
3793 newSize = UDim2.new(percent,0,1,0)
3794 end
3795
3796 if tweenAction then
3797 if not tweenLength then
3798 error("updateLoadingGuiPercent is set to tween new percentage, but got no tween time length! Please pass this in as third argument")
3799 end
3800
3801 if (newSize.X.Scale > 0) then
3802 loadingGreenBar.Visible = true
3803 loadingGreenBar:TweenSize( newSize,
3804 Enum.EasingDirection.Out,
3805 Enum.EasingStyle.Quad,
3806 tweenLength,
3807 true)
3808 else
3809 loadingGreenBar:TweenSize( newSize,
3810 Enum.EasingDirection.Out,
3811 Enum.EasingStyle.Quad,
3812 tweenLength,
3813 true,
3814 function()
3815 if (newSize.X.Scale < 0) then
3816 loadingGreenBar.Visible = false
3817 end
3818 end)
3819 end
3820
3821 else
3822 loadingGreenBar.Size = newSize
3823 loadingGreenBar.Visible = (newSize.X.Scale > 0)
3824 end
3825 end
3826
3827 loadingGreenBar.Changed:connect(function(prop)
3828 if prop == "Size" then
3829 loadingPercent.Text = tostring( math.ceil(loadingGreenBar.Size.X.Scale * 100) ) .. "%"
3830 end
3831 end)
3832
3833 return loadingFrame, updateLoadingGuiPercent, cancelButtonClicked
3834end
3835
3836t.CreatePluginFrame = function (name,size,position,scrollable,parent)
3837 local function createMenuButton(size,position,text,fontsize,name,parent)
3838 local button = Instance.new("TextButton",parent)
3839 button.AutoButtonColor = false
3840 button.Name = name
3841 button.BackgroundTransparency = 1
3842 button.Position = position
3843 button.Size = size
3844 button.Font = Enum.Font.ArialBold
3845 button.FontSize = fontsize
3846 button.Text = text
3847 button.TextColor3 = Color3.new(1,1,1)
3848 button.BorderSizePixel = 0
3849 button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
3850
3851 button.MouseEnter:connect(function ( )
3852 if button.Selected then return end
3853 button.BackgroundTransparency = 0
3854 end)
3855 button.MouseLeave:connect(function ( )
3856 if button.Selected then return end
3857 button.BackgroundTransparency = 1
3858 end)
3859
3860 return button
3861
3862 end
3863
3864 local dragBar = Instance.new("Frame",parent)
3865 dragBar.Name = tostring(name) .. "DragBar"
3866 dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
3867 dragBar.BorderColor3 = Color3.new(0,0,0)
3868 if size then
3869 dragBar.Size = UDim2.new(size.X.Scale,size.X.Offset,0,20) + UDim2.new(0,20,0,0)
3870 else
3871 dragBar.Size = UDim2.new(0,183,0,20)
3872 end
3873 if position then
3874 dragBar.Position = position
3875 end
3876 dragBar.Active = true
3877 dragBar.Draggable = true
3878 --dragBar.Visible = false
3879 dragBar.MouseEnter:connect(function ( )
3880 dragBar.BackgroundColor3 = Color3.new(49/255,49/255,49/255)
3881 end)
3882 dragBar.MouseLeave:connect(function ( )
3883 dragBar.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
3884 end)
3885
3886 -- plugin name label
3887 local pluginNameLabel = Instance.new("TextLabel",dragBar)
3888 pluginNameLabel.Name = "BarNameLabel"
3889 pluginNameLabel.Text = " " .. tostring(name)
3890 pluginNameLabel.TextColor3 = Color3.new(1,1,1)
3891 pluginNameLabel.TextStrokeTransparency = 0
3892 pluginNameLabel.Size = UDim2.new(1,0,1,0)
3893 pluginNameLabel.Font = Enum.Font.ArialBold
3894 pluginNameLabel.FontSize = Enum.FontSize.Size18
3895 pluginNameLabel.TextXAlignment = Enum.TextXAlignment.Left
3896 pluginNameLabel.BackgroundTransparency = 1
3897
3898 -- close button
3899 local closeButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-16,0.5,-8),"X",Enum.FontSize.Size14,"CloseButton",dragBar)
3900 local closeEvent = Instance.new("BindableEvent")
3901 closeEvent.Name = "CloseEvent"
3902 closeEvent.Parent = closeButton
3903 closeButton.MouseButton1Click:connect(function ()
3904 closeEvent:Fire()
3905 closeButton.BackgroundTransparency = 1
3906 end)
3907
3908 -- help button
3909 local helpButton = createMenuButton(UDim2.new(0,15,0,17),UDim2.new(1,-51,0.5,-8),"?",Enum.FontSize.Size14,"HelpButton",dragBar)
3910 local helpFrame = Instance.new("Frame",dragBar)
3911 helpFrame.Name = "HelpFrame"
3912 helpFrame.BackgroundColor3 = Color3.new(0,0,0)
3913 helpFrame.Size = UDim2.new(0,300,0,552)
3914 helpFrame.Position = UDim2.new(1,5,0,0)
3915 helpFrame.Active = true
3916 helpFrame.BorderSizePixel = 0
3917 helpFrame.Visible = false
3918
3919 helpButton.MouseButton1Click:connect(function( )
3920 helpFrame.Visible = not helpFrame.Visible
3921 if helpFrame.Visible then
3922 helpButton.Selected = true
3923 helpButton.BackgroundTransparency = 0
3924 local screenGui = getLayerCollectorAncestor(helpFrame)
3925 if screenGui then
3926 if helpFrame.AbsolutePosition.X + helpFrame.AbsoluteSize.X > screenGui.AbsoluteSize.X then --position on left hand side
3927 helpFrame.Position = UDim2.new(0,-5 - helpFrame.AbsoluteSize.X,0,0)
3928 else -- position on right hand side
3929 helpFrame.Position = UDim2.new(1,5,0,0)
3930 end
3931 else
3932 helpFrame.Position = UDim2.new(1,5,0,0)
3933 end
3934 else
3935 helpButton.Selected = false
3936 helpButton.BackgroundTransparency = 1
3937 end
3938 end)
3939
3940 local minimizeButton = createMenuButton(UDim2.new(0,16,0,17),UDim2.new(1,-34,0.5,-8),"-",Enum.FontSize.Size14,"MinimizeButton",dragBar)
3941 minimizeButton.TextYAlignment = Enum.TextYAlignment.Top
3942
3943 local minimizeFrame = Instance.new("Frame",dragBar)
3944 minimizeFrame.Name = "MinimizeFrame"
3945 minimizeFrame.BackgroundColor3 = Color3.new(73/255,73/255,73/255)
3946 minimizeFrame.BorderColor3 = Color3.new(0,0,0)
3947 minimizeFrame.Position = UDim2.new(0,0,1,0)
3948 if size then
3949 minimizeFrame.Size = UDim2.new(size.X.Scale,size.X.Offset,0,50) + UDim2.new(0,20,0,0)
3950 else
3951 minimizeFrame.Size = UDim2.new(0,183,0,50)
3952 end
3953 minimizeFrame.Visible = false
3954
3955 local minimizeBigButton = Instance.new("TextButton",minimizeFrame)
3956 minimizeBigButton.Position = UDim2.new(0.5,-50,0.5,-20)
3957 minimizeBigButton.Name = "MinimizeButton"
3958 minimizeBigButton.Size = UDim2.new(0,100,0,40)
3959 minimizeBigButton.Style = Enum.ButtonStyle.RobloxButton
3960 minimizeBigButton.Font = Enum.Font.ArialBold
3961 minimizeBigButton.FontSize = Enum.FontSize.Size18
3962 minimizeBigButton.TextColor3 = Color3.new(1,1,1)
3963 minimizeBigButton.Text = "Show"
3964
3965 local separatingLine = Instance.new("Frame",dragBar)
3966 separatingLine.Name = "SeparatingLine"
3967 separatingLine.BackgroundColor3 = Color3.new(115/255,115/255,115/255)
3968 separatingLine.BorderSizePixel = 0
3969 separatingLine.Position = UDim2.new(1,-18,0.5,-7)
3970 separatingLine.Size = UDim2.new(0,1,0,14)
3971
3972 local otherSeparatingLine = separatingLine:clone()
3973 otherSeparatingLine.Position = UDim2.new(1,-35,0.5,-7)
3974 otherSeparatingLine.Parent = dragBar
3975
3976 local widgetContainer = Instance.new("Frame",dragBar)
3977 widgetContainer.Name = "WidgetContainer"
3978 widgetContainer.BackgroundTransparency = 1
3979 widgetContainer.Position = UDim2.new(0,0,1,0)
3980 widgetContainer.BorderColor3 = Color3.new(0,0,0)
3981 if not scrollable then
3982 widgetContainer.BackgroundTransparency = 0
3983 widgetContainer.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
3984 end
3985
3986 if size then
3987 if scrollable then
3988 widgetContainer.Size = size
3989 else
3990 widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,size.Y.Scale,size.Y.Offset)
3991 end
3992 else
3993 if scrollable then
3994 widgetContainer.Size = UDim2.new(0,163,0,400)
3995 else
3996 widgetContainer.Size = UDim2.new(0,dragBar.AbsoluteSize.X,0,400)
3997 end
3998 end
3999 if position then
4000 widgetContainer.Position = position + UDim2.new(0,0,0,20)
4001 end
4002
4003 local frame,control,verticalDragger = nil
4004 if scrollable then
4005 --frame for widgets
4006 frame,control = t.CreateTrueScrollingFrame()
4007 frame.Size = UDim2.new(1, 0, 1, 0)
4008 frame.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
4009 frame.BorderColor3 = Color3.new(0,0,0)
4010 frame.Active = true
4011 frame.Parent = widgetContainer
4012 control.Parent = dragBar
4013 control.BackgroundColor3 = Color3.new(72/255,72/255,72/255)
4014 control.BorderSizePixel = 0
4015 control.BackgroundTransparency = 0
4016 control.Position = UDim2.new(1,-21,1,1)
4017 if size then
4018 control.Size = UDim2.new(0,21,size.Y.Scale,size.Y.Offset)
4019 else
4020 control.Size = UDim2.new(0,21,0,400)
4021 end
4022 control:FindFirstChild("ScrollDownButton").Position = UDim2.new(0,0,1,-20)
4023
4024 local fakeLine = Instance.new("Frame",control)
4025 fakeLine.Name = "FakeLine"
4026 fakeLine.BorderSizePixel = 0
4027 fakeLine.BackgroundColor3 = Color3.new(0,0,0)
4028 fakeLine.Size = UDim2.new(0,1,1,1)
4029 fakeLine.Position = UDim2.new(1,0,0,0)
4030
4031 verticalDragger = Instance.new("TextButton",widgetContainer)
4032 verticalDragger.ZIndex = 2
4033 verticalDragger.AutoButtonColor = false
4034 verticalDragger.Name = "VerticalDragger"
4035 verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
4036 verticalDragger.BorderColor3 = Color3.new(0,0,0)
4037 verticalDragger.Size = UDim2.new(1,20,0,20)
4038 verticalDragger.Position = UDim2.new(0,0,1,0)
4039 verticalDragger.Active = true
4040 verticalDragger.Text = ""
4041
4042 local scrubFrame = Instance.new("Frame",verticalDragger)
4043 scrubFrame.Name = "ScrubFrame"
4044 scrubFrame.BackgroundColor3 = Color3.new(1,1,1)
4045 scrubFrame.BorderSizePixel = 0
4046 scrubFrame.Position = UDim2.new(0.5,-5,0.5,0)
4047 scrubFrame.Size = UDim2.new(0,10,0,1)
4048 scrubFrame.ZIndex = 5
4049 local scrubTwo = scrubFrame:clone()
4050 scrubTwo.Position = UDim2.new(0.5,-5,0.5,-2)
4051 scrubTwo.Parent = verticalDragger
4052 local scrubThree = scrubFrame:clone()
4053 scrubThree.Position = UDim2.new(0.5,-5,0.5,2)
4054 scrubThree.Parent = verticalDragger
4055
4056 local areaSoak = Instance.new("TextButton",getLayerCollectorAncestor(parent))
4057 areaSoak.Name = "AreaSoak"
4058 areaSoak.Size = UDim2.new(1,0,1,0)
4059 areaSoak.BackgroundTransparency = 1
4060 areaSoak.BorderSizePixel = 0
4061 areaSoak.Text = ""
4062 areaSoak.ZIndex = 10
4063 areaSoak.Visible = false
4064 areaSoak.Active = true
4065
4066 local draggingVertical = false
4067 local startYPos = nil
4068 verticalDragger.MouseEnter:connect(function ()
4069 verticalDragger.BackgroundColor3 = Color3.new(60/255,60/255,60/255)
4070 end)
4071 verticalDragger.MouseLeave:connect(function ()
4072 verticalDragger.BackgroundColor3 = Color3.new(50/255,50/255,50/255)
4073 end)
4074 verticalDragger.MouseButton1Down:connect(function(x,y)
4075 draggingVertical = true
4076 areaSoak.Visible = true
4077 startYPos = y
4078 end)
4079 areaSoak.MouseButton1Up:connect(function ( )
4080 draggingVertical = false
4081 areaSoak.Visible = false
4082 end)
4083 areaSoak.MouseMoved:connect(function(x,y)
4084 if not draggingVertical then return end
4085
4086 local yDelta = y - startYPos
4087 if not control.ScrollDownButton.Visible and yDelta > 0 then
4088 return
4089 end
4090
4091 if (widgetContainer.Size.Y.Offset + yDelta) < 150 then
4092 widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,150)
4093 control.Size = UDim2.new (0,21,0,150)
4094 return
4095 end
4096
4097 startYPos = y
4098
4099 if widgetContainer.Size.Y.Offset + yDelta >= 0 then
4100 widgetContainer.Size = UDim2.new(widgetContainer.Size.X.Scale, widgetContainer.Size.X.Offset,widgetContainer.Size.Y.Scale,widgetContainer.Size.Y.Offset + yDelta)
4101 control.Size = UDim2.new(0,21,0,control.Size.Y.Offset + yDelta )
4102 end
4103 end)
4104 end
4105
4106 local function switchMinimize()
4107 minimizeFrame.Visible = not minimizeFrame.Visible
4108 if scrollable then
4109 frame.Visible = not frame.Visible
4110 verticalDragger.Visible = not verticalDragger.Visible
4111 control.Visible = not control.Visible
4112 else
4113 widgetContainer.Visible = not widgetContainer.Visible
4114 end
4115
4116 if minimizeFrame.Visible then
4117 minimizeButton.Text = "+"
4118 else
4119 minimizeButton.Text = "-"
4120 end
4121 end
4122
4123 minimizeBigButton.MouseButton1Click:connect(function ( )
4124 switchMinimize()
4125 end)
4126
4127 minimizeButton.MouseButton1Click:connect(function( )
4128 switchMinimize()
4129 end)
4130
4131 if scrollable then
4132 return dragBar, frame, helpFrame, closeEvent
4133 else
4134 return dragBar, widgetContainer, helpFrame, closeEvent
4135 end
4136end
4137
4138t.Help =
4139 function(funcNameOrFunc)
4140 --input argument can be a string or a function. Should return a description (of arguments and expected side effects)
4141 if funcNameOrFunc == "CreatePropertyDropDownMenu" or funcNameOrFunc == t.CreatePropertyDropDownMenu then
4142 return "Function CreatePropertyDropDownMenu. " ..
4143 "Arguments: (instance, propertyName, enumType). " ..
4144 "Side effect: returns a container with a drop-down-box that is linked to the 'property' field of 'instance' which is of type 'enumType'"
4145 end
4146 if funcNameOrFunc == "CreateDropDownMenu" or funcNameOrFunc == t.CreateDropDownMenu then
4147 return "Function CreateDropDownMenu. " ..
4148 "Arguments: (items, onItemSelected). " ..
4149 "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"
4150 end
4151 if funcNameOrFunc == "CreateMessageDialog" or funcNameOrFunc == t.CreateMessageDialog then
4152 return "Function CreateMessageDialog. " ..
4153 "Arguments: (title, message, buttons). " ..
4154 "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"
4155 end
4156 if funcNameOrFunc == "CreateStyledMessageDialog" or funcNameOrFunc == t.CreateStyledMessageDialog then
4157 return "Function CreateStyledMessageDialog. " ..
4158 "Arguments: (title, message, style, buttons). " ..
4159 "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"
4160 end
4161 if funcNameOrFunc == "GetFontHeight" or funcNameOrFunc == t.GetFontHeight then
4162 return "Function GetFontHeight. " ..
4163 "Arguments: (font, fontSize). " ..
4164 "Side effect: returns the size in pixels of the given font + fontSize"
4165 end
4166 if funcNameOrFunc == "LayoutGuiObjects" or funcNameOrFunc == t.LayoutGuiObjects then
4167
4168 end
4169 if funcNameOrFunc == "CreateScrollingFrame" or funcNameOrFunc == t.CreateScrollingFrame then
4170 return "Function CreateScrollingFrame. " ..
4171 "Arguments: (orderList, style) " ..
4172 "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)"
4173 end
4174 if funcNameOrFunc == "CreateTrueScrollingFrame" or funcNameOrFunc == t.CreateTrueScrollingFrame then
4175 return "Function CreateTrueScrollingFrame. " ..
4176 "Arguments: (nil) " ..
4177 "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."
4178 end
4179 if funcNameOrFunc == "AutoTruncateTextObject" or funcNameOrFunc == t.AutoTruncateTextObject then
4180 return "Function AutoTruncateTextObject. " ..
4181 "Arguments: (textLabel) " ..
4182 "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"
4183 end
4184 if funcNameOrFunc == "CreateSlider" or funcNameOrFunc == t.CreateSlider then
4185 return "Function CreateSlider. " ..
4186 "Arguments: (steps, width, position) " ..
4187 "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."
4188 end
4189 if funcNameOrFunc == "CreateSliderNew" or funcNameOrFunc == t.CreateSliderNew then
4190 return "Function CreateSliderNew. " ..
4191 "Arguments: (steps, width, position) " ..
4192 "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."
4193 end
4194 if funcNameOrFunc == "CreateLoadingFrame" or funcNameOrFunc == t.CreateLoadingFrame then
4195 return "Function CreateLoadingFrame. " ..
4196 "Arguments: (name, size, position) " ..
4197 "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."
4198 end
4199 if funcNameOrFunc == "CreateTerrainMaterialSelector" or funcNameOrFunc == t.CreateTerrainMaterialSelector then
4200 return "Function CreateTerrainMaterialSelector. " ..
4201 "Arguments: (size, position) " ..
4202 "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."
4203 end
4204 end
4205
4206return t