package com.oxylusflash.book { import com.oxylusflash.events.ParamEvent; import flash.display.Sprite; import flash.display.StageDisplayState; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.utils.Timer; public class ScrollBar extends FadeInOutItem { public var scrollTrack:ScrollTrack; public var scrollButton:ScrollButton; public var scrollUp:ScrollUp; public var scrollDown:ScrollDown; private var _proportion:Number; private var _percentage:Number; private var lastPerc:Number; private var h:Number; private var sh:Number; private var dy:Number; protected static var TOP_MARGIN:Number = 16; protected static var BTM_MARGIN:Number = 16; private static const Y_SPACING:Number = 1; public static const SCROLL:String = "scroll"; private static const SCROLL_UP:int = -1; private static const SCROLL_DOWN:int = 1; private static const SCROLL_MULT:Number = 0.25; private var waitTimer:Timer = new Timer(400, 1); private var scrollTimer:Timer = new Timer(30); private var scrollDir:int; public var blockScrollEvent:Boolean = false; /** * Scrollbar class. */ public function ScrollBar() { _state = FadeInOutItem.INVISIBLE; inTime = 0.1; outTime = 0.1; this.buttonMode = true; createParts(); this.addChild(scrollTrack); this.addChild(scrollButton); this.addChild(scrollUp); this.addChild(scrollDown); scrollTrack.y = TOP_MARGIN; this.proportion = 1; this.percentage = 0; this.height = 100; this.alpha = 0; if (stage) addEventListeners(); else this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true); } protected function createParts():void { scrollTrack = new LibScrollTrack; scrollButton = new LibScrollButton; scrollUp = new LibScrollUp; scrollDown = new LibScrollDown; } private function addedToStageHandler(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); addEventListeners(); } /** * Add events listeners. */ private function addEventListeners():void { scrollButton.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true); scrollTrack.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true); scrollUp.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler2, false, 0, true); scrollDown.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler2, false, 0, true); waitTimer.addEventListener(TimerEvent.TIMER_COMPLETE, waitTimer_timerCompleteHandler, false, 0, true); scrollTimer.addEventListener(TimerEvent.TIMER, scrollTimer_timerHandler, false, 0, true); } /** * Scroll up / down. */ public function doScrollUp():void { if (_proportion < 1) { this.percentage -= _proportion * SCROLL_MULT; } } public function doScrollDown():void { if (_proportion < 1) { this.percentage += _proportion * SCROLL_MULT; } } /** * Wait for automatic scrolling. * @param e */ private function waitTimer_timerCompleteHandler(e:TimerEvent):void { scrollTimer.start(); } /** * Automatic scrolling. * @param e */ private function scrollTimer_timerHandler(e:TimerEvent):void { if (scrollDir == SCROLL_UP) { doScrollUp(); if (_percentage == 0) scrollTimer.reset(); } else { doScrollDown(); if (_percentage == 1) scrollTimer.reset(); } //if (e && stage.displayState != StageDisplayState.FULL_SCREEN) e.updateAfterEvent(); } private function mouseDownHandler2(e:MouseEvent):void { if (e.target == scrollUp) { scrollDir = SCROLL_UP; doScrollUp(); } else { scrollDir = SCROLL_DOWN; doScrollDown(); } stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler2, false, 0, true); waitTimer.start(); } private function stage_mouseUpHandler2(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler2); waitTimer.reset(); scrollTimer.reset(); } private function mouseDownHandler(e:MouseEvent):void { dy = (e.target == scrollButton) ? mouseY - scrollButton.y : scrollButton.height * 0.5; stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler, false, 0, true); stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler, false, 0, true); if (e.target != scrollButton) stage_mouseMoveHandler(null); } private function stage_mouseMoveHandler(e:MouseEvent):void { this.percentage = (mouseY - dy - TOP_MARGIN - Y_SPACING) / sh; //if (e && stage.displayState != StageDisplayState.FULL_SCREEN) e.updateAfterEvent(); } private function stage_mouseUpHandler(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMoveHandler); stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUpHandler); } public function get proportion():Number { return _proportion; } public function set proportion(value:Number):void { _proportion = Math.max(0, Math.min(1, value)); scrollButton.height = _proportion * scrollTrack.height; this.state = _proportion < 1 ? FadeInOutItem.VISIBLE : FadeInOutItem.INVISIBLE; } public function get percentage():Number { return _percentage; } public function set percentage(value:Number):void { _percentage = Math.max(0, Math.min(1, value)); sh = scrollTrack.height - scrollButton.height - 2 * Y_SPACING; scrollButton.y = TOP_MARGIN + Y_SPACING + _percentage * sh; if (lastPerc != _percentage) { lastPerc = _percentage; if (!blockScrollEvent) dispatchEvent(new ParamEvent(SCROLL, { percentage: _percentage } )); } } /** * Overrides. */ override public function set height(value:Number):void { if (h != value) { h = value; scrollTrack.height = h - TOP_MARGIN - BTM_MARGIN; scrollDown.y = h - scrollDown.height; this.proportion = _proportion; this.percentage = _percentage; } } override public function set width(value:Number):void { } } }