2
0
Эх сурвалжийг харах

Merge branch 'node-polish' into avalonia-rewrite

flabbet 1 жил өмнө
parent
commit
bed328d050

+ 29 - 7
src/PixiEditor.AvaloniaUI/Helpers/DocumentViewModelBuilder.cs

@@ -288,13 +288,35 @@ internal class NodeGraphBuilder
                 .WithKeyFrames(
                 [
                     new KeyFrameData
-                        {
-                            AffectedElement = ImageLayerNode.ImageLayerKey,
-                            Data = new ChunkyImage(image),
-                            Duration = 0,
-                            StartFrame = 0,
-                            IsVisible = true
-                        }
+                    {
+                        AffectedElement = ImageLayerNode.ImageLayerKey,
+                        Data = new ChunkyImage(image),
+                        Duration = 0,
+                        StartFrame = 0,
+                        IsVisible = true
+                    }
+                ]));
+
+        id = AllNodes.Count;
+        return this;
+    }
+
+    public NodeGraphBuilder WithImageLayerNode(string name, VecI size, out int id)
+    {
+        AllNodes.Add(
+            this.WithNodeOfType(typeof(ImageLayerNode))
+                .WithName(name)
+                .WithId(AllNodes.Count + 1)
+                .WithKeyFrames(
+                [
+                    new KeyFrameData
+                    {
+                        AffectedElement = ImageLayerNode.ImageLayerKey,
+                        Data = new ChunkyImage(size),
+                        Duration = 0,
+                        StartFrame = 0,
+                        IsVisible = true
+                    }
                 ]));
 
         id = AllNodes.Count;

+ 1 - 1
src/PixiEditor.AvaloniaUI/Styles/Templates/NodeGraphView.axaml

@@ -12,7 +12,7 @@
                             <nodes:NodePicker
                                 AllNodeTypes="{Binding AllNodeTypes, RelativeSource={RelativeSource TemplatedParent}}"
                                 SearchQuery="{Binding SearchQuery, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
-                                SelectNodeCommand="{Binding CreateNodeCommand, RelativeSource={RelativeSource TemplatedParent}}"
+                                SelectNodeCommand="{Binding CreateNodeFromContextCommand, RelativeSource={RelativeSource TemplatedParent}}"
                                 />
                         </Flyout>
                         </Grid.ContextFlyout>

+ 1 - 1
src/PixiEditor.AvaloniaUI/ViewModels/Document/DocumentViewModel.cs

@@ -297,7 +297,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
 
         AddAnimationData(builderInstance.AnimationData, mappedNodeIds, mappedKeyFrameIds);
 
-        acc.AddFinishedActions(new DeleteRecordedChanges_Action());
+        acc.AddFinishedActions(new ChangeBoundary_Action(), new DeleteRecordedChanges_Action());
         viewModel.MarkAsSaved();
 
         return viewModel;

+ 25 - 4
src/PixiEditor.AvaloniaUI/ViewModels/Document/NodeGraphViewModel.cs

@@ -10,6 +10,7 @@ using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.ChangeableDocument.Changeables.Graph;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
 using PixiEditor.ChangeableDocument.Changeables.Graph.Nodes;
+using PixiEditor.ChangeableDocument.ChangeInfos;
 using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph;
 using PixiEditor.Numerics;
 
@@ -190,21 +191,41 @@ internal class NodeGraphViewModel : ViewModelBase, INodeGraphHandler
         Internals.ActionAccumulator.AddFinishedActions(new EndNodePosition_Action());
     }
 
-    public void CreateNode(Type nodeType)
+    public void CreateNode(Type nodeType, VecD pos = default)
     {
         IAction change;
 
         PairNodeAttribute? pairAttribute = nodeType.GetCustomAttribute<PairNodeAttribute>(true);
+        
+        List<IAction> changes = new();
+        
         if (pairAttribute != null)
         {
-            change = new CreateNodePair_Action(Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), nodeType);
+            Guid startId = Guid.NewGuid();
+            Guid endId = Guid.NewGuid();
+            changes.Add(new CreateNodePair_Action(startId, endId, Guid.NewGuid(), nodeType));
+            
+            if(pos != default)
+            {
+                changes.Add(new NodePosition_Action(startId, pos));
+                changes.Add(new EndNodePosition_Action());
+                changes.Add(new NodePosition_Action(endId, new VecD(pos.X + 400, pos.Y)));
+                changes.Add(new EndNodePosition_Action()); 
+            }
         }
         else
         {
-            change = new CreateNode_Action(nodeType, Guid.NewGuid());
+            Guid nodeId = Guid.NewGuid();
+            changes.Add(new CreateNode_Action(nodeType, nodeId));
+            
+            if(pos != default)
+            {
+                changes.Add(new NodePosition_Action(nodeId, pos));
+                changes.Add(new EndNodePosition_Action());
+            }
         }
 
-        Internals.ActionAccumulator.AddFinishedActions(change);
+        Internals.ActionAccumulator.AddFinishedActions(changes.ToArray());
     }
 
     public void RemoveNodes(Guid[] selectedNodes)

+ 1 - 1
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/FileViewModel.cs

@@ -302,7 +302,7 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
                 .WithGraph(x => x
                     .WithImageLayerNode(
                         new LocalizedString("BASE_LAYER_NAME"),
-                        new Surface(new VecI(newFile.Width, newFile.Height)), out int id)
+                        new VecI(newFile.Width, newFile.Height), out int id)
                     .WithOutputNode(id, "Output")
                 ));
         }

+ 3 - 3
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/NodeGraphManagerViewModel.cs

@@ -33,11 +33,11 @@ internal class NodeGraphManagerViewModel : SubViewModel<ViewModelMain>
     }
 
     [Command.Internal("PixiEditor.NodeGraph.CreateNode")]
-    public void CreateNode(Type nodeType)
+    public void CreateNode((Type nodeType, VecD pos) data)
     {
-        Owner.DocumentManagerSubViewModel.ActiveDocument?.NodeGraph.CreateNode(nodeType);
+        Owner.DocumentManagerSubViewModel.ActiveDocument?.NodeGraph.CreateNode(data.nodeType, data.pos);
     }
-
+    
     [Command.Internal("PixiEditor.NodeGraph.ConnectProperties")]
     public void ConnectProperties((INodePropertyHandler input, INodePropertyHandler output) args)
     {

+ 3 - 1
src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/Viewport.axaml.cs

@@ -437,7 +437,9 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     private void OnMainImageSizeChanged(object? sender, SizeChangedEventArgs e)
     {
         if (scene.Dimensions is { X: 0, Y: 0 }) return;
-        scene.CenterContent(new VecD(e.NewSize.Width, e.NewSize.Height));
+        scene.CenterContent();
+        scene.ZoomIntoCenter(-1);
+        scene.ZoomIntoCenter(1); // a bit hacky, but it resets brush overlay properly
     }
     
     private void ResetViewportClicked(object sender, RoutedEventArgs e)

+ 5 - 0
src/PixiEditor.AvaloniaUI/Views/Nodes/ConnectionLine.cs

@@ -42,6 +42,11 @@ public class ConnectionLine : Control
         AffectsRender<ConnectionLine>(LineBrushProperty, ThicknessProperty, StartPointProperty, EndPointProperty);
     }
 
+    public ConnectionLine()
+    {
+        IsHitTestVisible = false;
+    }
+
     public override void Render(DrawingContext context)
     {
         var p1 = new Point(StartPoint.X, StartPoint.Y);

+ 24 - 1
src/PixiEditor.AvaloniaUI/Views/Nodes/NodeGraphView.cs

@@ -70,6 +70,15 @@ internal class NodeGraphView : Zoombox.Zoombox
         AvaloniaProperty.Register<NodeGraphView, ICommand>(
             "ConnectPropertiesCommand");
 
+    public static readonly StyledProperty<ICommand> CreateNodeFromContextCommandProperty = AvaloniaProperty.Register<NodeGraphView, ICommand>(
+        "CreateNodeFromContextCommand");
+
+    public ICommand CreateNodeFromContextCommand
+    {
+        get => GetValue(CreateNodeFromContextCommandProperty);
+        set => SetValue(CreateNodeFromContextCommandProperty, value);
+    }
+
     public ICommand ConnectPropertiesCommand
     {
         get => GetValue(ConnectPropertiesCommandProperty);
@@ -162,6 +171,7 @@ internal class NodeGraphView : Zoombox.Zoombox
     private ConnectionLine _previewConnectionLine;
     private NodeConnectionViewModel? _hiddenConnection;
     private Color _startingPropColor;
+    private VecD _lastMouseClickPos;
 
     public NodeGraphView()
     {
@@ -170,9 +180,19 @@ internal class NodeGraphView : Zoombox.Zoombox
         DraggedCommand = new RelayCommand<PointerEventArgs>(Dragged);
         EndDragCommand = new RelayCommand<PointerCaptureLostEventArgs>(EndDrag);
         SocketDropCommand = new RelayCommand<NodeSocket>(SocketDrop);
+        CreateNodeFromContextCommand = new RelayCommand<Type>(CreateNodeType);
 
         AllNodeTypes = new ObservableCollection<Type>(GatherAssemblyTypes<Node>());
     }
+    
+    private void CreateNodeType(Type nodeType)
+    {
+        if (CreateNodeCommand != null && CreateNodeCommand.CanExecute(nodeType))
+        {
+            CreateNodeCommand.Execute((nodeType, _lastMouseClickPos));
+            ((Control)this.GetVisualDescendants().FirstOrDefault()).ContextFlyout.Hide();
+        }
+    }
 
     protected override void OnPointerPressed(PointerPressedEventArgs e)
     {
@@ -182,6 +202,9 @@ internal class NodeGraphView : Zoombox.Zoombox
         {
             ClearSelection();
         }
+        
+        Point pos = e.GetPosition(this);
+        _lastMouseClickPos = ToZoomboxSpace(new VecD(pos.X, pos.Y));
     }
 
     protected override void OnPointerMoved(PointerEventArgs e)
@@ -315,7 +338,7 @@ internal class NodeGraphView : Zoombox.Zoombox
             _previewConnectionLine = new ConnectionLine();
             _previewConnectionLine.Thickness = 2;
 
-            canvas.Children.Insert(0, _previewConnectionLine);
+            canvas.Children.Add(_previewConnectionLine);
         }
 
         _previewConnectionLine.IsVisible = true;

+ 3 - 6
src/PixiEditor.AvaloniaUI/Views/Nodes/NodePicker.cs

@@ -5,6 +5,8 @@ using Avalonia.Controls;
 using Avalonia.Controls.Primitives;
 using Avalonia.Interactivity;
 using Avalonia.Markup.Xaml;
+using CommunityToolkit.Mvvm.Input;
+using PixiEditor.Numerics;
 
 namespace PixiEditor.AvaloniaUI.Views.Nodes;
 
@@ -46,17 +48,12 @@ public partial class NodePicker : TemplatedControl
         get => GetValue(SelectNodeCommandProperty);
         set => SetValue(SelectNodeCommandProperty, value);
     }
-
+    
     static NodePicker()
     {
         SearchQueryProperty.Changed.Subscribe(OnSearchQueryChanged);
     }
 
-    public NodePicker()
-    {
-
-    }
-
     private static void OnSearchQueryChanged(AvaloniaPropertyChangedEventArgs e)
     {
         if (e.Sender is NodePicker nodePicker)

+ 0 - 1
src/PixiEditor.AvaloniaUI/Views/Rendering/Scene.cs

@@ -142,7 +142,6 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
 
         RectD dirtyBounds = new RectD(0, 0, Document.Width / resolutionScale, Document.Height / resolutionScale);
         Rect dirtyRect = new Rect(0, 0, Document.Width / resolutionScale, Document.Height / resolutionScale);
-        
 
         using var operation = new DrawSceneOperation(Surface, Document, CanvasPos, Scale * resolutionScale, angle, FlipX, FlipY,
             dirtyRect,

+ 7 - 0
src/PixiEditor.ChangeableDocument/Changeables/Graph/NodeGraph.cs

@@ -60,6 +60,13 @@ public class NodeGraph : IReadOnlyNodeGraph, IDisposable
                 {
                     continue;
                 }
+                
+                if(finalQueue.Contains(input.Connection.Node))
+                {
+                   // swap the order of the nodes
+                   finalQueue.Remove(input.Connection.Node);
+                   finalQueue.Add(input.Connection.Node);
+                }
 
                 queueNodes.Enqueue(input.Connection.Node);
             }