attempt to fix check fail by changing how module uses UIS

This commit is contained in:
sindri 2026-03-02 14:24:55 +01:00 committed by GitHub
parent a94aee800f
commit defb2883c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,93 +1,198 @@
local UserInputService = game and game:GetService("UserInputService") or nil local UserInputService = game and game:GetService("UserInputService") or nil
local function clamp(x, a, b)
if x < a then return a end
if x > b then return b end
return x
end
local function lerp(a, b, t)
return a + (b - a) * t
end
local function invLerp(a, b, v)
if a == b then return 0 end
return (v - a) / (b - a)
end
local function quantize(v, step)
if not step or step <= 0 then return v end
return math.floor((v / step) + 0.5) * step
end
-- Factory: inject Vide functions to avoid cyclic requires -- Factory: inject Vide functions to avoid cyclic requires
return function(action, cleanup) return function(create, source, action, cleanup)
return function(opts) return function(props)
opts = opts or {} props = props or {}
local axis = opts.axis or "both" -- "x" | "y" | "both"
return action(function(gui) local minV = props.min or 0
-- Non-Roblox / unit-test environment: allow requiring this module without crashing. local maxV = props.max or 1
-- Draggable behaviour is disabled when UserInputService is unavailable. local step = props.step
if not UserInputService then local value = props.value
return assert(value, "vide.slider: props.value (source<number>) is required")
end
-- Optional hardening: ignore non-GuiObject targets local theme = props.theme or {}
if typeof(gui) ~= "Instance" or not gui:IsA("GuiObject") then local format = props.format or function(v) return tostring(v) end
return local onChanged = props.onChanged
end
local dragging = false local trackRef = source(nil)
local dragInput
local dragStart
local startPos
local function update(input) local function setFromX(screenX)
local delta = input.Position - dragStart local track = trackRef()
if not track then return end
local xOff = startPos.X.Offset local absPosX = track.AbsolutePosition.X
local yOff = startPos.Y.Offset local absSizeX = track.AbsoluteSize.X
if absSizeX <= 0 then return end
if axis == "x" or axis == "both" then local t = clamp((screenX - absPosX) / absSizeX, 0, 1)
xOff = startPos.X.Offset + delta.X local v = lerp(minV, maxV, t)
end v = quantize(v, step)
if axis == "y" or axis == "both" then
yOff = startPos.Y.Offset + delta.Y
end
gui.Position = UDim2.new(startPos.X.Scale, xOff, startPos.Y.Scale, yOff) value(v)
if onChanged then onChanged(v) end
end
if opts.onDrag then return create "Frame" {
opts.onDrag(gui.Position) Name = props.name or "Slider",
end Size = props.size or UDim2.fromOffset(516, 90),
end Position = props.position,
AnchorPoint = props.anchorPoint,
LayoutOrder = props.layoutOrder,
BackgroundTransparency = 1,
local beganConn = gui.InputBegan:Connect(function(input) create "TextLabel" {
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then BackgroundTransparency = 1,
dragging = true Size = UDim2.fromOffset(516, 24),
dragStart = input.Position TextXAlignment = Enum.TextXAlignment.Left,
startPos = gui.Position FontFace = props.fontFace,
TextSize = props.labelTextSize or 16,
TextColor3 = props.labelTextColor or Color3.fromRGB(235, 238, 245),
Text = props.label or "Slider",
},
if opts.onDragStart then create "TextLabel" {
opts.onDragStart(startPos) BackgroundTransparency = 1,
end Size = UDim2.fromOffset(516, 24),
TextXAlignment = Enum.TextXAlignment.Right,
FontFace = props.fontFace,
TextSize = props.valueTextSize or 16,
TextColor3 = props.valueTextColor or Color3.fromRGB(200, 206, 220),
Text = function()
return format(value())
end,
},
local changedConn create "Frame" {
changedConn = input.Changed:Connect(function() Name = "Track",
if input.UserInputState == Enum.UserInputState.End then Position = UDim2.fromOffset(0, 38),
dragging = false Size = UDim2.fromOffset(516, 16),
if changedConn then changedConn:Disconnect() end BackgroundColor3 = theme.trackColor or Color3.fromRGB(20, 22, 28),
BackgroundTransparency = theme.trackTransparency or 0.15,
if opts.onDragEnd then action(function(track)
opts.onDragEnd(gui.Position) trackRef(track)
end
local trackBeganConn = track.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
setFromX(input.Position.X)
end end
end) end)
cleanup(function() cleanup(function()
if changedConn then changedConn:Disconnect() end if trackRef() == track then trackRef(nil) end
trackBeganConn:Disconnect()
end) end)
end end),
end)
local changedConn = gui.InputChanged:Connect(function(input) create "UICorner" { CornerRadius = UDim.new(0, theme.cornerRadius or 8) },
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then create "UIStroke" {
dragInput = input Thickness = 1,
end Color = theme.strokeColor or Color3.fromRGB(255, 255, 255),
end) Transparency = theme.strokeTransparency or 0.8,
},
local uisConn = UserInputService.InputChanged:Connect(function(input) create "Frame" {
if input == dragInput and dragging then Name = "Fill",
update(input) Size = function()
end local t = clamp(invLerp(minV, maxV, value()), 0, 1)
end) return UDim2.fromScale(t, 1)
end,
BackgroundColor3 = theme.fillColor or Color3.fromRGB(80, 140, 255),
BackgroundTransparency = theme.fillTransparency or 0.15,
create "UICorner" { CornerRadius = UDim.new(0, theme.cornerRadius or 8) },
},
cleanup(function() create "TextButton" {
beganConn:Disconnect() Name = "Knob",
changedConn:Disconnect() AutoButtonColor = false,
uisConn:Disconnect() Text = "",
end) Size = UDim2.fromOffset(24, 24),
end) AnchorPoint = Vector2.new(0.5, 0.5),
Position = function()
local t = clamp(invLerp(minV, maxV, value()), 0, 1)
return UDim2.fromScale(t, 0.5)
end,
BackgroundColor3 = theme.knobColor or Color3.fromRGB(235, 238, 245),
BackgroundTransparency = theme.knobTransparency or 0,
create "UICorner" { CornerRadius = UDim.new(0, theme.knobRadius or 999) },
create "UIStroke" { Thickness = 1, Color = Color3.fromRGB(0, 0, 0), Transparency = 0.75 },
action(function(btn)
-- Non-Roblox / unit-test environment: allow requiring this module without crashing.
-- Slider still renders; dragging is disabled when UserInputService is unavailable.
if not UserInputService then
return
end
if typeof(btn) ~= "Instance" or not btn:IsA("GuiButton") then
return
end
local dragInput
local dragging = false
local beganConn
local changedConn
local uisChangedConn
local function update(input)
setFromX(input.Position.X)
end
beganConn = btn.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
update(input)
changedConn = input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
dragging = false
end
end)
end
end)
btn.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
uisChangedConn = UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging then
update(input)
end
end)
cleanup(function()
if beganConn then beganConn:Disconnect() end
if changedConn then changedConn:Disconnect() end
if uisChangedConn then uisChangedConn:Disconnect() end
end)
end),
},
},
}
end end
end end