Browse Source

Always select closest member on delete

flabbet 10 months ago
parent
commit
f30b1d2ca2

+ 9 - 7
src/PixiEditor/Models/DocumentModels/ActionAccumulator.cs

@@ -99,12 +99,14 @@ internal class ActionAccumulator
             List<IRenderInfo> renderResult = new();
             if (DrawingBackendApi.Current.IsHardwareAccelerated)
             {
-                renderResult.AddRange(canvasUpdater.UpdateGatheredChunksSync(affectedAreas, undoBoundaryPassed || viewportRefreshRequest));
+                renderResult.AddRange(canvasUpdater.UpdateGatheredChunksSync(affectedAreas,
+                    undoBoundaryPassed || viewportRefreshRequest));
                 renderResult.AddRange(previewUpdater.UpdateGatheredChunksSync(affectedAreas, undoBoundaryPassed));
             }
             else
             {
-                renderResult.AddRange(await canvasUpdater.UpdateGatheredChunks(affectedAreas, undoBoundaryPassed || viewportRefreshRequest));
+                renderResult.AddRange(await canvasUpdater.UpdateGatheredChunks(affectedAreas,
+                    undoBoundaryPassed || viewportRefreshRequest));
                 renderResult.AddRange(await previewUpdater.UpdateGatheredChunks(affectedAreas, undoBoundaryPassed));
             }
 
@@ -156,7 +158,7 @@ internal class ActionAccumulator
                     RectI dirtyRect = new RectI(info.Pos, info.Size).Intersect(finalRect);
                     bitmap.AddDirtyRect(dirtyRect);
                 }
-                    break;
+                break;
                 case PreviewDirty_RenderInfo info:
                 {
                     var bitmap = document.StructureHelper.Find(info.GuidValue)?.PreviewSurface;
@@ -164,7 +166,7 @@ internal class ActionAccumulator
                         continue;
                     bitmap.AddDirtyRect(new RectI(0, 0, bitmap.Size.X, bitmap.Size.Y));
                 }
-                    break;
+                break;
                 case MaskPreviewDirty_RenderInfo info:
                 {
                     var bitmap = document.StructureHelper.Find(info.GuidValue)?.MaskPreviewSurface;
@@ -172,13 +174,13 @@ internal class ActionAccumulator
                         continue;
                     bitmap.AddDirtyRect(new RectI(0, 0, bitmap.Size.X, bitmap.Size.Y));
                 }
-                    break;
+                break;
                 case CanvasPreviewDirty_RenderInfo:
                 {
                     document.PreviewSurface.AddDirtyRect(new RectI(0, 0, document.PreviewSurface.Size.X,
                         document.PreviewSurface.Size.Y));
                 }
-                    break;
+                break;
                 case NodePreviewDirty_RenderInfo info:
                 {
                     var node = document.StructureHelper.Find(info.NodeId);
@@ -187,7 +189,7 @@ internal class ActionAccumulator
                     node.PreviewSurface.AddDirtyRect(new RectI(0, 0, node.PreviewSurface.Size.X,
                         node.PreviewSurface.Size.Y));
                 }
-                    break;
+                break;
             }
         }
     }

+ 13 - 14
src/PixiEditor/Models/DocumentModels/DocumentUpdater.cs

@@ -245,8 +245,6 @@ internal class DocumentUpdater
         if (member.Selection != StructureMemberSelectionType.Soft)
             return;
         member.Selection = StructureMemberSelectionType.None;
-        // TODO: Make sure Selection raises property changed internally
-        //member.OnPropertyChanged(nameof(member.Selection));
         doc.RemoveSoftSelectedMember(member);
     }
 
@@ -257,7 +255,6 @@ internal class DocumentUpdater
             if (oldMember.Selection == StructureMemberSelectionType.Hard)
                 continue;
             oldMember.Selection = StructureMemberSelectionType.None;
-            //oldMember.OnPropertyChanged(nameof(oldMember.Selection));
         }
 
         doc.ClearSoftSelectedMembers();
@@ -269,7 +266,6 @@ internal class DocumentUpdater
         if (member is null || member.Selection == StructureMemberSelectionType.Hard)
             return;
         member.Selection = StructureMemberSelectionType.Soft;
-        //member.OnPropertyChanged(nameof(member.Selection));
         doc.AddSoftSelectedMember(member);
     }
 
@@ -282,11 +278,9 @@ internal class DocumentUpdater
         if (doc.SelectedStructureMember is { } oldMember)
         {
             oldMember.Selection = StructureMemberSelectionType.None;
-            //oldMember.OnPropertyChanged(nameof(oldMember.Selection));
         }
 
         member.Selection = StructureMemberSelectionType.Hard;
-        //member.OnPropertyChanged(nameof(member.Selection));
         doc.SetSelectedMember(member);
     }
 
@@ -419,26 +413,31 @@ internal class DocumentUpdater
         if (doc.SelectedStructureMember is not null)
         {
             doc.SelectedStructureMember.Selection = StructureMemberSelectionType.None;
-            // TODO: Make sure property changed events are raised internally
-            //doc.SelectedStructureMember.OnPropertyChanged(nameof(doc.SelectedStructureMember.Selection));
         }
 
         doc.SetSelectedMember(memberVM);
         memberVM.Selection = StructureMemberSelectionType.Hard;
 
-        // TODO: Make sure property changed events are raised internally
-        /*doc.OnPropertyChanged(nameof(doc.SelectedStructureMember));
-        doc.OnPropertyChanged(nameof(memberVM.Selection));*/
-
         doc.InternalRaiseLayersChanged(new LayersChangedEventArgs(info.Id, LayerAction.Add));
     }
 
     private void ProcessDeleteStructureMember(DeleteStructureMember_ChangeInfo info)
     {
         IStructureMemberHandler memberVM = doc.StructureHelper.Find(info.Id);
-        //folderVM.Children.Remove(memberVM);
         if (doc.SelectedStructureMember == memberVM)
-            doc.SetSelectedMember(null);
+        {
+            var closestId = doc.StructureHelper.FindClosestMember(new[] { info.Id });
+            var closestMember = doc.StructureHelper.Find(closestId);
+
+            if (closestMember != null)
+            {
+                closestMember.Selection = StructureMemberSelectionType.Hard;
+            }
+
+            
+            doc.SetSelectedMember(closestMember);
+        }
+
         doc.ClearSoftSelectedMembers();
         doc.InternalRaiseLayersChanged(new LayersChangedEventArgs(info.Id, LayerAction.Remove));
     }

+ 2 - 45
src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -196,7 +196,7 @@ internal class DocumentOperationsModule : IDocumentOperations
         if (Internals.ChangeController.IsBlockingChangeActive)
             return;
 
-        Guid closestMember = FindClosestMember(guids);
+        Guid closestMember = Document.StructureHelper.FindClosestMember(guids);
         
         IAction[] actions = new IAction[guids.Count + (selectNext ? 1 : 0)];
         for (int i = 0; i < guids.Count; i++)
@@ -683,50 +683,7 @@ internal class DocumentOperationsModule : IDocumentOperations
         Internals.ActionAccumulator.AddFinishedActions(
             new SetSelection_Action(inverse.Op(selection, VectorPathOp.Difference)));
     }
-
-    private Guid FindClosestMember(IReadOnlyList<Guid> guids)
-    {
-        IStructureMemberHandler? firstNode = Document.StructureHelper.FindNode<IStructureMemberHandler>(guids[0]);
-        if (firstNode is null)
-            return Guid.Empty;
-
-        INodeHandler? parent = null;
-
-        firstNode.TraverseForwards(traversedNode =>
-        {
-            if (!guids.Contains(traversedNode.Id) && traversedNode is IStructureMemberHandler)
-            {
-                parent = traversedNode;
-                return false;
-            }
-
-            return true;
-        });
-
-        if (parent is null)
-        {
-            var lastNode = Document.StructureHelper.FindNode<IStructureMemberHandler>(guids[^1]);
-            if (lastNode is null)
-                return Guid.Empty;
-            
-            lastNode.TraverseBackwards(traversedNode =>
-            {
-                if (!guids.Contains(traversedNode.Id) && traversedNode is IStructureMemberHandler)
-                {
-                    parent = traversedNode;
-                    return false;
-                }
-
-                return true;
-            });
-        }
-        
-        if (parent is null)
-            return Guid.Empty;
-
-        return parent.Id;
-    }
-
+    
     public void Rasterize(Guid memberId)
     {
         if (Internals.ChangeController.IsBlockingChangeActive)

+ 55 - 11
src/PixiEditor/Models/DocumentModels/Public/DocumentStructureModule.cs

@@ -26,6 +26,50 @@ internal class DocumentStructureModule
         return doc.NodeGraphHandler.AllNodes.FirstOrDefault(x => x.Id == guid && x is T) as T;
     }
 
+
+    public Guid FindClosestMember(IReadOnlyList<Guid> guids)
+    {
+        IStructureMemberHandler? firstNode = FindNode<IStructureMemberHandler>(guids[0]);
+        if (firstNode is null)
+            return Guid.Empty;
+
+        INodeHandler? parent = null;
+
+        firstNode.TraverseForwards(traversedNode =>
+        {
+            if (!guids.Contains(traversedNode.Id) && traversedNode is IStructureMemberHandler)
+            {
+                parent = traversedNode;
+                return false;
+            }
+
+            return true;
+        });
+
+        if (parent is null)
+        {
+            var lastNode = FindNode<IStructureMemberHandler>(guids[^1]);
+            if (lastNode is null)
+                return Guid.Empty;
+
+            lastNode.TraverseBackwards(traversedNode =>
+            {
+                if (!guids.Contains(traversedNode.Id) && traversedNode is IStructureMemberHandler)
+                {
+                    parent = traversedNode;
+                    return false;
+                }
+
+                return true;
+            });
+        }
+
+        if (parent is null)
+            return Guid.Empty;
+
+        return parent.Id;
+    }
+
     public INodeHandler? FindFirstWhere(Predicate<INodeHandler> predicate)
     {
         return FindFirstWhere(predicate, doc.NodeGraphHandler);
@@ -115,9 +159,9 @@ internal class DocumentStructureModule
         INodeHandler? result = null;
         startNode.TraverseForwards(node =>
         {
-            if(node == startNode)
+            if (node == startNode)
                 return true;
-            
+
             result = node;
             return false;
         });
@@ -130,46 +174,46 @@ internal class DocumentStructureModule
         INodeHandler member = FindNode<INodeHandler>(memberId);
         if (member == null)
             return null;
-        
+
         IStructureMemberHandler? result = null;
         member.TraverseForwards(node =>
         {
             if (node != member && node is IStructureMemberHandler structureMemberNode)
             {
-                if(node is IFolderHandler && !includeFolders)
+                if (node is IFolderHandler && !includeFolders)
                     return true;
-                
+
                 result = structureMemberNode;
                 return false;
             }
 
             return true;
         });
-        
+
         return result;
     }
-    
+
     public IStructureMemberHandler? GetBelowMember(Guid memberId, bool includeFolders)
     {
         INodeHandler member = FindNode<INodeHandler>(memberId);
         if (member == null)
             return null;
-        
+
         IStructureMemberHandler? result = null;
         member.TraverseBackwards(node =>
         {
             if (node != member && node is IStructureMemberHandler structureMemberNode)
             {
-                if(node is IFolderHandler && !includeFolders)
+                if (node is IFolderHandler && !includeFolders)
                     return true;
-                
+
                 result = structureMemberNode;
                 return false;
             }
 
             return true;
         });
-        
+
         return result;
     }
 }

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/SimpleShapeToolExecutor.cs

@@ -176,7 +176,7 @@ internal abstract class SimpleShapeToolExecutor : UpdateableChangeExecutor,
     protected void AddMemberToSnapping()
     {
         var member = document.StructureHelper.Find(memberId);
-        document!.SnappingHandler.AddFromBounds(memberId.ToString(), () => member!.TightBounds ?? RectD.Empty);
+        document!.SnappingHandler.AddFromBounds(memberId.ToString(), () => member?.TightBounds ?? RectD.Empty);
     }
     
     protected VecD SnapAndHighlight(VecD pos)