/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
Large files are truncated click here to view the full file
- ////////////////////////////////////////////////////////////////////////////////
- //
- // ADOBE SYSTEMS INCORPORATED
- // Copyright 2003-2007 Adobe Systems Incorporated
- // All Rights Reserved.
- //
- // NOTICE: Adobe permits you to use, modify, and distribute this file
- // in accordance with the terms of the license agreement accompanying it.
- //
- ////////////////////////////////////////////////////////////////////////////////
- package mx.core
- {
- import flash.display.DisplayObject;
- import flash.display.DisplayObjectContainer;
- import flash.display.GradientType;
- import flash.display.Graphics;
- import flash.display.InteractiveObject;
- import flash.display.Loader;
- import flash.display.Sprite;
- import flash.display.Stage;
- import flash.events.Event;
- import flash.events.EventPhase;
- import flash.events.FocusEvent;
- import flash.events.IEventDispatcher;
- import flash.events.KeyboardEvent;
- import flash.geom.Matrix;
- import flash.geom.Point;
- import flash.geom.Rectangle;
- import flash.system.ApplicationDomain;
- import flash.text.TextLineMetrics;
- import flash.utils.getQualifiedClassName;
- import flash.utils.getQualifiedSuperclassName;
- import mx.automation.IAutomationObject;
- import mx.binding.BindingManager;
- import mx.controls.IFlexContextMenu;
- import mx.effects.EffectManager;
- import mx.effects.IEffect;
- import mx.effects.IEffectInstance;
- import mx.events.ChildExistenceChangedEvent;
- import mx.events.DragEvent;
- import mx.events.DynamicEvent;
- import mx.events.EffectEvent;
- import mx.events.FlexEvent;
- import mx.events.MoveEvent;
- import mx.events.PropertyChangeEvent;
- import mx.events.ResizeEvent;
- import mx.events.StateChangeEvent;
- import mx.events.ToolTipEvent;
- import mx.events.ValidationResultEvent;
- import mx.graphics.RoundedRectangle;
- import mx.managers.CursorManager;
- import mx.managers.ICursorManager;
- import mx.managers.IFocusManager;
- import mx.managers.IFocusManagerComponent;
- import mx.managers.IFocusManagerContainer;
- import mx.managers.ILayoutManagerClient;
- import mx.managers.ISystemManager;
- import mx.managers.IToolTipManagerClient;
- import mx.managers.SystemManager;
- import mx.managers.SystemManagerGlobals;
- import mx.managers.SystemManagerProxy;
- import mx.managers.ToolTipManager;
- import mx.modules.ModuleManager;
- import mx.resources.IResourceManager;
- import mx.resources.ResourceManager;
- import mx.states.State;
- import mx.states.Transition;
- import mx.styles.CSSStyleDeclaration;
- import mx.styles.ISimpleStyleClient;
- import mx.styles.IStyleClient;
- import mx.styles.StyleManager;
- import mx.styles.StyleProtoChain;
- import mx.utils.ColorUtil;
- import mx.utils.GraphicsUtil;
- import mx.utils.StringUtil;
- import mx.validators.IValidatorListener;
- import mx.validators.ValidationResult;
- import flash.system.Security;
- use namespace mx_internal;
- //--------------------------------------
- // Lifecycle events
- //--------------------------------------
- /**
- * Dispatched when the component is added to a container as a content child
- * by using the <code>addChild()</code> or <code>addChildAt()</code> method.
- * If the component is added to the container as a noncontent child by
- * using the <code>rawChildren.addChild()</code> or
- * <code>rawChildren.addChildAt()</code> method, the event is not dispatched.
- *
- * @eventType mx.events.FlexEvent.ADD
- */
- [Event(name="add", type="mx.events.FlexEvent")]
- /**
- * Dispatched when the component has finished its construction,
- * property processing, measuring, layout, and drawing.
- *
- * <p>At this point, depending on its <code>visible</code> property,
- * the component may not be visible even though it has been drawn.</p>
- *
- * @eventType mx.events.FlexEvent.CREATION_COMPLETE
- */
- [Event(name="creationComplete", type="mx.events.FlexEvent")]
- /**
- * Dispatched when an object has had its <code>commitProperties()</code>,
- * <code>measure()</code>, and
- * <code>updateDisplayList()</code> methods called (if needed).
- *
- * <p>This is the last opportunity to alter the component before it is
- * displayed. All properties have been committed and the component has
- * been measured and layed out.</p>
- *
- * @eventType mx.events.FlexEvent.UPDATE_COMPLETE
- */
- [Event(name="updateComplete", type="mx.events.FlexEvent")]
- /**
- * Dispatched when an object's state changes from visible to invisible.
- *
- * @eventType mx.events.FlexEvent.HIDE
- */
- [Event(name="hide", type="mx.events.FlexEvent")]
- /**
- * Dispatched when the component has finished its construction
- * and has all initialization properties set.
- *
- * <p>After the initialization phase, properties are processed, the component
- * is measured, laid out, and drawn, after which the
- * <code>creationComplete</code> event is dispatched.</p>
- *
- * @eventType mx.events.FlexEvent.INITIALIZE
- */
- [Event(name="initialize", type="mx.events.FlexEvent")]
- /**
- * Dispatched when the object has moved.
- *
- * <p>You can move the component by setting the <code>x</code>
- * or <code>y</code> properties, by calling the <code>move()</code>
- * method, by setting one
- * of the following properties either on the component or on other
- * components such that the LayoutManager needs to change the
- * <code>x</code> or <code>y</code> properties of the component:</p>
- *
- * <ul>
- * <li><code>minWidth</code></li>
- * <li><code>minHeight</code></li>
- * <li><code>maxWidth</code></li>
- * <li><code>maxHeight</code></li>
- * <li><code>explicitWidth</code></li>
- * <li><code>explicitHeight</code></li>
- * </ul>
- *
- * <p>When you call the <code>move()</code> method, the <code>move</code>
- * event is dispatched before the method returns.
- * In all other situations, the <code>move</code> event is not dispatched
- * until after the property changes.</p>
- *
- * @eventType mx.events.MoveEvent.MOVE
- */
- [Event(name="move", type="mx.events.MoveEvent")]
- /**
- * Dispatched at the beginning of the component initialization sequence.
- * The component is in a very raw state when this event is dispatched.
- * Many components, such as the Button control, create internal child
- * components to implement functionality; for example, the Button control
- * creates an internal UITextField component to represent its label text.
- * When Flex dispatches the <code>preinitialize</code> event,
- * the children, including the internal children, of a component
- * have not yet been created.
- *
- * @eventType mx.events.FlexEvent.PREINITIALIZE
- */
- [Event(name="preinitialize", type="mx.events.FlexEvent")]
- /**
- * Dispatched when the component is removed from a container as a content child
- * by using the <code>removeChild()</code> or <code>removeChildAt()</code> method.
- * If the component is removed from the container as a noncontent child by
- * using the <code>rawChildren.removeChild()</code> or
- * <code>rawChildren.removeChildAt()</code> method, the event is not dispatched.
- *
- * @eventType mx.events.FlexEvent.REMOVE
- */
- [Event(name="remove", type="mx.events.FlexEvent")]
- /**
- * Dispatched when the component is resized.
- *
- * <p>You can resize the component by setting the <code>width</code> or
- * <code>height</code> property, by calling the <code>setActualSize()</code>
- * method, or by setting one of
- * the following properties either on the component or on other components
- * such that the LayoutManager needs to change the <code>width</code> or
- * <code>height</code> properties of the component:</p>
- *
- * <ul>
- * <li><code>minWidth</code></li>
- * <li><code>minHeight</code></li>
- * <li><code>maxWidth</code></li>
- * <li><code>maxHeight</code></li>
- * <li><code>explicitWidth</code></li>
- * <li><code>explicitHeight</code></li>
- * </ul>
- *
- * <p>The <code>resize</code> event is not
- * dispatched until after the property changes.</p>
- *
- * @eventType mx.events.ResizeEvent.RESIZE
- */
- [Event(name="resize", type="mx.events.ResizeEvent")]
- /**
- * Dispatched when an object's state changes from invisible to visible.
- *
- * @eventType mx.events.FlexEvent.SHOW
- */
- [Event(name="show", type="mx.events.FlexEvent")]
- //--------------------------------------
- // Mouse events
- //--------------------------------------
- /**
- * Dispatched from a component opened using the PopUpManager
- * when the user clicks outside it.
- *
- * @eventType mx.events.FlexMouseEvent.MOUSE_DOWN_OUTSIDE
- */
- [Event(name="mouseDownOutside", type="mx.events.FlexMouseEvent")]
- /**
- * Dispatched from a component opened using the PopUpManager
- * when the user scrolls the mouse wheel outside it.
- *
- * @eventType mx.events.FlexMouseEvent.MOUSE_WHEEL_OUTSIDE
- */
- [Event(name="mouseWheelOutside", type="mx.events.FlexMouseEvent")]
- //--------------------------------------
- // Validation events
- //--------------------------------------
- /**
- * Dispatched when values are changed programmatically
- * or by user interaction.
- *
- * <p>Because a programmatic change triggers this event, make sure
- * that any <code>valueCommit</code> event handler does not change
- * a value that causes another <code>valueCommit</code> event.
- * For example, do not change a control's <code>dataProvider</code>
- * property in a <code>valueCommit</code> event handler. </p>
- *
- * @eventType mx.events.FlexEvent.VALUE_COMMIT
- */
- [Event(name="valueCommit", type="mx.events.FlexEvent")]
- /**
- * Dispatched when a component is monitored by a Validator
- * and the validation failed.
- *
- * @eventType mx.events.FlexEvent.INVALID
- */
- [Event(name="invalid", type="mx.events.FlexEvent")]
- /**
- * Dispatched when a component is monitored by a Validator
- * and the validation succeeded.
- *
- * @eventType mx.events.FlexEvent.VALID
- */
- [Event(name="valid", type="mx.events.FlexEvent")]
- //--------------------------------------
- // Drag-and-drop events
- //--------------------------------------
- /**
- * Dispatched by a component when the user moves the mouse over the component
- * during a drag operation.
- * In an application running in Flash Player,
- * the event is dispatched many times when you move the mouse over any component.
- * In an application running in AIR, the event is dispatched only once.
- *
- * <p>In order to be a valid drop target, you must define a handler
- * for this event.
- * In the handler, you can change the appearance of the drop target
- * to provide visual feedback to the user that the component can accept
- * the drag.
- * For example, you could draw a border around the drop target,
- * or give focus to the drop target.</p>
- *
- * <p>If you want to accept the drag, you must call the
- * <code>DragManager.acceptDragDrop()</code> method. If you don't
- * call <code>acceptDragDrop()</code>, you will not get any of the
- * other drag events.</p>
- *
- * <p>In Flash Player, the value of the <code>action</code> property is always
- * <code>DragManager.MOVE</code>, even if you are doing a copy.
- * This is because the <code>dragEnter</code> event occurs before
- * the control recognizes that the Control key is pressed to signal a copy.
- * The <code>action</code> property of the event object for the
- * <code>dragOver</code> event does contain a value that signifies the type of
- * drag operation. You may change the type of drag action by calling the
- * <code>DragManager.showFeedback()</code> method.</p>
- *
- * <p>In AIR, the default value of the <code>action</code> property is
- * <code>DragManager.COPY</code>.</p>
- *
- * <p>Because of the way data to a Tree control is structured,
- * the Tree control handles drag and drop differently from the other list-based controls.
- * For the Tree control, the event handler for the <code>dragDrop</code> event
- * only performs an action when you move or copy data in the same Tree control,
- * or copy data to another Tree control.
- * If you drag data from one Tree control and drop it onto another Tree control
- * to move the data, the event handler for the <code>dragComplete</code> event
- * actually performs the work to add the data to the destination Tree control,
- * rather than the event handler for the dragDrop event,
- * and also removes the data from the source Tree control.
- * This is necessary because to reparent the data being moved,
- * Flex must remove it first from the source Tree control.</p>
- *
- * @see mx.managers.DragManager
- *
- * @eventType mx.events.DragEvent.DRAG_ENTER
- */
- [Event(name="dragEnter", type="mx.events.DragEvent")]
- /**
- * Dispatched by a component when the user moves the mouse while over the component
- * during a drag operation.
- * In Flash Player, the event is dispatched
- * when you drag an item over a valid drop target.
- * In AIR, the event is dispatched when you drag an item over
- * any component, even if the component is not a valid drop target.
- *
- * <p>In the handler, you can change the appearance of the drop target
- * to provide visual feedback to the user that the component can accept
- * the drag.
- * For example, you could draw a border around the drop target,
- * or give focus to the drop target.</p>
- *
- * <p>You should handle this event to perform additional logic
- * before allowing the drop, such as dropping data to various locations
- * in the drop target, reading keyboard input to determine if the
- * drag-and-drop action is a move or copy of the drag data, or providing
- * different types of visual feedback based on the type of drag-and-drop
- * action.</p>
- *
- * <p>You may also change the type of drag action by changing the
- * <code>DragManager.showFeedback()</code> method.
- * The default value of the <code>action</code> property is
- * <code>DragManager.MOVE</code>.</p>
- *
- * @see mx.managers.DragManager
- *
- * @eventType mx.events.DragEvent.DRAG_OVER
- */
- [Event(name="dragOver", type="mx.events.DragEvent")]
- /**
- * Dispatched by the component when the user drags outside the component,
- * but does not drop the data onto the target.
- *
- * <p>You use this event to restore the drop target to its normal appearance
- * if you modified its appearance as part of handling the
- * <code>dragEnter</code> or <code>dragOver</code> event.</p>
- *
- * @eventType mx.events.DragEvent.DRAG_EXIT
- */
- [Event(name="dragExit", type="mx.events.DragEvent")]
- /**
- * Dispatched by the drop target when the user releases the mouse over it.
- *
- * <p>You use this event handler to add the drag data to the drop target.</p>
- *
- * <p>If you call <code>Event.preventDefault()</code> in the event handler
- * for the <code>dragDrop</code> event for
- * a Tree control when dragging data from one Tree control to another,
- * it prevents the drop.</p>
- *
- * @eventType mx.events.DragEvent.DRAG_DROP
- */
- [Event(name="dragDrop", type="mx.events.DragEvent")]
- /**
- * Dispatched by the drag initiator (the component that is the source
- * of the data being dragged) when the drag operation completes,
- * either when you drop the dragged data onto a drop target or when you end
- * the drag-and-drop operation without performing a drop.
- *
- * <p>You can use this event to perform any final cleanup
- * of the drag-and-drop operation.
- * For example, if you drag a List control item from one list to another,
- * you can delete the List control item from the source if you no longer
- * need it.</p>
- *
- * <p>If you call <code>Event.preventDefault()</code> in the event handler
- * for the <code>dragComplete</code> event for
- * a Tree control when dragging data from one Tree control to another,
- * it prevents the drop.</p>
- *
- * @eventType mx.events.DragEvent.DRAG_COMPLETE
- */
- [Event(name="dragComplete", type="mx.events.DragEvent")]
- /**
- * Dispatched by the drag initiator when starting a drag operation.
- * This event is used internally by the list-based controls;
- * you do not handle it when implementing drag and drop.
- * If you want to control the start of a drag-and-drop operation,
- * use the <code>mouseDown</code> or <code>mouseMove</code> event.
- *
- * @eventType mx.events.DragEvent.DRAG_START
- */
- [Event(name="dragStart", type="mx.events.DragEvent")]
- //--------------------------------------
- // Effect events
- //--------------------------------------
- /**
- * Dispatched just before an effect starts.
- *
- * <p>The effect does not start changing any visuals
- * until after this event is fired.</p>
- *
- * @eventType mx.events.EffectEvent.EFFECT_START
- */
- [Event(name="effectStart", type="mx.events.EffectEvent")]
- /**
- * Dispatched after an effect ends.
- *
- * <p>The effect will have made the last set of visual changes
- * before this event is fired, but those changes will not have
- * been rendered on the screen.
- * Thus, you might have to use the <code>callLater()</code> method
- * to delay any other changes that you want to make until after the
- * changes have been rendered onscreen.</p>
- *
- * @eventType mx.events.EffectEvent.EFFECT_END
- */
- [Event(name="effectEnd", type="mx.events.EffectEvent")]
- //--------------------------------------
- // State events
- //--------------------------------------
- /**
- * Dispatched after the <code>currentState</code> property changes,
- * but before the view state changes.
- *
- * @eventType mx.events.StateChangeEvent.CURRENT_STATE_CHANGING
- */
- [Event(name="currentStateChanging", type="mx.events.StateChangeEvent")]
- /**
- * Dispatched after the view state has changed.
- *
- * @eventType mx.events.StateChangeEvent.CURRENT_STATE_CHANGE
- */
- [Event(name="currentStateChange", type="mx.events.StateChangeEvent")]
- /**
- * Dispatched after the component has returned to the root view state.
- *
- * @eventType mx.events.FlexEvent.ENTER_STATE
- */
- [Event(name="enterState", type="mx.events.FlexEvent")]
- /**
- * Dispatched before the component exits from the root view state.
- *
- * @eventType mx.events.FlexEvent.EXIT_STATE
- */
- [Event(name="exitState", type="mx.events.FlexEvent")]
- //--------------------------------------
- // Tooltip events
- //--------------------------------------
- /**
- * Dispatched by the component when it is time to create a ToolTip.
- *
- * <p>If you create your own IToolTip object and place a reference
- * to it in the <code>toolTip</code> property of the event object
- * that is passed to your <code>toolTipCreate</code> handler,
- * the ToolTipManager displays your custom ToolTip.
- * Otherwise, the ToolTipManager creates an instance of
- * <code>ToolTipManager.toolTipClass</code> to display.</p>
- *
- * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
- * <code>toolTipCreate</code>, <code>toolTipShow</code>,
- * <code>toolTipShown</code>, <code>toolTipHide</code>,
- * and <code>toolTipEnd</code>.</p>
- *
- * @eventType mx.events.ToolTipEvent.TOOL_TIP_CREATE
- */
- [Event(name="toolTipCreate", type="mx.events.ToolTipEvent")]
- /**
- * Dispatched by the component when its ToolTip has been hidden
- * and will be discarded soon.
- *
- * <p>If you specify an effect using the
- * <code>ToolTipManager.hideEffect</code> property,
- * this event is dispatched after the effect stops playing.</p>
- *
- * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
- * <code>toolTipCreate</code>, <code>toolTipShow</code>,
- * <code>toolTipShown</code>, <code>toolTipHide</code>,
- * and <code>toolTipEnd</code>.</p>
- *
- * @eventType mx.events.ToolTipEvent.TOOL_TIP_END
- */
- [Event(name="toolTipEnd", type="mx.events.ToolTipEvent")]
- /**
- * Dispatched by the component when its ToolTip is about to be hidden.
- *
- * <p>If you specify an effect using the
- * <code>ToolTipManager.hideEffect</code> property,
- * this event is dispatched before the effect starts playing.</p>
- *
- * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
- * <code>toolTipCreate</code>, <code>toolTipShow</code>,
- * <code>toolTipShown</code>, <code>toolTipHide</code>,
- * and <code>toolTipEnd</code>.</p>
- *
- * @eventType mx.events.ToolTipEvent.TOOL_TIP_HIDE
- */
- [Event(name="toolTipHide", type="mx.events.ToolTipEvent")]
- /**
- * Dispatched by the component when its ToolTip is about to be shown.
- *
- * <p>If you specify an effect using the
- * <code>ToolTipManager.showEffect</code> property,
- * this event is dispatched before the effect starts playing.
- * You can use this event to modify the ToolTip before it appears.</p>
- *
- * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
- * <code>toolTipCreate</code>, <code>toolTipShow</code>,
- * <code>toolTipShown</code>, <code>toolTipHide</code>,
- * and <code>toolTipEnd</code>.</p>
- *
- * @eventType mx.events.ToolTipEvent.TOOL_TIP_SHOW
- */
- [Event(name="toolTipShow", type="mx.events.ToolTipEvent")]
- /**
- * Dispatched by the component when its ToolTip has been shown.
- *
- * <p>If you specify an effect using the
- * <code>ToolTipManager.showEffect</code> property,
- * this event is dispatched after the effect stops playing.</p>
- *
- * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
- * <code>toolTipCreate</code>, <code>toolTipShow</code>,
- * <code>toolTipShown</code>, <code>toolTipHide</code>,
- * and <code>toolTipEnd</code>.</p>
- *
- * @eventType mx.events.ToolTipEvent.TOOL_TIP_SHOWN
- */
- [Event(name="toolTipShown", type="mx.events.ToolTipEvent")]
- /**
- * Dispatched by a component whose <code>toolTip</code> property is set,
- * as soon as the user moves the mouse over it.
- *
- * <p>The sequence of ToolTip events is <code>toolTipStart</code>,
- * <code>toolTipCreate</code>, <code>toolTipShow</code>,
- * <code>toolTipShown</code>, <code>toolTipHide</code>,
- * and <code>toolTipEnd</code>.</p>
- *
- * @eventType mx.events.ToolTipEvent.TOOL_TIP_START
- */
- [Event(name="toolTipStart", type="mx.events.ToolTipEvent")]
- //--------------------------------------
- // Styles
- //--------------------------------------
- include "../styles/metadata/AnchorStyles.as";
- /**
- * Color of the component highlight when validation fails.
- * Flex also sets the <code>borderColor</code> style of the component to this
- * <code>errorColor</code> on a validation failure.
- *
- * @default 0xFF0000
- */
- [Style(name="errorColor", type="uint", format="Color", inherit="yes")]
- /**
- * Blend mode used by the focus rectangle.
- * For more information, see the <code>blendMode</code> property
- * of the flash.display.DisplayObject class.
- *
- * @default "normal"
- */
- [Style(name="focusBlendMode", type="String", inherit="no")]
- /**
- * Skin used to draw the focus rectangle.
- *
- * @default mx.skins.halo.HaloFocusRect
- */
- [Style(name="focusSkin", type="Class", inherit="no")]
- /**
- * Thickness, in pixels, of the focus rectangle outline.
- *
- * @default 2
- */
- [Style(name="focusThickness", type="Number", format="Length", inherit="no")]
- /**
- * Theme color of a component. This property controls the appearance of highlights,
- * appearance when a component is selected, and other similar visual cues, but it
- * does not have any effect on the regular borders or background colors of the component.
- * The preferred values are <code>haloGreen</code>, <code>haloBlue</code>,
- * <code>haloOrange</code>, and <code>haloSilver</code>, although any valid color
- * value can be used.
- *
- * <p>The default values of the <code>rollOverColor</code> and
- * <code>selectionColor</code> styles are based on the
- * <code>themeColor</code> value.</p>
- *
- * @default "haloBlue"
- */
- [Style(name="themeColor", type="uint", format="Color", inherit="yes")]
- //--------------------------------------
- // Effects
- //--------------------------------------
- /**
- * Played when the component is created.
- */
- [Effect(name="creationCompleteEffect", event="creationComplete")]
- /**
- * Played when the component is moved.
- */
- [Effect(name="moveEffect", event="move")]
- /**
- * Played when the component is resized.
- */
- [Effect(name="resizeEffect", event="resize")]
- /**
- * Played when the component becomes visible.
- */
- [Effect(name="showEffect", event="show")]
- /**
- * Played when the component becomes invisible.
- */
- [Effect(name="hideEffect", event="hide")]
- /**
- * Played when the user presses the mouse button while over the component.
- */
- [Effect(name="mouseDownEffect", event="mouseDown")]
- /**
- * Played when the user releases the mouse button while over the component.
- */
- [Effect(name="mouseUpEffect", event="mouseUp")]
- /**
- * Played when the user rolls the mouse over the component.
- */
- [Effect(name="rollOverEffect", event="rollOver")]
- /**
- * Played when the user rolls the mouse so it is no longer over the component.
- */
- [Effect(name="rollOutEffect", event="rollOut")]
- /**
- * Played when the component gains keyboard focus.
- */
- [Effect(name="focusInEffect", event="focusIn")]
- /**
- * Played when the component loses keyboard focus.
- */
- [Effect(name="focusOutEffect", event="focusOut")]
- /**
- * Played when the component is added as a child to a Container.
- */
- [Effect(name="addedEffect", event="added")]
- /**
- * Played when the component is removed from a Container.
- */
- [Effect(name="removedEffect", event="removed")]
- //--------------------------------------
- // Other metadata
- //--------------------------------------
- [AccessibilityClass(implementation="mx.accessibility.UIComponentAccImpl")]
- [ResourceBundle("core")]
- // skins resources aren't found because CSS visited by the compiler
- [ResourceBundle("skins")]
- /**
- * The UIComponent class is the base class for all visual components,
- * both interactive and noninteractive.
- *
- * <p>An interactive component can participate in tabbing and other kinds of
- * keyboard focus manipulation, accept low-level events like keyboard and
- * mouse input, and be disabled so that it does not receive keyboard and
- * mouse input.
- * This is in contrast to noninteractive components, like Label and
- * ProgressBar, which simply display contents and are not manipulated by
- * the user.</p>
- * <p>The UIComponent class is not used as an MXML tag, but is used as a base
- * class for other classes.</p>
- *
- * @mxml
- *
- * <p>All user interface components in Flex extend the UIComponent class.
- * Flex components inherit the following properties from the UIComponent
- * class:</p>
- *
- * <pre>
- * <mx:<i>tagname</i>
- * <b>Properties </b>
- * automationName="null"
- * cachePolicy="auto|on|off"
- * currentState="null"
- * doubleClickEnabled="false|true"
- * enabled="true|false"
- * explicitHeight="NaN"
- * explicitMaxHeight="NaN"
- * explicitMaxWidth="NaN"
- * explicitMinHeight="NaN"
- * explicitMinWidth="NaN"
- * explicitWidth="NaN"
- * focusEnabled="true|false"
- * height="0"
- * id=""
- * includeInLayout="true|false"
- * maxHeight="10000"
- * maxWidth="10000"
- * measuredHeight=
- * measuredMinHeight=
- * measuredMinWidth=
- * measuredWidth=
- * minHeight="0"
- * minWidth="0"
- * mouseFocusEnabled="true|false"
- * percentHeight="NaN"
- * percentWidth="NaN"
- * scaleX="1.0"
- * scaleY="1.0"
- * states="null"
- * styleName="undefined"
- * toolTip="null"
- * transitions=""
- * validationSubField
- * width="0"
- * x="0"
- * y="0"
- *
- * <b>Styles</b>
- * bottom="undefined"
- * errorColor="0xFF0000"
- * focusBlendMode="normal"
- * focusSkin="HaloFocusRect""
- * focusThickness="2"
- * horizontalCenter="undefined"
- * left="undefined"
- * right="undefined"
- * themeColor="haloGreen"
- * top="undefined"
- * verticalCenter="undefined"
- *
- * <b>Effects</b>
- * addedEffect="<i>No default</i>"
- * creationCompleteEffect="<i>No default</i>"
- * focusInEffect="<i>No default</i>"
- * focusOutEffect="<i>No default</i>"
- * hideEffect="<i>No default</i>"
- * mouseDownEffect="<i>No default</i>"
- * mouseUpEffect="<i>No default</i>"
- * moveEffect="<i>No default</i>"
- * removedEffect="<i>No default</i>"
- * resizeEffect="<i>No default</i>"
- * rollOutEffect="<i>No default</i>"
- * rollOverEffect="<i>No default</i>"
- * showEffect="<i>No default</i>"
- *
- * <b>Events</b>
- * add="<i>No default</i>"
- * creationComplete="<i>No default</i>"
- * currentStateChange="<i>No default</i>"
- * currentStateChanging="<i>No default</i>"
- * dragComplete="<i>No default</i>"
- * dragDrop="<i>No default</i>"
- * dragEnter="<i>No default</i>"
- * dragExit="<i>No default</i>"
- * dragOver="<i>No default</i>"
- * effectEnd="<i>No default</i>"
- * effectStart="<i>No default</i>"
- * enterState="<i>No default</i>"
- * exitState="<i>No default</i>"
- * hide="<i>No default</i>"
- * initialize="<i>No default</i>"
- * invalid="<i>No default</i>"
- * mouseDownOutside="<i>No default</i>"
- * mouseWheelOutside="<i>No default</i>"
- * move="<i>No default</i>"
- * preinitialize="<i>No default</i>"
- * record="<i>No default</i>"
- * remove="<i>No default</i>"
- * resize="<i>No default</i>"
- * show="<i>No default</i>"
- * toolTipCreate="<i>No default</i>"
- * toolTipEnd="<i>No default</i>"
- * toolTipHide="<i>No default</i>"
- * toolTipShow="<i>No default</i>"
- * toolTipShown="<i>No default</i>"
- * toolTipStart="<i>No default</i>"
- * updateComplete="<i>No default</i>"
- * valid="<i>No default</i>"
- * valueCommit="<i>No default</i>"
- * >
- * </pre>
- *
- * @see mx.core.UIComponent
- */
- public class UIComponent extends FlexSprite
- implements IAutomationObject, IChildList,
- IDeferredInstantiationUIComponent, IFlexDisplayObject,
- IFlexModule,
- IInvalidating, ILayoutManagerClient,
- IPropertyChangeNotifier, IRepeaterClient,
- ISimpleStyleClient, IStyleClient,
- IToolTipManagerClient, IUIComponent,
- IValidatorListener, IStateClient,
- IConstraintClient
- {
- include "../core/Version.as";
-
- //--------------------------------------------------------------------------
- //
- // Class constants
- //
- //--------------------------------------------------------------------------
- /**
- * The default value for the <code>measuredWidth</code> property.
- * Most components calculate a measuredWidth but some are flow-based and
- * have to pick a number that looks reasonable.
- *
- * @default 160
- */
- public static const DEFAULT_MEASURED_WIDTH:Number = 160;
- /**
- * The default value for the <code>measuredMinWidth</code> property.
- * Most components calculate a measuredMinWidth but some are flow-based and
- * have to pick a number that looks reasonable.
- *
- * @default 40
- */
- public static const DEFAULT_MEASURED_MIN_WIDTH:Number = 40;
- /**
- * The default value for the <code>measuredHeight</code> property.
- * Most components calculate a measuredHeight but some are flow-based and
- * have to pick a number that looks reasonable.
- *
- * @default 22
- */
- public static const DEFAULT_MEASURED_HEIGHT:Number = 22;
- /**
- * The default value for the <code>measuredMinHeight</code> property.
- * Most components calculate a measuredMinHeight but some are flow-based and
- * have to pick a number that looks reasonable.
- *
- * @default 22
- */
- public static const DEFAULT_MEASURED_MIN_HEIGHT:Number = 22;
- /**
- * The default value for the <code>maxWidth</code> property.
- *
- * @default 10000
- */
- public static const DEFAULT_MAX_WIDTH:Number = 10000;
- /**
- * The default value for the <code>maxHeight</code> property.
- *
- * @default 10000
- */
- public static const DEFAULT_MAX_HEIGHT:Number = 10000;
- /**
- * @private
- * The inheritingStyles and nonInheritingStyles properties
- * are initialized to this empty Object.
- * This allows the getStyle() and getStyle()
- * methods to simply access inheritingStyles[] and nonInheritingStyles[]
- * without needing to first check whether those objects exist.
- * If they were simply initialized to {}, we couldn't determine
- * whether the style chain has already been built or not.
- */
- mx_internal static var STYLE_UNINITIALIZED:Object = {};
- //--------------------------------------------------------------------------
- //
- // Class mixins
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- * Placeholder for mixin by UIComponentAccImpl.
- */
- mx_internal static var createAccessibilityImplementation:Function;
- //--------------------------------------------------------------------------
- //
- // Class properties
- //
- //--------------------------------------------------------------------------
- //----------------------------------
- // embeddedFontRegistry
- //----------------------------------
- /**
- * @private
- * Storage for the _embeddedFontRegistry property.
- * Note: This gets initialized on first access,
- * not when this class is initialized, in order to ensure
- * that the Singleton registry has already been initialized.
- */
- private static var _embeddedFontRegistry:IEmbeddedFontRegistry;
- /**
- * @private
- * A reference to the embedded font registry.
- * Single registry in the system.
- * Used to look up the moduleFactory of a font.
- */
- private static function get embeddedFontRegistry():IEmbeddedFontRegistry
- {
- if (!_embeddedFontRegistry)
- {
- _embeddedFontRegistry = IEmbeddedFontRegistry(
- Singleton.getInstance("mx.core::IEmbeddedFontRegistry"));
- }
- return _embeddedFontRegistry;
- }
-
- //--------------------------------------------------------------------------
- //
- // Class methods
- //
- //--------------------------------------------------------------------------
- /**
- * Blocks the background processing of methods
- * queued by <code>callLater()</code>,
- * until <code>resumeBackgroundProcessing()</code> is called.
- *
- * <p>These methods can be useful when you have time-critical code
- * which needs to execute without interruption.
- * For example, when you set the <code>suspendBackgroundProcessing</code>
- * property of an Effect to <code>true</code>,
- * <code>suspendBackgroundProcessing()</code> is automatically called
- * when it starts playing, and <code>resumeBackgroundProcessing</code>
- * is called when it stops, in order to ensure that the animation
- * is smooth.</p>
- *
- * <p>Since the LayoutManager uses <code>callLater()</code>,
- * this means that <code>commitProperties()</code>,
- * <code>measure()</code>, and <code>updateDisplayList()</code>
- * will not get called in between calls to
- * <code>suspendBackgroundProcessing()</code> and
- * <code>resumeBackgroundProcessing()</code>.</p>
- *
- * <p>It is safe for both an outer method and an inner method
- * (i.e., one that the outer methods calls) to call
- * <code>suspendBackgroundProcessing()</code>
- * and <code>resumeBackgroundProcessing()</code>, because these
- * methods actually increment and decrement a counter
- * which determines whether background processing occurs.</p>
- */
- public static function suspendBackgroundProcessing():void
- {
- UIComponentGlobals.callLaterSuspendCount++;
- }
- /**
- * Resumes the background processing of methods
- * queued by <code>callLater()</code>, after a call to
- * <code>suspendBackgroundProcessing()</code>.
- *
- * <p>Refer to the description of
- * <code>suspendBackgroundProcessing()</code> for more information.</p>
- */
- public static function resumeBackgroundProcessing():void
- {
- if (UIComponentGlobals.callLaterSuspendCount > 0)
- {
- UIComponentGlobals.callLaterSuspendCount--;
- // Once the suspend count gets back to 0, we need to
- // force a render event to happen
- if (UIComponentGlobals.callLaterSuspendCount == 0)
- {
- var sm:ISystemManager = SystemManagerGlobals.topLevelSystemManagers[0];
- if (sm && sm.stage)
- sm.stage.invalidate();
- }
- }
- }
- //--------------------------------------------------------------------------
- //
- // Constructor
- //
- //--------------------------------------------------------------------------
- /**
- * Constructor.
- */
- public function UIComponent()
- {
- super();
- // Override variables in superclasses.
- focusRect = false; // We do our own focus drawing.
- tabEnabled = (this is IFocusManagerComponent);
- // We are tab enabled by default if IFocusManagerComponent
- tabChildren = false;
- // Whether the component can accept user interaction.
- // The default is true. If you set enabled to false for a container,
- // Flex dims the color of the container and of all of its children,
- // and blocks user input to the container and to all of its children.
- // We set enabled to true here because some components keep their
- // own _enabled flag and may not initialize it to true.
- enabled = true;
- // Make the component invisible until the initialization sequence
- // is complete.
- // It will be set visible when the 'initialized' flag is set.
- $visible = false;
- addEventListener(Event.ADDED, addedHandler);
- addEventListener(Event.REMOVED, removedHandler);
- // Register for focus and keyboard events.
- if (this is IFocusManagerComponent)
- {
- addEventListener(FocusEvent.FOCUS_IN, focusInHandler);
- addEventListener(FocusEvent.FOCUS_OUT, focusOutHandler);
- addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
- addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
- }
- resourcesChanged();
- // Register as a weak listener for "change" events from ResourceManager.
- // If UIComponents registered as a strong listener,
- // they wouldn't get garbage collected.
- resourceManager.addEventListener(
- Event.CHANGE, resourceManager_changeHandler, false, 0, true);
- _width = super.width;
- _height = super.height;
- }
- //--------------------------------------------------------------------------
- //
- // Variables
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- * There is a bug (139381) where we occasionally get callLaterDispatcher()
- * even though we didn't expect it.
- * That causes us to do a removeEventListener() twice,
- * which messes up some internal thing in the player so that
- * the next addEventListener() doesn't actually get us the render event.
- */
- private var listeningForRender:Boolean = false;
- /**
- * @private
- * List of methods used by callLater().
- */
- private var methodQueue:Array /* of MethodQueueElement */ = [];
- /**
- * @private
- * Whether or not we "own" the focus graphic
- */
- private var hasFocusRect:Boolean = false;
- //--------------------------------------------------------------------------
- //
- // Variables: Creation
- //
- //--------------------------------------------------------------------------
- //----------------------------------
- // initialized
- //----------------------------------
- /**
- * @private
- * Storage for the initialized property.
- */
- private var _initialized:Boolean = false;
- [Inspectable(environment="none")]
- /**
- * A flag that determines if an object has been through all three phases
- * of layout: commitment, measurement, and layout (provided that any were required).
- */
- public function get initialized():Boolean
- {
- return _initialized;
- }
- /**
- * @private
- */
- public function set initialized(value:Boolean):void
- {
- _initialized = value;
-
- if (value)
- {
- setVisible(_visible, true);
- dispatchEvent(new FlexEvent(FlexEvent.CREATION_COMPLETE));
- }
- }
- //----------------------------------
- // processedDescriptors
- //----------------------------------
- /**
- * @private
- * Storage for the processedDescriptors property.
- */
- private var _processedDescriptors:Boolean = false;
- [Inspectable(environment="none")]
- /**
- * Set to <code>true</code> after immediate or deferred child creation,
- * depending on which one happens. For a Container object, it is set
- * to <code>true</code> at the end of
- * the <code>createComponentsFromDescriptors()</code> method,
- * meaning after the Container object creates its children from its child descriptors.
- *
- * <p>For example, if an Accordion container uses deferred instantiation,
- * the <code>processedDescriptors</code> property for the second pane of
- * the Accordion container does not become <code>true</code> until after
- * the user navigates to that pane and the pane creates its children.
- * But, if the Accordion had set the <code>creationPolicy</code> property
- * to <code>"all"</code>, the <code>processedDescriptors</code> property
- * for its second pane is set to <code>true</code> during application startup.</p>
- *
- * <p>For classes that are not containers, which do not have descriptors,
- * it is set to <code>true</code> after the <code>createChildren()</code>
- * method creates any internal component children.</p>
- */
- public function get processedDescriptors():Boolean
- {
- return _processedDescriptors;
- }
- /**
- * @private
- */
- public function set processedDescriptors(value:Boolean):void
- {
- _processedDescriptors = value;
-
- if (value)
- dispatchEvent(new FlexEvent(FlexEvent.INITIALIZE));
- }
- //----------------------------------
- // updateCompletePendingFlag
- //----------------------------------
- /**
- * @private
- * Storage for the updateCompletePendingFlag property.
- */
- private var _updateCompletePendingFlag:Boolean = false;
- [Inspectable(environment="none")]
- /**
- * A flag that determines if an object has been through all three phases
- * of layout validation (provided that any were required).
- */
- public function get updateCompletePendingFlag():Boolean
- {
- return _updateCompletePendingFlag;
- }
- /**
- * @private
- */
- public function set updateCompletePendingFlag(value:Boolean):void
- {
- _updateCompletePendingFlag = value;
- }
-
- //--------------------------------------------------------------------------
- //
- // Variables: Invalidation
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- * Whether this component needs to have its
- * commitProperties() method called.
- */
- mx_internal var invalidatePropertiesFlag:Boolean = false;
- /**
- * @private
- * Whether this component needs to have its
- * measure() method called.
- */
- mx_internal var invalidateSizeFlag:Boolean = false;
- /**
- * @private
- * Whether this component needs to be have its
- * updateDisplayList() method called.
- */
- mx_internal var invalidateDisplayListFlag:Boolean = false;
- //--------------------------------------------------------------------------
- //
- // Variables: Measurement
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- * Holds the last recorded value of the x property.
- * Used in dispatching a MoveEvent.
- */
- private var oldX:Number = 0;
- /**
- * @private
- * Holds the last recorded value of the y property.
- * Used in dispatching a MoveEvent.
- */
- private var oldY:Number = 0;
- /**
- * @private
- * Holds the last recorded value of the width property.
- * Used in dispatching a ResizeEvent.
- */
- private var oldWidth:Number = 0;
- /**
- * @private
- * Holds the last recorded value of the height property.
- * Used in dispatching a ResizeEvent.
- */
- private var oldHeight:Number = 0;
- /**
- * @private
- * Holds the last recorded value of the minWidth property.
- */
- private var oldMinWidth:Number;
- /**
- * @private
- * Holds the last recorded value of the minHeight property.
- */
- private var oldMinHeight:Number;
- /**
- * @private
- * Holds the last recorded value of the explicitWidth property.
- */
- private var oldExplicitWidth:Number;
- /**
- * @private
- * Holds the last recorded value of the explicitHeight property.
- */
- private var oldExplicitHeight:Number;
- /**
- * @private
- * Holds the last recorded value of the scaleX property.
- */
- private var oldScaleX:Number = 1.0;
- /**
- * @private
- * Holds the last recorded value of the scaleY property.
- */
- private var oldScaleY:Number = 1.0;
- /**
- * @private
- * True if createInFontContext has been called.
- */
- private var hasFontContextBeenSaved:Boolean = false;
-
- /**
- * @private
- * Holds the last recorded value of the module factory used to create the font.
- */
- private var oldEmbeddedFontContext:IFlexModuleFactory = null;
-
- /**
- * @private
- *
- * Cache last value of embedded font.
- */
- private var cachedEmbeddedFont:EmbeddedFont = null;
-
- //--------------------------------------------------------------------------
- //
- // Variables: Styles
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- */
- private var cachedTextFormat:UITextFormat;
- //--------------------------------------------------------------------------
- //
- // Variables: Effects
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- * Sprite used to display an overlay.
- */
- mx_internal var overlay:UIComponent;
- /**
- * @private
- * Color used for overlay.
- */
- mx_internal var overlayColor:uint;
- /**
- * @private
- * Counter to keep track of the number of current users
- * of the overlay.
- */
- mx_internal var overlayReferenceCount:int = 0;
- //--------------------------------------------------------------------------
- //
- // Variables: Validation
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- */
- mx_internal var saveBorderColor:Boolean = true;
- /**
- * @private
- */
- mx_internal var origBorderColor:Number;
- //--------------------------------------------------------------------------
- //
- // Variables: Other
- //
- //--------------------------------------------------------------------------
- /**
- * @private
- * Storage for automatically-created RadioButtonGroups.
- * If a RadioButton's groupName isn't the id of a RadioButtonGroup tag,
- * we automatically create a RadioButtonGroup and store it here as
- * document.automaticRadioButtonGroups[groupName] = theRadioButtonGroup;
- */
- mx_internal var automaticRadioButtonGroups:Object;
- //--------------------------------------------------------------------------
- //
- // Overridden properties
- //
- //--------------------------------------------------------------------------
- //----------------------------------
- // owner
- //----------------------------------
- /**
- * @private
- */
- private var _owner:DisplayObjectContainer;
- /**
- * The owner of this UIComponent. By default, it is the parent of this UIComponent.
- * However, if this UIComponent object is a child component that is
- * popped up by its parent, such as the dropdown list of a ComboBox control,
- * the owner is the component that popped up this UIComponent object.
- *
- * <p>This property is not managed by Flex, but by each component.
- * Therefore, if you use the <code>PopUpManger.createPopUp()</code> or
- * <code>PopUpManger.addPopUp()</code> method to pop up a child component,
- * you should set the <code>owner</code> property of the child component
- * to the component that popped it up.</p>
- *
- * <p>The default value is the value of the <code>parent</code> property.</p>
- */
- public function get owner():DisplayObjectContainer
- {
- return _owner ? _owner : parent;
- }
- public function set owner(value:DisplayObjectContainer):void
- {
- _owner = value;
- }
- //----------------------------------
- // parent
- //----------------------------------
- /**
- * @private
- * Reference to this component's virtual parent container.
- * "Virtual" means that this parent may not be the same
- * as the one that the Player returns as the 'parent'
- * property of a DisplayObject.
- * For example, if a Container has created a contentPane
- * to improve scrolling performance,
- * then its "children" are really its grandchildren
- * and their "parent" is actually their grandparent,
- * because we don't want developers to be concerned with
- * whether a contentPane exists or not.
- */
- mx_internal var _parent:DisplayObjectContainer;
- /**
- * The parent container or component for this component.
- * Only UIComponent objects should have a parent property.
- * Non-UIComponent objects should use another property to reference
- * the object to which they belong.
- * By convention, non-UIComponent objects use an <code>owner</code>
- * property to reference the object to which they b…