(function() {
"use strict";
// Class imports
var UIElementSettings = cloudkid.UIElementSettings,
UIElement = cloudkid.UIElement,
ScreenSettings = cloudkid.ScreenSettings;
/**
* The UI scale is responsible for scaling UI components
* to help easy the burden of different device aspect ratios
*
* @module cloudkid
* @class UIScaler
* @constructor
* @param {createjs.DisplayObject|PIXI.DisplayObject} parent The UI display container
* @param {Number} designedWidth The designed width of the UI
* @param {Number} designedHeight The designed height of the UI
* @param {Number} designedPPI The designed PPI of the UI
*/
var UIScaler = function(parent, designedWidth, designedHeight, designedPPI)
{
this._parent = parent;
this._items = [];
this._designedScreen = new ScreenSettings(designedWidth, designedHeight, designedPPI);
};
// Reference to the prototype
var p = UIScaler.prototype = {};
/**
* The current screen settings
* @property {ScreenSettings} currentScreen
* @static
* @private
*/
var currentScreen = new ScreenSettings(0, 0, 0);
/**
* If the screensize has been set
* @property {Boolean} initialized
* @static
* @private
*/
var initialized = false;
/**
* The UI display object to update
* @property {createjs.DisplayObject|PIXI.DisplayObject} _parent
* @private
*/
p._parent = null;
/**
* The screen settings object, contains information about designed size
* @property {ScreenSettings} _designedScreen
* @private
*/
p._designedScreen = null;
/**
* The configuration for each items
* @property {Array} _items
* @private
*/
p._items = null;
/**
* Vertically align to the top
* @property {String} ALIGN_TOP
* @static
* @final
* @readOnly
* @default "top"
*/
UIScaler.ALIGN_TOP = "top";
/**
* Vertically align to the bottom
* @property {String} ALIGN_BOTTOM
* @static
* @final
* @readOnly
* @default "bottom"
*/
UIScaler.ALIGN_BOTTOM = "bottom";
/**
* Horizontally align to the left
* @property {String} ALIGN_LEFT
* @static
* @final
* @readOnly
* @default "left"
*/
UIScaler.ALIGN_LEFT = "left";
/**
* Horizontally align to the right
* @property {String} ALIGN_RIGHT
* @static
* @final
* @readOnly
* @default "right"
*/
UIScaler.ALIGN_RIGHT = "right";
/**
* Vertically or horizontally align to the center
* @property {String} ALIGN_CENTER
* @static
* @final
* @readOnly
* @default "center"
*/
UIScaler.ALIGN_CENTER = "center";
/**
* Create the scaler from JSON data
* @method fromJSON
* @static
* @param {createjs.DisplayObject|PIXI.DisplayObject} parent The UI display container
* @param {Object} jsonSettings The json of the designed settings {designedWidth:800, designedHeight:600, designedPPI:72}
* @param {Object} jsonItems The json items object where the keys are the name of the property on the parent and the value
* is an object with keys of "titleSafe", "minScale", "maxScale", "centerHorizontally", "align"
* @param {Boolean} [immediateDestroy=true] If we should immediately cleanup the UIScaler after scaling items
* @return {UIScaler} The scaler object that can be reused
*/
UIScaler.fromJSON = function(parent, jsonSettings, jsonItems, immediateDestroy)
{
if (typeof immediateDestroy != "boolean") immediateDestroy = true;
var scaler = new UIScaler(
parent,
jsonSettings.designedWidth,
jsonSettings.designedHeight,
jsonSettings.designedPPI
);
// Temp variables
var item, i, align, vertAlign, horiAlign;
// Loop through all the items and register
// each dpending on the settings
for(i in jsonItems)
{
item = jsonItems[i];
if (item.align)
{
align = item.align.split("-");
vertAlign = align[0];
horiAlign = align[1];
}
else
{
vertAlign = ALIGN_CENTER;
horiAlign = ALIGN_CENTER;
}
scaler.add(
parent[i],
vertAlign,
horiAlign,
item.titleSafe || false,
item.minScale || NaN,
item.maxScale || NaN,
item.centeredHorizontally || false
);
}
// Scale the items
scaler.resize();
if (immediateDestroy)
{
scaler.destroy();
}
return scaler;
};
/**
* Set the current screen settings. If the stage size changes at all, re-call this function
* @method init
* @static
* @param {Number} screenWidth The fullscreen width
* @param {Number} screenHeight The fullscreen height
* @param {Number} screenPPI The screen resolution density
*/
UIScaler.init = function(screenWidth, screenHeight, screenPPI)
{
currentScreen.width = screenWidth;
currentScreen.height = screenHeight;
currentScreen.ppi = screenPPI;
initialized = true;
};
/**
* Get the current scale of the screen
* @method getScale
* @return {Number} The current stage scale
*/
p.getScale = function()
{
return currentScreen.height / this._designedScreen.height;
};
/**
* Manually add an item
* @method add
* @param {createjs.DisplayObject|PIXI.DisplayObject} item The display object item to add
* @param {String} [vertAlign="center"] The vertical align of the item (cefault is center)
* @param {String} [horiAlign="center"] The horizontal align of the item (default is center)
* @param {Boolean} [titleSafe=false] If the item needs to be in the title safe area (default is false)
* @param {Number} [minScale=1] The minimum scale amount (default, scales the same size as the stage)
* @param {Number} [maxScale=1] The maximum scale amount (default, scales the same size as the stage)
* @param {Boolean} [centeredHorizontally=false] Makes sure that the center of the object was at the center of the screen, assuming an origin at the top left of the object
*/
p.add = function(item, vertAlign, horiAlign, titleSafe, minScale, maxScale, centeredHorizontally)
{
// Create the item settings
var s = new UIElementSettings();
s.vertAlign = vertAlign || UIScaler.ALIGN_CENTER;
s.horiAlign = horiAlign || UIScaler.ALIGN_CENTER;
s.titleSafe = (typeof titleSafe != "boolean") ? false : titleSafe;
s.maxScale = (typeof maxScale != "number") ? NaN : maxScale;
s.minScale = (typeof minScale != "number") ? NaN : minScale;
s.centeredHorizontally = centeredHorizontally || false;
this._items.push(new UIElement(item, s, this._designedScreen));
};
/**
* Scale a single background image according to the UIScaler.width and height
* @method resizeBackground
* @static
* @param {createjs.Bitmap|PIXI.Bitmap} The bitmap to scale
*/
UIScaler.resizeBackground = function(bitmap)
{
if (!initialized) return;
var h, w, scale;
if(CONFIG_PIXI)
{
h = bitmap.height / bitmap.scale.y;
w = bitmap.width / bitmap.scale.x;
//scale the background
scale = currentScreen.height / h;
bitmap.scale.x = bitmap.scale.y = scale;
//center the background
bitmap.position.x = (currentScreen.width - bitmap.width) * 0.5;
}
else if(CONFIG_CREATEJS)
{
h = bitmap.image.height;
w = bitmap.image.width;
//scale the background
scale = currentScreen.height / h;
bitmap.scaleX = bitmap.scaleY = scale;
//center the background
bitmap.x = (currentScreen.width - w * scale) * 0.5;
}
};
/**
* Convenience function to scale a collection of backgrounds
* @method resizeBackgrounds
* @static
* @param {Array} bitmaps The collection of bitmap images
*/
UIScaler.resizeBackgrounds = function(bitmaps)
{
for(var i = 0, len = bitmaps.length; i < len; ++i)
{
UIScaler.resizeBackground(bitmaps[i]);
}
};
/**
* Scale the UI items that have been registered to the current screen
* @method resize
*/
p.resize = function()
{
if (this._items.length > 0)
{
for(var i = 0, len = this._items.length; i < len; ++i)
{
this._items[i].resize(currentScreen);
}
}
};
/**
* Destroy the scaler object
* @method destroy
*/
p.destroy = function()
{
if (this._items.length > 0)
{
for(var i = 0, len = this._items.length; i < len; ++i)
{
this._items[i].destroy();
}
}
this._parent = null;
this._designedScreen = null;
this._items = null;
};
namespace('cloudkid').UIScaler = UIScaler;
}());