123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- using System.Collections.Generic;
- using PixiEditor.AvaloniaUI.Models.Handlers;
- using PixiEditor.AvaloniaUI.Models.Layers;
- using PixiEditor.AvaloniaUI.ViewModels.Document;
- using PixiEditor.ChangeableDocument.Actions.Generated;
- using PixiEditor.ChangeableDocument.Changeables.Graph.Interfaces;
- using PixiEditor.ChangeableDocument.Enums;
- using PixiEditor.Extensions.Common.Localization;
- namespace PixiEditor.AvaloniaUI.Models.DocumentModels;
- #nullable enable
- internal class DocumentStructureHelper
- {
- private IDocument doc;
- private DocumentInternalParts internals;
- public DocumentStructureHelper(IDocument doc, DocumentInternalParts internals)
- {
- this.doc = doc;
- this.internals = internals;
- }
- private string GetUniqueName(string name, INodeHandler node)
- {
- int count = 1;
- node.TraverseBackwards(newNode =>
- {
- if (newNode is IStructureMemberHandler structureMemberHandler)
- {
- string childName = structureMemberHandler.NameBindable;
- if (childName.StartsWith(name))
- count++;
- }
- return true;
- });
- return $"{name} {count}";
- }
- public Guid CreateNewStructureMember(StructureMemberType type, string? name = null, bool finish = true)
- {
- IStructureMemberHandler? member = doc.SelectedStructureMember;
- if (member is null)
- {
- Guid guid = Guid.NewGuid();
- //put member on top
- internals.ActionAccumulator.AddActions(new CreateStructureMember_Action(
- doc.NodeGraphHandler.OutputNode.Id,
- guid, type));
- name ??= GetUniqueName(
- type == StructureMemberType.Layer
- ? new LocalizedString("NEW_LAYER")
- : new LocalizedString("NEW_FOLDER"), doc.NodeGraphHandler.OutputNode);
- internals.ActionAccumulator.AddActions(new StructureMemberName_Action(guid, name));
- if (finish)
- internals.ActionAccumulator.AddFinishedActions();
- return guid;
- }
- if (member is IFolderHandler folder)
- {
- Guid guid = Guid.NewGuid();
- //put member inside folder on top
- internals.ActionAccumulator.AddActions(new CreateStructureMember_Action(folder.Id, guid, type));
- name ??= GetUniqueName(
- type == StructureMemberType.Layer
- ? new LocalizedString("NEW_LAYER")
- : new LocalizedString("NEW_FOLDER"), folder);
- internals.ActionAccumulator.AddActions(new StructureMemberName_Action(guid, name));
- if (finish)
- internals.ActionAccumulator.AddFinishedActions();
- return guid;
- }
- if (member is ILayerHandler layer)
- {
- Guid guid = Guid.NewGuid();
- //put member above the layer
- INodeHandler parent = doc.StructureHelper.GetFirstForwardNode(layer);
- internals.ActionAccumulator.AddActions(new CreateStructureMember_Action(parent.Id, guid, type));
- name ??= GetUniqueName(
- type == StructureMemberType.Layer
- ? new LocalizedString("NEW_LAYER")
- : new LocalizedString("NEW_FOLDER"), parent);
- internals.ActionAccumulator.AddActions(new StructureMemberName_Action(guid, name));
- if (finish)
- internals.ActionAccumulator.AddFinishedActions();
- return guid;
- }
- throw new ArgumentException($"Unknown member type: {type}");
- }
- private void HandleMoveInside(Guid memberToMove, Guid memberToMoveInto)
- {
- if (memberToMoveInto == memberToMove)
- return;
- internals.ActionAccumulator.AddFinishedActions(new MoveStructureMember_Action(memberToMove, memberToMoveInto,
- true));
- }
- private void HandleMoveAboveBelow(Guid memberToMove, Guid referenceMemberId, bool above)
- {
- var referenceMember = doc.StructureHelper.FindNode<INodeHandler>(referenceMemberId);
- var memberToMoveInto = !above ? referenceMember : doc.StructureHelper.GetFirstForwardNode(referenceMember);
- internals.ActionAccumulator.AddFinishedActions(
- new MoveStructureMember_Action(memberToMove, memberToMoveInto.Id, above && memberToMoveInto is IFolderHandler));
- }
- public void TryMoveStructureMember(Guid memberToMove, Guid memberToMoveIntoOrNextTo,
- StructureMemberPlacement placement)
- {
- switch (placement)
- {
- case StructureMemberPlacement.Above:
- HandleMoveAboveBelow(memberToMove, memberToMoveIntoOrNextTo, true);
- break;
- case StructureMemberPlacement.Below:
- HandleMoveAboveBelow(memberToMove, memberToMoveIntoOrNextTo, false);
- break;
- case StructureMemberPlacement.Inside:
- HandleMoveInside(memberToMove, memberToMoveIntoOrNextTo);
- break;
- case StructureMemberPlacement.BelowOutsideFolder:
- {
- var path = doc.StructureHelper.FindPath(memberToMoveIntoOrNextTo);
- var folder = path.FirstOrDefault(x => x is IFolderHandler) as IFolderHandler;
- if (folder is null)
- HandleMoveAboveBelow(memberToMove, memberToMoveIntoOrNextTo, false);
- else
- HandleMoveAboveBelow(memberToMove, folder.Id, false);
- }
- break;
- }
- }
- }
|