Implement change propagation in matrices.

This commit is contained in:
Jürg Lehni 2013-11-26 19:03:58 +01:00
parent ade2a2f456
commit 56f25e8742
6 changed files with 45 additions and 18 deletions

View file

@ -83,13 +83,15 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @param {Number} ty the translateY coordinate of the transform
* @return {Matrix} this affine transform
*/
set: function(a, c, b, d, tx, ty) {
set: function(a, c, b, d, tx, ty, _dontNotify) {
this._a = a;
this._c = c;
this._b = b;
this._d = d;
this._tx = tx;
this._ty = ty;
if (!_dontNotify)
this._changed();
return this;
},
@ -97,6 +99,11 @@ var Matrix = Base.extend(/** @lends Matrix# */{
return Base.serialize(this.getValues(), options);
},
_changed: function() {
if (this._owner)
this._owner._changed(/*#=*/ Change.GEOMETRY);
},
/**
* @return {Matrix} a copy of this transform
*/
@ -136,6 +143,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
reset: function() {
this._a = this._d = 1;
this._c = this._b = this._tx = this._ty = 0;
this._changed();
return this;
},
@ -171,6 +179,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
this._d *= scale.y;
if (center)
this.translate(center.negate());
this._changed();
return this;
},
@ -197,6 +206,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
y = point.y;
this._tx += x * this._a + y * this._b;
this._ty += x * this._c + y * this._d;
this._changed();
return this;
},
@ -241,6 +251,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
this._d = -sin * c + cos * d;
this._tx += tx * a + ty * b;
this._ty += tx * c + ty * d;
this._changed();
return this;
},
@ -278,6 +289,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
this._d += point.x * c;
if (center)
this.translate(center.negate());
this._changed();
return this;
},
@ -298,6 +310,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
this._d = mx._b * c + mx._d * d;
this._tx += mx._tx * a + mx._ty * b;
this._ty += mx._tx * c + mx._ty * d;
this._changed();
return this;
},
@ -320,6 +333,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
this._d = mx._c * b + mx._d * d;
this._tx = mx._a * tx + mx._b * ty + mx._tx;
this._ty = mx._c * tx + mx._d * ty + mx._ty;
this._changed();
return this;
},
@ -327,8 +341,8 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* @return {Boolean} whether this transform is the identity transform
*/
isIdentity: function() {
return this._a == 1 && this._c == 0 && this._b == 0 && this._d == 1
&& this._tx == 0 && this._ty == 0;
return this._a === 1 && this._c === 0 && this._b === 0 && this._d === 1
&& this._tx === 0 && this._ty === 0;
},
/**
@ -386,7 +400,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* A faster version of transform that only takes one point and does not
* attempt to convert it.
*/
_transformPoint: function(point, dest, dontNotify) {
_transformPoint: function(point, dest, _dontNotify) {
var x = point.x,
y = point.y;
if (!dest)
@ -394,7 +408,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
return dest.set(
x * this._a + y * this._b + this._tx,
x * this._c + y * this._d + this._ty,
dontNotify
_dontNotify
);
},
@ -425,7 +439,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
* point and finding the new bounding box to these points. This is not
* really the transformed reactangle!
*/
_transformBounds: function(bounds, dest, dontNotify) {
_transformBounds: function(bounds, dest, _dontNotify) {
var coords = this._transformCorners(bounds),
min = coords.slice(0, 2),
max = coords.slice();
@ -440,7 +454,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
if (!dest)
dest = new Rectangle();
return dest.set(min[0], min[1], max[0] - min[0], max[1] - min[1],
dontNotify);
_dontNotify);
},
/**
@ -463,7 +477,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
? det : null;
},
_inverseTransform: function(point, dest, dontNotify) {
_inverseTransform: function(point, dest, _dontNotify) {
var det = this._getDeterminant();
if (!det)
return null;
@ -474,7 +488,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
return dest.set(
(x * this._d - y * this._b) / det,
(y * this._a - x * this._c) / det,
dontNotify
_dontNotify
);
},
@ -659,6 +673,7 @@ var Matrix = Base.extend(/** @lends Matrix# */{
};
this['set' + name] = function(value) {
this[prop] = value;
this._changed();
};
}, {});
});

View file

@ -932,10 +932,10 @@ var LinkedPoint = Point.extend({
this._setter = setter;
},
set: function(x, y, dontNotify) {
set: function(x, y, _dontNotify) {
this._x = x;
this._y = y;
if (!dontNotify)
if (!_dontNotify)
this._owner[this._setter](this);
return this;
},

View file

@ -829,12 +829,12 @@ var LinkedRectangle = Rectangle.extend({
this._setter = setter;
},
set: function(x, y, width, height, dontNotify) {
set: function(x, y, width, height, _dontNotify) {
this._x = x;
this._y = y;
this._width = width;
this._height = height;
if (!dontNotify)
if (!_dontNotify)
this._owner[this._setter](this);
return this;
}

View file

@ -537,10 +537,10 @@ var LinkedSize = Size.extend({
this._setter = setter;
},
set: function(width, height, dontNotify) {
set: function(width, height, _dontNotify) {
this._width = width;
this._height = height;
if (!dontNotify)
if (!_dontNotify)
this._owner[this._setter](this);
return this;
},

View file

@ -83,9 +83,10 @@ var Item = Base.extend(Callback, /** @lends Item# */{
}
}
this._style = new Style(this._project._currentStyle, this);
this._matrix = new Matrix();
var matrix = this._matrix = new Matrix();
if (point)
this._matrix.translate(point);
matrix.translate(point);
matrix._owner = this;
return props ? this._set(props, { insert: true }) : true;
},

View file

@ -97,7 +97,7 @@ var View = Base.extend(Callback, /** @lends View# */{
// Link this id to our view
View._viewsById[this._id] = this;
this._viewSize = size;
this._matrix = new Matrix();
(this._matrix = new Matrix())._owner = this;
this._zoom = 1;
// Make sure the first view is focused for keyboard input straight away
if (!View._focused)
@ -256,6 +256,17 @@ var View = Base.extend(Callback, /** @lends View# */{
}
},
/**
* Private notifier that is called whenever a change occurs in this view.
* Used only by Matrix for now.
*
* @param {ChangeFlag} flags describes what exactly has changed.
*/
_changed: function(flags) {
if (flags & /*#=*/ ChangeFlag.APPEARANCE)
this._project._needsRedraw = true;
},
_transform: function(matrix) {
this._matrix.concatenate(matrix);
// Force recalculation of these values next time they are requested.