Implemented functionality for copy node

This commit is contained in:
Ankitkumar Satapara
2026-04-18 20:07:33 +05:30
parent 381e187b6d
commit 7fd70219ea
3 changed files with 119 additions and 4 deletions

View File

@@ -28,6 +28,9 @@ namespace Nodify.Calculator
// Dynamic Split node: populate outputs when a model connects to the Square input // Dynamic Split node: populate outputs when a model connects to the Square input
HandleSplitNodeConnected(c); HandleSplitNodeConnected(c);
// Dynamic Copy node: adapt connectors when something connects
HandleCopyNodeConnected(c);
}) })
.WhenRemoved(c => .WhenRemoved(c =>
{ {
@@ -48,6 +51,9 @@ namespace Nodify.Calculator
// Dynamic Split node: clear outputs when model disconnects // Dynamic Split node: clear outputs when model disconnects
HandleSplitNodeDisconnected(c); HandleSplitNodeDisconnected(c);
// Dynamic Copy node: reset on disconnect
HandleCopyNodeDisconnected(c);
}); });
Operations.WhenAdded(x => Operations.WhenAdded(x =>
@@ -116,7 +122,8 @@ namespace Nodify.Calculator
internal bool CanCreateConnection(ConnectorViewModel source, ConnectorViewModel? target) internal bool CanCreateConnection(ConnectorViewModel source, ConnectorViewModel? target)
=> target == null || (source != target && => target == null || (source != target &&
source.Shape == target.Shape && (source.Shape == target.Shape ||
((source.IsCopyConnector || target.IsCopyConnector) && source.Shape != ConnectorShape.Triangle && target.Shape != ConnectorShape.Triangle)) &&
!source.IsConnected && !source.IsConnected &&
!target.IsConnected && !target.IsConnected &&
source.IsInput != target.IsInput && source.IsInput != target.IsInput &&
@@ -280,6 +287,90 @@ namespace Nodify.Calculator
sysVm.Title = "Split"; sysVm.Title = "Split";
} }
private void HandleCopyNodeConnected(ConnectionViewModel c)
{
// Find the COPY node's input connector
ConnectorViewModel copyConnector = null;
ConnectorViewModel sourceConnector = null;
if (c.Input.IsCopyConnector)
{
copyConnector = c.Input;
sourceConnector = c.Output;
}
else if (c.Output.IsCopyConnector)
{
copyConnector = c.Output;
sourceConnector = c.Input;
}
if (copyConnector == null) return;
var copyOp = copyConnector.Operation;
if (copyOp is not SystemOperationViewModel sysVm || sysVm.SystemOperationType != SystemOperations.COPY)
return;
// Adapt the input connector to match the source
copyConnector.Shape = sourceConnector.Shape;
copyConnector.ConnectorColor = sourceConnector.RawColor;
copyConnector.DataType = sourceConnector.DataType;
// Remove any existing outputs and their connections
var toRemove = copyOp.Output.ToList();
toRemove.ForEach(o =>
{
DisconnectConnector(o);
copyOp.Output.Remove(o);
});
// Create 2 output copy connectors matching the source
for (int i = 0; i < 2; i++)
{
copyOp.Output.Add(new ConnectorViewModel
{
Title = sourceConnector.Title ?? "",
IsInput = false,
Shape = sourceConnector.Shape,
ConnectorColor = sourceConnector.RawColor,
DataType = sourceConnector.DataType,
IsCopyConnector = true
});
}
}
private void HandleCopyNodeDisconnected(ConnectionViewModel c)
{
ConnectorViewModel copyConnector = null;
if (c.Input.IsCopyConnector && c.Input.IsInput)
copyConnector = c.Input;
else if (c.Output.IsCopyConnector && c.Output.IsInput)
copyConnector = c.Output;
if (copyConnector == null) return;
var copyOp = copyConnector.Operation;
if (copyOp is not SystemOperationViewModel sysVm || sysVm.SystemOperationType != SystemOperations.COPY)
return;
// Check if input still has a connection
var stillConnected = Connections.Any(con => con.Input == copyConnector || con.Output == copyConnector);
if (stillConnected) return;
// Reset input connector to universal
copyConnector.Shape = ConnectorShape.Circle;
copyConnector.ConnectorColor = System.Drawing.Color.White;
copyConnector.DataType = string.Empty;
// Remove all outputs and their connections
var toRemove = copyOp.Output.ToList();
toRemove.ForEach(o =>
{
DisconnectConnector(o);
copyOp.Output.Remove(o);
});
}
} }
} }

View File

@@ -67,6 +67,8 @@ namespace Nodify.Calculator
} }
} }
public System.Drawing.Color RawColor => _color;
public Brush Color public Brush Color
{ {
get get
@@ -108,6 +110,16 @@ namespace Nodify.Calculator
set => SetProperty(ref _dataType, value); set => SetProperty(ref _dataType, value);
} }
private bool _isCopyConnector;
/// <summary>
/// When true, this connector belongs to a COPY node and accepts any shape for connections.
/// </summary>
public bool IsCopyConnector
{
get => _isCopyConnector;
set => SetProperty(ref _isCopyConnector, value);
}
/// <summary> /// <summary>
/// Returns a color based on the C# data type. /// Returns a color based on the C# data type.
/// </summary> /// </summary>

View File

@@ -23,12 +23,10 @@ namespace Nodify.Calculator
{ {
Title = "COPY", Title = "COPY",
Type = OperationType.System, Type = OperationType.System,
OPType = "copy", sysOp = SystemOperations.COPY,
IsFlowNode = false, IsFlowNode = false,
}; };
copynode.Input.Add(""); copynode.Input.Add("");
copynode.Output.Add("");
copynode.Output.Add("");
var begin = new OperationInfoViewModel() var begin = new OperationInfoViewModel()
{ {
@@ -330,6 +328,20 @@ namespace Nodify.Calculator
SystemOperationType = info.sysOp SystemOperationType = info.sysOp
}; };
if (info.sysOp == SystemOperations.COPY)
{
sysOp.Title = info.Title;
// Universal input — accepts any shape. Starts with no outputs.
foreach (var item in input)
{
item.Shape = ConnectorShape.Circle;
item.ConnectorColor = Color.White;
item.IsCopyConnector = true;
sysOp.Input.Add(item);
}
return sysOp;
}
if (info.sysOp == SystemOperations.SPLIT) if (info.sysOp == SystemOperations.SPLIT)
{ {
sysOp.Title = info.Title; sysOp.Title = info.Title;