All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.feathers.controls.ImageLoader.as Maven / Gradle / Ivy

/*
Feathers
Copyright 2012-2015 Bowler Hat LLC. All Rights Reserved.

This program is free software. You can redistribute and/or modify it in
accordance with the terms of the accompanying license agreement.
*/
package feathers.controls
{
	import feathers.core.FeathersControl;
	import feathers.events.FeathersEventType;
	import feathers.layout.HorizontalAlign;
	import feathers.layout.VerticalAlign;
	import feathers.skins.IStyleProvider;
	import feathers.utils.display.stageToStarling;
	import feathers.utils.textures.TextureCache;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display3D.Context3DTextureFormat;
	import flash.errors.IllegalOperationError;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.system.ImageDecodingPolicy;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	import flash.utils.setTimeout;

	import starling.core.Starling;
	import starling.display.Image;
	import starling.display.Quad;
	import starling.events.EnterFrameEvent;
	import starling.events.Event;
	import starling.textures.Texture;
	import starling.textures.TextureSmoothing;
	import starling.utils.RectangleUtil;
	import starling.utils.ScaleMode;
	import starling.utils.SystemUtil;

	/**
	 * Dispatched when the source finishes loading, if the source is a URL. This
	 * event is not dispatched when the source is a texture.
	 *
	 * 

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
datanull
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @eventType starling.events.Event.COMPLETE */ [Event(name="complete",type="starling.events.Event")] /** * Dispatched periodically as the source loads, if the source is a URL. This * event is not dispatched when the source is a texture. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
dataA value between 0.0 and 1.0 to indicate * how much image data has loaded.
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @eventType feathers.events.FeathersEventType.PROGRESS */ [Event(name="progress",type="starling.events.Event")] /** * DEPRECATED: Replaced by Event.IO_ERROR and * Event.SECURITY_ERROR. * *

DEPRECATION WARNING: This event is deprecated * starting with Feathers 2.2. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

* * @eventType feathers.events.FeathersEventType.ERROR * * @see #event:ioError * @see #event:securityError */ [Event(name="error",type="starling.events.Event")] /** * Dispatched if an IO error occurs while loading the source content. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
dataThe flash.events.IOErrorEvent * dispatched by the loader.
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @eventType starling.events.Event.IO_ERROR */ [Event(name="ioError",type="starling.events.Event")] /** * Dispatched if a security error occurs while loading the source content. * *

The properties of the event object have the following values:

* * * * * * *
PropertyValue
bubblesfalse
currentTargetThe Object that defines the * event listener that handles the event. For example, if you use * myButton.addEventListener() to register an event listener, * myButton is the value of the currentTarget.
dataThe flash.events.SecurityErrorEvent * dispatched by the loader.
targetThe Object that dispatched the event; * it is not always the Object listening for the event. Use the * currentTarget property to always access the Object * listening for the event.
* * @eventType starling.events.Event.SECURITY_ERROR */ [Event(name="securityError",type="starling.events.Event")] /** * Displays an image, either from an existing Texture object or * from an image file loaded with its URL. Supported image files include ATF * format and any bitmap formats that may be loaded by * flash.display.Loader, including JPG, GIF, and PNG. * *

The following example passes a URL to an image loader and listens for * its complete event:

* * * var loader:ImageLoader = new ImageLoader(); * loader.source = "http://example.com/example.png"; * loader.addEventListener( Event.COMPLETE, loader_completeHandler ); * this.addChild( loader ); * *

The following example passes an existing texture to an image loader:

* * * var loader:ImageLoader = new ImageLoader(); * loader.source = Texture.fromBitmap( bitmap ); * this.addChild( loader ); */ public class ImageLoader extends FeathersControl { /** * @private */ private static const HELPER_RECTANGLE:Rectangle = new Rectangle(); /** * @private */ private static const HELPER_RECTANGLE2:Rectangle = new Rectangle(); /** * @private */ private static const CONTEXT_LOST_WARNING:String = "ImageLoader: Context lost while processing loaded image, retrying..."; /** * @private */ protected static const LOADER_CONTEXT:LoaderContext = new LoaderContext(true); LOADER_CONTEXT.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD; /** * @private */ protected static const ATF_FILE_EXTENSION:String = "atf"; /** * @private */ protected static var textureQueueHead:ImageLoader; /** * @private */ protected static var textureQueueTail:ImageLoader; /** * @private * DEPRECATED: Replaced by feathers.layout.HorizontalAlign.LEFT. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const HORIZONTAL_ALIGN_LEFT:String = "left"; /** * @private * DEPRECATED: Replaced by feathers.layout.HorizontalAlign.CENTER. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const HORIZONTAL_ALIGN_CENTER:String = "center"; /** * @private * DEPRECATED: Replaced by feathers.layout.HorizontalAlign.RIGHT. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const HORIZONTAL_ALIGN_RIGHT:String = "right"; /** * @private * DEPRECATED: Replaced by feathers.layout.VerticalAlign.TOP. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const VERTICAL_ALIGN_TOP:String = "top"; /** * @private * DEPRECATED: Replaced by feathers.layout.VerticalAlign.MIDDLE. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const VERTICAL_ALIGN_MIDDLE:String = "middle"; /** * @private * DEPRECATED: Replaced by feathers.layout.VerticalAlign.BOTTOM. * *

DEPRECATION WARNING: This constant is deprecated * starting with Feathers 3.0. It will be removed in a future version of * Feathers according to the standard * Feathers deprecation policy.

*/ public static const VERTICAL_ALIGN_BOTTOM:String = "bottom"; /** * The default IStyleProvider for all ImageLoader * components. * * @default null * @see feathers.core.FeathersControl#styleProvider */ public static var globalStyleProvider:IStyleProvider; /** * Constructor. */ public function ImageLoader() { this.isQuickHitAreaEnabled = true; } /** * The internal starling.display.Image child. */ protected var image:Image; /** * The internal flash.display.Loader used to load textures * from URLs. */ protected var loader:Loader; /** * The internal flash.net.URLLoader used to load raw data * from URLs. */ protected var urlLoader:URLLoader; /** * @private */ protected var _lastURL:String; /** * @private */ protected var _originalTextureWidth:Number = NaN; /** * @private */ protected var _originalTextureHeight:Number = NaN; /** * @private */ protected var _currentTextureWidth:Number = NaN; /** * @private */ protected var _currentTextureHeight:Number = NaN; /** * @private */ protected var _currentTexture:Texture; /** * @private */ protected var _isRestoringTexture:Boolean = false; /** * @private */ protected var _texture:Texture; /** * @private */ protected var _isTextureOwner:Boolean = false; /** * @private */ override protected function get defaultStyleProvider():IStyleProvider { return ImageLoader.globalStyleProvider; } /** * @private */ protected var _source:Object; /** * The Texture to display, or a URL pointing to an image * file. Supported image files include ATF format and any bitmap formats * that may be loaded by flash.display.Loader, including * JPG, GIF, and PNG. * *

In the following example, the image loader's source is set to a * texture:

* * * loader.source = Texture.fromBitmap( bitmap ); * *

In the following example, the image loader's source is set to the * URL of a PNG image:

* * * loader.source = "http://example.com/example.png"; * * @default null * * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Loader.html * @see http://wiki.starling-framework.org/manual/atf_textures */ public function get source():Object { return this._source; } /** * @private */ public function set source(value:Object):void { if(this._source == value) { return; } this._isRestoringTexture = false; if(this._isInTextureQueue) { this.removeFromTextureQueue(); } var oldTexture:Texture; //we should try to reuse the existing texture, if possible. if(this._isTextureOwner && value && !(value is Texture)) { oldTexture = this._texture; this._isTextureOwner = false; } this.cleanupTexture(); //the source variable needs to be set after cleanupTexture() is //called because cleanupTexture() needs to know the old source if //a TextureCache is in use. this._source = value; if(oldTexture) { this._texture = oldTexture; this._isTextureOwner = true; } if(this.image) { this.image.visible = false; } this.cleanupLoaders(true); this._lastURL = null; if(this._source is Texture) { this._isLoaded = true; } else { this._isLoaded = false; } this.invalidate(INVALIDATION_FLAG_DATA); } /** * @private */ protected var _textureCache:TextureCache; /** * An optional cache for textures. * *

In the following example, a cache is provided for textures:

* * * var cache:TextureCache = new TextureCache(30); * loader1.textureCache = cache; * loader2.textureCache = cache; * *

Warning: the textures in the cache will not be * disposed automatically. When the cache is no longer needed (such as * when the ImageLoader components have all been disposed), * you must call the dispose() method on the * TextureCache. Failing to do so will result in a serious * memory leak.

* * @default null */ public function get textureCache():TextureCache { return this._textureCache; } /** * @private */ public function set textureCache(value:TextureCache):void { this._textureCache = value; } /** * @private */ protected var _loadingTexture:Texture; /** * A texture to display while a URL source is loading. * *

In the following example, the image loader's loading texture is * customized:

* * * loader.source = "http://example.com/example.png"; * loader.loadingTexture = texture; * * @default null * * @see #errorTexture */ public function get loadingTexture():Texture { return this._loadingTexture; } /** * @private */ public function set loadingTexture(value:Texture):void { if(this._loadingTexture == value) { return; } this._loadingTexture = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _errorTexture:Texture; /** * A texture to display when a URL source cannot be loaded for any * reason. * *

In the following example, the image loader's error texture is * customized:

* * * loader.source = "http://example.com/example.png"; * loader.errorTexture = texture; * * @default null * * @see #loadingTexture */ public function get errorTexture():Texture { return this._errorTexture; } /** * @private */ public function set errorTexture(value:Texture):void { if(this._errorTexture == value) { return; } this._errorTexture = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _isLoaded:Boolean = false; /** * Indicates if the source has completed loading, if the source is a * URL. Always returns true when the source is a texture. * *

In the following example, we check if the image loader's source * has finished loading:

* * * if( loader.isLoaded ) * { * //do something * } */ public function get isLoaded():Boolean { return this._isLoaded; } /** * @private */ private var _textureScale:Number = 1; /** * Scales the texture dimensions during measurement. Useful for UI that * should scale based on screen density or resolution. * *

In the following example, the image loader's texture scale is * customized:

* * * loader.textureScale = 0.5; * * @default 1 */ public function get textureScale():Number { return this._textureScale; } /** * @private */ public function set textureScale(value:Number):void { if(this._textureScale == value) { return; } this._textureScale = value; this.invalidate(INVALIDATION_FLAG_SIZE); } /** * @private */ private var _scaleFactor:Number = 1; /** * The scale factor value to pass to Texture.fromBitmapData() * when creating a texture loaded from a URL. * *

In the following example, the image loader's scale factor is * customized:

* * * loader.scaleFactor = 2; * * @default 1 */ public function get scaleFactor():Number { return this._textureScale; } /** * @private */ public function set scaleFactor(value:Number):void { if(this._scaleFactor == value) { return; } this._scaleFactor = value; this.invalidate(INVALIDATION_FLAG_SIZE); } /** * @private */ private var _textureSmoothing:String = TextureSmoothing.BILINEAR; /** * The texture smoothing value to use on the internal Image. * *

In the following example, the image loader's smoothing is set to a * custom value:

* * * loader.textureSmoothing = TextureSmoothing.NONE; * * @default starling.textures.TextureSmoothing.BILINEAR * * @see http://doc.starling-framework.org/core/starling/textures/TextureSmoothing.html starling.textures.TextureSmoothing * @see http://doc.starling-framework.org/core/starling/display/Mesh.html#textureSmoothing starling.display.Mesh.textureSmoothing */ public function get textureSmoothing():String { return this._textureSmoothing; } /** * @private */ public function set textureSmoothing(value:String):void { if(this._textureSmoothing == value) { return; } this._textureSmoothing = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ private var _scale9Grid:Rectangle; /** * The scale9Grid value to use on the internal Image. * *

In the following example, the image loader's scale9Grid is set to a * custom value:

* * * loader.scale9Grid = Rectangle(2, 3, 7, 12); * * @default null * * @see http://doc.starling-framework.org/core/starling/display/Image.html#scale9Grid starling.display.Image.scale9Grid */ public function get scale9Grid():Rectangle { return this._scale9Grid; } /** * @private */ public function set scale9Grid(value:Rectangle):void { if(this._scale9Grid == value) { return; } this._scale9Grid = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ private var _tileGrid:Rectangle; /** * The tileGrid value to use on the internal Image. * *

In the following example, the image loader's tileGrid is set to a * custom value:

* * * loader.tileGrid = Rectangle(); * * @default null * * @see http://doc.starling-framework.org/core/starling/display/Image.html#tileGrid starling.display.Image.tileGrid */ public function get tileGrid():Rectangle { return this._tileGrid; } /** * @private */ public function set tileGrid(value:Rectangle):void { if(this._tileGrid == value) { return; } this._tileGrid = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ private var _pixelSnapping:Boolean = true; /** * The pixelSnapping value to use on the internal Image. * *

In the following example, the image loader's pixelSnapping is * disabled:

* * * loader.pixelSnapping = false; * * @default true * * @see http://doc.starling-framework.org/core/starling/display/Mesh.html#pixelSnapping starling.display.Mesh.pixelSnapping */ public function get pixelSnapping():Boolean { return this._pixelSnapping; } /** * @private */ public function set pixelSnapping(value:Boolean):void { if(this._pixelSnapping == value) { return; } this._pixelSnapping = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ private var _color:uint = 0xffffff; /** * The tint value to use on the internal Image. * *

In the following example, the image loader's texture color is * customized:

* * * loader.color = 0xff00ff; * * @default 0xffffff * * @see http://doc.starling-framework.org/core/starling/display/Image.html#color starling.display.Image.color */ public function get color():uint { return this._color; } /** * @private */ public function set color(value:uint):void { if(this._color == value) { return; } this._color = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ private var _textureFormat:String = Context3DTextureFormat.BGRA; /** * The texture format to use when creating a texture loaded from a URL. * *

In the following example, the image loader's texture format is set * to a custom value:

* * * loader.textureFormat = Context3DTextureFormat.BGRA_PACKED; * * @default flash.display3d.Context3DTextureFormat.BGRA * * @see http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display3D/Context3DTextureFormat.html flash.display3d.Context3DTextureFormat */ public function get textureFormat():String { return this._textureFormat; } /** * @private */ public function set textureFormat(value:String):void { if(this._textureFormat == value) { return; } this._textureFormat = value; this._lastURL = null; this.invalidate(INVALIDATION_FLAG_DATA); } /** * @private */ private var _scaleContent:Boolean = true; /** * Determines if the content will be scaled if the dimensions of the * ImageLoader are changed. * *

In the following example, the image loader's content is not * scaled:

* * * loader.scaleContent = false; * * @default true * * @see #horizontalAlign * @see #verticalAlign * @see #maintainAspectRatio */ public function get scaleContent():Boolean { return this._scaleContent; } /** * @private */ public function set scaleContent(value:Boolean):void { if(this._scaleContent == value) { return; } this._scaleContent = value; this.invalidate(INVALIDATION_FLAG_LAYOUT); } /** * @private */ private var _maintainAspectRatio:Boolean = true; /** * Determines if the aspect ratio of the texture is maintained when the * dimensions of the ImageLoader are changed manually and * the new dimensions have a different aspect ratio than the texture. * *

If the scaleContent property is set to * false, the maintainAspectRatio property is * ignored.

* *

In the following example, the image loader's aspect ratio is not * maintained:

* * * loader.maintainAspectRatio = false; * * @default true * * @see #scaleContent */ public function get maintainAspectRatio():Boolean { return this._maintainAspectRatio; } /** * @private */ public function set maintainAspectRatio(value:Boolean):void { if(this._maintainAspectRatio == value) { return; } this._maintainAspectRatio = value; this.invalidate(INVALIDATION_FLAG_LAYOUT); } /** * @private */ private var _scaleMode:String = ScaleMode.SHOW_ALL; [Inspectable(type="String",enumeration="showAll,noBorder,none")] /** * Determines how the texture is scaled if scaleContent and * maintainAspectRatio are both set to true. * See the starling.utils.ScaleMode class for details about * each scaling mode. * *

If the scaleContent property is set to * false, or the maintainAspectRatio property * is set to false, the scaleMode property is ignored.

* *

In the following example, the image loader's aspect ratio is not * maintained:

* * * loader.scaleMode = ScaleMode.NO_BORDER; * * @default starling.utils.ScaleMode.SHOW_ALL * * @see #scaleContent * @see #maintainAspectRatio * @see http://doc.starling-framework.org/core/starling/utils/ScaleMode.html starling.utils.ScaleMode */ public function get scaleMode():String { return this._scaleMode; } /** * @private */ public function set scaleMode(value:String):void { if(this._scaleMode == value) { return; } this._scaleMode = value; this.invalidate(INVALIDATION_FLAG_LAYOUT); } /** * @private */ protected var _horizontalAlign:String = HorizontalAlign.LEFT; [Inspectable(type="String",enumeration="left,center,right")] /** * The location where the content is aligned horizontally (on * the x-axis) when its width is larger or smaller than the width of * the ImageLoader. * *

If the scaleContent property is set to * true, the horizontalAlign property is * ignored.

* *

The following example aligns the content to the right:

* * * loader.horizontalAlign = HorizontalAlign.RIGHT; * * @default feathers.layout.HorizontalAlign.LEFT * * @see #scaleContent * @see feathers.layout.HorizontalAlign#LEFT * @see feathers.layout.HorizontalAlign#CENTER * @see feathers.layout.HorizontalAlign#RIGHT */ public function get horizontalAlign():String { return this._horizontalAlign; } /** * @private */ public function set horizontalAlign(value:String):void { if(this._horizontalAlign == value) { return; } this._horizontalAlign = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _verticalAlign:String = VerticalAlign.TOP; [Inspectable(type="String",enumeration="top,middle,bottom")] /** * The location where the content is aligned vertically (on * the y-axis) when its height is larger or smaller than the height of * the ImageLoader. * *

If the scaleContent property is set to * true, the verticalAlign property is * ignored.

* *

The following example aligns the content to the bottom:

* * * loader.verticalAlign = VerticalAlign.BOTTOM; * * @default feathers.layout.VerticalAlign.TOP * * @see #scaleContent * @see feathers.layout.VerticalAlign#TOP * @see feathers.layout.VerticalAlign#MIDDLE * @see feathers.layout.VerticalAlign#BOTTOM */ public function get verticalAlign():String { return _verticalAlign; } /** * @private */ public function set verticalAlign(value:String):void { if(this._verticalAlign == value) { return; } this._verticalAlign = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * The original width of the source content, in pixels. This value will * be 0 until the source content finishes loading. If the * source is a texture, this value will be 0 until the * ImageLoader validates. */ public function get originalSourceWidth():Number { if(this._originalTextureWidth === this._originalTextureWidth) //!isNaN { return this._originalTextureWidth; } return 0; } /** * The original height of the source content, in pixels. This value will * be 0 until the source content finishes loading. If the * source is a texture, this value will be 0 until the * ImageLoader validates. */ public function get originalSourceHeight():Number { if(this._originalTextureHeight === this._originalTextureHeight) //!isNaN { return this._originalTextureHeight; } return 0; } /** * @private */ protected var _pendingBitmapDataTexture:BitmapData; /** * @private */ protected var _pendingRawTextureData:ByteArray; /** * @private */ protected var _delayTextureCreation:Boolean = false; /** * Determines if a loaded bitmap may be converted to a texture * immediately after loading. If true, the loaded bitmap * will be saved until this property is set to false, and * only then it will be used to create the texture. * *

This property is intended to be used while a parent container, * such as a List, is scrolling in order to keep scrolling * as smooth as possible. Creating textures is expensive and performance * can be affected by it. Set this property to true when * the List dispatches FeathersEventType.SCROLL_START * and set back to false when the List dispatches * FeathersEventType.SCROLL_COMPLETE. You may also need * to set to false if the isScrolling property of the * List is true before you listen to those * events.

* *

In the following example, the image loader's texture creation is * delayed:

* * * loader.delayTextureCreation = true; * * @default false * * @see #textureQueueDuration * @see feathers.controls.Scroller#event:scrollStart * @see feathers.controls.Scroller#event:scrollComplete * @see feathers.controls.Scroller#isScrolling */ public function get delayTextureCreation():Boolean { return this._delayTextureCreation; } /** * @private */ public function set delayTextureCreation(value:Boolean):void { if(this._delayTextureCreation == value) { return; } this._delayTextureCreation = value; if(!this._delayTextureCreation) { this.processPendingTexture(); } } /** * @private */ protected var _isInTextureQueue:Boolean = false; /** * @private */ protected var _textureQueuePrevious:ImageLoader; /** * @private */ protected var _textureQueueNext:ImageLoader; /** * @private */ protected var _accumulatedPrepareTextureTime:Number; /** * @private */ protected var _textureQueueDuration:Number = Number.POSITIVE_INFINITY; /** * If delayTextureCreation is true and the * duration is not Number.POSITIVE_INFINITY, the loader * will be added to a queue where the textures are uploaded to the GPU * in sequence to avoid significantly affecting performance. Useful for * lists where many textures may need to be uploaded during scrolling. * *

If the duration is Number.POSITIVE_INFINITY, the * default value, the texture will not be uploaded until * delayTextureCreation is set to false. In * this situation, the loader will not be added to the queue, and other * loaders with a duration won't be affected.

* *

In the following example, the image loader's texture creation is * delayed by half a second:

* * * loader.delayTextureCreation = true; * loader.textureQueueDuration = 0.5; * * @default Number.POSITIVE_INFINITY * * @see #delayTextureCreation */ public function get textureQueueDuration():Number { return this._textureQueueDuration; } /** * @private */ public function set textureQueueDuration(value:Number):void { if(this._textureQueueDuration == value) { return; } var oldDuration:Number = this._textureQueueDuration; this._textureQueueDuration = value; if(this._delayTextureCreation) { if((this._pendingBitmapDataTexture || this._pendingRawTextureData) && oldDuration == Number.POSITIVE_INFINITY && this._textureQueueDuration < Number.POSITIVE_INFINITY) { this.addToTextureQueue(); } else if(this._isInTextureQueue && this._textureQueueDuration == Number.POSITIVE_INFINITY) { this.removeFromTextureQueue(); } } } /** * Quickly sets all padding properties to the same value. The * padding getter always returns the value of * paddingTop, but the other padding values may be * different. * *

In the following example, the image loader's padding is set to * 20 pixels on all sides:

* * * loader.padding = 20; * * @default 0 * * @see #paddingTop * @see #paddingRight * @see #paddingBottom * @see #paddingLeft */ public function get padding():Number { return this._paddingTop; } /** * @private */ public function set padding(value:Number):void { this.paddingTop = value; this.paddingRight = value; this.paddingBottom = value; this.paddingLeft = value; } /** * @private */ protected var _paddingTop:Number = 0; /** * The minimum space, in pixels, between the control's top edge and the * control's content. Value may be negative to extend the content * outside the edges of the control. Useful for skinning. * *

In the following example, the image loader's top padding is set * to 20 pixels:

* * * loader.paddingTop = 20; * * @default 0 */ public function get paddingTop():Number { return this._paddingTop; } /** * @private */ public function set paddingTop(value:Number):void { if(this._paddingTop == value) { return; } this._paddingTop = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _paddingRight:Number = 0; /** * The minimum space, in pixels, between the control's right edge and the * control's content. Value may be negative to extend the content * outside the edges of the control. Useful for skinning. * *

In the following example, the image loader's right padding is set * to 20 pixels:

* * * loader.paddingRight = 20; * * @default 0 */ public function get paddingRight():Number { return this._paddingRight; } /** * @private */ public function set paddingRight(value:Number):void { if(this._paddingRight == value) { return; } this._paddingRight = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _paddingBottom:Number = 0; /** * The minimum space, in pixels, between the control's bottom edge and the * control's content. Value may be negative to extend the content * outside the edges of the control. Useful for skinning. * *

In the following example, the image loader's bottom padding is set * to 20 pixels:

* * * loader.paddingBottom = 20; * * @default 0 */ public function get paddingBottom():Number { return this._paddingBottom; } /** * @private */ public function set paddingBottom(value:Number):void { if(this._paddingBottom == value) { return; } this._paddingBottom = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ protected var _paddingLeft:Number = 0; /** * The minimum space, in pixels, between the control's left edge and the * control's content. Value may be negative to extend the content * outside the edges of the control. Useful for skinning. * *

In the following example, the image loader's left padding is set * to 20 pixels:

* * * loader.paddingLeft = 20; * * @default 0 */ public function get paddingLeft():Number { return this._paddingLeft; } /** * @private */ public function set paddingLeft(value:Number):void { if(this._paddingLeft == value) { return; } this._paddingLeft = value; this.invalidate(INVALIDATION_FLAG_STYLES); } /** * @private */ override public function dispose():void { this._isRestoringTexture = false; if(this.loader) { this.loader.contentLoaderInfo.removeEventListener(flash.events.Event.COMPLETE, loader_completeHandler); this.loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, loader_progressHandler); this.loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, loader_ioErrorHandler); this.loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loader_securityErrorHandler); try { this.loader.close(); } catch(error:Error) { //no need to do anything in response } this.loader = null; } this.cleanupTexture(); super.dispose(); } /** * @private */ override protected function draw():void { var dataInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_DATA); var layoutInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_LAYOUT); var stylesInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_STYLES); var sizeInvalid:Boolean = this.isInvalid(INVALIDATION_FLAG_SIZE); if(dataInvalid) { this.commitData(); } if(dataInvalid || stylesInvalid) { this.commitStyles(); } sizeInvalid = this.autoSizeIfNeeded() || sizeInvalid; if(dataInvalid || layoutInvalid || sizeInvalid || stylesInvalid) { this.layout(); } } /** * If the component's dimensions have not been set explicitly, it will * measure its content and determine an ideal size for itself. If the * explicitWidth or explicitHeight member * variables are set, those value will be used without additional * measurement. If one is set, but not the other, the dimension with the * explicit value will not be measured, but the other non-explicit * dimension will still need measurement. * *

Calls setSizeInternal() to set up the * actualWidth and actualHeight member * variables used for layout.

* *

Meant for internal use, and subclasses may override this function * with a custom implementation.

*/ protected function autoSizeIfNeeded():Boolean { var needsWidth:Boolean = this._explicitWidth !== this._explicitWidth; //isNaN var needsHeight:Boolean = this._explicitHeight !== this._explicitHeight; //isNaN if(!needsWidth && !needsHeight) { return false; } var newWidth:Number = this._explicitWidth; if(needsWidth) { if(this._currentTextureWidth === this._currentTextureWidth) //!isNaN { newWidth = this._currentTextureWidth * this._textureScale; if(this._scaleContent && this._maintainAspectRatio) { var heightScale:Number = 1; if(!needsHeight) { heightScale = this._explicitHeight / (this._currentTextureHeight * this._textureScale); } else if(this._maxHeight < this._currentTextureHeight) { heightScale = this._maxHeight / (this._currentTextureHeight * this._textureScale); } else if(this._explicitMinHeight > this._currentTextureHeight) { heightScale = this._explicitMinHeight / (this._currentTextureHeight * this._textureScale); } if(heightScale !== 1) { newWidth *= heightScale; } } } else { newWidth = 0; } newWidth += this._paddingLeft + this._paddingRight; } var newHeight:Number = this._explicitHeight; if(needsHeight) { if(this._currentTextureHeight === this._currentTextureHeight) //!isNaN { newHeight = this._currentTextureHeight * this._textureScale; if(this._scaleContent && this._maintainAspectRatio) { var widthScale:Number = 1; if(!needsWidth) { widthScale = this._explicitWidth / (this._currentTextureWidth * this._textureScale); } else if(this._maxWidth < this._currentTextureWidth) { widthScale = this._maxWidth / (this._currentTextureWidth * this._textureScale); } else if(this._explicitMinWidth > this._currentTextureWidth) { widthScale = this._explicitMinWidth / (this._currentTextureWidth * this._textureScale); } if(widthScale !== 1) { newHeight *= widthScale; } } } else { newHeight = 0; } newHeight += this._paddingTop + this._paddingBottom; } return this.saveMeasurements(newWidth, newHeight, newWidth, newHeight); } /** * @private */ protected function commitData():void { if(this._source is Texture) { this._lastURL = null; this._texture = Texture(this._source); this.refreshCurrentTexture(); } else { var sourceURL:String = this._source as String; if(!sourceURL) { this._lastURL = null; } else if(sourceURL != this._lastURL) { this._lastURL = sourceURL; if(this.findSourceInCache()) { return; } if(isATFURL(sourceURL)) { if(this.loader) { this.loader = null; } if(!this.urlLoader) { this.urlLoader = new URLLoader(); this.urlLoader.dataFormat = URLLoaderDataFormat.BINARY; } this.urlLoader.addEventListener(flash.events.Event.COMPLETE, rawDataLoader_completeHandler); this.urlLoader.addEventListener(ProgressEvent.PROGRESS, rawDataLoader_progressHandler); this.urlLoader.addEventListener(IOErrorEvent.IO_ERROR, rawDataLoader_ioErrorHandler); this.urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, rawDataLoader_securityErrorHandler); this.urlLoader.load(new URLRequest(sourceURL)); return; } else //not ATF { if(this.urlLoader) { this.urlLoader = null; } if(!this.loader) { this.loader = new Loader(); } this.loader.contentLoaderInfo.addEventListener(flash.events.Event.COMPLETE, loader_completeHandler); this.loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loader_progressHandler); this.loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loader_ioErrorHandler); this.loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, loader_securityErrorHandler); this.loader.load(new URLRequest(sourceURL), LOADER_CONTEXT); } } this.refreshCurrentTexture(); } } /** * @private */ protected function commitStyles():void { if(!this.image) { return; } this.image.textureSmoothing = this._textureSmoothing; this.image.color = this._color; this.image.scale9Grid = this._scale9Grid; this.image.tileGrid = this._tileGrid; this.image.pixelSnapping = this._pixelSnapping; } /** * @private */ protected function layout():void { if(!this.image || !this._currentTexture) { return; } if(this._scaleContent) { if(this._maintainAspectRatio) { HELPER_RECTANGLE.x = 0; HELPER_RECTANGLE.y = 0; HELPER_RECTANGLE.width = this._currentTextureWidth * this._textureScale; HELPER_RECTANGLE.height = this._currentTextureHeight * this._textureScale; HELPER_RECTANGLE2.x = 0; HELPER_RECTANGLE2.y = 0; HELPER_RECTANGLE2.width = this.actualWidth - this._paddingLeft - this._paddingRight; HELPER_RECTANGLE2.height = this.actualHeight - this._paddingTop - this._paddingBottom; RectangleUtil.fit(HELPER_RECTANGLE, HELPER_RECTANGLE2, this._scaleMode, false, HELPER_RECTANGLE); this.image.x = HELPER_RECTANGLE.x + this._paddingLeft; this.image.y = HELPER_RECTANGLE.y + this._paddingTop; this.image.width = HELPER_RECTANGLE.width; this.image.height = HELPER_RECTANGLE.height; } else { this.image.x = this._paddingLeft; this.image.y = this._paddingTop; this.image.width = this.actualWidth - this._paddingLeft - this._paddingRight; this.image.height = this.actualHeight - this._paddingTop - this._paddingBottom; } } else { var imageWidth:Number = this._currentTextureWidth * this._textureScale; var imageHeight:Number = this._currentTextureHeight * this._textureScale; if(this._horizontalAlign === HorizontalAlign.RIGHT) { this.image.x = this.actualWidth - this._paddingRight - imageWidth; } else if(this._horizontalAlign === HorizontalAlign.CENTER) { this.image.x = this._paddingLeft + ((this.actualWidth - this._paddingLeft - this._paddingRight) - imageWidth) / 2; } else //left { this.image.x = this._paddingLeft; } if(this._verticalAlign === VerticalAlign.BOTTOM) { this.image.y = this.actualHeight - this._paddingBottom - imageHeight; } else if(this._verticalAlign === VerticalAlign.MIDDLE) { this.image.y = this._paddingTop + ((this.actualHeight - this._paddingTop - this._paddingBottom) - imageHeight) / 2; } else //top { this.image.y = this._paddingTop; } this.image.width = imageWidth; this.image.height = imageHeight; } if((!this._scaleContent || (this._maintainAspectRatio && this._scaleMode !== ScaleMode.SHOW_ALL)) && (this.actualWidth != imageWidth || this.actualHeight != imageHeight)) { var mask:Quad = this.mask as Quad; if(mask) { mask.x = 0; mask.y = 0; mask.width = this.actualWidth; mask.height = this.actualHeight; } else { mask = new Quad(1, 1, 0xff00ff); //the initial dimensions cannot be 0 or there's a runtime error, //and these values might be 0 mask.width = this.actualWidth; mask.height = this.actualHeight; this.mask = mask; } } else { this.mask = null; } } /** * @private */ protected function isATFURL(sourceURL:String):Boolean { var index:int = sourceURL.indexOf("?"); if(index >= 0) { sourceURL = sourceURL.substr(0, index); } return sourceURL.toLowerCase().lastIndexOf(ATF_FILE_EXTENSION) === sourceURL.length - 3; } /** * @private */ protected function refreshCurrentTexture():void { var newTexture:Texture = this._isLoaded ? this._texture : null; if(!newTexture) { if(this.loader || this.urlLoader) { newTexture = this._loadingTexture; } else { newTexture = this._errorTexture; } } if(this._currentTexture == newTexture) { return; } this._currentTexture = newTexture; if(!this._currentTexture) { if(this.image) { this.removeChild(this.image, true); this.image = null; } return; } //save the texture's frame so that we don't need to create a new //rectangle every time that we want to access it. var frame:Rectangle = this._currentTexture.frame; if(frame) { this._currentTextureWidth = frame.width; this._currentTextureHeight = frame.height; } else { this._currentTextureWidth = this._currentTexture.width; this._currentTextureHeight = this._currentTexture.height; this._originalTextureWidth = this._currentTexture.nativeWidth; this._originalTextureHeight = this._currentTexture.nativeHeight; } if(!this.image) { this.image = new Image(this._currentTexture); this.addChild(this.image); } else { this.image.texture = this._currentTexture; this.image.readjustSize(); } this.image.visible = true; } /** * @private */ protected function cleanupTexture():void { if(this._texture) { if(this._isTextureOwner) { this._texture.dispose(); } else if(this._textureCache && this._source is String) { this._textureCache.releaseTexture(this._source as String); } } if(this._pendingBitmapDataTexture) { this._pendingBitmapDataTexture.dispose(); } if(this._pendingRawTextureData) { this._pendingRawTextureData.clear(); } this._currentTexture = null; this._currentTextureWidth = NaN; this._currentTextureHeight = NaN; this._originalTextureWidth = NaN; this._originalTextureHeight = NaN; this._pendingBitmapDataTexture = null; this._pendingRawTextureData = null; this._texture = null; this._isTextureOwner = false; } /** * @private */ protected function cleanupLoaders(close:Boolean):void { if(this.urlLoader) { this.urlLoader.removeEventListener(flash.events.Event.COMPLETE, rawDataLoader_completeHandler); this.urlLoader.removeEventListener(ProgressEvent.PROGRESS, rawDataLoader_progressHandler); this.urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, rawDataLoader_ioErrorHandler); this.urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, rawDataLoader_securityErrorHandler); if(close) { try { this.urlLoader.close(); } catch(error:Error) { //no need to do anything in response } } this.urlLoader = null; } if(this.loader) { this.loader.contentLoaderInfo.removeEventListener(flash.events.Event.COMPLETE, loader_completeHandler); this.loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, loader_progressHandler); this.loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, loader_ioErrorHandler); this.loader.contentLoaderInfo.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, loader_securityErrorHandler); if(close) { try { this.loader.close(); } catch(error:Error) { //no need to do anything in response } } this.loader = null; } } /** * @private */ protected function findSourceInCache():Boolean { var sourceURL:String = this._source as String; if(this._textureCache && !this._isRestoringTexture && this._textureCache.hasTexture(sourceURL)) { this._texture = this._textureCache.retainTexture(sourceURL); this._isTextureOwner = false; this._isRestoringTexture = false; this._isLoaded = true; this.refreshCurrentTexture(); this.dispatchEventWith(starling.events.Event.COMPLETE); return true; } return false; } /** * @private */ protected function verifyCurrentStarling():void { if(!this.stage || Starling.current.stage === this.stage) { return; } var starling:Starling = stageToStarling(this.stage); starling.makeCurrent(); } /** * @private */ protected function replaceBitmapDataTexture(bitmapData:BitmapData):void { if(!Starling.current.contextValid) { //this trace duplicates the behavior of AssetManager trace(CONTEXT_LOST_WARNING); setTimeout(replaceBitmapDataTexture, 1, bitmapData); return; } if(!SystemUtil.isDesktop && !SystemUtil.isApplicationActive) { //avoiding stage3d calls when a mobile application isn't active SystemUtil.executeWhenApplicationIsActive(replaceBitmapDataTexture, bitmapData); return; } this.verifyCurrentStarling(); if(this.findSourceInCache()) { //someone else added this URL to the cache while we were in the //middle of loading it. we can reuse the texture from the cache! //don't forget to dispose the BitmapData, though... bitmapData.dispose(); //then invalidate so that everything is resized correctly this.invalidate(INVALIDATION_FLAG_DATA); return; } if(!this._texture) { //skip Texture.fromBitmapData() because we don't want //it to create an onRestore function that will be //immediately discarded for garbage collection. this._texture = Texture.empty(bitmapData.width / this._scaleFactor, bitmapData.height / this._scaleFactor, true, false, false, this._scaleFactor, this._textureFormat); var sourceURL:String = this._source as String; this._texture.root.onRestore = this.createTextureOnRestore(this._texture, sourceURL, this._textureFormat, this._scaleFactor); if(this._textureCache) { this._textureCache.addTexture(sourceURL, this._texture, true); } } this._texture.root.uploadBitmapData(bitmapData); bitmapData.dispose(); //if we have a cache for the textures, then the cache is the owner //because other ImageLoaders may use the same texture. this._isTextureOwner = this._textureCache === null; this._isRestoringTexture = false; this._isLoaded = true; this.invalidate(INVALIDATION_FLAG_DATA); this.dispatchEventWith(starling.events.Event.COMPLETE); } /** * @private */ protected function replaceRawTextureData(rawData:ByteArray):void { if(!Starling.current.contextValid) { //this trace duplicates the behavior of AssetManager trace(CONTEXT_LOST_WARNING); setTimeout(replaceRawTextureData, 1, rawData); return; } if(!SystemUtil.isDesktop && !SystemUtil.isApplicationActive) { //avoiding stage3d calls when a mobile application isn't active SystemUtil.executeWhenApplicationIsActive(replaceRawTextureData, rawData); return; } this.verifyCurrentStarling(); if(this.findSourceInCache()) { //someone else added this URL to the cache while we were in the //middle of loading it. we can reuse the texture from the cache! //don't forget to clear the ByteArray, though... rawData.clear(); //then invalidate so that everything is resized correctly this.invalidate(INVALIDATION_FLAG_DATA); return; } if(this._texture) { this._texture.root.uploadAtfData(rawData); } else { this._texture = Texture.fromAtfData(rawData, this._scaleFactor); var sourceURL:String = this._source as String; this._texture.root.onRestore = this.createTextureOnRestore(this._texture, sourceURL, this._textureFormat, this._scaleFactor); if(this._textureCache) { this._textureCache.addTexture(sourceURL, this._texture, true); } } rawData.clear(); //if we have a cache for the textures, then the cache is the owner //because other ImageLoaders may use the same texture. this._isTextureOwner = this._textureCache === null; this._isRestoringTexture = false; this._isLoaded = true; this.invalidate(INVALIDATION_FLAG_DATA); this.dispatchEventWith(starling.events.Event.COMPLETE); } /** * @private */ protected function addToTextureQueue():void { if(!this._delayTextureCreation) { throw new IllegalOperationError("Cannot add loader to delayed texture queue if delayTextureCreation is false."); } if(this._textureQueueDuration == Number.POSITIVE_INFINITY) { throw new IllegalOperationError("Cannot add loader to delayed texture queue if textureQueueDuration is Number.POSITIVE_INFINITY."); } if(this._isInTextureQueue) { throw new IllegalOperationError("Cannot add loader to delayed texture queue more than once."); } this.addEventListener(starling.events.Event.REMOVED_FROM_STAGE, imageLoader_removedFromStageHandler); this._isInTextureQueue = true; if(textureQueueTail) { textureQueueTail._textureQueueNext = this; this._textureQueuePrevious = textureQueueTail; textureQueueTail = this; } else { textureQueueHead = this; textureQueueTail = this; this.preparePendingTexture(); } } /** * @private */ protected function removeFromTextureQueue():void { if(!this._isInTextureQueue) { return; } var previous:ImageLoader = this._textureQueuePrevious; var next:ImageLoader = this._textureQueueNext; this._textureQueuePrevious = null; this._textureQueueNext = null; this._isInTextureQueue = false; this.removeEventListener(starling.events.Event.REMOVED_FROM_STAGE, imageLoader_removedFromStageHandler); this.removeEventListener(EnterFrameEvent.ENTER_FRAME, processTextureQueue_enterFrameHandler); if(previous) { previous._textureQueueNext = next; } if(next) { next._textureQueuePrevious = previous; } var wasHead:Boolean = textureQueueHead == this; var wasTail:Boolean = textureQueueTail == this; if(wasTail) { textureQueueTail = previous; if(wasHead) { textureQueueHead = previous; } } if(wasHead) { textureQueueHead = next; if(wasTail) { textureQueueTail = next; } } if(wasHead && textureQueueHead) { textureQueueHead.preparePendingTexture(); } } /** * @private */ protected function preparePendingTexture():void { if(this._textureQueueDuration > 0) { this._accumulatedPrepareTextureTime = 0; this.addEventListener(EnterFrameEvent.ENTER_FRAME, processTextureQueue_enterFrameHandler); } else { this.processPendingTexture(); } } /** * @private */ protected function processPendingTexture():void { if(this._pendingBitmapDataTexture) { var bitmapData:BitmapData = this._pendingBitmapDataTexture; this._pendingBitmapDataTexture = null; this.replaceBitmapDataTexture(bitmapData); } if(this._pendingRawTextureData) { var rawData:ByteArray = this._pendingRawTextureData; this._pendingRawTextureData = null; this.replaceRawTextureData(rawData); } if(this._isInTextureQueue) { this.removeFromTextureQueue(); } } /** * @private */ protected function createTextureOnRestore(texture:Texture, source:String, format:String, scaleFactor:Number):Function { return function():void { if(_texture === texture) { texture_onRestore(); return; } //this is a hacky way to handle restoring the texture when the //current ImageLoader is no longer displaying the texture being //restored. var otherLoader:ImageLoader = new ImageLoader(); otherLoader.source = source; otherLoader._texture = texture; otherLoader._textureFormat = format; otherLoader._scaleFactor = scaleFactor; otherLoader.validate(); otherLoader.addEventListener(starling.events.Event.COMPLETE, onRestore_onComplete); }; } /** * @private */ protected function onRestore_onComplete(event:starling.events.Event):void { var otherLoader:ImageLoader = ImageLoader(event.currentTarget); otherLoader._isTextureOwner = false; otherLoader._texture = null; otherLoader.dispose(); } /** * @private */ protected function texture_onRestore():void { //reload the texture from the URL this._isRestoringTexture = true; this._lastURL = null; this._isLoaded = false; this.invalidate(INVALIDATION_FLAG_DATA); } /** * @private */ protected function processTextureQueue_enterFrameHandler(event:EnterFrameEvent):void { this._accumulatedPrepareTextureTime += event.passedTime; if(this._accumulatedPrepareTextureTime >= this._textureQueueDuration) { this.removeEventListener(EnterFrameEvent.ENTER_FRAME, processTextureQueue_enterFrameHandler); this.processPendingTexture(); } } /** * @private */ protected function imageLoader_removedFromStageHandler(event:starling.events.Event):void { if(this._isInTextureQueue) { this.removeFromTextureQueue(); } } /** * @private */ protected function loader_completeHandler(event:flash.events.Event):void { var bitmap:Bitmap = Bitmap(this.loader.content); this.cleanupLoaders(false); var bitmapData:BitmapData = bitmap.bitmapData; //attempt to reuse the existing texture so that we don't need to //create a new one. var canReuseTexture:Boolean = this._texture && this._texture.nativeWidth === bitmapData.width && this._texture.nativeHeight === bitmapData.height && this._texture.scale === this._scaleFactor && this._texture.format === this._textureFormat; if(!canReuseTexture) { this.cleanupTexture(); } if(this._delayTextureCreation && !this._isRestoringTexture) { this._pendingBitmapDataTexture = bitmapData; if(this._textureQueueDuration < Number.POSITIVE_INFINITY) { this.addToTextureQueue(); } } else { this.replaceBitmapDataTexture(bitmapData); } } /** * @private */ protected function loader_progressHandler(event:ProgressEvent):void { this.dispatchEventWith(FeathersEventType.PROGRESS, false, event.bytesLoaded / event.bytesTotal); } /** * @private */ protected function loader_ioErrorHandler(event:IOErrorEvent):void { this.cleanupLoaders(false); this.cleanupTexture(); this.invalidate(INVALIDATION_FLAG_DATA); this.dispatchEventWith(FeathersEventType.ERROR, false, event); this.dispatchEventWith(starling.events.Event.IO_ERROR, false, event); } /** * @private */ protected function loader_securityErrorHandler(event:SecurityErrorEvent):void { this.cleanupLoaders(false); this.cleanupTexture(); this.invalidate(INVALIDATION_FLAG_DATA); this.dispatchEventWith(FeathersEventType.ERROR, false, event); this.dispatchEventWith(starling.events.Event.SECURITY_ERROR, false, event); } /** * @private */ protected function rawDataLoader_completeHandler(event:flash.events.Event):void { var rawData:ByteArray = ByteArray(this.urlLoader.data); this.cleanupLoaders(false); //only clear the texture if we're not restoring if(!this._isRestoringTexture) { this.cleanupTexture(); } if(this._delayTextureCreation && !this._isRestoringTexture) { this._pendingRawTextureData = rawData; if(this._textureQueueDuration < Number.POSITIVE_INFINITY) { this.addToTextureQueue(); } } else { this.replaceRawTextureData(rawData); } } /** * @private */ protected function rawDataLoader_progressHandler(event:ProgressEvent):void { this.dispatchEventWith(FeathersEventType.PROGRESS, false, event.bytesLoaded / event.bytesTotal); } /** * @private */ protected function rawDataLoader_ioErrorHandler(event:ErrorEvent):void { this.cleanupLoaders(false); this.cleanupTexture(); this.invalidate(INVALIDATION_FLAG_DATA); this.dispatchEventWith(FeathersEventType.ERROR, false, event); this.dispatchEventWith(starling.events.Event.IO_ERROR, false, event); } /** * @private */ protected function rawDataLoader_securityErrorHandler(event:ErrorEvent):void { this.cleanupLoaders(false); this.cleanupTexture(); this.invalidate(INVALIDATION_FLAG_DATA); this.dispatchEventWith(FeathersEventType.ERROR, false, event); this.dispatchEventWith(starling.events.Event.SECURITY_ERROR, false, event); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy