2 Replies Latest reply on Sep 4, 2010 11:10 PM by Shongrunden

    Problems with Transition of skinned custom components displayed in s:TileGroup

    Ron Pasch

      I have a problem with transitions not playing correctly on a custom component that is displayed in a <s:TileGroup>.

       

      Code of the custom component;

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:SkinnableComponent xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
       skinClass="com.mydomain.view.skins.SkinFile">
       
       <fx:Metadata>
        [SkinState("normal")]
        [SkinState("photo")]
       </fx:Metadata>
      
       <s:states>
        <s:State name="normal" enterState="invalidateSkinState()" />
        <s:State name="photo" enterState="invalidateSkinState()" />
       </s:states>
       
       <fx:Script>
        <![CDATA[
         override protected function getCurrentSkinState():String {
          return currentState;
         }
        ]]>
       </fx:Script> 
       
      </s:SkinnableComponent>
      

       

      The skinfile itself is relatively simple as well;

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx"
        width="300" height="200" width.photo="140"
        >
         
       <fx:Metadata>
        [HostComponent("com.mydomain.view.components.MyComponent")]
       </fx:Metadata>
       <s:states>
        <s:State name="normal"/>
        <s:State name="photo"/>
       </s:states>
       
       <s:transitions>
        <s:Transition autoReverse="true">
         <s:Resize target="{this}" duration="500" />
        </s:Transition>
       </s:transitions>
       
       
       <s:Rect id="rect" radiusX="15" radiusY="15" top="0" right="0" bottom="0" left="0">
        <s:fill>
         <s:LinearGradient rotation="90">
          <s:GradientEntry color="0xffffff" ratio="0" />
          <s:GradientEntry color="0xf0f0f0" ratio="1" />
         </s:LinearGradient>
        </s:fill>
        <s:stroke>
         <s:SolidColorStroke color="0xc0c0c0" weight="1"/>
        </s:stroke>
       </s:Rect>
       
      </s:Skin>
      

       

       

      When displaying a couple instanced of the MyComponent class in a s:TileGroup like so;

      <s:TileGroup width="940" verticalGap="20" horizontalGap="20" clipAndEnableScrolling="true">
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
       <components:MyComponent currentState="{theState}" />
      </s:TileGroup>
      

       

      and having two buttons to switch the value of "theState" to either "normal" or "photo", it resizes the component correctly to the smaller size, but going back from the smaller size to the bigger size, it does not play the transition. it simply makes it from small to big straight away.

       

      The strange thing is however that if I use a <s:HGroup> tag instead of <s:TileGroup> it works like a charm, so I imagine it's not so much the custom component and/or the skin that is causing the problems.

       

      When I put the transition of the size in the component itself instead of in it's skin, then it works as expected, but I think the transitions should be defined in the skin and not in the component itself, right?

       

      Am I doing something wrong or did I just encounter a bug perhaps?

        • 1. Re: Problems with Transition of skinned custom components displayed in s:TileGroup
          Ron Pasch Level 1

          A sidenote. If I put a <s:Group> in the skin file around the <s:Rect> tags and move the width="300" height="200" width.photo="140" attributes from the skin tag to the group tag I inserted and have the transition target as the ID of the group tag instead of {this}, then it works as well.

           

          It's a workaround I guess, but I still wonder why it doesn't work when using the width attributes on the skin tag and use {this} in the transition target. It works when using the components in HGroups, but simply not in TileGroups.

          • 2. Re: Problems with Transition of skinned custom components displayed in s:TileGroup
            Shongrunden Adobe Employee

            This took me a while to realize what the issue was.  TileLayout arranges its elements into a grid of "cells" and each cell is of identical size (the size of the largest element).  Then each element is positioned within its own cell by the horizontalAlign/verticalAlign properties.  By default TileLayout has horizontalAlign=justify which means it stretches the element to the size of the cell.  So having a resize effect play on the skin of the element shouldn't really have any effect.  It happens to work when shrinking, but fails growing larger, I assume because increasing the width of one element affects all other cells, whereas decreasing does not.

             

            So I think the right thing to do here is to either wrap a Group around the Rect and target that like you mentioned, or set TileGroup.horizontalAlign to left/center/right.

             

            Here is a simplified sample of how to reproduce this:

            <?xml version="1.0" encoding="utf-8"?>
            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                           xmlns:s="library://ns.adobe.com/flex/spark">
                <fx:Script>
                    <![CDATA[
                        [Bindable] public var test:Boolean = true;
                    ]]>
                </fx:Script>
               
                <fx:Declarations>
                    <fx:Component className="NewSkin">
                        <s:Skin width="150" width.disabled="300" height="50">
                            <s:states>
                                <s:State name="up" />
                                <s:State name="over" />
                                <s:State name="down" />
                                <s:State name="disabled" />
                            </s:states>
                           
                            <s:transitions>
                                <s:Transition fromState="up" toState="disabled" autoReverse="true">
                                    <s:Resize target="{this}" />
                                </s:Transition>
                                <s:Transition fromState="disabled" toState="up" autoReverse="true">
                                    <s:Resize target="{this}"  />
                                </s:Transition>
                            </s:transitions>
                           
                            <s:Rect left="0" right="0" top="0" bottom="0">
                                <s:fill><s:SolidColor color="black" /></s:fill>
                            </s:Rect>
                        </s:Skin>
                    </fx:Component>
                </fx:Declarations>
               
                <s:controlBarContent>
                    <s:Button label="toggle" click="test=!test" />
                </s:controlBarContent>
               
                <s:layout>
                    <s:VerticalLayout />
                </s:layout>
               
                <s:TileGroup>
                    <s:Button skinClass="NewSkin" enabled="{test}" />
                    <s:Button skinClass="NewSkin" enabled="{test}" />
                </s:TileGroup>
               
                <s:TileGroup horizontalAlign="left">
                    <s:Button skinClass="NewSkin" enabled="{test}" />
                    <s:Button skinClass="NewSkin" enabled="{test}" />
                </s:TileGroup>
               
                <s:VGroup>
                    <s:Button skinClass="NewSkin" enabled="{test}" />
                    <s:Button skinClass="NewSkin" enabled="{test}" />
                </s:VGroup>
               
            </s:Application>


            If you'd like you could file a bug about this, but I have a feeling we wouldn't/can't fix it since you probably shouldn't be using horizontalAlign=justify and changing the width of the element at the same time.