Uploaded image for project: 'Apache Flex'
  1. Apache Flex
  2. FLEX-24138

Nested Groups with BasicLayouts won't be measured correctly

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Minor
    • Resolution: Not A Problem
    • Adobe Flex SDK 4.0 (Release)
    • None
    • Spark: Group
    • None
    • Affected OS(s): All OS Platforms
      Affected OS(s): All OS Platforms
      Browser: Safari
      Language Found: English

    Description

      When creating a component's skin with a nested contentGroup, programmatic positioning within the updateDisplayList is not working properly. measuredWidth and measuredHeight are not calculated properly, if UIComponent.move or ILayoutElement api is used.

      Steps to reproduce:

      1. Implement a skin

      // -----------------------------------------------------------------------------

      <?xml version="1.0"?>
      <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
      xmlns:s="library://ns.adobe.com/flex/spark"
      xmlns:mx="library://ns.adobe.com/flex/mx"
      initialize="initializeHandler(event)"
      creationComplete="creationCompleteHandler(event)"
      updateComplete="updateCompleteHandler(event)">

      <fx:Script>
      <![CDATA[

      import mx.events.FlexEvent;

      protected function simpleLog():void

      { trace("\tcontents", "x:", contents.x, "y:", contents.y, "\n\t\twidth:", contents.width, "height:", contents.height, "\n\t\texplicitWidth:", contents.explicitWidth, "explicitHeight:", contents.explicitHeight, "\n\t\tmeasuredWidth:", contents.measuredWidth, "measuredHeight:", contents.height, "\n\t\tcontentWidth:", contents.contentWidth, "contentHeight:", contents.contentHeight); trace("\tcontentGroup", "x:", contentGroup.x, "y:", contentGroup.y, "\n\t\twidth:", contentGroup.width, "height:", contentGroup.height, "\n\t\texplicitWidth:", contentGroup.explicitWidth, "explicitHeight:", contentGroup.explicitHeight, "\n\t\tmeasuredWidth:", contentGroup.measuredWidth, "measuredHeight:", contentGroup.height, "\n\t\tcontentWidth:", contentGroup.contentWidth, "contentHeight:", contentGroup.contentHeight); }

      private function creationCompleteHandler(event:FlexEvent):void

      { trace(className + ".creationCompleteHandler"); simpleLog(); }

      private function initializeHandler(event:FlexEvent):void

      { trace(className + ".initializeHandler"); simpleLog(); }

      private function updateCompleteHandler(event:FlexEvent):void

      { trace(className + ".updateCompleteHandler"); simpleLog(); }

      protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void

      { super.updateDisplayList(unscaledWidth, unscaledHeight); }

      ]]
      >
      </fx:Script>

      <s:Group id="contents">
      <s:Group id="contentGroup">
      <s:Label id="headerDisplay" text="header" />
      <s:TextArea id="bodyDisplay" text="body" />
      </s:Group>
      </s:Group>

      </s:SparkSkin>

      //-----------------------------------------------------------------------------

      2. Implement a component with required skin parts using the skin.

      //-----------------------------------------------------------------------------

      package
      {
      import spark.components.Label;
      import spark.components.TextArea;
      import spark.components.supportClasses.SkinnableComponent;

      public class MyComponent extends SkinnableComponent
      {

      //---------------------------------------------------------------------
      //
      // Properties
      //
      //---------------------------------------------------------------------

      [SkinPart(required="true")]
      public var headerDisplay:Label;

      [SkinPart(required="true")]
      public var bodyDisplay:TextArea;

      //---------------------------------------------------------------------
      //
      // Contructor
      //
      //---------------------------------------------------------------------

      public function MyComponent()

      { super(); setStyle("skinClass", MySkin); }

      }
      }

      //-----------------------------------------------------------------------------

      3. Setting the x and y property of the children directly in upadeDisplayList, lead to the expected values in all live cycle phases

      //-----------------------------------------------------------------------------

      protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
      {
      super.updateDisplayList(unscaledWidth, unscaledHeight);

      headerDisplay.x = 20;
      headerDisplay.y = 20;
      bodyDisplay.x = 20;
      bodyDisplay.y = 40;
      }

      //-----------------------------------------------------------------------------

      4. But using UIComponent.move

      //-----------------------------------------------------------------------------

      protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
      {
      super.updateDisplayList(unscaledWidth, unscaledHeight);

      headerDisplay.move(20, 20);
      bodyDisplay.move(20, 40);
      }

      //-----------------------------------------------------------------------------

      or ILayoutElement.setlayoutBoundsPosition

      //-----------------------------------------------------------------------------

      protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
      {
      super.updateDisplayList(unscaledWidth, unscaledHeight);

      headerDisplay.setLayoutBoundsPosition(20, 20);
      bodyDisplay.setLayoutBoundsPosition(20, 40);
      }

      //-----------------------------------------------------------------------------

      in updateDiplayList will cause the measured values of the groups to be calculated without the children's positions included.

      Actual Results:

      The component is smaller than implemented.

      Expected Results:

      The component should be as big as it's children take up space within their containers boundaries if clipping is not enabled and no explicit values are set for the component's width and height

      Workaround (if any):

      Call Group.invalidateSize in the FlexEvent.CREATION_COMPLETE handler of the skin

      //-----------------------------------------------------------------------------

      private function creationCompleteHandler(event:FlexEvent):void
      {
      trace(className + ".creationCompleteHandler");
      simpleLog();
      contentGroup.invalidateSize();
      }

      //-----------------------------------------------------------------------------

      Attachments

        Activity

          People

            adobejira Adobe JIRA
            adobejira Adobe JIRA
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: