502 lines
13 KiB
ActionScript
Executable File
502 lines
13 KiB
ActionScript
Executable File
/*
|
||
Copyright (c) 2009 Yahoo! Inc. All rights reserved.
|
||
The copyrights embodied in the content of this file are licensed under the BSD (revised) open source license
|
||
*/
|
||
package com.yahoo.astra.fl.controls.menuClasses {
|
||
import flash.text.TextFormat;
|
||
import flash.filters.BevelFilter;
|
||
import flash.display.Graphics;
|
||
import flash.display.DisplayObject;
|
||
import fl.controls.listClasses.CellRenderer;
|
||
import com.yahoo.astra.fl.controls.Menu;
|
||
import fl.controls.listClasses.ListData;
|
||
import fl.core.InvalidationType;
|
||
import com.yahoo.astra.fl.utils.UIComponentUtil;
|
||
import com.yahoo.astra.utils.InstanceFactory;
|
||
|
||
//--------------------------------------
|
||
// Styles
|
||
//--------------------------------------
|
||
/**
|
||
* The icon to display when a menu has a submenu
|
||
*
|
||
* @default MenuBranchIcon
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="branchIcon", type="Class")]
|
||
/**
|
||
* The graphic to use for menu separators
|
||
*
|
||
* @default MenuSeparatorSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="separatorSkin", type="Class")]
|
||
/**
|
||
* The up skin
|
||
*
|
||
* @default MenuCellRenderer_upSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="upSkin", type="Class")]
|
||
/**
|
||
* The down skin
|
||
*
|
||
* @default MenuCellRenderer_downSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="downSkin", type="Class")]
|
||
/**
|
||
* The over skin
|
||
*
|
||
* @default MenuCellRenderer_overSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="overSkin", type="Class")]
|
||
/**
|
||
* The disabled skin
|
||
*
|
||
* @default MenuCellRenderer_disabledSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="disabledSkin", type="Class")]
|
||
/**
|
||
* The selected disabled skin
|
||
*
|
||
* @default MenuCellRenderer_selectedDisabledSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="selectedDisabledSkin", type="Class")]
|
||
/**
|
||
* The selected up skin
|
||
*
|
||
* @default MenuCellRenderer_selectedUpSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="selectedUpSkin", type="Class")]
|
||
/**
|
||
* The selected down skin
|
||
*
|
||
* @default MenuCellRenderer_selectedDownSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="selectedDownSkin", type="Class")]
|
||
/**
|
||
* The selected over skin
|
||
*
|
||
* @default MenuCellRenderer_selectedOverSkin
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="selectedOverSkin", type="Class")]
|
||
/**
|
||
* The text padding
|
||
*
|
||
* @default 5
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
[Style(name="upSkin", type="Class")]
|
||
//--------------------------------------
|
||
// Class description
|
||
//--------------------------------------
|
||
/**
|
||
* The MenuCellRenderer is the default renderer of a Menu's rows,
|
||
* adding support for branch icons and display of submenus.
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
* @includeExample examples/ButtonExample.as
|
||
*/
|
||
public class MenuCellRenderer extends CellRenderer
|
||
{
|
||
public function MenuCellRenderer() {
|
||
super();
|
||
menu = parent as Menu;
|
||
}
|
||
|
||
|
||
//----------------------------------
|
||
// branchIcon
|
||
//----------------------------------
|
||
/**
|
||
* Displays the branch icon
|
||
* in this renderer.
|
||
*
|
||
* @default
|
||
*/
|
||
protected var branchIcon:DisplayObject;
|
||
|
||
|
||
//----------------------------------
|
||
// menu
|
||
//----------------------------------
|
||
/**
|
||
* @private
|
||
* Storage for the menu property.
|
||
*/
|
||
private var _menu:Menu;
|
||
|
||
/**
|
||
* Contains a reference to the associated Menu control.
|
||
*
|
||
* @default null
|
||
*/
|
||
public function get menu():Menu
|
||
{
|
||
return _menu;
|
||
}
|
||
|
||
/**
|
||
* @private
|
||
*/
|
||
public function set menu(value:Menu):void
|
||
{
|
||
_menu = value;
|
||
}
|
||
|
||
//----------------------------------
|
||
// subMenu
|
||
//----------------------------------
|
||
/**
|
||
* @private
|
||
* Storage for the menu property.
|
||
*/
|
||
private var _subMenu:Menu;
|
||
/**
|
||
* Contains a reference to the associated subMenu, if any.
|
||
*
|
||
* @default null
|
||
*/
|
||
public function get subMenu():Menu
|
||
{
|
||
return _subMenu;
|
||
}
|
||
|
||
/**
|
||
* @private
|
||
*/
|
||
public function set subMenu(value:Menu):void
|
||
{
|
||
_subMenu = value;
|
||
}
|
||
|
||
|
||
/**
|
||
* @private
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
private static var defaultStyles:Object = { upSkin:"MenuCellRenderer_upSkin",
|
||
downSkin:"MenuCellRenderer_downSkin",
|
||
overSkin:"MenuCellRenderer_overSkin",
|
||
disabledSkin:"MenuCellRenderer_disabledSkin",
|
||
selectedDisabledSkin:"MenuCellRenderer_selectedDisabledSkin",
|
||
selectedUpSkin:"MenuCellRenderer_selectedUpSkin",
|
||
selectedDownSkin:"MenuCellRenderer_selectedDownSkin",
|
||
selectedOverSkin:"MenuCellRenderer_selectedOverSkin",
|
||
branchIcon: "MenuBranchIcon",
|
||
checkIcon: "MenuCheckIcon",
|
||
radioIcon: "MenuRadioIcon",
|
||
separatorSkin: "MenuSeparatorSkin",
|
||
textPadding: 3
|
||
};
|
||
|
||
/**
|
||
* @private
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
protected var _selectedIcon:DisplayObject;
|
||
|
||
/**
|
||
* @private
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
public static function getStyleDefinition():Object {
|
||
return mergeStyles(defaultStyles, CellRenderer.getStyleDefinition());
|
||
}
|
||
|
||
/**
|
||
* @private
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
override protected function drawLayout():void
|
||
{
|
||
var textPadding:Number = Number(getStyleValue("textPadding"));
|
||
var textFieldX:Number = 0;
|
||
var iconMaxWidth:Number = height/2;
|
||
var iconMaxHeight:Number = height/2;
|
||
var fullWidth:int = width;
|
||
textFieldX = textPadding + iconMaxWidth;
|
||
|
||
if(data.hasOwnProperty("type") && data.type.toLowerCase() == "separator")
|
||
{
|
||
icon.width = fullWidth - 3;
|
||
return;
|
||
}
|
||
|
||
//Align icon
|
||
if (icon != null) {
|
||
var iconDimensions:Object = getIconDimensions(icon.width, icon.height, iconMaxWidth, iconMaxHeight);
|
||
icon.height = iconDimensions.height;
|
||
icon.width = iconDimensions.width;
|
||
icon.x = icon.width < iconMaxWidth?Math.round((iconMaxWidth-icon.width)/2) + textPadding:textPadding;
|
||
icon.y = Math.round((height-icon.height)>>1);
|
||
}
|
||
|
||
//Align selected icon
|
||
if (_selectedIcon != null)
|
||
{
|
||
var selectedIconDimensions:Object = getIconDimensions(_selectedIcon.width, _selectedIcon.height, iconMaxWidth, iconMaxHeight);
|
||
_selectedIcon.height = selectedIconDimensions.height;
|
||
_selectedIcon.width = selectedIconDimensions.width;
|
||
_selectedIcon.x = _selectedIcon.width < iconMaxWidth?Math.round((iconMaxWidth-_selectedIcon.width)/2) + textPadding:textPadding;
|
||
_selectedIcon.y = Math.round((height-_selectedIcon.height)>>1);
|
||
}
|
||
|
||
// Align text
|
||
if (label.length > 0) {
|
||
textField.visible = true;
|
||
textField.height = textField.textHeight + 4;
|
||
textField.x = textFieldX + textPadding;
|
||
textField.y = Math.round((height-textField.height)>>1);
|
||
} else {
|
||
textField.visible = false;
|
||
}
|
||
|
||
// Size highlight
|
||
// the greater value between the existing width and the sum of the following:
|
||
// - available space for left icons and branch icons (iconMaxWidth*2)
|
||
// - text field width
|
||
// - space on both edges, and between icons and text field (textPadding*4)
|
||
fullWidth = Math.max(iconMaxWidth*2 + textField.textWidth + textPadding*4, width);
|
||
|
||
//show submenu icon
|
||
if (branchIcon != null)
|
||
{
|
||
var branchIconDimensions:Object = getIconDimensions(branchIcon.width, branchIcon.height, iconMaxWidth, iconMaxHeight);
|
||
branchIcon.width = branchIconDimensions.width;
|
||
branchIcon.height = branchIconDimensions.height;
|
||
branchIcon.x = fullWidth - (branchIcon.width + textPadding);
|
||
branchIcon.y = Math.round((height-branchIcon.height)>>1);
|
||
}
|
||
|
||
width = fullWidth;
|
||
background.width = fullWidth;
|
||
background.height = height;
|
||
|
||
//set enabled
|
||
if(data.hasOwnProperty("enabled"))
|
||
{
|
||
if(!data.enabled is Boolean && data.enabled is String)
|
||
{
|
||
enabled = data.enabled.toLowerCase() == "true";
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @private (protected)
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
//receives the width, height, maxWidth and maxHeight of the icon and returns the maximum width and height to render the icon while maintaining aspect ratio
|
||
protected function getIconDimensions(iconWidth:Number, iconHeight:Number, maxWidth:Number, maxHeight:Number):Object
|
||
{
|
||
var iconDimensions:Object = {width:iconWidth, height:iconHeight};
|
||
if(iconWidth > iconHeight)
|
||
{
|
||
if(iconWidth > maxWidth)
|
||
{
|
||
iconDimensions.width = maxWidth;
|
||
iconDimensions.height = (iconHeight/iconWidth) * maxWidth;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(iconHeight > maxHeight)
|
||
{
|
||
iconDimensions.height = maxHeight;
|
||
iconDimensions.width = (iconWidth/iconHeight) * maxHeight;
|
||
}
|
||
}
|
||
return iconDimensions;
|
||
}
|
||
|
||
/**
|
||
* @private (protected)
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
override protected function configUI():void {
|
||
super.configUI();
|
||
//resize label to its contents
|
||
textField.autoSize = "left";
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @private (setter)
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
//create necessary icons
|
||
override public function set data(value:Object):void
|
||
{
|
||
_data = value;
|
||
label = _data.label!=null?_data.label:"";
|
||
//branch icon
|
||
if(_data.hasOwnProperty("data"))
|
||
{
|
||
var branchIconStyle:Object = getStyleValue("branchIcon");
|
||
if (branchIconStyle != null)
|
||
{
|
||
branchIcon = getDisplayObjectInstance(branchIconStyle);
|
||
}
|
||
if (branchIcon != null)
|
||
{
|
||
branchIcon.visible = true;
|
||
addChild(branchIcon);
|
||
}
|
||
}
|
||
//separator
|
||
if(_data.hasOwnProperty("type"))
|
||
{
|
||
var type:String = _data.type.toLowerCase();
|
||
if (type == "separator")
|
||
{
|
||
label = "";
|
||
enabled = false;
|
||
var separatorStyle:Object = getStyleValue("separatorSkin");
|
||
if (separatorStyle != null)
|
||
{
|
||
icon = getDisplayObjectInstance(separatorStyle);
|
||
addChild(icon);
|
||
icon.visible = true;
|
||
}
|
||
return;
|
||
}
|
||
//Checks
|
||
if(type == "check")
|
||
{
|
||
var checkIcon:Object = getStyleValue("checkIcon");
|
||
if (checkIcon != null)
|
||
{
|
||
_selectedIcon = getDisplayObjectInstance(checkIcon);
|
||
_selectedIcon.visible = false;
|
||
addChild(_selectedIcon);
|
||
}
|
||
}
|
||
//Radio
|
||
if(type == "radio")
|
||
{
|
||
var radioIcon:Object = getStyleValue("radioIcon");
|
||
if(radioIcon != null)
|
||
{
|
||
_selectedIcon = getDisplayObjectInstance(radioIcon);
|
||
_selectedIcon.visible = false;
|
||
addChild(_selectedIcon);
|
||
}
|
||
}
|
||
}
|
||
//icon
|
||
if(_data.hasOwnProperty("icon"))
|
||
{
|
||
icon = getDisplayObjectInstance(_data.icon);
|
||
if(icon != null)
|
||
{
|
||
addChild(icon);
|
||
icon.visible = true;
|
||
}
|
||
}
|
||
//selected icon
|
||
if(_data.hasOwnProperty("selectedIcon"))
|
||
{
|
||
_selectedIcon = getDisplayObjectInstance(_data.selectedIcon);
|
||
if(_selectedIcon != null)
|
||
{
|
||
_selectedIcon.visible = false;
|
||
addChild(_selectedIcon);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @private (protected)
|
||
*
|
||
* @langversion 3.0
|
||
* @playerversion Flash 9.0.28.0
|
||
*/
|
||
//override drawIcon from the LabelButton class
|
||
//check the _data object's selected property
|
||
override protected function drawIcon():void
|
||
{
|
||
if(data.hasOwnProperty("selected"))
|
||
{
|
||
if(!data.selected is Boolean && data.selected is String)
|
||
{
|
||
data.selected = data.selected.toLowerCase() == "true";
|
||
}
|
||
}
|
||
else data.selected = false;
|
||
|
||
//if there is a selected icon and an icon, use the selected icon when selected and the icon when not selected
|
||
//if there is only an icon (i.e. check or radio) show the icon when selected and hide the icon when deselected.
|
||
if(_selectedIcon != null)
|
||
{
|
||
_selectedIcon.visible = data.selected;
|
||
}
|
||
if(icon != null)
|
||
{
|
||
icon.visible = !data.selected;
|
||
}
|
||
|
||
}
|
||
|
||
override public function setStyle(style:String, value:Object):void
|
||
{
|
||
//Use strict equality so we can set a style to null ... so if the instanceStyles[style] == undefined, null is still set.
|
||
//We also need to work around the specific use case of TextFormats
|
||
if (instanceStyles[style] === value && !(value is TextFormat)) { return; }
|
||
if(value is InstanceFactory)
|
||
{
|
||
instanceStyles[style] = UIComponentUtil.getDisplayObjectInstance(this, (value as InstanceFactory).createInstance());
|
||
}
|
||
else
|
||
{
|
||
instanceStyles[style] = value;
|
||
}
|
||
invalidate(InvalidationType.STYLES);
|
||
}
|
||
}
|
||
} |