PageRenderTime 1958ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/src/com/panosalado/core/PanoSalado.as

http://github.com/mstandio/SaladoPlayer
ActionScript | 591 lines | 334 code | 51 blank | 206 comment | 83 complexity | d8e8d6516bfad479cd502ecadf46fbe3 MD5 | raw file
Possible License(s): LGPL-3.0
  1. /*
  2. Copyright 2010 Zephyr Renner.
  3. This file is part of PanoSalado.
  4. PanoSalado is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. PanoSalado is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with PanoSalado. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package com.panosalado.core{
  16. import com.panosalado.controller.*;
  17. import com.panosalado.events.*;
  18. import com.panosalado.model.*;
  19. import com.panosalado.utils.*;
  20. import com.panosalado.view.*;
  21. import com.robertpenner.easing.*;
  22. import flash.display.Bitmap;
  23. import flash.display.BitmapData;
  24. import flash.display.DisplayObject;
  25. import flash.display.Sprite;
  26. import flash.events.Event;
  27. import flash.geom.Matrix3D;
  28. import flash.geom.Vector3D;
  29. import flash.utils.getQualifiedClassName;
  30. /**
  31. * Dispatched when a new panorama has loaded.
  32. *
  33. * @eventType flash.events.Event.COMPLETE
  34. */
  35. [Event(name="complete", type="flash.events.Event")]
  36. /**
  37. * Dispatched after PanoSalado finishes changing view properties as a result of API calls: loadPanorama,
  38. * renderAt, swingTo, swingToChild, startInertialSwing/stopInertialSwing.
  39. * With
  40. *
  41. * @eventType com.panosalado.events.CameraEvent.INACTIVE
  42. */
  43. [Event(name="inactive", type="com.panosalado.events.CameraEvent")]
  44. /**
  45. * Dispatched before PanoSalado begins to change view properties as a result of API calls: loadPanorama,
  46. * renderAt, swingTo, swingToChild, startInertialSwing/stopInertialSwing.
  47. *
  48. * @eventType com.panosalado.events.CameraEvent.ACTIVE
  49. */
  50. [Event(name="active", type="com.panosalado.events.CameraEvent")]
  51. /**
  52. * Dispatched after a swingTo is complete
  53. *
  54. * @eventType com.panosalado.events.PanoSaladoEvent.SWING_TO_COMPLETE
  55. */
  56. [Event(name="swingToComplete", type="com.panosalado.events.PanoSaladoEvent")]
  57. /**
  58. * Dispatched after a swingToChild is complete
  59. *
  60. * @eventType com.panosalado.events.PanoSaladoEvent.SWING_TO_CHILD_COMPLETE
  61. */
  62. [Event(name="swingToChildComplete", type="com.panosalado.events.PanoSaladoEvent")]
  63. /**
  64. * Displays panoramic images. Implements the Model, View, Controller paradigm.
  65. * The Model is the ViewData superclass, which extends Sprite. (This is done so that view data properties are
  66. * directly gettable / settable on an instance of PanoSalado.
  67. * The View is this class, along with a helper class like Panorama, which renders the panorama.
  68. * In the case of Panorama, the panorama is rendered as a vector to a Graphics object.
  69. * However, other renders could be implemented.
  70. * The Controllers are all optional and are passed in an array into the initialize() function.
  71. * Finally, this class contains a variety of public methods for modifying the ViewData model class to aid
  72. * in implementing "usual suspect" type functionality: loadPanorama(), renderAt(), swingTo(),
  73. * swingToChild(), startInertialSwing(), stopInertialSwing(), etc. The functionalities of all of these convenience
  74. * methods can also be had through direct manipulation of the ViewData properties.
  75. */
  76. public class PanoSalado extends ViewData implements ICamera{
  77. protected var _dependencyRelay :DependencyRelay;
  78. protected var _stageReference :StageReference;
  79. protected var _params :Object;
  80. protected var _background :Sprite;
  81. protected var _canvas :Sprite;
  82. protected var _canvasInternal :Sprite;
  83. protected var _children :Sprite;
  84. protected var _managedChildren :Sprite;
  85. protected var _renderFunction :Function;
  86. public function PanoSalado() {
  87. trace("PanoSalado2");
  88. _dependencyRelay = new DependencyRelay(false);
  89. _stageReference = new StageReference(true);
  90. _params = {};
  91. _background = new Sprite();
  92. _canvas = new Sprite();
  93. _canvasInternal = new Sprite();
  94. _children = new Sprite();
  95. _managedChildren = new Sprite();
  96. //_canvas.blendMode = BlendMode.LAYER; COREMOD: shows overlapping tiles when loading panorama but makes viewing much more fluent
  97. //_managedChildren.visible = false;
  98. $addChild(_background); //this one first so it is underneath
  99. $addChild(_canvas);
  100. _canvas.addChild(_canvasInternal);
  101. _canvasInternal.addChild(_managedChildren);
  102. $addChild(_children); // this one on top. for unmanaged children. buttons, etc.
  103. _dependencyRelay.addDependency(this, Characteristics.VIEW_DATA);
  104. //_dependencyRelay.addCallback(processDependency);
  105. _dependencyRelay.addCallback(_stageReference.processDependency);
  106. _dependencyRelay.addCallback(TilePyramid.processDependency);
  107. addEventListener(ViewEvent.NULL_PATH, clearGraphics, false, 0, true);
  108. }
  109. /**
  110. * @param reference Object
  111. * @param characteristics *
  112. */
  113. public function processDependency(reference:Object, characteristics:*):void{} // to satisfy ICamera
  114. /**
  115. * PanoSalado accepts an Array of Objects as dependencies for itself and for the other dependencies in the list.
  116. * This offers a means for any instance of a class passed in to the array to store a reference to any other
  117. * instance of a class passed in to the array. PanoSalado uses flash.utils.getQualifiedClassName()
  118. * on each dependency to create the characteristics object which provides an auxiliary means for the dependency
  119. * to identify itself to other dependencies looking for it. (This is in addition to the actual reference to the
  120. * dependency). Each dependency will be checked for a "processDependency" function, and if found the function will
  121. * be invoked with each dependency in the order of the dependencies Array.
  122. * @param dependencies Array of Objects
  123. * @see processDependency
  124. */
  125. public function initialize(dependencies:Array):void {
  126. for each (var dependency:* in dependencies) {
  127. if (dependency.hasOwnProperty("processDependency")) _dependencyRelay.addCallback(dependency.processDependency);
  128. _dependencyRelay.addDependency(dependency, flash.utils.getQualifiedClassName(dependency));
  129. if (dependency.hasOwnProperty("stageReference")) _stageReference.addNotification(dependency);
  130. }
  131. }
  132. public function get renderFunction():Function { return _renderFunction; }
  133. public function set renderFunction(value:Function):void {
  134. if (_renderFunction === value) return;
  135. _renderFunction = value;
  136. if (value != null)
  137. addEventListener(Event.RENDER, render, false, 0, true);
  138. else
  139. removeEventListener(Event.RENDER, render, false);
  140. }
  141. /**
  142. * Lowest Sprite
  143. */
  144. public function get background():Sprite { return _background; }
  145. /**
  146. * The Sprite whose x,y values can be used to move the primary panorama. Also the Sprite on which the BlendMode is set to LAYER.
  147. */
  148. public function get canvas():Sprite { return _canvas; }
  149. /**
  150. * The Sprite whose graphics object is used to draw the primary panorama. It's x,y is always at half the panorama's width, height.
  151. */
  152. public function get canvasInternal():Sprite { return _canvasInternal; }
  153. /**
  154. * The Sprite which is the container for all ManagedChild extending children of the primary panorama (hotspots usually).
  155. * When a child is added to PanoSalado, its class is checked for ManagedChild and if true, it will be added to this
  156. * Sprite and managed as part of the current panorama.
  157. */
  158. public function get managedChildren():Sprite { return _managedChildren; }
  159. /**
  160. * The Sprite which is the container for all children which do NOT extend ManagedChild.
  161. */
  162. public function get children():Sprite { return _children; };
  163. /**
  164. * function that draws the panorama. Normally it is not necessary to call this function at all; normally the function
  165. * is called to handle a RENDER event caused by setting a property on the ViewData instance with invalidates the stage.
  166. * However, this function can be called WITHOUT an event arg, and WITH a viewData arg in order to predict and start loading
  167. * images for the values in the viewData arg. Calling it with a null Event will not cause any drawing.
  168. * @param event Event non-null value will result in drawing using the superclass ViewData's properties
  169. * @param viewData ViewData non-null value will result in using this ViewData's properties
  170. */
  171. final public function render(event:Event = null, viewData:ViewData = null):void {
  172. if (viewData == null) viewData = this; //if other viewData was passed in, use it instead. useful for predicting future needed bitmaps.
  173. if (!viewData._tile ) return;
  174. if (viewData._tile && viewData.invalid) {
  175. _renderFunction(viewData, event ? _canvasInternal.graphics : null);
  176. if (viewData.invalidPerspective) {
  177. _managedChildren.transform.perspectiveProjection = viewData.perspectiveProjection;
  178. _canvasInternal.x = viewData._boundsWidth * 0.5;
  179. _canvasInternal.y = viewData._boundsHeight * 0.5;
  180. }
  181. viewData.invalid = viewData.invalidTransform = viewData.invalidPerspective = false;
  182. viewData.dispatchEvent(new ViewEvent(ViewEvent.RENDERED, event?_canvas:null));
  183. }
  184. updateChildren(viewData);
  185. }
  186. /**
  187. * Clears the graphics objects if path or secondaryPath are null.
  188. */
  189. protected function clearGraphics(e:Event):void {
  190. if (_path == null) _canvasInternal.graphics.clear();
  191. }
  192. /**
  193. * Updates the position of all managedChildren of PanoSalado
  194. * @see managedChildren
  195. */
  196. final protected function updateChildren(viewData:ViewData):void {
  197. for (var i:int = 0; i < _managedChildren.numChildren; i++) {
  198. var child:ManagedChild = _managedChildren.getChildAt(i) as ManagedChild;
  199. var matrix3D:Matrix3D = child._matrix3D;
  200. if (child.invalid) {
  201. matrix3D.recompose(child._decomposition);
  202. child.invalid = false;
  203. }
  204. matrix3D = matrix3D.clone();
  205. matrix3D.append(viewData.transformMatrix3D);
  206. matrix3D.appendTranslation(0, 0, -viewData.perspectiveProjection.focalLength);
  207. if (!child.flat) {
  208. child.transform.matrix3D = matrix3D;
  209. }else {
  210. var pos:Vector3D = matrix3D.decompose()[0];
  211. var t:Number = viewData.perspectiveProjection.focalLength / (viewData.perspectiveProjection.focalLength + pos.z);
  212. if (t > 0) {
  213. child.flatX = pos.x * t;
  214. child.flatY = pos.y * t;
  215. }else {
  216. child.flatX = 9999;
  217. child.flatY = 9999;
  218. }
  219. }
  220. }
  221. }
  222. /**
  223. * Loads a new panorama. This operation is asynchronous. The new panorama does not exist until PanoSalado
  224. * dispatches a COMPLETE event, at which time, all the properties of the Params arg will be copied the the
  225. * superclass ViewData. Any properties not specified in the Params object will be untouched. If you wish a panorama
  226. * to open with pan, tilt, fieldOfView of 0,0,120 create a Params object with those values, and all other values
  227. * will be inherited as they are. The only property of Params that must be set is the path.
  228. * @param Params
  229. */
  230. public function loadPanorama(params:Params):void {
  231. //if value is null then use the current value. i.e. new panorama inherits last panorama's values
  232. if (params == null || params.path == null) throw new Error("PanoSalado.loadPanorama() requires a non-null Params argument");
  233. var p:String = params.path;
  234. this.path = p;
  235. _params[p] = params;
  236. }
  237. //TODO: loadPanorama(params:Params,children:Vector.<DisplayObject>) and add children in commitPath AFTER PATH event.
  238. /**
  239. * Copies all the properties in the Params object received in loadPanorama to the current panorama.
  240. * @see loadPanorama
  241. */
  242. override protected function commitPath(e:ReadyEvent, updateFOV:Boolean = true):void {
  243. dispatchEvent(new CameraEvent(CameraEvent.ACTIVE));
  244. var path:String = e.tilePyramid.path;
  245. var params:Params = _params[path];
  246. if (params == null) { //path was set directly, so go to super's behavior directly
  247. super.commitPath(e, true);
  248. return;
  249. }
  250. if (canvas != null && canvas.width > 0 && canvas.height > 0) { // COREMOD, entire section
  251. try{
  252. var bd:BitmapData = new BitmapData(canvas.width, canvas.height);
  253. bd.draw(canvas);
  254. var bmp:Bitmap = new Bitmap(bd);
  255. bmp.alpha = canvas.alpha;
  256. _background.addChild(bmp);
  257. }catch(e:Error){}
  258. }
  259. updateFOV = (params.minFov) ? true : false ;
  260. _params[path] = null;
  261. params.path = null;
  262. params.copyInto(this as ViewData);
  263. super.commitPath(e, updateFOV);
  264. dispatchEvent( new CameraEvent(CameraEvent.INACTIVE));
  265. }
  266. /**
  267. * Renders the panorama at the specified pan,tilt,fieldOfView. This is a convenience method for directly setting
  268. * pan,tilt,fieldOfView. Any of the values will be untouched if NaN is passed. It also dispatches CameraEvent.ACTIVE and CameraEvent.INACTIVE before and after the changes
  269. * to stop autorotation for the benefit of any listening objects (AutorotationCamera).
  270. * @param pan Number (optional) pass NaN to use the current value
  271. * @param tilt Number (optional) pass NaN to use the current value
  272. * @param fieldOfView Number (optional) pass NaN to use the current value
  273. */
  274. public function renderAt(pan:Number = NaN, tilt:Number = NaN, fieldOfView:Number = NaN):void {
  275. if (isNaN(pan) && isNaN(tilt) && isNaN(fieldOfView)) return;
  276. //if value is null use the current value
  277. dispatchEvent(new CameraEvent(CameraEvent.ACTIVE));
  278. if (!isNaN(pan)) this.pan = pan;
  279. if (!isNaN(tilt)) this.tilt = tilt;
  280. if (!isNaN(fieldOfView)) this.fieldOfView = fieldOfView;
  281. dispatchEvent(new CameraEvent(CameraEvent.INACTIVE));
  282. }
  283. /**
  284. * Swings the camera to the specified pan,tilt,fieldOfView with the specified speed, using the specified tween
  285. * function (with a standard Robert Penner tween function signature). NaN passed for pan, tilt, or fieldOfView will
  286. * not changed the current value. It also dispatches CameraEvent.ACTIVE and CameraEvent.INACTIVE before and after the changes
  287. * to stop autorotation for the benefit of any listening objects (AutorotationCamera).
  288. * @param pan Number (optional) pass NaN to use the current value
  289. * @param tilt Number (optional) pass NaN to use the current value
  290. * @param fieldOfView Number (optional) pass NaN to use the current value
  291. * @param speed Number (optional) defaults to 20
  292. * @param tween Function (optional) defaults to Linear.easeNone. Function must have signature: function name (t:Number, b:Number, c:Number, d:Number):Number
  293. */
  294. public function swingTo(pan:Number = NaN, tilt:Number = NaN, fieldOfView:Number = NaN, speed:Number = 30, tween:Function = null):void {
  295. if (isNaN(pan) && isNaN(tilt) && isNaN(fieldOfView)) return;
  296. //if value is null then use current value
  297. dispatchEvent(new CameraEvent(CameraEvent.ACTIVE));
  298. var animation:Animation;
  299. if (tween == null) tween = Linear.easeNone;
  300. var properties:Vector.<String> = new Vector.<String>();
  301. var values:Vector.<Number> = new Vector.<Number>();
  302. if (!isNaN(pan)) {
  303. if (_pan - pan > 180) pan += 360;
  304. else if (_pan - pan < -180) pan -= 360;
  305. properties.push("pan");
  306. values.push(pan);
  307. }else {
  308. pan = 0;
  309. }
  310. if (!isNaN(tilt)) {
  311. properties.push("tilt");
  312. values.push(tilt);
  313. }else {
  314. tilt = 0;
  315. }
  316. if (!isNaN(fieldOfView)) {
  317. properties.push("fieldOfView");
  318. values.push(fieldOfView);
  319. }
  320. var time:Number = (Math.acos((Math.sin(_tilt * Math.PI / 180) * Math.sin(tilt * Math.PI / 180))
  321. + (Math.cos(_tilt*Math.PI/180) * Math.cos(tilt*Math.PI/180) * Math.cos((Math.abs(_pan - pan))*Math.PI/180)))*(180/Math.PI)) / speed;
  322. animation = new Animation(this,properties,values,time,tween);
  323. animation.addEventListener(Event.COMPLETE, swingToComplete, false, 0, true);
  324. }
  325. /**
  326. * @private
  327. */
  328. protected function swingToComplete(e:Event):void {
  329. dispatchEvent(new PanoSaladoEvent(PanoSaladoEvent.SWING_TO_COMPLETE));
  330. dispatchEvent(new CameraEvent(CameraEvent.INACTIVE));
  331. }
  332. /**
  333. * Swings the camera to the specified ManagedChild, fieldOfView, with the specified speed, using the
  334. * specified tween function (standard Robert Penner style signature). This function dispatches
  335. * CameraEvent.ACTIVE and CameraEvent.INACTIVE before the motion starts and after it ceases, respectively.
  336. * @param child ManagedChild
  337. * @param fieldOfView Number (optional) pass NaN to use the current value
  338. * @param speed Number (optional) defaults to 20
  339. * @param tween Function (optional) defaults to Linear.easeNone. Function must have signature: function name (t:Number, b:Number, c:Number, d:Number):Number
  340. */
  341. public function swingToChild(child:ManagedChild, fieldOfView:Number = NaN, speed:Number = 30, tween:Function = null):void {
  342. if (child == null) return;
  343. dispatchEvent(new CameraEvent(CameraEvent.ACTIVE));
  344. if (tween == null) tween = Linear.easeNone;
  345. var childPan:Number = Math.atan2(child.x, child.z) * 180 / Math.PI;
  346. var childTilt:Number = -Math.atan2(child.y, Math.sqrt(child.x * child.x + child.z * child.z)) * 180 / Math.PI;
  347. if (_pan - childPan > 180) childPan += 360;
  348. else if (_pan - childPan < -180) childPan -= 360;
  349. var animation:Animation;
  350. var properties:Vector.<String> = new Vector.<String>();
  351. var values:Vector.<Number> = new Vector.<Number>();
  352. properties.push("pan","tilt");
  353. values.push(childPan, childTilt);
  354. if (!isNaN(fieldOfView)) {
  355. properties.push("fieldOfView");
  356. values.push(fieldOfView);
  357. }
  358. var time:Number = (Math.acos((Math.sin(_tilt * Math.PI / 180) * Math.sin(childTilt * Math.PI / 180))
  359. + (Math.cos(_tilt*Math.PI/180) * Math.cos(childTilt*Math.PI/180) * Math.cos((Math.abs(_pan - childPan))*Math.PI/180)))*(180/Math.PI)) / speed;
  360. animation = new Animation(this, properties, values, time, tween);
  361. animation.addEventListener(Event.COMPLETE, swingToChildComplete, false, 0, true);
  362. }
  363. protected function swingToChildComplete(e:Event):void {
  364. dispatchEvent(new PanoSaladoEvent(PanoSaladoEvent.SWING_TO_CHILD_COMPLETE));
  365. dispatchEvent(new CameraEvent(CameraEvent.INACTIVE));
  366. }
  367. protected var _now:int;
  368. protected var _deltaPan:Number;
  369. protected var _deltaTilt:Number;
  370. protected var _panSpeed:Number;
  371. protected var _tiltSpeed:Number;
  372. protected var _sensitivity:Number;
  373. protected var _friction:Number;
  374. protected var _threshold:Number;
  375. /**
  376. * Starts inertial motion (like the InertialMouseCamera) with the specified panSpeed, tiltSpeed using
  377. * the specified sensitivity, friction, and threshold. For a panning motion (horizontal) pass a positive or negative non-zero
  378. * (positive = right) panSpeed value. For tilt, pass a non-zero tiltSpeed value (positive = up). Calling stopInertialSwing()
  379. * will zero out panSpeed and tiltSpeed, and slow the motion to a stop once the delta motion is under the threshold value.
  380. * Subsequent calls to this function, but prior to calling stopInertialSwing() will modified the values but continue the motion.
  381. * Calling stopInertialSwing() is identical in function to calling startInertialSwing(0,0). This function dispatches
  382. * CameraEvent.ACTIVE and CameraEvent.INACTIVE before the motion starts and after it ceases, respectively.
  383. * @param panSpeed Number (< 0 = left; > 0 right) the larger the absolute value, the faster the motion
  384. * @param tiltSpeed Number (< 0 = down; > 0 up) the larger the absolute value, the faster the motion
  385. * @param sensitivity Number (optional) defaults to 0.0003
  386. * @param friction Number (optional) defaults to 0.3
  387. * @param threshold Number (optional) defaults to 0.0001
  388. */
  389. public function startInertialSwing(panSpeed:Number,tiltSpeed:Number,sensitivity:Number = 0.0003,friction:Number = 0.3,threshold:Number = 0.0001):void {
  390. dispatchEvent(new CameraEvent(CameraEvent.ACTIVE));
  391. _now = (isNaN(_now) || _now == 0) ? flash.utils.getTimer() : _now;
  392. _deltaPan = isNaN(_deltaPan) ? 0 : _deltaPan;
  393. _deltaTilt = isNaN(_deltaTilt) ? 0 : _deltaTilt;
  394. _panSpeed = panSpeed;
  395. _tiltSpeed = tiltSpeed;
  396. _sensitivity = sensitivity;
  397. _friction = friction;
  398. _threshold = threshold;
  399. addEventListener(Event.ENTER_FRAME, inertialSwingEnterFrameHandler, false, 0, true);
  400. dispatchEvent(new CameraEvent(CameraEvent.ACTIVE));
  401. }
  402. /**
  403. * @private
  404. */
  405. protected function inertialSwingEnterFrameHandler(e:Event):void {
  406. var now:int = flash.utils.getTimer();
  407. var elapsedTime:int = now - _now;
  408. _now = now;
  409. _deltaPan -= _panSpeed * elapsedTime * _sensitivity;
  410. _deltaTilt -= _tiltSpeed * elapsedTime * _sensitivity;
  411. if ((_deltaPan * _deltaPan + _deltaTilt * _deltaTilt) > _threshold){
  412. // always apply friction so that motion slows
  413. var inverseFriction:Number = 1 - _friction;
  414. _deltaPan *= inverseFriction;
  415. _deltaTilt *= inverseFriction;
  416. pan += _deltaPan;
  417. tilt -= _deltaTilt;
  418. if (_tilt < - 90) tilt -= (_tilt + 90) * _friction * 2;
  419. else if ( _tilt > 90 ) tilt -= (_tilt - 90) * _friction * 2;
  420. }else { // motion is under threshold
  421. _now = NaN;
  422. _deltaPan = NaN;
  423. _deltaTilt = NaN;
  424. _panSpeed = NaN;
  425. _tiltSpeed = NaN;
  426. _sensitivity = NaN;
  427. _friction = NaN;
  428. _threshold = NaN;
  429. removeEventListener(Event.ENTER_FRAME, inertialSwingEnterFrameHandler);
  430. dispatchEvent(new CameraEvent(CameraEvent.INACTIVE));
  431. }
  432. }
  433. /**
  434. * Stops the inertial motion caused by a call to startInertialSwing(). This is identical to calling
  435. * startInertialSwing(0,0). Motion does not cease immediately; it slows until it is under the threshold
  436. * specified in startInertialSwing().
  437. */
  438. public function stopInertialSwing():void {
  439. _panSpeed = 0;
  440. _tiltSpeed = 0;
  441. }
  442. override public function addChild(child:DisplayObject):DisplayObject {
  443. if (child is IManagedChild) managedChildren.addChild(child)
  444. else children.addChild(child);
  445. return child;
  446. }
  447. /**
  448. * @private
  449. */
  450. public function $addChild(child:DisplayObject):DisplayObject { //not recommended to use this publicly
  451. return super.addChild(child);
  452. }
  453. override public function addChildAt(child:DisplayObject, index:int):DisplayObject {
  454. if (child is IManagedChild) managedChildren.addChildAt(child, index)
  455. else children.addChildAt(child, index);
  456. return child;
  457. }
  458. /**
  459. * @private
  460. */
  461. public function $addChildAt(child:DisplayObject, index:int):DisplayObject { //not recommended to use this publicly
  462. return super.addChildAt(child, index);
  463. }
  464. override public function contains(child:DisplayObject):Boolean {
  465. var ret:Boolean;
  466. if (child is IManagedChild) ret = managedChildren.contains(child)
  467. else ret = children.contains(child);
  468. return ret;
  469. }
  470. /**
  471. * Allows access to getChildAt() to get a managed or normal child depending on the managed switch
  472. * @param index int
  473. * @param managed Boolean
  474. */
  475. public function _getChildAt(index:int, managed:Boolean):DisplayObject {
  476. var ret:DisplayObject;
  477. if (managed) ret = managedChildren.getChildAt(index)
  478. else ret = children.getChildAt(index);
  479. return ret;
  480. }
  481. /**
  482. * Allows access to getChildByName() to get a managed or normal child depending on the managed switch
  483. * @param name String
  484. * @param managed Boolean
  485. */
  486. public function _getChildByName(name:String, managed:Boolean):DisplayObject {
  487. var ret:DisplayObject;
  488. if (managed) ret = managedChildren.getChildByName(name)
  489. else ret = children.getChildByName(name);
  490. return ret;
  491. }
  492. override public function getChildIndex(child:DisplayObject):int {
  493. var ret:int;
  494. if (child is IManagedChild) ret = managedChildren.getChildIndex(child)
  495. else ret = children.getChildIndex(child);
  496. return ret;
  497. }
  498. override public function removeChild(child:DisplayObject):DisplayObject {
  499. if (child is IManagedChild) managedChildren.removeChild(child)
  500. else children.removeChild(child);
  501. return child;
  502. }
  503. /**
  504. * Allows access to removeChildAt() for a managed or normal child depending on the managed switch
  505. * @param index int
  506. * @param managed Boolean
  507. */
  508. public function _removeChildAt(index:int, managed:Boolean):DisplayObject {
  509. var ret:DisplayObject;
  510. if (managed) ret = managedChildren.removeChildAt(index)
  511. else ret = children.removeChildAt(index);
  512. return ret;
  513. }
  514. override public function setChildIndex(child:DisplayObject, index:int):void {
  515. if (child is IManagedChild) managedChildren.setChildIndex(child, index)
  516. else children.setChildIndex(child, index);
  517. }
  518. override public function swapChildren(child1:DisplayObject, child2:DisplayObject):void {
  519. if (child1 is IManagedChild && child2 is IManagedChild) managedChildren.swapChildren(child1, child2)
  520. else children.swapChildren(child1, child2);
  521. }
  522. /**
  523. * Allows access to swapChildrenAt() for managed or normal children depending on the managed switch
  524. * @param index1 int
  525. * @param index2 int
  526. * @param managed Boolean
  527. */
  528. public function _swapChildrenAt(index1:int, index2:int, managed:Boolean):void {
  529. if (managed) managedChildren.swapChildrenAt(index1, index2)
  530. else children.swapChildrenAt(index1, index2);
  531. }
  532. override public function get numChildren():int {
  533. return managedChildren.numChildren + children.numChildren;
  534. }
  535. }
  536. }