Browse Source

Group IsVisible WIP

flabbet 4 years ago
parent
commit
6b65248ed0

+ 47 - 0
PixiEditor/Helpers/Converters/FinalIsVisibleToVisiblityConverter.cs

@@ -0,0 +1,47 @@
+using PixiEditor.Models.Layers;
+using PixiEditor.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Data;
+using System.Windows.Markup;
+
+namespace PixiEditor.Helpers.Converters
+{
+    public class FinalIsVisibleToVisiblityConverter : MarkupExtension, IMultiValueConverter
+    {
+        private static FinalIsVisibleToVisiblityConverter converter = null;
+
+        public override object ProvideValue(IServiceProvider serviceProvider)
+        {
+            if (converter == null)
+            {
+                converter = new FinalIsVisibleToVisiblityConverter();
+            }
+
+            return converter;
+        }
+
+        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (values[0] is Layer layer)
+            {
+                if (ViewModelMain.Current?.BitmapManager?.ActiveDocument != null)
+                {
+                    return ViewModelMain.Current.BitmapManager.ActiveDocument.GetFinalLayerIsVisible(layer) ? Visibility.Visible : Visibility.Collapsed;
+                }
+            }
+
+            return Visibility.Visible;
+        }
+
+        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+    }
+}

+ 1 - 1
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -136,7 +136,7 @@ namespace PixiEditor.Models.Controllers
 
 
         public WriteableBitmap GetCombinedLayersBitmap()
         public WriteableBitmap GetCombinedLayersBitmap()
         {
         {
-            return BitmapUtils.CombineLayers(ActiveDocument.Width, ActiveDocument.Height, ActiveDocument.Layers.Where(x => x.IsVisible).ToArray());
+            return BitmapUtils.CombineLayers(ActiveDocument.Width, ActiveDocument.Height, ActiveDocument.Layers.Where(x => ActiveDocument.GetFinalLayerIsVisible(x)).ToArray());
         }
         }
 
 
         /// <summary>
         /// <summary>

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

@@ -77,6 +77,35 @@ namespace PixiEditor.Models.DataHolders
             LayersChanged?.Invoke(this, new LayersChangedEventArgs(ActiveLayerGuid, LayerAction.SetActive));
             LayersChanged?.Invoke(this, new LayersChangedEventArgs(ActiveLayerGuid, LayerAction.SetActive));
         }
         }
 
 
+        /// <summary>
+        /// Gets final layer IsVisible taking into consideration group visibility.
+        /// </summary>
+        /// <param name="layer">Layer to check.</param>
+        /// <returns>True if is visible, false if at least parent is not visible or layer itself is invisible</returns>
+        public bool GetFinalLayerIsVisible(Layer layer)
+        {
+            if (!layer.IsVisible)
+            {
+                return false;
+            }
+
+            var group = LayerStructure.GetGroupByLayer(layer.LayerGuid);
+            bool atLeastOneParentIsInvisible = false;
+            GuidStructureItem groupToCheck = group;
+            while(groupToCheck != null)
+            {
+                if (!groupToCheck.IsVisible)
+                {
+                    atLeastOneParentIsInvisible = true;
+                    break;
+                }
+
+                groupToCheck = groupToCheck.Parent;
+            }
+
+            return !atLeastOneParentIsInvisible;
+        }
+
         public void UpdateLayersColor()
         public void UpdateLayersColor()
         {
         {
             foreach (var layer in Layers)
             foreach (var layer in Layers)

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

@@ -195,7 +195,7 @@ namespace PixiEditor.Models.DataHolders
         /// </summary>
         /// </summary>
         public void CenterContent()
         public void CenterContent()
         {
         {
-            var layersToCenter = Layers.Where(x => x.IsActive && x.IsVisible);
+            var layersToCenter = Layers.Where(x => x.IsActive && GetFinalLayerIsVisible(x));
             if (!layersToCenter.Any())
             if (!layersToCenter.Any())
             {
             {
                 return;
                 return;

+ 5 - 0
PixiEditor/Models/Layers/Layer.cs

@@ -232,6 +232,11 @@ namespace PixiEditor.Models.Layers
             };
             };
         }
         }
 
 
+        public void RaisePropertyChange(string property)
+        {
+            RaisePropertyChanged(property);
+        }
+
         /// <summary>
         /// <summary>
         ///     Resizes bitmap with it's content using NearestNeighbor interpolation.
         ///     Resizes bitmap with it's content using NearestNeighbor interpolation.
         /// </summary>
         /// </summary>

+ 4 - 4
PixiEditor/Models/Tools/Tools/MoveTool.cs

@@ -107,7 +107,8 @@ namespace PixiEditor.Models.Tools.Tools
             ResetSelectionValues(startPos);
             ResetSelectionValues(startPos);
 
 
             // Move offset if no selection
             // Move offset if no selection
-            Selection selection = ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection;
+            var doc = ViewModelMain.Current.BitmapManager.ActiveDocument;
+            Selection selection = doc.ActiveSelection;
             if (selection != null && selection.SelectedPoints.Count > 0)
             if (selection != null && selection.SelectedPoints.Count > 0)
             {
             {
                 currentSelection = selection.SelectedPoints.ToArray();
                 currentSelection = selection.SelectedPoints.ToArray();
@@ -119,13 +120,12 @@ namespace PixiEditor.Models.Tools.Tools
 
 
             if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
             if (Keyboard.IsKeyDown(Key.LeftCtrl) || MoveAll)
             {
             {
-                affectedLayers = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.Where(x => x.IsVisible)
+                affectedLayers = doc.Layers.Where(x => x.IsVisible)
                     .ToArray();
                     .ToArray();
             }
             }
             else
             else
             {
             {
-                affectedLayers = ViewModelMain.Current.BitmapManager.ActiveDocument
-                    .Layers.Where(x => x.IsActive && x.IsVisible).ToArray();
+                affectedLayers = doc.Layers.Where(x => x.IsActive && doc.GetFinalLayerIsVisible(x)).ToArray();
             }
             }
 
 
             startSelection = currentSelection;
             startSelection = currentSelection;

+ 5 - 4
PixiEditor/ViewModels/SubViewModels/Main/ClipboardViewModel.cs

@@ -55,11 +55,12 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
 
         private void Copy(object parameter)
         private void Copy(object parameter)
         {
         {
+            var doc = Owner.BitmapManager.ActiveDocument;
             ClipboardController.CopyToClipboard(
             ClipboardController.CopyToClipboard(
-                Owner.BitmapManager.ActiveDocument.Layers.Where(x => x.IsActive && x.IsVisible).ToArray(),
-                Owner.BitmapManager.ActiveDocument.ActiveSelection.SelectedPoints.ToArray(),
-                Owner.BitmapManager.ActiveDocument.Width,
-                Owner.BitmapManager.ActiveDocument.Height);
+                doc.Layers.Where(x => x.IsActive && doc.GetFinalLayerIsVisible(x)).ToArray(),
+                doc.ActiveSelection.SelectedPoints.ToArray(),
+                doc.Width,
+                doc.Height);
         }
         }
     }
     }
 }
 }

+ 4 - 2
PixiEditor/ViewModels/SubViewModels/Main/DocumentViewModel.cs

@@ -47,14 +47,16 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
                     return;
                     return;
                 }
                 }
             }
             }
+
             Owner.BitmapManager.CloseDocument(document);
             Owner.BitmapManager.CloseDocument(document);
         }
         }
 
 
         private void DeletePixels(object parameter)
         private void DeletePixels(object parameter)
         {
         {
+            var doc = Owner.BitmapManager.ActiveDocument;
             Owner.BitmapManager.BitmapOperations.DeletePixels(
             Owner.BitmapManager.BitmapOperations.DeletePixels(
-                Owner.BitmapManager.ActiveDocument.Layers.Where(x => x.IsActive && x.IsVisible).ToArray(),
-                Owner.BitmapManager.ActiveDocument.ActiveSelection.SelectedPoints.ToArray());
+                doc.Layers.Where(x => x.IsActive && doc.GetFinalLayerIsVisible(x)).ToArray(),
+                doc.ActiveSelection.SelectedPoints.ToArray());
         }
         }
 
 
         private void OpenResizePopup(object parameter)
         private void OpenResizePopup(object parameter)

+ 8 - 2
PixiEditor/Views/UserControls/DrawingViewPort.xaml

@@ -66,10 +66,16 @@
                     <ItemsControl.ItemTemplate>
                     <ItemsControl.ItemTemplate>
                         <DataTemplate>
                         <DataTemplate>
                             <Image VerticalAlignment="Top" HorizontalAlignment="Left" Source="{Binding LayerBitmap}"
                             <Image VerticalAlignment="Top" HorizontalAlignment="Left" Source="{Binding LayerBitmap}"
-                                               Visibility="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"
                                                RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Uniform"
                                                RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Uniform"
                                                Opacity="{Binding Opacity}"
                                                Opacity="{Binding Opacity}"
-                                               Width="{Binding Width}" Height="{Binding Height}" Margin="{Binding Offset}" />
+                                               Width="{Binding Width}" Height="{Binding Height}" Margin="{Binding Offset}">
+                                <Image.Visibility>
+                                    <MultiBinding Converter="{converters:FinalIsVisibleToVisiblityConverter}">
+                                        <Binding Path="."/>
+                                        <Binding Path="IsVisible"/>
+                                    </MultiBinding>
+                                </Image.Visibility>
+                            </Image>
                         </DataTemplate>
                         </DataTemplate>
                     </ItemsControl.ItemTemplate>
                     </ItemsControl.ItemTemplate>
                 </ItemsControl>
                 </ItemsControl>

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

@@ -8,6 +8,7 @@
              d:DesignHeight="60" d:DesignWidth="250" Name="groupControl">
              d:DesignHeight="60" d:DesignWidth="250" Name="groupControl">
     <UserControl.Resources>
     <UserControl.Resources>
         <converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
         <converters:InverseBooleanConverter x:Key="InverseBooleanConverter"/>
+        <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
     </UserControl.Resources>
     </UserControl.Resources>
     <Border BorderThickness="0 0 0 0.5" BorderBrush="Gray" MinWidth="60" Focusable="True" Tag="{Binding ElementName=groupControl}" MouseDown="Border_MouseDown">
     <Border BorderThickness="0 0 0 0.5" BorderBrush="Gray" MinWidth="60" Focusable="True" Tag="{Binding ElementName=groupControl}" MouseDown="Border_MouseDown">
         <i:Interaction.Behaviors>
         <i:Interaction.Behaviors>
@@ -27,7 +28,7 @@
                 </Grid.ColumnDefinitions>
                 </Grid.ColumnDefinitions>
                 <CheckBox Style="{StaticResource ImageCheckBox}" VerticalAlignment="Center"
                 <CheckBox Style="{StaticResource ImageCheckBox}" VerticalAlignment="Center"
                       IsThreeState="False" HorizontalAlignment="Center" 
                       IsThreeState="False" HorizontalAlignment="Center" 
-                      IsChecked="{Binding Path=IsVisibleUndoTriggerable, Mode=TwoWay, ElementName=groupControl}" Grid.Column="0" Height="16"/>
+                      IsChecked="{Binding Path=IsVisibleUndoTriggerable, ElementName=groupControl}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"  Grid.Column="0" Height="16"/>
                 
                 
                 <StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Left">
                 <StackPanel Orientation="Horizontal" Grid.Column="1" HorizontalAlignment="Left">
                     <Rectangle Width="{Binding Path=(helpers:TreeViewItemHelper.Indent).Value, Mode=OneWay, RelativeSource={RelativeSource AncestorType=ItemsPresenter}}" Fill="Transparent" StrokeThickness="0"/>
                     <Rectangle Width="{Binding Path=(helpers:TreeViewItemHelper.Indent).Value, Mode=OneWay, RelativeSource={RelativeSource AncestorType=ItemsPresenter}}" Fill="Transparent" StrokeThickness="0"/>

+ 36 - 21
PixiEditor/Views/UserControls/LayerGroupControl.xaml.cs

@@ -48,27 +48,7 @@ namespace PixiEditor.Views.UserControls
 
 
         // Using a DependencyProperty as the backing store for IsVisibleUndoTriggerable.  This enables animation, styling, binding, etc...
         // Using a DependencyProperty as the backing store for IsVisibleUndoTriggerable.  This enables animation, styling, binding, etc...
         public static readonly DependencyProperty IsVisibleUndoTriggerableProperty =
         public static readonly DependencyProperty IsVisibleUndoTriggerableProperty =
-            DependencyProperty.Register("IsVisibleUndoTriggerable", typeof(bool), typeof(LayerGroupControl), new PropertyMetadata(true, IsVisibleChangedCallback));
-
-        private static void IsVisibleChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
-        {
-            LayerGroupControl control = (LayerGroupControl)d;
-            var doc = control.LayersViewModel.Owner.BitmapManager.ActiveDocument;
-            var layers = doc.LayerStructure.GetGroupLayers(control.GroupData);
-
-            foreach (var layer in layers)
-            {
-                layer.IsVisible = (bool)e.NewValue;
-            }
-
-            doc.UndoManager.AddUndoChange(
-                new Change(
-                    nameof(IsVisibleUndoTriggerable), 
-                    e.OldValue,
-                    e.NewValue,
-                    $"Change {control.GroupName} visibility",
-                    control), true);
-        }
+            DependencyProperty.Register("IsVisibleUndoTriggerable", typeof(bool), typeof(LayerGroupControl), new PropertyMetadata(true));
 
 
         private static void LayersViewModelCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
         private static void LayersViewModelCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
         {
@@ -223,5 +203,40 @@ namespace PixiEditor.Views.UserControls
             var doc = LayersViewModel.Owner.BitmapManager.ActiveDocument;
             var doc = LayersViewModel.Owner.BitmapManager.ActiveDocument;
             doc.SetMainActiveLayer(doc.Layers.IndexOf(doc.Layers.First(x => x.LayerGuid == GroupData.EndLayerGuid)));
             doc.SetMainActiveLayer(doc.Layers.IndexOf(doc.Layers.First(x => x.LayerGuid == GroupData.EndLayerGuid)));
         }
         }
+
+        private void CheckBox_Checked(object sender, RoutedEventArgs e)
+        {
+            HandleCheckboxChange(true);
+        }
+
+        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
+        {
+            HandleCheckboxChange(false);
+        }
+
+        private void HandleCheckboxChange(bool value)
+        {
+            if (LayersViewModel?.Owner?.BitmapManager?.ActiveDocument != null)
+            {
+                var doc = LayersViewModel.Owner.BitmapManager.ActiveDocument;
+
+                doc.LayerStructure.GetGroupByGuid(GroupGuid).IsVisible = value;
+
+                var layers = doc.LayerStructure.GetGroupLayers(GroupData);
+
+                foreach (var layer in layers)
+                {
+                    layer.RaisePropertyChange(nameof(layer.IsVisible));
+                }
+
+                doc.UndoManager.AddUndoChange(
+                new Change(
+                    nameof(IsVisibleUndoTriggerable),
+                    !value,
+                    value,
+                    $"Change {GroupName} visibility",
+                    this), true) //wip, doesn't work
+            }
+        }
     }
     }
 }
 }

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

@@ -66,7 +66,7 @@
                 </TreeView.ItemsPanel>
                 </TreeView.ItemsPanel>
                 <TreeView.Resources>
                 <TreeView.Resources>
                     <HierarchicalDataTemplate DataType="{x:Type layers:LayerGroup}" ItemsSource="{Binding Items}">
                     <HierarchicalDataTemplate DataType="{x:Type layers:LayerGroup}" ItemsSource="{Binding Items}">
-                        <local:LayerGroupControl GroupName="{Binding Name}" LayersViewModel="{Binding LayerCommandsViewModel, ElementName=layersManager}" GroupGuid="{Binding GroupGuid}" GroupData="{Binding StructureData}" MouseMove="LayerGroup_MouseMove"/>
+                    <local:LayerGroupControl GroupName="{Binding Name}" LayersViewModel="{Binding LayerCommandsViewModel, ElementName=layersManager}" GroupGuid="{Binding GroupGuid}" GroupData="{Binding StructureData}" MouseMove="LayerGroup_MouseMove"/>
                     </HierarchicalDataTemplate>
                     </HierarchicalDataTemplate>
                     <DataTemplate DataType="{x:Type layers:Layer}">
                     <DataTemplate DataType="{x:Type layers:Layer}">
                         <local:LayerStructureItemContainer                             
                         <local:LayerStructureItemContainer                             

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

@@ -1,4 +1,5 @@
-using System.Collections.ObjectModel;
+using System.Collections;
+using System.Collections.ObjectModel;
 using System.Windows;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Controls;
 using PixiEditor.ViewModels.SubViewModels.Main;
 using PixiEditor.ViewModels.SubViewModels.Main;