123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853 |
- using PixiEditor.Helpers;
- using PixiEditor.Models.Controllers;
- using PixiEditor.Models.Enums;
- using PixiEditor.Models.Layers;
- using PixiEditor.Models.Layers.Utils;
- using PixiEditor.Models.Position;
- using PixiEditor.Models.Undo;
- using SkiaSharp;
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Text.RegularExpressions;
- using System.Windows;
- namespace PixiEditor.Models.DataHolders
- {
- public partial class Document
- {
- public const string MainSelectedLayerColor = "#505056";
- public const string SecondarySelectedLayerColor = "#7D505056";
- private static readonly Regex reversedLayerSuffixRegex = new(@"(?:\)([0-9]+)*\()? *([\s\S]+)", RegexOptions.Compiled);
- private Guid activeLayerGuid;
- private LayerStructure layerStructure;
- private WpfObservableRangeCollection<Layer> layers = new();
- public WpfObservableRangeCollection<Layer> Layers
- {
- get => layers;
- set
- {
- layers = value;
- Layers.CollectionChanged += Layers_CollectionChanged;
- Renderer.SetNewLayersCollection(value);
- }
- }
- public LayerStructure LayerStructure
- {
- get => layerStructure;
- private set
- {
- layerStructure = value;
- RaisePropertyChanged(nameof(LayerStructure));
- }
- }
- private LayerStackRenderer renderer;
- public LayerStackRenderer Renderer
- {
- get => renderer;
- private set
- {
- renderer = value;
- RaisePropertyChanged(nameof(Renderer));
- }
- }
- private Layer referenceLayer;
- private SingleLayerRenderer referenceLayerRenderer;
- public Layer ReferenceLayer
- {
- get => referenceLayer;
- set
- {
- referenceLayer = value;
- referenceLayerRenderer?.Dispose();
- referenceLayerRenderer = referenceLayer == null ? null : new SingleLayerRenderer(referenceLayer, referenceLayer.Width, referenceLayer.Height);
- RaisePropertyChanged(nameof(ReferenceLayer));
- RaisePropertyChanged(nameof(ReferenceLayerRenderer));
- }
- }
- public SingleLayerRenderer ReferenceLayerRenderer
- {
- get => referenceLayerRenderer;
- }
- public Layer ActiveLayer => Layers.Count > 0 ? Layers.FirstOrDefault(x => x.LayerGuid == ActiveLayerGuid) : null;
- public Guid ActiveLayerGuid
- {
- get => activeLayerGuid;
- set
- {
- if (value != activeLayerGuid)
- {
- activeLayerGuid = value;
- RaisePropertyChanged(nameof(ActiveLayerGuid));
- RaisePropertyChanged(nameof(ActiveLayer));
- }
- }
- }
- public event EventHandler<LayersChangedEventArgs> LayersChanged;
- public void SetMainActiveLayer(int index)
- {
- if (ActiveLayer != null && Layers.IndexOf(ActiveLayer) <= Layers.Count - 1)
- {
- ActiveLayer.IsActive = false;
- }
- foreach (var layer in Layers)
- {
- if (layer.IsActive)
- {
- layer.IsActive = false;
- }
- }
- ActiveLayerGuid = Layers[index].LayerGuid;
- ActiveLayer.IsActive = true;
- 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) => LayerStructureUtils.GetFinalLayerIsVisible(layer, LayerStructure);
- public void UpdateLayersColor()
- {
- foreach (var layer in Layers)
- {
- if (layer.LayerGuid == ActiveLayerGuid)
- {
- layer.LayerHighlightColor = MainSelectedLayerColor;
- }
- else
- {
- layer.LayerHighlightColor = SecondarySelectedLayerColor;
- }
- }
- }
- public void MoveLayerInStructure(Guid layerGuid, Guid referenceLayer, bool above = false, bool addToUndo = true)
- {
- var args = new object[] { layerGuid, referenceLayer, above };
- Layer layer = Layers.First(x => x.LayerGuid == layerGuid);
- int oldIndex = Layers.IndexOf(layer);
- var oldLayerStrcutureGroups = LayerStructure.CloneGroups();
- MoveLayerInStructureProcess(args);
- AddLayerStructureToUndo(oldLayerStrcutureGroups);
- if (!addToUndo) return;
- UndoManager.AddUndoChange(new Change(
- ReverseMoveLayerInStructureProcess,
- new object[] { oldIndex, layerGuid },
- MoveLayerInStructureProcess,
- args,
- "Move layer"));
- UndoManager.SquashUndoChanges(2, "Move layer");
- }
- public void MoveGroupInStructure(Guid groupGuid, Guid referenceLayer, bool above = false)
- {
- var args = new object[] { groupGuid, referenceLayer, above };
- var topLayer = Layers.First(x => x.LayerGuid == LayerStructure.GetGroupByGuid(groupGuid).EndLayerGuid);
- var bottomLayer = Layers.First(x => x.LayerGuid == LayerStructure.GetGroupByGuid(groupGuid).StartLayerGuid);
- int indexOfTopLayer = Layers.IndexOf(topLayer);
- Guid oldReferenceLayerGuid;
- bool oldAbove = false;
- if (indexOfTopLayer + 1 < Layers.Count)
- {
- oldReferenceLayerGuid = topLayer.LayerGuid;
- }
- else
- {
- int indexOfBottomLayer = Layers.IndexOf(bottomLayer);
- oldReferenceLayerGuid = Layers[indexOfBottomLayer - 1].LayerGuid;
- oldAbove = true;
- }
- var oldLayerStructure = LayerStructure.CloneGroups();
- MoveGroupInStructureProcess(args);
- AddLayerStructureToUndo(oldLayerStructure);
- UndoManager.AddUndoChange(new Change(
- MoveGroupInStructureProcess,
- new object[] { groupGuid, oldReferenceLayerGuid, oldAbove },
- MoveGroupInStructureProcess,
- args));
- UndoManager.SquashUndoChanges(2, "Move group");
- }
- public void AddNewLayer(string name, Surface bitmap, bool setAsActive = true)
- {
- AddNewLayer(name, bitmap.Width, bitmap.Height, setAsActive, bitmap);
- }
- public void AddNewLayer(string name, bool setAsActive = true)
- {
- AddNewLayer(name, 1, 1, setAsActive);
- }
- public void AddNewLayer(string name, int width, int height, bool setAsActive = true, Surface bitmap = null)
- {
- Layer layer;
- if (bitmap != null)
- {
- if (width != bitmap.Width || height != bitmap.Height)
- throw new ArgumentException("Inconsistent width and height");
- }
- if (width <= 0 || height <= 0)
- throw new ArgumentException("Dimensions must be greater than 0");
- layer = bitmap == null ? new Layer(name, width, height) : new Layer(name, bitmap);
- layer.MaxHeight = Height;
- layer.MaxWidth = Width;
- Layers.Add(layer);
- layer.Name = GetLayerSuffix(layer);
- if (setAsActive)
- {
- SetMainActiveLayer(Layers.Count - 1);
- }
- if (Layers.Count > 1)
- {
- StorageBasedChange storageChange = new(this, new[] { Layers[^1] }, false);
- UndoManager.AddUndoChange(
- storageChange.ToChange(
- RemoveLayerProcess,
- new object[] { Layers[^1].LayerGuid },
- RestoreLayersProcess,
- "Add layer"));
- }
- LayersChanged?.Invoke(this, new LayersChangedEventArgs(Layers[^1].LayerGuid, LayerAction.Add));
- }
- /// <summary>
- /// Duplicates the layer at the <paramref name="index"/>.
- /// </summary>
- /// <param name="index">The index of the layer to duplicate.</param>
- /// <returns>The duplicate.</returns>
- public Layer DuplicateLayer(int index)
- {
- Layer duplicate = Layers[index].Clone(true);
- duplicate.Name = GetLayerSuffix(duplicate);
- Layers.Insert(index + 1, duplicate);
- SetMainActiveLayer(index + 1);
- StorageBasedChange storageChange = new(this, new[] { duplicate }, false);
- UndoManager.AddUndoChange(
- storageChange.ToChange(
- RemoveLayerProcess,
- new object[] { duplicate.LayerGuid },
- RestoreLayersProcess,
- "Duplicate Layer"));
- return duplicate;
- }
- public void SetNextLayerAsActive(int lastLayerIndex)
- {
- if (Layers.Count > 0)
- {
- if (lastLayerIndex == 0)
- {
- SetMainActiveLayer(0);
- }
- else
- {
- SetMainActiveLayer(lastLayerIndex - 1);
- }
- }
- }
- public void SetNextSelectedLayerAsActive(Guid lastLayerGuid)
- {
- var selectedLayers = Layers.Where(x => x.IsActive);
- foreach (var layer in selectedLayers)
- {
- if (layer.LayerGuid != lastLayerGuid)
- {
- ActiveLayerGuid = layer.LayerGuid;
- LayersChanged?.Invoke(this, new LayersChangedEventArgs(ActiveLayerGuid, LayerAction.SetActive));
- return;
- }
- }
- }
- public void ToggleLayer(int index)
- {
- if (index < Layers.Count && index >= 0)
- {
- Layer layer = Layers[index];
- if (layer.IsActive && Layers.Count(x => x.IsActive) == 1)
- {
- return;
- }
- if (ActiveLayerGuid == layer.LayerGuid)
- {
- SetNextSelectedLayerAsActive(layer.LayerGuid);
- }
- layer.IsActive = !layer.IsActive;
- }
- }
- /// <summary>
- /// Selects all layers between active layer and layer at given index.
- /// </summary>
- /// <param name="index">End of range index.</param>
- public void SelectLayersRange(int index)
- {
- DeselectAllExcept(ActiveLayer);
- int firstIndex = Layers.IndexOf(ActiveLayer);
- int startIndex = Math.Min(index, firstIndex);
- for (int i = startIndex; i <= startIndex + Math.Abs(index - firstIndex); i++)
- {
- Layers[i].IsActive = true;
- }
- }
- public void DeselectAllExcept(Layer exceptLayer)
- {
- foreach (var layer in Layers)
- {
- if (layer == exceptLayer)
- {
- continue;
- }
- layer.IsActive = false;
- }
- }
- public void RemoveLayer(int layerIndex, bool addToUndo = true)
- {
- if (Layers.Count == 0)
- {
- return;
- }
- LayerStructure.AssignParent(Layers[layerIndex].LayerGuid, null);
- bool wasActive = Layers[layerIndex].IsActive;
- if (addToUndo)
- {
- StorageBasedChange change = new(this, new[] { Layers[layerIndex] });
- UndoManager.AddUndoChange(
- change.ToChange(RestoreLayersProcess, RemoveLayerProcess, new object[] { Layers[layerIndex].LayerGuid }));
- }
- Layers.RemoveAt(layerIndex);
- if (wasActive)
- {
- SetNextLayerAsActive(layerIndex);
- }
- }
- public void RemoveLayer(Layer layer, bool addToUndo)
- {
- RemoveLayer(Layers.IndexOf(layer), addToUndo);
- }
- public void RemoveActiveLayers()
- {
- if (Layers.Count == 0 || !Layers.Any(x => x.IsActive))
- {
- return;
- }
- var oldLayerStructure = LayerStructure.CloneGroups();
- Layer[] layers = Layers.Where(x => x.IsActive).ToArray();
- int firstIndex = Layers.IndexOf(layers[0]);
- object[] guidArgs = new object[] { layers.Select(x => x.LayerGuid).ToArray() };
- StorageBasedChange change = new(this, layers);
- RemoveLayersProcess(guidArgs);
- AddLayerStructureToUndo(oldLayerStructure);
- InjectRemoveActiveLayersUndo(guidArgs, change);
- UndoManager.SquashUndoChanges(2, "Removed active layers");
- SetNextLayerAsActive(firstIndex);
- }
- public void AddLayerStructureToUndo(WpfObservableRangeCollection<GuidStructureItem> oldLayerStructureGroups)
- {
- UndoManager.AddUndoChange(
- new Change(
- BuildLayerStructureProcess,
- new object[] { oldLayerStructureGroups },
- BuildLayerStructureProcess,
- new object[] { LayerStructure.CloneGroups() }, "Reload LayerStructure"));
- }
- public Layer MergeLayers(Layer[] layersToMerge, bool nameOfLast, int index)
- {
- if (layersToMerge == null || layersToMerge.Length < 2)
- {
- throw new ArgumentException("Not enough layers were provided to merge. Minimum amount is 2");
- }
- string name;
- // Which name should be used
- if (nameOfLast)
- {
- name = layersToMerge[^1].Name;
- }
- else
- {
- name = layersToMerge[0].Name;
- }
- Layer mergedLayer = layersToMerge[0];
- var groupParent = LayerStructure.GetGroupByLayer(layersToMerge[^1].LayerGuid);
- Layer placeholderLayer = new("_placeholder");
- Layers.Insert(index, placeholderLayer);
- LayerStructure.AssignParent(placeholderLayer.LayerGuid, groupParent?.GroupGuid);
- for (int i = 0; i < layersToMerge.Length - 1; i++)
- {
- Layer firstLayer = mergedLayer;
- Layer secondLayer = layersToMerge[i + 1];
- mergedLayer = firstLayer.MergeWith(secondLayer, name, Width, Height);
- RemoveLayer(layersToMerge[i], false);
- }
- Layers.Insert(index, mergedLayer);
- LayerStructure.AssignParent(mergedLayer.LayerGuid, groupParent?.GroupGuid);
- RemoveLayer(placeholderLayer, false);
- RemoveLayer(layersToMerge[^1], false);
- SetMainActiveLayer(Layers.IndexOf(mergedLayer));
- return mergedLayer;
- }
- public Layer MergeLayers(Layer[] layersToMerge, bool nameIsLastLayers)
- {
- if (layersToMerge == null || layersToMerge.Length < 2)
- {
- throw new ArgumentException("Not enough layers were provided to merge. Minimum amount is 2");
- }
- IEnumerable<Layer> undoArgs = layersToMerge;
- var oldLayerStructure = LayerStructure.CloneGroups();
- StorageBasedChange undoChange = new(this, undoArgs);
- int[] indexes = layersToMerge.Select(x => Layers.IndexOf(x)).ToArray();
- var layer = MergeLayers(layersToMerge, nameIsLastLayers, Layers.IndexOf(layersToMerge[0]));
- AddLayerStructureToUndo(oldLayerStructure);
- UndoManager.AddUndoChange(undoChange.ToChange(
- InsertLayersAtIndexesProcess,
- new object[] { indexes[0] },
- MergeLayersProcess,
- new object[] { indexes, nameIsLastLayers, layer.LayerGuid }));
- UndoManager.SquashUndoChanges(2, "Undo merge layers");
- return layer;
- }
- public SKColor GetColorAtPoint(int x, int y)
- {
- return Renderer.FinalSurface.GetSRGBPixel(x, y);
- }
- private void DisposeLayerBitmaps()
- {
- foreach (var layer in layers)
- {
- layer.LayerBitmap.Dispose();
- }
- referenceLayer?.LayerBitmap.Dispose();
- previewLayer?.LayerBitmap.Dispose();
- previewLayerRenderer?.Dispose();
- referenceLayerRenderer?.Dispose();
- renderer?.Dispose();
- }
- public void BuildLayerStructureProcess(object[] parameters)
- {
- if (parameters.Length > 0 && parameters[0] is WpfObservableRangeCollection<GuidStructureItem> groups)
- {
- LayerStructure.Groups.CollectionChanged -= Groups_CollectionChanged;
- LayerStructure.Groups = LayerStructure.CloneGroups(groups);
- LayerStructure.Groups.CollectionChanged += Groups_CollectionChanged;
- RaisePropertyChanged(nameof(LayerStructure));
- }
- }
- private void ReverseMoveLayerInStructureProcess(object[] props)
- {
- int indexTo = (int)props[0];
- Guid layerGuid = (Guid)props[1];
- Guid layerAtOldIndex = Layers[indexTo].LayerGuid;
- var startGroup = LayerStructure.GetGroupByLayer(layerGuid);
- LayerStructure.PreMoveReassignBounds(new GroupData(startGroup?.GroupGuid), layerGuid);
- Layers.Move(Layers.IndexOf(Layers.First(x => x.LayerGuid == layerGuid)), indexTo);
- var newGroup = LayerStructure.GetGroupByLayer(layerAtOldIndex);
- LayerStructure.PostMoveReassignBounds(new GroupData(newGroup?.GroupGuid), layerGuid);
- RaisePropertyChanged(nameof(LayerStructure));
- }
- private void InjectRemoveActiveLayersUndo(object[] guidArgs, StorageBasedChange change)
- {
- Action<Layer[], UndoLayer[]> undoAction = RestoreLayersProcess;
- Action<object[]> redoAction = RemoveLayersProcess;
- if (Layers.Count == 0)
- {
- Layer layer = new("Base Layer", 1, 1) { MaxHeight = Height, MaxWidth = Width };
- Layers.Add(layer);
- undoAction = (Layer[] layers, UndoLayer[] undoData) =>
- {
- Layers.RemoveAt(0);
- RestoreLayersProcess(layers, undoData);
- };
- redoAction = (object[] args) =>
- {
- RemoveLayersProcess(args);
- Layers.Add(layer);
- };
- }
- UndoManager.AddUndoChange(
- change.ToChange(
- undoAction,
- redoAction,
- guidArgs,
- "Remove layers"));
- }
- private void MergeLayersProcess(object[] args)
- {
- if (args.Length > 0
- && args[0] is int[] indexes
- && args[1] is bool nameOfSecond
- && args[2] is Guid mergedLayerGuid)
- {
- Layer[] layers = new Layer[indexes.Length];
- for (int i = 0; i < layers.Length; i++)
- {
- layers[i] = Layers[indexes[i]];
- }
- Layer layer = MergeLayers(layers, nameOfSecond, indexes[0]);
- layer.ChangeGuid(mergedLayerGuid);
- }
- }
- private void InsertLayersAtIndexesProcess(Layer[] layers, UndoLayer[] data, object[] args)
- {
- if (args.Length > 0 && args[0] is int layerIndex)
- {
- Layers.RemoveAt(layerIndex);
- for (int i = 0; i < layers.Length; i++)
- {
- Layer layer = layers[i];
- layer.IsActive = true;
- Layers.Insert(data[i].LayerIndex, layer);
- }
- ActiveLayerGuid = layers.First(x => x.LayerHighlightColor == MainSelectedLayerColor).LayerGuid;
- // Identifying main layer by highlightColor is a bit hacky, but shhh
- }
- }
- /// <summary>
- /// Moves offsets of layers by specified vector.
- /// </summary>
- private void MoveOffsets(IEnumerable<Layer> layers, Coordinates moveVector)
- {
- foreach (Layer layer in layers)
- {
- Thickness offset = layer.Offset;
- layer.Offset = new Thickness(offset.Left + moveVector.X, offset.Top + moveVector.Y, 0, 0);
- }
- }
- private void MoveOffsetsProcess(object[] arguments)
- {
- if (arguments.Length > 0 && arguments[0] is IEnumerable<Layer> layers && arguments[1] is Coordinates vector)
- {
- MoveOffsets(layers, vector);
- }
- else
- {
- throw new ArgumentException("Provided arguments were invalid. Expected IEnumerable<Layer> and Coordinates");
- }
- }
- private void MoveGroupInStructureProcess(object[] parameter)
- {
- Guid groupGuid = (Guid)parameter[0];
- Guid referenceLayerGuid = (Guid)parameter[1];
- bool above = (bool)parameter[2];
- GuidStructureItem group = LayerStructure.GetGroupByGuid(groupGuid);
- GuidStructureItem referenceLayerGroup = LayerStructure.GetGroupByLayer(referenceLayerGuid);
- Layer referenceLayer = Layers.First(x => x.LayerGuid == referenceLayerGuid);
- int layerIndex = Layers.IndexOf(referenceLayer);
- int folderTopIndex = Layers.IndexOf(Layers.First(x => x.LayerGuid == group?.EndLayerGuid));
- int oldIndex = folderTopIndex;
- if (layerIndex < folderTopIndex)
- {
- int folderBottomIndex = Layers.IndexOf(Layers.First(x => x.LayerGuid == group.StartLayerGuid));
- oldIndex = folderBottomIndex;
- }
- int newIndex = CalculateNewIndex(layerIndex, above, oldIndex);
- LayerStructure.MoveGroup(groupGuid, newIndex);
- LayerStructure.ReassignParent(group, referenceLayerGroup);
- LayerStructure.PostMoveReassignBounds(new GroupData(group?.Parent?.GroupGuid), new GroupData(group?.GroupGuid));
- }
- private int CalculateNewIndex(int layerIndex, bool above, int oldIndex)
- {
- int newIndex = layerIndex;
- int diff = newIndex - oldIndex;
- if (TriesToMoveAboveBelow(above, diff) || TriesToMoveBelowAbove(above, diff) || (above && newIndex < oldIndex) || (!above && newIndex > oldIndex))
- {
- newIndex += above ? 1 : -1;
- }
- return Math.Clamp(newIndex, 0, Layers.Count - 1);
- }
- private bool TriesToMoveAboveBelow(bool above, int diff) => above && diff == -1;
- private bool TriesToMoveBelowAbove(bool above, int diff) => !above && diff == 1;
- private void MoveLayerInStructureProcess(object[] parameter)
- {
- Guid layer = (Guid)parameter[0];
- Guid referenceLayer = (Guid)parameter[1];
- bool above = (bool)parameter[2];
- int layerIndex = Layers.IndexOf(Layers.First(x => x.LayerGuid == referenceLayer));
- int oldIndex = Layers.IndexOf(Layers.First(x => x.LayerGuid == layer));
- int newIndex = CalculateNewIndex(layerIndex, above, oldIndex);
- var startGroup = LayerStructure.GetGroupByLayer(layer);
- LayerStructure.PreMoveReassignBounds(new GroupData(startGroup?.GroupGuid), layer);
- Layers.Move(oldIndex, newIndex);
- var newFolder = LayerStructure.GetGroupByLayer(referenceLayer);
- LayerStructure.PostMoveReassignBounds(new GroupData(newFolder?.GroupGuid), layer);
- if (Layers.IndexOf(ActiveLayer) == oldIndex)
- {
- SetMainActiveLayer(newIndex);
- }
- RaisePropertyChanged(nameof(LayerStructure));
- }
- private void RestoreLayersProcess(Layer[] layers, UndoLayer[] layersData)
- {
- for (int i = 0; i < layers.Length; i++)
- {
- Layer layer = layers[i];
- Layers.Insert(layersData[i].LayerIndex, layer);
- if (layersData[i].IsActive)
- {
- SetMainActiveLayer(Layers.IndexOf(layer));
- }
- }
- }
- private void RemoveLayerProcess(object[] parameters)
- {
- if (parameters != null && parameters.Length > 0 && parameters[0] is Guid layerGuid)
- {
- Layer layer = Layers.First(x => x.LayerGuid == layerGuid);
- int index = Layers.IndexOf(layer);
- bool wasActive = layer.IsActive;
- var layerGroup = LayerStructure.GetGroupByLayer(layer.LayerGuid);
- LayerStructure.ExpandParentGroups(layerGroup);
- if (layerGroup?.Parent != null && LayerStructure.GroupContainsOnlyLayer(layer.LayerGuid, layerGroup))
- {
- LayerStructure.PreMoveReassignBounds(new GroupData(layerGroup.Parent.GroupGuid), new GroupData(layerGroup.GroupGuid));
- }
- LayerStructure.AssignParent(Layers[index].LayerGuid, null);
- RemoveGroupsIfEmpty(layer, layerGroup);
- Layers.Remove(layer);
- if (wasActive || Layers.IndexOf(ActiveLayer) >= index)
- {
- SetNextLayerAsActive(index);
- }
- LayersChanged?.Invoke(this, new LayersChangedEventArgs(layerGuid, LayerAction.Remove));
- }
- }
- private void RemoveGroupsIfEmpty(Layer layer, GuidStructureItem layerGroup)
- {
- if (LayerStructure.GroupContainsOnlyLayer(layer.LayerGuid, layerGroup))
- {
- if (layerGroup.Parent != null)
- {
- layerGroup.Parent.Subgroups.Remove(layerGroup);
- RemoveGroupsIfEmpty(layer, layerGroup.Parent);
- }
- else
- {
- LayerStructure.Groups.Remove(layerGroup);
- }
- }
- }
- /// <summary>
- /// Get's the layers suffix, e.g. "New Layer" becomes "New Layer (1)".
- /// </summary>
- /// <returns>Name of the layer with suffix.</returns>
- private string GetLayerSuffix(Layer layer)
- {
- Match match = reversedLayerSuffixRegex.Match(layer.Name.Reverse());
- int? highestValue = GetHighestSuffix(layer, match.Groups[2].Value, reversedLayerSuffixRegex);
- string actualName = match.Groups[2].Value.Reverse();
- if (highestValue == null)
- {
- return actualName;
- }
- return actualName + $" ({highestValue + 1})";
- }
- private int? GetHighestSuffix(Layer except, string layerName, Regex regex)
- {
- int? highestValue = null;
- foreach (Layer otherLayer in Layers)
- {
- if (otherLayer == except)
- {
- continue;
- }
- Match otherMatch = regex.Match(otherLayer.Name.Reverse());
- if (otherMatch.Groups[2].Value == layerName)
- {
- SetHighest(otherMatch.Groups[1].Value.Reverse(), ref highestValue);
- }
- }
- return highestValue;
- }
- /// <returns>Was the parse a sucess.</returns>
- private bool SetHighest(string number, ref int? highest, int? defaultValue = 0)
- {
- bool sucess = int.TryParse(number, out int parsedNumber);
- if (sucess)
- {
- if (highest == null || highest < parsedNumber)
- {
- highest = parsedNumber;
- }
- }
- else
- {
- if (highest == null)
- {
- highest = defaultValue;
- }
- }
- return sucess;
- }
- private void RemoveLayersProcess(object[] parameters)
- {
- if (parameters != null && parameters.Length > 0 && parameters[0] is IEnumerable<Guid> layerGuids)
- {
- object[] args = new object[1];
- foreach (var guid in layerGuids)
- {
- args[0] = guid;
- RemoveLayerProcess(args);
- }
- }
- }
- }
- }
|