mirror of
https://github.com/Ukendio/jecs.git
synced 2026-03-18 00:44:32 +00:00
229 lines
No EOL
5.9 KiB
Text
229 lines
No EOL
5.9 KiB
Text
local GuiService = game:GetService("GuiService")
|
|
local RunService = game:GetService("RunService")
|
|
local UserInputService = game:GetService("UserInputService")
|
|
|
|
local vide = require(script.Parent.Parent.Parent.Parent.Parent.vide)
|
|
local theme = require(script.Parent.Parent.Parent.Parent.util.theme)
|
|
local container = require(script.Parent.Parent.Parent.util.container)
|
|
|
|
local create = vide.create
|
|
local source = vide.source
|
|
local spring = vide.spring
|
|
local changed = vide.changed
|
|
local cleanup = vide.cleanup
|
|
|
|
type Source<T> = vide.Source<T>
|
|
type props = {
|
|
|
|
resize_range: number,
|
|
min_size: Vector2,
|
|
|
|
can_resize_left: Source<boolean>,
|
|
can_resize_right: Source<boolean>,
|
|
can_resize_bottom: Source<boolean>,
|
|
can_resize_top: Source<boolean>,
|
|
|
|
resizing: () -> boolean,
|
|
}
|
|
|
|
local function xpos(s: () -> number)
|
|
return function()
|
|
return Vector2.new(s(), 0)
|
|
end
|
|
end
|
|
|
|
local function ypos(s: () -> number)
|
|
return function()
|
|
return Vector2.new(0, s())
|
|
end
|
|
end
|
|
|
|
return function(props: props)
|
|
local RESIZE_RANGE = props.resize_range
|
|
local MIN_SIZE = props.min_size
|
|
|
|
local can_resize_left = props.can_resize_left
|
|
local can_resize_right = props.can_resize_right
|
|
local can_resize_bottom = props.can_resize_bottom
|
|
local can_resize_top = props.can_resize_top
|
|
local resizing = props.resizing
|
|
|
|
local absolute_size = source(Vector2.new(1, 1))
|
|
local absolute_position = source(Vector2.zero)
|
|
|
|
local thickness = 4
|
|
local border_selected = theme.acc[8]
|
|
local gradient = NumberSequence.new({
|
|
NumberSequenceKeypoint.new(0, 1),
|
|
NumberSequenceKeypoint.new(0.25, 1),
|
|
NumberSequenceKeypoint.new(0.5, 0),
|
|
NumberSequenceKeypoint.new(0.75, 1),
|
|
NumberSequenceKeypoint.new(1, 1),
|
|
})
|
|
|
|
local x = source(0)
|
|
local y = source(0)
|
|
|
|
cleanup(RunService.Heartbeat:Connect(function()
|
|
local mposition = UserInputService:GetMouseLocation()
|
|
local top_inset, bottom_inset = GuiService:GetGuiInset()
|
|
mposition += - top_inset - bottom_inset
|
|
|
|
if MIN_SIZE.X ~= absolute_size().X or not resizing() then x(mposition.X) end
|
|
if MIN_SIZE.Y ~= absolute_size().Y or not resizing() then y(mposition.Y) end
|
|
end))
|
|
|
|
cleanup(RunService.RenderStepped:Connect(function()
|
|
local mposition = UserInputService:GetMouseLocation()
|
|
local top_inset, bottom_inset = GuiService:GetGuiInset()
|
|
mposition += - top_inset - bottom_inset
|
|
local x, y = mposition.X, mposition.Y
|
|
|
|
if resizing() then return end
|
|
|
|
local left = absolute_position().X
|
|
local top = absolute_position().Y
|
|
local right = left + absolute_size().X
|
|
local bottom = top + absolute_size().Y
|
|
|
|
local topleft = absolute_position() - Vector2.new(RESIZE_RANGE, RESIZE_RANGE)
|
|
local bottomright = absolute_position() + absolute_size() + Vector2.new(RESIZE_RANGE, RESIZE_RANGE)
|
|
|
|
-- perform AABB to check if the cursor is in range
|
|
local within_bounds = x > topleft.X and y > topleft.Y and x < bottomright.X and y < bottomright.Y
|
|
|
|
can_resize_top(y > top - RESIZE_RANGE and y < top and within_bounds)
|
|
can_resize_left(x < left + RESIZE_RANGE and x > left - RESIZE_RANGE and within_bounds)
|
|
can_resize_bottom(y < bottom + RESIZE_RANGE and y > bottom - RESIZE_RANGE and within_bounds)
|
|
can_resize_right(x < right + RESIZE_RANGE and x > right - RESIZE_RANGE and within_bounds)
|
|
end))
|
|
|
|
return {
|
|
|
|
changed("AbsoluteSize", function(value: Vector2)
|
|
if value.Magnitude == 0 then return end
|
|
absolute_size(value)
|
|
end),
|
|
changed("AbsolutePosition", absolute_position),
|
|
|
|
container {
|
|
|
|
Name = "Left",
|
|
|
|
Position = UDim2.fromScale(0, 0.5),
|
|
Size = UDim2.new(0, thickness, 1, thickness * 2),
|
|
AnchorPoint = Vector2.new(1, 0.5),
|
|
|
|
BackgroundColor3 = border_selected,
|
|
|
|
BackgroundTransparency = spring(function()
|
|
return can_resize_left() and 0 or 1
|
|
end, 0.2),
|
|
|
|
ZIndex = 1000,
|
|
|
|
create "UIGradient" {
|
|
|
|
Rotation = 90,
|
|
|
|
Transparency = gradient,
|
|
Offset = ypos(spring(function()
|
|
return (y() - absolute_position().Y - absolute_size().Y / 2) / absolute_size().Y
|
|
end, 0.1)),
|
|
},
|
|
|
|
create "UICorner" {
|
|
CornerRadius = UDim.new(0, 4)
|
|
},
|
|
},
|
|
|
|
container {
|
|
|
|
Name = "Right",
|
|
|
|
Position = UDim2.fromScale(1, 0.5),
|
|
Size = UDim2.new(0, thickness, 1, thickness * 2),
|
|
AnchorPoint = Vector2.new(0, 0.5),
|
|
|
|
BackgroundColor3 = border_selected,
|
|
|
|
BackgroundTransparency = spring(function()
|
|
return can_resize_right() and 0 or 1
|
|
end, 0.2),
|
|
|
|
ZIndex = 1000,
|
|
|
|
create "UIGradient" {
|
|
|
|
Rotation = 90,
|
|
|
|
Transparency = gradient,
|
|
Offset = ypos(spring(function()
|
|
return (y() - absolute_position().Y - absolute_size().Y / 2) / absolute_size().Y
|
|
end, 0.1)),
|
|
},
|
|
|
|
create "UICorner" {
|
|
CornerRadius = UDim.new(0, 4)
|
|
},
|
|
},
|
|
|
|
container {
|
|
|
|
Name = "Bottom",
|
|
|
|
Position = UDim2.fromScale(0.5, 1),
|
|
Size = UDim2.new(1, thickness * 2, 0, thickness),
|
|
AnchorPoint = Vector2.new(0.5, 0),
|
|
|
|
BackgroundColor3 = border_selected,
|
|
|
|
BackgroundTransparency = spring(function()
|
|
return can_resize_bottom() and 0 or 1
|
|
end, 0.2),
|
|
|
|
ZIndex = 1000,
|
|
|
|
create "UIGradient" {
|
|
|
|
Transparency = gradient,
|
|
Offset = xpos(spring(function()
|
|
return (x() - absolute_position().X - absolute_size().X / 2) / absolute_size().X
|
|
end, 0.1)),
|
|
},
|
|
|
|
create "UICorner" {
|
|
CornerRadius = UDim.new(0, 4)
|
|
},
|
|
},
|
|
|
|
container {
|
|
|
|
Name = "Top",
|
|
|
|
Position = UDim2.fromScale(0.5, 0),
|
|
Size = UDim2.new(1, thickness * 2, 0, thickness),
|
|
AnchorPoint = Vector2.new(0.5, 1),
|
|
|
|
BackgroundColor3 = border_selected,
|
|
|
|
BackgroundTransparency = spring(function()
|
|
return can_resize_top() and 0 or 1
|
|
end, 0.2),
|
|
|
|
ZIndex = 1000,
|
|
|
|
create "UIGradient" {
|
|
|
|
Transparency = gradient,
|
|
Offset = xpos(spring(function()
|
|
return (x() - absolute_position().X - absolute_size().X / 2) / absolute_size().X
|
|
end, 0.1)),
|
|
},
|
|
|
|
create "UICorner" {
|
|
CornerRadius = UDim.new(0, 4)
|
|
},
|
|
},
|
|
} :: { any }
|
|
end |