Path: blob/trunk/third_party/closure/goog/graphics/ext/group.js
2868 views
// Copyright 2007 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.131415/**16* @fileoverview A thicker wrapper around graphics groups.17* @author [email protected] (Robby Walker)18*/192021goog.provide('goog.graphics.ext.Group');2223goog.require('goog.array');24goog.require('goog.graphics.ext.Element');25262728/**29* Wrapper for a graphics group.30* @param {goog.graphics.ext.Group} group Parent for this element. Can31* be null if this is a Graphics instance.32* @param {goog.graphics.GroupElement=} opt_wrapper The thin wrapper33* to wrap. If omitted, a new group will be created. Must be included34* when group is null.35* @constructor36* @extends {goog.graphics.ext.Element}37*/38goog.graphics.ext.Group = function(group, opt_wrapper) {39opt_wrapper = opt_wrapper ||40group.getGraphicsImplementation().createGroup(group.getWrapper());41goog.graphics.ext.Element.call(this, group, opt_wrapper);4243/**44* Array of child elements this group contains.45* @type {Array<goog.graphics.ext.Element>}46* @private47*/48this.children_ = [];49};50goog.inherits(goog.graphics.ext.Group, goog.graphics.ext.Element);515253/**54* Add an element to the group. This should be treated as package local, as55* it is called by the draw* methods.56* @param {!goog.graphics.ext.Element} element The element to add.57* @param {boolean=} opt_chain Whether this addition is part of a longer set58* of element additions.59*/60goog.graphics.ext.Group.prototype.addChild = function(element, opt_chain) {61if (!goog.array.contains(this.children_, element)) {62this.children_.push(element);63}6465var transformed = this.growToFit_(element);6667if (element.isParentDependent()) {68element.parentTransform();69}7071if (!opt_chain && element.isPendingTransform()) {72element.reset();73}7475if (transformed) {76this.reset();77}78};798081/**82* Remove an element from the group.83* @param {goog.graphics.ext.Element} element The element to remove.84*/85goog.graphics.ext.Group.prototype.removeChild = function(element) {86goog.array.remove(this.children_, element);8788// TODO(robbyw): shape.fireEvent('delete')8990this.getGraphicsImplementation().removeElement(element.getWrapper());91};929394/**95* Calls the given function on each of this component's children in order. If96* {@code opt_obj} is provided, it will be used as the 'this' object in the97* function when called. The function should take two arguments: the child98* component and its 0-based index. The return value is ignored.99* @param {Function} f The function to call for every child component; should100* take 2 arguments (the child and its index).101* @param {Object=} opt_obj Used as the 'this' object in f when called.102*/103goog.graphics.ext.Group.prototype.forEachChild = function(f, opt_obj) {104if (this.children_) {105goog.array.forEach(this.children_, f, opt_obj);106}107};108109110/**111* @return {goog.graphics.GroupElement} The underlying thin wrapper.112* @override113*/114goog.graphics.ext.Group.prototype.getWrapper;115116117/**118* Reset the element.119* @override120*/121goog.graphics.ext.Group.prototype.reset = function() {122goog.graphics.ext.Group.superClass_.reset.call(this);123124this.updateChildren();125};126127128/**129* Called from the parent class, this method resets any pre-computed positions130* and sizes.131* @protected132* @override133*/134goog.graphics.ext.Group.prototype.redraw = function() {135this.getWrapper().setSize(this.getWidth(), this.getHeight());136this.transformChildren();137};138139140/**141* Transform the children that need to be transformed.142* @protected143*/144goog.graphics.ext.Group.prototype.transformChildren = function() {145this.forEachChild(function(child) {146if (child.isParentDependent()) {147child.parentTransform();148}149});150};151152153/**154* As part of the reset process, update child elements.155*/156goog.graphics.ext.Group.prototype.updateChildren = function() {157this.forEachChild(function(child) {158if (child.isParentDependent() || child.isPendingTransform()) {159child.reset();160} else if (child.updateChildren) {161child.updateChildren();162}163});164};165166167/**168* When adding an element, grow this group's bounds to fit it.169* @param {!goog.graphics.ext.Element} element The added element.170* @return {boolean} Whether the size of this group changed.171* @private172*/173goog.graphics.ext.Group.prototype.growToFit_ = function(element) {174var transformed = false;175176var x = element.getMaxX();177if (x > this.getWidth()) {178this.setMinWidth(x);179transformed = true;180}181182var y = element.getMaxY();183if (y > this.getHeight()) {184this.setMinHeight(y);185transformed = true;186}187188return transformed;189};190191192/**193* @return {number} The width of the element's coordinate space.194*/195goog.graphics.ext.Group.prototype.getCoordinateWidth = function() {196return this.getWidth();197};198199200/**201* @return {number} The height of the element's coordinate space.202*/203goog.graphics.ext.Group.prototype.getCoordinateHeight = function() {204return this.getHeight();205};206207208/**209* Remove all drawing elements from the group.210*/211goog.graphics.ext.Group.prototype.clear = function() {212while (this.children_.length) {213this.removeChild(this.children_[0]);214}215};216217218