Round cornered TextInput – Spark SDK

Just ran into this problem to create a rounded corner textbox for my flex application Flex 4 Spark SDK. I found there is no option for cornerRadius, i tried many ways to achieve that, finally i just created a custom skin based on the default TextInputSkin and applied that skin to the TextInput skinClass.

Here's the code snippet for RoundedTextInputSkin.

<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
			 xmlns:s="library://ns.adobe.com/flex/spark"
			 alpha.disabled="0.5"
			 blendMode="normal">

	<fx:Metadata>
		<![CDATA[
		/**
		* @copy spark.skins.spark.ApplicationSkin#hostComponent
		*/
		[HostComponent("spark.components.TextInput")]
		]]>
	</fx:Metadata>

	<fx:Script>
		private var paddingChanged:Boolean;

		/* Define the skin elements that should not be colorized. */
		static private const exclusions:Array=["background", "textDisplay"];

		/**
		 * @copy spark.skins.SparkSkin#colorizeExclusions
		 */
		override public function get colorizeExclusions():Array
		{
			return exclusions;
		}

		/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
		static private const contentFill:Array=["bgFill"];

		/**
		 * @inheritDoc
		 */
		override public function get contentItems():Array
		{
			return contentFill
		}
		;

		/**
		 *  @private
		 */
		override protected function commitProperties():void
		{
			super.commitProperties();

			if (paddingChanged)
			{
				updatePadding();
				paddingChanged=false;
			}
		}

		/**
		 *  @private
		 */
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			if (getStyle("borderVisible") == true)
			{
				border.visible=true;
				shadow.visible=true;
				background.left=background.top=background.right=background.bottom=2;
				textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
			}
			else
			{
				border.visible=false;
				shadow.visible=false;
				background.left=background.top=background.right=background.bottom=0;
				textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
			}

			super.updateDisplayList(unscaledWidth, unscaledHeight);
		}

		/**
		 *  @private
		 */
		private function updatePadding():void
		{
			if (!textDisplay)
				return;

			// Push padding styles into the textDisplay
			var padding:Number;

			padding=getStyle("paddingLeft");
			if (textDisplay.getStyle("paddingLeft") != padding)
				textDisplay.setStyle("paddingLeft", padding);

			padding=getStyle("paddingTop");
			if (textDisplay.getStyle("paddingTop") != padding)
				textDisplay.setStyle("paddingTop", padding);

			padding=getStyle("paddingRight");
			if (textDisplay.getStyle("paddingRight") != padding)
				textDisplay.setStyle("paddingRight", padding);

			padding=getStyle("paddingBottom");
			if (textDisplay.getStyle("paddingBottom") != padding)
				textDisplay.setStyle("paddingBottom", padding);
		}

		/**
		 *  @private
		 */
		override public function styleChanged(styleProp:String):void
		{
			super.styleChanged(styleProp);

			if (!styleProp || styleProp.indexOf("padding") == 0)
			{
				paddingChanged=true;
				invalidateProperties();
			}
		}

		/**
		 * @inheritDoc
		 */
		override public function get focusSkinExclusions():Array
		{
			return [textDisplay]
		}
		;
	</fx:Script>

	<s:states>
		<s:State name="normal"/>
		<s:State name="disabled"/>
	</s:states>

	<!-- border -->
	<s:Rect left="0"
			right="0"
			top="0"
			bottom="0"
			id="border"
			radiusX="10">
		<s:stroke>
			<s:SolidColorStroke color="{getStyle('borderColor')}"
								alpha="{getStyle('borderAlpha')}"
								weight="2"/>
		</s:stroke>
	</s:Rect>

	<!-- fill -->
	<!--- Defines the appearance of the TextInput component's background. -->
	<s:Rect id="background"
			left="1"
			right="1"
			top="1"
			bottom="1"
			radiusX="10">
		<s:fill>
			<!--- Defines the background fill color. -->
			<s:SolidColor id="bgFill"
						  color="0xFFFFFF"/>
		</s:fill>
	</s:Rect>

	<!-- text -->
	<s:RichEditableText id="textDisplay"
						lineBreak="explicit"
						verticalAlign="middle"
						widthInChars="10"
						left="1"
						right="1"
						top="1"
						bottom="1"/>

</s:SparkSkin>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
alpha.disabled="0.5"
blendMode="normal">

<fx:Metadata>
<![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
[HostComponent("spark.components.TextInput")]
]]>
</fx:Metadata>

<fx:Script>
private var paddingChanged:Boolean;

/* Define the skin elements that should not be colorized. */
static private const exclusions:Array=["background", "textDisplay"];

/**
* @copy spark.skins.SparkSkin#colorizeExclusions
*/
override public function get colorizeExclusions():Array
{
return exclusions;
}

/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
static private const contentFill:Array=["bgFill"];

/**
* @inheritDoc
*/
override public function get contentItems():Array
{
return contentFill
}
;

/**
*  @private
*/
override protected function commitProperties():void
{
super.commitProperties();

if (paddingChanged)
{
updatePadding();
paddingChanged=false;
}
}

/**
*  @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if (getStyle("borderVisible") == true)
{
border.visible=true;
shadow.visible=true;
background.left=background.top=background.right=background.bottom=2;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
}
else
{
border.visible=false;
shadow.visible=false;
background.left=background.top=background.right=background.bottom=0;
textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
}

super.updateDisplayList(unscaledWidth, unscaledHeight);
}

/**
*  @private
*/
private function updatePadding():void
{
if (!textDisplay)
return;

// Push padding styles into the textDisplay
var padding:Number;

padding=getStyle("paddingLeft");
if (textDisplay.getStyle("paddingLeft") != padding)
textDisplay.setStyle("paddingLeft", padding);

padding=getStyle("paddingTop");
if (textDisplay.getStyle("paddingTop") != padding)
textDisplay.setStyle("paddingTop", padding);

padding=getStyle("paddingRight");
if (textDisplay.getStyle("paddingRight") != padding)
textDisplay.setStyle("paddingRight", padding);

padding=getStyle("paddingBottom");
if (textDisplay.getStyle("paddingBottom") != padding)
textDisplay.setStyle("paddingBottom", padding);
}

/**
*  @private
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);

if (!styleProp || styleProp.indexOf("padding") == 0)
{
paddingChanged=true;
invalidateProperties();
}
}

/**
* @inheritDoc
*/
override public function get focusSkinExclusions():Array
{
return [textDisplay]
}
;
</fx:Script>

<s:states>
<s:State name="normal"/>
<s:State name="disabled"/>
</s:states>

<!-- border -->
<s:Rect left="0"
right="0"
top="0"
bottom="0"
id="border"
radiusX="10">
<s:stroke>
<s:SolidColorStroke color="{getStyle('borderColor')}"
alpha="{getStyle('borderAlpha')}"
weight="2"/>
</s:stroke>
</s:Rect>

<!-- fill -->
<!--- Defines the appearance of the TextInput component's background. -->
<s:Rect id="background"
left="1"
right="1"
top="1"
bottom="1"
radiusX="10">
<s:fill>
<!--- Defines the background fill color. -->
<s:SolidColor id="bgFill"
color="0xFFFFFF"/>
</s:fill>
</s:Rect>

<!-- shadow -->
<s:Rect left="1"
top="1"
right="1"
height="1"
id="shadow">
<s:fill>
<s:SolidColor color="0x000000"
alpha="0"/>
</s:fill>
</s:Rect>

<!-- text -->
<s:RichEditableText id="textDisplay"
lineBreak="explicit"
verticalAlign="middle"
widthInChars="10"
left="1"
right="1"
top="1"
bottom="1"/>

</s:SparkSkin>

Be Sociable, Share!

18 Responses to “Round cornered TextInput – Spark SDK”

  1. jess says:

    This is perfect thanks! I think it is lame that adobe threw this away. I thought spark components were supposed to be better.

  2. Thilo says:

    Hi KBala,

    when I use the skin I get the error message “Required skin part popUp cannot be found”. I didn’t learn about skin parts yet, so I don’t have a clue about it. It seems the skin cannot be used generically. I’m using Flex 4 with Air 2.

    Thanks, Thilo

  3. Rob says:

    I love you, ive been tryin to do this all day.

  4. prasad says:

    Works well! thanks a lot for sharing.

    Regards

  5. Agraj says:

    Hi Bala,

    Thanks for sharing the code. Though I have a question for you. I see a lot of duplicated code from TextInputSkin from the Spark SDK.

    Can we not extend the basic TextInputSkin from our custom skin class (RoundedTextInputSkin) and implement only those methods which are needed for the new functionality ??

    Thanks,
    Agraj

  6. ilikeflex says:

    When i use the skin i am getting the error
    “shadow” should be initialized.

    This shadow is being used in updateDisplayList method.

    I am 4.1.0 sdk.

  7. digsafe says:

    I had the same issue as ilikeflex.
    I fixed by adding a shadow (note I tweaked this for a text box with a radiusX of 8).




  8. digsafe says:

    Grrr… hate comments that don’t recognize code
    Lemme try again;

    <!– SHADOW –>

    <s:Rect left=”5″ top=”0″ right=”5″ height=”1″id=”shadow1″>
    <s:fill>
    <s:SolidColor color=”0x000000″ alpha=”0.3″ />
    </s:fill>
    </s:Rect>

    <s:Rect left=”2″ top=”1″ right=”2″ height=”2″ id=”shadow2″>
    <s:fill>
    <s:SolidColor color=”0x000000″ alpha=”0.15″ />
    </s:fill>
    </s:Rect>

    <s:Rect left=”0″ top=”3″ right=”0″ height=”1″ id=”shadow3″>
    <s:fill>
    <s:SolidColor color=”0x000000″ alpha=”0.08″ />
    </s:fill>
    </s:Rect>

  9. Manu Mohan says:

    Thanks.This was exactly what i wanted.

  10. Thanks for spending the time to discuss this, I feel strongly about it and love studying more on this topic. If possible, as you change into an expert, would you mind updating your blog with more details?

  11. Rahul says:

    Hi ,

    I wanted to make the textinput show a magnifying glass image on the left side of the screen.(just like that in any browser)
    but i cannot do so .

    Can you please help me with it.

  12. Rahul says:

    Hi ,

    I wanted to make the text=-input show a magnifying glass image on the left side of the screen.(just like that in any browser)
    but i cannot do so .

    Can you please help me with it.

  13. jassi says:

    Can someone please help me with creating a custom skin without any border and have background color of my own.

    Thanks in advance.

  14. Arun says:

    Thnx for the code….but wen i used this for text input it shows the two states are missing that is…. normalWithPrompt and disabledWithPrompt. so i just added these two states and declared it.. so i finally got the output…. i was happy with that output…. here is the code that i had done….

    private var paddingChanged:Boolean;

    /* Define the skin elements that should not be colorized. */
    static private const exclusions:Array=[“background”, “textDisplay”];

    /**
    * @copy spark.skins.SparkSkin#colorizeExclusions
    */
    override public function get colorizeExclusions():Array
    {
    return exclusions;
    }

    /* Define the content fill items that should be colored by the “contentBackgroundColor” style. */
    static private const contentFill:Array=[“bgFill”];

    /**
    * @inheritDoc
    */
    override public function get contentItems():Array
    {
    return contentFill
    }
    ;

    /**
    * @private
    */
    override protected function commitProperties():void
    {
    super.commitProperties();

    if (paddingChanged)
    {
    updatePadding();
    paddingChanged=false;
    }
    }

    /**
    * @private
    */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
    if (getStyle(“borderVisible”) == true)
    {
    border.visible=true;
    //shadow.visible=true;
    background.left=background.top=background.right=background.bottom=2;
    textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
    }
    else
    {
    border.visible=false;
    //shadow.visible=false;
    background.left=background.top=background.right=background.bottom=0;
    textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
    }

    super.updateDisplayList(unscaledWidth, unscaledHeight);
    }

    /**
    * @private
    */
    private function updatePadding():void
    {
    if (!textDisplay)
    return;

    // Push padding styles into the textDisplay
    var padding:Number;

    padding=getStyle(“paddingLeft”);
    if (textDisplay.getStyle(“paddingLeft”) != padding)
    textDisplay.setStyle(“paddingLeft”, padding);

    padding=getStyle(“paddingTop”);
    if (textDisplay.getStyle(“paddingTop”) != padding)
    textDisplay.setStyle(“paddingTop”, padding);

    padding=getStyle(“paddingRight”);
    if (textDisplay.getStyle(“paddingRight”) != padding)
    textDisplay.setStyle(“paddingRight”, padding);

    padding=getStyle(“paddingBottom”);
    if (textDisplay.getStyle(“paddingBottom”) != padding)
    textDisplay.setStyle(“paddingBottom”, padding);
    }

    /**
    * @private
    */
    override public function styleChanged(styleProp:String):void
    {
    super.styleChanged(styleProp);

    if (!styleProp || styleProp.indexOf(“padding”) == 0)
    {
    paddingChanged=true;
    invalidateProperties();
    }
    }

    /**
    * @inheritDoc
    */
    override public function get focusSkinExclusions():Array
    {
    return [textDisplay]
    }
    ;


  15. Arun says:

    private var paddingChanged:Boolean;

    /* Define the skin elements that should not be colorized. */
    static private const exclusions:Array=[“background”, “textDisplay”];

    /**
    * @copy spark.skins.SparkSkin#colorizeExclusions
    */
    override public function get colorizeExclusions():Array
    {
    return exclusions;
    }

    /* Define the content fill items that should be colored by the “contentBackgroundColor” style. */
    static private const contentFill:Array=[“bgFill”];

    /**
    * @inheritDoc
    */
    override public function get contentItems():Array
    {
    return contentFill
    }
    ;

    /**
    * @private
    */
    override protected function commitProperties():void
    {
    super.commitProperties();

    if (paddingChanged)
    {
    updatePadding();
    paddingChanged=false;
    }
    }

    /**
    * @private
    */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
    if (getStyle(“borderVisible”) == true)
    {
    border.visible=true;
    //shadow.visible=true;
    background.left=background.top=background.right=background.bottom=2;
    textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=2;
    }
    else
    {
    border.visible=false;
    //shadow.visible=false;
    background.left=background.top=background.right=background.bottom=0;
    textDisplay.left=textDisplay.top=textDisplay.right=textDisplay.bottom=0;
    }

    super.updateDisplayList(unscaledWidth, unscaledHeight);
    }

    /**
    * @private
    */
    private function updatePadding():void
    {
    if (!textDisplay)
    return;

    // Push padding styles into the textDisplay
    var padding:Number;

    padding=getStyle(“paddingLeft”);
    if (textDisplay.getStyle(“paddingLeft”) != padding)
    textDisplay.setStyle(“paddingLeft”, padding);

    padding=getStyle(“paddingTop”);
    if (textDisplay.getStyle(“paddingTop”) != padding)
    textDisplay.setStyle(“paddingTop”, padding);

    padding=getStyle(“paddingRight”);
    if (textDisplay.getStyle(“paddingRight”) != padding)
    textDisplay.setStyle(“paddingRight”, padding);

    padding=getStyle(“paddingBottom”);
    if (textDisplay.getStyle(“paddingBottom”) != padding)
    textDisplay.setStyle(“paddingBottom”, padding);
    }

    /**
    * @private
    */
    override public function styleChanged(styleProp:String):void
    {
    super.styleChanged(styleProp);

    if (!styleProp || styleProp.indexOf(“padding”) == 0)
    {
    paddingChanged=true;
    invalidateProperties();
    }
    }

    /**
    * @inheritDoc
    */
    override public function get focusSkinExclusions():Array
    {
    return [textDisplay]
    }
    ;


  16. srvikram13 says:

    Just what I was looking for..

    Thanks!

Leave a Reply


Copyright © 2008-2010 K BalaSubramanian | Credits