| // 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.EventTarget'); |
| goog.require('goog.functions'); |
| 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. */ |
| 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; |
| |