////////////////////////////////////////////////////////////////////////////////
//
// 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.components
{
import mx.core.IVisualElement;
import mx.core.mx_internal;
import mx.utils.BitFlagUtil;
import spark.components.supportClasses.SkinnableComponent;
import spark.core.IDisplayText;
import spark.layouts.supportClasses.LayoutBase;
use namespace mx_internal;
//--------------------------------------
// Styles
//--------------------------------------
include "../styles/metadata/StyleableTextFieldTextStyles.as"
/**
* Alignment of the title relative to the ActionBar dimensions.
* Possible values are "left"
, "right"
,
* and "center"
.
*
* @default "center"
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="titleAlign", type="String", enumeration="left,right,center", inherit="no", theme="mobile")]
/**
* @copy spark.components.supportClasses.GroupBase#style:accentColor
*
* @default 0x0099FF
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="accentColor", type="uint", format="Color", inherit="yes", theme="mobile")]
/**
* @copy spark.components.SkinnableContainer#style:backgroundAlpha
*
* @default 1.0
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="backgroundAlpha", type="Number", inherit="no", theme="mobile", minValue="0.0", maxValue="1.0")]
/**
* @copy spark.components.SkinnableContainer#style:contentBackgroundAlpha
*
* @default 1.0
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="contentBackgroundAlpha", type="Number", inherit="yes", theme="mobile")]
/**
* @copy spark.components.supportClasses.GroupBase#style:contentBackgroundColor
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="contentBackgroundColor", type="uint", format="Color", inherit="yes", theme="mobile")]
/**
* @copy spark.components.supportClasses.GroupBase#style:focusColor
*
* @default 0x70B2EE
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="focusColor", type="uint", format="Color", inherit="yes", theme="mobile")]
/**
* Number of pixels between the bottom border and all content groups.
*
* @default 0
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]
/**
* Number of pixels between the left border and the navigationGroup.
*
* @default 0
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="paddingLeft", type="Number", format="Length", inherit="no")]
/**
* Number of pixels between the left border and the actionGroup.
*
* @default 0
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="paddingRight", type="Number", format="Length", inherit="no")]
/**
* Number of pixels between the top border and all content groups.
*
* @default 0
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Style(name="paddingTop", type="Number", format="Length", inherit="no")]
/**
* Color of text shadows.
*
* @default 0xFFFFFF
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="textShadowColor", type="uint", format="Color", inherit="yes", theme="mobile")]
/**
* Alpha of text shadows.
*
* @default 0.55
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="textShadowAlpha", type="Number",inherit="yes", minValue="0.0", maxValue="1.0", theme="mobile")]
/**
* Appearance of buttons in navigation and action groups.
* Valid MXML values are normal
and beveled
*
*
In ActionScript, you can use the following constants
* to set this property:
* ActionBarDefaultButtonAppearance.NORMAL
and
* ActionBarDefaultButtonAppearance.BEVELED
.
titleDisplay
* skin part and no content
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("title")]
/**
* ActionBar with content defined for the titleDisplay
* skin part, and components defined in the actionContent
* property for display in the actionGroup
skin part.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("titleWithAction")]
/**
* ActionBar with content defined for the titleDisplay
* skin part, and components defined in the navigationContent
* property for display in the navigationGroup
skin part.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("titleWithNavigation")]
/**
* ActionBar with content defined for the titleDisplay
* skin part, and components for display in
* the actionGroup
skin part and in
* the navigationGroup
skin part.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("titleWithActionAndNavigation")]
/**
* ActionBar with content in the titleContent
* skin part, but not in the titleDisplay
skin part.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("titleContent")]
/**
* ActionBar with content in the titleContent
* skin part, and components defined in the actionContent
* property for display in the actionGroup
skin part.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("titleContentWithAction")]
/**
* ActionBar with content in the titleContent
* skin part, and components defined in the navigationContent
* property for display in the navigationGroup
skin part.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("titleContentWithNavigation")]
/**
* ActionBar with content defined for the titleContent
* skin part, and components for display in
* the actionGroup
skin part and in
* the navigationGroup
skin part.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[SkinState("titleContentWithActionAndNavigation")]
/**
* The ActionBar class defines a component that includes title, navigation,
* and action content groups.
* The ActionBar control provides a standard area for navigation and action controls.
* It lets you define global controls that can be used from anywhere in the application,
* or controls specific to a view.
*
* The ActionBar control defines three distinct areas:
* *Contains components that let the user navigate the section.
* For example, you can define a home button in the navigation area.
* Use the navigationContent
property to define
* the components that appear in the navigation area.
* Use the navigationLayout
property to define
* the layout of the navigation area.
Contains either a String containing title text, or components.
* If you specify components, you cannot specify a title String.
* Use the title
property to specify the String to appear in
* the title area.
* Use the titleContent
property to define the
* components that appear in the title area.
* Use the titleLayout
property to define the
* layout of the title area.
* If you specify a value for the titleContent
property,
* the ActionBar skin ignores the title
property.
Contains components that define actions the user can take in a view.
* For example, you might define a search or refresh button as part of
* the action area.
* Use the actionContent
property to define the components
* that appear in the action area.
* Use the actionLayout
property to define the layout
* of the action area.
The following image shows the ActionBar with a home button in the navigation area, * a text input control in the title area, and a search button in the action area:
* ** *
* *For a mobile application with a single section, meaning a single * ViewNavigator container, all views share the same action bar. * For a mobile application with multiple sections, meaning one with multiple * ViewNavigator containers, each section defines its own action bar.
* * @mxml * *The <s:ActionBar>
tag inherits all of the tag
* attributes of its superclass and adds the following tag attributes:
* <s:ActionBar * Properties * actionContent="null" * actionLayout="HorizontalLayout" * navigationContent="null" * navigationLayout="HorizontalLayout" * title="" * titleContent="null" * titleLayout="HorizontalLayout" * * Common Styles * color="Theme dependent" * fontFamily="Theme dependent" * fontSize="Theme dependent" * fontStyle="normal" * fontWeight="normal" * leading="0" * letterSpacing="0" * textAlign="center" * textDecoration="none" * textIndent="0" * * Mobile Styles * accentColor="0x0099FF" * backgroundAlpha="1.0" * color="Theme dependent" * contentBackgroundAlpha="1.0" * contentBackgroundColor="0xFFFFFF" * focusColor="0x70B2EE" * textShadowAlpha="0.55" * textShadowColor="0xFFFFFF" * titleAlign="center" * * > ** * @see spark.components.SkinnableContainer * @see ViewNavigator * @see View * @see ViewNavigatorApplication * @see spark.skins.mobile.ActionBarSkin * * @includeExample examples/ActionBarExample2.mxml -noswf * @includeExample examples/ActionBarExample3.mxml -noswf * @includeExample examples/ActionBarExampleHomeView.mxml -noswf * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public class ActionBar extends SkinnableComponent { //-------------------------------------------------------------------------- // // Class constants // //-------------------------------------------------------------------------- /** * @private */ mx_internal static const CONTENT_PROPERTY_FLAG:uint = 1 << 0; /** * @private */ mx_internal static const LAYOUT_PROPERTY_FLAG:uint = 1 << 1; /** * @private */ mx_internal static const NAVIGATION_GROUP_PROPERTIES_INDEX:uint = 0; /** * @private */ mx_internal static const TITLE_GROUP_PROPERTIES_INDEX:uint = 1; /** * @private */ mx_internal static const ACTION_GROUP_PROPERTIES_INDEX:uint = 2 /** * @private */ mx_internal var contentGroupProperties:Array = [{}, {}, {}]; /** * Cache original skin layouts * @private */ mx_internal var contentGroupLayouts:Array = [null, null, null]; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function ActionBar() { super(); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // // Skin parts // //-------------------------------------------------------------------------- [SkinPart(required="false")] /** * The skin part that defines the appearance of the * navigation area of the component. * By default, the ActionBarSkin class defines the navigation area to appear * to the left of the title area. * * @see spark.skins.mobile.ActionBarSkin * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public var navigationGroup:Group; [SkinPart(required="false")] /** * The skin part that defines the appearance of the * title area of the component. * By default, the ActionBarSkin class defines the title area to appear * between the navigation and action areas. * * @see spark.skins.mobile.ActionBarSkin * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public var titleGroup:Group; [SkinPart(required="false")] /** * The skin part that defines the appearance of the * action area of the component. * By default, the ActionBarSkin class defines the action area to appear * to the right of the title area. * * @see spark.skins.mobile.ActionBarSkin * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public var actionGroup:Group; [SkinPart(required="false")] /** * The skin part that defines the appearance of the * title text in the component. * * You can use CSS to declare styles on the ActionBar's titleDisplay skin part, as the following example shows: * *
* @namespace s "library://ns.adobe.com/flex/spark"; * s|ActionBar #titleDisplay { * color:red; * } ** * @see spark.skins.mobile.ActionBarSkin * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4 */ public var titleDisplay:IDisplayText; //---------------------------------- // title //---------------------------------- private var _title:String = ""; [Bindable] /** * Title or caption displayed in the title area. * *
Use the titleContent
property to define
* the components that appear in the title area.
* If you specify a value for the titleContent
property,
* the ActionBar skin ignores the title
property.
navigationGroup
skin part.
*
* The location and appearance of the navigationGroup
* skin part is determined by the ActionBarSkin class.
* The default ActionBarSkin class defines the navigationGroup
* to appear to the left of the titleGroup
area of the ActionBar.
Create a custom ActionBarSkin skin class to change the default location
* and appearance of the navigationGroup
skin part.
navigationGroup
skin part.
*
* @default HorizontalLayout
*
* @see #navigationContent
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get navigationLayout():LayoutBase
{
if (navigationGroup)
return navigationGroup.layout;
else
return contentGroupProperties[NAVIGATION_GROUP_PROPERTIES_INDEX].layout;
}
/**
* @private
*/
public function set navigationLayout(value:LayoutBase):void
{
if (navigationGroup)
{
navigationGroup.layout = (value) ? value : contentGroupLayouts[NAVIGATION_GROUP_PROPERTIES_INDEX];
contentGroupProperties[NAVIGATION_GROUP_PROPERTIES_INDEX] =
BitFlagUtil.update(contentGroupProperties[NAVIGATION_GROUP_PROPERTIES_INDEX] as uint,
LAYOUT_PROPERTY_FLAG, true);
}
else
contentGroupProperties[NAVIGATION_GROUP_PROPERTIES_INDEX].layout = value;
}
//----------------------------------
// titleContent
//----------------------------------
[ArrayElementType("mx.core.IVisualElement")]
/**
* The components that appear in the title area of the control.
* These components appear in the titleGroup
* skin part of the ActionBar control.
*
* The location and appearance of the titleGroup
* skin part is determined by the ActionBarSkin class.
* The default ActionBarSkin class defines the titleGroup
* to appear in the center of the ActionBar,
* using the space remaining between navigationGroup
* and actionGroup
skin parts.
If titleContent
is null, the
* titleDisplay
skin part, if present, is displayed
* in place of the titleGroup
skin part.
Create a custom ActionBarSkin skin class to change the default
* location and appearance of the titleGroup
skin part.
titleGroup
* and titleDisplay
skin parts.
*
* If the titleContent
property is null,
* the titleDisplay
skin part is displayed
* in place of the titleGroup
skin part.
* The titleDisplay
skin part is positioned
* in the center of the ActionBar control
* by using the paddingLeft
and
* paddingRight
properties of the layout
* class specified by the titleLayout
property.
actionGroup
skin part.
*
* The location and appearance of the actionGroup
* skin part is determined by the ActionBarSkin class.
* The default ActionBarSkin class defines the actionGroup
* to appear to the right of the title display area of the ActionBar.
Create a custom ActionBarSkin skin class to change the default location
* and appearance of the actionGroup
skin part.
actionGroup
property.
*
* @default HorizontalLayout
*
* @see #actionContent
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get actionLayout():LayoutBase
{
if (actionGroup)
return actionGroup.layout;
else
return contentGroupProperties[ACTION_GROUP_PROPERTIES_INDEX].layout;
}
/**
* @private
*/
public function set actionLayout(value:LayoutBase):void
{
if (actionGroup)
{
actionGroup.layout = (value) ? value : contentGroupLayouts[ACTION_GROUP_PROPERTIES_INDEX];
contentGroupProperties[ACTION_GROUP_PROPERTIES_INDEX] =
BitFlagUtil.update(contentGroupProperties[ACTION_GROUP_PROPERTIES_INDEX] as uint,
LAYOUT_PROPERTY_FLAG, true);
}
else
contentGroupProperties[ACTION_GROUP_PROPERTIES_INDEX].layout = value;
}
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
if (!styleProp ||
styleProp == "styleName" ||
styleProp == "defaultButtonAppearance")
{
// prepend defaultButtonAppearance style name
var otherStyleNames:String = (styleName as String) ? String(styleName) : "";
var whitespace:int = otherStyleNames.indexOf(" ");
var firstStyleName:String = (whitespace > 0) ? otherStyleNames.substring(0, whitespace) : otherStyleNames;
var defaultButtonAppearance:String = getStyle("defaultButtonAppearance");
// only change styleName if necessary
if (firstStyleName != defaultButtonAppearance)
{
// remove previous defaultButtonAppearance value
if (firstStyleName == ActionBarDefaultButtonAppearance.BEVELED
|| firstStyleName == ActionBarDefaultButtonAppearance.NORMAL)
{
if (whitespace < 0)
otherStyleNames = "";
else
otherStyleNames = " " + otherStyleNames.substr(whitespace + 1);
}
styleName = defaultButtonAppearance + otherStyleNames;
}
}
super.styleChanged(styleProp);
}
//----------------------------------
// baselinePosition
//----------------------------------
/**
* @private
*/
override public function get baselinePosition():Number
{
return getBaselinePositionForPart(titleDisplay as IVisualElement);
}
/**
* @private
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
override protected function getCurrentSkinState():String
{
var state:String = (titleContent) ? "titleContent" : "title";
if (actionContent && navigationContent)
{
state += "WithActionAndNavigation";
}
else if (actionContent)
{
state += "WithAction";
}
else if (navigationContent)
{
state += "WithNavigation";
}
return state;
}
/**
* @private
*/
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
var group:Group;
var index:int = -1;
// set ID for CSS selectors
// (e.g. to style actionContent Buttons: s|ActionBar s|Group#actionGroup s|Button)
if (instance == navigationGroup)
{
group = navigationGroup;
index = NAVIGATION_GROUP_PROPERTIES_INDEX;
}
else if (instance == titleGroup)
{
group = titleGroup;
index = TITLE_GROUP_PROPERTIES_INDEX;
}
else if (instance == actionGroup)
{
group = actionGroup;
index = ACTION_GROUP_PROPERTIES_INDEX;
}
else if (instance == titleDisplay)
{
titleDisplay.text = title;
}
if (index > -1)
{
// cache original layout
contentGroupLayouts[index] = group.layout;
var newContentGroupProperties:uint = 0;
if (contentGroupProperties[index].content != null)
{
group.mxmlContent = contentGroupProperties[index].content;
newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties,
CONTENT_PROPERTY_FLAG, true);
}
if (contentGroupProperties[index].layout != null)
{
group.layout = contentGroupProperties[index].layout;
newContentGroupProperties = BitFlagUtil.update(newContentGroupProperties,
LAYOUT_PROPERTY_FLAG, true);
}
contentGroupProperties[index] = newContentGroupProperties;
}
}
/**
* @private
*/
override protected function partRemoved(partName:String, instance:Object):void
{
super.partRemoved(partName, instance);
var group:Group;
var index:int = -1;
if (instance == navigationGroup)
{
group = navigationGroup;
index = NAVIGATION_GROUP_PROPERTIES_INDEX;
}
else if (instance == titleGroup)
{
group = titleGroup;
index = TITLE_GROUP_PROPERTIES_INDEX;
}
else if (instance == actionGroup)
{
group = actionGroup;
index = ACTION_GROUP_PROPERTIES_INDEX;
}
if (index > -1)
{
var newContentGroupProperties:Object = {};
if (BitFlagUtil.isSet(contentGroupProperties[index] as uint, CONTENT_PROPERTY_FLAG))
newContentGroupProperties.content = group.getMXMLContent();
if (BitFlagUtil.isSet(contentGroupProperties[index] as uint, LAYOUT_PROPERTY_FLAG))
newContentGroupProperties.layout = group.layout;
contentGroupProperties[index] = newContentGroupProperties;
group.mxmlContent = null;
group.layout = null;
}
}
}
}