Equbuxu 4 年 前
コミット
decfb2c11b

+ 9 - 0
Custom.ruleset

@@ -1,14 +1,23 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RuleSet Name="Name" Description="Description" ToolsVersion="16.0">
+  <Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp" RuleNamespace="Microsoft.CodeAnalysis.CSharp">
+    <Rule Id="AD0001" Action="None" />
+  </Rules>
   <Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp.Features" RuleNamespace="Microsoft.CodeAnalysis.CSharp.Features">
     <Rule Id="IDE0090" Action="None" />
   </Rules>
+  <Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.CodeAnalysis.NetAnalyzers">
+    <Rule Id="CA1416" Action="None" />
+  </Rules>
   <Rules AnalyzerId="Microsoft.NetCore.Analyzers" RuleNamespace="Microsoft.NetCore.Analyzers">
     <Rule Id="CA1303" Action="None" />
+    <Rule Id="CA1416" Action="None" />
   </Rules>
   <Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
     <Rule Id="SA0001" Action="None" />
     <Rule Id="SA1000" Action="None" />
+    <Rule Id="SA1008" Action="None" />
+    <Rule Id="SA1009" Action="None" />
     <Rule Id="SA1101" Action="None" />
     <Rule Id="SA1110" Action="None" />
     <Rule Id="SA1111" Action="None" />

+ 20 - 20
PixiEditor/Helpers/Converters/LayerStructureToGroupsConverter.cs

@@ -1,16 +1,31 @@
-using System;
+using PixiEditor.Helpers.Extensions;
+using PixiEditor.Models.Layers;
+using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Globalization;
 using System.Linq;
 using System.Windows.Data;
-using PixiEditor.Helpers.Extensions;
-using PixiEditor.Models.Layers;
 
 namespace PixiEditor.Helpers.Converters
 {
     public class LayerStructureToGroupsConverter : IMultiValueConverter
     {
+        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (values[0] is LayerStructure structure)
+            {
+                return GetSubGroups(structure.Groups);
+            }
+
+            return Binding.DoNothing;
+        }
+
+        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+        {
+            throw new NotImplementedException();
+        }
+
         private ObservableCollection<GuidStructureItem> GetSubGroups(IEnumerable<GuidStructureItem> groups)
         {
             ObservableCollection<GuidStructureItem> finalGroups = new ObservableCollection<GuidStructureItem>();
@@ -29,7 +44,7 @@ namespace PixiEditor.Helpers.Converters
             foreach (var subGroup in group.Subgroups)
             {
                 groups.Add(subGroup);
-                if(subGroup.Subgroups.Count > 0)
+                if (subGroup.Subgroups.Count > 0)
                 {
                     groups.AddRange(GetSubGroups(subGroup));
                 }
@@ -37,20 +52,5 @@ namespace PixiEditor.Helpers.Converters
 
             return groups.Distinct();
         }
-
-        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
-        {
-            if (values[0] is LayerStructure structure)
-            {
-                return GetSubGroups(structure.Groups);
-            }
-
-            return Binding.DoNothing;
-        }
-
-        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
-        {
-            throw new NotImplementedException();
-        }
     }
-}
+}

+ 9 - 13
PixiEditor/Helpers/Converters/LayersToStructuredLayersConverter.cs

@@ -1,15 +1,14 @@
-using System;
+using PixiEditor.Models.Layers;
+using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
-using System.Diagnostics;
 using System.Globalization;
 using System.Linq;
 using System.Windows.Data;
-using PixiEditor.Models.Layers;
 
 namespace PixiEditor.Helpers.Converters
 {
-    //TODO: Implement rebuilding only changed items instead whole tree
+    // TODO: Implement rebuilding only changed items instead whole tree
     public class LayersToStructuredLayersConverter : IMultiValueConverter
     {
         private static StructuredLayerTree cachedTree;
@@ -38,13 +37,15 @@ namespace PixiEditor.Helpers.Converters
 
             return new StructuredLayerTree(null, null);
         }
-
+        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
+        {
+            throw new ArgumentException("Value is not a StructuredLayerTree");
+        }
         private bool LayerOrderIsDifferent(IList<Layer> layers)
         {
             var guids = layers.Select(x => x.LayerGuid).ToArray();
             return !guids.SequenceEqual(lastLayers);
         }
-
         private bool TryFindStructureDifferences(LayerStructure structure)
         {
             bool structureModified = false;
@@ -59,7 +60,7 @@ namespace PixiEditor.Helpers.Converters
             {
                 var matchingGroup = structure.Groups.FirstOrDefault(x => x.GroupGuid == treeItem.GroupGuid);
                 List<GuidStructureItem> changedGroups = new List<GuidStructureItem>();
-                if(matchingGroup == null || StructureMismatch(treeItem, matchingGroup))
+                if (matchingGroup == null || StructureMismatch(treeItem, matchingGroup))
                 {
                     structureModified = true;
                 }
@@ -85,10 +86,5 @@ namespace PixiEditor.Helpers.Converters
             }
             return rootMismatch;
         }
-
-        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
-        {
-            throw new ArgumentException("Value is not a StructuredLayerTree");
-        }
     }
-}
+}

+ 37 - 37
PixiEditor/Helpers/Extensions/ParserHelpers.cs

@@ -1,14 +1,14 @@
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.ImageManipulation;
 using PixiEditor.Models.Layers;
+using PixiEditor.Parser;
+using PixiEditor.Parser.Models;
+using System;
 using System.Collections.ObjectModel;
 using System.Linq;
 using System.Windows;
 using System.Windows.Media;
-using PixiEditor.Parser;
 using SDColor = System.Drawing.Color;
-using PixiEditor.Parser.Models;
-using System;
 
 namespace PixiEditor.Helpers.Extensions
 {
@@ -38,39 +38,6 @@ namespace PixiEditor.Helpers.Extensions
             return ToGroups(serializableDocument.Groups);
         }
 
-        private static ObservableCollection<GuidStructureItem> ToGroups(SerializableGuidStructureItem[] serializableGroups, GuidStructureItem parent = null)
-        {
-            ObservableCollection<GuidStructureItem> groups = new ObservableCollection<GuidStructureItem>();
-
-            if (serializableGroups == null)
-            {
-                return groups;
-            }
-
-            foreach (var serializableGroup in serializableGroups)
-            {
-                groups.Add(ToGroup(serializableGroup, parent));
-            }
-            return groups;
-        }
-
-        private static GuidStructureItem ToGroup(SerializableGuidStructureItem group, GuidStructureItem parent = null)
-        {
-            if (group == null)
-            {
-                return null;
-            }
-            var parsedGroup = new GuidStructureItem(
-                group.Name,
-                group.StartLayerGuid,
-                group.EndLayerGuid,
-                new ObservableCollection<GuidStructureItem>(),
-                parent)
-            { Opacity = group.Opacity, IsVisible = group.IsVisible, GroupGuid = group.GroupGuid, IsExpanded = true };
-            parsedGroup.Subgroups = ToGroups(group.Subgroups, parsedGroup);
-            return parsedGroup;
-        }
-
         public static ObservableCollection<Layer> ToLayers(this SerializableDocument serializableDocument)
         {
             ObservableCollection<Layer> layers = new ObservableCollection<Layer>();
@@ -140,6 +107,39 @@ namespace PixiEditor.Helpers.Extensions
             };
 
             return serializable;
+        }
+
+        private static ObservableCollection<GuidStructureItem> ToGroups(SerializableGuidStructureItem[] serializableGroups, GuidStructureItem parent = null)
+        {
+            ObservableCollection<GuidStructureItem> groups = new ObservableCollection<GuidStructureItem>();
+
+            if (serializableGroups == null)
+            {
+                return groups;
+            }
+
+            foreach (var serializableGroup in serializableGroups)
+            {
+                groups.Add(ToGroup(serializableGroup, parent));
+            }
+            return groups;
+        }
+
+        private static GuidStructureItem ToGroup(SerializableGuidStructureItem group, GuidStructureItem parent = null)
+        {
+            if (group == null)
+            {
+                return null;
+            }
+            var parsedGroup = new GuidStructureItem(
+                group.Name,
+                group.StartLayerGuid,
+                group.EndLayerGuid,
+                new ObservableCollection<GuidStructureItem>(),
+                parent)
+            { Opacity = group.Opacity, IsVisible = group.IsVisible, GroupGuid = group.GroupGuid, IsExpanded = true };
+            parsedGroup.Subgroups = ToGroups(group.Subgroups, parsedGroup);
+            return parsedGroup;
         }
     }
-}
+}

+ 21 - 20
PixiEditor/Models/Controllers/ClipboardController.cs

@@ -51,25 +51,6 @@ namespace PixiEditor.Models.Controllers
             }
         }
 
-        private static void RemoveLayerProcess(object[] parameters)
-        {
-            if (parameters.Length == 0 || !(parameters[0] is int))
-            {
-                return;
-            }
-
-            ViewModelMain.Current.BitmapManager.ActiveDocument.RemoveLayer((int)parameters[0], true);
-        }
-
-        private static void AddLayerProcess(object[] parameters)
-        {
-            if (parameters.Length == 0 || !(parameters[0] is WriteableBitmap))
-            {
-                return;
-            }
-
-            AddImageToLayers((WriteableBitmap)parameters[0]);
-        }
 
         /// <summary>
         ///     Gets image from clipboard, supported PNG, Dib and Bitmap.
@@ -123,9 +104,29 @@ namespace PixiEditor.Models.Controllers
             return bitmap.Crop(offsetX, offsetY, width, height);
         }
 
+        private static void RemoveLayerProcess(object[] parameters)
+        {
+            if (parameters.Length == 0 || !(parameters[0] is int))
+            {
+                return;
+            }
+
+            ViewModelMain.Current.BitmapManager.ActiveDocument.RemoveLayer((int)parameters[0], true);
+        }
+
+        private static void AddLayerProcess(object[] parameters)
+        {
+            if (parameters.Length == 0 || !(parameters[0] is WriteableBitmap))
+            {
+                return;
+            }
+
+            AddImageToLayers((WriteableBitmap)parameters[0]);
+        }
+
         private static void AddImageToLayers(WriteableBitmap image)
         {
             ViewModelMain.Current.BitmapManager.ActiveDocument.AddNewLayer("Image", image);
         }
     }
-}
+}

+ 20 - 21
PixiEditor/Models/DataHolders/Document/Document.Layers.cs

@@ -1,4 +1,11 @@
-using System;
+using PixiEditor.Helpers;
+using PixiEditor.Models.Controllers;
+using PixiEditor.Models.Enums;
+using PixiEditor.Models.ImageManipulation;
+using PixiEditor.Models.Layers;
+using PixiEditor.Models.Position;
+using PixiEditor.Models.Undo;
+using System;
 using System.Buffers;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
@@ -7,14 +14,6 @@ using System.Text.RegularExpressions;
 using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media.Imaging;
-using PixiEditor.Helpers;
-using PixiEditor.Models.Controllers;
-using PixiEditor.Models.Enums;
-using PixiEditor.Models.ImageManipulation;
-using PixiEditor.Models.Layers;
-using PixiEditor.Models.Layers.Utils;
-using PixiEditor.Models.Position;
-using PixiEditor.Models.Undo;
 
 namespace PixiEditor.Models.DataHolders
 {
@@ -22,11 +21,11 @@ namespace PixiEditor.Models.DataHolders
     {
         public const string MainSelectedLayerColor = "#505056";
         public const string SecondarySelectedLayerColor = "#7D505056";
-        private static readonly Regex reversedLayerSuffixRegex = new (@"(?:\)([0-9]+)*\()? *([\s\S]+)", RegexOptions.Compiled);
+        private static readonly Regex reversedLayerSuffixRegex = new(@"(?:\)([0-9]+)*\()? *([\s\S]+)", RegexOptions.Compiled);
         private Guid activeLayerGuid;
         private LayerStructure layerStructure;
 
-        private ObservableCollection<Layer> layers = new ();
+        private ObservableCollection<Layer> layers = new();
 
         public ObservableCollection<Layer> Layers
         {
@@ -101,7 +100,7 @@ namespace PixiEditor.Models.DataHolders
             var group = LayerStructure.GetGroupByLayer(layer.LayerGuid);
             bool atLeastOneParentIsInvisible = false;
             GuidStructureItem groupToCheck = group;
-            while(groupToCheck != null)
+            while (groupToCheck != null)
             {
                 if (!groupToCheck.IsVisible)
                 {
@@ -165,7 +164,7 @@ namespace PixiEditor.Models.DataHolders
             Guid oldReferenceLayerGuid;
             bool oldAbove = false;
 
-            if(indexOfTopLayer + 1 < Layers.Count)
+            if (indexOfTopLayer + 1 < Layers.Count)
             {
                 oldReferenceLayerGuid = topLayer.LayerGuid;
             }
@@ -247,7 +246,7 @@ namespace PixiEditor.Models.DataHolders
             Layers.Insert(index + 1, duplicate);
             SetMainActiveLayer(index + 1);
 
-            StorageBasedChange storageChange = new (this, new[] { duplicate }, false);
+            StorageBasedChange storageChange = new(this, new[] { duplicate }, false);
             UndoManager.AddUndoChange(
                 storageChange.ToChange(
                     RemoveLayerProcess,
@@ -480,9 +479,14 @@ namespace PixiEditor.Models.DataHolders
             return layer;
         }
 
+        public Color GetColorAtPoint(int x, int y)
+        {
+            return BitmapUtils.GetColorAtPointCombined(x, y, Layers.ToArray());
+        }
+
         private void BuildLayerStructureProcess(object[] parameters)
         {
-            if(parameters.Length > 0 && parameters[0] is ObservableCollection<GuidStructureItem> groups)
+            if (parameters.Length > 0 && parameters[0] is ObservableCollection<GuidStructureItem> groups)
             {
                 LayerStructure.Groups.CollectionChanged -= Groups_CollectionChanged;
                 LayerStructure.Groups = LayerStructure.CloneGroups(groups);
@@ -511,11 +515,6 @@ namespace PixiEditor.Models.DataHolders
             RaisePropertyChanged(nameof(LayerStructure));
         }
 
-        public Color GetColorAtPoint(int x, int y)
-        {
-            return BitmapUtils.GetColorAtPointCombined(x, y, Layers.ToArray());
-        }
-
         private void InjectRemoveActiveLayersUndo(object[] guidArgs, StorageBasedChange change)
         {
             Action<Layer[], UndoLayer[]> undoAction = RestoreLayersProcess;
@@ -819,4 +818,4 @@ namespace PixiEditor.Models.DataHolders
             }
         }
     }
-}
+}

+ 6 - 10
PixiEditor/Models/DataHolders/Document/Document.Operations.cs

@@ -1,14 +1,10 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using PixiEditor.Helpers.Extensions;
+using PixiEditor.Helpers.Extensions;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Undo;
+using System;
+using System.Linq;
+using System.Windows;
 
 namespace PixiEditor.Models.DataHolders
 {
@@ -101,7 +97,7 @@ namespace PixiEditor.Models.DataHolders
 
         private void ResizeDocumentProcess(object[] args)
         {
-            if (args.Length > 1 && args[0] is int width && args[1] is int height) 
+            if (args.Length > 1 && args[0] is int width && args[1] is int height)
             {
                 ResizeDocument(width, height);
             }
@@ -142,4 +138,4 @@ namespace PixiEditor.Models.DataHolders
             DocumentSizeChanged?.Invoke(this, new DocumentSizeChangedEventArgs(oldWidth, oldHeight, width, height));
         }
     }
-}
+}

+ 0 - 26
PixiEditor/Models/IO/BinarySerialization.cs

@@ -1,26 +0,0 @@
-using System.IO;
-using System.Runtime.Serialization.Formatters.Binary;
-
-namespace PixiEditor.Models.IO
-{
-    public static class BinarySerialization
-    {
-        public static void WriteToBinaryFile<T>(string path, T objectToWrite)
-        {
-            using (Stream stream = File.Open(path, FileMode.Create))
-            {
-                BinaryFormatter binaryFormatter = new BinaryFormatter();
-                binaryFormatter.Serialize(stream, objectToWrite);
-            }
-        }
-
-        public static T ReadFromBinaryFile<T>(string path)
-        {
-            using (Stream stream = File.Open(path, FileMode.Open))
-            {
-                BinaryFormatter formatter = new BinaryFormatter();
-                return (T)formatter.Deserialize(stream);
-            }
-        }
-    }
-}

+ 32 - 35
PixiEditor/Models/Layers/LayerStructure.cs

@@ -1,9 +1,8 @@
-using System;
+using PixiEditor.Models.DataHolders;
+using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Linq;
-using PixiEditor.Helpers;
-using PixiEditor.Models.DataHolders;
 
 namespace PixiEditor.Models.Layers
 {
@@ -50,16 +49,6 @@ namespace PixiEditor.Models.Layers
             return outputGroups;
         }
 
-        /// <summary>
-        /// Finds <see cref="GuidStructureItem"/> (Group) by it's guid.
-        /// </summary>
-        /// <param name="groupGuid">Guid of group.</param>
-        /// <returns><see cref="GuidStructureItem"/> if group was found or null if not.</returns>
-        public GuidStructureItem GetGroupByGuid(Guid? groupGuid)
-        {
-            return GetGroupByGuid(groupGuid, Groups);
-        }
-
         /// <summary>
         ///  Finds parent group by layer guid.
         /// </summary>
@@ -70,6 +59,16 @@ namespace PixiEditor.Models.Layers
             return GetGroupByLayer(layerGuid, Groups);
         }
 
+        /// <summary>
+        /// Finds <see cref="GuidStructureItem"/> (Group) by it's guid.
+        /// </summary>
+        /// <param name="groupGuid">Guid of group.</param>
+        /// <returns><see cref="GuidStructureItem"/> if group was found or null if not.</returns>
+        public GuidStructureItem GetGroupByGuid(Guid? groupGuid)
+        {
+            return GetGroupByGuid(groupGuid, Groups);
+        }
+
         public ObservableCollection<GuidStructureItem> CloneGroups()
         {
             return CloneGroups(Groups);
@@ -166,7 +165,6 @@ namespace PixiEditor.Models.Layers
             return group;
         }
 
-#nullable enable
         /// <summary>
         /// Moves group and it's children from one index to another. This method makes changes in <see cref="Document"/> Layers.
         /// </summary>
@@ -208,7 +206,7 @@ namespace PixiEditor.Models.Layers
         /// <param name="group">Group to check.</param>
         /// <param name="parent">Parent of that group.</param>
         /// <returns>True if group is nested inside parent, false if not.</returns>
-        public bool IsChildOf(GuidStructureItem? group, GuidStructureItem parent)
+        public bool IsChildOf(GuidStructureItem group, GuidStructureItem parent)
         {
             if (group == null)
             {
@@ -374,6 +372,17 @@ namespace PixiEditor.Models.Layers
             }
         }
 
+        private static Guid GetNextLayerGuid(Guid layer, List<Guid> allLayers, bool above)
+        {
+            int indexOfLayer = allLayers.IndexOf(layer);
+
+            int modifier = above ? 1 : -1;
+
+            int newIndex = Math.Clamp(indexOfLayer + modifier, 0, allLayers.Count - 1);
+
+            return allLayers[newIndex];
+        }
+
         /// <summary>
         /// Gets all layers inside group, including nested groups.
         /// </summary>
@@ -381,10 +390,10 @@ namespace PixiEditor.Models.Layers
         /// <returns>List of layer guids.</returns>
         private List<Guid> GetGroupLayerGuids(GuidStructureItem group)
         {
-            Layer? layerTop = Owner.Layers.FirstOrDefault(x => x.LayerGuid == group.EndLayerGuid);
-            Layer? layerBottom = Owner.Layers.FirstOrDefault(x => x.LayerGuid == group.StartLayerGuid);
+            Layer layerTop = Owner.Layers.FirstOrDefault(x => x.LayerGuid == group.EndLayerGuid);
+            Layer layerBottom = Owner.Layers.FirstOrDefault(x => x.LayerGuid == group.StartLayerGuid);
 
-            if(layerTop == null || layerBottom == null)
+            if (layerTop == null || layerBottom == null)
             {
                 return new List<Guid>();
             }
@@ -409,7 +418,7 @@ namespace PixiEditor.Models.Layers
             return layerGuids;
         }
 
-        private void PreMoveReassignBounds(GuidStructureItem? parentGroup, Guid layer)
+        private void PreMoveReassignBounds(GuidStructureItem parentGroup, Guid layer)
         {
             if (parentGroup != null)
             {
@@ -441,7 +450,7 @@ namespace PixiEditor.Models.Layers
             }
         }
 
-        private void PreMoveReassignBounds(GuidStructureItem? parentGroup, GuidStructureItem group)
+        private void PreMoveReassignBounds(GuidStructureItem parentGroup, GuidStructureItem group)
         {
             if (parentGroup != null)
             {
@@ -472,7 +481,7 @@ namespace PixiEditor.Models.Layers
             }
         }
 
-        private void PostMoveReassignBounds(GuidStructureItem? parentGroup, Guid layerGuid)
+        private void PostMoveReassignBounds(GuidStructureItem parentGroup, Guid layerGuid)
         {
             if (parentGroup != null)
             {
@@ -520,7 +529,7 @@ namespace PixiEditor.Models.Layers
             }
         }
 
-        private void PostMoveReassignBounds(GuidStructureItem? parentGroup, GuidStructureItem group)
+        private void PostMoveReassignBounds(GuidStructureItem parentGroup, GuidStructureItem group)
         {
             if (parentGroup != null)
             {
@@ -555,7 +564,7 @@ namespace PixiEditor.Models.Layers
             }
         }
 
-        private void AssignParent(Guid layer, GuidStructureItem? parent)
+        private void AssignParent(Guid layer, GuidStructureItem parent)
         {
             var currentParent = GetGroupByLayer(layer);
             if (currentParent != null)
@@ -636,17 +645,6 @@ namespace PixiEditor.Models.Layers
             return FindBoundLayer(layerGuid, parentFolderTopIndex, parentFolderBottomIndex, above);
         }
 
-        private static Guid GetNextLayerGuid(Guid layer, List<Guid> allLayers, bool above)
-        {
-            int indexOfLayer = allLayers.IndexOf(layer);
-
-            int modifier = above ? 1 : -1;
-
-            int newIndex = Math.Clamp(indexOfLayer + modifier, 0, allLayers.Count - 1);
-
-            return allLayers[newIndex];
-        }
-
         private void MoveLayersInGroup(List<Guid> layers, int moveBy, bool reverseOrder)
         {
             List<Guid> layerGuids = reverseOrder ? layers.Reverse<Guid>().ToList() : layers;
@@ -660,7 +658,6 @@ namespace PixiEditor.Models.Layers
             }
         }
 
-#nullable disable
         private GuidStructureItem GetGroupByLayer(Guid layerGuid, IEnumerable<GuidStructureItem> groups)
         {
             foreach (var currentGroup in groups)

+ 9 - 14
PixiEditor/Models/Layers/StructuredLayerTree.cs

@@ -13,6 +13,13 @@ namespace PixiEditor.Models.Layers
 
         public ObservableCollection<object> RootDirectoryItems { get; } = new ObservableCollection<object>();
 
+        private static void Swap(ref int startIndex, ref int endIndex)
+        {
+            int tmp = startIndex;
+            startIndex = endIndex;
+            endIndex = tmp;
+        }
+
         public StructuredLayerTree(ObservableCollection<Layer> layers, LayerStructure structure)
         {
             if (layers == null || structure == null)
@@ -128,7 +135,7 @@ namespace PixiEditor.Models.Layers
         {
             List<Layer> structureItemLayers = new();
 
-            Guid[] layersInFolder = GetLayersInFolder(layers, structureItem);
+            Guid[] layersInFolder = GetLayersInGroup(layers, structureItem);
 
             var subFolders = new List<LayerGroup>();
 
@@ -163,13 +170,8 @@ namespace PixiEditor.Models.Layers
             return folder;
         }
 
-        private Guid[] GetLayersInFolder(ObservableCollection<Layer> layers, GuidStructureItem structureItem)
+        private Guid[] GetLayersInGroup(ObservableCollection<Layer> layers, GuidStructureItem structureItem)
         {
-            if (structureItem.EndLayerGuid == null || structureItem.StartLayerGuid == null)
-            {
-                return Array.Empty<Guid>();
-            }
-
             var startLayer = layers.FirstOrDefault(x => x.LayerGuid == structureItem.StartLayerGuid);
             var endLayer = layers.FirstOrDefault(x => x.LayerGuid == structureItem.EndLayerGuid);
 
@@ -197,12 +199,5 @@ namespace PixiEditor.Models.Layers
 
             return guids;
         }
-
-        private static void Swap(ref int startIndex, ref int endIndex)
-        {
-            int tmp = startIndex;
-            startIndex = endIndex;
-            endIndex = tmp;
-        }
     }
 }

+ 28 - 28
PixiEditor/Models/Tools/ShapeTool.cs

@@ -1,39 +1,16 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Windows.Input;
-using System.Windows.Media;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Input;
+using System.Windows.Media;
 
 namespace PixiEditor.Models.Tools
 {
     public abstract class ShapeTool : BitmapOperationTool
     {
-        public ShapeTool()
-        {
-            RequiresPreviewLayer = true;
-            Cursor = Cursors.Cross;
-            Toolbar = new BasicShapeToolbar();
-        }
-
-        // TODO: Add cache for lines 31, 32 (hopefully it would speed up calculation)
-        public abstract override LayerChange[] Use(Layer layer, List<Coordinates> coordinates, Color color);
-
-        protected IEnumerable<Coordinates> GetThickShape(IEnumerable<Coordinates> shape, int thickness)
-        {
-            List<Coordinates> output = new List<Coordinates>();
-            foreach (Coordinates item in shape)
-            {
-                output.AddRange(
-                    CoordinatesCalculator.RectangleToCoordinates(
-                        CoordinatesCalculator.CalculateThicknessCenter(item, thickness)));
-            }
-
-            return output.Distinct();
-        }
-
         public static DoubleCords CalculateCoordinatesForShapeRotation(
             Coordinates startingCords,
             Coordinates secondCoordinates)
@@ -70,5 +47,28 @@ namespace PixiEditor.Models.Tools
 
             return new DoubleCords(startingCords, secondCoordinates);
         }
+
+        public ShapeTool()
+        {
+            RequiresPreviewLayer = true;
+            Cursor = Cursors.Cross;
+            Toolbar = new BasicShapeToolbar();
+        }
+
+        // TODO: Add cache for lines 31, 32 (hopefully it would speed up calculation)
+        public abstract override LayerChange[] Use(Layer layer, List<Coordinates> coordinates, Color color);
+
+        protected IEnumerable<Coordinates> GetThickShape(IEnumerable<Coordinates> shape, int thickness)
+        {
+            List<Coordinates> output = new List<Coordinates>();
+            foreach (Coordinates item in shape)
+            {
+                output.AddRange(
+                    CoordinatesCalculator.RectangleToCoordinates(
+                        CoordinatesCalculator.CalculateThicknessCenter(item, thickness)));
+            }
+
+            return output.Distinct();
+        }
     }
-}
+}

+ 6 - 8
PixiEditor/Models/Undo/StorageBasedChange.cs

@@ -1,13 +1,11 @@
-using System;
-using System.Buffers.Text;
+using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.IO;
+using PixiEditor.Models.Layers;
+using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
-using Newtonsoft.Json;
-using PixiEditor.Models.DataHolders;
-using PixiEditor.Models.IO;
-using PixiEditor.Models.Layers;
 
 namespace PixiEditor.Models.Undo
 {
@@ -90,7 +88,7 @@ namespace PixiEditor.Models.Undo
                     IsActive = storedLayer.IsActive,
                     Width = storedLayer.Width,
                     Height = storedLayer.Height,
-                    LayerHighlightColor = storedLayer.LayerHighlightColor                    
+                    LayerHighlightColor = storedLayer.LayerHighlightColor
                 };
                 layers[i].ChangeGuid(storedLayer.LayerGuid);
 
@@ -232,4 +230,4 @@ namespace PixiEditor.Models.Undo
             }
         }
     }
-}
+}

+ 4 - 1
PixiEditor/PixiEditor.csproj

@@ -147,10 +147,13 @@
     <PackageReference Include="DiscordRichPresence" Version="1.0.175" />
     <PackageReference Include="Expression.Blend.Sdk">
       <Version>1.0.2</Version>
+      <NoWarn>NU1701</NoWarn>
     </PackageReference>
     <PackageReference Include="Extended.Wpf.Toolkit" Version="3.8.2" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
-    <PackageReference Include="MvvmLightLibs" Version="5.4.1.1" />
+    <PackageReference Include="MvvmLightLibs" Version="5.4.1.1">
+      <NoWarn>NU1701</NoWarn>
+    </PackageReference>
     <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
     <PackageReference Include="PixiEditor.ColorPicker" Version="3.1.0" />
     <PackageReference Include="PixiEditor.Parser" Version="1.1.3.1" />

+ 0 - 1
PixiEditor/ViewModels/SaveFilePopupViewModel.cs

@@ -69,7 +69,6 @@ namespace PixiEditor.ViewModels
         /// <summary>
         ///     Command that handles Path choosing to save file
         /// </summary>
-        /// <param name="parameter"></param>
         private void ChoosePath(object parameter)
         {
             SaveFileDialog path = new SaveFileDialog

+ 7 - 8
PixiEditor/ViewModels/SubViewModels/Main/LayersViewModel.cs

@@ -1,7 +1,6 @@
 using PixiEditor.Helpers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Layers;
-using PixiEditor.Views;
 using PixiEditor.Views.UserControls;
 using System;
 using System.Linq;
@@ -64,16 +63,16 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
         public void CreateGroupFromActiveLayers(object parameter)
         {
-            //var doc = Owner.BitmapManager.ActiveDocument;
-            //if (doc != null)
-            //{
+            // var doc = Owner.BitmapManager.ActiveDocument;
+            // if (doc != null)
+            // {
             //    doc.LayerStructure.AddNewGroup($"{Owner.BitmapManager.ActiveLayer.Name} Group", doc.Layers.Where(x => x.IsActive).Reverse(), Owner.BitmapManager.ActiveDocument.ActiveLayerGuid);
-            //}
+            // }
         }
 
         public bool CanDeleteSelected(object parameter)
         {
-            return (parameter is not null and(Layer or LayerGroup)) || (Owner.BitmapManager?.ActiveDocument?.ActiveLayer != null);
+            return (parameter is not null and (Layer or LayerGroup)) || (Owner.BitmapManager?.ActiveDocument?.ActiveLayer != null);
         }
 
         public void DeleteSelected(object parameter)
@@ -82,7 +81,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             {
                 DeleteLayer(Owner.BitmapManager.ActiveDocument.Layers.IndexOf(layer));
             }
-            else if(parameter is LayerStructureItemContainer container)
+            else if (parameter is LayerStructureItemContainer container)
             {
                 DeleteLayer(Owner.BitmapManager.ActiveDocument.Layers.IndexOf(container.Layer));
             }
@@ -137,7 +136,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
                     Owner.BitmapManager.ActiveDocument.LayerStructure.ExpandParentGroups(group);
                 }
-                else if(control != null)
+                else if (control != null)
                 {
                     doc.LayerStructure.AddNewGroup($"{control.Name} Group", control);
                 }

+ 10 - 11
PixiEditor/ViewModels/ViewModelMain.cs

@@ -235,6 +235,15 @@ namespace PixiEditor.ViewModels
         {
             return BitmapManager.ActiveDocument != null;
         }
+        public void CloseWindow(object property)
+        {
+            if (!(property is CancelEventArgs))
+            {
+                throw new ArgumentException();
+            }
+
+            ((CancelEventArgs)property).Cancel = !RemoveDocumentsWithSaveConfirmation();
+        }
 
         [Conditional("DEBUG")]
         private void AddDebugOnlyViewModels()
@@ -259,16 +268,6 @@ namespace PixiEditor.ViewModels
             return new Shortcut(key, ToolsSubViewModel.SelectToolCommand, description, typeof(T), modifier);
         }
 
-        public void CloseWindow(object property)
-        {
-            if (!(property is CancelEventArgs))
-            {
-                throw new ArgumentException();
-            }
-
-            ((CancelEventArgs)property).Cancel = !RemoveDocumentsWithSaveConfirmation();
-        }
-
         /// <summary>
         /// Removes documents with unsaved changes confirmation dialog.
         /// </summary>
@@ -355,4 +354,4 @@ namespace PixiEditor.ViewModels
             }
         }
     }
-}
+}

+ 1 - 2
PixiEditor/Views/Dialogs/HelloTherePopup.xaml.cs

@@ -1,7 +1,6 @@
 using PixiEditor.Helpers;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.ViewModels.SubViewModels.Main;
-using System.Reflection;
 using System.Windows;
 using System.Windows.Input;
 
@@ -20,7 +19,7 @@ namespace PixiEditor.Views.Dialogs
         public static readonly DependencyProperty RecentlyOpenedEmptyProperty =
             DependencyProperty.Register(nameof(RecentlyOpenedEmpty), typeof(bool), typeof(HelloTherePopup));
 
-        public static string VersionText => 
+        public static string VersionText =>
             $"v{AssemblyHelper.GetCurrentAssemblyVersion(x => $"{x.Major}.{x.Minor}" + (x.Build != 0 ? $".{x.Build}" : ""))}";
 
         public FileViewModel FileViewModel { get => (FileViewModel)GetValue(FileViewModelProperty); set => SetValue(FileViewModelProperty, value); }

+ 1 - 1
PixiEditor/Views/UserControls/PreviewWindow.xaml.cs

@@ -18,7 +18,7 @@ namespace PixiEditor.Views.UserControls
             DependencyProperty.Register(nameof(Document), typeof(Document), typeof(PreviewWindow));
 
         public Document Document
-        { 
+        {
             get => (Document)GetValue(DocumentProperty);
             set => SetValue(DocumentProperty, value);
         }