/sandbox/chart/as/com/yahoo/renderers/Renderer.as

https://github.com/nonano/yui3 · ActionScript · 422 lines · 224 code · 42 blank · 156 comment · 51 complexity · a52c2dfe13e1b18ef5fd36982252f3e9 MD5 · raw file

  1. package com.yahoo.renderers
  2. {
  3. import flash.display.Sprite;
  4. import com.yahoo.renderers.DisplayChangeType;
  5. import com.yahoo.renderers.layout.ContainerType;
  6. import com.yahoo.renderers.styles.RendererStyles;
  7. import com.yahoo.renderers.styles.IStyle;
  8. import com.yahoo.renderers.events.RendererEvent;
  9. import com.yahoo.renderers.ApplicationGlobals;
  10. import flash.events.Event;
  11. /**
  12. * Base class for rendering DisplayObjects with styles
  13. */
  14. public class Renderer extends Sprite
  15. {
  16. //--------------------------------------
  17. // Static Properties
  18. //--------------------------------------
  19. /**
  20. * Reference to the style class.
  21. */
  22. private static var _styleClass:Class = RendererStyles;
  23. //--------------------------------------
  24. // Constructor
  25. //--------------------------------------
  26. /**
  27. * Constructor
  28. */
  29. public function Renderer(styles:IStyle = null)
  30. {
  31. super();
  32. if(styles) this._styles = styles;
  33. this.initializeRenderer();
  34. }
  35. //--------------------------------------
  36. // Properties
  37. //--------------------------------------
  38. /**
  39. * @private (protected)
  40. * Indicates that a flag has been set.
  41. */
  42. protected var _hasFlag:Boolean = false;
  43. /**
  44. * @private
  45. * Storage for sizing algorithm
  46. */
  47. public var _sizeMode:String = ContainerType.BOX;
  48. /**
  49. * Gets or sets the <code>sizeMode</code>.
  50. * <p>The <code>sizeMode</code> determines how the dimensions of a renderer are determined.
  51. * The available settings are below:
  52. * <ul>
  53. * <li><code>none</code>: The dimensions will be determined by the sum of its contents.</li>
  54. * <li><code>box</code>: Width and height are explicitly set.</li>
  55. * <li><code>hbox</code>: Height is explicitly set. Width is determined by the sum of its contents.</li>
  56. * <li><code>vbox</code>: Width is explicitly set. Height is determined by the sum of its contents.</li>
  57. * </ul>
  58. */
  59. public function get sizeMode():String
  60. {
  61. return this._sizeMode;
  62. }
  63. /**
  64. * @private (setter)
  65. */
  66. public function set sizeMode(value:String):void
  67. {
  68. if(value == this.sizeMode) return;
  69. this._sizeMode = value;
  70. this.setFlag("sizeMode");
  71. }
  72. /**
  73. * @private
  74. * Storage for width
  75. */
  76. private var _width:Number = 0;
  77. /**
  78. * @private
  79. */
  80. protected var _previousWidth:Number = 0;
  81. /**
  82. * Gets or sets the width
  83. */
  84. override public function get width():Number
  85. {
  86. if(this.sizeMode == ContainerType.BOX || this.sizeMode == ContainerType.VBOX) return this._width;
  87. return this.contentWidth;
  88. }
  89. /**
  90. * @private (setter)
  91. */
  92. override public function set width(value:Number):void
  93. {
  94. if(this.width == value) return;
  95. this._width = value;
  96. if(this.sizeMode == ContainerType.HBOX || this.sizeMode == ContainerType.NONE) return;
  97. if(isNaN(value)) return;
  98. var resizeEvent:RendererEvent = new RendererEvent(RendererEvent.RESIZE);
  99. resizeEvent.widthChange = true;
  100. this.dispatchEvent(resizeEvent);
  101. this.setFlag("resize");
  102. }
  103. /**
  104. * Gets or sets the <code>contentWidth</code>.
  105. */
  106. public function get contentWidth():Number
  107. {
  108. return super.width;
  109. }
  110. /**
  111. * @private
  112. * Storage for height
  113. */
  114. private var _height:Number = 0;
  115. /**
  116. * @private
  117. */
  118. protected var _previousHeight:Number = 0;
  119. /**
  120. * Gets or sets the width
  121. */
  122. override public function get height():Number
  123. {
  124. if(this.sizeMode == ContainerType.BOX || this.sizeMode == ContainerType.HBOX) return this._height;
  125. return this.contentHeight;
  126. }
  127. /**
  128. * @private (setter)
  129. */
  130. override public function set height(value:Number):void
  131. {
  132. if(this.height == value) return;
  133. this._height = value;
  134. if(this.sizeMode == ContainerType.VBOX || this.sizeMode == ContainerType.NONE) return;
  135. if(isNaN(value)) return;
  136. var resizeEvent:RendererEvent = new RendererEvent(RendererEvent.RESIZE);
  137. resizeEvent.heightChange = true;
  138. this.dispatchEvent(resizeEvent);
  139. this.setFlag("resize");
  140. }
  141. /**
  142. * Gets or sets the <code>contentHeight</code>.
  143. */
  144. public function get contentHeight():Number
  145. {
  146. return super.height;
  147. }
  148. /**
  149. * @private
  150. * Storage for styles property
  151. */
  152. protected var _styles:IStyle;
  153. /**
  154. * @private
  155. * Hash of flags to indicate whether task needs to occur on the redraw.
  156. */
  157. protected var _renderFlags:Object = {};
  158. /**
  159. * @private
  160. */
  161. protected var _laterFlags:Object = {};
  162. /**
  163. * @private (protected)
  164. */
  165. protected var _globalApp:ApplicationGlobals;
  166. /**
  167. * Indicates whether the Renderer is in the process of rendering.
  168. */
  169. public var rendering:Boolean = false;
  170. //--------------------------------------
  171. // Public Methods
  172. //--------------------------------------
  173. /**
  174. * Returns reference to the style class used
  175. */
  176. public function getStyleClass():Class
  177. {
  178. return _styleClass;
  179. }
  180. /**
  181. * @copy com.yahoo.styles.IStyle#getStyles()
  182. */
  183. public function getStyles():Object
  184. {
  185. return this._styles.getStyles();
  186. }
  187. /**
  188. * Returns the value of a style.
  189. */
  190. public function getStyle(value:String):Object
  191. {
  192. return this._styles.getStyle(value);
  193. }
  194. /**
  195. * Sets the value of a style
  196. */
  197. public function setStyle(style:String, value:Object):Boolean
  198. {
  199. if(style == "width" || style == "height" || style == "sizeMode")
  200. {
  201. this[style] = value as Number;
  202. return true;
  203. }
  204. var styleSet:Boolean = this._styles.setStyle(style, value);
  205. if(styleSet) this.setFlag(style);
  206. return styleSet;
  207. }
  208. /**
  209. * @copy com.yahoo.styles.IStyle#setStyles()
  210. */
  211. public function setStyles(styles:Object):void
  212. {
  213. var styleSet:Boolean,
  214. i:String;
  215. if(styles.hasOwnProperty("width")) this.width = styles.width as Number;
  216. if(styles.hasOwnProperty("height")) this.height = styles.height as Number;
  217. if(styles.hasOwnProperty("sizeMode")) this.sizeMode = styles.sizeMode as String;
  218. for(i in styles)
  219. {
  220. if(styles.hasOwnProperty(i))
  221. {
  222. styleSet = this._styles.setStyle(i, styles[i]);
  223. if(styleSet) this.setFlag(i);
  224. }
  225. }
  226. }
  227. /**
  228. * Forces a redraw
  229. */
  230. public function forceRender():void
  231. {
  232. this.render();
  233. }
  234. //--------------------------------------
  235. // Protected Methods
  236. //--------------------------------------
  237. /**
  238. * Renders the contents of the object.
  239. */
  240. protected function render():void
  241. {
  242. //Placeholder. Needs to be overridden to by class.
  243. }
  244. /**
  245. * @private
  246. */
  247. protected function initializeRenderer():void
  248. {
  249. this._globalApp = ApplicationGlobals.getInstance();
  250. this.setStyleInstance();
  251. }
  252. /**
  253. * @private (protected)
  254. */
  255. protected function setStyleInstance():void
  256. {
  257. if(!this._styles)
  258. {
  259. var styleClass:Class = this.getStyleClass();
  260. this._styles = new styleClass();
  261. }
  262. }
  263. //--------------------------------------
  264. // Private Methods
  265. //--------------------------------------
  266. /**
  267. * @private
  268. * Event handler for rendering.
  269. */
  270. public function callRender():void
  271. {
  272. if(!this.rendering)
  273. {
  274. this.rendering = true;
  275. this.render();
  276. this.clearFlags();
  277. this.updateRenderStatus();
  278. }
  279. }
  280. /**
  281. * @private
  282. */
  283. protected function updateRenderStatus():void
  284. {
  285. this.rendering = false;
  286. this.dispatchRenderEvents();
  287. }
  288. /**
  289. * @private (protected)
  290. * All the events that need to be dispatched after <code>render</code> has completed.
  291. */
  292. protected function dispatchRenderEvents():void
  293. {
  294. var event:RendererEvent = new RendererEvent(RendererEvent.RENDER_COMPLETE);
  295. event.changeFlags = this._renderFlags;
  296. event.widthChange = this._previousWidth != this.width;
  297. event.heightChange = this._previousHeight != this.height;
  298. this._previousWidth = this.width;
  299. this._previousHeight = this.height;
  300. if(this.willTrigger(event.type)) this.dispatchEvent(event);
  301. }
  302. public var autoRender:Boolean = true;
  303. /**
  304. * @private
  305. */
  306. protected function setFlag(value:String):void
  307. {
  308. if(!this._hasFlag)
  309. {
  310. this._hasFlag = true;
  311. if(this.autoRender)
  312. {
  313. this._globalApp.addRenderer(this);
  314. }
  315. }
  316. this._renderFlags[value] = true;
  317. }
  318. protected var _hasLaterFlag:Boolean = false;
  319. /**
  320. * @private
  321. * Sets a flag to mark for rendering on a later enterFrame.
  322. */
  323. protected function setLaterFlag(value:String):void
  324. {
  325. if(!this._hasLaterFlag)
  326. {
  327. this._hasLaterFlag = true;
  328. if(this.autoRender) this._globalApp.addLaterRenderer(this);
  329. }
  330. this._laterFlags[value] = true;
  331. }
  332. /**
  333. * @private
  334. */
  335. private function setFlags(value:Array):void
  336. {
  337. for(var i:int = 0; i < value.length; i++)
  338. {
  339. this.setFlag(value[i]);
  340. }
  341. }
  342. /**
  343. * @private
  344. */
  345. protected function clearFlags():void
  346. {
  347. this._renderFlags = {};
  348. this._hasFlag = false;
  349. for(var i:String in this._laterFlags)
  350. {
  351. this._renderFlags[i] = this._laterFlags[i];
  352. }
  353. this._hasLaterFlag = false;
  354. this._laterFlags = {};
  355. }
  356. /**
  357. * @private
  358. */
  359. protected function checkFlag(value:String):Boolean
  360. {
  361. return this._renderFlags[value];
  362. }
  363. /**
  364. * @private (protected)
  365. */
  366. protected function checkFlags(flags:Object):Boolean
  367. {
  368. var hasFlag:Boolean = false;
  369. for(var i:String in flags)
  370. {
  371. if(this._renderFlags[i])
  372. {
  373. hasFlag = true;
  374. break;
  375. }
  376. }
  377. return hasFlag;
  378. }
  379. }
  380. }