Browse Source

Flip layers complete

flabbet 2 years ago
parent
commit
d3ed4eb3c2

+ 2 - 3
src/PixiEditor.ChangeableDocument/Changeables/Document.cs

@@ -262,7 +262,7 @@ internal class Document : IChangeable, IReadOnlyDocument, IDisposable
         return false;
     }
     
-    public List<Guid> ExtractLayers(List<Guid> members)
+    public List<Guid> ExtractLayers(IList<Guid> members)
     {
         var result = new List<Guid>();
         foreach (var member in members)
@@ -282,7 +282,7 @@ internal class Document : IChangeable, IReadOnlyDocument, IDisposable
         return result;
     }
 
-    private List<Guid> ExtractLayers(Folder folder, List<Guid> list)
+    private void ExtractLayers(Folder folder, List<Guid> list)
     {
         foreach (var member in folder.Children)
         {
@@ -295,6 +295,5 @@ internal class Document : IChangeable, IReadOnlyDocument, IDisposable
                 ExtractLayers(childFolder, list);
             }
         }
-        return list;
     }
 }

+ 8 - 8
src/PixiEditor.ChangeableDocument/Changes/Root/CenterContent_Change.cs

@@ -6,25 +6,25 @@ namespace PixiEditor.ChangeableDocument.Changes.Root;
 internal class CenterContent_Change : Change
 {
     private VecI _oldOffset;
-    private List<Guid> _affectedLayers;
+    private List<Guid> affectedLayers;
     private Dictionary<Guid, CommittedChunkStorage>? originalLayerChunks;
 
     [GenerateMakeChangeAction]
     public CenterContent_Change(List<Guid> layers)
     {
-        _affectedLayers = layers;
+        affectedLayers = layers;
     }
     
     public override bool InitializeAndValidate(Document target)
     {
-        if (_affectedLayers.Count == 0)
+        if (affectedLayers.Count == 0)
         {
             return false;
         }
 
-        _affectedLayers = target.ExtractLayers(_affectedLayers);
+        affectedLayers = target.ExtractLayers(affectedLayers);
 
-        foreach (var layer in _affectedLayers)
+        foreach (var layer in affectedLayers)
         {
             if (!target.HasMember(layer)) return false;
         }
@@ -38,7 +38,7 @@ internal class CenterContent_Change : Change
     {
         VecI currentCenter = new VecI(0, 0);
         RectI? currentBounds = null;
-        foreach (var layerGuid in _affectedLayers)
+        foreach (var layerGuid in affectedLayers)
         {
             Layer layer = document.FindMemberOrThrow<Layer>(layerGuid);
             RectI? tightBounds = layer.LayerImage.FindPreciseBounds();
@@ -64,7 +64,7 @@ internal class CenterContent_Change : Change
         List<IChangeInfo> changes = new List<IChangeInfo>();
         originalLayerChunks = new Dictionary<Guid, CommittedChunkStorage>();
         
-        foreach (var layerGuid in _affectedLayers)
+        foreach (var layerGuid in affectedLayers)
         {
             Layer layer = target.FindMemberOrThrow<Layer>(layerGuid);
             var chunks = ShiftLayerHelper.DrawShiftedLayer(target, layerGuid, false, shift);
@@ -81,7 +81,7 @@ internal class CenterContent_Change : Change
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
         List<IChangeInfo> changes = new List<IChangeInfo>();
-        foreach (var layerGuid in _affectedLayers)
+        foreach (var layerGuid in affectedLayers)
         {
             var image = target.FindMemberOrThrow<Layer>(layerGuid).LayerImage;
             CommittedChunkStorage? originalChunks = originalLayerChunks?[layerGuid];

+ 41 - 14
src/PixiEditor.ChangeableDocument/Changes/Root/FlipImage_Change.cs

@@ -11,15 +11,28 @@ namespace PixiEditor.ChangeableDocument.Changes.Root;
 internal sealed class FlipImage_Change : Change
 {
     private readonly FlipType flipType;
+    private List<Guid> membersToFlip;
 
     [GenerateMakeChangeAction]
-    public FlipImage_Change(FlipType flipType)
+    public FlipImage_Change(FlipType flipType, List<Guid>? membersToFlip = null)
     {
         this.flipType = flipType;
+        membersToFlip ??= new List<Guid>();
+        this.membersToFlip = membersToFlip;
     }
     
     public override bool InitializeAndValidate(Document target)
     {
+        if (membersToFlip.Count > 0)
+        {
+            membersToFlip = target.ExtractLayers(membersToFlip);
+            
+            foreach (var layer in membersToFlip)
+            {
+                if (!target.HasMember(layer)) return false;
+            }  
+        }
+        
         return true;
     }
 
@@ -37,10 +50,20 @@ internal sealed class FlipImage_Change : Change
         {
             BlendMode = DrawingApi.Core.Surface.BlendMode.Src
         };
-        
+
+        RectI bounds = new RectI(VecI.Zero, img.LatestSize);
+        if (membersToFlip.Count > 0)
+        {
+            var preciseBounds = img.FindPreciseBounds();
+            if (preciseBounds.HasValue)
+            {
+                bounds = preciseBounds.Value;
+            }
+        }
+
         using Surface originalSurface = new(img.LatestSize);
         img.DrawMostUpToDateRegionOn(
-            new(VecI.Zero, img.LatestSize), 
+            new RectI(VecI.Zero, img.LatestSize), 
             ChunkResolution.Full,
             originalSurface.DrawingSurface,
             VecI.Zero);
@@ -51,8 +74,8 @@ internal sealed class FlipImage_Change : Change
         bool flipY = flipType == FlipType.Vertical;
         
         flipped.DrawingSurface.Canvas.Save();
-                flipped.DrawingSurface.Canvas.Scale(flipX ? -1 : 1, flipY ? -1 : 1, flipX ? img.LatestSize.X / 2f : 0,
-            flipY ? img.LatestSize.Y / 2f : 0f);
+                flipped.DrawingSurface.Canvas.Scale(flipX ? -1 : 1, flipY ? -1 : 1, flipX ? bounds.X + bounds.Width / 2f : 0,
+            flipY ? bounds.Y + bounds.Height / 2f : 0f);
         flipped.DrawingSurface.Canvas.DrawSurface(originalSurface.DrawingSurface, 0, 0, paint);
         flipped.DrawingSurface.Canvas.Restore();
         
@@ -71,17 +94,21 @@ internal sealed class FlipImage_Change : Change
 
         target.ForEveryMember(member =>
         {
-            if (member is Layer layer)
+            if (membersToFlip.Count == 0 || membersToFlip.Contains(member.GuidValue))
             {
-                FlipImage(layer.LayerImage);
-                changes.Add(new LayerImageChunks_ChangeInfo(member.GuidValue, layer.LayerImage.FindAffectedChunks()));
-                layer.LayerImage.CommitChanges();
-            }
+                if (member is Layer layer)
+                {
+                    FlipImage(layer.LayerImage);
+                    changes.Add(
+                        new LayerImageChunks_ChangeInfo(member.GuidValue, layer.LayerImage.FindAffectedChunks()));
+                    layer.LayerImage.CommitChanges();
+                }
 
-            if (member.Mask is not null)
-            {
-                FlipImage(member.Mask);
-                member.Mask.CommitChanges();
+                if (member.Mask is not null)
+                {
+                    FlipImage(member.Mask);
+                    member.Mask.CommitChanges();
+                }
             }
         });
 

+ 5 - 3
src/PixiEditor/Models/DocumentModels/Public/DocumentOperationsModule.cs

@@ -289,13 +289,15 @@ internal class DocumentOperationsModule
             return;
         Internals.ActionAccumulator.AddFinishedActions(new ClipCanvas_Action());
     }
-    
-    public void FlipImage(FlipType flipType)
+
+    public void FlipImage(FlipType flipType) => FlipImage(flipType, null);
+
+    public void FlipImage(FlipType flipType, List<Guid> membersToFlip)
     {
         if (Internals.ChangeController.IsChangeActive)
             return;
         
-        Internals.ActionAccumulator.AddFinishedActions(new FlipImage_Action(flipType));
+        Internals.ActionAccumulator.AddFinishedActions(new FlipImage_Action(flipType, membersToFlip));
     }
 
     public void CenterContent(IReadOnlyList<Guid> structureMembers)

+ 20 - 4
src/PixiEditor/ViewModels/SubViewModels/Document/DocumentManagerViewModel.cs

@@ -67,6 +67,15 @@ internal class DocumentManagerViewModel : SubViewModel<ViewModelMain>
         ActiveDocument?.Operations.FlipImage(FlipType.Horizontal);
     }
     
+    [Command.Basic("PixiEditor.Document.FlipLayersHorizontal", "Flip Selected Layers Horizontally", "Flip Selected Layers Horizontally", CanExecute = "PixiEditor.HasDocument")]
+    public void FlipLayersHorizontally()
+    {
+        if (ActiveDocument?.SelectedStructureMember == null)
+            return;
+        
+        ActiveDocument?.Operations.FlipImage(FlipType.Horizontal, ActiveDocument.GetSelectedMembers());
+    }
+    
     [Command.Basic("PixiEditor.Document.FlipImageVertical", "Flip Image Vertically", "Flip Image Vertically", CanExecute = "PixiEditor.HasDocument")]
     public void FlipImageVertically()
     {
@@ -75,6 +84,15 @@ internal class DocumentManagerViewModel : SubViewModel<ViewModelMain>
         
         ActiveDocument?.Operations.FlipImage(FlipType.Vertical);
     }
+    
+    [Command.Basic("PixiEditor.Document.FlipLayersVertical", "Flip Selected Layers Vertically", "Flip Selected Layers Vertically", CanExecute = "PixiEditor.HasDocument")]
+    public void FlipLayersVertically()
+    {
+        if (ActiveDocument?.SelectedStructureMember == null)
+            return;
+        
+        ActiveDocument?.Operations.FlipImage(FlipType.Vertical, ActiveDocument.GetSelectedMembers());
+    }
 
     [Command.Basic("PixiEditor.Document.ToggleVerticalSymmetryAxis", "Toggle vertical symmetry axis", "Toggle vertical symmetry axis", CanExecute = "PixiEditor.HasDocument", IconPath = "SymmetryVertical.png")]
     public void ToggleVerticalSymmetryAxis()
@@ -152,11 +170,9 @@ internal class DocumentManagerViewModel : SubViewModel<ViewModelMain>
     [Command.Basic("PixiEditor.Document.CenterContent", "Center Content", "Center Content", CanExecute = "PixiEditor.HasDocument")]
     public void CenterContent()
     {
-        if(ActiveDocument is null || ActiveDocument.SelectedStructureMember == null)
+        if(ActiveDocument?.SelectedStructureMember == null)
             return;
         
-        List<Guid> layerGuids = new List<Guid>() { ActiveDocument.SelectedStructureMember.GuidValue };
-        layerGuids.AddRange(ActiveDocument.SoftSelectedStructureMembers.Select(x => x.GuidValue));
-        ActiveDocument.Operations.CenterContent(layerGuids);
+        ActiveDocument.Operations.CenterContent(ActiveDocument.GetSelectedMembers());
     }
 }

+ 7 - 0
src/PixiEditor/ViewModels/SubViewModels/Document/DocumentViewModel.cs

@@ -459,4 +459,11 @@ internal partial class DocumentViewModel : NotifyableObject
     public void InternalAddSoftSelectedMember(StructureMemberViewModel member) => softSelectedStructureMembers.Add(member);
     public void InternalRemoveSoftSelectedMember(StructureMemberViewModel member) => softSelectedStructureMembers.Remove(member);
     #endregion
+
+    public List<Guid> GetSelectedMembers()
+    {
+        List<Guid> layerGuids = new List<Guid>() { SelectedStructureMember.GuidValue };
+        layerGuids.AddRange( SoftSelectedStructureMembers.Select(x => x.GuidValue));
+        return layerGuids;
+    }
 }

+ 7 - 15
src/PixiEditor/Views/MainWindow.xaml

@@ -256,21 +256,13 @@
                             IsEnabled="{Binding DocumentManagerSubViewModel.ActiveDocument, Source={vm:MainVM}, Converter={converters:NotNullToBoolConverter}}"
                             IsChecked="{Binding DocumentManagerSubViewModel.ActiveDocument.VerticalSymmetryAxisEnabledBindable}"
                             Header="_Vertical Line Symmetry"/>
-                        <!--<Separator/>
-                    <MenuItem Header="_Rotate to right 90&#186;" Command="{Binding DocumentSubViewModel.RotateToRightCommand}">
-                        <MenuItem.CommandParameter>
-                            <sys:Double>90</sys:Double>
-                        </MenuItem.CommandParameter>
-                    </MenuItem>
-                    <MenuItem Header="_Rotate to left 90&#186;" Command="{Binding DocumentSubViewModel.RotateToRightCommand}">
-                        <MenuItem.CommandParameter>
-                            <sys:Double>-90</sys:Double>
-                        </MenuItem.CommandParameter>
-                    </MenuItem>
-                    <Separator/>
-                    <MenuItem Header="_Flip Horizontal" Command="{Binding DocumentSubViewModel.FlipCommand}" CommandParameter="Horizontal"/>
-                    <MenuItem Header="_Flip Vertical" Command="{Binding DocumentSubViewModel.FlipCommand}" CommandParameter="Vertical"/>
-                -->
+                        <Separator/>
+                        <MenuItem Header="_Rotate">
+                            <MenuItem Header="Flip Image _Horizontally" cmds:Menu.Command="PixiEditor.Document.FlipImageHorizontal"/>
+                            <MenuItem Header="Flip Image _Vertically" cmds:Menu.Command="PixiEditor.Document.FlipImageVertical"/>
+                            <MenuItem Header="Flip Selected Layers _Horizontally" cmds:Menu.Command="PixiEditor.Document.FlipLayersHorizontal"/>
+                            <MenuItem Header="Flip Selected Layers _Vertically" cmds:Menu.Command="PixiEditor.Document.FlipLayersVertical"/>
+                        </MenuItem>
                     </MenuItem>
                     <MenuItem
                         Header="_View">