UNPKG

awayjs-display

Version:
588 lines 27.7 kB
"use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var ArgumentError_1 = require("awayjs-core/lib/errors/ArgumentError"); var RangeError_1 = require("awayjs-core/lib/errors/RangeError"); var DisplayObject_1 = require("../display/DisplayObject"); var HierarchicalProperties_1 = require("../base/HierarchicalProperties"); /** * The DisplayObjectContainer class is the base class for all objects that can * serve as display object containers on the display list. The display list * manages all objects displayed in the Flash runtimes. Use the * DisplayObjectContainer class to arrange the display objects in the display * list. Each DisplayObjectContainer object has its own child list for * organizing the z-order of the objects. The z-order is the front-to-back * order that determines which object is drawn in front, which is behind, and * so on. * * <p>DisplayObject is an abstract base class; therefore, you cannot call * DisplayObject directly. Invoking <code>new DisplayObject()</code> throws an * <code>ArgumentError</code> exception.</p> * The DisplayObjectContainer class is an abstract base class for all objects * that can contain child objects. It cannot be instantiated directly; calling * the <code>new DisplayObjectContainer()</code> constructor throws an * <code>ArgumentError</code> exception. * * <p>For more information, see the "Display Programming" chapter of the * <i>ActionScript 3.0 Developer's Guide</i>.</p> */ var DisplayObjectContainer = (function (_super) { __extends(DisplayObjectContainer, _super); /** * Calling the <code>new DisplayObjectContainer()</code> constructor throws * an <code>ArgumentError</code> exception. You <i>can</i>, however, call * constructors for the following subclasses of DisplayObjectContainer: * <ul> * <li><code>new Loader()</code></li> * <li><code>new Sprite()</code></li> * <li><code>new MovieClip()</code></li> * </ul> */ function DisplayObjectContainer() { _super.call(this); this._mouseChildren = true; this._depth_childs = {}; this._nextHighestDepth = 0; this._children = new Array(); } Object.defineProperty(DisplayObjectContainer.prototype, "assetType", { /** * */ get: function () { return DisplayObjectContainer.assetType; }, enumerable: true, configurable: true }); Object.defineProperty(DisplayObjectContainer.prototype, "mouseChildren", { /** * Determines whether or not the children of the object are mouse, or user * input device, enabled. If an object is enabled, a user can interact with * it by using a mouse or user input device. The default is * <code>true</code>. * * <p>This property is useful when you create a button with an instance of * the Sprite class(instead of using the SimpleButton class). When you use a * Sprite instance to create a button, you can choose to decorate the button * by using the <code>addChild()</code> method to add additional Sprite * instances. This process can cause unexpected behavior with mouse events * because the Sprite instances you add as children can become the target * object of a mouse event when you expect the parent instance to be the * target object. To ensure that the parent instance serves as the target * objects for mouse events, you can set the <code>mouseChildren</code> * property of the parent instance to <code>false</code>.</p> * * <p> No event is dispatched by setting this property. You must use the * <code>addEventListener()</code> method to create interactive * functionality.</p> */ get: function () { if (this._hierarchicalPropsDirty & HierarchicalProperties_1.default.MOUSE_ENABLED) this._updateMouseEnabled(); return this._mouseChildren; }, set: function (value) { if (this._mouseChildren == value) return; this._mouseChildren = value; this.pInvalidateHierarchicalProperties(HierarchicalProperties_1.default.MOUSE_ENABLED); }, enumerable: true, configurable: true }); Object.defineProperty(DisplayObjectContainer.prototype, "numChildren", { /** * Returns the number of children of this object. */ get: function () { return this._children.length; }, enumerable: true, configurable: true }); /** * Adds a child DisplayObject instance to this DisplayObjectContainer * instance. The child is added to the front(top) of all other children in * this DisplayObjectContainer instance.(To add a child to a specific index * position, use the <code>addChildAt()</code> method.) * * <p>If you add a child object that already has a different display object * container as a parent, the object is removed from the child list of the * other display object container. </p> * * <p><b>Note:</b> The command <code>stage.addChild()</code> can cause * problems with a published SWF file, including security problems and * conflicts with other loaded SWF files. There is only one Stage within a * Flash runtime instance, no matter how many SWF files you load into the * runtime. So, generally, objects should not be added to the Stage, * directly, at all. The only object the Stage should contain is the root * object. Create a DisplayObjectContainer to contain all of the items on the * display list. Then, if necessary, add that DisplayObjectContainer instance * to the Stage.</p> * * @param child The DisplayObject instance to add as a child of this * DisplayObjectContainer instance. * @return The DisplayObject instance that you pass in the <code>child</code> * parameter. * @throws ArgumentError Throws if the child is the same as the parent. Also * throws if the caller is a child(or grandchild etc.) * of the child being added. * @event added Dispatched when a display object is added to the display * list. */ DisplayObjectContainer.prototype.addChild = function (child) { return this.addChildAt(child, this._children.length); }; DisplayObjectContainer.prototype.addChildAtDepth = function (child, depth, replace) { if (replace === void 0) { replace = true; } if (child == null) throw new ArgumentError_1.default("Parameter child cannot be null."); //if child already has a parent, remove it. if (child._pParent) child._pParent.removeChildAtInternal(child._pParent.getChildIndex(child)); var index = this.getDepthIndexInternal(depth); if (index != -1) { if (replace) { this.removeChildAt(index); } else { //move depth of existing child up by 1 this.addChildAtDepth(this._children[index], depth + 1, false); } } if (this._nextHighestDepth < depth + 1) this._nextHighestDepth = depth + 1; this._depth_childs[depth] = child; this._children.push(child); child._depthID = depth; child.iSetParent(this); this._invalidateChildren(); return child; }; /** * Adds a child DisplayObject instance to this DisplayObjectContainer * instance. The child is added at the index position specified. An index of * 0 represents the back(bottom) of the display list for this * DisplayObjectContainer object. * * <p>For example, the following example shows three display objects, labeled * a, b, and c, at index positions 0, 2, and 1, respectively:</p> * * <p>If you add a child object that already has a different display object * container as a parent, the object is removed from the child list of the * other display object container. </p> * * @param child The DisplayObject instance to add as a child of this * DisplayObjectContainer instance. * @param index The index position to which the child is added. If you * specify a currently occupied index position, the child object * that exists at that position and all higher positions are * moved up one position in the child list. * @return The DisplayObject instance that you pass in the <code>child</code> * parameter. * @throws ArgumentError Throws if the child is the same as the parent. Also * throws if the caller is a child(or grandchild etc.) * of the child being added. * @throws RangeError Throws if the index position does not exist in the * child list. * @event added Dispatched when a display object is added to the display * list. */ DisplayObjectContainer.prototype.addChildAt = function (child, index) { return this.addChildAtDepth(child, (index < this._children.length) ? this._children[index]._depthID : this.getNextHighestDepth(), false); }; DisplayObjectContainer.prototype.addChildren = function () { var childarray = []; for (var _i = 0; _i < arguments.length; _i++) { childarray[_i - 0] = arguments[_i]; } var len = childarray.length; for (var i = 0; i < len; i++) this.addChild(childarray[i]); }; /** * */ DisplayObjectContainer.prototype.clone = function () { var newInstance = new DisplayObjectContainer(); this.copyTo(newInstance); return newInstance; }; DisplayObjectContainer.prototype.copyTo = function (newInstance) { _super.prototype.copyTo.call(this, newInstance); newInstance.mouseChildren = this._mouseChildren; var len = this._children.length; for (var i = 0; i < len; ++i) newInstance.addChild(this._children[i].clone()); }; /** * Determines whether the specified display object is a child of the * DisplayObjectContainer instance or the instance itself. The search * includes the entire display list including this DisplayObjectContainer * instance. Grandchildren, great-grandchildren, and so on each return * <code>true</code>. * * @param child The child object to test. * @return <code>true</code> if the <code>child</code> object is a child of * the DisplayObjectContainer or the container itself; otherwise * <code>false</code>. */ DisplayObjectContainer.prototype.contains = function (child) { return this._children.indexOf(child) >= 0; }; /** * */ DisplayObjectContainer.prototype.disposeValues = function () { for (var i = this._children.length - 1; i >= 0; i--) this.removeChild(this._children[i]); _super.prototype.disposeValues.call(this); }; DisplayObjectContainer.prototype.getChildAtDepth = function (depth) { return this._depth_childs[depth]; }; /** * Returns the child display object instance that exists at the specified * index. * * @param index The index position of the child object. * @return The child display object at the specified index position. * @throws RangeError Throws if the index does not exist in the child * list. */ DisplayObjectContainer.prototype.getChildAt = function (index /*int*/) { var child = this._children[index]; if (child == null) throw new RangeError_1.default("Index does not exist in the child list of the caller"); return child; }; /** * Returns the child display object that exists with the specified name. If * more that one child display object has the specified name, the method * returns the first object in the child list. * * <p>The <code>getChildAt()</code> method is faster than the * <code>getChildByName()</code> method. The <code>getChildAt()</code> method * accesses a child from a cached array, whereas the * <code>getChildByName()</code> method has to traverse a linked list to * access a child.</p> * * @param name The name of the child to return. * @return The child display object with the specified name. */ DisplayObjectContainer.prototype.getChildByName = function (name) { var len = this._children.length; for (var i = 0; i < len; ++i) if (this._children[i].name == name) return this._children[i]; return null; }; /** * Returns the index position of a <code>child</code> DisplayObject instance. * * @param child The DisplayObject instance to identify. * @return The index position of the child display object to identify. * @throws ArgumentError Throws if the child parameter is not a child of this * object. */ DisplayObjectContainer.prototype.getChildIndex = function (child) { var childIndex = this._children.indexOf(child); if (childIndex == -1) throw new ArgumentError_1.default("Child parameter is not a child of the caller"); return childIndex; }; DisplayObjectContainer.prototype.getNextHighestDepth = function () { if (this._nextHighestDepthDirty) this._updateNextHighestDepth(); return this._nextHighestDepth; }; /** * Returns an array of objects that lie under the specified point and are * children(or grandchildren, and so on) of this DisplayObjectContainer * instance. Any child objects that are inaccessible for security reasons are * omitted from the returned array. To determine whether this security * restriction affects the returned array, call the * <code>areInaccessibleObjectsUnderPoint()</code> method. * * <p>The <code>point</code> parameter is in the coordinate space of the * Stage, which may differ from the coordinate space of the display object * container(unless the display object container is the Stage). You can use * the <code>globalToLocal()</code> and the <code>localToGlobal()</code> * methods to convert points between these coordinate spaces.</p> * * @param point The point under which to look. * @return An array of objects that lie under the specified point and are * children(or grandchildren, and so on) of this * DisplayObjectContainer instance. */ DisplayObjectContainer.prototype.getObjectsUnderPoint = function (point) { return new Array(); }; /** * Removes the specified <code>child</code> DisplayObject instance from the * child list of the DisplayObjectContainer instance. The <code>parent</code> * property of the removed child is set to <code>null</code> , and the object * is garbage collected if no other references to the child exist. The index * positions of any display objects above the child in the * DisplayObjectContainer are decreased by 1. * * <p>The garbage collector reallocates unused memory space. When a variable * or object is no longer actively referenced or stored somewhere, the * garbage collector sweeps through and wipes out the memory space it used to * occupy if no other references to it exist.</p> * * @param child The DisplayObject instance to remove. * @return The DisplayObject instance that you pass in the <code>child</code> * parameter. * @throws ArgumentError Throws if the child parameter is not a child of this * object. */ DisplayObjectContainer.prototype.removeChild = function (child) { if (child == null) throw new ArgumentError_1.default("Parameter child cannot be null"); this.removeChildAt(this.getChildIndex(child)); return child; }; DisplayObjectContainer.prototype.removeChildAtDepth = function (depth /*int*/) { return this.removeChildAt(this.getDepthIndexInternal(depth)); }; /** * Removes a child DisplayObject from the specified <code>index</code> * position in the child list of the DisplayObjectContainer. The * <code>parent</code> property of the removed child is set to * <code>null</code>, and the object is garbage collected if no other * references to the child exist. The index positions of any display objects * above the child in the DisplayObjectContainer are decreased by 1. * * <p>The garbage collector reallocates unused memory space. When a variable * or object is no longer actively referenced or stored somewhere, the * garbage collector sweeps through and wipes out the memory space it used to * occupy if no other references to it exist.</p> * * @param index The child index of the DisplayObject to remove. * @return The DisplayObject instance that was removed. * @throws RangeError Throws if the index does not exist in the child * list. * @throws SecurityError This child display object belongs to a sandbox to * which the calling object does not have access. You * can avoid this situation by having the child movie * call the <code>Security.allowDomain()</code> method. */ DisplayObjectContainer.prototype.removeChildAt = function (index /*int*/) { var child = this.removeChildAtInternal(index); child.iSetParent(null); this._invalidateChildren(); return child; }; /** * Removes all <code>child</code> DisplayObject instances from the child list * of the DisplayObjectContainer instance. The <code>parent</code> property * of the removed children is set to <code>null</code>, and the objects are * garbage collected if no other references to the children exist. * * The garbage collector reallocates unused memory space. When a variable or * object is no longer actively referenced or stored somewhere, the garbage * collector sweeps through and wipes out the memory space it used to occupy * if no other references to it exist. * * @param beginIndex The beginning position. A value smaller than 0 throws a RangeError. * @param endIndex The ending position. A value smaller than 0 throws a RangeError. * @throws RangeError Throws if the beginIndex or endIndex positions do * not exist in the child list. */ DisplayObjectContainer.prototype.removeChildren = function (beginIndex, endIndex) { if (beginIndex === void 0) { beginIndex = 0; } if (endIndex === void 0) { endIndex = 2147483647; } if (beginIndex < 0) throw new RangeError_1.default("beginIndex is out of range of the child list"); if (endIndex > this._children.length) throw new RangeError_1.default("endIndex is out of range of the child list"); for (var i = beginIndex; i < endIndex; i++) this.removeChild(this._children[i]); }; /** * Changes the position of an existing child in the display object container. * This affects the layering of child objects. For example, the following * example shows three display objects, labeled a, b, and c, at index * positions 0, 1, and 2, respectively: * * <p>When you use the <code>setChildIndex()</code> method and specify an * index position that is already occupied, the only positions that change * are those in between the display object's former and new position. All * others will stay the same. If a child is moved to an index LOWER than its * current index, all children in between will INCREASE by 1 for their index * reference. If a child is moved to an index HIGHER than its current index, * all children in between will DECREASE by 1 for their index reference. For * example, if the display object container in the previous example is named * <code>container</code>, you can swap the position of the display objects * labeled a and b by calling the following code:</p> * * <p>This code results in the following arrangement of objects:</p> * * @param child The child DisplayObject instance for which you want to change * the index number. * @param index The resulting index number for the <code>child</code> display * object. * @throws ArgumentError Throws if the child parameter is not a child of this * object. * @throws RangeError Throws if the index does not exist in the child * list. */ DisplayObjectContainer.prototype.setChildIndex = function (child, index /*int*/) { //TODO }; /** * Swaps the z-order (front-to-back order) of the two specified child * objects. All other child objects in the display object container remain in * the same index positions. * * @param child1 The first child object. * @param child2 The second child object. * @throws ArgumentError Throws if either child parameter is not a child of * this object. */ DisplayObjectContainer.prototype.swapChildren = function (child1, child2) { this.swapChildrenAt(this.getChildIndex(child1), this.getChildIndex(child2)); }; /** * Swaps the z-order(front-to-back order) of the child objects at the two * specified index positions in the child list. All other child objects in * the display object container remain in the same index positions. * * @param index1 The index position of the first child object. * @param index2 The index position of the second child object. * @throws RangeError If either index does not exist in the child list. */ DisplayObjectContainer.prototype.swapChildrenAt = function (index1, index2) { var depth = this._children[index2]._depthID; var child = this._children[index1]; this.addChildAtDepth(this._children[index2], this._children[index1]._depthID); this.addChildAtDepth(child, depth); }; /** * //TODO * * @protected */ DisplayObjectContainer.prototype._pUpdateBoxBounds = function () { _super.prototype._pUpdateBoxBounds.call(this); var box; var numChildren = this._children.length; if (numChildren > 0) { var min; var max; var minX, minY, minZ; var maxX, maxY, maxZ; for (var i = 0; i < numChildren; ++i) { box = this._children[i].getBox(this); if (i == 0) { maxX = box.width + (minX = box.x); maxY = box.height + (minY = box.y); maxZ = box.depth + (minZ = box.z); } else { max = box.width + (min = box.x); if (min < minX) minX = min; if (max > maxX) maxX = max; max = box.height + (min = box.y); if (min < minY) minY = min; if (max > maxY) maxY = max; max = box.depth + (min = box.z); if (min < minZ) minZ = min; if (max > maxZ) maxZ = max; } } this._pBoxBounds.width = maxX - (this._pBoxBounds.x = minX); this._pBoxBounds.height = maxY - (this._pBoxBounds.y = minY); this._pBoxBounds.depth = maxZ - (this._pBoxBounds.z = minZ); } else { this._pBoxBounds.setEmpty(); } }; /** * @protected */ DisplayObjectContainer.prototype.pInvalidateHierarchicalProperties = function (bitFlag) { if (_super.prototype.pInvalidateHierarchicalProperties.call(this, bitFlag)) return true; var len = this._children.length; for (var i = 0; i < len; ++i) this._children[i].pInvalidateHierarchicalProperties(bitFlag); return false; }; /** * @internal */ DisplayObjectContainer.prototype._iSetScene = function (value, partition) { _super.prototype._iSetScene.call(this, value, partition); var len = this._children.length; for (var i = 0; i < len; ++i) this._children[i]._iSetScene(value, partition); }; /** * @private * * @param child */ DisplayObjectContainer.prototype.removeChildAtInternal = function (index) { var child = this._children.splice(index, 1)[0]; //update next highest depth if (this._nextHighestDepth == child._depthID + 1) this._nextHighestDepthDirty = true; delete this._depth_childs[child._depthID]; child._depthID = -16384; return child; }; DisplayObjectContainer.prototype.getDepthIndexInternal = function (depth /*int*/) { if (!this._depth_childs[depth]) return -1; return this._children.indexOf(this._depth_childs[depth]); }; DisplayObjectContainer.prototype._updateNextHighestDepth = function () { this._nextHighestDepthDirty = false; this._nextHighestDepth = 0; var len = this._children.length; for (var i = 0; i < len; i++) if (this._nextHighestDepth < this._children[i]._depthID) this._nextHighestDepth = this._children[i]._depthID; this._nextHighestDepth += 1; }; DisplayObjectContainer.prototype._hitTestPointInternal = function (x, y, shapeFlag, masksFlag) { var numChildren = this._children.length; for (var i = 0; i < numChildren; i++) if (this._children[i].hitTestPoint(x, y, shapeFlag, masksFlag)) return true; return false; }; DisplayObjectContainer.prototype._updateMaskMode = function () { if (this.maskMode) this.mouseChildren = false; _super.prototype._updateMaskMode.call(this); }; DisplayObjectContainer.prototype._invalidateChildren = function () { if (this._pIsContainer != Boolean(this._children.length)) { if (this._pImplicitPartition) this._pImplicitPartition._iUnregisterEntity(this); this._pIsContainer = Boolean(this._children.length); if (this._pImplicitPartition) this._pImplicitPartition._iRegisterEntity(this); } this._pInvalidateBounds(); }; DisplayObjectContainer.assetType = "[asset DisplayObjectContainer]"; return DisplayObjectContainer; }(DisplayObject_1.default)); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DisplayObjectContainer; //# sourceMappingURL=DisplayObjectContainer.js.map