Преглед на файлове

Display structured layers wip

flabbet преди 4 години
родител
ревизия
8a882af2c7

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

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Windows.Data;
+using PixiEditor.Models.Layers;
+
+namespace PixiEditor.Helpers.Converters
+{
+    public class LayersToStructuredLayersConverter : IMultiValueConverter
+    {
+        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (values[0] is IEnumerable<Layer> layers && values[1] is LayerStructure structure)
+            {
+                return new StructuredLayerTree(layers, structure).Items;
+            }
+
+            return null;
+        }
+
+        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 2 - 0
PixiEditor/Models/DataHolders/Document/Document.Layers.cs

@@ -19,6 +19,8 @@ namespace PixiEditor.Models.DataHolders
 
         public ObservableCollection<Layer> Layers { get; set; } = new ObservableCollection<Layer>();
 
+        public LayerStructure LayerStructure { get; set; } = new LayerStructure();
+
         public Layer ActiveLayer => Layers.Count > 0 ? Layers[ActiveLayerIndex] : null;
 
         public int ActiveLayerIndex

+ 15 - 0
PixiEditor/Models/Layers/GuidStructureItem.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.ObjectModel;
+
+namespace PixiEditor.Models.Layers
+{
+    public class GuidStructureItem
+    {
+        public ObservableCollection<Guid> Children { get; set; }
+
+        public GuidStructureItem(ObservableCollection<Guid> children)
+        {
+            Children = children;
+        }
+    }
+}

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

@@ -0,0 +1,19 @@
+using System.Collections.ObjectModel;
+
+namespace PixiEditor.Models.Layers
+{
+    public class LayerStructure
+    {
+        public ObservableCollection<GuidStructureItem> Items { get; set; }
+
+        public LayerStructure(ObservableCollection<GuidStructureItem> items)
+        {
+            Items = items;
+        }
+
+        public LayerStructure()
+        {
+            Items = new ObservableCollection<GuidStructureItem>();
+        }
+    }
+}

+ 14 - 0
PixiEditor/Models/Layers/LayerStructureItem.cs

@@ -0,0 +1,14 @@
+using System.Collections.ObjectModel;
+
+namespace PixiEditor.Models.Layers
+{
+    public class LayerStructureItem
+    {
+        public ObservableCollection<Layer> Children { get; set; }
+
+        public LayerStructureItem(ObservableCollection<Layer> children)
+        {
+            Children = children;
+        }
+    }
+}

+ 37 - 0
PixiEditor/Models/Layers/StructuredLayerTree.cs

@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using PixiEditor.Helpers.Extensions;
+
+namespace PixiEditor.Models.Layers
+{
+    public class StructuredLayerTree
+    {
+        public ObservableCollection<LayerStructureItem> Items { get; set; }
+
+        public StructuredLayerTree(IEnumerable<Layer> layers, LayerStructure structure)
+        {
+            Items = new ();
+            if (structure == null || structure.Items.Count == 0)
+            {
+                foreach (var layer in layers)
+                {
+                    Items.Add(new LayerStructureItem(new ObservableCollection<Layer> { layer }));
+                }
+
+                return;
+            }
+
+            for (int i = 0; i < structure.Items.Count; i++)
+            {
+                var itemChildren = new ObservableCollection<Layer>();
+                foreach (var guid in structure.Items[i].Children)
+                {
+                    itemChildren.Add(layers.First(x => x.LayerGuid == guid));
+                }
+
+                Items.Add(new LayerStructureItem(itemChildren));
+            }
+        }
+    }
+}

+ 6 - 10
PixiEditor/Views/UserControls/LayerItem.xaml.cs

@@ -1,21 +1,17 @@
 using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Collections.ObjectModel;
 using System.Windows;
 using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
 using System.Windows.Input;
-using System.Windows.Media;
 using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
 using PixiEditor.Helpers;
+using PixiEditor.Helpers.UI;
+using PixiEditor.Models.Layers;
 
 namespace PixiEditor.Views
 {
     /// <summary>
-    /// Interaction logic for LayerItem.xaml
+    /// Interaction logic for LayerItem.xaml.
     /// </summary>
     public partial class LayerItem : UserControl
     {
@@ -29,7 +25,7 @@ namespace PixiEditor.Views
 
         public bool IsRenaming
         {
-            get { return (bool) GetValue(IsRenamingProperty); }
+            get { return (bool)GetValue(IsRenamingProperty); }
             set { SetValue(IsRenamingProperty, value); }
         }
 
@@ -38,7 +34,7 @@ namespace PixiEditor.Views
 
         public bool IsActive
         {
-            get { return (bool) GetValue(IsActiveProperty); }
+            get { return (bool)GetValue(IsActiveProperty); }
             set { SetValue(IsActiveProperty, value); }
         }
 

+ 61 - 0
PixiEditor/Views/UserControls/LayerStructureItemContainer.xaml

@@ -0,0 +1,61 @@
+<UserControl x:Class="PixiEditor.Views.UserControls.LayerStructureItemContainer"
+             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:vws="clr-namespace:PixiEditor.Views"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800" Name="uc">
+    <Grid>
+        <vws:LayerItem Tag="{Binding Path=DataContext, ElementName=layersItemsControl}" 
+                                       LayerIndex="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
+                                Path=(ItemsControl.AlternationIndex)}" 
+                                       SetActiveLayerCommand="{Binding DataContext.LayersViewModel.SetActiveLayerCommand, 
+                            ElementName=layersItemsControl}"
+                                       LayerName="{Binding Name, Mode=TwoWay}" IsActive="{Binding IsActive, Mode=TwoWay}"
+                                       IsRenaming="{Binding IsRenaming, Mode=TwoWay}"
+                                       PreviewImage="{Binding LayerBitmap}"
+                                      MoveToBackCommand="{Binding DataContext.LayersViewModel.MoveToBackCommand, ElementName=layersItemsControl}"
+                                      MoveToFrontCommand="{Binding DataContext.LayersViewModel.MoveToFrontCommand, ElementName=layersItemsControl}">
+            <vws:LayerItem.ContextMenu>
+                <ContextMenu>
+                    <MenuItem Header="Delete"
+                                         Command="{Binding PlacementTarget.Tag.LayersViewModel.DeleteLayersCommand, 
+                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
+                                         CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
+                                Path=(ItemsControl.AlternationIndex)}" />
+                    <MenuItem Header="Rename"
+                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.RenameLayerCommand, 
+                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
+                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
+                                Path=(ItemsControl.AlternationIndex)}" />
+                    <MenuItem Header="Move to front"
+                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.MoveToFrontCommand, 
+                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
+                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
+                                Path=(ItemsControl.AlternationIndex)}" />
+                    <MenuItem Header="Move to back"
+                                    Command="{Binding PlacementTarget.Tag.LayersViewModel.MoveToBackCommand, 
+                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
+                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
+                                Path=(ItemsControl.AlternationIndex)}" />
+                    <Separator/>
+                    <MenuItem Header="Merge selected"
+                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.MergeSelectedCommand, 
+                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
+                    <MenuItem Header="Merge with above"
+                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.MergeWithAboveCommand, 
+                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
+                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
+                                Path=(ItemsControl.AlternationIndex)}" />
+                    <MenuItem Header="Merge with below"
+                                    Command="{Binding PlacementTarget.Tag.LayersViewModel.MergeWithBelowCommand, 
+                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
+                                    CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
+                                Path=(ItemsControl.AlternationIndex)}" />
+                </ContextMenu>
+            </vws:LayerItem.ContextMenu>
+        </vws:LayerItem>
+    </Grid>
+</UserControl>

+ 44 - 0
PixiEditor/Views/UserControls/LayerStructureItemContainer.xaml.cs

@@ -0,0 +1,44 @@
+using PixiEditor.Models.Layers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace PixiEditor.Views.UserControls
+{
+    /// <summary>
+    /// Interaction logic for LayerStructureItemContainer.xaml
+    /// </summary>
+    public partial class LayerStructureItemContainer : UserControl
+    {
+
+        public LayerStructureItem Item
+        {
+            get { return (LayerStructureItem)GetValue(ItemProperty); }
+            set { SetValue(ItemProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty ItemProperty =
+            DependencyProperty.Register(
+                "Item",
+                typeof(LayerStructureItem),
+                typeof(LayerStructureItemContainer),
+                new PropertyMetadata(default(LayerStructureItem)));
+
+        public LayerStructureItemContainer()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 10 - 51
PixiEditor/Views/UserControls/LayersManager.xaml

@@ -6,7 +6,7 @@
              xmlns:ui="clr-namespace:PixiEditor.Helpers.UI"
              xmlns:local="clr-namespace:PixiEditor.Views.UserControls"
              xmlns:vws="clr-namespace:PixiEditor.Views" 
-             xmlns:main="clr-namespace:PixiEditor.ViewModels.SubViewModels.Main" 
+             xmlns:layers="clr-namespace:PixiEditor.Models.Layers"
              xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters" 
              d:DataContext="{d:DesignInstance Type=local:LayersManager}"
              mc:Ignorable="d"
@@ -14,6 +14,7 @@
     <UserControl.Resources>
         <converters:NotNullToBoolConverter x:Key="NotNullToBoolConverter" />
         <converters:FloatNormalizeConverter x:Key="FloatNormalizeConverter" />
+        <converters:LayersToStructuredLayersConverter x:Key="LayersToStructuredLayersConverter"/>
     </UserControl.Resources>
     <Grid>
         <Grid.RowDefinitions>
@@ -40,8 +41,13 @@
         <Separator Grid.Row="2" Background="{StaticResource BrighterAccentColor}"/>
         <ScrollViewer Grid.Row="3" VerticalScrollBarVisibility="Auto">
             <ItemsControl DataContext="{Binding ElementName=uc}" 
-                          ItemsSource="{Binding BitmapManager.ActiveDocument.Layers, ElementName=uc}"
-                          x:Name="layersItemsControl" AlternationCount="9999">
+                          x:Name="layersItemsControl" AlternationCount="9999" d:DataContext="{x:Type layers:LayerStructureItem}">
+                <ItemsControl.ItemsSource>
+                    <MultiBinding Converter="{StaticResource LayersToStructuredLayersConverter}">
+                        <Binding Path="BitmapManager.ActiveDocument.Layers" ElementName="uc"/>
+                        <Binding Path="BitmapManager.ActiveDocument.LayerStructure" ElementName="uc"/>
+                    </MultiBinding>
+                </ItemsControl.ItemsSource>
                 <ItemsControl.ItemsPanel>
                     <ItemsPanelTemplate>
                         <ui:ReversedOrderStackPanel Orientation="Vertical" />
@@ -49,54 +55,7 @@
                 </ItemsControl.ItemsPanel>
                 <ItemsControl.ItemTemplate>
                     <DataTemplate>
-                        <vws:LayerItem Tag="{Binding Path=DataContext, ElementName=layersItemsControl}" 
-                                       LayerIndex="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
-                                Path=(ItemsControl.AlternationIndex)}" 
-                                       SetActiveLayerCommand="{Binding DataContext.LayersViewModel.SetActiveLayerCommand, ElementName=layersItemsControl}"
-                                       LayerName="{Binding Name, Mode=TwoWay}" IsActive="{Binding IsActive, Mode=TwoWay}"
-                                       IsRenaming="{Binding IsRenaming, Mode=TwoWay}"
-                                       PreviewImage="{Binding LayerBitmap}"
-                                      MoveToBackCommand="{Binding DataContext.LayersViewModel.MoveToBackCommand, ElementName=layersItemsControl}"
-                                      MoveToFrontCommand="{Binding DataContext.LayersViewModel.MoveToFrontCommand, ElementName=layersItemsControl}">
-                            <vws:LayerItem.ContextMenu>
-                                <ContextMenu>
-                                    <MenuItem Header="Delete"
-                                         Command="{Binding PlacementTarget.Tag.LayersViewModel.DeleteLayersCommand, 
-                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
-                                         CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
-                                Path=(ItemsControl.AlternationIndex)}" />
-                                    <MenuItem Header="Rename"
-                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.RenameLayerCommand, 
-                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
-                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
-                                Path=(ItemsControl.AlternationIndex)}" />
-                                    <MenuItem Header="Move to front"
-                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.MoveToFrontCommand, 
-                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
-                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
-                                Path=(ItemsControl.AlternationIndex)}" />
-                                    <MenuItem Header="Move to back"
-                                    Command="{Binding PlacementTarget.Tag.LayersViewModel.MoveToBackCommand, 
-                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
-                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
-                                Path=(ItemsControl.AlternationIndex)}" />
-                                    <Separator/>
-                                    <MenuItem Header="Merge selected"
-                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.MergeSelectedCommand, 
-                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
-                                    <MenuItem Header="Merge with above"
-                                     Command="{Binding PlacementTarget.Tag.LayersViewModel.MergeWithAboveCommand, 
-                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
-                                     CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
-                                Path=(ItemsControl.AlternationIndex)}" />
-                                    <MenuItem Header="Merge with below"
-                                    Command="{Binding PlacementTarget.Tag.LayersViewModel.MergeWithBelowCommand, 
-                                            RelativeSource={RelativeSource AncestorType=ContextMenu}}"
-                                    CommandParameter="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},
-                                Path=(ItemsControl.AlternationIndex)}" />
-                                </ContextMenu>
-                            </vws:LayerItem.ContextMenu>
-                        </vws:LayerItem>
+                        
                     </DataTemplate>
                 </ItemsControl.ItemTemplate>
             </ItemsControl>