PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/camo/core/display/AbstractDisplay.as

https://github.com/stewymac07/SG-Camo-Collections
ActionScript | 561 lines | 320 code | 119 blank | 122 comment | 15 complexity | 13a6825e8a77360696dcd12d343a92cd MD5 | raw file
  1. /**
  2. * <p>Original Author: jessefreeman</p>
  3. * <p>Class File: AbstarctDisplay.as</p>
  4. *
  5. * <p>Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:</p>
  11. *
  12. * <p>The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.</p>
  14. *
  15. * <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.</p>
  22. *
  23. * <p>Licensed under The MIT License</p>
  24. * <p>Redistributions of files must retain the above copyright notice.</p>
  25. *
  26. * <p>Revisions<br/>
  27. * 2.0 Initial version Jan 7, 2009</p>
  28. *
  29. * * Changes made on Sept 05, 2009 - Glenn (commented)
  30. *
  31. */
  32. package camo.core.display
  33. {
  34. import flash.geom.Point;
  35. import sg.camo.interfaces.IDisplayBase;
  36. import camo.core.events.CamoDisplayEvent;
  37. import camo.core.events.CamoChildEvent;
  38. //import flash.display.BitmapData; // BitmapData unnecessary for AbstractDisplay
  39. import flash.display.DisplayObject;
  40. import flash.display.Sprite;
  41. import flash.errors.IllegalOperationError;
  42. import flash.events.Event;
  43. import flash.utils.Dictionary;
  44. import flash.display.Stage;
  45. // Include camo interfaces
  46. import sg.camo.interfaces.IRecursableDestroyable;
  47. import sg.camo.interfaces.IDestroyable;
  48. import sg.camo.interfaces.IAncestorSprite;
  49. import sg.camo.SGCamoSettings;
  50. /**
  51. * The base class for the Flash Camouflage display core.
  52. * <br/><br/>
  53. * For more information on the whole Flash Camouflage display core and AbstractDisplay in general, refer
  54. * to:
  55. * <br/><br/>
  56. * For more information on the nature of the class' methods, refer to the following interfaces:
  57. * @see camo.core.display.IDisplay
  58. * @see sg.camo.interfaces.IAncestorSprite
  59. *
  60. * @author jessefreeman
  61. *
  62. * @author glenn (changes commented with text)
  63. *
  64. *
  65. *
  66. */
  67. public class AbstractDisplay extends Sprite implements IDisplay, IDisplayBase, IRecursableDestroyable, IAncestorSprite
  68. {
  69. /**
  70. * The child <code>display</code> Sprite reference.
  71. * @see camo.core.display.IDisplay
  72. */
  73. protected var display : Sprite;
  74. /** @private */
  75. protected var _id : String;
  76. /** @private */
  77. protected var _invalid : Boolean;
  78. /** @private */
  79. protected var _width : Number = 0;
  80. /** @private */
  81. protected var _height : Number = 0;
  82. // indicator to denote size/add/remove child changes which normally requires the draw event to bubble up the display list,
  83. /** @private */
  84. protected var _bubblingDraw:Boolean = false;
  85. //protected var invalidated : Dictionary = new Dictionary( ); // <- not being used in this version
  86. /** @private Flag to determine */
  87. protected var _destroyChildren:Boolean = SGCamoSettings.DESTROY_CHILDREN;
  88. public function get id() : String
  89. {
  90. return _id;
  91. }
  92. public function set id( value : String ) : void
  93. {
  94. _id = value;
  95. }
  96. public override function get width() : Number
  97. {
  98. return _width;
  99. }
  100. public function get __width():Number {
  101. return _width;
  102. }
  103. public override function set width( value : Number ) : void
  104. {
  105. if ( _width == value ) return;
  106. _bubblingDraw = true;
  107. _width = ! isNaN( value ) ? value : 0;
  108. invalidate( );
  109. }
  110. public override function get height() : Number
  111. {
  112. return _height;
  113. }
  114. public function get __height():Number {
  115. return _height;
  116. }
  117. public function set __width(val:Number):void {
  118. _width = val;
  119. _bubblingDraw = true;
  120. invalidate();
  121. }
  122. public function set __height(val:Number):void {
  123. _height = val;
  124. _bubblingDraw = true;
  125. invalidate();
  126. }
  127. public function get displayWidth():Number {
  128. return _width;
  129. }
  130. public function get displayHeight():Number {
  131. return _height;
  132. }
  133. public function get $width():Number {
  134. return super.width;
  135. }
  136. public function get $height():Number {
  137. return super.height;
  138. }
  139. public function set $width(val:Number):void {
  140. super.width = val;
  141. }
  142. public function set $height(val:Number):void {
  143. super.height = val;
  144. }
  145. public override function set height( value : Number ) : void
  146. {
  147. if ( _height == value ) return;
  148. _bubblingDraw = true;
  149. _height = ! isNaN( value ) ? value : 0;
  150. invalidate( );
  151. }
  152. // Not being used ...
  153. /*
  154. public function set center(point:Point):void
  155. {
  156. //TODO add center based on point.
  157. }*/
  158. override public function get numChildren() : int
  159. {
  160. return display.numChildren;
  161. }
  162. /**
  163. * @see sg.camo.interfaces.IAncestorSprite
  164. */
  165. public function get $numChildren():int {
  166. return super.numChildren;
  167. }
  168. // -- Removed, not being used.
  169. /*
  170. * Jesse:
  171. * <p>This allows immediate access to the bitmapData of the display. By
  172. * accessing this getter you can take a screen shot of the instance.</p>
  173. *
  174. * <p>TODO this needs to be fleshed out</p>
  175. */
  176. /*public function get bitmapData() : BitmapData
  177. {
  178. // Create BitmapData
  179. var bitmapData : BitmapData = new BitmapData( width, height, true );
  180. bitmapData.draw( this );
  181. return bitmapData;
  182. }
  183. */
  184. /**
  185. * Constructor. Attempts creation of <code>display</code> sprite reference if <code>display</code> value is found to be empty.
  186. * @param self (Required) A concrete reference to self (ie. <code>"this"</code>). (Else will throw an error)
  187. */
  188. public function AbstractDisplay(self : AbstractDisplay=null)
  189. {
  190. super(); // Construct children in super
  191. if(self != this)
  192. {
  193. throw new IllegalOperationError( "AbstarctDisplay cannot be instantiated directly." );
  194. }
  195. else
  196. {
  197. // Adds new display to the display-list only if needed,
  198. display = display != null ? display : $addChild( new Sprite() ) as Sprite;
  199. //display.name = "display"; // not required, on-stage instances cannot be renamed.
  200. addStageListeners( );
  201. }
  202. }
  203. public function getDisplay():DisplayObject {
  204. return display;
  205. }
  206. // Exclusive add/remove stage listener functions not tied to handlers
  207. protected function addStageListeners() : void
  208. {
  209. addEventListener( Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true );
  210. addEventListener( Event.REMOVED_FROM_STAGE, onRemovedFromStage, false, 0, true );
  211. }
  212. protected function removeStageListeners() : void
  213. {
  214. removeEventListener( Event.REMOVED_FROM_STAGE, onRemovedFromStage );
  215. removeEventListener( Event.ADDED_TO_STAGE, onAddedToStage );
  216. }
  217. public function move(newX : Number,newY : Number) : void
  218. {
  219. x = newX;
  220. y = newY;
  221. }
  222. public function resize(w : Number,h : Number) : void
  223. {
  224. width = w;
  225. height = h;
  226. }
  227. public function invalidate() : void
  228. {
  229. if( ! _invalid )
  230. {
  231. try
  232. {
  233. stage.invalidate( );
  234. _invalid = true;
  235. initializeAutoUpdate();
  236. }
  237. catch( error : Error )
  238. {
  239. _invalid = false;
  240. }
  241. }
  242. }
  243. // Stage listeners
  244. /**
  245. * @private
  246. * @param event
  247. */
  248. protected function onAddedToStage( event : Event ) : void
  249. {
  250. stage.addEventListener( Event.RENDER, onRender, false, 0, true );
  251. draw( );
  252. }
  253. /**
  254. * @private
  255. * @param e
  256. */
  257. protected function onRemovedFromStage(e:Event):void {
  258. stage.removeEventListener( Event.RENDER, onRender);
  259. // bug workaround: additional measure required to not break stage
  260. stage.addEventListener(Event.RENDER, killRender, false, 0, true);
  261. }
  262. private function killRender(e:Event):void {
  263. e.currentTarget.removeEventListener(Event.RENDER, killRender);
  264. }
  265. // WORKAROUND : need to retain listeners in case onRemovedFromStage occurs for another abstract display which
  266. // somehow prevents Event.RENDER from dispatching during stage.invalidate(), ever.
  267. /**
  268. * @private
  269. */
  270. protected function initializeAutoUpdate():void {
  271. stage.removeEventListener(Event.RENDER, onRender, false);
  272. stage.addEventListener(Event.RENDER, onRender, false, 0, true);
  273. }
  274. /**
  275. * @private
  276. * @param event
  277. */
  278. protected function onRender( event : Event = null) : void
  279. {
  280. if( _invalid )
  281. {
  282. draw( );
  283. _invalid = false;
  284. _bubblingDraw = false;
  285. }
  286. }
  287. public function invalidateSize():void {
  288. _bubblingDraw = true;
  289. invalidate();
  290. }
  291. public function refresh() : void
  292. {
  293. draw( );
  294. _invalid = false;
  295. }
  296. // -- Destructor
  297. public function destroy() : void
  298. {
  299. destroyRecurse(_destroyChildren);
  300. }
  301. public function destroyRecurse(recurse:Boolean = true):void {
  302. removeStageListeners();
  303. if (stage!=null) stage.removeEventListener( Event.RENDER, onRender);
  304. if (recurse) destroyChildren();
  305. }
  306. /**
  307. * @private
  308. */
  309. protected function destroyChildren():void {
  310. var child : DisplayObject;
  311. // changed for loop to while loop for performance, also removes all children from display list
  312. var i:int = numChildren;
  313. while (--i > -1) {
  314. child = getChildAt(0);
  315. if (child is IRecursableDestroyable) (child as IRecursableDestroyable).destroyRecurse(true)
  316. else if (child is IDestroyable) (child as IDestroyable).destroy();
  317. removeChild(child);
  318. }
  319. }
  320. /**
  321. * @private
  322. */
  323. protected function draw() : void
  324. {
  325. dispatchEvent( new CamoDisplayEvent( CamoDisplayEvent.DRAW, _bubblingDraw ) );
  326. }
  327. override public function addChild(child : DisplayObject) : DisplayObject
  328. {
  329. var retChild:DisplayObject = display.addChild( child );
  330. dispatchEvent( new CamoChildEvent( CamoChildEvent.ADD_CHILD, child ) );
  331. _bubblingDraw = true;
  332. invalidate( );
  333. return retChild;
  334. }
  335. public function $addChild(child : DisplayObject) : DisplayObject
  336. {
  337. invalidate( );
  338. return super.addChild( child );
  339. }
  340. override public function addChildAt(child : DisplayObject, index : int) : DisplayObject
  341. {
  342. var retChild:DisplayObject = display.addChildAt( child, index );
  343. dispatchEvent( new CamoChildEvent( CamoChildEvent.ADD_CHILD, child ) );
  344. _bubblingDraw = true;
  345. invalidate();
  346. return retChild;
  347. }
  348. public function $addChildAt(child : DisplayObject, index : int) : DisplayObject
  349. {
  350. invalidate( );
  351. return super.addChildAt( child, index );
  352. }
  353. override public function getChildAt(index : int) : DisplayObject
  354. {
  355. return display.getChildAt( index );
  356. }
  357. public function $getChildAt(index : int) : DisplayObject
  358. {
  359. return super.getChildAt( index );
  360. }
  361. override public function getChildByName(name : String) : DisplayObject
  362. {
  363. return display.getChildByName( name );
  364. }
  365. public function $getChildByName(name : String) : DisplayObject
  366. {
  367. return super.getChildByName( name );
  368. }
  369. override public function getChildIndex(child : DisplayObject) : int
  370. {
  371. return display.getChildIndex( child );
  372. }
  373. public function $getChildIndex(child : DisplayObject) : int
  374. {
  375. return super.getChildIndex( child );
  376. }
  377. override public function removeChild(child : DisplayObject) : DisplayObject
  378. {
  379. dispatchEvent( new CamoChildEvent( CamoChildEvent.REMOVE_CHILD, child) );
  380. _bubblingDraw = true;
  381. invalidate( );
  382. return display.removeChild( child );
  383. }
  384. public function $removeChild(child : DisplayObject) : DisplayObject
  385. {
  386. invalidate( );
  387. return super.removeChild( child );
  388. }
  389. override public function removeChildAt(index : int) : DisplayObject
  390. {
  391. var retChild:DisplayObject = display.removeChildAt( index )
  392. dispatchEvent( new CamoChildEvent( CamoChildEvent.REMOVE_CHILD, retChild) );
  393. _bubblingDraw = true;
  394. invalidate();
  395. return retChild;
  396. }
  397. public function $removeChildAt(index : int) : DisplayObject
  398. {
  399. invalidate( );
  400. return super.removeChildAt( index );
  401. }
  402. override public function setChildIndex(child : DisplayObject, index : int) : void
  403. {
  404. invalidate( );
  405. display.setChildIndex( child, index );
  406. }
  407. protected function $setChildIndex(child : DisplayObject, index : int) : void
  408. {
  409. invalidate( );
  410. super.setChildIndex( child, index );
  411. }
  412. override public function swapChildren(child1 : DisplayObject, child2 : DisplayObject) : void
  413. {
  414. invalidate( );
  415. display.swapChildren( child1, child2 );
  416. }
  417. protected function $swapChildren(child1 : DisplayObject, child2 : DisplayObject) : void
  418. {
  419. invalidate( );
  420. super.swapChildren( child1, child2 );
  421. }
  422. override public function swapChildrenAt(index1 : int, index2 : int) : void
  423. {
  424. invalidate( );
  425. display.swapChildrenAt( index1, index2 );
  426. }
  427. protected function $swapChildrenAt(index1 : int, index2 : int) : void
  428. {
  429. invalidate( );
  430. super.swapChildrenAt( index1, index2 );
  431. }
  432. override public function contains(child : DisplayObject) : Boolean
  433. {
  434. return display.contains( child );
  435. }
  436. public function $contains(child : DisplayObject) : Boolean
  437. {
  438. return super.contains( child );
  439. }
  440. }
  441. }