Index: /trunk/as3/com/jeroenwijering/utils/Draw.as
===================================================================
--- /trunk/as3/com/jeroenwijering/utils/Draw.as (revision 2)
+++ /trunk/as3/com/jeroenwijering/utils/Draw.as (revision 4)
@@ -5,6 +5,5 @@
 
 
-import flash.display.DisplayObject;
-import flash.display.Sprite;
+import flash.display.*;
 import flash.geom.Rectangle;
 import flash.text.TextField;
@@ -36,11 +35,8 @@
 	* @return		The clone; not yet added to the displaystack.
 	**/
-	public static function clone(tgt:DisplayObject):DisplayObject {
+	public static function clone(tgt:MovieClip):MovieClip {
 		var cls:Class = Object(tgt).constructor;
-		var dup:DisplayObject = new cls();
+		var dup:MovieClip = new cls();
 		dup.transform = tgt.transform;
-		dup.filters = tgt.filters;
-		dup.cacheAsBitmap = tgt.cacheAsBitmap;
-		dup.opaqueBackground = tgt.opaqueBackground;
 		if(tgt.scale9Grid) {
 			var rct:Rectangle = tgt.scale9Grid;
Index: /trunk/as3/com/jeroenwijering/utils/Strings.as
===================================================================
--- /trunk/as3/com/jeroenwijering/utils/Strings.as (revision 1)
+++ /trunk/as3/com/jeroenwijering/utils/Strings.as (revision 4)
@@ -9,22 +9,4 @@
 
 public class Strings {
-
-
-	/** 
-	* Fit string in a certain textbox, keeping full words. 
-	* 
-	* @param str	The string to chop.
-	* @param fld	The textfield the string should fit into.
-	**/
-	public static function fit(str:String,fld:TextField):String {
-		var wid = fld.width;
-		var lns = Math.round(fld.height/18);
-		var mxm = Math.round(wid*lns/6)-5;
-		if(str.length < mxm || str.indexOf(" ",mxm) == -1) { 
-			return str;
-		} else {
-			return str.substr(0,str.indexOf(" ",mxm)) + ' ..';
-		}
-	};
 
 
Index: /trunk/as3/com/jeroenwijering/utils/Stacker.as
===================================================================
--- /trunk/as3/com/jeroenwijering/utils/Stacker.as (revision 4)
+++ /trunk/as3/com/jeroenwijering/utils/Stacker.as (revision 4)
@@ -0,0 +1,85 @@
+/**
+* Parses children of a MovieClip and docks them to the left & right.
+**/
+
+
+package com.jeroenwijering.utils {
+
+
+import flash.display.MovieClip;
+
+
+public class Stacker {
+
+
+	/** Reference to the clip to stack. **/
+	public var clip:MovieClip;
+	/** SWF skin loader reference **/
+	private var stack:Array;
+	/** Original width of the clip. **/
+	private var _width:Number;
+	/** Latest width of the clip. **/
+	private var latest:Number;
+
+
+	/**
+	* Constructor.
+	*
+	* @param skn	The MovieClip to manage stacking of.
+	**/
+	public function Stacker(clp:MovieClip) {
+		clip = clp;
+		analyze();
+	};
+
+
+	/** Analyze the MovieClip and save its children.  **/
+	private function analyze() {
+		_width = clip.width;
+		stack = new Array();
+		for(var i=0; i<clip.numChildren; i++) {
+			var clp = clip.getChildAt(i);
+			stack.push({c:clp,x:clp.x,n:clp.name,w:clp.width});
+		}
+		stack.sortOn(['x','n'],[Array.NUMERIC,Array.CASEINSENSITIVE]);
+	};
+
+
+	/** Check if an child overlaps with others. **/
+	private function overlaps() { 
+		// working on this...
+	};
+
+
+	/** 
+	* Rearrange the contents of the clip. 
+	*
+	* @param wid	The target width of the clip.
+	**/
+	public function rearrange(wid:Number=undefined) { 
+		if(wid) { latest = wid; }
+		var rdf = latest-width;
+		var ldf = 0;
+		for(var i=0; i<stack.length; i++) {
+			if(stack[i].x > stack[0].w/2) { 
+				stack[i].c.x = stack[i].x + rdf;
+			} else {
+				stack[i].c.x = stack[i].x+ldf;
+			}
+			if(stack[i].w > width/3) {
+				stack[i].c.width = stack[i].w+rdf+ldf;
+			}
+		}
+	};
+
+
+	/** Getter for the original width of the MC. **/
+	public function get width():Number { 
+		return _width;
+	};
+
+
+}
+
+
+}
Index: /trunk/as3/com/jeroenwijering/player/View.as
===================================================================
--- /trunk/as3/com/jeroenwijering/player/View.as (revision 3)
+++ /trunk/as3/com/jeroenwijering/player/View.as (revision 4)
@@ -7,5 +7,4 @@
 import flash.display.MovieClip;
 import flash.events.EventDispatcher;
-import flash.external.ExternalInterface;
 import flash.system.Capabilities;
 import com.jeroenwijering.events.*;
@@ -44,16 +43,10 @@
 		views = new Array();
 		views.push(new CaptionsView(this));
+		views.push(new ControlbarView(this));
 		views.push(new DisplayView(this));
+		views.push(new ExternalView(this));
 		views.push(new KeyboardView(this));
 		views.push(new RightclickView(this));
-		if(_skin['controlbar']) {
-			//views.push(new ControlbarView(this));
-		}
-		if(_skin['playlist']) {
-			//views.push(new PlaylistView(this));
-		}
-		if(ExternalInterface.available || Capabilities.playerType == 'External') {
-			views.push(new ExternalView(this));
-		}
+		views.push(new PlaylistView(this));
 	};
 
Index: /trunk/as3/com/jeroenwijering/player/Player.as
===================================================================
--- /trunk/as3/com/jeroenwijering/player/Player.as (revision 3)
+++ /trunk/as3/com/jeroenwijering/player/Player.as (revision 4)
@@ -21,5 +21,5 @@
 		description:undefined,
 		duration:0,
-		file:'http://www.jeroenwijering.com/upload/mrss.xml',
+		file:'http://www.jeroenwijering.com/upload/xspf.xml',
 		image:undefined,
 		link:undefined,
@@ -28,7 +28,7 @@
 		type:undefined,
 
-		controlbar:'bottom',
+		controlbar:'over',
 		logo:undefined,
-		playlist:'none',
+		playlist:'bottom',
 		playlistsize:180,
 		skin:undefined,
@@ -37,4 +37,5 @@
 		bufferlength:1,
 		caption:true,
+		digits:true,
 		displayclick:'play',
 		fullscreen:false,
@@ -50,5 +51,5 @@
 		aboutlink:"http://www.jeroenwijering.com/?page=about",
 		linktarget:'_self',
-		streamscript:'lighttpd',
+		streamscript:undefined,
 		tracecall:undefined,
 
Index: /trunk/as3/com/jeroenwijering/views/ControlbarView.as
===================================================================
--- /trunk/as3/com/jeroenwijering/views/ControlbarView.as (revision 3)
+++ /trunk/as3/com/jeroenwijering/views/ControlbarView.as (revision 4)
@@ -7,4 +7,5 @@
 import com.jeroenwijering.events.*;
 import com.jeroenwijering.player.View;
+import com.jeroenwijering.utils.Stacker;
 import com.jeroenwijering.utils.Strings;
 import flash.display.MovieClip;
@@ -22,11 +23,9 @@
 	/** Reference to the view. **/
 	private var view:View;
-	/** A list with all controls docked to the left. **/
-	private var left:Array;
-	/** A list with all controls docked to the right. **/
-	private var right:Array;
+	/** A list with all controls. **/
+	private var stacker:Stacker;
 	/** Reference to the controlbar **/
 	private var bar:MovieClip;
-	/** Save whether slading is enabled. **/
+	/** Save whether sliding is enabled. **/
 	private var sliding:Boolean;
 	/** Timeout for hiding the bar. **/
@@ -37,5 +36,4 @@
 	public function ControlbarView(vie:View) {
 		view = vie;
-		view.addControllerListener(ControllerEvent.CAPTION,captionHandler);
 		view.addControllerListener(ControllerEvent.ITEM,itemHandler);
 		view.addControllerListener(ControllerEvent.MUTE,muteHandler);
@@ -46,4 +44,5 @@
 		view.addModelListener(ModelEvent.TIME,timeHandler);
 		bar = view.skin['controlbar'];
+		stacker = new Stacker(bar);
 		bar.addEventListener(MouseEvent.CLICK, clickHandler);
 		bar.timeSlider.addEventListener(MouseEvent.MOUSE_DOWN,timeslideHandler);
@@ -51,47 +50,9 @@
 		bar.volumeSlider.addEventListener(MouseEvent.MOUSE_DOWN,volumeslideHandler);
 		bar.volumeSlider.addEventListener(MouseEvent.MOUSE_OUT,outHandler);
-		checkButtons();
 		loadedHandler(new ModelEvent(ModelEvent.LOADED,{loaded:0,total:0}));
-		captionHandler(new ControllerEvent(ControllerEvent.CAPTION,{percentage:view.config['caption']}));
 		muteHandler(new ControllerEvent(ControllerEvent.MUTE,{state:view.config['mute']}));
 		stateHandler(new ModelEvent(ModelEvent.STATE,{newstate:ModelStates.IDLE}));
 		timeHandler(new ModelEvent(ModelEvent.TIME,{position:0,duration:0}));
 		volumeHandler(new ControllerEvent(ControllerEvent.VOLUME,{percentage:view.config['volume']}));
-	};
-
-
-	/** Handle a change in the current item **/
-	private function captionHandler(evt:ControllerEvent) {
-		if(evt.data.state == true) { 
-			try {
-				bar.captionButton.icn.visible = true;
-				bar.captionButton.alt.visible = false;
-			} catch (err:Error) {}
-		} else {
-			try {
-				bar.captionButton.icn.visible = false;
-				bar.captionButton.alt.visible = true;
-			} catch (err:Error) {}
-		}
-	};
-
-
-	/** Check which buttons are available and save their positions. **/
-	private function checkButtons() {
-		var mid = bar.width/2;
-		left = new Array();
-		right = new Array();
-		for(var i=0; i<bar.numChildren; i++) {
-			var clp = bar.getChildAt(i);
-			clp.buttonMode = true;
-			clp.mouseChildren = false;
-			if(clp.x < mid) {
-				left.push({c:clp,x:clp.x,n:clp.name,w:clp.width});
-			} else {
-				right.push({c:clp,x:clp.x,n:clp.name,w:clp.width});
-			}
-		}
-		left.sortOn(['x','n'],[Array.NUMERIC,Array.CASEINSENSITIVE]);
-		right.sortOn('x',Array.DESCENDING | Array.NUMERIC);
 	};
 
@@ -111,44 +72,21 @@
 
 
-	/** Returns whether the control should be hidden. **/
-	private function hideButton(nam:String):Boolean {
-		var obj = view.playlist[view.config['item']];
-		switch(nam) {
-			case 'prevButton':
-			case 'nextButton':
-				if(view.playlist.length < 2) {
-					return true;
-				}
-				break;
-			case 'elapsedText':
-			case 'remainingText':
-			case 'totalText':
-				if(bar.back.width < 200) {
-					return true;
-				}
-				break;
-			case 'linkButton':
-				if(!obj || !obj['link']) {
-					return true;
-				}
-				break;
-			case 'fullscreenButton':
-				if(view.config['fullscreen'] == false || bar.stage.displayState == null) {
-					return true;
-				}
-				break;
-			case 'captionButton':
-				if(!obj || !obj['captions']) {
-					return true;
-				}
-				break;
-		}
-		return false;
-	};
-
-
 	/** Handle a change in the current item **/
 	private function itemHandler(evt:ControllerEvent) {
-		setButtons();
+		if(view.playlist.length > 1) { 
+			bar.prevButton.visible = bar.nextButton.visible = true;
+		} else {
+			bar.prevButton.visible = bar.nextButton.visible = false;
+		}
+		if(view.playlist[view.config['item']]['link']) { 
+			bar.linkButton.visible = true;
+		} else { 
+			bar.linkButton.visible = false;
+		}
+		if(view.config['digits'] == false) {
+			bar.elapsedText.visible = bar.totalText.visible = false;
+		} else { 
+			bar.elapsedText.visible = bar.totalText.visible = true;
+		}
 	};
 
@@ -165,7 +103,7 @@
 		}
 		try {
-			var wid = bar.timeSlider.bck.width;
-			bar.timeSlider.bar.x = Math.round(pc2*wid);
-			bar.timeSlider.bar.width = Math.round(pc1*wid);  
+			var wid = bar.timeSlider.rail.width;
+			bar.timeSlider.mark.x = Math.round(pc2*wid);
+			bar.timeSlider.mark.width = Math.round(pc1*wid);  
 		} catch (err:Error) {}
 	};
@@ -191,11 +129,11 @@
 	private function muteHandler(evt:ControllerEvent) {
 		if(evt.data.state == true) { 
-			bar.muteButton.icn.visible = false;
-			bar.muteButton.alt.visible = true;
-			bar.volumeSlider.bar.visible = false;
-		} else {
-			bar.muteButton.icn.visible = true;
-			bar.muteButton.alt.visible = false;
-			bar.volumeSlider.bar.visible = true;
+			bar.muteButton.visible = false;
+			bar.unmuteButton.visible = true;
+			bar.volumeSlider.mark.visible = false;
+		} else {
+			bar.muteButton.visible = true;
+			bar.unmuteButton.visible = false;
+			bar.volumeSlider.mark.visible = true;
 		}
 	};
@@ -210,31 +148,34 @@
 	/** Process resizing requests **/
 	private function resizeHandler(evt:ControllerEvent) {
-		if(view.config['controlbar'] == 'above' || evt.data.fullscreen == true) {
+		var wid = stacker.width;
+		if(view.config['controlbar'] == 'over' || evt.data.fullscreen == true) {
 			bar.y = evt.data.height - view.config['controlbarsize']*2;
 			if(evt.data.width > 640) { 
-				bar.x = Math.round(evt.data.width/2 - 300);
-				try { bar.back.width = 600; } catch (err:Error) {}
+				bar.x = Math.round(evt.data.width/2-300);
+				wid = 600;
 			} else { 
 				bar.x = view.config['controlbarsize'];
-				try { bar.back.width = evt.data.width - view.config['controlbarsize']*2;  } catch (err:Error) {}
+				wid = evt.data.width - view.config['controlbarsize']*2;
 			}
 		} else {
 			bar.x = 0;
-			try { bar.back.width = evt.data.width;  } catch (err:Error) {}
+			wid = evt.data.width;
 			bar.y = evt.data.height;
-			if(view.config['playlist'] == 'right') { 
-				try { bar.back.width += view.config['playlistsize'];  } catch (err:Error) {}
+			if(view.config['playlist'] == 'right') {
+				wid += view.config['playlistsize'];
 			}
 		}
-		try { 
-			if(evt.data.fullscreen == true) { 
-				bar.fullscreenButton.icn.visible = false;
-				bar.fullscreenButton.alt.visible = true;
-			} else { 
-				bar.fullscreenButton.icn.visible = true;
-				bar.fullscreenButton.alt.visible = false;
-			}
-		} catch (err:Error) {}
-		setButtons();
+		if(view.config['fullscreen'] == false || bar.stage.displayState == null) {
+			bar.fullscreenButton.visible = false;
+			bar.normalscreenButton.visible = false;
+		} else if(evt.data.fullscreen == true) {
+			bar.fullscreenButton.visible = false;
+			bar.normalscreenButton.visible = true;
+		} else {
+			bar.fullscreenButton.visible = false;
+			bar.normalscreenButton.visible = true;
+		}
+		stacker.rearrange(wid);
+		bar.timeSlider.icon.scaleX = 1/bar.timeSlider.scaleX;
 	};
 
@@ -242,8 +183,8 @@
 	/** Send the new scrub position to the controller **/
 	private function sendScrub(evt:MouseEvent) {
-		bar.timeSlider.icn.stopDrag();
-		var xps = bar.timeSlider.icn.x - bar.timeSlider.bck.x;
+		bar.timeSlider.icon.stopDrag();
+		var xps = bar.timeSlider.icon.x - bar.timeSlider.rail.x;
 		var dur = view.playlist[view.config['item']]['duration'];
-		var pct = Math.round(xps*dur*10/bar.timeSlider.bck.width)/10;
+		var pct = Math.round(xps*dur*10/bar.timeSlider.rail.width)/10;
 		view.sendEvent(ViewEvent.SEEK,pct);
 	}
@@ -252,41 +193,8 @@
 	/** Send the new volume to the controlbar **/
 	private function sendVolume(evt:MouseEvent) {
-		bar.volumeSlider.icn.stopDrag();
-		var xps = bar.volumeSlider.icn.x - bar.volumeSlider.sld.x;
-		var pct = Math.round(xps*100/bar.volumeSlider.sld.width);
+		bar.volumeSlider.icon.stopDrag();
+		var xps = bar.volumeSlider.icon.x - bar.volumeSlider.rail.x;
+		var pct = Math.round(xps*100/bar.volumeSlider.mark.width);
 		view.sendEvent(ViewEvent.VOLUME,pct);
-	};
-
-
-	/** Set all buttons to their correct positions. **/
-	private function setButtons() {
-		var rdf = bar.back.width-left[0].w;
-		var ldf = 0;
-		for(var i=0; i<right.length; i++) {
-			if(hideButton(right[i].n)) {
-				right[i].c.visible = false;
-				rdf += right[i-1].x - right[i].x;
-			} else { 
-				right[i].c.visible = true;
-				right[i].c.x = right[i].x + rdf;
-			}
-		}
-		for(var j=0; j<left.length; j++) {
-			if(hideButton(left[j].n)) {
-				left[j].c.visible = false;
-				ldf += left[j+1].x - left[j].x;
-			} else {
-				left[j].c.visible = true;
-				left[j].c.x = left[j].x - ldf;
-			}
-			if(left[j].n == 'timeSlider') {
-				var old = bar.timeSlider.bck.width;
-				var wid = left[j].w+rdf+ldf;
-				bar.timeSlider.bck.width = wid;
-				bar.timeSlider.bar.width *= wid/old;
-				bar.timeSlider.bar.x *= wid/old;
-				bar.timeSlider.icn.x = Math.round(bar.timeSlider.icn.x*wid/old);
-			}
-		}
 	};
 
@@ -301,6 +209,6 @@
 				}
 			case ModelStates.BUFFERING:
-				bar.playButton.icn.visible = false;
-				bar.playButton.alt.visible = true;
+				bar.playButton.visible = false;
+				bar.pauseButton.visible = true;
 				break;
 			default: 
@@ -310,6 +218,6 @@
 					view.skin.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
 				}
-				bar.playButton.icn.visible = true;
-				bar.playButton.alt.visible = false;
+				bar.playButton.visible = true;
+				bar.pauseButton.visible = false;
 				break;
 		}
@@ -320,18 +228,14 @@
 	private function timeHandler(evt:ModelEvent) {
 		var dur = evt.data.duration;
-		try {
-			bar.elapsedText.txt.text = Strings.digits(evt.data.position);
-			bar.totalText.txt.text = Strings.digits(evt.data.duration);
-		} catch(err:Error) {}
+		bar.elapsedText.field.text = Strings.digits(evt.data.position);
+		bar.totalText.field.text = Strings.digits(evt.data.duration)
 		var pct = evt.data.position/evt.data.duration;
-		try {
-			var xps = Math.floor(pct*bar.timeSlider.bck.width);
-			if (dur <= 0) {
-				bar.timeSlider.icn.visible = false;
-			} else {
-				bar.timeSlider.icn.visible = true;
-				bar.timeSlider.icn.x = xps;
-			}
-		} catch(err:Error) {}
+		var xps = Math.floor(pct*bar.timeSlider.rail.width);
+		if (dur <= 0) {
+			bar.timeSlider.icon.visible = false;
+		} else {
+			bar.timeSlider.icon.visible = true;
+			bar.timeSlider.icon.x = xps;
+		}
 	};
 
@@ -339,6 +243,6 @@
 	/** Handle a move over the timeslider **/
 	private function timeslideHandler(evt:MouseEvent) {
-		var rct = new Rectangle(bar.timeSlider.bck.x,bar.timeSlider.icn.y,bar.timeSlider.bck.width,0);
-		bar.timeSlider.icn.startDrag(true,rct);
+		var rct = new Rectangle(bar.timeSlider.rail.x,bar.timeSlider.icon.y,bar.timeSlider.rail.width,0);
+		bar.timeSlider.icon.startDrag(true,rct);
 		sliding = true;
 	};
@@ -347,5 +251,5 @@
 	/** Reflect the new volume in the controlbar **/
 	private function volumeHandler(evt:ControllerEvent) {
-		bar.volumeSlider.bar.scaleX = evt.data.percentage/100;
+		bar.volumeSlider.mark.scaleX = evt.data.percentage/100;
 	};
 
@@ -353,6 +257,6 @@
 	/** Handle a move over the volume bar **/
 	private function volumeslideHandler(evt:MouseEvent) {
-		var rct = new Rectangle(bar.volumeSlider.sld.x,bar.volumeSlider.icn.y,bar.volumeSlider.sld.width,0);
-		bar.volumeSlider.icn.startDrag(true,rct);
+		var rct = new Rectangle(bar.volumeSlider.rail.x,bar.volumeSlider.icon.y,bar.volumeSlider.rail.width,0);
+		bar.volumeSlider.icon.startDrag(true,rct);
 		sliding = true;
 	};
Index: /trunk/as3/com/jeroenwijering/views/DisplayView.as
===================================================================
--- /trunk/as3/com/jeroenwijering/views/DisplayView.as (revision 3)
+++ /trunk/as3/com/jeroenwijering/views/DisplayView.as (revision 4)
@@ -163,4 +163,8 @@
 			setIcon('bufferIcon');
 		} else {
+			if(view.config['playlist'] == 'over') { 
+				setIcon();
+				return;
+			}
 			switch(view.config.displayclick) {
 				case 'play':
Index: /trunk/as3/com/jeroenwijering/views/PlaylistView.as
===================================================================
--- /trunk/as3/com/jeroenwijering/views/PlaylistView.as (revision 3)
+++ /trunk/as3/com/jeroenwijering/views/PlaylistView.as (revision 4)
@@ -7,8 +7,11 @@
 import com.jeroenwijering.events.*;
 import com.jeroenwijering.player.View;
-import com.jeroenwijering.utils.Draw;
+import com.jeroenwijering.utils.*;
+import flash.display.Loader;
 import flash.display.MovieClip;
+import flash.events.Event;
 import flash.events.MouseEvent;
 import flash.geom.Rectangle;
+import flash.net.URLRequest;
 import flash.utils.setInterval;
 import flash.utils.clearInterval;
@@ -25,5 +28,7 @@
 	private var buttons:Array;
 	/** Height of a button (to calculate scrolling) **/
-	private var buttonsize:Number;
+	private var buttonheight:Number;
+	/** Currently active button. **/
+	private var active:Number;
 	/** Proportion between clip and mask. **/
 	private var proportion:Number;
@@ -34,15 +39,21 @@
 	public function PlaylistView(vie:View) {
 		view = vie;
-		clip = view.skin['playlist'];
-		clip.visible = false;
 		view.addControllerListener(ControllerEvent.ITEM,itemHandler);
 		view.addControllerListener(ControllerEvent.PLAYLIST,playlistHandler);
 		view.addControllerListener(ControllerEvent.RESIZE,resizeHandler);
-		buttonsize = clip.scrollClip.getChildByName('button').height;
-		clip.list.mask = clip.scrollMask;
+		view.addModelListener(ModelEvent.STATE,stateHandler);
+		clip = view.skin['playlist'];
+		buttonheight = clip.list.button.height;
+		clip.list.button.visible = false;
+		clip.list.mask = clip.masker;
 		clip.slider.buttonMode = true;
 		clip.slider.mouseChildren = false;
+		clip.list.addEventListener(MouseEvent.CLICK,clickHandler);
+		clip.list.addEventListener(MouseEvent.MOUSE_OVER,overHandler);
+		clip.list.addEventListener(MouseEvent.MOUSE_OUT,outHandler);
+		clip.list.addEventListener(MouseEvent.MOUSE_UP,stopHandler);
 		clip.slider.addEventListener(MouseEvent.MOUSE_DOWN,startHandler);
-		view.skin.addEventListener(MouseEvent.MOUSE_UP,stopHandler);
+		clip.visible = false;
+		trace(clip);
 	};
 
@@ -52,30 +63,34 @@
 		var wid = clip.back.width;
 		var hei = clip.back.height;
-		proportion = view.playlist.length*buttonsize/hei;
+		proportion = view.playlist.length*buttonheight/hei;
 		if (proportion > 1) {
 			wid -=20;
-			buildScroller();
+			buildSlider();
 		} else {
-			clip.scrollBar.visible = false;
-		}
-		clip.scrollMask.height = hei;
-		clip.scrollMask.width = wid;
+			clip.slider.visible = false;
+		}
+		clip.masker.height = hei;
+		clip.masker.width = wid;
 		if(clr) {
-			clip.scrollClip.y = 0;
-			Draw.clear(clip.scrollClip);
+			clip.list.y = 0;
+			Draw.clear(clip.list);
 			buttons = new Array();
+			clip.visible= true;
+		} else { 
+			if(proportion > 1) { scrollCheck(); }
 		}
 		for(var i=0; i<view.playlist.length; i++) {
-			if(clr) { 
-				var btn = Draw.clone(clip.scrollClip.getChildByName('button')); 
-				// new PlaylistButton(i,wid,view);
-				clip.scrollClip.addChild(btn);
-				buttons.push(btn);
-			} else { 
-				buttons[i].resize(wid);
-				if(proportion > 1) { 
-					scrollCheck();
-				}
-			}
+			if(clr) {
+				var btn = Draw.clone(clip.list.button);
+				clip.list.addChild(btn);
+				var stc = new Stacker(btn);
+				btn.y = i*buttonheight;
+				btn.buttonMode = true;
+				btn.mouseChildren =false;
+				btn.name = i;
+				buttons.push({c:btn,s:stc});
+				setContents(i);
+			}
+			buttons[i].s.rearrange(wid);
 		}
 	};
@@ -83,9 +98,9 @@
 
 	/** Setup the scrollbar component **/
-	private function buildScroller() {
-		var scr = clip.scrollBar;
+	private function buildSlider() {
+		var scr = clip.slider;
 		scr.visible = true;
-		scr.x = clip.back.width - scr.width;
-		var dif = clip.back.height - scr.height;
+		scr.x = clip.back.width-scr.width;
+		var dif = clip.back.height-scr.height;
 		scr.back.height += dif;
 		scr.rail.height += dif;
@@ -94,7 +109,43 @@
 
 
+	/** Handle a click on a button. **/
+	private function clickHandler(evt:MouseEvent) {
+		view.sendEvent('item',Number(evt.target.name));
+	};
+
+
 	/** Switch the currently active item */
 	private function itemHandler(evt:ControllerEvent) {
-		// code for highlighting a certain button.
+		var idx = evt.data.index;
+		if(!isNaN(active)) {
+			buttons[active].c.gotoAndStop('out');
+		}
+		buttons[idx].c.gotoAndStop('active');
+		active = idx;
+	};
+
+
+	/** Loading of image completed; resume loading **/
+	private function loaderHandler(evt:Event) {
+		var ldr = Loader(evt.target.loader);
+		Stretcher.stretch(ldr,ldr.mask.width,ldr.mask.height,Stretcher.FILL);
+	};
+
+
+	/** Handle a button rollover. **/
+	private function overHandler(evt:MouseEvent) {
+		var idx = Number(evt.target.name);
+		buttons[idx].c.gotoAndStop('over');
+	};
+
+
+	/** Handle a button rollover. **/
+	private function outHandler(evt:MouseEvent) {
+		var idx = Number(evt.target.name);
+		if(idx == active) {
+			buttons[idx].c.gotoAndStop('active');
+		} else { 
+			buttons[idx].c.gotoAndStop('out');
+		}
 	};
 
@@ -102,5 +153,7 @@
 	/** New playlist loaded: rebuild the playclip. **/
 	private function playlistHandler(evt:ControllerEvent) {
-		buildList(true);
+		if(view.config['playlist'] != 'none') { 
+			buildList(true);
+		}
 	};
 
@@ -109,30 +162,20 @@
 	private function resizeHandler(evt:ControllerEvent) {
 		if(view.config['playlist'] == 'right') {
-			clip.visible = true;
 			clip.x = evt.data.width;
 			clip.y = 0;
 			clip.back.width = view.config['playlistsize'];
 			clip.back.height = evt.data.height;
-		} else if (view.config['playlist'] == 'below') {
-			clip.visible = true;
+		} else if (view.config['playlist'] == 'bottom') {
 			clip.x = 0;
 			clip.y = evt.data.height;
-			if (view.config['controlbar'] == 'below') {
+			if (view.config['controlbar'] == 'bottom') {
 				clip.y += view.config['controlbarsize'];
 			}
 			clip.back.height = view.config['playlistsize'];
 			clip.back.width = evt.data.width;
-		} else if (view.config['playlist'] == 'above') {
-			clip.visible = true;
-			var wid = evt.data.width-2*view.config['controlbarsize'];
-			var hei = evt.data.height-2*view.config['controlbarsize'];
-			if(evt.data.width > 640) { wid = 600; }
-			if(view.config['controlbar'] == 'above') { hei -= 2*view.config['controlbarsize']; }
-			clip.x = Math.round(evt.data.width/2 - wid/2);
-			clip.y = view.config['controlbarsize'];
-			clip.back.height = hei;
-			clip.back.width = wid;
-		} else { 
-			clip.visible = false;
+		} else if (view.config['playlist'] == 'over') {
+			clip.x = clip.y = 0;
+			clip.back.height = evt.data.height;
+			clip.back.width = evt.data.width;
 		}
 		buildList(false);
@@ -142,11 +185,11 @@
 	/** Make sure the playlist is not out of range. **/
 	private function scrollCheck() {
-		var scr = clip.scrollBar;
-		if(clip.scrollClip.y > 0) {
-			clip.scrollClip.y = 0;
+		var scr = clip.slider;
+		if(clip.list.y > 0) {
+			clip.list.y = 0;
 			scr.icon.y = scr.rail.y;
-		} else if (clip.scrollClip.y < clip.scrollMask.height-clip.scrollClip.height) {
+		} else if (clip.list.y < clip.masker.height-clip.list.height) {
 			scr.icon.y = scr.rail.y+scr.rail.height-scr.icon.height;
-			clip.scrollClip.y = clip.scrollMask.height-clip.scrollClip.height;
+			clip.list.y = clip.masker.height-clip.list.height;
 		}
 	};
@@ -155,11 +198,38 @@
 	/** Scrolling handler. **/
 	private function scrollHandler() {
-		var scr = clip.scrollBar;
+		var scr = clip.slider;
 		var yps = scr.mouseY;
 		var ips = yps - scr.icon.height/2;
-		var cps = clip.scrollMask.y+clip.scrollMask.height/2-proportion*yps;
+		var cps = clip.masker.y+clip.masker.height/2-proportion*yps;
 		scr.icon.y = Math.round(ips - (ips-scr.icon.y)/1.5);
-		clip.scrollClip.y = Math.round((cps - (cps-clip.scrollClip.y)/1.5));
+		clip.list.y = Math.round((cps - (cps-clip.list.y)/1.5));
 		scrollCheck();
+	};
+
+
+	/** Setup button elements **/
+	private function setContents(idx:Number) {
+		for (var itm in view.playlist[idx]) {
+			if(!buttons[idx].c[itm]) {
+				continue;
+			} else if(itm == 'image') {
+				var ldr = new Loader();
+				buttons[idx].c.addChild(ldr);
+				ldr.x = buttons[idx].c.image.x;
+				ldr.y = buttons[idx].c.image.y;
+				ldr.mask = buttons[idx].c.image;
+				ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderHandler);
+				ldr.load(new URLRequest(view.playlist[idx]['image']));
+			} else if(itm == 'duration') {
+				if(view.playlist[idx][itm] > 0) {
+					buttons[idx].c[itm].field.text = Strings.digits(view.playlist[idx][itm]);
+				}
+			} else {
+				buttons[idx].c[itm].field.text = view.playlist[idx][itm];
+			}
+		}
+		if(!view.playlist[idx]['image'] && buttons[idx].c['image']) {
+			buttons[idx].c['image'].visible = false;
+		}
 	};
 
@@ -172,4 +242,15 @@
 	};
 
+	/** Process state changes **/
+	private function stateHandler(evt:ModelEvent) {
+		if(view.config['playlist'] == 'over') {
+			if(evt.data.newstate == ModelStates.PLAYING || evt.data.newstate == ModelStates.BUFFERING) {
+				clip.visible = false;
+			} else {
+				clip.visible = true;
+			}
+		}
+	};
+
 
 	/** Stop scrolling the playlist. **/
@@ -179,6 +260,4 @@
 
 
-
-
 };
 
Index: /unk/as3/com/jeroenwijering/views/PlaylistButton.as
===================================================================
--- /trunk/as3/com/jeroenwijering/views/PlaylistButton.as (revision 3)
+++  (revision )
@@ -1,99 +1,0 @@
-/**
-* Placeholder class for a playlistbutton.
-**/
-package com.jeroenwijering.views {
-
-
-import com.jeroenwijering.player.View;
-import com.jeroenwijering.utils.*;
-import flash.display.Loader;
-import flash.display.MovieClip;
-import flash.events.Event;
-import flash.events.MouseEvent;
-import flash.net.URLRequest;
-import flash.text.TextField;
-
-
-
-public class PlaylistButton extends MovieClip {
-
-
-	/** Playlist index of this button. **/
-	private var index:Number;
-	/** Reference to the view (to access config & playlist). **/
-	private var view:View;
-	/** Loader for loading the thumbnail. **/
-	private var loader:Loader;
-	/** Maximum width of the button. **/
-	private var buttonsize:Number;
-
-
-	/** Constructor; saves vars. **/
-	public function PlaylistButton(idx:Number=undefined,wid:Number=undefined,vie:View=undefined) {
-		super();
-		index = idx;
-		buttonsize = back.width;
-		view = vie;
-		if(view) {
-			resize(wid);
-			setElements(); 
-		}
-	};
-
-
-	/** Setup button elements **/
-	private function setElements() {
-		this.y = this.height*index;
-		if(title && view.playlist[index]['title']) {
-			title.tf.text = Strings.fit(view.playlist[index]['title'],title.tf);
-		}
-		if(description && view.playlist[index]['description']) {
-			var dsc = Strings.strip(view.playlist[index]['description']);
-			description.tf.text = Strings.fit(dsc,description.tf);
-		}
-		if(view.playlist[index]['duration'] > 0) {
-			duration.tf.text = Strings.digits(view.playlist[index]['duration']);
-		} else { 
-			duration.visible = false;
-		}
-		if(view.playlist[index]['image']) {
-			loader = new Loader();
-			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderHandler);
-			loader.load(new URLRequest(view.playlist[index]['image']));
-		}
-		buttonMode = true;
-		mouseChildren =false;
-		addEventListener(MouseEvent.CLICK,clickHandler);
-		resize(buttonsize);
-	};
-
-
-	/** Loading of image completed; resume loading **/
-	private function loaderHandler(evt:Event) {
-		var itm = addChild(loader);
-		Stretcher.stretch(itm,image.width,image.height,Stretcher.FILL);
-		itm.mask = image;
-	}
-
-
-	/** Handle a click on the button. **/
-	private function clickHandler(evt:MouseEvent) {
-		view.sendEvent('item',index);
-	};
-
-
-	/** Resize the button if the stage changes **/
-	public function resize(wid:Number) { 
-		var dif = wid - buttonsize;
-		buttonsize = wid;
-		back.width = buttonsize;
-		duration.x = buttonsize - duration.width;
-		title.tf.width += dif;
-		description.tf.width += dif;
-	};
-
-
-};
-
-
-}
