List with custom ScrollBar

The Application:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" xmlns:controls="com.mariosh.controls.*" viewSourceURL="srcview/index.html"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; [Bindable] private var ac:ArrayCollection; private function init():void { ac = new ArrayCollection(); for(var i:int=0; i<30; i++) { var item:Object = new Object(); item.label = "item " + i; ac.addItem(item); } } ]]> </mx:Script> <controls:BasicList x="10" y="10" width="100" height="200" dataProvider="{ac}" verticalScrollPolicy="off"/> </mx:Application>
BasicList.as
package com.mariosh.controls { import flash.events.Event; import mx.controls.List; public class BasicList extends List { private var scrollbar:ScrollBar; public function BasicList() { super(); } override protected function createChildren():void { super.createChildren(); if(!scrollbar) { scrollbar = new ScrollBar(); scrollbar.addEventListener(Event.CHANGE, thumbChange); addChild(scrollbar); } } private function thumbChange(event:Event):void { var listIndex:int = scrollbar.scrollPercentage *(this.dataProvider.length - 9); this.verticalScrollPosition = listIndex; } override protected function commitProperties():void { super.commitProperties(); scrollbar.width = 10; scrollbar.height = this.height; this.verticalScrollPosition = 10; } override protected function updateDisplayList(uW:Number, uH:Number):void { super.updateDisplayList(uW, uH); scrollbar.move(uW-scrollbar.width, 0); } } }
ScrollBar.as
package com.mariosh.controls { import flash.events.Event; import flash.events.MouseEvent; import mx.core.UIComponent; [Event(name="change", type="flash.events.Event")] public class ScrollBar extends UIComponent { private var track:Track; private var thumb:Thumb; private var _yOffset:Number; private var _yMin:Number = 0; private var _yMax:Number; public function ScrollBar() { super(); } private function thumbDown(event:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, thumbMove); stage.addEventListener(MouseEvent.MOUSE_UP, thumbUp); _yOffset = this.mouseY - thumb.y; } private function thumbUp(event:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, thumbMove); stage.removeEventListener(MouseEvent.MOUSE_UP, thumbUp); } private function thumbMove(event:MouseEvent):void { thumb.y = this.mouseY - _yOffset; if(thumb.y <= _yMin) thumb.y = 0; if(thumb.y >= _yMax) thumb.y = _yMax; _sp = thumb.y / _yMax; dispatchEvent(new Event(Event.CHANGE)); event.updateAfterEvent(); } private var _sp:Number; public function get scrollPercentage():Number { return _sp; } //-------------------------------------------- // override methods //-------------------------------------------- override protected function createChildren():void { super.createChildren(); if(!track) { track = new Track(); track.width = 10; addChild(track); } if(!thumb) { thumb = new Thumb(); thumb.width = 10; thumb.height = 40; thumb.addEventListener(MouseEvent.MOUSE_DOWN, thumbDown); addChild(thumb); } } override protected function commitProperties():void { super.commitProperties(); track.height = this.height; _yMax = track.height - thumb.height; } } }
Track.as
package com.mariosh.controls { import mx.core.UIComponent; public class Track extends UIComponent { public function Track() { super(); } override protected function updateDisplayList(uW:Number, uH:Number):void { super.updateDisplayList(uW, uH); graphics.clear(); graphics.beginFill(0x333333); graphics.drawRect(0, 0, uW, uH); graphics.endFill(); } } }
Thumb.as
package com.mariosh.controls { import mx.core.UIComponent; public class Thumb extends UIComponent { public function Thumb() { super(); } override protected function updateDisplayList(uW:Number, uH:Number):void { super.updateDisplayList(uW, uH); graphics.clear(); graphics.beginFill(0x666666); graphics.drawRect(0, 0, uW, uH); graphics.endFill(); } } }

I’m Mariusz Tkaczyk.
Leave a comment