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

Made Structured layers render correctly

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

+ 2 - 0
PixiEditor/Helpers/Behaviours/ClearFocusOnClickBehavior.cs

@@ -1,5 +1,6 @@
 using System.Windows;
 using System.Windows.Interactivity;
+using PixiEditor.Models.Controllers.Shortcuts;
 
 namespace PixiEditor.Helpers.Behaviours
 {
@@ -19,6 +20,7 @@ namespace PixiEditor.Helpers.Behaviours
         private void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
         {
             AssociatedObject.Focus();
+            ShortcutController.BlockShortcutExecution = false;
         }
     }
 }

+ 28 - 0
PixiEditor/Helpers/Converters/IndexOfConverter.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Data;
+
+namespace PixiEditor.Helpers.Converters
+{
+    public class IndexOfConverter : IMultiValueConverter
+    {
+        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            if (values[0] is int containerIndex && values[1] is int relativeIndex)
+            {
+                return containerIndex + relativeIndex;
+            }
+
+            return -1;
+        }
+
+        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
+        {
+            return targetTypes.Select(t => Binding.DoNothing).ToArray();
+        }
+    }
+}

+ 17 - 2
PixiEditor/Helpers/Converters/LayersToStructuredLayersConverter.cs

@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Globalization;
+using System.Linq;
 using System.Windows.Data;
 using PixiEditor.Models.Layers;
 
@@ -15,12 +17,25 @@ namespace PixiEditor.Helpers.Converters
                 return new StructuredLayerTree(layers, structure).Items;
             }
 
-            return new StructuredLayerTree();
+            return new StructuredLayerTree().Items;
         }
 
         public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
         {
-            throw new NotImplementedException();
+            if (value is ObservableCollection<LayerStructureItem> tree)
+            {
+                List<Layer> layers = new ();
+                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))));
+                }
+
+                return new object[] { layers, structure };
+            }
+
+            throw new ArgumentException("Value is not a StructuredLayerTree");
         }
     }
 }

+ 11 - 0
PixiEditor/Models/DataHolders/Document/Document.Constructors.cs

@@ -19,6 +19,17 @@ namespace PixiEditor.Models.DataHolders
             UndoManager = new UndoManager();
             XamlAccesibleViewModel = ViewModelMain.Current ?? null;
             GeneratePreviewLayer();
+            Layers.CollectionChanged += Layers_CollectionChanged;
+        }
+
+        ~Document()
+        {
+            Layers.CollectionChanged -= Layers_CollectionChanged;
+        }
+
+        private void Layers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+        {
+            RaisePropertyChanged(nameof(Layers));
         }
     }
 }

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

@@ -18,12 +18,21 @@ namespace PixiEditor.Models.DataHolders
         public const string MainSelectedLayerColor = "#505056";
         public const string SecondarySelectedLayerColor = "#7D505056";
         private Guid activeLayerGuid;
+        private LayerStructure layerStructure = new ();
 
         public ObservableCollection<Layer> Layers { get; set; } = new ObservableCollection<Layer>();
 
-        public LayerStructure LayerStructure { get; set; } = new LayerStructure();
+        public LayerStructure LayerStructure
+        {
+            get => layerStructure;
+            set
+            {
+                layerStructure = value;
+                RaisePropertyChanged(nameof(LayerStructure));
+            }
+        }
 
-        public Layer ActiveLayer => Layers.Count > 0 ? Layers[ActiveLayerIndex] : null;
+        public Layer ActiveLayer => Layers.Count > 0 ? Layers.FirstOrDefault(x => x.LayerGuid == ActiveLayerGuid) : null;
 
         public Guid ActiveLayerGuid
         {
@@ -119,7 +128,7 @@ namespace PixiEditor.Models.DataHolders
                         "Add layer"));
             }
 
-            LayersChanged?.Invoke(this, new LayersChangedEventArgs(Layers[0].LayerGuid, LayerAction.Add));
+            LayersChanged?.Invoke(this, new LayersChangedEventArgs(Layers[^1].LayerGuid, LayerAction.Add));
         }
 
         public void SetNextLayerAsActive(int lastLayerIndex)

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

@@ -34,7 +34,6 @@ namespace PixiEditor.Models.Layers
 
         public StructuredLayerTree()
         {
-            
         }
     }
 }

+ 19 - 7
PixiEditor/Views/MainWindow.xaml

@@ -11,10 +11,10 @@
         xmlns:cmd="http://www.galasoft.ch/mvvmlight" 
         xmlns:avalondock="https://github.com/Dirkster99/AvalonDock"
         xmlns:colorpicker="clr-namespace:ColorPicker;assembly=ColorPicker" xmlns:usercontrols="clr-namespace:PixiEditor.Views.UserControls" xmlns:behaviours="clr-namespace:PixiEditor.Helpers.Behaviours" 
-        xmlns:avalonDockTheme="clr-namespace:PixiEditor.Styles.AvalonDock"
+        xmlns:avalonDockTheme="clr-namespace:PixiEditor.Styles.AvalonDock" d:DataContext="{d:DesignInstance Type=vm:ViewModelMain}"
         mc:Ignorable="d" WindowStyle="None" Initialized="MainWindow_Initialized"
         Title="PixiEditor" Name="mainWindow" Height="1000" Width="1600" Background="{StaticResource MainColor}"
-        WindowStartupLocation="CenterScreen" WindowState="Maximized" DataContext="{DynamicResource ViewModelMain}">
+        WindowStartupLocation="CenterScreen" WindowState="Maximized">
     <WindowChrome.WindowChrome>
         <WindowChrome CaptionHeight="32"
                       ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
@@ -22,9 +22,10 @@
 
     <Window.Resources>
         <ResourceDictionary>
-            <vm:ViewModelMain x:Key="ViewModelMain" />
             <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
             <converters:BoolToIntConverter x:Key="BoolToIntConverter" />
+            <converters:NotNullToBoolConverter x:Key="NotNullToBoolConverter" />
+            <converters:LayersToStructuredLayersConverter x:Key="LayersToStructuredLayersConverter"/>
             <converters:DoubleToIntConverter x:Key="DoubleToIntConverter"/>
             <ResourceDictionary.MergedDictionaries>
                 <ResourceDictionary Source="pack://application:,,,/ColorPicker;component/Styles/DefaultColorPickerStyle.xaml" />
@@ -251,7 +252,7 @@
                                                 </ItemsControl.ItemsPanel>
                                                 <ItemsControl.ItemTemplate>
                                                     <DataTemplate>
-                                                        <Grid Width="45" Height="45" Margin="0 5 5 5">
+                                                        <Grid Width="45" Height="45" Margin="0 5 5 5" Tag="{Binding DataContext, ElementName=mainWindow}">
                                                             <Border CornerRadius="5.5" Width="44" Height="44">
                                                                 <Border.Background>
                                                                     <ImageBrush ImageSource="../Images/transparentbg.png"
@@ -279,7 +280,8 @@
                                                             <Grid.ContextMenu>
                                                                 <ContextMenu>
                                                                     <MenuItem Header="Remove" Foreground="White"
-                                                                      Command="{Binding ColorsSubViewModel.RemoveSwatchCommand, Source={StaticResource ViewModelMain}}"
+                                                                      Command="{Binding PlacementTarget.Tag.ColorsSubViewModel.RemoveSwatchCommand, 
+                                                                        RelativeSource={RelativeSource AncestorType=ContextMenu}}"
                                                                       CommandParameter="{Binding}" />
                                                                 </ContextMenu>
                                                             </Grid.ContextMenu>
@@ -294,8 +296,18 @@
                                     <LayoutAnchorable ContentId="layers" Title="Layers" CanHide="False"
                                                          CanClose="False" CanAutoHide="False"
                                                          CanDockAsTabbedDocument="True" CanFloat="True">
-                                        <usercontrols:LayersManager LayersViewModel="{Binding LayersSubViewModel}"
-                                                                    BitmapManager="{Binding BitmapManager}"/>
+                                        <usercontrols:LayersManager
+                                            LayerOpacity="{Binding BitmapManager.ActiveDocument.ActiveLayer.OpacityUndoTriggerable}"
+                                            LayerCommandsViewModel="{Binding LayersSubViewModel}"
+                                            OpacityInputEnabled="{Binding BitmapManager.ActiveDocument, 
+                    Converter={StaticResource NotNullToBoolConverter}}">
+                                            <usercontrols:LayersManager.StructuredLayers>
+                                                <MultiBinding Converter="{StaticResource LayersToStructuredLayersConverter}">
+                                                    <Binding Path="BitmapManager.ActiveDocument.Layers" />
+                                                    <Binding Path="BitmapManager.ActiveDocument.LayerStructure"/>
+                                                </MultiBinding>
+                                            </usercontrols:LayersManager.StructuredLayers>
+                                        </usercontrols:LayersManager>
                                     </LayoutAnchorable>
                                 </LayoutAnchorablePane>
                             </LayoutAnchorablePaneGroup>

+ 86 - 51
PixiEditor/Views/UserControls/LayerStructureItemContainer.xaml

@@ -4,70 +4,105 @@
              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" xmlns:ui="clr-namespace:PixiEditor.Helpers.UI"
+             xmlns:vws="clr-namespace:PixiEditor.Views" xmlns:ui="clr-namespace:PixiEditor.Helpers.UI" xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters"
              mc:Ignorable="d" 
-             d:DesignHeight="60" d:DesignWidth="250" Name="uc">
-    <Grid>
-        <ItemsControl Name="itemsControl" ItemsSource="{Binding Item.Children, ElementName=uc}">
+             d:DesignHeight="60" d:DesignWidth="250" Name="layerStructureContainer">
+    <UserControl.Resources>
+        <converters:IndexOfConverter x:Key="IndexOfConverter"/>
+    </UserControl.Resources>
+    <ItemsControl Name="itemsControl" ItemsSource="{Binding Item.Children, ElementName=layerStructureContainer}" AlternationCount="9999">
             <ItemsControl.ItemsPanel>
                 <ItemsPanelTemplate>
-                    <ui:ReversedOrderStackPanel Orientation="Vertical" />
+                    <ui:ReversedOrderStackPanel Orientation="Vertical"/>
                 </ItemsPanelTemplate>
             </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}"
+                <vws:LayerItem Tag="{Binding ElementName=layerStructureContainer}"
+                               SetActiveLayerCommand="{Binding LayerCommandsViewModel.SetActiveLayerCommand, ElementName=layerStructureContainer}"
                                        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, 
+                                       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"
+                                         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"
+                                     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"
+                                     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"
+                                    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"
+                                     Command="{Binding PlacementTarget.Tag.LayerCommandsViewModel.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>
+                            <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"
+                                    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>
                 </DataTemplate>
             </ItemsControl.ItemTemplate>
         </ItemsControl>
-    </Grid>
 </UserControl>

+ 22 - 14
PixiEditor/Views/UserControls/LayerStructureItemContainer.xaml.cs

@@ -1,18 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
+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.Models.Layers;
+using PixiEditor.ViewModels.SubViewModels.Main;
 
 namespace PixiEditor.Views.UserControls
 {
@@ -21,7 +10,6 @@ namespace PixiEditor.Views.UserControls
     /// </summary>
     public partial class LayerStructureItemContainer : UserControl
     {
-
         public LayerStructureItem Item
         {
             get { return (LayerStructureItem)GetValue(ItemProperty); }
@@ -36,6 +24,26 @@ namespace PixiEditor.Views.UserControls
                 typeof(LayerStructureItemContainer),
                 new PropertyMetadata(default(LayerStructureItem)));
 
+        public LayersViewModel LayerCommandsViewModel
+        {
+            get { return (LayersViewModel)GetValue(LayerCommandsViewModelProperty); }
+            set { SetValue(LayerCommandsViewModelProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty LayerCommandsViewModelProperty =
+            DependencyProperty.Register("LayerCommandsViewModel", typeof(LayersViewModel), typeof(LayerStructureItemContainer), new PropertyMetadata(default(LayersViewModel)));
+
+        public int ContainerIndex
+        {
+            get { return (int)GetValue(ContainerIndexProperty); }
+            set { SetValue(ContainerIndexProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for ContainerIndex.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty ContainerIndexProperty =
+            DependencyProperty.Register("ContainerIndex", typeof(int), typeof(LayerStructureItemContainer), new PropertyMetadata(0));
+
         public LayerStructureItemContainer()
         {
             InitializeComponent();

+ 9 - 18
PixiEditor/Views/UserControls/LayersManager.xaml

@@ -8,13 +8,10 @@
              xmlns:vws="clr-namespace:PixiEditor.Views" 
              xmlns:layers="clr-namespace:PixiEditor.Models.Layers"
              xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters" 
-             d:DataContext="{d:DesignInstance Type=local:LayersManager}"
              mc:Ignorable="d"
-             d:DesignHeight="450" d:DesignWidth="250" Name="uc">
+             d:DesignHeight="450" d:DesignWidth="250" Name="layersManager">
     <UserControl.Resources>
-        <converters:NotNullToBoolConverter x:Key="NotNullToBoolConverter" />
         <converters:FloatNormalizeConverter x:Key="FloatNormalizeConverter" />
-        <converters:LayersToStructuredLayersConverter x:Key="LayersToStructuredLayersConverter"/>
     </UserControl.Resources>
     <Grid>
         <Grid.RowDefinitions>
@@ -23,31 +20,24 @@
             <RowDefinition Height="15"/>
             <RowDefinition Height="1*"/>
         </Grid.RowDefinitions>
-        <Button Grid.Row="0" Command="{Binding LayersViewModel.NewLayerCommand, ElementName=uc}" Height="30" Content="New Layer"
+        <Button Grid.Row="0" Command="{Binding LayerCommandsViewModel.NewLayerCommand, ElementName=layersManager}" Height="30" Content="New Layer"
                                             HorizontalAlignment="Stretch" Margin="5"
                                             Style="{StaticResource DarkRoundButton}" />
         <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="10,0">
             <Label Content="Opacity" Foreground="White" VerticalAlignment="Center"/>
             <vws:NumberInput                                         
                     Min="0" Max="100"
-                    IsEnabled="{Binding Path=BitmapManager.ActiveDocument, 
-                    Converter={StaticResource NotNullToBoolConverter}, ElementName=uc}" 
+                    IsEnabled="{Binding Path=OpacityInputEnabled, ElementName=layersManager}" 
                     Width="40" Height="20"
                     VerticalAlignment="Center"
-                    Value="{Binding BitmapManager.ActiveDocument.ActiveLayer.OpacityUndoTriggerable, Mode=TwoWay, 
-                    Converter={StaticResource FloatNormalizeConverter}, ElementName=uc}" />
+                    Value="{Binding LayerOpacity, Mode=TwoWay, 
+                    Converter={StaticResource FloatNormalizeConverter}, ElementName=layersManager}" />
             <Label Content="%" Foreground="White" VerticalAlignment="Center"/>
         </StackPanel>
         <Separator Grid.Row="2" Background="{StaticResource BrighterAccentColor}"/>
         <ScrollViewer Grid.Row="3" VerticalScrollBarVisibility="Auto">
-            <ItemsControl DataContext="{Binding ElementName=uc}" 
-                          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 DataContext="{Binding ElementName=layersManager}"
+                          x:Name="layersItemsControl" AlternationCount="9999" ItemsSource="{Binding StructuredLayers}">
                 <ItemsControl.ItemsPanel>
                     <ItemsPanelTemplate>
                         <ui:ReversedOrderStackPanel Orientation="Vertical" />
@@ -55,7 +45,8 @@
                 </ItemsControl.ItemsPanel>
                 <ItemsControl.ItemTemplate>
                     <DataTemplate>
-                        <local:LayerStructureItemContainer Item="{Binding}"/>
+                        <local:LayerStructureItemContainer Item="{Binding}" ContainerIndex="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource TemplatedParent}}"
+                                                           LayerCommandsViewModel="{Binding LayerCommandsViewModel, ElementName=layersManager}"/>
                     </DataTemplate>
                 </ItemsControl.ItemTemplate>
             </ItemsControl>

+ 40 - 13
PixiEditor/Views/UserControls/LayersManager.xaml.cs

@@ -1,6 +1,9 @@
-using System.Windows;
+using System.Collections.ObjectModel;
+using System.Windows;
 using System.Windows.Controls;
+using GalaSoft.MvvmLight.Command;
 using PixiEditor.Models.Controllers;
+using PixiEditor.Models.Layers;
 using PixiEditor.ViewModels.SubViewModels.Main;
 
 namespace PixiEditor.Views.UserControls
@@ -10,25 +13,49 @@ namespace PixiEditor.Views.UserControls
     /// </summary>
     public partial class LayersManager : UserControl
     {
-        public LayersViewModel LayersViewModel
+        public ObservableCollection<LayerStructureItem> StructuredLayers
         {
-            get { return (LayersViewModel)GetValue(LayersViewModelProperty); }
-            set { SetValue(LayersViewModelProperty, value); }
+            get { return (ObservableCollection<LayerStructureItem>)GetValue(StructuredLayersProperty); }
+            set { SetValue(StructuredLayersProperty, value); }
         }
 
-        // Using a DependencyProperty as the backing store for LayersViewModel.  This enables animation, styling, binding, etc...
-        public static readonly DependencyProperty LayersViewModelProperty =
-            DependencyProperty.Register("LayersViewModel", typeof(LayersViewModel), typeof(LayersManager), new PropertyMetadata(default(LayersViewModel)));
+        // Using a DependencyProperty as the backing store for StructuredLayers.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty StructuredLayersProperty =
+            DependencyProperty.Register(
+                "StructuredLayers",
+                typeof(ObservableCollection<LayerStructureItem>),
+                typeof(LayersManager),
+                new PropertyMetadata(default(ObservableCollection<LayerStructureItem>)));
 
-        public BitmapManager BitmapManager
+        public float LayerOpacity
         {
-            get { return (BitmapManager)GetValue(BitmapManagerProperty); }
-            set { SetValue(BitmapManagerProperty, value); }
+            get { return (float)GetValue(LayerOpacityProperty); }
+            set { SetValue(LayerOpacityProperty, value); }
         }
 
-        // Using a DependencyProperty as the backing store for BitmapManager.  This enables animation, styling, binding, etc...
-        public static readonly DependencyProperty BitmapManagerProperty =
-            DependencyProperty.Register("BitmapManager", typeof(BitmapManager), typeof(LayersManager), new PropertyMetadata(default(BitmapManager)));
+        // Using a DependencyProperty as the backing store for LayerOpacity.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty LayerOpacityProperty =
+            DependencyProperty.Register("LayerOpacity", typeof(float), typeof(LayersManager), new PropertyMetadata(0f));
+
+        public LayersViewModel LayerCommandsViewModel
+        {
+            get { return (LayersViewModel)GetValue(LayerCommandsViewModelProperty); }
+            set { SetValue(LayerCommandsViewModelProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for LayerCommandsViewModel.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty LayerCommandsViewModelProperty =
+            DependencyProperty.Register("LayerCommandsViewModel", typeof(LayersViewModel), typeof(LayersManager), new PropertyMetadata(default(LayersViewModel)));
+      
+        public bool OpacityInputEnabled
+        {
+            get { return (bool)GetValue(OpacityInputEnabledProperty); }
+            set { SetValue(OpacityInputEnabledProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for OpacityInputEnabled.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty OpacityInputEnabledProperty =
+            DependencyProperty.Register("OpacityInputEnabled", typeof(bool), typeof(LayersManager), new PropertyMetadata(false));
 
         public LayersManager()
         {