Editor/Commands/SuiDeleteElementCommand.cs
using System.Collections.Generic;
using SboxUiDesigner.Runtime;
namespace SboxUiDesigner.EditorUi.Commands;
/// <summary>
/// Delete an element and its descendants. Stores the removed elements so undo
/// reinstates the entire subtree in original order.
/// </summary>
public sealed class SuiDeleteElementCommand : ISuiCommand
{
private readonly string _elementId;
private string _parentId;
private int _siblingIndex;
private List<SuiElement> _removedSubtree;
public string Description => "Delete element";
public SuiDeleteElementCommand( string elementId )
{
_elementId = elementId;
}
public void Apply( SuiDocument doc )
{
if ( doc == null ) return;
var target = doc.GetElement( _elementId );
if ( target == null || string.IsNullOrEmpty( target.ParentId ) )
return; // cannot delete root or unknown
_parentId = target.ParentId;
// Capture the subtree (target + descendants) and the sibling index.
var byId = new Dictionary<string, SuiElement>();
foreach ( var el in doc.Elements )
if ( !string.IsNullOrEmpty( el.Id ) ) byId[el.Id] = el;
_removedSubtree = new List<SuiElement>();
CollectSubtree( target, byId, _removedSubtree );
var parent = doc.GetElement( _parentId );
_siblingIndex = parent != null ? parent.Children.IndexOf( _elementId ) : -1;
// Remove from parent's children list and the document's flat element list.
parent?.Children.Remove( _elementId );
foreach ( var el in _removedSubtree ) doc.Elements.Remove( el );
}
public void Undo( SuiDocument doc )
{
if ( doc == null || _removedSubtree == null ) return;
// Re-add elements in original order.
foreach ( var el in _removedSubtree )
doc.Elements.Add( el );
var parent = doc.GetElement( _parentId );
if ( parent != null )
{
var idx = _siblingIndex < 0 ? parent.Children.Count : _siblingIndex;
parent.Children.Insert( idx, _elementId );
}
}
private static void CollectSubtree( SuiElement root, Dictionary<string, SuiElement> byId, List<SuiElement> output )
{
output.Add( root );
foreach ( var childId in root.Children )
{
if ( byId.TryGetValue( childId, out var child ) )
CollectSubtree( child, byId, output );
}
}
}