Transferred from the Adobe Open Source Subversion Repository

Revision: 18173
Author:   jasonsj@adobe.com
Date:     2010-10-15T17:03:20.801634Z

Log Message:
-----------
Mobile Theme Initial check-in

* New light-look visuals from XD
* Changed airmobile-config.xml to use standalone Mobile theme instead of Spark overlay
* Added theme="spark, mobile" where spark was already white-listed and support is implemented and/or planned for Mobile/spark.css (see https://zerowing.corp.adobe.com/display/flexmobile/Mobile+Theme+Styles+Spec)
* MobileSkin has symbolColor and chromeColor support. Override beginChromeColorFill and drawChromeColor when defining custom chromeColor visuals.
* CheckBox and RadioButton now have chromeColor and symbolColor support
* Added textShadowColor and textShadowAlpha support to Button and ActionBar
* Added chromeColor support to HScrollBar and VScrollBar

QE notes: All mobile skins have been updaetd.
Doc notes: Update mobile skinning documentation for new APIs
Bugs:
SDK-28043 Investigate usage of "viewWidth", "viewHeight" for the Flex Mobile Skin Assets
SDK-27609 Mobile scroll bar skins should use chromeColor
SDK-27646 cornerradius has no effect on button in mobile application
Reviewer: gruehle
Tests run: checkintests
Is noteworthy for integration: Yes

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/VScrollBarTrackSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/MobileSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/defaults.css</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ActionBarSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Button.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/styles/metadata/BorderStyles.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/CheckBox_symbol.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ActionButtonSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Image.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/SkinnableComponent.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/RadioButton_symbol.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/Button_up.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/styles/metadata/ContainerBackgroundStyles.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/CheckBox.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Group.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobilecomponents/src/spark/components/ActionBar.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/CheckBox_up.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/ButtonBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/SkinnableTextBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ActionBarButtonSkinBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/HScrollBarThumbSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/SkinnableDataContainer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/RadioButton_up.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/TextInput_border.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/SliderBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/ButtonSkinBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/Button_down.fxg</path>
<path kind="file" action="D">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/CheckBox_upSelected.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/SkinnableContainer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/List.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/skins/spark/DefaultItemRenderer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/TextInputSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/RadioButton_upSelected.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/VScrollBarThumbSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GroupBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/CheckBox_down.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ButtonSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/TextAreaSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Scroller.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/ViewMenuItemSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/RadioButton_down.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/HScrollBarTrackSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/controls/ToolTip.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/RadioButton.as</path>
<path kind="file" action="D">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/CheckBox_downSelected.fxg</path>
<path kind="file" action="D">/private/flex/sdk/branches/hero_private/frameworks/themes/Mobile/spark.css</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/SelectableButtonSkinBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/airmobile-config.xml</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/CheckBoxSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/assets/RadioButton_downSelected.fxg</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/RadioButtonSkin.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/mobiletheme/src/spark/skins/mobile/NavigationButtonSkin.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1265861 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/ButtonSkinBase.as
+++ frameworks/projects/mobiletheme/src/spark/skins/mobile/supportClasses/ButtonSkinBase.as
@@ -11,545 +11,565 @@

 package spark.skins.mobile.supportClasses
 {
-
-    import flash.display.DisplayObject;
-    import flash.display.GradientType;
-    import flash.events.Event;
-    import flash.events.EventDispatcher;
-    import flash.geom.Matrix;
-    import flash.text.TextField;
-    import flash.text.TextFormat;
-    import flash.text.TextFormatAlign;
-    import flash.text.TextLineMetrics;
-
-    import mx.core.IFlexDisplayObject;
-    import mx.core.ILayoutElement;
-    import mx.core.IUITextField;
-    import mx.core.UITextField;
-    import mx.core.mx_internal;
-    import mx.events.FlexEvent;
-    import mx.managers.LayoutManager;
-    import mx.states.SetProperty;
-    import mx.states.State;
-    import mx.utils.ColorUtil;
-
-    import spark.components.Group;
-    import spark.components.IconPlacement;
-    import spark.components.supportClasses.ButtonBase;
-    import spark.components.supportClasses.StyleableTextField;
-    import spark.primitives.BitmapImage;
-    import spark.skins.mobile.supportClasses.MobileSkin;
-
-    use namespace mx_internal;
-
-    /*
-    ISSUES:
-    - should we support textAlign (if not, remove extra code)
-    */
-    /**
-     *  Actionscript based skin for mobile applications. The skin supports
-     *  icon and iconPlacement. It uses a couple of FXG classes to
-     *  implement the vector drawing.
+
+import flash.display.DisplayObject;
+import flash.display.GradientType;
+import flash.display.Graphics;
+import flash.events.Event;
+import flash.events.EventDispatcher;
+import flash.geom.Matrix;
+import flash.text.TextField;
+import flash.text.TextFormat;
+import flash.text.TextFormatAlign;
+import flash.text.TextLineMetrics;
+
+import mx.core.IFlexDisplayObject;
+import mx.core.ILayoutElement;
+import mx.core.IUITextField;
+import mx.core.UITextField;
+import mx.core.mx_internal;
+import mx.events.FlexEvent;
+import mx.managers.LayoutManager;
+import mx.states.SetProperty;
+import mx.states.State;
+import mx.utils.ColorUtil;
+
+import spark.components.Group;
+import spark.components.IconPlacement;
+import spark.components.supportClasses.ButtonBase;
+import spark.components.supportClasses.StyleableTextField;
+import spark.primitives.BitmapImage;
+import spark.skins.mobile.supportClasses.MobileSkin;
+
+use namespace mx_internal;
+
+/*
+ISSUES:
+- should we support textAlign (if not, remove extra code)
+*/
+/**
+ *  Actionscript based skin for mobile applications. The skin supports
+ *  icon and iconPlacement. It uses a couple of FXG classes to
+ *  implement the vector drawing.
+ *
+ *  @langversion 3.0
+ *  @playerversion Flash 10
+ *  @playerversion AIR 2.5
+ *  @productversion Flex 4.5
+ */
+public class ButtonSkinBase extends MobileSkin
+{
+    //--------------------------------------------------------------------------
+    //
+    //  Class statics
+    //
+    //--------------------------------------------------------------------------
+
+    private static var TEXT_WIDTH_PADDING:Number = UITextField.TEXT_WIDTH_PADDING + 1;
+    private static var MIN_WIDTH:Number = 48;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    //--------------------------------------------------------------------------
+
+    public function ButtonSkinBase()
+    {
+        super();
+
+        setStyle("textAlign", "center");
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  iconDisplay skin part.
+     */
+    private var iconChanged:Boolean = false;
+    private var iconInstance:Object;    // Can be either DisplayObject or BitmapImage
+    private var iconHolder:Group;       // Needed when iconInstance is a BitmapImage
+    private var _icon:Object;           // The currently set icon, can be Class, DisplayObject, URL
+
+    /**
+     *  labelDisplay skin part.
+     */
+    public var labelDisplay:StyleableTextField;
+
+    protected var labelDisplayShadow:StyleableTextField;
+
+    /**
+     *  If true, then create the iconDisplay using the icon style
      *
-     *  @langversion 3.0
-     *  @playerversion Flash 10
-     *  @playerversion AIR 2.5
-     *  @productversion Flex 4.5
-     */
-    public class ButtonSkinBase extends MobileSkin
-    {
-
-        //--------------------------------------------------------------------------
-        //
-        //  Constructor
-        //
-        //--------------------------------------------------------------------------
-
-        public function ButtonSkinBase()
-        {
-            super();
-
-            setStyle("textAlign", "center");
-            // TODO (jszeto) Ask XD if shadow color is dependant upon text color
-            setStyle("textShadowColor", 0x000000);
-        }
-
-        //--------------------------------------------------------------------------
-        //
-        //  Variables
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  iconDisplay skin part.
-         */
-        private var iconChanged:Boolean = false;
-        private var iconInstance:Object;    // Can be either DisplayObject or BitmapImage
-        private var iconHolder:Group;       // Needed when iconInstance is a BitmapImage
-        private var _icon:Object;           // The currently set icon, can be Class, DisplayObject, URL
-
-        /**
-         *  labelDisplay skin part.
-         */
-        public var labelDisplay:StyleableTextField;
-
-        protected var labelDisplayShadow:StyleableTextField;
-
-        /**
-         *  If true, then create the iconDisplay using the icon style
-         *
-         *  @default true
-         */
-        protected var useIconStyle:Boolean = true;
-
-        // TODO (jszeto) Either static consts or styles
-        protected var gap:int = 7;
-        protected var paddingLeft:int = 20;
-        protected var paddingRight:int = 20;
-        protected var paddingTop:int = 20;
-        protected var paddingBottom:int = 20;
-
-        private static var TEXT_WIDTH_PADDING:Number = UITextField.TEXT_WIDTH_PADDING + 1;
-        private static var MIN_WIDTH:Number = 48;
-
-        //--------------------------------------------------------------------------
-        //
-        //  Overridden properties
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         * @copy spark.skins.spark.ApplicationSkin#hostComponent
-         */
-        public var hostComponent:ButtonBase; // SkinnableComponent will popuplate
-
-        //--------------------------------------------------------------------------
-        //
-        //  Overridden methods
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  @private
-         */
-        override protected function commitCurrentState():void
-        {
-            super.commitCurrentState();
-
-            alpha = currentState.indexOf("disabled") == -1 ? 1 : 0.5;
-        }
-
-        /**
-         *  @private
-         */
-        override protected function createChildren():void
-        {
-            labelDisplay = StyleableTextField(createInFontContext(StyleableTextField));
-            labelDisplay.styleProvider = this;
-            labelDisplay.addEventListener(FlexEvent.VALUE_COMMIT, labelDisplay_valueCommitHandler);
-
-            labelDisplayShadow = StyleableTextField(createInFontContext(StyleableTextField));
-            labelDisplayShadow.styleProvider = this;
-
-            labelDisplayShadow.colorName = "textShadowColor";
-            labelDisplayShadow.alpha = .30;
-
-            addChild(labelDisplayShadow);
-            addChild(labelDisplay);
-        }
-
-        /**
-         *  @private
-         */
-        override public function styleChanged(styleProp:String):void
-        {
-            var allStyles:Boolean = !styleProp || styleProp == "styleName";
-
-            if (allStyles || styleProp == "iconPlacement")
-            {
-                invalidateSize();
-                invalidateDisplayList();
-            }
-
-            if (useIconStyle && (allStyles || styleProp == "icon"))
-            {
-                iconChanged = true;
-                invalidateProperties();
-            }
-
-            super.styleChanged(styleProp);
-
-            if (labelDisplay)
-                labelDisplay.styleChanged(styleProp);
-            if (labelDisplayShadow)
-                labelDisplayShadow.styleChanged(styleProp);
-        }
-
-        /**
-         *  @private
-         */
-        override protected function commitProperties():void
-        {
-            super.commitProperties();
-
-            if (iconChanged)
-            {
-                iconChanged = false;
-                if (useIconStyle)
-                    setIcon(getStyle("icon"));
-            }
-        }
-
-        /**
-         *  @private
-         */
-        override protected function measure():void
-        {
-            super.measure();
-
-            var iconPlacement:String = getStyle("iconPlacement");
-
-            var textWidth:Number = 0;
-            var textHeight:Number = 0;
-            var lineMetrics:TextLineMetrics;
-
-            if (hostComponent && hostComponent.label != "")
-            {
-                // FIXME (rfrishbe): rather than use lineMetrics, we should be using labelDisplay.textWidth.
-                // We need to change it here and in multiple places
-                lineMetrics = measureText(hostComponent.label);
-                textWidth = lineMetrics.width + TEXT_WIDTH_PADDING;
-                textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
-            }
-            else
-            {
-                lineMetrics = measureText("Wj");
-                textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
-            }
-
-            var iconDisplay:DisplayObject = getIconDisplay();
-            var iconWidth:Number = iconDisplay ? iconDisplay.width : 0;
-            var iconHeight:Number = iconDisplay ? iconDisplay.height : 0;
-            var w:Number = 0;
-            var h:Number = 0;
-
-            if (iconDisplay is ILayoutElement)
-            {
-                iconWidth = ILayoutElement(iconDisplay).getPreferredBoundsWidth(false);
-                iconHeight = ILayoutElement(iconDisplay).getPreferredBoundsHeight(false);
-            }
-
-            if (iconPlacement == IconPlacement.LEFT ||
-                iconPlacement == IconPlacement.RIGHT)
-            {
-                w = textWidth + iconWidth;
-                if (textWidth && iconWidth)
-                    w += gap; //getStyle("horizontalGap");
-                h = Math.max(textHeight, iconHeight);
-            }
-            else
-            {
-                w = Math.max(textWidth, iconWidth);
-                h = textHeight + iconHeight;
-                if (textHeight && iconHeight)
-                    h += gap; // getStyle("verticalGap");
-            }
-
-            w += paddingLeft + paddingRight; //getStyle("paddingLeft") + getStyle("paddingRight");
-            h += paddingTop + paddingBottom; //getStyle("paddingTop") + getStyle("paddingBottom");
-
-            measuredWidth = Math.max(w, MIN_WIDTH);
-            measuredMinHeight = measuredHeight = h;
-            measuredMinWidth = iconWidth + paddingLeft + paddingRight;
-        }
-
-        /**
-         *  @private
-         */
-        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
-        {
-            super.updateDisplayList(unscaledWidth, unscaledHeight);
-
-            var labelWidth:Number = 0;
-            var labelHeight:Number = 0;
-
-            var labelX:Number = 0;
-            var labelY:Number = 0;
-
-            var iconWidth:Number = 0;
-            var iconHeight:Number = 0;
-
-            var iconX:Number = 0;
-            var iconY:Number = 0;
-
-            var horizontalGap:Number = 0;
-            var verticalGap:Number = 0;
-
-            var iconPlacement:String = getStyle("iconPlacement");
-
-            var textWidth:Number = 0;
-            var textHeight:Number = 0;
-
-            var lineMetrics:TextLineMetrics;
-
-            if (hostComponent && hostComponent.label != "")
-            {
-                lineMetrics = measureText(hostComponent.label);
-                textWidth = lineMetrics.width + TEXT_WIDTH_PADDING;
-                textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
-            }
-            else
-            {
-                lineMetrics = measureText("Wj");
-                textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
-            }
-
-            var textAlign:String = "center"; // getStyle("textAlign");
-            // Map new Spark values that might be set in a selector
-            // affecting both Halo and Spark components.
-            /*if (textAlign == "start")
-                textAlign = TextFormatAlign.LEFT;
-            else if (textAlign == "end")
-                textAlign = TextFormatAlign.RIGHT;*/
-
-            var viewWidth:Number = unscaledWidth;
-            var viewHeight:Number = unscaledHeight;
-
-            var iconDisplay:DisplayObject = getIconDisplay();
-            if (iconDisplay)
-            {
-                if (iconDisplay is ILayoutElement)
-                {
-                    iconWidth = ILayoutElement(iconDisplay).getPreferredBoundsWidth();
-                    iconHeight = ILayoutElement(iconDisplay).getPreferredBoundsHeight();
-                }
-                else
-                {
-                    iconWidth = iconDisplay.width;
-                    iconHeight = iconDisplay.height;
-                }
-            }
-
-            if (iconPlacement == IconPlacement.LEFT ||
-                iconPlacement == IconPlacement.RIGHT)
-            {
-                horizontalGap = gap;
-
-                if (iconWidth == 0 || textWidth == 0)
-                    horizontalGap = 0;
-
-                if (textWidth > 0)
-                {
-                    labelWidth =
-                        Math.max(Math.min(viewWidth - iconWidth - horizontalGap -
-                            paddingLeft - paddingRight, textWidth), 0);
-                }
-                else
-                {
-                    labelWidth = 0;
-                }
-                labelHeight = Math.min(viewHeight, textHeight);
-
-                if (textAlign == "left")
-                {
-                    labelX += paddingLeft;
-                }
-                else if (textAlign == "right")
-                {
-                    labelX += (viewWidth - labelWidth - iconWidth -
-                        horizontalGap - paddingRight);
-                }
-                else // "center" -- default value
-                {
-                    labelX += ((viewWidth - labelWidth - iconWidth -
-                        horizontalGap - paddingLeft - paddingRight) / 2) + paddingLeft;
-                }
-
-                if (iconPlacement == IconPlacement.LEFT)
-                {
-                    labelX += iconWidth + horizontalGap;
-                    iconX = labelX - (iconWidth + horizontalGap);
-                }
-                else
-                {
-                    iconX  = labelX + labelWidth + horizontalGap;
-                }
-
-                iconY  = ((viewHeight - iconHeight - paddingTop - paddingBottom) / 2) + paddingTop;
-                labelY = ((viewHeight - labelHeight - paddingTop - paddingBottom) / 2) + paddingTop;
-            }
-            else
-            {
-                verticalGap = gap;
-
-                if (iconHeight == 0 || !hostComponent || hostComponent.label == "")
-                    verticalGap = 0;
-
-                if (textWidth > 0)
-                {
-                    labelWidth = Math.max(viewWidth - paddingLeft - paddingRight, 0);
-                    labelHeight =
-                        Math.min(viewHeight - iconHeight - paddingTop - paddingBottom - verticalGap, textHeight);
-                }
-                else
-                {
-                    labelWidth = 0;
-                    labelHeight = 0;
-                }
-
-                labelX = paddingLeft;
-
-                if (textAlign == "left")
-                {
-                    iconX += paddingLeft;
-                }
-                else if (textAlign == "right")
-                {
-                    iconX += Math.max(viewWidth - iconWidth - paddingRight, paddingLeft);
-                }
-                else
-                {
-                    iconX += ((viewWidth - iconWidth - paddingLeft - paddingRight) / 2) + paddingLeft;
-                }
-
-                if (iconPlacement == IconPlacement.BOTTOM)
-                {
-                    labelY += ((viewHeight - labelHeight - iconHeight -
-                        paddingTop - paddingBottom - verticalGap) / 2) + paddingTop;
-                    iconY += labelY + labelHeight + verticalGap;
-                }
-                else
-                {
-                    iconY += ((viewHeight - labelHeight - iconHeight -
-                        paddingTop - paddingBottom - verticalGap) / 2) + paddingTop;
-                    labelY += iconY + iconHeight + verticalGap;
-                }
-            }
-
-            labelDisplay.commitStyles();
-            resizePart(labelDisplay, labelWidth, labelHeight);
-            positionPart(labelDisplay, Math.max(0, Math.round(labelX)), Math.max(0, Math.round(labelY)));
-
-            // before truncating text, we need to reset it to its original value
-            if (hostComponent && labelDisplay.isTruncated)
-                labelDisplay.text = hostComponent.label;
-
-            if (textWidth > labelWidth)
-            {
-                labelDisplay.truncateToFit();
-            }
-
-            labelDisplayShadow.commitStyles();
-            resizePart(labelDisplayShadow, labelWidth, labelHeight);
-            positionPart(labelDisplayShadow, Math.max(0, Math.round(labelX)), Math.max(0, Math.round(labelY + 1)));
-
-            // if labelDisplay is truncated, then push it down here as well.
-            // otherwise, it would have gotten pushed in the labelDisplay_valueCommitHandler()
-            if (labelDisplay.isTruncated)
-                labelDisplayShadow.text = labelDisplay.text;
-
-            if (iconDisplay)
-            {
-                resizePart(iconDisplay, iconWidth, iconHeight);
-                positionPart(iconDisplay, Math.max(0, Math.round(iconX)), Math.max(0, Math.round(iconY)));
-            }
-        }
-
-        //--------------------------------------------------------------------------
-        //
-        //  Class methods
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  The current skin part that displays the icon.
-         *  If the icon is a Class, then the iconDisplay is an instance of that class.
-         *  If the icon is a DisplayObject instance, then the iconDisplay is that instance.
-         *  If the icon is URL, then iconDisplay is the Group that holds the BitmapImage with that URL.
-         *
-         *  @see #setIcon
-         *  @see #useIconStyle
-         */
-        protected function getIconDisplay():DisplayObject
-        {
-            return iconHolder ? iconHolder : iconInstance as DisplayObject;
-        }
-
-        /**
-         *  Sets the current icon for the iconDisplay skin part.
-         *  The iconDisplay skin part is created/set-up on demand.
-         *
-         *  @see #getIconDisplay
-         *  @see #useIconStyle
-         */
-        protected function setIcon(icon:Object):void
-        {
-            if (_icon == icon)
-                return;
-            _icon = icon;
-
-            // Clean-up the iconInstance
-            if (iconInstance)
-            {
-                if (iconHolder)
-                    iconHolder.removeAllElements();
-                else
-                    this.removeChild(iconInstance as DisplayObject);
-            }
-            iconInstance = null;
-
-            // Set-up the iconHolder
-            var needsHolder:Boolean = icon && !(icon is Class) && !(icon is DisplayObject);
-            if (needsHolder && !iconHolder)
-            {
-                iconHolder = new Group();
-                this.addChild(iconHolder);
-            }
-            else if (!needsHolder && iconHolder)
-            {
-                this.removeChild(iconHolder);
-                iconHolder = null;
-            }
-
-            // Set-up the icon
-            if (icon)
-            {
-                if (needsHolder)
-                {
-                    iconInstance = new BitmapImage();
-                    iconInstance.source = icon;
-                    iconHolder.addElement(iconInstance as BitmapImage);
-                }
-                else
-                {
-                    if (icon is Class)
-                        iconInstance = new (Class(icon))();
-                    else
-                        iconInstance = icon;
-
-                    addChild(iconInstance as DisplayObject);
-                }
-            }
-
-            // explicitly invalidate, since addChild/removeChild don't invalidate for us
+     *  @default true
+     */
+    protected var useIconStyle:Boolean = true;
+
+    // TODO (jszeto) Either static consts or styles
+    protected var gap:int = 7;
+    protected var paddingLeft:int = 20;
+    protected var paddingRight:int = 20;
+    protected var paddingTop:int = 20;
+    protected var paddingBottom:int = 20;
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden properties
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     * @copy spark.skins.spark.ApplicationSkin#hostComponent
+     */
+    public var hostComponent:ButtonBase; // SkinnableComponent will popuplate
+
+    //--------------------------------------------------------------------------
+    //
+    //  Overridden methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    override protected function commitCurrentState():void
+    {
+        super.commitCurrentState();
+
+        alpha = currentState.indexOf("disabled") == -1 ? 1 : 0.5;
+    }
+
+    /**
+     *  @private
+     */
+    override protected function createChildren():void
+    {
+        labelDisplay = StyleableTextField(createInFontContext(StyleableTextField));
+        labelDisplay.styleProvider = this;
+        labelDisplay.addEventListener(FlexEvent.VALUE_COMMIT, labelDisplay_valueCommitHandler);
+
+        labelDisplayShadow = StyleableTextField(createInFontContext(StyleableTextField));
+        labelDisplayShadow.styleProvider = this;
+
+        labelDisplayShadow.colorName = "textShadowColor";
+
+        addChild(labelDisplayShadow);
+        addChild(labelDisplay);
+    }
+
+    /**
+     *  @private
+     */
+    override public function styleChanged(styleProp:String):void
+    {
+        var allStyles:Boolean = !styleProp || styleProp == "styleName";
+
+        if (allStyles || styleProp == "iconPlacement")
+        {
             invalidateSize();
             invalidateDisplayList();
         }
-
-        //--------------------------------------------------------------------------
-        //
-        //  Event Handlers
-        //
-        //--------------------------------------------------------------------------
-
-        /**
-         *  @private
-         */
-        private function labelDisplay_valueCommitHandler(event:FlexEvent):void
-        {
+
+        if (useIconStyle && (allStyles || styleProp == "icon"))
+        {
+            iconChanged = true;
+            invalidateProperties();
+        }
+
+        if (styleProp == "textShadowAlpha")
+        {
+            invalidateDisplayList();
+        }
+
+        super.styleChanged(styleProp);
+
+        if (labelDisplay)
+            labelDisplay.styleChanged(styleProp);
+        if (labelDisplayShadow)
+            labelDisplayShadow.styleChanged(styleProp);
+    }
+
+    /**
+     *  @private
+     */
+    override protected function commitProperties():void
+    {
+        super.commitProperties();
+
+        if (iconChanged)
+        {
+            iconChanged = false;
+            if (useIconStyle)
+                setIcon(getStyle("icon"));
+        }
+    }
+
+    /**
+     *  @private
+     */
+    override protected function measure():void
+    {
+        super.measure();
+
+        var iconPlacement:String = getStyle("iconPlacement");
+
+        var textWidth:Number = 0;
+        var textHeight:Number = 0;
+        var lineMetrics:TextLineMetrics;
+
+        if (hostComponent && hostComponent.label != "")
+        {
+            // FIXME (rfrishbe): rather than use lineMetrics, we should be using labelDisplay.textWidth.
+            // We need to change it here and in multiple places
+            lineMetrics = measureText(hostComponent.label);
+            textWidth = lineMetrics.width + TEXT_WIDTH_PADDING;
+            textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
+        }
+        else
+        {
+            lineMetrics = measureText("Wj");
+            textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
+        }
+
+        var iconDisplay:DisplayObject = getIconDisplay();
+        var iconWidth:Number = iconDisplay ? iconDisplay.width : 0;
+        var iconHeight:Number = iconDisplay ? iconDisplay.height : 0;
+        var w:Number = 0;
+        var h:Number = 0;
+
+        if (iconDisplay is ILayoutElement)
+        {
+            iconWidth = ILayoutElement(iconDisplay).getPreferredBoundsWidth(false);
+            iconHeight = ILayoutElement(iconDisplay).getPreferredBoundsHeight(false);
+        }
+
+        if (iconPlacement == IconPlacement.LEFT ||
+            iconPlacement == IconPlacement.RIGHT)
+        {
+            w = textWidth + iconWidth;
+            if (textWidth && iconWidth)
+                w += gap; //getStyle("horizontalGap");
+            h = Math.max(textHeight, iconHeight);
+        }
+        else
+        {
+            w = Math.max(textWidth, iconWidth);
+            h = textHeight + iconHeight;
+            if (textHeight && iconHeight)
+                h += gap; // getStyle("verticalGap");
+        }
+
+        w += paddingLeft + paddingRight; //getStyle("paddingLeft") + getStyle("paddingRight");
+        h += paddingTop + paddingBottom; //getStyle("paddingTop") + getStyle("paddingBottom");
+
+        measuredWidth = Math.max(w, MIN_WIDTH);
+        measuredMinHeight = measuredHeight = h;
+        measuredMinWidth = iconWidth + paddingLeft + paddingRight;
+    }
+
+    /**
+     *  @private
+     *  CheckBox <code>chromeColor</code> is flat, no gradient.
+     */
+    override protected function beginChromeColorFill(chromeColorGraphics:Graphics):void
+    {
+        // solid color fill for selectable buttons
+        chromeColorGraphics.beginFill(getStyle("chromeColor"));
+    }
+
+    /**
+     *  @private
+     */
+    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        var labelWidth:Number = 0;
+        var labelHeight:Number = 0;
+
+        var labelX:Number = 0;
+        var labelY:Number = 0;
+
+        var iconWidth:Number = 0;
+        var iconHeight:Number = 0;
+
+        var iconX:Number = 0;
+        var iconY:Number = 0;
+
+        var horizontalGap:Number = 0;
+        var verticalGap:Number = 0;
+
+        var iconPlacement:String = getStyle("iconPlacement");
+
+        var textWidth:Number = 0;
+        var textHeight:Number = 0;
+
+        var lineMetrics:TextLineMetrics;
+
+        if (hostComponent && hostComponent.label != "")
+        {
+            lineMetrics = measureText(hostComponent.label);
+            textWidth = lineMetrics.width + TEXT_WIDTH_PADDING;
+            textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
+        }
+        else
+        {
+            lineMetrics = measureText("Wj");
+            textHeight = lineMetrics.height + UITextField.TEXT_HEIGHT_PADDING;
+        }
+
+        var textAlign:String = "center"; // getStyle("textAlign");
+        // Map new Spark values that might be set in a selector
+        // affecting both Halo and Spark components.
+        /*if (textAlign == "start")
+        textAlign = TextFormatAlign.LEFT;
+        else if (textAlign == "end")
+        textAlign = TextFormatAlign.RIGHT;*/
+
+        var viewWidth:Number = unscaledWidth;
+        var viewHeight:Number = unscaledHeight;
+
+        var iconDisplay:DisplayObject = getIconDisplay();
+        if (iconDisplay)
+        {
+            if (iconDisplay is ILayoutElement)
+            {
+                iconWidth = ILayoutElement(iconDisplay).getPreferredBoundsWidth();
+                iconHeight = ILayoutElement(iconDisplay).getPreferredBoundsHeight();
+            }
+            else
+            {
+                iconWidth = iconDisplay.width;
+                iconHeight = iconDisplay.height;
+            }
+        }
+
+        if (iconPlacement == IconPlacement.LEFT ||
+            iconPlacement == IconPlacement.RIGHT)
+        {
+            horizontalGap = gap;
+
+            if (iconWidth == 0 || textWidth == 0)
+                horizontalGap = 0;
+
+            if (textWidth > 0)
+            {
+                labelWidth =
+                    Math.max(Math.min(viewWidth - iconWidth - horizontalGap -
+                        paddingLeft - paddingRight, textWidth), 0);
+            }
+            else
+            {
+                labelWidth = 0;
+            }
+            labelHeight = Math.min(viewHeight, textHeight);
+
+            if (textAlign == "left")
+            {
+                labelX += paddingLeft;
+            }
+            else if (textAlign == "right")
+            {
+                labelX += (viewWidth - labelWidth - iconWidth -
+                    horizontalGap - paddingRight);
+            }
+            else // "center" -- default value
+            {
+                labelX += ((viewWidth - labelWidth - iconWidth -
+                    horizontalGap - paddingLeft - paddingRight) / 2) + paddingLeft;
+            }
+
+            if (iconPlacement == IconPlacement.LEFT)
+            {
+                labelX += iconWidth + horizontalGap;
+                iconX = labelX - (iconWidth + horizontalGap);
+            }
+            else
+            {
+                iconX  = labelX + labelWidth + horizontalGap;
+            }
+
+            iconY  = ((viewHeight - iconHeight - paddingTop - paddingBottom) / 2) + paddingTop;
+            labelY = ((viewHeight - labelHeight - paddingTop - paddingBottom) / 2) + paddingTop;
+        }
+        else
+        {
+            verticalGap = gap;
+
+            if (iconHeight == 0 || !hostComponent || hostComponent.label == "")
+                verticalGap = 0;
+
+            if (textWidth > 0)
+            {
+                labelWidth = Math.max(viewWidth - paddingLeft - paddingRight, 0);
+                labelHeight =
+                    Math.min(viewHeight - iconHeight - paddingTop - paddingBottom - verticalGap, textHeight);
+            }
+            else
+            {
+                labelWidth = 0;
+                labelHeight = 0;
+            }
+
+            labelX = paddingLeft;
+
+            if (textAlign == "left")
+            {
+                iconX += paddingLeft;
+            }
+            else if (textAlign == "right")
+            {
+                iconX += Math.max(viewWidth - iconWidth - paddingRight, paddingLeft);
+            }
+            else
+            {
+                iconX += ((viewWidth - iconWidth - paddingLeft - paddingRight) / 2) + paddingLeft;
+            }
+
+            if (iconPlacement == IconPlacement.BOTTOM)
+            {
+                labelY += ((viewHeight - labelHeight - iconHeight -
+                    paddingTop - paddingBottom - verticalGap) / 2) + paddingTop;
+                iconY += labelY + labelHeight + verticalGap;
+            }
+            else
+            {
+                iconY += ((viewHeight - labelHeight - iconHeight -
+                    paddingTop - paddingBottom - verticalGap) / 2) + paddingTop;
+                labelY += iconY + iconHeight + verticalGap;
+            }
+        }
+
+        labelDisplay.commitStyles();
+        resizePart(labelDisplay, labelWidth, labelHeight);
+        positionPart(labelDisplay, Math.max(0, Math.round(labelX)), Math.max(0, Math.round(labelY)));
+
+        // before truncating text, we need to reset it to its original value
+        if (hostComponent && labelDisplay.isTruncated)
+            labelDisplay.text = hostComponent.label;
+
+        if (textWidth > labelWidth)
+        {
+            labelDisplay.truncateToFit();
+        }
+
+        labelDisplayShadow.alpha = getStyle("textShadowAlpha");
+        labelDisplayShadow.commitStyles();
+        resizePart(labelDisplayShadow, labelWidth, labelHeight);
+        positionPart(labelDisplayShadow, Math.max(0, Math.round(labelX)), Math.max(0, Math.round(labelY + 1)));
+
+        // if labelDisplay is truncated, then push it down here as well.
+        // otherwise, it would have gotten pushed in the labelDisplay_valueCommitHandler()
+        if (labelDisplay.isTruncated)
             labelDisplayShadow.text = labelDisplay.text;
-            invalidateSize();
-            invalidateDisplayList();
-        }
-    }
+
+        if (iconDisplay)
+        {
+            resizePart(iconDisplay, iconWidth, iconHeight);
+            positionPart(iconDisplay, Math.max(0, Math.round(iconX)), Math.max(0, Math.round(iconY)));
+        }
+
+        // draw chromeColor after parts have been positioned
+        super.updateDisplayList(unscaledWidth, unscaledHeight);
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Class methods
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  The current skin part that displays the icon.
+     *  If the icon is a Class, then the iconDisplay is an instance of that class.
+     *  If the icon is a DisplayObject instance, then the iconDisplay is that instance.
+     *  If the icon is URL, then iconDisplay is the Group that holds the BitmapImage with that URL.
+     *
+     *  @see #setIcon
+     *  @see #useIconStyle
+     */
+    protected function getIconDisplay():DisplayObject
+    {
+        return iconHolder ? iconHolder : iconInstance as DisplayObject;
+    }
+
+    /**
+     *  Sets the current icon for the iconDisplay skin part.
+     *  The iconDisplay skin part is created/set-up on demand.
+     *
+     *  @see #getIconDisplay
+     *  @see #useIconStyle
+     */
+    protected function setIcon(icon:Object):void
+    {
+        if (_icon == icon)
+            return;
+        _icon = icon;
+
+        // Clean-up the iconInstance
+        if (iconInstance)
+        {
+            if (iconHolder)
+                iconHolder.removeAllElements();
+            else
+                this.removeChild(iconInstance as DisplayObject);
+        }
+        iconInstance = null;
+
+        // Set-up the iconHolder
+        var needsHolder:Boolean = icon && !(icon is Class) && !(icon is DisplayObject);
+        if (needsHolder && !iconHolder)
+        {
+            iconHolder = new Group();
+            this.addChildAt(iconHolder, 0);
+        }
+        else if (!needsHolder && iconHolder)
+        {
+            this.removeChild(iconHolder);
+            iconHolder = null;
+        }
+
+        // Set-up the icon
+        if (icon)
+        {
+            if (needsHolder)
+            {
+                iconInstance = new BitmapImage();
+                iconInstance.source = icon;
+                iconHolder.addElementAt(iconInstance as BitmapImage, 0);
+            }
+            else
+            {
+                if (icon is Class)
+                    iconInstance = new (Class(icon))();
+                else
+                    iconInstance = icon;
+
+                addChildAt(iconInstance as DisplayObject, 0);
+            }
+        }
+
+        // explicitly invalidate, since addChild/removeChild don't invalidate for us
+        invalidateSize();
+        invalidateDisplayList();
+    }
+
+    //--------------------------------------------------------------------------
+    //
+    //  Event Handlers
+    //
+    //--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     */
+    private function labelDisplay_valueCommitHandler(event:FlexEvent):void
+    {
+        labelDisplayShadow.text = labelDisplay.text;
+        invalidateSize();
+        invalidateDisplayList();
+    }
+}
 }


Transferred from the Adobe Open Source Subversion Repository

Revision: 17841
Author:   hmuller@adobe.com
Date:     2010-09-24T15:36:59.172298Z

Log Message:
-----------
The ColumnHeaderBar classes have been substantially revised simplified and some of the horizontal scrolling flashing has been eliminated.  I've temporarily removed the column header bar event handling code since we weren't using it.   It will be restored when the column resizing feature is added.

The new versions of ColumnHeaderBar and ColumnHeaderBarLayout only depend on Grid (not GridDimensions or GridLayout).

QE notes: Failing mustella tests (bitmap and geometry changes) have been excluded
Doc notes:
Bugs: SDK-27967
Reviewer: Kevin
Tests run: checkin, mustella cyclone
Is noteworthy for integration: no

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/IGridItemRenderer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/accessibility/DataGridAccImpl.as</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/skins/spark/DefaultGridHeaderRendererSkin.mxml</path>
<path kind="file" action="A">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/skins/spark/DefaultGridHeaderRenderer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/spark-manifest.xml</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GridRowNode.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GridLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/DataGrid.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/ColumnHeaderBarLayout.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Grid.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/IGridRowBackground.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/SparkClasses.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/ColumnHeaderBar.as</path>
<path kind="file" action="D">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/DefaultColumnHeaderRenderer.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GridColumn.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/defaults.css</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/skins/spark/DataGridSkin.mxml</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/supportClasses/GridRowList.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1281469 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderGroupLayout.as
+++ frameworks/projects/spark/src/spark/components/gridClasses/GridColumnHeaderGroupLayout.as
@@ -11,11 +11,21 @@

 package spark.components.supportClasses
 {
+import flash.geom.Rectangle;
+import flash.utils.Dictionary;
+
+import mx.collections.IList;
+import mx.core.IFactory;
 import mx.core.ILayoutElement;
 import mx.core.IVisualElement;
 import mx.core.mx_internal;

-import spark.components.DataGroup;
+import spark.components.ColumnHeaderBar;
+import spark.components.DataGrid;
+import spark.components.Grid;
+import spark.components.Group;
+import spark.components.IGridItemRenderer;
+import spark.components.supportClasses.GridLayer;
 import spark.layouts.supportClasses.LayoutBase;

 use namespace mx_internal;
@@ -24,12 +34,6 @@

 public class ColumnHeaderBarLayout extends LayoutBase
 {
-    //--------------------------------------------------------------------------
-    //
-    //  Constructor
-    //
-    //--------------------------------------------------------------------------
-
     /**
      *  Constructor.
      *
@@ -45,37 +49,43 @@

     //--------------------------------------------------------------------------
     //
-    //  Variables
+    //  Internal variables
     //
     //--------------------------------------------------------------------------

     /**
      *  @private
-     */
-    private var gridLayout:GridLayout;
-
-    /**
-     *  @private
-     */
-    private var visibleColumnIndices:Vector.<int> = new Vector.<int>;
-
-    /**
-     *  @private
-     */
-    private var oldVisibleColumnIndices:Vector.<int>;
-
-    /**
-     *  @private
-     */
-    private var visibleHeaderSeparators:Vector.<IVisualElement> =
-                                        new Vector.<IVisualElement>(0);
+     *  Cached header renderer heights maintained by the measure() method.
+     */
+    private const rendererHeights:Array = new Array();
+
+    /**
+     *  @private
+     *  Bounds of all currently visible header renderers.
+     */
+    private const visibleRenderersBounds:Rectangle = new Rectangle();
+
+    /**
+     *  @private
+     *  The elements available for reuse aka the "free list".   Maps from an IFactory
+     *  to a list of the elements that have been allocated by that factory and then freed.
+     *  The list is represented by a Vector.<IVisualElement>.
+     */
+    private var freeElementMap:Dictionary = new Dictionary();
+
+    /**
+     *  @private
+     *  Records the IFactory used to allocate a Element so that freeVisualElement()
+     *  can find it again.
+     */
+    private var elementToFactoryMap:Dictionary = new Dictionary();

     //---------------------------------------------------------------
     //
-    //  Class properties
+    //  Overridden methods
     //
     //---------------------------------------------------------------
-
+
     /**
      *  @private
      */
@@ -93,152 +103,356 @@

     /**
      *  @private
-     */
-    private function get columnGap():Number
-    {
-        return gridDimensions ? gridDimensions.columnGap : 0;
-    }
-
-    /**
-     *  @private
-     *  The GridDimensions associated with this CHB.
-     */
-    private function get gridDimensions():GridDimensions
-    {
-        return gridLayout ? gridLayout.gridDimensions : null;
-    }
-
+     *  Clear everything.
+     */
+    override public function clearVirtualLayoutCache():void
+    {
+        rendererHeights.length = 0;
+        visibleRenderersBounds.setEmpty();
+        elementToFactoryMap = new Dictionary();
+        freeElementMap = new Dictionary();
+    }
+
+    /**
+     *  @private
+     */
+    override protected function scrollPositionChanged():void
+    {
+        const columnHeaderBar:ColumnHeaderBar = columnHeaderBar;
+        if (!columnHeaderBar)
+            return;
+
+        super.scrollPositionChanged();  // sets columnHeaderBar.scrollRect
+
+        // Only invalidate if we're clipping and scrollR extends outside visibleRenderersBounds
+        const scrollR:Rectangle = columnHeaderBar.scrollRect;
+        if (scrollR && !visibleRenderersBounds.containsRect(scrollR))
+            columnHeaderBar.invalidateDisplayList();
+    }
+
+    /**
+     *  @private
+     */
+    override public function measure():void
+    {
+        const columnHeaderBar:ColumnHeaderBar = columnHeaderBar;
+        const grid:Grid = grid;
+
+        if (!columnHeaderBar || !grid)
+            return;
+
+        const columnHeaderBarNumElements:int = columnHeaderBar.numElements;
+        for (var eltIndex:int = 0; eltIndex < columnHeaderBarNumElements; eltIndex++)
+        {
+            var renderer:IGridItemRenderer = columnHeaderBar.getElementAt(eltIndex) as IGridItemRenderer;
+            if (!renderer || !renderer.visible)
+                continue;
+
+            rendererHeights[renderer.column.columnIndex] = renderer.getPreferredBoundsHeight();
+        }
+
+        const columns:IList = grid.columns;
+        rendererHeights.length = (columns) ? columns.length : 0;
+
+        var maxRendererHeight:Number = 0;
+        for each (var rendererHeight:Number in rendererHeights)
+            maxRendererHeight = Math.max(maxRendererHeight, rendererHeight);
+
+        const paddingLeft:Number = columnHeaderBar.getStyle("paddingLeft");
+        const paddingRight:Number = columnHeaderBar.getStyle("paddingRight");
+        const paddingTop:Number = columnHeaderBar.getStyle("paddingTop");
+        const paddingBottom:Number = columnHeaderBar.getStyle("paddingBottom");
+
+        columnHeaderBar.measuredWidth = Math.ceil(grid.contentWidth + paddingLeft + paddingRight);
+        columnHeaderBar.measuredHeight = Math.ceil(maxRendererHeight + paddingTop + paddingBottom);
+    }
+
+    /**
+     *  @private
+     */
+    override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
+    {
+        const columnHeaderBar:ColumnHeaderBar = columnHeaderBar;
+        const grid:Grid = grid;
+
+        if (!columnHeaderBar || !grid)
+            return;
+
+        const visibleColumnIndices:Vector.<int> = grid.getVisibleColumnIndices();
+        const oldRenderers:Dictionary = new Dictionary();
+
+        const overlayGroup:Group = columnHeaderBar.overlayGroup;
+        const columnSeparatorFactory:IFactory = columnHeaderBar.columnSeparator;
+
+        // Add all of the renderers whose column is still visible to oldRenderers and free the rest
+
+        for (var eltIndex:int = 0; eltIndex < columnHeaderBar.numElements; eltIndex++)
+        {
+            var renderer:IGridItemRenderer = columnHeaderBar.getElementAt(eltIndex) as IGridItemRenderer;
+            if (!renderer || !renderer.visible)
+                continue;
+
+            var column:GridColumn = renderer.column;
+            if (column && (visibleColumnIndices.indexOf(column.columnIndex) != -1))
+                oldRenderers[column] = renderer;
+            else
+                freeVisualElement(renderer);
+        }
+
+        // Add all of the separators to the free-list, since laying them out is cheap
+
+        for (eltIndex = 0; eltIndex < overlayGroup.numElements; eltIndex++)
+            freeVisualElement(overlayGroup.getElementAt(eltIndex));
+
+        // Layout the header renderers and update the CHB's content size
+
+        const paddingLeft:Number = columnHeaderBar.getStyle("paddingLeft");
+        const paddingRight:Number = columnHeaderBar.getStyle("paddingRight");
+        const paddingTop:Number = columnHeaderBar.getStyle("paddingTop");
+        const paddingBottom:Number = columnHeaderBar.getStyle("paddingBottom");
+
+        const columns:IList = grid.columns;
+        const columnsLength:int = (columns) ? columns.length : 0;
+        const rendererY:Number = paddingTop;
+        const rendererHeight:Number = unscaledHeight - paddingTop - paddingBottom;
+        const maxRendererX:Number = columnHeaderBar.horizontalScrollPosition + unscaledWidth;
+
+        var columnIndex:int = -1;
+        var visibleLeft:Number = 0;
+        var visibleRight:Number = 0;
+
+        // This isn't quite as simple as:
+        //     for each (var columnIndex:int in visibleColumnIndices)
+        // since the ColumnHeaderBar may be wider than the grid because it
+        // spans the vertical scrollbar.  If it does, we may need to display
+        // additional column headers (usually one).
+
+        for (var index:int = 0; /* termination conditions below */; index++)
+        {
+            if (index < visibleColumnIndices.length)
+                columnIndex = visibleColumnIndices[index];
+            else
+                columnIndex += 1;  // TBD: find the next visible column
+
+            if (columnIndex >= columnsLength)
+                break;
+
+            column = columns.getItemAt(columnIndex) as GridColumn;
+
+            // reuse or create a new renderer
+
+            renderer = oldRenderers[column];
+            if (!renderer)
+            {
+                var factory:IFactory = column.headerRenderer;
+                if (!factory)
+                    factory = columnHeaderBar.headerRenderer;
+                renderer = allocateVisualElement(factory) as IGridItemRenderer;
+            }
+
+            // initialize the renderer
+
+            renderer.column = column;
+            renderer.label = column.headerText;
+            renderer.visible = true;
+            if (renderer.parent != columnHeaderBar)
+                columnHeaderBar.addElement(renderer);
+
+            // layout the renderer
+
+            var isLastColumn:Boolean = columnIndex == (columnsLength - 1);
+            var rendererX:Number = grid.getCellX(0, columnIndex) + paddingLeft;
+            var rendererWidth:Number = grid.getColumnWidth(columnIndex);
+
+            if (isLastColumn)
+                rendererWidth = horizontalScrollPosition + unscaledWidth - rendererX - paddingRight;
+
+            renderer.setLayoutBoundsSize(rendererWidth, rendererHeight);
+            renderer.setLayoutBoundsPosition(rendererX, rendererY);
+
+            if (index == 0)
+                visibleLeft = rendererX;
+            visibleRight = rendererX + rendererWidth;
+
+            if ((rendererX + rendererWidth) > maxRendererX)
+                break;
+
+            // allocate and layout a column separator
+
+            if (columnSeparatorFactory && !isLastColumn)
+            {
+                var separator:IVisualElement = allocateVisualElement(columnSeparatorFactory);
+                separator.visible = true;
+                if (separator.parent != overlayGroup)
+                    overlayGroup.addElement(separator);
+
+                var separatorWidth:Number = separator.getPreferredBoundsWidth();
+                var separatorX:Number = rendererX + rendererWidth;
+                separator.setLayoutBoundsSize(separatorWidth, rendererHeight);
+                separator.setLayoutBoundsPosition(separatorX, rendererY);
+            }
+        }
+
+        columnHeaderBar.setContentSize(grid.contentWidth, rendererHeight);
+
+        visibleRenderersBounds.left = visibleLeft;
+        visibleRenderersBounds.right = visibleRight;
+        visibleRenderersBounds.top = rendererY;
+        visibleRenderersBounds.height = rendererHeight;
+
+        // We may have created new renderers or changed their visibility.  Force
+        // validation to avoid a display list flash.
+
+        overlayGroup.validateNow();
+        columnHeaderBar.validateNow();
+    }
+
     //---------------------------------------------------------------
     //
-    //  Class methods
-    //
+    //  Public methods
+    //
+    //---------------------------------------------------------------
+
+    /**
+     *  If the requested header renderer is visible, returns a reference to
+     *  the header renderer currently displayed for the specified column.
+     *  Note that once the returned header renderer is no longer visible it
+     *  may be recycled and its properties reset.
+     *
+     *
If the requested header renderer is not visible then,
+     *  each time this method is called, a new header renderer is created.  The
+     *  new item renderer is not visible

+     *
+     *
The width of the returned renderer is the same as for item renderers
+     *  returned by DataGrid/getItemRenderer().

+     *
+     *  @param columnIndex The 0-based column index of the header renderer's column
+     *  @return The item renderer or null if the column index is invalid.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 2.0
+     *  @productversion Flex 4.5
+     */
+    public function getHeaderRendererAt(columnIndex:int):IGridItemRenderer
+    {
+        const columnHeaderBar:ColumnHeaderBar = columnHeaderBar;
+        const grid:Grid = grid;
+
+        if (!columnHeaderBar || !grid)
+            return null;
+
+        const visibleColumnIndices:Vector.<int> = grid.getVisibleColumnIndices();
+        const eltIndex:int = visibleColumnIndices.indexOf(columnIndex);
+        if ((eltIndex != -1) && (eltIndex < columnHeaderBar.numElements))
+            return columnHeaderBar.getElementAt(eltIndex) as IGridItemRenderer;
+
+        // create a new renderer
+
+        const columns:IList = grid.columns;
+        if (!columns || (columns.length <= columnIndex))
+            return null;
+        const column:GridColumn = grid.columns.getItemAt(columnIndex) as GridColumn;
+
+        var factory:IFactory = column.headerRenderer;
+        if (!factory)
+            factory = columnHeaderBar.headerRenderer;
+        const renderer:IGridItemRenderer = allocateVisualElement(factory) as IGridItemRenderer;
+
+        columnHeaderBar.addElement(renderer);
+
+        // initialize the renderer
+
+        renderer.column = column;
+        renderer.label = column.headerText;
+
+        // layout the renderer
+
+        const paddingLeft:Number = columnHeaderBar.getStyle("paddingLeft");
+        const paddingRight:Number = columnHeaderBar.getStyle("paddingRight");
+        const paddingTop:Number = columnHeaderBar.getStyle("paddingTop");
+        const paddingBottom:Number = columnHeaderBar.getStyle("paddingBottom");
+
+        const isLastColumn:Boolean = columnIndex == (columns.length - 1);
+        const rendererX:Number = grid.getCellX(0, columnIndex) + paddingLeft;
+        const rendererY:Number = paddingTop;
+        const rendererHeight:Number = columnHeaderBar.height - paddingTop - paddingBottom;
+        var rendererWidth:Number = grid.getColumnWidth(columnIndex);
+
+        if (isLastColumn)
+            rendererWidth = horizontalScrollPosition + columnHeaderBar.width - rendererX - paddingRight;
+
+        renderer.setLayoutBoundsSize(rendererWidth, rendererHeight);
+        renderer.setLayoutBoundsPosition(rendererX, rendererY);
+
+        columnHeaderBar.removeElement(renderer);
+        renderer.visible = false;
+
+        return renderer;
+    }
+
     //---------------------------------------------------------------
-
-    /**
-     *  @private
-     *  Used to connect this layout with the grid layout and to
-     *  signal to this layout that it needs to update.
-     */
-    public function updateLayout(layout:GridLayout):void
-    {
-        gridLayout = layout;
-
-        const layoutTarget:GroupBase = target;
-        if (layoutTarget)
-            layoutTarget.invalidateDisplayList();
-    }
-
-    //---------------------------------------------------------------
-    //
-    //  Overridden methods
-    //
-    //---------------------------------------------------------------
-
-    /**
-     *  @private
-     */
-    override public function measure():void
-    {
-        var totalWidth:Number = 0;
-        var totalHeight:Number = 0;
-
-        // loop through the elements
-        var layoutTarget:GroupBase = target;
-        if (!layoutTarget)
-            return;
-
-        var count:int = layoutTarget.numElements;
-        for (var i:int = 0; i < count; i++)
+    //
+    //  Internal methods
+    //
+    //---------------------------------------------------------------
+
+    /**
+     *  @private
+     *  If the freeElementMap "free list" contains an instance of this factory, then
+     *  remove if from the free list and return it, otherwise return a new factory instance.
+     */
+    private function allocateVisualElement(factory:IFactory):IVisualElement
+    {
+        const freeElements:Vector.<IVisualElement> = freeElementMap[factory] as Vector.<IVisualElement>;
+        if (freeElements)
         {
-            var element:ILayoutElement = layoutTarget.getVirtualElementAt(i);
-
-            // The element returned could still be null. Look at the typical
-            // element instead.
-            if (!element)
-                element = typicalLayoutElement;
-
-            // Find the preferred sizes
-            var elementWidth:Number = element.getPreferredBoundsWidth();
-            var elementHeight:Number = element.getPreferredBoundsHeight();
-
-            totalWidth += elementWidth;
-            totalHeight = Math.max(totalHeight, elementHeight);
+            const freeElement:IVisualElement = freeElements.pop();
+            if (freeElements.length == 0)
+                delete freeElementMap[factory];
+            if (freeElement)
+                return freeElement;
         }
-        if (count > 0)
-            totalWidth += (count - 1) * columnGap;
-
-        layoutTarget.measuredWidth = totalWidth;
-        layoutTarget.measuredHeight = totalHeight;
-
-        // Since we really can't fit the content in space any
-        // smaller than this, set the measured minimum size
-        // to be the same as the measured size.
-        // If the container is clipping and scrolling, it will
-        // ignore these limits and will still be able to
-        // shrink below them.
-        layoutTarget.measuredMinWidth = totalWidth;
-        layoutTarget.measuredMinHeight = totalHeight;
-
-        //trace("CHB.measure", totalWidth, totalHeight);
-    }
-
-    /**
-     *  @private
-     */
-    override public function updateDisplayList(unscaledWidth:Number,
-                                               unscaledHeight:Number):void
-    {
-        var maxHeight:Number = 0;
-
-        var layoutTarget:GroupBase = target;
-        if (!layoutTarget || !gridLayout)
-            return;
-
-        //trace("CHB.udl", unscaledWidth, unscaledHeight);
-
-        oldVisibleColumnIndices = visibleColumnIndices;
-        visibleColumnIndices = gridLayout.getVisibleColumnIndices();
-
-        for each (var columnIndex:int in visibleColumnIndices)
+
+        const newElement:IVisualElement = factory.newInstance() as IVisualElement;
+        elementToFactoryMap[newElement] = factory;
+        return newElement;
+    }
+
+    /**
+     *  @private
+     *  Move the specified element to the free list after hiding it. Note that we
+     *  do not actually remove the element from its parent.
+     */
+    private function freeVisualElement(element:IVisualElement):void
+    {
+        const factory:IFactory = elementToFactoryMap[element];
+
+        var freeElements:Vector.<IVisualElement> = freeElementMap[factory];
+        if (!freeElements)
         {
-            var element:ILayoutElement =
-                layoutTarget.getVirtualElementAt(columnIndex);
-
-            var gridColumn:GridColumn =
-                DataGroup(target).dataProvider.getItemAt(columnIndex) as GridColumn;
-
-            var elementWidth:Number;
-            var elementHeight:Number;
-
-            // FIXME (klin): hack here to force the borders of each header to overlap.
-            elementWidth = gridDimensions.getColumnWidth(columnIndex) + 1;
-            elementHeight = element.getPreferredBoundsHeight();
-
-            element.setLayoutBoundsSize(elementWidth, elementHeight);
-
-            // Position the element.
-            // FIXME: can this be calculated from the width of each element
-            // plus the columnGap? (but there is not a columnGap property)
-            element.setLayoutBoundsPosition(gridDimensions.getCellX(0, columnIndex), 0);
-
-            // Find maximum element extents.
-            maxHeight = Math.max(maxHeight, elementHeight);
+            freeElements = new Vector.<IVisualElement>();
+            freeElementMap[factory] = freeElements;
         }
-
-        // Scrolling support - update the content size
-        layoutTarget.setContentSize(gridDimensions.getContentWidth(), maxHeight);
-
-        // ToDo(cframpto): refactor these methods so both GridLayout and
-        // this layout can use them.
-
-        // Now layout the separators between the headers.
-     /*   visibleHeaderSeparators = gridLayout.layoutColumnHeaderSeparators(
-                                                oldVisibleColumnIndices,
-                                                visibleColumnIndices,
-                                                visibleHeaderSeparators);*/
-
-        oldVisibleColumnIndices.length = 0;
-    }
-
+        freeElements.push(element);
+
+        element.visible = false;
+    }
+
+
+    private function get columnHeaderBar():ColumnHeaderBar
+    {
+        return target as ColumnHeaderBar;
+    }
+
+    private function get grid():Grid
+    {
+        const chb:ColumnHeaderBar = columnHeaderBar;
+        if (!chb)
+            return null;
+
+        const dg:DataGrid = chb.owner as DataGrid;
+        return (dg) ? dg.grid : null;
+    }
 }
 }


Transferred from the Adobe Open Source Subversion Repository

Revision: 20013
Author:   harishs@adobe.com
Date:     2011-01-31T15:32:09.255609Z

Log Message:
-----------
QE notes: Globalization changes. Full cyclone run has been done. Default locale changes and sort bug fixes since Dec 14 2010
Doc notes: ASDOC comments for all classes have been updated.
Bugs: SDK-29132 SDK-29127 SDK-28163  SDK-29075 SDK-28600 SDK-28492 SDK-28856

Reviewer: Gordon Smith, Xie Fang, Zhigang Qi
Tests run: cyclone and checkintests
Is noteworthy for integration:

Modified Paths:
--------------
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/styles/AdvancedStyleClient.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/SortField.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/supportClasses/NumberValidatorBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/ISort.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/supportClasses/GlobalizationValidatorBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/supportClasses/CollatorBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/NumberFormatter.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/ISortField.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/CurrencyFormatter.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/collections/Sort.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/NumberValidator.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/DateTimeFormatter.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/CurrencyValidator.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/core/UIComponent.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/collections/SortField.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/components/Group.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/supportClasses/GlobalizationBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/validators/supportClasses/GlobalizationUtils.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/SortingCollator.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/StringTools.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/LastOperationStatus.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/framework/src/mx/collections/Sort.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/formatters/supportClasses/NumberFormatterBase.as</path>
<path kind="file" action="M">/private/flex/sdk/branches/hero_private/frameworks/projects/spark/src/spark/globalization/MatchingCollator.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1262447 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/framework/src/mx/styles/AdvancedStyleClient.as
+++ frameworks/projects/framework/src/mx/styles/AdvancedStyleClient.as
@@ -257,8 +257,10 @@
         }

         return styleManager.inheritingStyles[styleProp] ?
-            _inheritingStyles    ? _inheritingStyles[styleProp]    : undefined :
-            _nonInheritingStyles ? _nonInheritingStyles[styleProp] : undefined;
+                   (_inheritingStyles    ? _inheritingStyles[styleProp]
+                                         : undefined) :
+                   (_nonInheritingStyles ? _nonInheritingStyles[styleProp]
+                                         : undefined);
     }

     /**


Transferred from the Adobe Open Source Subversion Repository

Revision: 6745
Author:   cframpto@adobe.com
Date:     2009-05-08T09:29:07.013898Z

Log Message:
-----------
Fix Catalyst RTE in RadioButtonGroup.breadthOrderCompare()

QE Notes: wee need Catalyst to verify this is fixed since they can't produce a test case for us but can reproduce this easily in their environment
Doc Notes:
Bugs: SDK-21009
Reviewers: Alex and Glenn

Modified Paths:
--------------
/flex/sdk/trunk/frameworks/projects/flex4/src/spark/components/RadioButtonGroup.as

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1279963 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/RadioButtonGroup.as
+++ frameworks/projects/spark/src/spark/components/RadioButtonGroup.as
@@ -20,7 +20,8 @@
 import mx.core.FlexGlobals;
 import mx.core.IFlexDisplayObject;
 import mx.core.IMXMLObject;
-import mx.core.IRawChildrenContainer;
+import mx.core.IVisualElement;
+import mx.core.IVisualElementContainer;
 import mx.core.UIComponent;
 import mx.core.mx_internal;
 import mx.events.FlexEvent;
@@ -562,9 +563,9 @@
      */
     private function breadthOrderCompare(a:DisplayObject, b:DisplayObject):Number
     {
-        var aParent:DisplayObject = a.parent;
-        var bParent:DisplayObject = b.parent;
-
+        var aParent:DisplayObjectContainer = a.parent;
+        var bParent:DisplayObjectContainer = b.parent;
+
         if (!aParent || !bParent)
             return 0;

@@ -585,17 +586,25 @@
         var aNestLevel:int = (a is UIComponent) ? UIComponent(a).nestLevel : -1;
         var bNestLevel:int = (b is UIComponent) ? UIComponent(b).nestLevel : -1;

-        var aIndex:int = aParent is IRawChildrenContainer ?
-            IRawChildrenContainer(aParent).rawChildren.getChildIndex(a) :
-            DisplayObjectContainer(aParent).getChildIndex(a);
-
-        var bIndex:int = bParent is IRawChildrenContainer ?
-            IRawChildrenContainer(bParent).rawChildren.getChildIndex(b) :
-            DisplayObjectContainer(bParent).getChildIndex(b);
-
-        if (aNestLevel > bNestLevel || (a.parent == b.parent && aIndex > bIndex))
+        var aIndex:int = 0;
+        var bIndex:int = 0;
+
+        if (aParent == bParent)
+        {
+            if (aParent is IVisualElementContainer && a is IVisualElement)
+                aIndex = IVisualElementContainer(aParent).getElementIndex(IVisualElement(a));
+            else
+                aIndex = DisplayObjectContainer(aParent).getChildIndex(a);
+
+            if (bParent is IVisualElementContainer && b is IVisualElement)
+                bIndex = IVisualElementContainer(bParent).getElementIndex(IVisualElement(b));
+            else
+                bIndex = DisplayObjectContainer(bParent).getChildIndex(b);
+        }
+
+        if (aNestLevel > bNestLevel || aIndex > bIndex)
             return 1;
-        else if (aNestLevel < bNestLevel ||  (a.parent == b.parent && bIndex > aIndex))
+        else if (aNestLevel < bNestLevel ||  bIndex > aIndex)
             return -1;
         else if (a == b)
             return 0;


Transferred from the Adobe Open Source Subversion Repository

Revision: 8458
Author:   smgilson@adobe.com
Date:     2009-07-08T18:35:15.696955Z

Log Message:
-----------
- Hide AdvancedLayoutFeatures.as from ASDoc
- ASDoc updates for IVisualElementContainer.as, UIComponent.as, IUIComponet
- Delete old ASDoc example and add a new one for RichEditableText.as

QE Notes: None
Doc Notes: None
Bugs: -
Checkintests: passed

Modified Paths:
--------------
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/primitives/RichEditableText.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/IVisualElementContainer.as</path>
<path kind="file" action="D">/flex/sdk/trunk/frameworks/projects/spark/asdoc/en_US/spark/components/examples/TextViewExample.mxml</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/spark/src/spark/components/supportClasses/SkinnableComponent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as</path>
<path kind="file" action="M">/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/AdvancedLayoutFeatures.as</path>

git-svn-id: 7146a936b37d36e51ea0d66f8acbe0b8281bc7b7@1280142 13f79535-47bb-0310-9956-ffa450edef68

--- frameworks/projects/spark/src/spark/components/RichEditableText.as
+++ frameworks/projects/spark/src/spark/components/RichEditableText.as
@@ -212,7 +212,7 @@
  *  @see spark.primitives.SimpleText
  *  @see spark.primitives.RichText
  *
- *  @includeExample examples/TextViewExample.mxml
+ *  @includeExample examples/RichEditableTextExample.mxml
  *
  *  @langversion 3.0
  *  @playerversion Flash 10
@@ -220,7 +220,7 @@
  *  @productversion Flex 4
  */
 public class RichEditableText extends UIComponent
-	implements IViewport, IIMESupport
+    implements IViewport, IIMESupport
 {
     include "../core/Version.as";

@@ -254,14 +254,14 @@
         staticTextLayoutFormat.paddingBottom = FormatValue.INHERIT;
         staticTextLayoutFormat.verticalAlign = FormatValue.INHERIT;

-    	// Create a single Configuration used by all TextContainerManager
-    	// instances.  It tells the TextContainerManager that we don't want it
-    	// to handle the ENTER key, because we need the ENTER key to behave
-    	// differently based on the 'multiline' property.
-    	staticTextContainerManagerConfiguration =
-    		Configuration(TextContainerManager.defaultConfiguration).clone();
-    	staticTextContainerManagerConfiguration.manageEnterKey = false;
-
+        // Create a single Configuration used by all TextContainerManager
+        // instances.  It tells the TextContainerManager that we don't want it
+        // to handle the ENTER key, because we need the ENTER key to behave
+        // differently based on the 'multiline' property.
+        staticTextContainerManagerConfiguration =
+            Configuration(TextContainerManager.defaultConfiguration).clone();
+        staticTextContainerManagerConfiguration.manageEnterKey = false;
+
         staticPlainTextImporter =
             TextConverter.getImporter(TextConverter.PLAIN_TEXT_FORMAT);

@@ -272,10 +272,10 @@
         staticPlainTextExporter =
             TextConverter.getExporter(TextConverter.PLAIN_TEXT_FORMAT);

-        // Used for embedded fonts.
-    	staticTextFormat = new TextFormat();
-
-    	classInitialized = true;
+        // Used for embedded fonts.
+        staticTextFormat = new TextFormat();
+
+        classInitialized = true;
     }

     //--------------------------------------------------------------------------
@@ -291,7 +291,7 @@

     /**
      *  @private
-	 *  Used for telling TextContainerManager not to process the Enter key.
+     *  Used for telling TextContainerManager not to process the Enter key.
      */
     private static var staticTextContainerManagerConfiguration:Configuration;

@@ -323,9 +323,9 @@

     /**
      *  @private
-	 *  Used for debugging.
-	 *  Set this to true to get trace output
-	 *  showing what TextContainerManager APIs are being called.
+     *  Used for debugging.
+     *  Set this to true to get trace output
+     *  showing what TextContainerManager APIs are being called.
      */
     mx_internal static var debug:Boolean = false;

@@ -426,10 +426,10 @@
             textContainerManager_compositionCompleteHandler);

         _textContainerManager.addEventListener(
-        	DamageEvent.DAMAGE, textContainerManager_damageHandler);
+            DamageEvent.DAMAGE, textContainerManager_damageHandler);

         _textContainerManager.addEventListener(
-        	Event.SCROLL, textContainerManager_scrollHandler);
+            Event.SCROLL, textContainerManager_scrollHandler);

         _textContainerManager.addEventListener(
             SelectionEvent.SELECTION_CHANGE,
@@ -987,7 +987,7 @@
      */
     private function get editingMode():String
     {
-    	return _textContainerManager.editingMode;
+        return _textContainerManager.editingMode;
     }

     /**
@@ -995,10 +995,10 @@
      */
     private function set editingMode(value:String):void
     {
-    	if (debug)
-     		trace("editingMode = ", value);
-
-     	_textContainerManager.editingMode = value;
+        if (debug)
+            trace("editingMode = ", value);
+
+        _textContainerManager.editingMode = value;
     }

     //----------------------------------
@@ -1105,11 +1105,11 @@
      *  The TLF TextContainerManager instance that displays,
      *  scrolls, and edits the text in this component.
      */
-	mx_internal function get textContainerManager():TextContainerManager
-	{
-		return _textContainerManager;
-	}
-
+    mx_internal function get textContainerManager():TextContainerManager
+    {
+        return _textContainerManager;
+    }
+
     //----------------------------------
     //  maxChars
     //----------------------------------
@@ -1269,7 +1269,7 @@
      */
     private var _selectionActivePosition:int = -1;

-	[Bindable("selectionChange")]
+    [Bindable("selectionChange")]

     /**
      *  The active position of the selection.
@@ -1299,7 +1299,7 @@
      */
     private var _selectionAnchorPosition:int = -1;

-	[Bindable("selectionChange")]
+    [Bindable("selectionChange")]

     /**
      *  The anchor position of the selection.
@@ -1595,31 +1595,31 @@

         if (!hostFormat)
         {
-	        // If the CSS styles for this component specify an embedded font,
-	        // embeddedFontContext will be set to the module factory that
-	        // should create TextLines (since they must be created in the
-	        // SWF where the embedded font is.)
-	        // Otherwise, this will be null.
+            // If the CSS styles for this component specify an embedded font,
+            // embeddedFontContext will be set to the module factory that
+            // should create TextLines (since they must be created in the
+            // SWF where the embedded font is.)
+            // Otherwise, this will be null.
             embeddedFontContext = getEmbeddedFontContext();

             if (debug)
-            	trace("hostFormat=");
+                trace("hostFormat=");
             _textContainerManager.hostFormat =
-            	hostFormat = new CSSTextLayoutFormat(this);
-       			// Note: CSSTextLayoutFormat has special processing
-        		// for the fontLookup style. If it is "auto",
-        		// the fontLookup format is set to either
-        		// "device" or "embedded" depending on whether
-        		// embeddedFontContext is null or non-null.
+                hostFormat = new CSSTextLayoutFormat(this);
+                // Note: CSSTextLayoutFormat has special processing
+                // for the fontLookup style. If it is "auto",
+                // the fontLookup format is set to either
+                // "device" or "embedded" depending on whether
+                // embeddedFontContext is null or non-null.
         }

         if (selectionFormatsChanged)
         {
-        	if (debug)
-        		trace("invalidateInteractionManager()");
-        	_textContainerManager.invalidateSelectionFormats();
-
-        	selectionFormatsChanged = false;
+            if (debug)
+                trace("invalidateInteractionManager()");
+            _textContainerManager.invalidateSelectionFormats();
+
+            selectionFormatsChanged = false;
         }

         // If fontMetrics changed, recalculate the ascent, and descent.
@@ -1981,9 +1981,9 @@

         ignoreDamageEvent = false;

-		if (debug)
-			trace("updateContainer()");
-
+        if (debug)
+            trace("updateContainer()");
+
         _textContainerManager.textLineCreator =
             ITextLineCreator(embeddedFontContext);

@@ -2213,33 +2213,33 @@
     //
     //--------------------------------------------------------------------------

-	/**
-	 *  @private
-	 */
-	mx_internal function createTextContainerManager():TextContainerManager
-	{
-		return new RichEditableTextContainerManager(
-			this, staticTextContainerManagerConfiguration);
-	}
-
-	/**
-	 *  @private
-	 *  Uses the component's CSS styles to determine the module factory
-	 *  that should creates its TextLines.
-	 */
-	private function getEmbeddedFontContext():IFlexModuleFactory
-	{
-		var fontContext:IFlexModuleFactory;
-
-		var fontLookup:String = getStyle("fontLookup");
-		if (fontLookup != FontLookup.DEVICE)
-        {
-			var font:String = getStyle("fontFamily");
-			var bold:Boolean = getStyle("fontWeight") == "bold";
-			var italic:Boolean = getStyle("fontStyle") == "italic";
-
+    /**
+     *  @private
+     */
+    mx_internal function createTextContainerManager():TextContainerManager
+    {
+        return new RichEditableTextContainerManager(
+            this, staticTextContainerManagerConfiguration);
+    }
+
+    /**
+     *  @private
+     *  Uses the component's CSS styles to determine the module factory
+     *  that should creates its TextLines.
+     */
+    private function getEmbeddedFontContext():IFlexModuleFactory
+    {
+        var fontContext:IFlexModuleFactory;
+
+        var fontLookup:String = getStyle("fontLookup");
+        if (fontLookup != FontLookup.DEVICE)
+        {
+            var font:String = getStyle("fontFamily");
+            var bold:Boolean = getStyle("fontWeight") == "bold";
+            var italic:Boolean = getStyle("fontStyle") == "italic";
+
             fontContext = embeddedFontRegistry.getAssociatedModuleFactory(
-            	font, bold, italic, this, moduleFactory);
+                font, bold, italic, this, moduleFactory);

             // If we found the font, then it is embedded.
             // But some fonts are not listed in info()
@@ -2250,9 +2250,9 @@
             {
                 var sm:ISystemManager;
                 if (moduleFactory != null && moduleFactory is ISystemManager)
-                	sm = ISystemManager(moduleFactory);
+                    sm = ISystemManager(moduleFactory);
                 else if (parent is IUIComponent)
-                	sm = IUIComponent(parent).systemManager;
+                    sm = IUIComponent(parent).systemManager;

                 staticTextFormat.font = font;
                 staticTextFormat.bold = bold;
@@ -2271,7 +2271,7 @@
         }

         return fontContext;
-	}
+    }

     /**
      *  @private
@@ -2286,7 +2286,7 @@
         if (editingMode == EditingMode.READ_ONLY)
             editingMode = EditingMode.READ_SELECT;

-    	return SelectionManager(_textContainerManager.beginInteraction());
+        return SelectionManager(_textContainerManager.beginInteraction());
     }

     /**
@@ -2536,35 +2536,35 @@

         s = getStyle("cffHinting");
         if (s != null)
-        	fontDescription.cffHinting = s;
+            fontDescription.cffHinting = s;

         s = getStyle("fontFamily");
         if (s != null)
-        	fontDescription.fontName = s;
+            fontDescription.fontName = s;

         s = getStyle("fontLookup");
         if (s != null)
         {
-        	// FTE understands only "device" and "embeddedCFF"
-        	// for fontLookup. But Flex allows this style to be
-        	// set to "auto", in which case we automatically
-        	// determine it based on whether the CSS styles
-        	// specify an embedded font.
-        	if (s == "auto")
-        	{
-        		s = embeddedFontContext ?
-        			FontLookup.EMBEDDED_CFF :
-                	FontLookup.DEVICE;
-        	}
+            // FTE understands only "device" and "embeddedCFF"
+            // for fontLookup. But Flex allows this style to be
+            // set to "auto", in which case we automatically
+            // determine it based on whether the CSS styles
+            // specify an embedded font.
+            if (s == "auto")
+            {
+                s = embeddedFontContext ?
+                    FontLookup.EMBEDDED_CFF :
+                    FontLookup.DEVICE;
+            }
         }

         s = getStyle("fontStyle");
         if (s != null)
-        	fontDescription.fontPosture = s;
+            fontDescription.fontPosture = s;

         s = getStyle("fontWeight");
         if (s != null)
-        	fontDescription.fontWeight = s;
+            fontDescription.fontWeight = s;

         var elementFormat:ElementFormat = new ElementFormat();
         elementFormat.fontDescription = fontDescription;
@@ -2588,22 +2588,22 @@
      */
     private function calculateWidthInChars():Number
     {
-    	var em:Number = getStyle("fontSize");
+        var em:Number = getStyle("fontSize");

         var effectiveWidthInChars:int;
-
+
         // If both height and width are NaN use 15 chars.  Otherwise if only
         // width is NaN, use 1.
-    	if (isNaN(_widthInChars))
-    	   effectiveWidthInChars = isNaN(_heightInLines) ? 10 : 1;
-    	else
-    	   effectiveWidthInChars = _widthInChars;
-
-    	// Without the explicit casts, if padding values are non-zero, the
-    	// returned width is a very large number.
-    	return getStyle("paddingLeft") +
-    		   effectiveWidthInChars * em +
-    		   getStyle("paddingRight");
+        if (isNaN(_widthInChars))
+           effectiveWidthInChars = isNaN(_heightInLines) ? 10 : 1;
+        else
+           effectiveWidthInChars = _widthInChars;
+
+        // Without the explicit casts, if padding values are non-zero, the
+        // returned width is a very large number.
+        return getStyle("paddingLeft") +
+               effectiveWidthInChars * em +
+               getStyle("paddingRight");
     }

     /**
@@ -2642,7 +2642,7 @@
         {
             var value:Object = getStyle("lineHeight");
             var lineHeight:Number =
-            	TextUtil.getNumberOrPercentOf(value, getStyle("fontSize"));
+                TextUtil.getNumberOrPercentOf(value, getStyle("fontSize"));

             // Default is 120%
             if (isNaN(lineHeight))
@@ -2663,50 +2663,50 @@
      */
     private function createTextFlowFromContent(content:Object):TextFlow
     {
-		var textFlow:TextFlow ;
-
-		// The whiteSpaceCollapse format determines how whitespace
-		// is processed when the children are set.
-		staticTextLayoutFormat.whiteSpaceCollapse =
-			getStyle("whiteSpaceCollapse");
-
-		if (content is TextFlow)
-		{
-			textFlow = content as TextFlow;
-			textFlow.hostFormat = staticTextLayoutFormat;
-					}
-		else if (content is Array)
-		{
-			textFlow = new TextFlow();
-			textFlow.hostFormat = staticTextLayoutFormat;
-			textFlow.mxmlChildren = content as Array;
-		}
-		else
-		{
-			textFlow = new TextFlow();
-			textFlow.hostFormat = staticTextLayoutFormat;
-			textFlow.mxmlChildren = [ content ];
-		}
-
-		return textFlow;
-	}
+        var textFlow:TextFlow ;
+
+        // The whiteSpaceCollapse format determines how whitespace
+        // is processed when the children are set.
+        staticTextLayoutFormat.whiteSpaceCollapse =
+            getStyle("whiteSpaceCollapse");
+
+        if (content is TextFlow)
+        {
+            textFlow = content as TextFlow;
+            textFlow.hostFormat = staticTextLayoutFormat;
+                    }
+        else if (content is Array)
+        {
+            textFlow = new TextFlow();
+            textFlow.hostFormat = staticTextLayoutFormat;
+            textFlow.mxmlChildren = content as Array;
+        }
+        else
+        {
+            textFlow = new TextFlow();
+            textFlow.hostFormat = staticTextLayoutFormat;
+            textFlow.mxmlChildren = [ content ];
+        }
+
+        return textFlow;
+    }

     /**
      *  @private
      */
     private function updateEditingMode():void
     {
-    	var newEditingMode:String = EditingMode.READ_ONLY;
-
-    	if (enabled)
-    	{
-    		if (_editable)
-    			newEditingMode = EditingMode.READ_WRITE;
-    		else if (_selectable)
-    			newEditingMode = EditingMode.READ_SELECT;
-    	}
-
-  		editingMode = newEditingMode;
+        var newEditingMode:String = EditingMode.READ_ONLY;
+
+        if (enabled)
+        {
+            if (_editable)
+                newEditingMode = EditingMode.READ_WRITE;
+            else if (_selectable)
+                newEditingMode = EditingMode.READ_SELECT;
+        }
+
+        editingMode = newEditingMode;
     }

     /**
@@ -2737,7 +2737,7 @@
         // Make sure all properties are committed before doing the operation.
         validateNow();

-		var selectionManager:ISelectionManager = getSelectionManager();
+        var selectionManager:ISelectionManager = getSelectionManager();

         selectionManager.selectRange(anchorPosition, activePosition);

@@ -3004,7 +3004,7 @@
         // Apply the three format objects to the current selection if
         // selectionState is null, else the specified selection.
         editManager.applyFormat(
-        	characterFormat, paragraphFormat, containerFormat, selectionState);
+            characterFormat, paragraphFormat, containerFormat, selectionState);

         // All done with the edit manager.
         releaseEditManager();
@@ -3043,9 +3043,9 @@
         validateDisplayList();
     }

-	/**
-	 *  @private
-	 */
+    /**
+     *  @private
+     */
     private function handlePasteOperation(op:PasteOperation):void
     {
         if (!restrict && !maxChars && !displayAsPassword)
@@ -3067,15 +3067,15 @@
         dispatchChangingEvent = false;

         var selectionState:SelectionState = new SelectionState(
-        	op.textFlow, op.absoluteStart,
-        	op.absoluteStart + pastedText.length);
+            op.textFlow, op.absoluteStart,
+            op.absoluteStart + pastedText.length);
         editManager.deleteText(selectionState);

         // Insert the same text, the same place where the paste was done.
         // This will go thru the InsertPasteOperation and do the right
         // things with restrict, maxChars and displayAsPassword.
         selectionState = new SelectionState(
-        	op.textFlow, op.absoluteStart, op.absoluteStart);
+            op.textFlow, op.absoluteStart, op.absoluteStart);
         editManager.insertText(pastedText, selectionState);

         // All done with the edit manager.
@@ -3178,7 +3178,7 @@
     mx_internal function keyDownHandler(event:KeyboardEvent):void
     {
         if (editingMode != EditingMode.READ_WRITE)
-        	return;
+            return;

         if (event.keyCode == Keyboard.ENTER)
         {
@@ -3186,8 +3186,8 @@
             {
                 // This is the same code that is in the EditManager for handling
                 // the enter key.
-        		getEditManager().splitParagraph();
-        		releaseEditManager();
+                getEditManager().splitParagraph();
+                releaseEditManager();
                 event.preventDefault();
                 //event.stopImmediatePropagation();
             }