Adding float-no-zero branch hosted build
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Graphics utility functions for advanced coordinates.
|
||||
*
|
||||
* This file assists the use of advanced coordinates in goog.graphics. Coords
|
||||
* can be specified as simple numbers which will correspond to units in the
|
||||
* graphics element's coordinate space. Alternately, coords can be expressed
|
||||
* in pixels, meaning no matter what tranformations or coordinate system changes
|
||||
* are present, the number of pixel changes will remain constant. Coords can
|
||||
* also be expressed as percentages of their parent's size.
|
||||
*
|
||||
* This file also allows for elements to have margins, expressable in any of
|
||||
* the ways described above.
|
||||
*
|
||||
* Additional pieces of advanced coordinate functionality can (soon) be found in
|
||||
* element.js and groupelement.js.
|
||||
*
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.ext.coordinates');
|
||||
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Cache of boolean values. For a given string (key), is it special? (value)
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.coordinates.specialCoordinateCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given coordinate is a percent based coordinate or an
|
||||
* expression with a percent based component.
|
||||
* @param {string} coord The coordinate to test.
|
||||
* @return {boolean} Whether the coordinate contains the string '%'.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.coordinates.isPercent_ = function(coord) {
|
||||
return goog.string.contains(coord, '%');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given coordinate is a pixel based coordinate or an
|
||||
* expression with a pixel based component.
|
||||
* @param {string} coord The coordinate to test.
|
||||
* @return {boolean} Whether the coordinate contains the string 'px'.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.coordinates.isPixels_ = function(coord) {
|
||||
return goog.string.contains(coord, 'px');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given coordinate is special - i.e. not just a number.
|
||||
* @param {string|number|null} coord The coordinate to test.
|
||||
* @return {boolean} Whether the coordinate is special.
|
||||
*/
|
||||
goog.graphics.ext.coordinates.isSpecial = function(coord) {
|
||||
var cache = goog.graphics.ext.coordinates.specialCoordinateCache_;
|
||||
|
||||
if (!(coord in cache)) {
|
||||
cache[coord] = goog.isString(coord) && (
|
||||
goog.graphics.ext.coordinates.isPercent_(coord) ||
|
||||
goog.graphics.ext.coordinates.isPixels_(coord));
|
||||
}
|
||||
|
||||
return cache[coord];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the given expression in the given context.
|
||||
*
|
||||
* Should be treated as package scope.
|
||||
*
|
||||
* @param {string|number} coord The coordinate to convert.
|
||||
* @param {number} size The size of the parent element.
|
||||
* @param {number} scale The ratio of pixels to units.
|
||||
* @return {number} The number of coordinate space units that corresponds to
|
||||
* this coordinate.
|
||||
*/
|
||||
goog.graphics.ext.coordinates.computeValue = function(coord, size, scale) {
|
||||
var number = parseFloat(String(coord));
|
||||
if (goog.isString(coord)) {
|
||||
if (goog.graphics.ext.coordinates.isPercent_(coord)) {
|
||||
return number * size / 100;
|
||||
} else if (goog.graphics.ext.coordinates.isPixels_(coord)) {
|
||||
return number / scale;
|
||||
}
|
||||
}
|
||||
|
||||
return number;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts the given coordinate to a number value in units.
|
||||
*
|
||||
* Should be treated as package scope.
|
||||
*
|
||||
* @param {string|number} coord The coordinate to retrieve the value for.
|
||||
* @param {boolean|undefined} forMaximum Whether we are computing the largest
|
||||
* value this coordinate would be in a parent of no size. The container
|
||||
* size in this case should be set to the size of the current element.
|
||||
* @param {number} containerSize The unit value of the size of the container of
|
||||
* this element. Should be set to the minimum width of this element if
|
||||
* forMaximum is true.
|
||||
* @param {number} scale The ratio of pixels to units.
|
||||
* @param {Object=} opt_cache Optional (but highly recommend) object to store
|
||||
* cached computations in. The calling class should manage clearing out
|
||||
* the cache when the scale or containerSize changes.
|
||||
* @return {number} The correct number of coordinate space units.
|
||||
*/
|
||||
goog.graphics.ext.coordinates.getValue = function(coord, forMaximum,
|
||||
containerSize, scale, opt_cache) {
|
||||
if (!goog.isNumber(coord)) {
|
||||
var cacheString = opt_cache && ((forMaximum ? 'X' : '') + coord);
|
||||
|
||||
if (opt_cache && cacheString in opt_cache) {
|
||||
coord = opt_cache[cacheString];
|
||||
} else {
|
||||
if (goog.graphics.ext.coordinates.isSpecial(
|
||||
/** @type {string} */ (coord))) {
|
||||
coord = goog.graphics.ext.coordinates.computeValue(coord,
|
||||
containerSize, scale);
|
||||
} else {
|
||||
// Simple coordinates just need to be converted from a string to a
|
||||
// number.
|
||||
coord = parseFloat(/** @type {string} */ (coord));
|
||||
}
|
||||
|
||||
// Cache the result.
|
||||
if (opt_cache) {
|
||||
opt_cache[cacheString] = coord;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return coord;
|
||||
};
|
||||
@@ -0,0 +1,968 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A thicker wrapper around the DOM element returned from
|
||||
* the different draw methods of the graphics implementation, and
|
||||
* all interfaces that the various element types support.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
goog.provide('goog.graphics.ext.Element');
|
||||
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.graphics');
|
||||
goog.require('goog.graphics.ext.coordinates');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for a wrapper around the goog.graphics wrapper that enables
|
||||
* more advanced functionality.
|
||||
* @param {goog.graphics.ext.Group?} group Parent for this element.
|
||||
* @param {goog.graphics.Element} wrapper The thin wrapper to wrap.
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
*/
|
||||
goog.graphics.ext.Element = function(group, wrapper) {
|
||||
goog.events.EventTarget.call(this);
|
||||
this.wrapper_ = wrapper;
|
||||
this.graphics_ = group ? group.getGraphics() : this;
|
||||
|
||||
this.xPosition_ = new goog.graphics.ext.Element.Position_(this, true);
|
||||
this.yPosition_ = new goog.graphics.ext.Element.Position_(this, false);
|
||||
|
||||
// Handle parent / child relationships.
|
||||
if (group) {
|
||||
this.parent_ = group;
|
||||
this.parent_.addChild(this);
|
||||
}
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Element, goog.events.EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* The graphics object that contains this element.
|
||||
* @type {goog.graphics.ext.Graphics|goog.graphics.ext.Element}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.graphics_;
|
||||
|
||||
|
||||
/**
|
||||
* The goog.graphics wrapper this class wraps.
|
||||
* @type {goog.graphics.Element}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.wrapper_;
|
||||
|
||||
|
||||
/**
|
||||
* The group or surface containing this element.
|
||||
* @type {goog.graphics.ext.Group|undefined}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.parent_;
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not computation of this element's position or size depends on its
|
||||
* parent's size.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.parentDependent_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the element has pending transformations.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.needsTransform_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* The current angle of rotation, expressed in degrees.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.rotation_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Object representing the x position and size of the element.
|
||||
* @type {goog.graphics.ext.Element.Position_}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.xPosition_;
|
||||
|
||||
|
||||
/**
|
||||
* Object representing the y position and size of the element.
|
||||
* @type {goog.graphics.ext.Element.Position_}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.yPosition_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.Element} The underlying thin wrapper.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getWrapper = function() {
|
||||
return this.wrapper_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.ext.Element|goog.graphics.ext.Graphics} The graphics
|
||||
* surface the element is a part of.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getGraphics = function() {
|
||||
return this.graphics_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the graphics implementation.
|
||||
* @return {goog.graphics.AbstractGraphics} The underlying graphics
|
||||
* implementation drawing this element's wrapper.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getGraphicsImplementation = function() {
|
||||
return this.graphics_.getImplementation();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.ext.Group|undefined} The parent of this element.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getParent = function() {
|
||||
return this.parent_;
|
||||
};
|
||||
|
||||
|
||||
// GENERAL POSITIONING
|
||||
|
||||
|
||||
/**
|
||||
* Internal convenience method for setting position - either as a left/top,
|
||||
* center/middle, or right/bottom value. Only one should be specified.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The position object to
|
||||
* set the value on.
|
||||
* @param {number|string} value The value of the coordinate.
|
||||
* @param {goog.graphics.ext.Element.PositionType_} type The type of the
|
||||
* coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setPosition_ = function(position, value,
|
||||
type, opt_chain) {
|
||||
position.setPosition(value, type);
|
||||
this.computeIsParentDependent_(position);
|
||||
|
||||
this.needsTransform_ = true;
|
||||
if (!opt_chain) {
|
||||
this.transform();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the width/height of the element.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The position object to
|
||||
* set the value on.
|
||||
* @param {string|number} size The new width/height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setSize_ = function(position, size,
|
||||
opt_chain) {
|
||||
if (position.setSize(size)) {
|
||||
this.needsTransform_ = true;
|
||||
|
||||
this.computeIsParentDependent_(position);
|
||||
|
||||
if (!opt_chain) {
|
||||
this.reset();
|
||||
}
|
||||
} else if (!opt_chain && this.isPendingTransform()) {
|
||||
this.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum width/height of the element.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The position object to
|
||||
* set the value on.
|
||||
* @param {string|number} minSize The minimum width/height of the element.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMinSize_ = function(position, minSize) {
|
||||
position.setMinSize(minSize);
|
||||
this.needsTransform_ = true;
|
||||
this.computeIsParentDependent_(position);
|
||||
};
|
||||
|
||||
|
||||
// HORIZONTAL POSITIONING
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The distance from the left edge of this element to the left
|
||||
* edge of its parent, specified in units of the parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getLeft = function() {
|
||||
return this.xPosition_.getStart();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the left coordinate of the element. Overwrites any previous value of
|
||||
* left, center, or right for this element.
|
||||
* @param {string|number} left The left coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setLeft = function(left, opt_chain) {
|
||||
this.setPosition_(this.xPosition_,
|
||||
left,
|
||||
goog.graphics.ext.Element.PositionType_.START,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The right coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getRight = function() {
|
||||
return this.xPosition_.getEnd();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the right coordinate of the element. Overwrites any previous value of
|
||||
* left, center, or right for this element.
|
||||
* @param {string|number} right The right coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setRight = function(right, opt_chain) {
|
||||
this.setPosition_(this.xPosition_,
|
||||
right,
|
||||
goog.graphics.ext.Element.PositionType_.END,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The center coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getCenter = function() {
|
||||
return this.xPosition_.getMiddle();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the center coordinate of the element. Overwrites any previous value of
|
||||
* left, center, or right for this element.
|
||||
* @param {string|number} center The center coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setCenter = function(center, opt_chain) {
|
||||
this.setPosition_(this.xPosition_,
|
||||
center,
|
||||
goog.graphics.ext.Element.PositionType_.MIDDLE,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
// VERTICAL POSITIONING
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The distance from the top edge of this element to the top
|
||||
* edge of its parent, specified in units of the parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getTop = function() {
|
||||
return this.yPosition_.getStart();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the top coordinate of the element. Overwrites any previous value of
|
||||
* top, middle, or bottom for this element.
|
||||
* @param {string|number} top The top coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setTop = function(top, opt_chain) {
|
||||
this.setPosition_(this.yPosition_,
|
||||
top,
|
||||
goog.graphics.ext.Element.PositionType_.START,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The bottom coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getBottom = function() {
|
||||
return this.yPosition_.getEnd();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the bottom coordinate of the element. Overwrites any previous value of
|
||||
* top, middle, or bottom for this element.
|
||||
* @param {string|number} bottom The bottom coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setBottom = function(bottom, opt_chain) {
|
||||
this.setPosition_(this.yPosition_,
|
||||
bottom,
|
||||
goog.graphics.ext.Element.PositionType_.END,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The middle coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMiddle = function() {
|
||||
return this.yPosition_.getMiddle();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the middle coordinate of the element. Overwrites any previous value of
|
||||
* top, middle, or bottom for this element
|
||||
* @param {string|number} middle The middle coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMiddle = function(middle, opt_chain) {
|
||||
this.setPosition_(this.yPosition_,
|
||||
middle,
|
||||
goog.graphics.ext.Element.PositionType_.MIDDLE,
|
||||
opt_chain);
|
||||
};
|
||||
|
||||
|
||||
// DIMENSIONS
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The width of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getWidth = function() {
|
||||
return this.xPosition_.getSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the width of the element.
|
||||
* @param {string|number} width The new width value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setWidth = function(width, opt_chain) {
|
||||
this.setSize_(this.xPosition_, width, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The minimum width of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMinWidth = function() {
|
||||
return this.xPosition_.getMinSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum width of the element.
|
||||
* @param {string|number} minWidth The minimum width of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMinWidth = function(minWidth) {
|
||||
this.setMinSize_(this.xPosition_, minWidth);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The height of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getHeight = function() {
|
||||
return this.yPosition_.getSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the height of the element.
|
||||
* @param {string|number} height The new height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setHeight = function(height, opt_chain) {
|
||||
this.setSize_(this.yPosition_, height, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The minimum height of the element, in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMinHeight = function() {
|
||||
return this.yPosition_.getMinSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum height of the element.
|
||||
* @param {string|number} minHeight The minimum height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setMinHeight = function(minHeight) {
|
||||
this.setMinSize_(this.yPosition_, minHeight);
|
||||
};
|
||||
|
||||
|
||||
// BOUNDS SHORTCUTS
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for setting the left and top position.
|
||||
* @param {string|number} left The left coordinate.
|
||||
* @param {string|number} top The top coordinate.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setPosition = function(left, top,
|
||||
opt_chain) {
|
||||
this.setLeft(left, true);
|
||||
this.setTop(top, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for setting the width and height.
|
||||
* @param {string|number} width The new width value.
|
||||
* @param {string|number} height The new height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setSize = function(width, height,
|
||||
opt_chain) {
|
||||
this.setWidth(width, true);
|
||||
this.setHeight(height, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shortcut for setting the left, top, width, and height.
|
||||
* @param {string|number} left The left coordinate.
|
||||
* @param {string|number} top The top coordinate.
|
||||
* @param {string|number} width The new width value.
|
||||
* @param {string|number} height The new height value.
|
||||
* @param {boolean=} opt_chain Optional flag to specify this function is part
|
||||
* of a chain of calls and therefore transformations should be set as
|
||||
* pending but not yet performed.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setBounds = function(left, top, width,
|
||||
height, opt_chain) {
|
||||
this.setLeft(left, true);
|
||||
this.setTop(top, true);
|
||||
this.setWidth(width, true);
|
||||
this.setHeight(height, opt_chain);
|
||||
};
|
||||
|
||||
|
||||
// MAXIMUM BOUNDS
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} An estimate of the maximum x extent this element would have
|
||||
* in a parent of no width.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMaxX = function() {
|
||||
return this.xPosition_.getMaxPosition();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} An estimate of the maximum y extent this element would have
|
||||
* in a parent of no height.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getMaxY = function() {
|
||||
return this.yPosition_.getMaxPosition();
|
||||
};
|
||||
|
||||
|
||||
// RESET
|
||||
|
||||
|
||||
/**
|
||||
* Reset the element. This is called when the element changes size, or when
|
||||
* the coordinate system changes in a way that would affect pixel based
|
||||
* rendering
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.reset = function() {
|
||||
this.xPosition_.resetCache();
|
||||
this.yPosition_.resetCache();
|
||||
|
||||
this.redraw();
|
||||
|
||||
this.needsTransform_ = true;
|
||||
this.transform();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Overridable function for subclass specific reset.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.redraw = goog.nullFunction;
|
||||
|
||||
|
||||
// PARENT DEPENDENCY
|
||||
|
||||
|
||||
/**
|
||||
* Computes whether the element is still parent dependent.
|
||||
* @param {goog.graphics.ext.Element.Position_} position The recently changed
|
||||
* position object.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.computeIsParentDependent_ = function(
|
||||
position) {
|
||||
this.parentDependent_ = position.isParentDependent() ||
|
||||
this.xPosition_.isParentDependent() ||
|
||||
this.yPosition_.isParentDependent() ||
|
||||
this.checkParentDependent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this element's bounds depend on its parents.
|
||||
*
|
||||
* This function should be treated as if it has package scope.
|
||||
* @return {boolean} Whether this element's bounds depend on its parents.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.isParentDependent = function() {
|
||||
return this.parentDependent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Overridable function for subclass specific parent dependency.
|
||||
* @return {boolean} Whether this shape's bounds depends on its parent's.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.checkParentDependent =
|
||||
goog.functions.FALSE;
|
||||
|
||||
|
||||
// ROTATION
|
||||
|
||||
|
||||
/**
|
||||
* Set the rotation of this element.
|
||||
* @param {number} angle The angle of rotation, in degrees.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.setRotation = function(angle) {
|
||||
if (this.rotation_ != angle) {
|
||||
this.rotation_ = angle;
|
||||
|
||||
this.needsTransform_ = true;
|
||||
this.transform();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The angle of rotation of this element, in degrees.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getRotation = function() {
|
||||
return this.rotation_;
|
||||
};
|
||||
|
||||
|
||||
// TRANSFORMS
|
||||
|
||||
|
||||
/**
|
||||
* Called by the parent when the parent has transformed.
|
||||
*
|
||||
* Should be treated as package scope.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.parentTransform = function() {
|
||||
this.needsTransform_ = this.needsTransform_ || this.parentDependent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether this element has pending transforms.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.isPendingTransform = function() {
|
||||
return this.needsTransform_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs a pending transform.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.transform = function() {
|
||||
if (this.isPendingTransform()) {
|
||||
this.needsTransform_ = false;
|
||||
|
||||
this.wrapper_.setTransformation(
|
||||
this.getLeft(),
|
||||
this.getTop(),
|
||||
this.rotation_,
|
||||
(this.getWidth() || 1) / 2,
|
||||
(this.getHeight() || 1) / 2);
|
||||
|
||||
// TODO(robbyw): this._fireEvent('transform', [ this ]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// PIXEL SCALE
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the x direction.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getPixelScaleX = function() {
|
||||
return this.getGraphics().getPixelScaleX();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the y direction.
|
||||
*/
|
||||
goog.graphics.ext.Element.prototype.getPixelScaleY = function() {
|
||||
return this.getGraphics().getPixelScaleY();
|
||||
};
|
||||
|
||||
|
||||
// EVENT HANDLING
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.graphics.ext.Element.prototype.disposeInternal = function() {
|
||||
goog.graphics.ext.Element.superClass_.disposeInternal.call();
|
||||
this.wrapper_.dispose();
|
||||
};
|
||||
|
||||
|
||||
// INTERNAL POSITION OBJECT
|
||||
|
||||
|
||||
/**
|
||||
* Position specification types. Start corresponds to left/top, middle to
|
||||
* center/middle, and end to right/bottom.
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.PositionType_ = {
|
||||
START: 0,
|
||||
MIDDLE: 1,
|
||||
END: 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Manages a position and size, either horizontal or vertical.
|
||||
* @param {goog.graphics.ext.Element} element The element the position applies
|
||||
* to.
|
||||
* @param {boolean} horizontal Whether the position is horizontal or vertical.
|
||||
* @constructor
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_ = function(element, horizontal) {
|
||||
this.element_ = element;
|
||||
this.horizontal_ = horizontal;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Object} The coordinate value computation cache.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getCoordinateCache_ = function() {
|
||||
return this.coordinateCache_ || (this.coordinateCache_ = {});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The size of the parent's coordinate space.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getParentSize_ = function() {
|
||||
var parent = this.element_.getParent();
|
||||
return this.horizontal_ ?
|
||||
parent.getCoordinateWidth() :
|
||||
parent.getCoordinateHeight();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The minimum width/height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getMinSize = function() {
|
||||
return this.getValue_(this.minSize_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the minimum width/height of the element.
|
||||
* @param {string|number} minSize The minimum width/height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.setMinSize = function(minSize) {
|
||||
this.minSize_ = minSize;
|
||||
this.resetCache();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The width/height of the element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getSize = function() {
|
||||
return Math.max(this.getValue_(this.size_), this.getMinSize());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the width/height of the element.
|
||||
* @param {string|number} size The width/height of the element.
|
||||
* @return {boolean} Whether the value was changed.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.setSize = function(size) {
|
||||
if (size != this.size_) {
|
||||
this.size_ = size;
|
||||
this.resetCache();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts the given x coordinate to a number value in units.
|
||||
* @param {string|number} v The coordinate to retrieve the value for.
|
||||
* @param {boolean=} opt_forMaximum Whether we are computing the largest value
|
||||
* this coordinate would be in a parent of no size.
|
||||
* @return {number} The correct number of coordinate space units.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getValue_ = function(v,
|
||||
opt_forMaximum) {
|
||||
if (!goog.graphics.ext.coordinates.isSpecial(v)) {
|
||||
return parseFloat(String(v));
|
||||
}
|
||||
|
||||
var cache = this.getCoordinateCache_();
|
||||
var scale = this.horizontal_ ?
|
||||
this.element_.getPixelScaleX() :
|
||||
this.element_.getPixelScaleY();
|
||||
|
||||
var containerSize;
|
||||
if (opt_forMaximum) {
|
||||
containerSize = goog.graphics.ext.coordinates.computeValue(
|
||||
this.size_ || 0, 0, scale);
|
||||
} else {
|
||||
var parent = this.element_.getParent();
|
||||
containerSize = this.horizontal_ ? parent.getWidth() : parent.getHeight();
|
||||
}
|
||||
|
||||
return goog.graphics.ext.coordinates.getValue(v, opt_forMaximum,
|
||||
containerSize, scale, cache);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The distance from the left/top edge of this element to the
|
||||
* left/top edge of its parent, specified in units of the parent's
|
||||
* coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getStart = function() {
|
||||
if (this.cachedValue_ == null) {
|
||||
var value = this.getValue_(this.distance_);
|
||||
if (this.distanceType_ == goog.graphics.ext.Element.PositionType_.START) {
|
||||
this.cachedValue_ = value;
|
||||
} else if (this.distanceType_ ==
|
||||
goog.graphics.ext.Element.PositionType_.MIDDLE) {
|
||||
this.cachedValue_ = value + (this.getParentSize_() - this.getSize()) / 2;
|
||||
} else {
|
||||
this.cachedValue_ = this.getParentSize_() - value - this.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
return this.cachedValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The middle coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getMiddle = function() {
|
||||
return this.distanceType_ == goog.graphics.ext.Element.PositionType_.MIDDLE ?
|
||||
this.getValue_(this.distance_) :
|
||||
(this.getParentSize_() - this.getSize()) / 2 - this.getStart();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The end coordinate of the element, in units of the
|
||||
* parent's coordinate system.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getEnd = function() {
|
||||
return this.distanceType_ == goog.graphics.ext.Element.PositionType_.END ?
|
||||
this.getValue_(this.distance_) :
|
||||
this.getParentSize_() - this.getStart() - this.getSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the position, either as a left/top, center/middle, or right/bottom
|
||||
* value.
|
||||
* @param {number|string} value The value of the coordinate.
|
||||
* @param {goog.graphics.ext.Element.PositionType_} type The type of the
|
||||
* coordinate.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.setPosition = function(value,
|
||||
type) {
|
||||
this.distance_ = value;
|
||||
this.distanceType_ = type;
|
||||
|
||||
// Clear cached value.
|
||||
this.cachedValue_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} An estimate of the maximum x/y extent this element would
|
||||
* have in a parent of no width/height.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.getMaxPosition = function() {
|
||||
// TODO(robbyw): Handle transformed or rotated coordinates
|
||||
// TODO(robbyw): Handle pixel based sizes?
|
||||
|
||||
return this.getValue_(this.distance_ || 0) + (
|
||||
goog.graphics.ext.coordinates.isSpecial(this.size_) ? 0 : this.getSize());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resets the caches of position values and coordinate values.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.resetCache = function() {
|
||||
this.coordinateCache_ = null;
|
||||
this.cachedValue_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the size or position of this element depends on
|
||||
* the size of the parent element.
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.isParentDependent = function() {
|
||||
return this.distanceType_ != goog.graphics.ext.Element.PositionType_.START ||
|
||||
goog.graphics.ext.coordinates.isSpecial(this.size_) ||
|
||||
goog.graphics.ext.coordinates.isSpecial(this.minSize_) ||
|
||||
goog.graphics.ext.coordinates.isSpecial(this.distance_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The lazy loaded distance from the parent's top/left edge to this element's
|
||||
* top/left edge expressed in the parent's coordinate system. We cache this
|
||||
* because it is most freqeuently requested by the element and it is easy to
|
||||
* compute middle and end values from it.
|
||||
* @type {?number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.cachedValue_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* A cache of computed x coordinates.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.coordinateCache_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The minimum width/height of this element, as specified by the caller.
|
||||
* @type {string|number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.minSize_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The width/height of this object, as specified by the caller.
|
||||
* @type {string|number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.size_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The coordinate of this object, as specified by the caller. The type of
|
||||
* coordinate is specified by distanceType_.
|
||||
* @type {string|number}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.distance_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* The coordinate type specified by distance_.
|
||||
* @type {goog.graphics.ext.Element.PositionType_}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Element.Position_.prototype.distanceType_ =
|
||||
goog.graphics.ext.Element.PositionType_.START;
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A thick wrapper around ellipses.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Ellipse');
|
||||
|
||||
goog.require('goog.graphics.ext.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics ellipse element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.StrokeAndFillElement}
|
||||
*/
|
||||
goog.graphics.ext.Ellipse = function(group) {
|
||||
// Initialize with some stock values.
|
||||
var wrapper = group.getGraphicsImplementation().drawEllipse(1, 1, 2, 2, null,
|
||||
null, group.getWrapper());
|
||||
goog.graphics.ext.StrokeAndFillElement.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Ellipse,
|
||||
goog.graphics.ext.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the ellipse. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Ellipse.prototype.redraw = function() {
|
||||
goog.graphics.ext.Ellipse.superClass_.redraw.call(this);
|
||||
|
||||
// Our position is already transformed in transform_, but because this is an
|
||||
// ellipse we need to position the center.
|
||||
var xRadius = this.getWidth() / 2;
|
||||
var yRadius = this.getHeight() / 2;
|
||||
var wrapper = this.getWrapper();
|
||||
wrapper.setCenter(xRadius, yRadius);
|
||||
wrapper.setRadius(xRadius, yRadius);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Extended graphics namespace.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext');
|
||||
|
||||
goog.require('goog.graphics.ext.Ellipse');
|
||||
goog.require('goog.graphics.ext.Graphics');
|
||||
goog.require('goog.graphics.ext.Group');
|
||||
goog.require('goog.graphics.ext.Image');
|
||||
goog.require('goog.graphics.ext.Rectangle');
|
||||
goog.require('goog.graphics.ext.Shape');
|
||||
goog.require('goog.graphics.ext.coordinates');
|
||||
@@ -0,0 +1,215 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Graphics surface type.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Graphics');
|
||||
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.graphics.ext.Group');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics surface.
|
||||
* @param {string|number} width The width in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {string|number} height The height in pixels. Strings
|
||||
* expressing percentages of parent with (e.g. '80%') are also accepted.
|
||||
* @param {?number=} opt_coordWidth The coordinate width - if
|
||||
* omitted or null, defaults to same as width.
|
||||
* @param {?number=} opt_coordHeight The coordinate height. - if
|
||||
* omitted or null, defaults to same as height.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The DOM helper object for the
|
||||
* document we want to render in.
|
||||
* @param {boolean=} opt_isSimple Flag used to indicate the graphics object will
|
||||
* be drawn to in a single pass, and the fastest implementation for this
|
||||
* scenario should be favored. NOTE: Setting to true may result in
|
||||
* degradation of text support.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Group}
|
||||
*/
|
||||
goog.graphics.ext.Graphics = function(width, height, opt_coordWidth,
|
||||
opt_coordHeight, opt_domHelper, opt_isSimple) {
|
||||
var surface = opt_isSimple ?
|
||||
goog.graphics.createSimpleGraphics(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper) :
|
||||
goog.graphics.createGraphics(width, height,
|
||||
opt_coordWidth, opt_coordHeight, opt_domHelper);
|
||||
this.implementation_ = surface;
|
||||
|
||||
goog.graphics.ext.Group.call(this, null, surface.getCanvasElement());
|
||||
|
||||
goog.events.listen(surface, goog.events.EventType.RESIZE,
|
||||
this.updateChildren, false, this);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Graphics, goog.graphics.ext.Group);
|
||||
|
||||
|
||||
/**
|
||||
* The root level graphics implementation.
|
||||
* @type {goog.graphics.AbstractGraphics}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.implementation_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.AbstractGraphics} The graphics implementation layer.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getImplementation = function() {
|
||||
return this.implementation_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate size.
|
||||
* @param {number} coordWidth The coordinate width.
|
||||
* @param {number} coordHeight The coordinate height.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.setCoordSize = function(coordWidth,
|
||||
coordHeight) {
|
||||
this.implementation_.setCoordSize(coordWidth, coordHeight);
|
||||
goog.graphics.ext.Graphics.superClass_.setSize.call(this, coordWidth,
|
||||
coordHeight);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size} The coordinate size.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getCoordSize = function() {
|
||||
return this.implementation_.getCoordSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the coordinate system position.
|
||||
* @param {number} left The coordinate system left bound.
|
||||
* @param {number} top The coordinate system top bound.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.setCoordOrigin = function(left, top) {
|
||||
this.implementation_.setCoordOrigin(left, top);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Coordinate} The coordinate system position.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getCoordOrigin = function() {
|
||||
return this.implementation_.getCoordOrigin();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change the size of the canvas.
|
||||
* @param {number} pixelWidth The width in pixels.
|
||||
* @param {number} pixelHeight The height in pixels.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.setPixelSize = function(pixelWidth,
|
||||
pixelHeight) {
|
||||
this.implementation_.setSize(pixelWidth, pixelHeight);
|
||||
|
||||
var coordSize = this.getCoordSize();
|
||||
goog.graphics.ext.Graphics.superClass_.setSize.call(this, coordSize.width,
|
||||
coordSize.height);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Size?} Returns the number of pixels spanned by the
|
||||
* surface, or null if the size could not be computed due to the size being
|
||||
* specified in percentage points and the component not being in the
|
||||
* document.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getPixelSize = function() {
|
||||
return this.implementation_.getPixelSize();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The coordinate width of the canvas.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getWidth = function() {
|
||||
return this.implementation_.getCoordSize().width;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The coordinate width of the canvas.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getHeight = function() {
|
||||
return this.implementation_.getCoordSize().height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the x direction.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getPixelScaleX = function() {
|
||||
return this.implementation_.getPixelScaleX();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of pixels per unit in the y direction.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getPixelScaleY = function() {
|
||||
return this.implementation_.getPixelScaleY();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Element} The root element of the graphics surface.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.getElement = function() {
|
||||
return this.implementation_.getElement();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Renders the underlying graphics.
|
||||
*
|
||||
* @param {Element} parentElement Parent element to render the component into.
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.render = function(parentElement) {
|
||||
this.implementation_.render(parentElement);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Never transform a surface.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.transform = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Called from the parent class, this method resets any pre-computed positions
|
||||
* and sizes.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Graphics.prototype.redraw = function() {
|
||||
this.transformChildren();
|
||||
};
|
||||
@@ -0,0 +1,215 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A thicker wrapper around graphics groups.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Group');
|
||||
|
||||
goog.require('goog.graphics.ext.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics group.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element. Can
|
||||
* be null if this is a Graphics instance.
|
||||
* @param {goog.graphics.GroupElement=} opt_wrapper The thin wrapper
|
||||
* to wrap. If omitted, a new group will be created. Must be included
|
||||
* when group is null.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Element}
|
||||
*/
|
||||
goog.graphics.ext.Group = function(group, opt_wrapper) {
|
||||
opt_wrapper = opt_wrapper || group.getGraphicsImplementation().createGroup(
|
||||
group.getWrapper());
|
||||
goog.graphics.ext.Element.call(this, group, opt_wrapper);
|
||||
|
||||
/**
|
||||
* Array of child elements this group contains.
|
||||
* @type {Array.<goog.graphics.ext.Element>}
|
||||
* @private
|
||||
*/
|
||||
this.children_ = [];
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Group, goog.graphics.ext.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Add an element to the group. This should be treated as package local, as
|
||||
* it is called by the draw* methods.
|
||||
* @param {!goog.graphics.ext.Element} element The element to add.
|
||||
* @param {boolean=} opt_chain Whether this addition is part of a longer set
|
||||
* of element additions.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.addChild = function(element, opt_chain) {
|
||||
if (!goog.array.contains(this.children_, element)) {
|
||||
this.children_.push(element);
|
||||
}
|
||||
|
||||
var transformed = this.growToFit_(element);
|
||||
|
||||
if (element.isParentDependent()) {
|
||||
element.parentTransform();
|
||||
}
|
||||
|
||||
if (!opt_chain && element.isPendingTransform()) {
|
||||
element.reset();
|
||||
}
|
||||
|
||||
if (transformed) {
|
||||
this.reset();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove an element from the group.
|
||||
* @param {goog.graphics.ext.Element} element The element to remove.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.removeChild = function(element) {
|
||||
goog.array.remove(this.children_, element);
|
||||
|
||||
// TODO(robbyw): shape.fireEvent('delete')
|
||||
|
||||
this.getGraphicsImplementation().removeElement(element.getWrapper());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the given function on each of this component's children in order. If
|
||||
* {@code opt_obj} is provided, it will be used as the 'this' object in the
|
||||
* function when called. The function should take two arguments: the child
|
||||
* component and its 0-based index. The return value is ignored.
|
||||
* @param {Function} f The function to call for every child component; should
|
||||
* take 2 arguments (the child and its index).
|
||||
* @param {Object=} opt_obj Used as the 'this' object in f when called.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.forEachChild = function(f, opt_obj) {
|
||||
if (this.children_) {
|
||||
goog.array.forEach(this.children_, f, opt_obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.graphics.GroupElement} The underlying thin wrapper.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.getWrapper;
|
||||
|
||||
|
||||
/**
|
||||
* Reset the element.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.reset = function() {
|
||||
goog.graphics.ext.Group.superClass_.reset.call(this);
|
||||
|
||||
this.updateChildren();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from the parent class, this method resets any pre-computed positions
|
||||
* and sizes.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.redraw = function() {
|
||||
this.getWrapper().setSize(this.getWidth(), this.getHeight());
|
||||
this.transformChildren();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transform the children that need to be transformed.
|
||||
* @protected
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.transformChildren = function() {
|
||||
this.forEachChild(function(child) {
|
||||
if (child.isParentDependent()) {
|
||||
child.parentTransform();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* As part of the reset process, update child elements.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.updateChildren = function() {
|
||||
this.forEachChild(function(child) {
|
||||
if (child.isParentDependent() || child.isPendingTransform()) {
|
||||
child.reset();
|
||||
} else if (child.updateChildren) {
|
||||
child.updateChildren();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* When adding an element, grow this group's bounds to fit it.
|
||||
* @param {!goog.graphics.ext.Element} element The added element.
|
||||
* @return {boolean} Whether the size of this group changed.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.growToFit_ = function(element) {
|
||||
var transformed = false;
|
||||
|
||||
var x = element.getMaxX();
|
||||
if (x > this.getWidth()) {
|
||||
this.setMinWidth(x);
|
||||
transformed = true;
|
||||
}
|
||||
|
||||
var y = element.getMaxY();
|
||||
if (y > this.getHeight()) {
|
||||
this.setMinHeight(y);
|
||||
transformed = true;
|
||||
}
|
||||
|
||||
return transformed;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The width of the element's coordinate space.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.getCoordinateWidth = function() {
|
||||
return this.getWidth();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The height of the element's coordinate space.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.getCoordinateHeight = function() {
|
||||
return this.getHeight();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove all drawing elements from the group.
|
||||
*/
|
||||
goog.graphics.ext.Group.prototype.clear = function() {
|
||||
while (this.children_.length) {
|
||||
this.removeChild(this.children_[0]);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A thick wrapper around images.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Image');
|
||||
|
||||
goog.require('goog.graphics.ext.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics image element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @param {string} src The path to the image to display.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Element}
|
||||
*/
|
||||
goog.graphics.ext.Image = function(group, src) {
|
||||
// Initialize with some stock values.
|
||||
var wrapper = group.getGraphicsImplementation().drawImage(0, 0, 1, 1, src,
|
||||
group.getWrapper());
|
||||
goog.graphics.ext.Element.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Image, goog.graphics.ext.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the image. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Image.prototype.redraw = function() {
|
||||
goog.graphics.ext.Image.superClass_.redraw.call(this);
|
||||
|
||||
// Our position is already handled bu transform_.
|
||||
this.getWrapper().setSize(this.getWidth(), this.getHeight());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the source of the image.
|
||||
* @param {string} src Source of the image.
|
||||
*/
|
||||
goog.graphics.ext.Image.prototype.setSource = function(src) {
|
||||
this.getWrapper().setSource(src);
|
||||
};
|
||||
@@ -0,0 +1,142 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A thick wrapper around paths.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Path');
|
||||
|
||||
goog.require('goog.graphics.AffineTransform');
|
||||
goog.require('goog.graphics.Path');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.math.Rect');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a path object
|
||||
* @constructor
|
||||
* @extends {goog.graphics.Path}
|
||||
*/
|
||||
goog.graphics.ext.Path = function() {
|
||||
goog.graphics.Path.call(this);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Path, goog.graphics.Path);
|
||||
|
||||
|
||||
/**
|
||||
* Optional cached or user specified bounding box. A user may wish to
|
||||
* precompute a bounding box to save time and include more accurate
|
||||
* computations.
|
||||
* @type {goog.math.Rect?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.bounds_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Clones the path.
|
||||
* @return {!goog.graphics.ext.Path} A clone of this path.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.clone = function() {
|
||||
var output = /** @type {goog.graphics.ext.Path} */
|
||||
(goog.graphics.ext.Path.superClass_.clone.call(this));
|
||||
output.bounds_ = this.bounds_ && this.bounds_.clone();
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Transforms the path. Only simple paths are transformable. Attempting
|
||||
* to transform a non-simple path will throw an error.
|
||||
* @param {!goog.graphics.AffineTransform} tx The transformation to perform.
|
||||
* @return {!goog.graphics.ext.Path} The path itself.
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.transform = function(tx) {
|
||||
goog.graphics.ext.Path.superClass_.transform.call(this, tx);
|
||||
|
||||
// Make sure the precomputed bounds are cleared when the path is transformed.
|
||||
this.bounds_ = null;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Modify the bounding box of the path. This may cause the path to be
|
||||
* simplified (i.e. arcs converted to curves) as a side-effect.
|
||||
* @param {number} deltaX How far to translate the x coordinates.
|
||||
* @param {number} deltaY How far to translate the y coordinates.
|
||||
* @param {number} xFactor After translation, all x coordinates are multiplied
|
||||
* by this number.
|
||||
* @param {number} yFactor After translation, all y coordinates are multiplied
|
||||
* by this number.
|
||||
* @return {goog.graphics.ext.Path} The path itself.
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.modifyBounds = function(deltaX, deltaY,
|
||||
xFactor, yFactor) {
|
||||
if (!this.isSimple()) {
|
||||
var simple = goog.graphics.Path.createSimplifiedPath(this);
|
||||
this.clear();
|
||||
this.appendPath(simple);
|
||||
}
|
||||
|
||||
return this.transform(goog.graphics.AffineTransform.getScaleInstance(
|
||||
xFactor, yFactor).translate(deltaX, deltaY));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the precomputed bounds.
|
||||
* @param {goog.math.Rect?} bounds The bounds to use, or set to null to clear
|
||||
* and recompute on the next call to getBoundingBox.
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.useBoundingBox = function(bounds) {
|
||||
this.bounds_ = bounds && bounds.clone();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.math.Rect?} The bounding box of the path, or null if the
|
||||
* path is empty.
|
||||
*/
|
||||
goog.graphics.ext.Path.prototype.getBoundingBox = function() {
|
||||
if (!this.bounds_ && !this.isEmpty()) {
|
||||
var minY;
|
||||
var minX = minY = Number.POSITIVE_INFINITY;
|
||||
var maxY;
|
||||
var maxX = maxY = Number.NEGATIVE_INFINITY;
|
||||
|
||||
var simplePath = this.isSimple() ? this :
|
||||
goog.graphics.Path.createSimplifiedPath(this);
|
||||
simplePath.forEachSegment(function(type, points) {
|
||||
for (var i = 0, len = points.length; i < len; i += 2) {
|
||||
minX = Math.min(minX, points[i]);
|
||||
maxX = Math.max(maxX, points[i]);
|
||||
minY = Math.min(minY, points[i + 1]);
|
||||
maxY = Math.max(maxY, points[i + 1]);
|
||||
}
|
||||
});
|
||||
|
||||
this.bounds_ = new goog.math.Rect(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
return this.bounds_;
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A thick wrapper around rectangles.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Rectangle');
|
||||
|
||||
goog.require('goog.graphics.ext.StrokeAndFillElement');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics rectangle element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.StrokeAndFillElement}
|
||||
*/
|
||||
goog.graphics.ext.Rectangle = function(group) {
|
||||
// Initialize with some stock values.
|
||||
var wrapper = group.getGraphicsImplementation().drawRect(0, 0, 1, 1, null,
|
||||
null, group.getWrapper());
|
||||
goog.graphics.ext.StrokeAndFillElement.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Rectangle,
|
||||
goog.graphics.ext.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the rectangle. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Rectangle.prototype.redraw = function() {
|
||||
goog.graphics.ext.Rectangle.superClass_.redraw.call(this);
|
||||
|
||||
// Our position is already handled by transform_.
|
||||
this.getWrapper().setSize(this.getWidth(), this.getHeight());
|
||||
};
|
||||
@@ -0,0 +1,146 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A thick wrapper around shapes with custom paths.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.Shape');
|
||||
|
||||
goog.require('goog.graphics.ext.Path');
|
||||
goog.require('goog.graphics.ext.StrokeAndFillElement');
|
||||
goog.require('goog.math.Rect');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for a graphics shape element.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @param {!goog.graphics.ext.Path} path The path to draw.
|
||||
* @param {boolean=} opt_autoSize Optional flag to specify the path should
|
||||
* automatically resize to fit the element. Defaults to false.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.StrokeAndFillElement}
|
||||
*/
|
||||
goog.graphics.ext.Shape = function(group, path, opt_autoSize) {
|
||||
this.autoSize_ = !!opt_autoSize;
|
||||
|
||||
var graphics = group.getGraphicsImplementation();
|
||||
var wrapper = graphics.drawPath(path, null, null,
|
||||
group.getWrapper());
|
||||
goog.graphics.ext.StrokeAndFillElement.call(this, group, wrapper);
|
||||
this.setPath(path);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.Shape, goog.graphics.ext.StrokeAndFillElement);
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not to automatically resize the shape's path when the element
|
||||
* itself is resized.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.autoSize_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* The original path, specified by the caller.
|
||||
* @type {goog.graphics.Path}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.path_;
|
||||
|
||||
|
||||
/**
|
||||
* The bounding box of the original path.
|
||||
* @type {goog.math.Rect?}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.boundingBox_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* The scaled path.
|
||||
* @type {goog.graphics.Path}
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.scaledPath_;
|
||||
|
||||
|
||||
/**
|
||||
* Get the path drawn by this shape.
|
||||
* @return {goog.graphics.Path?} The path drawn by this shape.
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.getPath = function() {
|
||||
return this.path_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the path to draw.
|
||||
* @param {goog.graphics.ext.Path} path The path to draw.
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.setPath = function(path) {
|
||||
this.path_ = path;
|
||||
|
||||
if (this.autoSize_) {
|
||||
this.boundingBox_ = path.getBoundingBox();
|
||||
}
|
||||
|
||||
this.scaleAndSetPath_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Scale the internal path to fit.
|
||||
* @private
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.scaleAndSetPath_ = function() {
|
||||
this.scaledPath_ = this.boundingBox_ ? this.path_.clone().modifyBounds(
|
||||
-this.boundingBox_.left, -this.boundingBox_.top,
|
||||
this.getWidth() / (this.boundingBox_.width || 1),
|
||||
this.getHeight() / (this.boundingBox_.height || 1)) : this.path_;
|
||||
|
||||
var wrapper = this.getWrapper();
|
||||
if (wrapper) {
|
||||
wrapper.setPath(this.scaledPath_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the ellipse. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.redraw = function() {
|
||||
goog.graphics.ext.Shape.superClass_.redraw.call(this);
|
||||
if (this.autoSize_) {
|
||||
this.scaleAndSetPath_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the shape is parent dependent.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.Shape.prototype.checkParentDependent = function() {
|
||||
return this.autoSize_ ||
|
||||
goog.graphics.ext.Shape.superClass_.checkParentDependent.call(this);
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A thick wrapper around elements with stroke and fill.
|
||||
* @author robbyw@google.com (Robby Walker)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.graphics.ext.StrokeAndFillElement');
|
||||
|
||||
goog.require('goog.graphics.ext.Element');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a graphics element that has a stroke and fill.
|
||||
* This is the base interface for ellipse, rectangle and other
|
||||
* shape interfaces.
|
||||
* You should not construct objects from this constructor. Use a subclass.
|
||||
* @param {goog.graphics.ext.Group} group Parent for this element.
|
||||
* @param {goog.graphics.StrokeAndFillElement} wrapper The thin wrapper to wrap.
|
||||
* @constructor
|
||||
* @extends {goog.graphics.ext.Element}
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement = function(group, wrapper) {
|
||||
goog.graphics.ext.Element.call(this, group, wrapper);
|
||||
};
|
||||
goog.inherits(goog.graphics.ext.StrokeAndFillElement,
|
||||
goog.graphics.ext.Element);
|
||||
|
||||
|
||||
/**
|
||||
* Sets the fill for this element.
|
||||
* @param {goog.graphics.Fill?} fill The fill object.
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement.prototype.setFill = function(fill) {
|
||||
this.getWrapper().setFill(fill);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the stroke for this element.
|
||||
* @param {goog.graphics.Stroke?} stroke The stroke object.
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement.prototype.setStroke = function(stroke) {
|
||||
this.getWrapper().setStroke(stroke);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Redraw the rectangle. Called when the coordinate system is changed.
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.graphics.ext.StrokeAndFillElement.prototype.redraw = function() {
|
||||
this.getWrapper().reapplyStroke();
|
||||
};
|
||||
Reference in New Issue
Block a user