| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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 spark.components |
| { |
| import mx.core.ContainerCreationPolicy; |
| import mx.core.IDeferredContentOwner; |
| import mx.core.IDeferredInstance; |
| import mx.core.IFlexModuleFactory; |
| import mx.core.IVisualElement; |
| import mx.core.IVisualElementContainer; |
| import mx.core.mx_internal; |
| import mx.events.FlexEvent; |
| import mx.utils.BitFlagUtil; |
| |
| import spark.components.supportClasses.SkinnableContainerBase; |
| import spark.events.ElementExistenceEvent; |
| import spark.layouts.supportClasses.LayoutBase; |
| |
| use namespace mx_internal; |
| |
| /** |
| * Dispatched after the content for this component has been created. With deferred |
| * instantiation, the content for a component may be created long after the |
| * component is created. |
| * |
| * @eventType mx.events.FlexEvent.CONTENT_CREATION_COMPLETE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="contentCreationComplete", type="mx.events.FlexEvent")] |
| |
| /** |
| * Dispatched when a visual element is added to the content holder. |
| * <code>event.element</code> is the visual element that was added. |
| * |
| * @eventType spark.events.ElementExistenceEvent.ELEMENT_ADD |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="elementAdd", type="spark.events.ElementExistenceEvent")] |
| |
| /** |
| * Dispatched when a visual element is removed from the content holder. |
| * <code>event.element</code> is the visual element that's being removed. |
| * |
| * @eventType spark.events.ElementExistenceEvent.ELEMENT_REMOVE |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Event(name="elementRemove", type="spark.events.ElementExistenceEvent")] |
| |
| include "../styles/metadata/BasicInheritingTextStyles.as" |
| include "../styles/metadata/AdvancedInheritingTextStyles.as" |
| include "../styles/metadata/SelectionFormatTextStyles.as" |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:accentColor |
| * |
| * @default #0099FF |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="accentColor", type="uint", format="Color", inherit="yes", theme="spark, mobile")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:alternatingItemColors |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="alternatingItemColors", type="Array", arrayType="uint", format="Color", inherit="yes", theme="spark, mobile")] |
| |
| /** |
| * Alpha level of the background for this component. |
| * Valid values range from 0.0 to 1.0. |
| * |
| * @default 1.0 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="backgroundAlpha", type="Number", inherit="no", theme="spark, mobile")] |
| |
| /** |
| * Background color of a component. |
| * |
| * @default 0xFFFFFF |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="backgroundColor", type="uint", format="Color", inherit="no", theme="spark, mobile")] |
| |
| /** |
| * The alpha of the content background for this component. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="contentBackgroundAlpha", type="Number", inherit="yes", theme="spark, mobile")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:contentBackgroundColor |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="contentBackgroundColor", type="uint", format="Color", inherit="yes", theme="spark, mobile")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:downColor |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10.1 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Style(name="downColor", type="uint", format="Color", inherit="yes", theme="mobile")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:focusColor |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="focusColor", type="uint", format="Color", inherit="yes", theme="spark, mobile")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:rollOverColor |
| * |
| * @default 0xCEDBEF |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="rollOverColor", type="uint", format="Color", inherit="yes", theme="spark")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:symbolColor |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="symbolColor", type="uint", format="Color", inherit="yes", theme="spark, mobile")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#style:touchDelay |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10.1 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| [Style(name="touchDelay", type="Number", format="Time", inherit="yes", minValue="0.0")] |
| |
| /** |
| * Color of text shadows. |
| * |
| * @default #FFFFFF |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="textShadowColor", type="uint", format="Color", inherit="yes", theme="mobile")] |
| |
| /** |
| * Alpha of text shadows. |
| * |
| * @default 0.55 |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| [Style(name="textShadowAlpha", type="Number",inherit="yes", minValue="0.0", maxValue="1.0", theme="mobile")] |
| |
| [IconFile("SkinnableContainer.png")] |
| |
| //-------------------------------------- |
| // Excluded APIs |
| //-------------------------------------- |
| |
| [DefaultProperty("mxmlContentFactory")] |
| |
| /** |
| * The SkinnableContainer class is the base class for skinnable containers that have |
| * visual content. |
| * The SkinnableContainer container takes as children any components that implement |
| * the IVisualElement interface. |
| * All Spark and Halo components implement the IVisualElement interface, as does |
| * the GraphicElement class. |
| * That means the container can use the graphics classes, such as Rect and Ellipse, as children. |
| * |
| * <p>To improve performance and minimize application size, |
| * you can use the Group container. The Group container cannot be skinned.</p> |
| * |
| * <p>The SkinnableContainer container has the following default characteristics:</p> |
| * <table class="innertable"> |
| * <tr><th>Characteristic</th><th>Description</th></tr> |
| * <tr><td>Default size</td><td>Large enough to display its children</td></tr> |
| * <tr><td>Minimum size</td><td>0 pixels</td></tr> |
| * <tr><td>Maximum size</td><td>10000 pixels wide and 10000 pixels high</td></tr> |
| * </table> |
| * |
| * @mxml |
| * |
| * <p>The <code><s:SkinnableContainer></code> tag inherits all of the tag |
| * attributes of its superclass and adds the following tag attributes:</p> |
| * |
| * <pre> |
| * <s:SkinnableContainer |
| * <strong>Properties</strong> |
| * autoLayout="true" |
| * creationPolicy="auto" |
| * layout="BasicLayout" |
| * |
| * <strong>Styles</strong> |
| * accentColor="0x0099FF" |
| * alignmentBaseline="useDominantBaseline" |
| * alternatingItemColors="" |
| * backgroundAlpha="1.0" |
| * backgroundColor="0xFFFFFF" |
| * baselineShift="0.0" |
| * blockProgression="TB" |
| * breakOpportunity="auto" |
| * cffHinting="horizontal_stem" |
| * clearFloats="none" |
| * color="0" |
| * contentBackgroundAlpha="" |
| * contentBackgroundColor="" |
| * digitCase="default" |
| * digitWidth="default" |
| * direction="LTR" |
| * dominantBaseline="auto" |
| * downColor="" |
| * firstBaselineOffset="auto" |
| * focusColor="" |
| * focusedTextSelectionColor="" |
| * fontFamily="Arial" |
| * fontLookup="device" |
| * fontSize="12" |
| * fontStyle="normal" |
| * fontWeight="normal" |
| * inactiveTextSelectionColor="0xE8E8E8" |
| * justificationRule="auto" |
| * justificationStyle="auto" |
| * kerning="auto" |
| * leadingModel="auto" |
| * ligatureLevel="common" |
| * lineHeight="120%" |
| * lineThrough="false" |
| * listAutoPadding="40" |
| * listStylePosition="outside" |
| * listStyleType="disc" |
| * locale="en" |
| * paragraphEndIndent="0" |
| * paragraphSpaceAfter="0" |
| * paragraphSpaceBefore="0" |
| * paragraphStartIndent="0" |
| * renderingMode="CFF" |
| * rollOverColor="" |
| * symbolColor="" |
| * tabStops="null" |
| * textAlign="start" |
| * textAlignLast="start" |
| * textAlpha="1" |
| * textDecoration="none" |
| * textIndent="0" |
| * textJustify="inter_word" |
| * textRotation="auto" |
| * trackingLeft="0" |
| * trackingRight="0" |
| * typographicCase="default" |
| * unfocusedTextSelectionColor="" |
| * verticalScrollPolicy="auto" |
| * whiteSpaceCollapse="collapse" |
| * wordSpacing="100%,50%,150%" |
| * |
| * <strong>Events</strong> |
| * elementAdd="<i>No default</i>" |
| * elementRemove="<i>No default</i>" |
| * /> |
| * </pre> |
| * |
| * @see SkinnableDataContainer |
| * @see Group |
| * @see spark.skins.spark.SkinnableContainerSkin |
| * |
| * @includeExample examples/SkinnableContainerExample.mxml |
| * @includeExample examples/MyBorderSkin.mxml -noswf |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public class SkinnableContainer extends SkinnableContainerBase |
| implements IDeferredContentOwner, IVisualElementContainer |
| { |
| include "../core/Version.as"; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Class constants |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| private static const AUTO_LAYOUT_PROPERTY_FLAG:uint = 1 << 0; |
| |
| /** |
| * @private |
| */ |
| private static const LAYOUT_PROPERTY_FLAG:uint = 1 << 1; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Constructor |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Constructor. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function SkinnableContainer() |
| { |
| super(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Skin Parts |
| // |
| //-------------------------------------------------------------------------- |
| |
| [Bindable] |
| [SkinPart(required="false")] |
| |
| /** |
| * An optional skin part that defines the Group where the content |
| * children get pushed into and laid out. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public var contentGroup:Group; |
| |
| /** |
| * @private |
| * Several properties are proxied to contentGroup. However, when contentGroup |
| * is not around, we need to store values set on SkinnableContainer. This object |
| * stores those values. If contentGroup is around, the values are stored |
| * on the contentGroup directly. However, we need to know what values |
| * have been set by the developer on the SkinnableContainer (versus set on |
| * the contentGroup or defaults of the contentGroup) as those are values |
| * we want to carry around if the contentGroup changes (via a new skin). |
| * In order to store this info effeciently, contentGroupProperties becomes |
| * a uint to store a series of BitFlags. These bits represent whether a |
| * property has been explicitely set on this SkinnableContainer. When the |
| * contentGroup is not around, contentGroupProperties is a typeless |
| * object to store these proxied properties. When contentGroup is around, |
| * contentGroupProperties stores booleans as to whether these properties |
| * have been explicitely set or not. |
| */ |
| private var contentGroupProperties:Object = {}; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden Properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // moduleFactory |
| //---------------------------------- |
| /** |
| * @private |
| */ |
| override public function set moduleFactory(moduleFactory:IFlexModuleFactory):void |
| { |
| super.moduleFactory = moduleFactory; |
| |
| // Register the _creationPolicy style as inheriting. See the creationPolicy |
| // getter for details on usage of this style. |
| styleManager.registerInheritingStyle("_creationPolicy"); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties |
| // |
| //-------------------------------------------------------------------------- |
| |
| // Used to hold the content until the contentGroup is created. |
| private var _placeHolderGroup:Group; |
| |
| mx_internal function get currentContentGroup():Group |
| { |
| createContentIfNeeded(); |
| |
| if (!contentGroup) |
| { |
| if (!_placeHolderGroup) |
| { |
| _placeHolderGroup = new Group(); |
| |
| if (_mxmlContent) |
| { |
| _placeHolderGroup.mxmlContent = _mxmlContent; |
| _mxmlContent = null; |
| } |
| |
| _placeHolderGroup.addEventListener( |
| ElementExistenceEvent.ELEMENT_ADD, contentGroup_elementAddedHandler); |
| _placeHolderGroup.addEventListener( |
| ElementExistenceEvent.ELEMENT_REMOVE, contentGroup_elementRemovedHandler); |
| } |
| return _placeHolderGroup; |
| } |
| else |
| { |
| return contentGroup; |
| } |
| } |
| |
| //---------------------------------- |
| // creationPolicy |
| //---------------------------------- |
| |
| // Internal flag used when creationPolicy="none". |
| // When set, the value of the backing store _creationPolicy |
| // style is "auto" so descendants inherit the correct value. |
| private var creationPolicyNone:Boolean = false; |
| |
| [Inspectable(enumeration="auto,all,none", defaultValue="auto")] |
| |
| /** |
| * @inheritDoc |
| * |
| * @default auto |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get creationPolicy():String |
| { |
| // Use an inheriting style as the backing storage for this property. |
| // This allows the property to be inherited by either mx or spark |
| // containers, and also to correctly cascade through containers that |
| // don't have this property (ie Group). |
| // This style is an implementation detail and should be considered |
| // private. Do not set it from CSS. |
| var result:String = getStyle("_creationPolicy"); |
| |
| if (result == null) |
| result = ContainerCreationPolicy.AUTO; |
| |
| if (creationPolicyNone) |
| result = ContainerCreationPolicy.NONE; |
| |
| return result; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set creationPolicy(value:String):void |
| { |
| if (value == ContainerCreationPolicy.NONE) |
| { |
| // creationPolicy of none is not inherited by descendants. |
| // In this case, set the style to "auto" and set a local |
| // flag for subsequent access to the creationPolicy property. |
| creationPolicyNone = true; |
| value = ContainerCreationPolicy.AUTO; |
| } |
| else |
| { |
| creationPolicyNone = false; |
| } |
| |
| setStyle("_creationPolicy", value); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Properties proxied to contentGroup |
| // |
| //-------------------------------------------------------------------------- |
| |
| //---------------------------------- |
| // autoLayout |
| //---------------------------------- |
| |
| [Inspectable(defaultValue="true")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#autoLayout |
| * |
| * @default true |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get autoLayout():Boolean |
| { |
| if (contentGroup) |
| return contentGroup.autoLayout; |
| else |
| { |
| // want the default to be true |
| var v:* = contentGroupProperties.autoLayout; |
| return (v === undefined) ? true : v; |
| } |
| } |
| |
| /** |
| * @private |
| */ |
| public function set autoLayout(value:Boolean):void |
| { |
| if (contentGroup) |
| { |
| contentGroup.autoLayout = value; |
| contentGroupProperties = BitFlagUtil.update(contentGroupProperties as uint, |
| AUTO_LAYOUT_PROPERTY_FLAG, true); |
| } |
| else |
| contentGroupProperties.autoLayout = value; |
| } |
| |
| //---------------------------------- |
| // layout |
| //---------------------------------- |
| |
| [Inspectable(category="General")] |
| |
| /** |
| * @copy spark.components.supportClasses.GroupBase#layout |
| * |
| * @default BasicLayout |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get layout():LayoutBase |
| { |
| return (contentGroup) |
| ? contentGroup.layout |
| : contentGroupProperties.layout; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set layout(value:LayoutBase):void |
| { |
| if (contentGroup) |
| { |
| contentGroup.layout = value; |
| contentGroupProperties = BitFlagUtil.update(contentGroupProperties as uint, |
| LAYOUT_PROPERTY_FLAG, true); |
| } |
| else |
| contentGroupProperties.layout = value; |
| |
| } |
| |
| //---------------------------------- |
| // mxmlContent |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Variable used to store the mxmlContent when the contentGroup is |
| * not around, and there hasnt' been a need yet for the placeHolderGroup. |
| */ |
| private var _mxmlContent:Array; |
| |
| /** |
| * @private |
| * Variable that represents whether the content has been explicitely set |
| * (via mxmlContent setter or with the mutation APIs, like addElement). |
| * This is used to figure out whether we should override the default "content" |
| * that is in the contentGroup of a skin. |
| */ |
| private var _contentModified:Boolean = false; |
| |
| [ArrayElementType("mx.core.IVisualElement")] |
| |
| /** |
| * @copy spark.components.Group#mxmlContent |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function set mxmlContent(value:Array):void |
| { |
| if (contentGroup) |
| contentGroup.mxmlContent = value; |
| else if (_placeHolderGroup) |
| _placeHolderGroup.mxmlContent = value; |
| else |
| _mxmlContent = value; |
| |
| if (value != null) |
| _contentModified = true; |
| } |
| |
| /** |
| * override setting of children |
| */ |
| override protected function addMXMLChildren(comps:Array):void |
| { |
| mxmlContent = comps; |
| } |
| |
| //---------------------------------- |
| // mxmlContentFactory |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Backing variable for the contentFactory property. |
| */ |
| private var _mxmlContentFactory:IDeferredInstance; |
| |
| /** |
| * @private |
| * Flag that indicates whether or not the content has been created. |
| */ |
| private var mxmlContentCreated:Boolean = false; |
| |
| [InstanceType("Array")] |
| [ArrayElementType("mx.core.IVisualElement")] |
| |
| /** |
| * A factory object that creates the initial value for the |
| * <code>content</code> property. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function set mxmlContentFactory(value:IDeferredInstance):void |
| { |
| if (value == _mxmlContentFactory) |
| return; |
| |
| _mxmlContentFactory = value; |
| mxmlContentCreated = false; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods proxied to contentGroup |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get numElements():int |
| { |
| return currentContentGroup.numElements; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getElementAt(index:int):IVisualElement |
| { |
| return currentContentGroup.getElementAt(index); |
| } |
| |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function getElementIndex(element:IVisualElement):int |
| { |
| return currentContentGroup.getElementIndex(element); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function addElement(element:IVisualElement):IVisualElement |
| { |
| _contentModified = true; |
| return currentContentGroup.addElement(element); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function addElementAt(element:IVisualElement, index:int):IVisualElement |
| { |
| _contentModified = true; |
| return currentContentGroup.addElementAt(element, index); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function removeElement(element:IVisualElement):IVisualElement |
| { |
| _contentModified = true; |
| return currentContentGroup.removeElement(element); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function removeElementAt(index:int):IVisualElement |
| { |
| _contentModified = true; |
| return currentContentGroup.removeElementAt(index); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function removeAllElements():void |
| { |
| _contentModified = true; |
| currentContentGroup.removeAllElements(); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 2.5 |
| * @productversion Flex 4.5 |
| */ |
| public function setElementIndex(element:IVisualElement, index:int):void |
| { |
| _contentModified = true; |
| currentContentGroup.setElementIndex(element, index); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function swapElements(element1:IVisualElement, element2:IVisualElement):void |
| { |
| _contentModified = true; |
| currentContentGroup.swapElements(element1, element2); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function swapElementsAt(index1:int, index2:int):void |
| { |
| _contentModified = true; |
| currentContentGroup.swapElementsAt(index1, index2); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| private var creatingDeferredContent:Boolean; |
| |
| override protected function generateMXMLInstances(document:Object, data:Array, recursive:Boolean = true):void |
| { |
| // don't generate children during super.createChildren |
| if (!creatingDeferredContent) |
| { |
| setMXMLDescriptor(data); |
| return; |
| } |
| |
| super.generateMXMLInstances(document, data, recursive); |
| } |
| |
| /** |
| * Create content children, if the <code>creationPolicy</code> property |
| * is not equal to <code>none</code>. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| override protected function createChildren():void |
| { |
| super.createChildren(); |
| |
| // TODO (rfrishbe): When navigator support is added, this is where we would |
| // determine if content should be created now, or wait until |
| // later. For now, we always create content here unless |
| // creationPolicy="none". |
| createContentIfNeeded(); |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| override protected function partAdded(partName:String, instance:Object):void |
| { |
| super.partAdded(partName, instance); |
| |
| if (instance == contentGroup) |
| { |
| if (_contentModified) |
| { |
| if (_placeHolderGroup != null) |
| { |
| var sourceContent:Array = _placeHolderGroup.getMXMLContent(); |
| |
| // TODO (rfrishbe): Also look at why we need a defensive copy for mxmlContent in Group, |
| // especially if we make it mx_internal. Also look at controlBarContent. |
| |
| // If a child element has been addElemented() to the placeHolderGroup, |
| // then it wouldn't been added to the display list and we can't just |
| // copy the mxmlContent from the placeHolderGroup, but we must also |
| // call removeElement() on those children. |
| |
| // remove listener prior to removal of elements |
| // or else we'll accidentally null out the owner field |
| _placeHolderGroup.removeEventListener( |
| ElementExistenceEvent.ELEMENT_REMOVE, contentGroup_elementRemovedHandler); |
| |
| for (var i:int = _placeHolderGroup.numElements; i > 0; i--) |
| { |
| _placeHolderGroup.removeElementAt(0); |
| } |
| |
| contentGroup.mxmlContent = sourceContent ? sourceContent.slice() : null; |
| |
| } |
| else if (_mxmlContent != null) |
| { |
| contentGroup.mxmlContent = _mxmlContent; |
| _mxmlContent = null; |
| } |
| } |
| |
| // copy proxied values from contentGroupProperties (if set) to contentGroup |
| |
| var newContentGroupProperties:uint = 0; |
| |
| if (contentGroupProperties.autoLayout !== undefined) |
| { |
| contentGroup.autoLayout = contentGroupProperties.autoLayout; |
| newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties, |
| AUTO_LAYOUT_PROPERTY_FLAG, true); |
| } |
| |
| if (contentGroupProperties.layout !== undefined) |
| { |
| contentGroup.layout = contentGroupProperties.layout; |
| newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties, |
| LAYOUT_PROPERTY_FLAG, true); |
| } |
| |
| contentGroupProperties = newContentGroupProperties; |
| |
| contentGroup.addEventListener( |
| ElementExistenceEvent.ELEMENT_ADD, contentGroup_elementAddedHandler); |
| contentGroup.addEventListener( |
| ElementExistenceEvent.ELEMENT_REMOVE, contentGroup_elementRemovedHandler); |
| |
| if (_placeHolderGroup) |
| { |
| _placeHolderGroup.removeEventListener( |
| ElementExistenceEvent.ELEMENT_ADD, contentGroup_elementAddedHandler); |
| _placeHolderGroup.removeEventListener( |
| ElementExistenceEvent.ELEMENT_REMOVE, contentGroup_elementRemovedHandler); |
| |
| _placeHolderGroup = null; |
| } |
| } |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| override protected function partRemoved(partName:String, instance:Object):void |
| { |
| super.partRemoved(partName, instance); |
| |
| if (instance == contentGroup) |
| { |
| contentGroup.removeEventListener( |
| ElementExistenceEvent.ELEMENT_ADD, contentGroup_elementAddedHandler); |
| contentGroup.removeEventListener( |
| ElementExistenceEvent.ELEMENT_REMOVE, contentGroup_elementRemovedHandler); |
| |
| // copy proxied values from contentGroup (if explicitely set) to contentGroupProperties |
| |
| var newContentGroupProperties:Object = {}; |
| |
| if (BitFlagUtil.isSet(contentGroupProperties as uint, AUTO_LAYOUT_PROPERTY_FLAG)) |
| newContentGroupProperties.autoLayout = contentGroup.autoLayout; |
| |
| if (BitFlagUtil.isSet(contentGroupProperties as uint, LAYOUT_PROPERTY_FLAG)) |
| newContentGroupProperties.layout = contentGroup.layout; |
| |
| contentGroupProperties = newContentGroupProperties; |
| |
| var myMxmlContent:Array = contentGroup.getMXMLContent(); |
| |
| if (_contentModified && myMxmlContent) |
| { |
| _placeHolderGroup = new Group(); |
| |
| _placeHolderGroup.mxmlContent = myMxmlContent; |
| |
| _placeHolderGroup.addEventListener( |
| ElementExistenceEvent.ELEMENT_ADD, contentGroup_elementAddedHandler); |
| _placeHolderGroup.addEventListener( |
| ElementExistenceEvent.ELEMENT_REMOVE, contentGroup_elementRemovedHandler); |
| } |
| |
| contentGroup.mxmlContent = null; |
| contentGroup.layout = null; |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // IDeferredContentOwner methods |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * Create the content for this component. |
| * When the <code>creationPolicy</code> property is <code>auto</code> or |
| * <code>all</code>, this function is called automatically by the Flex framework. |
| * When <code>creationPolicy</code> is <code>none</code>, you call this method to initialize |
| * the content. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function createDeferredContent():void |
| { |
| var children:Array = this.MXMLDescriptor; |
| if (children) |
| { |
| creatingDeferredContent = true; |
| generateMXMLInstances(document, children); |
| creatingDeferredContent = false; |
| mxmlContentCreated = true; // keep the code from recursing back into here. |
| _deferredContentCreated = true; |
| dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE)); |
| return; |
| } |
| |
| if (!mxmlContentCreated) |
| { |
| mxmlContentCreated = true; |
| |
| if (_mxmlContentFactory) |
| { |
| var deferredContent:Object = _mxmlContentFactory.getInstance(); |
| mxmlContent = deferredContent as Array; |
| _deferredContentCreated = true; |
| dispatchEvent(new FlexEvent(FlexEvent.CONTENT_CREATION_COMPLETE)); |
| } |
| } |
| } |
| |
| private var _deferredContentCreated:Boolean; |
| |
| /** |
| * Contains <code>true</code> if deferred content has been created. |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function get deferredContentCreated():Boolean |
| { |
| return _deferredContentCreated; |
| } |
| |
| /** |
| * @private |
| */ |
| private function createContentIfNeeded():void |
| { |
| if (!mxmlContentCreated && creationPolicy != ContainerCreationPolicy.NONE) |
| createDeferredContent(); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event Handlers |
| // |
| //-------------------------------------------------------------------------- |
| |
| private function contentGroup_elementAddedHandler(event:ElementExistenceEvent):void |
| { |
| event.element.owner = this |
| |
| // Re-dispatch the event |
| dispatchEvent(event); |
| } |
| |
| private function contentGroup_elementRemovedHandler(event:ElementExistenceEvent):void |
| { |
| event.element.owner = null; |
| |
| // Re-dispatch the event |
| dispatchEvent(event); |
| } |
| } |
| |
| } |