//////////////////////////////////////////////////////////////////////////////// // // 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.supportClasses { import flash.display.Stage; import flash.events.StageOrientationEvent; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; import mx.core.FlexGlobals; import mx.core.UIComponent; import mx.core.mx_internal; import mx.events.FlexEvent; import mx.events.PropertyChangeEvent; import mx.events.ResizeEvent; import mx.utils.DensityUtil; import spark.components.SkinnableContainer; import spark.components.View; import spark.utils.MultiDPIBitmapSource; use namespace mx_internal; /** * The ViewNavigatorBase class defines the base class logic and * interface used by view navigators. * This class contains methods and properties related to view management, * as well as integration points with ViewNavigatorApplicationBase application * classes. * * @mxml
The <s:ViewNavigatorBase>
tag inherits
* all of the tag attributes of its superclass and adds the following tag attributes:
* <s:ViewNavigatorBase * Properties * icon="null" * label="null" * transitionsEnabled="true" * /> ** * @see spark.components.ViewNavigator * @see spark.components.ViewNavigatorApplication * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public class ViewNavigatorBase extends SkinnableContainer { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function ViewNavigatorBase() { super(); _navigationStack = new NavigationStack(); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private * This private variable is used to indicate that the navigator shouldn't play * the pending visibility animation for the chrome components that it controls * (e.g, ActionBar and TabBar). This flag is set to true when the stage changes * orientation. This allows the framework to prevent the hide/show animation * from playing when the controls are hidden in either landscape or portrait. * * See SDK-28541 for more information. */ mx_internal var disableNextControlAnimation:Boolean = false; //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // active //---------------------------------- private var _active:Boolean = true; /** * Set to
true
when this navigator is active.
* The parent navigator automatically sets this flag its state changes.
*
* @default true
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get isActive():Boolean
{
return _active;
}
/**
* @private
* Setting the active state is hidden and should be managed my
* the components that manage navigators.
*/
mx_internal function setActive(value:Boolean, clearNavigationStack:Boolean = false):void
{
if (_active != value)
_active = value;
}
//----------------------------------
// activeView
//----------------------------------
/**
* The currently active view of the navigator.
* Only one view can be active at a time.
*
* @default null
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get activeView():View
{
return null;
}
//----------------------------------
// exitApplicationOnBackKey
//----------------------------------
/**
* @private
* This method determines if a device's default back key handler can
* be canceled. For example, by default, when the back key is pressed
* on android devices, the application exits. By returning true, that
* action will be canceled and the navigator's default back key behavior
* will run.
*
* This method is only called if the navigator is the main navigator * of a ViewNavigatorApplication class
. * * @default true * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ mx_internal function get exitApplicationOnBackKey():Boolean { return true; } //---------------------------------- // icon //---------------------------------- private var _icon:Object; /** * The icon used when this navigator is represented * by a visual component. * * @default null * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function get icon():Object { return _icon; } /** * @private */ public function set icon(value:Object):void { if (_icon != value) { var oldValue:Object = _icon; _icon = value; if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE)) { var changeEvent:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, "icon", oldValue, _icon); dispatchEvent(changeEvent); } } } //---------------------------------- // label //---------------------------------- private var _label:String = ""; [Bindable] /** * The label used when this navigator is represented by a visual component. * * @default null * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function get label():String { return _label; } /** * @private */ public function set label(value:String):void { if (_label != value) { var oldValue:String = _label; _label = value; if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE)) { var changeEvent:PropertyChangeEvent = PropertyChangeEvent.createUpdateEvent(this, "label", oldValue, _label); dispatchEvent(changeEvent); } } } //---------------------------------- // lastAction //---------------------------------- private var _lastAction:String = ViewNavigatorAction.NONE; /** * @private * The last action performed by the navigator. * * @see spark.components.supportClasses.ViewNavigatorAction */ mx_internal function get lastAction():String { return _lastAction; } /** * @private */ mx_internal function set lastAction(value:String):void { _lastAction = value; } //---------------------------------- // navigationStack //---------------------------------- /** * @private */ protected var _navigationStack:NavigationStack; /** * @private * The navigation stack that is being managed by the navigator. * An empty navigation stack is automatically created when * a navigator is created. * * @default null */ mx_internal function get navigationStack():NavigationStack { return _navigationStack; } /** * @private */ mx_internal function set navigationStack(value:NavigationStack):void { if (value == null) _navigationStack = new NavigationStack(); else _navigationStack = value; } //---------------------------------- // overlayControls //---------------------------------- private var _overlayControls:Boolean = false; /** * @private * This property controls the overlay state of the navigator. The * navigator will properly update this property in the * updateControlsForView() method with the View.overlayControls * property. * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ mx_internal function get overlayControls():Boolean { return _overlayControls; } mx_internal function set overlayControls(value:Boolean):void { if (value != _overlayControls) { _overlayControls = value; invalidateSkinState(); if (skin) { skin.invalidateSize(); skin.invalidateDisplayList(); } } } //---------------------------------- // parentNavigator //---------------------------------- private var _parentNavigator:ViewNavigatorBase; /** * The parent navigator for this navigator. * * @default null * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function get parentNavigator():ViewNavigatorBase { return _parentNavigator; } /** * @private */ mx_internal function setParentNavigator(value:ViewNavigatorBase):void { _parentNavigator = value; } //---------------------------------- // transitionsEnabled //---------------------------------- private var _transitionsEnabled:Boolean = true; /** * Set totrue
to enable view transitions
* when a view changes, or when the ActionBar control or
* TabBar control visibility changes.
*
* @default true
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get transitionsEnabled():Boolean
{
return _transitionsEnabled;
}
/**
* @private
*/
public function set transitionsEnabled(value:Boolean):void
{
_transitionsEnabled = value;
}
//--------------------------------------------------------------------------
//
// Public Methods
//
//--------------------------------------------------------------------------
/**
* This method executes the default back key behavior for a ViewNavigator.
*
* @langversion 3.0
* @playerversion AIR 3.1
* @productversion Flex 4.6
*/
public function backKeyUpHandler():void
{
}
/**
* Serializes all data related to
* the navigator's children into an object that can be saved
* by the persistence manager.
* This returned object is passed to the restoreViewData()
* method when the navigator is reinstantiated.
*
* @return The object that represents the navigators state
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function saveViewData():Object
{
var iconData:Object = icon;
if (iconData is MultiDPIBitmapSource)
{
var app:Object = FlexGlobals.topLevelApplication;
var dpi:Number;
if ("runtimeDPI" in app)
dpi = app["runtimeDPI"];
else
dpi = DensityUtil.getRuntimeDPI();
iconData = MultiDPIBitmapSource(iconData).getSource(dpi);
}
if (iconData is Class)
return {label:label, iconClassName:getQualifiedClassName(iconData)};
if (iconData is String)
return {label:label, iconStringName: iconData};
return {label:label};
}
/**
* Restores the state of a navigator's view
* from the value
argument.
* The object passed as the value
argument is
* created by a call to the saveViewData()
method.
*
* @param value The object used to restore the navigators state.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function loadViewData(value:Object):void
{
label = value.label;
var iconClassName:String = value.iconClassName;
if (iconClassName == null)
icon = value.iconStringName;
else if (iconClassName != null)
icon = getDefinitionByName(iconClassName);
// TODO (chiedozi): This is not module safe because of its use of
// getDefinitionByName. Should use systemManager to do this. (SDK-27424)
}
/**
* Updates various properties of the navigator when a
* new view is added and activated.
*
* @param view The view that was added.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function updateControlsForView(view:View):void
{
if (parentNavigator)
parentNavigator.updateControlsForView(view);
}
//--------------------------------------------------------------------------
//
// Private methods
//
//--------------------------------------------------------------------------
/**
* @private
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
override protected function getCurrentSkinState():String
{
var finalState:String = FlexGlobals.topLevelApplication.aspectRatio;
if (_overlayControls)
finalState += "AndOverlay";
return finalState;
}
/**
* @private
* This method checks if the current view can be removed
* from the display list. This is mx_internal because the
* TabbedViewNavigator needs to call it on its children.
*
* @return Returns true if the screen can be removed
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
mx_internal function canRemoveCurrentView():Boolean
{
// This is a method instead of a property because the default
// implementation in ViewNavigator has a side effect
return true;
}
/**
* @private
* Captures the important animation values of component to use
* when animating the actionBar's visiblity.
*
* @param component The component to capture the values from
*
* @return Returns an object that contains the properties
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
mx_internal function captureAnimationValues(component:UIComponent):Object
{
var values:Object = { x:component.x,
y:component.y,
width:component.width,
height:component.height,
explicitWidth:component.explicitWidth,
explicitHeight:component.explicitHeight,
percentWidth:component.percentWidth,
percentHeight:component.percentHeight,
visible: component.visible,
includeInLayout: component.includeInLayout,
cacheAsBitmap: component.cacheAsBitmap };
return values;
}
/**
* @private
* Creates the top view of the navigator and adds it to the
* display list. This method is used when the navigator exists
* inside a TabbedViewNavigator.
*/
mx_internal function createTopView():void
{
// Override in sub class
}
/**
* @private
*/
private function creationCompleteHandler(event:FlexEvent):void
{
removeEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
// Create a weak listener so stage doesn't hold a reference to the view
FlexGlobals.topLevelApplication.addEventListener(ResizeEvent.RESIZE,
stage_resizeHandler, false, 0, true);
}
/**
* @private
*/
mx_internal function updateFocus():void
{
var stage:Stage = systemManager.stage;
if (!stage.focus || !stage.focus.stage || stage.focus == this)
{
if (activeView)
stage.focus = activeView;
else
stage.focus = this;
}
}
/**
* @private
*/
mx_internal function stage_resizeHandler(event:ResizeEvent):void
{
disableNextControlAnimation = true;
invalidateSkinState();
}
//--------------------------------------------------------------------------
//
// Overridden methods: UIComponent
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function attachSkin():void
{
super.attachSkin();
// Since a new skin was added, update the state of the controls
// added as part of the new skin
updateControlsForView(activeView);
}
/**
* @private
*/
override public function initialize():void
{
super.initialize();
addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
}
}
}