| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import {
- TransformUtils,
- Command,
- Transform,
- UndoManagerObserver,
- } from "../internal";
- export class UndoManager {
- protected _redoStack: Array<UndoManager.Wrapped>;
- protected _undoStack: Array<UndoManager.Wrapped>;
- protected _transform: Transform;
- protected _observer: UndoManagerObserver;
- protected _transformStack(stack: Array<UndoManager.Wrapped>, command: Command): void {
- const transform = this._transform;
- const sizeof = stack.length - 1;
- for (let i = sizeof; i >= 0; i--) {
- const pair1 = transform.transfer(stack[i].redo, command);
- const pair2 = transform.transfer(stack[i].undo, pair1[1]);
- stack[i].redo = pair1[0];
- stack[i].undo = pair2[0];
- command = pair2[1];
- }
- }
- public constructor(transform: Transform) {
- this._redoStack = [];
- this._undoStack = [];
- this._transform = transform;
- this._observer = new UndoManagerObserver();
- }
- public transform(command: Command): void {
- this._transformStack(this._undoStack, command);
- this._transformStack(this._redoStack, command);
- }
- public canUndo(): boolean {
- return this._undoStack.length !== 0;
- }
- public canRedo(): boolean {
- return this._redoStack.length !== 0;
- }
- public addRedo(redo: Command, undo: Command): void
- public addRedo(wrapped: UndoManager.Wrapped): void
- public addRedo(...parameter: any): void {
- if (TransformUtils.hasLength(parameter, 1)) {
- const wrapped = parameter[0];
- this._redoStack.push(wrapped);
- this._observer.dispatchOnAddRedo(wrapped);
- return;
- }
- if (TransformUtils.hasLength(parameter, 2)) {
- const redo = parameter[0];
- const undo = parameter[1];
- const wrapped = { redo, undo };
- this._redoStack.push(wrapped);
- this._observer.dispatchOnAddRedo(wrapped);
- }
- }
- public addUndo(redo: Command, undo: Command): void
- public addUndo(wrapped: UndoManager.Wrapped): void
- public addUndo(...parameter: any): void {
- if (TransformUtils.hasLength(parameter, 1)) {
- const wrapped = parameter[0];
- this._undoStack.push(wrapped);
- this._observer.dispatchOnAddUndo(wrapped);
- return;
- }
- if (TransformUtils.hasLength(parameter, 2)) {
- const redo = parameter[0];
- const undo = parameter[1];
- const wrapped = { redo, undo };
- this._undoStack.push(wrapped);
- this._observer.dispatchOnAddUndo(wrapped);
- }
- }
- public performCommand(redo: Command, undo: Command): void
- public performCommand(wrapped: UndoManager.Wrapped): void
- public performCommand(...parameter: any): void {
- if (TransformUtils.hasLength(parameter, 1)) {
- const wrapped = parameter[0];
- this.addRedo(wrapped);
- return;
- }
- if (TransformUtils.hasLength(parameter, 2)) {
- const redo = parameter[0];
- const undo = parameter[1];
- const wrapped = { redo, undo };
- this.addRedo(wrapped);
- }
- }
- public performRedo(): void {
- if (this.canRedo()) {
- const wrapped = this._redoStack.pop();
- this.addUndo(wrapped);
- this._observer.dispatchOnRedo(wrapped);
- }
- }
- public performUndo(): void {
- if (this.canUndo()) {
- const wrapped = this._undoStack.pop();
- this.addRedo(wrapped);
- this._observer.dispatchOnUndo(wrapped);
- }
- }
- public getObserver(): UndoManagerObserver {
- return this._observer;
- }
- }
- export namespace UndoManager {
- export interface Wrapped{
- undo: Command,
- redo: Command,
- }
- }
|