make transformations undoable/redoable

This commit is contained in:
abakkk 2020-10-04 17:20:03 +02:00
parent 6374cc8c47
commit e218819edd
2 changed files with 62 additions and 4 deletions

26
area.js
View File

@ -546,6 +546,10 @@ var DrawingArea = new Lang.Class({
this._redisplay();
}
if (duplicate)
// For undo, ignore both the transformations inherited from the duplicated element
// and the current transformation.
this.grabbedElement.makeAllTransformationsNotUndoable();
this.motionHandler = this.connect('motion-event', (actor, event) => {
if (this.spaceKeyPressed)
@ -907,18 +911,36 @@ var DrawingArea = new Lang.Class({
deleteLastElement: function() {
this._stopAll();
this.elements.pop();
if (this.elements.length)
this.elements[this.elements.length - 1].resetUndoneTransformations();
this._redisplay();
},
undo: function() {
if (this.elements.length > 0)
if (!this.elements.length)
return;
let success = this.elements[this.elements.length - 1].undoTransformation();
if (!success) {
this.undoneElements.push(this.elements.pop());
if (this.elements.length)
this.elements[this.elements.length - 1].resetUndoneTransformations();
}
this._redisplay();
},
redo: function() {
if (this.undoneElements.length > 0)
let success = false;
if (this.elements.length)
success = this.elements[this.elements.length - 1].redoTransformation();
if (!success && this.undoneElements.length > 0)
this.elements.push(this.undoneElements.pop());
this._redisplay();
},

View File

@ -458,7 +458,7 @@ const _DrawingElement = new Lang.Class({
return;
let center = this._getOriginalCenter();
this.transformations[0] = { type: Transformations.ROTATION,
this.transformations[0] = { type: Transformations.ROTATION, notUndoable: true,
angle: getAngle(center[0], center[1], points[points.length - 1][0], points[points.length - 1][1], x, y) };
} else if (this.shape == Shapes.ELLIPSE && transform) {
@ -467,7 +467,7 @@ const _DrawingElement = new Lang.Class({
points[2] = [x, y];
let center = this._getOriginalCenter();
this.transformations[0] = { type: Transformations.ROTATION,
this.transformations[0] = { type: Transformations.ROTATION, notUndoable: true,
angle: getAngle(center[0], center[1], center[0] + 1, center[1], x, y) };
} else if (this.shape == Shapes.POLYGON || this.shape == Shapes.POLYLINE) {
@ -586,6 +586,42 @@ const _DrawingElement = new Lang.Class({
}
},
undoTransformation: function() {
if (this.transformations && this.transformations.length) {
// Do not undo initial transformations (transformations made during the drawing step).
if (this.lastTransformation.notUndoable)
return false;
if (!this._undoneTransformations)
this._undoneTransformations = [];
this._undoneTransformations.push(this.transformations.pop());
return true;
}
return false;
},
redoTransformation: function() {
if (this._undoneTransformations && this._undoneTransformations.length) {
if (!this.transformations)
this.transformations = [];
this.transformations.push(this._undoneTransformations.pop());
return true;
}
return false;
},
resetUndoneTransformations: function() {
delete this._undoneTransformations;
},
makeAllTransformationsNotUndoable: function() {
this.transformations.forEach(transformation => transformation.notUndoable = true);
},
// The figure rotation center before transformations (original).
// this.textWidth is computed during Cairo building.
_getOriginalCenter: function() {