Browse Source

Live selection changing

flabbet 11 months ago
parent
commit
bd853c0fce

+ 1 - 1
src/PixiEditor.ChangeableDocument/Changeables/Graph/Nodes/StructureNode.cs

@@ -31,7 +31,7 @@ public abstract class StructureNode : Node, IReadOnlyStructureNode, IBackgroundI
     public ChunkyImage? EmbeddedMask { get; set; }
     public virtual ShapeCorners GetTransformationCorners(KeyFrameTime frameTime)
     {
-        return new ShapeCorners((RectD)GetTightBounds(frameTime).GetValueOrDefault());
+        return new ShapeCorners(GetTightBounds(frameTime).GetValueOrDefault());
     }
 
     public string MemberName

+ 7 - 2
src/PixiEditor.ChangeableDocument/Changes/Vectors/SetShapeGeometry_UpdateableChange.cs

@@ -77,9 +77,14 @@ internal class SetShapeGeometry_UpdateableChange : UpdateableChange
         var node = target.FindNode<VectorLayerNode>(TargetId);
         node.ShapeData = originalData;
 
-        var affected = new AffectedArea(OperationHelper.FindChunksTouchingRectangle(
-            (RectI)node.ShapeData.TransformedAABB, ChunkyImage.FullChunkSize));
+        AffectedArea affected = default;
         
+        if (node.ShapeData != null)
+        {
+            affected = new AffectedArea(OperationHelper.FindChunksTouchingRectangle(
+                (RectI)node.ShapeData.TransformedAABB, ChunkyImage.FullChunkSize));
+        }
+
         return new VectorShape_ChangeInfo(node.Id, affected);
     }
 }

+ 5 - 0
src/PixiEditor/Models/DocumentModels/ChangeExecutionController.cs

@@ -196,6 +196,11 @@ internal class ChangeExecutionController
         currentSession?.OnTransformMoved(corners);
     }
     
+    public void MembersSelectedInlet(List<Guid> memberGuids)
+    {
+        currentSession?.OnMembersSelected(memberGuids);
+    }
+    
     public void TransformAppliedInlet() => currentSession?.OnTransformApplied();
     
     public void SettingsChangedInlet(string name, object value)

+ 52 - 13
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/TransformSelectedExecutor.cs

@@ -4,6 +4,7 @@ using ChunkyImageLib.DataHolders;
 using PixiEditor.ChangeableDocument.Actions.Generated;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.DrawingApi.Core.Surfaces.Vector;
+using PixiEditor.Models.DocumentModels.Public;
 using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers.Tools;
 using PixiEditor.Models.Tools;
@@ -14,8 +15,9 @@ namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
 #nullable enable
 internal class TransformSelectedExecutor : UpdateableChangeExecutor
 {
-    private Dictionary<Guid, ShapeCorners> memberCorners = new(); 
+    private Dictionary<Guid, ShapeCorners> memberCorners = new();
     private IMoveToolHandler? tool;
+    private bool isInProgress;
     public override ExecutorType Type { get; }
 
     public TransformSelectedExecutor(bool toolLinked)
@@ -31,16 +33,20 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor
 
         tool.TransformingSelectedArea = true;
         List<IStructureMemberHandler> members = new();
-        
+
         members = document.SoftSelectedStructureMembers
             .Append(document.SelectedStructureMember)
             .Where(static m => m is ILayerHandler).ToList();
-        
+
         if (!members.Any())
             return ExecutionState.Error;
 
-        bool allRaster = true; 
+        return SelectMembers(members);
+    }
 
+    private ExecutionState SelectMembers(List<IStructureMemberHandler> members)
+    {
+        bool allRaster = true;
         memberCorners = new();
         foreach (IStructureMemberHandler member in members)
         {
@@ -50,32 +56,61 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor
             {
                 targetCorners = new ShapeCorners(document.SelectionPathBindable.TightBounds);
             }
-            else if(member is not IRasterLayerHandler)
+            else if (member is not IRasterLayerHandler)
             {
                 allRaster = false;
             }
-            
+
             memberCorners.Add(member.Id, targetCorners);
         }
-        
-        ShapeCorners masterCorners = memberCorners.Count == 1 ? memberCorners.FirstOrDefault().Value : new ShapeCorners(memberCorners.Values.Select(static c => c.AABBBounds).Aggregate((a, b) => a.Union(b)));
-        
+
+        ShapeCorners masterCorners = memberCorners.Count == 1
+            ? memberCorners.FirstOrDefault().Value
+            : new ShapeCorners(memberCorners.Values.Select(static c => c.AABBBounds).Aggregate((a, b) => a.Union(b)));
+
         if (masterCorners.AABBBounds.Width == 0 || masterCorners.AABBBounds.Height == 0)
+        {
             return ExecutionState.Error;
+        }
 
         DocumentTransformMode mode = allRaster
             ? DocumentTransformMode.Scale_Rotate_Shear_Perspective
             : DocumentTransformMode.Scale_Rotate_Shear_NoPerspective;
         document.TransformHandler.ShowTransform(mode, true, masterCorners, Type == ExecutorType.Regular);
         internals!.ActionAccumulator.AddActions(
-            new TransformSelected_Action(masterCorners, tool.KeepOriginalImage, memberCorners, false, document.AnimationHandler.ActiveFrameBindable));
+            new TransformSelected_Action(masterCorners, tool.KeepOriginalImage, memberCorners, false,
+                document.AnimationHandler.ActiveFrameBindable));
+
+        isInProgress = true;
         return ExecutionState.Success;
     }
 
+    public override void OnMembersSelected(List<Guid> memberGuids)
+    {
+        if (isInProgress)
+        {
+            internals.ActionAccumulator.AddActions(new EndTransformSelected_Action());
+            document!.TransformHandler.HideTransform();
+            memberCorners.Clear();
+            isInProgress = false;
+        }
+
+        internals.ActionAccumulator.AddActions(new InvokeAction_PassthroughAction(() =>
+        {
+            List<IStructureMemberHandler> members = memberGuids.Select(g => document!.StructureHelper.Find(g))
+                .Where(x => x is ILayerHandler).Distinct().ToList();
+            SelectMembers(members);
+        }));
+    }
+
     public override void OnTransformMoved(ShapeCorners corners)
     {
+        if (!isInProgress)
+            return;
+
         internals!.ActionAccumulator.AddActions(
-            new TransformSelected_Action(corners, tool!.KeepOriginalImage, memberCorners, false, document!.AnimationHandler.ActiveFrameBindable));
+            new TransformSelected_Action(corners, tool!.KeepOriginalImage, memberCorners, false,
+                document!.AnimationHandler.ActiveFrameBindable));
     }
 
     public override void OnSelectedObjectNudged(VecI distance) => document!.TransformHandler.Nudge(distance);
@@ -90,7 +125,7 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor
         {
             tool.TransformingSelectedArea = false;
         }
-        
+
         internals!.ActionAccumulator.AddActions(new EndTransformSelected_Action());
         internals!.ActionAccumulator.AddFinishedActions();
         document!.TransformHandler.HideTransform();
@@ -100,6 +135,8 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor
         {
             GetHandler<IToolsHandler>().RestorePreviousTool();
         }
+
+        isInProgress = false;
     }
 
     public override void ForceStop()
@@ -108,9 +145,11 @@ internal class TransformSelectedExecutor : UpdateableChangeExecutor
         {
             tool.TransformingSelectedArea = false;
         }
-        
+
         internals!.ActionAccumulator.AddActions(new EndTransformSelected_Action());
         internals!.ActionAccumulator.AddFinishedActions();
         document!.TransformHandler.HideTransform();
+
+        isInProgress = false;
     }
 }

+ 1 - 0
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/UpdateableChangeExecutor.cs

@@ -66,4 +66,5 @@ internal abstract class UpdateableChangeExecutor
 
     public virtual void OnSettingsChanged(string name, object value) { }
     public virtual void OnColorChanged(Color color, bool primary) { }
+    public virtual void OnMembersSelected(List<Guid> memberGuids) { }
 }

+ 1 - 1
src/PixiEditor/Models/Handlers/ITransformHandler.cs

@@ -8,7 +8,7 @@ namespace PixiEditor.Models.Handlers;
 internal interface ITransformHandler : IHandler
 {
     public void KeyModifiersInlet(bool argsIsShiftDown, bool argsIsCtrlDown, bool argsIsAltDown);
-    public void ShowTransform(DocumentTransformMode transformMode, bool b, ShapeCorners shapeCorners, bool b1);
+    public void ShowTransform(DocumentTransformMode transformMode, bool coverWholeScreen, ShapeCorners shapeCorners, bool showApplyButton);
     public void HideTransform();
     public bool Undo();
     public bool Redo();

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

@@ -717,6 +717,7 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     public void SetSelectedMember(IStructureMemberHandler member)
     {
         SelectedStructureMember = member;
+        Internals.ChangeController.MembersSelectedInlet(GetSelectedMembers());
         OnPropertyChanged(nameof(SelectedStructureMember));
     }
 
@@ -748,15 +749,21 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     public void AddSoftSelectedMember(IStructureMemberHandler member)
     {
         softSelectedStructureMembers.Add(member);
+        Internals.ChangeController.MembersSelectedInlet(GetSelectedMembers());
     }
 
     public void RemoveSoftSelectedMember(IStructureMemberHandler member)
     {
         SelectedStructureMember = member;
+        Internals.ChangeController.MembersSelectedInlet(GetSelectedMembers());
         softSelectedStructureMembers.Remove(member);
     }
 
-    public void ClearSoftSelectedMembers() => softSelectedStructureMembers.Clear();
+    public void ClearSoftSelectedMembers()
+    {
+        softSelectedStructureMembers.Clear();
+        Internals.ChangeController.MembersSelectedInlet(GetSelectedMembers());
+    }
 
     #endregion