Flex AutoResizable Textarea

I’ve been quite busy those past weeks, working on some great projects and cool devices (Stay tune one will be available in all high tech shops soon).

Recently, I faced a very simple Flex problem. I had to work with a Textarea but I needed it to be autoresizable, and ALSO I had be able to set so constraints such as : maxchars displayed and maxheight. I had a quick look on the internet but I didn’t find a conponent fitting my needs. You may find some example using mx_internal properties but I try to avoid using this namespace…for many reasons.

Anyway, I crafted my own Autoresizable Textarea and share it to everyone who want to play with/improve/crash/burn/..etc it.


///////////////////////////////
// Author: Guillaume Nachury
//
//         Advanced Textarea
//
// -> Auoresize feature with
//             -> MaxChar limiter
//            -> MaxHeight limiter
///////////////////////////////

package
{
 import mx.controls.TextArea;

 public class AdvancedTextarea extends TextArea
 {

 private var _autoResize:Boolean =  false;
 private var _lineOffset:int = 5;
 public var fullText:String="";

 public function AdvancedTextarea(isAutoResize:Boolean=false)
 {
 super();
 _autoResize = isAutoResize;
 }

 //overrides        
 override public function set maxChars(i:int):void{
 super.maxChars = i;
 doValidations();
 }

 override public function set maxHeight(n:Number):void{
 super.maxHeight = n;
 doValidations();
 }

 override public function set text(s:String):void{
 //limit the number of chars if there's a limit
 fullText = s;
 if(super.maxChars>0 && s.length > super.maxChars){
 s = s.substring(0, super.maxChars)+"...";    
 super.text = s;
 }
 super.text = s;

 validateNow();
 doValidations();
 }

 private function doValidations():void{
 if(super.text != null && super.text.length >0){

 //limit the height if there's a limit
 if(!isNaN(super.maxHeight)){
 var textH:int = this.textField.measuredHeight+_lineOffset;
 if(textH > super.maxHeight && _autoResize == true){
 this.height = super.maxHeight;
 }
 else{
 if(_autoResize == true)    this.height = this.textField.measuredHeight+_lineOffset;

 }

 }
 else{
 if(_autoResize == true){
 this.height = this.textField.measuredHeight+_lineOffset;
 }

 }
 }
 }

 public function set autoResize(b:Boolean):void{
 _autoResize = b;
 doValidations();
 }

 }
}

Advertisements

Skinning a Flex Slider

[a part II of this post is available here]
It’s been a long long time since my last post but I recently move to my new apartment and it ISP forgot to move my internet access…It was a bit annoying at the beginning since I could not work on the version of NURVE, but I had a lot of time to explore new Flex features and especially customizing/creating UI components. I had so much fun doing this that I gonna write few posts on it.

The first component I worked on was the Slider (actually HSlider), because I think it’s the component that can be used in numerous cases and also because most of the time it doesn’t fit our my UI needs. Sorry to all the GREAT developers that worked on Flex UI components but the default Slider is just ugly…

Fortunately they add a cool feature that allow everyone to  customize the look and feel. (I think it’s important to understand that some of the time it may be interesting to change the look but changing the feel is also really important.) I won’t talk about the styles we can apply via CSS, but instead, how to use the sliderThumbClass and the trackSkin from the Slider Object.

Before jumping into the code, lets have a look to the result :

As you can see, no more default UI and a ‘Tooltip’ more useful. I used this Slider in one of my project where I had to navigate thru archives.

Ok so as I said I used sliderThumbClass to modify the ThumbSlider UI and the trackSkin in order to change the track of the slider.

The track skin:

This part is really easy, we just have to create a UIComponent with the desired shape. So just Create a new Class that extends UIComponent and override updateDisplayList function with your code that draws the shape you want.

package com.GuN.UI.customUIComponent.slider
{
	import mx.core.UIComponent;

	public class SliderTrack extends UIComponent
	{
			override public function get height():Number{
	            return 20;
	        }

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

            //create 2 circle that will act like round corners
            this.graphics.beginFill(0xFFFFFF,1);
            this.graphics.drawCircle(0,0,5);
            this.graphics.drawCircle(unscaledWidth,0,5);
            this.graphics.endFill();
            //create the line that represents the track
            this.graphics.moveTo(0,0);
            this.graphics.lineStyle(10,0xFFFFFF);
            this.graphics.lineTo(unscaledWidth,0);

        }

	}
}

I could use a drawRoundRect() aswell, but I will explain that on an other component customization post.
Ok now the track is now done, let’s have a look to the Thumb.

The slider Thumb

My Slider have a really simple thumb, it’s actually just a black circle. Like what we’ve done for the the track, we’ll do exactly the same for the Thumb. So create a class extends SliderThumb to inherit the behavior of a slider and override the updateDisplayList function.

package com.GuN.UI.customUIComponent.slider
{
	import mx.controls.sliderClasses.SliderThumb;

	public class CSpSliderThumb extends SliderThumb
	{

public function CSpSliderThumb()
		{
			super();
}

           override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
            super.updateDisplayList(unscaledWidth,unscaledHeight);
            this.graphics.beginFill(0x000000,1);
            this.graphics.drawCircle(2,-8,4);
           	this.graphics.endFill();
        }
     }
}

At this point you have a new slider without any cool effect. You can still continue using the default datatooltip but you can also create your very own datatooltip UI. On my slider I added a Sprite beneath the Thumb to display the data while sliding.

Here is the code for the datatip container :

package com.GuN.UI.customUIComponent.slider.sprites
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	public class CSpSprite extends Sprite
	{
		var lbl:TextField;
		var bkgColor:uint = 0x000000;
		var bkgAlpha:Number = .5;

		var textColor:uint = 0xFFFFFF;

		public function CSpSprite()
		{
			super();
			lbl = new TextField();
			drawShape();
			drawText();

		}

		private function drawText():void{
			lbl.x = -10;
			lbl.y = 3;
			lbl.autoSize = TextFieldAutoSize.CENTER;
            lbl.background = false;
            lbl.border = false;

            var format:TextFormat = new TextFormat();
            format.font = "Verdana";
            format.color = textColor;
            format.size = 9;
            format.underline = false;

            lbl.defaultTextFormat = format;
            addChild(lbl);
		}

		private function drawShape():void
		{

			this.graphics.beginFill(bkgColor,bkgAlpha);
			this.graphics.lineTo(35,0);
			this.graphics.lineTo(40,-9);
			this.graphics.lineTo(45,0);
			this.graphics.lineTo(80,0);
			this.graphics.lineTo(80,25);
			this.graphics.lineTo(0,25);
			this.graphics.lineTo(0,0);
			this.graphics.endFill();

			//Create a white border
			this.graphics.lineStyle(1, 0xFFFFFF, 1);
			this.graphics.moveTo(-1,-1);
			this.graphics.lineTo(34,-1);
			this.graphics.lineTo(39,-10);
			this.graphics.lineTo(44,-1);
			this.graphics.lineTo(79,-1);
			this.graphics.lineTo(79,24);
			this.graphics.lineTo(-1,24);
			this.graphics.lineTo(-1,-1);

		}

		public function setValue(v:String):void{
			lbl.text = v;
		}

	}
}

We can add our datatipcontainer to the SliderThumbClass we created before

package com.GuN.UI.customUIComponent.slider
{
	import mx.controls.sliderClasses.SliderThumb;

	public class CSpSliderThumb extends SliderThumb
	{

public function CSpSliderThumb()
		{
			super();
			initSprite();
			addChild(spr);

		}

private function initSprite():void{
			spr = new CSpSprite();
			spr.x = -(spr.width/2)+4;
			spr.y = 9;
		}

           override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
            super.updateDisplayList(unscaledWidth,unscaledHeight);
            this.graphics.beginFill(0x000000,1);
            this.graphics.drawCircle(2,-8,4);
           	this.graphics.endFill();
        }
     }
}

Now that our Slider is almost done, we can create the mxml that will house the custom slider. Like I said I used this slider to navigate thru archives so used an array of values that contains all the months that had to work with.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundGradientAlphas="&#91;1.0, 1.0&#93;" backgroundGradientColors="&#91;#353535, #353535&#93;">
	<mx:Script>
		<!&#91;CDATA&#91;
			import com.GuN.UI.customUIComponent.slider.SliderTrack;
			import com.GuN.UI.customUIComponent.slider.CSpSliderThumb;

			var arrayValues:Array = &#91;"null","January '08", "February '08", "March '08", "April '08", "May '08", "June '08", "July '08", "August '08",
										"September '08", "October '08", "November '08", "December '08"&#93;;

		&#93;&#93;>
	</mx:Script>

		<mx:HSlider x="10" y="107"
		id="s"
		showDataTip="false"
		values="{arrayValues}"
		creationComplete="{s.value=1}"
		snapInterval="1"
		minimum="1"
		maximum="{arrayValues.length-1}"
		liveDragging="true"
		trackSkin="{SliderTrack}"
		sliderThumbClass="{CSpSliderThumb}"
		 width="502"/>

</mx:Application>

For more details you can have look to the sources my work, as usual you can freely reuse/hack my code. 
By the way, if you wanna see cool effects check Chet Haase’s ‘Codedependent’ Blog and especially the Spring is in the AIR? post which is really interesting.

NURVE – Public alpha release

I’m pretty excited today since I’m releasing the first public alpha version of a project I’m working on, based on Adobe AIR/FLEX and Papervision3D , called NURVE.

NURVE is 3D, film trailers browser with an iTunes coverflow like navigation experience. NURVE allows you to browse the newest films trailers and watch them in HD quality on any, internet connected, OS that have AIR installed

Preview:

 

As my first shot with both FLEX and Papervision3D and since NURVE is still under development you may find some bugs/glitches or suggestions so please drop me an email or leave a comment here.

=> Download NURVE  (don’t forget to install Adobe AIR  )

Expected in the new release:

  • more 3D animations
  • film information displayed
  • some fix 
  • new icons
  • more films source

 

Like most of my works, I will release le source code as soon as most of the bugs are fixed;)