Ver código fonte

Added nested layers

flabbet 4 anos atrás
pai
commit
1c5c3bba09

+ 37 - 0
PixiEditor/Helpers/Converters/ILayerContainerToLayersConverter.cs

@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Windows.Data;
+using PixiEditor.Models.Layers;
+
+namespace PixiEditor.Helpers.Converters
+{
+    public class ILayerContainerToLayersConverter : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            List<Layer> layers = new ();
+            if (value is IEnumerable<ILayerContainer> items)
+            {
+                foreach (var item in items)
+                {
+                    layers.AddRange(item.GetLayers());
+                }
+
+                return layers;
+            }
+            else if (value is Layer layer)
+            {
+                layers.Add(layer);
+                return layers;
+            }
+
+            return Binding.DoNothing;
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 35 - 0
PixiEditor/Helpers/Converters/LayersCountToVisiblityConverter.cs

@@ -0,0 +1,35 @@
+using System;
+using System.Globalization;
+using System.Linq;
+using System.Windows;
+using System.Windows.Data;
+using PixiEditor.Models.Layers;
+
+namespace PixiEditor.Helpers.Converters
+{
+    public class LayersCountToVisiblityConverter : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (value is ILayerContainer container)
+            {
+                bool moreThan = true;
+                if (parameter is string)
+                {
+                    moreThan = false;
+                }
+
+                int layersCount = container.GetLayers().Count();
+
+                return layersCount > 0 && (layersCount > 1 || (!moreThan && layersCount == 1)) ? Visibility.Visible : Visibility.Collapsed;
+            }
+
+            return Binding.DoNothing;
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 3 - 3
PixiEditor/Helpers/Converters/LayersToStructuredLayersConverter.cs

@@ -12,7 +12,7 @@ namespace PixiEditor.Helpers.Converters
     {
         public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
         {
-            if (values[0] is IEnumerable<Layer> layers && values[1] is LayerStructure structure)
+            if (values[0] is IEnumerable<ILayerContainer> layers && values[1] is LayerStructure structure)
             {
                 return new StructuredLayerTree(layers, structure).Items;
             }
@@ -28,8 +28,8 @@ namespace PixiEditor.Helpers.Converters
                 LayerStructure structure = new ();
                 foreach (var branchLayers in tree.Select(x => x.Children))
                 {
-                    layers.AddRange(branchLayers);
-                    structure.Items.Add(new GuidStructureItem(new ObservableCollection<Guid>(branchLayers.Select(x => x.LayerGuid))));
+                    //layers.AddRange(branchLayers);
+                    //structure.Items.Add(new GuidStructureItem(new ObservableCollection<Guid>(branchLayers.Select(x => x.LayerGuid))));
                 }
 
                 return new object[] { layers, structure };

+ 9 - 0
PixiEditor/Models/Layers/ILayerContainer.cs

@@ -0,0 +1,9 @@
+using System.Collections.Generic;
+
+namespace PixiEditor.Models.Layers
+{
+    public interface ILayerContainer
+    {
+        public IEnumerable<Layer> GetLayers();
+    }
+}

+ 6 - 1
PixiEditor/Models/Layers/Layer.cs

@@ -13,7 +13,7 @@ using PixiEditor.ViewModels;
 namespace PixiEditor.Models.Layers
 {
     [DebuggerDisplay("'{name,nq}' {width}x{height}")]
-    public class Layer : BasicLayer
+    public class Layer : BasicLayer, ILayerContainer
     {
         private const int SizeOfArgb = 4;
         private bool clipRequested;
@@ -209,6 +209,11 @@ namespace PixiEditor.Models.Layers
             LayerGuid = newGuid;
         }
 
+        public IEnumerable<Layer> GetLayers()
+        {
+            return new Layer[] { this };
+        }
+
         /// <summary>
         ///     Returns clone of layer.
         /// </summary>

+ 2 - 2
PixiEditor/Models/Layers/LayerStructureItem.cs

@@ -4,9 +4,9 @@ namespace PixiEditor.Models.Layers
 {
     public class LayerStructureItem
     {
-        public ObservableCollection<Layer> Children { get; set; } = new ObservableCollection<Layer>();
+        public ObservableCollection<ILayerContainer> Children { get; set; } = new ObservableCollection<ILayerContainer>();
 
-        public LayerStructureItem(ObservableCollection<Layer> children)
+        public LayerStructureItem(ObservableCollection<ILayerContainer> children)
         {
             Children = children;
         }

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

@@ -1,6 +1,7 @@
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
+using PixiEditor.Helpers.Extensions;
 
 namespace PixiEditor.Models.Layers
 {
@@ -8,13 +9,15 @@ namespace PixiEditor.Models.Layers
     {
         public ObservableCollection<LayerStructureItem> Items { get; set; } = new ObservableCollection<LayerStructureItem>();
 
-        public StructuredLayerTree(IEnumerable<Layer> layers, LayerStructure structure)
+        public StructuredLayerTree(IEnumerable<ILayerContainer> layers, LayerStructure structure)
         {
             if (structure == null || structure.Items.Count == 0)
             {
                 foreach (var layer in layers)
                 {
-                    Items.Add(new LayerStructureItem(new ObservableCollection<Layer> { layer }));
+                    var collection = new ObservableCollection<ILayerContainer>();
+                    collection.AddRange(layer.GetLayers());
+                    Items.Add(new LayerStructureItem(collection));
                 }
 
                 return;
@@ -22,10 +25,10 @@ namespace PixiEditor.Models.Layers
 
             for (int i = 0; i < structure.Items.Count; i++)
             {
-                var itemChildren = new ObservableCollection<Layer>();
+                var itemChildren = new ObservableCollection<ILayerContainer>();
                 foreach (var guid in structure.Items[i].Children)
                 {
-                    itemChildren.Add(layers.First(x => x.LayerGuid == guid));
+                    itemChildren.Add(layers.First(x => x.GetLayers().First(y => y.LayerGuid == guid).LayerGuid == guid));
                 }
 
                 Items.Add(new LayerStructureItem(itemChildren));

+ 1 - 1
PixiEditor/Views/UserControls/LayerItem.xaml

@@ -4,7 +4,7 @@
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:PixiEditor.Views"
-             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours"
+             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours" xmlns:layers="clr-namespace:PixiEditor.Models.Layers"
              mc:Ignorable="d" Focusable="True"
              d:DesignHeight="60" d:DesignWidth="250" Name="uc"
              MouseLeave="LayerItem_OnMouseLeave" MouseEnter="LayerItem_OnMouseEnter">

+ 1 - 5
PixiEditor/Views/UserControls/LayerItem.xaml.cs

@@ -1,14 +1,10 @@
-using System;
-using System.Collections.ObjectModel;
-using System.Windows;
+using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using PixiEditor.Helpers;
-using PixiEditor.Helpers.UI;
 using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.Layers;
 using PixiEditor.Views.UserControls;
 
 namespace PixiEditor.Views

+ 73 - 62
PixiEditor/Views/UserControls/LayerStructureItemContainer.xaml

@@ -9,6 +9,8 @@
              d:DesignHeight="60" d:DesignWidth="250" Name="layerStructureContainer">
     <UserControl.Resources>
         <converters:IndexOfConverter x:Key="IndexOfConverter"/>
+        <converters:LayersCountToVisiblityConverter x:Key="LayersCountToVisiblityConverter"/>
+        <converters:ILayerContainerToLayersConverter x:Key="ILayerContainerToLayersConverter"/>
     </UserControl.Resources>
     <ItemsControl Name="itemsControl" ItemsSource="{Binding Item.Children, ElementName=layerStructureContainer}" AlternationCount="9999">
             <ItemsControl.ItemsPanel>
@@ -18,7 +20,11 @@
             </ItemsControl.ItemsPanel>
             <ItemsControl.ItemTemplate>
             <DataTemplate>
-                <vws:LayerItem Tag="{Binding ElementName=layerStructureContainer}"
+                <Grid>
+                    <ItemsControl Visibility="{Binding Converter={StaticResource LayersCountToVisiblityConverter}, ConverterParameter='equalsOne'}" ItemsSource="{Binding Converter={StaticResource ILayerContainerToLayersConverter}}">
+                        <ItemsControl.ItemTemplate>
+                            <DataTemplate>
+                                <vws:LayerItem Tag="{Binding ElementName=layerStructureContainer}"
                                SetActiveLayerCommand="{Binding LayerCommandsViewModel.SetActiveLayerCommand, ElementName=layerStructureContainer}"
                                        LayerName="{Binding Name, Mode=TwoWay}" 
                                        IsActive="{Binding IsActive, Mode=TwoWay}"
@@ -27,81 +33,86 @@
                                        LayerColor="{Binding LayerHighlightColor}"
                                       MoveToBackCommand="{Binding LayerCommandsViewModel.MoveToBackCommand, ElementName=layerStructureContainer}"
                                       MoveToFrontCommand="{Binding LayerCommandsViewModel.MoveToFrontCommand, ElementName=layerStructureContainer}">
-                    <vws:LayerItem.LayerIndex>
-                        <MultiBinding Converter="{StaticResource IndexOfConverter}">
-                            <Binding Path="ContainerIndex" ElementName="layerStructureContainer" />
-                            <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
-                        </MultiBinding>
-                    </vws:LayerItem.LayerIndex>
-                    <vws:LayerItem.ContextMenu>
-                        <ContextMenu>
-                            <MenuItem Header="Delete"
+                                    <vws:LayerItem.LayerIndex>
+                                        <MultiBinding Converter="{StaticResource IndexOfConverter}">
+                                            <Binding Path="ContainerIndex" ElementName="layerStructureContainer" />
+                                            <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
+                                        </MultiBinding>
+                                    </vws:LayerItem.LayerIndex>
+                                    <vws:LayerItem.ContextMenu>
+                                        <ContextMenu>
+                                            <MenuItem Header="Delete"
                                          Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.DeleteLayersCommand, 
                                             RelativeSource={RelativeSource AncestorType=ContextMenu}}">
-                                <MenuItem.CommandParameter>
-                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
-                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
-                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
-                                    </MultiBinding>
-                                </MenuItem.CommandParameter>
-                            </MenuItem>
-                            <MenuItem Header="Rename"
+                                                <MenuItem.CommandParameter>
+                                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
+                                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
+                                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
+                                                    </MultiBinding>
+                                                </MenuItem.CommandParameter>
+                                            </MenuItem>
+                                            <MenuItem Header="Rename"
                                      Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.RenameLayerCommand, 
                                             RelativeSource={RelativeSource AncestorType=ContextMenu}}">
-                                <MenuItem.CommandParameter>
-                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
-                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
-                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
-                                    </MultiBinding>
-                                </MenuItem.CommandParameter>
-                            </MenuItem>
-                            <MenuItem Header="Move to front"
+                                                <MenuItem.CommandParameter>
+                                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
+                                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
+                                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
+                                                    </MultiBinding>
+                                                </MenuItem.CommandParameter>
+                                            </MenuItem>
+                                            <MenuItem Header="Move to front"
                                      Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.MoveToFrontCommand, 
                                             RelativeSource={RelativeSource AncestorType=ContextMenu}}">
-                                <MenuItem.CommandParameter>
-                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
-                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
-                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
-                                    </MultiBinding>
-                                </MenuItem.CommandParameter>
-                            </MenuItem>
-                            <MenuItem Header="Move to back"
+                                                <MenuItem.CommandParameter>
+                                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
+                                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
+                                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
+                                                    </MultiBinding>
+                                                </MenuItem.CommandParameter>
+                                            </MenuItem>
+                                            <MenuItem Header="Move to back"
                                     Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.MoveToBackCommand, 
                                             RelativeSource={RelativeSource AncestorType=ContextMenu}}">
-                                <MenuItem.CommandParameter>
-                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
-                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
-                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
-                                    </MultiBinding>
-                                </MenuItem.CommandParameter>
-                            </MenuItem>
-                            <Separator/>
-                            <MenuItem Header="Merge selected"
+                                                <MenuItem.CommandParameter>
+                                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
+                                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
+                                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
+                                                    </MultiBinding>
+                                                </MenuItem.CommandParameter>
+                                            </MenuItem>
+                                            <Separator/>
+                                            <MenuItem Header="Merge selected"
                                      Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.MergeSelectedCommand, 
                                             RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
-                            <MenuItem Header="Merge with above"
+                                            <MenuItem Header="Merge with above"
                                      Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.MergeWithAboveCommand, 
                                             RelativeSource={RelativeSource AncestorType=ContextMenu}}">
-                                <MenuItem.CommandParameter>
-                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
-                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
-                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
-                                    </MultiBinding>
-                                </MenuItem.CommandParameter>
-                            </MenuItem>
-                            <MenuItem Header="Merge with below"
+                                                <MenuItem.CommandParameter>
+                                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
+                                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
+                                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
+                                                    </MultiBinding>
+                                                </MenuItem.CommandParameter>
+                                            </MenuItem>
+                                            <MenuItem Header="Merge with below"
                                     Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.MergeWithBelowCommand, 
                                             RelativeSource={RelativeSource AncestorType=ContextMenu}}">
-                                <MenuItem.CommandParameter>
-                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
-                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
-                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
-                                    </MultiBinding>
-                                </MenuItem.CommandParameter>
-                            </MenuItem>
-                        </ContextMenu>
-                    </vws:LayerItem.ContextMenu>
-                </vws:LayerItem>
+                                                <MenuItem.CommandParameter>
+                                                    <MultiBinding Converter="{StaticResource IndexOfConverter}">
+                                                        <Binding Path="PlacementTarget.Tag.ContainerIndex" RelativeSource="{RelativeSource AncestorType=ContextMenu}" />
+                                                        <Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource TemplatedParent}"/>
+                                                    </MultiBinding>
+                                                </MenuItem.CommandParameter>
+                                            </MenuItem>
+                                        </ContextMenu>
+                                    </vws:LayerItem.ContextMenu>
+                                </vws:LayerItem>
+                            </DataTemplate>
+                        </ItemsControl.ItemTemplate>
+                    </ItemsControl>
+                    <local:LayerStructureItemContainer Margin="20 0 0 0" Item="{Binding}" Visibility="{Binding Converter={StaticResource LayersCountToVisiblityConverter}}"/>
+                </Grid>
             </DataTemplate>
             </ItemsControl.ItemTemplate>
         </ItemsControl>