blob: 983d65e74927c3c72adc895fce8d7dc0c09dd690 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// 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 spark.skins.mobile
{
import flash.display.DisplayObject;
import flash.display.Graphics;
import mx.core.DPIClassification;
import spark.components.BusyIndicator;
import spark.components.Group;
import spark.components.Image;
import spark.primitives.BitmapImage;
import spark.skins.mobile.supportClasses.MobileSkin;
import spark.skins.mobile120.assets.ImageInvalid;
import spark.skins.mobile160.assets.ImageInvalid;
import spark.skins.mobile240.assets.ImageInvalid;
import spark.skins.mobile320.assets.ImageInvalid;
import spark.skins.mobile480.assets.ImageInvalid;
import spark.skins.mobile640.assets.ImageInvalid;
/**
* ActionScript-based skin for the Image component in mobile applications.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public class ImageSkin extends MobileSkin
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*
*/
public function ImageSkin()
{
super();
// set the right assets and dimensions to use based on the screen density
switch (applicationDPI)
{
case DPIClassification.DPI_640:
{
imageInvalidClass = spark.skins.mobile640.assets.ImageInvalid;
break;
}
case DPIClassification.DPI_480:
{
imageInvalidClass = spark.skins.mobile480.assets.ImageInvalid;
break;
}
case DPIClassification.DPI_320:
{
imageInvalidClass = spark.skins.mobile320.assets.ImageInvalid;
break;
}
case DPIClassification.DPI_240:
{
imageInvalidClass = spark.skins.mobile240.assets.ImageInvalid;
break;
}
case DPIClassification.DPI_120:
{
imageInvalidClass = spark.skins.mobile120.assets.ImageInvalid;
break;
}
default:
{
// default DPI_160
imageInvalidClass = spark.skins.mobile160.assets.ImageInvalid;
break;
}
}
}
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
public var hostComponent:Image;
//--------------------------------------------------------------------------
//
// Skin parts
//
//--------------------------------------------------------------------------
/**
* Image imageDisplay skin part that contains the image content
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public var imageDisplay:BitmapImage;
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* Container of the BitmapImage to be displayed
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
protected var imageHolder:Group;
/**
* The currently displayed asset: either the intended image,
* the loading indicator, the "invalid image" icon, or null.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
private var currentImage:DisplayObject;
/**
* Specifies the FXG class to use in the "invalid" image state
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
protected var imageInvalidClass:Class;
/**
* Specifies the DisplayObject to use in the "invalid" image state
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
private var imageInvalid:DisplayObject;
/**
* Displayed if the "enableLoadingState" style is true
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
protected var loadingIndicator:BusyIndicator = null;
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function commitCurrentState():void
{
var alphaValue:Number = 1.0;
if (currentState == "uninitialized")
{
if (imageInvalid)
{
removeChild(imageInvalid);
imageInvalid = null;
}
if (loadingIndicator)
{
removeChild(loadingIndicator);
loadingIndicator = null;
}
currentImage = null;
}
else if (currentState == "loading")
{
// turn off any other images
if (imageInvalid)
{
removeChild(imageInvalid);
imageInvalid = null;
}
if (!loadingIndicator)
{
loadingIndicator = new BusyIndicator();
addChild(loadingIndicator);
}
currentImage = loadingIndicator;
}
else if (currentState == "ready")
{
if (imageInvalid)
{
removeChild(imageInvalid);
imageInvalid = null;
}
if (loadingIndicator)
{
removeChild(loadingIndicator);
loadingIndicator = null;
}
currentImage = imageHolder;
}
else if (currentState == "invalid")
{
if (loadingIndicator)
{
removeChild(loadingIndicator);
loadingIndicator = null;
}
if (!imageInvalid)
{
imageInvalid = new imageInvalidClass();
addChild(imageInvalid);
}
currentImage = imageInvalid;
}
else if (currentState == "disabled")
{
alphaValue = 0.5;
// remove any loading or invalid images
if (imageInvalid)
{
removeChild(imageInvalid);
imageInvalid = null;
}
if (loadingIndicator)
{
removeChild(loadingIndicator);
loadingIndicator = null;
}
currentImage = imageHolder;
}
else
{
// unexpected state; ignore
}
alpha = alphaValue;
invalidateSize();
invalidateDisplayList();
}
/**
* @private
*/
override protected function createChildren():void
{
// create container for holding the currently displayed image
imageHolder = new Group();
addChild(imageHolder);
// required skin part; the Image component will set this directly
imageDisplay = new BitmapImage();
imageDisplay.left = 0;
imageDisplay.right = 0;
imageDisplay.top = 0;
imageDisplay.bottom = 0;
imageHolder.addElement(imageDisplay);
}
/**
* @private
*/
override protected function measure():void
{
super.measure();
if (currentImage)
{
measuredHeight = getElementPreferredHeight(currentImage);
measuredWidth = getElementPreferredWidth(currentImage);
}
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
var preferredWidth:Number;
var preferredHeight:Number;
if (loadingIndicator && currentImage == loadingIndicator)
{
preferredWidth = loadingIndicator.getPreferredBoundsWidth();
preferredHeight = loadingIndicator.getPreferredBoundsHeight();
// loading indicator will be no bigger than its preferred width/height
setElementSize(loadingIndicator,
Math.min(unscaledWidth, preferredWidth),
Math.min(unscaledHeight, preferredHeight));
// center the loading indicator
setElementPosition(loadingIndicator,
Math.max((unscaledWidth - preferredWidth) / 2, 0),
Math.max((unscaledHeight - preferredHeight) / 2, 0));
}
else if (imageInvalid && currentImage == imageInvalid)
{
preferredWidth = getElementPreferredWidth(imageInvalid);
preferredHeight = getElementPreferredHeight(imageInvalid);
// icon shrinks with any explicit image size
setElementSize(imageInvalid,
Math.min(preferredWidth, unscaledWidth),
Math.min(preferredHeight, unscaledHeight));
// center the invalid image icon
setElementPosition(imageInvalid,
Math.max((unscaledWidth - preferredWidth) / 2, 0),
Math.max((unscaledHeight - preferredHeight) / 2, 0));
}
else if (currentImage == imageHolder)
setElementSize(imageHolder, unscaledWidth, unscaledHeight);
// set the background rect if specified
var g:Graphics = graphics;
g.clear();
if (!isNaN(getStyle("backgroundColor")))
{
g.beginFill(getStyle("backgroundColor"), getStyle("backgroundAlpha"));
g.drawRect(0, 0, unscaledWidth, unscaledHeight);
}
}
}
}