|
@@ -15,6 +15,7 @@ using PixiEditor.AvaloniaUI.ViewModels.Document;
|
|
using PixiEditor.AvaloniaUI.ViewModels.Nodes;
|
|
using PixiEditor.AvaloniaUI.ViewModels.Nodes;
|
|
using PixiEditor.AvaloniaUI.Views.Nodes.Properties;
|
|
using PixiEditor.AvaloniaUI.Views.Nodes.Properties;
|
|
using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
|
|
using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
|
|
|
|
+using PixiEditor.ChangeableDocument.Changes.NodeGraph;
|
|
using PixiEditor.Numerics;
|
|
using PixiEditor.Numerics;
|
|
using Point = Avalonia.Point;
|
|
using Point = Avalonia.Point;
|
|
|
|
|
|
@@ -157,7 +158,10 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
private INodeHandler startConnectionNode;
|
|
private INodeHandler startConnectionNode;
|
|
private INodeHandler endConnectionNode;
|
|
private INodeHandler endConnectionNode;
|
|
|
|
|
|
|
|
+ private Point startDragConnectionPoint;
|
|
private ConnectionLine _previewConnectionLine;
|
|
private ConnectionLine _previewConnectionLine;
|
|
|
|
+ private NodeConnectionViewModel? _hiddenConnection;
|
|
|
|
+ private Color _startingPropColor;
|
|
|
|
|
|
public NodeGraphView()
|
|
public NodeGraphView()
|
|
{
|
|
{
|
|
@@ -184,23 +188,67 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
{
|
|
{
|
|
if (isDraggingConnection)
|
|
if (isDraggingConnection)
|
|
{
|
|
{
|
|
- Point pos = e.GetPosition(this);
|
|
|
|
- VecD currentPoint = ToZoomboxSpace(new VecD(pos.X, pos.Y));
|
|
|
|
- if (_previewConnectionLine != null)
|
|
|
|
|
|
+ UpdateConnectionEnd(e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void UpdateConnectionEnd(PointerEventArgs e)
|
|
|
|
+ {
|
|
|
|
+ Point pos = e.GetPosition(this);
|
|
|
|
+ VecD currentPoint = ToZoomboxSpace(new VecD(pos.X, pos.Y));
|
|
|
|
+
|
|
|
|
+ NodeSocket? nodeSocket = e.Source as NodeSocket;
|
|
|
|
+
|
|
|
|
+ if (nodeSocket != null)
|
|
|
|
+ {
|
|
|
|
+ Canvas canvas = nodeSocket.FindAncestorOfType<Canvas>();
|
|
|
|
+ pos = nodeSocket.ConnectPort.TranslatePoint(
|
|
|
|
+ new Point(nodeSocket.ConnectPort.Bounds.Width / 2, nodeSocket.ConnectPort.Bounds.Height / 2),
|
|
|
|
+ canvas) ?? default;
|
|
|
|
+ currentPoint = new VecD(pos.X, pos.Y);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (_previewConnectionLine != null)
|
|
|
|
+ {
|
|
|
|
+ Point endPoint = new Point(currentPoint.X, currentPoint.Y);
|
|
|
|
+
|
|
|
|
+ Color gradientStopFirstColor = _startingPropColor;
|
|
|
|
+ Color gradientStopSecondColor =
|
|
|
|
+ ((SolidColorBrush)nodeSocket?.SocketBrush)?.Color ?? gradientStopFirstColor;
|
|
|
|
+
|
|
|
|
+ if (endPoint.X > startDragConnectionPoint.X)
|
|
{
|
|
{
|
|
- _previewConnectionLine.EndPoint = new Point(currentPoint.X, currentPoint.Y);
|
|
|
|
|
|
+ _previewConnectionLine.StartPoint = endPoint;
|
|
|
|
+ _previewConnectionLine.EndPoint = startDragConnectionPoint;
|
|
|
|
+ (gradientStopFirstColor, gradientStopSecondColor) =
|
|
|
|
+ (gradientStopSecondColor, gradientStopFirstColor);
|
|
}
|
|
}
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ _previewConnectionLine.StartPoint = startDragConnectionPoint;
|
|
|
|
+ _previewConnectionLine.EndPoint = endPoint;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _previewConnectionLine.LineBrush = new LinearGradientBrush()
|
|
|
|
+ {
|
|
|
|
+ GradientStops = new GradientStops()
|
|
|
|
+ {
|
|
|
|
+ new GradientStop(gradientStopFirstColor, 0),
|
|
|
|
+ new GradientStop(gradientStopSecondColor, 1),
|
|
|
|
+ }
|
|
|
|
+ };
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
|
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
|
{
|
|
{
|
|
base.OnPointerReleased(e);
|
|
base.OnPointerReleased(e);
|
|
- if (startConnectionProperty != null)
|
|
|
|
|
|
+ if (startConnectionProperty is { IsInput: true } && e.Source is not NodeSocket)
|
|
{
|
|
{
|
|
SocketDrop(null);
|
|
SocketDrop(null);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (isDraggingConnection)
|
|
if (isDraggingConnection)
|
|
{
|
|
{
|
|
if (_previewConnectionLine != null)
|
|
if (_previewConnectionLine != null)
|
|
@@ -209,6 +257,7 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
}
|
|
}
|
|
|
|
|
|
isDraggingConnection = false;
|
|
isDraggingConnection = false;
|
|
|
|
+ _hiddenConnection = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -229,6 +278,18 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
startConnectionNode = nodeSocket.Node;
|
|
startConnectionNode = nodeSocket.Node;
|
|
isDraggingConnection = true;
|
|
isDraggingConnection = true;
|
|
|
|
|
|
|
|
+ if (nodeSocket is { IsInput: true, Property.ConnectedOutput: not null })
|
|
|
|
+ {
|
|
|
|
+ var conn = NodeGraph.Connections.FirstOrDefault(x => x.InputProperty == nodeSocket.Property);
|
|
|
|
+ if (conn != null)
|
|
|
|
+ {
|
|
|
|
+ _hiddenConnection = conn;
|
|
|
|
+ NodeGraph.Connections.Remove(conn);
|
|
|
|
+ NodeView view = FindNodeView(conn.OutputNode);
|
|
|
|
+ nodeSocket = view.GetSocket(conn.OutputProperty);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
UpdatePreviewLine(nodeSocket);
|
|
UpdatePreviewLine(nodeSocket);
|
|
}
|
|
}
|
|
else
|
|
else
|
|
@@ -241,6 +302,11 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private NodeView FindNodeView(INodeHandler node)
|
|
|
|
+ {
|
|
|
|
+ return this.GetVisualDescendants().OfType<NodeView>().FirstOrDefault(x => x.Node == node);
|
|
|
|
+ }
|
|
|
|
+
|
|
private void UpdatePreviewLine(NodeSocket nodeSocket)
|
|
private void UpdatePreviewLine(NodeSocket nodeSocket)
|
|
{
|
|
{
|
|
Canvas canvas = nodeSocket.FindAncestorOfType<Canvas>();
|
|
Canvas canvas = nodeSocket.FindAncestorOfType<Canvas>();
|
|
@@ -248,23 +314,17 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
{
|
|
{
|
|
_previewConnectionLine = new ConnectionLine();
|
|
_previewConnectionLine = new ConnectionLine();
|
|
_previewConnectionLine.Thickness = 2;
|
|
_previewConnectionLine.Thickness = 2;
|
|
- _previewConnectionLine.LineBrush = new LinearGradientBrush()
|
|
|
|
- {
|
|
|
|
- GradientStops = new GradientStops()
|
|
|
|
- {
|
|
|
|
- new GradientStop(Colors.Black, 0), new GradientStop(Colors.White, 1)
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
|
|
|
|
canvas.Children.Insert(0, _previewConnectionLine);
|
|
canvas.Children.Insert(0, _previewConnectionLine);
|
|
}
|
|
}
|
|
|
|
|
|
_previewConnectionLine.IsVisible = true;
|
|
_previewConnectionLine.IsVisible = true;
|
|
|
|
+ _startingPropColor = ((SolidColorBrush)nodeSocket.SocketBrush).Color;
|
|
_previewConnectionLine.LineBrush = new LinearGradientBrush()
|
|
_previewConnectionLine.LineBrush = new LinearGradientBrush()
|
|
{
|
|
{
|
|
GradientStops = new GradientStops()
|
|
GradientStops = new GradientStops()
|
|
{
|
|
{
|
|
- new GradientStop(((SolidColorBrush)nodeSocket.SocketBrush).Color, 1),
|
|
|
|
|
|
+ new GradientStop(_startingPropColor, 1),
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
@@ -272,6 +332,7 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
new Point(nodeSocket.ConnectPort.Bounds.Width / 2, nodeSocket.ConnectPort.Bounds.Height / 2),
|
|
new Point(nodeSocket.ConnectPort.Bounds.Width / 2, nodeSocket.ConnectPort.Bounds.Height / 2),
|
|
canvas) ?? default;
|
|
canvas) ?? default;
|
|
_previewConnectionLine.EndPoint = _previewConnectionLine.StartPoint;
|
|
_previewConnectionLine.EndPoint = _previewConnectionLine.StartPoint;
|
|
|
|
+ startDragConnectionPoint = _previewConnectionLine.StartPoint;
|
|
}
|
|
}
|
|
|
|
|
|
private void Dragged(PointerEventArgs e)
|
|
private void Dragged(PointerEventArgs e)
|
|
@@ -321,6 +382,12 @@ internal class NodeGraphView : Zoombox.Zoombox
|
|
|
|
|
|
if (startConnectionNode == endConnectionNode)
|
|
if (startConnectionNode == endConnectionNode)
|
|
{
|
|
{
|
|
|
|
+ if (_hiddenConnection != null)
|
|
|
|
+ {
|
|
|
|
+ NodeGraph.Connections.Add(_hiddenConnection);
|
|
|
|
+ _hiddenConnection = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|