//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.preloaders { import flash.display.DisplayObject; import flash.display.GradientType; import flash.display.Graphics; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.events.TimerEvent; import flash.geom.Matrix; import flash.geom.Rectangle; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.LoaderContext; import flash.text.TextField; import flash.text.TextFormat; import flash.utils.Timer; import flash.utils.getDefinitionByName; import flash.utils.getTimer; import mx.events.FlexEvent; import mx.events.RSLEvent; import mx.geom.RoundedRectangle; import mx.graphics.RectangularDropShadow; /** * The DownloadProgressBar class displays download progress. * It is used by the Preloader control to provide user feedback * while the application is downloading and loading. * *

The download progress bar displays information about * two different phases of the application: * the download phase and the initialization phase.

* *

In the Application container, use the * the preloader property to specify the name of your subclass.

* *

You can implement a custom download progress bar component * by creating a subclass of the DownloadProgressBar class. * Do not implement a download progress bar as an MXML component * because it loads too slowly.

* * @see mx.core.Application * @see mx.preloaders.IPreloaderDisplay * @see mx.preloaders.Preloader * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class DownloadProgressBar extends Sprite implements IPreloaderDisplay { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function DownloadProgressBar() { super(); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * The minimum number of milliseconds * that the display should appear visible. * If the downloading and initialization of the application * takes less time than this value, then Flex pauses for this amount * of time before dispatching the complete event. * * @default 0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected var MINIMUM_DISPLAY_TIME:uint = 0; /** * The percentage of the progress bar that the downloading phase * fills when the SWF file is fully downloaded. * The rest of the progress bar is filled during the initializing phase. * This should be a value from 0 to 100. * * @default 60 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected var DOWNLOAD_PERCENTAGE:uint = 60; /** * @private */ private var _showProgressBar:Boolean = true; /** * @private * Cached Rectangle returned by the labelRect getter. */ private var _labelRect:Rectangle = labelRect; /** * @private * Cached Rectangle returned by the percentRect getter. */ private var _percentRect:Rectangle = percentRect; /** * @private * Cached RoundedRectangle returned by the borderRect getter. */ private var _borderRect:RoundedRectangle = borderRect; /** * @private * Cached RoundedRectangle returned by the barFrameRect getter. */ private var _barFrameRect:RoundedRectangle = barFrameRect; /** * @private * Cached RoundedRectangle returned by the barRect getter. */ private var _barRect:RoundedRectangle = barRect; /** * @private */ private var _xOffset:Number = 20; /** * @private */ private var _yOffset:Number = 20; /** * @private */ private var _maximum:Number = 0; /** * @private */ private var _value:Number = 0; /** * @private */ private var _barSprite:Sprite; /** * @private */ private var _barFrameSprite:Sprite; /** * @private */ private var _labelObj:TextField; /** * @private */ private var _percentObj:TextField; /** * @private */ private var _startTime:int; /** * @private */ private var _displayTime:int; /** * @private */ private var _startedLoading:Boolean = false; /** * @private */ private var _startedInit:Boolean = false; /** * @private */ private var _showingDisplay:Boolean = false; /** * @private */ private var _displayStartCount:uint = 0; /** * @private */ private var _initProgressCount:uint = 0; /** * The total number of validation events you expect to get * in the initializing phase. This should be an integer * greater or equal to 4 (and note that if it is greater than 4 * you might have an inefficiency in your initialization code) * * @default 6 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 4 */ protected var initProgressTotal:uint = 6; //-------------------------------------------------------------------------- // // Overridden properties // //-------------------------------------------------------------------------- //---------------------------------- // visible //---------------------------------- /** * @private * Storage for the visible property. */ private var _visible:Boolean = false; /** * Specifies whether the download progress bar is visible. * *

When the Preloader control determines that the progress bar should be displayed, * it sets this value to true. When the Preloader control determines that * the progress bar should be hidden, it sets the value to false.

* *

A subclass of the DownloadProgressBar class should never modify this property. * Instead, you can override the setter method to recognize when * the Preloader control modifies it, and perform any necessary actions.

* * @default false * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ override public function get visible():Boolean { return _visible; } /** * @private */ override public function set visible(value:Boolean):void { if (!_visible && value) show(); else if (_visible && !value ) hide(); _visible = value; } //-------------------------------------------------------------------------- // // Properties: IPreloaderDisplay // //-------------------------------------------------------------------------- //---------------------------------- // backgroundAlpha //---------------------------------- /** * @private * Storage for the backgroundAlpha property. */ private var _backgroundAlpha:Number = 1; /** * Alpha level of the SWF file or image defined by * the backgroundImage property, or the color defined by * the backgroundColor property. * Valid values range from 0 to 1.0. * *

You can specify either a backgroundColor * or a backgroundImage, but not both.

* * @default 1.0 * * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get backgroundAlpha():Number { if (!isNaN(_backgroundAlpha)) return _backgroundAlpha; else return 1; } /** * @private */ public function set backgroundAlpha(value:Number):void { _backgroundAlpha = value; } //---------------------------------- // backgroundColor //---------------------------------- /** * @private * Storage for the backgroundColor property. */ private var _backgroundColor:uint; /** * Background color of a download progress bar. * You can have either a backgroundColor or a * backgroundImage, but not both. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get backgroundColor():uint { return _backgroundColor; } /** * @private */ public function set backgroundColor(value:uint):void { _backgroundColor = value; } //---------------------------------- // backgroundImage //---------------------------------- /** * @private * Storage for the backgroundImage property. */ private var _backgroundImage:Object; /** * The background image of the application, * which is passed in by the preloader. * You can specify either a backgroundColor * or a backgroundImage, but not both. * *

A value of null means "not set". * If this style and the backgroundColor style are undefined, * the component has a transparent background.

* *

The preloader does not display embedded images. * You can only use images loaded at runtime.

* * @default null * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get backgroundImage():Object { return _backgroundImage; } /** * @private */ public function set backgroundImage(value:Object):void { _backgroundImage = value; } //---------------------------------- // backgroundSize //---------------------------------- /** * @private * Storage for the backgroundSize property. */ private var _backgroundSize:String = ""; /** * Scales the image specified by backgroundImage * to different percentage sizes. * A value of "100%" stretches the image * to fit the entire component. * To specify a percentage value, you must include the percent sign (%). * A value of "auto", maintains * the original size of the image. * * @default "auto" * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get backgroundSize():String { return _backgroundSize; } /** * @private */ public function set backgroundSize(value:String):void { _backgroundSize = value; } //---------------------------------- // preloader //---------------------------------- /** * @private * Storage for the preloader property. */ private var _preloader:Sprite; /** * The Preloader class passes in a reference to itself to the display class * so that it can listen for events from the preloader. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function set preloader(value:Sprite):void { _preloader = value; value.addEventListener(ProgressEvent.PROGRESS, progressHandler); value.addEventListener(Event.COMPLETE, completeHandler); value.addEventListener(RSLEvent.RSL_PROGRESS, rslProgressHandler); value.addEventListener(RSLEvent.RSL_COMPLETE, rslCompleteHandler); value.addEventListener(RSLEvent.RSL_ERROR, rslErrorHandler); value.addEventListener(FlexEvent.INIT_PROGRESS, initProgressHandler); value.addEventListener(FlexEvent.INIT_COMPLETE, initCompleteHandler); } //---------------------------------- // stageHeight //---------------------------------- /** * @private * Storage for the stageHeight property. */ private var _stageHeight:Number = 375; /** * The height of the stage, * which is passed in by the Preloader class. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get stageHeight():Number { return _stageHeight; } /** * @private */ public function set stageHeight(value:Number):void { _stageHeight = value; } //---------------------------------- // stageWidth //---------------------------------- /** * @private * Storage for the stageHeight property. */ private var _stageWidth:Number = 500; /** * The width of the stage, * which is passed in by the Preloader class. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get stageWidth():Number { return _stageWidth; } /** * @private */ public function set stageWidth(value:Number):void { _stageWidth = value; } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // barFrameRect //---------------------------------- /** * The dimensions of the progress bar border. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get barFrameRect():RoundedRectangle { return new RoundedRectangle(14, 40, 154, 4); } //---------------------------------- // barRect //---------------------------------- /** * The dimensions of the progress bar. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get barRect():RoundedRectangle { return new RoundedRectangle(14, 39, 154, 6, 0); } //---------------------------------- // borderRect //---------------------------------- /** * The dimensions of the border of the display. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get borderRect():RoundedRectangle { return new RoundedRectangle(0, 0, 182, 60, 4); } //---------------------------------- // downloadingLabel //---------------------------------- /** * @private * Storage for the downloadingLabel property. */ private var _downloadingLabel:String = "Loading"; /** * The string to display as the label while in the downloading phase. * * @default "Loading" * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get downloadingLabel():String { return _downloadingLabel; } /** * @private */ protected function set downloadingLabel(value:String):void { _downloadingLabel = value; } //---------------------------------- // initializingLabel //---------------------------------- /** * @private * Storage for the initializingLabel property. */ private static var _initializingLabel:String = "Initializing"; /** * The string to display as the label while in the initializing phase. * * @default "Initializing" * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public static function get initializingLabel():String { return _initializingLabel; } /** * @private */ public static function set initializingLabel(value:String):void { _initializingLabel = value; } //---------------------------------- // label //---------------------------------- /** * @private * Storage for the label property. */ private var _label:String = ""; /** * Text to display when the progress bar is active. * The Preloader class sets this value * before displaying the progress bar. * Implementing this property in a subclass is optional. * * @default "" * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get label():String { return _label; } /** * @private */ protected function set label(value:String):void { if (!(value is Function)) _label = value; draw(); } //---------------------------------- // labelFormat //---------------------------------- /** * The TextFormat object of the TextField component of the label. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get labelFormat():TextFormat { var tf:TextFormat = new TextFormat(); tf.color = 0x333333; tf.font = "Verdana"; tf.size = 10; return tf; } //---------------------------------- // labelRect //---------------------------------- /** * The dimensions of the TextField component for the label. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get labelRect():Rectangle { return new Rectangle(14, 17, 100, 16); } //---------------------------------- // percentFormat //---------------------------------- /** * The TextFormat of the TextField component for displaying the percent. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get percentFormat():TextFormat { var tf:TextFormat = new TextFormat(); tf.align = "right"; tf.color = 0x000000; tf.font = "Verdana"; tf.size = 10; return tf; } //---------------------------------- // percentRect //---------------------------------- /** * The dimensions of the TextField component for displaying the percent. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get percentRect():Rectangle { return new Rectangle(108, 4, 34, 16); } //---------------------------------- // showLabel //---------------------------------- /** * @private * Storage for the showLabel property. */ private var _showLabel:Boolean = true; /** * Controls whether to display the label, true, * or not, false. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get showLabel():Boolean { return _showLabel; } /** * @private */ protected function set showLabel(value:Boolean):void { _showLabel = value; draw(); } //---------------------------------- // showPercentage //---------------------------------- /** * @private * Storage for the showPercentage property. */ private var _showPercentage:Boolean = false; /** * Controls whether to display the percentage, true, * or not, false. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get showPercentage():Boolean { return _showPercentage; } /** * @private */ protected function set showPercentage(value:Boolean):void { _showPercentage = value; draw(); } //-------------------------------------------------------------------------- // // Methods:IPreloaderDisplay // //-------------------------------------------------------------------------- /** * Called by the Preloader after the download progress bar * has been added as a child of the Preloader. * This should be the starting point for configuring your download progress bar. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function initialize():void { _startTime = getTimer(); center(stageWidth, stageHeight); } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * Centers the download progress bar based on the passed in dimensions. * * @param width The width of the area in which to center the download progress bar. * * @param height The height of the area in which to center the download progress bar. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function center(width:Number, height:Number):void { _xOffset = Math.floor((width - _borderRect.width) / 2); _yOffset = Math.floor((height - _borderRect.height) / 2); } /** * @private * Updates the display. */ private function draw():void { var percentage:Number; if (_startedLoading) { if (!_startedInit) { // 0 to MaxDL Percentage percentage = Math.round(getPercentLoaded(_value, _maximum) * DOWNLOAD_PERCENTAGE / 100); } else { // MaxDL percentage to 100 percentage = Math.round((getPercentLoaded(_value, _maximum) * (100 - DOWNLOAD_PERCENTAGE) / 100) + DOWNLOAD_PERCENTAGE); } } else { percentage = getPercentLoaded(_value, _maximum); } if (_labelObj) _labelObj.text = _label; if (_percentObj) { if (!_showPercentage) { _percentObj.visible = false; _percentObj.text = ""; } else { _percentObj.text = String(percentage) + "%"; } } if (_barSprite && _barFrameSprite) { if (!_showProgressBar) { _barSprite.visible = false; _barFrameSprite.visible = false; } else { drawProgressBar(percentage); } } } /** * Creates the subcomponents of the display. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function createChildren():void { var g:Graphics = graphics; var labelObj:TextField; var percentObj:TextField; // Draw the background first // Same value as StyleManager.NOT_A_COLOR. However, we don't want to bring in StyleManager at this point. if (backgroundColor != 0xFFFFFFFF) { g.beginFill(backgroundColor, backgroundAlpha); g.drawRect(0, 0, stageWidth, stageHeight); } if (backgroundImage != null) loadBackgroundImage(backgroundImage); _barFrameSprite = new Sprite(); _barSprite = new Sprite(); addChild(_barFrameSprite); addChild(_barSprite); // Draw the outside border and fill. g.beginFill(0xCCCCCC, 0.4); g.drawRoundRect(calcX(_borderRect.x), calcY(_borderRect.y), _borderRect.width, _borderRect.height, _borderRect.cornerRadius * 2, _borderRect.cornerRadius * 2); g.drawRoundRect(calcX(_borderRect.x + 1), calcY(_borderRect.y + 1), _borderRect.width - 2, _borderRect.height - 2, _borderRect.cornerRadius - 1 * 2, _borderRect.cornerRadius - 1 * 2); g.endFill(); g.beginFill(0xCCCCCC,0.4); g.drawRoundRect(calcX(_borderRect.x + 1), calcY(_borderRect.y + 1), _borderRect.width - 2, _borderRect.height - 2, _borderRect.cornerRadius - 1 * 2, _borderRect.cornerRadius - 1 * 2); g.endFill(); var frame_g:Graphics = _barFrameSprite.graphics; // Draw the bar frame border and fill var matrix:Matrix = new Matrix(); matrix.createGradientBox(_barFrameRect.width, _barFrameRect.height, Math.PI / 2, calcX(_barFrameRect.x), calcY(_barFrameRect.y)); frame_g.beginGradientFill(GradientType.LINEAR, [ 0x5C6266, 0xB5B8BA ], [ 1.0, 1.0 ], [ 0, 0xFF ], matrix); frame_g.drawRoundRect(calcX(_barFrameRect.x), calcY(_barFrameRect.y), _barFrameRect.width, _barFrameRect.height, _barFrameRect.cornerRadius * 2, _barFrameRect.cornerRadius * 2); frame_g.drawRoundRect(calcX(_barFrameRect.x + 1), calcY(_barFrameRect.y + 1), _barFrameRect.width - 2, _barFrameRect.height - 2, _barFrameRect.cornerRadius * 2, _barFrameRect.cornerRadius * 2); frame_g.endFill(); // Attach the label TextField. _labelObj = new TextField(); _labelObj.x = calcX(_labelRect.x); _labelObj.y = calcY(_labelRect.y); _labelObj.width = _labelRect.width; _labelObj.height = _labelRect.height; _labelObj.selectable = false; _labelObj.defaultTextFormat = labelFormat; addChild(_labelObj); // Attach the percentage TextField. _percentObj = new TextField(); _percentObj.x = calcX(_percentRect.x); _percentObj.y = calcY(_percentRect.y); _percentObj.width = _percentRect.width; _percentObj.height = _percentRect.height; _percentObj.selectable = false; _percentObj.defaultTextFormat = percentFormat; addChild(_percentObj); // Create dropshadow var ds:RectangularDropShadow = new RectangularDropShadow(); ds.color = 0x000000; ds.angle = 90; ds.alpha = .6; ds.distance = 2; ds.tlRadius = ds.trRadius = ds.blRadius = ds.brRadius = _borderRect.cornerRadius; ds.drawShadow(g, calcX(_borderRect.x), calcY(_borderRect.y), _borderRect.width, _borderRect.height); // Draw the top line g.lineStyle(1,0xFFFFFF, .3); g.moveTo(calcX(_borderRect.x) + _borderRect.cornerRadius, calcY(_borderRect.y)); g.lineTo(calcX(_borderRect.x) - _borderRect.cornerRadius + _borderRect.width, calcY(_borderRect.y)); } /** * @private * Draws the progress bar. */ private function drawProgressBar(percentage:Number):void { var g:Graphics = _barSprite.graphics; g.clear(); var colors:Array = [ 0xFFFFFF, 0xFFFFFF ]; var ratios:Array = [ 0, 0xFF ]; var matrix:Matrix = new Matrix(); // Middle var barWidth:Number = _barRect.width * percentage / 100; var barWidthSplit:Number = barWidth / 2; var barHeight:Number = _barRect.height-4; var barX:Number = calcX(_barRect.x); var barY:Number = calcY(_barRect.y) + 2; var barY2:Number; matrix.createGradientBox(barWidthSplit, barHeight, 0, barX, barY); g.beginGradientFill(GradientType.LINEAR, colors, [ .39, .85], ratios, matrix); g.drawRect(barX, barY, barWidthSplit, barHeight); matrix.createGradientBox(barWidthSplit, barHeight, 0, barX + barWidthSplit, barY); g.beginGradientFill(GradientType.LINEAR, colors, [.85, 1.0], ratios, matrix); g.drawRect(barX + barWidthSplit, barY, barWidthSplit, barHeight); // Outer highlight barWidthSplit = barWidth / 3; barHeight = _barRect.height; barY = calcY(_barRect.y); barY2 = barY + barHeight - 1; matrix.createGradientBox(barWidthSplit, barHeight, 0, barX, barY); g.beginGradientFill(GradientType.LINEAR, colors, [ .05, .15], ratios, matrix); g.drawRect(barX, barY, barWidthSplit, 1); g.drawRect(barX, barY2, barWidthSplit, 1); matrix.createGradientBox(barWidthSplit, barHeight, 0, barX + barWidthSplit, barY); g.beginGradientFill(GradientType.LINEAR, colors, [ .15, .25], ratios, matrix); g.drawRect(barX + barWidthSplit, barY, barWidthSplit, 1); g.drawRect(barX + barWidthSplit, barY2, barWidthSplit, 1); matrix.createGradientBox(barWidthSplit, barHeight, 0, barX + barWidthSplit * 2, barY); g.beginGradientFill(GradientType.LINEAR, colors, [ .25, .1], ratios, matrix); g.drawRect(barX + barWidthSplit * 2, barY, barWidthSplit, 1); g.drawRect(barX + barWidthSplit * 2, barY2, barWidthSplit, 1); // Inner highlight barWidthSplit = barWidth / 3; barHeight = _barRect.height; barY = calcY(_barRect.y) + 1; barY2 = calcY(_barRect.y) + barHeight - 2; matrix.createGradientBox(barWidthSplit, barHeight, 0, barX, barY); g.beginGradientFill(GradientType.LINEAR, colors, [ .15, .30], ratios, matrix); g.drawRect(barX, barY, barWidthSplit, 1); g.drawRect(barX, barY2, barWidthSplit, 1); matrix.createGradientBox(barWidthSplit, barHeight, 0, barX + barWidthSplit, barY); g.beginGradientFill(GradientType.LINEAR, colors, [ .30, .40], ratios, matrix); g.drawRect(barX + barWidthSplit, barY, barWidthSplit, 1); g.drawRect(barX + barWidthSplit, barY2, barWidthSplit, 1); matrix.createGradientBox(barWidthSplit, barHeight, 0, barX + barWidthSplit * 2, barY); g.beginGradientFill(GradientType.LINEAR, colors, [ .40, .25], ratios, matrix); g.drawRect(barX + barWidthSplit * 2, barY, barWidthSplit, 1); g.drawRect(barX + barWidthSplit * 2, barY2, barWidthSplit, 1); } /** * Updates the display of the download progress bar * with the current download information. * A typical implementation divides the loaded value by the total value * and displays a percentage. * If you do not implement this method, you should create * a progress bar that displays an animation to indicate to the user * that a download is occurring. * *

The setProgress() method is only called * if the application is being downloaded from a remote server * and the application is not in the browser cache.

* * @param completed Number of bytes of the application SWF file * that have been downloaded. * * @param total Size of the application SWF file in bytes. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function setProgress(completed:Number, total:Number):void { if (!isNaN(completed) && !isNaN(total) && completed >= 0 && total > 0) { _value = Number(completed); _maximum = Number(total); draw(); } } /** * Returns the percentage value of the application loaded. * * @param loaded Number of bytes of the application SWF file * that have been downloaded. * * @param total Size of the application SWF file in bytes. * * @return The percentage value of the loaded application. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function getPercentLoaded(loaded:Number, total:Number):Number { var perc:Number; if (loaded == 0 || total == 0 || isNaN(total) || isNaN(loaded)) return 0; else perc = 100 * loaded/total; if (isNaN(perc) || perc <= 0) return 0; else if (perc > 99) return 99; else return Math.round(perc); } /** * @private * Make the display class visible. */ private function show():void { _showingDisplay = true; calcScale(); draw(); _displayTime = getTimer(); // Time when the display is shown. } /** * @private */ private function hide():void { } /** * @private */ private function calcX(base:Number):Number { return base + _xOffset; } /** * @private */ private function calcY(base:Number):Number { return base + _yOffset; } /** * @private * Figure out the scale for the display class based on the stage size. * Then creates the children subcomponents. */ private function calcScale():void { if (stageWidth < 160 || stageHeight < 120) { scaleX = 1.0; scaleY = 1.0; } else if (stageWidth < 240 || stageHeight < 150) { // Scale to appropriate size createChildren(); var scale:Number = Math.min(stageWidth / 240.0, stageHeight / 150.0); scaleX = scale; scaleY = scale; } else { createChildren(); } } /** * Defines the algorithm for determining whether to show * the download progress bar while in the download phase. * * @param elapsedTime number of milliseconds that have elapsed * since the start of the download phase. * * @param event The ProgressEvent object that contains * the bytesLoaded and bytesTotal properties. * * @return If the return value is true, then show the * download progress bar. * The default behavior is to show the download progress bar * if more than 700 milliseconds have elapsed * and if Flex has downloaded less than half of the bytes of the SWF file. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function showDisplayForDownloading(elapsedTime:int, event:ProgressEvent):Boolean { return elapsedTime > 700 && event.bytesLoaded < event.bytesTotal / 2; } /** * Defines the algorithm for determining whether to show the download progress bar * while in the initialization phase, assuming that the display * is not currently visible. * * @param elapsedTime number of milliseconds that have elapsed * since the start of the download phase. * * @param count number of times that the initProgress event * has been received from the application. * * @return If true, then show the download progress bar. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function showDisplayForInit(elapsedTime:int, count:int):Boolean { return elapsedTime > 300 && count == 2; } /** * @private */ private function loadBackgroundImage(classOrString:Object):void { var cls:Class; // The "as" operator checks to see if classOrString // can be coerced to a Class if (classOrString && classOrString as Class) { // Load background image given a class pointer cls = Class(classOrString); initBackgroundImage(new cls()); } else if (classOrString && classOrString is String) { try { cls = Class(getDefinitionByName(String(classOrString))); } catch(e:Error) { // ignore } if (cls) { var newStyleObj:DisplayObject = new cls(); initBackgroundImage(newStyleObj); } else { // Loading the image is slightly different // than in Loader.loadContent()... is this on purpose? // Load background image from external URL var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener( Event.COMPLETE, loader_completeHandler); loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, loader_ioErrorHandler); var loaderContext:LoaderContext = new LoaderContext(); loaderContext.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain); loader.load(new URLRequest(String(classOrString)), loaderContext); } } } /** * @private */ private function initBackgroundImage(image:DisplayObject):void { addChildAt(image,0); var backgroundImageWidth:Number = image.width; var backgroundImageHeight:Number = image.height; // Scale according to backgroundSize var percentage:Number = calcBackgroundSize(); if (isNaN(percentage)) { var sX:Number = 1.0; var sY:Number = 1.0; } else { var scale:Number = percentage * 0.01; sX = scale * stageWidth / backgroundImageWidth; sY = scale * stageHeight / backgroundImageHeight; } image.scaleX = sX; image.scaleY = sY; // Center everything. // Use a scrollRect to position and clip the image. var offsetX:Number = Math.round(0.5 * (stageWidth - backgroundImageWidth * sX)); var offsetY:Number = Math.round(0.5 * (stageHeight - backgroundImageHeight * sY)); image.x = offsetX; image.y = offsetY; // Adjust alpha to match backgroundAlpha if (!isNaN(backgroundAlpha)) image.alpha = backgroundAlpha; } /** * @private */ private function calcBackgroundSize():Number { var percentage:Number = NaN; if (backgroundSize) { var index:int = backgroundSize.indexOf("%"); if (index != -1) percentage = Number(backgroundSize.substr(0, index)); } return percentage; } //-------------------------------------------------------------------------- // // Event handlers // //-------------------------------------------------------------------------- /** * Event listener for the ProgressEvent.PROGRESS event. * This implementation updates the progress bar * with the percentage of bytes downloaded. * * @param event The event object. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function progressHandler(event:ProgressEvent):void { var loaded:uint = event.bytesLoaded; var total:uint = event.bytesTotal; var elapsedTime:int = getTimer() - _startTime; // Only show the Loading phase if it will appear for awhile. if (_showingDisplay || showDisplayForDownloading(elapsedTime, event)) { if (!_startedLoading) { show(); label = downloadingLabel; _startedLoading = true; } setProgress(event.bytesLoaded, event.bytesTotal); } } /** * Event listener for the Event.COMPLETE event. * The default implementation does nothing. * * @param event The event object. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function completeHandler(event:Event):void { } /** * Event listener for the RSLEvent.RSL_PROGRESS event. * The default implementation does nothing. * * @param event The event object. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function rslProgressHandler(event:RSLEvent):void { } /** * Event listener for the RSLEvent.RSL_COMPLETE event. * * @param event The event object. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function rslCompleteHandler(event:RSLEvent):void { var word:String = "library"; if (event.isResourceModule) word = "module"; label = "Loaded " + word + " " + event.rslIndex + " of " + event.rslTotal; } /** * Event listener for the RSLEvent.RSL_ERROR event. * This event listner handles any errors detected when downloading an RSL. * * @param event The event object. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function rslErrorHandler(event:RSLEvent):void { _preloader.removeEventListener(ProgressEvent.PROGRESS, progressHandler); _preloader.removeEventListener(Event.COMPLETE, completeHandler); _preloader.removeEventListener(RSLEvent.RSL_PROGRESS, rslProgressHandler); _preloader.removeEventListener(RSLEvent.RSL_COMPLETE, rslCompleteHandler); _preloader.removeEventListener(RSLEvent.RSL_ERROR, rslErrorHandler); _preloader.removeEventListener(FlexEvent.INIT_PROGRESS, initProgressHandler); _preloader.removeEventListener(FlexEvent.INIT_COMPLETE, initCompleteHandler); if (!_showingDisplay) { show(); _showingDisplay = true; } label = "RSL Error " + (event.rslIndex + 1) + " of " + event.rslTotal; var errorField:ErrorField = new ErrorField(this); errorField.show(event.errorText); } /** * @private * Helper function that dispatches the Complete event to the preloader. * * @param event The event object. */ private function timerHandler(event:Event = null):void { dispatchEvent(new Event(Event.COMPLETE)); } /** * Event listener for the FlexEvent.INIT_PROGRESS event. * This implementation updates the progress bar * each time the event is dispatched, and changes the text of the label. * * @param event The event object. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function initProgressHandler(event:Event):void { var elapsedTime:int = getTimer() - _startTime; _initProgressCount++; if (!_showingDisplay && showDisplayForInit(elapsedTime, _initProgressCount)) { _displayStartCount = _initProgressCount; show(); } if (_showingDisplay) { if (!_startedInit) { // First init progress event. _startedInit = true; label = initializingLabel; } var loaded:Number = 100 * _initProgressCount / (initProgressTotal - _displayStartCount); setProgress(Math.min(loaded, 100), 100); } } /** * Event listener for the FlexEvent.INIT_COMPLETE event. * * @param event The event object. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function initCompleteHandler(event:Event):void { var elapsedTime:int = getTimer() - _displayTime; if (_showingDisplay && elapsedTime < MINIMUM_DISPLAY_TIME) { var timer:Timer = new Timer(MINIMUM_DISPLAY_TIME - elapsedTime, 1); timer.addEventListener(TimerEvent.TIMER, timerHandler); timer.start(); } else { timerHandler(); } } /** * @private */ private function loader_completeHandler(event:Event):void { var target:DisplayObject = DisplayObject(LoaderInfo(event.target).loader); initBackgroundImage(target); } private function loader_ioErrorHandler(event:IOErrorEvent):void { // Swallow the error } } } import flash.display.DisplayObject; import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFormat; import flash.system.Capabilities; import flash.text.TextFieldAutoSize; import flash.display.DisplayObjectContainer; import flash.display.Stage; import mx.preloaders.DownloadProgressBar; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * @private * * Area to display error messages to help debug startup problems. * */ class ErrorField extends Sprite { private var downloadProgressBar:DownloadProgressBar; private const MIN_WIDTH_INCHES:int = 2; // min width of error message in inches private const MAX_WIDTH_INCHES:int = 6; // max width of error message in inches private const TEXT_MARGIN_PX:int = 10; //---------------------------------- // labelFormat //---------------------------------- /** * The TextFormat object of the TextField component of the label. * This is a read-only property which you must override * if you need to change it. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get labelFormat():TextFormat { var tf:TextFormat = new TextFormat(); tf.color = 0x000000; tf.font = "Verdana"; tf.size = 10; return tf; } /** * @private * * @param - parent - parent of the error field. */ public function ErrorField(downloadProgressBar:DownloadProgressBar) { super(); this.downloadProgressBar = downloadProgressBar; } /** * Create and show the error message. * * @param errorText - text for error message. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function show(errorText:String):void { if (errorText == null || errorText.length == 0) return; var screenWidth:Number = downloadProgressBar.stageWidth; var screenHeight:Number = downloadProgressBar.stageHeight; // create the text field for the message and // add it to the parent. var textField:TextField = new TextField(); textField.autoSize = TextFieldAutoSize.LEFT; textField.multiline = true; textField.wordWrap = true; textField.background = true; textField.defaultTextFormat = labelFormat; textField.text = errorText; textField.width = Math.max(MIN_WIDTH_INCHES * Capabilities.screenDPI, screenWidth - (TEXT_MARGIN_PX * 2)); textField.width = Math.min(MAX_WIDTH_INCHES * Capabilities.screenDPI, textField.width); textField.y = Math.max(0, screenHeight - TEXT_MARGIN_PX - textField.height); // center field horizontally textField.x = (screenWidth - textField.width) / 2; downloadProgressBar.parent.addChild(this); this.addChild(textField); } }