| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package mx.core |
| { |
| import flash.accessibility.Accessibility; |
| import flash.accessibility.AccessibilityProperties; |
| import flash.display.BlendMode; |
| 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.Shader; |
| 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.ColorTransform; |
| import flash.geom.Matrix; |
| import flash.geom.Matrix3D; |
| import flash.geom.PerspectiveProjection; |
| import flash.geom.Point; |
| import flash.geom.Rectangle; |
| import flash.geom.Transform; |
| import flash.geom.Vector3D; |
| import flash.system.ApplicationDomain; |
| import flash.system.Capabilities; |
| import flash.text.TextFormatAlign; |
| import flash.text.TextLineMetrics; |
| import flash.ui.Keyboard; |
| import flash.utils.Dictionary; |
| import flash.utils.getQualifiedClassName; |
| |
| import mx.automation.IAutomationObject; |
| import mx.binding.Binding; |
| import mx.binding.BindingManager; |
| import mx.binding.FunctionReturnWatcher; |
| import mx.binding.PropertyWatcher; |
| import mx.binding.StaticPropertyWatcher; |
| import mx.binding.Watcher; |
| import mx.binding.XMLWatcher; |
| import mx.controls.IFlexContextMenu; |
| import mx.core.LayoutDirection; |
| import mx.effects.EffectManager; |
| import mx.effects.IEffect; |
| import mx.effects.IEffectInstance; |
| import mx.events.ChildExistenceChangedEvent; |
| 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.ValidationResultEvent; |
| import mx.filters.BaseFilter; |
| import mx.filters.IBitmapFilter; |
| import mx.geom.RoundedRectangle; |
| import mx.geom.Transform; |
| import mx.geom.TransformOffsets; |
| import mx.graphics.shaderClasses.ColorBurnShader; |
| import mx.graphics.shaderClasses.ColorDodgeShader; |
| import mx.graphics.shaderClasses.ColorShader; |
| import mx.graphics.shaderClasses.ExclusionShader; |
| import mx.graphics.shaderClasses.HueShader; |
| import mx.graphics.shaderClasses.LuminosityShader; |
| import mx.graphics.shaderClasses.SaturationShader; |
| import mx.graphics.shaderClasses.SoftLightShader; |
| 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.ToolTipManager; |
| import mx.resources.IResourceManager; |
| import mx.resources.ResourceManager; |
| import mx.states.State; |
| import mx.states.Transition; |
| import mx.styles.CSSStyleDeclaration; |
| import mx.styles.IAdvancedStyleClient; |
| import mx.styles.ISimpleStyleClient; |
| import mx.styles.IStyleClient; |
| import mx.styles.IStyleManager2; |
| import mx.styles.StyleManager; |
| import mx.styles.StyleProtoChain; |
| import mx.utils.ColorUtil; |
| import mx.utils.GraphicsUtil; |
| import mx.utils.MatrixUtil; |
| import mx.utils.NameUtil; |
| import mx.utils.StringUtil; |
| import mx.utils.TransformUtil; |
| import mx.validators.IValidatorListener; |
| import mx.validators.ValidationResult; |
| |
| use namespace mx_internal; |
| |
| // Excluding the property to enable code hinting for the layoutDirection style |
| [Exclude(name="layoutDirection", kind="property")] |
| |
| //-------------------------------------- |
| // Lifecycle events |
| //-------------------------------------- |
| |
| /** |
| * Dispatched when the component is added to a container as a content child |
| * by using the <code>addChild()</code>, <code>addChildAt()</code>, |
| * <code>addElement()</code>, or <code>addElementAt()</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. |
| * |
| * <p>This event is only dispatched when there are one or more relevant listeners |
| * attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.ADD |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 is not visible even though it has been drawn.</p> |
| * |
| * @eventType mx.events.FlexEvent.CREATION_COMPLETE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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> |
| * |
| * <p>This event is only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.UPDATE_COMPLETE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="updateComplete", type="mx.events.FlexEvent")] |
| |
| /** |
| * Dispatched when an object's state changes from visible to invisible. |
| * |
| * <p>This event is only dispatched when there are one or more relevant listeners |
| * attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.HIDE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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> |
| * |
| * <p>This event only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.MoveEvent.MOVE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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>, <code>removeChildAt()</code>, |
| * <code>removeElement()</code>, or <code>removeElementAt()</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. |
| * |
| * <p>This event only dispatched when there are one or more relevant listeners |
| * attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.REMOVE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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> |
| * |
| * <p>This event only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.ResizeEvent.RESIZE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="resize", type="mx.events.ResizeEvent")] |
| |
| /** |
| * Dispatched when an object's state changes from invisible to visible. |
| * |
| * <p>This event is only dispatched when there are one or more relevant listeners |
| * attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.SHOW |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 do 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 can 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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>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 can 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="effectStart", type="mx.events.EffectEvent")] |
| |
| /** |
| * Dispatched after an effect is stopped, which happens |
| * only by a call to <code>stop()</code> on the effect. |
| * |
| * <p>The effect then dispatches the EFFECT_END event |
| * as the effect finishes. The purpose of the EFFECT_STOP |
| * event is to let listeners know that the effect came to |
| * a premature end, rather than ending naturally or as a |
| * result of a call to <code>end()</code>.</p> |
| * |
| * @eventType mx.events.EffectEvent.EFFECT_STOP |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="effectStop", type="mx.events.EffectEvent")] |
| |
| /** |
| * Dispatched after an effect ends. |
| * |
| * <p>The effect makes the last set of visual changes |
| * before this event is fired, but those changes are not |
| * 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="effectEnd", type="mx.events.EffectEvent")] |
| |
| |
| //-------------------------------------- |
| // State events |
| //-------------------------------------- |
| |
| /** |
| * Dispatched after the <code>currentState</code> property changes, |
| * but before the view state changes. |
| * |
| * <p>This event is only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.StateChangeEvent.CURRENT_STATE_CHANGING |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="currentStateChanging", type="mx.events.StateChangeEvent")] |
| |
| /** |
| * Dispatched after the view state has changed. |
| * |
| * <p>This event is only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.StateChangeEvent.CURRENT_STATE_CHANGE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="currentStateChange", type="mx.events.StateChangeEvent")] |
| |
| /** |
| * Dispatched after the component has entered a view state. |
| * |
| * <p>This event is only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.ENTER_STATE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="enterState", type="mx.events.FlexEvent")] |
| |
| /** |
| * Dispatched just before the component exits a view state. |
| * |
| * <p>This event is only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.EXIT_STATE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="exitState", type="mx.events.FlexEvent")] |
| |
| /** |
| * Dispatched after the component has entered a new state and |
| * any state transition animation to that state has finished playing. |
| * |
| * The event is dispatched immediately if there's no transition playing |
| * between the states. |
| * |
| * If the component switches to a different state while the transition is |
| * underway, this event will be dispatched after the component completes the |
| * transition to that new state. |
| * |
| * <p>This event is only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.STATE_CHANGE_COMPLETE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Event(name="stateChangeComplete", type="mx.events.FlexEvent")] |
| |
| /** |
| * Dispatched when a component interrupts a transition to its current |
| * state in order to switch to a new state. |
| * |
| * <p>This event is only dispatched when there are one or more |
| * relevant listeners attached to the dispatching object.</p> |
| * |
| * @eventType mx.events.FlexEvent.STATE_CHANGE_INTERRUPTED |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Event(name="stateChangeInterrupted", type="mx.events.FlexEvent")] |
| |
| |
| //-------------------------------------- |
| // TouchInteraction events |
| //-------------------------------------- |
| |
| /** |
| * A cancellable event, dispatched by a component in an attempt to |
| * respond to a touch interaction user gesture. |
| * |
| * <p>The event is a bubbling event dispatched on the |
| * DisplayObject that the touch interaction |
| * started (where the mouseDown/touchBegin occurred).</p> |
| * |
| * <p>Components responding to touch interactions should listen for |
| * touch interaction events to coordinate with other components around |
| * what type of touch interaction the user intended to make and which component |
| * is responding to that touch interaction.</p> |
| * |
| * <p>A Scroller component will dispatch a touchInteractionStarting event |
| * to alert other components that may be responding to the same user's |
| * touch interaction that it would like to take control of this touch interaction. |
| * This is an opportunity for other components to cancel the Scroller's |
| * action and to maintain control over this touch interaction.</p> |
| * |
| * @eventType mx.events.TouchInteractionEvent.TOUCH_INTERACTION_STARTING |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Event(name="touchInteractionStarting", type="mx.events.TouchInteractionEvent")] |
| |
| /** |
| * A non-cancellable event, dispatched by a component when it starts |
| * responding to a touch interaction user gesture. |
| * |
| * <p>The event is a bubbling event dispatched on the |
| * DisplayObject that the touch interaction |
| * started (where the mouseDown/touchBegin occurred).</p> |
| * |
| * <p>Components responding to touch interactions should listen for |
| * touch interaction events to coordinate with other components around |
| * what type of touch interaction the user intended to make and which component |
| * is responding to that touch interaction.</p> |
| * |
| * <p>A Scroller component will dispatch a touchInteractionStart event |
| * to alert other components that may be responding to the same user's |
| * touch interaction that it is taking control of this touch interaction. |
| * When they see this event, other components should stop responding |
| * to the touch interaction, remove any visual indications that it is |
| * responding to the touch interaction, and perform other clean up.</p> |
| * |
| * @eventType mx.events.TouchInteractionEvent.TOUCH_INTERACTION_START |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Event(name="touchInteractionStart", type="mx.events.TouchInteractionEvent")] |
| |
| /** |
| * A non-cancellable event, dispatched by a component when it is done |
| * responding to a touch interaction user gesture. |
| * |
| * <p>The event is a bubbling event dispatched on the |
| * DisplayObject that the touch interaction |
| * started (where the mouseDown/touchBegin occurred).</p> |
| * |
| * <p>Components responding to touch interactions should listen for |
| * touch interaction events to coordinate with other components around |
| * what type of touch interaction the user intended to make and which component |
| * is responding to that touch interaction.</p> |
| * |
| * <p>A Scroller component will dispatch a touchInteractionEnd event |
| * to alert other components that it is done responding to the user's |
| * touch interaction.</p> |
| * |
| * @eventType mx.events.TouchInteractionEvent.TOUCH_INTERACTION_END |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Event(name="touchInteractionEnd", type="mx.events.TouchInteractionEvent")] |
| |
| //-------------------------------------- |
| // 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="toolTipCreate", type="mx.events.ToolTipEvent")] |
| |
| /** |
| * Dispatched by the component when its ToolTip has been hidden |
| * and is to 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Event(name="toolTipStart", type="mx.events.ToolTipEvent")] |
| |
| //-------------------------------------- |
| // Styles |
| //-------------------------------------- |
| |
| include "../styles/metadata/AnchorStyles.as"; |
| |
| /** |
| * The main color for a component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="chromeColor", type="uint", format="Color", inherit="yes", theme="spark")] |
| |
| /** |
| * 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. |
| * |
| * The default value for the Halo theme is <code>0xFF0000</code>. |
| * The default value for the Spark theme is <code>0xFE0000</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="errorColor", type="uint", format="Color", inherit="yes")] |
| |
| /** |
| * The primary interaction mode for this component. The acceptable values are: |
| * <code>mouse</code> and <code>touch</code>. |
| * |
| * The default value for the Halo theme is <code>mouse</code>. |
| * The default value for the Spark theme is <code>mouse</code>. |
| * The default value for the Mobile theme is <code>touch</code>. |
| * |
| * @see mx.core.InteractionMode#MOUSE |
| * @see mx.core.InteractionMode#TOUCH |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Style(name="interactionMode", type="String", enumeration="mouse,touch", 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" |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="focusBlendMode", type="String", inherit="no")] |
| |
| /** |
| * Skin used to draw the focus rectangle. |
| * |
| * The default value for Halo components is mx.skins.halo.HaloFocusRect. |
| * The default value for Spark components is spark.skins.spark.FocusSkin. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="focusSkin", type="Class", inherit="no")] |
| |
| /** |
| * Thickness, in pixels, of the focus rectangle outline. |
| * |
| * @default 2 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="focusThickness", type="Number", format="Length", inherit="no", minValue="0.0")] |
| |
| /** |
| * Specifies the desired layout direction of a component. The allowed values |
| * are <code>"ltr"</code> for left-to-right layout, used for |
| * components using Latin-style scripts, and <code>"rtl"</code> for |
| * right-to-left layout, used for components using scripts such |
| * as Arabic and Hebrew. |
| * |
| * <p>In ActionScript you can set the layoutDirection using the values |
| * <code>mx.core.LayoutDirection.LTR</code>, |
| * <code>mx.core.LayoutDirection.RTL</code> or |
| * <code>undefined</code>, to inherit the layoutDirection from the parent.</p> |
| * |
| * <p>The layoutDirection should typically be set on the |
| * <code>Application</code> rather than on individual components. If the |
| * layoutDirection is <code>"rtl"</code>, most visual elements, except text |
| * and images, will be mirrored. The directionality of text is determined |
| * by the <code>direction</code> style.</p> |
| * |
| * <p>Components which handle Keyboard.LEFT and Keyboard.RIGHT events |
| * typically swap the key’s meaning when layoutDirection is |
| * <code>“rtl”</code>. In other words, left always means move left and |
| * right always means move right, regardless of the |
| * <code>layoutDirection</code></p> |
| * |
| * <p>Note: This style applies to all Spark components and MX components that |
| * specify UIFTETextField as their textFieldClass.</p> |
| * |
| * @default "ltr" |
| * |
| * @see MXFTEText.css |
| * @see mx.core.ILayoutDirectionElement |
| * @see mx.core.LayoutDirection |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4.1 |
| */ |
| [Style(name="layoutDirection", type="String", enumeration="ltr,rtl", inherit="yes")] |
| |
| /** |
| * Show the error border or skin when this component is invalid |
| * |
| * @default true |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4.5 |
| */ |
| [Style(name="showErrorSkin", type="Boolean", inherit="yes")] |
| |
| /** |
| * Show the error tip when this component is invalid and the user |
| * rolls over it |
| * |
| * @default true |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4.5 |
| */ |
| [Style(name="showErrorTip", type="Boolean", inherit="yes")] |
| |
| /** |
| * 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" |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Style(name="themeColor", type="uint", format="Color", inherit="yes", theme="halo")] |
| |
| //-------------------------------------- |
| // Effects |
| //-------------------------------------- |
| |
| /** |
| * Played when the component is created. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="creationCompleteEffect", event="creationComplete")] |
| |
| /** |
| * Played when the component is moved. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="moveEffect", event="move")] |
| |
| /** |
| * Played when the component is resized. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="resizeEffect", event="resize")] |
| |
| /** |
| * Played when the component becomes visible. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="showEffect", event="show")] |
| |
| /** |
| * Played when the component becomes invisible. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="hideEffect", event="hide")] |
| |
| /** |
| * Played when the user presses the mouse button while over the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="mouseDownEffect", event="mouseDown")] |
| |
| /** |
| * Played when the user releases the mouse button while over the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="mouseUpEffect", event="mouseUp")] |
| |
| /** |
| * Played when the user rolls the mouse over the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="rollOverEffect", event="rollOver")] |
| |
| /** |
| * Played when the user rolls the mouse so it is no longer over the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="rollOutEffect", event="rollOut")] |
| |
| /** |
| * Played when the component gains keyboard focus. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="focusInEffect", event="focusIn")] |
| |
| /** |
| * Played when the component loses keyboard focus. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="focusOutEffect", event="focusOut")] |
| |
| /** |
| * Played when the component is added as a child to a Container. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="addedEffect", event="added")] |
| |
| /** |
| * Played when the component is removed from a Container. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| [Effect(name="removedEffect", event="removed")] |
| |
| //-------------------------------------- |
| // Other metadata |
| //-------------------------------------- |
| |
| [AccessibilityClass(implementation="mx.accessibility.UIComponentAccProps")] |
| |
| [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> |
| * accessibilityDescription="null" |
| * accessibilityName="null" |
| * accessibilityShortcut="null" |
| * accessibilitySilent="true|false" |
| * 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" |
| * hasFocusableChildren="false|true" |
| * 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" |
| * layoutDirection="ltr" |
| * 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>" |
| * 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public class UIComponent extends FlexSprite |
| implements IAutomationObject, IChildList, IConstraintClient, |
| IDeferredInstantiationUIComponent, IFlexDisplayObject, IFlexModule, |
| IInvalidating, ILayoutManagerClient, IPropertyChangeNotifier, |
| IRepeaterClient, IStateClient, IAdvancedStyleClient, IToolTipManagerClient, |
| IUIComponent, IValidatorListener, IVisualElement |
| { |
| 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public static const DEFAULT_MEASURED_MIN_HEIGHT:Number = 22; |
| |
| /** |
| * The default value for the <code>maxWidth</code> property. |
| * |
| * @default 10000 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public static const DEFAULT_MAX_WIDTH:Number = 10000; |
| // When changing this constant, make sure you change |
| // the constant with the same name in LayoutElementUIComponentUtils |
| |
| /** |
| * The default value for the <code>maxHeight</code> property. |
| * |
| * @default 10000 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public static const DEFAULT_MAX_HEIGHT:Number = 10000; |
| // When changing this constant, make sure you change |
| // the constant with the same name in LayoutElementUIComponentUtils |
| |
| /** |
| * @private |
| * Static constant representing no cached layout direction style value. |
| */ |
| private static const LAYOUT_DIRECTION_CACHE_UNSET:String = "layoutDirectionCacheUnset"; |
| |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class mixins |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Placeholder for mixin by UIComponentAccProps. |
| */ |
| mx_internal static var createAccessibilityImplementation:Function; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // embeddedFontRegistry |
| //---------------------------------- |
| |
| private static var noEmbeddedFonts:Boolean; |
| |
| /** |
| * @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. |
| */ |
| mx_internal static function get embeddedFontRegistry():IEmbeddedFontRegistry |
| { |
| if (!_embeddedFontRegistry && !noEmbeddedFonts) |
| { |
| try |
| { |
| _embeddedFontRegistry = IEmbeddedFontRegistry( |
| Singleton.getInstance("mx.core::IEmbeddedFontRegistry")); |
| } |
| catch (e:Error) |
| { |
| noEmbeddedFonts = true; |
| } |
| } |
| |
| 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> |
| * is not 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> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function UIComponent() |
| { |
| super(); |
| |
| // Override variables in superclasses. |
| focusRect = false; // We do our own focus drawing. |
| // We are tab enabled by default if IFocusManagerComponent |
| tabEnabled = (this is IFocusManagerComponent); |
| tabFocusEnabled = (this is IFocusManagerComponent); |
| |
| // 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); |
| addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler); |
| |
| // 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 |
| * Temporarily stores the values of styles specified with setStyle() until |
| * moduleFactory is set. |
| */ |
| private var deferredSetStyles:Object; |
| |
| /** |
| * @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; |
| |
| /** |
| * @private |
| * These variables cache the transition state from/to information for |
| * the transition currently running. This information is used when |
| * determining what to do with a new transition that interrupts the |
| * running transition. |
| */ |
| private var transitionFromState:String; |
| private var transitionToState:String; |
| |
| /** |
| * @private |
| */ |
| private var parentChangedFlag:Boolean = false; |
| |
| /** |
| * @private |
| * Cached layout direction style |
| */ |
| private var layoutDirectionCachedValue:String = LAYOUT_DIRECTION_CACHE_UNSET; |
| |
| /** |
| * @private |
| * Whether or not we've processed the MXMLDescriptors |
| */ |
| mx_internal var processedMXMLDescriptors: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). |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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). |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get updateCompletePendingFlag():Boolean |
| { |
| return _updateCompletePendingFlag; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set updateCompletePendingFlag(value:Boolean):void |
| { |
| _updateCompletePendingFlag = value; |
| } |
| |
| //------------------------------------------------------------------------ |
| // |
| // Properties: Accessibility |
| // |
| //------------------------------------------------------------------------ |
| |
| /** |
| * A convenience accessor for the <code>silent</code> property |
| * in this UIComponent's <code>accessibilityProperties</code> object. |
| * |
| * <p>Note that <code>accessibilityEnabled</code> has the opposite sense from silent; |
| * <code>accessibilityEnabled</code> is <code>true</code> |
| * when <code>silent</code> is <code>false</code>.</p> |
| * |
| * <p>The getter simply returns <code>accessibilityProperties.silent</code>, |
| * or <code>true</code> if <code>accessibilityProperties</code> is null. |
| * The setter first checks whether <code>accessibilityProperties</code> is null, |
| * and if it is, sets it to a new AccessibilityProperties instance. |
| * Then it sets <code>accessibilityProperties.silent</code>.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get accessibilityEnabled():Boolean |
| { |
| return accessibilityProperties ? !accessibilityProperties.silent : true; |
| } |
| |
| public function set accessibilityEnabled(value:Boolean):void |
| { |
| if (!Capabilities.hasAccessibility) |
| return; |
| |
| if (!accessibilityProperties) |
| accessibilityProperties = new AccessibilityProperties(); |
| |
| accessibilityProperties.silent = !value; |
| Accessibility.updateProperties(); |
| } |
| |
| /** |
| * A convenience accessor for the <code>name</code> property |
| * in this UIComponent's <code>accessibilityProperties</code> object. |
| * |
| * <p>The getter simply returns <code>accessibilityProperties.name</code>, |
| * or "" if accessibilityProperties is null. |
| * The setter first checks whether <code>accessibilityProperties</code> is null, |
| * and if it is, sets it to a new AccessibilityProperties instance. |
| * Then it sets <code>accessibilityProperties.name</code>.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get accessibilityName():String |
| { |
| return accessibilityProperties ? accessibilityProperties.name : ""; |
| } |
| |
| public function set accessibilityName(value:String):void |
| { |
| if (!Capabilities.hasAccessibility) |
| return; |
| |
| if (!accessibilityProperties) |
| accessibilityProperties = new AccessibilityProperties(); |
| |
| accessibilityProperties.name = value; |
| Accessibility.updateProperties(); |
| } |
| |
| /** |
| * A convenience accessor for the <code>description</code> property |
| * in this UIComponent's <code>accessibilityProperties</code> object. |
| * |
| * <p>The getter simply returns <code>accessibilityProperties.description</code>, |
| * or "" if <code>accessibilityProperties</code> is null. |
| * The setter first checks whether <code>accessibilityProperties</code> is null, |
| * and if it is, sets it to a new AccessibilityProperties instance. |
| * Then it sets <code>accessibilityProperties.description</code>.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get accessibilityDescription():String |
| { |
| return accessibilityProperties ? accessibilityProperties.description : ""; |
| } |
| |
| public function set accessibilityDescription(value:String):void |
| { |
| if (!Capabilities.hasAccessibility) |
| return; |
| |
| if (!accessibilityProperties) |
| accessibilityProperties = new AccessibilityProperties(); |
| |
| accessibilityProperties.description = value; |
| Accessibility.updateProperties(); |
| } |
| |
| /** |
| * A convenience accessor for the <code>shortcut</code> property |
| * in this UIComponent's <code>accessibilityProperties</code> object. |
| * |
| * <p>The getter simply returns <code>accessibilityProperties.shortcut</code>, |
| * or "" if <code>accessibilityProperties</code> is null. |
| * The setter first checks whether <code>accessibilityProperties</code> is null, |
| * and if it is, sets it to a new AccessibilityProperties instance. |
| * Then it sets <code>accessibilityProperties.shortcut</code>.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get accessibilityShortcut():String |
| { |
| return accessibilityProperties ? accessibilityProperties.shortcut : ""; |
| } |
| |
| public function set accessibilityShortcut(value:String):void |
| { |
| if (!Capabilities.hasAccessibility) |
| return; |
| |
| if (!accessibilityProperties) |
| accessibilityProperties = new AccessibilityProperties(); |
| |
| accessibilityProperties.shortcut = value; |
| Accessibility.updateProperties(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // 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; |
| |
| /** |
| * @private |
| * Whether setActualSize() has been called on this component |
| * at least once. This is used in validateBaselinePosition() |
| * to resize the component to explicit or measured |
| * size if baselinePosition getter is called before the |
| * component has been resized by the layout. |
| */ |
| mx_internal var setActualSizeCalled: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 |
| * |
| * storage for advanced layout and transform properties. |
| */ |
| mx_internal var _layoutFeatures:AdvancedLayoutFeatures; |
| |
| /** |
| * @private |
| * |
| * storage for the modified Transform object that can dispatch change events correctly. |
| */ |
| private var _transform:flash.geom.Transform; |
| //-------------------------------------------------------------------------- |
| // |
| // Variables: Styles |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var cachedTextFormat:UITextFormat; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Variables: Effects |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Sprite used to display an overlay. |
| */ |
| mx_internal var effectOverlay:UIComponent; |
| |
| /** |
| * @private |
| * Color used for overlay. |
| */ |
| mx_internal var effectOverlayColor:uint; |
| |
| /** |
| * @private |
| * Counter to keep track of the number of current users |
| * of the overlay. |
| */ |
| mx_internal var effectOverlayReferenceCount: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; |
| |
| private var _usingBridge:int = -1; |
| |
| /** |
| * @private |
| */ |
| private function get usingBridge():Boolean |
| { |
| if (_usingBridge == 0) return false; |
| if (_usingBridge == 1) return true; |
| |
| if (!_systemManager) return false; |
| |
| // no types so no dependencies |
| var mp:Object = _systemManager.getImplementation("mx.managers::IMarshalSystemManager"); |
| if (!mp) |
| { |
| _usingBridge = 0; |
| return false; |
| } |
| if (mp.useSWFBridge()) |
| { |
| _usingBridge = 1; |
| return true; |
| } |
| _usingBridge = 0; |
| return false; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // owner |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| mx_internal var _owner:DisplayObjectContainer; |
| |
| /** |
| * @copy mx.core.IVisualElement#owner |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| 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; |
| |
| /** |
| * @copy mx.core.IVisualElement#parent |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get parent():DisplayObjectContainer |
| { |
| // Flash PlaceObject tags can have super.parent set |
| // before we get to setting the _parent property. |
| try |
| { |
| return _parent ? _parent : super.parent; |
| } |
| catch (e:SecurityError) |
| { |
| // trace("UIComponent.get parent(): " + e); |
| } |
| |
| return null; |
| } |
| |
| //---------------------------------- |
| // x |
| //---------------------------------- |
| |
| [Bindable("xChanged")] |
| [Inspectable(category="General")] |
| |
| /** |
| * Number that specifies the component's horizontal position, |
| * in pixels, within its parent container. |
| * |
| * <p>Setting this property directly or calling <code>move()</code> |
| * has no effect -- or only a temporary effect -- if the |
| * component is parented by a layout container such as HBox, Grid, |
| * or Form, because the layout calculations of those containers |
| * set the <code>x</code> position to the results of the calculation. |
| * However, the <code>x</code> property must almost always be set |
| * when the parent is a Canvas or other absolute-positioning |
| * container because the default value is 0.</p> |
| * |
| * @default 0 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get x():Number |
| { |
| return (_layoutFeatures == null) ? super.x : _layoutFeatures.layoutX; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set x(value:Number):void |
| { |
| if (x == value) |
| return; |
| |
| if (_layoutFeatures == null) |
| { |
| super.x = value; |
| } |
| else |
| { |
| _layoutFeatures.layoutX = value; |
| invalidateTransform(); |
| } |
| |
| invalidateProperties(); |
| |
| if (parent && parent is UIComponent) |
| UIComponent(parent).childXYChanged(); |
| |
| if (hasEventListener("xChanged")) |
| dispatchEvent(new Event("xChanged")); |
| } |
| |
| [Bindable("zChanged")] |
| [Inspectable(category="General")] |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 3 |
| */ |
| override public function get z():Number |
| { |
| return (_layoutFeatures == null) ? super.z : _layoutFeatures.layoutZ; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set z(value:Number):void |
| { |
| if (z == value) |
| return; |
| |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| |
| _layoutFeatures.layoutZ = value; |
| invalidateTransform(); |
| invalidateProperties(); |
| if (was3D != is3D) |
| validateMatrix(); |
| |
| if (hasEventListener("zChanged")) |
| dispatchEvent(new Event("zChanged")); |
| } |
| |
| /** |
| * Sets the x coordinate for the transform center of the component. |
| * |
| * <p>When this component is the target of a Spark transform effect, |
| * you can override this property by setting |
| * the <code>AnimateTransform.autoCenterTransform</code> property. |
| * If <code>autoCenterTransform</code> is <code>false</code>, the transform |
| * center is determined by the <code>transformX</code>, |
| * <code>transformY</code>, and <code>transformZ</code> properties |
| * of the effect target. |
| * If <code>autoCenterTransform</code> is <code>true</code>, |
| * the effect occurs around the center of the target, |
| * <code>(width/2, height/2)</code>.</p> |
| * |
| * <p>Setting this property on the Spark effect class |
| * overrides the setting on the target component.</p> |
| * |
| * @see spark.effects.AnimateTransform#autoCenterTransform |
| * @see spark.effects.AnimateTransform#transformX |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get transformX():Number |
| { |
| return (_layoutFeatures == null) ? 0 : _layoutFeatures.transformX; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set transformX(value:Number):void |
| { |
| if (transformX == value) |
| return; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| _layoutFeatures.transformX = value; |
| invalidateTransform(); |
| invalidateProperties(); |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| /** |
| * Sets the y coordinate for the transform center of the component. |
| * |
| * <p>When this component is the target of a Spark transform effect, |
| * you can override this property by setting |
| * the <code>AnimateTransform.autoCenterTransform</code> property. |
| * If <code>autoCenterTransform</code> is <code>false</code>, the transform |
| * center is determined by the <code>transformX</code>, |
| * <code>transformY</code>, and <code>transformZ</code> properties |
| * of the effect target. |
| * If <code>autoCenterTransform</code> is <code>true</code>, |
| * the effect occurs around the center of the target, |
| * <code>(width/2, height/2)</code>.</p> |
| * |
| * <p>Seeting this property on the Spark effect class |
| * overrides the setting on the target component.</p> |
| * |
| * @see spark.effects.AnimateTransform#autoCenterTransform |
| * @see spark.effects.AnimateTransform#transformY |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get transformY():Number |
| { |
| return (_layoutFeatures == null) ? 0 : _layoutFeatures.transformY; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set transformY(value:Number):void |
| { |
| if (transformY == value) |
| return; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| _layoutFeatures.transformY = value; |
| invalidateTransform(); |
| invalidateProperties(); |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| /** |
| * Sets the z coordinate for the transform center of the component. |
| * |
| * <p>When this component is the target of a Spark transform effect, |
| * you can override this property by setting |
| * the <code>AnimateTransform.autoCenterTransform</code> property. |
| * If <code>autoCenterTransform</code> is <code>false</code>, the transform |
| * center is determined by the <code>transformX</code>, |
| * <code>transformY</code>, and <code>transformZ</code> properties |
| * of the effect target. |
| * If <code>autoCenterTransform</code> is <code>true</code>, |
| * the effect occurs around the center of the target, |
| * <code>(width/2, height/2)</code>.</p> |
| * |
| * <p>Seeting this property on the Spark effect class |
| * overrides the setting on the target component.</p> |
| * |
| * @see spark.effects.AnimateTransform#autoCenterTransform |
| * @see spark.effects.AnimateTransform#transformZ |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get transformZ():Number |
| { |
| return (_layoutFeatures == null) ? 0 : _layoutFeatures.transformZ; |
| } |
| /** |
| * @private |
| */ |
| public function set transformZ(value:Number):void |
| { |
| if (transformZ == value) |
| return; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| |
| _layoutFeatures.transformZ = value; |
| invalidateTransform(); |
| invalidateProperties(); |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| /** |
| * @copy mx.core.IFlexDisplayObject#rotation |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get rotation():Number |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| return super.rotation; |
| return (_layoutFeatures == null) ? super.rotation : _layoutFeatures.layoutRotationZ; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set rotation(value:Number):void |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| super.rotation = value; |
| return; |
| } |
| |
| if (rotation == value) |
| return; |
| |
| _hasComplexLayoutMatrix = true; |
| if (_layoutFeatures == null) |
| { |
| // clamp the rotation value between -180 and 180. This is what |
| // the Flash player does and what we mimic in CompoundTransform; |
| // however, the Flash player doesn't handle values larger than |
| // 2^15 - 1 (FP-749), so we need to clamp even when we're |
| // just setting super.rotation. |
| super.rotation = MatrixUtil.clampRotation(value); |
| } |
| else |
| { |
| _layoutFeatures.layoutRotationZ = value; |
| } |
| |
| invalidateTransform(); |
| invalidateProperties(); |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get rotationZ():Number |
| { |
| return rotation; |
| } |
| /** |
| * @private |
| */ |
| override public function set rotationZ(value:Number):void |
| { |
| rotation = value; |
| } |
| |
| /** |
| * Indicates the x-axis rotation of the DisplayObject instance, in degrees, from its original orientation |
| * relative to the 3D parent container. Values from 0 to 180 represent clockwise rotation; values |
| * from 0 to -180 represent counterclockwise rotation. Values outside this range are added to or subtracted from |
| * 360 to obtain a value within the range. |
| * |
| * This property is ignored during calculation by any of Flex's 2D layouts. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 3 |
| */ |
| override public function get rotationX():Number |
| { |
| return (_layoutFeatures == null) ? super.rotationX : _layoutFeatures.layoutRotationX; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set rotationX(value:Number):void |
| { |
| if (rotationX == value) |
| return; |
| |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| _layoutFeatures.layoutRotationX = value; |
| invalidateTransform(); |
| invalidateProperties(); |
| invalidateParentSizeAndDisplayList(); |
| if (was3D != is3D) |
| validateMatrix(); |
| } |
| |
| /** |
| * Indicates the y-axis rotation of the DisplayObject instance, in degrees, from its original orientation |
| * relative to the 3D parent container. Values from 0 to 180 represent clockwise rotation; values |
| * from 0 to -180 represent counterclockwise rotation. Values outside this range are added to or subtracted from |
| * 360 to obtain a value within the range. |
| * |
| * This property is ignored during calculation by any of Flex's 2D layouts. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get rotationY():Number |
| { |
| return (_layoutFeatures == null) ? super.rotationY : _layoutFeatures.layoutRotationY; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set rotationY(value:Number):void |
| { |
| if (rotationY == value) |
| return; |
| |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| _layoutFeatures.layoutRotationY = value; |
| invalidateTransform(); |
| invalidateProperties(); |
| invalidateParentSizeAndDisplayList(); |
| if (was3D != is3D) |
| validateMatrix(); |
| } |
| |
| //---------------------------------- |
| // y |
| //---------------------------------- |
| |
| [Bindable("yChanged")] |
| [Inspectable(category="General")] |
| |
| /** |
| * Number that specifies the component's vertical position, |
| * in pixels, within its parent container. |
| * |
| * <p>Setting this property directly or calling <code>move()</code> |
| * has no effect -- or only a temporary effect -- if the |
| * component is parented by a layout container such as HBox, Grid, |
| * or Form, because the layout calculations of those containers |
| * set the <code>x</code> position to the results of the calculation. |
| * However, the <code>x</code> property must almost always be set |
| * when the parent is a Canvas or other absolute-positioning |
| * container because the default value is 0.</p> |
| * |
| * @default 0 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get y():Number |
| { |
| return (_layoutFeatures == null) ? super.y : _layoutFeatures.layoutY; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set y(value:Number):void |
| { |
| if (y == value) |
| return; |
| |
| if (_layoutFeatures == null) |
| { |
| super.y = value; |
| } |
| else |
| { |
| _layoutFeatures.layoutY = value; |
| invalidateTransform(); |
| } |
| invalidateProperties(); |
| |
| if (parent && parent is UIComponent) |
| UIComponent(parent).childXYChanged(); |
| |
| if (hasEventListener("yChanged")) |
| dispatchEvent(new Event("yChanged")); |
| } |
| |
| //---------------------------------- |
| // width |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the width property. This should not be used to set the |
| * width because it bypasses the mirroring transform in the setter. |
| */ |
| mx_internal var _width:Number; |
| |
| [Bindable("widthChanged")] |
| [Inspectable(category="General")] |
| [PercentProxy("percentWidth")] |
| |
| /** |
| * Number that specifies the width of the component, in pixels, |
| * in the parent's coordinates. |
| * The default value is 0, but this property contains the actual component |
| * width after Flex completes sizing the components in your application. |
| * |
| * <p>Note: You can specify a percentage value in the MXML |
| * <code>width</code> attribute, such as <code>width="100%"</code>, |
| * but you cannot use a percentage value in the <code>width</code> |
| * property in ActionScript. |
| * Use the <code>percentWidth</code> property instead.</p> |
| * |
| * <p>Setting this property causes a <code>resize</code> event to |
| * be dispatched. |
| * See the <code>resize</code> event for details on when |
| * this event is dispatched.</p> |
| * |
| * @see #percentWidth |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get width():Number |
| { |
| return _width; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set width(value:Number):void |
| { |
| if (explicitWidth != value) |
| { |
| explicitWidth = value; |
| |
| // We invalidate size because locking in width |
| // may change the measured height in flow-based components. |
| invalidateSize(); |
| } |
| |
| if (_width != value) |
| { |
| invalidateProperties(); |
| invalidateDisplayList(); |
| invalidateParentSizeAndDisplayList(); |
| |
| _width = value; |
| |
| // The width is needed for the _layoutFeatures' mirror transform. |
| if (_layoutFeatures) |
| { |
| _layoutFeatures.layoutWidth = _width; |
| invalidateTransform(); |
| } |
| |
| if (hasEventListener("widthChanged")) |
| dispatchEvent(new Event("widthChanged")); |
| } |
| } |
| |
| //---------------------------------- |
| // height |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the height property. |
| */ |
| mx_internal var _height:Number; |
| |
| [Bindable("heightChanged")] |
| [Inspectable(category="General")] |
| [PercentProxy("percentHeight")] |
| |
| /** |
| * Number that specifies the height of the component, in pixels, |
| * in the parent's coordinates. |
| * The default value is 0, but this property contains the actual component |
| * height after Flex completes sizing the components in your application. |
| * |
| * <p>Note: You can specify a percentage value in the MXML |
| * <code>height</code> attribute, such as <code>height="100%"</code>, |
| * but you cannot use a percentage value for the <code>height</code> |
| * property in ActionScript; |
| * use the <code>percentHeight</code> property instead.</p> |
| * |
| * <p>Setting this property causes a <code>resize</code> event to be dispatched. |
| * See the <code>resize</code> event for details on when |
| * this event is dispatched.</p> |
| * |
| * @see #percentHeight |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get height():Number |
| { |
| return _height; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set height(value:Number):void |
| { |
| if (explicitHeight != value) |
| { |
| explicitHeight = value; |
| |
| // We invalidate size because locking in width |
| // may change the measured height in flow-based components. |
| invalidateSize(); |
| } |
| |
| if (_height != value) |
| { |
| invalidateProperties(); |
| invalidateDisplayList(); |
| invalidateParentSizeAndDisplayList(); |
| |
| _height = value; |
| |
| if (hasEventListener("heightChanged")) |
| dispatchEvent(new Event("heightChanged")); |
| } |
| } |
| |
| //---------------------------------- |
| // scaleX |
| //--------------------------------- |
| [Bindable("scaleXChanged")] |
| [Inspectable(category="Size", defaultValue="1.0")] |
| |
| /** |
| * Number that specifies the horizontal scaling factor. |
| * |
| * <p>The default value is 1.0, which means that the object |
| * is not scaled. |
| * A <code>scaleX</code> of 2.0 means the object has been |
| * magnified by a factor of 2, and a <code>scaleX</code> of 0.5 |
| * means the object has been reduced by a factor of 2.</p> |
| * |
| * <p>A value of 0.0 is an invalid value. |
| * Rather than setting it to 0.0, set it to a small value, or set |
| * the <code>visible</code> property to <code>false</code> to hide the component.</p> |
| * |
| * @default 1.0 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| |
| override public function get scaleX():Number |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| return _scaleX; |
| else |
| return (_layoutFeatures == null) ? super.scaleX : _layoutFeatures.layoutScaleX; |
| } |
| |
| /** |
| * @private |
| * Storage for the scaleX property. |
| */ |
| private var _scaleX:Number = 1.0; |
| |
| override public function set scaleX(value:Number):void |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| if (_scaleX == value) |
| return; |
| |
| _scaleX = value; |
| |
| invalidateProperties(); |
| invalidateSize(); |
| } |
| else |
| { |
| var prevValue:Number = (_layoutFeatures == null) ? scaleX : _layoutFeatures.layoutScaleX; |
| if (prevValue == value) |
| return; |
| |
| _hasComplexLayoutMatrix = true; |
| |
| // trace("set scaleX:" + this + "value = " + value); |
| if (_layoutFeatures == null) |
| super.scaleX = value; |
| else |
| { |
| _layoutFeatures.layoutScaleX = value; |
| } |
| invalidateTransform(); |
| invalidateProperties(); |
| |
| // If we're not compatible with Flex3 (measuredWidth is pre-scale always) |
| // and scaleX is changing we need to invalidate parent size and display list |
| // since we are not going to detect a change in measured sizes during measure. |
| invalidateParentSizeAndDisplayList(); |
| |
| } |
| dispatchEvent(new Event("scaleXChanged")); |
| } |
| |
| //---------------------------------- |
| // scaleY |
| //---------------------------------- |
| |
| [Bindable("scaleYChanged")] |
| [Inspectable(category="Size", defaultValue="1.0")] |
| |
| /** |
| * Number that specifies the vertical scaling factor. |
| * |
| * <p>The default value is 1.0, which means that the object |
| * is not scaled. |
| * A <code>scaleY</code> of 2.0 means the object has been |
| * magnified by a factor of 2, and a <code>scaleY</code> of 0.5 |
| * means the object has been reduced by a factor of 2.</p> |
| * |
| * <p>A value of 0.0 is an invalid value. |
| * Rather than setting it to 0.0, set it to a small value, or set |
| * the <code>visible</code> property to <code>false</code> to hide the component.</p> |
| * |
| * @default 1.0 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get scaleY():Number |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| return _scaleY; |
| } |
| else |
| return (_layoutFeatures == null) ? super.scaleY : _layoutFeatures.layoutScaleY; |
| } |
| |
| /** |
| * @private |
| * Storage for the scaleY property. |
| */ |
| private var _scaleY:Number = 1.0; |
| |
| |
| override public function set scaleY(value:Number):void |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| if (_scaleY == value) |
| return; |
| |
| _scaleY = value; |
| |
| invalidateProperties(); |
| invalidateSize(); |
| } |
| else |
| { |
| var prevValue:Number = (_layoutFeatures == null) ? scaleY : _layoutFeatures.layoutScaleY; |
| if (prevValue == value) |
| return; |
| |
| _hasComplexLayoutMatrix = true; |
| |
| if (_layoutFeatures == null) |
| super.scaleY = value; |
| else |
| { |
| _layoutFeatures.layoutScaleY = value; |
| } |
| invalidateTransform(); |
| invalidateProperties(); |
| |
| // If we're not compatible with Flex3 (measuredWidth is pre-scale always) |
| // and scaleX is changing we need to invalidate parent size and display list |
| // since we are not going to detect a change in measured sizes during measure. |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| dispatchEvent(new Event("scaleYChanged")); |
| } |
| |
| //---------------------------------- |
| // scaleZ |
| //---------------------------------- |
| |
| [Bindable("scaleZChanged")] |
| [Inspectable(category="Size", defaultValue="1.0")] |
| /** |
| * Number that specifies the scaling factor along the z axis. |
| * |
| * <p>A scaling along the z axis does not affect a typical component, which lies flat |
| * in the z=0 plane. components with children that have 3D transforms applied, or |
| * components with a non-zero transformZ, is affected.</p> |
| * |
| * <p>The default value is 1.0, which means that the object |
| * is not scaled.</p> |
| * |
| * <p>This property is ignored during calculation by any of Flex's 2D layouts. </p> |
| * |
| * @default 1.0 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get scaleZ():Number |
| { |
| return (_layoutFeatures == null) ? super.scaleZ : _layoutFeatures.layoutScaleZ; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set scaleZ(value:Number):void |
| { |
| if (scaleZ == value) |
| return; |
| |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| |
| _hasComplexLayoutMatrix = true; |
| _layoutFeatures.layoutScaleZ = value; |
| invalidateTransform(); |
| invalidateProperties(); |
| invalidateParentSizeAndDisplayList(); |
| if (was3D != is3D) |
| validateMatrix(); |
| dispatchEvent(new Event("scaleZChanged")); |
| } |
| |
| /** |
| * This property allows access to the Player's native implementation |
| * of the <code>scaleX</code> property, which can be useful since components |
| * can override <code>scaleX</code> and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| mx_internal final function get $scaleX():Number |
| { |
| return super.scaleX; |
| } |
| |
| mx_internal final function set $scaleX(value:Number):void |
| { |
| super.scaleX = value; |
| } |
| |
| /** |
| * This property allows access to the Player's native implementation |
| * of the <code>scaleY</code> property, which can be useful since components |
| * can override <code>scaleY</code> and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| mx_internal final function get $scaleY():Number |
| { |
| return super.scaleY; |
| } |
| |
| mx_internal final function set $scaleY(value:Number):void |
| { |
| super.scaleY = value; |
| } |
| |
| //---------------------------------- |
| // visible |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the visible property. |
| */ |
| private var _visible:Boolean = true; |
| |
| [Bindable("hide")] |
| [Bindable("show")] |
| [Inspectable(category="General", defaultValue="true")] |
| |
| /** |
| * Whether or not the display object is visible. |
| * Display objects that are not visible are disabled. |
| * For example, if <code>visible=false</code> for an InteractiveObject instance, |
| * it cannot be clicked. |
| * |
| * <p>When setting to <code>true</code>, the object dispatches |
| * a <code>show</code> event. |
| * When setting to <code>false</code>, the object dispatches |
| * a <code>hide</code> event. |
| * In either case the children of the object does not emit a |
| * <code>show</code> or <code>hide</code> event unless the object |
| * has specifically written an implementation to do so.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get visible():Boolean |
| { |
| return _visible; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set visible(value:Boolean):void |
| { |
| setVisible(value); |
| } |
| |
| /** |
| * Called when the <code>visible</code> property changes. |
| * Set the <code>visible</code> property to show or hide |
| * a component instead of calling this method directly. |
| * |
| * @param value The new value of the <code>visible</code> property. |
| * Specify <code>true</code> to show the component, and <code>false</code> to hide it. |
| * |
| * @param noEvent If <code>true</code>, do not dispatch an event. |
| * If <code>false</code>, dispatch a <code>show</code> event when |
| * the component becomes visible, and a <code>hide</code> event when |
| * the component becomes invisible. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function setVisible(value:Boolean, |
| noEvent:Boolean = false):void |
| { |
| _visible = value; |
| |
| if (!initialized) |
| return; |
| |
| if (designLayer && !designLayer.effectiveVisibility) |
| value = false; |
| |
| if ($visible == value) |
| return; |
| |
| $visible = value; |
| |
| if (!noEvent) |
| { |
| var eventType:String = value ? FlexEvent.SHOW :FlexEvent.HIDE; |
| |
| if (hasEventListener(eventType)) |
| dispatchEvent(new FlexEvent(eventType)); |
| } |
| } |
| |
| //---------------------------------- |
| // alpha |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the alpha property. |
| */ |
| private var _alpha:Number = 1.0; |
| |
| [Bindable("alphaChanged")] |
| [Inspectable(defaultValue="1.0", category="General", verbose="1", minValue="0.0", maxValue="1.0")] |
| |
| /** |
| * @private |
| */ |
| override public function get alpha():Number |
| { |
| // Here we roundtrip alpha in the same manner as the |
| // player (purposely introducing a rounding error). |
| return int(_alpha * 256.0) / 256.0; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set alpha(value:Number):void |
| { |
| if (_alpha != value) |
| { |
| _alpha = value; |
| |
| if (designLayer) |
| value = value * designLayer.effectiveAlpha; |
| |
| $alpha = value; |
| |
| dispatchEvent(new Event("alphaChanged")); |
| } |
| } |
| |
| //---------------------------------- |
| // blendMode |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the blendMode property. |
| */ |
| private var _blendMode:String = BlendMode.NORMAL; |
| private var blendShaderChanged:Boolean; |
| private var blendModeChanged:Boolean; |
| |
| [Inspectable(category="General", enumeration="add,alpha,darken,difference,erase,hardlight,invert,layer,lighten,multiply,normal,subtract,screen,overlay,colordodge,colorburn,exclusion,softlight,hue,saturation,color,luminosity", defaultValue="normal")] |
| |
| /** |
| * @private |
| */ |
| override public function get blendMode():String |
| { |
| return _blendMode; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set blendMode(value:String):void |
| { |
| if (_blendMode != value) |
| { |
| _blendMode = value; |
| blendModeChanged = true; |
| |
| // If one of the non-native Flash blendModes is set, |
| // record the new value and set the appropriate |
| // blendShader on the display object. |
| if (value == "colordodge" || |
| value =="colorburn" || value =="exclusion" || |
| value =="softlight" || value =="hue" || |
| value =="saturation" || value =="color" || |
| value =="luminosity") |
| { |
| blendShaderChanged = true; |
| } |
| invalidateProperties(); |
| } |
| } |
| |
| //---------------------------------- |
| // doubleClickEnabled |
| //---------------------------------- |
| |
| [Inspectable(enumeration="true,false", defaultValue="true")] |
| |
| /** |
| * Specifies whether the UIComponent object receives <code>doubleClick</code> events. |
| * The default value is <code>false</code>, which means that the UIComponent object |
| * does not receive <code>doubleClick</code> events. |
| * |
| * <p>The <code>mouseEnabled</code> property must also be set to <code>true</code>, |
| * its default value, for the object to receive <code>doubleClick</code> events.</p> |
| * |
| * @default false |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get doubleClickEnabled():Boolean |
| { |
| return super.doubleClickEnabled; |
| } |
| |
| /** |
| * @private |
| * Propagate to children. |
| */ |
| override public function set doubleClickEnabled(value:Boolean):void |
| { |
| super.doubleClickEnabled = value; |
| |
| var childList:IChildList; |
| |
| if (this is IRawChildrenContainer) |
| childList = IRawChildrenContainer(this).rawChildren; |
| else |
| childList = IChildList(this); |
| |
| for (var i:int = 0; i < childList.numChildren; i++) |
| { |
| var child:InteractiveObject = childList.getChildAt(i) as InteractiveObject; |
| if (child) |
| child.doubleClickEnabled = value; |
| } |
| } |
| |
| //---------------------------------- |
| // enabled |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _enabled:Boolean = false; |
| |
| [Inspectable(category="General", enumeration="true,false", defaultValue="true")] |
| [Bindable("enabledChanged")] |
| |
| /** |
| * @copy mx.core.IUIComponent#enabled |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get enabled():Boolean |
| { |
| return _enabled; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set enabled(value:Boolean):void |
| { |
| _enabled = value; |
| |
| // Need to flush the cached TextFormat |
| // so it recalcs with the disabled color, |
| cachedTextFormat = null; |
| |
| invalidateDisplayList(); |
| |
| dispatchEvent(new Event("enabledChanged")); |
| } |
| |
| //---------------------------------- |
| // cacheAsBitmap |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| override public function set cacheAsBitmap(value:Boolean):void |
| { |
| super.cacheAsBitmap = value; |
| |
| // If cacheAsBitmap is set directly, |
| // reset the value of cacheAsBitmapCount. |
| cacheAsBitmapCount = value ? 1 : 0; |
| } |
| |
| //---------------------------------- |
| // filters |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the filters property. |
| */ |
| private var _filters:Array; |
| |
| /** |
| * @private |
| */ |
| override public function get filters():Array |
| { |
| return _filters ? _filters : super.filters; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function set filters(value:Array):void |
| { |
| var n:int; |
| var i:int; |
| var e:IEventDispatcher; |
| |
| if (_filters) |
| { |
| n = _filters.length; |
| for (i = 0; i < n; i++) |
| { |
| e = _filters[i] as IEventDispatcher; |
| if (e) |
| e.removeEventListener(BaseFilter.CHANGE, filterChangeHandler); |
| } |
| } |
| |
| _filters = value; |
| |
| var clonedFilters:Array = []; |
| if (_filters) |
| { |
| n = _filters.length; |
| for (i = 0; i < n; i++) |
| { |
| if (_filters[i] is IBitmapFilter) |
| { |
| e = _filters[i] as IEventDispatcher; |
| if (e) |
| e.addEventListener(BaseFilter.CHANGE, filterChangeHandler); |
| clonedFilters.push(IBitmapFilter(_filters[i]).clone()); |
| } |
| else |
| { |
| clonedFilters.push(_filters[i]); |
| } |
| } |
| } |
| |
| super.filters = clonedFilters; |
| } |
| |
| //---------------------------------- |
| // layer |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the layer property. |
| */ |
| private var _designLayer:DesignLayer; |
| |
| [Inspectable (environment='none')] |
| |
| /** |
| * @copy mx.core.IVisualElement#designLayer |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get designLayer():DesignLayer |
| { |
| return _designLayer; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set designLayer(value:DesignLayer):void |
| { |
| if (_designLayer) |
| _designLayer.removeEventListener("layerPropertyChange", layer_PropertyChange, false); |
| |
| _designLayer = value; |
| |
| if (_designLayer) |
| _designLayer.addEventListener("layerPropertyChange", layer_PropertyChange, false, 0, true); |
| |
| $alpha = _designLayer ? _alpha * _designLayer.effectiveAlpha : _alpha; |
| $visible = designLayer ? _visible && _designLayer.effectiveVisibility : _visible; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Display |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // $alpha |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'alpha' property, which can be useful since components |
| * can override 'alpha' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $alpha():Number |
| { |
| return super.alpha; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $alpha(value:Number):void |
| { |
| super.alpha = value; |
| } |
| |
| //---------------------------------- |
| // $blendMode |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'blendMode' property, which can be useful since components |
| * can override 'alpha' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $blendMode():String |
| { |
| return super.blendMode; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $blendMode(value:String):void |
| { |
| super.blendMode = value; |
| } |
| |
| //---------------------------------- |
| // $blendShader |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $blendShader(value:Shader):void |
| { |
| super.blendShader = value; |
| } |
| |
| //---------------------------------- |
| // $parent |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'parent' property, which can be useful since components |
| * can override 'parent' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $parent():DisplayObjectContainer |
| { |
| return super.parent; |
| } |
| |
| //---------------------------------- |
| // $x |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'x' property, which can be useful since components |
| * can override 'x' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $x():Number |
| { |
| return super.x; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $x(value:Number):void |
| { |
| super.x = value; |
| } |
| |
| //---------------------------------- |
| // $y |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'y' property, which can be useful since components |
| * can override 'y' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $y():Number |
| { |
| return super.y; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $y(value:Number):void |
| { |
| super.y = value; |
| } |
| |
| //---------------------------------- |
| // $width |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'width' property, which can be useful since components |
| * can override 'width' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $width():Number |
| { |
| return super.width; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $width(value:Number):void |
| { |
| super.width = value; |
| } |
| |
| //---------------------------------- |
| // $height |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'height' property, which can be useful since components |
| * can override 'height' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $height():Number |
| { |
| return super.height; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $height(value:Number):void |
| { |
| super.height = value; |
| } |
| |
| //---------------------------------- |
| // $visible |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the 'visible' property, which can be useful since components |
| * can override 'visible' and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $visible():Boolean |
| { |
| return super.visible; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function set $visible(value:Boolean):void |
| { |
| super.visible = value; |
| } |
| |
| //---------------------------------- |
| // contentMouseX |
| //---------------------------------- |
| |
| /** |
| * Returns the <i>x</i> position of the mouse, in the content coordinate system. |
| * Content coordinates specify a pixel position relative to the upper left |
| * corner of the component's content, and include all of the component's |
| * content area, including any regions that are currently clipped and must |
| * be accessed by scrolling the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get contentMouseX():Number |
| { |
| return mouseX; |
| } |
| |
| //---------------------------------- |
| // contentMouseY |
| //---------------------------------- |
| |
| /** |
| * Returns the <i>y</i> position of the mouse, in the content coordinate system. |
| * Content coordinates specify a pixel position relative to the upper left |
| * corner of the component's content, and include all of the component's |
| * content area, including any regions that are currently clipped and must |
| * be accessed by scrolling the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get contentMouseY():Number |
| { |
| return mouseY; |
| } |
| |
| //---------------------------------- |
| // tweeningProperties |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _tweeningProperties:Array; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Array of properties that are currently being tweened on this object. |
| * |
| * <p>Used to alert the EffectManager that certain properties of this object |
| * are being tweened, so that the EffectManger doesn't attempt to animate |
| * the same properties.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get tweeningProperties():Array |
| { |
| return _tweeningProperties; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set tweeningProperties(value:Array):void |
| { |
| _tweeningProperties = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Manager access |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // cursorManager |
| //---------------------------------- |
| |
| /** |
| * Gets the CursorManager that controls the cursor for this component |
| * and its peers. |
| * Each top-level window has its own instance of a CursorManager; |
| * To make sure you're talking to the right one, use this method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get cursorManager():ICursorManager |
| { |
| var o:DisplayObject = parent; |
| |
| while (o) |
| { |
| if (o is IUIComponent && "cursorManager" in o) |
| { |
| var cm:ICursorManager = o["cursorManager"]; |
| return cm; |
| } |
| |
| o = o.parent; |
| } |
| |
| return CursorManager.getInstance(); |
| } |
| |
| //---------------------------------- |
| // focusManager |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the focusManager property. |
| */ |
| private var _focusManager:IFocusManager; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Gets the FocusManager that controls focus for this component |
| * and its peers. |
| * Each popup has its own focus loop and therefore its own instance |
| * of a FocusManager. |
| * To make sure you're talking to the right one, use this method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get focusManager():IFocusManager |
| { |
| if (_focusManager) |
| return _focusManager; |
| |
| var o:DisplayObject = parent; |
| |
| while (o) |
| { |
| if (o is IFocusManagerContainer) |
| return IFocusManagerContainer(o).focusManager; |
| |
| o = o.parent; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @private |
| * IFocusManagerContainers have this property assigned by the framework |
| */ |
| public function set focusManager(value:IFocusManager):void |
| { |
| _focusManager = value; |
| dispatchEvent(new FlexEvent(FlexEvent.ADD_FOCUS_MANAGER)); |
| } |
| |
| //---------------------------------- |
| // resourceManager |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the resourceManager property. |
| */ |
| private var _resourceManager:IResourceManager = ResourceManager.getInstance(); |
| |
| /** |
| * @private |
| * This metadata suppresses a trace() in PropertyWatcher: |
| * "warning: unable to bind to property 'resourceManager' ..." |
| */ |
| [Bindable("unused")] |
| |
| /** |
| * A reference to the object which manages |
| * all of the application's localized resources. |
| * This is a singleton instance which implements |
| * the IResourceManager interface. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function get resourceManager():IResourceManager |
| { |
| return _resourceManager; |
| } |
| |
| //---------------------------------- |
| // styleManager |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _styleManager:IStyleManager2; |
| |
| /** |
| * Returns the StyleManager instance used by this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get styleManager():IStyleManager2 |
| { |
| if (!_styleManager) |
| _styleManager = StyleManager.getStyleManager(moduleFactory); |
| |
| return _styleManager; |
| } |
| |
| //---------------------------------- |
| // systemManager |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the systemManager property. |
| * Set by the SystemManager so that each UIComponent |
| * has a references to its SystemManager |
| */ |
| private var _systemManager:ISystemManager; |
| |
| /** |
| * @private |
| * if component has been reparented, we need to potentially |
| * reassign systemManager, cause we could be in a new Window. |
| */ |
| private var _systemManagerDirty:Boolean = false; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Returns the SystemManager object used by this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get systemManager():ISystemManager |
| { |
| if (!_systemManager || _systemManagerDirty) |
| { |
| var r:DisplayObject = root; |
| if (_systemManager && _systemManager.isProxy) |
| { |
| // keep the existing proxy |
| } |
| else if (r && !(r is Stage)) |
| { |
| // If this object is attached to the display list, then |
| // the root property holds its SystemManager. |
| _systemManager = (r as ISystemManager); |
| } |
| else if (r) |
| { |
| // if the root is the Stage, then we are in a second AIR window |
| _systemManager = Stage(r).getChildAt(0) as ISystemManager; |
| } |
| else |
| { |
| // If this object isn't attached to the display list, then |
| // we need to walk up the parent chain ourselves. |
| var o:DisplayObjectContainer = parent; |
| while (o) |
| { |
| var ui:IUIComponent = o as IUIComponent; |
| if (ui) |
| { |
| _systemManager = ui.systemManager; |
| break; |
| } |
| else if (o is ISystemManager) |
| { |
| _systemManager = o as ISystemManager; |
| break; |
| } |
| o = o.parent; |
| } |
| } |
| _systemManagerDirty = false; |
| } |
| |
| return _systemManager; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set systemManager(value:ISystemManager):void |
| { |
| _systemManager = value; |
| _systemManagerDirty = false; |
| } |
| |
| /** |
| * @private |
| * Returns the current system manager, <code>systemManager</code>, |
| * unless it is null. |
| * If the current system manager is null, |
| * then search to find the correct system manager. |
| * |
| * @return A system manager. This value is never null. |
| */ |
| mx_internal function getNonNullSystemManager():ISystemManager |
| { |
| var sm:ISystemManager = systemManager; |
| |
| if (!sm) |
| sm = ISystemManager(SystemManager.getSWFRoot(this)); |
| |
| if (!sm) |
| return SystemManagerGlobals.topLevelSystemManagers[0]; |
| |
| return sm; |
| } |
| |
| /** |
| * @private |
| */ |
| protected function invalidateSystemManager():void |
| { |
| var childList:IChildList = (this is IRawChildrenContainer) ? |
| IRawChildrenContainer(this).rawChildren : IChildList(this); |
| |
| var n:int = childList.numChildren; |
| for (var i:int = 0; i < n; i++) |
| { |
| var child:UIComponent = childList.getChildAt(i) as UIComponent; |
| if (child) |
| child.invalidateSystemManager(); |
| } |
| _systemManagerDirty = true; |
| } |
| |
| //---------------------------------- |
| // nestLevel |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the nestLevel property. |
| */ |
| private var _nestLevel:int = 0; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Depth of this object in the containment hierarchy. |
| * This number is used by the measurement and layout code. |
| * The value is 0 if this component is not on the DisplayList. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get nestLevel():int |
| { |
| return _nestLevel; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set nestLevel(value:int):void |
| { |
| // If my parent hasn't been attached to the display list, then its nestLevel |
| // will be zero. If it tries to set my nestLevel to 1, ignore it. We'll |
| // update nest levels again after the parent is added to the display list. |
| if (value == 1) |
| return; |
| |
| // Also punt if the new value for nestLevel is the same as my current value. |
| // TODO: (aharui) add early exit if nestLevel isn't changing |
| if (value > 1 && _nestLevel != value) |
| { |
| _nestLevel = value; |
| |
| updateCallbacks(); |
| |
| value ++; |
| } |
| else if (value == 0) |
| _nestLevel = value = 0; |
| else |
| value ++; |
| |
| var childList:IChildList = (this is IRawChildrenContainer) ? |
| IRawChildrenContainer(this).rawChildren : IChildList(this); |
| |
| var n:int = childList.numChildren; |
| for (var i:int = 0; i < n; i++) |
| { |
| var ui:ILayoutManagerClient = childList.getChildAt(i) as ILayoutManagerClient; |
| if (ui) |
| { |
| ui.nestLevel = value; |
| } |
| else |
| { |
| var textField:IUITextField = childList.getChildAt(i) as IUITextField; |
| |
| if (textField) |
| textField.nestLevel = value; |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: MXML |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // descriptor |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the descriptor property. |
| * This variable is initialized in the construct() method |
| * using the _descriptor in the initObj, which is set in |
| * createComponentFromDescriptor(). |
| * If this UIComponent was not created by createComponentFromDescriptor(), |
| * its 'descriptor' property is null. |
| */ |
| mx_internal var _descriptor:UIComponentDescriptor; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Reference to the UIComponentDescriptor, if any, that was used |
| * by the <code>createComponentFromDescriptor()</code> method to create this |
| * UIComponent instance. If this UIComponent instance |
| * was not created from a descriptor, this property is null. |
| * |
| * @see mx.core.UIComponentDescriptor |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get descriptor():UIComponentDescriptor |
| { |
| return _descriptor; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set descriptor(value:UIComponentDescriptor):void |
| { |
| _descriptor = value; |
| } |
| |
| //---------------------------------- |
| // document |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the document property. |
| * This variable is initialized in the init() method. |
| * A document object (i.e., an Object at the top of the hierarchy |
| * of a Flex application, MXML component, or AS component) has an |
| * autogenerated override of initalize() which sets its _document to |
| * 'this', so that its 'document' property is a reference to itself. |
| * Other UIComponents set their _document to their parent's _document, |
| * so that their 'document' property refers to the document object |
| * that they are inside. |
| */ |
| mx_internal var _document:Object; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * A reference to the document object associated with this UIComponent. |
| * A document object is an Object at the top of the hierarchy of a |
| * Flex application, MXML component, or AS component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get document():Object |
| { |
| return _document; |
| } |
| |
| /** |
| * A reference to the document object associated with this UIComponent. |
| * A document object is an Object at the top of the hierarchy of a |
| * Flex application, MXML component, or AS component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function set document(value:Object):void |
| { |
| var n:int = numChildren; |
| for (var i:int = 0; i < n; i++) |
| { |
| var child:IUIComponent = getChildAt(i) as IUIComponent; |
| if (!child) |
| continue; |
| |
| if (child.document == _document || |
| child.document == FlexGlobals.topLevelApplication) |
| { |
| child.document = value; |
| } |
| } |
| |
| _document = value; |
| } |
| |
| //---------------------------------- |
| // documentDescriptor |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the documentDescriptor property. |
| * A document object (i.e., a UIComponent at the top of the |
| * hierarchy of a Flex application, MXML component, |
| * or AS component) has an autogenerated override of init() |
| * which sets its _documentDescriptor to the descriptor |
| * at the top of the autogenerated descriptor tree for that |
| * document. For other UIComponents, _documentDescriptor is |
| * never defined. |
| */ |
| mx_internal var _documentDescriptor:UIComponentDescriptor; |
| |
| /** |
| * @private |
| * For a document object, which is an instance of a UIComponent |
| * at the top of the hierarchy of a Flex application, MXML |
| * component, or ActionScript component, the |
| * <code>documentDescriptor</code> property is a reference |
| * to the UIComponentDescriptor at the top of the autogenerated |
| * descriptor tree for that document, which describes the |
| * set of children and their attributes for that document. |
| * For other UIComponents, it is <code>null</code>. |
| */ |
| mx_internal function get documentDescriptor():UIComponentDescriptor |
| { |
| return _documentDescriptor; |
| } |
| |
| //---------------------------------- |
| // id |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _id:String; |
| |
| /** |
| * ID of the component. This value becomes the instance name of the object |
| * and should not contain any white space or special characters. Each component |
| * throughout an application should have a unique id. |
| * |
| * <p>If your application is going to be tested by third party tools, give each component |
| * a meaningful id. Testing tools use ids to represent the control in their scripts and |
| * having a meaningful name can make scripts more readable. For example, set the |
| * value of a button to submit_button rather than b1 or button1.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get id():String |
| { |
| return _id; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set id(value:String):void |
| { |
| _id = value; |
| } |
| |
| //---------------------------------- |
| // isDocument |
| //---------------------------------- |
| |
| /** |
| * Contains <code>true</code> if this UIComponent instance is a document object. |
| * That means it is at the top of the hierarchy of a Flex |
| * application, MXML component, or ActionScript component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get isDocument():Boolean |
| { |
| return document == this; |
| } |
| |
| //---------------------------------- |
| // MXML Descriptor |
| //---------------------------------- |
| |
| /** |
| * The descriptor of MXML children. |
| */ |
| private var _MXMLDescriptor:Array; |
| |
| public function get MXMLDescriptor():Array |
| { |
| return _MXMLDescriptor; |
| } |
| |
| public function setMXMLDescriptor(value:Array):void |
| { |
| _MXMLDescriptor = value; |
| } |
| |
| //---------------------------------- |
| // MXML Properties |
| //---------------------------------- |
| |
| /** |
| * The attributes of MXML top tag. |
| */ |
| private var _MXMLProperties:Array; |
| |
| public function get MXMLProperties():Array |
| { |
| return _MXMLProperties; |
| } |
| |
| public function setMXMLProperties(value:Array):void |
| { |
| _MXMLProperties = value; |
| } |
| |
| //---------------------------------- |
| // parentApplication |
| //---------------------------------- |
| |
| [Bindable("initialize")] |
| |
| /* |
| * Note: |
| * There are two reasons that 'parentApplication' is typed as Object |
| * rather than as Application. The first is that typing it as Application |
| * would make UIComponent dependent on Application, slowing down compile |
| * times not only for SWCs for also for MXML and AS components. The |
| * second is that authors would not be able to access properties and |
| * methods in the <Script> of their <Application> without casting it |
| * to their application's subclass, as in |
| * MyApplication(paentApplication).myAppMethod(). |
| * Therefore we decided to dispense with strict typing for |
| * 'parentApplication'. |
| */ |
| /** |
| * A reference to the Application object that contains this UIComponent |
| * instance. |
| * This Application object might exist in a SWFLoader control in another |
| * Application, and so on, creating a chain of Application objects that |
| * can be walked using parentApplication. |
| * |
| * <p>The <code>parentApplication</code> property of an Application is never itself; |
| * it is either the Application into which it was loaded or null |
| * (for the top-level Application).</p> |
| * |
| * <p>Walking the application chain using the <code>parentApplication</code> |
| * property is similar to walking the document chain using the |
| * <code>parentDocument</code> property. |
| * You can access the top-level application using the |
| * <code>application</code> property of the Application class.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get parentApplication():Object |
| { |
| // Look for the SystemManager's document, |
| // which should be the Application. |
| var o:Object = systemManager.document; |
| |
| // If this UIComponent is its own root, then it is an Application. |
| // We want to return its parent Application, or null |
| // (if it has no parent because it is the top-level Application). |
| // The hierarchy in this situation looks something like this: |
| // |
| // SystemManager |
| // Application |
| // SomeContainer |
| // Loader |
| // Loaded App's SystemManager |
| // Application |
| // ThisComponent |
| if (o == this) |
| { |
| var p:UIComponent = o.systemManager.parent as UIComponent; |
| o = p ? p.systemManager.document : null; |
| } |
| |
| return o; |
| } |
| |
| //---------------------------------- |
| // parentDocument |
| //---------------------------------- |
| |
| [Bindable("initialize")] |
| |
| /** |
| * A reference to the parent document object for this UIComponent. |
| * A document object is a UIComponent at the top of the hierarchy |
| * of a Flex application, MXML component, or AS component. |
| * |
| * <p>For the Application object, the <code>parentDocument</code> |
| * property is null. |
| * This property is useful in MXML scripts to go up a level |
| * in the chain of document objects. |
| * It can be used to walk this chain using |
| * <code>parentDocument.parentDocument</code>, and so on.</p> |
| * |
| * <p>It is typed as Object so that authors can access properties |
| * and methods on ancestor document objects without casting.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get parentDocument():Object |
| { |
| if (document == this) |
| { |
| var p:IUIComponent = parent as IUIComponent; |
| if (p) |
| return p.document; |
| |
| var sm:ISystemManager = parent as ISystemManager; |
| if (sm) |
| return sm.document; |
| |
| return null; |
| } |
| else |
| { |
| return document; |
| } |
| } |
| |
| //---------------------------------- |
| // screen |
| //---------------------------------- |
| |
| /** |
| * Returns an object that contains the size and position of the base |
| * drawing surface for this object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get screen():Rectangle |
| { |
| var sm:ISystemManager = systemManager; |
| |
| return sm ? sm.screen : null; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Modules |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // moduleFactory |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the moduleFactory property. |
| */ |
| private var _moduleFactory:IFlexModuleFactory; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * A module factory is used as context for using embedded fonts and for |
| * finding the style manager that controls the styles for this |
| * component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get moduleFactory():IFlexModuleFactory |
| { |
| return _moduleFactory; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set moduleFactory(factory:IFlexModuleFactory):void |
| { |
| _styleManager = null; |
| |
| var n:int = numChildren; |
| for (var i:int = 0; i < n; i++) |
| { |
| var child:IFlexModule = getChildAt(i) as IFlexModule; |
| if (!child) |
| continue; |
| |
| if (child.moduleFactory == null || child.moduleFactory == _moduleFactory) |
| { |
| child.moduleFactory = factory; |
| } |
| } |
| |
| if (advanceStyleClientChildren != null) |
| { |
| for (var styleClient:Object in advanceStyleClientChildren) |
| { |
| var iAdvanceStyleClientChild:IFlexModule = styleClient |
| as IFlexModule; |
| |
| if (iAdvanceStyleClientChild && |
| (iAdvanceStyleClientChild.moduleFactory == null |
| || iAdvanceStyleClientChild.moduleFactory == _moduleFactory)) |
| { |
| iAdvanceStyleClientChild.moduleFactory = factory; |
| } |
| } |
| } |
| _moduleFactory = factory; |
| |
| setDeferredStyles(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Styles |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // inheritingStyles |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the inheritingStyles property. |
| */ |
| private var _inheritingStyles:Object = StyleProtoChain.STYLE_UNINITIALIZED; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * The beginning of this component's chain of inheriting styles. |
| * The <code>getStyle()</code> method simply accesses |
| * <code>inheritingStyles[styleName]</code> to search the entire |
| * prototype-linked chain. |
| * This object is set up by <code>initProtoChain()</code>. |
| * Developers typically never need to access this property directly. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get inheritingStyles():Object |
| { |
| return _inheritingStyles; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set inheritingStyles(value:Object):void |
| { |
| _inheritingStyles = value; |
| } |
| |
| //---------------------------------- |
| // nonInheritingStyles |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the nonInheritingStyles property. |
| */ |
| private var _nonInheritingStyles:Object = |
| StyleProtoChain.STYLE_UNINITIALIZED; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * The beginning of this component's chain of non-inheriting styles. |
| * The <code>getStyle()</code> method simply accesses |
| * <code>nonInheritingStyles[styleName]</code> to search the entire |
| * prototype-linked chain. |
| * This object is set up by <code>initProtoChain()</code>. |
| * Developers typically never need to access this property directly. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get nonInheritingStyles():Object |
| { |
| return _nonInheritingStyles; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set nonInheritingStyles(value:Object):void |
| { |
| _nonInheritingStyles = value; |
| } |
| |
| //---------------------------------- |
| // styleDeclaration |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the styleDeclaration property. |
| */ |
| private var _styleDeclaration:CSSStyleDeclaration; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Storage for the inline inheriting styles on this object. |
| * This CSSStyleDeclaration is created the first time that |
| * the <code>setStyle()</code> method |
| * is called on this component to set an inheriting style. |
| * Developers typically never need to access this property directly. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get styleDeclaration():CSSStyleDeclaration |
| { |
| return _styleDeclaration; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set styleDeclaration(value:CSSStyleDeclaration):void |
| { |
| _styleDeclaration = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Bitmap caching |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // cachePolicy |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for cachePolicy property. |
| */ |
| private var _cachePolicy:String = UIComponentCachePolicy.AUTO; |
| |
| [Inspectable(enumeration="on,off,auto", defaultValue="auto")] |
| |
| /** |
| * Specifies the bitmap caching policy for this object. |
| * Possible values in MXML are <code>"on"</code>, |
| * <code>"off"</code> and |
| * <code>"auto"</code> (default). |
| * |
| * <p>Possible values in ActionScript are <code>UIComponentCachePolicy.ON</code>, |
| * <code>UIComponentCachePolicy.OFF</code> and |
| * <code>UIComponentCachePolicy.AUTO</code> (default).</p> |
| * |
| * <p><ul> |
| * <li>A value of <code>UIComponentCachePolicy.ON</code> means that |
| * the object is always cached as a bitmap.</li> |
| * <li>A value of <code>UIComponentCachePolicy.OFF</code> means that |
| * the object is never cached as a bitmap.</li> |
| * <li>A value of <code>UIComponentCachePolicy.AUTO</code> means that |
| * the framework uses heuristics to decide whether the object should |
| * be cached as a bitmap.</li> |
| * </ul></p> |
| * |
| * @default UIComponentCachePolicy.AUTO |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get cachePolicy():String |
| { |
| return _cachePolicy; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set cachePolicy(value:String):void |
| { |
| if (_cachePolicy != value) |
| { |
| _cachePolicy = value; |
| |
| if (value == UIComponentCachePolicy.OFF) |
| cacheAsBitmap = false; |
| else if (value == UIComponentCachePolicy.ON) |
| cacheAsBitmap = true; |
| else |
| cacheAsBitmap = (cacheAsBitmapCount > 0); |
| } |
| } |
| |
| //---------------------------------- |
| // cacheHeuristic |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Counter used by the cacheHeuristic property. |
| */ |
| private var cacheAsBitmapCount:int = 0; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Used by Flex to suggest bitmap caching for the object. |
| * If <code>cachePolicy</code> is <code>UIComponentCachePolicy.AUTO</code>, |
| * then <code>cacheHeuristic</code> |
| * is used to control the object's <code>cacheAsBitmap</code> property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function set cacheHeuristic(value:Boolean):void |
| { |
| if (_cachePolicy == UIComponentCachePolicy.AUTO) |
| { |
| if (value) |
| cacheAsBitmapCount++; |
| else if (cacheAsBitmapCount != 0) |
| cacheAsBitmapCount--; |
| |
| super.cacheAsBitmap = (cacheAsBitmapCount != 0); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Focus management |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // focusPane |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the focusPane property. |
| */ |
| private var _focusPane:Sprite; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * The focus pane associated with this object. |
| * An object has a focus pane when one of its children has focus. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get focusPane():Sprite |
| { |
| return _focusPane; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set focusPane(value:Sprite):void |
| { |
| if (value) |
| { |
| addChild(value); |
| |
| value.x = 0; |
| value.y = 0; |
| value.scrollRect = null; |
| |
| _focusPane = value; |
| } |
| else |
| { |
| removeChild(_focusPane); |
| |
| _focusPane.mask = null; |
| _focusPane = null; |
| } |
| } |
| |
| //---------------------------------- |
| // focusEnabled |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the focusEnabled property. |
| */ |
| private var _focusEnabled:Boolean = true; |
| |
| [Inspectable(defaultValue="true")] |
| |
| /** |
| * Indicates whether the component can receive focus when tabbed to. |
| * You can set <code>focusEnabled</code> to <code>false</code> |
| * when a UIComponent is used as a subcomponent of another component |
| * so that the outer component becomes the focusable entity. |
| * If this property is <code>false</code>, focus is transferred to |
| * the first parent that has <code>focusEnable</code> |
| * set to <code>true</code>. |
| * |
| * <p>The default value is <code>true</code>, except for the |
| * spark.components.Scroller component. |
| * For that component, the default value is <code>false</code>.</p> |
| * |
| * @see spark.components.Scroller |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get focusEnabled():Boolean |
| { |
| return _focusEnabled; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set focusEnabled(value:Boolean):void |
| { |
| _focusEnabled = value; |
| } |
| |
| //---------------------------------- |
| // hasFocusableChildren |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the hasFocusableChildren property. |
| */ |
| private var _hasFocusableChildren:Boolean = false; |
| |
| [Bindable("hasFocusableChildrenChange")] |
| [Inspectable(defaultValue="false")] |
| |
| /** |
| * A flag that indicates whether child objects can receive focus. |
| * |
| * <p><b>Note: </b>This property is similar to the <code>tabChildren</code> property |
| * used by Flash Player. |
| * Use the <code>hasFocusableChildren</code> property with Flex applications. |
| * Do not use the <code>tabChildren</code> property.</p> |
| * |
| * <p>This property is usually <code>false</code> because most components |
| * either receive focus themselves or delegate focus to a single |
| * internal sub-component and appear as if the component has |
| * received focus. |
| * For example, a TextInput control contains a focusable |
| * child RichEditableText control, but while the RichEditableText |
| * sub-component actually receives focus, it appears as if the |
| * TextInput has focus. TextInput sets <code>hasFocusableChildren</code> |
| * to <code>false</code> because TextInput is considered the |
| * component that has focus. Its internal structure is an |
| * abstraction.</p> |
| * |
| * <p>Usually only navigator components, such as TabNavigator and |
| * Accordion, have this flag set to <code>true</code> because they |
| * receive focus on Tab but focus goes to components in the child |
| * containers on further Tabs.</p> |
| * |
| * <p>The default value is <code>false</code>, except for the |
| * spark.components.Scroller component. |
| * For that component, the default value is <code>true</code>.</p> |
| * |
| * @see spark.components.Scroller |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get hasFocusableChildren():Boolean |
| { |
| return _hasFocusableChildren; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set hasFocusableChildren(value:Boolean):void |
| { |
| if (value != _hasFocusableChildren) |
| { |
| _hasFocusableChildren = value; |
| dispatchEvent(new Event("hasFocusableChildrenChange")); |
| } |
| } |
| |
| //---------------------------------- |
| // mouseFocusEnabled |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the mouseFocusEnabled property. |
| */ |
| private var _mouseFocusEnabled:Boolean = true; |
| |
| [Inspectable(defaultValue="true")] |
| |
| /** |
| * Whether you can receive focus when clicked on. |
| * If <code>false</code>, focus is transferred to |
| * the first parent that is <code>mouseFocusEnable</code> |
| * set to <code>true</code>. |
| * For example, you can set this property to <code>false</code> |
| * on a Button control so that you can use the Tab key to move focus |
| * to the control, but not have the control get focus when you click on it. |
| * |
| * <p>The default value is <code>true</code> for most subclasses, except the Spark TabBar. In that case, the default is <code>false</code>.</p> |
| * |
| * @default true |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get mouseFocusEnabled():Boolean |
| { |
| return _mouseFocusEnabled; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set mouseFocusEnabled(value:Boolean):void |
| { |
| _mouseFocusEnabled = value; |
| } |
| |
| //---------------------------------- |
| // tabFocusEnabled |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the tabFocusEnabled property. |
| */ |
| private var _tabFocusEnabled:Boolean = true; |
| |
| [Bindable("tabFocusEnabledChange")] |
| [Inspectable(defaultValue="true")] |
| |
| /** |
| * A flag that indicates whether this object can receive focus |
| * via the TAB key |
| * |
| * <p>This is similar to the <code>tabEnabled</code> property |
| * used by the Flash Player.</p> |
| * |
| * <p>This is usually <code>true</code> for components that |
| * handle keyboard input, but some components in controlbars |
| * have them set to <code>false</code> because they should not steal |
| * focus from another component like an editor. |
| * </p> |
| * |
| * @default true |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get tabFocusEnabled():Boolean |
| { |
| return _tabFocusEnabled; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set tabFocusEnabled(value:Boolean):void |
| { |
| if (value != _tabFocusEnabled) |
| { |
| _tabFocusEnabled = value; |
| dispatchEvent(new Event("tabFocusEnabledChange")); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Measurement |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // measuredMinWidth |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the measuredMinWidth property. |
| */ |
| private var _measuredMinWidth:Number = 0; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * The default minimum width of the component, in pixels. |
| * This value is set by the <code>measure()</code> method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get measuredMinWidth():Number |
| { |
| return _measuredMinWidth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set measuredMinWidth(value:Number):void |
| { |
| _measuredMinWidth = value; |
| } |
| |
| //---------------------------------- |
| // measuredMinHeight |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the measuredMinHeight property. |
| */ |
| private var _measuredMinHeight:Number = 0; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * The default minimum height of the component, in pixels. |
| * This value is set by the <code>measure()</code> method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get measuredMinHeight():Number |
| { |
| return _measuredMinHeight; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set measuredMinHeight(value:Number):void |
| { |
| _measuredMinHeight = value; |
| } |
| |
| //---------------------------------- |
| // measuredWidth |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the measuredWidth property. |
| */ |
| private var _measuredWidth:Number = 0; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * The default width of the component, in pixels. |
| * This value is set by the <code>measure()</code> method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get measuredWidth():Number |
| { |
| return _measuredWidth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set measuredWidth(value:Number):void |
| { |
| _measuredWidth = value; |
| } |
| |
| //---------------------------------- |
| // measuredHeight |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the measuredHeight property. |
| */ |
| private var _measuredHeight:Number = 0; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * The default height of the component, in pixels. |
| * This value is set by the <code>measure()</code> method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get measuredHeight():Number |
| { |
| return _measuredHeight; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set measuredHeight(value:Number):void |
| { |
| _measuredHeight = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Layout |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // percentWidth |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the percentWidth property. |
| */ |
| private var _percentWidth:Number; |
| |
| [Bindable("resize")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * Specifies the width of a component as a percentage |
| * of its parent's size. Allowed values are 0-100. The default value is NaN. |
| * Setting the <code>width</code> or <code>explicitWidth</code> properties |
| * resets this property to NaN. |
| * |
| * <p>This property returns a numeric value only if the property was |
| * previously set; it does not reflect the exact size of the component |
| * in percent.</p> |
| * |
| * <p>This property is always set to NaN for the UITextField control.</p> |
| * |
| * <p>When used with Spark layouts, this property is used to calculate the |
| * width of the component's bounds after scaling and rotation. For example |
| * if the component is rotated at 90 degrees, then specifying |
| * <code>percentWidth</code> will affect the component's height.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get percentWidth():Number |
| { |
| return _percentWidth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set percentWidth(value:Number):void |
| { |
| if (_percentWidth == value) |
| return; |
| |
| if (!isNaN(value)) |
| _explicitWidth = NaN; |
| |
| _percentWidth = value; |
| |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| //---------------------------------- |
| // percentHeight |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the percentHeight property. |
| */ |
| private var _percentHeight:Number; |
| |
| [Bindable("resize")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * Specifies the height of a component as a percentage |
| * of its parent's size. Allowed values are 0-100. The default value is NaN. |
| * Setting the <code>height</code> or <code>explicitHeight</code> properties |
| * resets this property to NaN. |
| * |
| * <p>This property returns a numeric value only if the property was |
| * previously set; it does not reflect the exact size of the component |
| * in percent.</p> |
| * |
| * <p>This property is always set to NaN for the UITextField control.</p> |
| * |
| * <p>When used with Spark layouts, this property is used to calculate the |
| * height of the component's bounds after scaling and rotation. For example |
| * if the component is rotated at 90 degrees, then specifying |
| * <code>percentHeight</code> will affect the component's width.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get percentHeight():Number |
| { |
| return _percentHeight; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set percentHeight(value:Number):void |
| { |
| if (_percentHeight == value) |
| return; |
| |
| if (!isNaN(value)) |
| _explicitHeight = NaN; |
| |
| _percentHeight = value; |
| |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| //---------------------------------- |
| // minWidth |
| //---------------------------------- |
| |
| [Bindable("explicitMinWidthChanged")] |
| [Inspectable(category="Size", defaultValue="0")] |
| |
| /** |
| * The minimum recommended width of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. The default value depends on |
| * the component's implementation. |
| * |
| * <p>If the application developer sets the value of minWidth, |
| * the new value is stored in explicitMinWidth. The default value of minWidth |
| * does not change. As a result, at layout time, if |
| * minWidth was explicitly set by the application developer, then the value of |
| * explicitMinWidth is used for the component's minimum recommended width. |
| * If minWidth is not set explicitly by the application developer, then the value of |
| * measuredMinWidth is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>minWidth</code> with respect to its parent |
| * is affected by the <code>scaleX</code> property.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get minWidth():Number |
| { |
| if (!isNaN(explicitMinWidth)) |
| return explicitMinWidth; |
| |
| return measuredMinWidth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set minWidth(value:Number):void |
| { |
| if (explicitMinWidth == value) |
| return; |
| |
| explicitMinWidth = value; |
| } |
| |
| //---------------------------------- |
| // minHeight |
| //---------------------------------- |
| |
| [Bindable("explicitMinHeightChanged")] |
| [Inspectable(category="Size", defaultValue="0")] |
| |
| /** |
| * The minimum recommended height of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. The default value depends on |
| * the component's implementation. |
| * |
| * <p>If the application developer sets the value of minHeight, |
| * the new value is stored in explicitMinHeight. The default value of minHeight |
| * does not change. As a result, at layout time, if |
| * minHeight was explicitly set by the application developer, then the value of |
| * explicitMinHeight is used for the component's minimum recommended height. |
| * If minHeight is not set explicitly by the application developer, then the value of |
| * measuredMinHeight is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>minHeight</code> with respect to its parent |
| * is affected by the <code>scaleY</code> property.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get minHeight():Number |
| { |
| if (!isNaN(explicitMinHeight)) |
| return explicitMinHeight; |
| |
| return measuredMinHeight; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set minHeight(value:Number):void |
| { |
| if (explicitMinHeight == value) |
| return; |
| |
| explicitMinHeight = value; |
| } |
| |
| //---------------------------------- |
| // maxWidth |
| //---------------------------------- |
| |
| [Bindable("explicitMaxWidthChanged")] |
| [Inspectable(category="Size", defaultValue="10000")] |
| |
| /** |
| * The maximum recommended width of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. The default value of this property is |
| * set by the component developer. |
| * |
| * <p>The component developer uses this property to set an upper limit on the |
| * width of the component.</p> |
| * |
| * <p>If the application developer overrides the default value of maxWidth, |
| * the new value is stored in explicitMaxWidth. The default value of maxWidth |
| * does not change. As a result, at layout time, if |
| * maxWidth was explicitly set by the application developer, then the value of |
| * explicitMaxWidth is used for the component's maximum recommended width. |
| * If maxWidth is not set explicitly by the user, then the default value is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>maxWidth</code> with respect to its parent |
| * is affected by the <code>scaleX</code> property. |
| * Some components have no theoretical limit to their width. |
| * In those cases their <code>maxWidth</code> is set to |
| * <code>UIComponent.DEFAULT_MAX_WIDTH</code>.</p> |
| * |
| * @default 10000 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get maxWidth():Number |
| { |
| return !isNaN(explicitMaxWidth) ? |
| explicitMaxWidth : |
| DEFAULT_MAX_WIDTH; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set maxWidth(value:Number):void |
| { |
| if (explicitMaxWidth == value) |
| return; |
| |
| explicitMaxWidth = value; |
| } |
| |
| //---------------------------------- |
| // maxHeight |
| //---------------------------------- |
| |
| [Bindable("explicitMaxHeightChanged")] |
| [Inspectable(category="Size", defaultValue="10000")] |
| |
| /** |
| * The maximum recommended height of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. The default value of this property is |
| * set by the component developer. |
| * |
| * <p>The component developer uses this property to set an upper limit on the |
| * height of the component.</p> |
| * |
| * <p>If the application developer overrides the default value of maxHeight, |
| * the new value is stored in explicitMaxHeight. The default value of maxHeight |
| * does not change. As a result, at layout time, if |
| * maxHeight was explicitly set by the application developer, then the value of |
| * explicitMaxHeight is used for the component's maximum recommended height. |
| * If maxHeight is not set explicitly by the user, then the default value is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>maxHeight</code> with respect to its parent |
| * is affected by the <code>scaleY</code> property. |
| * Some components have no theoretical limit to their height. |
| * In those cases their <code>maxHeight</code> is set to |
| * <code>UIComponent.DEFAULT_MAX_HEIGHT</code>.</p> |
| * |
| * @default 10000 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get maxHeight():Number |
| { |
| return !isNaN(explicitMaxHeight) ? |
| explicitMaxHeight : |
| DEFAULT_MAX_HEIGHT; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set maxHeight(value:Number):void |
| { |
| if (explicitMaxHeight == value) |
| return; |
| |
| explicitMaxHeight = value; |
| } |
| |
| //---------------------------------- |
| // explicitMinWidth |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the minWidth property. |
| */ |
| mx_internal var _explicitMinWidth:Number; |
| |
| [Bindable("explicitMinWidthChanged")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * The minimum recommended width of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. |
| * |
| * <p>Application developers typically do not set the explicitMinWidth property. Instead, they |
| * set the value of the minWidth property, which sets the explicitMinWidth property. The |
| * value of minWidth does not change.</p> |
| * |
| * <p>At layout time, if minWidth was explicitly set by the application developer, then |
| * the value of explicitMinWidth is used. Otherwise, the value of measuredMinWidth |
| * is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>minWidth</code> with respect to its parent |
| * is affected by the <code>scaleX</code> property.</p> |
| * |
| * @default NaN |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get explicitMinWidth():Number |
| { |
| return _explicitMinWidth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set explicitMinWidth(value:Number):void |
| { |
| if (_explicitMinWidth == value) |
| return; |
| |
| _explicitMinWidth = value; |
| |
| // We invalidate size because locking in width |
| // may change the measured height in flow-based components. |
| invalidateSize(); |
| invalidateParentSizeAndDisplayList(); |
| |
| dispatchEvent(new Event("explicitMinWidthChanged")); |
| } |
| |
| //---------------------------------- |
| // minHeight |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the minHeight property. |
| */ |
| mx_internal var _explicitMinHeight:Number; |
| |
| [Bindable("explictMinHeightChanged")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * The minimum recommended height of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. |
| * |
| * <p>Application developers typically do not set the explicitMinHeight property. Instead, they |
| * set the value of the minHeight property, which sets the explicitMinHeight property. The |
| * value of minHeight does not change.</p> |
| * |
| * <p>At layout time, if minHeight was explicitly set by the application developer, then |
| * the value of explicitMinHeight is used. Otherwise, the value of measuredMinHeight |
| * is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>minHeight</code> with respect to its parent |
| * is affected by the <code>scaleY</code> property.</p> |
| * |
| * @default NaN |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get explicitMinHeight():Number |
| { |
| return _explicitMinHeight; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set explicitMinHeight(value:Number):void |
| { |
| if (_explicitMinHeight == value) |
| return; |
| |
| _explicitMinHeight = value; |
| |
| // We invalidate size because locking in height |
| // may change the measured width in flow-based components. |
| invalidateSize(); |
| invalidateParentSizeAndDisplayList(); |
| |
| dispatchEvent(new Event("explicitMinHeightChanged")); |
| } |
| |
| //---------------------------------- |
| // explicitMaxWidth |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the maxWidth property. |
| */ |
| mx_internal var _explicitMaxWidth:Number; |
| |
| [Bindable("explicitMaxWidthChanged")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * The maximum recommended width of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. |
| * |
| * <p>Application developers typically do not set the explicitMaxWidth property. Instead, they |
| * set the value of the maxWidth property, which sets the explicitMaxWidth property. The |
| * value of maxWidth does not change.</p> |
| * |
| * <p>At layout time, if maxWidth was explicitly set by the application developer, then |
| * the value of explicitMaxWidth is used. Otherwise, the default value for maxWidth |
| * is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>maxWidth</code> with respect to its parent |
| * is affected by the <code>scaleX</code> property. |
| * Some components have no theoretical limit to their width. |
| * In those cases their <code>maxWidth</code> is set to |
| * <code>UIComponent.DEFAULT_MAX_WIDTH</code>.</p> |
| * |
| * @default NaN |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get explicitMaxWidth():Number |
| { |
| return _explicitMaxWidth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set explicitMaxWidth(value:Number):void |
| { |
| if (_explicitMaxWidth == value) |
| return; |
| |
| _explicitMaxWidth = value; |
| |
| // Se invalidate size because locking in width |
| // may change the measured height in flow-based components. |
| invalidateSize(); |
| invalidateParentSizeAndDisplayList(); |
| |
| dispatchEvent(new Event("explicitMaxWidthChanged")); |
| } |
| |
| //---------------------------------- |
| // explicitMaxHeight |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the maxHeight property. |
| */ |
| mx_internal var _explicitMaxHeight:Number; |
| |
| [Bindable("explicitMaxHeightChanged")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * The maximum recommended height of the component to be considered |
| * by the parent during layout. This value is in the |
| * component's coordinates, in pixels. |
| * |
| * <p>Application developers typically do not set the explicitMaxHeight property. Instead, they |
| * set the value of the maxHeight property, which sets the explicitMaxHeight property. The |
| * value of maxHeight does not change.</p> |
| * |
| * <p>At layout time, if maxHeight was explicitly set by the application developer, then |
| * the value of explicitMaxHeight is used. Otherwise, the default value for maxHeight |
| * is used.</p> |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>maxHeight</code> with respect to its parent |
| * is affected by the <code>scaleY</code> property. |
| * Some components have no theoretical limit to their height. |
| * In those cases their <code>maxHeight</code> is set to |
| * <code>UIComponent.DEFAULT_MAX_HEIGHT</code>.</p> |
| * |
| * @default NaN |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get explicitMaxHeight():Number |
| { |
| return _explicitMaxHeight; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set explicitMaxHeight(value:Number):void |
| { |
| if (_explicitMaxHeight == value) |
| return; |
| |
| _explicitMaxHeight = value; |
| |
| // Se invalidate size because locking in height |
| // may change the measured width in flow-based components. |
| invalidateSize(); |
| invalidateParentSizeAndDisplayList(); |
| |
| dispatchEvent(new Event("explicitMaxHeightChanged")); |
| } |
| |
| //---------------------------------- |
| // explicitWidth |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the explicitWidth property. |
| */ |
| private var _explicitWidth:Number; |
| |
| [Bindable("explicitWidthChanged")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * Number that specifies the explicit width of the component, |
| * in pixels, in the component's coordinates. |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>explicitWidth</code> with respect to its parent |
| * is affected by the <code>scaleX</code> property.</p> |
| * <p>Setting the <code>width</code> property also sets this property to |
| * the specified width value.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get explicitWidth():Number |
| { |
| return _explicitWidth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set explicitWidth(value:Number):void |
| { |
| if (_explicitWidth == value) |
| return; |
| |
| // width can be pixel or percent not both |
| if (!isNaN(value)) |
| _percentWidth = NaN; |
| |
| _explicitWidth = value; |
| |
| // We invalidate size because locking in width |
| // may change the measured height in flow-based components. |
| invalidateSize(); |
| invalidateParentSizeAndDisplayList(); |
| |
| dispatchEvent(new Event("explicitWidthChanged")); |
| } |
| |
| //---------------------------------- |
| // explicitHeight |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the explicitHeight property. |
| */ |
| private var _explicitHeight:Number; |
| |
| [Bindable("explicitHeightChanged")] |
| [Inspectable(environment="none")] |
| |
| /** |
| * Number that specifies the explicit height of the component, |
| * in pixels, in the component's coordinates. |
| * |
| * <p>This value is used by the container in calculating |
| * the size and position of the component. |
| * It is not used by the component itself in determining |
| * its default size. |
| * Thus this property may not have any effect if parented by |
| * Container, or containers that don't factor in |
| * this property. |
| * Because the value is in component coordinates, |
| * the true <code>explicitHeight</code> with respect to its parent |
| * is affected by the <code>scaleY</code> property.</p> |
| * <p>Setting the <code>height</code> property also sets this property to |
| * the specified height value.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get explicitHeight():Number |
| { |
| return _explicitHeight; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set explicitHeight(value:Number):void |
| { |
| if (_explicitHeight == value) |
| return; |
| |
| // height can be pixel or percent, not both |
| if (!isNaN(value)) |
| _percentHeight = NaN; |
| |
| _explicitHeight = value; |
| |
| // We invalidate size because locking in height |
| // may change the measured width in flow-based components. |
| invalidateSize(); |
| invalidateParentSizeAndDisplayList(); |
| |
| dispatchEvent(new Event("explicitHeightChanged")); |
| } |
| |
| //---------------------------------- |
| // hasComplexLayoutMatrix |
| //---------------------------------- |
| |
| /** |
| * @private |
| * |
| * when false, the transform on this component consists only of translation. Otherwise, it may be arbitrarily complex. |
| */ |
| private var _hasComplexLayoutMatrix:Boolean = false; |
| |
| /** |
| * Returns <code>true</code> if the UIComponent has any non-translation (x,y) transform properties. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| protected function get hasComplexLayoutMatrix():Boolean |
| { |
| // we set _hasComplexLayoutMatrix when any scale or rotation transform gets set |
| // because sometimes when those are set, we don't allocate a layoutFeatures object. |
| |
| // if the flag isn't set, we def. don't have a complex layout matrix. |
| // if the flag is set and we don't have an AdvancedLayoutFeatures object, |
| // then we'll check the transform and see if it's actually transformed. |
| // otherwise we'll check the layoutMatrix on the AdvancedLayoutFeatures object, |
| // to see if we're actually transformed. |
| if (!_hasComplexLayoutMatrix) { |
| return false; |
| } |
| else |
| { |
| if (_layoutFeatures == null) |
| { |
| var tmpMatrix:Matrix = super.transform.matrix; |
| _hasComplexLayoutMatrix = tmpMatrix && !MatrixUtil.isDeltaIdentity(tmpMatrix); |
| return _hasComplexLayoutMatrix; |
| } |
| else |
| { |
| return _layoutFeatures.layoutMatrix && !MatrixUtil.isDeltaIdentity(_layoutFeatures.layoutMatrix); |
| } |
| } |
| } |
| |
| //---------------------------------- |
| // includeInLayout |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the includeInLayout property. |
| */ |
| private var _includeInLayout:Boolean = true; |
| |
| [Bindable("includeInLayoutChanged")] |
| [Inspectable(category="General", defaultValue="true")] |
| |
| /** |
| * Specifies whether this component is included in the layout of the |
| * parent container. |
| * If <code>true</code>, the object is included in its parent container's |
| * layout and is sized and positioned by its parent container as per its layout rules. |
| * If <code>false</code>, the object size and position are not affected by its parent container's |
| * layout. |
| * |
| * @default true |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get includeInLayout():Boolean |
| { |
| return _includeInLayout; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set includeInLayout(value:Boolean):void |
| { |
| if (_includeInLayout != value) |
| { |
| _includeInLayout = value; |
| |
| var p:IInvalidating = parent as IInvalidating; |
| if (p) |
| { |
| p.invalidateSize(); |
| p.invalidateDisplayList(); |
| } |
| |
| dispatchEvent(new Event("includeInLayoutChanged")); |
| } |
| } |
| |
| //---------------------------------- |
| // layoutDirection |
| //---------------------------------- |
| |
| /** |
| * Checked at commitProperties() time to see if our layoutDirection has changed, |
| * or our parent's layoutDirection has changed. This variable is reset after the |
| * entire validateProperties() phase is complete so that it's possible for a child |
| * to check if its parent's layoutDirection has changed, see commitProperties(). |
| * The flag is cleared in validateDisplayList(). |
| */ |
| mx_internal var oldLayoutDirection:String = LayoutDirection.LTR; |
| |
| /** |
| * @inheritDoc |
| */ |
| public function get layoutDirection():String |
| { |
| if (layoutDirectionCachedValue == LAYOUT_DIRECTION_CACHE_UNSET) |
| { |
| layoutDirectionCachedValue = getStyle("layoutDirection"); |
| } |
| return layoutDirectionCachedValue; |
| } |
| |
| /** |
| * @private |
| * Changes to the layoutDirection style cause an invalidateProperties() call, |
| * see StyleProtoChain/styleChanged(). At commitProperties() time we use |
| * invalidateLayoutDirection() to add/remove the mirroring transform. |
| * |
| * layoutDirection=undefined or layoutDirection=null has the same effect |
| * as setStyle(“layoutDirection”, undefined). |
| */ |
| public function set layoutDirection(value:String):void |
| { |
| // Set the value to null to inherit the layoutDirection. |
| if (value == null) |
| setStyle("layoutDirection", undefined); |
| else |
| setStyle("layoutDirection", value); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Repeater |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // instanceIndex |
| //---------------------------------- |
| |
| /** |
| * The index of a repeated component. |
| * If the component is not within a Repeater, the value is -1. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get instanceIndex():int |
| { |
| // For efficiency, _instanceIndices starts out null rather than []. |
| return _instanceIndices ? |
| _instanceIndices[_instanceIndices.length - 1] : |
| -1; |
| } |
| |
| //---------------------------------- |
| // instanceIndices |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the instanceIndices and index properties. |
| */ |
| private var _instanceIndices:Array /* of int */; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * An Array containing the indices required to reference |
| * this UIComponent object from its parent document. |
| * The Array is empty unless this UIComponent object is within one or more Repeaters. |
| * The first element corresponds to the outermost Repeater. |
| * For example, if the id is "b" and instanceIndices is [2,4], |
| * you would reference it on the parent document as b[2][4]. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get instanceIndices():Array |
| { |
| // For efficiency, _instanceIndices starts out undefined rather than []. |
| return _instanceIndices ? _instanceIndices.slice(0) : null; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set instanceIndices(value:Array):void |
| { |
| _instanceIndices = value; |
| } |
| |
| //---------------------------------- |
| // repeater |
| //---------------------------------- |
| |
| /** |
| * A reference to the Repeater object |
| * in the parent document that produced this UIComponent. |
| * Use this property, rather than the <code>repeaters</code> property, |
| * when the UIComponent is created by a single Repeater object. |
| * Use the <code>repeaters</code> property when this UIComponent is created |
| * by nested Repeater objects. |
| * |
| * <p>The property is set to <code>null</code> when this UIComponent |
| * is not created by a Repeater.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get repeater():IRepeater |
| { |
| // For efficiency, _repeaters starts out undefined rather than []. |
| return _repeaters ? _repeaters[_repeaters.length - 1] : null; |
| } |
| |
| //---------------------------------- |
| // repeaters |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the repeaters and repeater properties. |
| */ |
| private var _repeaters:Array /* of Repeater */; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * An Array containing references to the Repeater objects |
| * in the parent document that produced this UIComponent. |
| * The Array is empty unless this UIComponent is within |
| * one or more Repeaters. |
| * The first element corresponds to the outermost Repeater object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get repeaters():Array |
| { |
| // For efficiency, _repeaters starts out undefined rather than []. |
| return _repeaters ? _repeaters.slice(0) : []; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set repeaters(value:Array):void |
| { |
| _repeaters = value; |
| } |
| |
| //---------------------------------- |
| // repeaterIndex |
| //---------------------------------- |
| |
| /** |
| * The index of the item in the data provider |
| * of the Repeater that produced this UIComponent. |
| * Use this property, rather than the <code>repeaterIndices</code> property, |
| * when the UIComponent is created by a single Repeater object. |
| * Use the <code>repeaterIndices</code> property when this UIComponent is created |
| * by nested Repeater objects. |
| * |
| * <p>This property is set to -1 when this UIComponent is |
| * not created by a Repeater.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get repeaterIndex():int |
| { |
| // For efficiency, _repeaterIndices starts out null rather than []. |
| return _repeaterIndices ? |
| _repeaterIndices[_repeaterIndices.length - 1] : |
| -1; |
| } |
| |
| //---------------------------------- |
| // repeaterIndices |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the repeaterIndices and repeaterIndex properties. |
| */ |
| private var _repeaterIndices:Array /* of int */; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * An Array containing the indices of the items in the data provider |
| * of the Repeaters in the parent document that produced this UIComponent. |
| * The Array is empty unless this UIComponent is within one or more Repeaters. |
| * |
| * <p>The first element in the Array corresponds to the outermost Repeater. |
| * For example, if <code>repeaterIndices</code> is [2,4] it means that the |
| * outer repeater used item <code>dataProvider[2]</code> and the inner repeater |
| * used item <code>dataProvider[4]</code>.</p> |
| * |
| * <p>Note that this property differs from the <code>instanceIndices</code> property |
| * if the <code>startingIndex</code> property of any of the Repeaters is not 0. |
| * For example, even if a Repeater starts at <code>dataProvider[4]</code>, |
| * the document reference of the first repeated object is b[0], not b[4].</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get repeaterIndices():Array |
| { |
| // For efficiency, _repeaterIndices starts out null rather than []. |
| return _repeaterIndices ? _repeaterIndices.slice() : []; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set repeaterIndices(value:Array):void |
| { |
| _repeaterIndices = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: States |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // currentState |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the currentState property. |
| */ |
| private var _currentState:String; |
| |
| /** |
| * @private |
| * Pending current state name. |
| */ |
| private var requestedCurrentState:String; |
| |
| /** |
| * @private |
| * Flag to play state transition |
| */ |
| private var playStateTransition:Boolean = true; |
| |
| /** |
| * @private |
| * Flag that is set when the currentState has changed and needs to be |
| * committed. |
| * This property name needs the initial underscore to avoid collisions |
| * with the "currentStateChange" event attribute. |
| */ |
| private var _currentStateChanged:Boolean; |
| |
| [Bindable("currentStateChange")] |
| |
| /** |
| * The current view state of the component. |
| * Set to <code>""</code> or <code>null</code> to reset |
| * the component back to its base state. |
| * |
| * <p>When you use this property to set a component's state, |
| * Flex applies any transition you have defined. |
| * You can also use the <code>setCurrentState()</code> method to set the |
| * current state; this method can optionally change states without |
| * applying a transition.</p> |
| * |
| * @see #setCurrentState() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get currentState():String |
| { |
| return _currentStateChanged ? requestedCurrentState : _currentState; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set currentState(value:String):void |
| { |
| // We have a deferred state change currently queued up, let's override |
| // the originally requested state with the newly requested. Otherwise |
| // we'll synchronously assign our new state. |
| if (_currentStateDeferred != null) |
| _currentStateDeferred = value; |
| else |
| setCurrentState(value, true); |
| } |
| |
| /** |
| * @private |
| * Backing variable for currentStateDeferred property |
| */ |
| private var _currentStateDeferred:String; |
| |
| /** |
| * @private |
| * Version of currentState property that defers setting currentState |
| * until commitProperties() time. This is used by SetProperty.remove() |
| * to avoid causing state transitions when currentState is being rolled |
| * back in a state change operation just to be set immediately after to the |
| * actual new currentState value. This avoids unnecessary, and sometimes |
| * incorrect, use of transitions based on this transient state of currentState. |
| */ |
| mx_internal function get currentStateDeferred():String |
| { |
| return (_currentStateDeferred != null) ? _currentStateDeferred : currentState; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function set currentStateDeferred(value:String):void |
| { |
| _currentStateDeferred = value; |
| if (value != null) |
| invalidateProperties(); |
| } |
| |
| |
| //---------------------------------- |
| // states |
| //---------------------------------- |
| |
| private var _states:Array /* of State */ = []; |
| |
| [Inspectable(arrayType="mx.states.State")] |
| [ArrayElementType("mx.states.State")] |
| |
| /** |
| * The view states that are defined for this component. |
| * You can specify the <code>states</code> property only on the root |
| * of the application or on the root tag of an MXML component. |
| * The compiler generates an error if you specify it on any other control. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get states():Array |
| { |
| return _states; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set states(value:Array):void |
| { |
| _states = value; |
| } |
| |
| //---------------------------------- |
| // transitions |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Transition currently playing. |
| */ |
| private var _currentTransition:Transition; |
| |
| private var _transitions:Array /* of Transition */ = []; |
| |
| [Inspectable(arrayType="mx.states.Transition")] |
| [ArrayElementType("mx.states.Transition")] |
| |
| /** |
| * An Array of Transition objects, where each Transition object defines a |
| * set of effects to play when a view state change occurs. |
| * |
| * @see mx.states.Transition |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get transitions():Array |
| { |
| return _transitions; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set transitions(value:Array):void |
| { |
| _transitions = value; |
| } |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Other |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // baselinePosition |
| //---------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get baselinePosition():Number |
| { |
| if (!validateBaselinePosition()) |
| return NaN; |
| |
| // Unless the height is very small, the baselinePosition |
| // of a generic UIComponent is calculated as if there was |
| // a UITextField using the component's styles |
| // whose top coincides with the component's top. |
| // If the height is small, the baselinePosition is calculated |
| // as if there were text within whose ascent the component |
| // is vertically centered. |
| // At the crossover height, these two calculations |
| // produce the same result. |
| |
| var lineMetrics:TextLineMetrics = measureText("Wj"); |
| |
| if (height < 2 + lineMetrics.ascent + 2) |
| return int(height + (lineMetrics.ascent - height) / 2); |
| |
| return 2 + lineMetrics.ascent; |
| } |
| |
| //---------------------------------- |
| // className |
| //---------------------------------- |
| |
| /** |
| * The name of this instance's class, such as <code>"Button"</code>. |
| * |
| * <p>This string does not include the package name. |
| * If you need the package name as well, call the |
| * <code>getQualifiedClassName()</code> method in the flash.utils package. |
| * It returns a string such as <code>"mx.controls::Button"</code>.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get className():String |
| { |
| return NameUtil.getUnqualifiedClassName(this); |
| } |
| |
| //---------------------------------- |
| // effectsStarted |
| //---------------------------------- |
| |
| /** |
| * The list of effects that are currently playing on the component, |
| * as an Array of EffectInstance instances. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get activeEffects():Array |
| { |
| return _effectsStarted; |
| } |
| |
| //---------------------------------- |
| // flexContextMenu |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the flexContextMenu property. |
| */ |
| private var _flexContextMenu:IFlexContextMenu; |
| |
| /** |
| * The context menu for this UIComponent. |
| * |
| * @default null |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get flexContextMenu():IFlexContextMenu |
| { |
| return _flexContextMenu; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set flexContextMenu(value:IFlexContextMenu):void |
| { |
| if (_flexContextMenu) |
| _flexContextMenu.unsetContextMenu(this); |
| |
| _flexContextMenu = value; |
| |
| if (value != null) |
| _flexContextMenu.setContextMenu(this); |
| } |
| |
| //---------------------------------- |
| // styleName |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the styleName property. |
| */ |
| private var _styleName:Object /* String, CSSStyleDeclaration, or UIComponent */; |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * The class style used by this component. This can be a String, CSSStyleDeclaration |
| * or an IStyleClient. |
| * |
| * <p>If this is a String, it is the name of one or more whitespace delimited class |
| * declarations in an <code><fx:Style></code> tag or CSS file. You do not include the period |
| * in the <code>styleName</code>. For example, if you have a class style named <code>".bigText"</code>, |
| * set the <code>styleName</code> property to <code>"bigText"</code> (no period).</p> |
| * |
| * <p>If this is an IStyleClient (typically a UIComponent), all styles in the |
| * <code>styleName</code> object are used by this component.</p> |
| * |
| * @default null |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get styleName():Object /* String, CSSStyleDeclaration, or UIComponent */ |
| { |
| return _styleName; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set styleName(value:Object /* String, CSSStyleDeclaration, or UIComponent */):void |
| { |
| if (_styleName === value) |
| return; |
| |
| _styleName = value; |
| |
| // If inheritingStyles is undefined, then this object is being |
| // initialized and we haven't yet generated the proto chain. |
| // To avoid redundant work, don't bother to create |
| // the proto chain here. |
| if (inheritingStyles == StyleProtoChain.STYLE_UNINITIALIZED) |
| return; |
| |
| regenerateStyleCache(true); |
| |
| initThemeColor(); |
| |
| styleChanged("styleName"); |
| |
| notifyStyleChangeInChildren("styleName", true); |
| } |
| |
| //---------------------------------- |
| // toolTip |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the toolTip property. |
| */ |
| mx_internal var _toolTip:String; |
| |
| [Bindable("toolTipChanged")] |
| [Inspectable(category="General", defaultValue="null")] |
| |
| /** |
| * Text to display in the ToolTip. |
| * |
| * @default null |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get toolTip():String |
| { |
| return _toolTip; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set toolTip(value:String):void |
| { |
| var oldValue:String = _toolTip; |
| _toolTip = value; |
| |
| ToolTipManager.registerToolTip(this, oldValue, value); |
| |
| dispatchEvent(new Event("toolTipChanged")); |
| } |
| |
| //---------------------------------- |
| // uid |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _uid:String; |
| |
| /** |
| * A unique identifier for the object. |
| * Flex data-driven controls, including all controls that are |
| * subclasses of List class, use a UID to track data provider items. |
| * |
| * <p>Flex can automatically create and manage UIDs. |
| * However, there are circumstances when you must supply your own |
| * <code>uid</code> property by implementing the IUID interface, |
| * or when supplying your own <code>uid</code> property improves processing efficiency. |
| * UIDs do not need to be universally unique for most uses in Flex. |
| * One exception is for messages sent by data services.</p> |
| * |
| * @see IUID |
| * @see mx.utils.UIDUtil |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get uid():String |
| { |
| if (!_uid) |
| _uid = toString(); |
| |
| return _uid; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set uid(uid:String):void |
| { |
| this._uid = uid; |
| } |
| |
| //---------------------------------- |
| // indexedID |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Utility getter used by uid. It returns an indexed id string |
| * such as "foo[1][2]" if this object is a repeated object, |
| * or a nonindexed id string like "bar" if it isn't. |
| */ |
| private function get indexedID():String |
| { |
| var s:String = id; |
| var indices:Array /* of int */ = instanceIndices; |
| if (indices) |
| s += "[" + indices.join("][") + "]"; |
| return s; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Popups |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // isPopUp |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _isPopUp:Boolean; |
| |
| [Inspectable(environment="none")] |
| |
| /** |
| * Set to <code>true</code> by the PopUpManager to indicate |
| * that component has been popped up. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get isPopUp():Boolean |
| { |
| return _isPopUp; |
| } |
| public function set isPopUp(value:Boolean):void |
| { |
| _isPopUp = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties: Required to support automated testing |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // automationDelegate |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _automationDelegate:IAutomationObject; |
| |
| /** |
| * The delegate object that handles the automation-related functionality. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get automationDelegate():Object |
| { |
| return _automationDelegate; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set automationDelegate(value:Object):void |
| { |
| _automationDelegate = value as IAutomationObject; |
| } |
| |
| //---------------------------------- |
| // automationName |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the <code>automationName</code> property. |
| */ |
| private var _automationName:String = null; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get automationName():String |
| { |
| if (_automationName) |
| return _automationName; |
| if (automationDelegate) |
| return automationDelegate.automationName; |
| |
| return ""; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set automationName(value:String):void |
| { |
| _automationName = value; |
| } |
| |
| /** |
| * @copy mx.automation.IAutomationObject#automationValue |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get automationValue():Array |
| { |
| if (automationDelegate) |
| return automationDelegate.automationValue; |
| |
| return []; |
| } |
| |
| //---------------------------------- |
| // showInAutomationHierarchy |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the <code>showInAutomationHierarchy</code> property. |
| */ |
| private var _showInAutomationHierarchy:Boolean = true; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get showInAutomationHierarchy():Boolean |
| { |
| return _showInAutomationHierarchy; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set showInAutomationHierarchy(value:Boolean):void |
| { |
| _showInAutomationHierarchy = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties Validation |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // errorString |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for errorString property. |
| */ |
| mx_internal var _errorString:String = ""; |
| |
| /** |
| * @private |
| * Storage for previous errorString property. |
| */ |
| private var oldErrorString:String = ""; |
| |
| /** |
| * @private |
| * Individual error messages from validators |
| */ |
| private var errorArray:Array; |
| |
| /** |
| * @private |
| * Array of validators who gave error messages |
| */ |
| private var errorObjectArray:Array; |
| |
| /** |
| * @private |
| * Flag set when error string changes. |
| */ |
| private var errorStringChanged:Boolean = false; |
| |
| [Bindable("errorStringChanged")] |
| |
| /** |
| * The text that displayed by a component's error tip when a |
| * component is monitored by a Validator and validation fails. |
| * |
| * <p>You can use the <code>errorString</code> property to show a |
| * validation error for a component, without actually using a validator class. |
| * When you write a String value to the <code>errorString</code> property, |
| * Flex draws a red border around the component to indicate the validation error, |
| * and the String appears in a tooltip as the validation error message when you move |
| * the mouse over the component, just as if a validator detected a validation error.</p> |
| * |
| * <p>To clear the validation error, write an empty String, "", |
| * to the <code>errorString</code> property.</p> |
| * |
| * <p>Note that writing a value to the <code>errorString</code> property |
| * does not trigger the valid or invalid events; it only changes the border |
| * color and displays the validation error message.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get errorString():String |
| { |
| return _errorString; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set errorString(value:String):void |
| { |
| if (value == _errorString) |
| return; |
| |
| oldErrorString = _errorString; |
| _errorString = value; |
| |
| errorStringChanged = true; |
| invalidateProperties(); |
| dispatchEvent(new Event("errorStringChanged")); |
| } |
| |
| /** |
| * @private |
| * Set the appropriate borderColor based on errorString. |
| * If we have an errorString, use errorColor. If we don't |
| * have an errorString, restore the original borderColor. |
| */ |
| private function setBorderColorForErrorString():void |
| { |
| var showErrorSkin:Boolean = FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0 || getStyle("showErrorSkin"); |
| |
| if (showErrorSkin) |
| { |
| |
| if (!_errorString || _errorString.length == 0) |
| { |
| if (!isNaN(origBorderColor)) |
| { |
| setStyle("borderColor", origBorderColor); |
| saveBorderColor = true; |
| } |
| } |
| else |
| { |
| // Remember the original border color |
| if (saveBorderColor) |
| { |
| saveBorderColor = false; |
| origBorderColor = getStyle("borderColor"); |
| } |
| |
| setStyle("borderColor", getStyle("errorColor")); |
| } |
| |
| styleChanged("themeColor"); |
| |
| var focusManager:IFocusManager = focusManager; |
| var focusObj:DisplayObject = focusManager ? |
| DisplayObject(focusManager.getFocus()) : |
| null; |
| if (focusManager && focusManager.showFocusIndicator && |
| focusObj == this) |
| { |
| drawFocus(true); |
| } |
| |
| } |
| } |
| |
| //---------------------------------- |
| // validationSubField |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the validationSubField property. |
| */ |
| private var _validationSubField:String; |
| |
| /** |
| * Used by a validator to associate a subfield with this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get validationSubField():String |
| { |
| return _validationSubField; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set validationSubField(value:String):void |
| { |
| _validationSubField = value; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| override public function addChild(child:DisplayObject):DisplayObject |
| { |
| var formerParent:DisplayObjectContainer = child.parent; |
| if (formerParent && !(formerParent is Loader)) |
| formerParent.removeChild(child); |
| |
| // If there is an overlay, place the child underneath it. |
| var index:int = effectOverlayReferenceCount && child != effectOverlay ? |
| Math.max(0, super.numChildren - 1) : |
| super.numChildren; |
| |
| // Do anything that needs to be done before the child is added. |
| // When adding a child to UIComponent, this will set the child's |
| // virtual parent, its nestLevel, its document, etc. |
| // When adding a child to a Container, the override will also |
| // invalidate the container, adjust its content/chrome partitions, |
| // etc. |
| addingChild(child); |
| |
| // Call a low-level player method in DisplayObjectContainer which |
| // actually attaches the child to this component. |
| // The player dispatches an "added" event from the child just after |
| // it is attached, so all "added" handlers execute during this call. |
| // UIComponent registers an addedHandler() in its constructor, |
| // which makes it runs before any other "added" handlers except |
| // capture-phase ones; it sets up the child's styles. |
| $addChildAt(child, index); |
| |
| // Do anything that needs to be done after the child is added |
| // and after all "added" handlers have executed. |
| // This is where |
| childAdded(child); |
| |
| return child; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function addChildAt(child:DisplayObject, |
| index:int):DisplayObject |
| { |
| var formerParent:DisplayObjectContainer = child.parent; |
| if (formerParent && !(formerParent is Loader)) |
| formerParent.removeChild(child); |
| |
| // If there is an overlay, place the child underneath it. |
| if (effectOverlayReferenceCount && child != effectOverlay) |
| index = Math.min(index, Math.max(0, super.numChildren - 1)); |
| |
| addingChild(child); |
| |
| $addChildAt(child, index); |
| |
| childAdded(child); |
| |
| return child; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function removeChild(child:DisplayObject):DisplayObject |
| { |
| removingChild(child); |
| |
| $removeChild(child); |
| |
| childRemoved(child); |
| |
| return child; |
| } |
| |
| |
| /** |
| * @private |
| */ |
| override public function removeChildAt(index:int):DisplayObject |
| { |
| var child:DisplayObject = getChildAt(index); |
| |
| removingChild(child); |
| |
| $removeChild(child); |
| |
| childRemoved(child); |
| |
| return child; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function setChildIndex(child:DisplayObject, |
| newIndex:int):void |
| { |
| // Place the child underneath the overlay. |
| if (effectOverlayReferenceCount && child != effectOverlay) |
| newIndex = Math.min(newIndex, Math.max(0, super.numChildren - 2)); |
| |
| super.setChildIndex(child, newIndex); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function stopDrag():void |
| { |
| super.stopDrag(); |
| |
| invalidateProperties(); |
| |
| dispatchEvent(new Event("xChanged")); |
| dispatchEvent(new Event("yChanged")); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Access to overridden methods of base classes |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of addChild(), which can be useful since components |
| * can override addChild() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $addChild(child:DisplayObject):DisplayObject |
| { |
| return super.addChild(child); |
| } |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of addChildAt(), which can be useful since components |
| * can override addChildAt() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $addChildAt(child:DisplayObject, |
| index:int):DisplayObject |
| { |
| return super.addChildAt(child, index); |
| } |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of removeChild(), which can be useful since components |
| * can override removeChild() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $removeChild(child:DisplayObject):DisplayObject |
| { |
| return super.removeChild(child); |
| } |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of removeChildAt(), which can be useful since components |
| * can override removeChildAt() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $removeChildAt(index:int):DisplayObject |
| { |
| return super.removeChildAt(index); |
| } |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of setChildIndex(), which can be useful since components |
| * can override setChildIndex() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $setChildIndex(child:DisplayObject, index:int):void |
| { |
| super.setChildIndex(child, index); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Initialization |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| mx_internal function updateCallbacks():void |
| { |
| if (invalidateDisplayListFlag) |
| UIComponentGlobals.layoutManager.invalidateDisplayList(this); |
| |
| if (invalidateSizeFlag) |
| UIComponentGlobals.layoutManager.invalidateSize(this); |
| |
| if (invalidatePropertiesFlag) |
| UIComponentGlobals.layoutManager.invalidateProperties(this); |
| |
| // systemManager getter tries to set the internal _systemManager varaible |
| // if it is null. Hence a call to the getter is necessary. |
| // Stage can be null when an untrusted application is loaded by an application |
| // that isn't on stage yet. |
| if (systemManager && (_systemManager.stage || usingBridge)) |
| { |
| if (methodQueue.length > 0 && !listeningForRender) |
| { |
| _systemManager.addEventListener(FlexEvent.RENDER, callLaterDispatcher); |
| _systemManager.addEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher); |
| listeningForRender = true; |
| } |
| |
| if (_systemManager.stage) |
| _systemManager.stage.invalidate(); |
| } |
| } |
| |
| /** |
| * Called by Flex when a UIComponent object is added to or removed from a parent. |
| * Developers typically never need to call this method. |
| * |
| * @param p The parent of this UIComponent object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function parentChanged(p:DisplayObjectContainer):void |
| { |
| // trace("parentChanged: " + _parent + " of " + this + " changed to "); |
| |
| if (!p) |
| { |
| _parent = null; |
| nestLevel = 0; |
| } |
| else if (p is IStyleClient) |
| { |
| _parent = p; |
| } |
| else if (p is ISystemManager) |
| { |
| _parent = p; |
| } |
| else |
| { |
| _parent = p.parent; |
| } |
| |
| // trace(" " + p); |
| parentChangedFlag = true; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function addingChild(child:DisplayObject):void |
| { |
| // If the document property isn't already set on the child, |
| // set it to be the same as this component's document. |
| // The document setter will recursively set it on any |
| // descendants of the child that exist. |
| if (child is IUIComponent && |
| !IUIComponent(child).document) |
| { |
| IUIComponent(child).document = document ? |
| document : |
| FlexGlobals.topLevelApplication; |
| } |
| |
| // Propagate moduleFactory to the child, but don't overwrite an existing moduleFactory. |
| if (child is IFlexModule && IFlexModule(child).moduleFactory == null) |
| { |
| if (moduleFactory != null) |
| IFlexModule(child).moduleFactory = moduleFactory; |
| |
| else if (document is IFlexModule && document.moduleFactory != null) |
| IFlexModule(child).moduleFactory = document.moduleFactory; |
| |
| else if (parent is IFlexModule && IFlexModule(parent).moduleFactory != null) |
| IFlexModule(child).moduleFactory = IFlexModule(parent).moduleFactory; |
| } |
| |
| // Set the font context in non-UIComponent children. |
| // UIComponent children use moduleFactory. |
| if (child is IFontContextComponent && !(child is UIComponent) && |
| IFontContextComponent(child).fontContext == null) |
| IFontContextComponent(child).fontContext = moduleFactory; |
| |
| if (child is IUIComponent) |
| IUIComponent(child).parentChanged(this); |
| |
| // Set the nestLevel of the child to be one greater |
| // than the nestLevel of this component. |
| // The nestLevel setter will recursively set it on any |
| // descendants of the child that exist. |
| if (child is ILayoutManagerClient) |
| ILayoutManagerClient(child).nestLevel = nestLevel + 1; |
| else if (child is IUITextField) |
| IUITextField(child).nestLevel = nestLevel + 1; |
| |
| if (child is InteractiveObject) |
| if (doubleClickEnabled) |
| InteractiveObject(child).doubleClickEnabled = true; |
| |
| // Sets up the inheritingStyles and nonInheritingStyles objects |
| // and their proto chains so that getStyle() works. |
| // If this object already has some children, |
| // then reinitialize the children's proto chains. |
| if (child is IStyleClient) |
| IStyleClient(child).regenerateStyleCache(true); |
| else if (child is IUITextField && IUITextField(child).inheritingStyles) |
| StyleProtoChain.initTextField(IUITextField(child)); |
| |
| if (child is ISimpleStyleClient) |
| ISimpleStyleClient(child).styleChanged(null); |
| |
| if (child is IStyleClient) |
| IStyleClient(child).notifyStyleChangeInChildren(null, true); |
| |
| if (child is UIComponent) |
| UIComponent(child).initThemeColor(); |
| |
| // Inform the component that it's style properties |
| // have been fully initialized. Most components won't care, |
| // but some need to react to even this early change. |
| if (child is UIComponent) |
| UIComponent(child).stylesInitialized(); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function childAdded(child:DisplayObject):void |
| { |
| if (!UIComponentGlobals.designMode) |
| { |
| if (child is UIComponent) |
| { |
| if (!UIComponent(child).initialized) |
| UIComponent(child).initialize(); |
| } |
| else if (child is IUIComponent) |
| { |
| IUIComponent(child).initialize(); |
| } |
| } |
| else |
| { |
| try |
| { |
| if (child is UIComponent) |
| { |
| if (!UIComponent(child).initialized) |
| UIComponent(child).initialize(); |
| } |
| else if (child is IUIComponent) |
| { |
| IUIComponent(child).initialize(); |
| } |
| } |
| catch (e:Error) |
| { |
| // Dispatch a initializeError dynamic event for tooling. |
| var initializeErrorEvent:DynamicEvent = new DynamicEvent("initializeError"); |
| initializeErrorEvent.error = e; |
| initializeErrorEvent.source = child; |
| systemManager.dispatchEvent(initializeErrorEvent); |
| } |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function removingChild(child:DisplayObject):void |
| { |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function childRemoved(child:DisplayObject):void |
| { |
| if (child is IUIComponent) |
| { |
| // only reset document if the child isn't |
| // a document itself |
| if (IUIComponent(child).document != child) |
| IUIComponent(child).document = null; |
| IUIComponent(child).parentChanged(null); |
| } |
| } |
| |
| /** |
| * Initializes the internal structure of this component. |
| * |
| * <p>Initializing a UIComponent is the fourth step in the creation |
| * of a visual component instance, and happens automatically |
| * the first time that the instance is added to a parent. |
| * Therefore, you do not generally need to call |
| * <code>initialize()</code>; the Flex framework calls it for you |
| * from UIComponent's override of the <code>addChild()</code> |
| * and <code>addChildAt()</code> methods.</p> |
| * |
| * <p>The first step in the creation of a visual component instance |
| * is construction, with the <code>new</code> operator:</p> |
| * |
| * <pre> |
| * var okButton:Button = new Button();</pre> |
| * |
| * <p>After construction, the new Button instance is a solitary |
| * DisplayObject; it does not yet have a UITextField as a child |
| * to display its label, and it doesn't have a parent.</p> |
| * |
| * <p>The second step is configuring the newly-constructed instance |
| * with the appropriate properties, styles, and event handlers:</p> |
| * |
| * <pre> |
| * okButton.label = "OK"; |
| * okButton.setStyle("cornerRadius", 0); |
| * okButton.addEventListener(MouseEvent.CLICK, clickHandler);</pre> |
| * |
| * <p>The third step is adding the instance to a parent:</p> |
| * |
| * <pre> |
| * someContainer.addChild(okButton);</pre> |
| * |
| * <p>A side effect of calling <code>addChild()</code> |
| * or <code>addChildAt()</code>, when adding a component to a parent |
| * for the first time, is that <code>initialize</code> gets |
| * automatically called.</p> |
| * |
| * <p>This method first dispatches a <code>preinitialize</code> event, |
| * giving developers using this component a chance to affect it |
| * before its internal structure has been created. |
| * Next it calls the <code>createChildren()</code> method |
| * to create the component's internal structure; for a Button, |
| * this method creates and adds the UITextField for the label. |
| * Then it dispatches an <code>initialize</code> event, |
| * giving developers a chance to affect the component |
| * after its internal structure has been created.</p> |
| * |
| * <p>Note that it is the act of attaching a component to a parent |
| * for the first time that triggers the creation of its internal structure. |
| * If its internal structure includes other UIComponents, then this is a |
| * recursive process in which the tree of DisplayObjects grows by one leaf |
| * node at a time.</p> |
| * |
| * <p>If you are writing a component, you do not need |
| * to override this method.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function initialize():void |
| { |
| if (initialized) |
| return; |
| |
| // The "preinitialize" event gets dispatched after everything about this |
| // DisplayObject has been initialized, and it has been attached to |
| // its parent, but before any of its children have been created. |
| // This allows a "preinitialize" event handler to set properties which |
| // affect child creation. |
| // Note that this implies that "preinitialize" handlers are called |
| // top-down; i.e., parents before children. |
| dispatchEvent(new FlexEvent(FlexEvent.PREINITIALIZE)); |
| |
| // Create child objects. |
| |
| CONFIG::performanceInstrumentation |
| { |
| var perfUtil:mx.utils.PerfUtil = mx.utils.PerfUtil.getInstance(); |
| var token:int = perfUtil.markStart(); |
| } |
| |
| createChildren(); |
| |
| CONFIG::performanceInstrumentation |
| { |
| perfUtil.markEnd(".createChildren()", token, 2 /*tolerance*/, this); |
| } |
| |
| childrenCreated(); |
| |
| // Create and initialize the accessibility implementation. |
| // for this component. For some components accessible object is attached |
| // to child component so it should be called after createChildren |
| initializeAccessibility(); |
| |
| // This should always be the last thing that initialize() calls. |
| initializationComplete(); |
| } |
| |
| /** |
| * Finalizes the initialization of this component. |
| * |
| * <p>This method is the last code that executes when you add a component |
| * to a parent for the first time using <code>addChild()</code> |
| * or <code>addChildAt()</code>. |
| * It handles some housekeeping related to dispatching |
| * the <code>initialize</code> event. |
| * If you are writing a component, you do not need |
| * to override this method.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function initializationComplete():void |
| { |
| processedDescriptors = true; |
| } |
| |
| /** |
| * Initializes this component's accessibility code. |
| * |
| * <p>This method is called by the <code>initialize()</code> method to hook in the |
| * component's accessibility code, which resides in a separate class |
| * in the mx.accessibility package. |
| * Each subclass that supports accessibility must override this method |
| * because the hook-in process uses a different static variable |
| * in each subclass.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function initializeAccessibility():void |
| { |
| if (UIComponent.createAccessibilityImplementation != null) |
| UIComponent.createAccessibilityImplementation(this); |
| } |
| |
| /** |
| * Initializes various properties which keep track of repeated instances |
| * of this component. |
| * |
| * <p>An MXML <code><mx:Repeater/></code> tag can cause repeated instances |
| * of a component to be created, one instance for each item in the |
| * Repeater's data provider. |
| * The <code>instanceIndices</code>, <code>repeaters</code>, |
| * and <code>repeaterIndices</code> properties of UIComponent |
| * keep track of which instance came from which data item |
| * and which Repeater.</p> |
| * |
| * <p>This method is an internal method which is automatically called |
| * by the Flex framework. |
| * You do not have to call it or override it.</p> |
| * |
| * @param parent The parent object containing the Repeater that created |
| * this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function initializeRepeaterArrays(parent:IRepeaterClient):void |
| { |
| // In the case, where the parent is a document, but isn't the |
| // child's document, we want to copy the instanceIndices down. |
| // See SDK-15317. |
| if (parent && parent.instanceIndices && |
| ((!parent.isDocument) || (parent != descriptor.document)) && |
| !_instanceIndices) |
| { |
| _instanceIndices = parent.instanceIndices; |
| _repeaters = parent.repeaters; |
| _repeaterIndices = parent.repeaterIndices; |
| } |
| } |
| |
| /** |
| * Create child objects of the component. |
| * This is an advanced method that you might override |
| * when creating a subclass of UIComponent. |
| * |
| * <p>A component that creates other components or objects within it is called a composite component. |
| * For example, the Flex ComboBox control is actually made up of a TextInput control |
| * to define the text area of the ComboBox, and a Button control to define the ComboBox arrow. |
| * Components implement the <code>createChildren()</code> method to create child |
| * objects (such as other components) within the component.</p> |
| * |
| * <p>From within an override of the <code>createChildren()</code> method, |
| * you call the <code>addChild()</code> method to add each child object. </p> |
| * |
| * <p>You do not call this method directly. Flex calls the |
| * <code>createChildren()</code> method in response to the call to |
| * the <code>addChild()</code> method to add the component to its parent. </p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function createChildren():void |
| { |
| var children:Array = this.MXMLDescriptor; |
| if (children && !processedMXMLDescriptors) |
| { |
| generateMXMLInstances(document, children); |
| processedMXMLDescriptors = true; |
| } |
| } |
| |
| protected function addMXMLChildren(comps:Array):void |
| { |
| for each (var i:Object in comps) |
| { |
| addChild(i as DisplayObject); |
| } |
| } |
| |
| protected function generateMXMLObject(document:Object, data:Array):Object |
| { |
| var i:int = 0; |
| var cls:Class = data[i++]; |
| var comp:Object = new cls(); |
| |
| var m:int; |
| var j:int; |
| var name:String; |
| var simple:*; |
| var value:Object; |
| var id:String; |
| |
| m = data[i++]; // num props |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple === null) |
| value = generateMXMLArray(document, value as Array); |
| else if (simple === undefined) |
| value = generateMXMLVector(document, value as Array); |
| else if (simple == false) |
| value = generateMXMLObject(document, value as Array); |
| if (name == "id") |
| { |
| document[value] = comp; |
| id = value as String; |
| if (comp is IMXMLObject) |
| continue; // skip assigment to comp |
| if (!("id" in comp)) |
| continue; |
| } |
| else if (name == "_id") |
| { |
| document[value] = comp; |
| id = value as String; |
| continue; // skip assignment to comp |
| } |
| comp[name] = value; |
| } |
| m = data[i++]; // num styles |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple == null) |
| value = generateMXMLArray(document, value as Array); |
| else if (simple == false) |
| value = generateMXMLObject(document, value as Array); |
| comp.setStyle(name, value); |
| } |
| |
| m = data[i++]; // num effects |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple == null) |
| value = generateMXMLArray(document, value as Array); |
| else if (simple == false) |
| value = generateMXMLObject(document, value as Array); |
| comp.setStyle(name, value); |
| } |
| |
| m = data[i++]; // num events |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| value = data[i++]; |
| comp.addEventListener(name, value); |
| } |
| |
| if (comp is IUIComponent) |
| { |
| if (comp.document == null) |
| comp.document = document; |
| } |
| var children:Array = data[i++]; |
| if (children) |
| { |
| comp.generateMXMLInstances(document, children); |
| } |
| |
| if (id) |
| { |
| document[id] = comp; |
| mx.binding.BindingManager.executeBindings(document, id, comp); |
| } |
| if (comp is IMXMLObject) |
| comp.initialized(document, id); |
| return comp; |
| } |
| |
| public function generateMXMLVector(document:Object, data:Array, recursive:Boolean = true):* |
| { |
| var comps:Array; |
| |
| var n:int = data.length; |
| var hint:* = data.shift(); |
| var generatorFunction:Function = data.shift(); |
| comps = generateMXMLArray(document, data, recursive); |
| return generatorFunction(comps); |
| } |
| |
| public function generateMXMLArray(document:Object, data:Array, recursive:Boolean = true):Array |
| { |
| var comps:Array = []; |
| |
| var n:int = data.length; |
| var i:int = 0; |
| while (i < n) |
| { |
| var cls:Class = data[i++]; |
| var comp:Object = new cls(); |
| |
| var m:int; |
| var j:int; |
| var name:String; |
| var simple:*; |
| var value:Object; |
| var id:String = null; |
| |
| m = data[i++]; // num props |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple === null) |
| value = generateMXMLArray(document, value as Array, recursive); |
| else if (simple === undefined) |
| value = generateMXMLVector(document, value as Array, recursive); |
| else if (simple == false) |
| value = generateMXMLObject(document, value as Array); |
| if (name == "id") |
| { |
| document[value] = comp; |
| id = value as String; |
| if (comp is IMXMLObject) |
| continue; // skip assigment to comp |
| try { |
| if (!("id" in comp)) |
| continue; |
| } |
| catch (e:Error) |
| { |
| continue; // proxy subclasses might throw here |
| } |
| } |
| if (name == "document" && !comp.document) |
| comp.document = document; |
| else if (name == "_id") |
| id = value as String; // and don't assign to comp |
| else |
| comp[name] = value; |
| } |
| m = data[i++]; // num styles |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple == null) |
| value = generateMXMLArray(document, value as Array, recursive); |
| else if (simple == false) |
| value = generateMXMLObject(document, value as Array); |
| comp.setStyle(name, value); |
| } |
| |
| m = data[i++]; // num effects |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple == null) |
| value = generateMXMLArray(document, value as Array, recursive); |
| else if (simple == false) |
| value = generateMXMLObject(document, value as Array); |
| comp.setStyle(name, value); |
| } |
| |
| m = data[i++]; // num events |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| value = data[i++]; |
| comp.addEventListener(name, value); |
| } |
| |
| if (comp is IUIComponent) |
| { |
| if (comp.document == null) |
| comp.document = document; |
| } |
| var children:Array = data[i++]; |
| if (children) |
| { |
| if (recursive) |
| comp.generateMXMLInstances(document, children, recursive); |
| else |
| comp.setMXMLDescriptor(children); |
| } |
| |
| if (id) |
| { |
| document[id] = comp; |
| mx.binding.BindingManager.executeBindings(document, id, comp); |
| } |
| if (comp is IMXMLObject) |
| comp.initialized(document, id); |
| comps.push(comp); |
| } |
| return comps; |
| } |
| |
| protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void |
| { |
| var comps:Array = generateMXMLArray(document, data, recursive); |
| var children:Array = []; |
| for each (var comp:Object in comps) |
| { |
| if (comp is DisplayObject || comp is IVisualElement) |
| children.push(comp); |
| } |
| addMXMLChildren(children); |
| } |
| |
| protected function generateMXMLAttributes(data:Array):void |
| { |
| var i:int = 0; |
| var m:int; |
| var j:int; |
| var name:String; |
| var simple:*; |
| var value:Object; |
| var id:String = null; |
| |
| m = data[i++]; // num props |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple === null) |
| value = generateMXMLArray(this, value as Array); |
| else if (simple === undefined) |
| value = generateMXMLVector(this, value as Array); |
| else if (simple == false) |
| value = generateMXMLObject(this, value as Array); |
| if (name == "id") |
| id = value as String; |
| if (name == "_id") |
| id = value as String; // and don't assign |
| else |
| this[name] = value; |
| } |
| m = data[i++]; // num styles |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple == null) |
| value = generateMXMLArray(this, value as Array, false); |
| else if (simple == false) |
| value = generateMXMLObject(this, value as Array); |
| this.setStyle(name, value); |
| } |
| |
| m = data[i++]; // num effects |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| simple = data[i++]; |
| value = data[i++]; |
| if (simple == null) |
| value = generateMXMLArray(this, value as Array, false); |
| else if (simple == false) |
| value = generateMXMLObject(this, value as Array); |
| this.setStyle(name, value); |
| } |
| |
| m = data[i++]; // num events |
| for (j = 0; j < m; j++) |
| { |
| name = data[i++]; |
| value = data[i++]; |
| this.addEventListener(name, value as Function); |
| } |
| } |
| |
| mx_internal function setupBindings(bindingData:Array):void |
| { |
| var fieldWatcher:Object; |
| var n:int = bindingData[0]; |
| var bindings:Array = []; |
| var i:int; |
| var index:int = 1; |
| for (i = 0; i < n; i++) |
| { |
| var source:Object = bindingData[index++]; |
| var destFunc:Object = bindingData[index++]; |
| var destStr:Object = bindingData[index++]; |
| var binding:Binding = new Binding(this, |
| (source is Function) ? source as Function : null, |
| (destFunc is Function) ? destFunc as Function : null, |
| (destStr is String) ? destStr as String : destStr.join("."), |
| (source is Function) ? null : (source is String) ? source as String : source.join(".")); |
| bindings.push(binding); |
| } |
| var watchers:Object = decodeWatcher(this, bindingData.slice(index), bindings); |
| this["_bindings"] = bindings; |
| this["_watchers"] = watchers; |
| for each (binding in bindings) |
| binding.execute(); |
| |
| } |
| |
| private function decodeWatcher(target:Object, bindingData:Array, bindings:Array):Array |
| { |
| var watcherMap:Object = {}; |
| var watchers:Array = []; |
| var n:int = bindingData.length; |
| var index:int = 0; |
| var watcherData:Object; |
| var theBindings:Array; |
| var bindingIndices:Array; |
| var bindingIndex:int; |
| var propertyName:String; |
| var eventNames:Array; |
| var eventName:String; |
| var eventObject:Object; |
| var getterFunction:Function; |
| var value:*; |
| var w:Watcher; |
| |
| while (index < n) |
| { |
| var parentObj:Object = target; |
| var watcherIndex:int = bindingData[index++]; |
| var type:int = bindingData[index++]; |
| switch (type) |
| { |
| case 0: |
| { |
| var functionName:String = bindingData[index++]; |
| var paramFunction:Function = bindingData[index++]; |
| value = bindingData[index++]; |
| if (value is String) |
| eventNames = [ value ]; |
| else |
| eventNames = value; |
| eventObject = {}; |
| for each (eventName in eventNames) |
| eventObject[eventName] = true; |
| value = bindingData[index++]; |
| if (value is Array) |
| bindingIndices = value; |
| else |
| bindingIndices = [ value ]; |
| theBindings = []; |
| for each (bindingIndex in bindingIndices) |
| theBindings.push(bindings[bindingIndex]); |
| w = new FunctionReturnWatcher(functionName, |
| this, |
| paramFunction, |
| eventObject, |
| theBindings); |
| break; |
| } |
| case 1: |
| { |
| propertyName = bindingData[index++]; |
| value = bindingData[index++]; |
| if (value is String) |
| eventNames = [ value ]; |
| else |
| eventNames = value; |
| eventObject = {}; |
| for each (eventName in eventNames) |
| eventObject[eventName] = true; |
| value = bindingData[index++]; |
| if (value is Array) |
| bindingIndices = value; |
| else |
| bindingIndices = [ value ]; |
| theBindings = []; |
| for each (bindingIndex in bindingIndices) |
| theBindings.push(bindings[bindingIndex]); |
| getterFunction = bindingData[index++]; |
| w = new StaticPropertyWatcher(propertyName, |
| eventObject, theBindings, getterFunction); |
| parentObj = bindingData[index++]; |
| break; |
| } |
| case 2: |
| { |
| propertyName = bindingData[index++]; |
| value = bindingData[index++]; |
| if (value is String) |
| eventNames = [ value ]; |
| else |
| eventNames = value; |
| eventObject = {}; |
| for each (eventName in eventNames) |
| eventObject[eventName] = true; |
| value = bindingData[index++]; |
| if (value is Array) |
| bindingIndices = value; |
| else |
| bindingIndices = [ value ]; |
| theBindings = []; |
| for each (bindingIndex in bindingIndices) |
| theBindings.push(bindings[bindingIndex]); |
| getterFunction = bindingData[index++]; |
| w = new PropertyWatcher(propertyName, |
| eventObject, theBindings, getterFunction); |
| break; |
| } |
| case 3: |
| { |
| propertyName = bindingData[index++]; |
| value = bindingData[index++]; |
| if (value is Array) |
| bindingIndices = value; |
| else |
| bindingIndices = [ value ]; |
| theBindings = []; |
| for each (bindingIndex in bindingIndices) |
| theBindings.push(bindings[bindingIndex]); |
| w = new XMLWatcher(propertyName, theBindings); |
| break; |
| } |
| } |
| watchers.push(w); |
| w.updateParent(parentObj); |
| if (target is Watcher) |
| { |
| if (w is FunctionReturnWatcher) |
| FunctionReturnWatcher(w).parentWatcher = Watcher(target); |
| Watcher(target).addChild(w); |
| } |
| |
| var children:Array = bindingData[index++]; |
| if (children != null) |
| { |
| children = decodeWatcher(w, children, bindings); |
| } |
| } |
| return watchers; |
| } |
| |
| /** |
| * Performs any final processing after child objects are created. |
| * This is an advanced method that you might override |
| * when creating a subclass of UIComponent. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function childrenCreated():void |
| { |
| invalidateProperties(); |
| invalidateSize(); |
| invalidateDisplayList(); |
| } |
| |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Invalidation |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Marks a component so that its <code>commitProperties()</code> |
| * method gets called during a later screen update. |
| * |
| * <p>Invalidation is a useful mechanism for eliminating duplicate |
| * work by delaying processing of changes to a component until a |
| * later screen update. |
| * For example, if you want to change the text color and size, |
| * it would be wasteful to update the color immediately after you |
| * change it and then update the size when it gets set. |
| * It is more efficient to change both properties and then render |
| * the text with its new size and color once.</p> |
| * |
| * <p>Invalidation methods rarely get called. |
| * In general, setting a property on a component automatically |
| * calls the appropriate invalidation method.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function invalidateProperties():void |
| { |
| if (!invalidatePropertiesFlag) |
| { |
| invalidatePropertiesFlag = true; |
| |
| if (nestLevel && UIComponentGlobals.layoutManager) |
| UIComponentGlobals.layoutManager.invalidateProperties(this); |
| } |
| } |
| |
| /** |
| * Marks a component so that its <code>measure()</code> |
| * method gets called during a later screen update. |
| * |
| * <p>Invalidation is a useful mechanism for eliminating duplicate |
| * work by delaying processing of changes to a component until a |
| * later screen update. |
| * For example, if you want to change the text and font size, |
| * it would be wasteful to update the text immediately after you |
| * change it and then update the size when it gets set. |
| * It is more efficient to change both properties and then render |
| * the text with its new size once.</p> |
| * |
| * <p>Invalidation methods rarely get called. |
| * In general, setting a property on a component automatically |
| * calls the appropriate invalidation method.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function invalidateSize():void |
| { |
| if (!invalidateSizeFlag) |
| { |
| invalidateSizeFlag = true; |
| |
| if (nestLevel && UIComponentGlobals.layoutManager) |
| UIComponentGlobals.layoutManager.invalidateSize(this); |
| } |
| } |
| |
| /** |
| * Helper method to invalidate parent size and display list if |
| * this object affects its layout (includeInLayout is true). |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function invalidateParentSizeAndDisplayList():void |
| { |
| if (!includeInLayout) |
| return; |
| |
| var p:IInvalidating = parent as IInvalidating; |
| if (!p) |
| return; |
| |
| p.invalidateSize(); |
| p.invalidateDisplayList(); |
| } |
| |
| /** |
| * Marks a component so that its <code>updateDisplayList()</code> |
| * method gets called during a later screen update. |
| * |
| * <p>Invalidation is a useful mechanism for eliminating duplicate |
| * work by delaying processing of changes to a component until a |
| * later screen update. |
| * For example, if you want to change the width and height, |
| * it would be wasteful to update the component immediately after you |
| * change the width and then update again with the new height. |
| * It is more efficient to change both properties and then render |
| * the component with its new size once.</p> |
| * |
| * <p>Invalidation methods rarely get called. |
| * In general, setting a property on a component automatically |
| * calls the appropriate invalidation method.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function invalidateDisplayList():void |
| { |
| if (!invalidateDisplayListFlag) |
| { |
| invalidateDisplayListFlag = true; |
| |
| if (nestLevel && UIComponentGlobals.layoutManager) |
| UIComponentGlobals.layoutManager.invalidateDisplayList(this); |
| } |
| } |
| |
| private function invalidateTransform():void |
| { |
| if (_layoutFeatures && _layoutFeatures.updatePending == false) |
| { |
| _layoutFeatures.updatePending = true; |
| if (nestLevel && UIComponentGlobals.layoutManager && |
| invalidateDisplayListFlag == false) |
| { |
| UIComponentGlobals.layoutManager.invalidateDisplayList(this); |
| } |
| } |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function invalidateLayoutDirection():void |
| { |
| const parentElt:ILayoutDirectionElement = parent as ILayoutDirectionElement; |
| const thisLayoutDirection:String = layoutDirection; |
| |
| // If this element's layoutDirection doesn't match its parent's, then |
| // set the _layoutFeatures.mirror flag. Similarly, if mirroring isn't |
| // required, then clear the _layoutFeatures.mirror flag. |
| |
| const mirror:Boolean = (parentElt) |
| ? (parentElt.layoutDirection != thisLayoutDirection) |
| : (LayoutDirection.LTR != thisLayoutDirection); |
| |
| if ((_layoutFeatures) ? (mirror != _layoutFeatures.mirror) : mirror) |
| { |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| _layoutFeatures.mirror = mirror; |
| // width may have already been set |
| _layoutFeatures.layoutWidth = _width; |
| invalidateTransform(); |
| } |
| |
| // Children are notified only if the component's layoutDirection has changed. |
| if (oldLayoutDirection != layoutDirection) |
| { |
| var i:int; |
| |
| // If we have children, the styleChanged() machinery (via commitProperties()) will |
| // deal with UIComponent children. We have to deal with IVisualElement and |
| // ILayoutDirectionElement children that don't support styles, like GraphicElements, here. |
| if (this is IVisualElementContainer) |
| { |
| const thisContainer:IVisualElementContainer = IVisualElementContainer(this); |
| const thisContainerNumElements:int = thisContainer.numElements; |
| |
| for (i = 0; i < thisContainerNumElements; i++) |
| { |
| var elt:IVisualElement = thisContainer.getElementAt(i); |
| // Can be null if IUITextField or IUIFTETextField. |
| if (elt && !(elt is IStyleClient)) |
| elt.invalidateLayoutDirection(); |
| } |
| } |
| else |
| { |
| const thisNumChildren:int = numChildren; |
| |
| for (i = 0; i < thisNumChildren; i++) |
| { |
| var child:DisplayObject = getChildAt(i); |
| if (!(child is IStyleClient) && child is ILayoutDirectionElement) |
| ILayoutDirectionElement(child).invalidateLayoutDirection(); |
| } |
| } |
| } |
| } |
| |
| private function transformOffsetsChangedHandler(e:Event):void |
| { |
| invalidateTransform(); |
| } |
| |
| |
| /** |
| * Flex calls the <code>stylesInitialized()</code> method when |
| * the styles for a component are first initialized. |
| * |
| * <p>This is an advanced method that you might override |
| * when creating a subclass of UIComponent. Flex guarantees that |
| * your component's styles are fully initialized before |
| * the first time your component's <code>measure</code> and |
| * <code>updateDisplayList</code> methods are called. For most |
| * components, that is sufficient. But if you need early access to |
| * your style values, you can override the stylesInitialized() function |
| * to access style properties as soon as they are initialized the first time.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function stylesInitialized():void |
| { |
| } |
| |
| /** |
| * Detects changes to style properties. When any style property is set, |
| * Flex calls the <code>styleChanged()</code> method, |
| * passing to it the name of the style being set. |
| * |
| * <p>This is an advanced method that you might override |
| * when creating a subclass of UIComponent. When you create a custom component, |
| * you can override the <code>styleChanged()</code> method |
| * to check the style name passed to it, and handle the change accordingly. |
| * This lets you override the default behavior of an existing style, |
| * or add your own custom style properties.</p> |
| * |
| * <p>If you handle the style property, your override of |
| * the <code>styleChanged()</code> method should call the |
| * <code>invalidateDisplayList()</code> method to cause Flex to execute |
| * the component's <code>updateDisplayList()</code> method at the next screen update.</p> |
| * |
| * @param styleProp The name of the style property, or null if all styles for this |
| * component have changed. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function styleChanged(styleProp:String):void |
| { |
| var allStyles:Boolean = !styleProp || styleProp == "styleName"; |
| |
| StyleProtoChain.styleChanged(this, styleProp); |
| |
| if (!allStyles) |
| { |
| if (hasEventListener(styleProp + "Changed")) |
| dispatchEvent(new Event(styleProp + "Changed")); |
| } |
| else |
| { |
| if (hasEventListener("allStylesChanged")) |
| dispatchEvent(new Event("allStylesChanged")); |
| } |
| |
| if (allStyles || styleProp == "layoutDirection") |
| layoutDirectionCachedValue = LAYOUT_DIRECTION_CACHE_UNSET; |
| } |
| |
| /** |
| * Validate and update the properties and layout of this object |
| * and redraw it, if necessary. |
| * |
| * Processing properties that require substantial computation are normally |
| * not processed until the script finishes executing. |
| * For example setting the <code>width</code> property is delayed, because it can |
| * require recalculating the widths of the objects children or its parent. |
| * Delaying the processing prevents it from being repeated |
| * multiple times if the script sets the <code>width</code> property more than once. |
| * This method lets you manually override this behavior. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function validateNow():void |
| { |
| UIComponentGlobals.layoutManager.validateClient(this); |
| } |
| |
| /** |
| * @private |
| * This method is called at the beginning of each getter |
| * for the baselinePosition property. |
| * If it returns false, the getter should return NaN |
| * because the baselinePosition can't be computed. |
| * If it returns true, the getter can do computations |
| * like textField.y + textField.baselinePosition |
| * because these properties will be valid. |
| */ |
| mx_internal function validateBaselinePosition():Boolean |
| { |
| // If this component isn't parented, |
| // then it doesn't know its text styles |
| // and we can't compute a baselinePosition. |
| if (!parent) |
| return false; |
| |
| // If this component hasn't been sized yet, assign it |
| // an actual size that's based on its explicit or measured size. |
| // |
| // TODO (egeorgie): remove this code when all SDK clients |
| // follow the rule to size first and query baselinePosition later. |
| if (!setActualSizeCalled && (width == 0 || height == 0)) |
| { |
| validateNow(); |
| |
| var w:Number = getExplicitOrMeasuredWidth(); |
| var h:Number = getExplicitOrMeasuredHeight(); |
| |
| setActualSize(w, h); |
| } |
| |
| // Ensure that this component's internal TextFields |
| // are properly laid out, so that we can use |
| // their locations to compute a baselinePosition. |
| validateNow(); |
| |
| |
| return true; |
| } |
| |
| /** |
| * Queues a function to be called later. |
| * |
| * <p>Before each update of the screen, Flash Player or AIR calls |
| * the set of functions that are scheduled for the update. |
| * Sometimes, a function should be called in the next update |
| * to allow the rest of the code scheduled for the current |
| * update to be executed. |
| * Some features, like effects, can cause queued functions to be |
| * delayed until the feature completes.</p> |
| * |
| * @param method Reference to a method to be executed later. |
| * |
| * @param args Array of Objects that represent the arguments to pass to the method. |
| * |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function callLater(method:Function, |
| args:Array /* of Object */ = null):void |
| { |
| // trace(">>calllater " + this) |
| // Push the method and the arguments onto the method queue. |
| methodQueue.push(new MethodQueueElement(method, args)); |
| |
| // Register to get the next "render" event |
| // just before the next rasterization. |
| var sm:ISystemManager = systemManager; |
| |
| // Stage can be null when an untrusted application is loaded by an application |
| // that isn't on stage yet. |
| if (sm && (sm.stage || usingBridge)) |
| { |
| if (!listeningForRender) |
| { |
| // trace(" added"); |
| sm.addEventListener(FlexEvent.RENDER, callLaterDispatcher); |
| sm.addEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher); |
| listeningForRender = true; |
| } |
| |
| // Force a "render" event to happen soon |
| if (sm.stage) |
| sm.stage.invalidate(); |
| } |
| |
| // trace("<<calllater " + this) |
| } |
| |
| /** |
| * @private |
| * Cancels all queued functions. |
| */ |
| mx_internal function cancelAllCallLaters():void |
| { |
| var sm:ISystemManager = systemManager; |
| |
| // Stage can be null when an untrusted application is loaded by an application |
| // that isn't on stage yet. |
| if (sm && (sm.stage || usingBridge)) |
| { |
| if (listeningForRender) |
| { |
| sm.removeEventListener(FlexEvent.RENDER, callLaterDispatcher); |
| sm.removeEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher); |
| listeningForRender = false; |
| } |
| } |
| |
| // Empty the method queue. |
| methodQueue.splice(0); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Commitment |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Used by layout logic to validate the properties of a component |
| * by calling the <code>commitProperties()</code> method. |
| * In general, subclassers should |
| * override the <code>commitProperties()</code> method and not this method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function validateProperties():void |
| { |
| if (invalidatePropertiesFlag) |
| { |
| commitProperties(); |
| |
| invalidatePropertiesFlag = false; |
| } |
| } |
| |
| /** |
| * Processes the properties set on the component. |
| * This is an advanced method that you might override |
| * when creating a subclass of UIComponent. |
| * |
| * <p>You do not call this method directly. |
| * Flex calls the <code>commitProperties()</code> method when you |
| * use the <code>addChild()</code> method to add a component to a container, |
| * or when you call the <code>invalidateProperties()</code> method of the component. |
| * Calls to the <code>commitProperties()</code> method occur before calls to the |
| * <code>measure()</code> method. This lets you set property values that might |
| * be used by the <code>measure()</code> method.</p> |
| * |
| * <p>Some components have properties that affect the number or kinds |
| * of child objects that they need to create, or have properties that |
| * interact with each other, such as the <code>horizontalScrollPolicy</code> |
| * and <code>horizontalScrollPosition</code> properties. |
| * It is often best at startup time to process all of these |
| * properties at one time to avoid duplicating work.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function commitProperties():void |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| if (_scaleX != oldScaleX) |
| { |
| var scalingFactorX:Number = Math.abs(_scaleX / oldScaleX); |
| if (!isNaN(explicitMinWidth)) |
| explicitMinWidth *= scalingFactorX; |
| if (!isNaN(explicitWidth)) |
| explicitWidth *= scalingFactorX; |
| if (!isNaN(explicitMaxWidth)) |
| explicitMaxWidth *= scalingFactorX; |
| |
| _width *= scalingFactorX; |
| |
| super.scaleX = oldScaleX = _scaleX; |
| } |
| |
| if (_scaleY != oldScaleY) |
| { |
| var scalingFactorY:Number = Math.abs(_scaleY / oldScaleY); |
| if (!isNaN(explicitMinHeight)) |
| explicitMinHeight *= scalingFactorY; |
| if (!isNaN(explicitHeight)) |
| explicitHeight *= scalingFactorY; |
| if (!isNaN(explicitMaxHeight)) |
| explicitMaxHeight *= scalingFactorY; |
| |
| _height *= scalingFactorY; |
| |
| super.scaleY = oldScaleY = _scaleY; |
| } |
| } |
| else |
| { |
| // Handle a deferred state change request. |
| if (_currentStateDeferred != null) |
| { |
| var newState:String = _currentStateDeferred; |
| _currentStateDeferred = null; |
| currentState = newState; |
| } |
| |
| oldScaleX = scaleX; |
| oldScaleY = scaleY; |
| } |
| |
| // Typically state changes occur immediately, but during |
| // component initialization we defer until commitProperties to |
| // reduce a bit of the startup noise. |
| if (_currentStateChanged && !initialized) |
| { |
| _currentStateChanged = false; |
| commitCurrentState(); |
| } |
| |
| if (FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_0) |
| { |
| // If this component's layout direction has changed, or its parent's layoutDirection |
| // has changed, then call invalidateLayoutDirection(). |
| const parentUIC:UIComponent = parent as UIComponent; |
| |
| if ((oldLayoutDirection != layoutDirection) || parentChangedFlag || |
| (parentUIC && (parentUIC.layoutDirection != parentUIC.oldLayoutDirection))) |
| invalidateLayoutDirection(); |
| } |
| |
| if (x != oldX || y != oldY) |
| { |
| dispatchMoveEvent(); |
| } |
| |
| if (width != oldWidth || height != oldHeight) |
| dispatchResizeEvent(); |
| |
| if (errorStringChanged) |
| { |
| errorStringChanged = false; |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0 || getStyle("showErrorTip")) |
| ToolTipManager.registerErrorString(this, oldErrorString, errorString); |
| |
| setBorderColorForErrorString(); |
| } |
| |
| if (blendModeChanged) |
| { |
| blendModeChanged = false; |
| |
| if (!blendShaderChanged) |
| { |
| $blendMode = _blendMode; |
| } |
| else |
| { |
| // The graphic element's blendMode was set to a non-Flash |
| // blendMode. We mimic the look by instantiating the |
| // appropriate shader class and setting the blendShader |
| // property on the displayObject. |
| blendShaderChanged = false; |
| |
| $blendMode = BlendMode.NORMAL; |
| |
| switch(_blendMode) |
| { |
| case "color": |
| { |
| $blendShader = new ColorShader(); |
| break; |
| } |
| case "colordodge": |
| { |
| $blendShader = new ColorDodgeShader(); |
| break; |
| } |
| case "colorburn": |
| { |
| $blendShader = new ColorBurnShader(); |
| break; |
| } |
| case "exclusion": |
| { |
| $blendShader = new ExclusionShader(); |
| break; |
| } |
| case "hue": |
| { |
| $blendShader = new HueShader(); |
| break; |
| } |
| case "luminosity": |
| { |
| $blendShader = new LuminosityShader(); |
| break; |
| } |
| case "saturation": |
| { |
| $blendShader = new SaturationShader(); |
| break; |
| } |
| case "softlight": |
| { |
| $blendShader = new SoftLightShader(); |
| break; |
| } |
| } |
| } |
| } |
| |
| parentChangedFlag = false; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Measurement |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function validateSize(recursive:Boolean = false):void |
| { |
| if (recursive) |
| { |
| for (var i:int = 0; i < numChildren; i++) |
| { |
| var child:DisplayObject = getChildAt(i); |
| if (child is ILayoutManagerClient ) |
| (child as ILayoutManagerClient ).validateSize(true); |
| } |
| } |
| |
| if (invalidateSizeFlag) |
| { |
| var sizeChanging:Boolean = measureSizes(); |
| |
| if (sizeChanging && includeInLayout) |
| { |
| // TODO (egeorgie): we don't need this invalidateDisplayList() here |
| // because we'll call it if the parent sets new actual size? |
| invalidateDisplayList(); |
| invalidateParentSizeAndDisplayList(); |
| } |
| } |
| } |
| |
| /** |
| * Determines if the call to the <code>measure()</code> method can be skipped. |
| * |
| * @return Returns <code>true</code> when the <code>measureSizes()</code> method can skip the call to |
| * the <code>measure()</code> method. For example this is usually <code>true</code> when both <code>explicitWidth</code> and |
| * <code>explicitHeight</code> are set. For paths, this is <code>true</code> when the bounds of the path |
| * have not changed. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| protected function canSkipMeasurement():Boolean |
| { |
| // We can skip the measure function if the object's width and height |
| // have been explicitly specified (e.g.: the object's MXML tag has |
| // attributes like width="50" and height="100"). |
| // |
| // If an object's width and height have been explicitly specified, |
| // then the explicitWidth and explicitHeight properties contain |
| // Numbers (as opposed to NaN) |
| return !isNaN(explicitWidth) && !isNaN(explicitHeight); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function measureSizes():Boolean |
| { |
| var changed:Boolean = false; |
| |
| if (!invalidateSizeFlag) |
| return changed; |
| |
| var scalingFactor:Number; |
| var newValue:Number; |
| |
| if (canSkipMeasurement()) |
| { |
| invalidateSizeFlag = false; |
| _measuredMinWidth = 0; |
| _measuredMinHeight = 0; |
| } |
| else |
| { |
| var xScale:Number = Math.abs(scaleX); |
| var yScale:Number = Math.abs(scaleY); |
| |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| if (xScale != 1.0) |
| { |
| _measuredMinWidth /= xScale; |
| _measuredWidth /= xScale; |
| } |
| |
| if (yScale != 1.0) |
| { |
| _measuredMinHeight /= yScale; |
| _measuredHeight /= yScale; |
| } |
| } |
| |
| measure(); |
| |
| invalidateSizeFlag = false; |
| |
| if (!isNaN(explicitMinWidth) && measuredWidth < explicitMinWidth) |
| measuredWidth = explicitMinWidth; |
| |
| if (!isNaN(explicitMaxWidth) && measuredWidth > explicitMaxWidth) |
| measuredWidth = explicitMaxWidth; |
| |
| if (!isNaN(explicitMinHeight) && measuredHeight < explicitMinHeight) |
| measuredHeight = explicitMinHeight; |
| |
| if (!isNaN(explicitMaxHeight) && measuredHeight > explicitMaxHeight) |
| measuredHeight = explicitMaxHeight; |
| |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| if (xScale != 1.0) |
| { |
| _measuredMinWidth *= xScale; |
| _measuredWidth *= xScale; |
| } |
| |
| if (yScale != 1.0) |
| { |
| _measuredMinHeight *= yScale; |
| _measuredHeight *= yScale; |
| } |
| } |
| } |
| |
| adjustSizesForScaleChanges(); |
| |
| if (isNaN(oldMinWidth)) |
| { |
| // This branch does the same thing as the else branch, |
| // but it is optimized for the first time that |
| // measureSizes() is called on this object. |
| oldMinWidth = !isNaN(explicitMinWidth) ? |
| explicitMinWidth : |
| measuredMinWidth; |
| |
| oldMinHeight = !isNaN(explicitMinHeight) ? |
| explicitMinHeight : |
| measuredMinHeight; |
| |
| oldExplicitWidth = !isNaN(explicitWidth) ? |
| explicitWidth : |
| measuredWidth; |
| |
| oldExplicitHeight = !isNaN(explicitHeight) ? |
| explicitHeight : |
| measuredHeight; |
| |
| changed = true; |
| } |
| else |
| { |
| newValue = !isNaN(explicitMinWidth) ? |
| explicitMinWidth : |
| measuredMinWidth; |
| if (newValue != oldMinWidth) |
| { |
| oldMinWidth = newValue; |
| changed = true; |
| } |
| |
| newValue = !isNaN(explicitMinHeight) ? |
| explicitMinHeight : |
| measuredMinHeight; |
| if (newValue != oldMinHeight) |
| { |
| oldMinHeight = newValue; |
| changed = true; |
| } |
| |
| newValue = !isNaN(explicitWidth) ? |
| explicitWidth : |
| measuredWidth; |
| if (newValue != oldExplicitWidth) |
| { |
| oldExplicitWidth = newValue; |
| changed = true; |
| } |
| |
| newValue = !isNaN(explicitHeight) ? |
| explicitHeight : |
| measuredHeight; |
| if (newValue != oldExplicitHeight) |
| { |
| oldExplicitHeight = newValue; |
| changed = true; |
| } |
| |
| } |
| |
| return changed; |
| } |
| |
| /** |
| * Calculates the default size, and optionally the default minimum size, |
| * of the component. This is an advanced method that you might override when |
| * creating a subclass of UIComponent. |
| * |
| * <p>You do not call this method directly. Flex calls the |
| * <code>measure()</code> method when the component is added to a container |
| * using the <code>addChild()</code> method, and when the component's |
| * <code>invalidateSize()</code> method is called. </p> |
| * |
| * <p>When you set a specific height and width of a component, |
| * Flex does not call the <code>measure()</code> method, |
| * even if you explicitly call the <code>invalidateSize()</code> method. |
| * That is, Flex only calls the <code>measure()</code> method if |
| * the <code>explicitWidth</code> property or the <code>explicitHeight</code> |
| * property of the component is NaN. </p> |
| * |
| * <p>In your override of this method, you must set the |
| * <code>measuredWidth</code> and <code>measuredHeight</code> properties |
| * to define the default size. |
| * You can optionally set the <code>measuredMinWidth</code> and |
| * <code>measuredMinHeight</code> properties to define the default |
| * minimum size.</p> |
| * |
| * <p>Most components calculate these values based on the content they are |
| * displaying, and from the properties that affect content display. |
| * A few components simply have hard-coded default values. </p> |
| * |
| * <p>The conceptual point of <code>measure()</code> is for the component to provide |
| * its own natural or intrinsic size as a default. Therefore, the |
| * <code>measuredWidth</code> and <code>measuredHeight</code> properties |
| * should be determined by factors such as:</p> |
| * <ul> |
| * <li>The amount of text the component needs to display.</li> |
| * <li>The styles, such as <code>fontSize</code>, for that text.</li> |
| * <li>The size of a JPEG image that the component displays.</li> |
| * <li>The measured or explicit sizes of the component's children.</li> |
| * <li>Any borders, margins, and gaps.</li> |
| * </ul> |
| * |
| * <p>In some cases, there is no intrinsic way to determine default values. |
| * For example, a simple GreenCircle component might simply set |
| * measuredWidth = 100 and measuredHeight = 100 in its <code>measure()</code> method to |
| * provide a reasonable default size. In other cases, such as a TextArea, |
| * an appropriate computation (such as finding the right width and height |
| * that would just display all the text and have the aspect ratio of a Golden Rectangle) |
| * might be too time-consuming to be worthwhile.</p> |
| * |
| * <p>The default implementation of <code>measure()</code> |
| * sets <code>measuredWidth</code>, <code>measuredHeight</code>, |
| * <code>measuredMinWidth</code>, and <code>measuredMinHeight</code> |
| * to <code>0</code>.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function measure():void |
| { |
| measuredMinWidth = 0; |
| measuredMinHeight = 0; |
| measuredWidth = 0; |
| measuredHeight = 0; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function adjustSizesForScaleChanges():void |
| { |
| var xScale:Number = scaleX; |
| var yScale:Number = scaleY; |
| |
| var scalingFactor:Number; |
| |
| if (xScale != oldScaleX) |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| scalingFactor = Math.abs(xScale / oldScaleX); |
| |
| if (explicitMinWidth) |
| explicitMinWidth *= scalingFactor; |
| |
| if (!isNaN(explicitWidth)) |
| explicitWidth *= scalingFactor; |
| |
| if (explicitMaxWidth) |
| explicitMaxWidth *= scalingFactor; |
| } |
| |
| oldScaleX = xScale; |
| } |
| |
| if (yScale != oldScaleY) |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| scalingFactor = Math.abs(yScale / oldScaleY); |
| |
| if (explicitMinHeight) |
| explicitMinHeight *= scalingFactor; |
| |
| if (explicitHeight) |
| explicitHeight *= scalingFactor; |
| |
| if (explicitMaxHeight) |
| explicitMaxHeight *= scalingFactor; |
| } |
| |
| oldScaleY = yScale; |
| } |
| } |
| |
| /** |
| * A convenience method for determining whether to use the |
| * explicit or measured width |
| * |
| * @return A Number which is explicitWidth if defined |
| * or measuredWidth if not. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getExplicitOrMeasuredWidth():Number |
| { |
| return !isNaN(explicitWidth) ? explicitWidth : measuredWidth; |
| } |
| |
| /** |
| * A convenience method for determining whether to use the |
| * explicit or measured height |
| * |
| * @return A Number which is explicitHeight if defined |
| * or measuredHeight if not. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getExplicitOrMeasuredHeight():Number |
| { |
| return !isNaN(explicitHeight) ? explicitHeight : measuredHeight; |
| } |
| |
| /** |
| * A convenience method for determining the unscaled width |
| * of the component |
| * All of a component's drawing and child layout should be done |
| * within a bounding rectangle of this width, which is also passed |
| * as an argument to <code>updateDisplayList()</code>. |
| * |
| * @return A Number which is unscaled width of the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function get unscaledWidth():Number |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| return width / Math.abs(scaleX); |
| else |
| return width; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function getUnscaledWidth():Number { return unscaledWidth; } |
| |
| /** |
| * A convenience method for setting the unscaledWidth of a |
| * component. |
| * |
| * Setting this sets the width of the component as desired |
| * before any transformation is applied. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| mx_internal function setUnscaledWidth(value:Number):void |
| { |
| var newValue:Number = value; |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| newValue *= Math.abs(oldScaleX); |
| if (_explicitWidth == newValue) |
| return; |
| |
| // width can be pixel or percent not both |
| if (!isNaN(newValue)) |
| _percentWidth = NaN; |
| |
| _explicitWidth = newValue; |
| |
| // We invalidate size because locking in width |
| // may change the measured height in flow-based components. |
| invalidateSize(); |
| |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| /** |
| * A convenience method for determining the unscaled height |
| * of the component. |
| * All of a component's drawing and child layout should be done |
| * within a bounding rectangle of this height, which is also passed |
| * as an argument to <code>updateDisplayList()</code>. |
| * |
| * @return A Number which is unscaled height of the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function get unscaledHeight():Number |
| { |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| return height / Math.abs(scaleY); |
| else |
| return height; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function getUnscaledHeight():Number { return unscaledHeight; } |
| |
| /** |
| * A convenience method for setting the unscaledHeight of a |
| * component. |
| * |
| * Setting this sets the height of the component as desired |
| * before any transformation is applied. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| mx_internal function setUnscaledHeight(value:Number):void |
| { |
| var newValue:Number = value; |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| newValue *= Math.abs(oldScaleY); |
| if (_explicitHeight == newValue) |
| return; |
| |
| // height can be pixel or percent, not both |
| if (!isNaN(newValue)) |
| _percentHeight = NaN; |
| |
| _explicitHeight = newValue; |
| |
| // We invalidate size because locking in height |
| // may change the measured width in flow-based components. |
| invalidateSize(); |
| |
| invalidateParentSizeAndDisplayList(); |
| } |
| |
| /** |
| * Measures the specified text, assuming that it is displayed |
| * in a single-line UITextField (or UIFTETextField) using a UITextFormat |
| * determined by the styles of this UIComponent. Does not |
| * work for Spark components since they don't use UITextField |
| * (or UIFTETextField). To measure text in Spark components, |
| * get the measurements of a spark.components.Label |
| * or spark.components.RichText |
| * |
| * @param text A String specifying the text to measure. |
| * |
| * @return A TextLineMetrics object containing the text measurements. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function measureText(text:String):TextLineMetrics |
| { |
| return determineTextFormatFromStyles().measureText(text); |
| } |
| |
| /** |
| * Measures the specified HTML text, which can contain HTML tags such |
| * as <code><font></code> and <code><b></code>, |
| * assuming that it is displayed |
| * in a single-line UITextField using a UITextFormat |
| * determined by the styles of this UIComponent. |
| * |
| * @param text A String specifying the HTML text to measure. |
| * |
| * @return A TextLineMetrics object containing the text measurements. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function measureHTMLText(htmlText:String):TextLineMetrics |
| { |
| return determineTextFormatFromStyles().measureHTMLText(htmlText); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Drawing and Child Layout |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var lastUnscaledWidth:Number; |
| /** |
| * @private |
| */ |
| private var lastUnscaledHeight:Number; |
| |
| /** |
| * @private |
| */ |
| protected function validateMatrix():void |
| { |
| if (_layoutFeatures != null && _layoutFeatures.updatePending == true) |
| { |
| applyComputedMatrix(); |
| } |
| |
| if (_maintainProjectionCenter) |
| { |
| var pmatrix:PerspectiveProjection = super.transform.perspectiveProjection; |
| if (pmatrix != null) |
| { |
| pmatrix.projectionCenter = new Point(unscaledWidth/2,unscaledHeight/2); |
| } |
| } |
| } |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function validateDisplayList():void |
| { |
| oldLayoutDirection = layoutDirection; |
| |
| if (invalidateDisplayListFlag) |
| { |
| // Check if our parent is the top level system manager |
| var sm:ISystemManager = parent as ISystemManager; |
| if (sm) |
| { |
| if (sm.isProxy || (sm == systemManager.topLevelSystemManager && |
| sm.document != this)) |
| { |
| // Size ourself to the new measured width/height This can |
| // cause the _layoutFeatures computed matrix to become invalid |
| setActualSize(getExplicitOrMeasuredWidth(), |
| getExplicitOrMeasuredHeight()); |
| } |
| } |
| |
| // Don't validate transform.matrix until after setting actual size |
| validateMatrix(); |
| |
| var unscaledWidth:Number = width; |
| var unscaledHeight:Number = height; |
| if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| { |
| unscaledWidth = scaleX == 0 ? 0 : width / scaleX; |
| unscaledHeight = scaleY == 0 ? 0 : height / scaleY; |
| |
| // Use some hysteresis to prevent roundoff errors from |
| // causing problems as we scale. This isn't a full solution, |
| // but it helps. |
| if (Math.abs(unscaledWidth - lastUnscaledWidth) < .00001) |
| unscaledWidth = lastUnscaledWidth; |
| if (Math.abs(unscaledHeight - lastUnscaledHeight) < .00001) |
| unscaledHeight = lastUnscaledHeight; |
| } |
| updateDisplayList(unscaledWidth,unscaledHeight); |
| lastUnscaledWidth = unscaledWidth; |
| lastUnscaledHeight = unscaledHeight; |
| |
| invalidateDisplayListFlag = false; |
| |
| // LAYOUT_DEBUG |
| // LayoutManager.debugHelper.addElement(ILayoutElement(this)); |
| } |
| else |
| validateMatrix(); |
| |
| } |
| |
| /** |
| * Draws the object and/or sizes and positions its children. |
| * This is an advanced method that you might override |
| * when creating a subclass of UIComponent. |
| * |
| * <p>You do not call this method directly. Flex calls the |
| * <code>updateDisplayList()</code> method when the component is added to a container |
| * using the <code>addChild()</code> method, and when the component's |
| * <code>invalidateDisplayList()</code> method is called. </p> |
| * |
| * <p>If the component has no children, this method |
| * is where you would do programmatic drawing |
| * using methods on the component's Graphics object |
| * such as <code>graphics.drawRect()</code>.</p> |
| * |
| * <p>If the component has children, this method is where |
| * you would call the <code>move()</code> and <code>setActualSize()</code> |
| * methods on its children.</p> |
| * |
| * <p>Components can do programmatic drawing even if |
| * they have children. In doing either, use the |
| * component's <code>unscaledWidth</code> and <code>unscaledHeight</code> |
| * as its bounds.</p> |
| * |
| * <p>It is important to use <code>unscaledWidth</code> and |
| * <code>unscaledHeight</code> instead of the <code>width</code> |
| * and <code>height</code> properties.</p> |
| * |
| * @param unscaledWidth Specifies the width of the component, in pixels, |
| * in the component's coordinates, regardless of the value of the |
| * <code>scaleX</code> property of the component. |
| * |
| * @param unscaledHeight Specifies the height of the component, in pixels, |
| * in the component's coordinates, regardless of the value of the |
| * <code>scaleY</code> property of the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function updateDisplayList(unscaledWidth:Number, |
| unscaledHeight:Number):void |
| { |
| } |
| |
| /** |
| * Returns a layout constraint value, which is the same as |
| * getting the constraint style for this component. |
| * |
| * @param constraintName The name of the constraint style, which |
| * can be any of the following: left, right, top, bottom, |
| * verticalCenter, horizontalCenter, baseline |
| * |
| * @return Returns the layout constraint value, which can be |
| * specified in either of two forms. It can be specified as a |
| * numeric string, for example, "10" or it can be specified as |
| * identifier:numeric string. For identifier:numeric string, |
| * identifier is the <code>id</code> of a ConstraintRow or |
| * ConstraintColumn. For example, a value of "cc1:10" specifies a |
| * value of 10 for the ConstraintColumn that has the |
| * <code>id</code> "cc1." |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getConstraintValue(constraintName:String):* |
| { |
| return getStyle(constraintName); |
| } |
| |
| /** |
| * Sets a layout constraint value, which is the same as |
| * setting the constraint style for this component. |
| * |
| * @param constraintName The name of the constraint style, which |
| * can be any of the following: left, right, top, bottom, |
| * verticalCenter, horizontalCenter, baseline |
| * |
| * @param value The value of the constraint can be specified in either |
| * of two forms. It can be specified as a numeric string, for |
| * example, "10" or it can be specified as identifier:numeric |
| * string. For identifier:numeric string, identifier is the |
| * <code>id</code> of a ConstraintRow or ConstraintColumn. For |
| * example, a value of "cc1:10" specifies a value of 10 for the |
| * ConstraintColumn that has the <code>id</code> "cc1." |
| * |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function setConstraintValue(constraintName:String, value:*):void |
| { |
| setStyle(constraintName, value); |
| } |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * <p>For components, this layout constraint property is a |
| * facade on top of the similarly-named style. To set |
| * a state-specific value of the property in MXML to its default |
| * value of <code>undefined</code>, |
| * use the @Clear() directive. For example, in MXML code, |
| * <code>left.s2="@Clear()"</code> unsets the <code>left</code> |
| * constraint in state s2. Or in ActionScript code, |
| * <code>button.left = undefined</code> unsets the <code>left</code> |
| * constraint on <code>button</code>.</p> |
| * |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get left():Object |
| { |
| return getConstraintValue("left"); |
| } |
| public function set left(value:Object):void |
| { |
| setConstraintValue("left", value != null ? value : undefined); |
| } |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * <p>For components, this layout constraint property is a |
| * facade on top of the similarly-named style. To set |
| * the property to its default value of <code>undefined</code>, |
| * use the @Clear() directive in MXML or the <code>undefined</code> |
| * value in ActionScript code. For example, in MXML code, |
| * <code>right.s2="@Clear()"</code> unsets the <code>right</code> |
| * constraint in state s2. Or in ActionScript code, |
| * <code>button.right = undefined</code> unsets the <code>right</code> |
| * constraint on <code>button</code>.</p> |
| * |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get right():Object |
| { |
| return getConstraintValue("right"); |
| } |
| public function set right(value:Object):void |
| { |
| setConstraintValue("right", value != null ? value : undefined); |
| } |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * <p>For components, this layout constraint property is a |
| * facade on top of the similarly-named style. To set |
| * the property to its default value of <code>undefined</code>, |
| * use the @Clear() directive in MXML or the <code>undefined</code> |
| * value in ActionScript code. For example, in MXML code, |
| * <code>top.s2="@Clear()"</code> unsets the <code>top</code> |
| * constraint in state s2. Or in ActionScript code, |
| * <code>button.top = undefined</code> unsets the <code>top</code> |
| * constraint on <code>button</code>.</p> |
| * |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get top():Object |
| { |
| return getConstraintValue("top"); |
| } |
| public function set top(value:Object):void |
| { |
| setConstraintValue("top", value != null ? value : undefined); |
| } |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * <p>For components, this layout constraint property is a |
| * facade on top of the similarly-named style. To set |
| * the property to its default value of <code>undefined</code>, |
| * use the @Clear() directive in MXML or the <code>undefined</code> |
| * value in ActionScript code. For example, in MXML code, |
| * <code>bottom.s2="@Clear()"</code> unsets the <code>bottom</code> |
| * constraint in state s2. Or in ActionScript code, |
| * <code>button.bottom = undefined</code> unsets the <code>bottom</code> |
| * constraint on <code>button</code>.</p> |
| * |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get bottom():Object |
| { |
| return getConstraintValue("bottom"); |
| } |
| public function set bottom(value:Object):void |
| { |
| setConstraintValue("bottom", value != null ? value : undefined); |
| } |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * <p>For components, this layout constraint property is a |
| * facade on top of the similarly-named style. To set |
| * the property to its default value of <code>undefined</code>, |
| * use the @Clear() directive in MXML or the <code>undefined</code> |
| * value in ActionScript code. For example, in MXML code, |
| * <code>horizontalCenter.s2="@Clear()"</code> unsets the |
| * <code>horizontalCenter</code> |
| * constraint in state s2. Or in ActionScript code, |
| * <code>button.horizontalCenter = undefined</code> unsets the |
| * <code>horizontalCenter</code> constraint on <code>button</code>.</p> |
| * |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get horizontalCenter():Object |
| { |
| return getConstraintValue("horizontalCenter"); |
| } |
| public function set horizontalCenter(value:Object):void |
| { |
| setConstraintValue("horizontalCenter", value != null ? value : undefined); |
| } |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * <p>For components, this layout constraint property is a |
| * facade on top of the similarly-named style. To set |
| * the property to its default value of <code>undefined</code>, |
| * use the @Clear() directive in MXML or the <code>undefined</code> |
| * value in ActionScript code. For example, in MXML code, |
| * <code>verticalCenter.s2="@Clear()"</code> unsets the <code>verticalCenter</code> |
| * constraint in state s2. Or in ActionScript code, |
| * <code>button.verticalCenter = undefined</code> unsets the <code>verticalCenter</code> |
| * constraint on <code>button</code>.</p> |
| * |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get verticalCenter():Object |
| { |
| return getConstraintValue("verticalCenter"); |
| } |
| public function set verticalCenter(value:Object):void |
| { |
| setConstraintValue("verticalCenter", value != null ? value : undefined); |
| } |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * <p>For components, this layout constraint property is a |
| * facade on top of the similarly-named style. To set |
| * the property to its default value of <code>undefined</code>, |
| * use the @Clear() directive in MXML or the <code>undefined</code> |
| * value in ActionScript code. For example, in MXML code, |
| * <code>baseline.s2="@Clear()"</code> unsets the <code>baseline</code> |
| * constraint in state s2. Or in ActionScript code, |
| * <code>button.baseline = undefined</code> unsets the <code>baseline</code> |
| * constraint on <code>button</code>.</p> |
| * |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get baseline():Object |
| { |
| return getConstraintValue("baseline"); |
| } |
| public function set baseline(value:Object):void |
| { |
| setConstraintValue("baseline", value != null ? value : undefined); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Drawing |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Returns a box Matrix which can be passed to the |
| * <code>drawRoundRect()</code> method |
| * as the <code>rot</code> parameter when drawing a horizontal gradient. |
| * |
| * <p>For performance reasons, the Matrix is stored in a static variable |
| * which is reused by all calls to <code>horizontalGradientMatrix()</code> |
| * and <code>verticalGradientMatrix()</code>. |
| * Therefore, pass the resulting Matrix |
| * to <code>drawRoundRect()</code> before calling |
| * <code>horizontalGradientMatrix()</code> |
| * or <code>verticalGradientMatrix()</code> again.</p> |
| * |
| * @param x The left coordinate of the gradient, in pixels. |
| * |
| * @param y The top coordinate of the gradient, in pixels. |
| * |
| * @param width The width of the gradient, in pixels. |
| * |
| * @param height The height of the gradient, in pixels. |
| * |
| * @return The Matrix for the horizontal gradient. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function horizontalGradientMatrix(x:Number, y:Number, |
| width:Number, |
| height:Number):Matrix |
| { |
| UIComponentGlobals.tempMatrix.createGradientBox(width, height, 0, x, y); |
| return UIComponentGlobals.tempMatrix; |
| } |
| |
| /** |
| * Returns a box Matrix which can be passed to <code>drawRoundRect()</code> |
| * as the <code>rot</code> parameter when drawing a vertical gradient. |
| * |
| * <p>For performance reasons, the Matrix is stored in a static variable |
| * which is reused by all calls to <code>horizontalGradientMatrix()</code> |
| * and <code>verticalGradientMatrix()</code>. |
| * Therefore, pass the resulting Matrix |
| * to <code>drawRoundRect()</code> before calling |
| * <code>horizontalGradientMatrix()</code> |
| * or <code>verticalGradientMatrix()</code> again.</p> |
| * |
| * @param x The left coordinate of the gradient, in pixels. |
| * |
| * @param y The top coordinate of the gradient, in pixels. |
| * |
| * @param width The width of the gradient, in pixels. |
| * |
| * @param height The height of the gradient, in pixels. |
| * |
| * @return The Matrix for the vertical gradient. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function verticalGradientMatrix(x:Number, y:Number, |
| width:Number, |
| height:Number):Matrix |
| { |
| UIComponentGlobals.tempMatrix.createGradientBox(width, height, Math.PI / 2, x, y); |
| return UIComponentGlobals.tempMatrix; |
| } |
| |
| /** |
| * Programmatically draws a rectangle into this skin's Graphics object. |
| * |
| * <p>The rectangle can have rounded corners. |
| * Its edges are stroked with the current line style |
| * of the Graphics object. |
| * It can have a solid color fill, a gradient fill, or no fill. |
| * A solid fill can have an alpha transparency. |
| * A gradient fill can be linear or radial. You can specify |
| * up to 15 colors and alpha values at specified points along |
| * the gradient, and you can specify a rotation angle |
| * or transformation matrix for the gradient. |
| * Finally, the rectangle can have a rounded rectangular hole |
| * carved out of it.</p> |
| * |
| * <p>This versatile rectangle-drawing routine is used by many skins. |
| * It calls the <code>drawRect()</code> or |
| * <code>drawRoundRect()</code> |
| * methods (in the flash.display.Graphics class) to draw into this |
| * skin's Graphics object.</p> |
| * |
| * @param x Horizontal position of upper-left corner |
| * of rectangle within this skin. |
| * |
| * @param y Vertical position of upper-left corner |
| * of rectangle within this skin. |
| * |
| * @param w Width of rectangle, in pixels. |
| * |
| * @param h Height of rectangle, in pixels. |
| * |
| * @param r Corner radius/radii of rectangle. |
| * Can be <code>null</code>, a Number, or an Object. |
| * If it is <code>null</code>, it specifies that the corners should be square |
| * rather than rounded. |
| * If it is a Number, it specifies the same radius, in pixels, |
| * for all four corners. |
| * If it is an Object, it should have properties named |
| * <code>tl</code>, <code>tr</code>, <code>bl</code>, and |
| * <code>br</code>, whose values are Numbers specifying |
| * the radius, in pixels, for the top left, top right, |
| * bottom left, and bottom right corners. |
| * For example, you can pass a plain Object such as |
| * <code>{ tl: 5, tr: 5, bl: 0, br: 0 }</code>. |
| * The default value is null (square corners). |
| * |
| * @param c The RGB color(s) for the fill. |
| * Can be <code>null</code>, a uint, or an Array. |
| * If it is <code>null</code>, the rectangle not filled. |
| * If it is a uint, it specifies an RGB fill color. |
| * For example, pass <code>0xFF0000</code> to fill with red. |
| * If it is an Array, it should contain uints |
| * specifying the gradient colors. |
| * For example, pass <code>[ 0xFF0000, 0xFFFF00, 0x0000FF ]</code> |
| * to fill with a red-to-yellow-to-blue gradient. |
| * You can specify up to 15 colors in the gradient. |
| * The default value is null (no fill). |
| * |
| * @param alpha Alpha value(s) for the fill. |
| * Can be null, a Number, or an Array. |
| * This argument is ignored if <code>color</code> is null. |
| * If <code>color</code> is a uint specifying an RGB fill color, |
| * then <code>alpha</code> should be a Number specifying |
| * the transparency of the fill, where 0.0 is completely transparent |
| * and 1.0 is completely opaque. |
| * You can also pass null instead of 1.0 in this case |
| * to specify complete opaqueness. |
| * If <code>color</code> is an Array specifying gradient colors, |
| * then <code>alpha</code> should be an Array of Numbers, of the |
| * same length, that specifies the corresponding alpha values |
| * for the gradient. |
| * In this case, the default value is <code>null</code> (completely opaque). |
| * |
| * @param rot Matrix object used for the gradient fill. |
| * The utility methods <code>horizontalGradientMatrix()</code>, |
| * <code>verticalGradientMatrix()</code>, and |
| * <code>rotatedGradientMatrix()</code> can be used to create the value for |
| * this parameter. |
| * |
| * @param gradient Type of gradient fill. The possible values are |
| * <code>GradientType.LINEAR</code> or <code>GradientType.RADIAL</code>. |
| * (The GradientType class is in the package flash.display.) |
| * |
| * @param ratios |
| * Specifies the distribution of colors. The number of entries must match |
| * the number of colors defined in the <code>color</code> parameter. |
| * Each value defines the percentage of the width where the color is |
| * sampled at 100%. The value 0 represents the left-hand position in |
| * the gradient box, and 255 represents the right-hand position in the |
| * gradient box. |
| * |
| * @param hole A rounded rectangular hole |
| * that should be carved out of the middle |
| * of the otherwise solid rounded rectangle |
| * { x: #, y: #, w: #, h: #, r: # or { br: #, bl: #, tl: #, tr: # } } |
| * |
| * @see flash.display.Graphics#beginGradientFill() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function drawRoundRect(x:Number, y:Number, w:Number, h:Number, |
| r:Object = null, c:Object = null, |
| alpha:Object = null, rot:Object = null, |
| gradient:String = null, ratios:Array = null, |
| hole:Object = null):void |
| { |
| var g:Graphics = graphics; |
| |
| // Quick exit if w or h is zero. This happens when scaling a component |
| // to a very small value, which then gets rounded to 0. |
| if (!w || !h) |
| return; |
| |
| // If color is an object then allow for complex fills. |
| if (c !== null) |
| { |
| if (c is Array) |
| { |
| var alphas:Array; |
| |
| if (alpha is Array) |
| alphas = alpha as Array; |
| else |
| alphas = [ alpha, alpha ]; |
| |
| if (!ratios) |
| ratios = [ 0, 0xFF ]; |
| |
| var matrix:Matrix = null; |
| |
| if (rot) |
| { |
| if (rot is Matrix) |
| { |
| matrix = Matrix(rot); |
| } |
| else |
| { |
| matrix = new Matrix(); |
| |
| if (rot is Number) |
| { |
| matrix.createGradientBox( |
| w, h, Number(rot) * Math.PI / 180, x, y); |
| } |
| else |
| { |
| matrix.createGradientBox( |
| rot.w, rot.h, rot.r, rot.x, rot.y); |
| } |
| } |
| } |
| |
| if (gradient == GradientType.RADIAL) |
| { |
| g.beginGradientFill(GradientType.RADIAL, |
| c as Array, alphas, ratios, matrix); |
| } |
| else |
| { |
| g.beginGradientFill(GradientType.LINEAR, |
| c as Array, alphas, ratios, matrix); |
| } |
| } |
| else |
| { |
| g.beginFill(Number(c), Number(alpha)); |
| } |
| } |
| |
| var ellipseSize:Number; |
| |
| // Stroke the rectangle. |
| if (!r) |
| { |
| g.drawRect(x, y, w, h); |
| } |
| else if (r is Number) |
| { |
| ellipseSize = Number(r) * 2; |
| g.drawRoundRect(x, y, w, h, ellipseSize, ellipseSize); |
| } |
| else |
| { |
| GraphicsUtil.drawRoundRectComplex(g, x, y, w, h, r.tl, r.tr, r.bl, r.br); |
| } |
| |
| // Carve a rectangular hole out of the middle of the rounded rect. |
| if (hole) |
| { |
| var holeR:Object = hole.r; |
| if (holeR is Number) |
| { |
| ellipseSize = Number(holeR) * 2; |
| g.drawRoundRect(hole.x, hole.y, hole.w, hole.h, |
| ellipseSize, ellipseSize); |
| } |
| else |
| { |
| GraphicsUtil.drawRoundRectComplex(g, hole.x, hole.y, hole.w, hole.h, |
| holeR.tl, holeR.tr, holeR.bl, holeR.br); |
| } |
| } |
| |
| if (c !== null) |
| g.endFill(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Moving and sizing |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Moves the component to a specified position within its parent. |
| * Calling this method is exactly the same as |
| * setting the component's <code>x</code> and <code>y</code> properties. |
| * |
| * <p>If you are overriding the <code>updateDisplayList()</code> method |
| * in a custom component, call the <code>move()</code> method |
| * rather than setting the <code>x</code> and <code>y</code> properties. |
| * The difference is that the <code>move()</code> method changes the location |
| * of the component and then dispatches a <code>move</code> event when you |
| * call the method, while setting the <code>x</code> and <code>y</code> |
| * properties changes the location of the component and dispatches |
| * the event on the next screen refresh.</p> |
| * |
| * @param x Left position of the component within its parent. |
| * |
| * @param y Top position of the component within its parent. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function move(x:Number, y:Number):void |
| { |
| var changed:Boolean = false; |
| |
| if (x != this.x) |
| { |
| if (_layoutFeatures == null) |
| super.x = x; |
| else |
| _layoutFeatures.layoutX = x; |
| |
| if (hasEventListener("xChanged")) |
| dispatchEvent(new Event("xChanged")); |
| changed = true; |
| } |
| |
| if (y != this.y) |
| { |
| if (_layoutFeatures == null) |
| super.y = y; |
| else |
| _layoutFeatures.layoutY = y; |
| |
| if (hasEventListener("yChanged")) |
| dispatchEvent(new Event("yChanged")); |
| changed = true; |
| } |
| |
| if (changed) |
| { |
| invalidateTransform(); |
| dispatchMoveEvent(); |
| } |
| } |
| |
| /** |
| * Sizes the object. |
| * Unlike directly setting the <code>width</code> and <code>height</code> |
| * properties, calling the <code>setActualSize()</code> method |
| * does not set the <code>explictWidth</code> and |
| * <code>explicitHeight</code> properties, so a future layout |
| * calculation can result in the object returning to its previous size. |
| * This method is used primarily by component developers implementing |
| * the <code>updateDisplayList()</code> method, by Effects, |
| * and by the LayoutManager. |
| * |
| * @param w Width of the object. |
| * |
| * @param h Height of the object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function setActualSize(w:Number, h:Number):void |
| { |
| // trace("setActualSize: " + this + " width = " + w + " height = " + h); |
| |
| var changed:Boolean = false; |
| |
| if (_width != w) |
| { |
| _width = w; |
| if(_layoutFeatures) |
| { |
| _layoutFeatures.layoutWidth = w; // for the mirror transform |
| invalidateTransform(); |
| } |
| if (hasEventListener("widthChanged")) |
| dispatchEvent(new Event("widthChanged")); |
| changed = true; |
| } |
| |
| if (_height != h) |
| { |
| _height = h; |
| if (hasEventListener("heightChanged")) |
| dispatchEvent(new Event("heightChanged")); |
| changed = true; |
| } |
| |
| if (changed) |
| { |
| invalidateDisplayList(); |
| dispatchResizeEvent(); |
| } |
| |
| setActualSizeCalled = true; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Content coordinate transformations |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Converts a <code>Point</code> object from content coordinates to global coordinates. |
| * Content coordinates specify a pixel position relative to the upper left corner |
| * of the component's content, and include all of the component's content area, |
| * including any regions that are currently clipped and must be |
| * accessed by scrolling the component. |
| * You use the content coordinate system to set and get the positions of children |
| * of a container that uses absolute positioning. |
| * Global coordinates specify a pixel position relative to the upper-left corner |
| * of the stage, that is, the outermost edge of the application. |
| * |
| * @param point A Point object that |
| * specifies the <i>x</i> and <i>y</i> coordinates in the content coordinate system |
| * as properties. |
| * |
| * @return A Point object with coordinates relative to the Stage. |
| * |
| * @see #globalToContent() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function contentToGlobal(point:Point):Point |
| { |
| return localToGlobal(point); |
| } |
| |
| /** |
| * Converts a <code>Point</code> object from global to content coordinates. |
| * Global coordinates specify a pixel position relative to the upper-left corner |
| * of the stage, that is, the outermost edge of the application. |
| * Content coordinates specify a pixel position relative to the upper left corner |
| * of the component's content, and include all of the component's content area, |
| * including any regions that are currently clipped and must be |
| * accessed by scrolling the component. |
| * You use the content coordinate system to set and get the positions of children |
| * of a container that uses absolute positioning. |
| * |
| * @param point A Point object that |
| * specifies the <i>x</i> and <i>y</i> coordinates in the global (Stage) |
| * coordinate system as properties. |
| * |
| * @return Point A Point object with coordinates relative to the component. |
| * |
| * @see #contentToGlobal() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function globalToContent(point:Point):Point |
| { |
| return globalToLocal(point); |
| } |
| |
| /** |
| * Converts a <code>Point</code> object from content to local coordinates. |
| * Content coordinates specify a pixel position relative to the upper left corner |
| * of the component's content, and include all of the component's content area, |
| * including any regions that are currently clipped and must be |
| * accessed by scrolling the component. |
| * You use the content coordinate system to set and get the positions of children |
| * of a container that uses absolute positioning. |
| * Local coordinates specify a pixel position relative to the |
| * upper left corner of the component. |
| * |
| * @param point A Point object that specifies the <i>x</i> and <i>y</i> |
| * coordinates in the content coordinate system as properties. |
| * |
| * @return Point A Point object with coordinates relative to the |
| * local coordinate system. |
| * |
| * @see #contentToGlobal() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function contentToLocal(point:Point):Point |
| { |
| return point; |
| } |
| |
| /** |
| * Converts a <code>Point</code> object from local to content coordinates. |
| * Local coordinates specify a pixel position relative to the |
| * upper left corner of the component. |
| * Content coordinates specify a pixel position relative to the upper left corner |
| * of the component's content, and include all of the component's content area, |
| * including any regions that are currently clipped and must be |
| * accessed by scrolling the component. |
| * You use the content coordinate system to set and get the positions of children |
| * of a container that uses absolute positioning. |
| * |
| * @param point A Point object that specifies the <i>x</i> and <i>y</i> |
| * coordinates in the local coordinate system as properties. |
| * |
| * @return Point A Point object with coordinates relative to the |
| * content coordinate system. |
| * |
| * @see #contentToLocal() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function localToContent(point:Point):Point |
| { |
| return point; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Focus |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Gets the object that currently has focus. |
| * It might not be this object. |
| * Note that this method does not necessarily return the component |
| * that has focus. |
| * It can return the internal subcomponent of the component |
| * that has focus. |
| * To get the component that has focus, use the |
| * <code>focusManager.focus</code> property. |
| * |
| * @return Object that has focus. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getFocus():InteractiveObject |
| { |
| var sm:ISystemManager = systemManager; |
| if (!sm) |
| return null; |
| |
| if (UIComponentGlobals.nextFocusObject) |
| return UIComponentGlobals.nextFocusObject; |
| |
| if (sm.stage) |
| return sm.stage.focus; |
| |
| return null; |
| } |
| |
| /** |
| * Sets the focus to this component. |
| * The component can in turn pass focus to a subcomponent. |
| * |
| * <p><b>Note:</b> Only the TextInput and TextArea controls show a highlight |
| * when this method sets the focus. |
| * All controls show a highlight when the user tabs to the control.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function setFocus():void |
| { |
| var sm:ISystemManager = systemManager; |
| if (sm && (sm.stage || usingBridge)) |
| { |
| if (UIComponentGlobals.callLaterDispatcherCount == 0) |
| { |
| sm.stage.focus = this; |
| UIComponentGlobals.nextFocusObject = null; |
| } |
| else |
| { |
| UIComponentGlobals.nextFocusObject = this; |
| sm.addEventListener(FlexEvent.ENTER_FRAME, setFocusLater); |
| } |
| } |
| else |
| { |
| UIComponentGlobals.nextFocusObject = this; |
| callLater(setFocusLater); |
| } |
| } |
| |
| /** |
| * @private |
| * Returns the focus object |
| */ |
| mx_internal function getFocusObject():DisplayObject |
| { |
| var fm:IFocusManager = focusManager; |
| |
| if (!fm || !fm.focusPane) |
| return null; |
| |
| return fm.focusPane.numChildren == 0 ? |
| null : |
| fm.focusPane.getChildAt(0); |
| } |
| |
| /** |
| * Shows or hides the focus indicator around this component. |
| * |
| * <p>UIComponent implements this by creating an instance of the class |
| * specified by the <code>focusSkin</code> style and positioning it |
| * appropriately.</p> |
| * |
| * @param isFocused Determines if the focus indicator should be displayed. Set to |
| * <code>true</code> to display the focus indicator. Set to <code>false</code> to hide it. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function drawFocus(isFocused:Boolean):void |
| { |
| // Gets called by removeChild() after un-parented. |
| if (!parent) |
| return; |
| |
| var focusObj:DisplayObject = getFocusObject(); |
| var focusPane:Sprite = focusManager ? focusManager.focusPane : null; |
| |
| if (isFocused && !preventDrawFocus) //&& !isEffectStarted |
| { |
| var focusOwner:DisplayObjectContainer = focusPane.parent; |
| |
| if (focusOwner != parent) |
| { |
| if (focusOwner) |
| { |
| if (focusOwner is ISystemManager) |
| ISystemManager(focusOwner).focusPane = null; |
| else |
| IUIComponent(focusOwner).focusPane = null; |
| } |
| if (parent is ISystemManager) |
| ISystemManager(parent).focusPane = focusPane; |
| else |
| IUIComponent(parent).focusPane = focusPane; |
| } |
| |
| var focusClass:Class = getStyle("focusSkin"); |
| |
| if (!focusClass) |
| return; |
| |
| if (focusObj && !(focusObj is focusClass)) |
| { |
| focusPane.removeChild(focusObj); |
| focusObj = null; |
| } |
| |
| if (!focusObj) |
| { |
| focusObj = new focusClass(); |
| |
| focusObj.name = "focus"; |
| |
| focusPane.addChild(focusObj); |
| } |
| |
| if (focusObj is ILayoutManagerClient ) |
| ILayoutManagerClient (focusObj).nestLevel = nestLevel; |
| |
| if (focusObj is ISimpleStyleClient) |
| ISimpleStyleClient(focusObj).styleName = this; |
| |
| addEventListener(MoveEvent.MOVE, focusObj_moveHandler, true); |
| addEventListener(MoveEvent.MOVE, focusObj_moveHandler); |
| addEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler, true); |
| addEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler); |
| addEventListener(Event.REMOVED, focusObj_removedHandler, true); |
| |
| focusObj.visible = true; |
| hasFocusRect = true; |
| |
| adjustFocusRect(); |
| } |
| else if (hasFocusRect) |
| { |
| hasFocusRect = false; |
| |
| if (focusObj) |
| { |
| focusObj.visible = false; |
| |
| if (focusObj is ISimpleStyleClient) |
| ISimpleStyleClient(focusObj).styleName = null; |
| } |
| |
| removeEventListener(MoveEvent.MOVE, focusObj_moveHandler); |
| removeEventListener(MoveEvent.MOVE, focusObj_moveHandler, true); |
| removeEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler, true); |
| removeEventListener(ResizeEvent.RESIZE, focusObj_resizeHandler); |
| removeEventListener(Event.REMOVED, focusObj_removedHandler, true); |
| } |
| } |
| |
| /** |
| * Adjust the focus rectangle. |
| * |
| * @param The component whose focus rectangle to modify. |
| * If omitted, the default value is this UIComponent object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function adjustFocusRect(obj:DisplayObject = null):void |
| { |
| if (!obj) |
| obj = this; |
| |
| // Make sure that when we calculate the size of the Focus rect we |
| // work with post-scale width & height. |
| var width:Number; |
| var height:Number; |
| if (obj is UIComponent) |
| { |
| width = UIComponent(obj).unscaledWidth * Math.abs(obj.scaleX); |
| height = UIComponent(obj).unscaledHeight * Math.abs(obj.scaleY); |
| } |
| else |
| { |
| width = obj.width; |
| height = obj.height; |
| } |
| |
| // Something inside the lisder has a width and height of NaN |
| if (isNaN(width) || isNaN(height)) |
| return; |
| |
| var fm:IFocusManager = focusManager; |
| if (!fm) |
| return; // we've been unparented so ignore |
| |
| var focusObj:IFlexDisplayObject = IFlexDisplayObject(getFocusObject()); |
| if (focusObj) |
| { |
| var rectCol:Number; |
| var showErrorSkin:Boolean = FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0 || getStyle("showErrorSkin"); |
| if (errorString && errorString != "" && showErrorSkin) |
| rectCol = getStyle("errorColor"); |
| else if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| rectCol = getStyle("themeColor"); |
| else |
| rectCol = getStyle("focusColor"); |
| |
| var thickness:Number = getStyle("focusThickness"); |
| |
| if (focusObj is IStyleClient) |
| { |
| IStyleClient(focusObj).setStyle("focusColor", rectCol); |
| } |
| //if (getStyle("focusColor") != rectCol) |
| // setStyle("focusColor", rectCol); |
| |
| focusObj.setActualSize(width + 2 * thickness, |
| height + 2 * thickness); |
| |
| var pt:Point; |
| |
| if (rotation) |
| { |
| var rotRad:Number = rotation * Math.PI / 180; |
| pt = new Point(obj.x - thickness * (Math.cos(rotRad) - Math.sin(rotRad)), |
| obj.y - thickness * (Math.cos(rotRad) + Math.sin(rotRad))); |
| DisplayObject(focusObj).rotation = rotation; |
| } |
| else |
| { |
| pt = new Point(obj.x - thickness, obj.y - thickness); |
| DisplayObject(focusObj).rotation = 0; |
| } |
| |
| if (obj.parent == this) |
| { |
| // This adjustment only works if obj is a direct child of this. |
| pt.x += x; |
| pt.y += y; |
| } |
| |
| // If necessary, compenstate for mirroring, if the obj to receive |
| // focus isn't this component. It is likely to be an icon within |
| // the component such as a radio button or check box. This works |
| // as long as the focusObj is symmetric. |
| // ToDo(cframpto):ProgrammaticSkin implement ILayoutDirectionElement. |
| if (obj != this) |
| { |
| // The focusObj is attached to this component's parent. Assume |
| // the focusObj is a class which doesn't support layoutDirection |
| // and will be laid out like the component's parent. If the |
| // component is being mirrored it means its layout differs from |
| // its parent and we need to compenstate. |
| if (_layoutFeatures && _layoutFeatures.mirror) |
| pt.x += this.width - obj.width; |
| } |
| |
| pt = parent.localToGlobal(pt); |
| pt = parent.globalToLocal(pt); |
| focusObj.move(pt.x, pt.y); |
| |
| if (focusObj is IInvalidating) |
| IInvalidating(focusObj).validateNow(); |
| |
| else if (focusObj is IProgrammaticSkin) |
| IProgrammaticSkin(focusObj).validateNow(); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Events |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Helper method for dispatching a PropertyChangeEvent |
| * when a property is updated. |
| * |
| * @param prop Name of the property that changed. |
| * |
| * @param oldValue Old value of the property. |
| * |
| * @param value New value of the property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function dispatchPropertyChangeEvent(prop:String, oldValue:*, |
| value:*):void |
| { |
| if (hasEventListener("propertyChange")) |
| dispatchEvent(PropertyChangeEvent.createUpdateEvent( |
| this, prop, oldValue, value)); |
| } |
| |
| /** |
| * @private |
| */ |
| private function dispatchMoveEvent():void |
| { |
| if (hasEventListener(MoveEvent.MOVE)) |
| { |
| var moveEvent:MoveEvent = new MoveEvent(MoveEvent.MOVE); |
| moveEvent.oldX = oldX; |
| moveEvent.oldY = oldY; |
| dispatchEvent(moveEvent); |
| } |
| |
| oldX = x; |
| oldY = y; |
| } |
| |
| /** |
| * @private |
| */ |
| private function dispatchResizeEvent():void |
| { |
| if (hasEventListener(ResizeEvent.RESIZE)) |
| { |
| var resizeEvent:ResizeEvent = new ResizeEvent(ResizeEvent.RESIZE); |
| resizeEvent.oldWidth = oldWidth; |
| resizeEvent.oldHeight = oldHeight; |
| dispatchEvent(resizeEvent); |
| } |
| |
| oldWidth = width; |
| oldHeight = height; |
| } |
| |
| /** |
| * @private |
| * Called when the child transform changes (currently x and y on UIComponent), |
| * so that the Group has a chance to invalidate the layout. |
| */ |
| mx_internal function childXYChanged():void |
| { |
| } |
| |
| /** |
| * @private |
| * Typically, Keyboard.LEFT means go left, regardless of the |
| * layoutDirection, and similiarly for Keyboard.RIGHT. When |
| * layoutDirection="rtl", rather than duplicating lots of code in the |
| * switch statement of the keyDownHandler, map Keyboard.LEFT to |
| * Keyboard.RIGHT, and similiarly for Keyboard.RIGHT. |
| * |
| * Optionally, Keyboard.UP can be tied with Keyboard.LEFT and |
| * Keyboard.DOWN can be tied with Keyboard.RIGHT since some components |
| * do this. |
| * |
| * @return keyCode to use for the layoutDirection if always using ltr |
| * actions |
| */ |
| // TODO(cframpto): change to protected after getting PARB review of name. |
| mx_internal function mapKeycodeForLayoutDirection( |
| event:KeyboardEvent, |
| mapUpDown:Boolean=false):uint |
| { |
| var keyCode:uint = event.keyCode; |
| |
| // If rtl layout, left still means left and right still means right so |
| // swap the keys to get the correct action. |
| switch (keyCode) |
| { |
| case Keyboard.DOWN: |
| { |
| // typically, if ltr, the same as RIGHT |
| if (mapUpDown && layoutDirection == LayoutDirection.RTL) |
| keyCode = Keyboard.LEFT; |
| break; |
| } |
| case Keyboard.RIGHT: |
| { |
| if (layoutDirection == LayoutDirection.RTL) |
| keyCode = Keyboard.LEFT; |
| break; |
| } |
| case Keyboard.UP: |
| { |
| // typically, if ltr, the same as LEFT |
| if (mapUpDown && layoutDirection == LayoutDirection.RTL) |
| keyCode = Keyboard.RIGHT; |
| break; |
| } |
| case Keyboard.LEFT: |
| { |
| if (layoutDirection == LayoutDirection.RTL) |
| keyCode = Keyboard.RIGHT; |
| break; |
| } |
| } |
| |
| return keyCode; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: States |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Set the current state. |
| * |
| * @param stateName The name of the new view state. |
| * |
| * @param playTransition If <code>true</code>, play |
| * the appropriate transition when the view state changes. |
| * |
| * @see #currentState |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function setCurrentState(stateName:String, |
| playTransition:Boolean = true):void |
| { |
| // Flex 4 has no concept of an explicit base state, so ensure we |
| // fall back to something appropriate. |
| stateName = isBaseState(stateName) ? getDefaultState() : stateName; |
| |
| // Only change if the requested state is different. Since the root |
| // state can be either null or "", we need to add additional check |
| // to make sure we're not going from null to "" or vice-versa. |
| if (stateName != currentState && |
| !(isBaseState(stateName) && isBaseState(currentState))) |
| { |
| requestedCurrentState = stateName; |
| // Don't play transition if we're just getting started |
| // In Flex4, there is no "base state", so if isBaseState() is true |
| // then we're just going into our first real state |
| playStateTransition = |
| (this is IStateClient2) && isBaseState(currentState) ? |
| false : |
| playTransition; |
| if (initialized) |
| { |
| commitCurrentState(); |
| } |
| else |
| { |
| _currentStateChanged = true; |
| invalidateProperties(); |
| } |
| } |
| } |
| |
| /** |
| * @copy mx.core.IStateClient2#hasState() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function hasState(stateName:String):Boolean |
| { |
| return (getState(stateName, false) != null); |
| } |
| |
| /** |
| * @private |
| * Returns true if the passed in state name is the 'base' state, which |
| * is currently defined as null or "" |
| */ |
| private function isBaseState(stateName:String):Boolean |
| { |
| return !stateName || stateName == ""; |
| } |
| |
| /** |
| * @private |
| * Returns the default state. For Flex 4 and later we return the base |
| * the first defined state, otherwise (Flex 3 and earlier), we return |
| * the base (null) state. |
| */ |
| private function getDefaultState():String |
| { |
| return (this is IStateClient2 && (states.length > 0)) ? states[0].name : null; |
| } |
| |
| // Used by commitCurrentState() to avoid hard-linking against Effect |
| private static var effectType:Class; |
| private static var effectLoaded:Boolean = false; |
| |
| /** |
| * @private |
| * Commit a pending current state change. |
| */ |
| private function commitCurrentState():void |
| { |
| var nextTransition:Transition = |
| playStateTransition ? |
| getTransition(_currentState, requestedCurrentState) : |
| null; |
| var commonBaseState:String = findCommonBaseState(_currentState, requestedCurrentState); |
| var event:StateChangeEvent; |
| var oldState:String = _currentState ? _currentState : ""; |
| var destination:State = getState(requestedCurrentState); |
| var prevTransitionEffect:Object; |
| var tmpPropertyChanges:Array; |
| |
| // First, make sure we've loaded the Effect class - some of the logic |
| // below requires it |
| if (nextTransition && !effectLoaded) |
| { |
| effectLoaded = true; |
| if (ApplicationDomain.currentDomain.hasDefinition("mx.effects.Effect")) |
| effectType = Class(ApplicationDomain.currentDomain. |
| getDefinition("mx.effects.Effect")); |
| } |
| |
| // Stop any transition that may still be playing |
| var prevTransitionFraction:Number; |
| if (_currentTransition) |
| { |
| // Remove the event listener, we don't want to trigger it as it |
| // dispatches FlexEvent.STATE_CHANGE_COMPLETE and we are |
| // interrupting _currentTransition instead. |
| _currentTransition.effect.removeEventListener(EffectEvent.EFFECT_END, transition_effectEndHandler); |
| |
| // 'stop' interruptions take precedence over autoReverse behavior |
| if (nextTransition && _currentTransition.interruptionBehavior == "stop") |
| { |
| prevTransitionEffect = _currentTransition.effect; |
| prevTransitionEffect.transitionInterruption = true; |
| // This logic stops the effect from applying the end values |
| // so that we can capture the interrupted values correctly |
| // in captureStartValues() below. Save the values in the |
| // tmp variable because stop() clears out propertyChangesArray |
| // from the effect. |
| tmpPropertyChanges = prevTransitionEffect.propertyChangesArray; |
| prevTransitionEffect.applyEndValuesWhenDone = false; |
| prevTransitionEffect.stop(); |
| prevTransitionEffect.applyEndValuesWhenDone = true; |
| } |
| else |
| { |
| if (_currentTransition.autoReverse && |
| transitionFromState == requestedCurrentState && |
| transitionToState == _currentState) |
| { |
| if (_currentTransition.effect.duration == 0) |
| prevTransitionFraction = 0; |
| else |
| prevTransitionFraction = |
| _currentTransition.effect.playheadTime / |
| getTotalDuration(_currentTransition.effect); |
| } |
| _currentTransition.effect.end(); |
| } |
| |
| // The current transition is being interrupted, dispatch an event |
| if (hasEventListener(FlexEvent.STATE_CHANGE_INTERRUPTED)) |
| dispatchEvent(new FlexEvent(FlexEvent.STATE_CHANGE_INTERRUPTED)); |
| _currentTransition = null; |
| } |
| |
| // Initialize the state we are going to. |
| initializeState(requestedCurrentState); |
| |
| // Capture transition start values |
| if (nextTransition) |
| nextTransition.effect.captureStartValues(); |
| |
| // Now that we've captured the start values, apply the end values of |
| // the effect as normal. This makes sure that objects unaffected by the |
| // next transition have their correct end values from the previous |
| // transition |
| if (tmpPropertyChanges) |
| prevTransitionEffect.applyEndValues(tmpPropertyChanges, |
| prevTransitionEffect.targets); |
| |
| // Dispatch currentStateChanging event |
| if (hasEventListener(StateChangeEvent.CURRENT_STATE_CHANGING)) |
| { |
| event = new StateChangeEvent(StateChangeEvent.CURRENT_STATE_CHANGING); |
| event.oldState = oldState; |
| event.newState = requestedCurrentState ? requestedCurrentState : ""; |
| dispatchEvent(event); |
| } |
| |
| // If we're leaving the base state, send an exitState event |
| if (isBaseState(_currentState) && hasEventListener(FlexEvent.EXIT_STATE)) |
| dispatchEvent(new FlexEvent(FlexEvent.EXIT_STATE)); |
| |
| // Remove the existing state |
| removeState(_currentState, commonBaseState); |
| _currentState = requestedCurrentState; |
| |
| // Check for state specific styles |
| stateChanged(oldState, _currentState, true); |
| |
| // If we're going back to the base state, dispatch an |
| // enter state event, otherwise apply the state. |
| if (isBaseState(currentState)) |
| { |
| if (hasEventListener(FlexEvent.ENTER_STATE)) |
| dispatchEvent(new FlexEvent(FlexEvent.ENTER_STATE)); |
| } |
| else |
| applyState(_currentState, commonBaseState); |
| |
| // Dispatch currentStateChange |
| if (hasEventListener(StateChangeEvent.CURRENT_STATE_CHANGE)) |
| { |
| event = new StateChangeEvent(StateChangeEvent.CURRENT_STATE_CHANGE); |
| event.oldState = oldState; |
| event.newState = _currentState ? _currentState : ""; |
| dispatchEvent(event); |
| } |
| |
| if (nextTransition) |
| { |
| var reverseTransition:Boolean = |
| nextTransition && nextTransition.autoReverse && |
| (nextTransition.toState == oldState || |
| nextTransition.fromState == _currentState); |
| // Force a validation before playing the transition effect |
| UIComponentGlobals.layoutManager.validateNow(); |
| _currentTransition = nextTransition; |
| transitionFromState = oldState; |
| transitionToState = _currentState; |
| // Tell the effect whether it is running in interruption mode, in which |
| // case it should grab values from the states instead of from current |
| // property values |
| Object(nextTransition.effect).transitionInterruption = |
| (prevTransitionEffect != null); |
| nextTransition.effect.addEventListener(EffectEvent.EFFECT_END, |
| transition_effectEndHandler); |
| nextTransition.effect.play(null, reverseTransition); |
| if (!isNaN(prevTransitionFraction) && |
| nextTransition.effect.duration != 0) |
| nextTransition.effect.playheadTime = (1 - prevTransitionFraction) * |
| getTotalDuration(nextTransition.effect); |
| } |
| else |
| { |
| // Dispatch an event that the transition has completed. |
| if (hasEventListener(FlexEvent.STATE_CHANGE_COMPLETE)) |
| dispatchEvent(new FlexEvent(FlexEvent.STATE_CHANGE_COMPLETE)); |
| } |
| } |
| |
| // Used by getTotalDuration() to avoid hard-linking against |
| // CompositeEffect |
| private static var compositeEffectType:Class; |
| private static var compositeEffectLoaded:Boolean = false; |
| |
| /** |
| * @private |
| * returns the 'total' duration of an effect. This value |
| * takes into account any startDelay and repetition data. |
| * For CompositeEffect objects, it also accounts for the |
| * total duration of that effect's children. |
| */ |
| private function getTotalDuration(effect:IEffect):Number |
| { |
| // TODO (chaase): we should add timing properties to some |
| // interface to avoid these hacks |
| var duration:Number = 0; |
| var effectObj:Object = Object(effect); |
| if (!compositeEffectLoaded) |
| { |
| compositeEffectLoaded = true; |
| if (ApplicationDomain.currentDomain.hasDefinition("mx.effects.CompositeEffect")) |
| compositeEffectType = Class(ApplicationDomain.currentDomain. |
| getDefinition("mx.effects.CompositeEffect")); |
| } |
| if (compositeEffectType && (effect is compositeEffectType)) |
| duration = effectObj.compositeDuration; |
| else |
| duration = effect.duration; |
| var repeatDelay:int = ("repeatDelay" in effect) ? |
| effectObj.repeatDelay : 0; |
| var repeatCount:int = ("repeatCount" in effect) ? |
| effectObj.repeatCount : 0; |
| var startDelay:int = ("startDelay" in effect) ? |
| effectObj.startDelay : 0; |
| // Now add in startDelay/repeat info |
| duration = |
| duration * repeatCount + |
| (repeatDelay * (repeatCount - 1)) + |
| startDelay; |
| return duration; |
| } |
| |
| /** |
| * @private |
| */ |
| private function transition_effectEndHandler(event:EffectEvent):void |
| { |
| _currentTransition = null; |
| |
| // Dispatch an event that the transition has completed. |
| if (hasEventListener(FlexEvent.STATE_CHANGE_COMPLETE)) |
| dispatchEvent(new FlexEvent(FlexEvent.STATE_CHANGE_COMPLETE)); |
| } |
| |
| /** |
| * @private |
| * Returns the state with the specified name, or null if it doesn't exist. |
| * If multiple states have the same name the first one will be returned. |
| */ |
| private function getState(stateName:String, throwOnUndefined:Boolean=true):State |
| { |
| if (!states || isBaseState(stateName)) |
| return null; |
| |
| // Do a simple linear search for now. This can |
| // be optimized later if needed. |
| for (var i:int = 0; i < states.length; i++) |
| { |
| if (states[i].name == stateName) |
| return states[i]; |
| } |
| |
| if (throwOnUndefined) |
| { |
| var message:String = resourceManager.getString( |
| "core", "stateUndefined", [ stateName ]); |
| throw new ArgumentError(message); |
| } |
| return null; |
| } |
| |
| /** |
| * @private |
| * Find the deepest common state between two states. For example: |
| * |
| * State A |
| * State B basedOn A |
| * State C basedOn A |
| * |
| * findCommonBaseState(B, C) returns A |
| * |
| * If there are no common base states, the root state ("") is returned. |
| */ |
| private function findCommonBaseState(state1:String, state2:String):String |
| { |
| var firstState:State = getState(state1); |
| var secondState:State = getState(state2); |
| |
| // Quick exit if either state is the base state |
| if (!firstState || !secondState) |
| return ""; |
| |
| // Quick exit if both states are not based on other states |
| if (isBaseState(firstState.basedOn) && isBaseState(secondState.basedOn)) |
| return ""; |
| |
| // Get the base states for each state and walk from the top |
| // down until we find the deepest common base state. |
| var firstBaseStates:Array = getBaseStates(firstState); |
| var secondBaseStates:Array = getBaseStates(secondState); |
| var commonBase:String = ""; |
| |
| while (firstBaseStates[firstBaseStates.length - 1] == |
| secondBaseStates[secondBaseStates.length - 1]) |
| { |
| commonBase = firstBaseStates.pop(); |
| secondBaseStates.pop(); |
| |
| if (!firstBaseStates.length || !secondBaseStates.length) |
| break; |
| } |
| |
| // Finally, check to see if one of the states is directly based on the other. |
| if (firstBaseStates.length && |
| firstBaseStates[firstBaseStates.length - 1] == secondState.name) |
| { |
| commonBase = secondState.name; |
| } |
| else if (secondBaseStates.length && |
| secondBaseStates[secondBaseStates.length - 1] == firstState.name) |
| { |
| commonBase = firstState.name; |
| } |
| |
| return commonBase; |
| } |
| |
| /** |
| * @private |
| * Returns the base states for a given state. |
| * This Array is in high-to-low order - the first entry |
| * is the immediate basedOn state, the last entry is the topmost |
| * basedOn state. |
| */ |
| private function getBaseStates(state:State):Array |
| { |
| var baseStates:Array = []; |
| |
| // Push each basedOn name |
| while (state && state.basedOn) |
| { |
| baseStates.push(state.basedOn); |
| state = getState(state.basedOn); |
| } |
| |
| return baseStates; |
| } |
| |
| /** |
| * @private |
| * Remove the overrides applied by a state, and any |
| * states it is based on. |
| */ |
| private function removeState(stateName:String, lastState:String):void |
| { |
| var state:State = getState(stateName); |
| |
| if (stateName == lastState) |
| return; |
| |
| // Remove existing state overrides. |
| // This must be done in reverse order |
| if (state) |
| { |
| // Dispatch the "exitState" event |
| state.dispatchExitState(); |
| |
| var overrides:Array = state.overrides; |
| |
| for (var i:int = overrides.length; i; i--) |
| overrides[i-1].remove(this); |
| |
| // Remove any basedOn deltas last |
| if (state.basedOn != lastState) |
| removeState(state.basedOn, lastState); |
| } |
| } |
| |
| /** |
| * @private |
| * Apply the overrides from a state, and any states it |
| * is based on. |
| */ |
| private function applyState(stateName:String, lastState:String):void |
| { |
| var state:State = getState(stateName); |
| |
| if (stateName == lastState) |
| return; |
| |
| if (state) |
| { |
| // Apply "basedOn" overrides first |
| if (state.basedOn != lastState) |
| applyState(state.basedOn, lastState); |
| |
| // Apply new state overrides |
| var overrides:Array = state.overrides; |
| |
| for (var i:int = 0; i < overrides.length; i++) |
| overrides[i].apply(this); |
| |
| // Dispatch the "enterState" event |
| state.dispatchEnterState(); |
| } |
| } |
| |
| /** |
| * @private |
| * Initialize the state, and any states it is based on |
| */ |
| private function initializeState(stateName:String):void |
| { |
| var state:State = getState(stateName); |
| |
| while (state) |
| { |
| state.initialize(); |
| state = getState(state.basedOn); |
| } |
| } |
| |
| /** |
| * @private |
| * Find the appropriate transition to play between two states. |
| */ |
| private function getTransition(oldState:String, newState:String):Transition |
| { |
| var result:Transition = null; // Current candidate |
| var priority:int = 0; // Priority fromState toState |
| // 1 * * |
| // 2 reverse * |
| // 3 * reverse |
| // 4 reverse reverse |
| // 5 match * |
| // 6 * match |
| // 7 match match |
| |
| if (!transitions) |
| return null; |
| |
| if (!oldState) |
| oldState = ""; |
| |
| if (!newState) |
| newState = ""; |
| |
| for (var i:int = 0; i < transitions.length; i++) |
| { |
| var t:Transition = transitions[i]; |
| |
| if (t.fromState == "*" && t.toState == "*" && priority < 1) |
| { |
| result = t; |
| priority = 1; |
| } |
| else if (t.toState == oldState && t.fromState == "*" && t.autoReverse && priority < 2) |
| { |
| result = t; |
| priority = 2; |
| } |
| else if (t.toState == "*" && t.fromState == newState && t.autoReverse && priority < 3) |
| { |
| result = t; |
| priority = 3; |
| } |
| else if (t.toState == oldState && t.fromState == newState && t.autoReverse && priority < 4) |
| { |
| result = t; |
| priority = 4; |
| } |
| else if (t.fromState == oldState && t.toState == "*" && priority < 5) |
| { |
| result = t; |
| priority = 5; |
| } |
| else if (t.fromState == "*" && t.toState == newState && priority < 6) |
| { |
| result = t; |
| priority = 6; |
| } |
| else if (t.fromState == oldState && t.toState == newState && priority < 7) |
| { |
| result = t; |
| priority = 7; |
| |
| // Can't get any higher than this, let's go. |
| break; |
| } |
| } |
| // If Transition does not contain an effect, then don't return it |
| // because there is no transition effect to run |
| if (result && !result.effect) |
| result = null; |
| |
| return result; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Styling |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * The state to be used when matching CSS pseudo-selectors. By default |
| * this is the <code>currentState</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| protected function get currentCSSState():String |
| { |
| return currentState; |
| } |
| |
| /** |
| * A component's parent is used to evaluate descendant selectors. A parent |
| * must also be an IAdvancedStyleClient to participate in advanced style |
| * declarations. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get styleParent():IAdvancedStyleClient |
| { |
| return parent as IAdvancedStyleClient; |
| } |
| |
| public function set styleParent(parent:IAdvancedStyleClient):void |
| { |
| |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function matchesCSSState(cssState:String):Boolean |
| { |
| return currentCSSState == cssState; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function matchesCSSType(cssType:String):Boolean |
| { |
| return StyleProtoChain.matchesCSSType(this, cssType); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.6 |
| */ |
| public function hasCSSState():Boolean |
| { |
| return currentCSSState != null; |
| } |
| |
| /** |
| * @private |
| * Sets up the inheritingStyles and nonInheritingStyles objects |
| * and their proto chains so that getStyle() can work. |
| */ |
| // Note that initProtoChain is 99% copied into DataGridItemRenderer |
| mx_internal function initProtoChain():void |
| { |
| StyleProtoChain.initProtoChain(this); |
| } |
| |
| /** |
| * Finds the type selectors for this UIComponent instance. |
| * The algorithm walks up the superclass chain. |
| * For example, suppose that class MyButton extends Button. |
| * A MyButton instance first looks for a MyButton type selector |
| * then, it looks for a Button type selector. |
| * then, it looks for a UIComponent type selector. |
| * (The superclass chain is considered to stop at UIComponent, not Object.) |
| * |
| * @return An Array of type selectors for this UIComponent instance. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getClassStyleDeclarations():Array |
| { |
| return StyleProtoChain.getClassStyleDeclarations(this); |
| } |
| |
| /** |
| * Builds or rebuilds the CSS style cache for this component |
| * and, if the <code>recursive</code> parameter is <code>true</code>, |
| * for all descendants of this component as well. |
| * |
| * <p>The Flex framework calls this method in the following |
| * situations:</p> |
| * |
| * <ul> |
| * <li>When you add a UIComponent to a parent using the |
| * <code>addChild()</code> or <code>addChildAt()</code> methods.</li> |
| * <li>When you change the <code>styleName</code> property |
| * of a UIComponent.</li> |
| * <li>When you set a style in a CSS selector using the |
| * <code>setStyle()</code> method of CSSStyleDeclaration.</li> |
| * </ul> |
| * |
| * <p>Building the style cache is a computation-intensive operation, |
| * so avoid changing <code>styleName</code> or |
| * setting selector styles unnecessarily.</p> |
| * |
| * <p>This method is not called when you set an instance style |
| * by calling the <code>setStyle()</code> method of UIComponent. |
| * Setting an instance style is a relatively fast operation |
| * compared with setting a selector style.</p> |
| * |
| * <p>You do not need to call or override this method.</p> |
| * |
| * @param recursive Recursively regenerates the style cache for |
| * all children of this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function regenerateStyleCache(recursive:Boolean):void |
| { |
| // Regenerate the proto chain for this object |
| initProtoChain(); |
| |
| var childList:IChildList = |
| this is IRawChildrenContainer ? |
| IRawChildrenContainer(this).rawChildren : |
| IChildList(this); |
| |
| // Recursively call this method on each child. |
| var n:int = childList.numChildren; |
| |
| for (var i:int = 0; i < n; i++) |
| { |
| var child:Object = childList.getChildAt(i); |
| |
| if (child is IStyleClient) |
| { |
| // Does this object already have a proto chain? |
| // If not, there's no need to regenerate a new one. |
| if (IStyleClient(child).inheritingStyles != |
| StyleProtoChain.STYLE_UNINITIALIZED) |
| { |
| IStyleClient(child).regenerateStyleCache(recursive); |
| } |
| } |
| else if (child is IUITextField) |
| { |
| // Does this object already have a proto chain? |
| // If not, there's no need to regenerate a new one. |
| if (IUITextField(child).inheritingStyles) |
| StyleProtoChain.initTextField(IUITextField(child)); |
| } |
| } |
| |
| // Call this method on each non-visual StyleClient |
| if (advanceStyleClientChildren != null) |
| { |
| for (var styleClient:Object in advanceStyleClientChildren) |
| { |
| var iAdvanceStyleClientChild:IAdvancedStyleClient = styleClient |
| as IAdvancedStyleClient; |
| |
| if (iAdvanceStyleClientChild && |
| iAdvanceStyleClientChild.inheritingStyles != |
| StyleProtoChain.STYLE_UNINITIALIZED) |
| { |
| iAdvanceStyleClientChild.regenerateStyleCache(recursive); |
| } |
| } |
| } |
| } |
| /** |
| * This method is called when a state changes to check whether |
| * state-specific styles apply to this component. If there is a chance |
| * of a matching CSS pseudo-selector for the current state, the style |
| * cache needs to be regenerated for this instance and, potentially all |
| * children, if the <code>recursive</code> param is set to <code>true</code>. |
| * |
| * @param oldState The name of th eold state. |
| * |
| * @param newState The name of the new state. |
| * |
| * @param recursive Set to <code>true</code> to perform a recursive check. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| protected function stateChanged(oldState:String, newState:String, recursive:Boolean):void |
| { |
| // This test only checks for pseudo conditions on the subject of the selector. |
| // Pseudo conditions on ancestor selectors are not detected - eg: |
| // List ScrollBar:inactive #track |
| // The track styles will not change when the scrollbar is in the inactive state. |
| if (currentCSSState && oldState != newState && |
| (styleManager.hasPseudoCondition(oldState) || |
| styleManager.hasPseudoCondition(newState))) |
| { |
| regenerateStyleCache(recursive); |
| initThemeColor(); |
| styleChanged(null); |
| notifyStyleChangeInChildren(null, recursive); |
| } |
| } |
| |
| [Bindable(style="true")] |
| /** |
| * Gets a style property that has been set anywhere in this |
| * component's style lookup chain. |
| * |
| * <p>This same method is used to get any kind of style property, |
| * so the value returned can be a Boolean, String, Number, int, |
| * uint (for an RGB color), Class (for a skin), or any kind of object. |
| * Therefore the return type is simply specified as ~~.</p> |
| * |
| * <p>If you are getting a particular style property, you |
| * know its type and often want to store the result in a |
| * variable of that type. |
| * No casting from ~~ to that type is necessary.</p> |
| * |
| * <p> |
| * <code> |
| * var backgroundColor:uint = getStyle("backgroundColor"); |
| * </code> |
| * </p> |
| * |
| * <p>If the style property has not been set anywhere in the |
| * style lookup chain, the value returned by <code>getStyle()</code> |
| * is <code>undefined</code>. |
| * Note that <code>undefined</code> is a special value that is |
| * not the same as <code>false</code>, <code>""</code>, |
| * <code>NaN</code>, <code>0</code>, or <code>null</code>. |
| * No valid style value is ever <code>undefined</code>. |
| * You can use the method |
| * <code>IStyleManager2.isValidStyleValue()</code> |
| * to test whether the value was set.</p> |
| * |
| * @param styleProp Name of the style property. |
| * |
| * @return Style value. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getStyle(styleProp:String):* |
| { |
| // If a moduleFactory has not be set yet, first check for any deferred |
| // styles. If there are no deferred styles or the styleProp is not in |
| // the deferred styles, the look in the proto chain. |
| if (!moduleFactory) |
| { |
| if (deferredSetStyles && deferredSetStyles[styleProp] !== undefined) |
| return deferredSetStyles[styleProp]; |
| } |
| |
| return styleManager.inheritingStyles[styleProp] ? |
| _inheritingStyles[styleProp] : |
| _nonInheritingStyles[styleProp]; |
| } |
| |
| /** |
| * Sets a style property on this component instance. |
| * |
| * <p>This can override a style that was set globally.</p> |
| * |
| * <p>Calling the <code>setStyle()</code> method can result in decreased performance. |
| * Use it only when necessary.</p> |
| * |
| * @param styleProp Name of the style property. |
| * |
| * @param newValue New value for the style. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function setStyle(styleProp:String, newValue:*):void |
| { |
| // If there is no module factory then defer the set |
| // style until a module factory is set. |
| if (moduleFactory) |
| { |
| StyleProtoChain.setStyle(this, styleProp, newValue); |
| } |
| else |
| { |
| if (!deferredSetStyles) |
| deferredSetStyles = {}; |
| deferredSetStyles[styleProp] = newValue; |
| } |
| } |
| |
| |
| /** |
| * @private |
| * Set styles that were deferred because a module factory was not |
| * set yet. |
| */ |
| private function setDeferredStyles():void |
| { |
| if (!deferredSetStyles) |
| return; |
| |
| for (var styleProp:String in deferredSetStyles) |
| StyleProtoChain.setStyle(this, styleProp, deferredSetStyles[styleProp]); |
| |
| deferredSetStyles = null; |
| } |
| |
| /** |
| * Deletes a style property from this component instance. |
| * |
| * <p>This does not necessarily cause the <code>getStyle()</code> method |
| * to return <code>undefined</code>.</p> |
| * |
| * @param styleProp The name of the style property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function clearStyle(styleProp:String):void |
| { |
| setStyle(styleProp, undefined); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal var advanceStyleClientChildren:Dictionary = null; |
| |
| /** |
| * Adds a non-visual style client to this component instance. Once |
| * this method has been called, the style client will inherit style |
| * changes from this component instance. Style clients that are |
| * DisplayObjects must use the <code>addChild</code> or |
| * <code>addChildAt</code> methods to be added to a |
| * <code>UIComponent</code>. |
| * |
| * As a side effect, this method will set the <code>styleParent</code> |
| * property of the <code>styleClient</code> parameter to reference |
| * this instance of the <code>UIComponent</code>. |
| * |
| * If the <code>styleClient</code> parameter already has a |
| * <code>styleParent</code>, this method will call |
| * <code>removeStyleClient</code> from this previous |
| * <code>styleParent</code>. |
| * |
| * |
| * @param styleClient The <code>IAdvancedStyleClient</code> to |
| * add to this component's list of non-visual style clients. |
| * |
| * @throws ArgumentError if the <code>styleClient</code> parameter |
| * is a <code>DisplayObject</code>. |
| * |
| * @see removeStyleClient |
| * @see mx.styles.IAdvancedStyleClient |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4.5 |
| */ |
| public function addStyleClient(styleClient:IAdvancedStyleClient):void |
| { |
| if(!(styleClient is DisplayObject)) |
| { |
| if(styleClient.styleParent!=null) |
| { |
| var parentComponent:UIComponent = styleClient.styleParent as UIComponent; |
| if (parentComponent) |
| parentComponent.removeStyleClient(styleClient); |
| } |
| // Create a dictionary with weak references to the key |
| if (advanceStyleClientChildren == null) |
| advanceStyleClientChildren = new Dictionary(true); |
| // Add the styleClient as a key in the dictionary. |
| // The value assigned to this key entry is currently not used. |
| advanceStyleClientChildren[styleClient] = true; |
| styleClient.styleParent=this; |
| |
| styleClient.regenerateStyleCache(true); |
| |
| styleClient.styleChanged(null); |
| } |
| else |
| { |
| var message:String = resourceManager.getString( |
| "core", "badParameter", [ styleClient ]); |
| throw new ArgumentError(message); |
| } |
| } |
| |
| /** |
| * Removes a non-visual style client from this component instance. |
| * Once this method has been called, the non-visual style client will |
| * no longer inherit style changes from this component instance. |
| * |
| * As a side effect, this method will set the |
| * <code>styleParent</code> property of the <code>styleClient</code> |
| * parameter to <code>null</code>. |
| * |
| * If the <code>styleClient</code> has not been added to this |
| * component instance, no action will be taken. |
| * |
| * @param styleClient The <code>IAdvancedStyleClient</code> to remove |
| * from this component's list of non-visual style clients. |
| * |
| * @return The non-visual style client that was passed in as the |
| * <code>styleClient</code> parameter. |
| * |
| * @see addStyleClient |
| * @see mx.styles.IAdvancedStyleClient |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4.5 |
| */ |
| public function removeStyleClient(styleClient:IAdvancedStyleClient):void |
| { |
| if(advanceStyleClientChildren && |
| advanceStyleClientChildren[styleClient]) |
| { |
| delete advanceStyleClientChildren[styleClient]; |
| |
| styleClient.styleParent = null; |
| |
| styleClient.regenerateStyleCache(true); |
| |
| styleClient.styleChanged(null); |
| } |
| } |
| |
| /** |
| * Propagates style changes to the children. |
| * You typically never need to call this method. |
| * |
| * @param styleProp String specifying the name of the style property. |
| * |
| * @param recursive Recursivly notify all children of this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function notifyStyleChangeInChildren( |
| styleProp:String, recursive:Boolean):void |
| { |
| cachedTextFormat = null; |
| |
| var n:int = numChildren; |
| for (var i:int = 0; i < n; i++) |
| { |
| var child:ISimpleStyleClient = getChildAt(i) as ISimpleStyleClient; |
| |
| if (child) |
| { |
| child.styleChanged(styleProp); |
| |
| // Always recursively call this function because of my |
| // descendants might have a styleName property that points |
| // to this object. The recursive flag is respected in |
| // Container.notifyStyleChangeInChildren. |
| if (child is IStyleClient) |
| IStyleClient(child).notifyStyleChangeInChildren(styleProp, recursive); |
| } |
| } |
| |
| if (advanceStyleClientChildren != null) |
| { |
| for (var styleClient:Object in advanceStyleClientChildren) |
| { |
| var iAdvanceStyleClientChild:IAdvancedStyleClient = styleClient |
| as IAdvancedStyleClient; |
| |
| if (iAdvanceStyleClientChild) |
| { |
| iAdvanceStyleClientChild.styleChanged(styleProp); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @private |
| * If this object has a themeColor style, which is not inherited, |
| * then set it inline. |
| */ |
| mx_internal function initThemeColor():Boolean |
| { |
| if (FlexVersion.compatibilityVersion >= FlexVersion.VERSION_4_0) |
| return true; |
| |
| var styleName:Object /* String or UIComponent */ = _styleName; |
| |
| var tc:Object; // Can be number or string |
| var rc:Number; |
| var sc:Number; |
| var i:int; |
| |
| // First look for locally-declared styles |
| if (_styleDeclaration) |
| { |
| tc = _styleDeclaration.getStyle("themeColor"); |
| rc = _styleDeclaration.getStyle("rollOverColor"); |
| sc = _styleDeclaration.getStyle("selectionColor"); |
| } |
| |
| if (styleManager.hasAdvancedSelectors()) |
| { |
| // Next look for matching selectors (working backwards, starting |
| // with the most specific selector) |
| if (tc === null || !styleManager.isValidStyleValue(tc)) |
| { |
| var styleDeclarations:Array = StyleProtoChain.getMatchingStyleDeclarations(this); |
| for (i = styleDeclarations.length - 1; i >= 0; i--) |
| { |
| var decl:CSSStyleDeclaration = styleDeclarations[i]; |
| if (decl) |
| { |
| tc = decl.getStyle("themeColor"); |
| rc = decl.getStyle("rollOverColor"); |
| sc = decl.getStyle("selectionColor"); |
| } |
| |
| if (tc !== null && styleManager.isValidStyleValue(tc)) |
| break; |
| } |
| } |
| } |
| else |
| { |
| // Next look for class selectors |
| if ((tc === null || !styleManager.isValidStyleValue(tc)) && |
| (styleName && !(styleName is ISimpleStyleClient))) |
| { |
| var classSelector:Object = |
| styleName is String ? |
| styleManager.getMergedStyleDeclaration("." + styleName) : |
| styleName; |
| |
| if (classSelector) |
| { |
| tc = classSelector.getStyle("themeColor"); |
| rc = classSelector.getStyle("rollOverColor"); |
| sc = classSelector.getStyle("selectionColor"); |
| } |
| } |
| |
| // Finally look for type selectors |
| if (tc === null || !styleManager.isValidStyleValue(tc)) |
| { |
| var typeSelectors:Array = getClassStyleDeclarations(); |
| |
| for (i = 0; i < typeSelectors.length; i++) |
| { |
| var typeSelector:CSSStyleDeclaration = typeSelectors[i]; |
| |
| if (typeSelector) |
| { |
| tc = typeSelector.getStyle("themeColor"); |
| rc = typeSelector.getStyle("rollOverColor"); |
| sc = typeSelector.getStyle("selectionColor"); |
| } |
| |
| if (tc !== null && styleManager.isValidStyleValue(tc)) |
| break; |
| } |
| } |
| } |
| |
| // If we have a themeColor but no rollOverColor or selectionColor, call |
| // setThemeColor here which will calculate rollOver/selectionColor based |
| // on the themeColor. |
| if (tc !== null && styleManager.isValidStyleValue(tc) && isNaN(rc) && isNaN(sc)) |
| { |
| setThemeColor(tc); |
| return true; |
| } |
| |
| return (tc !== null && styleManager.isValidStyleValue(tc)) && !isNaN(rc) && !isNaN(sc); |
| } |
| |
| /** |
| * @private |
| * Calculate and set new roll over and selection colors based on theme color. |
| */ |
| mx_internal function setThemeColor(value:Object /* Number or String */):void |
| { |
| var newValue:Number; |
| |
| if (newValue is String) |
| newValue = parseInt(String(value)); |
| else |
| newValue = Number(value); |
| |
| if (isNaN(newValue)) |
| newValue = styleManager.getColorName(value); |
| |
| var newValueS:Number = ColorUtil.adjustBrightness2(newValue, 50); |
| |
| var newValueR:Number = ColorUtil.adjustBrightness2(newValue, 70); |
| |
| setStyle("selectionColor", newValueS); |
| setStyle("rollOverColor", newValueR); |
| } |
| |
| /** |
| * Returns a UITextFormat object corresponding to the text styles |
| * for this UIComponent. |
| * |
| * @return UITextFormat object corresponding to the text styles |
| * for this UIComponent. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function determineTextFormatFromStyles():UITextFormat |
| { |
| var textFormat:UITextFormat = cachedTextFormat; |
| |
| if (!textFormat) |
| { |
| var font:String = |
| StringUtil.trimArrayElements(_inheritingStyles.fontFamily, ","); |
| textFormat = new UITextFormat(getNonNullSystemManager(), font); |
| textFormat.moduleFactory = moduleFactory; |
| |
| // Not all flex4 textAlign values are valid so convert to a valid one. |
| var align:String = _inheritingStyles.textAlign; |
| if (align == "start") |
| align = TextFormatAlign.LEFT; |
| else if (align == "end") |
| align = TextFormatAlign.RIGHT; |
| textFormat.align = align; |
| textFormat.bold = _inheritingStyles.fontWeight == "bold"; |
| textFormat.color = enabled ? |
| _inheritingStyles.color : |
| _inheritingStyles.disabledColor; |
| textFormat.font = font; |
| textFormat.indent = _inheritingStyles.textIndent; |
| textFormat.italic = _inheritingStyles.fontStyle == "italic"; |
| textFormat.kerning = _inheritingStyles.kerning; |
| textFormat.leading = _nonInheritingStyles.leading; |
| textFormat.leftMargin = _nonInheritingStyles.paddingLeft; |
| textFormat.letterSpacing = _inheritingStyles.letterSpacing; |
| textFormat.rightMargin = _nonInheritingStyles.paddingRight; |
| textFormat.size = _inheritingStyles.fontSize; |
| textFormat.underline = |
| _nonInheritingStyles.textDecoration == "underline"; |
| |
| textFormat.antiAliasType = _inheritingStyles.fontAntiAliasType; |
| textFormat.gridFitType = _inheritingStyles.fontGridFitType; |
| textFormat.sharpness = _inheritingStyles.fontSharpness; |
| textFormat.thickness = _inheritingStyles.fontThickness; |
| |
| textFormat.useFTE = |
| getTextFieldClassName() == "mx.core::UIFTETextField" || |
| getTextInputClassName() == "mx.controls::MXFTETextInput"; |
| |
| if (textFormat.useFTE) |
| { |
| textFormat.direction = _inheritingStyles.direction; |
| textFormat.locale = _inheritingStyles.locale; |
| } |
| |
| cachedTextFormat = textFormat; |
| } |
| |
| return textFormat; |
| } |
| |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Binding |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Executes all the bindings for which the UIComponent object is the destination. |
| * |
| * @param recurse Recursively execute bindings for children of this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function executeBindings(recurse:Boolean = false):void |
| { |
| var bindingsHost:Object = descriptor && descriptor.document ? descriptor.document : parentDocument; |
| BindingManager.executeBindings(bindingsHost, id, this); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Effects |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * For each effect event, registers the EffectManager |
| * as one of the event listeners. |
| * You typically never need to call this method. |
| * |
| * @param effects The names of the effect events. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function registerEffects(effects:Array /* of String */):void |
| { |
| var n:int = effects.length; |
| for (var i:int = 0; i < n; i++) |
| { |
| // Ask the EffectManager for the event associated with this effectTrigger |
| var event:String = EffectManager.getEventForEffectTrigger(effects[i]); |
| |
| if (event != null && event != "") |
| { |
| addEventListener(event, EffectManager.eventHandler, |
| false, EventPriority.EFFECT); |
| } |
| } |
| } |
| |
| /** |
| * @private |
| * |
| * Adds an overlay object that's always on top of our children. |
| * Calls createOverlay(), which returns the overlay object. |
| * Currently used by the Dissolve and Resize effects. |
| * |
| * Returns the overlay object. |
| */ |
| mx_internal function addOverlay(color:uint, |
| targetArea:RoundedRectangle = null):void |
| { |
| if (!effectOverlay) |
| { |
| effectOverlayColor = color; |
| effectOverlay = new UIComponent(); |
| effectOverlay.name = "overlay"; |
| // Have to set visibility immediately |
| // to make sure we avoid flicker |
| effectOverlay.$visible = true; |
| |
| fillOverlay(effectOverlay, color, targetArea); |
| |
| attachOverlay(); |
| |
| if (!targetArea) |
| addEventListener(ResizeEvent.RESIZE, overlay_resizeHandler); |
| |
| effectOverlay.x = 0; |
| effectOverlay.y = 0; |
| |
| invalidateDisplayList(); |
| |
| effectOverlayReferenceCount = 1; |
| } |
| else |
| { |
| effectOverlayReferenceCount++; |
| } |
| |
| dispatchEvent(new ChildExistenceChangedEvent(ChildExistenceChangedEvent.OVERLAY_CREATED, true, false, effectOverlay)); |
| } |
| |
| /** |
| * This is an internal method used by the Flex framework |
| * to support the Dissolve effect. |
| * You do not have to call it or override it. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function attachOverlay():void |
| { |
| addChild(effectOverlay); |
| } |
| |
| /** |
| * @private |
| * Fill an overlay object which is always the topmost child. |
| * Used by the Dissolve effect. |
| * Never call this function directly. |
| * It is called internally by addOverlay(). |
| * |
| * The overlay object is filled with a solid rectangle that has the |
| * same width and height as the component. |
| */ |
| mx_internal function fillOverlay(overlay:UIComponent, color:uint, |
| targetArea:RoundedRectangle = null):void |
| { |
| if (!targetArea) |
| targetArea = new RoundedRectangle(0, 0, unscaledWidth, unscaledHeight, 0); |
| |
| var g:Graphics = overlay.graphics; |
| g.clear(); |
| g.beginFill(color); |
| |
| g.drawRoundRect(targetArea.x, targetArea.y, |
| targetArea.width, targetArea.height, |
| targetArea.cornerRadius * 2, |
| targetArea.cornerRadius * 2); |
| g.endFill(); |
| } |
| |
| /** |
| * @private |
| * Removes the overlay object added by addOverlay(). |
| */ |
| mx_internal function removeOverlay():void |
| { |
| if (effectOverlayReferenceCount > 0 && --effectOverlayReferenceCount == 0 && effectOverlay) |
| { |
| removeEventListener(ResizeEvent.RESIZE, overlay_resizeHandler); |
| |
| if (super.getChildByName("overlay")) |
| $removeChild(effectOverlay); |
| |
| effectOverlay = null; |
| } |
| } |
| /** |
| * @private |
| * Resize the overlay when the components size changes |
| * |
| */ |
| private function overlay_resizeHandler(event:Event):void |
| { |
| fillOverlay(effectOverlay, effectOverlayColor, null); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal var _effectsStarted:Array = []; |
| |
| /** |
| * @private |
| */ |
| mx_internal var _affectedProperties:Object = {}; |
| |
| /** |
| * Contains <code>true</code> if an effect is currently playing on the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| private var _isEffectStarted:Boolean = false; |
| mx_internal function get isEffectStarted():Boolean |
| { |
| return _isEffectStarted; |
| } |
| mx_internal function set isEffectStarted(value:Boolean):void |
| { |
| _isEffectStarted = value; |
| } |
| |
| private var preventDrawFocus:Boolean = false; |
| |
| /** |
| * Called by the effect instance when it starts playing on the component. |
| * You can use this method to perform a modification to the component as part |
| * of an effect. You can use the <code>effectFinished()</code> method |
| * to restore the modification when the effect ends. |
| * |
| * @param effectInst The effect instance object playing on the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function effectStarted(effectInst:IEffectInstance):void |
| { |
| // Check that the instance isn't already in our list |
| _effectsStarted.push(effectInst); |
| |
| var aProps:Array = effectInst.effect.getAffectedProperties(); |
| for (var j:int = 0; j < aProps.length; j++) |
| { |
| var propName:String = aProps[j]; |
| if (_affectedProperties[propName] == undefined) |
| { |
| _affectedProperties[propName] = []; |
| } |
| |
| _affectedProperties[propName].push(effectInst); |
| } |
| |
| isEffectStarted = true; |
| // Hide the focus ring if the target already has one drawn |
| if (effectInst.hideFocusRing) |
| { |
| preventDrawFocus = true; |
| drawFocus(false); |
| } |
| } |
| |
| |
| private var _endingEffectInstances:Array = []; |
| |
| /** |
| * Called by the effect instance when it stops playing on the component. |
| * You can use this method to restore a modification to the component made |
| * by the <code>effectStarted()</code> method when the effect started, |
| * or perform some other action when the effect ends. |
| * |
| * @param effectInst The effect instance object playing on the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function effectFinished(effectInst:IEffectInstance):void |
| { |
| _endingEffectInstances.push(effectInst); |
| invalidateProperties(); |
| |
| // weak reference |
| UIComponentGlobals.layoutManager.addEventListener( |
| FlexEvent.UPDATE_COMPLETE, updateCompleteHandler, false, 0, true); |
| } |
| |
| /** |
| * Ends all currently playing effects on the component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function endEffectsStarted():void |
| { |
| var len:int = _effectsStarted.length; |
| for (var i:int = 0; i < len; i++) |
| { |
| _effectsStarted[i].end(); |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| private function updateCompleteHandler(event:FlexEvent):void |
| { |
| UIComponentGlobals.layoutManager.removeEventListener( |
| FlexEvent.UPDATE_COMPLETE, updateCompleteHandler); |
| processEffectFinished(_endingEffectInstances); |
| _endingEffectInstances = []; |
| } |
| |
| /** |
| * @private |
| */ |
| private function processEffectFinished(effectInsts:Array):void |
| { |
| // Find the instance in our list. |
| for (var i:int = _effectsStarted.length - 1; i >= 0; i--) |
| { |
| for (var j:int = 0; j < effectInsts.length; j++) |
| { |
| var effectInst:IEffectInstance = effectInsts[j]; |
| if (effectInst == _effectsStarted[i]) |
| { |
| // Remove the effect from our array. |
| var removedInst:IEffectInstance = _effectsStarted[i]; |
| _effectsStarted.splice(i, 1); |
| |
| // Remove the affected properties from our internal object |
| var aProps:Array = removedInst.effect.getAffectedProperties(); |
| for (var k:int = 0; k < aProps.length; k++) |
| { |
| var propName:String = aProps[k]; |
| if (_affectedProperties[propName] != undefined) |
| { |
| for (var l:int = 0; l < _affectedProperties[propName].length; l++) |
| { |
| if (_affectedProperties[propName][l] == effectInst) |
| { |
| _affectedProperties[propName].splice(l, 1); |
| break; |
| } |
| } |
| |
| if (_affectedProperties[propName].length == 0) |
| delete _affectedProperties[propName]; |
| } |
| } |
| break; |
| } |
| } |
| } |
| |
| isEffectStarted = _effectsStarted.length > 0 ? true : false; |
| if (effectInst && effectInst.hideFocusRing) |
| { |
| preventDrawFocus = false; |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function getEffectsForProperty(propertyName:String):Array |
| { |
| return _affectedProperties[propertyName] != undefined ? |
| _affectedProperties[propertyName] : |
| []; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Repeater |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function createReferenceOnParentDocument( |
| parentDocument:IFlexDisplayObject):void |
| { |
| if (id && id != "") |
| { |
| var indices:Array = _instanceIndices; |
| if (!indices) |
| { |
| parentDocument[id] = this; |
| } |
| else |
| { |
| var r:Object = parentDocument[id]; |
| |
| if (! (r is Array)) |
| { |
| r = parentDocument[id] = []; |
| } |
| |
| var n:int = indices.length; |
| for (var i:int = 0; i < n - 1; i++) |
| { |
| var s:Object = r[indices[i]]; |
| |
| if (!(s is Array)) |
| s = r[indices[i]] = []; |
| |
| r = s; |
| } |
| |
| r[indices[n - 1]] = this; |
| |
| if (parentDocument.hasEventListener("propertyChange")) |
| { |
| var event:PropertyChangeEvent = |
| PropertyChangeEvent.createUpdateEvent(parentDocument, |
| id, |
| parentDocument[id], |
| parentDocument[id]); |
| parentDocument.dispatchEvent(event); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function deleteReferenceOnParentDocument( |
| parentDocument:IFlexDisplayObject):void |
| { |
| if (id && id != "") |
| { |
| var indices:Array = _instanceIndices; |
| if (!indices) |
| { |
| parentDocument[id] = null; |
| } |
| else |
| { |
| var r:Object = parentDocument[id]; |
| |
| if (!r) |
| return; |
| |
| var stack:Array = []; |
| stack.push(r); |
| |
| var n:int = indices.length; |
| for (var i:int = 0; i < n - 1; i++) |
| { |
| var s:Object = r[indices[i]]; |
| |
| if (!s) |
| return; |
| |
| r = s; |
| stack.push(r); |
| } |
| |
| r.splice(indices[n - 1], 1); |
| |
| for (var j:int = stack.length - 1; j > 0; j--) |
| { |
| if (stack[j].length == 0) |
| stack[j - 1].splice(indices[j], 1); |
| } |
| |
| if ((stack.length > 0) && (stack[0].length == 0)) |
| { |
| parentDocument[id] = null; |
| } |
| else |
| { |
| if (parentDocument.hasEventListener("propertyChange")) |
| { |
| var event:PropertyChangeEvent = |
| PropertyChangeEvent.createUpdateEvent(parentDocument, |
| id, |
| parentDocument[id], |
| parentDocument[id]); |
| parentDocument.dispatchEvent(event); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Returns the item in the <code>dataProvider</code> that was used |
| * by the specified Repeater to produce this Repeater, or |
| * <code>null</code> if this Repeater isn't repeated. |
| * The argument <code>whichRepeater</code> is 0 for the outermost |
| * Repeater, 1 for the next inner Repeater, and so on. |
| * If <code>whichRepeater</code> is not specified, |
| * the innermost Repeater is used. |
| * |
| * @param whichRepeater Number of the Repeater, |
| * counting from the outermost one, starting at 0. |
| * |
| * @return The requested repeater item. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getRepeaterItem(whichRepeater:int = -1):Object |
| { |
| var repeaterArray:Array = repeaters; |
| |
| // If repeaterArray has no items the caller is not |
| // in a repeater. Return null. |
| if (repeaterArray.length == 0) |
| return null; |
| |
| // If whichRepeater isn't specified, assume the |
| // innermost Repeater. This lets authors simply write |
| // myRepeater.getRepeaterItem() |
| if (whichRepeater == -1) |
| whichRepeater = repeaterArray.length - 1; |
| |
| return repeaterArray[whichRepeater]. |
| getItemAt(repeaterIndices[whichRepeater]); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Resources |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * This method is called when a UIComponent is constructed, |
| * and again whenever the ResourceManager dispatches |
| * a <code>"change"</code> Event to indicate |
| * that the localized resources have changed in some way. |
| * |
| * <p>This event is dispatched when you set the ResourceManager's |
| * <code>localeChain</code> property, when a resource module |
| * has finished loading, and when you call the ResourceManager's |
| * <code>update()</code> method.</p> |
| * |
| * <p>Subclasses should override this method and, after calling |
| * <code>super.resourcesChanged()</code>, do whatever is appropriate |
| * in response to having new resource values.</p> |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function resourcesChanged():void |
| { |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Printing |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Prepares an IFlexDisplayObject for printing. |
| * For the UIComponent class, the method performs no action. |
| * Flex containers override the method to prepare for printing; |
| * for example, by removing scroll bars from the printed output. |
| * |
| * <p>This method is normally not used by application developers. </p> |
| * |
| * @param target The component to be printed. |
| * It can be the current component or one of its children. |
| * |
| * @return Object containing the properties of the current component |
| * required by the <code>finishPrint()</code> method |
| * to restore it to its previous state. |
| * |
| * @see mx.printing.FlexPrintJob |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function prepareToPrint(target:IFlexDisplayObject):Object |
| { |
| return null; |
| } |
| |
| /** |
| * Called after printing is complete. |
| * For the UIComponent class, the method performs no action. |
| * Flex containers override the method to restore the container after printing. |
| * |
| * <p>This method is normally not used by application developers. </p> |
| * |
| * @param obj Contains the properties of the component that |
| * restore it to its state before printing. |
| * |
| * @param target The component that just finished printing. |
| * It can be the current component or one of its children. |
| * |
| * @see mx.printing.FlexPrintJob |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function finishPrint(obj:Object, target:IFlexDisplayObject):void |
| { |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers: Invalidation |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Callback that then calls queued functions. |
| */ |
| private function callLaterDispatcher(event:Event):void |
| { |
| // trace(">>calllaterdispatcher " + this); |
| UIComponentGlobals.callLaterDispatcherCount++; |
| |
| // At run-time, callLaterDispatcher2() is called |
| // without a surrounding try-catch. |
| if (!UIComponentGlobals.catchCallLaterExceptions) |
| { |
| callLaterDispatcher2(event); |
| } |
| |
| // At design-time, callLaterDispatcher2() is called |
| // with a surrounding try-catch. |
| else |
| { |
| try |
| { |
| callLaterDispatcher2(event); |
| } |
| catch(e:Error) |
| { |
| // Dispatch a callLaterError dynamic event for Design View. |
| var callLaterErrorEvent:DynamicEvent = new DynamicEvent("callLaterError"); |
| callLaterErrorEvent.error = e; |
| callLaterErrorEvent.source = this; |
| systemManager.dispatchEvent(callLaterErrorEvent); |
| } |
| } |
| // trace("<<calllaterdispatcher"); |
| UIComponentGlobals.callLaterDispatcherCount--; |
| } |
| |
| /** |
| * @private |
| * Callback that then calls queued functions. |
| */ |
| private function callLaterDispatcher2(event:Event):void |
| { |
| if (UIComponentGlobals.callLaterSuspendCount > 0) |
| return; |
| |
| // trace(" >>calllaterdispatcher2"); |
| var sm:ISystemManager = systemManager; |
| |
| // Stage can be null when an untrusted application is loaded by an application |
| // that isn't on stage yet. |
| if (sm && (sm.stage || usingBridge) && listeningForRender) |
| { |
| // trace(" removed"); |
| sm.removeEventListener(FlexEvent.RENDER, callLaterDispatcher); |
| sm.removeEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher); |
| listeningForRender = false; |
| } |
| |
| // Move the method queue off to the side, so that subsequent |
| // calls to callLater get added to a new queue that'll get handled |
| // next time. |
| var queue:Array = methodQueue; |
| methodQueue = []; |
| |
| // Call each method currently in the method queue. |
| // These methods can call callLater(), causing additional |
| // methods to be queued, but these will get called the next |
| // time around. |
| var n:int = queue.length; |
| // trace(" queue length " + n); |
| for (var i:int = 0; i < n; i++) |
| { |
| var mqe:MethodQueueElement = MethodQueueElement(queue[i]); |
| |
| mqe.method.apply(null, mqe.args); |
| } |
| |
| // trace(" <<calllaterdispatcher2 " + this); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers: Keyboard |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * The event handler called for a <code>keyDown</code> event. |
| * If you override this method, make sure to call the base class version. |
| * |
| * @param event The event object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function keyDownHandler(event:KeyboardEvent):void |
| { |
| // You must override this function if your component accepts focus |
| } |
| |
| /** |
| * The event handler called for a <code>keyUp</code> event. |
| * If you override this method, make sure to call the base class version. |
| * |
| * @param event The event object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function keyUpHandler(event:KeyboardEvent):void |
| { |
| // You must override this function if your component accepts focus |
| } |
| |
| /** |
| * Typically overridden by components containing UITextField objects, |
| * where the UITextField object gets focus. |
| * |
| * @param target A UIComponent object containing a UITextField object |
| * that can receive focus. |
| * |
| * @return Returns <code>true</code> if the UITextField object has focus. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function isOurFocus(target:DisplayObject):Boolean |
| { |
| return target == this; |
| } |
| |
| /** |
| * The event handler called when a UIComponent object gets focus. |
| * If you override this method, make sure to call the base class version. |
| * |
| * @param event The event object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function focusInHandler(event:FocusEvent):void |
| { |
| if (isOurFocus(DisplayObject(event.target))) |
| { |
| var fm:IFocusManager = focusManager; |
| if (fm && fm.showFocusIndicator) |
| drawFocus(true); |
| |
| ContainerGlobals.checkFocus(event.relatedObject, this); |
| } |
| } |
| |
| /** |
| * The event handler called when a UIComponent object loses focus. |
| * If you override this method, make sure to call the base class version. |
| * |
| * @param event The event object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function focusOutHandler(event:FocusEvent):void |
| { |
| // We don't need to remove our event listeners here because we |
| // won't receive keyboard events. |
| if (isOurFocus(DisplayObject(event.target))) |
| drawFocus(false); |
| } |
| |
| /** |
| * @private |
| * The player dispatches an "added" event when the addChild() |
| * or addChildAt() method of DisplayObjectContainer is called, |
| * but handling this event at that time can be dangerous |
| * so we prevent the event dispatched then from propagating; |
| * we'll dispatch another "added" event later when it is safe. |
| * The reason the timing of this player event is dangerous |
| * is that the Flex framework overrides addChild() and addChildAt(), |
| * to perform important additional work after calling the super |
| * method, such as setting _parent to skip over the contentPane |
| * of a Container. So if an "added" handler executes too early, |
| * the child is in an inconsistent state. (For example, its |
| * toString() can be wrong because the contentPane is wrongly |
| * included when traversing the parent chain.) Our overrides |
| * delay dispatching the "added" event until the end of the |
| * override, as opposed to in the middle when super.addChild() |
| * is called. |
| * Note: This event handler is registered by the UIComponent |
| * constructor, which means it is registered before any |
| * other handlers for an "added" event. |
| * Therefore it can prevent all others from being called. |
| */ |
| private function addedHandler(event:Event):void |
| { |
| //reset systemManager in case we've been reparented to a new Window. |
| //systemManager will be set on get systemManager() |
| if (event.eventPhase != EventPhase.AT_TARGET) |
| return; |
| |
| try |
| { |
| if (parent is IContainer && IContainer(parent).creatingContentPane) |
| { |
| event.stopImmediatePropagation(); |
| return; |
| } |
| } |
| catch (error:SecurityError) |
| { |
| |
| } |
| } |
| |
| /** |
| * @private |
| * See the comments for addedHandler() above. |
| */ |
| private function removedHandler(event:Event):void |
| { |
| if (event.eventPhase != EventPhase.AT_TARGET) |
| return; |
| |
| try |
| { |
| if (parent is IContainer && IContainer(parent).creatingContentPane) |
| { |
| event.stopImmediatePropagation(); |
| return; |
| } |
| } |
| catch (error:SecurityError) |
| { |
| |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| private function removedFromStageHandler(event:Event):void |
| { |
| _systemManagerDirty = true; |
| } |
| |
| /** |
| * @private |
| * There is a bug (139390) where setting focus from within callLaterDispatcher |
| * screws up the ActiveX player. We defer focus until enterframe. |
| */ |
| private function setFocusLater(event:Event = null):void |
| { |
| var sm:ISystemManager = systemManager; |
| if (sm && sm.stage) |
| { |
| sm.stage.removeEventListener(Event.ENTER_FRAME, setFocusLater); |
| if (UIComponentGlobals.nextFocusObject) |
| sm.stage.focus = UIComponentGlobals.nextFocusObject; |
| UIComponentGlobals.nextFocusObject = null; |
| } |
| } |
| |
| /** |
| * @private |
| * Called when this component moves. Adjust the focus rect. |
| */ |
| private function focusObj_scrollHandler(event:Event):void |
| { |
| adjustFocusRect(); |
| } |
| |
| /** |
| * @private |
| * Called when this component moves. Adjust the focus rect. |
| */ |
| private function focusObj_moveHandler(event:MoveEvent):void |
| { |
| adjustFocusRect(); |
| } |
| |
| /** |
| * @private |
| * Called when this component resizes. Adjust the focus rect. |
| */ |
| private function focusObj_resizeHandler(event:Event):void |
| { |
| if (event is ResizeEvent) |
| adjustFocusRect(); |
| } |
| |
| /** |
| * @private |
| * Called when this component is unloaded. Hide the focus rect. |
| */ |
| private function focusObj_removedHandler(event:Event):void |
| { |
| // ignore if we captured on a child |
| if (event.target != this) |
| return; |
| |
| var focusObject:DisplayObject = getFocusObject(); |
| |
| if (focusObject) |
| focusObject.visible = false; |
| } |
| |
| /** |
| * @private |
| * Called when our associated layer parent needs to inform us of |
| * a change to it's visibility or alpha. |
| */ |
| protected function layer_PropertyChange(event:PropertyChangeEvent):void |
| { |
| switch (event.property) |
| { |
| case "effectiveVisibility": |
| { |
| var newValue:Boolean = (event.newValue && _visible); |
| if (newValue != $visible) |
| $visible = newValue; |
| break; |
| } |
| case "effectiveAlpha": |
| { |
| var newAlpha:Number = Number(event.newValue) * _alpha; |
| if (newAlpha != $alpha) |
| $alpha = newAlpha; |
| break; |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers: Validation |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Handles both the <code>valid</code> and <code>invalid</code> events from a |
| * validator assigned to this component. |
| * |
| * <p>You typically handle the <code>valid</code> and <code>invalid</code> events |
| * dispatched by a validator by assigning event listeners to the validators. |
| * If you want to handle validation events directly in the component that is being validated, |
| * you can override this method to handle the <code>valid</code> |
| * and <code>invalid</code> events. You typically call |
| * <code>super.validationResultHandler(event)</code> in your override.</p> |
| * |
| * @param event The event object for the validation. |
| * |
| * @see mx.events.ValidationResultEvent |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function validationResultHandler(event:ValidationResultEvent):void |
| { |
| if (errorObjectArray === null) |
| { |
| errorObjectArray = []; |
| errorArray = []; |
| } |
| |
| var validatorIndex:int = errorObjectArray.indexOf(event.target); |
| // If we are valid, then clear the error string |
| if (event.type == ValidationResultEvent.VALID) |
| { |
| if (validatorIndex != -1) |
| { |
| errorObjectArray.splice(validatorIndex, 1); |
| errorArray.splice(validatorIndex, 1); |
| errorString = errorArray.join("\n"); |
| if (errorArray.length == 0) |
| dispatchEvent(new FlexEvent(FlexEvent.VALID)); |
| } |
| } |
| else // If we get an invalid event |
| { |
| var msg:String; |
| var result:ValidationResult; |
| |
| // We are associated with a subfield |
| if (validationSubField != null && validationSubField != "" && event.results) |
| { |
| for (var i:int = 0; i < event.results.length; i++) |
| { |
| result = event.results[i]; |
| // Find the result that is meant for us |
| if (result.subField == validationSubField) |
| { |
| if (result.isError) |
| { |
| msg = result.errorMessage; |
| } |
| else |
| { |
| if (validatorIndex != -1) |
| { |
| errorObjectArray.splice(validatorIndex, 1); |
| errorArray.splice(validatorIndex, 1); |
| errorString = errorArray.join("\n"); |
| if (errorArray.length == 0) |
| dispatchEvent(new FlexEvent(FlexEvent.VALID)); |
| } |
| } |
| break; |
| } |
| } |
| } |
| else if (event.results && event.results.length > 0) |
| { |
| msg = event.results[0].errorMessage; |
| } |
| |
| if (msg && validatorIndex != -1) |
| { |
| // Handle the case where this target already had this invalid |
| // event and the errorString has been cleared. |
| errorArray[validatorIndex] = msg; |
| errorString = errorArray.join("\n"); |
| dispatchEvent(new FlexEvent(FlexEvent.INVALID)); |
| } |
| else if (msg && validatorIndex == -1) |
| { |
| errorObjectArray.push(event.target); |
| errorArray.push(msg); |
| errorString = errorArray.join("\n"); |
| dispatchEvent(new FlexEvent(FlexEvent.INVALID)); |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers: Resources |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function resourceManager_changeHandler(event:Event):void |
| { |
| resourcesChanged(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event handlers: Filters |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private function filterChangeHandler(event:Event):void |
| { |
| filters = _filters; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // IUIComponent |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Returns <code>true</code> if the chain of <code>owner</code> properties |
| * points from <code>child</code> to this UIComponent. |
| * |
| * @param child A UIComponent. |
| * |
| * @return <code>true</code> if the child is parented or owned by this UIComponent. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function owns(child:DisplayObject):Boolean |
| { |
| var childList:IChildList = |
| this is IRawChildrenContainer ? |
| IRawChildrenContainer(this).rawChildren : |
| IChildList(this); |
| |
| if (childList.contains(child)) |
| return true; |
| |
| try |
| { |
| while (child && child != this) |
| { |
| // do a parent walk |
| if (child is IUIComponent) |
| child = IUIComponent(child).owner; |
| else |
| child = child.parent; |
| } |
| } |
| catch (e:SecurityError) |
| { |
| // You can't own what you don't have access to. |
| return false; |
| } |
| |
| return child == this; |
| } |
| |
| /** |
| * @private |
| * Finds a module factory that can create a TextField |
| * that can display the given font. |
| * This is important for embedded fonts, not for system fonts. |
| * |
| * @param fontName The name of the fontFamily. |
| * |
| * @param bold A flag which true if the font weight is bold, |
| * and false otherwise. |
| * |
| * @param italic A flag which is true if the font style is italic, |
| * and false otherwise. |
| * |
| * @return The IFlexModuleFactory that represents the context |
| * where an object wanting to use the font should be created. |
| */ |
| mx_internal function getFontContext(fontName:String, bold:Boolean, |
| italic:Boolean, embeddedCff:*=undefined):IFlexModuleFactory |
| { |
| if (noEmbeddedFonts) |
| return null; |
| |
| var registry:IEmbeddedFontRegistry = embeddedFontRegistry; |
| |
| return registry ? registry.getAssociatedModuleFactory( |
| fontName, bold, italic, this, moduleFactory, systemManager, |
| embeddedCff) : null; |
| } |
| |
| /** |
| * Creates a new object using a context |
| * based on the embedded font being used. |
| * |
| * <p>This method is used to solve a problem |
| * with access to fonts embedded in an application SWF |
| * when the framework is loaded as an RSL |
| * (the RSL has its own SWF context). |
| * Embedded fonts can only be accessed from the SWF file context |
| * in which they were created. |
| * By using the context of the application SWF, |
| * the RSL can create objects in the application SWF context |
| * that has access to the application's embedded fonts.</p> |
| * |
| * <p>Call this method only after the font styles |
| * for this object are set.</p> |
| * |
| * @param class The class to create. |
| * |
| * @return The instance of the class created in the context |
| * of the SWF owning the embedded font. |
| * If this object is not using an embedded font, |
| * the class is created in the context of this object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function createInFontContext(classObj:Class):Object |
| { |
| hasFontContextBeenSaved = true; |
| |
| var fontName:String = StringUtil.trimArrayElements(getStyle("fontFamily"), ","); |
| var fontWeight:String = getStyle("fontWeight"); |
| var fontStyle:String = getStyle("fontStyle"); |
| var bold:Boolean = (fontWeight == "bold"); |
| var italic:Boolean = (fontStyle == "italic"); |
| |
| var className:String = getQualifiedClassName(classObj); |
| |
| // If the caller requests a UITextField, |
| // we may actually return a UITLFTextField, |
| // depending on the version number |
| // and the value of the textFieldClass style. |
| if (className == "mx.core::UITextField") |
| { |
| className = getTextFieldClassName(); |
| if (className == "mx.core::UIFTETextField") |
| classObj = Class(ApplicationDomain.currentDomain. |
| getDefinition(className)); |
| } |
| |
| // Save for hasFontContextChanged(). |
| oldEmbeddedFontContext = getFontContext(fontName, bold, italic, |
| className == "mx.core::UIFTETextField"); |
| |
| var moduleContext:IFlexModuleFactory = oldEmbeddedFontContext ? |
| oldEmbeddedFontContext : |
| moduleFactory; |
| |
| // Not in font registry, so create in this font context. |
| var obj:Object = createInModuleContext(moduleContext, className); |
| |
| if (obj == null) |
| obj = new classObj(); |
| |
| // If we just created a UITLFTextField, set its fontContext property |
| // so that it knows what module to use for creating its TextLines. |
| if (className == "mx.core::UIFTETextField") |
| obj.fontContext = moduleContext; |
| |
| return obj; |
| } |
| |
| /** |
| * @private |
| * Returns either "mx.core::UITextField" or "mx.core::UIFTETextField", |
| * based on the version number and the textFieldClass style. |
| */ |
| private function getTextFieldClassName():String |
| { |
| var c:Class = getStyle("textFieldClass"); |
| |
| if (!c || FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| return "mx.core::UITextField"; |
| |
| return getQualifiedClassName(c); |
| } |
| |
| /** |
| * @private |
| * Returns either "mx.core::TextInput" or "mx.core::MXFTETextInput", |
| * based on the version number and the textInputClass style. |
| */ |
| private function getTextInputClassName():String |
| { |
| var c:Class = getStyle("textInputClass"); |
| |
| if (!c || FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0) |
| return "mx.core::TextInput"; |
| |
| return getQualifiedClassName(c); |
| } |
| |
| /** |
| * Creates the object using a given moduleFactory. |
| * If the moduleFactory is null or the object |
| * cannot be created using the module factory, |
| * then fall back to creating the object using a systemManager. |
| * |
| * @param moduleFactory The moduleFactory to create the class in; |
| * can be null. |
| * |
| * @param className The name of the class to create. |
| * |
| * @return The object created in the context of the moduleFactory. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| protected function createInModuleContext(moduleFactory:IFlexModuleFactory, |
| className:String):Object |
| { |
| var newObject:Object = null; |
| |
| if (moduleFactory) |
| newObject = moduleFactory.create(className); |
| |
| return newObject; |
| } |
| |
| /** |
| * @private |
| * |
| * Tests if the current font context has changed |
| * since that last time createInFontContext() was called. |
| */ |
| public function hasFontContextChanged():Boolean |
| { |
| |
| // If the font has not been set yet, then return false; |
| // the font has not changed. |
| if (!hasFontContextBeenSaved) |
| return false; |
| |
| // Check if the module factory has changed. |
| var fontName:String = |
| StringUtil.trimArrayElements(getStyle("fontFamily"), ","); |
| var fontWeight:String = getStyle("fontWeight"); |
| var fontStyle:String = getStyle("fontStyle"); |
| var bold:Boolean = fontWeight == "bold"; |
| var italic:Boolean = fontStyle == "italic"; |
| var fontContext:IFlexModuleFactory = noEmbeddedFonts ? null : |
| embeddedFontRegistry.getAssociatedModuleFactory( |
| fontName, bold, italic, this, moduleFactory, |
| systemManager); |
| return fontContext != oldEmbeddedFontContext; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function createAutomationIDPart(child:IAutomationObject):Object |
| { |
| if (automationDelegate) |
| return automationDelegate.createAutomationIDPart(child); |
| return null; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function createAutomationIDPartWithRequiredProperties(child:IAutomationObject, |
| properties:Array):Object |
| { |
| if (automationDelegate) |
| return automationDelegate.createAutomationIDPartWithRequiredProperties(child, properties); |
| return null; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function resolveAutomationIDPart(criteria:Object):Array |
| { |
| if (automationDelegate) |
| return automationDelegate.resolveAutomationIDPart(criteria); |
| return []; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getAutomationChildAt(index:int):IAutomationObject |
| { |
| if (automationDelegate) |
| return automationDelegate.getAutomationChildAt(index); |
| return null; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getAutomationChildren():Array |
| { |
| if (automationDelegate) |
| return automationDelegate.getAutomationChildren(); |
| return null; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get numAutomationChildren():int |
| { |
| if (automationDelegate) |
| return automationDelegate.numAutomationChildren; |
| return 0; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get automationTabularData():Object |
| { |
| if (automationDelegate) |
| return automationDelegate.automationTabularData; |
| return null; |
| } |
| |
| //---------------------------------- |
| // automationOwner |
| //---------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function get automationOwner():DisplayObjectContainer |
| { |
| return owner; |
| } |
| |
| //---------------------------------- |
| // automationParent |
| //---------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function get automationParent():DisplayObjectContainer |
| { |
| return parent; |
| } |
| |
| //---------------------------------- |
| // automationEnabled |
| //---------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function get automationEnabled():Boolean |
| { |
| return enabled; |
| } |
| |
| //---------------------------------- |
| // automationVisible |
| //---------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 4 |
| */ |
| public function get automationVisible():Boolean |
| { |
| return visible; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function replayAutomatableEvent(event:Event):Boolean |
| { |
| if (automationDelegate) |
| return automationDelegate.replayAutomatableEvent(event); |
| return false; |
| } |
| |
| |
| /** |
| * Get the bounds of this object that are visible to the user |
| * on the screen. |
| * |
| * @param targetParent The parent to stop at when calculating the visible |
| * bounds. If null, this object's system manager will be used as |
| * the parent. |
| * |
| * @return a <code>Rectangle</code> including the visible portion of the this |
| * object. The rectangle is in global coordinates. |
| */ |
| public function getVisibleRect(targetParent:DisplayObject = null):Rectangle |
| { |
| if (!targetParent) |
| targetParent = DisplayObject(systemManager); |
| |
| var thisParent:DisplayObject = $parent ? $parent : parent; |
| |
| // If the object is not on the display list then it is not visible. |
| if (!thisParent) |
| return new Rectangle(); |
| |
| var pt:Point = new Point(x, y); |
| pt = thisParent.localToGlobal(pt); |
| |
| // bounds of this object to return. Keep in global coordinates |
| // until the end and set back to targetParent coordinates. |
| var bounds:Rectangle = new Rectangle(pt.x, pt.y, width, height); |
| var current:DisplayObject = this; |
| var currentRect:Rectangle = new Rectangle(); |
| |
| do |
| { |
| if (current is UIComponent) |
| { |
| if (UIComponent(current).$parent) |
| current = UIComponent(current).$parent; |
| else |
| current = UIComponent(current).parent; |
| } |
| else |
| current = current.parent; |
| |
| if (current && current.scrollRect) |
| { |
| // clip the bounds by the scroll rect |
| currentRect = current.scrollRect.clone(); |
| pt = current.localToGlobal(currentRect.topLeft); |
| currentRect.x = pt.x; |
| currentRect.y = pt.y; |
| bounds = bounds.intersection(currentRect); |
| } |
| } while (current && current != targetParent); |
| |
| return bounds; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Diagnostics |
| // |
| //-------------------------------------------------------------------------- |
| |
| mx_internal static var dispatchEventHook:Function; |
| |
| /** |
| * Dispatches an event into the event flow. |
| * The event target is the EventDispatcher object upon which |
| * the <code>dispatchEvent()</code> method is called. |
| * |
| * Note that when <code>dispatchEvent()</code> is called by code inside a |
| * <code>try</code> block, any error thrown thereafter can be caught by |
| * listening to LoaderInfo.uncaughtErrorEvents. It will NOT reach the |
| * <code>catch</code> block. |
| * |
| * |
| * @param event The Event object that is dispatched into the event flow. |
| * If the event is being redispatched, a clone of the event is created automatically. |
| * After an event is dispatched, its <code>target</code> property cannot be changed, |
| * so you must create a new copy of the event for redispatching to work. |
| * |
| * @return A value of <code>true</code> if the event was successfully dispatched. |
| * A value of <code>false</code> indicates failure or that |
| * the <code>preventDefault()</code> method was called on the event. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function dispatchEvent(event:Event):Boolean |
| { |
| if (dispatchEventHook != null) |
| dispatchEventHook(event, this); |
| |
| return super.dispatchEvent(event); |
| } |
| |
| private static var fakeMouseX:QName = new QName(mx_internal, "_mouseX"); |
| private static var fakeMouseY:QName = new QName(mx_internal, "_mouseY"); |
| |
| /** |
| * @private |
| */ |
| override public function get mouseX():Number |
| { |
| if (!root || root is Stage || root[fakeMouseX] === undefined) |
| return super.mouseX; |
| return globalToLocal(new Point(root[fakeMouseX], 0)).x; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function get mouseY():Number |
| { |
| if (!root || root is Stage || root[fakeMouseY] === undefined) |
| return super.mouseY; |
| return globalToLocal(new Point(0, root[fakeMouseY])).y; |
| } |
| |
| |
| /** |
| * Initializes the implementation and storage of some of the less frequently |
| * used advanced layout features of a component. |
| * |
| * Call this function before attempting to use any of the features implemented |
| * by the AdvancedLayoutFeatures object. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| protected function initAdvancedLayoutFeatures():void |
| { |
| internal_initAdvancedLayoutFeatures(); |
| } |
| |
| |
| /** |
| * @private |
| */ |
| mx_internal function transformRequiresValidations():Boolean |
| { |
| return (_layoutFeatures != null); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function clearAdvancedLayoutFeatures():void |
| { |
| if (_layoutFeatures) |
| { |
| // Make sure the matrix is validated before we free the |
| // layout features. |
| validateMatrix(); |
| _layoutFeatures = null; |
| } |
| } |
| |
| /** |
| * Passed to TransformUtil to create the layout features when performing |
| * transformation operations. |
| */ |
| private function internal_initAdvancedLayoutFeatures():AdvancedLayoutFeatures |
| { |
| var features:AdvancedLayoutFeatures = new AdvancedLayoutFeatures(); |
| |
| _hasComplexLayoutMatrix = true; |
| |
| features.layoutScaleX = scaleX; |
| features.layoutScaleY = scaleY; |
| features.layoutScaleZ = scaleZ; |
| features.layoutRotationX = rotationX; |
| features.layoutRotationY = rotationY; |
| features.layoutRotationZ = rotation; |
| features.layoutX = x; |
| features.layoutY = y; |
| features.layoutZ = z; |
| features.layoutWidth = width; // for the mirror transform |
| _layoutFeatures = features; |
| invalidateTransform(); |
| return features; |
| } |
| |
| /** |
| * @private |
| * Helper function to update the storage vairable _transform. |
| * Also updates the <code>target</code> property of the new and the old |
| * values. |
| */ |
| private function setTransform(value:flash.geom.Transform):void |
| { |
| // Clean up the old transform |
| var oldTransform:mx.geom.Transform = _transform as mx.geom.Transform; |
| if (oldTransform) |
| oldTransform.target = null; |
| |
| var newTransform:mx.geom.Transform = value as mx.geom.Transform; |
| |
| if (newTransform) |
| newTransform.target = this; |
| |
| _transform = value; |
| } |
| |
| /** |
| * @private |
| * Documentation is not currently available |
| */ |
| mx_internal function get $transform():flash.geom.Transform |
| { |
| return super.transform; |
| } |
| |
| /** |
| * @private |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get transform():flash.geom.Transform |
| { |
| if (_transform == null) |
| { |
| setTransform(new mx.geom.Transform(this)); |
| } |
| return _transform; |
| } |
| |
| /** |
| * An object with properties pertaining to a display object's matrix, color transform, |
| * and pixel bounds. The specific properties — matrix, colorTransform, and three read-only |
| * properties (<code>concatenatedMatrix</code>, <code>concatenatedColorTransform</code>, and <code>pixelBounds</code>) — |
| * are described in the entry for the <code>Transform</code> class. |
| * |
| * <p>Each of the transform object's properties is itself an object. This concept is |
| * important because the only way to set new values for the matrix or colorTransform |
| * objects is to create a new object and copy that object into the transform.matrix or |
| * transform.colorTransform property.</p> |
| * |
| * <p>For example, to increase the tx value of a display object's matrix, you must make a copy |
| * of the entire matrix object, then copy the new object into the matrix property of the |
| * transform object:</p> |
| * |
| * <pre> |
| * var myMatrix:Matrix = myUIComponentObject.transform.matrix; |
| * myMatrix.tx += 10; |
| * myUIComponent.transform.matrix = myMatrix; |
| * </pre> |
| * |
| * You cannot directly set the tx property. The following code has no effect on myUIComponent: |
| * |
| * <pre> |
| * myUIComponent.transform.matrix.tx += 10; |
| * </pre> |
| * |
| * <p>Note that for <code>UIComponent</code>, unlike <code>DisplayObject</code>, the <code>transform</code> |
| * keeps the <code>matrix</code> and <code>matrix3D</code> values in sync and <code>matrix3D</code> is not null |
| * even when the component itself has no 3D properties set. Developers should use the <code>is3D</code> property |
| * to check if the component has 3D propertis set. If the component has 3D properties, the transform's |
| * <code>matrix3D</code> should be used instead of transform's <code>matrix</code>.</p> |
| * |
| * @see #setLayoutMatrix |
| * @see #setLayoutMatrix3D |
| * @see #getLayoutMatrix |
| * @see #getLayoutMatrix3D |
| * @see #is3D |
| * @see mx.geom.Transform |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function set transform(value:flash.geom.Transform):void |
| { |
| var m:Matrix = value.matrix; |
| var m3:Matrix3D = value.matrix3D; |
| var ct:ColorTransform = value.colorTransform; |
| var pp:PerspectiveProjection = value.perspectiveProjection; |
| |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| |
| var mxTransform:mx.geom.Transform = value as mx.geom.Transform; |
| if (mxTransform) |
| { |
| if (!mxTransform.applyMatrix) |
| m = null; |
| |
| if (!mxTransform.applyMatrix3D) |
| m3 = null; |
| } |
| |
| setTransform(value); |
| |
| if (m != null) |
| setLayoutMatrix(m.clone(), true /*triggerLayoutPass*/); |
| else if (m3 != null) |
| setLayoutMatrix3D(m3.clone(), true /*triggerLayoutPass*/); |
| |
| super.transform.colorTransform = ct; |
| super.transform.perspectiveProjection = pp; |
| if (maintainProjectionCenter) |
| invalidateDisplayList(); |
| if (was3D != is3D) |
| validateMatrix(); |
| } |
| |
| /** |
| * @copy mx.core.IVisualElement#postLayoutTransformOffsets |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get postLayoutTransformOffsets():TransformOffsets |
| { |
| return (_layoutFeatures != null)? _layoutFeatures.postLayoutTransformOffsets:null; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set postLayoutTransformOffsets(value:TransformOffsets):void |
| { |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| |
| if (_layoutFeatures.postLayoutTransformOffsets != null) |
| _layoutFeatures.postLayoutTransformOffsets.removeEventListener(Event.CHANGE,transformOffsetsChangedHandler); |
| _layoutFeatures.postLayoutTransformOffsets = value; |
| if (_layoutFeatures.postLayoutTransformOffsets != null) |
| _layoutFeatures.postLayoutTransformOffsets.addEventListener(Event.CHANGE,transformOffsetsChangedHandler); |
| if (was3D != is3D) |
| validateMatrix(); |
| |
| invalidateTransform(); |
| } |
| |
| /** |
| * @private |
| */ |
| private var _maintainProjectionCenter:Boolean = false; |
| |
| /** |
| * When true, the component keeps its projection matrix centered on the |
| * middle of its bounding box. If no projection matrix is defined on the |
| * component, one is added automatically. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function set maintainProjectionCenter(value:Boolean):void |
| { |
| _maintainProjectionCenter = value; |
| if (value && super.transform.perspectiveProjection == null) |
| { |
| super.transform.perspectiveProjection = new PerspectiveProjection(); |
| } |
| invalidateDisplayList(); |
| } |
| /** |
| * @private |
| */ |
| public function get maintainProjectionCenter():Boolean |
| { |
| return _maintainProjectionCenter; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function setLayoutMatrix(value:Matrix, invalidateLayout:Boolean):void |
| { |
| var previousMatrix:Matrix = _layoutFeatures ? |
| _layoutFeatures.layoutMatrix : super.transform.matrix; |
| |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| _hasComplexLayoutMatrix = true; |
| |
| if (_layoutFeatures == null) |
| { |
| // flash will make a copy of this on assignment. |
| super.transform.matrix = value; |
| } |
| else |
| { |
| // layout features will internally make a copy of this matrix rather than |
| // holding onto a reference to it. |
| _layoutFeatures.layoutMatrix = value; |
| invalidateTransform(); |
| } |
| |
| // Early exit if possible. We don't want to invalidate unnecessarily. |
| // We need to do the check here, after our new value has been applied |
| // because our matrix components are rounded upon being applied to a |
| // DisplayObject. |
| if (MatrixUtil.isEqual(previousMatrix, _layoutFeatures ? |
| _layoutFeatures.layoutMatrix : super.transform.matrix)) |
| { |
| return; |
| } |
| |
| invalidateProperties(); |
| |
| if (invalidateLayout) |
| invalidateParentSizeAndDisplayList(); |
| |
| if (was3D != is3D) |
| validateMatrix(); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function setLayoutMatrix3D(value:Matrix3D, invalidateLayout:Boolean):void |
| { |
| // Early exit if possible. We don't want to invalidate unnecessarily. |
| if (_layoutFeatures && MatrixUtil.isEqual3D(_layoutFeatures.layoutMatrix3D, value)) |
| return; |
| |
| // validateMatrix when switching between 2D/3D, works around player bug |
| // see sdk-23421 |
| var was3D:Boolean = is3D; |
| |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| // layout features will internally make a copy of this matrix rather than |
| // holding onto a reference to it. |
| _layoutFeatures.layoutMatrix3D = value; |
| invalidateTransform(); |
| |
| invalidateProperties(); |
| |
| if (invalidateLayout) |
| invalidateParentSizeAndDisplayList(); |
| |
| if (was3D != is3D) |
| validateMatrix(); |
| } |
| |
| /** |
| * @copy mx.core.ILayoutElement#transformAround() |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function transformAround(transformCenter:Vector3D, |
| scale:Vector3D = null, |
| rotation:Vector3D = null, |
| translation:Vector3D = null, |
| postLayoutScale:Vector3D = null, |
| postLayoutRotation:Vector3D = null, |
| postLayoutTranslation:Vector3D = null, |
| invalidateLayout:Boolean = true):void |
| { |
| // Make sure that no transform setters will trigger parent invalidation. |
| // Reset the flag at the end of the method. |
| var oldIncludeInLayout:Boolean; |
| if (!invalidateLayout) |
| { |
| oldIncludeInLayout = _includeInLayout; |
| _includeInLayout = false; |
| } |
| |
| var prevX:Number = x; |
| var prevY:Number = y; |
| var prevZ:Number = z; |
| |
| TransformUtil.transformAround(this, |
| transformCenter, |
| scale, |
| rotation, |
| translation, |
| postLayoutScale, |
| postLayoutRotation, |
| postLayoutTranslation, |
| _layoutFeatures, |
| internal_initAdvancedLayoutFeatures); |
| |
| if (_layoutFeatures != null) |
| { |
| invalidateTransform(); |
| |
| // Will not invalidate parent if we have set _includeInLayout to false |
| // in the beginning of the method |
| invalidateParentSizeAndDisplayList(); |
| |
| if (prevX != _layoutFeatures.layoutX) |
| dispatchEvent(new Event("xChanged")); |
| if (prevY != _layoutFeatures.layoutY) |
| dispatchEvent(new Event("yChanged")); |
| if (prevZ != _layoutFeatures.layoutZ) |
| dispatchEvent(new Event("zChanged")); |
| } |
| |
| if (!invalidateLayout) |
| _includeInLayout = oldIncludeInLayout; |
| } |
| |
| /** |
| * A utility method to transform a point specified in the local |
| * coordinates of this object to its location in the object's parent's |
| * coordinates. The pre-layout and post-layout result is set on |
| * the <code>position</code> and <code>postLayoutPosition</code> |
| * parameters, if they are non-null. |
| * |
| * @param localPosition The point to be transformed, specified in the |
| * local coordinates of the object. |
| * |
| * @param position A Vector3D point that holds the pre-layout |
| * result. If null, the parameter is ignored. |
| * |
| * @param postLayoutPosition A Vector3D point that holds the post-layout |
| * result. If null, the parameter is ignored. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function transformPointToParent(localPosition:Vector3D, |
| position:Vector3D, |
| postLayoutPosition:Vector3D):void |
| { |
| TransformUtil.transformPointToParent(this, |
| localPosition, |
| position, |
| postLayoutPosition, |
| _layoutFeatures); |
| } |
| |
| /** |
| * The transform matrix that is used to calculate a component's layout |
| * relative to its siblings. This matrix is defined by the component's |
| * 3D properties (which include the 2D properties such as <code>x</code>, |
| * <code>y</code>, <code>rotation</code>, <code>scaleX</code>, |
| * <code>scaleY</code>, <code>transformX</code>, and |
| * <code>transformY</code>, as well as <code>rotationX</code>, |
| * <code>rotationY</code>, <code>scaleZ</code>, <code>z</code>, and |
| * <code>transformZ</code>. |
| * |
| * <p>Most components do not have any 3D transform properties set on them.</p> |
| * |
| * <p>This layout matrix is combined with the values of the |
| * <code>postLayoutTransformOffsets</code> property to determine the |
| * component's final, computed matrix.</p> |
| * |
| * @see #postLayoutTransformOffsets |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function set layoutMatrix3D(value:Matrix3D):void |
| { |
| setLayoutMatrix3D(value, true /*invalidateLayout*/); |
| } |
| |
| //---------------------------------- |
| // depth |
| //---------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get depth():Number |
| { |
| return (_layoutFeatures == null) ? 0 : _layoutFeatures.depth; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set depth(value:Number):void |
| { |
| if (value == depth) |
| return; |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| |
| _layoutFeatures.depth = value; |
| if (parent is UIComponent) |
| UIComponent(parent).invalidateLayering(); |
| } |
| |
| /** |
| * Called by a component's items to indicate that their <code>depth</code> |
| * property has changed. Note that while this function is defined on |
| * <code>UIComponent</code>, it is up to subclasses to implement support |
| * for complex layering. |
| * |
| * By default, only <code>Group</code> and <code>DataGroup</code> support |
| * arbitrary layering of their children. |
| * |
| * @see #depth |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.4 |
| * @productversion Flex 4 |
| */ |
| public function invalidateLayering():void |
| { |
| } |
| |
| /** |
| * Commits the computed matrix built from the combination of the layout |
| * matrix and the transform offsets to the flash displayObject's transform. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| protected function applyComputedMatrix():void |
| { |
| _layoutFeatures.updatePending = false; |
| if (_layoutFeatures.is3D) |
| { |
| super.transform.matrix3D = _layoutFeatures.computedMatrix3D; |
| } |
| else |
| { |
| super.transform.matrix = _layoutFeatures.computedMatrix; |
| } |
| } |
| |
| mx_internal function get computedMatrix():Matrix |
| { |
| return (_layoutFeatures) ? _layoutFeatures.computedMatrix : transform.matrix; |
| } |
| |
| /** |
| * Specifies a transform stretch factor in the horizontal and vertical direction. |
| * The stretch factor is applied to the computed matrix before any other transformation. |
| * @param stretchX The horizontal component of the stretch factor. |
| * @param stretchY The vertical component of the stretch factor. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| protected function setStretchXY(stretchX:Number, stretchY:Number):void |
| { |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| if (stretchX != _layoutFeatures.stretchX || |
| stretchY != _layoutFeatures.stretchY) |
| { |
| _layoutFeatures.stretchX = stretchX; |
| _layoutFeatures.stretchY = stretchY; |
| invalidateTransform(); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| |
| //-------------------------------------------------------------------------- |
| // |
| // ILayoutElement |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getPreferredBoundsWidth(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getPreferredBoundsWidth(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getPreferredBoundsHeight(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getPreferredBoundsHeight(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getMinBoundsWidth(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getMinBoundsWidth(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getMinBoundsHeight(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getMinBoundsHeight(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getMaxBoundsWidth(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getMaxBoundsWidth(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getMaxBoundsHeight(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getMaxBoundsHeight(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getBoundsXAtSize(width:Number, height:Number, postLayoutTransform:Boolean = true):Number |
| { |
| return LayoutElementUIComponentUtils.getBoundsXAtSize(this, width, height, |
| postLayoutTransform ? nonDeltaLayoutMatrix() : null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getBoundsYAtSize(width:Number, height:Number, postLayoutTransform:Boolean = true):Number |
| { |
| return LayoutElementUIComponentUtils.getBoundsYAtSize(this, width, height, |
| postLayoutTransform ? nonDeltaLayoutMatrix() : null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getLayoutBoundsWidth(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getLayoutBoundsWidth(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getLayoutBoundsHeight(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getLayoutBoundsHeight(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getLayoutBoundsX(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getLayoutBoundsX(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getLayoutBoundsY(postLayoutTransform:Boolean=true):Number |
| { |
| return LayoutElementUIComponentUtils.getLayoutBoundsY(this,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function setLayoutBoundsPosition(x:Number, y:Number, postLayoutTransform:Boolean=true):void |
| { |
| LayoutElementUIComponentUtils.setLayoutBoundsPosition(this,x,y,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function setLayoutBoundsSize(width:Number, |
| height:Number, |
| postLayoutTransform:Boolean = true):void |
| { |
| LayoutElementUIComponentUtils.setLayoutBoundsSize(this,width,height,postLayoutTransform? nonDeltaLayoutMatrix():null); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getLayoutMatrix():Matrix |
| { |
| var superMatrix:Matrix = super.transform.matrix; |
| if (_layoutFeatures != null || superMatrix == null) |
| { |
| // TODO: this is a workaround for a situation in which the |
| // object is in 2D, but used to be in 3D and the player has not |
| // yet cleaned up the matrices. So the matrix property is null, but |
| // the matrix3D property is non-null. layoutFeatures can deal with |
| // that situation, so we allocate it here and let it handle it for |
| // us. The downside is that we have now allocated layoutFeatures |
| // forever and will continue to use it for future situations that |
| // might not have required it. Eventually, we should recognize |
| // situations when we can de-allocate layoutFeatures and back off |
| // to letting the player handle transforms for us. |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| |
| // esg: _layoutFeatures keeps a single internal copy of the layoutMatrix. |
| // since this is an internal class, we don't need to worry about developers |
| // accidentally messing with this matrix, _unless_ we hand it out. Instead, |
| // we hand out a clone. |
| return _layoutFeatures.layoutMatrix.clone(); |
| } |
| else |
| { |
| // flash also returns copies. |
| return superMatrix; |
| } |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get hasLayoutMatrix3D():Boolean |
| { |
| return _layoutFeatures ? _layoutFeatures.layoutIs3D : false; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get is3D():Boolean |
| { |
| return _layoutFeatures ? _layoutFeatures.is3D : false; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getLayoutMatrix3D():Matrix3D |
| { |
| if (_layoutFeatures == null) |
| initAdvancedLayoutFeatures(); |
| // esg: _layoutFeatures keeps a single internal copy of the layoutMatrix. |
| // since this is an internal class, we don't need to worry about developers |
| // accidentally messing with this matrix, _unless_ we hand it out. Instead, |
| // we hand out a clone. |
| return _layoutFeatures.layoutMatrix3D.clone(); |
| } |
| |
| /** |
| * @private |
| */ |
| protected function nonDeltaLayoutMatrix():Matrix |
| { |
| if (!hasComplexLayoutMatrix) |
| return null; |
| if (_layoutFeatures != null) |
| { |
| return _layoutFeatures.layoutMatrix; |
| } |
| else |
| { |
| return super.transform.matrix; |
| } |
| } |
| } |
| |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Helper class: MethodQueueElement |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| /** |
| * @private |
| * An element of the methodQueue array. |
| */ |
| class MethodQueueElement |
| { |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructor. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function MethodQueueElement(method:Function, |
| args:Array /* of Object */ = null) |
| { |
| super(); |
| |
| this.method = method; |
| this.args = args; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // method |
| //---------------------------------- |
| |
| /** |
| * A reference to the method to be called. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public var method:Function; |
| |
| //---------------------------------- |
| // args |
| //---------------------------------- |
| |
| /** |
| * The arguments to be passed to the method. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 9 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public var args:Array /* of Object */; |
| } |