package com.oxylusflash.book { import caurina.transitions.Tweener; import com.oxylusflash.utils.StringUtil; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.DisplayObject; import flash.display.GradientType; import flash.display.SpreadMethod; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; public class BookPage extends Sprite { public static var zoomSources:Array = []; private var pageZoomIndex:int = -1; private static const ICON_MARGIN:Number = 5; public static const LEFT_SIDE:int = 0; public static const RIGHT_SIDE:int = 1; private var baseColorMc:Sprite; private var contentMc:Sprite; private var flipIconMc:FlipIcon; private var _bitmap:BitmapData; private var _index:int; private var _side:int; private var _printAsBitmap:Boolean; private var flipZone:Rectangle; private var shadingMc:Bitmap; private var midLine:Sprite; private var spinLoader:Sprite; public var page3D:BookPage3D; public function BookPage(content:DisplayObject, pageNode:XML, idx:int):void { _printAsBitmap = StringUtil.parse(pageNode.printAsBitmap[0].text()) === true; // Create bitmap representation for 3D flip. _bitmap = new BitmapData(Global.xmlBookPage.width, Global.xmlBookPage.height, false); _bitmap.lock(); _index = idx; this.x = -(idx % 2) * Global.xmlBookPage.width; _side = this.x < 0 ? LEFT_SIDE : RIGHT_SIDE; this.scrollRect = new Rectangle(0, 0, Global.xmlBookPage.width, Global.xmlBookPage.height); // Set base color. baseColorMc = this.addChild(new Sprite) as Sprite; baseColorMc.graphics.beginFill(uint(pageNode.baseColor[0].text())); baseColorMc.graphics.drawRect(0, 0, Global.xmlBookPage.width, Global.xmlBookPage.height); baseColorMc.graphics.endFill(); baseColorMc.cacheAsBitmap = true; // Add content if exists contentMc = this.addChild(new Sprite) as Sprite; if (!StringUtil.isBlank(pageNode.source[0].text())) { spinLoader = new LibSpinningPreloader; spinLoader.x = int(baseColorMc.width * 0.5); spinLoader.y = int(baseColorMc.height * 0.5); this.addChild(spinLoader); this.mouseEnabled = this.mouseChildren = false; } updatePageContent(content); // Define flip zone flipZone = new Rectangle(0, 0, Global.xmlBookPage.flipZoneWidth, Global.xmlBookPage.flipZoneHeight); flipZone.x = _side == LEFT_SIDE ? 0 : Global.xmlBookPage.width - flipZone.width; switch(Global.xmlBookPage.flipZoneAlignY.toLowerCase()) { case "top": flipZone.y = 0; break; case "center": flipZone.y = Math.round((Global.xmlBookPage.height - flipZone.height) * 0.5); default: flipZone.y = Global.xmlBookPage.height - flipZone.height; } // Add shading. if (Global.pageShading) { shadingMc = this.addChild(new Bitmap(Global.pageShading)) as Bitmap; shadingMc.blendMode = BlendMode.MULTIPLY; if (_side == RIGHT_SIDE) { shadingMc.scaleX = -1; shadingMc.x = Global.xmlBookPage.width; } } // Add mid line. if (_side == RIGHT_SIDE) { midLine = this.addChild(new Sprite) as Sprite; midLine.graphics.beginFill(0x000000, 0.1); midLine.graphics.drawRect(0, 0, 1, Global.xmlBookPage.height); midLine.graphics.endFill(); midLine.blendMode = BlendMode.DARKEN; midLine.cacheAsBitmap = true; } // Add flip icon flipIconMc = this.addChild(_side == LEFT_SIDE ? new LibIconLTR : new LibIconRTL) as FlipIcon; flipIconMc.x = _side == LEFT_SIDE ? ICON_MARGIN : Global.xmlBookPage.width - flipIconMc.width - ICON_MARGIN; flipIconMc.y = Global.xmlBookPage.height - flipIconMc.height - ICON_MARGIN; // Zoom content source var zoomSource:String = pageNode.zoomSource[0].text(); if (!StringUtil.isBlank(zoomSource)) { zoomSources.push( { zoomSource: zoomSource, pageIndex: _index, printAsBitmap: StringUtil.parse(pageNode.zoomPrintAsBitmap[0].text()) === true } ); pageZoomIndex = zoomSources.length - 1; } // Add event listeners this.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler, false, 0, true); this.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler, false, 0, true); this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true); this.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler, false, 0, true); } /** * Event handlers */ private function rollOverHandler(e:MouseEvent):void { if (Global.pageZoomIsOn) { if (pageZoomIndex >= 0) Global.zoomCursor.state = CustomCursor.VISIBLE; else Global.noZoomCursor.state = CustomCursor.VISIBLE; } else { this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, false, 0, true); mouseMoveHandler(e.clone() as MouseEvent); } } private function rollOutHandler(e:MouseEvent):void { if (Global.pageZoomIsOn) { if (pageZoomIndex >= 0) Global.zoomCursor.state = CustomCursor.INVISIBLE; else Global.noZoomCursor.state = CustomCursor.INVISIBLE; } else { this.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); flipIconMc.state = FadeInOutItem.INVISIBLE; } } private function mouseMoveHandler(e:MouseEvent):void { if (!e.buttonDown) { flipIconMc.state = mouseInFlipZone ? FadeInOutItem.VISIBLE : FadeInOutItem.INVISIBLE; this.doubleClickEnabled = flipIconMc.state == FadeInOutItem.INVISIBLE; } } private function mouseDownHandler(e:MouseEvent):void { if (Global.pageZoomIsOn && pageZoomIndex >= 0) { Global.fullView.show(pageZoomIndex); } } private function doubleClickHandler(e:MouseEvent):void { if (!Global.pageZoomIsOn && pageZoomIndex >= 0) { Global.fullView.show(pageZoomIndex); } } /** * Bitmap representation of the page, used for texturing the 3D page. */ public function get bitmap():BitmapData { updateBitmap(); return _bitmap; } /* Update bitmap */ private function updateBitmap():void { if (spinLoader) spinLoader.visible = false; if (flipIconMc) flipIconMc.visible = false; _bitmap.draw(this); if (spinLoader) spinLoader.visible = true; if (flipIconMc) flipIconMc.visible = true; } /** * Page index. */ public function get index():int { return _index; } /** * Page side. */ public function get side():int { return _side; } /** * Will print as bitmap or vector. */ public function get printAsBitmap():Boolean { return _printAsBitmap; } /** * Check if mouse is over the flip zone. */ public function get mouseInFlipZone():Boolean { return flipZone.containsPoint(new Point(mouseX, mouseY)) && !Global.pageZoomIsOn; } /** * Show or hide print version. * @param yes If yes is true, the page is changed to print version. */ public function printVersion(yes:Boolean = true, w:Number = 0, h:Number = 0):void { if (shadingMc) shadingMc.visible = !yes; if (midLine) midLine.visible = !yes; this.scaleX = yes ? Math.min(1, w / this.width, h / this.height) : 1; this.scaleY = this.scaleX; if (yes) { if (this.parent == null) Global.theBook.stage.addChild(this); } else { if (this.parent == Global.theBook.stage) { Global.theBook.stage.removeChild(this); } } } /* Later content update */ public function updatePageContent(content:DisplayObject):void { if (content) { if (!contentMc.scrollRect) { contentMc.scrollRect = new Rectangle(0, 0, content.loaderInfo.width, content.loaderInfo.height); contentMc.x = Math.max(0, Math.round((Global.xmlBookPage.width - content.loaderInfo.width) * 0.5)); contentMc.y = Math.max(0, Math.round((Global.xmlBookPage.height - content.loaderInfo.height) * 0.5)); if (content.loaderInfo.contentType.indexOf("image") >= 0) { Bitmap(content).smoothing = true; } contentMc.addChild(content); if (_index > 0) { contentMc.alpha = 0; Tweener.addTween(contentMc, { alpha: 1, time: 0.2, transition: "easeoutquad" } ); } if (spinLoader) { this.removeChild(spinLoader); spinLoader = null; this.mouseEnabled = this.mouseChildren = true; } //updateBitmap(); /*if (page3D) { if (flipIconMc) flipIconMc.visible = false; if (_side == RIGHT_SIDE) page3D.frontMat.bitmap.draw(this); else page3D.backMat.bitmap.draw(this); page3D = null; if (flipIconMc) flipIconMc.visible = true; }*/ } } } //private function gcPage3D():void { page3D = null; } /** * Overrides. */ override public function get doubleClickEnabled():Boolean { return super.doubleClickEnabled; } override public function set doubleClickEnabled(value:Boolean):void { if (super.doubleClickEnabled != value) { super.doubleClickEnabled = value; if (baseColorMc) baseColorMc.doubleClickEnabled = value; if (contentMc) contentMc.doubleClickEnabled = value; } } } }