PageRenderTime 54ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/library/src/flexlib/controls/treeGridClasses/TreeGridItemRenderer.as

https://github.com/Houssi/flexlib
ActionScript | 543 lines | 312 code | 105 blank | 126 comment | 41 complexity | 4ad962a21556d290edf7845a0bb3ce6a MD5 | raw file
  1. /*
  2. Copyright (c) 2007 FlexLib Contributors. See:
  3. http://code.google.com/p/flexlib/wiki/ProjectContributors
  4. Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. this software and associated documentation files (the "Software"), to deal in
  6. the Software without restriction, including without limitation the rights to
  7. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  8. of the Software, and to permit persons to whom the Software is furnished to do
  9. so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. */
  20. package flexlib.controls.treeGridClasses
  21. {
  22. import flash.display.DisplayObject;
  23. import flash.display.InteractiveObject;
  24. import flash.display.Shape;
  25. import flash.display.Sprite;
  26. import flash.events.Event;
  27. import flash.events.MouseEvent;
  28. import flash.geom.Point;
  29. import flash.geom.Rectangle;
  30. import flexlib.controls.TreeGrid;
  31. import mx.controls.Image;
  32. import mx.controls.dataGridClasses.DataGridListData;
  33. import mx.controls.listClasses.BaseListData;
  34. import mx.controls.listClasses.IDropInListItemRenderer;
  35. import mx.controls.listClasses.IListItemRenderer;
  36. import mx.core.IDataRenderer;
  37. import mx.core.IFlexDisplayObject;
  38. import mx.core.IToolTip;
  39. import mx.core.SpriteAsset;
  40. import mx.core.UIComponent;
  41. import mx.core.UITextField;
  42. import mx.events.FlexEvent;
  43. import mx.events.ToolTipEvent;
  44. import mx.events.TreeEvent;
  45. import mx.managers.ILayoutManagerClient;
  46. import mx.styles.IStyleClient;
  47. [Event(name="dataChange", type="mx.events.FlexEvent")]
  48. /**
  49. *
  50. */
  51. public class TreeGridItemRenderer extends UIComponent
  52. implements IDataRenderer,
  53. IDropInListItemRenderer,
  54. ILayoutManagerClient,
  55. IListItemRenderer
  56. {
  57. //----------------------------------
  58. // disclosureIcon
  59. //----------------------------------
  60. /**
  61. * The internal IFlexDisplayObject that displays the disclosure icon
  62. * in this renderer.
  63. */
  64. protected var disclosureIcon:IFlexDisplayObject;
  65. //----------------------------------
  66. // icon
  67. //----------------------------------
  68. /**
  69. * The internal IFlexDisplayObject that displays the icon in this renderer.
  70. */
  71. protected var icon:IFlexDisplayObject;
  72. //----------------------------------
  73. // label
  74. //----------------------------------
  75. /**
  76. * The internal UITextField that displays the text in this renderer.
  77. */
  78. protected var label:UITextField;
  79. /**
  80. * The internal shape that displays the trunks in this renderer.
  81. */
  82. protected var trunk:Sprite;
  83. private var listOwner : TreeGrid;
  84. /**
  85. * Constructor.
  86. */
  87. public function TreeGridItemRenderer()
  88. {
  89. super();
  90. }
  91. /**
  92. * @private
  93. */
  94. override protected function createChildren():void
  95. {
  96. super.createChildren();
  97. if (!label)
  98. {
  99. label = new UITextField();
  100. label.styleName = this;
  101. addChild(label);
  102. }
  103. addEventListener(ToolTipEvent.TOOL_TIP_SHOW, toolTipShowHandler);
  104. }
  105. /**
  106. * @private
  107. */
  108. override protected function commitProperties():void
  109. {
  110. super.commitProperties();
  111. if (icon)
  112. {
  113. removeChild(DisplayObject(icon));
  114. icon = null;
  115. }
  116. if (disclosureIcon)
  117. {
  118. disclosureIcon.removeEventListener(MouseEvent.MOUSE_DOWN,
  119. disclosureMouseDownHandler);
  120. removeChild(DisplayObject(disclosureIcon));
  121. disclosureIcon = null;
  122. }
  123. if(trunk)
  124. {
  125. trunk.graphics.clear();
  126. removeChild(DisplayObject(trunk));
  127. trunk = null;
  128. }
  129. if ( _data )
  130. {
  131. listOwner = TreeGrid( _listData.owner );
  132. if (_listData.disclosureIcon)
  133. {
  134. var disclosureIconClass:Class = _listData.disclosureIcon;
  135. var disclosureInstance:* = new disclosureIconClass();
  136. // If not already an interactive object, then we'll wrap
  137. // in one so we can dispatch mouse events.
  138. if (!(disclosureInstance is InteractiveObject))
  139. {
  140. var wrapper:SpriteAsset = new SpriteAsset();
  141. wrapper.addChild(disclosureInstance as DisplayObject);
  142. disclosureIcon = wrapper as IFlexDisplayObject;
  143. }
  144. else
  145. {
  146. disclosureIcon = disclosureInstance;
  147. }
  148. addChild(disclosureIcon as DisplayObject);
  149. disclosureIcon.addEventListener(MouseEvent.MOUSE_DOWN,
  150. disclosureMouseDownHandler);
  151. }
  152. if(_listData.trunk != "none" )
  153. {
  154. trunk = new Sprite();
  155. addChild(trunk);
  156. }
  157. if (_listData.icon)
  158. {
  159. var iconClass:Class = _listData.icon;
  160. icon = new iconClass();
  161. addChild(DisplayObject(icon));
  162. }
  163. label.text = _listData.label;
  164. label.multiline = listOwner.variableRowHeight;
  165. label.wordWrap = listOwner.wordWrap;
  166. if (listOwner.showDataTips)
  167. {
  168. if (label.textWidth > label.width ||
  169. listOwner.dataTipFunction != null)
  170. {
  171. toolTip = listOwner.itemToDataTip(_data);
  172. }
  173. else
  174. {
  175. toolTip = null;
  176. }
  177. }
  178. else
  179. {
  180. toolTip = null;
  181. }
  182. }
  183. else
  184. {
  185. label.text = " ";
  186. toolTip = null;
  187. }
  188. invalidateDisplayList();
  189. }
  190. /**
  191. * @private
  192. */
  193. override protected function measure():void
  194. {
  195. super.measure();
  196. var w:Number = _data ? _listData.indent : 5;
  197. w = w + 5;
  198. if (disclosureIcon)
  199. w += disclosureIcon.width;
  200. if (icon)
  201. w += icon.measuredWidth;
  202. // guarantee that label width isn't zero because it messes up ability to measure
  203. if (label.width < 4 || label.height < 4)
  204. {
  205. label.width = 4;
  206. label.height = 16;
  207. }
  208. if (isNaN(explicitWidth))
  209. {
  210. w += label.getExplicitOrMeasuredWidth();
  211. measuredWidth = w;
  212. measuredHeight = label.getExplicitOrMeasuredHeight();
  213. }
  214. else
  215. {
  216. label.width = Math.max(explicitWidth - w, 4);
  217. measuredHeight = label.getExplicitOrMeasuredHeight();
  218. if (icon && icon.measuredHeight > measuredHeight)
  219. measuredHeight = icon.measuredHeight;
  220. }
  221. }
  222. /**
  223. * @private
  224. */
  225. override protected function updateDisplayList(unscaledWidth:Number,
  226. unscaledHeight:Number):void
  227. {
  228. super.updateDisplayList(unscaledWidth, unscaledHeight);
  229. var startx:Number = _data ? _listData.indent : 0;
  230. //if( startx == 0 )
  231. startx = startx + 5;
  232. if (disclosureIcon)
  233. {
  234. disclosureIcon.x = startx;
  235. startx = disclosureIcon.x + disclosureIcon.width;
  236. disclosureIcon.setActualSize(disclosureIcon.width,
  237. disclosureIcon.height);
  238. disclosureIcon.visible = _data ?
  239. _listData.hasChildren :
  240. false;
  241. }
  242. if(trunk)
  243. {
  244. trunk.graphics.clear();
  245. trunk.graphics.lineStyle( 1, _listData.trunkColor, 0.5 );
  246. for( var i : int = 0; i < _listData.depth - 1; i++ )
  247. {
  248. var currentx : Number = 5 + i * _listData.indentationGap;
  249. trunk.graphics.moveTo(currentx + (disclosureIcon.width / 2), 0 - _listData.trunkOffsetTop );
  250. trunk.graphics.lineTo(currentx + (disclosureIcon.width / 2), this.height + _listData.trunkOffsetBottom );
  251. }
  252. if(disclosureIcon && disclosureIcon.visible)
  253. {
  254. //vertical item line (separated in 2 part, top of the icon and bottom of the icon)
  255. trunk.graphics.moveTo(startx - (disclosureIcon.width / 2), 0 - _listData.trunkOffsetTop );
  256. trunk.graphics.lineTo(startx - (disclosureIcon.width / 2), disclosureIcon.y );
  257. if(_listData.hasSibling)
  258. {
  259. trunk.graphics.moveTo(startx - (disclosureIcon.width / 2), disclosureIcon.y + disclosureIcon.height );
  260. trunk.graphics.lineTo(startx - (disclosureIcon.width / 2), this.height + _listData.trunkOffsetBottom );
  261. }
  262. //horizontal item line
  263. trunk.graphics.moveTo(startx, disclosureIcon.y + disclosureIcon.height / 2 );
  264. trunk.graphics.lineTo(startx + (_listData.indentationGap / 3), disclosureIcon.y + disclosureIcon.height / 2 );
  265. startx = startx + (_listData.indentationGap / 3);
  266. }
  267. else
  268. {
  269. if(!disclosureIcon.visible)
  270. {
  271. var endy : Number=0;
  272. //vertical item line
  273. if(_listData.hasSibling)
  274. {
  275. endy = this.height + _listData.trunkOffsetBottom;
  276. }
  277. else
  278. {
  279. endy = disclosureIcon.y + disclosureIcon.height / 2;
  280. }
  281. trunk.graphics.moveTo(startx - (disclosureIcon.width / 2), 0 - _listData.trunkOffsetTop );
  282. trunk.graphics.lineTo(startx - (disclosureIcon.width / 2), endy );
  283. //horizontal item line
  284. trunk.graphics.moveTo(startx - (disclosureIcon.width / 2) , disclosureIcon.y + disclosureIcon.height / 2 );
  285. trunk.graphics.lineTo(startx + (_listData.indentationGap / 3) , disclosureIcon.y + disclosureIcon.height / 2 );
  286. startx = startx + (_listData.indentationGap / 3);
  287. }
  288. else
  289. {
  290. //trunk.graphics.moveTo(startx , 0 - _listData.trunkOffsetTop );
  291. //trunk.graphics.lineTo(startx , this.height + _listData.trunkOffsetBottom );
  292. }
  293. }
  294. }
  295. if (icon)
  296. {
  297. icon.x = startx;
  298. startx = icon.x + icon.measuredWidth;
  299. icon.setActualSize(icon.measuredWidth, icon.measuredHeight);
  300. }
  301. label.x = startx;
  302. label.setActualSize(unscaledWidth - startx, measuredHeight);
  303. // using truncateToFit to add the 3 dots to labels if the columns are too small
  304. if( label.truncateToFit() )
  305. {
  306. label.toolTip = _listData.label;
  307. }
  308. //var verticalAlign:String = getStyle("verticalAlign");
  309. /*if (verticalAlign == "top")
  310. {
  311. label.y = 0;
  312. if (icon)
  313. icon.y = 0;
  314. if (disclosureIcon)
  315. disclosureIcon.y = 0;
  316. }
  317. else if (verticalAlign == "bottom")
  318. {
  319. label.y = unscaledHeight - label.height + 2; // 2 for gutter
  320. if (icon)
  321. icon.y = unscaledHeight - icon.height;
  322. if (disclosureIcon)
  323. disclosureIcon.y = unscaledHeight - disclosureIcon.height;
  324. }
  325. else
  326. {*/
  327. // TODO
  328. //}
  329. label.y = (unscaledHeight - label.height) / 2;
  330. if (icon)
  331. icon.y = (unscaledHeight - icon.height) / 2;
  332. if (disclosureIcon)
  333. disclosureIcon.y = (unscaledHeight - disclosureIcon.height) / 2;
  334. var labelColor:Number;
  335. if (data && parent)
  336. {
  337. if (!enabled)
  338. labelColor = getStyle("disabledColor");
  339. else if (listOwner.isItemHighlighted(listData.uid))
  340. labelColor = getStyle("textRollOverColor");
  341. else if (listOwner.isItemSelected(listData.uid))
  342. labelColor = getStyle("textSelectedColor");
  343. else
  344. labelColor = getStyle("color");
  345. label.setColor(labelColor);
  346. }
  347. }
  348. /**
  349. * @private
  350. */
  351. private function toolTipShowHandler(event:ToolTipEvent):void
  352. {
  353. var toolTip:IToolTip = event.toolTip;
  354. // Calculate global position of label.
  355. var pt:Point = new Point(0, 0);
  356. pt = label.localToGlobal(pt);
  357. pt = root.globalToLocal(pt);
  358. toolTip.move(pt.x, pt.y + (height - toolTip.height) / 2);
  359. var screen:Rectangle = systemManager.screen;
  360. var screenRight:Number = screen.x + screen.width;
  361. if (toolTip.x + toolTip.width > screenRight)
  362. toolTip.move(screenRight - toolTip.width, toolTip.y);
  363. }
  364. /**
  365. * @private
  366. */
  367. private function disclosureMouseDownHandler(event:Event):void
  368. {
  369. event.stopPropagation();
  370. //if (listOwner.isOpening || !listOwner.enabled)
  371. // return;
  372. var open:Boolean = _listData.open;
  373. _listData.open = !open;
  374. listOwner.dispatchTreeEvent(TreeEvent.ITEM_OPENING,
  375. _listData, //listData
  376. this, //renderer
  377. event, //trigger
  378. !open, //opening
  379. true) //dispatch
  380. }
  381. /**
  382. * @private
  383. */
  384. private var invalidatePropertiesFlag:Boolean = false;
  385. /**
  386. * @private
  387. */
  388. private var invalidateSizeFlag:Boolean = false;
  389. //--------------------------------------------------------------------------
  390. //
  391. // Overridden properties: UIComponent
  392. //
  393. //--------------------------------------------------------------------------
  394. //----------------------------------
  395. // nestLevel
  396. //----------------------------------
  397. /**
  398. * @private
  399. */
  400. override public function set nestLevel(value:int):void
  401. {
  402. super.nestLevel = value;
  403. }
  404. /**
  405. * @private
  406. */
  407. private var _listData:TreeGridListData;
  408. [Bindable("dataChange")]
  409. public function get listData() : BaseListData
  410. {
  411. return _listData;
  412. }
  413. public function set listData( value : BaseListData ) : void
  414. {
  415. if( !value )
  416. return;
  417. _listData = TreeGridListData( value );
  418. }
  419. /**
  420. * @private
  421. */
  422. private var _data:Object;
  423. [Bindable("dataChange")]
  424. public function get data(): Object
  425. {
  426. return _data;
  427. }
  428. public function set data( value : Object ):void
  429. {
  430. _data = value;
  431. invalidateProperties();
  432. dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
  433. }
  434. } // end class
  435. } // end package