PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/axiis/src/org/axiis/core/AbstractLayout.as

http://axiis.googlecode.com/
ActionScript | 984 lines | 565 code | 77 blank | 342 comment | 71 complexity | 76d6ee14c39ab6acdd6fe79d19d4cdd7 MD5 | raw file
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) 2009 Team Axiis
  3. //
  4. // Permission is hereby granted, free of charge, to any person
  5. // obtaining a copy of this software and associated documentation
  6. // files (the "Software"), to deal in the Software without
  7. // restriction, including without limitation the rights to use,
  8. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following
  11. // conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. // OTHER DEALINGS IN THE SOFTWARE.
  24. ///////////////////////////////////////////////////////////////////////////////
  25. package org.axiis.core
  26. {
  27. import com.degrafa.core.IGraphicsFill;
  28. import com.degrafa.core.IGraphicsStroke;
  29. import com.degrafa.geometry.Geometry;
  30. import flash.display.Sprite;
  31. import flash.events.Event;
  32. import flash.events.EventDispatcher;
  33. import flash.geom.Rectangle;
  34. import flash.utils.getTimer;
  35. import mx.collections.ArrayCollection;
  36. import mx.core.IFactory;
  37. import mx.core.UIComponent;
  38. import org.axiis.DataCanvas;
  39. import org.axiis.events.LayoutItemEvent;
  40. import org.axiis.layouts.utils.GeometryRepeater;
  41. import org.axiis.managers.AnchoredDataTipManager;
  42. import org.axiis.managers.IDataTipManager;
  43. import org.axiis.utils.ObjectUtils;
  44. /**
  45. * Dispatched when an AxiisSprite is mousedOver.
  46. */
  47. [Event(name="itemDataTip", type="flash.events.Event")]
  48. /**
  49. * AbstractLayout is an base class that provides definitions of properties and
  50. * stubs for methods required by BaseLayout. It is up to the subclass to appropriately
  51. * override these implementations.
  52. */
  53. public class AbstractLayout extends EventDispatcher
  54. {
  55. /**
  56. * Constructor.
  57. */
  58. public function AbstractLayout()
  59. {
  60. super();
  61. }
  62. /**
  63. * The IDataTipManager responsible for laying out data tips for children of this layout.
  64. */
  65. public function get dataTipManager():IDataTipManager {
  66. return _dataTipManager;
  67. }
  68. public function set dataTipManager(value:IDataTipManager):void {
  69. _dataTipManager=value;
  70. }
  71. private var _dataTipManager:IDataTipManager=new AnchoredDataTipManager;
  72. /**
  73. * I Hate to put this here, but until we rethink DataTips it seems like the best place
  74. */
  75. public var dataTipFill:IGraphicsFill;
  76. public var dataTipStroke:IGraphicsStroke;
  77. [Bindable]
  78. /**
  79. * A placeholder for fills used within this layout. Modifying
  80. * this array will not have any effect on the rendering of the layout.
  81. */
  82. public var fills:Array = [];
  83. [Bindable]
  84. /**
  85. * A placeholder for strokes used within this layout. Modifying
  86. * this array will not have any effect on the rendering of the layout.
  87. */
  88. public var strokes:Array = [];
  89. [Bindable]
  90. /**
  91. * A placeholder for palettes used within this layout. Modifying
  92. * this array will not have any effect on the rendering of the layout.
  93. */
  94. public var palettes:Array = [];
  95. [Bindable]
  96. /**
  97. * Whether or not this layout is visible. Layouts that are not visible
  98. * will return from their render methods immediately after they are
  99. * called without making any changes to the display list.
  100. */
  101. public function get visible():Boolean
  102. {
  103. return _visible;
  104. }
  105. public function set visible(value:Boolean):void
  106. {
  107. _visible = value;
  108. }
  109. private var _visible:Boolean=true;
  110. /**
  111. * A flag that indicates to DataCanvas that it should listen for mouse
  112. * events that signal the need to create a data tip.
  113. */
  114. public function get showDataTips():Boolean
  115. {
  116. return _showDataTips;
  117. }
  118. public function set showDataTips(value:Boolean):void
  119. {
  120. _showDataTips=value;
  121. }
  122. private var _showDataTips:Boolean = true;
  123. [Bindable]
  124. /**
  125. * A reference to the layout that contains this layout.
  126. */
  127. public function get parentLayout():AbstractLayout
  128. {
  129. return _parentLayout;
  130. }
  131. public function set parentLayout(value:AbstractLayout):void
  132. {
  133. _parentLayout = value;
  134. }
  135. private var _parentLayout:AbstractLayout;
  136. [Bindable(event="boundsChange")]
  137. /**
  138. * A rectangle that acts as the bounding area for this layout
  139. */
  140. public function get bounds():Rectangle
  141. {
  142. return _bounds;
  143. }
  144. public function set bounds(value:Rectangle):void
  145. {
  146. if(value != _bounds)
  147. {
  148. _bounds = value;
  149. dispatchEvent(new Event("boundsChange"));
  150. }
  151. }
  152. /**
  153. * @private
  154. */
  155. protected var _bounds:Rectangle;
  156. /**
  157. * An array of states that should be applied to this layout.
  158. *
  159. * <p>
  160. * As Layouts create children, each child sets up listeners on
  161. * itself for the Layout's states' <code>enterStateEvent</code> and
  162. * <code>exitStateEvent</code> events. When those events are triggered, the
  163. * relevant state's apply and remove methods are called, respectively. This
  164. * is usually used to modify the <code>drawingGeometry</code> of the Layout.
  165. * </p>
  166. *
  167. * @see State
  168. */
  169. public function get states():Array
  170. {
  171. return _states;
  172. }
  173. public function set states(value:Array):void
  174. {
  175. if(_states != value)
  176. {
  177. _states=value;
  178. invalidate();
  179. }
  180. }
  181. private var _states:Array = [];
  182. [Bindable(event="itemCountChange")]
  183. /**
  184. * The number of items in the dataProvider.
  185. */
  186. public function get itemCount():int
  187. {
  188. return _itemCount;
  189. }
  190. /**
  191. * @private
  192. */
  193. protected function set _itemCount(value:int):void
  194. {
  195. if(value != __itemCount)
  196. {
  197. __itemCount = value;
  198. dispatchEvent(new Event("itemCountChange"));
  199. }
  200. }
  201. /**
  202. * @private
  203. */
  204. protected function get _itemCount():int
  205. {
  206. return __itemCount;
  207. }
  208. private var __itemCount:int;
  209. [Bindable(event="dataItemsChange")]
  210. /**
  211. * An array of objects extracted from the dataProvider.
  212. */
  213. public function get dataItems():Array
  214. {
  215. return _dataItems;
  216. }
  217. /**
  218. * @private
  219. */
  220. protected function set _dataItems(value:Array):void
  221. {
  222. if(value != __dataItems)
  223. {
  224. __dataItems = value;
  225. dispatchEvent(new Event("dataItemsChange"));
  226. }
  227. }
  228. /**
  229. * @private
  230. */
  231. protected function get _dataItems():Array
  232. {
  233. return __dataItems;
  234. }
  235. private var __dataItems:Array;
  236. [Bindable(event="dataProviderChange")]
  237. /**
  238. * An Array, ArrayCollection, or Object containing the data this layout
  239. * should render.
  240. *
  241. * <p>
  242. * If this property is Array or ArrayCollection the layout should render
  243. * each item. If this property is an Object, it should use an array of
  244. * the object's properties as they are exposed in a for..each loop.
  245. * </p>
  246. */
  247. public function get dataProvider():Object
  248. {
  249. return _dataProvider;
  250. }
  251. public function set dataProvider(value:Object):void
  252. {
  253. var t:Number=flash.utils.getTimer();
  254. if(_dataProvider != value)
  255. {
  256. _dataProvider = value;
  257. invalidateDataProvider();
  258. dispatchEvent(new Event("dataProviderChange"));
  259. }
  260. }
  261. // TODO this should be private
  262. /**
  263. * @private
  264. */
  265. protected var _dataProvider:Object;
  266. //Used when filtering data rows tells external classes what index it is on
  267. public function get dataFilterIndex():Number {
  268. return _dataFilterIndex;
  269. }
  270. /**
  271. * @private
  272. */
  273. protected var _dataFilterIndex:Number=-1;
  274. // TODO This should really be renamed. It *validates* the dataProvider more than it invalidates it. Perhaps we could use a method that returns the dataItems rather than setting them directly.
  275. /**
  276. * Iterates over the items in the dataProvider and stores them in
  277. * dataItems.
  278. *
  279. * <p>
  280. * If the dataProvider is Array or ArrayCollection dataItems will contain
  281. * each item. If dataProvider is an Object, dataItems will contain an
  282. * the object's properties as they are exposed in a for..each loop.
  283. * </p>
  284. */
  285. public function invalidateDataProvider():void
  286. {
  287. _dataItems=new Array();
  288. if (dataProvider is ArrayCollection) {
  289. for (var i:int=0;i<dataProvider.source.length;i++) {
  290. _dataFilterIndex=i;
  291. if (dataProvider.source[i] != null) {
  292. if (dataFilterFunction != null) {
  293. if (dataFilterFunction.call(this,dataProvider.source[i])) {
  294. _dataItems.push(dataProvider.source[i]);
  295. }
  296. }
  297. else {
  298. _dataItems.push(dataProvider.source[i]);
  299. }
  300. }
  301. }
  302. }
  303. else if (dataProvider is Array) {
  304. for (var j:int=0;j<dataProvider.length;j++) {
  305. _dataFilterIndex=j;
  306. if (dataProvider[j] != null) {
  307. if (dataFilterFunction != null) {
  308. if (dataFilterFunction.call(this,dataProvider[j])) {
  309. _dataItems.push(dataProvider[j]);
  310. }
  311. }
  312. else {
  313. _dataItems.push(dataProvider[j]);
  314. }
  315. }
  316. }
  317. }
  318. else {
  319. // If the dataProvider is just a single object we need to push it onto _dataItems
  320. // because none of the above cases will have taken care of it. This arises when
  321. // using DataSet.processXML when a node has no siblings.
  322. _dataItems.push(dataProvider);
  323. }
  324. _dataFilterIndex=-1;
  325. _itemCount=_dataItems.length;
  326. this.deselectChildren(); //Since the data has changed so have our indexes, deselect children
  327. this.invalidate();
  328. }
  329. //---------------------------------------------------------------------
  330. // "Current" properties
  331. //---------------------------------------------------------------------
  332. [Bindable(event="currentIndexChange")]
  333. /**
  334. * The index of the item in the dataProvider that the layout is
  335. * currently rendering.
  336. */
  337. public function get currentIndex():int
  338. {
  339. return _currentIndex;
  340. }
  341. /**
  342. * @private
  343. */
  344. protected function set _currentIndex(value:int):void
  345. {
  346. //if(value != __currentIndex)
  347. {
  348. __currentIndex = value;
  349. dispatchEvent(new Event("currentIndexChange"));
  350. }
  351. }
  352. /**
  353. * @private
  354. */
  355. protected function get _currentIndex():int
  356. {
  357. return __currentIndex;
  358. }
  359. private var __currentIndex:int;
  360. [Bindable(event="currentDatumChange")]
  361. /**
  362. * The item in the dataProvider that the layout is currently rendering.
  363. */
  364. public function get currentDatum():*
  365. {
  366. return _currentDatum;
  367. }
  368. /**
  369. * @private
  370. */
  371. protected function set _currentDatum(value:*):void
  372. {
  373. //if(value != __currentDatum)
  374. {
  375. __currentDatum = value;
  376. dispatchEvent(new Event("currentDatumChange"));
  377. }
  378. }
  379. /**
  380. * @private
  381. */
  382. protected function get _currentDatum():*
  383. {
  384. return __currentDatum;
  385. }
  386. private var __currentDatum:*;
  387. [Bindable(event="currentValueChange")]
  388. /**
  389. * The value of the item in the dataProvider that the layout is
  390. * currently rendering, as determined by taking currentDatum[dataField],
  391. * if a dataField is defined.
  392. */
  393. public function get currentValue():*
  394. {
  395. return _currentValue;
  396. }
  397. /**
  398. * @private
  399. */
  400. protected function set _currentValue(value:*):void
  401. {
  402. //if(value != __currentValue)
  403. {
  404. __currentValue = value;
  405. dispatchEvent(new Event("currentValueChange"));
  406. }
  407. }
  408. /**
  409. * @private
  410. */
  411. protected function get _currentValue():*
  412. {
  413. return __currentValue;
  414. }
  415. private var __currentValue:*;
  416. [Bindable(event="currentLabelChange")]
  417. // TODO the label function should be applied somewhere other than the getter
  418. /**
  419. * The label of the item in the dataProvider that the layout is
  420. * currently rendering, as determine by taking currentDatum[labelField],
  421. * if a labelField is defined.
  422. */
  423. public function get currentLabel():String
  424. {
  425. if (owner && owner.labelFunction != null && labelField)
  426. return owner.labelFunction.call(this,_currentDatum[labelField],_currentDatum);
  427. else
  428. return _currentLabel;
  429. }
  430. /**
  431. * @private
  432. */
  433. protected function set _currentLabel(value:String):void
  434. {
  435. //if(value != __currentLabel)
  436. {
  437. __currentLabel = value;
  438. dispatchEvent(new Event("currentLabelChange"));
  439. }
  440. }
  441. /**
  442. * @private
  443. */
  444. protected function get _currentLabel():String
  445. {
  446. return __currentLabel;
  447. }
  448. private var __currentLabel:String;
  449. [Bindable(event="currentReferenceChange")]
  450. /**
  451. * The geometry that is being used to render the current data item as it
  452. * appears after the necessary iterations of the referenceRepeater have
  453. * been executed.
  454. */
  455. public function get currentReference():Geometry
  456. {
  457. return _currentReference;
  458. }
  459. /**
  460. * @private
  461. */
  462. protected function set _currentReference(value:Geometry):void
  463. {
  464. //We want this to fire each time so the geometry property changes propogate
  465. __currentReference = value;
  466. dispatchEvent(new Event("currentReferenceChange"));
  467. }
  468. /**
  469. * @private
  470. */
  471. protected function get _currentReference():Geometry
  472. {
  473. return __currentReference;
  474. }
  475. private var __currentReference:Geometry;
  476. [Bindable(event="dataFieldChange")]
  477. /**
  478. * The property within each item in the dataProvider that contains the
  479. * field used to determine the value of the item.
  480. */
  481. public function get dataField():Object
  482. {
  483. return _dataField;
  484. }
  485. public function set dataField(value:Object):void
  486. {
  487. if(value != _dataField)
  488. {
  489. _dataField = value;
  490. dispatchEvent(new Event("dataFieldChange"));
  491. }
  492. }
  493. // TODO this should be private
  494. /**
  495. * @private
  496. */
  497. protected var _dataField:Object;
  498. [Bindable(event="labelFieldChange")]
  499. /**
  500. * The property within each item in the dataProvider that contains the
  501. * field used to determine the label for the item.
  502. */
  503. public function get labelField():Object
  504. {
  505. return _labelField;
  506. }
  507. public function set labelField(value:Object):void
  508. {
  509. if(value != _labelField)
  510. {
  511. _labelField = value;
  512. dispatchEvent(new Event("labelFieldChange"));
  513. }
  514. }
  515. // TODO This should be private
  516. /**
  517. * @private
  518. */
  519. protected var _labelField:Object;
  520. [Bindable(event="xChange")]
  521. /**
  522. * The horizontal position of the top left corner of this layout within
  523. * its parent.
  524. */
  525. public function get x():Number
  526. {
  527. return _x;
  528. }
  529. public function set x(value:Number):void
  530. {
  531. if(value != _x)
  532. {
  533. _x = value;
  534. invalidate();
  535. dispatchEvent(new Event("xChange"));
  536. }
  537. }
  538. private var _x:Number=0;
  539. [Bindable(event="yChange")]
  540. /**
  541. * The vertical position of the top left corner of this layout within
  542. * its parent.
  543. */
  544. public function get y():Number
  545. {
  546. return _y;
  547. }
  548. public function set y(value:Number):void
  549. {
  550. if(value != _y)
  551. {
  552. _y = value;
  553. invalidate();
  554. dispatchEvent(new Event("yChange"));
  555. }
  556. }
  557. private var _y:Number=0;
  558. [Bindable(event="widthChange")]
  559. /**
  560. * The width of the layout.
  561. */
  562. public function get width():Number
  563. {
  564. return _width;
  565. }
  566. public function set width(value:Number):void
  567. {
  568. if(value != _width)
  569. {
  570. _width = value;
  571. invalidate();
  572. dispatchEvent(new Event("widthChange"));
  573. }
  574. }
  575. private var _width:Number=0;
  576. [Bindable(event="heightChange")]
  577. /**
  578. * The height of the layout.
  579. */
  580. public function get height():Number
  581. {
  582. return _height;
  583. }
  584. public function set height(value:Number):void
  585. {
  586. if(value != _height)
  587. {
  588. _height = value;
  589. invalidate();
  590. dispatchEvent(new Event("heightChange"));
  591. }
  592. }
  593. private var _height:Number=0;
  594. /**
  595. * Registers a DisplayObject as the owner of this layout.
  596. * Throws an error if the layout already has an owner.
  597. */
  598. public function registerOwner(dataCanvas:DataCanvas):void
  599. {
  600. if(!owner)
  601. {
  602. owner = dataCanvas;
  603. for each(var childLayout:AbstractLayout in layouts)
  604. {
  605. childLayout.registerOwner(owner);
  606. }
  607. }
  608. else
  609. {
  610. throw new Error("Layout already has an owner.");
  611. }
  612. }
  613. /**
  614. * @private
  615. */
  616. protected var owner:DataCanvas;
  617. /**
  618. * The AxiisSprites this layout has created to render each item in its dataProvider.
  619. */
  620. public function get childSprites():Array
  621. {
  622. return _childSprites;
  623. }
  624. private var _childSprites:Array = [];
  625. // TODO we can cut this
  626. /**
  627. * A string used to identify this layout.
  628. */
  629. public var name:String = "";
  630. /**
  631. * Determines how long (milliseconds) a layout will spend on a given frame to render X number of datums
  632. *
  633. */
  634. public var msPerRenderFrame:Number=50;
  635. [Bindable(event="layoutsChange")]
  636. /**
  637. * The layouts that should be displayed within this layout.
  638. */
  639. public function get layouts():Array
  640. {
  641. return _layouts;
  642. }
  643. public function set layouts(value:Array):void
  644. {
  645. if(value != _layouts)
  646. {
  647. for each(var layout:AbstractLayout in _layouts) {
  648. layout.removeEventListener("itemDataTip",onItemDataTip);
  649. }
  650. _layouts = value;
  651. for each(layout in _layouts) {
  652. if (layout.showDataTips)
  653. layout.addEventListener("itemDataTip",onItemDataTip);
  654. }
  655. dispatchEvent(new Event("layoutsChange"));
  656. }
  657. }
  658. private var _layouts:Array = [];
  659. //I hate to put yet another function in here, but I think we want a default data tip function
  660. private function dataTipFunction(axiisSprite:AxiisSprite):String
  661. {
  662. if(dataField && labelField)
  663. {
  664. return "<b>" + String(getProperty(axiisSprite.data,labelField)) + "</b><br/>" + String(getProperty(axiisSprite.data,dataField));
  665. }
  666. return "";
  667. }
  668. // TODO This should be cut. DataSet should manage the data.
  669. // I disagree, from a developer workflow this is very convienent - your filters are almost unique to visulization and
  670. // even though this deviates from OO best practices I think it is a good approach if we always assume we will be processing
  671. // an array or collection - tg 8/7/09
  672. /**
  673. * This provides a way to further refine a layouts dataProvider by
  674. * providing access to a custom filter data filter function. This allows
  675. * developers to easily visualize subsets of the data without having to
  676. * change the underlying data structure.
  677. */
  678. public var dataFilterFunction:Function;
  679. [Bindable(event="dataTipLabelFunctionChange")]
  680. /**
  681. * A method used to determine the text that appears in the data tip for
  682. * an item rendered by this layout.
  683. *
  684. * <p>
  685. * This method takes one argument, the item to determine the label for,
  686. * and returns a String, the text to show in the data tip.
  687. * </p>
  688. */
  689. public function get dataTipLabelFunction():Function
  690. {
  691. return _dataTipLabelFunction;
  692. }
  693. public function set dataTipLabelFunction(value:Function):void
  694. {
  695. if(value != _dataTipLabelFunction)
  696. {
  697. _dataTipLabelFunction = value;
  698. dispatchEvent(new Event("dataTipLabelFunctionChange"));
  699. }
  700. }
  701. private var _dataTipLabelFunction:Function=dataTipFunction;
  702. [Inspectable(category="General")]
  703. [Bindable(event="referenceRepeaterChange")]
  704. /**
  705. * A GeometryRepeater that will be applied to the drawingGeometries once
  706. * for each item in the dataProvider.
  707. */
  708. public function get referenceRepeater():GeometryRepeater
  709. {
  710. return _referenceGeometryRepeater;
  711. }
  712. public function set referenceRepeater(value:GeometryRepeater):void
  713. {
  714. if(value != _referenceGeometryRepeater)
  715. {
  716. _referenceGeometryRepeater = value;
  717. dispatchEvent(new Event("referenceRepeaterChange"));
  718. }
  719. }
  720. // TODO This should be private
  721. /**
  722. * @private
  723. */
  724. protected var _referenceGeometryRepeater:GeometryRepeater=new GeometryRepeater();
  725. [Bindable(event="geometryChange")]
  726. /**
  727. * An array of geometries that should be drawn for each item in the data
  728. * provider. You can modify these items by using GeometryRepeaters
  729. * and PropertyModifiers.
  730. *
  731. * @see GeometryRepeater
  732. * @see PropertyModifier
  733. */
  734. public function get drawingGeometries():Array
  735. {
  736. return _geometries;
  737. }
  738. public function set drawingGeometries(value:Array):void
  739. {
  740. if(value != _geometries)
  741. {
  742. _geometries = value;
  743. dispatchEvent(new Event("geometryChange"));
  744. }
  745. }
  746. private var _geometries:Array;
  747. // TODO We have this property sprite, getSprite(), and render(sprite = null). We should use a single method to manipulating the sprite
  748. /**
  749. * The sprite this layout is currently rendering to.
  750. */
  751. protected function get sprite():AxiisSprite
  752. {
  753. return _sprite;
  754. }
  755. protected function set sprite(value:AxiisSprite):void
  756. {
  757. if(value != _sprite)
  758. {
  759. _sprite = value;
  760. dispatchEvent(new Event("spriteChange"));
  761. }
  762. }
  763. private var _sprite:AxiisSprite;
  764. /**
  765. * Returns the Sprite associated with this layout if owner is
  766. * in fact the owner of this layout.
  767. */
  768. public function getSprite(owner:DataCanvas):Sprite
  769. {
  770. if(!sprite)
  771. sprite = new AxiisSprite();
  772. return sprite;
  773. }
  774. /**
  775. * Draws this layout to the specified AxiisSprite.
  776. *
  777. * <p>
  778. * If no sprite is provided this layout will use the last AxiisSprite
  779. * it rendered to, if such an AxiisSprite exists. Otherwise this returns
  780. * immediately.
  781. * </p>
  782. *
  783. * <p>
  784. * This method is meant to be overridden by a subclass.
  785. * </p>
  786. *
  787. * @param sprite The AxiisSprite this layout should render to.
  788. */
  789. public function render(newSprite:AxiisSprite = null):void
  790. {
  791. }
  792. /**
  793. * Notifies the DataCanvas that this layout needs to be rendered.
  794. */
  795. public function invalidate():void
  796. {
  797. this.dataTipManager.destroyAllDataTips();
  798. dispatchEvent(new Event("layoutInvalidate"));
  799. }
  800. [Bindable(event="renderingChange")]
  801. /**
  802. * Whether or not this layout is currently in a render cycle. Rendering
  803. * can take place over several frames. By watching this property you
  804. * can take an appropriate action handle artifacts for multiframe
  805. * rendering, such as hiding the layout entirely.
  806. */
  807. public function get rendering():Boolean
  808. {
  809. return _rendering;
  810. }
  811. /**
  812. * @private
  813. */
  814. protected function set _rendering(value:Boolean):void
  815. {
  816. if(value != __rendering)
  817. {
  818. __rendering = value;
  819. dispatchEvent(new Event("renderingChange"));
  820. }
  821. }
  822. /**
  823. * @private
  824. */
  825. protected function get _rendering():Boolean
  826. {
  827. return __rendering;
  828. }
  829. private var __rendering:Boolean = false;
  830. [Bindable(event="dataTipAnchorPointChange")]
  831. /**
  832. * An Object with x and y values used to determine the location of anchored data tips. By using
  833. * the currentReference, you can update this value during the render cycle.
  834. */
  835. public function get dataTipAnchorPoint():Object
  836. {
  837. return _dataTipAnchorPoint;
  838. }
  839. public function set dataTipAnchorPoint(value:Object):void
  840. {
  841. if(value != _dataTipAnchorPoint)
  842. {
  843. _dataTipAnchorPoint = value;
  844. invalidate();
  845. dispatchEvent(new Event("dataTipAnchorPointChange"));
  846. }
  847. }
  848. private var _dataTipAnchorPoint:Object;
  849. [Bindable(event="dataTipContentClassChange")]
  850. // NOTE : Not sure that a factory pattern is what we want here.
  851. // * 1. It makes it difficult to get access to the concrete class at run time
  852. // * 2. It might be memory intensive, and easier to pass around a single class that is arleady in memory
  853. /**
  854. * A ClassFactory that creates the UIComponent that should be used in the data tip for this AxiisSprite.
  855. */
  856. public function get dataTipContentClass():IFactory
  857. {
  858. return _dataTipContentClass;
  859. }
  860. public function set dataTipContentClass(value:IFactory):void
  861. {
  862. if(value != _dataTipContentClass)
  863. {
  864. _dataTipContentClass = value;
  865. dispatchEvent(new Event("dataTipContentClassChange"));
  866. }
  867. }
  868. private var _dataTipContentClass:IFactory;
  869. [Bindable(event="dataTipContentComponentChange")]
  870. /**
  871. * A component that gets passed to any data tip.
  872. */
  873. public function get dataTipContentComponent():UIComponent
  874. {
  875. return _dataTipContentComponent;
  876. }
  877. public function set dataTipContentComponent(value:UIComponent):void
  878. {
  879. if(value != _dataTipContentComponent)
  880. {
  881. _dataTipContentComponent = value;
  882. dispatchEvent(new Event("dataTipContentComponentChange"));
  883. }
  884. }
  885. private var _dataTipContentComponent:UIComponent;
  886. //When a chid layout emits an event we want to bubble it
  887. private function onItemDataTip(e:LayoutItemEvent):void {
  888. this.dispatchEvent(new LayoutItemEvent("itemDataTip",e.item,e.sourceEvent));
  889. }
  890. /**
  891. * Uses ObjectUtils.getProperty(this,obj,propertyName) to get a property on an object.
  892. *
  893. * @see ObjectUtils#getProperty
  894. */
  895. public function getProperty(obj:Object,propertyName:Object):* {
  896. return ObjectUtils.getProperty(this,obj,propertyName);
  897. }
  898. /**
  899. * Marks all children as deselected.
  900. */
  901. protected function deselectChildren():void {
  902. for (var i:int=0; i<childSprites.length;i++) {
  903. AxiisSprite(childSprites[i]).selected=false;
  904. }
  905. }
  906. }
  907. }