Ver código fonte

Move folders relative to folder wip

flabbet 4 anos atrás
pai
commit
7de1ab03f7

+ 1 - 0
Custom.ruleset

@@ -5,6 +5,7 @@
   </Rules>
   <Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
     <Rule Id="SA0001" Action="None" />
+    <Rule Id="SA1000" Action="None" />
     <Rule Id="SA1101" Action="None" />
     <Rule Id="SA1201" Action="None" />
     <Rule Id="SA1310" Action="None" />

+ 1 - 1
PixiEditor/Models/DataHolders/Document/Document.Constructors.cs

@@ -21,7 +21,7 @@ namespace PixiEditor.Models.DataHolders
             XamlAccesibleViewModel = ViewModelMain.Current ?? null;
             GeneratePreviewLayer();
             Layers.CollectionChanged += Layers_CollectionChanged;
-            LayerStructure.Folders.CollectionChanged += Folders_CollectionChanged1;
+            LayerStructure.Groups.CollectionChanged += Folders_CollectionChanged1;
         }
 
         private void Folders_CollectionChanged1(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)

+ 5 - 5
PixiEditor/Models/DataHolders/Document/Document.Layers.cs

@@ -467,7 +467,7 @@ namespace PixiEditor.Models.DataHolders
             Guid referenceLayerGuid = (Guid)parameter[1];
             bool above = (bool)parameter[2];
 
-            GuidStructureItem folder = LayerStructure.GetFolderByGuid(folderGuid);
+            GuidStructureItem folder = LayerStructure.GetGroupByGuid(folderGuid);
             GuidStructureItem referenceLayerFolder = LayerStructure.GetGroupByLayer(referenceLayerGuid);
 
             Layer referenceLayer = Layers.First(x => x.LayerGuid == referenceLayerGuid);
@@ -494,16 +494,16 @@ namespace PixiEditor.Models.DataHolders
         private void ReassignParent(GuidStructureItem folder, GuidStructureItem referenceLayerFolder)
         {
             folder.Parent?.Subfolders.Remove(folder);
-            if (LayerStructure.Folders.Contains(folder))
+            if (LayerStructure.Groups.Contains(folder))
             {
-                LayerStructure.Folders.Remove(folder);
+                LayerStructure.Groups.Remove(folder);
             }
 
             if (referenceLayerFolder == null)
             {
-                if (!LayerStructure.Folders.Contains(folder))
+                if (!LayerStructure.Groups.Contains(folder))
                 {
-                    LayerStructure.Folders.Add(folder);
+                    LayerStructure.Groups.Add(folder);
                     folder.Parent = null;
                 }
             }

+ 9 - 9
PixiEditor/Models/Layers/LayerFolder.cs → PixiEditor/Models/Layers/LayerGroup.cs

@@ -8,21 +8,21 @@ using PixiEditor.ViewModels;
 
 namespace PixiEditor.Models.Layers
 {
-    public class LayerFolder : NotifyableObject
+    public class LayerGroup : NotifyableObject
     {
-        public Guid FolderGuid { get; init; }
+        public Guid GroupGuid { get; init; }
 
         public GuidStructureItem StructureData { get; init; }
 
         public ObservableCollection<Layer> Layers { get; set; } = new ObservableCollection<Layer>();
 
-        public ObservableCollection<LayerFolder> Subfolders { get; set; } = new ObservableCollection<LayerFolder>();
+        public ObservableCollection<LayerGroup> Subfolders { get; set; } = new ObservableCollection<LayerGroup>();
 
         public IEnumerable Items => BuildItems();
 
         private IEnumerable BuildItems()
         {
-            List<object> obj = new List<object>(Layers.Reverse());
+            List<object> obj = new(Layers.Reverse());
             foreach (var subfolder in Subfolders)
             {
                 obj.Insert(subfolder.DisplayIndex - DisplayIndex, subfolder);
@@ -84,26 +84,26 @@ namespace PixiEditor.Models.Layers
 
         private void UpdateIsExpandedInDocument(bool value)
         {
-            var folder = ViewModelMain.Current.BitmapManager.ActiveDocument.LayerStructure.GetFolderByGuid(FolderGuid);
+            var folder = ViewModelMain.Current.BitmapManager.ActiveDocument.LayerStructure.GetGroupByGuid(GroupGuid);
             if (folder != null)
             {
                 folder.IsExpanded = value;
             }
         }
 
-        public LayerFolder(IEnumerable<Layer> layers, IEnumerable<LayerFolder> subfolders, string name, 
+        public LayerGroup(IEnumerable<Layer> layers, IEnumerable<LayerGroup> subfolders, string name,
             int displayIndex, int topIndex, GuidStructureItem structureData)
             : this(layers, subfolders, name, Guid.NewGuid(), displayIndex, topIndex, structureData)
         {
         }
 
-        public LayerFolder(IEnumerable<Layer> layers, IEnumerable<LayerFolder> subfolders, string name,
+        public LayerGroup(IEnumerable<Layer> layers, IEnumerable<LayerGroup> subfolders, string name,
             Guid guid, int displayIndex, int topIndex, GuidStructureItem structureData)
         {
             Layers = new ObservableCollection<Layer>(layers);
-            Subfolders = new ObservableCollection<LayerFolder>(subfolders);
+            Subfolders = new ObservableCollection<LayerGroup>(subfolders);
             Name = name;
-            FolderGuid = guid;
+            GroupGuid = guid;
             DisplayIndex = displayIndex;
             TopIndex = topIndex;
             StructureData = structureData;

+ 70 - 37
PixiEditor/Models/Layers/LayerStructure.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
+using System.Windows;
 using PixiEditor.Models.DataHolders;
 
 namespace PixiEditor.Models.Layers
@@ -10,16 +11,16 @@ namespace PixiEditor.Models.Layers
     {
         public Document Owner { get; set; }
 
-        public ObservableCollection<GuidStructureItem> Folders { get; set; }
+        public ObservableCollection<GuidStructureItem> Groups { get; set; }
 
-        public GuidStructureItem GetFolderByGuid(Guid? folderGuid)
+        public GuidStructureItem GetGroupByGuid(Guid? groupGuid)
         {
-            return GetFolderByGuid(folderGuid, Folders);
+            return GetGroupByGuid(groupGuid, Groups);
         }
 
         public GuidStructureItem GetGroupByLayer(Guid layerGuid)
         {
-            return GetGroupByLayer(layerGuid, Folders);
+            return GetGroupByLayer(layerGuid, Groups);
         }
 
         public void AddNewGroup(string groupName, Guid childLayer)
@@ -28,7 +29,7 @@ namespace PixiEditor.Models.Layers
             GuidStructureItem group = new (groupName, childLayer);
             if (parent == null)
             {
-                Folders.Add(group);
+                Groups.Add(group);
             }
             else
             {
@@ -38,19 +39,19 @@ namespace PixiEditor.Models.Layers
         }
 
 #nullable enable
-        public void MoveGroup(Guid folderGuid, GuidStructureItem? parentFolder, int newIndex)
+        public void MoveGroup(Guid groupGuid, GuidStructureItem? parentGroup, int newIndex)
         {
-            var folder = GetFolderByGuid(folderGuid);
+            var group = GetGroupByGuid(groupGuid);
             bool reverseOrder = true;
-            int folderTopIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == folder.EndLayerGuid));
-            int folderBottomIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == folder.StartLayerGuid));
+            int groupTopIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == group.EndLayerGuid));
+            int groupBottomIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == group.StartLayerGuid));
 
-            int difference = newIndex - folderTopIndex;
+            int difference = newIndex - groupTopIndex;
 
-            if (newIndex < folderTopIndex)
+            if (newIndex < groupTopIndex)
             {
                 reverseOrder = false;
-                difference = newIndex - folderBottomIndex;
+                difference = newIndex - groupBottomIndex;
             }
 
             if (difference == 0)
@@ -58,9 +59,9 @@ namespace PixiEditor.Models.Layers
                 return;
             }
 
-            PreMoveReassignBounds(parentFolder, folder);
+            PreMoveReassignBounds(parentGroup, group);
 
-            List<Guid> layersInOrder = GetLayersInOrder(new FolderData(folderTopIndex, folderBottomIndex));
+            List<Guid> layersInOrder = GetLayersInOrder(new FolderData(groupTopIndex, groupBottomIndex));
 
             MoveLayersInGroup(layersInOrder, difference, reverseOrder);
         }
@@ -97,17 +98,17 @@ namespace PixiEditor.Models.Layers
             }
         }
 
-        public void PostMoveReassignBounds(GuidStructureItem? parentFolder, GuidStructureItem folder)
+        public void PostMoveReassignBounds(GuidStructureItem? parentGroup, GuidStructureItem folder)
         {
-            if (parentFolder != null)
+            if (parentGroup != null)
             {
                 if (folder.StartLayerGuid != null && folder.EndLayerGuid != null)
                 {
                     int folderTopIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == folder.EndLayerGuid));
                     int folderBottomIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == folder.StartLayerGuid));
 
-                    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));
+                    int parentFolderTopIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == parentGroup.EndLayerGuid));
+                    int parentFolderBottomIndex = Owner.Layers.IndexOf(Owner.Layers.First(x => x.LayerGuid == parentGroup.StartLayerGuid));
 
                     int finalTopIndex = Math.Max(folderTopIndex, parentFolderTopIndex);
                     int finalBottomIndex = Math.Min(folderBottomIndex, parentFolderBottomIndex);
@@ -115,45 +116,77 @@ namespace PixiEditor.Models.Layers
                     Guid? topBoundLayer = FindBoundLayer((Guid)folder.StartLayerGuid, finalTopIndex, finalBottomIndex, false);
                     Guid? bottomBoundLayer = FindBoundLayer((Guid)folder.EndLayerGuid, finalTopIndex, finalBottomIndex, true);
 
-                    if (topBoundLayer == parentFolder.EndLayerGuid)
+                    if (topBoundLayer == parentGroup.EndLayerGuid)
                     {
-                        parentFolder.EndLayerGuid = folder.EndLayerGuid;
+                        parentGroup.EndLayerGuid = folder.EndLayerGuid;
                     }
 
-                    if (bottomBoundLayer == parentFolder.StartLayerGuid)
+                    if (bottomBoundLayer == parentGroup.StartLayerGuid)
                     {
-                        parentFolder.StartLayerGuid = folder.StartLayerGuid;
+                        parentGroup.StartLayerGuid = folder.StartLayerGuid;
                     }
                 }
 
-                if (parentFolder.Parent != null)
+                if (parentGroup.Parent != null)
                 {
-                    PostMoveReassignBounds(parentFolder.Parent, parentFolder);
+                    PostMoveReassignBounds(parentGroup.Parent, parentGroup);
                 }
             }
         }
 
-        public void PreMoveReassignBounds(GuidStructureItem? parentFolder, Guid layer)
+        public void AssignParent(Guid layer, GuidStructureItem parent)
         {
-            if (parentFolder != null)
+            var currentParent = GetGroupByLayer(layer);
+            if(currentParent != null)
             {
-                if (parentFolder.EndLayerGuid == layer)
+                PreMoveReassignBounds(currentParent, layer);
+            }
+
+            PostMoveReassignBounds(parent, layer);
+        }
+
+        public void PreMoveReassignBounds(GuidStructureItem? parentGroup, Guid layer)
+        {
+            if (parentGroup != null)
+            {
+                GuidStructureItem parentOfParent = parentGroup.Parent;
+                if (parentGroup.Subfolders.Count == 0 && parentGroup.StartLayerGuid == layer && parentGroup.EndLayerGuid == layer)
                 {
-                    parentFolder.EndLayerGuid = FindBoundLayer(parentFolder, layer, false);
+                    RemoveGroup(parentGroup);
                 }
-
-                if (parentFolder.StartLayerGuid == layer)
+                else
                 {
-                    parentFolder.StartLayerGuid = FindBoundLayer(parentFolder, layer, true);
+
+                    if (parentGroup.EndLayerGuid == layer)
+                    {
+                        parentGroup.EndLayerGuid = FindBoundLayer(parentGroup, layer, false);
+                    }
+
+                    if (parentGroup.StartLayerGuid == layer)
+                    {
+                        parentGroup.StartLayerGuid = FindBoundLayer(parentGroup, layer, true);
+                    }
                 }
 
-                if (parentFolder.Parent != null)
+                if (parentOfParent != null)
                 {
-                    PreMoveReassignBounds(parentFolder.Parent, layer);
+                    PreMoveReassignBounds(parentOfParent, layer);
                 }
             }
         }
 
+        private void RemoveGroup(GuidStructureItem parentFolder)
+        {
+            if (parentFolder.Parent == null)
+            {
+                Groups.Remove(parentFolder);
+            }
+            else
+            {
+                parentFolder.Parent.Subfolders.Remove(parentFolder);
+            }
+        }
+
         private void PreMoveReassignBounds(GuidStructureItem? parentFolder, GuidStructureItem folder)
         {
             if (parentFolder != null)
@@ -262,7 +295,7 @@ namespace PixiEditor.Models.Layers
             return null;
         }
 
-        private GuidStructureItem GetFolderByGuid(Guid? folderGuid, IEnumerable<GuidStructureItem> folders)
+        private GuidStructureItem GetGroupByGuid(Guid? folderGuid, IEnumerable<GuidStructureItem> folders)
         {
             foreach (var folder in folders)
             {
@@ -273,7 +306,7 @@ namespace PixiEditor.Models.Layers
 
                 if (folder.Subfolders.Count > 0)
                 {
-                    return GetFolderByGuid(folderGuid, folder.Subfolders);
+                    return GetGroupByGuid(folderGuid, folder.Subfolders);
                 }
             }
 
@@ -282,13 +315,13 @@ namespace PixiEditor.Models.Layers
 
         public LayerStructure(ObservableCollection<GuidStructureItem> items, Document owner)
         {
-            Folders = items;
+            Groups = items;
             Owner = owner;
         }
 
         public LayerStructure(Document owner)
         {
-            Folders = new ObservableCollection<GuidStructureItem>();
+            Groups = new ObservableCollection<GuidStructureItem>();
             Owner = owner;
         }
     }

+ 12 - 12
PixiEditor/Models/Layers/StructuredLayerTree.cs

@@ -16,13 +16,13 @@ namespace PixiEditor.Models.Layers
 
         public StructuredLayerTree(ObservableCollection<Layer> layers, LayerStructure structure)
         {
-            if (structure.Folders == null || structure.Folders.Count == 0)
+            if (structure.Groups == null || structure.Groups.Count == 0)
             {
                 RootDirectoryItems.AddRange(layers);
                 return;
             }
 
-            var parsedFolders = ParseFolders(structure.Folders, layers);
+            var parsedFolders = ParseFolders(structure.Groups, layers);
 
             parsedFolders = parsedFolders.OrderBy(x => x.DisplayIndex).ToList();
 
@@ -31,11 +31,11 @@ namespace PixiEditor.Models.Layers
             layersInStructure.Clear();
         }
 
-        private void PlaceItems(List<LayerFolder> parsedFolders, ObservableCollection<Layer> layers)
+        private void PlaceItems(List<LayerGroup> parsedFolders, ObservableCollection<Layer> layers)
         {
-            LayerFolder currentFolder = null;
-            List<LayerFolder> foldersAtIndex = new ();
-            Stack<LayerFolder> unfinishedFolders = new ();
+            LayerGroup currentFolder = null;
+            List<LayerGroup> foldersAtIndex = new ();
+            Stack<LayerGroup> unfinishedFolders = new ();
 
             for (int i = 0; i < layers.Count; i++)
             {
@@ -58,7 +58,7 @@ namespace PixiEditor.Models.Layers
                     foldersAtIndex = parsedFolders.Where(x => x.StructureData.StartLayerGuid == layers[i].LayerGuid).ToList();
                     for (int j = 0; j < foldersAtIndex.Count; j++)
                     {
-                        LayerFolder folder = foldersAtIndex[j];
+                        LayerGroup folder = foldersAtIndex[j];
 
                         if (currentFolder != null)
                         {
@@ -94,9 +94,9 @@ namespace PixiEditor.Models.Layers
             return displayIndex + (originalTopIndex - originalBottomIndex);
         }
 
-        private List<LayerFolder> ParseFolders(IEnumerable<GuidStructureItem> folders, ObservableCollection<Layer> layers)
+        private List<LayerGroup> ParseFolders(IEnumerable<GuidStructureItem> folders, ObservableCollection<Layer> layers)
         {
-            List<LayerFolder> parsedFolders = new();
+            List<LayerGroup> parsedFolders = new();
             foreach (var structureItem in folders)
             {
                 parsedFolders.Add(ParseFolder(structureItem, layers));
@@ -105,13 +105,13 @@ namespace PixiEditor.Models.Layers
             return parsedFolders;
         }
 
-        private LayerFolder ParseFolder(GuidStructureItem structureItem, ObservableCollection<Layer> layers)
+        private LayerGroup ParseFolder(GuidStructureItem structureItem, ObservableCollection<Layer> layers)
         {
             List<Layer> structureItemLayers = new();
 
             Guid[] layersInFolder = GetLayersInFolder(layers, structureItem);
 
-            var subFolders = new List<LayerFolder>();
+            var subFolders = new List<LayerGroup>();
 
             if (structureItem.Subfolders.Count > 0)
             {
@@ -132,7 +132,7 @@ namespace PixiEditor.Models.Layers
 
             structureItemLayers.Reverse();
 
-            LayerFolder folder = new (structureItemLayers, subFolders, structureItem.Name,
+            LayerGroup folder = new (structureItemLayers, subFolders, structureItem.Name,
                 structureItem.FolderGuid, displayIndex, displayIndex + structureItemLayers.Count - 1, structureItem)
             {
                 IsExpanded = structureItem.IsExpanded

+ 0 - 86
PixiEditor/Views/UserControls/LayerFolder.xaml.cs

@@ -1,86 +0,0 @@
-using System;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-using PixiEditor.ViewModels.SubViewModels.Main;
-
-namespace PixiEditor.Views.UserControls
-{
-    /// <summary>
-    /// Interaction logic for LayerFolder.xaml.
-    /// </summary>
-    public partial class LayerFolder : UserControl
-    {
-        public Guid FolderGuid
-        {
-            get { return (Guid)GetValue(FolderGuidProperty); }
-            set { SetValue(FolderGuidProperty, value); }
-        }
-
-        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
-        public static readonly DependencyProperty FolderGuidProperty =
-            DependencyProperty.Register("FolderGuid", typeof(Guid), typeof(LayerFolder), new PropertyMetadata(Guid.NewGuid()));
-
-        public LayersViewModel LayersViewModel
-        {
-            get { return (LayersViewModel)GetValue(LayersViewModelProperty); }
-            set { SetValue(LayersViewModelProperty, value); }
-        }
-
-        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
-        public static readonly DependencyProperty LayersViewModelProperty =
-            DependencyProperty.Register("LayersViewModel", typeof(LayersViewModel), typeof(LayerFolder), new PropertyMetadata(default(LayersViewModel)));
-
-        public string FolderName
-        {
-            get { return (string)GetValue(FolderNameProperty); }
-            set { SetValue(FolderNameProperty, value); }
-        }
-
-        // Using a DependencyProperty as the backing store for FolderName.  This enables animation, styling, binding, etc...
-        public static readonly DependencyProperty FolderNameProperty =
-            DependencyProperty.Register("FolderName", typeof(string), typeof(LayerFolder), new PropertyMetadata(""));
-
-        public LayerFolder()
-        {
-            InitializeComponent();
-        }
-
-        private void Grid_DragEnter(object sender, DragEventArgs e)
-        {
-            Grid item = sender as Grid;
-
-            item.Background = LayerItem.HighlightColor;
-        }
-
-        private void Grid_DragLeave(object sender, DragEventArgs e)
-        {
-            Grid grid = (Grid)sender;
-
-            LayerItem.RemoveDragEffect(grid);
-        }
-
-        private void Grid_Drop_Top(object sender, DragEventArgs e)
-        {
-
-        }
-
-        private void Grid_Drop_Bottom(object sender, DragEventArgs e)
-        {
-
-        }
-
-        private void Grid_Drop_Middle(object sender, DragEventArgs e)
-        {
-            Grid grid = (Grid)sender;
-
-            LayerItem.RemoveDragEffect(grid);
-
-            if (e.Data.GetDataPresent("PixiEditor.Views.UserControls.LayerStructureItemContainer"))
-            {
-
-            }
-        }
-    }
-}

+ 8 - 8
PixiEditor/Views/UserControls/LayerFolder.xaml → PixiEditor/Views/UserControls/LayerGroupControl.xaml

@@ -1,35 +1,35 @@
-<UserControl x:Class="PixiEditor.Views.UserControls.LayerFolder"
+<UserControl x:Class="PixiEditor.Views.UserControls.LayerGroupControl"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:PixiEditor.Views.UserControls" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours" xmlns:userControls="clr-namespace:PixiEditor.Views"
              mc:Ignorable="d" Focusable="True"
-             d:DesignHeight="60" d:DesignWidth="250" Name="folderControl">
+             d:DesignHeight="60" d:DesignWidth="250" Name="groupControl">
     <Border BorderThickness="0 0 0 0.5" BorderBrush="Gray" MinWidth="60" Focusable="True" >
         <i:Interaction.Behaviors>
             <behaviors:ClearFocusOnClickBehavior/>
         </i:Interaction.Behaviors>
         <Grid>
             <Grid.RowDefinitions>
-                <RowDefinition Height="7.5"/>
-                <RowDefinition Height="20"/>
-                <RowDefinition Height="7.5"/>
+                <RowDefinition Height="10"/>
+                <RowDefinition Height="15"/>
+                <RowDefinition Height="10"/>
             </Grid.RowDefinitions>
             <Grid AllowDrop="True" DragEnter="Grid_DragEnter" Drop="Grid_Drop_Top" DragLeave="Grid_DragLeave" Grid.Row="0" Grid.ColumnSpan="3" Background="Transparent"/>
-            <Grid Grid.Row="1" Drop="Grid_Drop_Middle" AllowDrop="True" DragEnter="Grid_DragEnter" DragLeave="Grid_DragLeave">
+            <Grid Grid.Row="0" Grid.RowSpan="3" Margin="5 0 5 0">
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="30"/>
                     <ColumnDefinition Width="1*"/>
                     <ColumnDefinition Width="20"/>
                 </Grid.ColumnDefinitions>
-                <Image Source="/Images/Folder.png" />
+                <Image Source="/Images/Folder.png" Height="20"/>
                 <StackPanel Grid.Row="1" Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Left" Margin="5,0,0,0">
                     <userControls:EditableTextBlock
                     IsEditing="False"
                     FontSize="16"
                     VerticalAlignment="Center"
-                    Text="{Binding FolderName, ElementName=folderControl, Mode=TwoWay}" />
+                    Text="{Binding GroupName, ElementName=groupControl, Mode=TwoWay}" />
                 </StackPanel>
             </Grid>
             <Grid DragEnter="Grid_DragEnter" Drop="Grid_Drop_Bottom"  DragLeave="Grid_DragLeave" Grid.Row="2" AllowDrop="True" Grid.ColumnSpan="3" Background="Transparent"/>

+ 114 - 0
PixiEditor/Views/UserControls/LayerGroupControl.xaml.cs

@@ -0,0 +1,114 @@
+using System;
+using System.Linq;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using PixiEditor.Models.Layers;
+using PixiEditor.ViewModels.SubViewModels.Main;
+
+namespace PixiEditor.Views.UserControls
+{
+    /// <summary>
+    /// Interaction logic for LayerFolder.xaml.
+    /// </summary>
+    public partial class LayerGroupControl : UserControl
+    {
+        public Guid GroupGuid
+        {
+            get { return (Guid)GetValue(GroupGuidProperty); }
+            set { SetValue(GroupGuidProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty GroupGuidProperty =
+            DependencyProperty.Register("GroupGuid", typeof(Guid), typeof(LayerGroupControl), new PropertyMetadata(Guid.NewGuid()));
+
+        public LayersViewModel LayersViewModel
+        {
+            get { return (LayersViewModel)GetValue(LayersViewModelProperty); }
+            set { SetValue(LayersViewModelProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty LayersViewModelProperty =
+            DependencyProperty.Register("LayersViewModel", typeof(LayersViewModel), typeof(LayerGroupControl), new PropertyMetadata(default(LayersViewModel)));
+
+        public string GroupName
+        {
+            get { return (string)GetValue(GroupNameProperty); }
+            set { SetValue(GroupNameProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for FolderName.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty GroupNameProperty =
+            DependencyProperty.Register("GroupName", typeof(string), typeof(LayerGroupControl), new PropertyMetadata(default(string)));
+
+        public GuidStructureItem GroupData
+        {
+            get { return (GuidStructureItem)GetValue(GroupDataProperty); }
+            set { SetValue(GroupDataProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty GroupDataProperty =
+            DependencyProperty.Register("GroupData", typeof(GuidStructureItem), typeof(LayerGroupControl), new PropertyMetadata(default(GuidStructureItem)));
+
+        public LayerGroupControl()
+        {
+            InitializeComponent();
+        }
+
+        private void Grid_DragEnter(object sender, DragEventArgs e)
+        {
+            Grid item = sender as Grid;
+
+            item.Background = LayerItem.HighlightColor;
+        }
+
+        private void Grid_DragLeave(object sender, DragEventArgs e)
+        {
+            Grid grid = (Grid)sender;
+
+            LayerItem.RemoveDragEffect(grid);
+        }
+
+        private void HandleDrop(IDataObject dataObj, bool above)
+        {
+            Guid referenceLayer = above ? (Guid)GroupData.EndLayerGuid : (Guid)GroupData.StartLayerGuid;
+
+            if (dataObj.GetDataPresent("PixiEditor.Views.UserControls.LayerStructureItemContainer"))
+            {
+                var data = (LayerStructureItemContainer)dataObj.GetData("PixiEditor.Views.UserControls.LayerStructureItemContainer");
+                Guid group = data.Layer.LayerGuid;
+
+                data.LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.MoveLayerInStructure(group, referenceLayer, above);
+                data.LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.LayerStructure.AssignParent(group, GroupData.Parent);
+            }
+
+            if (dataObj.GetDataPresent("PixiEditor.Views.UserControls.LayerGroupControl"))
+            {
+                var data = (LayerGroupControl)dataObj.GetData("PixiEditor.Views.UserControls.LayerGroupControl");
+                Guid group = data.GroupGuid;
+                var document = data.LayersViewModel.Owner.BitmapManager.ActiveDocument;
+
+                Layer layer = document.Layers.First(x => x.LayerGuid == referenceLayer);
+                int indexOfReferenceLayer = document.Layers.IndexOf(layer) + 1;
+
+                Layer tempLayer = new("_temp");
+                document.Layers.Insert(indexOfReferenceLayer, tempLayer);
+                document.MoveFolderInStructure(group, tempLayer.LayerGuid, above); //TODO fix
+                document.Layers.Remove(tempLayer);
+            }
+        }
+
+        private void Grid_Drop_Top(object sender, DragEventArgs e)
+        {
+            HandleDrop(e.Data, true);
+        }
+
+        private void Grid_Drop_Bottom(object sender, DragEventArgs e)
+        {
+            HandleDrop(e.Data, false);
+        }
+    }
+}

+ 3 - 3
PixiEditor/Views/UserControls/LayerItem.xaml.cs

@@ -168,10 +168,10 @@ namespace PixiEditor.Views
                 data.LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.MoveLayerInStructure(layer, LayerGuid, above);
             }
 
-            if (e.Data.GetDataPresent("PixiEditor.Views.UserControls.LayerFolder"))
+            if (e.Data.GetDataPresent("PixiEditor.Views.UserControls.LayerGroupControl"))
             {
-                var data = (LayerFolder)e.Data.GetData("PixiEditor.Views.UserControls.LayerFolder");
-                Guid folder = data.FolderGuid;
+                var data = (LayerGroupControl)e.Data.GetData("PixiEditor.Views.UserControls.LayerGroupControl");
+                Guid folder = data.GroupGuid;
 
                 data.LayersViewModel.Owner.BitmapManager.ActiveDocument.MoveFolderInStructure(folder, LayerGuid, above);
             }

+ 3 - 3
PixiEditor/Views/UserControls/LayersManager.xaml

@@ -25,7 +25,7 @@
         <Button Grid.Row="0" Command="{Binding LayerCommandsViewModel.NewLayerCommand, ElementName=layersManager}" Height="30" Content="New Layer"
                                             HorizontalAlignment="Stretch" Margin="5"
                                             Style="{StaticResource DarkRoundButton}" />
-        <Button Grid.Row="0" Command="{Binding LayerCommandsViewModel.NewGroupCommand, ElementName=layersManager}" Height="30" Content="New Folder"
+        <Button Grid.Row="0" Command="{Binding LayerCommandsViewModel.NewGroupCommand, ElementName=layersManager}" Height="30" Content="New Group"
                                             HorizontalAlignment="Stretch" Margin="5"
                                             Style="{StaticResource DarkRoundButton}" />
         </StackPanel>
@@ -49,8 +49,8 @@
                     </ItemsPanelTemplate>
                 </TreeView.ItemsPanel>
                 <TreeView.Resources>
-                    <HierarchicalDataTemplate DataType="{x:Type layers:LayerFolder}" ItemsSource="{Binding Items}">
-                        <local:LayerFolder FolderName="{Binding Name}" LayersViewModel="{Binding LayerCommandsViewModel, ElementName=layersManager}" FolderGuid="{Binding FolderGuid}" MouseMove="LayerFolder_MouseMove"/>
+                    <HierarchicalDataTemplate DataType="{x:Type layers:LayerGroup}" ItemsSource="{Binding Items}">
+                        <local:LayerGroupControl GroupName="{Binding Name}" LayersViewModel="{Binding LayerCommandsViewModel, ElementName=layersManager}" GroupGuid="{Binding GroupGuid}" GroupData="{Binding StructureData}" MouseMove="LayerFolder_MouseMove"/>
                     </HierarchicalDataTemplate>
                     <DataTemplate DataType="{x:Type layers:Layer}">
                         <local:LayerStructureItemContainer                             

+ 1 - 1
PixiEditor/Views/UserControls/LayersManager.xaml.cs

@@ -69,7 +69,7 @@ namespace PixiEditor.Views.UserControls
 
         private void LayerFolder_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
         {
-            if (sender is LayerFolder container && e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
+            if (sender is LayerGroupControl container && e.LeftButton == System.Windows.Input.MouseButtonState.Pressed)
             {
                 DragDrop.DoDragDrop(container, container, DragDropEffects.Move);
             }