Source code for simvx.editor.commands
"""Editor undo/redo commands for node tree operations.
Provides self-contained command objects for every undoable editor action.
Each command stores all data needed to execute, undo, and redo without
external state. Use with ``UndoStack.push()`` to record operations.
Structural add / remove / reparent leaves live in ``simvx.core.undo`` so
non-editor tools (IDE plugins, asset importers, scripted demos) can
record undoable scene-tree mutations without re-implementing them. The
``AddNodeCommand`` / ``RemoveNodeCommand`` aliases below keep the editor
naming convention.
"""
from typing import Any
from simvx.core import (
AddChildCommand,
BatchCommand,
CallableCommand,
Node,
PropertyCommand,
RemoveChildCommand,
ReparentCommand,
)
__all__ = [
"AddNodeCommand",
"RemoveNodeCommand",
"ReparentCommand",
"ReorderCommand",
"RenameCommand",
"TransformCommand",
]
# Editor-facing names map onto the generic core commands. ``AddNodeCommand``
# and ``RemoveNodeCommand`` are the editor's vocabulary: keeping the alias
# avoids a churn pass through every consumer for no value.
AddNodeCommand = AddChildCommand
RemoveNodeCommand = RemoveChildCommand
# ReparentCommand is re-exported under its original name.
[docs]
class ReorderCommand(CallableCommand):
"""Change a child's index within its parent. Undo restores original index."""
def __init__(self, parent: Node, child: Node, new_index: int, old_index: int) -> None:
self._parent = parent
self._child = child
self._new_index = new_index
self._old_index = old_index
def _move(idx: int) -> None:
lst = self._parent.children._list
lst.remove(self._child)
lst.insert(idx, self._child)
self._parent.children._dirty = True
super().__init__(lambda: _move(self._new_index), lambda: _move(self._old_index), f"Reorder {child.name}")
[docs]
class RenameCommand(CallableCommand):
"""Rename a node. Undo restores the old name."""
def __init__(self, node: Node, new_name: str, old_name: str) -> None:
self._node = node
self._new_name = new_name
self._old_name = old_name
super().__init__(
lambda: setattr(self._node, "name", self._new_name),
lambda: setattr(self._node, "name", self._old_name),
f"Rename {old_name} \u2192 {new_name}",
)