|
|
|
|
|
|
|
|
|
|
|
local SocketLinkOffset = point(10, 0) |
|
local LinkMouseHoverDist = 7 |
|
local LinkThickness = 8 |
|
local SplineSampleStep = 10 |
|
local NodeSelectedColor = RGB(248, 220, 120) |
|
local GraphSocketColors = { |
|
number = RGB(205, 0, 205), |
|
string = RGB(0, 150, 100), |
|
boolean = RGB(0, 100, 0), |
|
any = RGB(240, 240, 240), |
|
} |
|
|
|
DefineClass.XGraphEditor = { |
|
__parents = { "XMap" }, |
|
|
|
drag_start_socket = false, |
|
drag_end_socket = false, |
|
drag_end_pt = false, |
|
last_node_pt = false, |
|
menu = false, |
|
links = false, |
|
read_only = false, |
|
selected_node = false, |
|
|
|
UseCustomTime = false, |
|
|
|
NodeClassItems = false, |
|
OnGraphEdited = empty_func, |
|
OnNodeSelected = empty_func, |
|
} |
|
|
|
function XGraphEditor:Init() |
|
self.links = {} |
|
end |
|
|
|
function XGraphEditor:SelectNode(node) |
|
if self.selected_node ~= node then |
|
if self.selected_node then |
|
self.selected_node:Select(false) |
|
end |
|
self.selected_node = node |
|
if node then |
|
node:Select(true) |
|
end |
|
end |
|
self:OnNodeSelected(node) |
|
end |
|
|
|
function XGraphEditor:GetGraphData() |
|
local data = { links = {} } |
|
local node_to_idx = {} |
|
for idx, node in ipairs(self) do |
|
if IsKindOf(node, "XGraphNode") then |
|
table.insert(data, { x = node.PosX, y = node.PosY, node_class = node.node_class, handle = node.handle }) |
|
node_to_idx[node] = idx |
|
end |
|
end |
|
for _, link in ipairs(self.links) do |
|
local start_sock = link.start_socket |
|
local end_sock = link.end_socket |
|
table.insert(data.links, { |
|
start_node = node_to_idx[start_sock.parent_node], |
|
start_socket = start_sock.socket_id, |
|
end_node = node_to_idx[end_sock.parent_node], |
|
end_socket = end_sock.socket_id, |
|
}) |
|
end |
|
return data |
|
end |
|
|
|
function XGraphEditor:SetGraphData(data) |
|
self:DeleteChildren() |
|
for _, data in ipairs(data) do |
|
local node = XGraphNode:new({}, self) |
|
node:SetNodeClass(data.node_class) |
|
node:SetPos(data.x, data.y) |
|
node.handle = data.handle |
|
end |
|
self.links = {} |
|
for _, link in ipairs(data and data.links) do |
|
local start_sock = table.find_value(self[link.start_node].sockets, "socket_id", link.start_socket) |
|
local end_sock = table.find_value(self[link.end_node].sockets, "socket_id", link.end_socket) |
|
if start_sock and end_sock then |
|
self:AddLink(start_sock, end_sock) |
|
end |
|
end |
|
end |
|
|
|
function XGraphEditor:SetReadOnly(read_only) |
|
self.read_only = read_only |
|
self:CloseContextMenu() |
|
self:Invalidate() |
|
end |
|
|
|
function XGraphEditor:DrawContent() |
|
UIL.DrawSolidRect(box(0, 0, self.map_size:x(), self.map_size:y()), RGB(85, 85, 85)) |
|
|
|
local color1 = self.read_only and RGB(115, 115, 115) or RGB(175, 175, 175) |
|
local color2 = self.read_only and RGB( 95, 95, 95) or RGB(125, 125, 125) |
|
for x = 0, self.map_size:x(), 25 do |
|
local thick = x % 125 == 0 |
|
UIL.DrawLineAntialised(thick and 7 or 3, point(x, 0), point(x, self.map_size:y()), thick and color2 or color1) |
|
end |
|
for y = 0, self.map_size:y(), 25 do |
|
local thick = y % 125 == 0 |
|
UIL.DrawLineAntialised(thick and 7 or 3, point(0, y), point(self.map_size:x(), y), thick and color2 or color1) |
|
end |
|
end |
|
|
|
local function get_link_spline(start_point, end_point) |
|
local offset = start_point:x() < end_point:x() and SocketLinkOffset or -SocketLinkOffset |
|
local spline_start = start_point + offset |
|
local spline_end = end_point - offset |
|
local the_x = spline_end:x() - spline_start:x() |
|
local vector_end1 = point(spline_start:x() + the_x/4, spline_start:y()) |
|
local vector_end2 = point(spline_end:x() - the_x/4, spline_end:y()) |
|
return { spline_start, vector_end1, vector_end2, spline_end } |
|
end |
|
|
|
local function draw_link(start_point, end_point, spline, color) |
|
UIL.DrawLineAntialised(LinkThickness, start_point, spline[1], color) |
|
local spline_length = BS3_GetSplineLength2D(spline) |
|
local last_pos = spline[1] |
|
local i = SplineSampleStep |
|
while i < spline_length do |
|
local next_pos = point(BS3_GetSplinePos2D(spline, i, spline_length)) |
|
UIL.DrawLineAntialised(LinkThickness, last_pos, next_pos, color) |
|
last_pos = next_pos |
|
i = i + SplineSampleStep |
|
end |
|
UIL.DrawLineAntialised(LinkThickness, last_pos, spline[4], color) |
|
UIL.DrawLineAntialised(LinkThickness, spline[4], end_point, color) |
|
end |
|
|
|
function XGraphEditor:DrawChildren(clip_box) |
|
XMap.DrawChildren(self, clip_box) |
|
if self.drag_end_pt and self.drag_start_socket then |
|
local start_pos, end_pos = self.drag_start_socket.box:Center(), self.drag_end_pt |
|
local spline = get_link_spline(start_pos, end_pos) |
|
draw_link(start_pos, end_pos, spline, self.drag_start_socket.ImageColor) |
|
end |
|
for _, link in ipairs(self.links) do |
|
link:DrawSpline(self.drag_end_pt) |
|
end |
|
end |
|
|
|
function XGraphEditor:CloseContextMenu() |
|
if self.menu then |
|
self.menu:delete() |
|
self.menu = false |
|
end |
|
end |
|
|
|
function XGraphEditor:OnMousePos(pt, button) |
|
self.drag_end_pt = self:ScreenToMapPt(pt) |
|
self:Invalidate() |
|
return XMap.OnMousePos(self, pt, button) |
|
end |
|
|
|
function XGraphEditor:OnMouseButtonDown(pt, button) |
|
self:CloseContextMenu() |
|
|
|
local pt1 = self:ScreenToMapPt(pt) |
|
if not self.read_only and button == "L" then |
|
if #self.links > 0 then |
|
for _, spline in ipairs(self.links) do |
|
if BS3_GetSplineToPointDist2D(spline.spline1, self.drag_end_pt) <= LinkMouseHoverDist and not spline.split_point then |
|
local split = XGraphEditorSplineSplitPoint:new({ PosX = pt1:x(), PosY = pt1:y() }, self) |
|
split:OnMouseButtonDown(pt, "L") |
|
spline.split_point = split |
|
self:OnGraphEdited() |
|
break |
|
end |
|
end |
|
end |
|
elseif not self.read_only and button == "R" then |
|
|
|
for idx, spline in ipairs(self.links) do |
|
if BS3_GetSplineToPointDist2D(spline.spline1, self.drag_end_pt) <= LinkMouseHoverDist or |
|
spline.split_point and BS3_GetSplineToPointDist2D(spline.spline2, self.drag_end_pt) <= LinkMouseHoverDist |
|
then |
|
spline:delete() |
|
table.remove(self.links, idx) |
|
self:OnGraphEdited() |
|
return "break" |
|
end |
|
end |
|
|
|
|
|
self.menu = XPopupList:new({ |
|
Background = RGB(196, 196, 196), |
|
}, terminal.desktop) |
|
self.menu:SetAnchorType("mouse") |
|
self.menu.Anchor = pt |
|
for _, obj in ipairs(self.NodeClassItems) do |
|
XTextButton:new({ |
|
OnPress = function() |
|
local node = XGraphNode:new({}, self) |
|
node:SetNodeClass(obj.Class) |
|
node:SetPos(pt1:x(), pt1:y()) |
|
node.handle = #self == 1 and 1 or self[#self - 1].handle + 1 |
|
node.OnLayoutComplete = function() |
|
local clip = false |
|
for _, obj in ipairs(node.map) do |
|
if obj ~= node and node.box:Intersect2D(obj.box) ~= const.irOutside then |
|
clip = true |
|
node:Move(node.box:Center(), obj.box:sizex(), 0, 100) |
|
break |
|
end |
|
end |
|
if not clip then |
|
node.last_valid_pt = node:GetPos() |
|
end |
|
node.OnLayoutComplete = nil |
|
end |
|
self:CloseContextMenu() |
|
self:OnGraphEdited() |
|
end, |
|
Text = obj.EditorName, |
|
RolloverBackground = RGB(204, 232, 255), |
|
PressedBackground = RGB(121, 189, 241), |
|
}, self.menu) |
|
end |
|
return "break" |
|
end |
|
return XMap.OnMouseButtonDown(self, pt, button) |
|
end |
|
|
|
function XGraphEditor:AddLink(sock1, sock2) |
|
if self:CanConnect(sock1, sock2) then |
|
local link = XGraphLink:new{ start_socket = sock2, end_socket = sock1 } |
|
table.insert(self.links, link) |
|
return link |
|
end |
|
end |
|
|
|
function XGraphEditor:RemoveLinks(sock) |
|
for idx = #self.links, 1, -1 do |
|
local spline = self.links[idx] |
|
if spline.end_socket == sock or spline.start_socket == sock then |
|
spline:delete() |
|
table.remove(self.links, idx) |
|
end |
|
end |
|
end |
|
|
|
function XGraphEditor:OnLayoutComplete() |
|
self:UpdateLinkSplines() |
|
return XMap.OnLayoutComplete(self) |
|
end |
|
|
|
function XGraphEditor:UpdateLinkSplines(sock) |
|
for _, spline in ipairs(self.links) do |
|
if not sock or spline.end_socket == sock or spline.start_socket == sock then |
|
spline:CalcSplinePoints() |
|
end |
|
end |
|
end |
|
|
|
function XGraphEditor:CanConnect(sock1, sock2) |
|
local data1, data2 = sock1.link_data, sock2.link_data |
|
return |
|
sock1.parent_node ~= sock2.parent_node and |
|
(data1.type == nil or data2.type == nil or data1.type == data2.type) and |
|
(data1.input == nil or data2.input == nil or data1.input ~= data2.input) |
|
end |
|
|
|
function XGraphEditor:IsConnected(sock1, sock2) |
|
for _, spline in ipairs(self.links) do |
|
if spline.start_socket == sock2 and spline.end_socket == sock1 or spline.start_socket == sock1 and spline.end_socket == sock2 then |
|
return true |
|
end |
|
end |
|
end |
|
|
|
|
|
DefineClass.XGraphNode = { |
|
__parents = { "XMapObject" }, |
|
|
|
Background = RGB(196, 196, 196), |
|
BorderColor = NodeSelectedColor, |
|
LayoutMethod = "HList", |
|
|
|
node_class = false, |
|
handle = false, |
|
sockets = false, |
|
last_valid_pt = false, |
|
diff_x = false, |
|
diff_y = false, |
|
} |
|
|
|
function XGraphNode:SetNodeClass(node_class) |
|
self:DeleteChildren() |
|
self.sockets = {} |
|
self.node_class = node_class |
|
|
|
local class = g_Classes[node_class] |
|
local title = XText:new({ |
|
Dock = "top", |
|
TextHAlign = "center", |
|
TextStyle = "GedTitle", |
|
UseClipBox = false, |
|
Clip = false, |
|
}, self) |
|
title:SetText(class.EditorName) |
|
local inputW = XWindow:new({ |
|
HAlign = "left", |
|
LayoutMethod = "VList", |
|
UseClipBox = false, |
|
Margins = box(0, 0, 10, 0), |
|
}, self) |
|
local outputW = XWindow:new({ |
|
HAlign = "right", |
|
LayoutMethod = "VList", |
|
UseClipBox = false, |
|
Margins = box(10, 0, 0, 0), |
|
}, self) |
|
|
|
|
|
for _, link_data in ipairs(class.GraphLinkSockets) do |
|
local alignment = link_data.input and "right" or "left" |
|
local socket_parent = link_data.input and inputW or outputW |
|
local inputBlock = XWindow:new({ |
|
HAlign = link_data.input and "left" or "right", |
|
UseClipBox = false, |
|
}, socket_parent) |
|
local sock = XGraphSocket:new({ |
|
HAlign = alignment, |
|
parent_node = self, |
|
link_data = link_data, |
|
}, inputBlock) |
|
local text = XText:new({ |
|
Dock = alignment, |
|
TextHAlign = alignment, |
|
TextStyle = "GedTitle", |
|
UseClipBox = false, |
|
Clip = false, |
|
}, inputBlock) |
|
text:SetText(link_data.name or link_data.id) |
|
table.insert(self.sockets, sock) |
|
end |
|
end |
|
|
|
function XGraphNode:Select(selected) |
|
self:SetBorderWidth(selected and 2 or 0) |
|
end |
|
|
|
function XGraphNode:OnMouseButtonDown(pt, button) |
|
self.map:CloseContextMenu() |
|
|
|
if not self.map.read_only and button == "L" then |
|
terminal.desktop:SetMouseCapture(self) |
|
local pt1 = self.map:ScreenToMapPt(pt) |
|
self.map.last_node_pt = self:GetPos() |
|
self.last_valid_pt = self:GetPos() |
|
self.diff_x = self.PosX - pt1:x() |
|
self.diff_y = self.PosY - pt1:y() |
|
self.map:SelectNode(self) |
|
return "break" |
|
elseif not self.map.read_only and button == "R" then |
|
local map = self.map |
|
map.menu = XPopupList:new({ |
|
Background = RGB(196, 196, 196), |
|
}, terminal.desktop) |
|
map.menu:SetAnchorType("mouse") |
|
map.menu.Anchor = pt |
|
XTextButton:new({ |
|
OnPress = function() |
|
self:DeleteLinks() |
|
self:delete() |
|
map:CloseContextMenu() |
|
map:OnGraphEdited() |
|
end, |
|
Text = "Delete Node", |
|
RolloverBackground = RGB(204, 232, 255), |
|
PressedBackground = RGB(121, 189, 241), |
|
HAlign = "left", |
|
}, self.map.menu) |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphNode:OnMousePos(pt, button) |
|
if terminal.desktop:GetMouseCapture() == self then |
|
if self:IsThreadRunning("ScrollThread") then |
|
if self.map.box:Point2DInside(pt) then |
|
self:DeleteThread("ScrollThread") |
|
end |
|
return "break" |
|
end |
|
local my_pt = self:GetPos() |
|
local pt1 = self.map:ScreenToMapPt(pt) |
|
local my_min = self.map:ScreenToMapPt(point(self.map.box:minx(),self.map.box:miny())) |
|
local my_max = self.map:ScreenToMapPt(point(self.map.box:maxx(),self.map.box:maxy())) |
|
if my_pt:x() > 0 + self.box:sizex()/2 or |
|
my_pt:x() < self.map.box:sizex() - self.box:sizex()/2 or |
|
my_pt:y() > 0 + self.box:sizey()/2 or |
|
my_pt:y() < self.map.box:sizey() - self.box:sizex()/2 |
|
then |
|
if pt1:x() < my_min:x() + self.box:sizex()/2 or |
|
pt1:x() > my_max:x() - self.box:sizex()/2 or |
|
pt1:y() < my_min:y() + self.box:sizey()/2 or |
|
pt1:y() > my_max:y() - self.box:sizey()/2 |
|
then |
|
self:CreateThread("ScrollThread", function() |
|
while true do |
|
self:Move(pt1, self.diff_x, self.diff_y, 100) |
|
Sleep(100) |
|
end |
|
end) |
|
else |
|
self:Move(pt1, self.diff_x, self.diff_y, false) |
|
end |
|
end |
|
local clip = false |
|
for i, obj in ipairs(self.map) do |
|
if obj ~= self and self.box:Intersect2D(obj.box) ~= const.irOutside then |
|
clip = true |
|
break |
|
end |
|
end |
|
if not clip then |
|
self.last_valid_pt = self:GetPos() |
|
end |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphNode:OnMouseButtonUp(pt, button) |
|
if terminal.desktop:GetMouseCapture() == self then |
|
if self:IsThreadRunning("ScrollThread") then |
|
self:DeleteThread("ScrollThread") |
|
else |
|
self:SetPos(self.last_valid_pt:x(), self.last_valid_pt:y()) |
|
end |
|
terminal.desktop:SetMouseCapture(false) |
|
self.map:OnGraphEdited() |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphNode:Move(mouse_pt, dx, dy, scroll) |
|
local my_min = self.map:ScreenToMapPt(point(self.map.box:minx(), self.map.box:miny())) |
|
local my_max = self.map:ScreenToMapPt(point(self.map.box:maxx(), self.map.box:maxy())) |
|
self:SetPos( |
|
Clamp(mouse_pt:x() + dx, self.box:sizex()/2, self.map.map_size:x() - self.box:sizex()/2), |
|
Clamp(mouse_pt:y() + dy, self.box:sizey()/2, self.map.map_size:y() - self.box:sizey()/2), |
|
scroll) |
|
if scroll then |
|
local xd = self.PosX - self.map.last_node_pt:x() |
|
local yd = self.PosY - self.map.last_node_pt:y() |
|
xd = MulDivRound(xd, 1000, self.map.scale:x()) |
|
yd = MulDivRound(yd, 1000, self.map.scale:y()) |
|
self.map:ScrollMap(-xd, -yd, scroll) |
|
end |
|
if mouse_pt:x() > self.map.map_size:x() or mouse_pt:y() > self.map.map_size:y() then |
|
if mouse_pt:x() > self.map.map_size:x() then |
|
self.map.map_size = point(self.map.map_size:x() + 25, self.map.map_size:y()) |
|
end |
|
if mouse_pt:y() > self.map.map_size:y() then |
|
self.map.map_size = point(self.map.map_size:x(), self.map.map_size:y() + 25) |
|
end |
|
end |
|
self.map.last_node_pt = self:GetPos() |
|
|
|
for _, sock in ipairs(self.sockets) do |
|
self.map:UpdateLinkSplines(sock) |
|
end |
|
end |
|
|
|
function XGraphNode:DeleteLinks() |
|
for _, sock in ipairs(self.sockets) do |
|
self.map:RemoveLinks(sock) |
|
end |
|
end |
|
|
|
|
|
DefineClass.XGraphSocket = { |
|
__parents = { "XImage" }, |
|
|
|
UseClipBox = false, |
|
Image = "CommonAssets/UI/Ged/socket_empty", |
|
ImageScale = point(500, 500), |
|
HandleMouse = true, |
|
|
|
link_data = false, |
|
socket_id = false, |
|
parent_node = false, |
|
connections = 0, |
|
} |
|
|
|
function XGraphSocket:Init() |
|
self.socket_id = self.link_data.id |
|
self.ImageColor = GraphSocketColors[self.link_data.type] or GraphSocketColors.any |
|
end |
|
|
|
function XGraphSocket:AddConnection() |
|
self.connections = self.connections + 1 |
|
self:SetImage("CommonAssets/UI/Ged/socket_full") |
|
end |
|
|
|
function XGraphSocket:RemoveConnection() |
|
self.connections = self.connections - 1 |
|
if self.connections == 0 then |
|
self:SetImage("CommonAssets/UI/Ged/socket_empty") |
|
end |
|
end |
|
|
|
function XGraphSocket:OnMouseButtonDown(pt, button) |
|
local map = GetParentOfKind(self, "XMap") |
|
if not map.read_only and button == "L" then |
|
map.drag_start_socket = self |
|
terminal.desktop:SetMouseCapture(self) |
|
return "break" |
|
elseif not map.read_only and button == "R" then |
|
map:RemoveLinks(self) |
|
map:OnGraphEdited() |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphSocket:OnMousePos(pt, button) |
|
if terminal.desktop:GetMouseCapture() == self then |
|
self:SetImage("CommonAssets/UI/Ged/socket_full") |
|
local map = GetParentOfKind(self, "XMap") |
|
local target = map:GetMouseTarget(pt) |
|
if IsKindOf(target, "XGraphSocket") and map:CanConnect(self, target) and target.connections == 0 then |
|
if map.drag_end_socket and map.drag_end_socket ~= target then |
|
map.drag_end_socket:SetImage("CommonAssets/UI/Ged/socket_empty") |
|
end |
|
target:SetImage("CommonAssets/UI/Ged/socket_full") |
|
map.drag_end_socket = target |
|
elseif map.drag_end_socket then |
|
map.drag_end_socket:SetImage("CommonAssets/UI/Ged/socket_empty") |
|
map.drag_end_socket = false |
|
end |
|
map.drag_end_pt = map:ScreenToMapPt(pt) |
|
map:Invalidate() |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphSocket:OnMouseButtonUp(pt, button) |
|
if terminal.desktop:GetMouseCapture() == self then |
|
terminal.desktop:SetMouseCapture(false) |
|
local map = GetParentOfKind(self, "XMap") |
|
local target = map:GetMouseTarget(pt) |
|
if IsKindOf(target, "XGraphSocket") and map:CanConnect(target, self) then |
|
map:AddLink(self, target):CalcSplinePoints() |
|
elseif self.connections == 0 then |
|
self:SetImage("CommonAssets/UI/Ged/socket_empty") |
|
end |
|
map.drag_end_socket = false |
|
map.drag_start_socket = false |
|
map:Invalidate() |
|
map:OnGraphEdited() |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphSocket:OnSetRollover(inside) |
|
if inside or self.connections > 0 then |
|
self:SetImage("CommonAssets/UI/Ged/socket_full") |
|
else |
|
self:SetImage("CommonAssets/UI/Ged/socket_empty") |
|
end |
|
end |
|
|
|
|
|
DefineClass.XGraphLink = { |
|
__parents = { "InitDone" }, |
|
|
|
spline1 = false, |
|
spline2 = false, |
|
start_socket = false, |
|
end_socket = false, |
|
split_point = false, |
|
} |
|
|
|
function XGraphLink:Init() |
|
self.start_socket:AddConnection() |
|
self.end_socket:AddConnection() |
|
end |
|
|
|
function XGraphLink:Done() |
|
self.start_socket:RemoveConnection() |
|
self.end_socket:RemoveConnection() |
|
if spline.split_point then |
|
spline.split_point:delete() |
|
end |
|
end |
|
|
|
function XGraphLink:CalcSplinePoints() |
|
local start_point = self.start_socket.box:Center() |
|
local end_point = self.end_socket.box:Center() |
|
if self.split_point then |
|
local midpoint = self.split_point.box:Center() |
|
self.spline1 = get_link_spline(start_point, midpoint - SocketLinkOffset) |
|
self.spline2 = get_link_spline(midpoint + SocketLinkOffset, end_point) |
|
else |
|
self.spline1 = get_link_spline(start_point, end_point) |
|
end |
|
end |
|
|
|
function XGraphLink:PointInside(mouse_pt) |
|
if self.split_point then |
|
return (BS3_GetSplineToPointDist2D(self.spline1, mouse_pt) <= LinkMouseHoverDist or |
|
BS3_GetSplineToPointDist2D(self.spline2, mouse_pt) <= LinkMouseHoverDist) |
|
else |
|
return BS3_GetSplineToPointDist2D(self.spline1, mouse_pt) <= LinkMouseHoverDist |
|
end |
|
end |
|
|
|
function XGraphLink:DrawSpline(mouse_pt) |
|
local color = GraphSocketColors[self.start_socket.link_data.type or self.end_socket.link_data.type or "any"] |
|
if mouse_pt and self:PointInside(mouse_pt) and not terminal.desktop:GetMouseCapture() then |
|
color = InterpolateRGB(color, const.clrWhite, 1, 3) |
|
end |
|
|
|
local start_point = self.start_socket.box:Center() |
|
local end_point = self.end_socket.box:Center() |
|
if not self.split_point then |
|
draw_link(start_point, end_point, self.spline1, color) |
|
else |
|
local split_point = self.split_point.box:Center() |
|
draw_link(start_point, split_point, self.spline1, color) |
|
draw_link(split_point, end_point, self.spline2, color) |
|
end |
|
end |
|
|
|
|
|
DefineClass.XGraphEditorSplineSplitPoint = { |
|
__parents = { "XMapObject" }, |
|
|
|
HandleMouse = true, |
|
MinWidth = 10, |
|
MaxWidth = 10, |
|
MinHeight = 10, |
|
MaxHeight = 10, |
|
} |
|
|
|
function XGraphEditorSplineSplitPoint:OnMouseButtonDown(pt, button) |
|
if not self.map.read_only and button == "L" then |
|
terminal.desktop:SetMouseCapture(self) |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphEditorSplineSplitPoint:OnMousePos(pt, button) |
|
if terminal.desktop:GetMouseCapture() == self then |
|
local pt1 = self.map:ScreenToMapPt(pt) |
|
self:SetPos(pt1:x(), pt1:y()) |
|
self.map:Invalidate() |
|
return "break" |
|
end |
|
end |
|
|
|
function XGraphEditorSplineSplitPoint:OnMouseButtonUp(pt, button) |
|
if terminal.desktop:GetMouseCapture() == self then |
|
local pt1 = self.map:ScreenToMapPt(pt) |
|
self:SetPos(pt1:x(), pt1:y()) |
|
terminal.desktop:SetMouseCapture(false) |
|
self.map:OnGraphEdited() |
|
return "break" |
|
end |
|
end |
|
|
|
|
|
|
|
|
|
DefineClass("TestGraphNode", "PropertyObject") |
|
|
|
DefineClass.GraphNodeMath = { |
|
__parents = { "TestGraphNode" }, |
|
properties = { |
|
{ id = "Operation", editor = "text", default = "" }, |
|
}, |
|
|
|
GraphLinkSockets = { |
|
{ id = "input1", name = "A", input = true, type = "number", }, |
|
{ id = "input2", name = "B", input = true, type = "number", }, |
|
{ id = "output", name = "Output", input = false, type = "number", }, |
|
}, |
|
EditorName = "Math Node", |
|
} |
|
|
|
DefineClass.GraphNodeBooleanCheck = { |
|
__parents = { "TestGraphNode" }, |
|
|
|
GraphLinkSockets = { |
|
{ id = "input1", name = "InfoCheck", input = true, }, |
|
{ id = "input2", name = "InfoGot", input = true, }, |
|
{ id = "output1", name = "false", input = false, type = "boolean", }, |
|
{ id = "output2", name = "true", input = false, type = "boolean", }, |
|
}, |
|
EditorName = "Boolean Node", |
|
} |
|
|
|
DefineClass.GraphNodeString = { |
|
__parents = { "TestGraphNode" }, |
|
|
|
GraphLinkSockets = { |
|
{ id = "input1", name = "word", input = true, type = "string", }, |
|
{ id = "input2", name = "another word", input = true, type = "string", }, |
|
{ id = "input3", name = "even more word", input = true, type = "string", }, |
|
{ id = "input4", name = "many a word", input = true, type = "string", }, |
|
{ id = "output", name = "Sentence", input = false, type = "string", }, |
|
}, |
|
EditorName = "String Node", |
|
} |
|
|