PageRenderTime 97ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/Sample/mx/core/UIComponent.as

https://github.com/ingydotnet/yaml-oscon2009-talk
ActionScript | 9391 lines | 3597 code | 1187 blank | 4607 comment | 722 complexity | 0e45c94c110a3d960aa5a72a5e0131f0 MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // ADOBE SYSTEMS INCORPORATED
  4. // Copyright 2003-2007 Adobe Systems Incorporated
  5. // All Rights Reserved.
  6. //
  7. // NOTICE: Adobe permits you to use, modify, and distribute this file
  8. // in accordance with the terms of the license agreement accompanying it.
  9. //
  10. ////////////////////////////////////////////////////////////////////////////////
  11. package mx.core
  12. {
  13. import flash.display.DisplayObject;
  14. import flash.display.DisplayObjectContainer;
  15. import flash.display.GradientType;
  16. import flash.display.Graphics;
  17. import flash.display.InteractiveObject;
  18. import flash.display.Loader;
  19. import flash.display.Sprite;
  20. import flash.display.Stage;
  21. import flash.events.Event;
  22. import flash.events.EventPhase;
  23. import flash.events.FocusEvent;
  24. import flash.events.IEventDispatcher;
  25. import flash.events.KeyboardEvent;
  26. import flash.geom.Matrix;
  27. import flash.geom.Point;
  28. import flash.geom.Rectangle;
  29. import flash.system.ApplicationDomain;
  30. import flash.text.TextLineMetrics;
  31. import flash.utils.getQualifiedClassName;
  32. import flash.utils.getQualifiedSuperclassName;
  33. import mx.automation.IAutomationObject;
  34. import mx.binding.BindingManager;
  35. import mx.controls.IFlexContextMenu;
  36. import mx.effects.EffectManager;
  37. import mx.effects.IEffect;
  38. import mx.effects.IEffectInstance;
  39. import mx.events.ChildExistenceChangedEvent;
  40. import mx.events.DragEvent;
  41. import mx.events.DynamicEvent;
  42. import mx.events.EffectEvent;
  43. import mx.events.FlexEvent;
  44. import mx.events.MoveEvent;
  45. import mx.events.PropertyChangeEvent;
  46. import mx.events.ResizeEvent;
  47. import mx.events.StateChangeEvent;
  48. import mx.events.ToolTipEvent;
  49. import mx.events.ValidationResultEvent;
  50. import mx.graphics.RoundedRectangle;
  51. import mx.managers.CursorManager;
  52. import mx.managers.ICursorManager;
  53. import mx.managers.IFocusManager;
  54. import mx.managers.IFocusManagerComponent;
  55. import mx.managers.IFocusManagerContainer;
  56. import mx.managers.ILayoutManagerClient;
  57. import mx.managers.ISystemManager;
  58. import mx.managers.IToolTipManagerClient;
  59. import mx.managers.SystemManager;
  60. import mx.managers.SystemManagerGlobals;
  61. import mx.managers.SystemManagerProxy;
  62. import mx.managers.ToolTipManager;
  63. import mx.modules.ModuleManager;
  64. import mx.resources.IResourceManager;
  65. import mx.resources.ResourceManager;
  66. import mx.states.State;
  67. import mx.states.Transition;
  68. import mx.styles.CSSStyleDeclaration;
  69. import mx.styles.ISimpleStyleClient;
  70. import mx.styles.IStyleClient;
  71. import mx.styles.StyleManager;
  72. import mx.styles.StyleProtoChain;
  73. import mx.utils.ColorUtil;
  74. import mx.utils.GraphicsUtil;
  75. import mx.utils.StringUtil;
  76. import mx.validators.IValidatorListener;
  77. import mx.validators.ValidationResult;
  78. import flash.system.Security;
  79. use namespace mx_internal;
  80. //--------------------------------------
  81. // Lifecycle events
  82. //--------------------------------------
  83. /**
  84. * Dispatched when the component is added to a container as a content child
  85. * by using the <code>addChild()</code> or <code>addChildAt()</code> method.
  86. * If the component is added to the container as a noncontent child by
  87. * using the <code>rawChildren.addChild()</code> or
  88. * <code>rawChildren.addChildAt()</code> method, the event is not dispatched.
  89. *
  90. * @eventType mx.events.FlexEvent.ADD
  91. */
  92. [Event(name="add", type="mx.events.FlexEvent")]
  93. /**
  94. * Dispatched when the component has finished its construction,
  95. * property processing, measuring, layout, and drawing.
  96. *
  97. * <p>At this point, depending on its <code>visible</code> property,
  98. * the component may not be visible even though it has been drawn.</p>
  99. *
  100. * @eventType mx.events.FlexEvent.CREATION_COMPLETE
  101. */
  102. [Event(name="creationComplete", type="mx.events.FlexEvent")]
  103. /**
  104. * Dispatched when an object has had its <code>commitProperties()</code>,
  105. * <code>measure()</code>, and
  106. * <code>updateDisplayList()</code> methods called (if needed).
  107. *
  108. * <p>This is the last opportunity to alter the component before it is
  109. * displayed. All properties have been committed and the component has
  110. * been measured and layed out.</p>
  111. *
  112. * @eventType mx.events.FlexEvent.UPDATE_COMPLETE
  113. */
  114. [Event(name="updateComplete", type="mx.events.FlexEvent")]
  115. /**
  116. * Dispatched when an object's state changes from visible to invisible.
  117. *
  118. * @eventType mx.events.FlexEvent.HIDE
  119. */
  120. [Event(name="hide", type="mx.events.FlexEvent")]
  121. /**
  122. * Dispatched when the component has finished its construction
  123. * and has all initialization properties set.
  124. *
  125. * <p>After the initialization phase, properties are processed, the component
  126. * is measured, laid out, and drawn, after which the
  127. * <code>creationComplete</code> event is dispatched.</p>
  128. *
  129. * @eventType mx.events.FlexEvent.INITIALIZE
  130. */
  131. [Event(name="initialize", type="mx.events.FlexEvent")]
  132. /**
  133. * Dispatched when the object has moved.
  134. *
  135. * <p>You can move the component by setting the <code>x</code>
  136. * or <code>y</code> properties, by calling the <code>move()</code>
  137. * method, by setting one
  138. * of the following properties either on the component or on other
  139. * components such that the LayoutManager needs to change the
  140. * <code>x</code> or <code>y</code> properties of the component:</p>
  141. *
  142. * <ul>
  143. * <li><code>minWidth</code></li>
  144. * <li><code>minHeight</code></li>
  145. * <li><code>maxWidth</code></li>
  146. * <li><code>maxHeight</code></li>
  147. * <li><code>explicitWidth</code></li>
  148. * <li><code>explicitHeight</code></li>
  149. * </ul>
  150. *
  151. * <p>When you call the <code>move()</code> method, the <code>move</code>
  152. * event is dispatched before the method returns.
  153. * In all other situations, the <code>move</code> event is not dispatched
  154. * until after the property changes.</p>
  155. *
  156. * @eventType mx.events.MoveEvent.MOVE
  157. */
  158. [Event(name="move", type="mx.events.MoveEvent")]
  159. /**
  160. * Dispatched at the beginning of the component initialization sequence.
  161. * The component is in a very raw state when this event is dispatched.
  162. * Many components, such as the Button control, create internal child
  163. * components to implement functionality; for example, the Button control
  164. * creates an internal UITextField component to represent its label text.
  165. * When Flex dispatches the <code>preinitialize</code> event,
  166. * the children, including the internal children, of a component
  167. * have not yet been created.
  168. *
  169. * @eventType mx.events.FlexEvent.PREINITIALIZE
  170. */
  171. [Event(name="preinitialize", type="mx.events.FlexEvent")]
  172. /**
  173. * Dispatched when the component is removed from a container as a content child
  174. * by using the <code>removeChild()</code> or <code>removeChildAt()</code> method.
  175. * If the component is removed from the container as a noncontent child by
  176. * using the <code>rawChildren.removeChild()</code> or
  177. * <code>rawChildren.removeChildAt()</code> method, the event is not dispatched.
  178. *
  179. * @eventType mx.events.FlexEvent.REMOVE
  180. */
  181. [Event(name="remove", type="mx.events.FlexEvent")]
  182. /**
  183. * Dispatched when the component is resized.
  184. *
  185. * <p>You can resize the component by setting the <code>width</code> or
  186. * <code>height</code> property, by calling the <code>setActualSize()</code>
  187. * method, or by setting one of
  188. * the following properties either on the component or on other components
  189. * such that the LayoutManager needs to change the <code>width</code> or
  190. * <code>height</code> properties of the component:</p>
  191. *
  192. * <ul>
  193. * <li><code>minWidth</code></li>
  194. * <li><code>minHeight</code></li>
  195. * <li><code>maxWidth</code></li>
  196. * <li><code>maxHeight</code></li>
  197. * <li><code>explicitWidth</code></li>
  198. * <li><code>explicitHeight</code></li>
  199. * </ul>
  200. *
  201. * <p>The <code>resize</code> event is not
  202. * dispatched until after the property changes.</p>
  203. *
  204. * @eventType mx.events.ResizeEvent.RESIZE
  205. */
  206. [Event(name="resize", type="mx.events.ResizeEvent")]
  207. /**
  208. * Dispatched when an object's state changes from invisible to visible.
  209. *
  210. * @eventType mx.events.FlexEvent.SHOW
  211. */
  212. [Event(name="show", type="mx.events.FlexEvent")]
  213. //--------------------------------------
  214. // Mouse events
  215. //--------------------------------------
  216. /**
  217. * Dispatched from a component opened using the PopUpManager
  218. * when the user clicks outside it.
  219. *
  220. * @eventType mx.events.FlexMouseEvent.MOUSE_DOWN_OUTSIDE
  221. */
  222. [Event(name="mouseDownOutside", type="mx.events.FlexMouseEvent")]
  223. /**
  224. * Dispatched from a component opened using the PopUpManager
  225. * when the user scrolls the mouse wheel outside it.
  226. *
  227. * @eventType mx.events.FlexMouseEvent.MOUSE_WHEEL_OUTSIDE
  228. */
  229. [Event(name="mouseWheelOutside", type="mx.events.FlexMouseEvent")]
  230. //--------------------------------------
  231. // Validation events
  232. //--------------------------------------
  233. /**
  234. * Dispatched when values are changed programmatically
  235. * or by user interaction.
  236. *
  237. * <p>Because a programmatic change triggers this event, make sure
  238. * that any <code>valueCommit</code> event handler does not change
  239. * a value that causes another <code>valueCommit</code> event.
  240. * For example, do not change a control's <code>dataProvider</code>
  241. * property in a <code>valueCommit</code> event handler. </p>
  242. *
  243. * @eventType mx.events.FlexEvent.VALUE_COMMIT
  244. */
  245. [Event(name="valueCommit", type="mx.events.FlexEvent")]
  246. /**
  247. * Dispatched when a component is monitored by a Validator
  248. * and the validation failed.
  249. *
  250. * @eventType mx.events.FlexEvent.INVALID
  251. */
  252. [Event(name="invalid", type="mx.events.FlexEvent")]
  253. /**
  254. * Dispatched when a component is monitored by a Validator
  255. * and the validation succeeded.
  256. *
  257. * @eventType mx.events.FlexEvent.VALID
  258. */
  259. [Event(name="valid", type="mx.events.FlexEvent")]
  260. //--------------------------------------
  261. // Drag-and-drop events
  262. //--------------------------------------
  263. /**
  264. * Dispatched by a component when the user moves the mouse over the component
  265. * during a drag operation.
  266. * In an application running in Flash Player,
  267. * the event is dispatched many times when you move the mouse over any component.
  268. * In an application running in AIR, the event is dispatched only once.
  269. *
  270. * <p>In order to be a valid drop target, you must define a handler
  271. * for this event.
  272. * In the handler, you can change the appearance of the drop target
  273. * to provide visual feedback to the user that the component can accept
  274. * the drag.
  275. * For example, you could draw a border around the drop target,
  276. * or give focus to the drop target.</p>
  277. *
  278. * <p>If you want to accept the drag, you must call the
  279. * <code>DragManager.acceptDragDrop()</code> method. If you don't
  280. * call <code>acceptDragDrop()</code>, you will not get any of the
  281. * other drag events.</p>
  282. *
  283. * <p>In Flash Player, the value of the <code>action</code> property is always
  284. * <code>DragManager.MOVE</code>, even if you are doing a copy.
  285. * This is because the <code>dragEnter</code> event occurs before
  286. * the control recognizes that the Control key is pressed to signal a copy.
  287. * The <code>action</code> property of the event object for the
  288. * <code>dragOver</code> event does contain a value that signifies the type of
  289. * drag operation. You may change the type of drag action by calling the
  290. * <code>DragManager.showFeedback()</code> method.</p>
  291. *
  292. * <p>In AIR, the default value of the <code>action</code> property is
  293. * <code>DragManager.COPY</code>.</p>
  294. *
  295. * <p>Because of the way data to a Tree control is structured,
  296. * the Tree control handles drag and drop differently from the other list-based controls.
  297. * For the Tree control, the event handler for the <code>dragDrop</code> event
  298. * only performs an action when you move or copy data in the same Tree control,
  299. * or copy data to another Tree control.
  300. * If you drag data from one Tree control and drop it onto another Tree control
  301. * to move the data, the event handler for the <code>dragComplete</code> event
  302. * actually performs the work to add the data to the destination Tree control,
  303. * rather than the event handler for the dragDrop event,
  304. * and also removes the data from the source Tree control.
  305. * This is necessary because to reparent the data being moved,
  306. * Flex must remove it first from the source Tree control.</p>
  307. *
  308. * @see mx.managers.DragManager
  309. *
  310. * @eventType mx.events.DragEvent.DRAG_ENTER
  311. */
  312. [Event(name="dragEnter", type="mx.events.DragEvent")]
  313. /**
  314. * Dispatched by a component when the user moves the mouse while over the component
  315. * during a drag operation.
  316. * In Flash Player, the event is dispatched
  317. * when you drag an item over a valid drop target.
  318. * In AIR, the event is dispatched when you drag an item over
  319. * any component, even if the component is not a valid drop target.
  320. *
  321. * <p>In the handler, you can change the appearance of the drop target
  322. * to provide visual feedback to the user that the component can accept
  323. * the drag.
  324. * For example, you could draw a border around the drop target,
  325. * or give focus to the drop target.</p>
  326. *
  327. * <p>You should handle this event to perform additional logic
  328. * before allowing the drop, such as dropping data to various locations
  329. * in the drop target, reading keyboard input to determine if the
  330. * drag-and-drop action is a move or copy of the drag data, or providing
  331. * different types of visual feedback based on the type of drag-and-drop
  332. * action.</p>
  333. *
  334. * <p>You may also change the type of drag action by changing the
  335. * <code>DragManager.showFeedback()</code> method.
  336. * The default value of the <code>action</code> property is
  337. * <code>DragManager.MOVE</code>.</p>
  338. *
  339. * @see mx.managers.DragManager
  340. *
  341. * @eventType mx.events.DragEvent.DRAG_OVER
  342. */
  343. [Event(name="dragOver", type="mx.events.DragEvent")]
  344. /**
  345. * Dispatched by the component when the user drags outside the component,
  346. * but does not drop the data onto the target.
  347. *
  348. * <p>You use this event to restore the drop target to its normal appearance
  349. * if you modified its appearance as part of handling the
  350. * <code>dragEnter</code> or <code>dragOver</code> event.</p>
  351. *
  352. * @eventType mx.events.DragEvent.DRAG_EXIT
  353. */
  354. [Event(name="dragExit", type="mx.events.DragEvent")]
  355. /**
  356. * Dispatched by the drop target when the user releases the mouse over it.
  357. *
  358. * <p>You use this event handler to add the drag data to the drop target.</p>
  359. *
  360. * <p>If you call <code>Event.preventDefault()</code> in the event handler
  361. * for the <code>dragDrop</code> event for
  362. * a Tree control when dragging data from one Tree control to another,
  363. * it prevents the drop.</p>
  364. *
  365. * @eventType mx.events.DragEvent.DRAG_DROP
  366. */
  367. [Event(name="dragDrop", type="mx.events.DragEvent")]
  368. /**
  369. * Dispatched by the drag initiator (the component that is the source
  370. * of the data being dragged) when the drag operation completes,
  371. * either when you drop the dragged data onto a drop target or when you end
  372. * the drag-and-drop operation without performing a drop.
  373. *
  374. * <p>You can use this event to perform any final cleanup
  375. * of the drag-and-drop operation.
  376. * For example, if you drag a List control item from one list to another,
  377. * you can delete the List control item from the source if you no longer
  378. * need it.</p>
  379. *
  380. * <p>If you call <code>Event.preventDefault()</code> in the event handler
  381. * for the <code>dragComplete</code> event for
  382. * a Tree control when dragging data from one Tree control to another,
  383. * it prevents the drop.</p>
  384. *
  385. * @eventType mx.events.DragEvent.DRAG_COMPLETE
  386. */
  387. [Event(name="dragComplete", type="mx.events.DragEvent")]
  388. /**
  389. * Dispatched by the drag initiator when starting a drag operation.
  390. * This event is used internally by the list-based controls;
  391. * you do not handle it when implementing drag and drop.
  392. * If you want to control the start of a drag-and-drop operation,
  393. * use the <code>mouseDown</code> or <code>mouseMove</code> event.
  394. *
  395. * @eventType mx.events.DragEvent.DRAG_START
  396. */
  397. [Event(name="dragStart", type="mx.events.DragEvent")]
  398. //--------------------------------------
  399. // Effect events
  400. //--------------------------------------
  401. /**
  402. * Dispatched just before an effect starts.
  403. *
  404. * <p>The effect does not start changing any visuals
  405. * until after this event is fired.</p>
  406. *
  407. * @eventType mx.events.EffectEvent.EFFECT_START
  408. */
  409. [Event(name="effectStart", type="mx.events.EffectEvent")]
  410. /**
  411. * Dispatched after an effect ends.
  412. *
  413. * <p>The effect will have made the last set of visual changes
  414. * before this event is fired, but those changes will not have
  415. * been rendered on the screen.
  416. * Thus, you might have to use the <code>callLater()</code> method
  417. * to delay any other changes that you want to make until after the
  418. * changes have been rendered onscreen.</p>
  419. *
  420. * @eventType mx.events.EffectEvent.EFFECT_END
  421. */
  422. [Event(name="effectEnd", type="mx.events.EffectEvent")]
  423. //--------------------------------------
  424. // State events
  425. //--------------------------------------
  426. /**
  427. * Dispatched after the <code>currentState</code> property changes,
  428. * but before the view state changes.
  429. *
  430. * @eventType mx.events.StateChangeEvent.CURRENT_STATE_CHANGING
  431. */
  432. [Event(name="currentStateChanging", type="mx.events.StateChangeEvent")]
  433. /**
  434. * Dispatched after the view state has changed.
  435. *
  436. * @eventType mx.events.StateChangeEvent.CURRENT_STATE_CHANGE
  437. */
  438. [Event(name="currentStateChange", type="mx.events.StateChangeEvent")]
  439. /**
  440. * Dispatched after the component has returned to the root view state.
  441. *
  442. * @eventType mx.events.FlexEvent.ENTER_STATE
  443. */
  444. [Event(name="enterState", type="mx.events.FlexEvent")]
  445. /**
  446. * Dispatched before the component exits from the root view state.
  447. *
  448. * @eventType mx.events.FlexEvent.EXIT_STATE
  449. */
  450. [Event(name="exitState", type="mx.events.FlexEvent")]
  451. //--------------------------------------
  452. // Tooltip events
  453. //--------------------------------------
  454. /**
  455. * Dispatched by the component when it is time to create a ToolTip.
  456. *
  457. * <p>If you create your own IToolTip object and place a reference
  458. * to it in the <code>toolTip</code> property of the event object
  459. * that is passed to your <code>toolTipCreate</code> handler,
  460. * the ToolTipManager displays your custom ToolTip.
  461. * Otherwise, the ToolTipManager creates an instance of
  462. * <code>ToolTipManager.toolTipClass</code> to display.</p>
  463. *
  464. * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
  465. * <code>toolTipCreate</code>, <code>toolTipShow</code>,
  466. * <code>toolTipShown</code>, <code>toolTipHide</code>,
  467. * and <code>toolTipEnd</code>.</p>
  468. *
  469. * @eventType mx.events.ToolTipEvent.TOOL_TIP_CREATE
  470. */
  471. [Event(name="toolTipCreate", type="mx.events.ToolTipEvent")]
  472. /**
  473. * Dispatched by the component when its ToolTip has been hidden
  474. * and will be discarded soon.
  475. *
  476. * <p>If you specify an effect using the
  477. * <code>ToolTipManager.hideEffect</code> property,
  478. * this event is dispatched after the effect stops playing.</p>
  479. *
  480. * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
  481. * <code>toolTipCreate</code>, <code>toolTipShow</code>,
  482. * <code>toolTipShown</code>, <code>toolTipHide</code>,
  483. * and <code>toolTipEnd</code>.</p>
  484. *
  485. * @eventType mx.events.ToolTipEvent.TOOL_TIP_END
  486. */
  487. [Event(name="toolTipEnd", type="mx.events.ToolTipEvent")]
  488. /**
  489. * Dispatched by the component when its ToolTip is about to be hidden.
  490. *
  491. * <p>If you specify an effect using the
  492. * <code>ToolTipManager.hideEffect</code> property,
  493. * this event is dispatched before the effect starts playing.</p>
  494. *
  495. * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
  496. * <code>toolTipCreate</code>, <code>toolTipShow</code>,
  497. * <code>toolTipShown</code>, <code>toolTipHide</code>,
  498. * and <code>toolTipEnd</code>.</p>
  499. *
  500. * @eventType mx.events.ToolTipEvent.TOOL_TIP_HIDE
  501. */
  502. [Event(name="toolTipHide", type="mx.events.ToolTipEvent")]
  503. /**
  504. * Dispatched by the component when its ToolTip is about to be shown.
  505. *
  506. * <p>If you specify an effect using the
  507. * <code>ToolTipManager.showEffect</code> property,
  508. * this event is dispatched before the effect starts playing.
  509. * You can use this event to modify the ToolTip before it appears.</p>
  510. *
  511. * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
  512. * <code>toolTipCreate</code>, <code>toolTipShow</code>,
  513. * <code>toolTipShown</code>, <code>toolTipHide</code>,
  514. * and <code>toolTipEnd</code>.</p>
  515. *
  516. * @eventType mx.events.ToolTipEvent.TOOL_TIP_SHOW
  517. */
  518. [Event(name="toolTipShow", type="mx.events.ToolTipEvent")]
  519. /**
  520. * Dispatched by the component when its ToolTip has been shown.
  521. *
  522. * <p>If you specify an effect using the
  523. * <code>ToolTipManager.showEffect</code> property,
  524. * this event is dispatched after the effect stops playing.</p>
  525. *
  526. * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
  527. * <code>toolTipCreate</code>, <code>toolTipShow</code>,
  528. * <code>toolTipShown</code>, <code>toolTipHide</code>,
  529. * and <code>toolTipEnd</code>.</p>
  530. *
  531. * @eventType mx.events.ToolTipEvent.TOOL_TIP_SHOWN
  532. */
  533. [Event(name="toolTipShown", type="mx.events.ToolTipEvent")]
  534. /**
  535. * Dispatched by a component whose <code>toolTip</code> property is set,
  536. * as soon as the user moves the mouse over it.
  537. *
  538. * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
  539. * <code>toolTipCreate</code>, <code>toolTipShow</code>,
  540. * <code>toolTipShown</code>, <code>toolTipHide</code>,
  541. * and <code>toolTipEnd</code>.</p>
  542. *
  543. * @eventType mx.events.ToolTipEvent.TOOL_TIP_START
  544. */
  545. [Event(name="toolTipStart", type="mx.events.ToolTipEvent")]
  546. //--------------------------------------
  547. // Styles
  548. //--------------------------------------
  549. include "../styles/metadata/AnchorStyles.as";
  550. /**
  551. * Color of the component highlight when validation fails.
  552. * Flex also sets the <code>borderColor</code> style of the component to this
  553. * <code>errorColor</code> on a validation failure.
  554. *
  555. * @default 0xFF0000
  556. */
  557. [Style(name="errorColor", type="uint", format="Color", inherit="yes")]
  558. /**
  559. * Blend mode used by the focus rectangle.
  560. * For more information, see the <code>blendMode</code> property
  561. * of the flash.display.DisplayObject class.
  562. *
  563. * @default "normal"
  564. */
  565. [Style(name="focusBlendMode", type="String", inherit="no")]
  566. /**
  567. * Skin used to draw the focus rectangle.
  568. *
  569. * @default mx.skins.halo.HaloFocusRect
  570. */
  571. [Style(name="focusSkin", type="Class", inherit="no")]
  572. /**
  573. * Thickness, in pixels, of the focus rectangle outline.
  574. *
  575. * @default 2
  576. */
  577. [Style(name="focusThickness", type="Number", format="Length", inherit="no")]
  578. /**
  579. * Theme color of a component. This property controls the appearance of highlights,
  580. * appearance when a component is selected, and other similar visual cues, but it
  581. * does not have any effect on the regular borders or background colors of the component.
  582. * The preferred values are <code>haloGreen</code>, <code>haloBlue</code>,
  583. * <code>haloOrange</code>, and <code>haloSilver</code>, although any valid color
  584. * value can be used.
  585. *
  586. * <p>The default values of the <code>rollOverColor</code> and
  587. * <code>selectionColor</code> styles are based on the
  588. * <code>themeColor</code> value.</p>
  589. *
  590. * @default "haloBlue"
  591. */
  592. [Style(name="themeColor", type="uint", format="Color", inherit="yes")]
  593. //--------------------------------------
  594. // Effects
  595. //--------------------------------------
  596. /**
  597. * Played when the component is created.
  598. */
  599. [Effect(name="creationCompleteEffect", event="creationComplete")]
  600. /**
  601. * Played when the component is moved.
  602. */
  603. [Effect(name="moveEffect", event="move")]
  604. /**
  605. * Played when the component is resized.
  606. */
  607. [Effect(name="resizeEffect", event="resize")]
  608. /**
  609. * Played when the component becomes visible.
  610. */
  611. [Effect(name="showEffect", event="show")]
  612. /**
  613. * Played when the component becomes invisible.
  614. */
  615. [Effect(name="hideEffect", event="hide")]
  616. /**
  617. * Played when the user presses the mouse button while over the component.
  618. */
  619. [Effect(name="mouseDownEffect", event="mouseDown")]
  620. /**
  621. * Played when the user releases the mouse button while over the component.
  622. */
  623. [Effect(name="mouseUpEffect", event="mouseUp")]
  624. /**
  625. * Played when the user rolls the mouse over the component.
  626. */
  627. [Effect(name="rollOverEffect", event="rollOver")]
  628. /**
  629. * Played when the user rolls the mouse so it is no longer over the component.
  630. */
  631. [Effect(name="rollOutEffect", event="rollOut")]
  632. /**
  633. * Played when the component gains keyboard focus.
  634. */
  635. [Effect(name="focusInEffect", event="focusIn")]
  636. /**
  637. * Played when the component loses keyboard focus.
  638. */
  639. [Effect(name="focusOutEffect", event="focusOut")]
  640. /**
  641. * Played when the component is added as a child to a Container.
  642. */
  643. [Effect(name="addedEffect", event="added")]
  644. /**
  645. * Played when the component is removed from a Container.
  646. */
  647. [Effect(name="removedEffect", event="removed")]
  648. //--------------------------------------
  649. // Other metadata
  650. //--------------------------------------
  651. [AccessibilityClass(implementation="mx.accessibility.UIComponentAccImpl")]
  652. [ResourceBundle("core")]
  653. // skins resources aren't found because CSS visited by the compiler
  654. [ResourceBundle("skins")]
  655. /**
  656. * The UIComponent class is the base class for all visual components,
  657. * both interactive and noninteractive.
  658. *
  659. * <p>An interactive component can participate in tabbing and other kinds of
  660. * keyboard focus manipulation, accept low-level events like keyboard and
  661. * mouse input, and be disabled so that it does not receive keyboard and
  662. * mouse input.
  663. * This is in contrast to noninteractive components, like Label and
  664. * ProgressBar, which simply display contents and are not manipulated by
  665. * the user.</p>
  666. * <p>The UIComponent class is not used as an MXML tag, but is used as a base
  667. * class for other classes.</p>
  668. *
  669. * @mxml
  670. *
  671. * <p>All user interface components in Flex extend the UIComponent class.
  672. * Flex components inherit the following properties from the UIComponent
  673. * class:</p>
  674. *
  675. * <pre>
  676. * &lt;mx:<i>tagname</i>
  677. * <b>Properties </b>
  678. * automationName="null"
  679. * cachePolicy="auto|on|off"
  680. * currentState="null"
  681. * doubleClickEnabled="false|true"
  682. * enabled="true|false"
  683. * explicitHeight="NaN"
  684. * explicitMaxHeight="NaN"
  685. * explicitMaxWidth="NaN"
  686. * explicitMinHeight="NaN"
  687. * explicitMinWidth="NaN"
  688. * explicitWidth="NaN"
  689. * focusEnabled="true|false"
  690. * height="0"
  691. * id=""
  692. * includeInLayout="true|false"
  693. * maxHeight="10000"
  694. * maxWidth="10000"
  695. * measuredHeight=
  696. * measuredMinHeight=
  697. * measuredMinWidth=
  698. * measuredWidth=
  699. * minHeight="0"
  700. * minWidth="0"
  701. * mouseFocusEnabled="true|false"
  702. * percentHeight="NaN"
  703. * percentWidth="NaN"
  704. * scaleX="1.0"
  705. * scaleY="1.0"
  706. * states="null"
  707. * styleName="undefined"
  708. * toolTip="null"
  709. * transitions=""
  710. * validationSubField
  711. * width="0"
  712. * x="0"
  713. * y="0"
  714. *
  715. * <b>Styles</b>
  716. * bottom="undefined"
  717. * errorColor="0xFF0000"
  718. * focusBlendMode="normal"
  719. * focusSkin="HaloFocusRect""
  720. * focusThickness="2"
  721. * horizontalCenter="undefined"
  722. * left="undefined"
  723. * right="undefined"
  724. * themeColor="haloGreen"
  725. * top="undefined"
  726. * verticalCenter="undefined"
  727. *
  728. * <b>Effects</b>
  729. * addedEffect="<i>No default</i>"
  730. * creationCompleteEffect="<i>No default</i>"
  731. * focusInEffect="<i>No default</i>"
  732. * focusOutEffect="<i>No default</i>"
  733. * hideEffect="<i>No default</i>"
  734. * mouseDownEffect="<i>No default</i>"
  735. * mouseUpEffect="<i>No default</i>"
  736. * moveEffect="<i>No default</i>"
  737. * removedEffect="<i>No default</i>"
  738. * resizeEffect="<i>No default</i>"
  739. * rollOutEffect="<i>No default</i>"
  740. * rollOverEffect="<i>No default</i>"
  741. * showEffect="<i>No default</i>"
  742. *
  743. * <b>Events</b>
  744. * add="<i>No default</i>"
  745. * creationComplete="<i>No default</i>"
  746. * currentStateChange="<i>No default</i>"
  747. * currentStateChanging="<i>No default</i>"
  748. * dragComplete="<i>No default</i>"
  749. * dragDrop="<i>No default</i>"
  750. * dragEnter="<i>No default</i>"
  751. * dragExit="<i>No default</i>"
  752. * dragOver="<i>No default</i>"
  753. * effectEnd="<i>No default</i>"
  754. * effectStart="<i>No default</i>"
  755. * enterState="<i>No default</i>"
  756. * exitState="<i>No default</i>"
  757. * hide="<i>No default</i>"
  758. * initialize="<i>No default</i>"
  759. * invalid="<i>No default</i>"
  760. * mouseDownOutside="<i>No default</i>"
  761. * mouseWheelOutside="<i>No default</i>"
  762. * move="<i>No default</i>"
  763. * preinitialize="<i>No default</i>"
  764. * record="<i>No default</i>"
  765. * remove="<i>No default</i>"
  766. * resize="<i>No default</i>"
  767. * show="<i>No default</i>"
  768. * toolTipCreate="<i>No default</i>"
  769. * toolTipEnd="<i>No default</i>"
  770. * toolTipHide="<i>No default</i>"
  771. * toolTipShow="<i>No default</i>"
  772. * toolTipShown="<i>No default</i>"
  773. * toolTipStart="<i>No default</i>"
  774. * updateComplete="<i>No default</i>"
  775. * valid="<i>No default</i>"
  776. * valueCommit="<i>No default</i>"
  777. * &gt;
  778. * </pre>
  779. *
  780. * @see mx.core.UIComponent
  781. */
  782. public class UIComponent extends FlexSprite
  783. implements IAutomationObject, IChildList,
  784. IDeferredInstantiationUIComponent, IFlexDisplayObject,
  785. IFlexModule,
  786. IInvalidating, ILayoutManagerClient,
  787. IPropertyChangeNotifier, IRepeaterClient,
  788. ISimpleStyleClient, IStyleClient,
  789. IToolTipManagerClient, IUIComponent,
  790. IValidatorListener, IStateClient,
  791. IConstraintClient
  792. {
  793. include "../core/Version.as";
  794. //--------------------------------------------------------------------------
  795. //
  796. // Class constants
  797. //
  798. //--------------------------------------------------------------------------
  799. /**
  800. * The default value for the <code>measuredWidth</code> property.
  801. * Most components calculate a measuredWidth but some are flow-based and
  802. * have to pick a number that looks reasonable.
  803. *
  804. * @default 160
  805. */
  806. public static const DEFAULT_MEASURED_WIDTH:Number = 160;
  807. /**
  808. * The default value for the <code>measuredMinWidth</code> property.
  809. * Most components calculate a measuredMinWidth but some are flow-based and
  810. * have to pick a number that looks reasonable.
  811. *
  812. * @default 40
  813. */
  814. public static const DEFAULT_MEASURED_MIN_WIDTH:Number = 40;
  815. /**
  816. * The default value for the <code>measuredHeight</code> property.
  817. * Most components calculate a measuredHeight but some are flow-based and
  818. * have to pick a number that looks reasonable.
  819. *
  820. * @default 22
  821. */
  822. public static const DEFAULT_MEASURED_HEIGHT:Number = 22;
  823. /**
  824. * The default value for the <code>measuredMinHeight</code> property.
  825. * Most components calculate a measuredMinHeight but some are flow-based and
  826. * have to pick a number that looks reasonable.
  827. *
  828. * @default 22
  829. */
  830. public static const DEFAULT_MEASURED_MIN_HEIGHT:Number = 22;
  831. /**
  832. * The default value for the <code>maxWidth</code> property.
  833. *
  834. * @default 10000
  835. */
  836. public static const DEFAULT_MAX_WIDTH:Number = 10000;
  837. /**
  838. * The default value for the <code>maxHeight</code> property.
  839. *
  840. * @default 10000
  841. */
  842. public static const DEFAULT_MAX_HEIGHT:Number = 10000;
  843. /**
  844. * @private
  845. * The inheritingStyles and nonInheritingStyles properties
  846. * are initialized to this empty Object.
  847. * This allows the getStyle() and getStyle()
  848. * methods to simply access inheritingStyles[] and nonInheritingStyles[]
  849. * without needing to first check whether those objects exist.
  850. * If they were simply initialized to {}, we couldn't determine
  851. * whether the style chain has already been built or not.
  852. */
  853. mx_internal static var STYLE_UNINITIALIZED:Object = {};
  854. //--------------------------------------------------------------------------
  855. //
  856. // Class mixins
  857. //
  858. //--------------------------------------------------------------------------
  859. /**
  860. * @private
  861. * Placeholder for mixin by UIComponentAccImpl.
  862. */
  863. mx_internal static var createAccessibilityImplementation:Function;
  864. //--------------------------------------------------------------------------
  865. //
  866. // Class properties
  867. //
  868. //--------------------------------------------------------------------------
  869. //----------------------------------
  870. // embeddedFontRegistry
  871. //----------------------------------
  872. /**
  873. * @private
  874. * Storage for the _embeddedFontRegistry property.
  875. * Note: This gets initialized on first access,
  876. * not when this class is initialized, in order to ensure
  877. * that the Singleton registry has already been initialized.
  878. */
  879. private static var _embeddedFontRegistry:IEmbeddedFontRegistry;
  880. /**
  881. * @private
  882. * A reference to the embedded font registry.
  883. * Single registry in the system.
  884. * Used to look up the moduleFactory of a font.
  885. */
  886. private static function get embeddedFontRegistry():IEmbeddedFontRegistry
  887. {
  888. if (!_embeddedFontRegistry)
  889. {
  890. _embeddedFontRegistry = IEmbeddedFontRegistry(
  891. Singleton.getInstance("mx.core::IEmbeddedFontRegistry"));
  892. }
  893. return _embeddedFontRegistry;
  894. }
  895. //--------------------------------------------------------------------------
  896. //
  897. // Class methods
  898. //
  899. //--------------------------------------------------------------------------
  900. /**
  901. * Blocks the background processing of methods
  902. * queued by <code>callLater()</code>,
  903. * until <code>resumeBackgroundProcessing()</code> is called.
  904. *
  905. * <p>These methods can be useful when you have time-critical code
  906. * which needs to execute without interruption.
  907. * For example, when you set the <code>suspendBackgroundProcessing</code>
  908. * property of an Effect to <code>true</code>,
  909. * <code>suspendBackgroundProcessing()</code> is automatically called
  910. * when it starts playing, and <code>resumeBackgroundProcessing</code>
  911. * is called when it stops, in order to ensure that the animation
  912. * is smooth.</p>
  913. *
  914. * <p>Since the LayoutManager uses <code>callLater()</code>,
  915. * this means that <code>commitProperties()</code>,
  916. * <code>measure()</code>, and <code>updateDisplayList()</code>
  917. * will not get called in between calls to
  918. * <code>suspendBackgroundProcessing()</code> and
  919. * <code>resumeBackgroundProcessing()</code>.</p>
  920. *
  921. * <p>It is safe for both an outer method and an inner method
  922. * (i.e., one that the outer methods calls) to call
  923. * <code>suspendBackgroundProcessing()</code>
  924. * and <code>resumeBackgroundProcessing()</code>, because these
  925. * methods actually increment and decrement a counter
  926. * which determines whether background processing occurs.</p>
  927. */
  928. public static function suspendBackgroundProcessing():void
  929. {
  930. UIComponentGlobals.callLaterSuspendCount++;
  931. }
  932. /**
  933. * Resumes the background processing of methods
  934. * queued by <code>callLater()</code>, after a call to
  935. * <code>suspendBackgroundProcessing()</code>.
  936. *
  937. * <p>Refer to the description of
  938. * <code>suspendBackgroundProcessing()</code> for more information.</p>
  939. */
  940. public static function resumeBackgroundProcessing():void
  941. {
  942. if (UIComponentGlobals.callLaterSuspendCount > 0)
  943. {
  944. UIComponentGlobals.callLaterSuspendCount--;
  945. // Once the suspend count gets back to 0, we need to
  946. // force a render event to happen
  947. if (UIComponentGlobals.callLaterSuspendCount == 0)
  948. {
  949. var sm:ISystemManager = SystemManagerGlobals.topLevelSystemManagers[0];
  950. if (sm && sm.stage)
  951. sm.stage.invalidate();
  952. }
  953. }
  954. }
  955. //--------------------------------------------------------------------------
  956. //
  957. // Constructor
  958. //
  959. //--------------------------------------------------------------------------
  960. /**
  961. * Constructor.
  962. */
  963. public function UIComponent()
  964. {
  965. super();
  966. // Override variables in superclasses.
  967. focusRect = false; // We do our own focus drawing.
  968. tabEnabled = (this is IFocusManagerComponent);
  969. // We are tab enabled by default if IFocusManagerComponent
  970. tabChildren = false;
  971. // Whether the component can accept user interaction.
  972. // The default is true. If you set enabled to false for a container,
  973. // Flex dims the color of the container and of all of its children,
  974. // and blocks user input to the container and to all of its children.
  975. // We set enabled to true here because some components keep their
  976. // own _enabled flag and may not initialize it to true.
  977. enabled = true;
  978. // Make the component invisible until the initialization sequence
  979. // is complete.
  980. // It will be set visible when the 'initialized' flag is set.
  981. $visible = false;
  982. addEventListener(Event.ADDED, addedHandler);
  983. addEventListener(Event.REMOVED, removedHandler);
  984. // Register for focus and keyboard events.
  985. if (this is IFocusManagerComponent)
  986. {
  987. addEventListener(FocusEvent.FOCUS_IN, focusInHandler);
  988. addEventListener(FocusEvent.FOCUS_OUT, focusOutHandler);
  989. addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
  990. addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
  991. }
  992. resourcesChanged();
  993. // Register as a weak listener for "change" events from ResourceManager.
  994. // If UIComponents registered as a strong listener,
  995. // they wouldn't get garbage collected.
  996. resourceManager.addEventListener(
  997. Event.CHANGE, resourceManager_changeHandler, false, 0, true);
  998. _width = super.width;
  999. _height = super.height;
  1000. }
  1001. //--------------------------------------------------------------------------
  1002. //
  1003. // Variables
  1004. //
  1005. //--------------------------------------------------------------------------
  1006. /**
  1007. * @private
  1008. * There is a bug (139381) where we occasionally get callLaterDispatcher()
  1009. * even though we didn't expect it.
  1010. * That causes us to do a removeEventListener() twice,
  1011. * which messes up some internal thing in the player so that
  1012. * the next addEventListener() doesn't actually get us the render event.
  1013. */
  1014. private var listeningForRender:Boolean = false;
  1015. /**
  1016. * @private
  1017. * List of methods used by callLater().
  1018. */
  1019. private var methodQueue:Array /* of MethodQueueElement */ = [];
  1020. /**
  1021. * @private
  1022. * Whether or not we "own" the focus graphic
  1023. */
  1024. private var hasFocusRect:Boolean = false;
  1025. //--------------------------------------------------------------------------
  1026. //
  1027. // Variables: Creation
  1028. //
  1029. //--------------------------------------------------------------------------
  1030. //----------------------------------
  1031. // initialized
  1032. //----------------------------------
  1033. /**
  1034. * @private
  1035. * Storage for the initialized property.
  1036. */
  1037. private var _initialized:Boolean = false;
  1038. [Inspectable(environment="none")]
  1039. /**
  1040. * A flag that determines if an object has been through all three phases
  1041. * of layout: commitment, measurement, and layout (provided that any were required).
  1042. */
  1043. public function get initialized():Boolean
  1044. {
  1045. return _initialized;
  1046. }
  1047. /**
  1048. * @private
  1049. */
  1050. public function set initialized(value:Boolean):void
  1051. {
  1052. _initialized = value;
  1053. if (value)
  1054. {
  1055. setVisible(_visible, true);
  1056. dispatchEvent(new FlexEvent(FlexEvent.CREATION_COMPLETE));
  1057. }
  1058. }
  1059. //----------------------------------
  1060. // processedDescriptors
  1061. //----------------------------------
  1062. /**
  1063. * @private
  1064. * Storage for the processedDescriptors property.
  1065. */
  1066. private var _processedDescriptors:Boolean = false;
  1067. [Inspectable(environment="none")]
  1068. /**
  1069. * Set to <code>true</code> after immediate or deferred child creation,
  1070. * depending on which one happens. For a Container object, it is set
  1071. * to <code>true</code> at the end of
  1072. * the <code>createComponentsFromDescriptors()</code> method,
  1073. * meaning after the Container object creates its children from its child descriptors.
  1074. *
  1075. * <p>For example, if an Accordion container uses deferred instantiation,
  1076. * the <code>processedDescriptors</code> property for the second pane of
  1077. * the Accordion container does not become <code>true</code> until after
  1078. * the user navigates to that pane and the pane creates its children.
  1079. * But, if the Accordion had set the <code>creationPolicy</code> property
  1080. * to <code>"all"</code>, the <code>processedDescriptors</code> property
  1081. * for its second pane is set to <code>true</code> during application startup.</p>
  1082. *
  1083. * <p>For classes that are not containers, which do not have descriptors,
  1084. * it is set to <code>true</code> after the <code>createChildren()</code>
  1085. * method creates any internal component children.</p>
  1086. */
  1087. public function get processedDescriptors():Boolean
  1088. {
  1089. return _processedDescriptors;
  1090. }
  1091. /**
  1092. * @private
  1093. */
  1094. public function set processedDescriptors(value:Boolean):void
  1095. {
  1096. _processedDescriptors = value;
  1097. if (value)
  1098. dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
  1099. }
  1100. //----------------------------------
  1101. // updateCompletePendingFlag
  1102. //----------------------------------
  1103. /**
  1104. * @private
  1105. * Storage for the updateCompletePendingFlag property.
  1106. */
  1107. private var _updateCompletePendingFlag:Boolean = false;
  1108. [Inspectable(environment="none")]
  1109. /**
  1110. * A flag that determines if an object has been through all three phases
  1111. * of layout validation (provided that any were required).
  1112. */
  1113. public function get updateCompletePendingFlag():Boolean
  1114. {
  1115. return _updateCompletePendingFlag;
  1116. }
  1117. /**
  1118. * @private
  1119. */
  1120. public function set updateCompletePendingFlag(value:Boolean):void
  1121. {
  1122. _updateCompletePendingFlag = value;
  1123. }
  1124. //--------------------------------------------------------------------------
  1125. //
  1126. // Variables: Invalidation
  1127. //
  1128. //--------------------------------------------------------------------------
  1129. /**
  1130. * @private
  1131. * Whether this component needs to have its
  1132. * commitProperties() method called.
  1133. */
  1134. mx_internal var invalidatePropertiesFlag:Boolean = false;
  1135. /**
  1136. * @private
  1137. * Whether this component needs to have its
  1138. * measure() method called.
  1139. */
  1140. mx_internal var invalidateSizeFlag:Boolean = false;
  1141. /**
  1142. * @private
  1143. * Whether this component needs to be have its
  1144. * updateDisplayList() method called.
  1145. */
  1146. mx_internal var invalidateDisplayListFlag:Boolean = false;
  1147. //--------------------------------------------------------------------------
  1148. //
  1149. // Variables: Measurement
  1150. //
  1151. //--------------------------------------------------------------------------
  1152. /**
  1153. * @private
  1154. * Holds the last recorded value of the x property.
  1155. * Used in dispatching a MoveEvent.
  1156. */
  1157. private var oldX:Number = 0;
  1158. /**
  1159. * @private
  1160. * Holds the last recorded value of the y property.
  1161. * Used in dispatching a MoveEvent.
  1162. */
  1163. private var oldY:Number = 0;
  1164. /**
  1165. * @private
  1166. * Holds the last recorded value of the width property.
  1167. * Used in dispatching a ResizeEvent.
  1168. */
  1169. private var oldWidth:Number = 0;
  1170. /**
  1171. * @private
  1172. * Holds the last recorded value of the height property.
  1173. * Used in dispatching a ResizeEvent.
  1174. */
  1175. private var oldHeight:Number = 0;
  1176. /**
  1177. * @private
  1178. * Holds the last recorded value of the minWidth property.
  1179. */
  1180. private var oldMinWidth:Number;
  1181. /**
  1182. * @private
  1183. * Holds the last recorded value of the minHeight property.
  1184. */
  1185. private var oldMinHeight:Number;
  1186. /**
  1187. * @private
  1188. * Holds the last recorded value of the explicitWidth property.
  1189. */
  1190. private var oldExplicitWidth:Number;
  1191. /**
  1192. * @private
  1193. * Holds the last recorded value of the explicitHeight property.
  1194. */
  1195. private var oldExplicitHeight:Number;
  1196. /**
  1197. * @private
  1198. * Holds the last recorded value of the scaleX property.
  1199. */
  1200. private var oldScaleX:Number = 1.0;
  1201. /**
  1202. * @private
  1203. * Holds the last recorded value of the scaleY property.
  1204. */
  1205. private var oldScaleY:Number = 1.0;
  1206. /**
  1207. * @private
  1208. * True if createInFontContext has been called.
  1209. */
  1210. private var hasFontContextBeenSaved:Boolean = false;
  1211. /**
  1212. * @private
  1213. * Holds the last recorded value of the module factory used to create the font.
  1214. */
  1215. private var oldEmbeddedFontContext:IFlexModuleFactory = null;
  1216. /**
  1217. * @private
  1218. *
  1219. * Cache last value of embedded font.
  1220. */
  1221. private var cachedEmbeddedFont:EmbeddedFont = null;
  1222. //--------------------------------------------------------------------------
  1223. //
  1224. // Variables: Styles
  1225. //
  1226. //--------------------------------------------------------------------------
  1227. /**
  1228. * @private
  1229. */
  1230. private var cachedTextFormat:UITextFormat;
  1231. //--------------------------------------------------------------------------
  1232. //
  1233. // Variables: Effects
  1234. //
  1235. //--------------------------------------------------------------------------
  1236. /**
  1237. * @private
  1238. * Sprite used to display an overlay.
  1239. */
  1240. mx_internal var overlay:UIComponent;
  1241. /**
  1242. * @private
  1243. * Color used for overlay.
  1244. */
  1245. mx_internal var overlayColor:uint;
  1246. /**
  1247. * @private
  1248. * Counter to keep track of the number of current users
  1249. * of the overlay.
  1250. */
  1251. mx_internal var overlayReferenceCount:int = 0;
  1252. //--------------------------------------------------------------------------
  1253. //
  1254. // Variables: Validation
  1255. //
  1256. //--------------------------------------------------------------------------
  1257. /**
  1258. * @private
  1259. */
  1260. mx_internal var saveBorderColor:Boolean = true;
  1261. /**
  1262. * @private
  1263. */
  1264. mx_internal var origBorderColor:Number;
  1265. //--------------------------------------------------------------------------
  1266. //
  1267. // Variables: Other
  1268. //
  1269. //--------------------------------------------------------------------------
  1270. /**
  1271. * @private
  1272. * Storage for automatically-created RadioButtonGroups.
  1273. * If a RadioButton's groupName isn't the id of a RadioButtonGroup tag,
  1274. * we automatically create a RadioButtonGroup and store it here as
  1275. * document.automaticRadioButtonGroups[groupName] = theRadioButtonGroup;
  1276. */
  1277. mx_internal var automaticRadioButtonGroups:Object;
  1278. //--------------------------------------------------------------------------
  1279. //
  1280. // Overridden properties
  1281. //
  1282. //--------------------------------------------------------------------------
  1283. //----------------------------------
  1284. // owner
  1285. //----------------------------------
  1286. /**
  1287. * @private
  1288. */
  1289. private var _owner:DisplayObjectContainer;
  1290. /**
  1291. * The owner of this UIComponent. By default, it is the parent of this UIComponent.
  1292. * However, if this UIComponent object is a child component that is
  1293. * popped up by its parent, such as the dropdown list of a ComboBox control,
  1294. * the owner is the component that popped up this UIComponent object.
  1295. *
  1296. * <p>This property is not managed by Flex, but by each component.
  1297. * Therefore, if you use the <code>PopUpManger.createPopUp()</code> or
  1298. * <code>PopUpManger.addPopUp()</code> method to pop up a child component,
  1299. * you should set the <code>owner</code> property of the child component
  1300. * to the component that popped it up.</p>
  1301. *
  1302. * <p>The default value is the value of the <code>parent</code> property.</p>
  1303. */
  1304. public function get owner():DisplayObjectContainer
  1305. {
  1306. return _owner ? _owner : parent;
  1307. }
  1308. public function set owner(value:DisplayObjectContainer):void
  1309. {
  1310. _owner = value;
  1311. }
  1312. //----------------------------------
  1313. // parent
  1314. //----------------------------------
  1315. /**
  1316. * @private
  1317. * Reference to this component's virtual parent container.
  1318. * "Virtual" means that this parent may not be the same
  1319. * as the one that the Player returns as the 'parent'
  1320. * property of a DisplayObject.
  1321. * For example, if a Container has created a contentPane
  1322. * to improve scrolling performance,
  1323. * then its "children" are really its grandchildren
  1324. * and their "parent" is actually their grandparent,
  1325. * because we don't want developers to be concerned with
  1326. * whether a contentPane exists or not.
  1327. */
  1328. mx_internal var _parent:DisplayObjectContainer;
  1329. /**
  1330. * The parent container or component for this component.
  1331. * Only UIComponent objects should have a parent property.
  1332. * Non-UIComponent objects should use another property to reference
  1333. * the object to which they belong.
  1334. * By convention, non-UIComponent objects use an <code>owner</code>
  1335. * property to reference the object to which they belong.
  1336. */
  1337. override public function get parent():DisplayObjectContainer
  1338. {
  1339. // Flash PlaceObject tags can have super.parent set
  1340. // before we get to setting the _parent property.
  1341. try
  1342. {
  1343. return _parent ? _parent : super.parent;
  1344. }
  1345. catch (e:SecurityError)
  1346. {
  1347. // trace("UIComponent.get parent(): " + e);
  1348. }
  1349. return null;
  1350. }
  1351. //----------------------------------
  1352. // x
  1353. //----------------------------------
  1354. [Bindable("xChanged")]
  1355. [Inspectable(category="General")]
  1356. /**
  1357. * Number that specifies the component's horizontal position,
  1358. * in pixels, within its parent container.
  1359. *
  1360. * <p>Setting this property directly or calling <code>move()</code>
  1361. * will have no effect -- or only a temporary effect -- if the
  1362. * component is parented by a layout container such as HBox, Grid,
  1363. * or Form, because the layout calculations of those containers
  1364. * set the <code>x</code> position to the results of the calculation.
  1365. * However, the <code>x</code> property must almost always be set
  1366. * when the parent is a Canvas or other absolute-positioning
  1367. * container because the default value is 0.</p>
  1368. *
  1369. * @default 0
  1370. */
  1371. override public function get x():Number
  1372. {
  1373. return super.x;
  1374. }
  1375. /**
  1376. * @private
  1377. */
  1378. override public function set x(value:Number):void
  1379. {
  1380. if (super.x == value)
  1381. return;
  1382. super.x = value;
  1383. invalidateProperties();
  1384. dispatchEvent(new Event("xChanged"));
  1385. }
  1386. //----------------------------------
  1387. // y
  1388. //----------------------------------
  1389. [Bindable("yChanged")]
  1390. [Inspectable(category="General")]
  1391. /**
  1392. * Number that specifies the component's vertical position,
  1393. * in pixels, within its parent container.
  1394. *
  1395. * <p>Setting this property directly or calling <code>move()</code>
  1396. * will have no effect -- or only a temporary effect -- if the
  1397. * component is parented by a layout container such as HBox, Grid,
  1398. * or Form, because the layout calculations of those containers
  1399. * set the <code>x</code> position to the results of the calculation.
  1400. * However, the <code>x</code> property must almost always be set
  1401. * when the parent is a Canvas or other absolute-positioning
  1402. * container because the default value is 0.</p>
  1403. *
  1404. * @default 0
  1405. */
  1406. override public function get y():Number
  1407. {
  1408. return super.y;
  1409. }
  1410. /**
  1411. * @private
  1412. */
  1413. override public function set y(value:Number):void
  1414. {
  1415. if (super.y == value)
  1416. return;
  1417. super.y = value;
  1418. invalidateProperties();
  1419. dispatchEvent(new Event("yChanged"));
  1420. }
  1421. //----------------------------------
  1422. // width
  1423. //----------------------------------
  1424. /**
  1425. * @private
  1426. * Storage for the width property.
  1427. */
  1428. mx_internal var _width:Number;
  1429. [Bindable("widthChanged")]
  1430. [Inspectable(category="General")]
  1431. [PercentProxy("percentWidth")]
  1432. /**
  1433. * Number that specifies the width of the component, in pixels,
  1434. * in the parent's coordinates.
  1435. * The default value is 0, but this property will contain the actual component
  1436. * width after Flex completes sizing the components in your application.
  1437. *
  1438. * <p>Note: You can specify a percentage value in the MXML
  1439. * <code>width</code> attribute, such as <code>width="100%"</code>,
  1440. * but you cannot use a percentage value in the <code>width</code>
  1441. * property in ActionScript.
  1442. * Use the <code>percentWidth</code> property instead.</p>
  1443. *
  1444. * <p>Setting this property causes a <code>resize</code> event to
  1445. * be dispatched.
  1446. * See the <code>resize</code> event for details on when
  1447. * this event is dispatched.
  1448. * If the component's <code>scaleX</code> property is not 1.0,
  1449. * the width of the component from its internal coordinates
  1450. * will not match.
  1451. * Thus a 100 pixel wide component with a <code>scaleX</code>
  1452. * of 2 will take 100 pixels in the parent, but will
  1453. * internally think it is 50 pixels wide.</p>
  1454. */
  1455. override public function get width():Number
  1456. {
  1457. return _width;
  1458. }
  1459. /**
  1460. * @private
  1461. */
  1462. override public function set width(value:Number):void
  1463. {
  1464. if (explicitWidth != value)
  1465. {
  1466. explicitWidth = value;
  1467. // We invalidate size because locking in width
  1468. // may change the measured height in flow-based components.
  1469. invalidateSize();
  1470. }
  1471. if (_width != value)
  1472. {
  1473. invalidateProperties();
  1474. invalidateDisplayList();
  1475. var p:IInvalidating = parent as IInvalidating;
  1476. if (p && includeInLayout)
  1477. {
  1478. p.invalidateSize();
  1479. p.invalidateDisplayList();
  1480. }
  1481. _width = value;
  1482. dispatchEvent(new Event("widthChanged"));
  1483. }
  1484. }
  1485. //----------------------------------
  1486. // height
  1487. //----------------------------------
  1488. /**
  1489. * @private
  1490. * Storage for the height property.
  1491. */
  1492. mx_internal var _height:Number;
  1493. [Bindable("heightChanged")]
  1494. [Inspectable(category="General")]
  1495. [PercentProxy("percentHeight")]
  1496. /**
  1497. * Number that specifies the height of the component, in pixels,
  1498. * in the parent's coordinates.
  1499. * The default value is 0, but this property will contain the actual component
  1500. * height after Flex completes sizing the components in your application.
  1501. *
  1502. * <p>Note: You can specify a percentage value in the MXML
  1503. * <code>height</code> attribute, such as <code>height="100%"</code>,
  1504. * but you cannot use a percentage value for the <code>height</code>
  1505. * property in ActionScript;
  1506. * use the <code>percentHeight</code> property instead.</p>
  1507. *
  1508. * <p>Setting this property causes a <code>resize</code> event to be dispatched.
  1509. * See the <code>resize</code> event for details on when
  1510. * this event is dispatched.
  1511. * If the component's <code>scaleY</code> property is not 100,
  1512. * the height of the component from its internal coordinates
  1513. * will not match.
  1514. * Thus a 100 pixel high component with a <code>scaleY</code>
  1515. * of 200 will take 100 pixels in the parent, but will
  1516. * internally think it is 50 pixels high.</p>
  1517. */
  1518. override public function get height():Number
  1519. {
  1520. return _height;
  1521. }
  1522. /**
  1523. * @private
  1524. */
  1525. override public function set height(value:Number):void
  1526. {
  1527. if (explicitHeight != value)
  1528. {
  1529. explicitHeight = value;
  1530. // We invalidate size because locking in width
  1531. // may change the measured height in flow-based components.
  1532. invalidateSize();
  1533. }
  1534. if (_height != value)
  1535. {
  1536. invalidateProperties();
  1537. invalidateDisplayList();
  1538. var p:IInvalidating = parent as IInvalidating;
  1539. if (p && includeInLayout)
  1540. {
  1541. p.invalidateSize();
  1542. p.invalidateDisplayList();
  1543. }
  1544. _height = value;
  1545. dispatchEvent(new Event("heightChanged"));
  1546. }
  1547. }
  1548. //----------------------------------
  1549. // scaleX
  1550. //----------------------------------
  1551. /**
  1552. * @private
  1553. * Storage for the scaleX property.
  1554. */
  1555. private var _scaleX:Number = 1.0;
  1556. [Bindable("scaleXChanged")]
  1557. [Inspectable(category="Size", defaultValue="1.0")]
  1558. /**
  1559. * Number that specifies the horizontal scaling factor.
  1560. *
  1561. * <p>The default value is 1.0, which means that the object
  1562. * is not scaled.
  1563. * A <code>scaleX</code> of 2.0 means the object has been
  1564. * magnified by a factor of 2, and a <code>scaleX</code> of 0.5
  1565. * means the object has been reduced by a factor of 2.</p>
  1566. *
  1567. * <p>A value of 0.0 is an invalid value.
  1568. * Rather than setting it to 0.0, set it to a small value, or set
  1569. * the <code>visible</code> property to <code>false</code> to hide the component.</p>
  1570. *
  1571. * @default 1.0
  1572. */
  1573. override public function get scaleX():Number
  1574. {
  1575. return _scaleX;
  1576. }
  1577. /**
  1578. * @private
  1579. */
  1580. override public function set scaleX(value:Number):void
  1581. {
  1582. if (_scaleX == value)
  1583. return;
  1584. // trace("set scaleX:" + this + "value = " + value);
  1585. _scaleX = value;
  1586. invalidateProperties();
  1587. invalidateSize();
  1588. dispatchEvent(new Event("scaleXChanged"));
  1589. }
  1590. //----------------------------------
  1591. // scaleY
  1592. //----------------------------------
  1593. /**
  1594. * @private
  1595. * Storage for the scaleY property.
  1596. */
  1597. private var _scaleY:Number = 1.0;
  1598. [Bindable("scaleYChanged")]
  1599. [Inspectable(category="Size", defaultValue="1.0")]
  1600. /**
  1601. * Number that specifies the vertical scaling factor.
  1602. *
  1603. * <p>The default value is 1.0, which means that the object
  1604. * is not scaled.
  1605. * A <code>scaleY</code> of 2.0 means the object has been
  1606. * magnified by a factor of 2, and a <code>scaleY</code> of 0.5
  1607. * means the object has been reduced by a factor of 2.</p>
  1608. *
  1609. * <p>A value of 0.0 is an invalid value.
  1610. * Rather than setting it to 0.0, set it to a small value, or set
  1611. * the <code>visible</code> property to <code>false</code> to hide the component.</p>
  1612. *
  1613. * @default 1.0
  1614. */
  1615. override public function get scaleY():Number
  1616. {
  1617. return _scaleY;
  1618. }
  1619. /**
  1620. * @private
  1621. */
  1622. override public function set scaleY(value:Number):void
  1623. {
  1624. if (_scaleY == value)
  1625. return;
  1626. _scaleY = value;
  1627. invalidateProperties();
  1628. invalidateSize();
  1629. dispatchEvent(new Event("scaleYChanged"));
  1630. }
  1631. //----------------------------------
  1632. // visible
  1633. //----------------------------------
  1634. /**
  1635. * @private
  1636. * Storage for the visible property.
  1637. */
  1638. private var _visible:Boolean = true;
  1639. [Bindable("hide")]
  1640. [Bindable("show")]
  1641. [Inspectable(category="General", defaultValue="true")]
  1642. /**
  1643. * Controls the visibility of this UIComponent. If <code>true</code>,
  1644. * the object is visible.
  1645. *
  1646. * <p>When setting to <code>true</code>, the object will dispatch
  1647. * a <code>show</code> event.
  1648. * When setting to <code>false</code>, the object will dispatch
  1649. * a <code>hide</code> event.
  1650. * In either case the children of the object will not emit a
  1651. * <code>show</code> or <code>hide</code> event unless the object
  1652. * has specifically written an implementation to do so.</p>
  1653. *
  1654. * @default true
  1655. */
  1656. override public function get visible():Boolean
  1657. {
  1658. return _visible;
  1659. }
  1660. /**
  1661. * @private
  1662. */
  1663. override public function set visible(value:Boolean):void
  1664. {
  1665. setVisible(value);
  1666. }
  1667. /**
  1668. * Called when the <code>visible</code> property changes.
  1669. * You should set the <code>visible</code> property to show or hide
  1670. * a component instead of calling this method directly.
  1671. *
  1672. * @param value The new value of the <code>visible</code> property.
  1673. * Specify <code>true</code> to show the component, and <code>false</code> to hide it.
  1674. *
  1675. * @param noEvent If <code>true</code>, do not dispatch an event.
  1676. * If <code>false</code>, dispatch a <code>show</code> event when
  1677. * the component becomes visible, and a <code>hide</code> event when
  1678. * the component becomes invisible.
  1679. */
  1680. public function setVisible(value:Boolean,
  1681. noEvent:Boolean = false):void
  1682. {
  1683. _visible = value;
  1684. if (!initialized)
  1685. return;
  1686. if ($visible == value)
  1687. return;
  1688. $visible = value;
  1689. if (!noEvent)
  1690. {
  1691. dispatchEvent(new FlexEvent(value ?
  1692. FlexEvent.SHOW :
  1693. FlexEvent.HIDE));
  1694. }
  1695. }
  1696. //----------------------------------
  1697. // alpha
  1698. //----------------------------------
  1699. [Bindable("alphaChanged")]
  1700. [Inspectable(defaultValue="1.0", category="General", verbose="1")]
  1701. /**
  1702. * @private
  1703. */
  1704. override public function set alpha(value:Number):void
  1705. {
  1706. super.alpha = value;
  1707. dispatchEvent(new Event("alphaChanged"));
  1708. }
  1709. //----------------------------------
  1710. // doubleClickEnabled
  1711. //----------------------------------
  1712. [Inspectable(enumeration="true,false", defaultValue="true")]
  1713. /**
  1714. * Specifies whether the UIComponent object receives <code>doubleClick</code> events.
  1715. * The default value is <code>false</code>, which means that the UIComponent object
  1716. * does not receive <code>doubleClick</code> events.
  1717. *
  1718. * <p>The <code>mouseEnabled</code> property must also be set to <code>true</code>,
  1719. * its default value, for the object to receive <code>doubleClick</code> events.</p>
  1720. *
  1721. * @default false
  1722. */
  1723. override public function get doubleClickEnabled():Boolean
  1724. {
  1725. return super.doubleClickEnabled;
  1726. }
  1727. /**
  1728. * @private
  1729. * Propagate to children.
  1730. */
  1731. override public function set doubleClickEnabled(value:Boolean):void
  1732. {
  1733. super.doubleClickEnabled = value;
  1734. var childList:IChildList;
  1735. if (this is IRawChildrenContainer)
  1736. childList = IRawChildrenContainer(this).rawChildren;
  1737. else
  1738. childList = IChildList(this);
  1739. for (var i:int = 0; i < childList.numChildren; i++)
  1740. {
  1741. var child:InteractiveObject = childList.getChildAt(i) as InteractiveObject;
  1742. if (child)
  1743. child.doubleClickEnabled = value;
  1744. }
  1745. }
  1746. //----------------------------------
  1747. // enabled
  1748. //----------------------------------
  1749. /**
  1750. * @private
  1751. */
  1752. private var _enabled:Boolean = false;
  1753. [Inspectable(category="General", enumeration="true,false", defaultValue="true")]
  1754. [Bindable("enabledChanged")]
  1755. /**
  1756. * @copy mx.core.IUIComponent#enabled
  1757. */
  1758. public function get enabled():Boolean
  1759. {
  1760. return _enabled;
  1761. }
  1762. /**
  1763. * @private
  1764. */
  1765. public function set enabled(value:Boolean):void
  1766. {
  1767. _enabled = value;
  1768. // Need to flush the cached TextFormat
  1769. // so it recalcs with the disabled color,
  1770. cachedTextFormat = null;
  1771. invalidateDisplayList();
  1772. dispatchEvent(new Event("enabledChanged"));
  1773. }
  1774. //----------------------------------
  1775. // cacheAsBitmap
  1776. //----------------------------------
  1777. /**
  1778. * @private
  1779. */
  1780. override public function set cacheAsBitmap(value:Boolean):void
  1781. {
  1782. super.cacheAsBitmap = value;
  1783. // If cacheAsBitmap is set directly,
  1784. // reset the value of cacheAsBitmapCount.
  1785. cacheAsBitmapCount = value ? 1 : 0;
  1786. }
  1787. //----------------------------------
  1788. // filters
  1789. //----------------------------------
  1790. /**
  1791. * @private
  1792. * Storage for the filters property.
  1793. */
  1794. private var _filters:Array;
  1795. /**
  1796. * @private
  1797. */
  1798. override public function get filters():Array
  1799. {
  1800. return _filters ? _filters : super.filters;
  1801. }
  1802. /**
  1803. * @private
  1804. */
  1805. override public function set filters(value:Array):void
  1806. {
  1807. var n:int;
  1808. var i:int;
  1809. var e:IEventDispatcher;
  1810. if (_filters)
  1811. {
  1812. n = _filters.length;
  1813. for (i = 0; i < n; i++)
  1814. {
  1815. e = _filters[i] as IEventDispatcher;
  1816. if (e)
  1817. e.removeEventListener("change", filterChangeHandler);
  1818. }
  1819. }
  1820. _filters = value;
  1821. if (_filters)
  1822. {
  1823. n = _filters.length;
  1824. for (i = 0; i < n; i++)
  1825. {
  1826. e = _filters[i] as IEventDispatcher;
  1827. if (e)
  1828. e.addEventListener("change", filterChangeHandler);
  1829. }
  1830. }
  1831. super.filters = _filters;
  1832. }
  1833. //--------------------------------------------------------------------------
  1834. //
  1835. // Properties: Display
  1836. //
  1837. //--------------------------------------------------------------------------
  1838. //----------------------------------
  1839. // $parent
  1840. //----------------------------------
  1841. /**
  1842. * @private
  1843. * This property allows access to the Player's native implementation
  1844. * of the 'parent' property, which can be useful since components
  1845. * can override 'parent' and thereby hide the native implementation.
  1846. * Note that this "base property" is final and cannot be overridden,
  1847. * so you can count on it to reflect what is happening at the player level.
  1848. */
  1849. mx_internal final function get $parent():DisplayObjectContainer
  1850. {
  1851. return super.parent;
  1852. }
  1853. //----------------------------------
  1854. // $x
  1855. //----------------------------------
  1856. /**
  1857. * @private
  1858. * This property allows access to the Player's native implementation
  1859. * of the 'x' property, which can be useful since components
  1860. * can override 'x' and thereby hide the native implementation.
  1861. * Note that this "base property" is final and cannot be overridden,
  1862. * so you can count on it to reflect what is happening at the player level.
  1863. */
  1864. mx_internal final function get $x():Number
  1865. {
  1866. return super.x;
  1867. }
  1868. /**
  1869. * @private
  1870. */
  1871. mx_internal final function set $x(value:Number):void
  1872. {
  1873. super.x = value;
  1874. }
  1875. //----------------------------------
  1876. // $y
  1877. //----------------------------------
  1878. /**
  1879. * @private
  1880. * This property allows access to the Player's native implementation
  1881. * of the 'y' property, which can be useful since components
  1882. * can override 'y' and thereby hide the native implementation.
  1883. * Note that this "base property" is final and cannot be overridden,
  1884. * so you can count on it to reflect what is happening at the player level.
  1885. */
  1886. mx_internal final function get $y():Number
  1887. {
  1888. return super.y;
  1889. }
  1890. /**
  1891. * @private
  1892. */
  1893. mx_internal final function set $y(value:Number):void
  1894. {
  1895. super.y = value;
  1896. }
  1897. //----------------------------------
  1898. // $width
  1899. //----------------------------------
  1900. /**
  1901. * @private
  1902. * This property allows access to the Player's native implementation
  1903. * of the 'width' property, which can be useful since components
  1904. * can override 'width' and thereby hide the native implementation.
  1905. * Note that this "base property" is final and cannot be overridden,
  1906. * so you can count on it to reflect what is happening at the player level.
  1907. */
  1908. mx_internal final function get $width():Number
  1909. {
  1910. return super.width;
  1911. }
  1912. /**
  1913. * @private
  1914. */
  1915. mx_internal final function set $width(value:Number):void
  1916. {
  1917. super.width = value;
  1918. }
  1919. //----------------------------------
  1920. // $height
  1921. //----------------------------------
  1922. /**
  1923. * @private
  1924. * This property allows access to the Player's native implementation
  1925. * of the 'height' property, which can be useful since components
  1926. * can override 'height' and thereby hide the native implementation.
  1927. * Note that this "base property" is final and cannot be overridden,
  1928. * so you can count on it to reflect what is happening at the player level.
  1929. */
  1930. mx_internal final function get $height():Number
  1931. {
  1932. return super.height;
  1933. }
  1934. /**
  1935. * @private
  1936. */
  1937. mx_internal final function set $height(value:Number):void
  1938. {
  1939. super.height = value;
  1940. }
  1941. //----------------------------------
  1942. // $visible
  1943. //----------------------------------
  1944. /**
  1945. * @private
  1946. * This property allows access to the Player's native implementation
  1947. * of the 'visible' property, which can be useful since components
  1948. * can override 'visible' and thereby hide the native implementation.
  1949. * Note that this "base property" is final and cannot be overridden,
  1950. * so you can count on it to reflect what is happening at the player level.
  1951. */
  1952. mx_internal final function get $visible():Boolean
  1953. {
  1954. return super.visible;
  1955. }
  1956. /**
  1957. * @private
  1958. */
  1959. mx_internal final function set $visible(value:Boolean):void
  1960. {
  1961. super.visible = value;
  1962. }
  1963. //----------------------------------
  1964. // contentMouseX
  1965. //----------------------------------
  1966. /**
  1967. * Returns the <i>x</i> position of the mouse, in the content coordinate system.
  1968. * Content coordinates specify a pixel position relative to the upper left
  1969. * corner of the component's content, and include all of the component's
  1970. * content area, including any regions that are currently clipped and must
  1971. * be accessed by scrolling the component.
  1972. */
  1973. public function get contentMouseX():Number
  1974. {
  1975. return mouseX;
  1976. }
  1977. //----------------------------------
  1978. // contentMouseY
  1979. //----------------------------------
  1980. /**
  1981. * Returns the <i>y</i> position of the mouse, in the content coordinate system.
  1982. * Content coordinates specify a pixel position relative to the upper left
  1983. * corner of the component's content, and include all of the component's
  1984. * content area, including any regions that are currently clipped and must
  1985. * be accessed by scrolling the component.
  1986. */
  1987. public function get contentMouseY():Number
  1988. {
  1989. return mouseY;
  1990. }
  1991. //----------------------------------
  1992. // tweeningProperties
  1993. //----------------------------------
  1994. /**
  1995. * @private
  1996. */
  1997. private var _tweeningProperties:Array;
  1998. [Inspectable(environment="none")]
  1999. /**
  2000. * Array of properties that are currently being tweened on this object.
  2001. *
  2002. * <p>Used to alert the EffectManager that certain properties of this object
  2003. * are being tweened, so that the EffectManger doesn't attempt to animate
  2004. * the same properties.</p>
  2005. */
  2006. public function get tweeningProperties():Array
  2007. {
  2008. return _tweeningProperties;
  2009. }
  2010. /**
  2011. * @private
  2012. */
  2013. public function set tweeningProperties(value:Array):void
  2014. {
  2015. _tweeningProperties = value;
  2016. }
  2017. //--------------------------------------------------------------------------
  2018. //
  2019. // Properties: Manager access
  2020. //
  2021. //--------------------------------------------------------------------------
  2022. //----------------------------------
  2023. // cursorManager
  2024. //----------------------------------
  2025. /**
  2026. * Gets the CursorManager that controls the cursor for this component
  2027. * and its peers.
  2028. * Each top-level window has its own instance of a CursorManager;
  2029. * To make sure you're talking to the right one, use this method.
  2030. */
  2031. public function get cursorManager():ICursorManager
  2032. {
  2033. var o:DisplayObject = parent;
  2034. while (o)
  2035. {
  2036. if (o is IUIComponent && "cursorManager" in o)
  2037. {
  2038. var cm:ICursorManager = o["cursorManager"];
  2039. return cm;
  2040. }
  2041. o = o.parent;
  2042. }
  2043. return CursorManager.getInstance();
  2044. }
  2045. //----------------------------------
  2046. // focusManager
  2047. //----------------------------------
  2048. /**
  2049. * @private
  2050. * Storage for the focusManager property.
  2051. */
  2052. private var _focusManager:IFocusManager;
  2053. [Inspectable(environment="none")]
  2054. /**
  2055. * Gets the FocusManager that controls focus for this component
  2056. * and its peers.
  2057. * Each popup has its own focus loop and therefore its own instance
  2058. * of a FocusManager.
  2059. * To make sure you're talking to the right one, use this method.
  2060. */
  2061. public function get focusManager():IFocusManager
  2062. {
  2063. if (_focusManager)
  2064. return _focusManager;
  2065. var o:DisplayObject = parent;
  2066. while (o)
  2067. {
  2068. if (o is IFocusManagerContainer)
  2069. return IFocusManagerContainer(o).focusManager;
  2070. o = o.parent;
  2071. }
  2072. return null;
  2073. }
  2074. /**
  2075. * @private
  2076. * IFocusManagerContainers have this property assigned by the framework
  2077. */
  2078. public function set focusManager(value:IFocusManager):void
  2079. {
  2080. _focusManager = value;
  2081. }
  2082. //----------------------------------
  2083. // resourceManager
  2084. //----------------------------------
  2085. /**
  2086. * @private
  2087. * Storage for the resourceManager property.
  2088. */
  2089. private var _resourceManager:IResourceManager = ResourceManager.getInstance();
  2090. /**
  2091. * @private
  2092. * This metadata suppresses a trace() in PropertyWatcher:
  2093. * "warning: unable to bind to property 'resourceManager' ..."
  2094. */
  2095. [Bindable("unused")]
  2096. /**
  2097. * A reference to the object which manages
  2098. * all of the application's localized resources.
  2099. * This is a singleton instance which implements
  2100. * the IResourceManager interface.
  2101. */
  2102. protected function get resourceManager():IResourceManager
  2103. {
  2104. return _resourceManager;
  2105. }
  2106. //----------------------------------
  2107. // systemManager
  2108. //----------------------------------
  2109. /**
  2110. * @private
  2111. * Storage for the systemManager property.
  2112. * Set by the SystemManager so that each UIComponent
  2113. * has a references to its SystemManager
  2114. */
  2115. private var _systemManager:ISystemManager;
  2116. /**
  2117. * @private
  2118. * if component has been reparented, we need to potentially
  2119. * reassign systemManager, cause we could be in a new Window.
  2120. */
  2121. private var _systemManagerDirty:Boolean = false;
  2122. [Inspectable(environment="none")]
  2123. /**
  2124. * Returns the SystemManager object used by this component.
  2125. */
  2126. public function get systemManager():ISystemManager
  2127. {
  2128. if (!_systemManager || _systemManagerDirty)
  2129. {
  2130. var r:DisplayObject = root;
  2131. if (_systemManager is SystemManagerProxy)
  2132. {
  2133. // keep the existing proxy
  2134. }
  2135. else if (r && !(r is Stage))
  2136. {
  2137. // If this object is attached to the display list, then
  2138. // the root property holds its SystemManager.
  2139. _systemManager = (r as ISystemManager);
  2140. }
  2141. else if (r)
  2142. {
  2143. // if the root is the Stage, then we are in a second AIR window
  2144. _systemManager = Stage(r).getChildAt(0) as ISystemManager;
  2145. }
  2146. else
  2147. {
  2148. // If this object isn't attached to the display list, then
  2149. // we need to walk up the parent chain ourselves.
  2150. var o:DisplayObjectContainer = parent;
  2151. while (o)
  2152. {
  2153. var ui:IUIComponent = o as IUIComponent;
  2154. if (ui)
  2155. {
  2156. _systemManager = ui.systemManager;
  2157. break;
  2158. }
  2159. else if (o is ISystemManager)
  2160. {
  2161. _systemManager = o as ISystemManager;
  2162. break;
  2163. }
  2164. o = o.parent;
  2165. }
  2166. }
  2167. _systemManagerDirty = false;
  2168. }
  2169. return _systemManager;
  2170. }
  2171. /**
  2172. * @private
  2173. */
  2174. public function set systemManager(value:ISystemManager):void
  2175. {
  2176. _systemManager = value;
  2177. _systemManagerDirty = false;
  2178. }
  2179. /**
  2180. * @private
  2181. * Returns the current system manager, <code>systemManager</code>,
  2182. * unless it is null.
  2183. * If the current system manager is null,
  2184. * then search to find the correct system manager.
  2185. *
  2186. * @return A system manager, will not be null.
  2187. */
  2188. mx_internal function getNonNullSystemManager():ISystemManager
  2189. {
  2190. var sm:ISystemManager = systemManager;
  2191. if (!sm)
  2192. sm = ISystemManager(SystemManager.getSWFRoot(this));
  2193. if (!sm)
  2194. return SystemManagerGlobals.topLevelSystemManagers[0];
  2195. return sm;
  2196. }
  2197. //----------------------------------
  2198. // nestLevel
  2199. //----------------------------------
  2200. /**
  2201. * @private
  2202. * Storage for the nestLevel property.
  2203. */
  2204. private var _nestLevel:int = 0;
  2205. [Inspectable(environment="none")]
  2206. /**
  2207. * Depth of this object in the containment hierarchy.
  2208. * This number is used by the measurement and layout code.
  2209. * The value is 0 if this component is not on the DisplayList.
  2210. */
  2211. public function get nestLevel():int
  2212. {
  2213. return _nestLevel;
  2214. }
  2215. /**
  2216. * @private
  2217. */
  2218. public function set nestLevel(value:int):void
  2219. {
  2220. // If my parent hasn't been attached to the display list, then its nestLevel
  2221. // will be zero. If it tries to set my nestLevel to 1, ignore it. We'll
  2222. // update nest levels again after the parent is added to the display list.
  2223. //
  2224. // Also punt if the new value for nestLevel is the same as my current value.
  2225. if (value > 1 && _nestLevel != value)
  2226. {
  2227. _nestLevel = value;
  2228. updateCallbacks();
  2229. var childList:IChildList = (this is IRawChildrenContainer) ?
  2230. IRawChildrenContainer(this).rawChildren : IChildList(this);
  2231. var n:int = childList.numChildren;
  2232. for (var i:int = 0; i < n; i++)
  2233. {
  2234. var ui:ILayoutManagerClient = childList.getChildAt(i) as ILayoutManagerClient;
  2235. if (ui)
  2236. {
  2237. ui.nestLevel = value + 1;
  2238. }
  2239. else
  2240. {
  2241. var textField:IUITextField = childList.getChildAt(i) as IUITextField;
  2242. if (textField)
  2243. textField.nestLevel = value + 1;
  2244. }
  2245. }
  2246. }
  2247. }
  2248. //--------------------------------------------------------------------------
  2249. //
  2250. // Properties: MXML
  2251. //
  2252. //--------------------------------------------------------------------------
  2253. //----------------------------------
  2254. // descriptor
  2255. //----------------------------------
  2256. /**
  2257. * @private
  2258. * Storage for the descriptor property.
  2259. * This variable is initialized in the construct() method
  2260. * using the _descriptor in the initObj, which is set in
  2261. * createComponentFromDescriptor().
  2262. * If this UIComponent was not created by createComponentFromDescriptor(),
  2263. * its 'descriptor' property is null.
  2264. */
  2265. mx_internal var _descriptor:UIComponentDescriptor;
  2266. [Inspectable(environment="none")]
  2267. /**
  2268. * Reference to the UIComponentDescriptor, if any, that was used
  2269. * by the <code>createComponentFromDescriptor()</code> method to create this
  2270. * UIComponent instance. If this UIComponent instance
  2271. * was not created from a descriptor, this property is null.
  2272. *
  2273. * @see mx.core.UIComponentDescriptor
  2274. */
  2275. public function get descriptor():UIComponentDescriptor
  2276. {
  2277. return _descriptor;
  2278. }
  2279. /**
  2280. * @private
  2281. */
  2282. public function set descriptor(value:UIComponentDescriptor):void
  2283. {
  2284. _descriptor = value;
  2285. }
  2286. //----------------------------------
  2287. // document
  2288. //----------------------------------
  2289. /**
  2290. * @private
  2291. * Storage for the document property.
  2292. * This variable is initialized in the init() method.
  2293. * A document object (i.e., an Object at the top of the hierarchy
  2294. * of a Flex application, MXML component, or AS component) has an
  2295. * autogenerated override of initalize() which sets its _document to
  2296. * 'this', so that its 'document' property is a reference to itself.
  2297. * Other UIComponents set their _document to their parent's _document,
  2298. * so that their 'document' property refers to the document object
  2299. * that they are inside.
  2300. */
  2301. mx_internal var _document:Object;
  2302. [Inspectable(environment="none")]
  2303. /**
  2304. * A reference to the document object associated with this UIComponent.
  2305. * A document object is an Object at the top of the hierarchy of a
  2306. * Flex application, MXML component, or AS component.
  2307. */
  2308. public function get document():Object
  2309. {
  2310. return _document;
  2311. }
  2312. /**
  2313. * A reference to the document object associated with this UIComponent.
  2314. * A document object is an Object at the top of the hierarchy of a
  2315. * Flex application, MXML component, or AS component.
  2316. */
  2317. public function set document(value:Object):void
  2318. {
  2319. var n:int = numChildren;
  2320. for (var i:int = 0; i < n; i++)
  2321. {
  2322. var child:IUIComponent = getChildAt(i) as IUIComponent;
  2323. if (!child)
  2324. continue;
  2325. if (child.document == _document ||
  2326. child.document == ApplicationGlobals.application)
  2327. {
  2328. child.document = value;
  2329. }
  2330. }
  2331. _document = value;
  2332. }
  2333. //----------------------------------
  2334. // documentDescriptor
  2335. //----------------------------------
  2336. /**
  2337. * @private
  2338. * Storage for the documentDescriptor property.
  2339. * A document object (i.e., a UIComponent at the top of the
  2340. * hierarchy of a Flex application, MXML component,
  2341. * or AS component) has an autogenerated override of init()
  2342. * which sets its _documentDescriptor to the descriptor
  2343. * at the top of the autogenerated descriptor tree for that
  2344. * document. For other UIComponents, _documentDescriptor is
  2345. * never defined.
  2346. */
  2347. mx_internal var _documentDescriptor:UIComponentDescriptor;
  2348. /**
  2349. * @private
  2350. * For a document object, which is an instance of a UIComponent
  2351. * at the top of the hierarchy of a Flex application, MXML
  2352. * component, or ActionScript component, the
  2353. * <code>documentDescriptor</code> property is a reference
  2354. * to the UIComponentDescriptor at the top of the autogenerated
  2355. * descriptor tree for that document, which describes the
  2356. * set of children and their attributes for that document.
  2357. * For other UIComponents, it is <code>null</code>.
  2358. */
  2359. mx_internal function get documentDescriptor():UIComponentDescriptor
  2360. {
  2361. return _documentDescriptor;
  2362. }
  2363. //----------------------------------
  2364. // id
  2365. //----------------------------------
  2366. /**
  2367. * @private
  2368. */
  2369. private var _id:String;
  2370. /**
  2371. * ID of the component. This value becomes the instance name of the object
  2372. * and should not contain any white space or special characters. Each component
  2373. * throughout an application should have a unique id.
  2374. *
  2375. * <p>If your application is going to be tested by third party tools, give each component
  2376. * a meaningful id. Testing tools use ids to represent the control in their scripts and
  2377. * having a meaningful name can make scripts more readable. For example, set the
  2378. * value of a button to submit_button rather than b1 or button1.</p>
  2379. */
  2380. public function get id():String
  2381. {
  2382. return _id;
  2383. }
  2384. /**
  2385. * @private
  2386. */
  2387. public function set id(value:String):void
  2388. {
  2389. _id = value;
  2390. }
  2391. //----------------------------------
  2392. // isDocument
  2393. //----------------------------------
  2394. /**
  2395. * Determines whether this UIComponent instance is a document object,
  2396. * that is, whether it is at the top of the hierarchy of a Flex
  2397. * application, MXML component, or ActionScript component.
  2398. */
  2399. public function get isDocument():Boolean
  2400. {
  2401. return document == this;
  2402. }
  2403. //----------------------------------
  2404. // parentApplication
  2405. //----------------------------------
  2406. [Bindable("initialize")]
  2407. /**
  2408. * A reference to the Application object that contains this UIComponent
  2409. * instance.
  2410. * This Application object might exist in a SWFLoader control in another
  2411. * Application, and so on, creating a chain of Application objects that
  2412. * can be walked using parentApplication.
  2413. * The <code>parentApplication</code> property of an Application is never itself;
  2414. * it is either the Application into which it was loaded or null
  2415. * (for the top-level Application).
  2416. * Walking the application chain using the <code>parentApplication</code>
  2417. * property is similar to walking the document chain using the
  2418. * <code>parentDocument</code> property.
  2419. * You can access the top-level application using the
  2420. * <code>application</code> property of the Application class.
  2421. */
  2422. /*
  2423. * Note:
  2424. * There are two reasons that 'parentApplication' is typed as Object
  2425. * rather than as Application. The first is that typing it as Application
  2426. * would make UIComponent dependent on Application, slowing down compile
  2427. * times not only for SWCs for also for MXML and AS components. The
  2428. * second is that authors would not be able to access properties and
  2429. * methods in the <Script> of their <Application> without casting it
  2430. * to their application's subclass, as in
  2431. * MyApplication(paentApplication).myAppMethod().
  2432. * Therefore we decided to dispense with strict typing for
  2433. * 'parentApplication'.
  2434. */
  2435. public function get parentApplication():Object
  2436. {
  2437. // Look for the SystemManager's document,
  2438. // which should be the Application.
  2439. var o:Object = systemManager.document;
  2440. // If this UIComponent is its own root, then it is an Application.
  2441. // We want to return its parent Application, or null
  2442. // (if it has no parent because it is the top-level Application).
  2443. // The hierarchy in this situation looks something like this:
  2444. //
  2445. // SystemManager
  2446. // Application
  2447. // SomeContainer
  2448. // Loader
  2449. // Loaded App's SystemManager
  2450. // Application
  2451. // ThisComponent
  2452. if (o == this)
  2453. {
  2454. var p:UIComponent = o.systemManager.parent as UIComponent;
  2455. o = p ? p.systemManager.document : null;
  2456. }
  2457. return o;
  2458. }
  2459. //----------------------------------
  2460. // parentDocument
  2461. //----------------------------------
  2462. [Bindable("initialize")]
  2463. /**
  2464. * A reference to the parent document object for this UIComponent.
  2465. * A document object is a UIComponent at the top of the hierarchy
  2466. * of a Flex application, MXML component, or AS component.
  2467. * For the Application object, the <code>parentDocument</code>
  2468. * property is null.
  2469. * This property is useful in MXML scripts to go up a level
  2470. * in the chain of document objects.
  2471. * It can be used to walk this chain using
  2472. * <code>parentDocument.parentDocument</code>, and so on.
  2473. * It is typed as Object so that authors can access properties
  2474. * and methods on ancestor document objects without casting.
  2475. */
  2476. public function get parentDocument():Object
  2477. {
  2478. if (document == this)
  2479. {
  2480. var p:IUIComponent = parent as IUIComponent;
  2481. if (p)
  2482. return p.document;
  2483. var sm:ISystemManager = parent as ISystemManager;
  2484. if (sm)
  2485. return sm.document;
  2486. return null;
  2487. }
  2488. else
  2489. {
  2490. return document;
  2491. }
  2492. }
  2493. //----------------------------------
  2494. // screen
  2495. //----------------------------------
  2496. /**
  2497. * Returns an object that contains the size and position of the base
  2498. * drawing surface for this object.
  2499. */
  2500. public function get screen():Rectangle
  2501. {
  2502. var sm:ISystemManager = systemManager;
  2503. return sm ? sm.screen : null;
  2504. }
  2505. //--------------------------------------------------------------------------
  2506. //
  2507. // Properties: Modules
  2508. //
  2509. //--------------------------------------------------------------------------
  2510. //----------------------------------
  2511. // moduleFactory
  2512. //----------------------------------
  2513. /**
  2514. * @private
  2515. * Storage for the moduleFactory property.
  2516. */
  2517. private var _moduleFactory:IFlexModuleFactory;
  2518. [Inspectable(environment="none")]
  2519. /**
  2520. * The moduleFactory that is used to create TextFields in the correct SWF context. This is necessary so that
  2521. * embedded fonts will work.
  2522. */
  2523. public function get moduleFactory():IFlexModuleFactory
  2524. {
  2525. return _moduleFactory;
  2526. }
  2527. /**
  2528. * @private
  2529. */
  2530. public function set moduleFactory(factory:IFlexModuleFactory):void
  2531. {
  2532. var n:int = numChildren;
  2533. for (var i:int = 0; i < n; i++)
  2534. {
  2535. var child:UIComponent = getChildAt(i) as UIComponent;
  2536. if (!child)
  2537. continue;
  2538. if (child.moduleFactory == null || child.moduleFactory == _moduleFactory)
  2539. {
  2540. child.moduleFactory = factory;
  2541. }
  2542. }
  2543. _moduleFactory = factory;
  2544. }
  2545. //--------------------------------------------------------------------------
  2546. //
  2547. // Properties: Styles
  2548. //
  2549. //--------------------------------------------------------------------------
  2550. //----------------------------------
  2551. // inheritingStyles
  2552. //----------------------------------
  2553. /**
  2554. * @private
  2555. * Storage for the inheritingStyles property.
  2556. */
  2557. private var _inheritingStyles:Object = UIComponent.STYLE_UNINITIALIZED;
  2558. [Inspectable(environment="none")]
  2559. /**
  2560. * The beginning of this component's chain of inheriting styles.
  2561. * The <code>getStyle()</code> method simply accesses
  2562. * <code>inheritingStyles[styleName]</code> to search the entire
  2563. * prototype-linked chain.
  2564. * This object is set up by <code>initProtoChain()</code>.
  2565. * Developers typically never need to access this property directly.
  2566. */
  2567. public function get inheritingStyles():Object
  2568. {
  2569. return _inheritingStyles;
  2570. }
  2571. /**
  2572. * @private
  2573. */
  2574. public function set inheritingStyles(value:Object):void
  2575. {
  2576. _inheritingStyles = value;
  2577. }
  2578. //----------------------------------
  2579. // nonInheritingStyles
  2580. //----------------------------------
  2581. /**
  2582. * @private
  2583. * Storage for the nonInheritingStyles property.
  2584. */
  2585. private var _nonInheritingStyles:Object = UIComponent.STYLE_UNINITIALIZED;
  2586. [Inspectable(environment="none")]
  2587. /**
  2588. * The beginning of this component's chain of non-inheriting styles.
  2589. * The <code>getStyle()</code> method simply accesses
  2590. * <code>nonInheritingStyles[styleName]</code> to search the entire
  2591. * prototype-linked chain.
  2592. * This object is set up by <code>initProtoChain()</code>.
  2593. * Developers typically never need to access this property directly.
  2594. */
  2595. public function get nonInheritingStyles():Object
  2596. {
  2597. return _nonInheritingStyles;
  2598. }
  2599. /**
  2600. * @private
  2601. */
  2602. public function set nonInheritingStyles(value:Object):void
  2603. {
  2604. _nonInheritingStyles = value;
  2605. }
  2606. //----------------------------------
  2607. // styleDeclaration
  2608. //----------------------------------
  2609. /**
  2610. * @private
  2611. * Storage for the styleDeclaration property.
  2612. */
  2613. private var _styleDeclaration:CSSStyleDeclaration;
  2614. [Inspectable(environment="none")]
  2615. /**
  2616. * Storage for the inline inheriting styles on this object.
  2617. * This CSSStyleDeclaration is created the first time that
  2618. * the <code>setStyle()</code> method
  2619. * is called on this component to set an inheriting style.
  2620. * Developers typically never need to access this property directly.
  2621. */
  2622. public function get styleDeclaration():CSSStyleDeclaration
  2623. {
  2624. return _styleDeclaration;
  2625. }
  2626. /**
  2627. * @private
  2628. */
  2629. public function set styleDeclaration(value:CSSStyleDeclaration):void
  2630. {
  2631. _styleDeclaration = value;
  2632. }
  2633. //--------------------------------------------------------------------------
  2634. //
  2635. // Properties: Bitmap caching
  2636. //
  2637. //--------------------------------------------------------------------------
  2638. //----------------------------------
  2639. // cachePolicy
  2640. //----------------------------------
  2641. /**
  2642. * @private
  2643. * Storage for cachePolicy property.
  2644. */
  2645. private var _cachePolicy:String = UIComponentCachePolicy.AUTO;
  2646. [Inspectable(enumeration="on,off,auto", defaultValue="auto")]
  2647. /**
  2648. * Specifies the bitmap caching policy for this object.
  2649. * Possible values in MXML are <code>"on"</code>,
  2650. * <code>"off"</code> and
  2651. * <code>"auto"</code> (default).
  2652. *
  2653. * <p>Possible values in ActionScript are <code>UIComponentCachePolicy.ON</code>,
  2654. * <code>UIComponentCachePolicy.OFF</code> and
  2655. * <code>UIComponentCachePolicy.AUTO</code> (default).</p>
  2656. *
  2657. * <p><ul>
  2658. * <li>A value of <code>UIComponentCachePolicy.ON</code> means that
  2659. * the object is always cached as a bitmap.</li>
  2660. * <li>A value of <code>UIComponentCachePolicy.OFF</code> means that
  2661. * the object is never cached as a bitmap.</li>
  2662. * <li>A value of <code>UIComponentCachePolicy.AUTO</code> means that
  2663. * the framework uses heuristics to decide whether the object should
  2664. * be cached as a bitmap.</li>
  2665. * </ul></p>
  2666. *
  2667. * @default UIComponentCachePolicy.AUTO
  2668. */
  2669. public function get cachePolicy():String
  2670. {
  2671. return _cachePolicy;
  2672. }
  2673. /**
  2674. * @private
  2675. */
  2676. public function set cachePolicy(value:String):void
  2677. {
  2678. if (_cachePolicy != value)
  2679. {
  2680. _cachePolicy = value;
  2681. if (value == UIComponentCachePolicy.OFF)
  2682. cacheAsBitmap = false;
  2683. else if (value == UIComponentCachePolicy.ON)
  2684. cacheAsBitmap = true;
  2685. else
  2686. cacheAsBitmap = (cacheAsBitmapCount > 0);
  2687. }
  2688. }
  2689. //----------------------------------
  2690. // cacheHeuristic
  2691. //----------------------------------
  2692. /**
  2693. * @private
  2694. * Counter used by the cacheHeuristic property.
  2695. */
  2696. private var cacheAsBitmapCount:int = 0;
  2697. [Inspectable(environment="none")]
  2698. /**
  2699. * Used by Flex to suggest bitmap caching for the object.
  2700. * If <code>cachePolicy</code> is <code>UIComponentCachePolicy.AUTO</code>,
  2701. * then <code>cacheHeuristic</code>
  2702. * is used to control the object's <code>cacheAsBitmap</code> property.
  2703. */
  2704. public function set cacheHeuristic(value:Boolean):void
  2705. {
  2706. if (_cachePolicy == UIComponentCachePolicy.AUTO)
  2707. {
  2708. if (value)
  2709. cacheAsBitmapCount++;
  2710. else if (cacheAsBitmapCount != 0)
  2711. cacheAsBitmapCount--;
  2712. super.cacheAsBitmap = (cacheAsBitmapCount != 0);
  2713. }
  2714. }
  2715. //--------------------------------------------------------------------------
  2716. //
  2717. // Properties: Focus management
  2718. //
  2719. //--------------------------------------------------------------------------
  2720. //----------------------------------
  2721. // focusPane
  2722. //----------------------------------
  2723. /**
  2724. * @private
  2725. * Storage for the focusPane property.
  2726. */
  2727. private var _focusPane:Sprite;
  2728. [Inspectable(environment="none")]
  2729. /**
  2730. * The focus pane associated with this object.
  2731. * An object has a focus pane when one of its children has focus.
  2732. */
  2733. public function get focusPane():Sprite
  2734. {
  2735. return _focusPane;
  2736. }
  2737. /**
  2738. * @private
  2739. */
  2740. public function set focusPane(value:Sprite):void
  2741. {
  2742. if (value)
  2743. {
  2744. addChild(value);
  2745. value.x = 0;
  2746. value.y = 0;
  2747. value.scrollRect = null;
  2748. _focusPane = value;
  2749. }
  2750. else
  2751. {
  2752. removeChild(_focusPane);
  2753. _focusPane.mask = null;
  2754. _focusPane = null;
  2755. }
  2756. }
  2757. //----------------------------------
  2758. // focusEnabled
  2759. //----------------------------------
  2760. /**
  2761. * @private
  2762. * Storage for the focusEnabled property.
  2763. */
  2764. private var _focusEnabled:Boolean = true;
  2765. [Inspectable(defaultValue="true")]
  2766. /**
  2767. * Indicates whether the component can receive focus when tabbed to.
  2768. * You can set <code>focusEnabled</code> to <code>false</code>
  2769. * when a UIComponent is used as a subcomponent of another component
  2770. * so that the outer component becomes the focusable entity.
  2771. * If this property is <code>false</code>, focus will be transferred to
  2772. * the first parent that has <code>focusEnable</code>
  2773. * set to <code>true</code>.
  2774. *
  2775. * @default true
  2776. */
  2777. public function get focusEnabled():Boolean
  2778. {
  2779. return _focusEnabled;
  2780. }
  2781. /**
  2782. * @private
  2783. */
  2784. public function set focusEnabled(value:Boolean):void
  2785. {
  2786. _focusEnabled = value;
  2787. }
  2788. //----------------------------------
  2789. // mouseFocusEnabled
  2790. //----------------------------------
  2791. /**
  2792. * @private
  2793. * Storage for the mouseFocusEnabled property.
  2794. */
  2795. private var _mouseFocusEnabled:Boolean = true;
  2796. [Inspectable(defaultValue="true")]
  2797. /**
  2798. * Whether you can receive focus when clicked on.
  2799. * If <code>false</code>, focus will be transferred to
  2800. * the first parent that is <code>mouseFocusEnable</code>
  2801. * set to <code>true</code>.
  2802. * For example, you can set this property to <code>false</code>
  2803. * on a Button control so that you can use the Tab key to move focus
  2804. * to the control, but not have the control get focus when you click on it.
  2805. *
  2806. * @default true
  2807. */
  2808. public function get mouseFocusEnabled():Boolean
  2809. {
  2810. return _mouseFocusEnabled;
  2811. }
  2812. /**
  2813. * @private
  2814. */
  2815. public function set mouseFocusEnabled(value:Boolean):void
  2816. {
  2817. _mouseFocusEnabled = value;
  2818. }
  2819. //--------------------------------------------------------------------------
  2820. //
  2821. // Properties: Measurement
  2822. //
  2823. //--------------------------------------------------------------------------
  2824. //----------------------------------
  2825. // measuredMinWidth
  2826. //----------------------------------
  2827. /**
  2828. * @private
  2829. * Storage for the measuredMinWidth property.
  2830. */
  2831. private var _measuredMinWidth:Number = 0;
  2832. [Inspectable(environment="none")]
  2833. /**
  2834. * The default minimum width of the component, in pixels.
  2835. * This value is set by the <code>measure()</code> method.
  2836. */
  2837. public function get measuredMinWidth():Number
  2838. {
  2839. return _measuredMinWidth;
  2840. }
  2841. /**
  2842. * @private
  2843. */
  2844. public function set measuredMinWidth(value:Number):void
  2845. {
  2846. _measuredMinWidth = value;
  2847. }
  2848. //----------------------------------
  2849. // measuredMinHeight
  2850. //----------------------------------
  2851. /**
  2852. * @private
  2853. * Storage for the measuredMinHeight property.
  2854. */
  2855. private var _measuredMinHeight:Number = 0;
  2856. [Inspectable(environment="none")]
  2857. /**
  2858. * The default minimum height of the component, in pixels.
  2859. * This value is set by the <code>measure()</code> method.
  2860. */
  2861. public function get measuredMinHeight():Number
  2862. {
  2863. return _measuredMinHeight;
  2864. }
  2865. /**
  2866. * @private
  2867. */
  2868. public function set measuredMinHeight(value:Number):void
  2869. {
  2870. _measuredMinHeight = value;
  2871. }
  2872. //----------------------------------
  2873. // measuredWidth
  2874. //----------------------------------
  2875. /**
  2876. * @private
  2877. * Storage for the measuredWidth property.
  2878. */
  2879. private var _measuredWidth:Number = 0;
  2880. [Inspectable(environment="none")]
  2881. /**
  2882. * The default width of the component, in pixels.
  2883. * This value is set by the <code>measure()</code> method.
  2884. */
  2885. public function get measuredWidth():Number
  2886. {
  2887. return _measuredWidth;
  2888. }
  2889. /**
  2890. * @private
  2891. */
  2892. public function set measuredWidth(value:Number):void
  2893. {
  2894. _measuredWidth = value;
  2895. }
  2896. //----------------------------------
  2897. // measuredHeight
  2898. //----------------------------------
  2899. /**
  2900. * @private
  2901. * Storage for the measuredHeight property.
  2902. */
  2903. private var _measuredHeight:Number = 0;
  2904. [Inspectable(environment="none")]
  2905. /**
  2906. * The default height of the component, in pixels.
  2907. * This value is set by the <code>measure()</code> method.
  2908. */
  2909. public function get measuredHeight():Number
  2910. {
  2911. return _measuredHeight;
  2912. }
  2913. /**
  2914. * @private
  2915. */
  2916. public function set measuredHeight(value:Number):void
  2917. {
  2918. _measuredHeight = value;
  2919. }
  2920. //--------------------------------------------------------------------------
  2921. //
  2922. // Properties: Layout
  2923. //
  2924. //--------------------------------------------------------------------------
  2925. //----------------------------------
  2926. // percentWidth
  2927. //----------------------------------
  2928. /**
  2929. * @private
  2930. * Storage for the percentWidth property.
  2931. */
  2932. private var _percentWidth:Number;
  2933. [Bindable("resize")]
  2934. [Inspectable(environment="none")]
  2935. /**
  2936. * Number that specifies the width of a component as a percentage
  2937. * of its parent's size. Allowed values are 0-100. The default value is NaN.
  2938. * Setting the <code>width</code> or <code>explicitWidth</code> properties
  2939. * resets this property to NaN.
  2940. *
  2941. * <p>This property returns a numeric value only if the property was
  2942. * previously set; it does not reflect the exact size of the component
  2943. * in percent.</p>
  2944. *
  2945. * <p>This property is always set to NaN for the UITextField control.</p>
  2946. */
  2947. public function get percentWidth():Number
  2948. {
  2949. return _percentWidth;
  2950. }
  2951. /**
  2952. * @private
  2953. */
  2954. public function set percentWidth(value:Number):void
  2955. {
  2956. if (_percentWidth == value)
  2957. return;
  2958. if (!isNaN(value))
  2959. _explicitWidth = NaN;
  2960. _percentWidth = value;
  2961. var p:IInvalidating = parent as IInvalidating;
  2962. if (p)
  2963. {
  2964. p.invalidateSize();
  2965. p.invalidateDisplayList();
  2966. }
  2967. }
  2968. //----------------------------------
  2969. // percentHeight
  2970. //----------------------------------
  2971. /**
  2972. * @private
  2973. * Storage for the percentHeight property.
  2974. */
  2975. private var _percentHeight:Number;
  2976. [Bindable("resize")]
  2977. [Inspectable(environment="none")]
  2978. /**
  2979. * Number that specifies the height of a component as a percentage
  2980. * of its parent's size. Allowed values are 0-100. The default value is NaN.
  2981. * Setting the <code>height</code> or <code>explicitHeight</code> properties
  2982. * resets this property to NaN.
  2983. *
  2984. * <p>This property returns a numeric value only if the property was
  2985. * previously set; it does not reflect the exact size of the component
  2986. * in percent.</p>
  2987. *
  2988. * <p>This property is always set to NaN for the UITextField control.</p>
  2989. */
  2990. public function get percentHeight():Number
  2991. {
  2992. return _percentHeight;
  2993. }
  2994. /**
  2995. * @private
  2996. */
  2997. public function set percentHeight(value:Number):void
  2998. {
  2999. if (_percentHeight == value)
  3000. return;
  3001. if (!isNaN(value))
  3002. _explicitHeight = NaN;
  3003. _percentHeight = value;
  3004. var p:IInvalidating = parent as IInvalidating;
  3005. if (p)
  3006. {
  3007. p.invalidateSize();
  3008. p.invalidateDisplayList();
  3009. }
  3010. }
  3011. //----------------------------------
  3012. // minWidth
  3013. //----------------------------------
  3014. [Bindable("explicitMinWidthChanged")]
  3015. [Inspectable(category="Size", defaultValue="0")]
  3016. /**
  3017. * The minimum recommended width of the component to be considered
  3018. * by the parent during layout. This value is in the
  3019. * component's coordinates, in pixels. The default value depends on
  3020. * the component's implementation.
  3021. *
  3022. * <p>If the application developer sets the value of minWidth,
  3023. * the new value is stored in explicitMinWidth. The default value of minWidth
  3024. * does not change. As a result, at layout time, if
  3025. * minWidth was explicitly set by the application developer, then the value of
  3026. * explicitMinWidth is used for the component's minimum recommended width.
  3027. * If minWidth is not set explicitly by the application developer, then the value of
  3028. * measuredMinWidth is used.</p>
  3029. *
  3030. * <p>This value is used by the container in calculating
  3031. * the size and position of the component.
  3032. * It is not used by the component itself in determining
  3033. * its default size.
  3034. * Thus this property may not have any effect if parented by
  3035. * Container, or containers that don't factor in
  3036. * this property.
  3037. * Because the value is in component coordinates,
  3038. * the true <code>minWidth</code> with respect to its parent
  3039. * is affected by the <code>scaleX</code> property.</p>
  3040. */
  3041. public function get minWidth():Number
  3042. {
  3043. if (!isNaN(explicitMinWidth))
  3044. return explicitMinWidth;
  3045. return measuredMinWidth;
  3046. }
  3047. /**
  3048. * @private
  3049. */
  3050. public function set minWidth(value:Number):void
  3051. {
  3052. if (explicitMinWidth == value)
  3053. return;
  3054. explicitMinWidth = value;
  3055. }
  3056. //----------------------------------
  3057. // minHeight
  3058. //----------------------------------
  3059. [Bindable("explicitMinHeightChanged")]
  3060. [Inspectable(category="Size", defaultValue="0")]
  3061. /**
  3062. * The minimum recommended height of the component to be considered
  3063. * by the parent during layout. This value is in the
  3064. * component's coordinates, in pixels. The default value depends on
  3065. * the component's implementation.
  3066. *
  3067. * <p>If the application developer sets the value of minHeight,
  3068. * the new value is stored in explicitMinHeight. The default value of minHeight
  3069. * does not change. As a result, at layout time, if
  3070. * minHeight was explicitly set by the application developer, then the value of
  3071. * explicitMinHeight is used for the component's minimum recommended height.
  3072. * If minHeight is not set explicitly by the application developer, then the value of
  3073. * measuredMinHeight is used.</p>
  3074. *
  3075. * <p>This value is used by the container in calculating
  3076. * the size and position of the component.
  3077. * It is not used by the component itself in determining
  3078. * its default size.
  3079. * Thus this property may not have any effect if parented by
  3080. * Container, or containers that don't factor in
  3081. * this property.
  3082. * Because the value is in component coordinates,
  3083. * the true <code>minHeight</code> with respect to its parent
  3084. * is affected by the <code>scaleY</code> property.</p>
  3085. */
  3086. public function get minHeight():Number
  3087. {
  3088. if (!isNaN(explicitMinHeight))
  3089. return explicitMinHeight;
  3090. return measuredMinHeight;
  3091. }
  3092. /**
  3093. * @private
  3094. */
  3095. public function set minHeight(value:Number):void
  3096. {
  3097. if (explicitMinHeight == value)
  3098. return;
  3099. explicitMinHeight = value;
  3100. }
  3101. //----------------------------------
  3102. // maxWidth
  3103. //----------------------------------
  3104. [Bindable("explicitMaxWidthChanged")]
  3105. [Inspectable(category="Size", defaultValue="10000")]
  3106. /**
  3107. * The maximum recommended width of the component to be considered
  3108. * by the parent during layout. This value is in the
  3109. * component's coordinates, in pixels. The default value of this property is
  3110. * set by the component developer.
  3111. *
  3112. * <p>The component developer uses this property to set an upper limit on the
  3113. * width of the component.</p>
  3114. *
  3115. * <p>If the application developer overrides the default value of maxWidth,
  3116. * the new value is stored in explicitMaxWidth. The default value of maxWidth
  3117. * does not change. As a result, at layout time, if
  3118. * maxWidth was explicitly set by the application developer, then the value of
  3119. * explicitMaxWidth is used for the component's maximum recommended width.
  3120. * If maxWidth is not set explicitly by the user, then the default value is used.</p>
  3121. *
  3122. * <p>This value is used by the container in calculating
  3123. * the size and position of the component.
  3124. * It is not used by the component itself in determining
  3125. * its default size.
  3126. * Thus this property may not have any effect if parented by
  3127. * Container, or containers that don't factor in
  3128. * this property.
  3129. * Because the value is in component coordinates,
  3130. * the true <code>maxWidth</code> with respect to its parent
  3131. * is affected by the <code>scaleX</code> property.
  3132. * Some components have no theoretical limit to their width.
  3133. * In those cases their <code>maxWidth</code> will be set to
  3134. * <code>UIComponent.DEFAULT_MAX_WIDTH</code>.</p>
  3135. *
  3136. * @default 10000
  3137. */
  3138. public function get maxWidth():Number
  3139. {
  3140. return !isNaN(explicitMaxWidth) ?
  3141. explicitMaxWidth :
  3142. DEFAULT_MAX_WIDTH;
  3143. }
  3144. /**
  3145. * @private
  3146. */
  3147. public function set maxWidth(value:Number):void
  3148. {
  3149. if (explicitMaxWidth == value)
  3150. return;
  3151. explicitMaxWidth = value;
  3152. }
  3153. //----------------------------------
  3154. // maxHeight
  3155. //----------------------------------
  3156. [Bindable("explicitMaxHeightChanged")]
  3157. [Inspectable(category="Size", defaultValue="10000")]
  3158. /**
  3159. * The maximum recommended height of the component to be considered
  3160. * by the parent during layout. This value is in the
  3161. * component's coordinates, in pixels. The default value of this property is
  3162. * set by the component developer.
  3163. *
  3164. * <p>The component developer uses this property to set an upper limit on the
  3165. * height of the component.</p>
  3166. *
  3167. * <p>If the application developer overrides the default value of maxHeight,
  3168. * the new value is stored in explicitMaxHeight. The default value of maxHeight
  3169. * does not change. As a result, at layout time, if
  3170. * maxHeight was explicitly set by the application developer, then the value of
  3171. * explicitMaxHeight is used for the component's maximum recommended height.
  3172. * If maxHeight is not set explicitly by the user, then the default value is used.</p>
  3173. *
  3174. * <p>This value is used by the container in calculating
  3175. * the size and position of the component.
  3176. * It is not used by the component itself in determining
  3177. * its default size.
  3178. * Thus this property may not have any effect if parented by
  3179. * Container, or containers that don't factor in
  3180. * this property.
  3181. * Because the value is in component coordinates,
  3182. * the true <code>maxHeight</code> with respect to its parent
  3183. * is affected by the <code>scaleY</code> property.
  3184. * Some components have no theoretical limit to their height.
  3185. * In those cases their <code>maxHeight</code> will be set to
  3186. * <code>UIComponent.DEFAULT_MAX_HEIGHT</code>.</p>
  3187. *
  3188. * @default 10000
  3189. */
  3190. public function get maxHeight():Number
  3191. {
  3192. return !isNaN(explicitMaxHeight) ?
  3193. explicitMaxHeight :
  3194. DEFAULT_MAX_HEIGHT;
  3195. }
  3196. /**
  3197. * @private
  3198. */
  3199. public function set maxHeight(value:Number):void
  3200. {
  3201. if (explicitMaxHeight == value)
  3202. return;
  3203. explicitMaxHeight = value;
  3204. }
  3205. //----------------------------------
  3206. // explicitMinWidth
  3207. //----------------------------------
  3208. /**
  3209. * @private
  3210. * Storage for the minWidth property.
  3211. */
  3212. mx_internal var _explicitMinWidth:Number;
  3213. [Bindable("explicitMinWidthChanged")]
  3214. [Inspectable(environment="none")]
  3215. /**
  3216. * The minimum recommended width of the component to be considered
  3217. * by the parent during layout. This value is in the
  3218. * component's coordinates, in pixels.
  3219. *
  3220. * <p>Application developers typically do not set the explicitMinWidth property. Instead, they
  3221. * set the value of the minWidth property, which sets the explicitMinWidth property. The
  3222. * value of minWidth does not change.</p>
  3223. *
  3224. * <p>At layout time, if minWidth was explicitly set by the application developer, then
  3225. * the value of explicitMinWidth is used. Otherwise, the value of measuredMinWidth
  3226. * is used.</p>
  3227. *
  3228. * <p>This value is used by the container in calculating
  3229. * the size and position of the component.
  3230. * It is not used by the component itself in determining
  3231. * its default size.
  3232. * Thus this property may not have any effect if parented by
  3233. * Container, or containers that don't factor in
  3234. * this property.
  3235. * Because the value is in component coordinates,
  3236. * the true <code>minWidth</code> with respect to its parent
  3237. * is affected by the <code>scaleX</code> property.</p>
  3238. *
  3239. * @default NaN
  3240. */
  3241. public function get explicitMinWidth():Number
  3242. {
  3243. return _explicitMinWidth;
  3244. }
  3245. /**
  3246. * @private
  3247. */
  3248. public function set explicitMinWidth(value:Number):void
  3249. {
  3250. if (_explicitMinWidth == value)
  3251. return;
  3252. _explicitMinWidth = value;
  3253. // We invalidate size because locking in width
  3254. // may change the measured height in flow-based components.
  3255. invalidateSize();
  3256. var p:IInvalidating = parent as IInvalidating;
  3257. if (p)
  3258. {
  3259. p.invalidateSize();
  3260. p.invalidateDisplayList();
  3261. }
  3262. dispatchEvent(new Event("explicitMinWidthChanged"));
  3263. }
  3264. //----------------------------------
  3265. // minHeight
  3266. //----------------------------------
  3267. /**
  3268. * @private
  3269. * Storage for the minHeight property.
  3270. */
  3271. mx_internal var _explicitMinHeight:Number;
  3272. [Bindable("explictMinHeightChanged")]
  3273. [Inspectable(environment="none")]
  3274. /**
  3275. * The minimum recommended height of the component to be considered
  3276. * by the parent during layout. This value is in the
  3277. * component's coordinates, in pixels.
  3278. *
  3279. * <p>Application developers typically do not set the explicitMinHeight property. Instead, they
  3280. * set the value of the minHeight property, which sets the explicitMinHeight property. The
  3281. * value of minHeight does not change.</p>
  3282. *
  3283. * <p>At layout time, if minHeight was explicitly set by the application developer, then
  3284. * the value of explicitMinHeight is used. Otherwise, the value of measuredMinHeight
  3285. * is used.</p>
  3286. *
  3287. * <p>This value is used by the container in calculating
  3288. * the size and position of the component.
  3289. * It is not used by the component itself in determining
  3290. * its default size.
  3291. * Thus this property may not have any effect if parented by
  3292. * Container, or containers that don't factor in
  3293. * this property.
  3294. * Because the value is in component coordinates,
  3295. * the true <code>minHeight</code> with respect to its parent
  3296. * is affected by the <code>scaleY</code> property.</p>
  3297. *
  3298. * @default NaN
  3299. */
  3300. public function get explicitMinHeight():Number
  3301. {
  3302. return _explicitMinHeight;
  3303. }
  3304. /**
  3305. * @private
  3306. */
  3307. public function set explicitMinHeight(value:Number):void
  3308. {
  3309. if (_explicitMinHeight == value)
  3310. return;
  3311. _explicitMinHeight = value;
  3312. // We invalidate size because locking in height
  3313. // may change the measured width in flow-based components.
  3314. invalidateSize();
  3315. var p:IInvalidating = parent as IInvalidating;
  3316. if (p)
  3317. {
  3318. p.invalidateSize();
  3319. p.invalidateDisplayList();
  3320. }
  3321. dispatchEvent(new Event("explicitMinHeightChanged"));
  3322. }
  3323. //----------------------------------
  3324. // explicitMaxWidth
  3325. //----------------------------------
  3326. /**
  3327. * @private
  3328. * Storage for the maxWidth property.
  3329. */
  3330. mx_internal var _explicitMaxWidth:Number;
  3331. [Bindable("explicitMaxWidthChanged")]
  3332. [Inspectable(environment="none")]
  3333. /**
  3334. * The maximum recommended width of the component to be considered
  3335. * by the parent during layout. This value is in the
  3336. * component's coordinates, in pixels.
  3337. *
  3338. * <p>Application developers typically do not set the explicitMaxWidth property. Instead, they
  3339. * set the value of the maxWidth property, which sets the explicitMaxWidth property. The
  3340. * value of maxWidth does not change.</p>
  3341. *
  3342. * <p>At layout time, if maxWidth was explicitly set by the application developer, then
  3343. * the value of explicitMaxWidth is used. Otherwise, the default value for maxWidth
  3344. * is used.</p>
  3345. *
  3346. * <p>This value is used by the container in calculating
  3347. * the size and position of the component.
  3348. * It is not used by the component itself in determining
  3349. * its default size.
  3350. * Thus this property may not have any effect if parented by
  3351. * Container, or containers that don't factor in
  3352. * this property.
  3353. * Because the value is in component coordinates,
  3354. * the true <code>maxWidth</code> with respect to its parent
  3355. * is affected by the <code>scaleX</code> property.
  3356. * Some components have no theoretical limit to their width.
  3357. * In those cases their <code>maxWidth</code> will be set to
  3358. * <code>UIComponent.DEFAULT_MAX_WIDTH</code>.</p>
  3359. *
  3360. * @default NaN
  3361. */
  3362. public function get explicitMaxWidth():Number
  3363. {
  3364. return _explicitMaxWidth;
  3365. }
  3366. /**
  3367. * @private
  3368. */
  3369. public function set explicitMaxWidth(value:Number):void
  3370. {
  3371. if (_explicitMaxWidth == value)
  3372. return;
  3373. _explicitMaxWidth = value;
  3374. // Se invalidate size because locking in width
  3375. // may change the measured height in flow-based components.
  3376. invalidateSize();
  3377. var p:IInvalidating = parent as IInvalidating;
  3378. if (p)
  3379. {
  3380. p.invalidateSize();
  3381. p.invalidateDisplayList();
  3382. }
  3383. dispatchEvent(new Event("explicitMaxWidthChanged"));
  3384. }
  3385. //----------------------------------
  3386. // explicitMaxHeight
  3387. //----------------------------------
  3388. /**
  3389. * @private
  3390. * Storage for the maxHeight property.
  3391. */
  3392. mx_internal var _explicitMaxHeight:Number;
  3393. [Bindable("explicitMaxHeightChanged")]
  3394. [Inspectable(environment="none")]
  3395. /**
  3396. * The maximum recommended height of the component to be considered
  3397. * by the parent during layout. This value is in the
  3398. * component's coordinates, in pixels.
  3399. *
  3400. * <p>Application developers typically do not set the explicitMaxHeight property. Instead, they
  3401. * set the value of the maxHeight property, which sets the explicitMaxHeight property. The
  3402. * value of maxHeight does not change.</p>
  3403. *
  3404. * <p>At layout time, if maxHeight was explicitly set by the application developer, then
  3405. * the value of explicitMaxHeight is used. Otherwise, the default value for maxHeight
  3406. * is used.</p>
  3407. *
  3408. * <p>This value is used by the container in calculating
  3409. * the size and position of the component.
  3410. * It is not used by the component itself in determining
  3411. * its default size.
  3412. * Thus this property may not have any effect if parented by
  3413. * Container, or containers that don't factor in
  3414. * this property.
  3415. * Because the value is in component coordinates,
  3416. * the true <code>maxHeight</code> with respect to its parent
  3417. * is affected by the <code>scaleY</code> property.
  3418. * Some components have no theoretical limit to their height.
  3419. * In those cases their <code>maxHeight</code> will be set to
  3420. * <code>UIComponent.DEFAULT_MAX_HEIGHT</code>.</p>
  3421. *
  3422. * @default NaN
  3423. */
  3424. public function get explicitMaxHeight():Number
  3425. {
  3426. return _explicitMaxHeight;
  3427. }
  3428. /**
  3429. * @private
  3430. */
  3431. public function set explicitMaxHeight(value:Number):void
  3432. {
  3433. if (_explicitMaxHeight == value)
  3434. return;
  3435. _explicitMaxHeight = value;
  3436. // Se invalidate size because locking in height
  3437. // may change the measured width in flow-based components.
  3438. invalidateSize();
  3439. var p:IInvalidating = parent as IInvalidating;
  3440. if (p)
  3441. {
  3442. p.invalidateSize();
  3443. p.invalidateDisplayList();
  3444. }
  3445. dispatchEvent(new Event("explicitMaxHeightChanged"));
  3446. }
  3447. //----------------------------------
  3448. // explicitWidth
  3449. //----------------------------------
  3450. /**
  3451. * @private
  3452. * Storage for the explicitWidth property.
  3453. */
  3454. private var _explicitWidth:Number;
  3455. [Bindable("explicitWidthChanged")]
  3456. [Inspectable(environment="none")]
  3457. /**
  3458. * Number that specifies the explicit width of the component,
  3459. * in pixels, in the component's coordinates.
  3460. *
  3461. * <p>This value is used by the container in calculating
  3462. * the size and position of the component.
  3463. * It is not used by the component itself in determining
  3464. * its default size.
  3465. * Thus this property may not have any effect if parented by
  3466. * Container, or containers that don't factor in
  3467. * this property.
  3468. * Because the value is in component coordinates,
  3469. * the true <code>explicitWidth</code> with respect to its parent
  3470. * is affected by the <code>scaleX</code> property.</p>
  3471. * <p>Setting the <code>width</code> property also sets this property to
  3472. * the specified width value.</p>
  3473. */
  3474. public function get explicitWidth():Number
  3475. {
  3476. return _explicitWidth;
  3477. }
  3478. /**
  3479. * @private
  3480. */
  3481. public function set explicitWidth(value:Number):void
  3482. {
  3483. if (_explicitWidth == value)
  3484. return;
  3485. // width can be pixel or percent not both
  3486. if (!isNaN(value))
  3487. _percentWidth = NaN;
  3488. _explicitWidth = value;
  3489. // We invalidate size because locking in width
  3490. // may change the measured height in flow-based components.
  3491. invalidateSize();
  3492. var p:IInvalidating = parent as IInvalidating;
  3493. if (p && includeInLayout)
  3494. {
  3495. p.invalidateSize();
  3496. p.invalidateDisplayList();
  3497. }
  3498. dispatchEvent(new Event("explicitWidthChanged"));
  3499. }
  3500. //----------------------------------
  3501. // explicitHeight
  3502. //----------------------------------
  3503. /**
  3504. * @private
  3505. * Storage for the explicitHeight property.
  3506. */
  3507. private var _explicitHeight:Number;
  3508. [Bindable("explicitHeightChanged")]
  3509. [Inspectable(environment="none")]
  3510. /**
  3511. * Number that specifies the explicit height of the component,
  3512. * in pixels, in the component's coordinates.
  3513. *
  3514. * <p>This value is used by the container in calculating
  3515. * the size and position of the component.
  3516. * It is not used by the component itself in determining
  3517. * its default size.
  3518. * Thus this property may not have any effect if parented by
  3519. * Container, or containers that don't factor in
  3520. * this property.
  3521. * Because the value is in component coordinates,
  3522. * the true <code>explicitHeight</code> with respect to its parent
  3523. * is affected by the <code>scaleY</code> property.</p>
  3524. * <p>Setting the <code>height</code> property also sets this property to
  3525. * the specified height value.</p>
  3526. */
  3527. public function get explicitHeight():Number
  3528. {
  3529. return _explicitHeight;
  3530. }
  3531. /**
  3532. * @private
  3533. */
  3534. public function set explicitHeight(value:Number):void
  3535. {
  3536. if (_explicitHeight == value)
  3537. return;
  3538. // height can be pixel or percent, not both
  3539. if (!isNaN(value))
  3540. _percentHeight = NaN;
  3541. _explicitHeight = value;
  3542. // We invalidate size because locking in height
  3543. // may change the measured width in flow-based components.
  3544. invalidateSize();
  3545. var p:IInvalidating = parent as IInvalidating;
  3546. if (p && includeInLayout)
  3547. {
  3548. p.invalidateSize();
  3549. p.invalidateDisplayList();
  3550. }
  3551. dispatchEvent(new Event("explicitHeightChanged"));
  3552. }
  3553. //----------------------------------
  3554. // includeInLayout
  3555. //----------------------------------
  3556. /**
  3557. * @private
  3558. * Storage for the includeInLayout property.
  3559. */
  3560. private var _includeInLayout:Boolean = true;
  3561. [Bindable("includeInLayoutChanged")]
  3562. [Inspectable(category="General", defaultValue="true")]
  3563. /**
  3564. * Specifies whether this component is included in the layout of the
  3565. * parent container.
  3566. * If <code>true</code>, the object is included in its parent container's
  3567. * layout. If <code>false</code>, the object is positioned by its parent
  3568. * container as per its layout rules, but it is ignored for the purpose of
  3569. * computing the position of the next child.
  3570. *
  3571. * @default true
  3572. */
  3573. public function get includeInLayout():Boolean
  3574. {
  3575. return _includeInLayout;
  3576. }
  3577. /**
  3578. * @private
  3579. */
  3580. public function set includeInLayout(value:Boolean):void
  3581. {
  3582. if (_includeInLayout != value)
  3583. {
  3584. _includeInLayout = value;
  3585. var p:IInvalidating = parent as IInvalidating;
  3586. if (p)
  3587. {
  3588. p.invalidateSize();
  3589. p.invalidateDisplayList();
  3590. }
  3591. dispatchEvent(new Event("includeInLayoutChanged"));
  3592. }
  3593. }
  3594. //--------------------------------------------------------------------------
  3595. //
  3596. // Properties: Repeater
  3597. //
  3598. //--------------------------------------------------------------------------
  3599. //----------------------------------
  3600. // instanceIndex
  3601. //----------------------------------
  3602. /**
  3603. * The index of a repeated component.
  3604. * If the component is not within a Repeater, the value is -1.
  3605. */
  3606. public function get instanceIndex():int
  3607. {
  3608. // For efficiency, _instanceIndices starts out null rather than [].
  3609. return _instanceIndices ?
  3610. _instanceIndices[_instanceIndices.length - 1] :
  3611. -1;
  3612. }
  3613. //----------------------------------
  3614. // instanceIndices
  3615. //----------------------------------
  3616. /**
  3617. * @private
  3618. * Storage for the instanceIndices and index properties.
  3619. */
  3620. private var _instanceIndices:Array /* of int */;
  3621. [Inspectable(environment="none")]
  3622. /**
  3623. * An Array containing the indices required to reference
  3624. * this UIComponent object from its parent document.
  3625. * The Array is empty unless this UIComponent object is within one or more Repeaters.
  3626. * The first element corresponds to the outermost Repeater.
  3627. * For example, if the id is "b" and instanceIndices is [2,4],
  3628. * you would reference it on the parent document as b[2][4].
  3629. */
  3630. public function get instanceIndices():Array
  3631. {
  3632. // For efficiency, _instanceIndices starts out undefined rather than [].
  3633. return _instanceIndices ? _instanceIndices.slice(0) : null;
  3634. }
  3635. /**
  3636. * @private
  3637. */
  3638. public function set instanceIndices(value:Array):void
  3639. {
  3640. _instanceIndices = value;
  3641. }
  3642. //----------------------------------
  3643. // repeater
  3644. //----------------------------------
  3645. /**
  3646. * A reference to the Repeater object
  3647. * in the parent document that produced this UIComponent.
  3648. * Use this property, rather than the <code>repeaters</code> property,
  3649. * when the UIComponent is created by a single Repeater object.
  3650. * Use the <code>repeaters</code> property when this UIComponent is created
  3651. * by nested Repeater objects.
  3652. *
  3653. * <p>The property is set to <code>null</code> when this UIComponent
  3654. * is not created by a Repeater.</p>
  3655. */
  3656. public function get repeater():IRepeater
  3657. {
  3658. // For efficiency, _repeaters starts out undefined rather than [].
  3659. return _repeaters ? _repeaters[_repeaters.length - 1] : null;
  3660. }
  3661. //----------------------------------
  3662. // repeaters
  3663. //----------------------------------
  3664. /**
  3665. * @private
  3666. * Storage for the repeaters and repeater properties.
  3667. */
  3668. private var _repeaters:Array /* of Repeater */;
  3669. [Inspectable(environment="none")]
  3670. /**
  3671. * An Array containing references to the Repeater objects
  3672. * in the parent document that produced this UIComponent.
  3673. * The Array is empty unless this UIComponent is within
  3674. * one or more Repeaters.
  3675. * The first element corresponds to the outermost Repeater object.
  3676. */
  3677. public function get repeaters():Array
  3678. {
  3679. // For efficiency, _repeaters starts out undefined rather than [].
  3680. return _repeaters ? _repeaters.slice(0) : [];
  3681. }
  3682. /**
  3683. * @private
  3684. */
  3685. public function set repeaters(value:Array):void
  3686. {
  3687. _repeaters = value;
  3688. }
  3689. //----------------------------------
  3690. // repeaterIndex
  3691. //----------------------------------
  3692. /**
  3693. * The index of the item in the data provider
  3694. * of the Repeater that produced this UIComponent.
  3695. * Use this property, rather than the <code>repeaterIndices</code> property,
  3696. * when the UIComponent is created by a single Repeater object.
  3697. * Use the <code>repeaterIndices</code> property when this UIComponent is created
  3698. * by nested Repeater objects.
  3699. *
  3700. * <p>This property is set to -1 when this UIComponent is
  3701. * not created by a Repeater.</p>
  3702. */
  3703. public function get repeaterIndex():int
  3704. {
  3705. // For efficiency, _repeaterIndices starts out null rather than [].
  3706. return _repeaterIndices ?
  3707. _repeaterIndices[_repeaterIndices.length - 1] :
  3708. -1;
  3709. }
  3710. //----------------------------------
  3711. // repeaterIndices
  3712. //----------------------------------
  3713. /**
  3714. * @private
  3715. * Storage for the repeaterIndices and repeaterIndex properties.
  3716. */
  3717. private var _repeaterIndices:Array /* of int */;
  3718. [Inspectable(environment="none")]
  3719. /**
  3720. * An Array containing the indices of the items in the data provider
  3721. * of the Repeaters in the parent document that produced this UIComponent.
  3722. * The Array is empty unless this UIComponent is within one or more Repeaters.
  3723. *
  3724. * <p>The first element in the Array corresponds to the outermost Repeater.
  3725. * For example, if <code>repeaterIndices</code> is [2,4] it means that the
  3726. * outer repeater used item <code>dataProvider[2]</code> and the inner repeater
  3727. * used item <code>dataProvider[4]</code>.</p>
  3728. *
  3729. * <p>Note that this property differs from the <code>instanceIndices</code> property
  3730. * if the <code>startingIndex</code> property of any of the Repeaters is not 0.
  3731. * For example, even if a Repeater starts at <code>dataProvider[4]</code>,
  3732. * the document reference of the first repeated object is b[0], not b[4].</p>
  3733. */
  3734. public function get repeaterIndices():Array
  3735. {
  3736. // For efficiency, _repeaterIndices starts out null rather than [].
  3737. return _repeaterIndices ? _repeaterIndices.slice() : [];
  3738. }
  3739. /**
  3740. * @private
  3741. */
  3742. public function set repeaterIndices(value:Array):void
  3743. {
  3744. _repeaterIndices = value;
  3745. }
  3746. //--------------------------------------------------------------------------
  3747. //
  3748. // Properties: States
  3749. //
  3750. //--------------------------------------------------------------------------
  3751. //----------------------------------
  3752. // currentState
  3753. //----------------------------------
  3754. /**
  3755. * @private
  3756. * Storage for the currentState property.
  3757. */
  3758. private var _currentState:String;
  3759. /**
  3760. * @private
  3761. * Pending current state name.
  3762. */
  3763. private var requestedCurrentState:String;
  3764. /**
  3765. * @private
  3766. * Flag to play state transition
  3767. */
  3768. private var playStateTransition:Boolean = true;
  3769. /**
  3770. * @private
  3771. * Flag that is set when the currentState has changed and needs to be
  3772. * committed.
  3773. * This property name needs the initial underscore to avoid collisions
  3774. * with the "currentStateChange" event attribute.
  3775. */
  3776. private var _currentStateChanged:Boolean;
  3777. [Bindable("currentStateChange")]
  3778. /**
  3779. * The current view state of the component.
  3780. * Set to <code>""</code> or <code>null</code> to reset
  3781. * the component back to its base state.
  3782. *
  3783. * <p>When you use this property to set a component's state,
  3784. * Flex applies any transition you have defined.
  3785. * You can also use the <code>setCurrentState()</code> method to set the
  3786. * current state; this method can optionally change states without
  3787. * applying a transition.</p>
  3788. *
  3789. * @see #setCurrentState()
  3790. */
  3791. public function get currentState():String
  3792. {
  3793. return _currentStateChanged ? requestedCurrentState : _currentState;
  3794. }
  3795. /**
  3796. * @private
  3797. */
  3798. public function set currentState(value:String):void
  3799. {
  3800. setCurrentState(value, true);
  3801. }
  3802. //----------------------------------
  3803. // states
  3804. //----------------------------------
  3805. [Inspectable(arrayType="mx.states.State")]
  3806. [ArrayElementType("mx.states.State")]
  3807. /**
  3808. * The view states that are defined for this component.
  3809. * You can specify the <code>states</code> property only on the root
  3810. * of the application or on the root tag of an MXML component.
  3811. * The compiler generates an error if you specify it on any other control.
  3812. */
  3813. public var states:Array /* of State */ = [];
  3814. //----------------------------------
  3815. // transitions
  3816. //----------------------------------
  3817. /**
  3818. * @private
  3819. * Transition effect currently playing.
  3820. */
  3821. private var _currentTransitionEffect:IEffect;
  3822. [Inspectable(arrayType="mx.states.Transition")]
  3823. [ArrayElementType("mx.states.Transition")]
  3824. /**
  3825. * An Array of Transition objects, where each Transition object defines a
  3826. * set of effects to play when a view state change occurs.
  3827. *
  3828. * @see mx.states.Transition
  3829. */
  3830. public var transitions:Array /* of Transition */ = [];
  3831. //--------------------------------------------------------------------------
  3832. //
  3833. // Properties: Other
  3834. //
  3835. //--------------------------------------------------------------------------
  3836. //----------------------------------
  3837. // baselinePosition
  3838. //----------------------------------
  3839. /**
  3840. * The y-coordinate of the baseline
  3841. * of the first line of text of the component.
  3842. *
  3843. * <p>This property is used to implement
  3844. * the <code>baseline</code> constraint style.
  3845. * It is also used to align the label of a FormItem
  3846. * with the controls in the FormItem.</p>
  3847. *
  3848. * <p>Each component should override this property.</p>
  3849. */
  3850. public function get baselinePosition():Number
  3851. {
  3852. if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_3_0)
  3853. return NaN;
  3854. if (!validateBaselinePosition())
  3855. return NaN;
  3856. // Unless the height is very small, the baselinePosition
  3857. // of a generic UIComponent is calculated as if there was
  3858. // a UITextField using the component's styles
  3859. // whose top coincides with the component's top.
  3860. // If the height is small, the baselinePosition is calculated
  3861. // as if there were text within whose ascent the component
  3862. // is vertically centered.
  3863. // At the crossover height, these two calculations
  3864. // produce the same result.
  3865. var lineMetrics:TextLineMetrics = measureText("Wj");
  3866. if (height < 2 + lineMetrics.ascent + 2)
  3867. return int(height + (lineMetrics.ascent - height) / 2);
  3868. return 2 + lineMetrics.ascent;
  3869. }
  3870. //----------------------------------
  3871. // className
  3872. //----------------------------------
  3873. /**
  3874. * The name of this instance's class, such as <code>"Button"</code>.
  3875. *
  3876. * <p>This string does not include the package name.
  3877. * If you need the package name as well, call the
  3878. * <code>getQualifiedClassName()</code> method in the flash.utils package.
  3879. * It will return a string such as <code>"mx.controls::Button"</code>.</p>
  3880. */
  3881. public function get className():String
  3882. {
  3883. var name:String = getQualifiedClassName(this);
  3884. // If there is a package name, strip it off.
  3885. var index:int = name.indexOf("::");
  3886. if (index != -1)
  3887. name = name.substr(index + 2);
  3888. return name;
  3889. }
  3890. //----------------------------------
  3891. // effectsStarted
  3892. //----------------------------------
  3893. /**
  3894. * The list of effects that are currently playing on the component,
  3895. * as an Array of EffectInstance instances.
  3896. */
  3897. public function get activeEffects():Array
  3898. {
  3899. return _effectsStarted;
  3900. }
  3901. //----------------------------------
  3902. // flexContextMenu
  3903. //----------------------------------
  3904. /**
  3905. * @private
  3906. * Storage for the flexContextMenu property.
  3907. */
  3908. private var _flexContextMenu:IFlexContextMenu;
  3909. /**
  3910. * The context menu for this UIComponent.
  3911. *
  3912. * @default null
  3913. */
  3914. public function get flexContextMenu():IFlexContextMenu
  3915. {
  3916. return _flexContextMenu;
  3917. }
  3918. /**
  3919. * @private
  3920. */
  3921. public function set flexContextMenu(value:IFlexContextMenu):void
  3922. {
  3923. if (_flexContextMenu)
  3924. _flexContextMenu.unsetContextMenu(this);
  3925. _flexContextMenu = value;
  3926. if (value != null)
  3927. _flexContextMenu.setContextMenu(this);
  3928. }
  3929. //----------------------------------
  3930. // styleName
  3931. //----------------------------------
  3932. /**
  3933. * @private
  3934. * Storage for the styleName property.
  3935. */
  3936. private var _styleName:Object /* String, CSSStyleDeclaration, or UIComponent */;
  3937. [Inspectable(category="General")]
  3938. /**
  3939. * The class style used by this component. This can be a String, CSSStyleDeclaration
  3940. * or an IStyleClient.
  3941. *
  3942. * <p>If this is a String, it is the name of a class declaration
  3943. * in an <code>mx:Style</code> tag or CSS file. You do not include the period in
  3944. * the <code>styleName</code>. For example, if you have a class style named <code>".bigText"</code>,
  3945. * set the <code>styleName</code> property to <code>"bigText"</code> (no period).</p>
  3946. *
  3947. * <p>If this is an IStyleClient (typically a UIComponent), all styles in the
  3948. * <code>styleName</code> object are used by this component.</p>
  3949. *
  3950. * @default null
  3951. */
  3952. public function get styleName():Object /* String, CSSStyleDeclaration, or UIComponent */
  3953. {
  3954. return _styleName;
  3955. }
  3956. /**
  3957. * @private
  3958. */
  3959. public function set styleName(value:Object /* String, CSSStyleDeclaration, or UIComponent */):void
  3960. {
  3961. if (_styleName === value)
  3962. return;
  3963. _styleName = value;
  3964. // If inheritingStyles is undefined, then this object is being
  3965. // initialized and we haven't yet generated the proto chain.
  3966. // To avoid redundant work, don't bother to create
  3967. // the proto chain here.
  3968. if (inheritingStyles == UIComponent.STYLE_UNINITIALIZED)
  3969. return;
  3970. regenerateStyleCache(true);
  3971. initThemeColor();
  3972. styleChanged("styleName");
  3973. notifyStyleChangeInChildren("styleName", true);
  3974. }
  3975. //----------------------------------
  3976. // toolTip
  3977. //----------------------------------
  3978. /**
  3979. * @private
  3980. * Storage for the toolTip property.
  3981. */
  3982. mx_internal var _toolTip:String;
  3983. [Bindable("toolTipChanged")]
  3984. [Inspectable(category="General", defaultValue="null")]
  3985. /**
  3986. * Text to display in the ToolTip.
  3987. *
  3988. * @default null
  3989. */
  3990. public function get toolTip():String
  3991. {
  3992. return _toolTip;
  3993. }
  3994. /**
  3995. * @private
  3996. */
  3997. public function set toolTip(value:String):void
  3998. {
  3999. var oldValue:String = _toolTip;
  4000. _toolTip = value;
  4001. ToolTipManager.registerToolTip(this, oldValue, value);
  4002. dispatchEvent(new Event("toolTipChanged"));
  4003. }
  4004. //----------------------------------
  4005. // uid
  4006. //----------------------------------
  4007. /**
  4008. * @private
  4009. */
  4010. private var _uid:String;
  4011. /**
  4012. * A unique identifier for the object.
  4013. * Flex data-driven controls, including all controls that are
  4014. * subclasses of List class, use a UID to track data provider items.
  4015. *
  4016. * <p>Flex can automatically create and manage UIDs.
  4017. * However, there are circumstances when you must supply your own
  4018. * <code>uid</code> property by implementing the IUID interface,
  4019. * or when supplying your own <code>uid</code> property improves processing efficiency.
  4020. * UIDs do not need to be universally unique for most uses in Flex.
  4021. * One exception is for messages sent by data services.</p>
  4022. *
  4023. * @see IUID
  4024. * @see mx.utils.UIDUtil
  4025. */
  4026. public function get uid():String
  4027. {
  4028. if (!_uid)
  4029. _uid = toString();
  4030. return _uid;
  4031. }
  4032. /**
  4033. * @private
  4034. */
  4035. public function set uid(uid:String):void
  4036. {
  4037. this._uid = uid;
  4038. }
  4039. //----------------------------------
  4040. // indexedID
  4041. //----------------------------------
  4042. /**
  4043. * @private
  4044. * Utility getter used by uid. It returns an indexed id string
  4045. * such as "foo[1][2]" if this object is a repeated object,
  4046. * or a nonindexed id string like "bar" if it isn't.
  4047. */
  4048. private function get indexedID():String
  4049. {
  4050. var s:String = id;
  4051. var indices:Array /* of int */ = instanceIndices;
  4052. if (indices)
  4053. s += "[" + indices.join("][") + "]";
  4054. return s;
  4055. }
  4056. //--------------------------------------------------------------------------
  4057. //
  4058. // Properties: Popups
  4059. //
  4060. //--------------------------------------------------------------------------
  4061. //----------------------------------
  4062. // isPopUp
  4063. //----------------------------------
  4064. /**
  4065. * @private
  4066. */
  4067. private var _isPopUp:Boolean;
  4068. [Inspectable(environment="none")]
  4069. /**
  4070. * Set to <code>true</code> by the PopUpManager to indicate
  4071. * that component has been popped up.
  4072. */
  4073. public function get isPopUp():Boolean
  4074. {
  4075. return _isPopUp;
  4076. }
  4077. public function set isPopUp(value:Boolean):void
  4078. {
  4079. _isPopUp = value;
  4080. }
  4081. //--------------------------------------------------------------------------
  4082. //
  4083. // Properties: Required to support automated testing
  4084. //
  4085. //--------------------------------------------------------------------------
  4086. //----------------------------------
  4087. // automationDelegate
  4088. //----------------------------------
  4089. /**
  4090. * @private
  4091. */
  4092. private var _automationDelegate:IAutomationObject;
  4093. /**
  4094. * The delegate object that handles the automation-related functionality.
  4095. */
  4096. public function get automationDelegate():Object
  4097. {
  4098. return _automationDelegate;
  4099. }
  4100. /**
  4101. * @private
  4102. */
  4103. public function set automationDelegate(value:Object):void
  4104. {
  4105. _automationDelegate = value as IAutomationObject;
  4106. }
  4107. //----------------------------------
  4108. // automationName
  4109. //----------------------------------
  4110. /**
  4111. * @private
  4112. * Storage for the <code>automationName</code> property.
  4113. */
  4114. private var _automationName:String = null;
  4115. /**
  4116. * @inheritDoc
  4117. */
  4118. public function get automationName():String
  4119. {
  4120. if (_automationName)
  4121. return _automationName;
  4122. if (automationDelegate)
  4123. return automationDelegate.automationName;
  4124. return "";
  4125. }
  4126. /**
  4127. * @private
  4128. */
  4129. public function set automationName(value:String):void
  4130. {
  4131. _automationName = value;
  4132. }
  4133. /**
  4134. * @copy mx.automation.IAutomationObject#automationValue
  4135. */
  4136. public function get automationValue():Array
  4137. {
  4138. if (automationDelegate)
  4139. return automationDelegate.automationValue;
  4140. return [];
  4141. }
  4142. //----------------------------------
  4143. // showInAutomationHierarchy
  4144. //----------------------------------
  4145. /**
  4146. * @private
  4147. * Storage for the <code>showInAutomationHierarchy</code> property.
  4148. */
  4149. private var _showInAutomationHierarchy:Boolean = true;
  4150. /**
  4151. * @inheritDoc
  4152. */
  4153. public function get showInAutomationHierarchy():Boolean
  4154. {
  4155. return _showInAutomationHierarchy;
  4156. }
  4157. /**
  4158. * @private
  4159. */
  4160. public function set showInAutomationHierarchy(value:Boolean):void
  4161. {
  4162. _showInAutomationHierarchy = value;
  4163. }
  4164. //--------------------------------------------------------------------------
  4165. //
  4166. // Properties Validation
  4167. //
  4168. //--------------------------------------------------------------------------
  4169. //----------------------------------
  4170. // errorString
  4171. //----------------------------------
  4172. /**
  4173. * @private
  4174. * Storage for errorString property.
  4175. */
  4176. mx_internal var _errorString:String = "";
  4177. /**
  4178. * @private
  4179. * Flag set when error string changes.
  4180. */
  4181. private var errorStringChanged:Boolean = false;
  4182. [Bindable("errorStringChanged")]
  4183. /**
  4184. * The text that will be displayed by a component's error tip when a
  4185. * component is monitored by a Validator and validation fails.
  4186. *
  4187. * <p>You can use the <code>errorString</code> property to show a
  4188. * validation error for a component, without actually using a validator class.
  4189. * When you write a String value to the <code>errorString</code> property,
  4190. * Flex draws a red border around the component to indicate the validation error,
  4191. * and the String appears in a tooltip as the validation error message when you move
  4192. * the mouse over the component, just as if a validator detected a validation error.</p>
  4193. *
  4194. * <p>To clear the validation error, write an empty String, "",
  4195. * to the <code>errorString</code> property.</p>
  4196. *
  4197. * <p>Note that writing a value to the <code>errorString</code> property
  4198. * does not trigger the valid or invalid events; it only changes the border
  4199. * color and displays the validation error message.</p>
  4200. */
  4201. public function get errorString():String
  4202. {
  4203. return _errorString;
  4204. }
  4205. /**
  4206. * @private
  4207. */
  4208. public function set errorString(value:String):void
  4209. {
  4210. var oldValue:String = _errorString;
  4211. _errorString = value;
  4212. ToolTipManager.registerErrorString(this, oldValue, value);
  4213. errorStringChanged = true;
  4214. invalidateProperties();
  4215. dispatchEvent(new Event("errorStringChanged"));
  4216. }
  4217. /**
  4218. * @private
  4219. * Set the appropriate borderColor based on errorString.
  4220. * If we have an errorString, use errorColor. If we don't
  4221. * have an errorString, restore the original borderColor.
  4222. */
  4223. private function setBorderColorForErrorString():void
  4224. {
  4225. if (!_errorString || _errorString.length == 0)
  4226. {
  4227. if (!isNaN(origBorderColor))
  4228. {
  4229. setStyle("borderColor", origBorderColor);
  4230. saveBorderColor = true;
  4231. }
  4232. }
  4233. else
  4234. {
  4235. // Remember the original border color
  4236. if (saveBorderColor)
  4237. {
  4238. saveBorderColor = false;
  4239. origBorderColor = getStyle("borderColor");
  4240. }
  4241. setStyle("borderColor", getStyle("errorColor"));
  4242. }
  4243. styleChanged("themeColor");
  4244. var focusManager:IFocusManager = focusManager;
  4245. var focusObj:DisplayObject = focusManager ?
  4246. DisplayObject(focusManager.getFocus()) :
  4247. null;
  4248. if (focusManager && focusManager.showFocusIndicator &&
  4249. focusObj == this)
  4250. {
  4251. drawFocus(true);
  4252. }
  4253. }
  4254. //----------------------------------
  4255. // validationSubField
  4256. //----------------------------------
  4257. /**
  4258. * @private
  4259. * Storage for the validationSubField property.
  4260. */
  4261. private var _validationSubField:String;
  4262. /**
  4263. * Used by a validator to associate a subfield with this component.
  4264. */
  4265. public function get validationSubField():String
  4266. {
  4267. return _validationSubField;
  4268. }
  4269. /**
  4270. * @private
  4271. */
  4272. public function set validationSubField(value:String):void
  4273. {
  4274. _validationSubField = value;
  4275. }
  4276. //--------------------------------------------------------------------------
  4277. //
  4278. // Overridden methods
  4279. //
  4280. //--------------------------------------------------------------------------
  4281. /**
  4282. * @private
  4283. */
  4284. override public function addChild(child:DisplayObject):DisplayObject
  4285. {
  4286. var formerParent:DisplayObjectContainer = child.parent;
  4287. if (formerParent && !(formerParent is Loader))
  4288. formerParent.removeChild(child);
  4289. // If there is an overlay, place the child underneath it.
  4290. var index:int = overlayReferenceCount && child != overlay ?
  4291. Math.max(0, super.numChildren - 1) :
  4292. super.numChildren;
  4293. // Do anything that needs to be done before the child is added.
  4294. // When adding a child to UIComponent, this will set the child's
  4295. // virtual parent, its nestLevel, its document, etc.
  4296. // When adding a child to a Container, the override will also
  4297. // invalidate the container, adjust its content/chrome partitions,
  4298. // etc.
  4299. addingChild(child);
  4300. // Call a low-level player method in DisplayObjectContainer which
  4301. // actually attaches the child to this component.
  4302. // The player dispatches an "added" event from the child just after
  4303. // it is attached, so all "added" handlers execute during this call.
  4304. // UIComponent registers an addedHandler() in its constructor,
  4305. // which makes it runs before any other "added" handlers except
  4306. // capture-phase ones; it sets up the child's styles.
  4307. $addChildAt(child, index);
  4308. // Do anything that needs to be done after the child is added
  4309. // and after all "added" handlers have executed.
  4310. // This is where
  4311. childAdded(child);
  4312. return child;
  4313. }
  4314. /**
  4315. * @private
  4316. */
  4317. override public function addChildAt(child:DisplayObject,
  4318. index:int):DisplayObject
  4319. {
  4320. var formerParent:DisplayObjectContainer = child.parent;
  4321. if (formerParent && !(formerParent is Loader))
  4322. formerParent.removeChild(child);
  4323. // If there is an overlay, place the child underneath it.
  4324. if (overlayReferenceCount && child != overlay)
  4325. index = Math.min(index, Math.max(0, super.numChildren - 1));
  4326. addingChild(child);
  4327. $addChildAt(child, index);
  4328. childAdded(child);
  4329. return child;
  4330. }
  4331. /**
  4332. * @private
  4333. */
  4334. override public function removeChild(child:DisplayObject):DisplayObject
  4335. {
  4336. removingChild(child);
  4337. $removeChild(child);
  4338. childRemoved(child);
  4339. return child;
  4340. }
  4341. /**
  4342. * @private
  4343. */
  4344. override public function removeChildAt(index:int):DisplayObject
  4345. {
  4346. var child:DisplayObject = getChildAt(index);
  4347. removingChild(child);
  4348. $removeChild(child);
  4349. childRemoved(child);
  4350. return child;
  4351. }
  4352. /**
  4353. * @private
  4354. */
  4355. override public function setChildIndex(child:DisplayObject,
  4356. newIndex:int):void
  4357. {
  4358. // Place the child underneath the overlay.
  4359. if (overlayReferenceCount && child != overlay)
  4360. newIndex = Math.min(newIndex, Math.max(0, super.numChildren - 2));
  4361. super.setChildIndex(child, newIndex);
  4362. }
  4363. /**
  4364. * @private
  4365. */
  4366. override public function stopDrag():void
  4367. {
  4368. super.stopDrag();
  4369. invalidateProperties();
  4370. dispatchEvent(new Event("xChanged"));
  4371. dispatchEvent(new Event("yChanged"));
  4372. }
  4373. //--------------------------------------------------------------------------
  4374. //
  4375. // Methods: Access to overridden methods of base classes
  4376. //
  4377. //--------------------------------------------------------------------------
  4378. /**
  4379. * @private
  4380. * This method allows access to the Player's native implementation
  4381. * of addChild(), which can be useful since components
  4382. * can override addChild() and thereby hide the native implementation.
  4383. * Note that this "base method" is final and cannot be overridden,
  4384. * so you can count on it to reflect what is happening at the player level.
  4385. */
  4386. mx_internal final function $addChild(child:DisplayObject):DisplayObject
  4387. {
  4388. return super.addChild(child);
  4389. }
  4390. /**
  4391. * @private
  4392. * This method allows access to the Player's native implementation
  4393. * of addChildAt(), which can be useful since components
  4394. * can override addChildAt() and thereby hide the native implementation.
  4395. * Note that this "base method" is final and cannot be overridden,
  4396. * so you can count on it to reflect what is happening at the player level.
  4397. */
  4398. mx_internal final function $addChildAt(child:DisplayObject,
  4399. index:int):DisplayObject
  4400. {
  4401. return super.addChildAt(child, index);
  4402. }
  4403. /**
  4404. * @private
  4405. * This method allows access to the Player's native implementation
  4406. * of removeChild(), which can be useful since components
  4407. * can override removeChild() and thereby hide the native implementation.
  4408. * Note that this "base method" is final and cannot be overridden,
  4409. * so you can count on it to reflect what is happening at the player level.
  4410. */
  4411. mx_internal final function $removeChild(child:DisplayObject):DisplayObject
  4412. {
  4413. return super.removeChild(child);
  4414. }
  4415. /**
  4416. * @private
  4417. * This method allows access to the Player's native implementation
  4418. * of removeChildAt(), which can be useful since components
  4419. * can override removeChildAt() and thereby hide the native implementation.
  4420. * Note that this "base method" is final and cannot be overridden,
  4421. * so you can count on it to reflect what is happening at the player level.
  4422. */
  4423. mx_internal final function $removeChildAt(index:int):DisplayObject
  4424. {
  4425. return super.removeChildAt(index);
  4426. }
  4427. //--------------------------------------------------------------------------
  4428. //
  4429. // Methods: Initialization
  4430. //
  4431. //--------------------------------------------------------------------------
  4432. /**
  4433. * @private
  4434. */
  4435. mx_internal function updateCallbacks():void
  4436. {
  4437. if (invalidateDisplayListFlag)
  4438. UIComponentGlobals.layoutManager.invalidateDisplayList(this);
  4439. if (invalidateSizeFlag)
  4440. UIComponentGlobals.layoutManager.invalidateSize(this);
  4441. if (invalidatePropertiesFlag)
  4442. UIComponentGlobals.layoutManager.invalidateProperties(this);
  4443. // systemManager getter tries to set the internal _systemManager varaible
  4444. // if it is null. Hence a call to the getter is necessary.
  4445. // Stage can be null when an untrusted application is loaded by an application
  4446. // that isn't on stage yet.
  4447. if (systemManager && (_systemManager.stage || _systemManager.useSWFBridge()))
  4448. {
  4449. if (methodQueue.length > 0 && !listeningForRender)
  4450. {
  4451. _systemManager.addEventListener(FlexEvent.RENDER, callLaterDispatcher);
  4452. _systemManager.addEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher);
  4453. listeningForRender = true;
  4454. }
  4455. if (_systemManager.stage)
  4456. _systemManager.stage.invalidate();
  4457. }
  4458. }
  4459. /**
  4460. * Called by Flex when a UIComponent object is added to or removed from a parent.
  4461. * Developers typically never need to call this method.
  4462. *
  4463. * @param p The parent of this UIComponent object.
  4464. */
  4465. public function parentChanged(p:DisplayObjectContainer):void
  4466. {
  4467. // trace("parentChanged: " + _parent + " of " + this + " changed to ");
  4468. if (!p)
  4469. {
  4470. _parent = null;
  4471. _nestLevel = 0;
  4472. }
  4473. else if (p is IStyleClient)
  4474. {
  4475. _parent = p;
  4476. }
  4477. else if (p is ISystemManager)
  4478. {
  4479. _parent = p;
  4480. }
  4481. else
  4482. {
  4483. _parent = p.parent;
  4484. }
  4485. // trace(" " + p);
  4486. }
  4487. /**
  4488. * @private
  4489. */
  4490. mx_internal function addingChild(child:DisplayObject):void
  4491. {
  4492. // If the document property isn't already set on the child,
  4493. // set it to be the same as this component's document.
  4494. // The document setter will recursively set it on any
  4495. // descendants of the child that exist.
  4496. if (child is IUIComponent &&
  4497. !IUIComponent(child).document)
  4498. {
  4499. IUIComponent(child).document = document ?
  4500. document :
  4501. ApplicationGlobals.application;
  4502. }
  4503. // Propagate moduleFactory to the child, but don't overwrite an existing moduleFactory.
  4504. if (child is UIComponent && UIComponent(child).moduleFactory == null)
  4505. {
  4506. if (moduleFactory != null)
  4507. UIComponent(child).moduleFactory = moduleFactory;
  4508. else if (document is IFlexModule && document.moduleFactory != null)
  4509. UIComponent(child).moduleFactory = document.moduleFactory;
  4510. else if (parent is UIComponent && UIComponent(parent).moduleFactory != null)
  4511. UIComponent(child).moduleFactory = UIComponent(parent).moduleFactory;
  4512. }
  4513. // Set the font context in non-UIComponent children.
  4514. // UIComponent children use moduleFactory.
  4515. if (child is IFontContextComponent && !child is UIComponent &&
  4516. IFontContextComponent(child).fontContext == null)
  4517. IFontContextComponent(child).fontContext = moduleFactory;
  4518. if (child is IUIComponent)
  4519. IUIComponent(child).parentChanged(this);
  4520. // Set the nestLevel of the child to be one greater
  4521. // than the nestLevel of this component.
  4522. // The nestLevel setter will recursively set it on any
  4523. // descendants of the child that exist.
  4524. if (child is ILayoutManagerClient)
  4525. ILayoutManagerClient(child).nestLevel = nestLevel + 1;
  4526. else if (child is IUITextField)
  4527. IUITextField(child).nestLevel = nestLevel + 1;
  4528. if (child is InteractiveObject)
  4529. if (doubleClickEnabled)
  4530. InteractiveObject(child).doubleClickEnabled = true;
  4531. // Sets up the inheritingStyles and nonInheritingStyles objects
  4532. // and their proto chains so that getStyle() works.
  4533. // If this object already has some children,
  4534. // then reinitialize the children's proto chains.
  4535. if (child is IStyleClient)
  4536. IStyleClient(child).regenerateStyleCache(true);
  4537. else if (child is IUITextField && IUITextField(child).inheritingStyles)
  4538. StyleProtoChain.initTextField(IUITextField(child));
  4539. if (child is ISimpleStyleClient)
  4540. ISimpleStyleClient(child).styleChanged(null);
  4541. if (child is IStyleClient)
  4542. IStyleClient(child).notifyStyleChangeInChildren(null, true);
  4543. if (child is UIComponent)
  4544. UIComponent(child).initThemeColor();
  4545. // Inform the component that it's style properties
  4546. // have been fully initialized. Most components won't care,
  4547. // but some need to react to even this early change.
  4548. if (child is UIComponent)
  4549. UIComponent(child).stylesInitialized();
  4550. }
  4551. /**
  4552. * @private
  4553. */
  4554. mx_internal function childAdded(child:DisplayObject):void
  4555. {
  4556. if (child is UIComponent)
  4557. {
  4558. if (!UIComponent(child).initialized)
  4559. UIComponent(child).initialize();
  4560. }
  4561. else if (child is IUIComponent)
  4562. {
  4563. IUIComponent(child).initialize();
  4564. }
  4565. }
  4566. /**
  4567. * @private
  4568. */
  4569. mx_internal function removingChild(child:DisplayObject):void
  4570. {
  4571. }
  4572. /**
  4573. * @private
  4574. */
  4575. mx_internal function childRemoved(child:DisplayObject):void
  4576. {
  4577. if (child is IUIComponent)
  4578. {
  4579. // only reset document if the child isn't
  4580. // a document itself
  4581. if (IUIComponent(child).document != child)
  4582. IUIComponent(child).document = null;
  4583. IUIComponent(child).parentChanged(null);
  4584. }
  4585. }
  4586. /**
  4587. * Initializes the internal structure of this component.
  4588. *
  4589. * <p>Initializing a UIComponent is the fourth step in the creation
  4590. * of a visual component instance, and happens automatically
  4591. * the first time that the instance is added to a parent.
  4592. * Therefore, you do not generally need to call
  4593. * <code>initialize()</code>; the Flex framework calls it for you
  4594. * from UIComponent's override of the <code>addChild()</code>
  4595. * and <code>addChildAt()</code> methods.</p>
  4596. *
  4597. * <p>The first step in the creation of a visual component instance
  4598. * is construction, with the <code>new</code> operator:</p>
  4599. *
  4600. * <pre>
  4601. * var okButton:Button = new Button();</pre>
  4602. *
  4603. * <p>After construction, the new Button instance is a solitary
  4604. * DisplayObject; it does not yet have a UITextField as a child
  4605. * to display its label, and it doesn't have a parent.</p>
  4606. *
  4607. * <p>The second step is configuring the newly-constructed instance
  4608. * with the appropriate properties, styles, and event handlers:</p>
  4609. *
  4610. * <pre>
  4611. * okButton.label = "OK";
  4612. * okButton.setStyle("cornerRadius", 0);
  4613. * okButton.addEventListener(MouseEvent.CLICK, clickHandler);</pre>
  4614. *
  4615. * <p>The third step is adding the instance to a parent:</p>
  4616. *
  4617. * <pre>
  4618. * someContainer.addChild(okButton);</pre>
  4619. *
  4620. * <p>A side effect of calling <code>addChild()</code>
  4621. * or <code>addChildAt()</code>, when adding a component to a parent
  4622. * for the first time, is that <code>initialize</code> gets
  4623. * automatically called.</p>
  4624. *
  4625. * <p>This method first dispatches a <code>preinitialize</code> event,
  4626. * giving developers using this component a chance to affect it
  4627. * before its internal structure has been created.
  4628. * Next it calls the <code>createChildren()</code> method
  4629. * to create the component's internal structure; for a Button,
  4630. * this method creates and adds the UITextField for the label.
  4631. * Then it dispatches an <code>initialize</code> event,
  4632. * giving developers a chance to affect the component
  4633. * after its internal structure has been created.</p>
  4634. *
  4635. * <p>Note that it is the act of attaching a component to a parent
  4636. * for the first time that triggers the creation of its internal structure.
  4637. * If its internal structure includes other UIComponents, then this is a
  4638. * recursive process in which the tree of DisplayObjects grows by one leaf
  4639. * node at a time.</p>
  4640. *
  4641. * <p>If you are writing a component, you should not need
  4642. * to override this method.</p>
  4643. */
  4644. public function initialize():void
  4645. {
  4646. if (initialized)
  4647. return;
  4648. // The "preinitialize" event gets dispatched after everything about this
  4649. // DisplayObject has been initialized, and it has been attached to
  4650. // its parent, but before any of its children have been created.
  4651. // This allows a "preinitialize" event handler to set properties which
  4652. // affect child creation.
  4653. // Note that this implies that "preinitialize" handlers are called
  4654. // top-down; i.e., parents before children.
  4655. dispatchEvent(new FlexEvent(FlexEvent.PREINITIALIZE));
  4656. // Create child objects.
  4657. createChildren();
  4658. childrenCreated();
  4659. // Create and initialize the accessibility implementation.
  4660. // for this component. For some components accessible object is attached
  4661. // to child component so it should be called after createChildren
  4662. initializeAccessibility();
  4663. // This should always be the last thing that initialize() calls.
  4664. initializationComplete();
  4665. }
  4666. /**
  4667. * Finalizes the initialization of this component.
  4668. *
  4669. * <p>This method is the last code that executes when you add a component
  4670. * to a parent for the first time using <code>addChild()</code>
  4671. * or <code>addChildAt()</code>.
  4672. * It handles some housekeeping related to dispatching
  4673. * the <code>initialize</code> event.
  4674. * If you are writing a component, you should not need
  4675. * to override this method.</p>
  4676. */
  4677. protected function initializationComplete():void
  4678. {
  4679. processedDescriptors = true;
  4680. }
  4681. /**
  4682. * Initializes this component's accessibility code.
  4683. *
  4684. * <p>This method is called by the <code>initialize()</code> method to hook in the
  4685. * component's accessibility code, which resides in a separate class
  4686. * in the mx.accessibility package.
  4687. * Each subclass that supports accessibility must override this method
  4688. * because the hook-in process uses a different static variable
  4689. * in each subclass.</p>
  4690. */
  4691. protected function initializeAccessibility():void
  4692. {
  4693. if (UIComponent.createAccessibilityImplementation != null)
  4694. UIComponent.createAccessibilityImplementation(this);
  4695. }
  4696. /**
  4697. * Initializes various properties which keep track of repeated instances
  4698. * of this component.
  4699. *
  4700. * <p>An MXML <code>&lt;mx:Repeater/&gt;</code> tag can cause repeated instances
  4701. * of a component to be created, one instance for each item in the
  4702. * Repeater's data provider.
  4703. * The <code>instanceIndices</code>, <code>repeaters</code>,
  4704. * and <code>repeaterIndices</code> properties of UIComponent
  4705. * keep track of which instance came from which data item
  4706. * and which Repeater.</p>
  4707. *
  4708. * <p>This method is an internal method which is automatically called
  4709. * by the Flex framework.
  4710. * You should not have to call it or override it.</p>
  4711. *
  4712. * @param parent The parent object containing the Repeater that created
  4713. * this component.
  4714. */
  4715. public function initializeRepeaterArrays(parent:IRepeaterClient):void
  4716. {
  4717. // In the case, where the parent is a document, but isn't the
  4718. // child's document, we want to copy the instanceIndices down.
  4719. // See SDK-15317.
  4720. if (parent && parent.instanceIndices &&
  4721. ((!parent.isDocument) || (parent != descriptor.document)) &&
  4722. !_instanceIndices)
  4723. {
  4724. _instanceIndices = parent.instanceIndices;
  4725. _repeaters = parent.repeaters;
  4726. _repeaterIndices = parent.repeaterIndices;
  4727. }
  4728. }
  4729. /**
  4730. * Create child objects of the component.
  4731. * This is an advanced method that you might override
  4732. * when creating a subclass of UIComponent.
  4733. *
  4734. * <p>A component that creates other components or objects within it is called a composite component.
  4735. * For example, the Flex ComboBox control is actually made up of a TextInput control
  4736. * to define the text area of the ComboBox, and a Button control to define the ComboBox arrow.
  4737. * Components implement the <code>createChildren()</code> method to create child
  4738. * objects (such as other components) within the component.</p>
  4739. *
  4740. * <p>From within an override of the <code>createChildren()</code> method,
  4741. * you call the <code>addChild()</code> method to add each child object. </p>
  4742. *
  4743. * <p>You do not call this method directly. Flex calls the
  4744. * <code>createChildren()</code> method in response to the call to
  4745. * the <code>addChild()</code> method to add the component to its parent. </p>
  4746. */
  4747. protected function createChildren():void
  4748. {
  4749. }
  4750. /**
  4751. * Performs any final processing after child objects are created.
  4752. * This is an advanced method that you might override
  4753. * when creating a subclass of UIComponent.
  4754. */
  4755. protected function childrenCreated():void
  4756. {
  4757. invalidateProperties();
  4758. invalidateSize();
  4759. invalidateDisplayList();
  4760. }
  4761. //--------------------------------------------------------------------------
  4762. //
  4763. // Methods: Invalidation
  4764. //
  4765. //--------------------------------------------------------------------------
  4766. /**
  4767. * Marks a component so that its <code>commitProperties()</code>
  4768. * method gets called during a later screen update.
  4769. *
  4770. * <p>Invalidation is a useful mechanism for eliminating duplicate
  4771. * work by delaying processing of changes to a component until a
  4772. * later screen update.
  4773. * For example, if you want to change the text color and size,
  4774. * it would be wasteful to update the color immediately after you
  4775. * change it and then update the size when it gets set.
  4776. * It is more efficient to change both properties and then render
  4777. * the text with its new size and color once.</p>
  4778. *
  4779. * <p>Invalidation methods rarely get called.
  4780. * In general, setting a property on a component automatically
  4781. * calls the appropriate invalidation method.</p>
  4782. */
  4783. public function invalidateProperties():void
  4784. {
  4785. if (!invalidatePropertiesFlag)
  4786. {
  4787. invalidatePropertiesFlag = true;
  4788. if (parent && UIComponentGlobals.layoutManager)
  4789. UIComponentGlobals.layoutManager.invalidateProperties(this);
  4790. }
  4791. }
  4792. /**
  4793. * Marks a component so that its <code>measure()</code>
  4794. * method gets called during a later screen update.
  4795. *
  4796. * <p>Invalidation is a useful mechanism for eliminating duplicate
  4797. * work by delaying processing of changes to a component until a
  4798. * later screen update.
  4799. * For example, if you want to change the text and font size,
  4800. * it would be wasteful to update the text immediately after you
  4801. * change it and then update the size when it gets set.
  4802. * It is more efficient to change both properties and then render
  4803. * the text with its new size once.</p>
  4804. *
  4805. * <p>Invalidation methods rarely get called.
  4806. * In general, setting a property on a component automatically
  4807. * calls the appropriate invalidation method.</p>
  4808. */
  4809. public function invalidateSize():void
  4810. {
  4811. if (!invalidateSizeFlag)
  4812. {
  4813. invalidateSizeFlag = true;
  4814. if (parent && UIComponentGlobals.layoutManager)
  4815. UIComponentGlobals.layoutManager.invalidateSize(this);
  4816. }
  4817. }
  4818. /**
  4819. * Marks a component so that its <code>updateDisplayList()</code>
  4820. * method gets called during a later screen update.
  4821. *
  4822. * <p>Invalidation is a useful mechanism for eliminating duplicate
  4823. * work by delaying processing of changes to a component until a
  4824. * later screen update.
  4825. * For example, if you want to change the width and height,
  4826. * it would be wasteful to update the component immediately after you
  4827. * change the width and then update again with the new height.
  4828. * It is more efficient to change both properties and then render
  4829. * the component with its new size once.</p>
  4830. *
  4831. * <p>Invalidation methods rarely get called.
  4832. * In general, setting a property on a component automatically
  4833. * calls the appropriate invalidation method.</p>
  4834. */
  4835. public function invalidateDisplayList():void
  4836. {
  4837. if (!invalidateDisplayListFlag)
  4838. {
  4839. invalidateDisplayListFlag = true;
  4840. if (isOnDisplayList() && UIComponentGlobals.layoutManager)
  4841. UIComponentGlobals.layoutManager.invalidateDisplayList(this);
  4842. }
  4843. }
  4844. private function isOnDisplayList():Boolean
  4845. {
  4846. var p:DisplayObjectContainer;
  4847. try
  4848. {
  4849. p = _parent ? _parent : super.parent;
  4850. }
  4851. catch (e:SecurityError)
  4852. {
  4853. // trace("UIComponent.isOnDisplayList(): " + e);
  4854. return true; // we are on the display list but the parent is in another sandbox
  4855. }
  4856. return p ? true : false;
  4857. }
  4858. /**
  4859. * Flex calls the <code>stylesInitialized()</code> method when
  4860. * the styles for a component are first initialized.
  4861. *
  4862. * <p>This is an advanced method that you might override
  4863. * when creating a subclass of UIComponent. Flex guarantees that
  4864. * your component's styles will be fully initialized before
  4865. * the first time your component's <code>measure</code> and
  4866. * <code>updateDisplayList</code> methods are called. For most
  4867. * components, that is sufficient. But if you need early access to
  4868. * your style values, you can override the stylesInitialized() function
  4869. * to access style properties as soon as they are initialized the first time.</p>
  4870. */
  4871. public function stylesInitialized():void
  4872. {
  4873. }
  4874. /**
  4875. * Detects changes to style properties. When any style property is set,
  4876. * Flex calls the <code>styleChanged()</code> method,
  4877. * passing to it the name of the style being set.
  4878. *
  4879. * <p>This is an advanced method that you might override
  4880. * when creating a subclass of UIComponent. When you create a custom component,
  4881. * you can override the <code>styleChanged()</code> method
  4882. * to check the style name passed to it, and handle the change accordingly.
  4883. * This lets you override the default behavior of an existing style,
  4884. * or add your own custom style properties.</p>
  4885. *
  4886. * <p>If you handle the style property, your override of
  4887. * the <code>styleChanged()</code> method should call the
  4888. * <code>invalidateDisplayList()</code> method to cause Flex to execute
  4889. * the component's <code>updateDisplayList()</code> method at the next screen update.</p>
  4890. *
  4891. * @param styleProp The name of the style property, or null if all styles for this
  4892. * component have changed.
  4893. */
  4894. public function styleChanged(styleProp:String):void
  4895. {
  4896. // If font changed, then invalidateProperties so
  4897. // we can re-create the text field in commitProperties
  4898. if (this is IFontContextComponent && hasFontContextChanged())
  4899. invalidateProperties();
  4900. // Check to see if this is one of the style properties
  4901. // that is known to affect layout.
  4902. if (!styleProp ||
  4903. styleProp == "styleName" ||
  4904. StyleManager.isSizeInvalidatingStyle(styleProp))
  4905. {
  4906. // This style property change may affect the layout of this
  4907. // object. Signal the LayoutManager to re-measure the object.
  4908. invalidateSize();
  4909. }
  4910. if (!styleProp ||
  4911. styleProp == "styleName" ||
  4912. styleProp == "themeColor")
  4913. {
  4914. initThemeColor();
  4915. }
  4916. invalidateDisplayList();
  4917. if (parent is IInvalidating)
  4918. {
  4919. if (StyleManager.isParentSizeInvalidatingStyle(styleProp))
  4920. IInvalidating(parent).invalidateSize();
  4921. if (StyleManager.isParentDisplayListInvalidatingStyle(styleProp))
  4922. IInvalidating(parent).invalidateDisplayList();
  4923. }
  4924. }
  4925. /**
  4926. * Validate and update the properties and layout of this object
  4927. * and redraw it, if necessary.
  4928. *
  4929. * Processing properties that require substantial computation are normally
  4930. * not processed until the script finishes executing.
  4931. * For example setting the <code>width</code> property is delayed, because it may
  4932. * require recalculating the widths of the objects children or its parent.
  4933. * Delaying the processing prevents it from being repeated
  4934. * multiple times if the script sets the <code>width</code> property more than once.
  4935. * This method lets you manually override this behavior.
  4936. */
  4937. public function validateNow():void
  4938. {
  4939. UIComponentGlobals.layoutManager.validateClient(this);
  4940. }
  4941. /**
  4942. * @private
  4943. * This method is called at the beginning of each getter
  4944. * for the baselinePosition property.
  4945. * If it returns false, the getter should return NaN
  4946. * because the baselinePosition can't be computed.
  4947. * If it returns true, the getter can do computations
  4948. * like textField.y + textField.baselinePosition
  4949. * because these properties will be valid.
  4950. */
  4951. mx_internal function validateBaselinePosition():Boolean
  4952. {
  4953. // If this component isn't parented,
  4954. // then it doesn't know its text styles
  4955. // and we can't compute a baselinePosition.
  4956. if (!parent)
  4957. return false;
  4958. // If this component hasn't been sized yet, assign it
  4959. // an actual size that's based on its explicit or measured size.
  4960. if (width == 0 && height == 0)
  4961. {
  4962. validateNow();
  4963. var w:Number = getExplicitOrMeasuredWidth();
  4964. var h:Number = getExplicitOrMeasuredHeight();
  4965. setActualSize(w, h);
  4966. }
  4967. // Ensure that this component's internal TextFields
  4968. // are properly laid out, so that we can use
  4969. // their locations to compute a baselinePosition.
  4970. validateNow();
  4971. return true;
  4972. }
  4973. /**
  4974. * Queues a function to be called later.
  4975. *
  4976. * <p>Before each update of the screen, Flash Player or AIR calls
  4977. * the set of functions that are scheduled for the update.
  4978. * Sometimes, a function should be called in the next update
  4979. * to allow the rest of the code scheduled for the current
  4980. * update to be executed.
  4981. * Some features, like effects, can cause queued functions to be
  4982. * delayed until the feature completes.</p>
  4983. *
  4984. * @param method Reference to a method to be executed later.
  4985. *
  4986. * @param args Array of Objects that represent the arguments to pass to the method.
  4987. *
  4988. */
  4989. public function callLater(method:Function,
  4990. args:Array /* of Object */ = null):void
  4991. {
  4992. // trace(">>calllater " + this)
  4993. // Push the method and the arguments onto the method queue.
  4994. methodQueue.push(new MethodQueueElement(method, args));
  4995. // Register to get the next "render" event
  4996. // just before the next rasterization.
  4997. var sm:ISystemManager = systemManager;
  4998. // Stage can be null when an untrusted application is loaded by an application
  4999. // that isn't on stage yet.
  5000. if (sm && (sm.stage || sm.useSWFBridge()))
  5001. {
  5002. if (!listeningForRender)
  5003. {
  5004. // trace(" added");
  5005. sm.addEventListener(FlexEvent.RENDER, callLaterDispatcher);
  5006. sm.addEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher);
  5007. listeningForRender = true;
  5008. }
  5009. // Force a "render" event to happen soon
  5010. if (sm.stage)
  5011. sm.stage.invalidate();
  5012. }
  5013. // trace("<<calllater " + this)
  5014. }
  5015. /**
  5016. * @private
  5017. * Cancels all queued functions.
  5018. */
  5019. mx_internal function cancelAllCallLaters():void
  5020. {
  5021. var sm:ISystemManager = systemManager;
  5022. // Stage can be null when an untrusted application is loaded by an application
  5023. // that isn't on stage yet.
  5024. if (sm && (sm.stage || sm.useSWFBridge()))
  5025. {
  5026. if (listeningForRender)
  5027. {
  5028. sm.removeEventListener(FlexEvent.RENDER, callLaterDispatcher);
  5029. sm.removeEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher);
  5030. listeningForRender = false;
  5031. }
  5032. }
  5033. // Empty the method queue.
  5034. methodQueue.splice(0);
  5035. }
  5036. //--------------------------------------------------------------------------
  5037. //
  5038. // Methods: Commitment
  5039. //
  5040. //--------------------------------------------------------------------------
  5041. /**
  5042. * Used by layout logic to validate the properties of a component
  5043. * by calling the <code>commitProperties()</code> method.
  5044. * In general, subclassers should
  5045. * override the <code>commitProperties()</code> method and not this method.
  5046. */
  5047. public function validateProperties():void
  5048. {
  5049. if (invalidatePropertiesFlag)
  5050. {
  5051. commitProperties();
  5052. invalidatePropertiesFlag = false;
  5053. }
  5054. }
  5055. /**
  5056. * Processes the properties set on the component.
  5057. * This is an advanced method that you might override
  5058. * when creating a subclass of UIComponent.
  5059. *
  5060. * <p>You do not call this method directly.
  5061. * Flex calls the <code>commitProperties()</code> method when you
  5062. * use the <code>addChild()</code> method to add a component to a container,
  5063. * or when you call the <code>invalidateProperties()</code> method of the component.
  5064. * Calls to the <code>commitProperties()</code> method occur before calls to the
  5065. * <code>measure()</code> method. This lets you set property values that might
  5066. * be used by the <code>measure()</code> method.</p>
  5067. *
  5068. * <p>Some components have properties that affect the number or kinds
  5069. * of child objects that they need to create, or have properties that
  5070. * interact with each other, such as the <code>horizontalScrollPolicy</code>
  5071. * and <code>horizontalScrollPosition</code> properties.
  5072. * It is often best at startup time to process all of these
  5073. * properties at one time to avoid duplicating work.</p>
  5074. */
  5075. protected function commitProperties():void
  5076. {
  5077. if (_scaleX != oldScaleX)
  5078. {
  5079. var scalingFactorX:Number = Math.abs(_scaleX / oldScaleX);
  5080. if (!isNaN(explicitMinWidth))
  5081. explicitMinWidth *= scalingFactorX;
  5082. if (!isNaN(explicitWidth))
  5083. explicitWidth *= scalingFactorX;
  5084. if (!isNaN(explicitMaxWidth))
  5085. explicitMaxWidth *= scalingFactorX;
  5086. _width *= scalingFactorX;
  5087. super.scaleX = oldScaleX = _scaleX;
  5088. }
  5089. if (_scaleY != oldScaleY)
  5090. {
  5091. var scalingFactorY:Number = Math.abs(_scaleY / oldScaleY);
  5092. if (!isNaN(explicitMinHeight))
  5093. explicitMinHeight *= scalingFactorY;
  5094. if (!isNaN(explicitHeight))
  5095. explicitHeight *= scalingFactorY;
  5096. if (!isNaN(explicitMaxHeight))
  5097. explicitMaxHeight *= scalingFactorY;
  5098. _height *= scalingFactorY;
  5099. super.scaleY = oldScaleY = _scaleY;
  5100. }
  5101. if (x != oldX || y != oldY)
  5102. dispatchMoveEvent();
  5103. if (width != oldWidth || height != oldHeight)
  5104. dispatchResizeEvent();
  5105. if (errorStringChanged)
  5106. {
  5107. errorStringChanged = false;
  5108. setBorderColorForErrorString();
  5109. }
  5110. }
  5111. //--------------------------------------------------------------------------
  5112. //
  5113. // Methods: Measurement
  5114. //
  5115. //--------------------------------------------------------------------------
  5116. /**
  5117. * @inheritDoc
  5118. */
  5119. public function validateSize(recursive:Boolean = false):void
  5120. {
  5121. if (recursive)
  5122. {
  5123. for (var i:int = 0; i < numChildren; i++)
  5124. {
  5125. var child:DisplayObject = getChildAt(i);
  5126. if (child is ILayoutManagerClient )
  5127. (child as ILayoutManagerClient ).validateSize(true);
  5128. }
  5129. }
  5130. if (invalidateSizeFlag)
  5131. {
  5132. var sizeChanging:Boolean = measureSizes();
  5133. if (sizeChanging && includeInLayout)
  5134. {
  5135. invalidateDisplayList();
  5136. var p:IInvalidating = parent as IInvalidating;
  5137. if (p)
  5138. {
  5139. p.invalidateSize();
  5140. p.invalidateDisplayList();
  5141. }
  5142. }
  5143. }
  5144. }
  5145. /**
  5146. * @private
  5147. */
  5148. private function measureSizes():Boolean
  5149. {
  5150. var changed:Boolean = false;
  5151. if (!invalidateSizeFlag)
  5152. return changed;
  5153. var scalingFactor:Number;
  5154. var newValue:Number;
  5155. // We can skip the measure function if the object's width and height
  5156. // have been explicitly specified (e.g.: the object's MXML tag has
  5157. // attributes like width="50" and height="100").
  5158. //
  5159. // If an object's width and height have been explicitly specified,
  5160. // then the explicitWidth and explicitHeight properties contain
  5161. // Numbers (as opposed to NaN)
  5162. if (isNaN(explicitWidth) ||
  5163. isNaN(explicitHeight))
  5164. {
  5165. var xScale:Number = Math.abs(scaleX);
  5166. var yScale:Number = Math.abs(scaleY);
  5167. if (xScale != 1.0)
  5168. {
  5169. _measuredMinWidth /= xScale;
  5170. _measuredWidth /= xScale;
  5171. }
  5172. if (yScale != 1.0)
  5173. {
  5174. _measuredMinHeight /= yScale;
  5175. _measuredHeight /= yScale;
  5176. }
  5177. measure();
  5178. invalidateSizeFlag = false;
  5179. if (!isNaN(explicitMinWidth) && measuredWidth < explicitMinWidth)
  5180. measuredWidth = explicitMinWidth;
  5181. if (!isNaN(explicitMaxWidth) && measuredWidth > explicitMaxWidth)
  5182. measuredWidth = explicitMaxWidth;
  5183. if (!isNaN(explicitMinHeight) && measuredHeight < explicitMinHeight)
  5184. measuredHeight = explicitMinHeight;
  5185. if (!isNaN(explicitMaxHeight) && measuredHeight > explicitMaxHeight)
  5186. measuredHeight = explicitMaxHeight;
  5187. if (xScale != 1.0)
  5188. {
  5189. _measuredMinWidth *= xScale;
  5190. _measuredWidth *= xScale;
  5191. }
  5192. if (yScale != 1.0)
  5193. {
  5194. _measuredMinHeight *= yScale;
  5195. _measuredHeight *= yScale;
  5196. }
  5197. }
  5198. else
  5199. {
  5200. invalidateSizeFlag = false;
  5201. _measuredMinWidth = 0;
  5202. _measuredMinHeight = 0;
  5203. }
  5204. adjustSizesForScaleChanges();
  5205. if (isNaN(oldMinWidth))
  5206. {
  5207. // This branch does the same thing as the else branch,
  5208. // but it is optimized for the first time that
  5209. // measureSizes() is called on this object.
  5210. oldMinWidth = !isNaN(explicitMinWidth) ?
  5211. explicitMinWidth :
  5212. measuredMinWidth;
  5213. oldMinHeight = !isNaN(explicitMinHeight) ?
  5214. explicitMinHeight :
  5215. measuredMinHeight;
  5216. oldExplicitWidth = !isNaN(explicitWidth) ?
  5217. explicitWidth :
  5218. measuredWidth;
  5219. oldExplicitHeight = !isNaN(explicitHeight) ?
  5220. explicitHeight :
  5221. measuredHeight;
  5222. changed = true;
  5223. }
  5224. else
  5225. {
  5226. newValue = !isNaN(explicitMinWidth) ?
  5227. explicitMinWidth :
  5228. measuredMinWidth;
  5229. if (newValue != oldMinWidth)
  5230. {
  5231. oldMinWidth = newValue;
  5232. changed = true;
  5233. }
  5234. newValue = !isNaN(explicitMinHeight) ?
  5235. explicitMinHeight :
  5236. measuredMinHeight;
  5237. if (newValue != oldMinHeight)
  5238. {
  5239. oldMinHeight = newValue;
  5240. changed = true;
  5241. }
  5242. newValue = !isNaN(explicitWidth) ?
  5243. explicitWidth :
  5244. measuredWidth;
  5245. if (newValue != oldExplicitWidth)
  5246. {
  5247. oldExplicitWidth = newValue;
  5248. changed = true;
  5249. }
  5250. newValue = !isNaN(explicitHeight) ?
  5251. explicitHeight :
  5252. measuredHeight;
  5253. if (newValue != oldExplicitHeight)
  5254. {
  5255. oldExplicitHeight = newValue;
  5256. changed = true;
  5257. }
  5258. }
  5259. return changed;
  5260. }
  5261. /**
  5262. * Calculates the default size, and optionally the default minimum size,
  5263. * of the component. This is an advanced method that you might override when
  5264. * creating a subclass of UIComponent.
  5265. *
  5266. * <p>You do not call this method directly. Flex calls the
  5267. * <code>measure()</code> method when the component is added to a container
  5268. * using the <code>addChild()</code> method, and when the component's
  5269. * <code>invalidateSize()</code> method is called. </p>
  5270. *
  5271. * <p>When you set a specific height and width of a component,
  5272. * Flex does not call the <code>measure()</code> method,
  5273. * even if you explicitly call the <code>invalidateSize()</code> method.
  5274. * That is, Flex only calls the <code>measure()</code> method if
  5275. * the <code>explicitWidth</code> property or the <code>explicitHeight</code>
  5276. * property of the component is NaN. </p>
  5277. *
  5278. * <p>In your override of this method, you must set the
  5279. * <code>measuredWidth</code> and <code>measuredHeight</code> properties
  5280. * to define the default size.
  5281. * You may optionally set the <code>measuredMinWidth</code> and
  5282. * <code>measuredMinHeight</code> properties to define the default
  5283. * minimum size.</p>
  5284. *
  5285. * <p>Most components calculate these values based on the content they are
  5286. * displaying, and from the properties that affect content display.
  5287. * A few components simply have hard-coded default values. </p>
  5288. *
  5289. * <p>The conceptual point of <code>measure()</code> is for the component to provide
  5290. * its own natural or intrinsic size as a default. Therefore, the
  5291. * <code>measuredWidth</code> and <code>measuredHeight</code> properties
  5292. * should be determined by factors such as:</p>
  5293. * <ul>
  5294. * <li>The amount of text the component needs to display.</li>
  5295. * <li>The styles, such as <code>fontSize</code>, for that text.</li>
  5296. * <li>The size of a JPEG image that the component displays.</li>
  5297. * <li>The measured or explicit sizes of the component's children.</li>
  5298. * <li>Any borders, margins, and gaps.</li>
  5299. * </ul>
  5300. *
  5301. * <p>In some cases, there is no intrinsic way to determine default values.
  5302. * For example, a simple GreenCircle component might simply set
  5303. * measuredWidth = 100 and measuredHeight = 100 in its <code>measure()</code> method to
  5304. * provide a reasonable default size. In other cases, such as a TextArea,
  5305. * an appropriate computation (such as finding the right width and height
  5306. * that would just display all the text and have the aspect ratio of a Golden Rectangle)
  5307. * might be too time-consuming to be worthwhile.</p>
  5308. *
  5309. * <p>The default implementation of <code>measure()</code>
  5310. * sets <code>measuredWidth</code>, <code>measuredHeight</code>,
  5311. * <code>measuredMinWidth</code>, and <code>measuredMinHeight</code>
  5312. * to <code>0</code>.</p>
  5313. */
  5314. protected function measure():void
  5315. {
  5316. measuredMinWidth = 0;
  5317. measuredMinHeight = 0;
  5318. measuredWidth = 0;
  5319. measuredHeight = 0;
  5320. }
  5321. /**
  5322. * @private
  5323. */
  5324. mx_internal function adjustSizesForScaleChanges():void
  5325. {
  5326. var xScale:Number = scaleX;
  5327. var yScale:Number = scaleY;
  5328. var scalingFactor:Number;
  5329. if (xScale != oldScaleX)
  5330. {
  5331. scalingFactor = Math.abs(xScale / oldScaleX);
  5332. if (explicitMinWidth)
  5333. explicitMinWidth *= scalingFactor;
  5334. if (!isNaN(explicitWidth))
  5335. explicitWidth *= scalingFactor;
  5336. if (explicitMaxWidth)
  5337. explicitMaxWidth *= scalingFactor;
  5338. oldScaleX = xScale;
  5339. }
  5340. if (yScale != oldScaleY)
  5341. {
  5342. scalingFactor = Math.abs(yScale / oldScaleY);
  5343. if (explicitMinHeight)
  5344. explicitMinHeight *= scalingFactor;
  5345. if (explicitHeight)
  5346. explicitHeight *= scalingFactor;
  5347. if (explicitMaxHeight)
  5348. explicitMaxHeight *= scalingFactor;
  5349. oldScaleY = yScale;
  5350. }
  5351. }
  5352. /**
  5353. * A convenience method for determining whether to use the
  5354. * explicit or measured width
  5355. *
  5356. * @return A Number which is explicitWidth if defined
  5357. * or measuredWidth if not.
  5358. */
  5359. public function getExplicitOrMeasuredWidth():Number
  5360. {
  5361. return !isNaN(explicitWidth) ? explicitWidth : measuredWidth;
  5362. }
  5363. /**
  5364. * A convenience method for determining whether to use the
  5365. * explicit or measured height
  5366. *
  5367. * @return A Number which is explicitHeight if defined
  5368. * or measuredHeight if not.
  5369. */
  5370. public function getExplicitOrMeasuredHeight():Number
  5371. {
  5372. return !isNaN(explicitHeight) ? explicitHeight : measuredHeight;
  5373. }
  5374. /**
  5375. * A convenience method for determining the unscaled width
  5376. * of the component
  5377. * All of a component's drawing and child layout should be done
  5378. * within a bounding rectangle of this width, which is also passed
  5379. * as an argument to <code>updateDisplayList()</code>.
  5380. *
  5381. * @return A Number which is unscaled width of the component.
  5382. */
  5383. protected function get unscaledWidth():Number
  5384. {
  5385. return width / Math.abs(scaleX);
  5386. }
  5387. /**
  5388. * A convenience method for setting the unscaledWidth of a
  5389. * component.
  5390. *
  5391. * Setting this sets the width of the component as desired
  5392. * before any transformation is applied.
  5393. */
  5394. mx_internal function setUnscaledWidth(value:Number):void
  5395. {
  5396. var scaledValue:Number = value * Math.abs(oldScaleX);
  5397. if (_explicitWidth == scaledValue)
  5398. return;
  5399. // width can be pixel or percent not both
  5400. if (!isNaN(scaledValue))
  5401. _percentWidth = NaN;
  5402. _explicitWidth = scaledValue;
  5403. // We invalidate size because locking in width
  5404. // may change the measured height in flow-based components.
  5405. invalidateSize();
  5406. var p:IInvalidating = parent as IInvalidating;
  5407. if (p && includeInLayout)
  5408. {
  5409. p.invalidateSize();
  5410. p.invalidateDisplayList();
  5411. }
  5412. }
  5413. /**
  5414. * A convenience method for determining the unscaled height
  5415. * of the component.
  5416. * All of a component's drawing and child layout should be done
  5417. * within a bounding rectangle of this height, which is also passed
  5418. * as an argument to <code>updateDisplayList()</code>.
  5419. *
  5420. * @return A Number which is unscaled height of the component.
  5421. */
  5422. protected function get unscaledHeight():Number
  5423. {
  5424. return height / Math.abs(scaleY);
  5425. }
  5426. /**
  5427. * A convenience method for setting the unscaledHeight of a
  5428. * component.
  5429. *
  5430. * Setting this sets the height of the component as desired
  5431. * before any transformation is applied.
  5432. */
  5433. mx_internal function setUnscaledHeight(value:Number):void
  5434. {
  5435. var scaledValue:Number = value * Math.abs(oldScaleY);
  5436. if (_explicitHeight == scaledValue)
  5437. return;
  5438. // height can be pixel or percent, not both
  5439. if (!isNaN(scaledValue))
  5440. _percentHeight = NaN;
  5441. _explicitHeight = scaledValue;
  5442. // We invalidate size because locking in height
  5443. // may change the measured width in flow-based components.
  5444. invalidateSize();
  5445. var p:IInvalidating = parent as IInvalidating;
  5446. if (p && includeInLayout)
  5447. {
  5448. p.invalidateSize();
  5449. p.invalidateDisplayList();
  5450. }
  5451. }
  5452. /**
  5453. * Measures the specified text, assuming that it is displayed
  5454. * in a single-line UITextField using a UITextFormat
  5455. * determined by the styles of this UIComponent.
  5456. *
  5457. * @param text A String specifying the text to measure.
  5458. *
  5459. * @return A TextLineMetrics object containing the text measurements.
  5460. */
  5461. public function measureText(text:String):TextLineMetrics
  5462. {
  5463. return determineTextFormatFromStyles().measureText(text);
  5464. }
  5465. /**
  5466. * Measures the specified HTML text, which may contain HTML tags such
  5467. * as <code>&lt;font&gt;</code> and <code>&lt;b&gt;</code>,
  5468. * assuming that it is displayed
  5469. * in a single-line UITextField using a UITextFormat
  5470. * determined by the styles of this UIComponent.
  5471. *
  5472. * @param text A String specifying the HTML text to measure.
  5473. *
  5474. * @return A TextLineMetrics object containing the text measurements.
  5475. */
  5476. public function measureHTMLText(htmlText:String):TextLineMetrics
  5477. {
  5478. return determineTextFormatFromStyles().measureHTMLText(htmlText);
  5479. }
  5480. //--------------------------------------------------------------------------
  5481. //
  5482. // Methods: Drawing and Child Layout
  5483. //
  5484. //--------------------------------------------------------------------------
  5485. /**
  5486. * @private
  5487. */
  5488. private var lastUnscaledWidth:Number;
  5489. /**
  5490. * @private
  5491. */
  5492. private var lastUnscaledHeight:Number;
  5493. /**
  5494. * @inheritDoc
  5495. */
  5496. public function validateDisplayList():void
  5497. {
  5498. if (invalidateDisplayListFlag)
  5499. {
  5500. // Check if our parent is the top level system manager
  5501. var sm:ISystemManager = parent as ISystemManager;
  5502. if (sm)
  5503. {
  5504. if (sm is SystemManagerProxy || (sm == systemManager.topLevelSystemManager &&
  5505. sm.document != this))
  5506. {
  5507. // Size ourself to the new measured width/height
  5508. setActualSize(getExplicitOrMeasuredWidth(),
  5509. getExplicitOrMeasuredHeight());
  5510. }
  5511. }
  5512. var unscaledWidth:Number = scaleX == 0 ? 0 : width / scaleX;
  5513. var unscaledHeight:Number = scaleY == 0 ? 0 : height / scaleY;
  5514. // Use some hysteresis to prevent roundoff errors from
  5515. // causing problems as we scale. This isn't a full solution,
  5516. // but it helps.
  5517. if (Math.abs(unscaledWidth - lastUnscaledWidth) < .00001)
  5518. unscaledWidth = lastUnscaledWidth;
  5519. if (Math.abs(unscaledHeight - lastUnscaledHeight) < .00001)
  5520. unscaledHeight = lastUnscaledHeight;
  5521. updateDisplayList(unscaledWidth,unscaledHeight);
  5522. lastUnscaledWidth = unscaledWidth;
  5523. lastUnscaledHeight = unscaledHeight;
  5524. invalidateDisplayListFlag = false;
  5525. }
  5526. }
  5527. /**
  5528. * Draws the object and/or sizes and positions its children.
  5529. * This is an advanced method that you might override
  5530. * when creating a subclass of UIComponent.
  5531. *
  5532. * <p>You do not call this method directly. Flex calls the
  5533. * <code>updateDisplayList()</code> method when the component is added to a container
  5534. * using the <code>addChild()</code> method, and when the component's
  5535. * <code>invalidateDisplayList()</code> method is called. </p>
  5536. *
  5537. * <p>If the component has no children, this method
  5538. * is where you would do programmatic drawing
  5539. * using methods on the component's Graphics object
  5540. * such as <code>graphics.drawRect()</code>.</p>
  5541. *
  5542. * <p>If the component has children, this method is where
  5543. * you would call the <code>move()</code> and <code>setActualSize()</code>
  5544. * methods on its children.</p>
  5545. *
  5546. * <p>Components may do programmatic drawing even if
  5547. * they have children. In doing either, you should use the
  5548. * component's <code>unscaledWidth</code> and <code>unscaledHeight</code>
  5549. * as its bounds.</p>
  5550. *
  5551. * <p>It is important to use <code>unscaledWidth</code> and
  5552. * <code>unscaledHeight</code> instead of the <code>width</code>
  5553. * and <code>height</code> properties.</p>
  5554. *
  5555. * @param unscaledWidth Specifies the width of the component, in pixels,
  5556. * in the component's coordinates, regardless of the value of the
  5557. * <code>scaleX</code> property of the component.
  5558. *
  5559. * @param unscaledHeight Specifies the height of the component, in pixels,
  5560. * in the component's coordinates, regardless of the value of the
  5561. * <code>scaleY</code> property of the component.
  5562. */
  5563. protected function updateDisplayList(unscaledWidth:Number,
  5564. unscaledHeight:Number):void
  5565. {
  5566. }
  5567. /**
  5568. * Returns a layout constraint value, which is the same as
  5569. * getting the constraint style for this component.
  5570. *
  5571. * @param constraintName The name of the constraint style, which
  5572. * can be any of the following: left, right, top, bottom,
  5573. * verticalCenter, horizontalCenter, baseline
  5574. *
  5575. * @return Returns the layout constraint value, which can be
  5576. * specified in either of two forms. It can be specified as a
  5577. * numeric string, for example, "10" or it can be specified as
  5578. * identifier:numeric string. For identifier:numeric string,
  5579. * identifier is the <code>id</code> of a ConstraintRow or
  5580. * ConstraintColumn. For example, a value of "cc1:10" specifies a
  5581. * value of 10 for the ConstraintColumn that has the
  5582. * <code>id</code> "cc1."
  5583. */
  5584. public function getConstraintValue(constraintName:String):*
  5585. {
  5586. return getStyle(constraintName);
  5587. }
  5588. /**
  5589. * Sets a layout constraint value, which is the same as
  5590. * setting the constraint style for this component.
  5591. *
  5592. * @param constraintName The name of the constraint style, which
  5593. * can be any of the following: left, right, top, bottom,
  5594. * verticalCenter, horizontalCenter, baseline
  5595. *
  5596. * @value The value of the constraint can be specified in either
  5597. * of two forms. It can be specified as a numeric string, for
  5598. * example, "10" or it can be specified as identifier:numeric
  5599. * string. For identifier:numeric string, identifier is the
  5600. * <code>id</code> of a ConstraintRow or ConstraintColumn. For
  5601. * example, a value of "cc1:10" specifies a value of 10 for the
  5602. * ConstraintColumn that has the <code>id</code> "cc1."
  5603. *
  5604. */
  5605. public function setConstraintValue(constraintName:String, value:*):void
  5606. {
  5607. setStyle(constraintName, value);
  5608. }
  5609. //--------------------------------------------------------------------------
  5610. //
  5611. // Methods: Drawing
  5612. //
  5613. //--------------------------------------------------------------------------
  5614. /**
  5615. * Returns a box Matrix which can be passed to the
  5616. * <code>drawRoundRect()</code> method
  5617. * as the <code>rot</code> parameter when drawing a horizontal gradient.
  5618. *
  5619. * <p>For performance reasons, the Matrix is stored in a static variable
  5620. * which is reused by all calls to <code>horizontalGradientMatrix()</code>
  5621. * and <code>verticalGradientMatrix()</code>.
  5622. * Therefore, you should pass the resulting Matrix
  5623. * to <code>drawRoundRect()</code> before calling
  5624. * <code>horizontalGradientMatrix()</code>
  5625. * or <code>verticalGradientMatrix()</code> again.</p>
  5626. *
  5627. * @param x The left coordinate of the gradient, in pixels.
  5628. *
  5629. * @param y The top coordinate of the gradient, in pixels.
  5630. *
  5631. * @param width The width of the gradient, in pixels.
  5632. *
  5633. * @param height The height of the gradient, in pixels.
  5634. *
  5635. * @return The Matrix for the horizontal gradient.
  5636. */
  5637. public function horizontalGradientMatrix(x:Number, y:Number,
  5638. width:Number,
  5639. height:Number):Matrix
  5640. {
  5641. UIComponentGlobals.tempMatrix.createGradientBox(width, height, 0, x, y);
  5642. return UIComponentGlobals.tempMatrix;
  5643. }
  5644. /**
  5645. * Returns a box Matrix which can be passed to <code>drawRoundRect()</code>
  5646. * as the <code>rot</code> parameter when drawing a vertical gradient.
  5647. *
  5648. * <p>For performance reasons, the Matrix is stored in a static variable
  5649. * which is reused by all calls to <code>horizontalGradientMatrix()</code>
  5650. * and <code>verticalGradientMatrix()</code>.
  5651. * Therefore, you should pass the resulting Matrix
  5652. * to <code>drawRoundRect()</code> before calling
  5653. * <code>horizontalGradientMatrix()</code>
  5654. * or <code>verticalGradientMatrix()</code> again.</p>
  5655. *
  5656. * @param x The left coordinate of the gradient, in pixels.
  5657. *
  5658. * @param y The top coordinate of the gradient, in pixels.
  5659. *
  5660. * @param width The width of the gradient, in pixels.
  5661. *
  5662. * @param height The height of the gradient, in pixels.
  5663. *
  5664. * @return The Matrix for the vertical gradient.
  5665. */
  5666. public function verticalGradientMatrix(x:Number, y:Number,
  5667. width:Number,
  5668. height:Number):Matrix
  5669. {
  5670. UIComponentGlobals.tempMatrix.createGradientBox(width, height, Math.PI / 2, x, y);
  5671. return UIComponentGlobals.tempMatrix;
  5672. }
  5673. /**
  5674. * @copy mx.skins.ProgrammaticSkin#drawRoundRect()
  5675. */
  5676. public function drawRoundRect(x:Number, y:Number, w:Number, h:Number,
  5677. r:Object = null, c:Object = null,
  5678. alpha:Object = null, rot:Object = null,
  5679. gradient:String = null, ratios:Array = null,
  5680. hole:Object = null):void
  5681. {
  5682. var g:Graphics = graphics;
  5683. // Quick exit if w or h is zero. This happens when scaling a component
  5684. // to a very small value, which then gets rounded to 0.
  5685. if (!w || !h)
  5686. return;
  5687. // If color is an object then allow for complex fills.
  5688. if (c !== null)
  5689. {
  5690. if (c is Array)
  5691. {
  5692. var alphas:Array;
  5693. if (alpha is Array)
  5694. alphas = alpha as Array;
  5695. else
  5696. alphas = [ alpha, alpha ];
  5697. if (!ratios)
  5698. ratios = [ 0, 0xFF ];
  5699. var matrix:Matrix = null;
  5700. if (rot)
  5701. {
  5702. if (rot is Matrix)
  5703. {
  5704. matrix = Matrix(rot);
  5705. }
  5706. else
  5707. {
  5708. matrix = new Matrix();
  5709. if (rot is Number)
  5710. {
  5711. matrix.createGradientBox(
  5712. w, h, Number(rot) * Math.PI / 180, x, y);
  5713. }
  5714. else
  5715. {
  5716. matrix.createGradientBox(
  5717. rot.w, rot.h, rot.r, rot.x, rot.y);
  5718. }
  5719. }
  5720. }
  5721. if (gradient == GradientType.RADIAL)
  5722. {
  5723. g.beginGradientFill(GradientType.RADIAL,
  5724. c as Array, alphas, ratios, matrix);
  5725. }
  5726. else
  5727. {
  5728. g.beginGradientFill(GradientType.LINEAR,
  5729. c as Array, alphas, ratios, matrix);
  5730. }
  5731. }
  5732. else
  5733. {
  5734. g.beginFill(Number(c), Number(alpha));
  5735. }
  5736. }
  5737. var ellipseSize:Number;
  5738. // Stroke the rectangle.
  5739. if (!r)
  5740. {
  5741. g.drawRect(x, y, w, h);
  5742. }
  5743. else if (r is Number)
  5744. {
  5745. ellipseSize = Number(r) * 2;
  5746. g.drawRoundRect(x, y, w, h, ellipseSize, ellipseSize);
  5747. }
  5748. else
  5749. {
  5750. GraphicsUtil.drawRoundRectComplex(g, x, y, w, h, r.tl, r.tr, r.bl, r.br);
  5751. }
  5752. // Carve a rectangular hole out of the middle of the rounded rect.
  5753. if (hole)
  5754. {
  5755. var holeR:Object = hole.r;
  5756. if (holeR is Number)
  5757. {
  5758. ellipseSize = Number(holeR) * 2;
  5759. g.drawRoundRect(hole.x, hole.y, hole.w, hole.h,
  5760. ellipseSize, ellipseSize);
  5761. }
  5762. else
  5763. {
  5764. GraphicsUtil.drawRoundRectComplex(g, hole.x, hole.y, hole.w, hole.h,
  5765. holeR.tl, holeR.tr, holeR.bl, holeR.br);
  5766. }
  5767. }
  5768. if (c !== null)
  5769. g.endFill();
  5770. }
  5771. //--------------------------------------------------------------------------
  5772. //
  5773. // Methods: Moving and sizing
  5774. //
  5775. //--------------------------------------------------------------------------
  5776. /**
  5777. * Moves the component to a specified position within its parent.
  5778. * Calling this method is exactly the same as
  5779. * setting the component's <code>x</code> and <code>y</code> properties.
  5780. *
  5781. * <p>If you are overriding the <code>updateDisplayList()</code> method
  5782. * in a custom component, you should call the <code>move()</code> method
  5783. * rather than setting the <code>x</code> and <code>y</code> properties.
  5784. * The difference is that the <code>move()</code> method changes the location
  5785. * of the component and then dispatches a <code>move</code> event when you
  5786. * call the method, while setting the <code>x</code> and <code>y</code>
  5787. * properties changes the location of the component and dispatches
  5788. * the event on the next screen refresh.</p>
  5789. *
  5790. * @param x Left position of the component within its parent.
  5791. *
  5792. * @param y Top position of the component within its parent.
  5793. */
  5794. public function move(x:Number, y:Number):void
  5795. {
  5796. var changed:Boolean = false;
  5797. if (x != super.x)
  5798. {
  5799. super.x = x;
  5800. dispatchEvent(new Event("xChanged"));
  5801. changed = true;
  5802. }
  5803. if (y != super.y)
  5804. {
  5805. super.y = y;
  5806. dispatchEvent(new Event("yChanged"));
  5807. changed = true;
  5808. }
  5809. if (changed)
  5810. dispatchMoveEvent();
  5811. }
  5812. /**
  5813. * Sizes the object.
  5814. * Unlike directly setting the <code>width</code> and <code>height</code>
  5815. * properties, calling the <code>setActualSize()</code> method
  5816. * does not set the <code>explictWidth</code> and
  5817. * <code>explicitHeight</code> properties, so a future layout
  5818. * calculation may result in the object returning to its previous size.
  5819. * This method is used primarily by component developers implementing
  5820. * the <code>updateDisplayList()</code> method, by Effects,
  5821. * and by the LayoutManager.
  5822. *
  5823. * @param w Width of the object.
  5824. *
  5825. * @param h Height of the object.
  5826. */
  5827. public function setActualSize(w:Number, h:Number):void
  5828. {
  5829. // trace("setActualSize: " + this + " width = " + w + " height = " + h);
  5830. var changed:Boolean = false;
  5831. if (_width != w)
  5832. {
  5833. _width = w;
  5834. dispatchEvent(new Event("widthChanged"));
  5835. changed = true;
  5836. }
  5837. if (_height != h)
  5838. {
  5839. _height = h;
  5840. dispatchEvent(new Event("heightChanged"));
  5841. changed = true;
  5842. }
  5843. if (changed)
  5844. {
  5845. invalidateDisplayList();
  5846. dispatchResizeEvent();
  5847. }
  5848. }
  5849. //--------------------------------------------------------------------------
  5850. //
  5851. // Methods: Content coordinate transformations
  5852. //
  5853. //--------------------------------------------------------------------------
  5854. /**
  5855. * Converts a <code>Point</code> object from content coordinates to global coordinates.
  5856. * Content coordinates specify a pixel position relative to the upper left corner
  5857. * of the component's content, and include all of the component's content area,
  5858. * including any regions that are currently clipped and must be
  5859. * accessed by scrolling the component.
  5860. * You use the content coordinate system to set and get the positions of children
  5861. * of a container that uses absolute positioning.
  5862. * Global coordinates specify a pixel position relative to the upper-left corner
  5863. * of the stage, that is, the outermost edge of the application.
  5864. *
  5865. * @param point A Point object that
  5866. * specifies the <i>x</i> and <i>y</i> coordinates in the content coordinate system
  5867. * as properties.
  5868. *
  5869. * @return A Point object with coordinates relative to the Stage.
  5870. *
  5871. * @see #globalToContent()
  5872. */
  5873. public function contentToGlobal(point:Point):Point
  5874. {
  5875. return localToGlobal(point);
  5876. }
  5877. /**
  5878. * Converts a <code>Point</code> object from global to content coordinates.
  5879. * Global coordinates specify a pixel position relative to the upper-left corner
  5880. * of the stage, that is, the outermost edge of the application.
  5881. * Content coordinates specify a pixel position relative to the upper left corner
  5882. * of the component's content, and include all of the component's content area,
  5883. * including any regions that are currently clipped and must be
  5884. * accessed by scrolling the component.
  5885. * You use the content coordinate system to set and get the positions of children
  5886. * of a container that uses absolute positioning.
  5887. *
  5888. * @param point A Point object that
  5889. * specifies the <i>x</i> and <i>y</i> coordinates in the global (Stage)
  5890. * coordinate system as properties.
  5891. *
  5892. * @return Point A Point object with coordinates relative to the component.
  5893. *
  5894. * @see #contentToGlobal()
  5895. */
  5896. public function globalToContent(point:Point):Point
  5897. {
  5898. return globalToLocal(point);
  5899. }
  5900. /**
  5901. * Converts a <code>Point</code> object from content to local coordinates.
  5902. * Content coordinates specify a pixel position relative to the upper left corner
  5903. * of the component's content, and include all of the component's content area,
  5904. * including any regions that are currently clipped and must be
  5905. * accessed by scrolling the component.
  5906. * You use the content coordinate system to set and get the positions of children
  5907. * of a container that uses absolute positioning.
  5908. * Local coordinates specify a pixel position relative to the
  5909. * upper left corner of the component.
  5910. *
  5911. * @param point A Point object that specifies the <i>x</i> and <i>y</i>
  5912. * coordinates in the content coordinate system as properties.
  5913. *
  5914. * @return Point A Point object with coordinates relative to the
  5915. * local coordinate system.
  5916. *
  5917. * @see #contentToGlobal()
  5918. */
  5919. public function contentToLocal(point:Point):Point
  5920. {
  5921. return point;
  5922. }
  5923. /**
  5924. * Converts a <code>Point</code> object from local to content coordinates.
  5925. * Local coordinates specify a pixel position relative to the
  5926. * upper left corner of the component.
  5927. * Content coordinates specify a pixel position relative to the upper left corner
  5928. * of the component's content, and include all of the component's content area,
  5929. * including any regions that are currently clipped and must be
  5930. * accessed by scrolling the component.
  5931. * You use the content coordinate system to set and get the positions of children
  5932. * of a container that uses absolute positioning.
  5933. *
  5934. * @param point A Point object that specifies the <i>x</i> and <i>y</i>
  5935. * coordinates in the local coordinate system as properties.
  5936. *
  5937. * @return Point A Point object with coordinates relative to the
  5938. * content coordinate system.
  5939. *
  5940. * @see #contentToLocal()
  5941. */
  5942. public function localToContent(point:Point):Point
  5943. {
  5944. return point;
  5945. }
  5946. //--------------------------------------------------------------------------
  5947. //
  5948. // Methods: Focus
  5949. //
  5950. //--------------------------------------------------------------------------
  5951. /**
  5952. * Gets the object that currently has focus.
  5953. * It might not be this object.
  5954. * Note that this method does not necessarily return the component
  5955. * that has focus.
  5956. * It may return the internal subcomponent of the component
  5957. * that has focus.
  5958. * To get the component that has focus, use the
  5959. * <code>focusManager.focus</code> property.
  5960. *
  5961. * @return Object that has focus.
  5962. */
  5963. public function getFocus():InteractiveObject
  5964. {
  5965. var sm:ISystemManager = systemManager;
  5966. if (!sm)
  5967. return null;
  5968. if (UIComponentGlobals.nextFocusObject)
  5969. return UIComponentGlobals.nextFocusObject;
  5970. return sm.stage.focus;
  5971. }
  5972. /**
  5973. * Sets the focus to this component.
  5974. * The component may in turn pass focus to a subcomponent.
  5975. *
  5976. * <p><b>Note:</b> Only the TextInput and TextArea controls show a highlight
  5977. * when this method sets the focus.
  5978. * All controls show a highlight when the user tabs to the control.</p>
  5979. */
  5980. public function setFocus():void
  5981. {
  5982. var sm:ISystemManager = systemManager;
  5983. if (sm && (sm.stage || sm.useSWFBridge()))
  5984. {
  5985. if (UIComponentGlobals.callLaterDispatcherCount == 0)
  5986. {
  5987. sm.stage.focus = this;
  5988. UIComponentGlobals.nextFocusObject = null;
  5989. }
  5990. else
  5991. {
  5992. UIComponentGlobals.nextFocusObject = this;
  5993. sm.addEventListener(FlexEvent.ENTER_FRAME, setFocusLater);
  5994. }
  5995. }
  5996. else
  5997. {
  5998. UIComponentGlobals.nextFocusObject = this;
  5999. callLater(setFocusLater);
  6000. }
  6001. }
  6002. /**
  6003. * @private
  6004. * Returns the focus object
  6005. */
  6006. mx_internal function getFocusObject():DisplayObject
  6007. {
  6008. var fm:IFocusManager = focusManager;
  6009. if (!fm || !fm.focusPane)
  6010. return null;
  6011. return fm.focusPane.numChildren == 0 ?
  6012. null :
  6013. fm.focusPane.getChildAt(0);
  6014. }
  6015. /**
  6016. * Shows or hides the focus indicator around this component.
  6017. *
  6018. * <p>UIComponent implements this by creating an instance of the class
  6019. * specified by the <code>focusSkin</code> style and positioning it
  6020. * appropriately.</p>
  6021. *
  6022. * @param isFocused Determines if the focus indicator should be displayed. Set to
  6023. * <code>true</code> to display the focus indicator. Set to <code>false</code> to hide it.
  6024. */
  6025. public function drawFocus(isFocused:Boolean):void
  6026. {
  6027. // Gets called by removeChild() after un-parented.
  6028. if (!parent)
  6029. return;
  6030. var focusObj:DisplayObject = getFocusObject();
  6031. var focusPane:Sprite = focusManager ? focusManager.focusPane : null;
  6032. if (isFocused && !preventDrawFocus) //&& !isEffectStarted
  6033. {
  6034. var focusOwner:DisplayObjectContainer = focusPane.parent;
  6035. if (focusOwner != parent)
  6036. {
  6037. if (focusOwner)
  6038. {
  6039. if (focusOwner is ISystemManager)
  6040. ISystemManager(focusOwner).focusPane = null;
  6041. else
  6042. IUIComponent(focusOwner).focusPane = null;
  6043. }
  6044. if (parent is ISystemManager)
  6045. ISystemManager(parent).focusPane = focusPane;
  6046. else
  6047. IUIComponent(parent).focusPane = focusPane;
  6048. }
  6049. var focusClass:Class = getStyle("focusSkin");
  6050. if (focusObj && !(focusObj is focusClass))
  6051. {
  6052. focusPane.removeChild(focusObj);
  6053. focusObj = null;
  6054. }
  6055. if (!focusObj)
  6056. {
  6057. focusObj = new focusClass();
  6058. focusObj.name = "focus";
  6059. focusPane.addChild(focusObj);
  6060. }
  6061. if (focusObj is ILayoutManagerClient )
  6062. ILayoutManagerClient (focusObj).nestLevel = nestLevel;
  6063. if (focusObj is ISimpleStyleClient)
  6064. ISimpleStyleClient(focusObj).styleName = this;
  6065. addEventListener(MoveEvent.MOVE, focusObj_moveHandler, true);
  6066. addEventListener(MoveEvent.MOVE, focusObj_moveHandler);
  6067. addEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler, true);
  6068. addEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler);
  6069. addEventListener(Event.REMOVED, focusObj_removedHandler, true);
  6070. focusObj.visible = true;
  6071. hasFocusRect = true;
  6072. adjustFocusRect();
  6073. }
  6074. else if (hasFocusRect)
  6075. {
  6076. hasFocusRect = false;
  6077. if (focusObj)
  6078. {
  6079. focusObj.visible = false;
  6080. if (focusObj is ISimpleStyleClient)
  6081. ISimpleStyleClient(focusObj).styleName = null;
  6082. }
  6083. removeEventListener(MoveEvent.MOVE, focusObj_moveHandler);
  6084. removeEventListener(MoveEvent.MOVE, focusObj_moveHandler, true);
  6085. removeEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler, true);
  6086. removeEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler);
  6087. removeEventListener(Event.REMOVED, focusObj_removedHandler, true);
  6088. }
  6089. }
  6090. /**
  6091. * Adjust the focus rectangle.
  6092. *
  6093. * @param The component whose focus rectangle to modify.
  6094. * If omitted, the default value is this UIComponent object.
  6095. */
  6096. protected function adjustFocusRect(obj:DisplayObject = null):void
  6097. {
  6098. if (!obj)
  6099. obj = this;
  6100. // Something inside the lisder has a width and height of NaN
  6101. if (isNaN(obj.width) || isNaN(obj.height))
  6102. return;
  6103. var fm:IFocusManager = focusManager;
  6104. if (!fm)
  6105. return; // we've been unparented so ignore
  6106. var focusObj:IFlexDisplayObject = IFlexDisplayObject(getFocusObject());
  6107. if (focusObj)
  6108. {
  6109. var rectCol:Number;
  6110. if (errorString && errorString != "")
  6111. rectCol = getStyle("errorColor");
  6112. else
  6113. rectCol = getStyle("themeColor");
  6114. var thickness:Number = getStyle("focusThickness");
  6115. if (focusObj is IStyleClient)
  6116. {
  6117. IStyleClient(focusObj).setStyle("focusColor", rectCol);
  6118. }
  6119. //if (getStyle("focusColor") != rectCol)
  6120. // setStyle("focusColor", rectCol);
  6121. focusObj.setActualSize(obj.width + 2 * thickness,
  6122. obj.height + 2 * thickness);
  6123. var pt:Point;
  6124. if (rotation)
  6125. {
  6126. var rotRad:Number = rotation * Math.PI / 180;
  6127. pt = new Point(obj.x - thickness * (Math.cos(rotRad) - Math.sin(rotRad)),
  6128. obj.y - thickness * (Math.cos(rotRad) + Math.sin(rotRad)));
  6129. DisplayObject(focusObj).rotation = rotation;
  6130. }
  6131. else
  6132. {
  6133. pt = new Point(obj.x - thickness, obj.y - thickness);
  6134. }
  6135. if (obj.parent == this)
  6136. {
  6137. // This adjustment only works if obj is a direct child of this.
  6138. pt.x += x;
  6139. pt.y += y;
  6140. }
  6141. pt = parent.localToGlobal(pt);
  6142. pt = parent.globalToLocal(pt);
  6143. focusObj.move(pt.x, pt.y);
  6144. if (focusObj is IInvalidating)
  6145. IInvalidating(focusObj).validateNow();
  6146. else if (focusObj is IProgrammaticSkin)
  6147. IProgrammaticSkin(focusObj).validateNow();
  6148. }
  6149. }
  6150. //--------------------------------------------------------------------------
  6151. //
  6152. // Methods: Events
  6153. //
  6154. //--------------------------------------------------------------------------
  6155. /**
  6156. * @private
  6157. */
  6158. private function dispatchMoveEvent():void
  6159. {
  6160. var moveEvent:MoveEvent = new MoveEvent(MoveEvent.MOVE);
  6161. moveEvent.oldX = oldX;
  6162. moveEvent.oldY = oldY;
  6163. dispatchEvent(moveEvent);
  6164. oldX = x;
  6165. oldY = y;
  6166. }
  6167. /**
  6168. * @private
  6169. */
  6170. private function dispatchResizeEvent():void
  6171. {
  6172. var resizeEvent:ResizeEvent = new ResizeEvent(ResizeEvent.RESIZE);
  6173. resizeEvent.oldWidth = oldWidth;
  6174. resizeEvent.oldHeight = oldHeight;
  6175. dispatchEvent(resizeEvent);
  6176. oldWidth = width;
  6177. oldHeight = height;
  6178. }
  6179. //--------------------------------------------------------------------------
  6180. //
  6181. // Methods: States
  6182. //
  6183. //--------------------------------------------------------------------------
  6184. /**
  6185. * Set the current state.
  6186. *
  6187. * @param stateName The name of the new view state.
  6188. *
  6189. * @param playTransition If <code>true</code>, play
  6190. * the appropriate transition when the view state changes.
  6191. *
  6192. * @see #currentState
  6193. */
  6194. public function setCurrentState(stateName:String,
  6195. playTransition:Boolean = true):void
  6196. {
  6197. // Only change if the requested state is different. Since the root
  6198. // state can be either null or "", we need to add additional check
  6199. // to make sure we're not going from null to "" or vice-versa.
  6200. if (stateName != currentState &&
  6201. !(isBaseState(stateName) && isBaseState(currentState)))
  6202. {
  6203. requestedCurrentState = stateName;
  6204. playStateTransition = playTransition;
  6205. if (initialized)
  6206. {
  6207. commitCurrentState();
  6208. }
  6209. else
  6210. {
  6211. _currentStateChanged = true;
  6212. // We need to wait until we're fully initialized before commiting
  6213. // the current state. Otherwise children may not be created
  6214. // (if we're inside a deferred instantiation container), or
  6215. // bindings may not be fired yet.
  6216. addEventListener(FlexEvent.CREATION_COMPLETE,
  6217. creationCompleteHandler);
  6218. }
  6219. }
  6220. }
  6221. /**
  6222. * @private
  6223. * Returns true if the passed in state name is the 'base' state, which
  6224. * is currently defined as null or ""
  6225. */
  6226. private function isBaseState(stateName:String):Boolean
  6227. {
  6228. return !stateName || stateName == "";
  6229. }
  6230. /**
  6231. * @private
  6232. * Commit a pending current state change.
  6233. */
  6234. private function commitCurrentState():void
  6235. {
  6236. var transition:IEffect =
  6237. playStateTransition ?
  6238. getTransition(_currentState, requestedCurrentState) :
  6239. null;
  6240. var commonBaseState:String = findCommonBaseState(_currentState, requestedCurrentState);
  6241. var event:StateChangeEvent;
  6242. var oldState:String = _currentState ? _currentState : "";
  6243. var destination:State = getState(requestedCurrentState);
  6244. // Stop any transition that may still be playing
  6245. if (_currentTransitionEffect)
  6246. _currentTransitionEffect.end();
  6247. // Initialize the state we are going to.
  6248. initializeState(requestedCurrentState);
  6249. // Capture transition start values
  6250. if (transition)
  6251. transition.captureStartValues();
  6252. // Dispatch currentStateChanging event
  6253. event = new StateChangeEvent(StateChangeEvent.CURRENT_STATE_CHANGING);
  6254. event.oldState = oldState;
  6255. event.newState = requestedCurrentState ? requestedCurrentState : "";
  6256. dispatchEvent(event);
  6257. // If we're leaving the base state, send an exitState event
  6258. if (isBaseState(_currentState))
  6259. dispatchEvent(new FlexEvent(FlexEvent.EXIT_STATE));
  6260. // Remove the existing state
  6261. removeState(_currentState, commonBaseState);
  6262. _currentState = requestedCurrentState;
  6263. // If we're going back to the base state, dispatch an
  6264. // enter state event, otherwise apply the state.
  6265. if (isBaseState(currentState))
  6266. dispatchEvent(new FlexEvent(FlexEvent.ENTER_STATE));
  6267. else
  6268. applyState(_currentState, commonBaseState);
  6269. // Dispatch currentStateChange
  6270. event = new StateChangeEvent(StateChangeEvent.CURRENT_STATE_CHANGE);
  6271. event.oldState = oldState;
  6272. event.newState = _currentState ? _currentState : "";
  6273. dispatchEvent(event);
  6274. if (transition)
  6275. {
  6276. // Force a validation before playing the transition effect
  6277. UIComponentGlobals.layoutManager.validateNow();
  6278. _currentTransitionEffect = transition;
  6279. transition.addEventListener(EffectEvent.EFFECT_END, transition_effectEndHandler);
  6280. transition.play();
  6281. }
  6282. }
  6283. /**
  6284. * @private
  6285. */
  6286. private function transition_effectEndHandler(event:EffectEvent):void
  6287. {
  6288. _currentTransitionEffect = null;
  6289. }
  6290. /**
  6291. * @private
  6292. * Returns the state with the specified name, or null if it doesn't exist.
  6293. * If multiple states have the same name the first one will be returned.
  6294. */
  6295. private function getState(stateName:String):State
  6296. {
  6297. if (!states || isBaseState(stateName))
  6298. return null;
  6299. // Do a simple linear search for now. This can
  6300. // be optimized later if needed.
  6301. for (var i:int = 0; i < states.length; i++)
  6302. {
  6303. if (states[i].name == stateName)
  6304. return states[i];
  6305. }
  6306. var message:String = resourceManager.getString(
  6307. "core", "stateUndefined", [ stateName ]);
  6308. throw new ArgumentError(message);
  6309. return null;
  6310. }
  6311. /**
  6312. * @private
  6313. * Find the deepest common state between two states. For example:
  6314. *
  6315. * State A
  6316. * State B basedOn A
  6317. * State C basedOn A
  6318. *
  6319. * findCommonBaseState(B, C) returns A
  6320. *
  6321. * If there are no common base states, the root state ("") is returned.
  6322. */
  6323. private function findCommonBaseState(state1:String, state2:String):String
  6324. {
  6325. var firstState:State = getState(state1);
  6326. var secondState:State = getState(state2);
  6327. // Quick exit if either state is the base state
  6328. if (!firstState || !secondState)
  6329. return "";
  6330. // Quick exit if both states are not based on other states
  6331. if (isBaseState(firstState.basedOn) && isBaseState(secondState.basedOn))
  6332. return "";
  6333. // Get the base states for each state and walk from the top
  6334. // down until we find the deepest common base state.
  6335. var firstBaseStates:Array = getBaseStates(firstState);
  6336. var secondBaseStates:Array = getBaseStates(secondState);
  6337. var commonBase:String = "";
  6338. while (firstBaseStates[firstBaseStates.length - 1] ==
  6339. secondBaseStates[secondBaseStates.length - 1])
  6340. {
  6341. commonBase = firstBaseStates.pop();
  6342. secondBaseStates.pop();
  6343. if (!firstBaseStates.length || !secondBaseStates.length)
  6344. break;
  6345. }
  6346. // Finally, check to see if one of the states is directly based on the other.
  6347. if (firstBaseStates.length &&
  6348. firstBaseStates[firstBaseStates.length - 1] == secondState.name)
  6349. {
  6350. commonBase = secondState.name;
  6351. }
  6352. else if (secondBaseStates.length &&
  6353. secondBaseStates[secondBaseStates.length - 1] == firstState.name)
  6354. {
  6355. commonBase = firstState.name;
  6356. }
  6357. return commonBase;
  6358. }
  6359. /**
  6360. * @private
  6361. * Returns the base states for a given state.
  6362. * This Array is in high-to-low order - the first entry
  6363. * is the immediate basedOn state, the last entry is the topmost
  6364. * basedOn state.
  6365. */
  6366. private function getBaseStates(state:State):Array
  6367. {
  6368. var baseStates:Array = [];
  6369. // Push each basedOn name
  6370. while (state && state.basedOn)
  6371. {
  6372. baseStates.push(state.basedOn);
  6373. state = getState(state.basedOn);
  6374. }
  6375. return baseStates;
  6376. }
  6377. /**
  6378. * @private
  6379. * Remove the overrides applied by a state, and any
  6380. * states it is based on.
  6381. */
  6382. private function removeState(stateName:String, lastState:String):void
  6383. {
  6384. var state:State = getState(stateName);
  6385. if (stateName == lastState)
  6386. return;
  6387. // Remove existing state overrides.
  6388. // This must be done in reverse order
  6389. if (state)
  6390. {
  6391. // Dispatch the "exitState" event
  6392. state.dispatchExitState();
  6393. var overrides:Array = state.overrides;
  6394. for (var i:int = overrides.length; i; i--)
  6395. overrides[i-1].remove(this);
  6396. // Remove any basedOn deltas last
  6397. if (state.basedOn != lastState)
  6398. removeState(state.basedOn, lastState);
  6399. }
  6400. }
  6401. /**
  6402. * @private
  6403. * Apply the overrides from a state, and any states it
  6404. * is based on.
  6405. */
  6406. private function applyState(stateName:String, lastState:String):void
  6407. {
  6408. var state:State = getState(stateName);
  6409. if (stateName == lastState)
  6410. return;
  6411. if (state)
  6412. {
  6413. // Apply "basedOn" overrides first
  6414. if (state.basedOn != lastState)
  6415. applyState(state.basedOn, lastState);
  6416. // Apply new state overrides
  6417. var overrides:Array = state.overrides;
  6418. for (var i:int = 0; i < overrides.length; i++)
  6419. overrides[i].apply(this);
  6420. // Dispatch the "enterState" event
  6421. state.dispatchEnterState();
  6422. }
  6423. }
  6424. /**
  6425. * @private
  6426. * Initialize the state, and any states it is based on
  6427. */
  6428. private function initializeState(stateName:String):void
  6429. {
  6430. var state:State = getState(stateName);
  6431. while (state)
  6432. {
  6433. state.initialize();
  6434. state = getState(state.basedOn);
  6435. }
  6436. }
  6437. /**
  6438. * @private
  6439. * Find the appropriate transition to play between two states.
  6440. */
  6441. private function getTransition(oldState:String, newState:String):IEffect
  6442. {
  6443. var result:IEffect = null; // Current candidate
  6444. var priority:int = 0; // Priority fromState toState
  6445. // 1 * *
  6446. // 2 match *
  6447. // 3 * match
  6448. // 4 match match
  6449. if (!transitions)
  6450. return null;
  6451. if (!oldState)
  6452. oldState = "";
  6453. if (!newState)
  6454. newState = "";
  6455. for (var i:int = 0; i < transitions.length; i++)
  6456. {
  6457. var t:Transition = transitions[i];
  6458. if (t.fromState == "*" && t.toState == "*" && priority < 1)
  6459. {
  6460. result = t.effect;
  6461. priority = 1;
  6462. }
  6463. else if (t.fromState == oldState && t.toState == "*" && priority < 2)
  6464. {
  6465. result = t.effect;
  6466. priority = 2;
  6467. }
  6468. else if (t.fromState == "*" && t.toState == newState && priority < 3)
  6469. {
  6470. result = t.effect;
  6471. priority = 3;
  6472. }
  6473. else if (t.fromState == oldState && t.toState == newState && priority < 4)
  6474. {
  6475. result = t.effect;
  6476. priority = 4;
  6477. // Can't get any higher than this, let's go.
  6478. break;
  6479. }
  6480. }
  6481. return result;
  6482. }
  6483. //--------------------------------------------------------------------------
  6484. //
  6485. // Methods: Styling
  6486. //
  6487. //--------------------------------------------------------------------------
  6488. /**
  6489. * @private
  6490. * Sets up the inheritingStyles and nonInheritingStyles objects
  6491. * and their proto chains so that getStyle() can work.
  6492. */
  6493. // Note that initProtoChain is 99% copied into DataGridItemRenderer
  6494. mx_internal function initProtoChain():void
  6495. {
  6496. //trace("initProtoChain", name);
  6497. var classSelector:CSSStyleDeclaration;
  6498. if (styleName)
  6499. {
  6500. if (styleName is CSSStyleDeclaration)
  6501. {
  6502. // Get the style sheet referenced by the styleName property
  6503. classSelector = CSSStyleDeclaration(styleName);
  6504. }
  6505. else if (styleName is IFlexDisplayObject || styleName is IStyleClient)
  6506. {
  6507. // If the styleName property is a UIComponent, then there's a
  6508. // special search path for that case.
  6509. StyleProtoChain.initProtoChainForUIComponentStyleName(this);
  6510. return;
  6511. }
  6512. else if (styleName is String)
  6513. {
  6514. // Get the style sheet referenced by the styleName property
  6515. classSelector =
  6516. StyleManager.getStyleDeclaration("." + styleName);
  6517. }
  6518. }
  6519. // To build the proto chain, we start at the end and work forward.
  6520. // Referring to the list at the top of this function, we'll start by
  6521. // getting the tail of the proto chain, which is:
  6522. // - for non-inheriting styles, the global style sheet
  6523. // - for inheriting styles, my parent's style object
  6524. var nonInheritChain:Object = StyleManager.stylesRoot;
  6525. if (nonInheritChain && nonInheritChain.effects)
  6526. registerEffects(nonInheritChain.effects);
  6527. var p:IStyleClient = parent as IStyleClient;
  6528. if (p)
  6529. {
  6530. var inheritChain:Object = p.inheritingStyles;
  6531. if (inheritChain == UIComponent.STYLE_UNINITIALIZED)
  6532. inheritChain = nonInheritChain;
  6533. }
  6534. else
  6535. {
  6536. // Pop ups inheriting chain starts at Application instead of global.
  6537. // This allows popups to grab styles like themeColor that are
  6538. // set on Application.
  6539. if (isPopUp)
  6540. {
  6541. if (FlexVersion.compatibilityVersion >= FlexVersion.VERSION_3_0 && _owner && _owner is IStyleClient)
  6542. inheritChain = IStyleClient(_owner).inheritingStyles;
  6543. else
  6544. inheritChain = ApplicationGlobals.application.inheritingStyles;
  6545. }
  6546. else
  6547. inheritChain = StyleManager.stylesRoot;
  6548. }
  6549. // Working backwards up the list, the next element in the
  6550. // search path is the type selector
  6551. var typeSelectors:Array = getClassStyleDeclarations();
  6552. var n:int = typeSelectors.length;
  6553. for (var i:int = 0; i < n; i++)
  6554. {
  6555. var typeSelector:CSSStyleDeclaration = typeSelectors[i];
  6556. inheritChain =
  6557. typeSelector.addStyleToProtoChain(inheritChain, this);
  6558. nonInheritChain =
  6559. typeSelector.addStyleToProtoChain(nonInheritChain, this);
  6560. if (typeSelector.effects)
  6561. registerEffects(typeSelector.effects);
  6562. }
  6563. // Next is the class selector
  6564. if (classSelector)
  6565. {
  6566. inheritChain =
  6567. classSelector.addStyleToProtoChain(inheritChain, this);
  6568. nonInheritChain =
  6569. classSelector.addStyleToProtoChain(nonInheritChain, this);
  6570. if (classSelector.effects)
  6571. registerEffects(classSelector.effects);
  6572. }
  6573. // Finally, we'll add the in-line styles
  6574. // to the head of the proto chain.
  6575. inheritingStyles =
  6576. _styleDeclaration ?
  6577. _styleDeclaration.addStyleToProtoChain(inheritChain, this) :
  6578. inheritChain;
  6579. nonInheritingStyles =
  6580. _styleDeclaration ?
  6581. _styleDeclaration.addStyleToProtoChain(nonInheritChain, this) :
  6582. nonInheritChain;
  6583. }
  6584. /**
  6585. * Finds the type selectors for this UIComponent instance.
  6586. * The algorithm walks up the superclass chain.
  6587. * For example, suppose that class MyButton extends Button.
  6588. * A MyButton instance will first look for a MyButton type selector
  6589. * then, it will look for a Button type selector.
  6590. * then, it will look for a UIComponent type selector.
  6591. * (The superclass chain is considered to stop at UIComponent, not Object.)
  6592. *
  6593. * @return An Array of type selectors for this UIComponent instance.
  6594. */
  6595. public function getClassStyleDeclarations():Array
  6596. {
  6597. var myApplicationDomain:ApplicationDomain;
  6598. var factory:IFlexModuleFactory = ModuleManager.getAssociatedFactory(this);
  6599. if (factory != null)
  6600. {
  6601. myApplicationDomain = ApplicationDomain(factory.info()["currentDomain"]);
  6602. }
  6603. else
  6604. {
  6605. var myRoot:DisplayObject = SystemManager.getSWFRoot(this);
  6606. if (!myRoot)
  6607. return [];
  6608. myApplicationDomain = myRoot.loaderInfo.applicationDomain;
  6609. }
  6610. var className:String = getQualifiedClassName(this)
  6611. className = className.replace("::", ".");
  6612. var cache:Array;
  6613. cache = StyleManager.typeSelectorCache[className];
  6614. if (cache)
  6615. return cache;
  6616. // trace("getClassStyleDeclaration", className);
  6617. var decls:Array = [];
  6618. var classNames:Array = [];
  6619. var caches:Array = [];
  6620. var declcache:Array = [];
  6621. while (className != null &&
  6622. className != "mx.core.UIComponent" &&
  6623. className != "mx.core.UITextField")
  6624. {
  6625. var s:CSSStyleDeclaration;
  6626. cache = StyleManager.typeSelectorCache[className];
  6627. if (cache)
  6628. {
  6629. decls = decls.concat(cache);
  6630. break;
  6631. }
  6632. s = StyleManager.getStyleDeclaration(className);
  6633. if (s)
  6634. {
  6635. decls.unshift(s);
  6636. // we found one so the next set define the selectors for this
  6637. // found class and its ancestors. Save the old list and start
  6638. // a new list
  6639. classNames.push(className);
  6640. caches.push(classNames);
  6641. declcache.push(decls);
  6642. decls = [];
  6643. classNames = [];
  6644. // trace(" ", className);
  6645. // break;
  6646. }
  6647. else
  6648. classNames.push(className);
  6649. try
  6650. {
  6651. className = getQualifiedSuperclassName(myApplicationDomain.getDefinition(className));
  6652. className = className.replace("::", ".");
  6653. }
  6654. catch(e:ReferenceError)
  6655. {
  6656. className = null;
  6657. }
  6658. }
  6659. caches.push(classNames);
  6660. declcache.push(decls);
  6661. decls = [];
  6662. while (caches.length)
  6663. {
  6664. classNames = caches.pop();
  6665. decls = decls.concat(declcache.pop());
  6666. while (classNames.length)
  6667. {
  6668. StyleManager.typeSelectorCache[classNames.pop()] = decls;
  6669. }
  6670. }
  6671. return decls;
  6672. }
  6673. /**
  6674. * Builds or rebuilds the CSS style cache for this component
  6675. * and, if the <code>recursive</code> parameter is <code>true</code>,
  6676. * for all descendants of this component as well.
  6677. *
  6678. * <p>The Flex framework calls this method in the following
  6679. * situations:</p>
  6680. *
  6681. * <ul>
  6682. * <li>When you add a UIComponent to a parent using the
  6683. * <code>addChild()</code> or <code>addChildAt()</code> methods.</li>
  6684. * <li>When you change the <code>styleName</code> property
  6685. * of a UIComponent.</li>
  6686. * <li>When you set a style in a CSS selector using the
  6687. * <code>setStyle()</code> method of CSSStyleDeclaration.</li>
  6688. * </ul>
  6689. *
  6690. * <p>Building the style cache is a computation-intensive operation,
  6691. * so you should avoid changing <code>styleName</code> or
  6692. * setting selector styles unnecessarily.</p>
  6693. *
  6694. * <p>This method is not called when you set an instance style
  6695. * by calling the <code>setStyle()</code> method of UIComponent.
  6696. * Setting an instance style is a relatively fast operation
  6697. * compared with setting a selector style.</p>
  6698. *
  6699. * <p>You should not need to call or override this method.</p>
  6700. *
  6701. * @param recursive Recursivly regenerates the style cache for
  6702. * all children of this component.
  6703. */
  6704. public function regenerateStyleCache(recursive:Boolean):void
  6705. {
  6706. // Regenerate the proto chain for this object
  6707. initProtoChain();
  6708. var childList:IChildList =
  6709. this is IRawChildrenContainer ?
  6710. IRawChildrenContainer(this).rawChildren :
  6711. IChildList(this);
  6712. // Recursively call this method on each child.
  6713. var n:int = childList.numChildren;
  6714. for (var i:int = 0; i < n; i++)
  6715. {
  6716. var child:DisplayObject = childList.getChildAt(i);
  6717. if (child is IStyleClient)
  6718. {
  6719. // Does this object already have a proto chain?
  6720. // If not, there's no need to regenerate a new one.
  6721. if (IStyleClient(child).inheritingStyles !=
  6722. UIComponent.STYLE_UNINITIALIZED)
  6723. {
  6724. IStyleClient(child).regenerateStyleCache(recursive);
  6725. }
  6726. }
  6727. else if (child is IUITextField)
  6728. {
  6729. // Does this object already have a proto chain?
  6730. // If not, there's no need to regenerate a new one.
  6731. if (IUITextField(child).inheritingStyles)
  6732. StyleProtoChain.initTextField(IUITextField(child));
  6733. }
  6734. }
  6735. }
  6736. /**
  6737. * Gets a style property that has been set anywhere in this
  6738. * component's style lookup chain.
  6739. *
  6740. * <p>This same method is used to get any kind of style property,
  6741. * so the value returned may be a Boolean, String, Number, int,
  6742. * uint (for an RGB color), Class (for a skin), or any kind of object.
  6743. * Therefore the return type is simply specified as ~~.</p>
  6744. *
  6745. * <p>If you are getting a particular style property, you will
  6746. * know its type and will often want to store the result in a
  6747. * variable of that type.
  6748. * No casting from ~~ to that type is necessary.</p>
  6749. *
  6750. * <p>
  6751. * <code>
  6752. * var backgroundColor:uint = getStyle("backgroundColor");
  6753. * </code>
  6754. * </p>
  6755. *
  6756. * <p>If the style property has not been set anywhere in the
  6757. * style lookup chain, the value returned by <code>getStyle()</code>
  6758. * will be <code>undefined</code>.
  6759. * Note that <code>undefined</code> is a special value that is
  6760. * not the same as <code>false</code>, <code>""</code>,
  6761. * <code>NaN</code>, <code>0</code>, or <code>null</code>.
  6762. * No valid style value is ever <code>undefined</code>.
  6763. * You can use the static method
  6764. * <code>StyleManager.isValidStyleValue()</code>
  6765. * to test whether the value was set.</p>
  6766. *
  6767. * @param styleProp Name of the style property.
  6768. *
  6769. * @return Style value.
  6770. */
  6771. public function getStyle(styleProp:String):*
  6772. {
  6773. return StyleManager.inheritingStyles[styleProp] ?
  6774. _inheritingStyles[styleProp] :
  6775. _nonInheritingStyles[styleProp];
  6776. }
  6777. /**
  6778. * Sets a style property on this component instance.
  6779. *
  6780. * <p>This may override a style that was set globally.</p>
  6781. *
  6782. * <p>Calling the <code>setStyle()</code> method can result in decreased performance.
  6783. * Use it only when necessary.</p>
  6784. *
  6785. * @param styleProp Name of the style property.
  6786. *
  6787. * @param newValue New value for the style.
  6788. */
  6789. public function setStyle(styleProp:String, newValue:*):void
  6790. {
  6791. if (styleProp == "styleName")
  6792. {
  6793. // Let the setter handle this one, see UIComponent.
  6794. styleName = newValue;
  6795. // Short circuit, because styleName isn't really a style.
  6796. return;
  6797. }
  6798. if (EffectManager.getEventForEffectTrigger(styleProp) != "")
  6799. EffectManager.setStyle(styleProp,this);
  6800. /*
  6801. if (StyleManager.isEffectStyle(styleProp))
  6802. EffectManager.setStyle(styleProp,this);
  6803. */
  6804. // If this UIComponent didn't previously have any inline styles,
  6805. // then regenerate the UIComponent's proto chain (and the proto chains
  6806. // of this UIComponent's descendants).
  6807. var isInheritingStyle:Boolean =
  6808. StyleManager.isInheritingStyle(styleProp);
  6809. var isProtoChainInitialized:Boolean =
  6810. inheritingStyles != UIComponent.STYLE_UNINITIALIZED;
  6811. var valueChanged:Boolean = getStyle(styleProp) != newValue;
  6812. if (!_styleDeclaration)
  6813. {
  6814. _styleDeclaration = new CSSStyleDeclaration();
  6815. _styleDeclaration.mx_internal::setStyle(styleProp, newValue);
  6816. // If inheritingStyles is undefined, then this object is being
  6817. // initialized and we haven't yet generated the proto chain. To
  6818. // avoid redundant work, don't bother to create the proto chain here.
  6819. if (isProtoChainInitialized)
  6820. regenerateStyleCache(isInheritingStyle);
  6821. }
  6822. else
  6823. {
  6824. _styleDeclaration.mx_internal::setStyle(styleProp, newValue);
  6825. }
  6826. if (isProtoChainInitialized && valueChanged)
  6827. {
  6828. styleChanged(styleProp);
  6829. notifyStyleChangeInChildren(styleProp, isInheritingStyle);
  6830. }
  6831. }
  6832. /**
  6833. * Deletes a style property from this component instance.
  6834. *
  6835. * <p>This does not necessarily cause the <code>getStyle()</code> method
  6836. * to return <code>undefined</code>.</p>
  6837. *
  6838. * @param styleProp The name of the style property.
  6839. */
  6840. public function clearStyle(styleProp:String):void
  6841. {
  6842. setStyle(styleProp, undefined);
  6843. }
  6844. /**
  6845. * Propagates style changes to the children.
  6846. * You typically never need to call this method.
  6847. *
  6848. * @param styleProp String specifying the name of the style property.
  6849. *
  6850. * @param recursive Recursivly notify all children of this component.
  6851. */
  6852. public function notifyStyleChangeInChildren(
  6853. styleProp:String, recursive:Boolean):void
  6854. {
  6855. cachedTextFormat = null;
  6856. var n:int = numChildren;
  6857. for (var i:int = 0; i < n; i++)
  6858. {
  6859. var child:ISimpleStyleClient = getChildAt(i) as ISimpleStyleClient;
  6860. if (child)
  6861. {
  6862. child.styleChanged(styleProp);
  6863. // Always recursively call this function because of my
  6864. // descendants might have a styleName property that points
  6865. // to this object. The recursive flag is respected in
  6866. // Container.notifyStyleChangeInChildren.
  6867. if (child is IStyleClient)
  6868. IStyleClient(child).notifyStyleChangeInChildren(styleProp, recursive);
  6869. }
  6870. }
  6871. }
  6872. /**
  6873. * @private
  6874. * If this object has a themeColor style, which is not inherited,
  6875. * then set it inline.
  6876. */
  6877. mx_internal function initThemeColor():Boolean
  6878. {
  6879. var styleName:Object /* String or UIComponent */ = _styleName;
  6880. var tc:Object; // Can be number or string
  6881. var rc:Number;
  6882. var sc:Number;
  6883. // First look for locally-declared styles
  6884. if (_styleDeclaration)
  6885. {
  6886. tc = _styleDeclaration.getStyle("themeColor");
  6887. rc = _styleDeclaration.getStyle("rollOverColor");
  6888. sc = _styleDeclaration.getStyle("selectionColor");
  6889. }
  6890. // Next look for class selectors
  6891. if ((tc === null || !StyleManager.isValidStyleValue(tc)) &&
  6892. (styleName && !(styleName is ISimpleStyleClient)))
  6893. {
  6894. var classSelector:Object =
  6895. styleName is String ?
  6896. StyleManager.getStyleDeclaration("." + styleName) :
  6897. styleName;
  6898. if (classSelector)
  6899. {
  6900. tc = classSelector.getStyle("themeColor");
  6901. rc = classSelector.getStyle("rollOverColor");
  6902. sc = classSelector.getStyle("selectionColor");
  6903. }
  6904. }
  6905. // Finally look for type selectors
  6906. if (tc === null || !StyleManager.isValidStyleValue(tc))
  6907. {
  6908. var typeSelectors:Array = getClassStyleDeclarations();
  6909. for (var i:int = 0; i < typeSelectors.length; i++)
  6910. {
  6911. var typeSelector:CSSStyleDeclaration = typeSelectors[i];
  6912. if (typeSelector)
  6913. {
  6914. tc = typeSelector.getStyle("themeColor");
  6915. rc = typeSelector.getStyle("rollOverColor");
  6916. sc = typeSelector.getStyle("selectionColor");
  6917. }
  6918. if (tc !== null && StyleManager.isValidStyleValue(tc))
  6919. break;
  6920. }
  6921. }
  6922. // If we have a themeColor but no rollOverColor or selectionColor, call
  6923. // setThemeColor here which will calculate rollOver/selectionColor based
  6924. // on the themeColor.
  6925. if (tc !== null && StyleManager.isValidStyleValue(tc) && isNaN(rc) && isNaN(sc))
  6926. {
  6927. setThemeColor(tc);
  6928. return true;
  6929. }
  6930. return (tc !== null && StyleManager.isValidStyleValue(tc)) && !isNaN(rc) && !isNaN(sc);
  6931. }
  6932. /**
  6933. * @private
  6934. * Calculate and set new roll over and selection colors based on theme color.
  6935. */
  6936. mx_internal function setThemeColor(value:Object /* Number or String */):void
  6937. {
  6938. var newValue:Number;
  6939. if (newValue is String)
  6940. newValue = parseInt(String(value));
  6941. else
  6942. newValue = Number(value);
  6943. if (isNaN(newValue))
  6944. newValue = StyleManager.getColorName(value);
  6945. var newValueS:Number = ColorUtil.adjustBrightness2(newValue, 50);
  6946. var newValueR:Number = ColorUtil.adjustBrightness2(newValue, 70);
  6947. setStyle("selectionColor", newValueS);
  6948. setStyle("rollOverColor", newValueR);
  6949. }
  6950. /**
  6951. * Returns a UITextFormat object corresponding to the text styles
  6952. * for this UIComponent.
  6953. *
  6954. * @return UITextFormat object corresponding to the text styles
  6955. * for this UIComponent.
  6956. */
  6957. public function determineTextFormatFromStyles():UITextFormat
  6958. {
  6959. var textFormat:UITextFormat = cachedTextFormat;
  6960. if (!textFormat)
  6961. {
  6962. var font:String =
  6963. StringUtil.trimArrayElements(_inheritingStyles.fontFamily, ",");
  6964. textFormat = new UITextFormat(getNonNullSystemManager(), font);
  6965. textFormat.moduleFactory = moduleFactory;
  6966. textFormat.align = _inheritingStyles.textAlign;
  6967. textFormat.bold = _inheritingStyles.fontWeight == "bold";
  6968. textFormat.color = enabled ?
  6969. _inheritingStyles.color :
  6970. _inheritingStyles.disabledColor;
  6971. textFormat.font = font;
  6972. textFormat.indent = _inheritingStyles.textIndent;
  6973. textFormat.italic = _inheritingStyles.fontStyle == "italic";
  6974. textFormat.kerning = _inheritingStyles.kerning;
  6975. textFormat.leading = _nonInheritingStyles.leading;
  6976. textFormat.leftMargin = _nonInheritingStyles.paddingLeft;
  6977. textFormat.letterSpacing = _inheritingStyles.letterSpacing;
  6978. textFormat.rightMargin = _nonInheritingStyles.paddingRight;
  6979. textFormat.size = _inheritingStyles.fontSize;
  6980. textFormat.underline =
  6981. _nonInheritingStyles.textDecoration == "underline";
  6982. textFormat.antiAliasType = _inheritingStyles.fontAntiAliasType;
  6983. textFormat.gridFitType = _inheritingStyles.fontGridFitType;
  6984. textFormat.sharpness = _inheritingStyles.fontSharpness;
  6985. textFormat.thickness = _inheritingStyles.fontThickness;
  6986. cachedTextFormat = textFormat;
  6987. }
  6988. return textFormat;
  6989. }
  6990. //--------------------------------------------------------------------------
  6991. //
  6992. // Methods: Binding
  6993. //
  6994. //--------------------------------------------------------------------------
  6995. /**
  6996. * Executes the data bindings into this UIComponent object.
  6997. *
  6998. * Workaround for MXML container/bindings problem (177074):
  6999. * override Container.executeBindings() to prefer descriptor.document over parentDocument in the
  7000. * call to BindingManager.executeBindings().
  7001. *
  7002. * This should always provide the correct behavior for instances created by descriptor, and will
  7003. * provide the original behavior for procedurally-created instances. (The bug may or may not appear
  7004. * in the latter case.)
  7005. *
  7006. * A more complete fix, guaranteeing correct behavior in both non-DI and reparented-component
  7007. * scenarios, is anticipated for updater 1.
  7008. *
  7009. * @param recurse Recursively execute bindings for children of this component.
  7010. */
  7011. public function executeBindings(recurse:Boolean = false):void
  7012. {
  7013. var bindingsHost:Object = descriptor && descriptor.document ? descriptor.document : parentDocument;
  7014. BindingManager.executeBindings(bindingsHost, id, this);
  7015. }
  7016. //--------------------------------------------------------------------------
  7017. //
  7018. // Methods: Effects
  7019. //
  7020. //--------------------------------------------------------------------------
  7021. /**
  7022. * For each effect event, registers the EffectManager
  7023. * as one of the event listeners.
  7024. * You typically never need to call this method.
  7025. *
  7026. * @param effects The names of the effect events.
  7027. */
  7028. public function registerEffects(effects:Array /* of String */):void
  7029. {
  7030. var n:int = effects.length;
  7031. for (var i:int = 0; i < n; i++)
  7032. {
  7033. // Ask the EffectManager for the event associated with this effectTrigger
  7034. var event:String = EffectManager.getEventForEffectTrigger(effects[i]);
  7035. if (event != null && event != "")
  7036. {
  7037. addEventListener(event, EffectManager.eventHandler,
  7038. false, EventPriority.EFFECT);
  7039. }
  7040. }
  7041. }
  7042. /**
  7043. * @private
  7044. *
  7045. * Adds an overlay object that's always on top of our children.
  7046. * Calls createOverlay(), which returns the overlay object.
  7047. * Currently used by the Dissolve and Resize effects.
  7048. *
  7049. * Returns the overlay object.
  7050. */
  7051. mx_internal function addOverlay(color:uint,
  7052. targetArea:RoundedRectangle = null):void
  7053. {
  7054. if (!overlay)
  7055. {
  7056. overlayColor = color;
  7057. overlay = new UIComponent();
  7058. overlay.name = "overlay";
  7059. // Have to set visibility immediately
  7060. // to make sure we avoid flicker
  7061. overlay.$visible = true;
  7062. fillOverlay(overlay, color, targetArea);
  7063. attachOverlay();
  7064. if (!targetArea)
  7065. addEventListener(ResizeEvent.RESIZE, overlay_resizeHandler);
  7066. overlay.x = 0;
  7067. overlay.y = 0;
  7068. invalidateDisplayList();
  7069. overlayReferenceCount = 1;
  7070. }
  7071. else
  7072. {
  7073. overlayReferenceCount++;
  7074. }
  7075. dispatchEvent(new ChildExistenceChangedEvent(ChildExistenceChangedEvent.OVERLAY_CREATED, true, false, overlay));
  7076. }
  7077. /**
  7078. * This is an internal method used by the Flex framework
  7079. * to support the Dissolve effect.
  7080. * You should not need to call it or override it.
  7081. */
  7082. protected function attachOverlay():void
  7083. {
  7084. addChild(overlay);
  7085. }
  7086. /**
  7087. * @private
  7088. * Fill an overlay object which is always the topmost child.
  7089. * Used by the Dissolve effect.
  7090. * Never call this function directly.
  7091. * It is called internally by addOverlay().
  7092. *
  7093. * The overlay object is filled with a solid rectangle that has the
  7094. * same width and height as the component.
  7095. */
  7096. mx_internal function fillOverlay(overlay:UIComponent, color:uint,
  7097. targetArea:RoundedRectangle = null):void
  7098. {
  7099. if (!targetArea)
  7100. targetArea = new RoundedRectangle(0, 0, unscaledWidth, unscaledHeight, 0);
  7101. var g:Graphics = overlay.graphics;
  7102. g.clear();
  7103. g.beginFill(color);
  7104. g.drawRoundRect(targetArea.x, targetArea.y,
  7105. targetArea.width, targetArea.height,
  7106. targetArea.cornerRadius * 2,
  7107. targetArea.cornerRadius * 2);
  7108. g.endFill();
  7109. }
  7110. /**
  7111. * @private
  7112. * Removes the overlay object added by addOverlay().
  7113. */
  7114. mx_internal function removeOverlay():void
  7115. {
  7116. if (overlayReferenceCount > 0 && --overlayReferenceCount == 0 && overlay)
  7117. {
  7118. removeEventListener("resize", overlay_resizeHandler);
  7119. if (super.getChildByName("overlay"))
  7120. $removeChild(overlay);
  7121. overlay = null;
  7122. }
  7123. }
  7124. /**
  7125. * @private
  7126. * Resize the overlay when the components size changes
  7127. *
  7128. */
  7129. private function overlay_resizeHandler(event:Event):void
  7130. {
  7131. fillOverlay(overlay, overlayColor, null);
  7132. }
  7133. /**
  7134. * @private
  7135. */
  7136. mx_internal var _effectsStarted:Array = [];
  7137. /**
  7138. * @private
  7139. */
  7140. mx_internal var _affectedProperties:Object = {};
  7141. /**
  7142. * Contains <code>true</code> if an effect is currently playing on the component.
  7143. */
  7144. private var _isEffectStarted:Boolean = false;
  7145. mx_internal function get isEffectStarted():Boolean
  7146. {
  7147. return _isEffectStarted;
  7148. }
  7149. mx_internal function set isEffectStarted(value:Boolean):void
  7150. {
  7151. _isEffectStarted = value;
  7152. }
  7153. private var preventDrawFocus:Boolean = false;
  7154. /**
  7155. * Called by the effect instance when it starts playing on the component.
  7156. * You can use this method to perform a modification to the component as part
  7157. * of an effect. You can use the <code>effectFinished()</code> method
  7158. * to restore the modification when the effect ends.
  7159. *
  7160. * @param effectInst The effect instance object playing on the component.
  7161. */
  7162. public function effectStarted(effectInst:IEffectInstance):void
  7163. {
  7164. // Check that the instance isn't already in our list
  7165. _effectsStarted.push(effectInst);
  7166. var aProps:Array = effectInst.effect.getAffectedProperties();
  7167. for (var j:int = 0; j < aProps.length; j++)
  7168. {
  7169. var propName:String = aProps[j];
  7170. if (_affectedProperties[propName] == undefined)
  7171. {
  7172. _affectedProperties[propName] = [];
  7173. }
  7174. _affectedProperties[propName].push(effectInst);
  7175. }
  7176. isEffectStarted = true;
  7177. // Hide the focus ring if the target already has one drawn
  7178. if (effectInst.hideFocusRing)
  7179. {
  7180. preventDrawFocus = true;
  7181. drawFocus(false);
  7182. }
  7183. }
  7184. private var _endingEffectInstances:Array = [];
  7185. /**
  7186. * Called by the effect instance when it stops playing on the component.
  7187. * You can use this method to restore a modification to the component made
  7188. * by the <code>effectStarted()</code> method when the effect started,
  7189. * or perform some other action when the effect ends.
  7190. *
  7191. * @param effectInst The effect instance object playing on the component.
  7192. */
  7193. public function effectFinished(effectInst:IEffectInstance):void
  7194. {
  7195. _endingEffectInstances.push(effectInst);
  7196. invalidateProperties();
  7197. // weak reference
  7198. UIComponentGlobals.layoutManager.addEventListener(
  7199. FlexEvent.UPDATE_COMPLETE, updateCompleteHandler, false, 0, true);
  7200. }
  7201. /**
  7202. * Ends all currently playing effects on the component.
  7203. */
  7204. public function endEffectsStarted():void
  7205. {
  7206. var len:int = _effectsStarted.length;
  7207. for (var i:int = 0; i < len; i++)
  7208. {
  7209. _effectsStarted[i].end();
  7210. }
  7211. }
  7212. /**
  7213. * @private
  7214. */
  7215. private function updateCompleteHandler(event:FlexEvent):void
  7216. {
  7217. UIComponentGlobals.layoutManager.removeEventListener(
  7218. FlexEvent.UPDATE_COMPLETE, updateCompleteHandler);
  7219. processEffectFinished(_endingEffectInstances);
  7220. _endingEffectInstances = [];
  7221. }
  7222. /**
  7223. * @private
  7224. */
  7225. private function processEffectFinished(effectInsts:Array):void
  7226. {
  7227. // Find the instance in our list.
  7228. for (var i:int = _effectsStarted.length - 1; i >= 0; i--)
  7229. {
  7230. for (var j:int = 0; j < effectInsts.length; j++)
  7231. {
  7232. var effectInst:IEffectInstance = effectInsts[j];
  7233. if (effectInst == _effectsStarted[i])
  7234. {
  7235. // Remove the effect from our array.
  7236. var removedInst:IEffectInstance = _effectsStarted[i];
  7237. _effectsStarted.splice(i, 1);
  7238. // Remove the affected properties from our internal object
  7239. var aProps:Array = removedInst.effect.getAffectedProperties();
  7240. for (var k:int = 0; k < aProps.length; k++)
  7241. {
  7242. var propName:String = aProps[k];
  7243. if (_affectedProperties[propName] != undefined)
  7244. {
  7245. for (var l:int = 0; l < _affectedProperties[propName].length; l++)
  7246. {
  7247. if (_affectedProperties[propName][l] == effectInst)
  7248. {
  7249. _affectedProperties[propName].splice(l, 1);
  7250. break;
  7251. }
  7252. }
  7253. if (_affectedProperties[propName].length == 0)
  7254. delete _affectedProperties[propName];
  7255. }
  7256. }
  7257. break;
  7258. }
  7259. }
  7260. }
  7261. isEffectStarted = _effectsStarted.length > 0 ? true : false;
  7262. if (effectInst && effectInst.hideFocusRing)
  7263. {
  7264. preventDrawFocus = false;
  7265. }
  7266. }
  7267. /**
  7268. * @private
  7269. */
  7270. mx_internal function getEffectsForProperty(propertyName:String):Array
  7271. {
  7272. return _affectedProperties[propertyName] != undefined ?
  7273. _affectedProperties[propertyName] :
  7274. [];
  7275. }
  7276. //--------------------------------------------------------------------------
  7277. //
  7278. // Methods: Repeater
  7279. //
  7280. //--------------------------------------------------------------------------
  7281. /**
  7282. * @inheritDoc
  7283. */
  7284. public function createReferenceOnParentDocument(
  7285. parentDocument:IFlexDisplayObject):void
  7286. {
  7287. if (id && id != "")
  7288. {
  7289. var indices:Array = _instanceIndices;
  7290. if (!indices)
  7291. {
  7292. parentDocument[id] = this;
  7293. }
  7294. else
  7295. {
  7296. var r:Object = parentDocument[id];
  7297. if (! (r is Array))
  7298. {
  7299. r = parentDocument[id] = [];
  7300. }
  7301. var n:int = indices.length;
  7302. for (var i:int = 0; i < n - 1; i++)
  7303. {
  7304. var s:Object = r[indices[i]];
  7305. if (!(s is Array))
  7306. s = r[indices[i]] = [];
  7307. r = s;
  7308. }
  7309. r[indices[n - 1]] = this;
  7310. var event:PropertyChangeEvent =
  7311. PropertyChangeEvent.createUpdateEvent(parentDocument,
  7312. id,
  7313. parentDocument[id],
  7314. parentDocument[id]);
  7315. parentDocument.dispatchEvent(event);
  7316. }
  7317. }
  7318. }
  7319. /**
  7320. * @inheritDoc
  7321. */
  7322. public function deleteReferenceOnParentDocument(
  7323. parentDocument:IFlexDisplayObject):void
  7324. {
  7325. if (id && id != "")
  7326. {
  7327. var indices:Array = _instanceIndices;
  7328. if (!indices)
  7329. {
  7330. parentDocument[id] = null;
  7331. }
  7332. else
  7333. {
  7334. var r:Object = parentDocument[id];
  7335. if (!r)
  7336. return;
  7337. var stack:Array = [];
  7338. stack.push(r);
  7339. var n:int = indices.length;
  7340. for (var i:int = 0; i < n - 1; i++)
  7341. {
  7342. var s:Object = r[indices[i]];
  7343. if (!s)
  7344. return;
  7345. r = s;
  7346. stack.push(r);
  7347. }
  7348. r.splice(indices[n - 1], 1);
  7349. for (var j:int = stack.length - 1; j > 0; j--)
  7350. {
  7351. if (stack[j].length == 0)
  7352. stack[j - 1].splice(indices[j], 1);
  7353. }
  7354. if ((stack.length > 0) && (stack[0].length == 0))
  7355. {
  7356. parentDocument[id] = null;
  7357. }
  7358. else
  7359. {
  7360. var event:PropertyChangeEvent =
  7361. PropertyChangeEvent.createUpdateEvent(parentDocument,
  7362. id,
  7363. parentDocument[id],
  7364. parentDocument[id]);
  7365. parentDocument.dispatchEvent(event);
  7366. }
  7367. }
  7368. }
  7369. }
  7370. /**
  7371. * Returns the item in the <code>dataProvider</code> that was used
  7372. * by the specified Repeater to produce this Repeater, or
  7373. * <code>null</code> if this Repeater isn't repeated.
  7374. * The argument <code>whichRepeater</code> is 0 for the outermost
  7375. * Repeater, 1 for the next inner Repeater, and so on.
  7376. * If <code>whichRepeater</code> is not specified,
  7377. * the innermost Repeater is used.
  7378. *
  7379. * @param whichRepeater Number of the Repeater,
  7380. * counting from the outermost one, starting at 0.
  7381. *
  7382. * @return The requested repeater item.
  7383. */
  7384. public function getRepeaterItem(whichRepeater:int = -1):Object
  7385. {
  7386. var repeaterArray:Array = repeaters;
  7387. // If whichRepeater isn't specified, assume the
  7388. // innermost Repeater. This lets authors simply write
  7389. // myRepeater.getRepeaterItem()
  7390. if (whichRepeater == -1)
  7391. whichRepeater = repeaterArray.length - 1;
  7392. return repeaterArray[whichRepeater].
  7393. getItemAt(repeaterIndices[whichRepeater]);
  7394. }
  7395. //--------------------------------------------------------------------------
  7396. //
  7397. // Methods: Resources
  7398. //
  7399. //--------------------------------------------------------------------------
  7400. /**
  7401. * This method is called when a UIComponent is constructed,
  7402. * and again whenever the ResourceManager dispatches
  7403. * a <code>"change"</code> Event to indicate
  7404. * that the localized resources have changed in some way.
  7405. *
  7406. * <p>This event will be dispatched when you set the ResourceManager's
  7407. * <code>localeChain</code> property, when a resource module
  7408. * has finished loading, and when you call the ResourceManager's
  7409. * <code>update()</code> method.</p>
  7410. *
  7411. * <p>Subclasses should override this method and, after calling
  7412. * <code>super.resourcesChanged()</code>, do whatever is appropriate
  7413. * in response to having new resource values.</p>
  7414. */
  7415. protected function resourcesChanged():void
  7416. {
  7417. }
  7418. //--------------------------------------------------------------------------
  7419. //
  7420. // Methods: Printing
  7421. //
  7422. //--------------------------------------------------------------------------
  7423. /**
  7424. * Prepares an IFlexDisplayObject for printing.
  7425. * For the UIComponent class, the method performs no action.
  7426. * Flex containers override the method to prepare for printing;
  7427. * for example, by removing scroll bars from the printed output.
  7428. *
  7429. * <p>This method is normally not used by application developers. </p>
  7430. *
  7431. * @param target The component to be printed.
  7432. * It may be the current component or one of its children.
  7433. *
  7434. * @return Object containing the properties of the current component
  7435. * required by the <code>finishPrint()</code> method
  7436. * to restore it to its previous state.
  7437. *
  7438. * @see mx.printing.FlexPrintJob
  7439. */
  7440. public function prepareToPrint(target:IFlexDisplayObject):Object
  7441. {
  7442. return null;
  7443. }
  7444. /**
  7445. * Called after printing is complete.
  7446. * For the UIComponent class, the method performs no action.
  7447. * Flex containers override the method to restore the container after printing.
  7448. *
  7449. * <p>This method is normally not used by application developers. </p>
  7450. *
  7451. * @param obj Contains the properties of the component that
  7452. * restore it to its state before printing.
  7453. *
  7454. * @param target The component that just finished printing.
  7455. * It may be the current component or one of its children.
  7456. *
  7457. * @see mx.printing.FlexPrintJob
  7458. */
  7459. public function finishPrint(obj:Object, target:IFlexDisplayObject):void
  7460. {
  7461. }
  7462. //--------------------------------------------------------------------------
  7463. //
  7464. // Event handlers: Invalidation
  7465. //
  7466. //--------------------------------------------------------------------------
  7467. /**
  7468. * @private
  7469. * Callback that then calls queued functions.
  7470. */
  7471. private function callLaterDispatcher(event:Event):void
  7472. {
  7473. // trace(">>calllaterdispatcher " + this);
  7474. UIComponentGlobals.callLaterDispatcherCount++;
  7475. // At run-time, callLaterDispatcher2() is called
  7476. // without a surrounding try-catch.
  7477. if (!UIComponentGlobals.catchCallLaterExceptions)
  7478. {
  7479. callLaterDispatcher2(event);
  7480. }
  7481. // At design-time, callLaterDispatcher2() is called
  7482. // with a surrounding try-catch.
  7483. else
  7484. {
  7485. try
  7486. {
  7487. callLaterDispatcher2(event);
  7488. }
  7489. catch(e:Error)
  7490. {
  7491. var callLaterErrorEvent:DynamicEvent = new DynamicEvent("callLaterError");
  7492. callLaterErrorEvent.error = e;
  7493. systemManager.dispatchEvent(callLaterErrorEvent);
  7494. }
  7495. }
  7496. // trace("<<calllaterdispatcher");
  7497. UIComponentGlobals.callLaterDispatcherCount--;
  7498. }
  7499. /**
  7500. * @private
  7501. * Callback that then calls queued functions.
  7502. */
  7503. private function callLaterDispatcher2(event:Event):void
  7504. {
  7505. if (UIComponentGlobals.callLaterSuspendCount > 0)
  7506. return;
  7507. // trace(" >>calllaterdispatcher2");
  7508. var sm:ISystemManager = systemManager;
  7509. // Stage can be null when an untrusted application is loaded by an application
  7510. // that isn't on stage yet.
  7511. if (sm && (sm.stage || sm.useSWFBridge()) && listeningForRender)
  7512. {
  7513. // trace(" removed");
  7514. sm.removeEventListener(FlexEvent.RENDER, callLaterDispatcher);
  7515. sm.removeEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher);
  7516. listeningForRender = false;
  7517. }
  7518. // Move the method queue off to the side, so that subsequent
  7519. // calls to callLater get added to a new queue that'll get handled
  7520. // next time.
  7521. var queue:Array = methodQueue;
  7522. methodQueue = [];
  7523. // Call each method currently in the method queue.
  7524. // These methods can call callLater(), causing additional
  7525. // methods to be queued, but these will get called the next
  7526. // time around.
  7527. var n:int = queue.length;
  7528. // trace(" queue length " + n);
  7529. for (var i:int = 0; i < n; i++)
  7530. {
  7531. var mqe:MethodQueueElement = MethodQueueElement(queue[i]);
  7532. mqe.method.apply(null, mqe.args);
  7533. }
  7534. // trace(" <<calllaterdispatcher2 " + this);
  7535. }
  7536. /**
  7537. * @private
  7538. * Event handler called when creation is complete and we have a pending
  7539. * current state change. We commit the current state change here instead
  7540. * of inside commitProperties since the state may have bindings to children
  7541. * that have not been created yet if we are inside a deferred instantiation
  7542. * container.
  7543. */
  7544. private function creationCompleteHandler(event:FlexEvent):void
  7545. {
  7546. if (_currentStateChanged)
  7547. {
  7548. _currentStateChanged = false;
  7549. commitCurrentState();
  7550. // Need to call validateNow() to avoid screen flicker. This handler
  7551. // is called immediately before the component is displayed, and
  7552. // changing states takes a frame to commit the changes, which
  7553. // results in the base state flashing quickly on the screen before
  7554. // the desired state is entered.
  7555. validateNow();
  7556. }
  7557. removeEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
  7558. }
  7559. //--------------------------------------------------------------------------
  7560. //
  7561. // Event handlers: Keyboard
  7562. //
  7563. //--------------------------------------------------------------------------
  7564. /**
  7565. * The event handler called for a <code>keyDown</code> event.
  7566. * If you override this method, make sure to call the base class version.
  7567. *
  7568. * @param event The event object.
  7569. */
  7570. protected function keyDownHandler(event:KeyboardEvent):void
  7571. {
  7572. // You must override this function if your component accepts focus
  7573. }
  7574. /**
  7575. * The event handler called for a <code>keyUp</code> event.
  7576. * If you override this method, make sure to call the base class version.
  7577. *
  7578. * @param event The event object.
  7579. */
  7580. protected function keyUpHandler(event:KeyboardEvent):void
  7581. {
  7582. // You must override this function if your component accepts focus
  7583. }
  7584. /**
  7585. * Typically overridden by components containing UITextField objects,
  7586. * where the UITextField object gets focus.
  7587. *
  7588. * @param target A UIComponent object containing a UITextField object
  7589. * that can receive focus.
  7590. *
  7591. * @return Returns <code>true</code> if the UITextField object has focus.
  7592. */
  7593. protected function isOurFocus(target:DisplayObject):Boolean
  7594. {
  7595. return target == this;
  7596. }
  7597. /**
  7598. * The event handler called when a UIComponent object gets focus.
  7599. * If you override this method, make sure to call the base class version.
  7600. *
  7601. * @param event The event object.
  7602. */
  7603. protected function focusInHandler(event:FocusEvent):void
  7604. {
  7605. if (isOurFocus(DisplayObject(event.target)))
  7606. {
  7607. var fm:IFocusManager = focusManager;
  7608. if (fm && fm.showFocusIndicator)
  7609. drawFocus(true);
  7610. ContainerGlobals.checkFocus(event.relatedObject, this);
  7611. }
  7612. }
  7613. /**
  7614. * The event handler called when a UIComponent object loses focus.
  7615. * If you override this method, make sure to call the base class version.
  7616. *
  7617. * @param event The event object.
  7618. */
  7619. protected function focusOutHandler(event:FocusEvent):void
  7620. {
  7621. // We don't need to remove our event listeners here because we
  7622. // won't receive keyboard events.
  7623. if (isOurFocus(DisplayObject(event.target)))
  7624. drawFocus(false);
  7625. }
  7626. /**
  7627. * @private
  7628. * The player dispatches an "added" event when the addChild()
  7629. * or addChildAt() method of DisplayObjectContainer is called,
  7630. * but handling this event at that time can be dangerous
  7631. * so we prevent the event dispatched then from propagating;
  7632. * we'll dispatch another "added" event later when it is safe.
  7633. * The reason the timing of this player event is dangerous
  7634. * is that the Flex framework overrides addChild() and addChildAt(),
  7635. * to perform important additional work after calling the super
  7636. * method, such as setting _parent to skip over the contentPane
  7637. * of a Container. So if an "added" handler executes too early,
  7638. * the child is in an inconsistent state. (For example, its
  7639. * toString() can be wrong because the contentPane is wrongly
  7640. * included when traversing the parent chain.) Our overrides
  7641. * delay dispatching the "added" event until the end of the
  7642. * override, as opposed to in the middle when super.addChild()
  7643. * is called.
  7644. * Note: This event handler is registered by the UIComponent
  7645. * constructor, which means it is registered before any
  7646. * other handlers for an "added" event.
  7647. * Therefore it can prevent all others from being called.
  7648. */
  7649. private function addedHandler(event:Event):void
  7650. {
  7651. //reset systemManager in case we've been reparented to a new Window.
  7652. //systemManager will be set on get systemManager()
  7653. if (event.eventPhase != EventPhase.AT_TARGET)
  7654. return;
  7655. try
  7656. {
  7657. if (parent is IContainer && IContainer(parent).creatingContentPane)
  7658. {
  7659. event.stopImmediatePropagation();
  7660. return;
  7661. }
  7662. }
  7663. catch (error:SecurityError)
  7664. {
  7665. }
  7666. }
  7667. /**
  7668. * @private
  7669. * See the comments for addedHandler() above.
  7670. */
  7671. private function removedHandler(event:Event):void
  7672. {
  7673. if (event.eventPhase != EventPhase.AT_TARGET)
  7674. return;
  7675. try
  7676. {
  7677. if (parent is IContainer && IContainer(parent).creatingContentPane)
  7678. {
  7679. event.stopImmediatePropagation();
  7680. return;
  7681. }
  7682. }
  7683. catch (error:SecurityError)
  7684. {
  7685. }
  7686. _systemManagerDirty = true;
  7687. }
  7688. /**
  7689. * @private
  7690. * There is a bug (139390) where setting focus from within callLaterDispatcher
  7691. * screws up the ActiveX player. We defer focus until enterframe.
  7692. */
  7693. private function setFocusLater(event:Event = null):void
  7694. {
  7695. var sm:ISystemManager = systemManager;
  7696. if (sm && sm.stage)
  7697. {
  7698. sm.stage.removeEventListener(Event.ENTER_FRAME, setFocusLater);
  7699. if (UIComponentGlobals.nextFocusObject)
  7700. sm.stage.focus = UIComponentGlobals.nextFocusObject;
  7701. UIComponentGlobals.nextFocusObject = null;
  7702. }
  7703. }
  7704. /**
  7705. * @private
  7706. * Called when this component moves. Adjust the focus rect.
  7707. */
  7708. private function focusObj_scrollHandler(event:Event):void
  7709. {
  7710. adjustFocusRect();
  7711. }
  7712. /**
  7713. * @private
  7714. * Called when this component moves. Adjust the focus rect.
  7715. */
  7716. private function focusObj_moveHandler(event:MoveEvent):void
  7717. {
  7718. adjustFocusRect();
  7719. }
  7720. /**
  7721. * @private
  7722. * Called when this component resizes. Adjust the focus rect.
  7723. */
  7724. private function focusObj_resizeHandler(event:ResizeEvent):void
  7725. {
  7726. adjustFocusRect();
  7727. }
  7728. /**
  7729. * @private
  7730. * Called when this component is unloaded. Hide the focus rect.
  7731. */
  7732. private function focusObj_removedHandler(event:Event):void
  7733. {
  7734. // ignore if we captured on a child
  7735. if (event.target != this)
  7736. return;
  7737. var focusObject:DisplayObject = getFocusObject();
  7738. if (focusObject)
  7739. focusObject.visible = false;
  7740. }
  7741. //--------------------------------------------------------------------------
  7742. //
  7743. // Event handlers: Validation
  7744. //
  7745. //--------------------------------------------------------------------------
  7746. /**
  7747. * Handles both the <code>valid</code> and <code>invalid</code> events from a
  7748. * validator assigned to this component.
  7749. *
  7750. * <p>You typically handle the <code>valid</code> and <code>invalid</code> events
  7751. * dispatched by a validator by assigning event listeners to the validators.
  7752. * If you want to handle validation events directly in the component that is being validated,
  7753. * you can override this method to handle the <code>valid</code>
  7754. * and <code>invalid</code> events. You typically call
  7755. * <code>super.validationResultHandler(event)</code> in your override.</p>
  7756. *
  7757. * @param event The event object for the validation.
  7758. *
  7759. * @see mx.events.ValidationResultEvent
  7760. */
  7761. public function validationResultHandler(event:ValidationResultEvent):void
  7762. {
  7763. // If we are valid, then clear the error string
  7764. if (event.type == ValidationResultEvent.VALID)
  7765. {
  7766. if (errorString != "")
  7767. {
  7768. errorString = "";
  7769. dispatchEvent(new FlexEvent(FlexEvent.VALID));
  7770. }
  7771. }
  7772. else // If we get an invalid event
  7773. {
  7774. var msg:String;
  7775. var result:ValidationResult;
  7776. // We are associated with a subfield
  7777. if (validationSubField != null && validationSubField != "" && event.results)
  7778. {
  7779. for (var i:int = 0; i < event.results.length; i++)
  7780. {
  7781. result = event.results[i];
  7782. // Find the result that is meant for us
  7783. if (result.subField == validationSubField)
  7784. {
  7785. if (result.isError)
  7786. {
  7787. msg = result.errorMessage;
  7788. }
  7789. else
  7790. {
  7791. if (errorString != "")
  7792. {
  7793. errorString = "";
  7794. dispatchEvent(new FlexEvent(FlexEvent.VALID));
  7795. }
  7796. }
  7797. break;
  7798. }
  7799. }
  7800. }
  7801. else if (event.results && event.results.length > 0)
  7802. {
  7803. msg = event.results[0].errorMessage;
  7804. }
  7805. if (msg && errorString != msg)
  7806. {
  7807. errorString = msg;
  7808. dispatchEvent(new FlexEvent(FlexEvent.INVALID));
  7809. }
  7810. }
  7811. }
  7812. //--------------------------------------------------------------------------
  7813. //
  7814. // Event handlers: Resources
  7815. //
  7816. //--------------------------------------------------------------------------
  7817. /**
  7818. * @private
  7819. */
  7820. private function resourceManager_changeHandler(event:Event):void
  7821. {
  7822. resourcesChanged();
  7823. }
  7824. //--------------------------------------------------------------------------
  7825. //
  7826. // Event handlers: Filters
  7827. //
  7828. //--------------------------------------------------------------------------
  7829. /**
  7830. * @private
  7831. */
  7832. private function filterChangeHandler(event:Event):void
  7833. {
  7834. super.filters = _filters;
  7835. }
  7836. //--------------------------------------------------------------------------
  7837. //
  7838. // IUIComponent
  7839. //
  7840. //--------------------------------------------------------------------------
  7841. /**
  7842. * Returns <code>true</code> if the chain of <code>owner</code> properties
  7843. * points from <code>child</code> to this UIComponent.
  7844. *
  7845. * @param child A UIComponent.
  7846. *
  7847. * @return <code>true</code> if the child is parented or owned by this UIComponent.
  7848. */
  7849. public function owns(child:DisplayObject):Boolean
  7850. {
  7851. var childList:IChildList =
  7852. this is IRawChildrenContainer ?
  7853. IRawChildrenContainer(this).rawChildren :
  7854. IChildList(this);
  7855. if (childList.contains(child))
  7856. return true;
  7857. try
  7858. {
  7859. while (child && child != this)
  7860. {
  7861. // do a parent walk
  7862. if (child is IUIComponent)
  7863. child = IUIComponent(child).owner;
  7864. else
  7865. child = child.parent;
  7866. }
  7867. }
  7868. catch (e:SecurityError)
  7869. {
  7870. // You can't own what you don't have access to.
  7871. return false;
  7872. }
  7873. return child == this;
  7874. }
  7875. /**
  7876. * @private
  7877. *
  7878. * Get the embedded font for a set of font attributes.
  7879. */
  7880. mx_internal function getEmbeddedFont(fontName:String, bold:Boolean, italic:Boolean):EmbeddedFont
  7881. {
  7882. // Check if we can reuse a cached value.
  7883. if (cachedEmbeddedFont)
  7884. {
  7885. if (cachedEmbeddedFont.fontName == fontName &&
  7886. cachedEmbeddedFont.fontStyle == EmbeddedFontRegistry.getFontStyle(bold, italic))
  7887. {
  7888. return cachedEmbeddedFont;
  7889. }
  7890. }
  7891. cachedEmbeddedFont = new EmbeddedFont(fontName, bold, italic);
  7892. return cachedEmbeddedFont;
  7893. }
  7894. /**
  7895. * @private
  7896. * Finds a module factory that can create a TextField
  7897. * that can display the given font.
  7898. * This is important for embedded fonts, not for system fonts.
  7899. *
  7900. * @param fontName The name of the fontFamily.
  7901. *
  7902. * @param bold A flag which true if the font weight is bold,
  7903. * and false otherwise.
  7904. *
  7905. * @param italic A flag which is true if the font style is italic,
  7906. * and false otherwise.
  7907. *
  7908. * @return The IFlexModuleFactory that represents the context
  7909. * where an object wanting to use the font should be created.
  7910. */
  7911. mx_internal function getFontContext(fontName:String, bold:Boolean,
  7912. italic:Boolean):IFlexModuleFactory
  7913. {
  7914. return embeddedFontRegistry.getAssociatedModuleFactory(
  7915. getEmbeddedFont(fontName, bold, italic), moduleFactory);
  7916. }
  7917. /**
  7918. * Creates a new object using a context
  7919. * based on the embedded font being used.
  7920. *
  7921. * <p>This method is used to solve a problem
  7922. * with access to fonts embedded in an application SWF
  7923. * when the framework is loaded as an RSL
  7924. * (the RSL has its own SWF context).
  7925. * Embedded fonts may only be accessed from the SWF file context
  7926. * in which they were created.
  7927. * By using the context of the application SWF,
  7928. * the RSL can create objects in the application SWF context
  7929. * that will have access to the application's embedded fonts.</p>
  7930. *
  7931. * <p>Call this method only after the font styles
  7932. * for this object are set.</p>
  7933. *
  7934. * @param class The class to create.
  7935. *
  7936. * @return The instance of the class created in the context
  7937. * of the SWF owning the embedded font.
  7938. * If this object is not using an embedded font,
  7939. * the class is created in the context of this object.
  7940. */
  7941. protected function createInFontContext(classObj:Class):Object
  7942. {
  7943. hasFontContextBeenSaved = true;
  7944. var fontName:String = StringUtil.trimArrayElements(getStyle("fontFamily"), ",");
  7945. var fontWeight:String = getStyle("fontWeight");
  7946. var fontStyle:String = getStyle("fontStyle");
  7947. var bold:Boolean = (fontWeight == "bold");
  7948. var italic:Boolean = (fontStyle == "italic");
  7949. // save for hasFontContextChanged()
  7950. oldEmbeddedFontContext = getFontContext(fontName, bold, italic);
  7951. // not in font registry so create in this font context.
  7952. var obj:Object = createInModuleContext(oldEmbeddedFontContext ?
  7953. oldEmbeddedFontContext : moduleFactory,
  7954. getQualifiedClassName(classObj));
  7955. if (obj == null)
  7956. obj = new classObj;
  7957. return obj;
  7958. }
  7959. /**
  7960. * Creates the object using a given moduleFactory.
  7961. * If the moduleFactory is null or the object
  7962. * cannot be created using the module factory,
  7963. * then fall back to creating the object using a systemManager.
  7964. *
  7965. * @param moduleFactory The moduleFactory to create the class in;
  7966. * may be null.
  7967. *
  7968. * @param className The name of the class to create.
  7969. *
  7970. * @return The object created in the context of the moduleFactory.
  7971. */
  7972. protected function createInModuleContext(moduleFactory:IFlexModuleFactory,
  7973. className:String):Object
  7974. {
  7975. var newObject:Object = null;
  7976. if (moduleFactory)
  7977. newObject = moduleFactory.create(className);
  7978. return newObject;
  7979. }
  7980. /**
  7981. * @private
  7982. *
  7983. * Tests if the current font context has changed
  7984. * since that last time createInFontContext() was called.
  7985. */
  7986. public function hasFontContextChanged():Boolean
  7987. {
  7988. // If the font has not been set yet, then return false;
  7989. // the font has not changed.
  7990. if (!hasFontContextBeenSaved)
  7991. return false;
  7992. // Check if the module factory has changed.
  7993. var fontName:String =
  7994. StringUtil.trimArrayElements(getStyle("fontFamily"), ",");
  7995. var fontWeight:String = getStyle("fontWeight");
  7996. var fontStyle:String = getStyle("fontStyle");
  7997. var bold:Boolean = fontWeight == "bold";
  7998. var italic:Boolean = fontStyle == "italic";
  7999. var embeddedFont:EmbeddedFont =
  8000. getEmbeddedFont(fontName, bold, italic);
  8001. var fontContext:IFlexModuleFactory =
  8002. embeddedFontRegistry.getAssociatedModuleFactory(
  8003. embeddedFont, moduleFactory);
  8004. return fontContext != oldEmbeddedFontContext;
  8005. }
  8006. /**
  8007. * @inheritDoc
  8008. */
  8009. public function createAutomationIDPart(child:IAutomationObject):Object
  8010. {
  8011. if (automationDelegate)
  8012. return automationDelegate.createAutomationIDPart(child);
  8013. return null;
  8014. }
  8015. /**
  8016. * @inheritDoc
  8017. */
  8018. public function resolveAutomationIDPart(criteria:Object):Array
  8019. {
  8020. if (automationDelegate)
  8021. return automationDelegate.resolveAutomationIDPart(criteria);
  8022. return [];
  8023. }
  8024. /**
  8025. * @inheritDoc
  8026. */
  8027. public function getAutomationChildAt(index:int):IAutomationObject
  8028. {
  8029. if (automationDelegate)
  8030. return automationDelegate.getAutomationChildAt(index);
  8031. return null;
  8032. }
  8033. /**
  8034. * @inheritDoc
  8035. */
  8036. public function get numAutomationChildren():int
  8037. {
  8038. if (automationDelegate)
  8039. return automationDelegate.numAutomationChildren;
  8040. return 0;
  8041. }
  8042. /**
  8043. * @inheritDoc
  8044. */
  8045. public function get automationTabularData():Object
  8046. {
  8047. if (automationDelegate)
  8048. return automationDelegate.automationTabularData;
  8049. return null;
  8050. }
  8051. /**
  8052. * @inheritDoc
  8053. */
  8054. public function replayAutomatableEvent(event:Event):Boolean
  8055. {
  8056. if (automationDelegate)
  8057. return automationDelegate.replayAutomatableEvent(event);
  8058. return false;
  8059. }
  8060. /**
  8061. * @private
  8062. *
  8063. * Get the bounds of this object that are visible to the user
  8064. * on the screen.
  8065. *
  8066. * @param targetParent The parent to stop at when calculating the visible
  8067. * bounds. If null, this object's system manager will be used as
  8068. * the parent.
  8069. *
  8070. * @return a <code>Rectangle</code> including the visible portion of the this
  8071. * object. The rectangle is in global coordinates.
  8072. */
  8073. public function getVisibleRect(targetParent:DisplayObject = null):Rectangle
  8074. {
  8075. if (!targetParent)
  8076. targetParent = DisplayObject(systemManager);
  8077. var thisParent:DisplayObject = $parent ? $parent : parent;
  8078. // If the object is not on the display list then it is not visible.
  8079. if (!thisParent)
  8080. return new Rectangle();
  8081. var pt:Point = new Point(x, y);
  8082. pt = thisParent.localToGlobal(pt);
  8083. // bounds of this object to return. Keep in global coordinates
  8084. // until the end and set back to targetParent coordinates.
  8085. var bounds:Rectangle = new Rectangle(pt.x, pt.y, width, height);
  8086. var current:DisplayObject = this;
  8087. var currentRect:Rectangle = new Rectangle();
  8088. do
  8089. {
  8090. if (current is UIComponent)
  8091. {
  8092. if (UIComponent(current).$parent)
  8093. current = UIComponent(current).$parent;
  8094. else
  8095. current = UIComponent(current).parent;
  8096. }
  8097. else
  8098. current = current.parent;
  8099. if (current && current.scrollRect)
  8100. {
  8101. // clip the bounds by the scroll rect
  8102. currentRect = current.scrollRect.clone();
  8103. pt = current.localToGlobal(currentRect.topLeft);
  8104. currentRect.x = pt.x;
  8105. currentRect.y = pt.y;
  8106. bounds = bounds.intersection(currentRect);
  8107. }
  8108. } while (current && current != targetParent);
  8109. return bounds;
  8110. }
  8111. //--------------------------------------------------------------------------
  8112. //
  8113. // Diagnostics
  8114. //
  8115. //--------------------------------------------------------------------------
  8116. mx_internal static var dispatchEventHook:Function;
  8117. /**
  8118. * Dispatches an event into the event flow.
  8119. * The event target is the EventDispatcher object upon which
  8120. * the <code>dispatchEvent()</code> method is called.
  8121. *
  8122. * @param event The Event object that is dispatched into the event flow.
  8123. * If the event is being redispatched, a clone of the event is created automatically.
  8124. * After an event is dispatched, its <code>target</code> property cannot be changed,
  8125. * so you must create a new copy of the event for redispatching to work.
  8126. *
  8127. * @return A value of <code>true</code> if the event was successfully dispatched.
  8128. * A value of <code>false</code> indicates failure or that
  8129. * the <code>preventDefault()</code> method was called on the event.
  8130. */
  8131. override public function dispatchEvent(event:Event):Boolean
  8132. {
  8133. if (dispatchEventHook != null)
  8134. dispatchEventHook(event, this);
  8135. return super.dispatchEvent(event);
  8136. }
  8137. private static var fakeMouseX:QName = new QName(mx_internal, "_mouseX");
  8138. private static var fakeMouseY:QName = new QName(mx_internal, "_mouseY");
  8139. /**
  8140. * @private
  8141. */
  8142. override public function get mouseX():Number
  8143. {
  8144. if (!root || root is Stage || root[fakeMouseX] === undefined)
  8145. return super.mouseX;
  8146. return globalToLocal(new Point(root[fakeMouseX], 0)).x;
  8147. }
  8148. /**
  8149. * @private
  8150. */
  8151. override public function get mouseY():Number
  8152. {
  8153. if (!root || root is Stage || root[fakeMouseY] === undefined)
  8154. return super.mouseY;
  8155. return globalToLocal(new Point(0, root[fakeMouseY])).y;
  8156. }
  8157. }
  8158. }
  8159. ////////////////////////////////////////////////////////////////////////////////
  8160. //
  8161. // Helper class: MethodQueueElement
  8162. //
  8163. ////////////////////////////////////////////////////////////////////////////////
  8164. /**
  8165. * @private
  8166. * An element of the methodQueue array.
  8167. */
  8168. class MethodQueueElement
  8169. {
  8170. //--------------------------------------------------------------------------
  8171. //
  8172. // Constructor
  8173. //
  8174. //--------------------------------------------------------------------------
  8175. /**
  8176. * Constructor.
  8177. */
  8178. public function MethodQueueElement(method:Function,
  8179. args:Array /* of Object */ = null)
  8180. {
  8181. super();
  8182. this.method = method;
  8183. this.args = args;
  8184. }
  8185. //--------------------------------------------------------------------------
  8186. //
  8187. // Properties
  8188. //
  8189. //--------------------------------------------------------------------------
  8190. //----------------------------------
  8191. // method
  8192. //----------------------------------
  8193. /**
  8194. * A reference to the method to be called.
  8195. */
  8196. public var method:Function;
  8197. //----------------------------------
  8198. // args
  8199. //----------------------------------
  8200. /**
  8201. * The arguments to be passed to the method.
  8202. */
  8203. public var args:Array /* of Object */;
  8204. }