package com.oxylusflash.book { import caurina.transitions.*; import com.oxylusflash.events.*; import com.oxylusflash.framework.misc.StageReference; import com.oxylusflash.utils.*; import flash.display.*; import flash.events.*; import flash.geom.*; import flash.net.*; public class BookApplication extends Sprite { // Place holder sprite, will be removed. public var placeHolderMc:Sprite; // Logo public var logoLoader:Loader; public var logoWrapper:Sprite; // Sprite with default bg color. public var baseColorMc:Sprite; // Will hold the bg image. public var bgImgMc:Bitmap; // XML private var xml:XML; // Loaders private var xmlLoader:URLLoader; private var bgLoader:Loader; /** * Constructor. */ public function BookApplication() { Global.bookApp = this; this.removeChild(placeHolderMc); placeHolderMc = null; this.tabChildren = false; this.scaleX = this.scaleY = 1; this.x = Math.round(this.x); this.y = Math.round(this.y); this.alpha = 0; if (stage) init(); else this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler, false, 0, true); } private function addedToStageHandler(e:Event):void { this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler); init(); } /** * Init. */ private function init():void { StageReference.init(stage); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; loadXML(stage.loaderInfo.parameters.xmlFile); } /** * Manually load XML. * @param xmlFile XML path as string. */ public function loadXML(xmlFile:String):void { xmlLoader = new URLLoader(); xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, xmlLoader_ioErrorHandler, false, 0, true); xmlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, xmlLoader_securityErrorHandler, false, 0, true); xmlLoader.addEventListener(Event.COMPLETE, xmlLoader_completeHandler, false, 0, true); xmlLoader.load(new URLRequest(xmlFile || "book.xml")); } /** * XML loader event handlers. */ private function xmlLoader_ioErrorHandler(e:IOErrorEvent):void { trace("[ERROR] XML I/O error: " + e.text); } private function xmlLoader_securityErrorHandler(e:SecurityErrorEvent):void { trace("[ERROR] XML security error: " + e.text); } /** * Get data from loaded xm file. */ private function xmlLoader_completeHandler(e:Event):void { // parse xml and destroy loader xml = new XML(xmlLoader.data); xmlLoader = null; Global.pdfVersion = String(xml.pdfVersion[0].text()); Global.styleSheet.parseCSS(xml.globalStyleSheet[0].text()); Global.toolbarVis = String(xml.fullView[0].toolbar[0].@visible) != "false"; // Store XML information for global access. // 3D page section Global.xmlPage3D = com.oxylusflash.utils.XMLUtil.getParams(xml.page3D[0]); // Layout information. Global.xmlLayout = com.oxylusflash.utils.XMLUtil.getParams(xml.layout[0]); // Logo. Global.xmlLogo = com.oxylusflash.utils.XMLUtil.getParams(xml.logo[0]); // Background information. Global.xmlBackground = com.oxylusflash.utils.XMLUtil.getParams(xml.background[0]); // Summary panel information. Global.xmlSummaryPanel = com.oxylusflash.utils.XMLUtil.getParams(xml.summaryPanel[0]); // Auto flip information. Global.xmlAutoFlip = com.oxylusflash.utils.XMLUtil.getParams(xml.autoFlip[0]); // Actual 3D book information. Global.xmlFlipBook = com.oxylusflash.utils.XMLUtil.getParams(xml.flipBook[0]); // Book page information. Global.xmlBookPage = com.oxylusflash.utils.XMLUtil.getParams(xml.bookPage[0]); // Background music information. Global.xmlBgMusic = com.oxylusflash.utils.XMLUtil.getParams(xml.bgMusic[0]); // Translation strings. Global.xmlTranslate = com.oxylusflash.utils.XMLUtil.getParams(xml.translate[0]); // Search settings. Global.xmlSearch = com.oxylusflash.utils.XMLUtil.getParams(xml.search[0]); //Tell a friend window data. Global.xmlTellAFriend = com.oxylusflash.utils.XMLUtil.getParams(xml.tellAFriend[0]); //Contact us window data. Global.xmlContactUs = com.oxylusflash.utils.XMLUtil.getParams(xml.contactUs[0]); //About us window data. Global.xmlAboutUs = com.oxylusflash.utils.XMLUtil.getParams(xml.aboutUs[0]); // Social xml links items. Global.socialXML = xml.social[0]; // Create page shading. if (Global.xmlBookPage.shading) Global.pageShading = new PageShading(); // Calculate half of page width and half of page height. Global.pageW2 = Math.round(Global.xmlBookPage.width * 0.5); Global.pageH2 = Math.round(Global.xmlBookPage.height * 0.5); // If page width is lower than page height, the 3D page bend should switch axes. Global.bendSwitchAxes = Global.xmlBookPage.width < Global.xmlBookPage.height; // Create base color sprite. baseColorMc = this.addChild(new Sprite) as Sprite; baseColorMc.graphics.beginFill(uint(Global.xmlBackground.baseColor)); baseColorMc.graphics.drawRect(0, 0, 100, 100); baseColorMc.graphics.endFill(); baseColorMc.cacheAsBitmap = true; // Create main user intereface elements. // The 3D book. Global.theBook = this.addChild(new BookHolder) as BookHolder; // Summary list pane. Global.summList = this.addChild(new LibSummaryPanel) as SummaryPanel; // Options bar ar the bottom. Global.optBar = this.addChild(new LibOptionsBar) as OptionsBar; // Setup logo. if (Global.xmlLogo.source) { logoWrapper = this.addChild(new Sprite) as Sprite; logoWrapper.alpha = 0; logoWrapper.visible = false; logoLoader = new Loader; logoLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, logoLoader_eventsHandler, false, 0, true); logoLoader.contentLoaderInfo.addEventListener(Event.INIT, logoLoader_eventsHandler, false, 0, true); logoLoader.load(new URLRequest(Global.xmlLogo.source)); if (Global.xmlLogo.link) { logoWrapper.buttonMode = true; logoWrapper.addEventListener(MouseEvent.CLICK, logoWrapper_clickHandler, false, 0, true); } } // Dark overlay. Global.overlay = this.addChild(new Overlay) as Overlay; // Zoom view for pages. Global.fullView = this.addChild(new LibFullView) as FullView; // Send to friend (tell a friend) popup window. Global.sendToFriend = this.addChild(new PopupWindow(Global.xmlTranslate.str27, LibSendToFriend, Global.xmlTellAFriend.width, Global.xmlTellAFriend.height)) as PopupWindow; // Contact us popup window. Global.contactUs = this.addChild(new PopupWindow(Global.xmlTranslate.str54, LibContactUs, Global.xmlContactUs.width, Global.xmlContactUs.height)) as PopupWindow; // About us popup window. Global.aboutUs = this.addChild(new PopupWindow(Global.xmlTranslate.str55, LibAboutUs, Global.xmlAboutUs.width, Global.xmlAboutUs.height)) as PopupWindow; // Message box. Global.msgBox = this.addChild(new LibMessageBox) as MessageBox; // Zoom cursor. Global.zoomCursor = this.addChild(new LibZoomCursor) as CustomCursor; // Zoom disabled cursor. Global.noZoomCursor = this.addChild(new LibNoZoomCursor) as CustomCursor; // Init UI elements. Global.optBar.init(xml.optionsBar[0].groups[0]); Global.optBar.visible = xml.optionsBar[0].@visible != "false"; Global.theBook.init(xml.pages[0]); Global.summList.feedSummary(xml.summary[0]); Global.fullViewToolBar.init(xml.fullView[0].toolbar[0].item); // Handle layout resize / positioning Global.layout.addEventListener(StageLayoutEvent.RESIZE, layout_resizeHandler, false, 0, true); Global.layout.init(stage, Global.xmlLayout.width, Global.xmlLayout.height, Global.xmlLayout.minWidth, Global.xmlLayout.minHeight, Global.xmlLayout.offsetX, Global.xmlLayout.offsetY); // Init options bar tooltips. Global.optBar.initTooltips(); // Load background. if (Global.xmlBackground.source) { bgLoader = new Loader(); bgLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, bgLoader_eventsHandler, false, 0, true); bgLoader.contentLoaderInfo.addEventListener(Event.INIT, bgLoader_eventsHandler, false, 0, true); bgLoader.load(new URLRequest(Global.xmlBackground.source)); } // Fade in. Tweener.addTween(this, { alpha: 1, base: Global.baseTween } ); } /** * Handle logo load. */ private function logoLoader_eventsHandler(e:Event):void { switch(e.type) { case IOErrorEvent.IO_ERROR: trace("[ERROR] Logo load I/O error !"); break; case Event.INIT: logoWrapper.visible = true; logoWrapper.addChild(logoLoader.content); arrangeLogo(); Tweener.addTween(logoWrapper, { alpha: 1, base: Global.baseTween } ); break; } logoLoader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, logoLoader_eventsHandler); logoLoader.contentLoaderInfo.removeEventListener(Event.INIT, logoLoader_eventsHandler); logoLoader = null; } /** * Logo launch link. */ private function logoWrapper_clickHandler(e:MouseEvent):void { navigateToURL(new URLRequest(Global.xmlLogo.link), Global.xmlLogo.linkTarget); } /** * Background image load handlers. */ private function bgLoader_eventsHandler(e:Event):void { switch(e.type) { case IOErrorEvent.IO_ERROR: trace("[ERROR] Background image I/O error"); break; case Event.INIT: bgImgMc = new Bitmap(new BitmapData(bgLoader.content.width, bgLoader.content.height, true, 0)); bgImgMc.bitmapData.draw(bgLoader.content); bgImgMc.cacheAsBitmap = true; this.addChildAt(bgImgMc, 0); this.setChildIndex(baseColorMc, 0); updateBgImgMc(); bgImgMc.alpha = 0; Tweener.addTween(bgImgMc, { alpha: 1, time: 0.3, transition: "easeoutquad" }); break; } try { bgLoader.unload(); } catch(error:Error) { } bgLoader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, bgLoader_eventsHandler); bgLoader.contentLoaderInfo.removeEventListener(Event.INIT, bgLoader_eventsHandler); bgLoader = null; } /** * Update bg image position. */ private function updateBgImgMc():void { var o:Object = Resize.getParams(Global.layout.width, Global.layout.height, bgImgMc.bitmapData.width, bgImgMc.bitmapData.height, 0, 0, Global.xmlBackground.resize, Global.xmlBackground.align); bgImgMc.smoothing = o.w != bgImgMc.bitmapData.width || o.h != bgImgMc.bitmapData.height; bgImgMc.x = o.x; bgImgMc.y = o.y; bgImgMc.width = o.w; bgImgMc.height = o.h; } /** * Arrange logo. */ private function arrangeLogo():void { var o:Object = Resize.getParams(Global.layout.width - 2 * Global.xmlLogo.xMargin, Global.layout.height - 2 * Global.xmlLogo.yMargin, logoWrapper.width, logoWrapper.height, 0, 0, "resizeToOriginal", Global.xmlLogo.align); logoWrapper.x = Global.xmlLogo.xMargin + o.x; logoWrapper.y = Global.xmlLogo.yMargin + o.y; } /** * Layout resize handler. */ private function layout_resizeHandler(e:StageLayoutEvent):void { this.x = Global.xmlLayout.offsetX; this.y = Global.xmlLayout.offsetY; this.scrollRect = new Rectangle(0, 0, Global.layout.width, Global.layout.height); baseColorMc.x = 0; baseColorMc.y = 0; baseColorMc.width = Global.layout.width; baseColorMc.height = Global.layout.height; Global.optBar.x = 0; Global.optBar.y = Global.layout.height - Global.optBar.height; Global.optBar.width = Global.layout.width; Global.theBook.width = Global.layout.width; Global.theBook.height = Global.layout.height - Global.optBar.height; Global.overlay.width = Global.layout.width; Global.overlay.height = Global.layout.height; if (Global.xmlSummaryPanel.align != "left") { Global.summList.x = Global.layout.width - (Global.xmlSummaryPanel.width + Global.xmlSummaryPanel.margin); } else { Global.summList.x = Global.xmlSummaryPanel.margin; } Global.summList.height = Global.layout.height - Global.optBar.height; Global.sendToFriend.x = (Global.layout.width - Global.sendToFriend.width) * 0.5; Global.sendToFriend.y = (Global.layout.height - Global.sendToFriend.height) * 0.5; Global.contactUs.x = (Global.layout.width - Global.contactUs.width) * 0.5; Global.contactUs.y = (Global.layout.height - Global.contactUs.height) * 0.5; Global.aboutUs.x = (Global.layout.width - Global.aboutUs.width) * 0.5; Global.aboutUs.y = (Global.layout.height - Global.aboutUs.height) * 0.5; Global.fullView.width = Global.layout.width; Global.fullView.height = Global.layout.height; Global.msgBox.x = (Global.layout.width - Global.msgBox.width) * 0.5; Global.msgBox.y = (Global.layout.height - Global.msgBox.height) * 0.5; if (logoWrapper) arrangeLogo(); if (bgImgMc) updateBgImgMc(); } /** * Overrides. */ override public function get width():Number { return this.scrollRect.width; } override public function set width(value:Number):void { } override public function get height():Number { return this.scrollRect.height; } override public function set height(value:Number):void { } override public function get alpha():Number { return super.alpha; } override public function set alpha(value:Number):void { super.alpha = value; this.visible = value > 0; } } }