65 lines
3.5 KiB
Markdown
65 lines
3.5 KiB
Markdown
## ADDED Requirements
|
|
|
|
### Requirement: ICommand interface
|
|
The system SHALL provide an `ICommand` pure-virtual interface with `Execute()`, `Undo()`, and `GetDescription()` methods that all reversible operations implement.
|
|
|
|
#### Scenario: Execute runs the operation
|
|
- **WHEN** `ICommand::Execute()` is called on a newly created command
|
|
- **THEN** the operation is applied to the USD stage and the scene reflects the new state
|
|
|
|
#### Scenario: Undo reverses the operation
|
|
- **WHEN** `ICommand::Undo()` is called after `Execute()`
|
|
- **THEN** the USD stage returns to the state it was in before `Execute()` was called
|
|
|
|
### Requirement: CommandHistory stack management
|
|
The system SHALL maintain two stacks (undo stack, redo stack). `Push(cmd)` executes the command, pushes it onto the undo stack, and clears the redo stack. `Undo()` pops from the undo stack, calls `Undo()` on the command, and pushes it onto the redo stack. `Redo()` pops from the redo stack, calls `Execute()` on the command, and pushes it back onto the undo stack.
|
|
|
|
#### Scenario: Push clears redo stack
|
|
- **WHEN** the user undoes two steps and then makes a new edit
|
|
- **THEN** the redo stack is cleared and the new command is the top of the undo stack
|
|
|
|
#### Scenario: Undo with empty stack is a no-op
|
|
- **WHEN** `CommandHistory::Undo()` is called and the undo stack is empty
|
|
- **THEN** no crash occurs and the scene is unchanged
|
|
|
|
#### Scenario: Redo with empty stack is a no-op
|
|
- **WHEN** `CommandHistory::Redo()` is called and the redo stack is empty
|
|
- **THEN** no crash occurs and the scene is unchanged
|
|
|
|
### Requirement: Ctrl+Z / Ctrl+Y hotkeys
|
|
The application SHALL process `Ctrl+Z` to invoke `Undo()` and `Ctrl+Y` (and `Ctrl+Shift+Z`) to invoke `Redo()` during the ImGui main loop, unless an ImGui text input widget has keyboard focus.
|
|
|
|
#### Scenario: Ctrl+Z triggers undo
|
|
- **WHEN** the user presses `Ctrl+Z` and the undo stack is non-empty
|
|
- **THEN** the most recent command is undone and the viewport reflects the reverted state
|
|
|
|
#### Scenario: Ctrl+Y triggers redo
|
|
- **WHEN** the user presses `Ctrl+Y` and the redo stack is non-empty
|
|
- **THEN** the most recent undone command is reapplied and the viewport reflects the restored state
|
|
|
|
#### Scenario: Hotkeys ignored in text inputs
|
|
- **WHEN** an ImGui `InputText` widget has keyboard focus and the user presses `Ctrl+Z`
|
|
- **THEN** ImGui handles the keypress as text-widget undo and `CommandHistory::Undo()` is NOT called
|
|
|
|
### Requirement: Edit menu Undo/Redo items
|
|
The application SHALL provide **Edit → Undo** and **Edit → Redo** menu items. Each item SHALL display the description of the command that would be affected. Items SHALL be greyed out (disabled) when the respective stack is empty.
|
|
|
|
#### Scenario: Undo item shows command description
|
|
- **WHEN** the undo stack is non-empty and the Edit menu is opened
|
|
- **THEN** the Undo item reads "Undo: <description of top command>" and is enabled
|
|
|
|
#### Scenario: Undo item disabled when stack empty
|
|
- **WHEN** the undo stack is empty and the Edit menu is opened
|
|
- **THEN** the Undo item is greyed out and clicking it has no effect
|
|
|
|
### Requirement: History cleared on stage lifecycle events
|
|
The system SHALL call `CommandHistory::Clear()` whenever a stage is opened, closed, or replaced, so that stale USD object references cannot be dereferenced.
|
|
|
|
#### Scenario: History clears on stage open
|
|
- **WHEN** the user opens a new USD file
|
|
- **THEN** both undo and redo stacks are empty after the stage loads
|
|
|
|
#### Scenario: History clears on stage close
|
|
- **WHEN** the user closes the current stage
|
|
- **THEN** both undo and redo stacks are empty
|