| // 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; |
| }; |