/**
* @fileoverview A class representing an engine-independent
* hoverable, selectable, modifiable and creatable rectangle shape.
*/
goog.provide('xrx.shape.Rect');
goog.provide('xrx.shape.RectCreatable');
goog.provide('xrx.shape.RectHoverable');
goog.provide('xrx.shape.RectModifiable');
goog.provide('xrx.shape.RectSelectable');
goog.require('goog.array');
goog.require('xrx.geometry.Path');
goog.require('xrx.shape.Creatable');
goog.require('xrx.shape.Dragger');
goog.require('xrx.shape.Hoverable');
goog.require('xrx.shape.Modifiable');
goog.require('xrx.shape.PathLike');
goog.require('xrx.shape.Selectable');
/**
* A class representing an engine-independent rectangle shape.
* @param {xrx.drawing.Drawing} drawing The parent drawing canvas.
* @extends {xrx.shape.Style}
* @constructor
*/
xrx.shape.Rect = function(drawing) {
goog.base(this, drawing, new xrx.geometry.Path(4));
/**
* The engine element.
* @type {(xrx.canvas.Rect|xrx.svg.Rect|xrx.vml.Rect)}
* @private
*/
this.engineElement_ = this.drawing_.getEngine().createRect();
};
goog.inherits(xrx.shape.Rect, xrx.shape.PathLike);
/**
* Sets the X coordinate of this rectangle.
* @param {number} x The coordinate.
*/
xrx.shape.Rect.prototype.setX = function(x) {
this.geometry_.coords[0][0] = x;
this.geometry_.coords[3][0] = x;
};
/**
* Returns the X coordinate of this rectangle.
* @return {number} The coordinate.
*/
xrx.shape.Rect.prototype.getX = function() {
return this.geometry_.coords[0][0];
};
/**
* Sets the Y coordinate of this rectangle.
* @param {number} y The coordinate.
*/
xrx.shape.Rect.prototype.setY = function(y) {
this.geometry_.coords[0][1] = y;
this.geometry_.coords[1][1] = y;
};
/**
* Returns the Y coordinate of this rectangle.
* @return {number} The coordinate.
*/
xrx.shape.Rect.prototype.getY = function() {
return this.geometry_.coords[0][1];
};
/**
* Sets the width of this rectangle.
* @param {number} width The width.
*/
xrx.shape.Rect.prototype.setWidth = function(width) {
var x = this.geometry_.coords[0][0];
this.geometry_.coords[1][0] = x + width;
this.geometry_.coords[2][0] = x + width;
};
/**
* Returns the width of this rectangle.
* @return {number} The width.
*/
xrx.shape.Rect.prototype.getWidth = function() {
var coords = this.geometry_.coords;
return coords[1][0] - coords[0][0];
};
/**
* Sets the height of this rectangle.
* @param {height} height The height.
*/
xrx.shape.Rect.prototype.setHeight = function(height) {
var y = this.geometry_.coords[0][1];
this.geometry_.coords[2][1] = y + height;
this.geometry_.coords[3][1] = y + height;
};
/**
* Returns the height of this rectangle.
* @return {number} The height.
*/
xrx.shape.Rect.prototype.getHeight = function() {
var coords = this.geometry_.coords;
return coords[3][1] - coords[0][1];
};
/**
* Function makes sure that the underlying polygon rendering class
* stays a rectangle.
* @param {number} position The nth vertex currently modified.
* @private
*/
xrx.shape.Rect.prototype.setAffineCoords = function(position) {
var coords = this.getCoords();
if (position === 0 || position === 2) {
coords[1][0] = coords[2][0];
coords[1][1] = coords[0][1];
coords[3][0] = coords[0][0];
coords[3][1] = coords[2][1];
} else {
coords[0][0] = coords[3][0];
coords[0][1] = coords[1][1];
coords[2][0] = coords[1][0];
coords[2][1] = coords[3][1];
}
return coords;
};
/**
* Draws this rectangle.
* @private
*/
xrx.shape.Rect.prototype.draw = function() {
this.startDrawing_();
this.engineElement_.draw(this.getCoords(), this.getRenderingFillColor(),
this.getRenderingFillOpacity(), this.getRenderingStrokeColor(),
this.getRenderingStrokeWidth());
this.finishDrawing_();
};
/**
* Returns a helper shape that makes this shape hoverable.
* @return {xrx.shape.RectHoverable} The hoverable rectangle shape.
*/
xrx.shape.Rect.prototype.getHoverable = function() {
if (!this.hoverable_) this.hoverable_ = new xrx.shape.RectHoverable(this);
return this.hoverable_;
};
/**
* Returns a helper shape that makes this shape selectable.
* @return {xrx.shape.RectSelectable} The selectable rectangle shape.
*/
xrx.shape.Rect.prototype.getSelectable = function() {
if (!this.selectable_) this.selectable_ = new xrx.shape.RectSelectable(this);
return this.selectable_;
};
/**
* Returns a helper shape that makes this shape modifiable.
* @return {xrx.shape.RectHoverable} The modifiable rectangle shape.
*/
xrx.shape.Rect.prototype.getModifiable = function(drawing) {
if (!this.modifiable_) this.modifiable_ = new xrx.shape.RectModifiable(this);
return this.modifiable_;
};
/**
* Returns a helper shape that makes this shape creatable.
* @return {xrx.shape.RectHoverable} The creatable rectangle shape.
*/
xrx.shape.Rect.prototype.getCreatable = function() {
if (!this.creatable_) this.creatable_ = new xrx.shape.RectCreatable(this);
return this.creatable_;
};
/**
* Disposes this rectangle shape.
*/
xrx.shape.Rect.prototype.disposeInternal = function() {
goog.base(this, 'disposeInternal');
};
/**
* A class representing a hoverable rectangle shape.
* @param {xrx.shape.Rect} rect The parent rectangle shape.
* @constructor
* @private
*/
xrx.shape.RectHoverable = function(rect) {
goog.base(this, rect);
};
goog.inherits(xrx.shape.RectHoverable, xrx.shape.Hoverable);
/**
* Disposes this hoverable rectangle shape.
*/
xrx.shape.RectHoverable.prototype.disposeInternal = function() {
goog.base(this, 'disposeInternal');
};
/**
* A class representing a selectable rectangle shape.
* @param {xrx.shape.Rect} rect The parent rectangle shape.
* @constructor
* @private
*/
xrx.shape.RectSelectable = function(rect) {
goog.base(this, rect);
};
goog.inherits(xrx.shape.RectSelectable, xrx.shape.Selectable);
/**
* Disposes this selectable shape.
*/
xrx.shape.RectSelectable.prototype.disposeInternal = function() {
goog.base(this, 'disposeInternal');
};
/**
* A class representing a modifiable rectangle shape.
* @param {xrx.shape.Rect} rect The parent rectangle shape.
* @constructor
* @private
*/
xrx.shape.RectModifiable = function(rect, helper) {
goog.base(this, rect, helper);
this.init_();
};
goog.inherits(xrx.shape.RectModifiable, xrx.shape.Modifiable);
/**
* @private
*/
xrx.shape.RectModifiable.prototype.setCoords = function(coords, position) {
for(var i = 0, len = this.dragger_.length; i < len; i++) {
if (i !== position) {
this.dragger_[i].setCoordX(coords[i][0]);
this.dragger_[i].setCoordY(coords[i][1]);
}
}
this.shape_.setCoords(coords);
};
/**
* @private
*/
xrx.shape.RectModifiable.prototype.setCoordAt = function(pos, coord) {
var coords;
this.shape_.setCoordAt(pos, coord);
this.shape_.setAffineCoords(pos);
coords = this.shape_.getCoords();
this.dragger_[0].setCoordX(coords[0][0]);
this.dragger_[0].setCoordY(coords[0][1]);
this.dragger_[1].setCoordX(coords[1][0]);
this.dragger_[1].setCoordY(coords[1][1]);
this.dragger_[2].setCoordX(coords[2][0]);
this.dragger_[2].setCoordY(coords[2][1]);
this.dragger_[3].setCoordX(coords[3][0]);
this.dragger_[3].setCoordY(coords[3][1]);
};
/**
* @private
*/
xrx.shape.RectModifiable.prototype.move = function(distX, distY) {
var coords = this.shape_.getCoordsCopy();
for (var i = 0, len = coords.length; i < len; i++) {
coords[i][0] += distX;
coords[i][1] += distY;
}
this.setCoords(coords);
};
/**
* Disposes this modifiable rectangle shape.
*/
xrx.shape.RectModifiable.prototype.disposeInternal = function() {
goog.base(this, 'disposeInternal');
};
/**
* @private
*/
xrx.shape.RectModifiable.prototype.init_ = function() {
var coords = this.shape_.getCoords();
var draggers = [];
var dragger;
for(var i = 0, len = coords.length; i < len; i++) {
dragger = new xrx.shape.Dragger(this, i);
dragger.setCoords([coords[i]]);
draggers.push(dragger);
}
this.setDragger(draggers);
};
/**
* A class representing a creatable rectangle shape.
* @param {xrx.shape.Rect} rect The parent rectangle shape.
* @constructor
* @private
*/
xrx.shape.RectCreatable = function(rect) {
goog.base(this, rect, new xrx.shape.Rect(rect.getDrawing()));
};
goog.inherits(xrx.shape.RectCreatable, xrx.shape.Creatable);
/**
* Returns the coordinates of the rectangle currently created.
* @return Array<number> The coordinates.
* @private
*/
xrx.shape.RectCreatable.prototype.getCoords = function() {
return this.preview_.getCoords();
};
/**
* @private
*/
xrx.shape.RectCreatable.prototype.handleDown = function(e, cursor) {
var point = cursor.getPointTransformed();
var coords = new Array(4);
coords[0] = goog.array.clone(point);
coords[1] = goog.array.clone(point);
coords[2] = goog.array.clone(point);
coords[3] = goog.array.clone(point);
this.preview_.setCoords(coords);
this.target_.getDrawing().eventShapeCreate([this.preview_]);
};
/**
* @private
*/
xrx.shape.RectCreatable.prototype.handleMove = function(e, cursor) {
var point = cursor.getPointTransformed();
this.preview_.setCoordAt(2, point);
this.preview_.setAffineCoords(2);
};
/**
* @private
*/
xrx.shape.RectCreatable.prototype.handleUp = function(e, cursor) {
var rect = new xrx.shape.Rect(this.target_.getDrawing());
rect.setStyle(this.target_);
rect.setCoords(this.preview_.getCoordsCopy());
this.target_.getDrawing().eventShapeCreated(rect);
};
/**
* Disposes this creatable rectangle shape.
*/
xrx.shape.RectCreatable.prototype.disposeInternal = function() {
goog.base(this, 'disposeInternal');
};