Browse Source

Added possibility to reattach inpus. Fixed undo color space for beta files

flabbet 6 months ago
parent
commit
aa2e2ccfc2

+ 114 - 47
src/PixiEditor.ChangeableDocument/Changes/NodeGraph/ConnectProperties_Change.cs

@@ -14,7 +14,8 @@ internal class ConnectProperties_Change : Change
     public string InputProperty { get; }
     public string OutputProperty { get; }
 
-    private IOutputProperty? originalConnection;
+    private PropertyConnection originalConnection;
+    private List<PropertyConnection> originalConnectionsAtOutput;
 
     [GenerateMakeChangeAction]
     public ConnectProperties_Change(Guid inputNodeId, Guid outputNodeId, string inputProperty, string outputProperty)
@@ -38,12 +39,21 @@ internal class ConnectProperties_Change : Change
         InputProperty? inputProp = inputNode.GetInputProperty(InputProperty);
         OutputProperty? outputProp = outputNode.GetOutputProperty(OutputProperty);
 
+        if (inputNode == outputNode && outputProp == null)
+        {
+            var input = inputNode.GetInputProperty(OutputProperty);
+            if (input is { Connection: not null })
+            {
+                outputProp = input.Connection as OutputProperty;
+            }
+        }
+
         if (inputProp == null || outputProp == null)
         {
             return false;
         }
-        
-        if(IsLoop(inputProp, outputProp))
+
+        if (IsLoop(inputProp, outputProp))
         {
             return false;
         }
@@ -55,35 +65,17 @@ internal class ConnectProperties_Change : Change
             return false;
         }
 
-        originalConnection = inputProp.Connection;
+        originalConnection =
+            new PropertyConnection(inputProp.Connection?.Node.Id, inputProp.Connection?.InternalPropertyName);
+        originalConnectionsAtOutput = new List<PropertyConnection>();
 
-        return true;
-    }
-    
-    private bool IsLoop(InputProperty input, OutputProperty output)
-    {
-        if (input.Node == output.Node)
+        foreach (var connection in outputProp.Connections)
         {
-            return true;
-        }
-        if(input.Node.OutputProperties.Any(x => x.Connections.Any(y => y.Node == output.Node)))
-        {
-            return true;
+            originalConnectionsAtOutput.Add(new PropertyConnection(connection.Node.Id,
+                connection.InternalPropertyName));
         }
-        
-        bool isLoop = false;
-        input.Node.TraverseForwards(x =>
-        {
-            if (x == output.Node)
-            {
-                isLoop = true;
-                return false;
-            }
-
-            return true;
-        });
 
-        return isLoop;
+        return true;
     }
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
@@ -95,11 +87,32 @@ internal class ConnectProperties_Change : Change
         InputProperty inputProp = inputNode.GetInputProperty(InputProperty);
         OutputProperty outputProp = outputNode.GetOutputProperty(OutputProperty);
 
+        List<IChangeInfo> changes = new();
+
+        if (inputNode == outputNode && outputProp == null)
+        {
+            var input = inputNode.GetInputProperty(OutputProperty);
+            if (input is { Connection: not null })
+            {
+                outputProp = input.Connection as OutputProperty;
+
+                if (outputProp != null)
+                {
+                    changes.Add(new ConnectProperty_ChangeInfo(null, inputNode.Id, null, OutputProperty));
+                }
+
+                outputProp.DisconnectFrom(input);
+            }
+        }
+
         outputProp.ConnectTo(inputProp);
 
         ignoreInUndo = false;
 
-        return new ConnectProperty_ChangeInfo(outputNode.Id, inputNode.Id, OutputProperty, InputProperty);
+        changes.Add(new ConnectProperty_ChangeInfo(outputProp.Node.Id, InputNodeId, outputProp.InternalPropertyName,
+            InputProperty));
+        
+        return changes;
     }
 
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
@@ -110,25 +123,79 @@ internal class ConnectProperties_Change : Change
         InputProperty inputProp = inputNode.GetInputProperty(InputProperty);
         OutputProperty outputProp = outputNode.GetOutputProperty(OutputProperty);
 
-        outputProp.DisconnectFrom(inputProp);
+        List<IChangeInfo> changes = new();
+
+        if (inputNode == outputNode && outputProp == null)
+        {
+            var input = inputNode.GetInputProperty(OutputProperty);
 
-        ConnectProperty_ChangeInfo change = new(null, InputNodeId, null, InputProperty);
+            if (inputProp.Connection != null)
+            {
+                inputProp.Connection.ConnectTo(input);
+                changes.Add(new ConnectProperty_ChangeInfo(inputProp.Connection.Node.Id, input.Node.Id,
+                    inputProp.Connection.InternalPropertyName, input.InternalPropertyName));
+                
+                outputProp = input.Connection as OutputProperty;
+            }
+        }
 
-        inputProp.Connection = originalConnection;
+        outputProp.DisconnectFrom(inputProp);
 
-        List<IChangeInfo> changes = new() { change, };
+        changes.Add(new ConnectProperty_ChangeInfo(null, InputNodeId, null, InputProperty));
 
-        if (originalConnection != null)
+        if (originalConnection.NodeId != null)
         {
-            ConnectProperty_ChangeInfo oldConnection = new(originalConnection.Node.Id, InputNodeId,
-                originalConnection.InternalPropertyName, InputProperty);
-            changes.Add(oldConnection);
+            Node originalNode = target.FindNode(originalConnection.NodeId.Value);
+            IOutputProperty? originalOutput = originalNode.GetOutputProperty(originalConnection.PropertyName);
+            originalOutput.ConnectTo(inputProp);
+
+            changes.Add(new ConnectProperty_ChangeInfo(originalOutput.Node.Id, inputProp.Node.Id,
+                originalOutput.InternalPropertyName, InputProperty));
         }
 
+        foreach (var connection in originalConnectionsAtOutput)
+        {
+            if (connection.NodeId.HasValue)
+            {
+                Node originalNode = target.FindNode(connection.NodeId.Value);
+                IInputProperty? originalInput = originalNode.GetInputProperty(connection.PropertyName);
+                outputProp.ConnectTo(originalInput);
+
+                changes.Add(new ConnectProperty_ChangeInfo(outputProp.Node.Id, originalInput.Node.Id,
+                    outputProp.InternalPropertyName, originalInput.InternalPropertyName));
+            }
+        }
 
         return changes;
     }
 
+    private bool IsLoop(InputProperty input, OutputProperty output)
+    {
+        if (input.Node == output.Node)
+        {
+            return true;
+        }
+
+        if (input.Node.OutputProperties.Any(x => x.Connections.Any(y => y.Node == output.Node)))
+        {
+            return true;
+        }
+
+        bool isLoop = false;
+        input.Node.TraverseForwards(x =>
+        {
+            if (x == output.Node)
+            {
+                isLoop = true;
+                return false;
+            }
+
+            return true;
+        });
+
+        return isLoop;
+    }
+
     private static bool CheckTypeCompatibility(InputProperty input, OutputProperty output)
     {
         if (input.ValueType != output.ValueType)
@@ -139,17 +206,17 @@ internal class ConnectProperties_Change : Change
             }
 
             object? outputValue = output.Value;
-            
-            if(IsExpressionToConstant(output, input, out var result))
+
+            if (IsExpressionToConstant(output, input, out var result))
             {
                 outputValue = result;
             }
-            
-            if(IsConstantToExpression(input, outputValue, out result))
+
+            if (IsConstantToExpression(input, outputValue, out result))
             {
                 return ConversionTable.TryConvert(result, output.ValueType, out _);
             }
-            
+
             if (output.ValueType.IsAssignableTo(input.ValueType))
             {
                 return true;
@@ -165,7 +232,7 @@ internal class ConnectProperties_Change : Change
 
         return true;
     }
-    
+
     private static bool IsConstantToExpression(InputProperty input, object objValue, out object result)
     {
         if (input.Value is Delegate func && func.Method.ReturnType.IsAssignableTo(typeof(ShaderExpressionVariable)))
@@ -173,7 +240,7 @@ internal class ConnectProperties_Change : Change
             try
             {
                 var actualArg = func.DynamicInvoke(FuncContext.NoContext);
-                if(actualArg is ShaderExpressionVariable variable)
+                if (actualArg is ShaderExpressionVariable variable)
                 {
                     result = variable.GetConstant();
                     return true;
@@ -197,11 +264,11 @@ internal class ConnectProperties_Change : Change
             try
             {
                 o = func.DynamicInvoke(FuncContext.NoContext);
-                if(o is ShaderExpressionVariable variable)
+                if (o is ShaderExpressionVariable variable)
                 {
                     o = variable.GetConstant();
                 }
-                
+
                 return true;
             }
             catch
@@ -221,7 +288,7 @@ internal class ConnectProperties_Change : Change
         {
             return secondType.IsAssignableTo(typeof(Delegate));
         }
-        
+
         return false;
     }
 }

+ 7 - 1
src/PixiEditor/ViewModels/SubViewModels/NodeGraphManagerViewModel.cs

@@ -61,8 +61,14 @@ internal class NodeGraphManagerViewModel : SubViewModel<ViewModelMain>
     }
     
     [Command.Internal("PixiEditor.NodeGraph.ConnectProperties")]
-    public void ConnectProperties((INodePropertyHandler input, INodePropertyHandler output) args)
+    public void ConnectProperties((INodePropertyHandler input, INodePropertyHandler output, INodePropertyHandler? inputToDisconnect) args)
     {
+        using var changeBlock = Owner.DocumentManagerSubViewModel.ActiveDocument.Operations.StartChangeBlock();
+        if (args.inputToDisconnect != null)
+        {
+            Owner.DocumentManagerSubViewModel.ActiveDocument.NodeGraph.ConnectProperties(args.inputToDisconnect, null);
+        }
+        
         Owner.DocumentManagerSubViewModel.ActiveDocument?.NodeGraph.ConnectProperties(args.input, args.output);
     }
 

+ 23 - 10
src/PixiEditor/Views/Nodes/NodeGraphView.cs

@@ -300,7 +300,7 @@ internal class NodeGraphView : Zoombox.Zoombox
             }
         }
     }
-    
+
     private void Node_PropertyChanged(object? sender, PropertyChangedEventArgs e)
     {
         if (e.PropertyName == nameof(NodeViewModel.PositionBindable))
@@ -582,11 +582,11 @@ internal class NodeGraphView : Zoombox.Zoombox
 
     private void UpdateConnections(NodeView nodeView)
     {
-        if(nodeView == null)
+        if (nodeView == null)
         {
             return;
         }
-        
+
         foreach (NodePropertyView propertyView in nodeView.GetVisualDescendants().OfType<NodePropertyView>())
         {
             NodePropertyViewModel property = (NodePropertyViewModel)propertyView.DataContext;
@@ -639,7 +639,7 @@ internal class NodeGraphView : Zoombox.Zoombox
             return;
         }
 
-        (INodePropertyHandler, INodePropertyHandler) connection = (startConnectionProperty, null);
+        (INodePropertyHandler, INodePropertyHandler, INodePropertyHandler?) connection = (startConnectionProperty, null, null);
         if (socket != null)
         {
             endConnectionNode = socket.Node;
@@ -651,20 +651,33 @@ internal class NodeGraphView : Zoombox.Zoombox
                 return;
             }
 
-            connection = (startConnectionProperty, endConnectionProperty);
+            connection = (startConnectionProperty, endConnectionProperty, null);
+
+            if (startConnectionProperty.IsInput && endConnectionProperty.IsInput &&
+                startConnectionProperty.ConnectedOutput != null)
+            {
+                connection = (startConnectionProperty.ConnectedOutput, endConnectionProperty, startConnectionProperty);
+            }
 
             if (startConnectionNode == endConnectionNode)
             {
-                if (_hiddenConnection != null)
+                if (startConnectionProperty != endConnectionProperty)
                 {
-                    NodeGraph.Connections.Add(_hiddenConnection);
-                    _hiddenConnection = null;
+                    connection = (endConnectionProperty, startConnectionProperty, null);
+                }
+                else
+                {
+                    return;
                 }
-
-                return;
             }
         }
 
+        if (_hiddenConnection != null)
+        {
+            NodeGraph.Connections.Add(_hiddenConnection);
+            _hiddenConnection = null;
+        }
+
         if (ConnectPropertiesCommand != null && ConnectPropertiesCommand.CanExecute(connection))
         {
             ConnectPropertiesCommand.Execute(connection);

+ 1 - 0
src/PixiEditor/Views/Windows/BetaExampleButton.axaml.cs

@@ -72,6 +72,7 @@ public partial class BetaExampleButton : UserControl
         
         ViewModelMain.Current.FileSubViewModel.OpenRecoveredDotPixi(null, bytes);
         ViewModelMain.Current.DocumentManagerSubViewModel.Documents[^1].Operations.UseSrgbProcessing();
+        ViewModelMain.Current.DocumentManagerSubViewModel.Documents[^1].Operations.ClearUndo();
         Analytics.SendOpenExample(FileName);
     }