• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
Locked
0

Skins - Get Properties From Parent Component

Engaged ,
Dec 27, 2019 Dec 27, 2019

Copy link to clipboard

Copied

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>
		<![CDATA[ 
		[HostComponent("spark.components.Button")]
		]]>
	</fx:Metadata>
	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;
			
			protected function init(event:FlexEvent):void
			{
				trace(this.parent.height);
				buttonRect.bottomLeftRadiusX = this.parent.height/2.0;
				buttonRect.bottomLeftRadiusY = this.parent.height/2.0;
				buttonRect.bottomRightRadiusX = this.parent.height/2.0;
				buttonRect.bottomRightRadiusY = this.parent.height/2.0;
				buttonRect.topLeftRadiusX = this.parent.height/2.0;
				buttonRect.topLeftRadiusY = this.parent.height/2.0;
				buttonRect.topRightRadiusX = this.parent.height/2.0;
				buttonRect.topRightRadiusY = this.parent.height/2.0;
			}
		]]>
	</fx:Script>
	
	
	<!-- states -->
	<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:Rect width="100%" height="100%" alpha="0" includeIn="up, over, down, disabled">
		<s:fill>
			<s:SolidColor color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
	
</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.

TOPICS
Development , Performance issues , Product issue

Views

359

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Engaged , Dec 30, 2019 Dec 30, 2019

Ok, I am not a big fan of data binding because of the performance hits you can take with large arraycollections and dataproviders, I prefer to set my associations manually - much better performance.  But in this case, it turns out that using bindings is the best way to go.  Because of the way that data binding logic seems to work, it all gets handled in a skin before the screen gets refreshed, so I don't have to rely on a unreliable timing mechanism to try and get the effect that I want as in my

...

Votes

Translate

Translate
Engaged ,
Dec 27, 2019 Dec 27, 2019

Copy link to clipboard

Copied

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>
		<![CDATA[ 
		[HostComponent("spark.components.Button")]
		]]>
	</fx:Metadata>
	<fx:Script>
		<![CDATA[
			import flash.utils.setTimeout;
			
			import mx.events.FlexEvent;
			
			protected function sizeRect(event:Event):void
			{
				buttonRect.radiusX = this.parent.height/2.0;
				buttonRect.radiusY = this.parent.height/2.0;
				setTimeout(changeVisibility, 100);
			}
			
			protected function changeVisibility():void {
				this.visible = true;
			}			
			
		]]>
	</fx:Script>
	
	
	<!-- states -->
	<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>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 30, 2019 Dec 30, 2019

Copy link to clipboard

Copied

LATEST

Ok, I am not a big fan of data binding because of the performance hits you can take with large arraycollections and dataproviders, I prefer to set my associations manually - much better performance.  But in this case, it turns out that using bindings is the best way to go.  Because of the way that data binding logic seems to work, it all gets handled in a skin before the screen gets refreshed, so I don't have to rely on a unreliable timing mechanism to try and get the effect that I want as in my workaround above.  So my final code for a pill-shaped button skin 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.*">
	
	<fx:Metadata>
		<![CDATA[ 
		[HostComponent("spark.components.Button")]
		]]>
	</fx:Metadata>	
	
	<!-- states -->
	<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:SparkButtonSkin>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines