UXUndoGroup
UXUndoGroup makes several model edits undo as one user action.
#use <UXKit> // or #import "UXUndoManager.xc"Overview
Section titled “Overview”class UXUndoGroup { Array<UXUndoOp>* ops; // the inverses, newest last u8* name; // shown in "Undo <name>"; 0 = none}UXUndoManager makes and stacks these;
you do not construct one. When a group opens and closes decides what a single
press of Undo reverses.
A group is the unit of undo
Section titled “A group is the unit of undo”The stacks hold groups, not operations. One Undo pops one group and runs every inverse in it.
“Delete the selection” might change ten objects in the model. It is one group and one Undo, provided the ten registrations happened inside the group.
Implicit and explicit grouping
Section titled “Implicit and explicit grouping”undo.registerUndo(&self.setX, box(oldX)); // implicit: its own groupA registration outside any explicit group opens a group, adds itself, and closes it. One edit gives one Undo with no extra calls.
undo.beginUndoGrouping();for (each selected object) { … registerUndo … }undo.setActionName((u8*)"Delete");undo.endUndoGrouping(); // one group, one UndoExplicit grouping marks registrations that belong together. Nesting is counted: begin/end pairs can nest, and only the outermost close pushes the group. A compound operation can therefore call smaller operations that group internally, and they do not become separate Undos.
Ops run in reverse
Section titled “Ops run in reverse”Array<UXUndoOp>* ops // newest lastUndoing walks the array backwards. This is required for correctness whenever edits interact.
If you move an object and then delete it, undoing must recreate the object before restoring its position; otherwise the position is set on something that does not exist. Recording forwards and replaying backwards handles this automatically.
The name comes from the action
Section titled “The name comes from the action”u8* name // 0 when never setThe name is what a menu shows as “Undo Delete”. It is stamped on the group
when the group closes, or set on the most recent group when
setActionName is called
right after a single registration. The second case supports the ordinary idiom:
undo.registerUndo(&self.setX, box(oldX));undo.setActionName((u8*)"Change X"); // names the edit it followsA null name is valid and means the menu reads plain “Undo”. Check for it before printing it.
The name travels with the group across the stacks. Undoing an action named “Delete” puts a group named “Delete” on the redo stack, and the menu reads “Redo Delete”. Nothing re-labels it.
Fields
Section titled “Fields”Array<UXUndoOp>* opsThe inverses, in registration order. Held strongly: a group owns its operations, and through them the data needed to restore.
u8* nameKept, not copied. Pass a literal, or a string that outlives the undo stack.
Conforms to
Section titled “Conforms to”- A plain class (not an
Objectsubclass)
See also
Section titled “See also”UXUndoManager: the stacks and the machineUXUndoOp: one recorded inverse