Răsfoiți Sursa

Moving nested folders works

flabbet 4 ani în urmă
părinte
comite
24edc7b821

+ 0 - 1
PixiEditor/Helpers/Converters/LayersToStructuredLayersConverter.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Globalization;
 using System.Windows.Data;

+ 14 - 1
PixiEditor/Models/Layers/LayerFolder.cs

@@ -16,7 +16,20 @@ namespace PixiEditor.Models.Layers
 
         public ObservableCollection<LayerFolder> Subfolders { get; set; } = new ObservableCollection<LayerFolder>();
 
-        public IEnumerable Items => Subfolders?.Cast<object>().Concat(Layers);
+        public IEnumerable Items => BuildItems();
+
+        private IEnumerable BuildItems()
+        {
+            List<object> obj = new List<object>(Layers.Reverse());
+            foreach (var subfolder in Subfolders)
+            {
+                obj.Insert(subfolder.DisplayIndex - DisplayIndex, subfolder);
+            }
+
+            obj.Reverse();
+
+            return obj;
+        }
 
         private string name;
 

+ 83 - 25
PixiEditor/Models/Layers/LayerStructure.cs

@@ -52,7 +52,7 @@ namespace PixiEditor.Models.Layers
 
             int difference;
 
-            if (newIndex > folderTopIndex)
+            if (newIndex >= folderTopIndex)
             {
                 difference = newIndex - folderTopIndex;
             }
@@ -62,30 +62,85 @@ namespace PixiEditor.Models.Layers
                 difference = newIndex - folderBottomIndex;
             }
 
-            MoveLayersInFolder(new FolderData(folderTopIndex, folderBottomIndex), difference, reverseOrder);
-
-            if (folder.Parent == null)
+            if (difference == 0)
             {
-                Folders.Remove(folder);
+                return;
             }
 
-            if (parentFolder == null && !Folders.Contains(folder))
+            List<Guid> layersInOrder = GetLayersInOrder(new FolderData(folderTopIndex, folderBottomIndex));
+            bool parentBoundsReassigned = ReassignBounds(parentFolder, folder);
+
+            Guid oldLayerAtIndex = Owner.Layers[newIndex].LayerGuid;
+
+            MoveLayersInFolder(layersInOrder, difference, reverseOrder);
+
+            if (parentBoundsReassigned)
             {
-                Folders.Add(folder);
+                parentFolder!.Subfolders.Remove(folder);
+                GuidStructureItem? newParent = GetFolderByLayer(oldLayerAtIndex);
+                if(newParent != null)
+                {
+                    newParent.Subfolders.Add(folder);
+                }
             }
-            else if (parentFolder != null)
+        }
+
+        private bool ReassignBounds(GuidStructureItem? parentFolder, GuidStructureItem folder)
+        {
+            if (parentFolder != null)
             {
-                parentFolder.Subfolders.Add(folder);
+                if (folder.EndLayerGuid == parentFolder.EndLayerGuid && folder.StartLayerGuid != null)
+                {
+                    parentFolder.EndLayerGuid = FindBoundLayer(parentFolder, (Guid)folder.StartLayerGuid, false);
+                    return true;
+                }
+                else if (folder.StartLayerGuid == parentFolder.StartLayerGuid && folder.EndLayerGuid != null)
+                {
+                    parentFolder.StartLayerGuid = FindBoundLayer(parentFolder, (Guid)folder.EndLayerGuid, true);
+                    return true;
+                }
             }
+
+            return false;
         }
 
-        private void MoveLayersInFolder(FolderData folder, int moveBy, bool reverseOrder)
+        private Guid? FindBoundLayer(GuidStructureItem parentFolder, Guid oldLayerGuid, bool above)
         {
-            List<Guid> layersInOrder = GetLayersInOrder(folder);
+            int parentFolderTopIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == parentFolder.EndLayerGuid));
+            int parentFolderBottomIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == parentFolder.StartLayerGuid));
 
-            List<Guid> layerGuids = reverseOrder ? layersInOrder.Reverse<Guid>().ToList() : layersInOrder;
+            return GetNextLayerGuid(
+                    oldLayerGuid,
+                    GetLayersInOrder(new FolderData(parentFolderTopIndex, parentFolderBottomIndex)),
+                    above);
+        }
 
-            for (int i = 0; i < layersInOrder.Count; i++)
+        private Guid? GetNextLayerGuid(Guid? layer, List<Guid> allLayers, bool above)
+        {
+            if (layer == null)
+            {
+                return null;
+            }
+
+            int indexOfLayer = allLayers.IndexOf(layer.Value);
+
+            int modifier = above ? 1 : -1;
+
+            int newIndex = indexOfLayer + modifier;
+
+            if (newIndex < 0 || newIndex >= allLayers.Count)
+            {
+                return null;
+            }
+
+            return allLayers[newIndex];
+        }
+
+        private void MoveLayersInFolder(List<Guid> layers, int moveBy, bool reverseOrder)
+        {
+            List<Guid> layerGuids = reverseOrder ? layers.Reverse<Guid>().ToList() : layers;
+
+            for (int i = 0; i < layers.Count; i++)
             {
                 Guid layerGuid = layerGuids[i];
                 var layer = Owner.Layers.First(x => x.LayerGuid == layerGuid);
@@ -111,18 +166,21 @@ namespace PixiEditor.Models.Layers
 #nullable disable
         private GuidStructureItem GetFolderByLayer(Guid layerGuid, IEnumerable<GuidStructureItem> folders)
         {
-            //foreach (var folder in folders)
-            //{
-            //    if (folder.LayerGuids.Contains(layerGuid))
-            //    {
-            //        return folder;
-            //    }
-
-            //    if (folder.Subfolders.Count > 0)
-            //    {
-            //        return GetFolderByLayer(layerGuid, folder.Subfolders);
-            //    }
-            //}
+            foreach (var folder in folders)
+            {
+                int topIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == folder.EndLayerGuid));
+                int bottomIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == folder.StartLayerGuid));
+                var layers = GetLayersInOrder(new FolderData(topIndex, bottomIndex));
+                if (layers.Contains(layerGuid))
+                {
+                    return folder;
+                }
+
+                if (folder.Subfolders.Count > 0)
+                {
+                    return GetFolderByLayer(layerGuid, folder.Subfolders);
+                }
+            }
 
             return null;
         }

+ 14 - 4
PixiEditor/Models/Layers/StructuredLayerTree.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
@@ -27,12 +28,17 @@ namespace PixiEditor.Models.Layers
 
             RootDirectoryItems.AddRange(layers.Where(x => !layersInStructure.Contains(x)));
 
+            MoveFoldersToDisplayIndex(RootDirectoryItems, parsedFolders);
+
+            layersInStructure.Clear();
+        }
+
+        private void MoveFoldersToDisplayIndex(ObservableCollection<object> parentList, IList<LayerFolder> parsedFolders)
+        {
             for (int i = 0; i < parsedFolders.Count; i++)
             {
-                RootDirectoryItems.Move(i, parsedFolders[i].DisplayIndex);
+                parentList.Move(i, parsedFolders[i].DisplayIndex);
             }
-
-            layersInStructure.Clear();
         }
 
         private List<LayerFolder> ParseFolders(IEnumerable<GuidStructureItem> folders, ObservableCollection<Layer> layers)
@@ -69,7 +75,7 @@ namespace PixiEditor.Models.Layers
                 }
             }
 
-            int displayIndex = layersInStructure.Min(x => layers.IndexOf(x));
+            int displayIndex = layersInFolder.Length > 0 ? layersInStructure.Min(x => layers.IndexOf(x)) : 0;
 
             structureItemLayers.Reverse();
 
@@ -83,6 +89,10 @@ namespace PixiEditor.Models.Layers
 
         private Guid[] GetLayersInFolder(ObservableCollection<Layer> layers, GuidStructureItem structureItem)
         {
+            if (structureItem.EndLayerGuid == null || structureItem.StartLayerGuid == null)
+            {
+                return Array.Empty<Guid>();
+            }
             int startIndex = layers.IndexOf(layers.First(x => x.LayerGuid == structureItem.StartLayerGuid));
             int endIndex = layers.IndexOf(layers.First(x => x.LayerGuid == structureItem.EndLayerGuid));