Skinning Flex HSLider component. part II

This post is a quick follow up on my last skinning post, since I realized  that I should add some details about the sliderThumb customization.

In order to create our very own sliderThumb UI we created a class that extends SliderThumb (see full code below). But we need to override some method of SliderThumb otherwise the slider won’t be displayed correctly. (e.g. the original triangle thumb will still be visible :s )

In order to remove the legacy thumb there are several tricks.

  1. Reduce the size of the thumb, to make it almost invisible.
  2. Just override the measure() function and set the size to 0*0 

    override protected function measure():void{
                super.measure();
                measuredWidth = 0;
                measuredHeight = 0;
                measuredMinHeight = -1;
                measuredMinWidth = -1;
            }
    

    That ‘s not the best solution since a small glitchy point will remain visible as the thumb. Check below we can see a small ‘blueish’ ball

  3. Apply a transparent skin to the thumb. (Best solution so far)
  4. In the properties of the H/VSlider we can set a thumbSkin and Flex replace the ugly triangle by our image/skin. The trick here is to use a 1 px transparent image as the skin which going to remove the old thumb so we can only see our custom component.

    //in the mxml
    <mx:Style>
    		HSlider{
    			thumbSkin: Embed(source="com/GuN/UI/customUIComponent/slider/empty.png");	
    		}
    	</mx:Style>
    	
    	<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: Panel x="0" y="0" width="527" height="104" layout="absolute" title="Custom Slider" backgroundColor="#000000">
    		<mx:HSlider x="73.5" y="10"
    			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="360"/>
    	</mx: Panel>
    

    Check the result here (once on the page right click to get the src)

Full custom sliderthumb source :

package com.GuN.UI.customUIComponent.slider
{
	import com.GuN.UI.customUIComponent.slider.effect.FadeEffect;
	import com.GuN.UI.customUIComponent.slider.sprites.CSpSprite;
	
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;
	
	import mx.controls.sliderClasses.Slider;
	import mx.controls.sliderClasses.SliderThumb;

	public class CSpSliderThumb extends SliderThumb
	{
		var isMoving:Boolean = false;
		var spr:CSpSprite;
		var gfxFade:FadeEffect;
		var isDisplayed:Boolean = false;
		
			public function CSpSliderThumb()
			{
			
			
			initListeners();
			initSprite();
			
			var shadow: DropShadowFilter = new DropShadowFilter();
				shadow.distance = 3;
				shadow.angle = 45;
				spr.filters = [shadow];
			gfxFade = new FadeEffect(spr);
			spr.alpha = 0;	
			addChild(spr);
			useHandCursor = true;
			
			
			
		}
		
		private function initListeners():void{
			addEventListener(MouseEvent.MOUSE_MOVE, myMouseMoveHandler);
			addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
			addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
		}
		
		
		
		
		private function myMouseMoveHandler(event:MouseEvent):void
			{	
				if (isMoving)
				{
					spr.setValue(String(Slider(owner).values[Slider(owner).value]));
				}
			}
			
			
		private function mouseOver(evt:MouseEvent){
			if(!isDisplayed){
				    isDisplayed = true;
					gfxFade.show = true;
					spr.setValue(String(Slider(owner).values[Slider(owner).value]));
					gfxFade.play();
			}
				
		}
		
		private function mouseOut(evt:MouseEvent){
			if(isDisplayed && !isMoving){
				    isDisplayed = false;
					gfxFade.show = false;
					spr.setValue(String(Slider(owner).values[Slider(owner).value]));
					gfxFade.play();
			}
				
		}
		
		override protected function mouseDownHandler(event:MouseEvent):void
			{
				super.mouseDownHandler(event);
				isMoving = true;
				
				
				
			}
			
		override protected function mouseUpHandler(event:MouseEvent):void
			{
				super.mouseUpHandler(event);
				isMoving = false;
				
            
			}
			
		
		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();
        }
       
        
        override protected function measure():void{
            super.measure();
            measuredWidth = 4;
            measuredHeight = 4;
            measuredMinHeight = -1;
            measuredMinWidth = -1;
        }
        
       
		
	}
}

	

As always drop me an email/ or a comment if you have any question.

Advertisements

9 Responses

  1. Just passing by.Btw, your website have great content!

  2. Hi,

    Very nice work on your custom slider, much cleaner design than the default Flex implementation. Given your apparent expertise at customizing Flex components (esp sliders), figured you’re the right person to ask about that.

    I’m trying to extend the Flex HSlider so that when using two thumbs and showTrackHighlight = “true”, instead of there only being a colored highlight between the thumbs, each track segment would have its own highlight color (e.g., red between left edge of track and left thumb, yellow between the thumbs, and green between the right thumb and right edge).

    Gather that this will likely involve creating a custom skin (or skins) for the track, but I’m a Flex novice and don’t really know where to start.

    Any help is much appreciated!

    Cheers,
    Jeff

  3. doh, meant to check email notification…

  4. […] Component, Flex, Skin, Slider, UI [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 […]

  5. Had trouble with the suggested above (which was not, btw, in the source code…).

    Instead, add this in the Actionscript:
    [Bindable]
    [Embed(source=”com/GuN/UI/customUIComponent/slider/empty.png”)]
    private var EmptyImageClass:Class;

    and in the mx:HSlider, add

    thumbSkin=”{EmptyImageClass}”

    Note that the demo still has the little “.” below the slider, and this fixes that problem.

    Very helpful example! Thanks! I’m building an http://www.apple.com/itunes slider, and the next step is to add text into the slidertrack.

  6. Very helpful. I found that you get rid of the triangle if you set the thumbSkin to null, and don’t call super.updateDisplayList in the subclass to SliderThumb.

    I am a novice to this though and its very possible that this is a very stupid solution…

  7. Hi ,I am using a Flex vslider with double thumb.I need a flex code which will change slider body color in such a fashion so that slider portion below lower thumb will show red color,above upper thumb will show green color and portion between two thumb will show orange color.

  8. @Jim – perhaps you should pay Guillaume to do it then.

  9. I am trying to emulate your custom dataTip but I cannot get the valuesArray to actually show up. Can you help me? In my main app I have created an array with the appropriate values (numbers from 0.01 to 0.09), but they will not show up in the dataTip even though the slider has its “values” property bound to the array.

    my code:

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

    public class CustomDataTipSprite extends Sprite
    {
    private var lbl:TextField;
    private var bkgColor:uint = 0x000000;
    private var bkgAlpha:Number = .3;

    private var textColor:uint = 0x000000;

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

    private function drawText():void{
    lbl.x = 3;
    lbl.y = 0;
    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
    {
    var CsdataTip:Sprite = new Sprite();
    with (CsdataTip.graphics){
    beginFill(bkgColor, bkgAlpha);
    lineTo(10,0);
    lineTo(15,-6);
    lineTo(20,0);
    lineTo(30,0);
    curveTo(40,7.5,30,15);
    lineTo(0,15);
    curveTo(-10,7.5,0,0);
    endFill();
    }
    addChild(CsdataTip);
    CsdataTip.x = 8;
    CsdataTip.y = 0;
    }

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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: