Browse Source

Changed how moving layers work, Undo TODO

flabbet 4 năm trước cách đây
mục cha
commit
369d7b585c

+ 25 - 12
PixiEditor/Models/DataHolders/Document/Document.Layers.cs

@@ -97,15 +97,16 @@ namespace PixiEditor.Models.DataHolders
             }
         }
 
-        public void MoveLayerIndexBy(int layerIndex, int amount)
+        public void MoveLayerInStructure(Guid layer, Guid referenceLayer, bool above = false)
         {
-            MoveLayerProcess(new object[] { layerIndex, amount });
+            var args = new object[] { layer, referenceLayer, above };
+            MoveLayerInStructureProcess(args);
 
             UndoManager.AddUndoChange(new Change(
-                MoveLayerProcess,
-                new object[] { layerIndex + amount, -amount },
-                MoveLayerProcess,
-                new object[] { layerIndex, amount },
+                MoveLayerInStructureProcess,
+                new object[] { layer, referenceLayer, !above },
+                MoveLayerInStructureProcess,
+                args,
                 "Move layer"));
         }
 
@@ -421,16 +422,28 @@ namespace PixiEditor.Models.DataHolders
             }
         }
 
-        private void MoveLayerProcess(object[] parameter)
+        private void MoveLayerInStructureProcess(object[] parameter)
         {
-            int layerIndex = (int)parameter[0];
-            int amount = (int)parameter[1];
+            Guid layer = (Guid)parameter[0];
+            Guid referenceLayer = (Guid)parameter[1];
+            bool above = (bool)parameter[2];
 
-            Layers.Move(layerIndex, layerIndex + amount);
-            if (Layers.IndexOf(ActiveLayer) == layerIndex)
+            int oldIndex = Layers.IndexOf(Layers.First(x => x.LayerGuid == layer));
+            int newIndex = Layers.IndexOf(Layers.First(x => x.LayerGuid == referenceLayer));
+
+            if ((oldIndex - newIndex == -1 && !above) || (oldIndex - newIndex == 1 && above))
             {
-                SetMainActiveLayer(layerIndex + amount);
+                newIndex += above ? 1 : -1;
             }
+
+            Layers.Move(oldIndex, newIndex);
+            if (Layers.IndexOf(ActiveLayer) == oldIndex)
+            {
+                SetMainActiveLayer(newIndex);
+            }
+
+            //LayerStructure.MoveLayerToFolder(layerGuid, folderGuid);
+            //RaisePropertyChanged(nameof(LayerStructure));
         }
 
         private void RestoreLayersProcess(Layer[] layers, UndoLayer[] layersData)

+ 43 - 0
PixiEditor/Models/Layers/LayerStructure.cs

@@ -13,6 +13,49 @@ namespace PixiEditor.Models.Layers
             return GetFolderByGuid(folderGuid, Folders);
         }
 
+        /// <summary>
+        /// Moves layer from folder if already exist to new one, or removes completely if specified folderGuid is null;
+        /// </summary>
+        /// <param name="layerGuid">Guid of layer to move.</param>
+        /// <param name="folderGuid">Folder guid to move layer to, set to null to remove completely.</param>
+        public void MoveLayerToFolder(Guid layerGuid, Guid? folderGuid)
+        {
+            GuidStructureItem oldFolder = GetFolderByLayer(layerGuid);
+            if (oldFolder != null)
+            {
+                oldFolder.LayerGuids.Remove(layerGuid);
+            }
+
+            if (folderGuid != null)
+            {
+                var folder = GetFolderByGuid((Guid)folderGuid);
+                folder.LayerGuids.Add(layerGuid);
+            }
+        }
+
+        public GuidStructureItem GetFolderByLayer(Guid layerGuid)
+        {
+            return GetFolderByLayer(layerGuid, Folders);
+        }
+
+        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);
+                }
+            }
+
+            return null;
+        }
+
         private GuidStructureItem GetFolderByGuid(Guid folderGuid, IEnumerable<GuidStructureItem> folders)
         {
             foreach (var folder in folders)

+ 18 - 18
PixiEditor/ViewModels/SubViewModels/Main/FileViewModel.cs

@@ -110,24 +110,24 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
             Owner.ResetProgramStateValues();
 
-            Owner.BitmapManager.ActiveDocument.AddNewLayer("Test");
-            Owner.BitmapManager.ActiveDocument.AddNewLayer("Test1");
-            Owner.BitmapManager.ActiveDocument.AddNewLayer("Test1 sub1");
-            Owner.BitmapManager.ActiveDocument.AddNewLayer("Test1 sub2");
-            Owner.BitmapManager.ActiveDocument.LayerStructure.Folders.Add(
-                new GuidStructureItem("Folder 1", new ObservableCollection<Guid>()
-                {
-                    Owner.BitmapManager.ActiveDocument.Layers[1].LayerGuid,
-                    Owner.BitmapManager.ActiveDocument.Layers[2].LayerGuid
-                },
-                new GuidStructureItem[] {
-                        new GuidStructureItem("Subfolder 1", new ObservableCollection<Guid>()
-                    {
-                        Owner.BitmapManager.ActiveDocument.Layers[3].LayerGuid,
-                        Owner.BitmapManager.ActiveDocument.Layers[4].LayerGuid
-                    },  Array.Empty<GuidStructureItem>()
-                    )})
-                { IsExpanded = true});
+            //Owner.BitmapManager.ActiveDocument.AddNewLayer("Test");
+            //Owner.BitmapManager.ActiveDocument.AddNewLayer("Test1");
+            //Owner.BitmapManager.ActiveDocument.AddNewLayer("Test1 sub1");
+            //Owner.BitmapManager.ActiveDocument.AddNewLayer("Test1 sub2");
+            //Owner.BitmapManager.ActiveDocument.LayerStructure.Folders.Add(
+            //    new GuidStructureItem("Folder 1", new ObservableCollection<Guid>()
+            //    {
+            //        Owner.BitmapManager.ActiveDocument.Layers[1].LayerGuid,
+            //        Owner.BitmapManager.ActiveDocument.Layers[2].LayerGuid
+            //    },
+            //    new GuidStructureItem[] {
+            //            new GuidStructureItem("Subfolder 1", new ObservableCollection<Guid>()
+            //        {
+            //            Owner.BitmapManager.ActiveDocument.Layers[3].LayerGuid,
+            //            Owner.BitmapManager.ActiveDocument.Layers[4].LayerGuid
+            //        },  Array.Empty<GuidStructureItem>()
+            //        )})
+            //    { IsExpanded = true});
         }
 
         /// <summary>

+ 6 - 2
PixiEditor/ViewModels/SubViewModels/Main/LayersViewModel.cs

@@ -126,13 +126,17 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         public void MoveLayerToFront(object parameter)
         {
             int oldIndex = (int)parameter;
-            Owner.BitmapManager.ActiveDocument.MoveLayerIndexBy(oldIndex, 1);
+            Guid layerToMove = Owner.BitmapManager.ActiveDocument.Layers[oldIndex].LayerGuid;
+            Guid referenceLayer = Owner.BitmapManager.ActiveDocument.Layers[oldIndex + 1].LayerGuid;
+            Owner.BitmapManager.ActiveDocument.MoveLayerInStructure(layerToMove, referenceLayer, true);
         }
 
         public void MoveLayerToBack(object parameter)
         {
             int oldIndex = (int)parameter;
-            Owner.BitmapManager.ActiveDocument.MoveLayerIndexBy(oldIndex, -1);
+            Guid layerToMove = Owner.BitmapManager.ActiveDocument.Layers[oldIndex].LayerGuid;
+            Guid referenceLayer = Owner.BitmapManager.ActiveDocument.Layers[oldIndex - 1].LayerGuid;
+            Owner.BitmapManager.ActiveDocument.MoveLayerInStructure(layerToMove, referenceLayer, false);
         }
 
         public bool CanMoveToFront(object property)

+ 3 - 4
PixiEditor/Views/UserControls/LayerFolder.xaml

@@ -4,9 +4,8 @@
              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"
-             MouseLeave="FolderControl_MouseLeave"  MouseEnter="FolderControl_MouseEnter">
+             mc:Ignorable="d" Focusable="True" MouseMove="FolderControl_MouseMove"
+             d:DesignHeight="60" d:DesignWidth="250" Name="folderControl">
     <Border BorderThickness="0 0 0 0.5" BorderBrush="Gray" MinWidth="60" Focusable="True" >
         <i:Interaction.Behaviors>
             <behaviors:ClearFocusOnClickBehavior/>
@@ -18,7 +17,7 @@
                 <RowDefinition Height="7.5"/>
             </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" DragEnter="Grid_DragEnter" DragLeave="Grid_DragLeave">
+            <Grid Grid.Row="1" Drop="Grid_Drop_Middle" DragEnter="Grid_DragEnter" DragLeave="Grid_DragLeave">
                 <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="30"/>
                     <ColumnDefinition Width="1*"/>

+ 6 - 6
PixiEditor/Views/UserControls/LayerFolder.xaml.cs

@@ -47,32 +47,32 @@ namespace PixiEditor.Views.UserControls
             InitializeComponent();
         }
 
-        private void FolderControl_MouseLeave(object sender, MouseEventArgs e)
+        private void Grid_DragEnter(object sender, DragEventArgs e)
         {
 
         }
 
-        private void FolderControl_MouseEnter(object sender, MouseEventArgs e)
+        private void Grid_DragLeave(object sender, DragEventArgs e)
         {
 
         }
 
-        private void Grid_DragEnter(object sender, DragEventArgs e)
+        private void Grid_Drop_Top(object sender, DragEventArgs e)
         {
 
         }
 
-        private void Grid_DragLeave(object sender, DragEventArgs e)
+        private void Grid_Drop_Bottom(object sender, DragEventArgs e)
         {
 
         }
 
-        private void Grid_Drop_Top(object sender, DragEventArgs e)
+        private void Grid_Drop_Middle(object sender, DragEventArgs e)
         {
 
         }
 
-        private void Grid_Drop_Bottom(object sender, DragEventArgs e)
+        private void FolderControl_MouseMove(object sender, MouseEventArgs e)
         {
 
         }

+ 29 - 13
PixiEditor/Views/UserControls/LayerItem.xaml.cs

@@ -1,4 +1,5 @@
-using System.Windows;
+using System;
+using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Input;
 using System.Windows.Media;
@@ -53,7 +54,7 @@ namespace PixiEditor.Views
 
         public int LayerIndex
         {
-            get { return (int) GetValue(LayerIndexProperty); }
+            get { return (int)GetValue(LayerIndexProperty); }
             set { SetValue(LayerIndexProperty, value); }
         }
 
@@ -66,6 +67,16 @@ namespace PixiEditor.Views
             set { SetValue(LayerNameProperty, value); }
         }
 
+        public Guid LayerGuid
+        {
+            get { return (Guid)GetValue(LayerGuidProperty); }
+            set { SetValue(LayerGuidProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for LayerGuid.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty LayerGuidProperty =
+            DependencyProperty.Register("LayerGuid", typeof(Guid), typeof(LayerItem), new PropertyMetadata(default(Guid)));
+
         public static readonly DependencyProperty ControlButtonsVisibleProperty = DependencyProperty.Register(
             "ControlButtonsVisible", typeof(Visibility), typeof(LayerItem), new PropertyMetadata(System.Windows.Visibility.Hidden));
 
@@ -144,7 +155,7 @@ namespace PixiEditor.Views
             RemoveDragEffect(item);
         }
 
-        private void HandleGridDrop(object sender, DragEventArgs e, int indexModifier)
+        private void HandleGridDrop(object sender, DragEventArgs e, bool above)
         {
             Grid item = sender as Grid;
             RemoveDragEffect(item);
@@ -152,25 +163,30 @@ namespace PixiEditor.Views
             if (e.Data.GetDataPresent("PixiEditor.Views.UserControls.LayerStructureItemContainer"))
             {
                 var data = (LayerStructureItemContainer)e.Data.GetData("PixiEditor.Views.UserControls.LayerStructureItemContainer");
-                int oldIndex = data.ContainerIndex;
-                int moveBy = LayerIndex + indexModifier - oldIndex;
-                if (moveBy > 0)
-                {
-                    moveBy--;
-                }
-
-                data.LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.MoveLayerIndexBy(oldIndex, moveBy);
+                Guid layer = data.Layer.LayerGuid;
+
+                //var folder = data.LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.LayerStructure.GetFolderByLayer(
+                //    data.LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.Layers[LayerIndex + moveBy].LayerGuid);
+
+                //Guid? folderGuid = null;
+
+                //if (folder != null)
+                //{
+                //    folderGuid = folder.FolderGuid;
+                //}
+
+                data.LayerCommandsViewModel.Owner.BitmapManager.ActiveDocument.MoveLayerInStructure(layer, LayerGuid, above);
             }
         }
 
         private void Grid_Drop_Top(object sender, DragEventArgs e)
         {
-            HandleGridDrop(sender, e, 1);
+            HandleGridDrop(sender, e, true);
         }
 
         private void Grid_Drop_Bottom(object sender, DragEventArgs e)
         {
-            HandleGridDrop(sender, e, 0);
+            HandleGridDrop(sender, e, false);
         }
     }
 }

+ 2 - 1
PixiEditor/Views/UserControls/LayerStructureItemContainer.xaml

@@ -3,7 +3,7 @@
              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:vws="clr-namespace:PixiEditor.Views"
+             xmlns:vws="clr-namespace:PixiEditor.Views" xmlns:layers="clr-namespace:PixiEditor.Models.Layers" d:DataContext="{d:DesignInstance Type=layers:Layer}"
              mc:Ignorable="d"
              d:DesignHeight="60" d:DesignWidth="250" Name="layerStructureContainer">
     <vws:LayerItem Tag="{Binding ElementName=layerStructureContainer}"
@@ -12,6 +12,7 @@
                                        IsActive="{Binding IsActive, Mode=TwoWay}"
                                        IsRenaming="{Binding IsRenaming, Mode=TwoWay}"
                                        PreviewImage="{Binding LayerBitmap}"
+                                       LayerGuid="{Binding LayerGuid}"
                                        LayerColor="{Binding LayerHighlightColor}"
                                        LayerIndex="{Binding ContainerIndex, ElementName=layerStructureContainer}"
                                       MoveToBackCommand="{Binding LayerCommandsViewModel.MoveToBackCommand, ElementName=layerStructureContainer}"

+ 5 - 0
PixiEditor/Views/UserControls/LayersManager.xaml

@@ -43,6 +43,11 @@
         <Separator Grid.Row="2" Background="{StaticResource BrighterAccentColor}"/>
         <ScrollViewer Grid.Row="3" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
             <TreeView ItemsSource="{Binding LayerTreeRoot, ElementName=layersManager}">
+                <TreeView.ItemsPanel>
+                    <ItemsPanelTemplate>
+                        <ui:ReversedOrderStackPanel/>
+                    </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}" />