Skins - Get Properties From Parent Component

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Skins - Get Properties From Parent Component

bilbosax
I have created a simple button skin that has rounded corners that I want to
look like a pill-button.  I want it to work no matter how large or small the
button is.  The main visual object in the skin is of course a <Rect> object
that I will have to set the radius parameters on to round out the button. To
get this to work, you need to be able to get the size of the button that is
applied to the parent, and then apply those dimensions to the <Rect> in the
skin.  I thought that I could use the "parent" property to get the width and
height of the button that I was placing the skin on, but this is
unfortunately not working.  The skin code looks like the following:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
                                   xmlns:s="library://ns.adobe.com/flex/spark"
                                   xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
                                   minWidth="20" minHeight="20"
                                   alpha.disabled="0.5" xmlns:fxgAssets="fxgAssets.*"
creationComplete="init(event)">
       
        <fx:Metadata>
               
        </fx:Metadata>
        <fx:Script>
               
        </fx:Script>
       
       
       
        <s:states>
                <s:State name="up" />
                <s:State name="over" />
                <s:State name="down" />
                <s:State name="disabled" />
        </s:states>
       
        <s:Rect id="buttonRect" width="100%" height="100%">
                <s:fill>
                        <s:SolidColor color.up="#323233" color.down="#2B8D00"/>
                </s:fill>
        </s:Rect>
        <s:Label id="labelDisplay" color="#FAFAFA" horizontalCenter="0"
verticalCenter="0"/>
       
</s:SparkButtonSkin>


You can see that in the init() method on creationcomplete, I trace out
this.parent.height which is tracing 41 pixels, but the actual height of the
button is tracing out as 61.44 pixels, so using "parent" to get the
dimensions of the parent component is not working and is giving an
undesireable number.  How can I go about getting the X and Y dimensions of
the button component from within the skin so that I can apply the correct
radius values to the <Rect> in my skin??

Thanks for any thoughts or guesses at all.



--
Sent from: http://apache-flex-users.2333346.n4.nabble.com/
Reply | Threaded
Open this post in threaded view
|

Re: Skins - Get Properties From Parent Component

bilbosax
I think I figured it out, or at least found a workaround.  When I was tracing
out the button dimensions in both the original button and on the skin, the
skin value was tracing out BEFORE the button value, and of course giving an
erroneous value.  I believe that because of the way that I manually lay out
the display objects in my app, the creationComplete event in the skin was
firing BEFORE the width and height of the actual button were being set.  So
I stopped using creationComplete on the skin, and switched to updateComplete
and then all of the width/height dimensions started tracing out correctly
and the <Rect> component started to draw correctly.

The only other problem I ran into is that I could SEE the button redraw
itself an instant after it displayed which looked unprofessional, so I used
setTimeout to give it 100 ms before I made the skin visible.  Now it looks
perfect.  So my final skin code looks like this:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
                                   xmlns:s="library://ns.adobe.com/flex/spark"
                                   xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
                                   minWidth="20" minHeight="20"
                                   alpha.disabled="0.5" xmlns:fxgAssets="fxgAssets.*"
updateComplete="sizeRect(event)" visible="false">
       
        <fx:Metadata>
               
        </fx:Metadata>
        <fx:Script>
               
        </fx:Script>
       
       
       
        <s:states>
                <s:State name="up" />
                <s:State name="over" />
                <s:State name="down" />
                <s:State name="disabled" />
        </s:states>
       
        <s:Rect id="buttonRect" width="100%" height="100%">
                <s:fill>
                        <s:SolidColor color.up="#323233" color.down="#2B8D00"/>
                </s:fill>
        </s:Rect>
        <s:Label id="labelDisplay" color="#FAFAFA" horizontalCenter="0"
verticalCenter="0"/>
       
</s:SparkButtonSkin>



--
Sent from: http://apache-flex-users.2333346.n4.nabble.com/
Reply | Threaded
Open this post in threaded view
|

Re: Skins - Get Properties From Parent Component

Alex Harui-2
MXML skins are meant to be declarative. As in:
-I declare this label to be red
-I declare the background to be white.

But then, sometimes you can't declare it at compile time and need to figure it out at runtime.  Most of the time, binding expressions can be used as they are also declarative:
-I want the label to be half way across the component: <label x="{width/2}" />

If you can use a binding expression, the binding subsystem should evaluate the binding before the screen is refreshed.

In some cases, it is too much of a pain to create a binding expression.  There are often APIs you can override.  I think ButtonSkin has an updateDisplayList method.

HTH,
-Alex

´╗┐On 12/27/19, 1:12 PM, "bilbosax" <[hidden email]> wrote:

    I think I figured it out, or at least found a workaround.  When I was tracing
    out the button dimensions in both the original button and on the skin, the
    skin value was tracing out BEFORE the button value, and of course giving an
    erroneous value.  I believe that because of the way that I manually lay out
    the display objects in my app, the creationComplete event in the skin was
    firing BEFORE the width and height of the actual button were being set.  So
    I stopped using creationComplete on the skin, and switched to updateComplete
    and then all of the width/height dimensions started tracing out correctly
    and the <Rect> component started to draw correctly.
   
    The only other problem I ran into is that I could SEE the button redraw
    itself an instant after it displayed which looked unprofessional, so I used
    setTimeout to give it 100 ms before I made the skin visible.  Now it looks
    perfect.  So my final skin code looks like this:
   
    <?xml version="1.0" encoding="utf-8"?>
    <s:SparkButtonSkin xmlns:fx="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fmxml%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7C886e37e5681f410ecc9b08d78b116d1e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637130779292453190&amp;sdata=Fjtk4aAktSRr5p4JMV5lINa0vWTXoMtdh4zcrLar77U%3D&amp;reserved=0"
      xmlns:s="library://ns.adobe.com/flex/spark"
      xmlns:fb="https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fns.adobe.com%2Fflashbuilder%2F2009&amp;data=02%7C01%7Caharui%40adobe.com%7C886e37e5681f410ecc9b08d78b116d1e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637130779292463185&amp;sdata=kUBD0VwmTaWqoNO%2BvB1jq3OkIkCEtQONmg5%2FPJyDqH8%3D&amp;reserved=0"
      minWidth="20" minHeight="20"
      alpha.disabled="0.5" xmlns:fxgAssets="fxgAssets.*"
    updateComplete="sizeRect(event)" visible="false">
   
    <fx:Metadata>
   
    </fx:Metadata>
    <fx:Script>
   
    </fx:Script>
   
   
   
    <s:states>
    <s:State name="up" />
    <s:State name="over" />
    <s:State name="down" />
    <s:State name="disabled" />
    </s:states>
   
    <s:Rect id="buttonRect" width="100%" height="100%">
    <s:fill>
    <s:SolidColor color.up="#323233" color.down="#2B8D00"/>
    </s:fill>
    </s:Rect>
    <s:Label id="labelDisplay" color="#FAFAFA" horizontalCenter="0"
    verticalCenter="0"/>
   
    </s:SparkButtonSkin>
   
   
   
    --
    Sent from: https://nam04.safelinks.protection.outlook.com/?url=http%3A%2F%2Fapache-flex-users.2333346.n4.nabble.com%2F&amp;data=02%7C01%7Caharui%40adobe.com%7C886e37e5681f410ecc9b08d78b116d1e%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C637130779292463185&amp;sdata=yCCadE26g9zOH5mBKD9OkOUdMwbqJ2pxvjyZTu3FW4Y%3D&amp;reserved=0
   

Reply | Threaded
Open this post in threaded view
|

Re: Skins - Get Properties From Parent Component

bilbosax
This post was updated on .
Alex, to be honest, I have become accustomed to avoiding binding expressions
due to performance hits, especially with large array collections and
dataproviders.  I assign everything manually these days. I have become sooooo accustomed to doing this, that it
didn't even cross my mind to use a binding expression.  But binding expressions are brilliant in this
situation and streamlines the process considerably, getting rid of two
unneccessary methods and a timing mechanism that can't be 100% relied upon.
Thanks for this simple but very useful solution.  Here is what the skin code
looks like now:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
                                   xmlns:s="library://ns.adobe.com/flex/spark"
                                   xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
                                   minWidth="20" minHeight="20"
                                   alpha.disabled="0.5" xmlns:fxgAssets="fxgAssets.*">
       
        <fx:Metadata>
               
        </fx:Metadata>       
       
       
        <s:states>
                <s:State name="up" />
                <s:State name="over" />
                <s:State name="down" />
                <s:State name="disabled" />
        </s:states>
       
        <s:Rect id="buttonRect" width="100%" height="100%"
bottomLeftRadiusX="{height/2}" bottomLeftRadiusY="{height/2}"
bottomRightRadiusX="{height/2}" bottomRightRadiusY="{height/2}"
topLeftRadiusX="{height/2}" topLeftRadiusY="{height/2}"
topRightRadiusX="{height/2}" topRightRadiusY="{height/2}">
                <s:fill>
                        <s:SolidColor color.up="#2B8D00" color.down="#323233"/>
                </s:fill>
        </s:Rect>
        <s:Label id="labelDisplay" color="#FAFAFA" styleName="titleMedium"
fontWeight="bold" horizontalCenter="0" verticalCenter="0"/>
        <s:Rect width="100%" height="100%" alpha="0" includeIn="up, over, down,
disabled">
                <s:fill>
                        <s:SolidColor color="#FFFFFF"/>
                </s:fill>
        </s:Rect>
       
</s:SparkButtonSkin>



--
Sent from: http://apache-flex-users.2333346.n4.nabble.com/
Reply | Threaded
Open this post in threaded view
|

Re: Skins - Get Properties From Parent Component

Greg Dove
You can also access other properties on the 'parent' component that the
skin is attached to if they are bindable as well.
{hostComponent.whateverHere}

And of course for custom components/custom skins you can define the host
component's type via [HostComponent()] metadata inside the skin's
fx:Metadata tag.

Mobile skins used to be quite important to try to avoid bindings in and
instead use actionscript based skins. But they might even be ok with using
mxml and bindings in today's mobile devices.
A lot of things got so much faster simply by time going by.
It's been a while since I used Flex 4 skinning now. Miss it a lot!


On Mon, Dec 30, 2019 at 4:18 PM bilbosax <[hidden email]> wrote:

> Alex, to be honest, I have become accustomed to avoiding binding
> expressions
> due to performance hits, especially with large array collections and
> dataproviders.  I have become sooooo accustomed to doing this, that it
> didn't even cross my mind.  But a binding expressions are brilliant in this
> situation and streamlines the process considerably, getting rid of two
> unneccessary methods and a timing mechanism that can't be 100% relied
> upon.
> Thanks for this simple but very useful solution.  Here is what the skin
> code
> looks like now:
>
> <?xml version="1.0" encoding="utf-8"?>
> <s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
>                                    xmlns:s="library://
> ns.adobe.com/flex/spark"
>                                    xmlns:fb="
> http://ns.adobe.com/flashbuilder/2009"
>                                    minWidth="20" minHeight="20"
>                                    alpha.disabled="0.5"
> xmlns:fxgAssets="fxgAssets.*">
>
>         <fx:Metadata>
>
>         </fx:Metadata>
>
>
>         <s:states>
>                 <s:State name="up" />
>                 <s:State name="over" />
>                 <s:State name="down" />
>                 <s:State name="disabled" />
>         </s:states>
>
>         <s:Rect id="buttonRect" width="100%" height="100%"
> bottomLeftRadiusX="{height/2}" bottomLeftRadiusY="{height/2}"
> bottomRightRadiusX="{height/2}" bottomRightRadiusY="{height/2}"
> topLeftRadiusX="{height/2}" topLeftRadiusY="{height/2}"
> topRightRadiusX="{height/2}" topRightRadiusY="{height/2}">
>                 <s:fill>
>                         <s:SolidColor color.up="#2B8D00"
> color.down="#323233"/>
>                 </s:fill>
>         </s:Rect>
>         <s:Label id="labelDisplay" color="#FAFAFA" styleName="titleMedium"
> fontWeight="bold" horizontalCenter="0" verticalCenter="0"/>
>         <s:Rect width="100%" height="100%" alpha="0" includeIn="up, over,
> down,
> disabled">
>                 <s:fill>
>                         <s:SolidColor color="#FFFFFF"/>
>                 </s:fill>
>         </s:Rect>
>
> </s:SparkButtonSkin>
>
>
>
> --
> Sent from: http://apache-flex-users.2333346.n4.nabble.com/
>
Reply | Threaded
Open this post in threaded view
|

Re: Skins - Get Properties From Parent Component

Kessler CTR Mark J-2
In reply to this post by bilbosax
Side note, to add to the discussion, here is a couple of ways to also update properties in code for <s:Skin> and <s:SparkSkin> with  [1] and [2].


[1]
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
    doStuff();

    super.updateDisplayList(unscaledWidth, unscaledHeight);
}


[2]
//
override public function styleChanged(styleProp:String):void
{
    If (styleProper == "myStyleName")
    {
        doStuff();
    }
}


-Mark K

-----Original Message-----
From: bilbosax <[hidden email]>
Sent: Sunday, December 29, 2019 10:27 PM
To: [hidden email]
Subject: [Non-DoD Source] Re: Skins - Get Properties From Parent Component

Alex, to be honest, I have become accustomed to avoiding binding expressions
due to performance hits, especially with large array collections and
dataproviders.  I have become sooooo accustomed to doing this, that it
didn't even cross my mind.  But a binding expressions are brilliant in this
situation and streamlines the process considerably, getting rid of two
unneccessary methods and a timing mechanism that can't be 100% relied upon.
Thanks for this simple but very useful solution.  Here is what the skin code
looks like now:

<?xml version="1.0" encoding="utf-8"?>
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
                                   xmlns:s="library://ns.adobe.com/flex/spark"
                                   xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
                                   minWidth="20" minHeight="20"
                                   alpha.disabled="0.5" xmlns:fxgAssets="fxgAssets.*">

        <fx:Metadata>

        </fx:Metadata>


        <s:states>
                <s:State name="up" />
                <s:State name="over" />
                <s:State name="down" />
                <s:State name="disabled" />
        </s:states>

        <s:Rect id="buttonRect" width="100%" height="100%"
bottomLeftRadiusX="{height/2}" bottomLeftRadiusY="{height/2}"
bottomRightRadiusX="{height/2}" bottomRightRadiusY="{height/2}"
topLeftRadiusX="{height/2}" topLeftRadiusY="{height/2}"
topRightRadiusX="{height/2}" topRightRadiusY="{height/2}">
                <s:fill>
                        <s:SolidColor color.up="#2B8D00" color.down="#323233"/>
                </s:fill>
        </s:Rect>
        <s:Label id="labelDisplay" color="#FAFAFA" styleName="titleMedium"
fontWeight="bold" horizontalCenter="0" verticalCenter="0"/>
        <s:Rect width="100%" height="100%" alpha="0" includeIn="up, over, down,
disabled">
                <s:fill>
                        <s:SolidColor color="#FFFFFF"/>
                </s:fill>
        </s:Rect>

</s:SparkButtonSkin>



--
Sent from: http://apache-flex-users.2333346.n4.nabble.com/