forked from aya/aya
2039 lines
68 KiB
Lua
2039 lines
68 KiB
Lua
--[[
|
|
Filename: SettingsPage.lua
|
|
Written by: jeditkacheff
|
|
Version 1.0
|
|
Description: Base Page Functionality for all Settings Pages
|
|
--]]
|
|
|
|
------------------ CONSTANTS --------------------
|
|
local SELECTED_COLOR = Color3.fromRGB(135, 57, 255)
|
|
local NON_SELECTED_COLOR = Color3.new(78/255,84/255,96/255)
|
|
|
|
local SELECTED_LEFT_IMAGE = "ayaasset://textures/ui/Settings/Slider/SelectedBarLeft.png"
|
|
local NON_SELECTED_LEFT_IMAGE = "ayaasset://textures/ui/Settings/Slider/BarLeft.png"
|
|
local SELECTED_RIGHT_IMAGE = "ayaasset://textures/ui/Settings/Slider/SelectedBarRight.png"
|
|
local NON_SELECTED_RIGHT_IMAGE= "ayaasset://textures/ui/Settings/Slider/BarRight.png"
|
|
|
|
local CONTROLLER_SCROLL_DELTA = 0.2
|
|
local CONTROLLER_THUMBSTICK_DEADZONE = 0.8
|
|
|
|
------------- SERVICES ----------------
|
|
local HttpService = game:GetService("HttpService")
|
|
local UserInputService = game:GetService("UserInputService")
|
|
local GuiService = game:GetService("GuiService")
|
|
local RunService = game:GetService("RunService")
|
|
local CoreGui = game:GetService("CoreGui")
|
|
local RobloxGui = CoreGui:FindFirstChild("RobloxGui")
|
|
local ContextActionService = game:GetService("ContextActionService")
|
|
local GameSettings = UserSettings().GameSettings
|
|
|
|
------------------ VARIABLES --------------------
|
|
local tenFootInterfaceEnabled = false
|
|
do
|
|
RobloxGui:WaitForChild("Modules"):WaitForChild("TenFootInterface")
|
|
tenFootInterfaceEnabled = require(RobloxGui.Modules.TenFootInterface):IsEnabled()
|
|
end
|
|
|
|
|
|
|
|
----------- UTILITIES --------------
|
|
local Util = {}
|
|
do
|
|
function Util.Create(instanceType)
|
|
return function(data)
|
|
local obj = Instance.new(instanceType)
|
|
for k, v in pairs(data) do
|
|
if type(k) == 'number' then
|
|
v.Parent = obj
|
|
else
|
|
obj[k] = v
|
|
end
|
|
end
|
|
return obj
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- used by several guis to show no selection adorn
|
|
local noSelectionObject = Util.Create'ImageLabel'
|
|
{
|
|
Image = "",
|
|
BackgroundTransparency = 1
|
|
};
|
|
|
|
|
|
-- MATH --
|
|
function clamp(low, high, input)
|
|
return math.max(low, math.min(high, input))
|
|
end
|
|
|
|
function ClampVector2(low, high, input)
|
|
return Vector2.new(clamp(low.x, high.x, input.x), clamp(low.y, high.y, input.y))
|
|
end
|
|
|
|
---- TWEENZ ----
|
|
local Linear = function(t, b, c, d)
|
|
if t >= d then return b + c end
|
|
|
|
return c*t/d + b
|
|
end
|
|
|
|
local EaseOutQuad = function(t, b, c, d)
|
|
if t >= d then return b + c end
|
|
|
|
t = t/d;
|
|
return -c * t*(t-2) + b
|
|
end
|
|
|
|
local EaseInOutQuad = function(t, b, c, d)
|
|
if t >= d then return b + c end
|
|
|
|
t = t / (d/2);
|
|
if (t < 1) then return c/2*t*t + b end;
|
|
t = t - 1;
|
|
return -c/2 * (t*(t-2) - 1) + b;
|
|
end
|
|
|
|
function PropertyTweener(instance, prop, start, final, duration, easingFunc, cbFunc)
|
|
local this = {}
|
|
this.StartTime = tick()
|
|
this.EndTime = this.StartTime + duration
|
|
this.Cancelled = false
|
|
|
|
local finished = false
|
|
local percentComplete = 0
|
|
|
|
local function finalize()
|
|
if instance then
|
|
instance[prop] = easingFunc(1, start, final - start, 1)
|
|
end
|
|
finished = true
|
|
percentComplete = 1
|
|
if cbFunc then
|
|
cbFunc()
|
|
end
|
|
end
|
|
|
|
-- Initial set
|
|
instance[prop] = easingFunc(0, start, final - start, duration)
|
|
spawn(function()
|
|
local now = tick()
|
|
while now < this.EndTime and instance do
|
|
if this.Cancelled then
|
|
return
|
|
end
|
|
instance[prop] = easingFunc(now - this.StartTime, start, final - start, duration)
|
|
percentComplete = clamp(0, 1, (now - this.StartTime) / duration)
|
|
RunService.RenderStepped:wait()
|
|
now = tick()
|
|
end
|
|
if this.Cancelled == false and instance then
|
|
finalize()
|
|
end
|
|
end)
|
|
|
|
function this:GetFinal()
|
|
return final
|
|
end
|
|
|
|
function this:GetPercentComplete()
|
|
return percentComplete
|
|
end
|
|
|
|
function this:IsFinished()
|
|
return finished
|
|
end
|
|
|
|
function this:Finish()
|
|
if not finished then
|
|
self:Cancel()
|
|
finalize()
|
|
end
|
|
end
|
|
|
|
function this:Cancel()
|
|
this.Cancelled = true
|
|
end
|
|
|
|
return this
|
|
end
|
|
|
|
----------- CLASS DECLARATION --------------
|
|
|
|
local function CreateSignal()
|
|
local sig = {}
|
|
|
|
local mSignaler = Instance.new('BindableEvent')
|
|
|
|
local mArgData = nil
|
|
local mArgDataCount = nil
|
|
|
|
function sig:fire(...)
|
|
mArgData = {...}
|
|
mArgDataCount = select('#', ...)
|
|
mSignaler:Fire()
|
|
end
|
|
|
|
function sig:connect(f)
|
|
if not f then error("connect(nil)", 2) end
|
|
return mSignaler.Event:connect(function()
|
|
f(unpack(mArgData, 1, mArgDataCount))
|
|
end)
|
|
end
|
|
|
|
function sig:wait()
|
|
mSignaler.Event:wait()
|
|
assert(mArgData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
|
|
return unpack(mArgData, 1, mArgDataCount)
|
|
end
|
|
|
|
return sig
|
|
end
|
|
|
|
local function getViewportSize()
|
|
while not game.Workspace.CurrentCamera do
|
|
game.Workspace.Changed:wait()
|
|
end
|
|
|
|
while game.Workspace.CurrentCamera.ViewportSize == Vector2.new(0,0) do
|
|
game.Workspace.CurrentCamera.Changed:wait()
|
|
end
|
|
|
|
return game.Workspace.CurrentCamera.ViewportSize
|
|
end
|
|
|
|
local function isSmallTouchScreen()
|
|
return UserInputService.TouchEnabled and getViewportSize().Y <= 500
|
|
end
|
|
|
|
local function isTenFootInterface()
|
|
return tenFootInterfaceEnabled
|
|
end
|
|
|
|
local function usesSelectedObject()
|
|
if UserInputService.TouchEnabled and not UserInputService.GamepadEnabled then return false end
|
|
|
|
return true
|
|
end
|
|
|
|
local function isPosOverGui(pos, gui, debug) -- does not account for rotation
|
|
local ax, ay = gui.AbsolutePosition.x, gui.AbsolutePosition.y
|
|
local sx, sy = gui.AbsoluteSize.x, gui.AbsoluteSize.y
|
|
local bx, by = ax+sx, ay+sy
|
|
|
|
if pos.x > ax and pos.x < bx and pos.y > ay and pos.y < by then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
local function isPosOverGuiWithClipping(pos, gui) -- isPosOverGui, accounts for clipping and visibility, does not account for rotation
|
|
if not isPosOverGui(pos, gui) then
|
|
return false
|
|
end
|
|
|
|
local clipping = false
|
|
local check = gui
|
|
while true do
|
|
if check == nil or (not check:IsA'GuiObject' and not check:IsA'LayerCollector') then
|
|
clipping = true
|
|
if check and check:IsA'CoreGui' then
|
|
clipping = false
|
|
end
|
|
break
|
|
end
|
|
|
|
if check:IsA'GuiObject' and not check.Visible then
|
|
clipping = true
|
|
break
|
|
end
|
|
if check:IsA'LayerCollector' or check.ClipsDescendants then
|
|
if not isPosOverGui(pos, check) then
|
|
clipping = true
|
|
break
|
|
end
|
|
end
|
|
|
|
check = check.Parent
|
|
end
|
|
|
|
if clipping then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function areGuisIntersecting(a, b) -- does not account for rotation
|
|
local aax, aay = a.AbsolutePosition.x, a.AbsolutePosition.y
|
|
local asx, asy = a.AbsoluteSize.x, a.AbsoluteSize.y
|
|
local abx, aby = aax+asx, aay+asy
|
|
local bax, bay = b.AbsolutePosition.x, b.AbsolutePosition.y
|
|
local bsx, bsy = b.AbsoluteSize.x, b.AbsoluteSize.y
|
|
local bbx, bby = bax+bsx, bay+bsy
|
|
|
|
local intersectingX = aax < bbx and abx > bax
|
|
local intersectingY = aay < bby and aby > bay
|
|
local intersecting = intersectingX and intersectingY
|
|
|
|
return intersecting
|
|
end
|
|
|
|
local function isGuiVisible(gui, debug) -- true if any part of the gui is visible on the screen, considers clipping, does not account for rotation
|
|
local clipping = false
|
|
local check = gui
|
|
while true do
|
|
if check == nil or not check:IsA'GuiObject' and not check:IsA'LayerCollector' then
|
|
clipping = true
|
|
if check and check:IsA'CoreGui' then
|
|
clipping = false
|
|
end
|
|
break
|
|
end
|
|
|
|
if check:IsA'GuiObject' and not check.Visible then
|
|
clipping = true
|
|
break
|
|
end
|
|
if check:IsA'LayerCollector' or check.ClipsDescendants then
|
|
if not areGuisIntersecting(check, gui) then
|
|
clipping = true
|
|
break
|
|
end
|
|
end
|
|
|
|
check = check.Parent
|
|
end
|
|
|
|
if clipping then
|
|
return false
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function MakeButton(name, text, size, clickFunc, pageRef, hubRef)
|
|
local SelectionOverrideObject = Util.Create'ImageLabel'
|
|
{
|
|
Image = "",
|
|
BackgroundTransparency = 1,
|
|
};
|
|
|
|
local button = Util.Create'ImageButton'
|
|
{
|
|
Name = name .. "Button",
|
|
Image = "ayaasset://textures/ui/Settings/MenuBarAssets/MenuButton.png",
|
|
ScaleType = Enum.ScaleType.Slice,
|
|
SliceCenter = Rect.new(8,6,46,44),
|
|
AutoButtonColor = false,
|
|
BackgroundTransparency = 1,
|
|
Size = size,
|
|
ZIndex = 2,
|
|
SelectionImageObject = SelectionOverrideObject
|
|
};
|
|
button.NextSelectionLeft = button
|
|
button.NextSelectionRight = button
|
|
|
|
local enabled = Util.Create'BoolValue'
|
|
{
|
|
Name = 'Enabled',
|
|
Parent = button,
|
|
Value = true
|
|
}
|
|
|
|
if clickFunc then
|
|
button.MouseButton1Click:connect(function()
|
|
local lastInputType = nil
|
|
pcall(function() lastInputType = UserInputService:GetLastInputType() end)
|
|
if lastInputType then
|
|
clickFunc(lastInputTypee == Enum.UserInputType.Gamepad1 or lastInputType == Enum.UserInputType.Gamepad2 or
|
|
lastInputType == Enum.UserInputType.Gamepad3 or lastInputType == Enum.UserInputType.Gamepad4)
|
|
else
|
|
clickFunc(false)
|
|
end
|
|
end)
|
|
end
|
|
|
|
local function isPointerInput(inputObject)
|
|
return (inputObject.UserInputType == Enum.UserInputType.MouseMovement or inputObject.UserInputType == Enum.UserInputType.Touch)
|
|
end
|
|
|
|
local function selectButton()
|
|
local hub = hubRef
|
|
if hub == nil then
|
|
if pageRef then
|
|
hub = pageRef.HubRef
|
|
end
|
|
end
|
|
|
|
if (hub and hub.Active or hub == nil) then
|
|
button.Image = "ayaasset://textures/ui/Settings/MenuBarAssets/MenuButtonSelected.png"
|
|
|
|
local scrollTo = button
|
|
if rowRef then
|
|
scrollTo = rowRef
|
|
end
|
|
if hub then
|
|
hub:ScrollToFrame(scrollTo)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function deselectButton()
|
|
button.Image = "ayaasset://textures/ui/Settings/MenuBarAssets/MenuButton.png"
|
|
end
|
|
|
|
local inputBegan1 = button.InputBegan:connect(function(inputObject)
|
|
if button.Selectable and isPointerInput(inputObject) then
|
|
selectButton()
|
|
end
|
|
end)
|
|
local inputEnded1 = button.InputEnded:connect(function(inputObject)
|
|
if button.Selectable and GuiService.SelectedCoreObject ~= button and isPointerInput(inputObject) then
|
|
deselectButton()
|
|
end
|
|
end)
|
|
|
|
|
|
local rowRef = nil
|
|
local function setRowRef(ref)
|
|
rowRef = ref
|
|
end
|
|
button.SelectionGained:connect(function()
|
|
selectButton()
|
|
end)
|
|
button.SelectionLost:connect(function()
|
|
deselectButton()
|
|
end)
|
|
|
|
local textLabel = Util.Create'TextLabel'
|
|
{
|
|
Name = name .. "TextLabel",
|
|
BackgroundTransparency = 1,
|
|
BorderSizePixel = 0,
|
|
Size = UDim2.new(1, 0, 1, -8),
|
|
Position = UDim2.new(0,0,0,0),
|
|
TextColor3 = Color3.new(1,1,1),
|
|
TextYAlignment = Enum.TextYAlignment.Center,
|
|
Font = Enum.Font.SourceSansBold,
|
|
FontSize = Enum.FontSize.Size24,
|
|
Text = text,
|
|
TextWrapped = true,
|
|
ZIndex = 2,
|
|
Parent = button
|
|
};
|
|
|
|
if isSmallTouchScreen() then
|
|
textLabel.FontSize = Enum.FontSize.Size18
|
|
elseif isTenFootInterface() then
|
|
textLabel.FontSize = Enum.FontSize.Size36
|
|
end
|
|
|
|
local guiServiceCon = GuiService.Changed:connect(function(prop)
|
|
if prop ~= "SelectedCoreObject" then return end
|
|
if not usesSelectedObject() then return end
|
|
|
|
if GuiService.SelectedCoreObject == nil or GuiService.SelectedCoreObject ~= button then
|
|
deselectButton()
|
|
return
|
|
end
|
|
|
|
if button.Selectable then
|
|
selectButton()
|
|
end
|
|
end)
|
|
|
|
return button, textLabel, setRowRef
|
|
end
|
|
|
|
local function CreateDropDown(dropDownStringTable, startPosition, settingsHub, dropDownText)
|
|
-------------------- CONSTANTS ------------------------
|
|
local DEFAULT_DROPDOWN_TEXT = "Choose One"
|
|
local SCROLLING_FRAME_PIXEL_OFFSET = 25
|
|
local SELECTION_TEXT_COLOR_NORMAL = Color3.new(0.7,0.7,0.7)
|
|
local SELECTION_TEXT_COLOR_HIGHLIGHTED = Color3.new(1,1,1)
|
|
|
|
-------------------- VARIABLES ------------------------
|
|
local lastSelectedCoreObject= nil
|
|
|
|
-------------------- SETUP ------------------------
|
|
local this = {}
|
|
this.CurrentIndex = nil
|
|
|
|
local indexChangedEvent = Instance.new("BindableEvent")
|
|
indexChangedEvent.Name = "IndexChanged"
|
|
|
|
if type(dropDownStringTable) ~= "table" then
|
|
error("CreateDropDown dropDownStringTable (first arg) is not a table")
|
|
return this
|
|
end
|
|
|
|
local indexChangedEvent = Instance.new("BindableEvent")
|
|
indexChangedEvent.Name = "IndexChanged"
|
|
|
|
local interactable = true
|
|
local guid = HttpService:GenerateGUID(false)
|
|
local dropDownButtonEnabled
|
|
|
|
this.CurrentIndex = 0
|
|
|
|
----------------- GUI SETUP ------------------------
|
|
local DropDownFullscreenFrame = Util.Create'ImageButton'
|
|
{
|
|
Name = "DropDownFullscreenFrame",
|
|
BackgroundTransparency = 0.2,
|
|
BorderSizePixel = 0,
|
|
Size = UDim2.new(1, 0, 1, 0),
|
|
BackgroundColor3 = Color3.new(0,0,0),
|
|
ZIndex = 10,
|
|
Active = true,
|
|
Visible = false,
|
|
Selectable = false,
|
|
AutoButtonColor = false,
|
|
Parent = CoreGui.RobloxGui
|
|
};
|
|
|
|
local DropDownSelectionFrame = Util.Create'ImageLabel'
|
|
{
|
|
Name = "DropDownSelectionFrame",
|
|
Image = "ayaasset://textures/ui/Settings/MenuBarAssets/MenuButton.png",
|
|
ScaleType = Enum.ScaleType.Slice,
|
|
SliceCenter = Rect.new(8,6,46,44),
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0, 400, 0.9, 0),
|
|
Position = UDim2.new(0.5, -200, 0.05, 0),
|
|
ZIndex = 10,
|
|
Parent = DropDownFullscreenFrame
|
|
};
|
|
|
|
local DropDownScrollingFrame = Util.Create'ScrollingFrame'
|
|
{
|
|
Name = "DropDownScrollingFrame",
|
|
BackgroundTransparency = 1,
|
|
BorderSizePixel = 0,
|
|
Size = UDim2.new(1, -20, 1, -SCROLLING_FRAME_PIXEL_OFFSET),
|
|
Position = UDim2.new(0, 10, 0, 10),
|
|
ZIndex = 10,
|
|
Parent = DropDownSelectionFrame
|
|
};
|
|
|
|
local guiServiceChangeCon = nil
|
|
local active = false
|
|
local hideDropDownSelection = function(name, inputState)
|
|
if name ~= nil and inputState ~= Enum.UserInputState.Begin then return end
|
|
this.DropDownFrame.Selectable = interactable
|
|
|
|
if DropDownFullscreenFrame.Visible and usesSelectedObject() then
|
|
GuiService.SelectedCoreObject = lastSelectedCoreObject
|
|
end
|
|
DropDownFullscreenFrame.Visible = false
|
|
if guiServiceChangeCon then guiServiceChangeCon:disconnect() end
|
|
ContextActionService:UnbindCoreAction(guid .. "Action")
|
|
ContextActionService:UnbindCoreAction(guid .. "FreezeAction")
|
|
|
|
if settingsHub then
|
|
settingsHub:SetActive(true)
|
|
end
|
|
|
|
dropDownButtonEnabled.Value = interactable
|
|
active = false
|
|
end
|
|
|
|
local noOpFunc = function() end
|
|
|
|
local DropDownFrameClicked = function()
|
|
if not interactable then return end
|
|
|
|
this.DropDownFrame.Selectable = false
|
|
active = true
|
|
|
|
DropDownFullscreenFrame.Visible = true
|
|
if not this.CurrentIndex then this.CurrentIndex = 1 end
|
|
if this.CurrentIndex <= 0 then this.CurrentIndex = 1 end
|
|
|
|
lastSelectedCoreObject = this.DropDownFrame
|
|
GuiService.SelectedCoreObject = this.Selections[this.CurrentIndex]
|
|
|
|
guiServiceChangeCon = GuiService.Changed:connect(function(prop)
|
|
if not prop == "SelectedCoreObject" then return end
|
|
for i = 1, #this.Selections do
|
|
if GuiService.SelectedCoreObject == this.Selections[i] then
|
|
this.Selections[i].TextColor3 = SELECTION_TEXT_COLOR_HIGHLIGHTED
|
|
else
|
|
this.Selections[i].TextColor3 = SELECTION_TEXT_COLOR_NORMAL
|
|
end
|
|
end
|
|
end)
|
|
|
|
ContextActionService:BindCoreAction(guid .. "FreezeAction", noOpFunc, false, Enum.UserInputType.Keyboard, Enum.UserInputType.Gamepad1)
|
|
ContextActionService:BindCoreAction(guid .. "Action", hideDropDownSelection, false, Enum.KeyCode.ButtonB, Enum.KeyCode.Escape)
|
|
|
|
if settingsHub then
|
|
settingsHub:SetActive(false)
|
|
end
|
|
|
|
dropDownButtonEnabled.Value = false
|
|
end
|
|
|
|
local dropDownFrameSize = UDim2.new(0,400,0,44)
|
|
if isSmallTouchScreen() then
|
|
dropDownFrameSize = UDim2.new(0,300,0,44)
|
|
end
|
|
local overrideText = DEFAULT_DROPDOWN_TEXT
|
|
if not dropDownText == nil then
|
|
overrideText = dropDownText
|
|
end
|
|
this.DropDownFrame = MakeButton("DropDownFrame", overrideText, dropDownFrameSize, DropDownFrameClicked)
|
|
dropDownButtonEnabled = this.DropDownFrame.Enabled
|
|
local selectedTextLabel = this.DropDownFrame.DropDownFrameTextLabel
|
|
local dropDownImage = Util.Create'ImageLabel'
|
|
{
|
|
Name = "DropDownImage",
|
|
Image = "ayaasset://textures/ui/Settings/DropDown/DropDown.png",
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0,15,0,10),
|
|
Position = UDim2.new(1, -45,0.5,-7),
|
|
ZIndex = 2,
|
|
Parent = this.DropDownFrame
|
|
};
|
|
|
|
|
|
---------------------- FUNCTIONS -----------------------------------
|
|
local function setSelection(index)
|
|
local shouldFireChanged = false
|
|
for i, selectionLabel in pairs(this.Selections) do
|
|
if i == index then
|
|
selectedTextLabel.Text = selectionLabel.Text
|
|
this.CurrentIndex = i
|
|
|
|
shouldFireChanged = true
|
|
end
|
|
end
|
|
|
|
if shouldFireChanged then
|
|
indexChangedEvent:Fire(index)
|
|
end
|
|
end
|
|
|
|
local function setSelectionByValue(value)
|
|
local shouldFireChanged = false
|
|
for i, selectionLabel in pairs(this.Selections) do
|
|
if selectionLabel.Text == value then
|
|
selectedTextLabel.Text = selectionLabel.Text
|
|
this.CurrentIndex = i
|
|
|
|
shouldFireChanged = true
|
|
end
|
|
end
|
|
|
|
if shouldFireChanged then
|
|
indexChangedEvent:Fire(this.CurrentIndex)
|
|
end
|
|
return shouldFireChanged
|
|
end
|
|
|
|
local enterIsDown = false
|
|
local function processInput(input)
|
|
if input.UserInputState == Enum.UserInputState.Begin then
|
|
if input.KeyCode == Enum.KeyCode.Return then
|
|
if GuiService.SelectedCoreObject == this.DropDownFrame or this.SelectionInfo and this.SelectionInfo[GuiService.SelectedCoreObject] then
|
|
enterIsDown = true
|
|
end
|
|
end
|
|
elseif input.UserInputState == Enum.UserInputState.End then
|
|
if input.KeyCode == Enum.KeyCode.Return and enterIsDown then
|
|
enterIsDown = false
|
|
if GuiService.SelectedCoreObject == this.DropDownFrame then
|
|
DropDownFrameClicked()
|
|
elseif this.SelectionInfo and this.SelectionInfo[GuiService.SelectedCoreObject] then
|
|
local info = this.SelectionInfo[GuiService.SelectedCoreObject]
|
|
info.Clicked()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--------------------- PUBLIC FACING FUNCTIONS -----------------------
|
|
this.IndexChanged = indexChangedEvent.Event
|
|
|
|
function this:SetSelectionIndex(newIndex)
|
|
setSelection(newIndex)
|
|
end
|
|
|
|
function this:SetSelectionByValue(value)
|
|
return setSelectionByValue(value)
|
|
end
|
|
|
|
function this:ResetSelectionIndex()
|
|
this.CurrentIndex = nil
|
|
selectedTextLabel.Text = DEFAULT_DROPDOWN_TEXT
|
|
hideDropDownSelection()
|
|
end
|
|
|
|
function this:GetSelectedIndex()
|
|
return this.CurrentIndex
|
|
end
|
|
|
|
function this:SetZIndex(newZIndex)
|
|
this.DropDownFrame.ZIndex = newZIndex
|
|
dropDownImage.ZIndex = newZIndex
|
|
selectedTextLabel.ZIndex = newZIndex
|
|
end
|
|
|
|
function this:SetInteractable(value)
|
|
interactable = value
|
|
this.DropDownFrame.Selectable = interactable
|
|
|
|
if not interactable then
|
|
hideDropDownSelection()
|
|
this:SetZIndex(1)
|
|
else
|
|
this:SetZIndex(2)
|
|
end
|
|
|
|
dropDownButtonEnabled.Value = value and not active
|
|
end
|
|
|
|
|
|
function this:UpdateDropDownList(dropDownStringTable)
|
|
if this.Selections then
|
|
for i = 1, #this.Selections do
|
|
this.Selections[i]:Destroy()
|
|
end
|
|
end
|
|
|
|
this.Selections = {}
|
|
this.SelectionInfo = {}
|
|
|
|
for i,v in pairs(dropDownStringTable) do
|
|
local SelectionOverrideObject = Util.Create'Frame'
|
|
{
|
|
BackgroundTransparency = 0.7,
|
|
BorderSizePixel = 0,
|
|
Size = UDim2.new(1, 0, 1, 0)
|
|
};
|
|
|
|
local nextSelection = Util.Create'TextButton'
|
|
{
|
|
Name = "Selection" .. tostring(i),
|
|
BackgroundTransparency = 1,
|
|
BorderSizePixel = 0,
|
|
AutoButtonColor = false,
|
|
Size = UDim2.new(1, -28, 0, 50),
|
|
Position = UDim2.new(0,14,0, (i - 1) * 51),
|
|
TextColor3 = SELECTION_TEXT_COLOR_NORMAL,
|
|
Font = Enum.Font.SourceSans,
|
|
FontSize = Enum.FontSize.Size24,
|
|
Text = v,
|
|
ZIndex = 10,
|
|
SelectionImageObject = SelectionOverrideObject,
|
|
Parent = DropDownScrollingFrame
|
|
};
|
|
|
|
if i == startPosition then
|
|
this.CurrentIndex = i
|
|
selectedTextLabel.Text = v
|
|
nextSelection.TextColor3 = SELECTION_TEXT_COLOR_HIGHLIGHTED
|
|
elseif not startPosition and i == 1 then
|
|
nextSelection.TextColor3 = SELECTION_TEXT_COLOR_HIGHLIGHTED
|
|
end
|
|
|
|
local clicked = function()
|
|
selectedTextLabel.Text = nextSelection.Text
|
|
hideDropDownSelection()
|
|
this.CurrentIndex = i
|
|
indexChangedEvent:Fire(i)
|
|
end
|
|
|
|
nextSelection.MouseButton1Click:connect(clicked)
|
|
|
|
nextSelection.MouseEnter:connect(function()
|
|
if usesSelectedObject() then
|
|
GuiService.SelectedCoreObject = nextSelection
|
|
end
|
|
end)
|
|
|
|
this.Selections[i] = nextSelection
|
|
this.SelectionInfo[nextSelection] = {Clicked = clicked}
|
|
end
|
|
|
|
GuiService:RemoveSelectionGroup(guid)
|
|
GuiService:AddSelectionTuple(guid, unpack(this.Selections))
|
|
|
|
DropDownScrollingFrame.CanvasSize = UDim2.new(1,-20,0,#dropDownStringTable * 51)
|
|
|
|
local function updateDropDownSize()
|
|
if DropDownScrollingFrame.CanvasSize.Y.Offset < (DropDownFullscreenFrame.AbsoluteSize.Y - 10) then
|
|
DropDownSelectionFrame.Size = UDim2.new(DropDownSelectionFrame.Size.X.Scale, DropDownSelectionFrame.Size.X.Offset,
|
|
0,DropDownScrollingFrame.CanvasSize.Y.Offset + SCROLLING_FRAME_PIXEL_OFFSET)
|
|
DropDownSelectionFrame.Position = UDim2.new(DropDownSelectionFrame.Position.X.Scale, DropDownSelectionFrame.Position.X.Offset,
|
|
0.5, -DropDownSelectionFrame.Size.Y.Offset/2)
|
|
else
|
|
DropDownSelectionFrame.Size = UDim2.new(0, 400, 0.9, 0)
|
|
DropDownSelectionFrame.Position = UDim2.new(0.5, -200, 0.05, 0)
|
|
end
|
|
end
|
|
|
|
DropDownFullscreenFrame.Changed:connect(function(prop)
|
|
if prop ~= "AbsoluteSize" then return end
|
|
updateDropDownSize()
|
|
end)
|
|
|
|
updateDropDownSize()
|
|
end
|
|
|
|
----------------------- CONNECTIONS/SETUP --------------------------------
|
|
this:UpdateDropDownList(dropDownStringTable)
|
|
|
|
DropDownFullscreenFrame.MouseButton1Click:connect(hideDropDownSelection)
|
|
|
|
if settingsHub then
|
|
settingsHub.PoppedMenu:connect(function(poppedMenu)
|
|
if poppedMenu == DropDownFullscreenFrame then
|
|
hideDropDownSelection()
|
|
end
|
|
end)
|
|
end
|
|
|
|
local inputBegan2 = UserInputService.InputBegan:connect(processInput)
|
|
local inputEnded2 = UserInputService.InputEnded:connect(processInput)
|
|
|
|
|
|
return this
|
|
end
|
|
|
|
|
|
local function CreateSelector(selectionStringTable, startPosition)
|
|
|
|
-------------------- VARIABLES ------------------------
|
|
local lastInputDirection = 0
|
|
local TweenTime = 0.15
|
|
|
|
-------------------- SETUP ------------------------
|
|
local this = {}
|
|
this.HubRef = nil
|
|
|
|
if type(selectionStringTable) ~= "table" then
|
|
error("CreateSelector selectionStringTable (first arg) is not a table")
|
|
return this
|
|
end
|
|
|
|
local indexChangedEvent = Instance.new("BindableEvent")
|
|
indexChangedEvent.Name = "IndexChanged"
|
|
|
|
local interactable = true
|
|
|
|
this.CurrentIndex = 0
|
|
|
|
----------------- GUI SETUP ------------------------
|
|
this.SelectorFrame = Util.Create'ImageButton'
|
|
{
|
|
Name = "Selector",
|
|
Image = "",
|
|
AutoButtonColor = false,
|
|
NextSelectionLeft = this.SelectorFrame,
|
|
NextSelectionRight = this.SelectorFrame,
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0,502,0,50),
|
|
ZIndex = 2,
|
|
SelectionImageObject = noSelectionObject
|
|
};
|
|
if isSmallTouchScreen() then
|
|
this.SelectorFrame.Size = UDim2.new(0,400,0,50)
|
|
end
|
|
|
|
local leftButton = Util.Create'ImageButton'
|
|
{
|
|
Name = "LeftButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(0,-10,0.5,-25),
|
|
Size = UDim2.new(0,60,0,50),
|
|
Image = "",
|
|
ZIndex = 3,
|
|
Selectable = false,
|
|
Active = true,
|
|
Parent = this.SelectorFrame
|
|
};
|
|
local rightButton = Util.Create'ImageButton'
|
|
{
|
|
Name = "RightButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(1,-50,0.5,-25),
|
|
Size = UDim2.new(0,50,0,50),
|
|
Image = "",
|
|
ZIndex = 3,
|
|
Selectable = false,
|
|
Parent = this.SelectorFrame
|
|
};
|
|
|
|
local leftButtonImage = Util.Create'ImageLabel'
|
|
{
|
|
Name = "LeftButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(1,-24,0.5,-15),
|
|
Size = UDim2.new(0,18,0,30),
|
|
Image = "ayaasset://textures/ui/Settings/Slider/Left.png",
|
|
ZIndex = 2,
|
|
Active = true,
|
|
Parent = leftButton
|
|
};
|
|
local rightButtonImage = Util.Create'ImageLabel'
|
|
{
|
|
Name = "RightButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(0,6,0.5,-15),
|
|
Size = UDim2.new(0,18,0,30),
|
|
Image = "ayaasset://textures/ui/Settings/Slider/Right.png",
|
|
ZIndex = 2,
|
|
Parent = rightButton
|
|
};
|
|
|
|
|
|
this.Selections = {}
|
|
local isSelectionLabelVisible = {}
|
|
local isAutoSelectButton = {}
|
|
|
|
for i,v in pairs(selectionStringTable) do
|
|
local nextSelection = Util.Create'TextLabel'
|
|
{
|
|
Name = "Selection" .. tostring(i),
|
|
BackgroundTransparency = 1,
|
|
BorderSizePixel = 0,
|
|
Size = UDim2.new(1,leftButton.Size.X.Offset * -2, 1, 0),
|
|
Position = UDim2.new(1,0,0,0),
|
|
TextColor3 = Color3.new(1,1,1),
|
|
TextYAlignment = Enum.TextYAlignment.Center,
|
|
TextTransparency = 0.5,
|
|
Font = Enum.Font.SourceSans,
|
|
FontSize = Enum.FontSize.Size24,
|
|
Text = v,
|
|
ZIndex = 2,
|
|
Visible = false,
|
|
Parent = this.SelectorFrame
|
|
};
|
|
if isTenFootInterface() then
|
|
nextSelection.FontSize = Enum.FontSize.Size36
|
|
end
|
|
|
|
if i == startPosition then
|
|
this.CurrentIndex = i
|
|
nextSelection.Position = UDim2.new(0,leftButton.Size.X.Offset,0,0)
|
|
nextSelection.Visible = true
|
|
|
|
isSelectionLabelVisible[nextSelection] = true
|
|
else
|
|
isSelectionLabelVisible[nextSelection] = false
|
|
end
|
|
|
|
local autoSelectButton = Util.Create'ImageButton'{
|
|
Name = 'AutoSelectButton',
|
|
BackgroundTransparency = 1,
|
|
Image = '',
|
|
Size = UDim2.new(1, 0, 1, 0),
|
|
Parent = nextSelection,
|
|
ZIndex = 2
|
|
}
|
|
autoSelectButton.MouseButton1Click:connect(function()
|
|
local newIndex = this.CurrentIndex + 1
|
|
if newIndex > #this.Selections then
|
|
newIndex = 1
|
|
end
|
|
this:SetSelectionIndex(newIndex)
|
|
if usesSelectedObject() then
|
|
GuiService.SelectedCoreObject = this.SelectorFrame
|
|
end
|
|
end)
|
|
isAutoSelectButton[autoSelectButton] = true
|
|
|
|
this.Selections[i] = nextSelection
|
|
end
|
|
|
|
|
|
---------------------- FUNCTIONS -----------------------------------
|
|
local function setSelection(index, direction)
|
|
for i, selectionLabel in pairs(this.Selections) do
|
|
local isSelected = (i == index)
|
|
|
|
if not selectionLabel:IsDescendantOf(game) then
|
|
this.CurrentIndex = i
|
|
indexChangedEvent:Fire(index)
|
|
return
|
|
end
|
|
|
|
local tweenPos = UDim2.new(0,leftButton.Size.X.Offset * direction * 3,0,0)
|
|
if isSelectionLabelVisible[selectionLabel] then
|
|
tweenPos = UDim2.new(0,leftButton.Size.X.Offset * -direction * 3,0,0)
|
|
end
|
|
|
|
if tweenPos.X.Offset < 0 then
|
|
tweenPos = UDim2.new(0,tweenPos.X.Offset + (selectionLabel.AbsoluteSize.X/4),0,0)
|
|
end
|
|
|
|
if isSelected then
|
|
isSelectionLabelVisible[selectionLabel] = true
|
|
selectionLabel.Position = tweenPos
|
|
selectionLabel.Visible = true
|
|
PropertyTweener(selectionLabel, "TextTransparency", 1, 0, TweenTime * 1.1, EaseOutQuad)
|
|
selectionLabel:TweenPosition(UDim2.new(0,leftButton.Size.X.Offset,0,0), Enum.EasingDirection.In, Enum.EasingStyle.Quad, TweenTime, true)
|
|
this.CurrentIndex = i
|
|
indexChangedEvent:Fire(index)
|
|
elseif isSelectionLabelVisible[selectionLabel] then
|
|
isSelectionLabelVisible[selectionLabel] = false
|
|
PropertyTweener(selectionLabel, "TextTransparency", 0, 1, TweenTime * 1.1, EaseOutQuad)
|
|
selectionLabel:TweenPosition(tweenPos, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, TweenTime * 0.9, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function stepFunc(inputObject, step)
|
|
if not interactable then return end
|
|
|
|
if inputObject ~= nil and inputObject.UserInputType ~= Enum.UserInputType.MouseButton1 and
|
|
inputObject.UserInputType ~= Enum.UserInputType.Gamepad1 and inputObject.UserInputType ~= Enum.UserInputType.Gamepad2 and
|
|
inputObject.UserInputType ~= Enum.UserInputType.Gamepad3 and inputObject.UserInputType ~= Enum.UserInputType.Gamepad4 and
|
|
inputObject.UserInputType ~= Enum.UserInputType.Keyboard then return end
|
|
|
|
if usesSelectedObject() then
|
|
GuiService.SelectedCoreObject = this.SelectorFrame
|
|
end
|
|
|
|
local newIndex = step + this.CurrentIndex
|
|
|
|
local direction = 0
|
|
if newIndex > this.CurrentIndex then
|
|
direction = 1
|
|
else
|
|
direction = -1
|
|
end
|
|
|
|
if newIndex > #this.Selections then
|
|
newIndex = 1
|
|
elseif newIndex < 1 then
|
|
newIndex = #this.Selections
|
|
end
|
|
|
|
setSelection(newIndex, direction)
|
|
end
|
|
|
|
local guiServiceCon = nil
|
|
local function connectToGuiService()
|
|
guiServiceCon = GuiService.Changed:connect(function(prop)
|
|
if prop == "SelectedCoreObject" then
|
|
if GuiService.SelectedCoreObject == this.SelectorFrame then
|
|
this.Selections[this.CurrentIndex].TextTransparency = 0
|
|
else
|
|
if GuiService.SelectedCoreObject ~= nil and isAutoSelectButton[GuiService.SelectedCoreObject] then
|
|
GuiService.SelectedCoreObject = this.SelectorFrame
|
|
else
|
|
this.Selections[this.CurrentIndex].TextTransparency = 0.5
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
--------------------- PUBLIC FACING FUNCTIONS -----------------------
|
|
this.IndexChanged = indexChangedEvent.Event
|
|
|
|
function this:SetSelectionIndex(newIndex)
|
|
setSelection(newIndex, 1)
|
|
end
|
|
|
|
function this:GetSelectedIndex()
|
|
return this.CurrentIndex
|
|
end
|
|
|
|
function this:SetZIndex(newZIndex)
|
|
leftButton.ZIndex = newZIndex
|
|
rightButton.ZIndex = newZIndex
|
|
leftButtonImage.ZIndex = newZIndex
|
|
rightButtonImage.ZIndex = newZIndex
|
|
|
|
for i = 1, #this.Selections do
|
|
this.Selections[i].ZIndex = newZIndex
|
|
end
|
|
end
|
|
|
|
function this:SetInteractable(value)
|
|
interactable = value
|
|
this.SelectorFrame.Selectable = interactable
|
|
end
|
|
|
|
--------------------- SETUP -----------------------
|
|
leftButton.InputBegan:connect(function(inputObject)
|
|
if inputObject.UserInputType == Enum.UserInputType.Touch then
|
|
stepFunc(nil, -1)
|
|
end
|
|
end)
|
|
leftButton.MouseButton1Click:connect(function()
|
|
if not UserInputService.TouchEnabled then
|
|
stepFunc(nil, -1)
|
|
end
|
|
end)
|
|
rightButton.InputBegan:connect(function(inputObject)
|
|
if inputObject.UserInputType == Enum.UserInputType.Touch then
|
|
stepFunc(nil, 1)
|
|
end
|
|
end)
|
|
rightButton.MouseButton1Click:connect(function()
|
|
if not UserInputService.TouchEnabled then
|
|
stepFunc(nil, 1)
|
|
end
|
|
end)
|
|
|
|
local isInTree = true
|
|
|
|
UserInputService.InputBegan:connect(function(inputObject)
|
|
if not interactable then return end
|
|
if not isInTree then return end
|
|
|
|
if inputObject.UserInputType ~= Enum.UserInputType.Gamepad1 and inputObject.UserInputType ~= Enum.UserInputType.Keyboard then return end
|
|
if GuiService.SelectedCoreObject ~= this.SelectorFrame then return end
|
|
|
|
if inputObject.KeyCode == Enum.KeyCode.DPadLeft or inputObject.KeyCode == Enum.KeyCode.Left or inputObject.KeyCode == Enum.KeyCode.A then
|
|
stepFunc(inputObject, -1)
|
|
elseif inputObject.KeyCode == Enum.KeyCode.DPadRight or inputObject.KeyCode == Enum.KeyCode.Right or inputObject.KeyCode == Enum.KeyCode.D then
|
|
stepFunc(inputObject, 1)
|
|
end
|
|
end)
|
|
|
|
UserInputService.InputChanged:connect(function(inputObject)
|
|
if not interactable then return end
|
|
if not isInTree then lastInputDirection = 0 return end
|
|
|
|
if inputObject.UserInputType ~= Enum.UserInputType.Gamepad1 then return end
|
|
if GuiService.SelectedCoreObject ~= this.SelectorFrame then return end
|
|
if inputObject.KeyCode ~= Enum.KeyCode.Thumbstick1 then return end
|
|
|
|
|
|
if inputObject.Position.X > CONTROLLER_THUMBSTICK_DEADZONE and inputObject.Delta.X > 0 and lastInputDirection ~= 1 then
|
|
lastInputDirection = 1
|
|
stepFunc(inputObject, lastInputDirection)
|
|
elseif inputObject.Position.X < -CONTROLLER_THUMBSTICK_DEADZONE and inputObject.Delta.X < 0 and lastInputDirection ~= -1 then
|
|
lastInputDirection = -1
|
|
stepFunc(inputObject, lastInputDirection)
|
|
elseif math.abs(inputObject.Position.X) < CONTROLLER_THUMBSTICK_DEADZONE then
|
|
lastInputDirection = 0
|
|
end
|
|
end)
|
|
|
|
this.SelectorFrame.AncestryChanged:connect(function(child, parent)
|
|
isInTree = parent
|
|
if not isInTree then
|
|
if guiServiceCon then guiServiceCon:disconnect() end
|
|
else
|
|
connectToGuiService()
|
|
end
|
|
end)
|
|
|
|
connectToGuiService()
|
|
|
|
return this
|
|
end
|
|
|
|
local function ShowAlert(alertMessage, okButtonText, settingsHub, okPressedFunc, hasBackground)
|
|
if CoreGui.RobloxGui:FindFirstChild("AlertViewFullScreen") then return end
|
|
|
|
local NON_SELECTED_TEXT_COLOR = Color3.new(59/255, 166/255, 241/255)
|
|
local SELECTED_TEXT_COLOR = Color3.new(1,1,1)
|
|
|
|
local AlertViewBacking = Util.Create'ImageLabel'
|
|
{
|
|
Name = "AlertViewBacking",
|
|
Image = "ayaasset://textures/ui/Settings/MenuBarAssets/MenuButton.png",
|
|
ScaleType = Enum.ScaleType.Slice,
|
|
SliceCenter = Rect.new(8,6,46,44),
|
|
BackgroundTransparency = 1,
|
|
ImageTransparency = 1,
|
|
Size = UDim2.new(0, 400, 0, 350),
|
|
Position = UDim2.new(0.5, -200, 0.5, -175),
|
|
ZIndex = 9,
|
|
Parent = CoreGui.RobloxGui
|
|
};
|
|
if hasBackground then
|
|
AlertViewBacking.ImageTransparency = 0
|
|
else
|
|
AlertViewBacking.Size = UDim2.new(0.8, 0, 0, 350)
|
|
AlertViewBacking.Position = UDim2.new(0.1, 0, 0.1, 0)
|
|
end
|
|
|
|
if CoreGui.RobloxGui.AbsoluteSize.Y <= AlertViewBacking.Size.Y.Offset then
|
|
AlertViewBacking.Size = UDim2.new(AlertViewBacking.Size.X.Scale, AlertViewBacking.Size.X.Offset,
|
|
AlertViewBacking.Size.Y.Scale, CoreGui.RobloxGui.AbsoluteSize.Y)
|
|
AlertViewBacking.Position = UDim2.new(0.5, -AlertViewBacking.Size.X.Offset/2, 0.5, -AlertViewBacking.Size.Y.Offset/2)
|
|
end
|
|
|
|
local AlertViewText = Util.Create'TextLabel'
|
|
{
|
|
Name = "AlertViewText",
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0.95, 0, 0.6, 0),
|
|
Position = UDim2.new(0.025, 0, 0.05, 0),
|
|
Font = Enum.Font.SourceSansBold,
|
|
FontSize = Enum.FontSize.Size36,
|
|
Text = alertMessage,
|
|
TextWrapped = true,
|
|
TextColor3 = Color3.new(1,1,1),
|
|
TextXAlignment = Enum.TextXAlignment.Center,
|
|
TextYAlignment = Enum.TextYAlignment.Center,
|
|
ZIndex = 10,
|
|
Parent = AlertViewBacking
|
|
};
|
|
|
|
local SelectionOverrideObject = Util.Create'ImageLabel'
|
|
{
|
|
Image = "",
|
|
BackgroundTransparency = 1
|
|
};
|
|
|
|
local removeId = HttpService:GenerateGUID(false)
|
|
|
|
local destroyAlert = function()
|
|
AlertViewBacking:Destroy()
|
|
if okPressedFunc then
|
|
okPressedFunc()
|
|
end
|
|
ContextActionService:UnbindCoreAction(removeId)
|
|
Game.GuiService.SelectedCoreObject = nil
|
|
if settingsHub then
|
|
settingsHub:ShowBar()
|
|
end
|
|
end
|
|
|
|
local AlertViewButtonSize = UDim2.new(1, -20, 0, 60)
|
|
local AlertViewButtonPosition = UDim2.new(0, 10, 0.65, 0)
|
|
if not hasBackground then
|
|
AlertViewButtonSize = UDim2.new(0, 200, 0, 50)
|
|
AlertViewButtonPosition = UDim2.new(0.5, -100, 0.65, 0)
|
|
end
|
|
|
|
local AlertViewButton, AlertViewText = MakeButton("AlertViewButton", okButtonText, AlertViewButtonSize, destroyAlert)
|
|
AlertViewButton.Position = AlertViewButtonPosition
|
|
AlertViewButton.NextSelectionLeft = AlertViewButton
|
|
AlertViewButton.NextSelectionRight = AlertViewButton
|
|
AlertViewButton.NextSelectionUp = AlertViewButton
|
|
AlertViewButton.NextSelectionDown = AlertViewButton
|
|
AlertViewButton.ZIndex = 10
|
|
AlertViewText.ZIndex = AlertViewButton.ZIndex
|
|
AlertViewButton.Parent = AlertViewBacking
|
|
|
|
if usesSelectedObject() then
|
|
Game.GuiService.SelectedCoreObject = AlertViewButton
|
|
end
|
|
|
|
GuiService.SelectedCoreObject = AlertViewButton
|
|
|
|
ContextActionService:BindCoreAction(removeId, destroyAlert, false, Enum.KeyCode.Escape, Enum.KeyCode.ButtonB, Enum.KeyCode.ButtonA)
|
|
|
|
if settingsHub then
|
|
settingsHub:HideBar()
|
|
settingsHub.Pages.CurrentPage:Hide(1, 1)
|
|
end
|
|
end
|
|
|
|
local function CreateNewSlider(numOfSteps, startStep, minStep)
|
|
-------------------- SETUP ------------------------
|
|
local this = {}
|
|
|
|
local spacing = 4
|
|
local initialSpacing = 8
|
|
local steps = tonumber(numOfSteps)
|
|
local currentStep = startStep
|
|
|
|
local lastInputDirection = 0
|
|
local timeAtLastInput = nil
|
|
|
|
local interactable = true
|
|
|
|
local renderStepBindName = HttpService:GenerateGUID(false)
|
|
|
|
-- this is done to prevent using these values below (trying to keep the variables consistent)
|
|
numOfSteps = ""
|
|
startStep = ""
|
|
|
|
if steps <= 0 then
|
|
error("CreateNewSlider failed because numOfSteps (first arg) is 0 or negative, please supply a positive integer")
|
|
return
|
|
end
|
|
|
|
local valueChangedEvent = Instance.new("BindableEvent")
|
|
valueChangedEvent.Name = "ValueChanged"
|
|
|
|
----------------- GUI SETUP ------------------------
|
|
this.SliderFrame = Util.Create'ImageButton'
|
|
{
|
|
Name = "Slider",
|
|
Image = "",
|
|
AutoButtonColor = false,
|
|
NextSelectionLeft = this.SliderFrame,
|
|
NextSelectionRight = this.SliderFrame,
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0,502,0,50),
|
|
SelectionImageObject = noSelectionObject,
|
|
ZIndex = 2
|
|
};
|
|
if isSmallTouchScreen() then
|
|
this.SliderFrame.Size = UDim2.new(0,400,0,30)
|
|
end
|
|
|
|
local leftButton = Util.Create'ImageButton'
|
|
{
|
|
Name = "LeftButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(0,0,0.5,-25),
|
|
Size = UDim2.new(0,50,0,50),
|
|
Image = "",
|
|
ZIndex = 2,
|
|
Selectable = false,
|
|
Active = true,
|
|
Parent = this.SliderFrame
|
|
};
|
|
local rightButton = Util.Create'ImageButton'
|
|
{
|
|
Name = "RightButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(1,-50,0.5,-25),
|
|
Size = UDim2.new(0,50,0,50),
|
|
Image = "",
|
|
ZIndex = 2,
|
|
Selectable = false,
|
|
Active = true,
|
|
Parent = this.SliderFrame
|
|
};
|
|
|
|
local leftButtonImage = Util.Create'ImageLabel'
|
|
{
|
|
Name = "LeftButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(1,-24,0.5,-15),
|
|
Size = UDim2.new(0,18,0,30),
|
|
Image = "ayaasset://textures/ui/Settings/Slider/Left.png",
|
|
ZIndex = 2,
|
|
Parent = leftButton
|
|
};
|
|
local rightButtonImage = Util.Create'ImageLabel'
|
|
{
|
|
Name = "RightButton",
|
|
BackgroundTransparency = 1,
|
|
Position = UDim2.new(0,6,0.5,-15),
|
|
Size = UDim2.new(0,18,0,30),
|
|
Image = "ayaasset://textures/ui/Settings/Slider/Right.png",
|
|
ZIndex = 2,
|
|
Parent = rightButton
|
|
};
|
|
|
|
|
|
this.Steps = {}
|
|
local stepXSize = 35
|
|
if isSmallTouchScreen() then
|
|
stepXSize = 25
|
|
end
|
|
|
|
for i = 1, steps do
|
|
local nextStep = Util.Create'ImageButton'
|
|
{
|
|
Name = "Step" .. tostring(i),
|
|
BackgroundColor3 = SELECTED_COLOR,
|
|
BackgroundTransparency = 0.36,
|
|
BorderSizePixel = 0,
|
|
AutoButtonColor = false,
|
|
Active = false,
|
|
Position = UDim2.new(0,initialSpacing + leftButton.Size.X.Offset + ((stepXSize + spacing) * (i - 1)),0.5,-12),
|
|
Size = UDim2.new(0,stepXSize,0, 24),
|
|
Image = "",
|
|
ZIndex = 2,
|
|
Selectable = false,
|
|
ImageTransparency = 0.36,
|
|
Parent = this.SliderFrame
|
|
};
|
|
|
|
if i > currentStep then
|
|
nextStep.BackgroundColor3 = NON_SELECTED_COLOR
|
|
end
|
|
|
|
if i == 1 or i == steps then
|
|
nextStep.BackgroundTransparency = 1
|
|
nextStep.ScaleType = Enum.ScaleType.Slice
|
|
nextStep.SliceCenter = Rect.new(3,3,32,21)
|
|
|
|
if i <= currentStep then
|
|
if i == 1 then
|
|
nextStep.Image = SELECTED_LEFT_IMAGE
|
|
else
|
|
nextStep.Image = SELECTED_RIGHT_IMAGE
|
|
end
|
|
else
|
|
if i == 1 then
|
|
nextStep.Image = NON_SELECTED_LEFT_IMAGE
|
|
else
|
|
nextStep.Image = NON_SELECTED_RIGHT_IMAGE
|
|
end
|
|
end
|
|
end
|
|
|
|
this.Steps[#this.Steps + 1] = nextStep
|
|
end
|
|
|
|
local xSize = initialSpacing + (leftButton.Size.X.Offset) + this.Steps[#this.Steps].Size.X.Offset +
|
|
this.Steps[#this.Steps].Position.X.Offset
|
|
this.SliderFrame.Size = UDim2.new(0, xSize, 0, this.SliderFrame.Size.Y.Offset)
|
|
|
|
|
|
------------------- FUNCTIONS ---------------------
|
|
local function hideSelection()
|
|
for i = 1, steps do
|
|
this.Steps[i].BackgroundColor3 = NON_SELECTED_COLOR
|
|
if i == 1 then
|
|
this.Steps[i].Image = NON_SELECTED_LEFT_IMAGE
|
|
elseif i == steps then
|
|
this.Steps[i].Image = NON_SELECTED_RIGHT_IMAGE
|
|
end
|
|
end
|
|
end
|
|
local function showSelection()
|
|
for i = 1, steps do
|
|
if i > currentStep then break end
|
|
this.Steps[i].BackgroundColor3 = SELECTED_COLOR
|
|
if i == 1 then
|
|
this.Steps[i].Image = SELECTED_LEFT_IMAGE
|
|
elseif i == steps then
|
|
this.Steps[i].Image = SELECTED_RIGHT_IMAGE
|
|
end
|
|
end
|
|
end
|
|
local function modifySelection(alpha)
|
|
for i = 1, steps do
|
|
if i == 1 or i == steps then
|
|
this.Steps[i].ImageTransparency = alpha
|
|
else
|
|
this.Steps[i].BackgroundTransparency = alpha
|
|
end
|
|
end
|
|
end
|
|
|
|
local function setCurrentStep(newStepPosition)
|
|
if not minStep then minStep = 0 end
|
|
|
|
leftButton.Visible = true
|
|
rightButton.Visible = true
|
|
|
|
if newStepPosition <= minStep then
|
|
newStepPosition = minStep
|
|
leftButton.Visible = false
|
|
end
|
|
if newStepPosition >= steps then
|
|
newStepPosition = steps
|
|
rightButton.Visible = false
|
|
end
|
|
|
|
if currentStep == newStepPosition then return end
|
|
|
|
currentStep = newStepPosition
|
|
|
|
hideSelection()
|
|
showSelection()
|
|
|
|
timeAtLastInput = tick()
|
|
valueChangedEvent:Fire(currentStep)
|
|
end
|
|
|
|
local function mouseDownFunc(inputObject, newStepPos, repeatAction)
|
|
if not interactable then return end
|
|
|
|
if inputObject == nil then return end
|
|
if inputObject.UserInputType ~= Enum.UserInputType.MouseButton1 and inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
|
|
|
|
if usesSelectedObject() then
|
|
GuiService.SelectedCoreObject = this.SliderFrame
|
|
end
|
|
|
|
if repeatAction then
|
|
lastInputDirection = newStepPos - currentStep
|
|
else
|
|
lastInputDirection = 0
|
|
|
|
local mouseInputMovedCon = nil
|
|
local mouseInputEndedCon = nil
|
|
mouseInputMovedCon = UserInputService.InputChanged:connect(function( inputObject )
|
|
if inputObject.UserInputType ~= Enum.UserInputType.MouseMovement and inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
|
|
|
|
local mousePos = inputObject.Position.X
|
|
for i = 1, steps do
|
|
local stepPosition = this.Steps[i].AbsolutePosition.X
|
|
local stepSize = this.Steps[i].AbsoluteSize.X
|
|
if mousePos >= stepPosition and mousePos <= stepPosition + stepSize then
|
|
setCurrentStep(i)
|
|
break
|
|
elseif i == 1 and mousePos < stepPosition then
|
|
setCurrentStep(0)
|
|
break
|
|
elseif i == steps and mousePos >= stepPosition then
|
|
setCurrentStep(i)
|
|
break
|
|
end
|
|
end
|
|
end)
|
|
mouseInputEndedCon = UserInputService.InputEnded:connect(function( inputObject )
|
|
if inputObject.UserInputType ~= Enum.UserInputType.MouseButton1 and inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
|
|
|
|
lastInputDirection = 0
|
|
mouseInputEndedCon:disconnect()
|
|
mouseInputMovedCon:disconnect()
|
|
end)
|
|
|
|
end
|
|
|
|
setCurrentStep(newStepPos)
|
|
end
|
|
|
|
local function mouseUpFunc(inputObject)
|
|
if not interactable then return end
|
|
if inputObject.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
|
|
|
|
lastInputDirection = 0
|
|
end
|
|
|
|
local function touchClickFunc(inputObject, newStepPos, repeatAction)
|
|
mouseDownFunc(inputObject, newStepPos, repeatAction)
|
|
end
|
|
|
|
--------------------- PUBLIC FACING FUNCTIONS -----------------------
|
|
this.ValueChanged = valueChangedEvent.Event
|
|
|
|
function this:SetValue(newValue)
|
|
setCurrentStep(newValue)
|
|
end
|
|
|
|
function this:GetValue()
|
|
return currentStep
|
|
end
|
|
|
|
function this:SetInteractable(value)
|
|
lastInputDirection = 0
|
|
interactable = value
|
|
this.SliderFrame.Selectable = value
|
|
if not interactable then
|
|
hideSelection()
|
|
else
|
|
showSelection()
|
|
end
|
|
end
|
|
|
|
function this:SetZIndex(newZIndex)
|
|
leftButton.ZIndex = newZIndex
|
|
rightButton.ZIndex = newZIndex
|
|
leftButtonImage.ZIndex = newZIndex
|
|
rightButtonImage.ZIndex = newZIndex
|
|
|
|
for i = 1, #this.Steps do
|
|
this.Steps[i].ZIndex = newZIndex
|
|
end
|
|
end
|
|
|
|
function this:SetMinStep(newMinStep)
|
|
if newMinStep >= 0 and newMinStep <= steps then
|
|
minStep = newMinStep
|
|
end
|
|
|
|
if currentStep <= minStep then
|
|
currentStep = minStep
|
|
leftButton.Visible = false
|
|
end
|
|
if currentStep >= steps then
|
|
currentStep = steps
|
|
rightButton.Visible = false
|
|
end
|
|
end
|
|
|
|
--------------------- SETUP -----------------------
|
|
|
|
leftButton.InputBegan:connect(function(inputObject) mouseDownFunc(inputObject, currentStep - 1, true) end)
|
|
leftButton.InputEnded:connect(function(inputObject) mouseUpFunc(inputObject) end)
|
|
leftButton.MouseButton1Click:connect(function()
|
|
if UserInputService.TouchEnabled and not UserInputService.GamepadEnabled then
|
|
touchClickFunc(inputObject, currentStep - 1, true)
|
|
end
|
|
end)
|
|
rightButton.InputBegan:connect(function(inputObject) mouseDownFunc(inputObject, currentStep + 1, true) end)
|
|
rightButton.InputEnded:connect(function(inputObject) mouseUpFunc(inputObject) end)
|
|
rightButton.MouseButton1Click:connect(function()
|
|
if UserInputService.TouchEnabled and not UserInputService.GamepadEnabled then
|
|
touchClickFunc(inputObject, currentStep + 1, true)
|
|
end
|
|
end)
|
|
|
|
for i = 1, steps do
|
|
this.Steps[i].InputBegan:connect(function(inputObject) mouseDownFunc(inputObject, i) end)
|
|
this.Steps[i].InputEnded:connect(function(inputObject) mouseUpFunc(inputObject) end)
|
|
end
|
|
|
|
this.SliderFrame.InputBegan:connect(function(inputObject) mouseDownFunc(inputObject, currentStep) end)
|
|
this.SliderFrame.InputEnded:connect(function(inputObject) mouseUpFunc(inputObject) end)
|
|
|
|
|
|
local stepSliderFunc = function()
|
|
if timeAtLastInput == nil then return end
|
|
|
|
local currentTime = tick()
|
|
local timeSinceLastInput = currentTime - timeAtLastInput
|
|
|
|
if timeSinceLastInput >= CONTROLLER_SCROLL_DELTA then
|
|
setCurrentStep(currentStep + lastInputDirection)
|
|
end
|
|
end
|
|
|
|
local isInTree = true
|
|
UserInputService.InputBegan:connect(function(inputObject)
|
|
if not interactable then return end
|
|
if not isInTree then return end
|
|
|
|
if inputObject.UserInputType ~= Enum.UserInputType.Gamepad1 and inputObject.UserInputType ~= Enum.UserInputType.Keyboard then return end
|
|
if GuiService.SelectedCoreObject ~= this.SliderFrame then return end
|
|
|
|
if inputObject.KeyCode == Enum.KeyCode.DPadLeft or inputObject.KeyCode == Enum.KeyCode.Left or inputObject.KeyCode == Enum.KeyCode.A then
|
|
lastInputDirection = -1
|
|
setCurrentStep(currentStep - 1)
|
|
elseif inputObject.KeyCode == Enum.KeyCode.DPadRight or inputObject.KeyCode == Enum.KeyCode.Right or inputObject.KeyCode == Enum.KeyCode.D then
|
|
lastInputDirection = 1
|
|
setCurrentStep(currentStep + 1)
|
|
end
|
|
end)
|
|
|
|
local inputEnded3 = UserInputService.InputEnded:connect(function(inputObject)
|
|
if not interactable then return end
|
|
|
|
if inputObject.UserInputType ~= Enum.UserInputType.Gamepad1 and inputObject.UserInputType ~= Enum.UserInputType.Keyboard then return end
|
|
if GuiService.SelectedCoreObject ~= this.SliderFrame then return end
|
|
|
|
if inputObject.KeyCode == Enum.KeyCode.Thumbstick1 or inputObject.KeyCode == Enum.KeyCode.DPadLeft
|
|
or inputObject.KeyCode == Enum.KeyCode.DPadRight or inputObject.KeyCode == Enum.KeyCode.Left
|
|
or inputObject.KeyCode == Enum.KeyCode.A or inputObject.KeyCode == Enum.KeyCode.Right or inputObject.KeyCode == Enum.KeyCode.D then
|
|
lastInputDirection = 0
|
|
end
|
|
end)
|
|
|
|
UserInputService.InputChanged:connect(function(inputObject)
|
|
if not interactable then
|
|
lastInputDirection = 0
|
|
return
|
|
end
|
|
if not isInTree then
|
|
lastInputDirection = 0
|
|
return
|
|
end
|
|
|
|
if inputObject.UserInputType ~= Enum.UserInputType.Gamepad1 then return end
|
|
if GuiService.SelectedCoreObject ~= this.SliderFrame then return end
|
|
if inputObject.KeyCode ~= Enum.KeyCode.Thumbstick1 then return end
|
|
|
|
if inputObject.Position.X > CONTROLLER_THUMBSTICK_DEADZONE and inputObject.Delta.X > 0 and lastInputDirection ~= 1 then
|
|
lastInputDirection = 1
|
|
setCurrentStep(currentStep + 1)
|
|
elseif inputObject.Position.X < -CONTROLLER_THUMBSTICK_DEADZONE and inputObject.Delta.X < 0 and lastInputDirection ~= -1 then
|
|
lastInputDirection = -1
|
|
setCurrentStep(currentStep - 1)
|
|
elseif math.abs(inputObject.Position.X) < CONTROLLER_THUMBSTICK_DEADZONE then
|
|
lastInputDirection = 0
|
|
end
|
|
end)
|
|
|
|
GuiService.Changed:connect(function(prop)
|
|
if prop ~= "SelectedCoreObject" then return end
|
|
|
|
if GuiService.SelectedCoreObject == this.SliderFrame then
|
|
modifySelection(0)
|
|
RunService:BindToRenderStep(renderStepBindName, Enum.RenderPriority.Input.Value + 1, stepSliderFunc)
|
|
else
|
|
modifySelection(0.36)
|
|
RunService:UnbindFromRenderStep(renderStepBindName)
|
|
end
|
|
end)
|
|
|
|
this.SliderFrame.AncestryChanged:connect(function(child, parent)
|
|
isInTree = parent
|
|
end)
|
|
|
|
setCurrentStep(currentStep)
|
|
|
|
return this
|
|
end
|
|
|
|
local ROW_HEIGHT = 50
|
|
if isTenFootInterface() then ROW_HEIGHT = 90 end
|
|
|
|
local nextPosTable = {}
|
|
local function AddNewRow(pageToAddTo, rowDisplayName, selectionType, rowValues, rowDefault, extraSpacing)
|
|
local nextRowPositionY = 0
|
|
local isARealRow = selectionType ~= 'TextBox' -- Textboxes are constructed in this function - they don't have an associated class.
|
|
|
|
if nextPosTable[pageToAddTo] then
|
|
nextRowPositionY = nextPosTable[pageToAddTo]
|
|
end
|
|
|
|
local RowFrame = nil
|
|
RowFrame = Util.Create'ImageButton'
|
|
{
|
|
Name = rowDisplayName .. "Frame",
|
|
BackgroundTransparency = 1,
|
|
BorderSizePixel = 0,
|
|
Image = "",
|
|
Active = false,
|
|
AutoButtonColor = false,
|
|
Size = UDim2.new(1,0,0,ROW_HEIGHT),
|
|
Position = UDim2.new(0,0,0,nextRowPositionY),
|
|
ZIndex = 2,
|
|
Selectable = false,
|
|
Parent = pageToAddTo.Page
|
|
};
|
|
|
|
if RowFrame and extraSpacing then
|
|
RowFrame.Position = UDim2.new(RowFrame.Position.X.Scale,RowFrame.Position.X.Offset,
|
|
RowFrame.Position.Y.Scale,RowFrame.Position.Y.Offset + extraSpacing)
|
|
end
|
|
|
|
local RowLabel = nil
|
|
RowLabel = Util.Create'TextLabel'
|
|
{
|
|
Name = rowDisplayName .. "Label",
|
|
Text = rowDisplayName,
|
|
Font = Enum.Font.SourceSansBold,
|
|
FontSize = Enum.FontSize.Size24,
|
|
TextColor3 = Color3.new(1,1,1),
|
|
TextXAlignment = Enum.TextXAlignment.Left,
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0,200,1,0),
|
|
Position = UDim2.new(0,10,0,0),
|
|
ZIndex = 2,
|
|
Parent = RowFrame
|
|
};
|
|
if isTenFootInterface() then
|
|
RowLabel.FontSize = Enum.FontSize.Size36
|
|
end
|
|
if not isARealRow then
|
|
RowLabel.Text = ''
|
|
end
|
|
|
|
local ValueChangerSelection = nil
|
|
local ValueChangerInstance = nil
|
|
if selectionType == "Slider" then
|
|
ValueChangerInstance = CreateNewSlider(rowValues, rowDefault)
|
|
ValueChangerInstance.SliderFrame.Position = UDim2.new(1,-ValueChangerInstance.SliderFrame.Size.X.Offset,
|
|
0.5,-ValueChangerInstance.SliderFrame.Size.Y.Offset/2)
|
|
ValueChangerInstance.SliderFrame.Parent = RowFrame
|
|
ValueChangerSelection = ValueChangerInstance.SliderFrame
|
|
elseif selectionType == "Selector" then
|
|
ValueChangerInstance = CreateSelector(rowValues, rowDefault)
|
|
ValueChangerInstance.SelectorFrame.Position = UDim2.new(1,-ValueChangerInstance.SelectorFrame.Size.X.Offset,
|
|
0.5,-ValueChangerInstance.SelectorFrame.Size.Y.Offset/2)
|
|
ValueChangerInstance.SelectorFrame.Parent = RowFrame
|
|
ValueChangerSelection = ValueChangerInstance.SelectorFrame
|
|
elseif selectionType == "DropDown" then
|
|
ValueChangerInstance = CreateDropDown(rowValues, rowDefault, pageToAddTo.HubRef, nil, rowDefault)
|
|
ValueChangerInstance.DropDownFrame.Position = UDim2.new(1,-ValueChangerInstance.DropDownFrame.Size.X.Offset - 50,
|
|
0.5,-ValueChangerInstance.DropDownFrame.Size.Y.Offset/2)
|
|
ValueChangerInstance.DropDownFrame.Parent = RowFrame
|
|
ValueChangerSelection = ValueChangerInstance.DropDownFrame
|
|
elseif selectionType == "TextBox" then
|
|
local isMouseOverRow = false
|
|
local forceReturnSelectionOnFocusLost = false
|
|
local SelectionOverrideObject = Util.Create'ImageLabel'
|
|
{
|
|
Image = "",
|
|
BackgroundTransparency = 1,
|
|
};
|
|
|
|
ValueChangerInstance = {}
|
|
ValueChangerInstance.HubRef = nil
|
|
|
|
local box = Util.Create'TextBox'
|
|
{
|
|
Size = UDim2.new(1,-10,0,100),
|
|
Position = UDim2.new(0,5,0,nextRowPositionY),
|
|
Text = rowDisplayName,
|
|
TextColor3 = Color3.new(49/255, 49/255, 49/255),
|
|
BackgroundTransparency = 0.5,
|
|
BorderSizePixel = 0,
|
|
TextYAlignment = Enum.TextYAlignment.Top,
|
|
TextXAlignment = Enum.TextXAlignment.Left,
|
|
TextWrapped = true,
|
|
Font = Enum.Font.SourceSans,
|
|
FontSize = Enum.FontSize.Size24,
|
|
ZIndex = 2,
|
|
SelectionImageObject = SelectionOverrideObject,
|
|
ClearTextOnFocus = false,
|
|
Parent = pageToAddTo.Page
|
|
};
|
|
ValueChangerSelection = box
|
|
|
|
box.Focused:connect(function()
|
|
if usesSelectedObject() then
|
|
GuiService.SelectedCoreObject = box
|
|
end
|
|
|
|
if box.Text == rowDisplayName then
|
|
box.Text = ""
|
|
end
|
|
end)
|
|
box.FocusLost:connect(function(enterPressed, inputObject)
|
|
if GuiService.SelectedCoreObject == box and (not isMouseOverRow or forceReturnSelectionOnFocusLost) then
|
|
GuiService.SelectedCoreObject = nil
|
|
end
|
|
forceReturnSelectionOnFocusLost = false
|
|
end)
|
|
if extraSpacing then
|
|
box.Position = UDim2.new(box.Position.X.Scale,box.Position.X.Offset,
|
|
box.Position.Y.Scale,box.Position.Y.Offset + extraSpacing)
|
|
end
|
|
|
|
ValueChangerSelection.SelectionGained:connect(function()
|
|
if usesSelectedObject() then
|
|
box.BackgroundTransparency = 0.1
|
|
|
|
if ValueChangerInstance.HubRef then
|
|
ValueChangerInstance.HubRef:ScrollToFrame(ValueChangerSelection)
|
|
end
|
|
end
|
|
end)
|
|
ValueChangerSelection.SelectionLost:connect(function()
|
|
if usesSelectedObject() then
|
|
box.BackgroundTransparency = 0.5
|
|
end
|
|
end)
|
|
|
|
local setRowSelection = function()
|
|
local fullscreenDropDown = CoreGui.RobloxGui:FindFirstChild("DropDownFullscreenFrame")
|
|
if fullscreenDropDown and fullscreenDropDown.Visible then return end
|
|
|
|
local valueFrame = ValueChangerSelection
|
|
|
|
if valueFrame and valueFrame.Visible and valueFrame.ZIndex > 1 and usesSelectedObject() and pageToAddTo.Active then
|
|
GuiService.SelectedCoreObject = valueFrame
|
|
isMouseOverRow = true
|
|
end
|
|
end
|
|
local function processInput(input)
|
|
if input.UserInputState == Enum.UserInputState.Begin then
|
|
if input.KeyCode == Enum.KeyCode.Return then
|
|
if GuiService.SelectedCoreObject == ValueChangerSelection then
|
|
forceReturnSelectionOnFocusLost = true
|
|
box:CaptureFocus()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
RowFrame.MouseEnter:connect(setRowSelection)
|
|
RowFrame.Size = UDim2.new(1, 0, 0, 100)
|
|
|
|
UserInputService.InputBegan:connect(processInput)
|
|
end
|
|
|
|
ValueChangerInstance.Name = rowDisplayName .. "ValueChanger"
|
|
|
|
nextRowPositionY = nextRowPositionY + ROW_HEIGHT
|
|
if extraSpacing then
|
|
nextRowPositionY = nextRowPositionY + extraSpacing
|
|
end
|
|
|
|
nextPosTable[pageToAddTo] = nextRowPositionY
|
|
|
|
if isARealRow then
|
|
local setRowSelection = function()
|
|
local fullscreenDropDown = CoreGui.RobloxGui:FindFirstChild("DropDownFullscreenFrame")
|
|
if fullscreenDropDown and fullscreenDropDown.Visible then return end
|
|
|
|
local valueFrame = ValueChangerInstance.SliderFrame
|
|
if not valueFrame then
|
|
valueFrame = ValueChangerInstance.SliderFrame
|
|
end
|
|
if not valueFrame then
|
|
valueFrame = ValueChangerInstance.DropDownFrame
|
|
end
|
|
if not valueFrame then
|
|
valueFrame = ValueChangerInstance.SelectorFrame
|
|
end
|
|
|
|
if valueFrame and valueFrame.Visible and valueFrame.ZIndex > 1 and usesSelectedObject() and pageToAddTo.Active then
|
|
GuiService.SelectedCoreObject = valueFrame
|
|
end
|
|
end
|
|
RowFrame.MouseEnter:connect(setRowSelection)
|
|
|
|
ValueChangerSelection.SelectionGained:connect(function()
|
|
if usesSelectedObject() then
|
|
RowFrame.BackgroundTransparency = 0.5
|
|
|
|
if ValueChangerInstance.HubRef then
|
|
ValueChangerInstance.HubRef:ScrollToFrame(RowFrame)
|
|
end
|
|
end
|
|
end)
|
|
ValueChangerSelection.SelectionLost:connect(function()
|
|
if usesSelectedObject() then
|
|
RowFrame.BackgroundTransparency = 1
|
|
end
|
|
end)
|
|
end
|
|
|
|
pageToAddTo:AddRow(RowFrame, RowLabel, ValueChangerInstance, extraSpacing, false)
|
|
|
|
ValueChangerInstance.Selection = ValueChangerSelection
|
|
|
|
return RowFrame, RowLabel, ValueChangerInstance
|
|
end
|
|
|
|
local function AddNewRowObject(pageToAddTo, rowDisplayName, rowObject, extraSpacing)
|
|
local nextRowPositionY = 0
|
|
|
|
if nextPosTable[pageToAddTo] then
|
|
nextRowPositionY = nextPosTable[pageToAddTo]
|
|
end
|
|
|
|
local RowFrame = Util.Create'ImageButton'
|
|
{
|
|
Name = rowDisplayName .. "Frame",
|
|
BackgroundTransparency = 1,
|
|
BorderSizePixel = 0,
|
|
Image = "",
|
|
Active = false,
|
|
AutoButtonColor = false,
|
|
Size = UDim2.new(1,0,0,ROW_HEIGHT),
|
|
Position = UDim2.new(0,0,0,nextRowPositionY),
|
|
ZIndex = 2,
|
|
Selectable = false,
|
|
SelectionImageObject = noSelectionObject,
|
|
Parent = pageToAddTo.Page
|
|
};
|
|
RowFrame.SelectionGained:connect(function()
|
|
RowFrame.BackgroundTransparency = 0.5
|
|
end)
|
|
RowFrame.SelectionLost:connect(function()
|
|
RowFrame.BackgroundTransparency = 1
|
|
end)
|
|
|
|
local RowLabel = Util.Create'TextLabel'
|
|
{
|
|
Name = rowDisplayName .. "Label",
|
|
Text = rowDisplayName,
|
|
Font = Enum.Font.SourceSansBold,
|
|
FontSize = Enum.FontSize.Size24,
|
|
TextColor3 = Color3.new(1,1,1),
|
|
TextXAlignment = Enum.TextXAlignment.Left,
|
|
BackgroundTransparency = 1,
|
|
Size = UDim2.new(0,200,1,0),
|
|
Position = UDim2.new(0,10,0,0),
|
|
ZIndex = 2,
|
|
Parent = RowFrame
|
|
};
|
|
if isTenFootInterface() then
|
|
RowLabel.FontSize = Enum.FontSize.Size36
|
|
end
|
|
|
|
if extraSpacing then
|
|
RowFrame.Position = UDim2.new(RowFrame.Position.X.Scale,RowFrame.Position.X.Offset,
|
|
RowFrame.Position.Y.Scale,RowFrame.Position.Y.Offset + extraSpacing)
|
|
end
|
|
|
|
nextRowPositionY = nextRowPositionY + ROW_HEIGHT
|
|
if extraSpacing then
|
|
nextRowPositionY = nextRowPositionY + extraSpacing
|
|
end
|
|
|
|
nextPosTable[pageToAddTo] = nextRowPositionY
|
|
|
|
local setRowSelection = function()
|
|
if RowFrame.Visible then
|
|
GuiService.SelectedCoreObject = RowFrame
|
|
end
|
|
end
|
|
RowFrame.MouseEnter:connect(setRowSelection)
|
|
|
|
rowObject.SelectionImageObject = noSelectionObject
|
|
|
|
rowObject.SelectionGained:connect(function()
|
|
RowFrame.BackgroundTransparency = 0.5
|
|
end)
|
|
rowObject.SelectionLost:connect(function()
|
|
RowFrame.BackgroundTransparency = 1
|
|
end)
|
|
|
|
rowObject.Parent = RowFrame
|
|
|
|
pageToAddTo:AddRow(RowFrame, RowLabel, rowObject, extraSpacing, true)
|
|
return RowFrame
|
|
end
|
|
|
|
-------- public facing API ----------------
|
|
local moduleApiTable = {}
|
|
|
|
function moduleApiTable:Create(instanceType)
|
|
return function(data)
|
|
local obj = Instance.new(instanceType)
|
|
for k, v in pairs(data) do
|
|
if type(k) == 'number' then
|
|
v.Parent = obj
|
|
else
|
|
obj[k] = v
|
|
end
|
|
end
|
|
return obj
|
|
end
|
|
end
|
|
|
|
function moduleApiTable:GetEaseLinear()
|
|
return Linear
|
|
end
|
|
function moduleApiTable:GetEaseOutQuad()
|
|
return EaseOutQuad
|
|
end
|
|
function moduleApiTable:GetEaseInOutQuad()
|
|
return EaseInOutQuad
|
|
end
|
|
|
|
function moduleApiTable:CreateNewSlider(numOfSteps, startStep, minStep)
|
|
return CreateNewSlider(numOfSteps, startStep, minStep)
|
|
end
|
|
|
|
function moduleApiTable:CreateNewSelector(selectionStringTable, startPosition)
|
|
return CreateSelector(selectionStringTable, startPosition)
|
|
end
|
|
|
|
function moduleApiTable:CreateNewDropDown(dropDownStringTable, startPosition)
|
|
return CreateDropDown(dropDownStringTable, startPosition, nil, nil)
|
|
end
|
|
|
|
function moduleApiTable:AddNewRow(pageToAddTo, rowDisplayName, selectionType, rowValues, rowDefault, extraSpacing)
|
|
return AddNewRow(pageToAddTo, rowDisplayName, selectionType, rowValues, rowDefault, extraSpacing)
|
|
end
|
|
|
|
function moduleApiTable:AddNewRowObject(pageToAddTo, rowDisplayName, rowObject, extraSpacing)
|
|
return AddNewRowObject(pageToAddTo, rowDisplayName, rowObject, extraSpacing)
|
|
end
|
|
|
|
function moduleApiTable:ShowAlert(alertMessage, okButtonText, settingsHub, okPressedFunc, hasBackground)
|
|
ShowAlert(alertMessage, okButtonText, settingsHub, okPressedFunc, hasBackground)
|
|
end
|
|
|
|
function moduleApiTable:IsSmallTouchScreen()
|
|
return isSmallTouchScreen()
|
|
end
|
|
|
|
function moduleApiTable:MakeStyledButton(name, text, size, clickFunc, pageRef, hubRef)
|
|
return MakeButton(name, text, size, clickFunc, pageRef, hubRef)
|
|
end
|
|
|
|
function moduleApiTable:CreateSignal()
|
|
return CreateSignal()
|
|
end
|
|
|
|
function moduleApiTable:UsesSelectedObject()
|
|
return usesSelectedObject();
|
|
end
|
|
|
|
function moduleApiTable:TweenProperty(instance, prop, start, final, duration, easingFunc, cbFunc)
|
|
return PropertyTweener(instance, prop, start, final, duration, easingFunc, cbFunc)
|
|
end
|
|
|
|
return moduleApiTable |