mirror of
https://github.com/Ukendio/jecs.git
synced 2026-03-18 00:44:32 +00:00
299 lines
No EOL
7.7 KiB
Text
299 lines
No EOL
7.7 KiB
Text
local GuiService = game:GetService("GuiService")
|
|
local Players = game:GetService("Players")
|
|
local RunService = game:GetService("RunService")
|
|
local UserInputService = game:GetService("UserInputService")
|
|
|
|
local vide = require(script.Parent.Parent.Parent.Parent.vide)
|
|
local theme = require(script.Parent.Parent.Parent.util.theme)
|
|
local container = require(script.Parent.Parent.util.container)
|
|
local padding = require(script.Parent.Parent.util.padding)
|
|
local shadow = require(script.Parent.Parent.util.shadow)
|
|
local divider = require(script.Parent.divider)
|
|
local snapping = require(script.Parent.snapping)
|
|
local borders = require(script.borders)
|
|
local topbar = require(script.topbar)
|
|
|
|
local create = vide.create
|
|
local source = vide.source
|
|
local cleanup = vide.cleanup
|
|
local changed = vide.changed
|
|
local reference = vide.action
|
|
local spring = vide.spring
|
|
|
|
type can<T> = T | () -> T
|
|
type props = {
|
|
|
|
title: can<string>,
|
|
subtitle: can<string>?,
|
|
min_size: Vector2?,
|
|
position: Vector2?,
|
|
size: Vector2?,
|
|
|
|
bind_to_close: (() -> ())?,
|
|
|
|
[number]: any
|
|
|
|
}
|
|
|
|
local HIGHEST_DISPLAY_ORDER = 100000
|
|
local RESIZE_RANGE = 6
|
|
|
|
local docks
|
|
|
|
vide.mount(function()
|
|
|
|
docks = snapping()
|
|
|
|
return create "ScreenGui" {
|
|
Name = "docks",
|
|
AutoLocalize = false,
|
|
|
|
-- create "Frame" {
|
|
-- Size = UDim2.new(1, 0, 0, 200),
|
|
|
|
-- BackgroundTransparency = 1,
|
|
|
|
-- docks.snap_area {}
|
|
-- },
|
|
|
|
-- create "Frame" {
|
|
-- Size = UDim2.new(1, 0, 0, 200),
|
|
-- Position = UDim2.fromScale(0, 1),
|
|
-- AnchorPoint = Vector2.new(0, 1),
|
|
-- BackgroundTransparency = 1,
|
|
|
|
-- docks.snap_area {}
|
|
-- },
|
|
|
|
create "Frame" {
|
|
Size = UDim2.new(0, 16, 1, 0),
|
|
BackgroundTransparency = 1,
|
|
AutoLocalize = false,
|
|
|
|
docks.snap_area {}
|
|
},
|
|
}
|
|
|
|
end, Players.LocalPlayer.PlayerGui)
|
|
|
|
return function(props: props)
|
|
local min_size = Vector2.new(100, 100):Max(props.min_size or Vector2.zero)
|
|
local position = props.position or Vector2.new(32, 32)
|
|
local base_size = props.size or min_size * 1.5
|
|
|
|
local x_size = source(math.max(min_size.X, base_size.X))
|
|
local y_size = source(math.max(min_size.Y, base_size.Y))
|
|
local x_position = source(position.X)
|
|
local y_position = source(position.Y)
|
|
|
|
local offset = source(Vector2.zero)
|
|
local dragging = source(false)
|
|
local absolute_position = source(Vector2.zero)
|
|
local absolute_size = source(Vector2.zero)
|
|
|
|
local can_resize_top = source(false)
|
|
local can_resize_bottom = source(false)
|
|
local can_resize_right = source(false)
|
|
local can_resize_left = source(false)
|
|
local resizing = source(false)
|
|
local ref = source()
|
|
local display_order = source(HIGHEST_DISPLAY_ORDER + 1)
|
|
HIGHEST_DISPLAY_ORDER += 1
|
|
|
|
local mouse_inside = source(false)
|
|
|
|
local top: Vector2
|
|
local bottom: Vector2
|
|
|
|
cleanup(UserInputService.InputEnded:Connect(function(input)
|
|
if
|
|
input.UserInputType ~= Enum.UserInputType.MouseButton1
|
|
and input.UserInputType ~= Enum.UserInputType.Touch
|
|
then
|
|
return
|
|
end
|
|
resizing(false)
|
|
dragging(false)
|
|
end))
|
|
|
|
cleanup(UserInputService.InputChanged:Connect(function(input: InputObject)
|
|
if input.UserInputType ~= Enum.UserInputType.MouseMovement then return end
|
|
if not resizing() then return end
|
|
|
|
local mposition = UserInputService:GetMouseLocation()
|
|
local top_inset, bottom_inset = GuiService:GetGuiInset()
|
|
mposition += - top_inset - bottom_inset
|
|
local x, y = mposition.X, mposition.Y
|
|
|
|
if can_resize_bottom() then y_size(math.max(y - top.Y, min_size.Y)) end
|
|
if can_resize_right() then x_size(math.max(x - top.X, min_size.X)) end
|
|
if can_resize_top() then
|
|
y_size(math.max(bottom.Y - y, min_size.Y))
|
|
y_position(math.min(y, bottom.Y - min_size.Y))
|
|
end
|
|
if can_resize_left() then
|
|
x_size(math.max(bottom.X - x, min_size.X))
|
|
x_position(math.min(x, bottom.X - min_size.X))
|
|
end
|
|
end))
|
|
|
|
cleanup(UserInputService.InputBegan:Connect(function(input)
|
|
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
|
|
if not dragging() then resizing(true) end
|
|
|
|
top = absolute_position()
|
|
bottom = absolute_position() + absolute_size()
|
|
|
|
local player_gui
|
|
if Players.LocalPlayer and RunService:IsRunning() then
|
|
player_gui = Players.LocalPlayer:WaitForChild("PlayerGui") :: PlayerGui
|
|
elseif RunService:IsStudio() and RunService:IsRunning() then
|
|
player_gui = game:GetService("CoreGui") :: any
|
|
else
|
|
return
|
|
end
|
|
|
|
local objects = player_gui:GetGuiObjectsAtPosition(input.Position.X, input.Position.Y)
|
|
if #objects == 0 then return end
|
|
if not objects[1]:IsDescendantOf(ref()) then return end
|
|
|
|
display_order(HIGHEST_DISPLAY_ORDER + 1)
|
|
HIGHEST_DISPLAY_ORDER += 1
|
|
end))
|
|
|
|
cleanup(UserInputService.InputChanged:Connect(function(input: InputObject)
|
|
if dragging() == false then return end
|
|
if not UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
|
|
dragging(false)
|
|
return
|
|
end
|
|
|
|
local position = UserInputService:GetMouseLocation()
|
|
-- local top_inset, bottom_inset = GuiService:GetGuiInset()
|
|
-- position += - top_inset - bottom_inset
|
|
x_position(position.X + offset().X)
|
|
y_position(position.Y + offset().Y)
|
|
end))
|
|
|
|
local snapped = source(false)
|
|
local snap_size = source(UDim2.new())
|
|
local snap_pos = source(UDim2.new())
|
|
|
|
local function radius()
|
|
return if snapped() then UDim.new() else UDim.new(0, 6)
|
|
end
|
|
|
|
return create "ScreenGui" {
|
|
Name = props.title,
|
|
AutoLocalize = false,
|
|
DisplayOrder = display_order,
|
|
reference(ref),
|
|
|
|
create "Frame" {
|
|
AutoLocalize = false,
|
|
Position = function()
|
|
return if snapped() then snap_pos() else UDim2.fromOffset(x_position(), y_position())
|
|
end,
|
|
|
|
Size = function()
|
|
return if snapped() then UDim2.fromOffset(x_size() + 6, snap_size().Y.Offset) else UDim2.fromOffset(x_size() + 6, y_size() + 6)
|
|
end,
|
|
|
|
Active = true,
|
|
|
|
BackgroundColor3 = theme.bg[0],
|
|
|
|
MouseMoved = function()
|
|
if resizing() then return end
|
|
|
|
local mposition = UserInputService:GetMouseLocation()
|
|
local top_inset, bottom_inset = GuiService:GetGuiInset()
|
|
position += - top_inset - bottom_inset
|
|
local x, y = mposition.X, mposition.Y
|
|
x -= absolute_position().X
|
|
y -= absolute_position().Y
|
|
|
|
can_resize_top(y < RESIZE_RANGE)
|
|
can_resize_left(x < RESIZE_RANGE)
|
|
can_resize_bottom(y > (absolute_size().Y - RESIZE_RANGE))
|
|
can_resize_right(x > (absolute_size().X - RESIZE_RANGE))
|
|
end,
|
|
|
|
MouseEnter = function()
|
|
mouse_inside(true)
|
|
end,
|
|
|
|
MouseLeave = function()
|
|
if resizing() then return end
|
|
if RunService:IsRunning() == false then return end
|
|
|
|
mouse_inside(false)
|
|
end,
|
|
|
|
changed("AbsolutePosition", absolute_position),
|
|
changed("AbsoluteSize", absolute_size),
|
|
|
|
create "UICorner" {
|
|
CornerRadius = radius
|
|
},
|
|
|
|
shadow {},
|
|
|
|
borders {
|
|
|
|
resize_range = RESIZE_RANGE,
|
|
min_size = min_size,
|
|
|
|
can_resize_top = can_resize_top,
|
|
can_resize_bottom = can_resize_bottom,
|
|
can_resize_left = can_resize_left,
|
|
can_resize_right = can_resize_right,
|
|
|
|
resizing = resizing,
|
|
},
|
|
|
|
container {
|
|
Size = UDim2.fromScale(1, 1),
|
|
|
|
create "UIListLayout" {},
|
|
|
|
topbar {
|
|
title = props.title,
|
|
subtitle = props.subtitle,
|
|
dragging = dragging,
|
|
offset = offset,
|
|
bind_to_close = props.bind_to_close,
|
|
radius = radius
|
|
},
|
|
|
|
divider {},
|
|
|
|
container {
|
|
Size = UDim2.fromScale(1, 0),
|
|
|
|
padding {
|
|
x = UDim.new(0, 8),
|
|
y = UDim.new(0, 8)
|
|
},
|
|
|
|
unpack(props),
|
|
|
|
create "UIFlexItem" {
|
|
FlexMode = Enum.UIFlexMode.Grow
|
|
},
|
|
}
|
|
},
|
|
|
|
docks.snappable {
|
|
dragging = dragging,
|
|
|
|
snapped = snapped,
|
|
position = snap_pos,
|
|
size = snap_size
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
end |