////////////////////////////////////////////////////////////////////////////////
//
// 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 flash.events.StageOrientationEvent;
import mx.core.FlexGlobals;
import mx.core.IDataRenderer;
import mx.core.IVisualElement;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
import mx.events.ResizeEvent;
import spark.core.ContainerDestructionPolicy;
import spark.events.ViewNavigatorEvent;
import spark.layouts.supportClasses.LayoutBase;
use namespace mx_internal;
[Exclude(name="height", kind="property")]
[Exclude(name="minHeight", kind="property")]
[Exclude(name="maxHeight", kind="property")]
[Exclude(name="width", kind="property")]
[Exclude(name="minWidth", kind="property")]
[Exclude(name="maxWidth", kind="property")]
[Exclude(name="scaleX", kind="property")]
[Exclude(name="scaleY", kind="property")]
[Exclude(name="scaleZ", kind="property")]
[Exclude(name="z", kind="property")]
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when the back key is pressed when a view exists inside
* a mobile application.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*
* @eventType mx.events.FlexEvent.BACK_KEY_PRESSED
*
*/
[Event(name="backKeyPressed", type="mx.events.FlexEvent")]
/**
* Dispatched when the data
property changes.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*
* @eventType mx.events.FlexEvent.DATA_CHANGE
*
*/
[Event(name="dataChange", type="mx.events.FlexEvent")]
/**
* Dispatched when the menu key is pressed when a view exists inside
* a mobile application.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*
* @eventType mx.events.FlexEvent.MENU_KEY_PRESSED
*
*/
[Event(name="menuKeyPressed", type="mx.events.FlexEvent")]
/**
* Dispatched when the current view has been activated.
*
* @eventType spark.events.ViewNavigatorEvent.VIEW_ACTIVATE
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Event(name="viewActivate", type="spark.events.ViewNavigatorEvent")]
/**
* Dispatched when the current view has been deactivated.
*
* @eventType spark.events.ViewNavigatorEvent.VIEW_DEACTIVATE
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Event(name="viewDeactivate", type="spark.events.ViewNavigatorEvent")]
/**
* Dispatched when the screen is about to be removed in response
* to a screen change.
* Calling preventDefault()
* while handling this event cancels the screen change.
*
* @eventType spark.events.ViewNavigatorEvent.REMOVING
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Event(name="removing", type="spark.events.ViewNavigatorEvent")]
/**
* The View class is the base container class for all views used by view
* navigators.
* The View container extends the Group container and adds
* additional properties used to communicate with it's parent
* navigator.
*
*
In a mobile application, the content area of the application * displays the individual screens, or views, that make up the application. * Users navigate the views of the application by using the touch screen, * components built into the application, and the input controls of the mobile device.
* *The following image shows a View container with a List control:
* ** *
* *Each view in an application corresponds to a View container defined
* in an ActionScript or MXML file.
* Each View contains a data
property that specifies the data
* associated with that view.
* Views can use the data
property to pass information to each
* other as the user navigates the application.
The <s:View>
tag inherits all of the tag
* attributes of its superclass and adds the following tag attributes:
* <s:View * Properties * actionBarVisible="true" * actionContent="null" * actionLayout="null" * data="null" * destructionPolicy="auto" * navigationContent="null" * navigationLayout="null" * overlayControls="false" * tabBarVisible="true" * title="" * titleContent="null" * titleLayout="null" * viewMenuItems="null" * * Events * backKeyPressed="No default" * dataChange="No default" * menuKeyPressed="No default" * removing="No default" * viewActivate="No default" * viewDeactivate="No default" * * > ** * @see ViewNavigator * * @includeExample examples/ViewExample.mxml -noswf * @includeExample examples/ViewExampleHomeView.mxml -noswf * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public class View extends SkinnableContainer implements IDataRenderer { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion AIR 2.5 * @productversion Flex 4.5 */ public function View() { super(); } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // active //---------------------------------- private var _active:Boolean = false; /** * Indicates whether the current view is active. * The view's navigator automatically sets this flag to
true
* or false
as its state changes.
* Setting this property can dispatch the viewActivate
or
* viewDeactivate
events.
*
* @default false
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get isActive():Boolean
{
return _active;
}
/**
* @private
*/
mx_internal function setActive(value:Boolean):void
{
if (_active != value)
{
_active = value;
// Switch orientation states if needed
if (_active)
updateOrientationState();
var eventName:String = _active ?
ViewNavigatorEvent.VIEW_ACTIVATE :
ViewNavigatorEvent.VIEW_DEACTIVATE;
if (hasEventListener(eventName))
dispatchEvent(new ViewNavigatorEvent(eventName, false, false, navigator.lastAction));
}
}
//----------------------------------
// canRemove
//----------------------------------
/**
* @private
* Determines if the current view can be removed by a navigator. The default
* implementation dispatches a FlexEvent.REMOVING
event. If
* preventDefault() is called on the event, this property will return false.
*
* @return Returns true if the view can be removed
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
mx_internal function canRemove():Boolean
{
if (hasEventListener(ViewNavigatorEvent.REMOVING))
{
var event:ViewNavigatorEvent =
new ViewNavigatorEvent(ViewNavigatorEvent.REMOVING,
false, true, navigator.lastAction);
return dispatchEvent(event);
}
return true;
}
/**
* @private
*/
mx_internal function backKeyHandledByView():Boolean
{
if (hasEventListener(FlexEvent.BACK_KEY_PRESSED))
{
var event:FlexEvent = new FlexEvent(FlexEvent.BACK_KEY_PRESSED, false, true);
var eventCanceled:Boolean = !dispatchEvent(event);
// If the event was canceled, that means the application
// is doing its own custom logic for the back key
return eventCanceled;
}
return false;
}
/**
* @private
*/
mx_internal function menuKeyHandledByView():Boolean
{
if (hasEventListener(FlexEvent.MENU_KEY_PRESSED))
{
var event:FlexEvent = new FlexEvent(FlexEvent.MENU_KEY_PRESSED, false, true);
var eventCanceled:Boolean = !dispatchEvent(event);
// If the event was canceled, that means the application
// is doing its own custom logic for the back key
return eventCanceled;
}
return false;
}
//----------------------------------
// overlayControls
//----------------------------------
private var _overlayControls:Boolean = false;
[Inspectable(category="General", defaultValue="false")]
/**
* By default, the TabBar and ActionBar controls of a
* mobile application define an area that cannot be used
* by the views of an application.
* That means your content cannot use the full screen size
* of the mobile device.
* If you set this property to true
, the content area
* of the application spans the entire width and height of the screen.
* The ActionBar and TabBar controls hover over the content area with
* an alpha
value of 0.5 so that they are partially transparent.
*
* @default false
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get overlayControls():Boolean
{
return _overlayControls;
}
/**
* @private
*/
public function set overlayControls(value:Boolean):void
{
if (_overlayControls != value)
{
var oldValue:Boolean = _overlayControls;
_overlayControls = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "overlayControls", oldValue, _overlayControls);
dispatchEvent(changeEvent);
}
}
}
//----------------------------------
// destructionPolicy
//----------------------------------
private var _destructionPolicy:String = ContainerDestructionPolicy.AUTO;
[Inspectable(category="General", enumeration="auto,never", defaultValue="auto")]
/**
* Defines the destruction policy the view's navigator should use
* when this view is removed. If set to "auto", the navigator will
* destroy the view when it isn't active. If set to "never", the
* view will be cached in memory.
*
* @default auto
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get destructionPolicy():String
{
return _destructionPolicy;
}
/**
* @private
*/
public function set destructionPolicy(value:String):void
{
_destructionPolicy = value;
}
//----------------------------------
// navigator
//----------------------------------
private var _navigator:ViewNavigator = null;
/**
* The view navigator that this view resides in.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
[Bindable("navigatorChanged")]
public function get navigator():ViewNavigator
{
return _navigator;
}
/**
* @private
*/
mx_internal function setNavigator(value:ViewNavigator):void
{
_navigator = value;
if (hasEventListener("navigatorChanged"))
dispatchEvent(new Event("navigatorChanged"));
}
//--------------------------------------------------------------------------
//
// UI Template Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// actionBarVisible
//----------------------------------
private var _actionBarVisible:Boolean = true;
[Inspectable(category="General", defaultValue="true")]
/**
* Specifies whether a view should show the action bar or not.
* This property does not necessarily correlate to the
* visible
property of the view navigator's ActionBar control.
*
* @default true
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get actionBarVisible():Boolean
{
return _actionBarVisible;
}
/**
* @private
*/
public function set actionBarVisible(value:Boolean):void
{
_actionBarVisible = value;
// Immediately request actionBar's visibility be toggled
if (isActive && navigator)
{
if (_actionBarVisible)
navigator.showActionBar();
else
navigator.hideActionBar();
}
}
/**
* @private
* Method called by parent navigator to update the actionBarVisible
* flag as a result of the showActionBar() or hideActionBar() methods.
*/
mx_internal function setActionBarVisible(value:Boolean):void
{
_actionBarVisible = value;
}
//----------------------------------
// actionContent
//----------------------------------
private var _actionContent:Array;
[ArrayElementType("mx.core.IVisualElement")]
/**
* This property overrides the actionContent
* property in the ActionBar, ViewNavigator, and
* ViewNavigatorApplication components.
*
* @copy ActionBar#actionContent
*
* @default null
*
* @see ActionBar#actionContent
* @see spark.skins.mobile.ActionBarSkin
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get actionContent():Array
{
return _actionContent;
}
/**
* @private
*/
public function set actionContent(value:Array):void
{
var oldValue:Array = _actionContent;
_actionContent = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "actionContent", oldValue, _actionContent);
dispatchEvent(changeEvent);
}
}
//----------------------------------
// actionLayout
//----------------------------------
private var _actionLayout:LayoutBase;
/**
* @copy ActionBar#actionLayout
*
* @default null
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get actionLayout():LayoutBase
{
return _actionLayout;
}
/**
* @private
*/
public function set actionLayout(value:LayoutBase):void
{
var oldValue:LayoutBase = value;
_actionLayout = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "actionLayout", oldValue, _actionLayout);
dispatchEvent(changeEvent);
}
}
//----------------------------------
// viewMenuItems
//----------------------------------
private var _viewMenuItems:Vector.navigationContent
* property in the ActionBar, ViewNavigator, and
* ViewNavigatorApplication components.
*
* @copy ActionBar#navigationContent
*
* @default null
*
* @see ActionBar#navigationContent
* @see spark.skins.mobile.ActionBarSkin
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get navigationContent():Array
{
return _navigationContent;
}
/**
* @private
*/
public function set navigationContent(value:Array):void
{
var oldValue:Array = _navigationContent;
_navigationContent = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "navigationContent", oldValue, _navigationContent);
dispatchEvent(changeEvent);
}
}
//----------------------------------
// navigationLayout
//----------------------------------
private var _navigationLayout:LayoutBase;
/**
* @copy ActionBar#navigationLayout
*
* @default null
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get navigationLayout():LayoutBase
{
return _navigationLayout;
}
/**
* @private
*/
public function set navigationLayout(value:LayoutBase):void
{
var oldValue:LayoutBase = _navigationLayout;
_navigationLayout = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "navigationLayout", _navigationLayout, value);
dispatchEvent(changeEvent);
}
}
//----------------------------------
// tabBarVisible
//----------------------------------
private var _tabBarVisible:Boolean = true;
[Inspectable(category="General", defaultValue="true")]
/**
* Specifies whether a view should show the tab bar or not.
* This property does not necessarily correlate to the
* visible
property of the navigator's TabBar control.
*
* @default true
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get tabBarVisible():Boolean
{
return _tabBarVisible;
}
/**
* @private
*/
public function set tabBarVisible(value:Boolean):void
{
var oldValue:Boolean = _tabBarVisible;
_tabBarVisible = value;
// Immediately request actionBar's visibility be toggled
if (isActive && navigator)
{
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "tabBarVisible", oldValue, value);
dispatchEvent(changeEvent);
}
}
}
/**
* @private
* Method called by parent navigator to update the actionBarVisible
* flag as a result of the showTabBar() or hideTabBar() methods.
*/
mx_internal function setTabBarVisible(value:Boolean):void
{
_tabBarVisible = value;
}
//----------------------------------
// title
//----------------------------------
private var _title:String;
[Bindable]
/**
* This property overrides the title
* property in the ActionBar, ViewNavigator, and
* ViewNavigatorApplication components.
*
* @copy ActionBar#title
*
* @default ""
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get title():String
{
return _title;
}
/**
* @private
*/
public function set title(value:String):void
{
if (_title != value)
{
var oldValue:String = _title;
_title = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "title", oldValue, _title);
dispatchEvent(changeEvent);
}
}
}
//----------------------------------
// titleContent
//----------------------------------
private var _titleContent:Array;
[ArrayElementType("mx.core.IVisualElement")]
/**
* This property overrides the titleContent
* property in the ActionBar, ViewNavigator, and
* ViewNavigatorApplication components.
*
* @copy ActionBar#titleContent
*
* @default null
*
* @see ActionBar#titleContent
* @see spark.skins.mobile.ActionBarSkin
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get titleContent():Array
{
return _titleContent;
}
/**
* @private
*/
public function set titleContent(value:Array):void
{
var oldValue:Array = _titleContent;
_titleContent = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "titleContent", oldValue, _titleContent);
dispatchEvent(changeEvent);
}
}
//----------------------------------
// titleLayout
//----------------------------------
private var _titleLayout:LayoutBase;
/**
* @copy ActionBar#titleLayout
*
* @default null
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get titleLayout():LayoutBase
{
return _titleLayout;
}
/**
* @private
*/
public function set titleLayout(value:LayoutBase):void
{
var oldValue:LayoutBase = _titleLayout;
_titleLayout = value;
if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
{
var changeEvent:PropertyChangeEvent =
PropertyChangeEvent.createUpdateEvent(this, "titleLayout", oldValue, _titleLayout);
dispatchEvent(changeEvent);
}
}
//--------------------------------------------------------------------------
//
// IDataRenderer Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// data
//----------------------------------
private var _data:Object;
[Bindable("dataChange")]
/**
* The data associated with the current view.
* You use this property to pass infomration to the View when
* it is pushed onto the navigator's stack.
* You can set this property by passing a data
* argument to the pushView()
method.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function get data():Object
{
return _data;
}
/**
* @private
*/
public function set data(value:Object):void
{
_data = value;
if (hasEventListener(FlexEvent.DATA_CHANGE))
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* Creates an object returned to the view navigator
* when this view is popped off the navigator's stack.
*
* Override this method in a View to return data back the new
* view when this view is popped off the stack.
* The createReturnObject()
method returns a single Object.
* The Object returned by this method is written to the
* ViewNavigator.poppedViewReturnedObject
property.
The ViewNavigator.poppedViewReturnedObject
property
* is of type ViewReturnObject.
* The ViewReturnObject.object
property contains the
* value returned by this method.
If the poppedViewReturnedObject
property is null,
* no data was returned.
* The poppedViewReturnedObject
property is guaranteed to be set
* in the new view before the new view receives the add
event.
object
field of the
* ViewNavigator.poppedViewReturnedObject
property.
*
* @see ViewNavigator#poppedViewReturnedObject
* @see spark.components.supportClasses.ViewReturnObject
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function createReturnObject():Object
{
return null;
}
/**
* Checks the aspect ratio of the stage and returns the proper state
* that the View should change to.
*
* @return A String specifying the name of the state to apply to the view.
* The possible return values are "portrait"
* or "landscape"
.
* The state is only changed if the desired state exists
* on the View.
* If it does not, this method returns the component's current state.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function getCurrentViewState():String
{
var aspectRatio:String = FlexGlobals.topLevelApplication.aspectRatio;
if (hasState(aspectRatio))
return aspectRatio;
// If the appropriate state for the orientation of the device
// isn't defined, return the current state
return currentState;
}
//--------------------------------------------------------------------------
//
// Private Methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
private function application_resizeHandler(event:Event):void
{
if (isActive)
updateOrientationState();
}
/**
* @private
*/
mx_internal function updateOrientationState():void
{
setCurrentState(getCurrentViewState(), false);
}
//--------------------------------------------------------------------------
//
// Overridden methods: UIComponent
//
//--------------------------------------------------------------------------
/**
* @private
*/
override public function initialize():void
{
super.initialize();
addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
}
/**
* @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,
application_resizeHandler, false, 0, true);
updateOrientationState();
}
//--------------------------------------------------------------------------
//
// Persistence Methods
//
//--------------------------------------------------------------------------
/**
* Responsible for serializes the view's data
property
* when the view is being persisted to disk.
* The returned object should be something that can
* be successfully written to a shared object.
* By default, this method returns the data
property
* of the view.
*
* @return The serialized data object.
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function serializeData():Object
{
return data;
}
/**
* Deserializes a data object that was saved to disk by the view,
* typically by a call to the serializeData()
method.
*
* @param value The data object to deserialize.
*
* @return The value assigned to the
* view's data
property.
*
*
* @langversion 3.0
* @playerversion AIR 2.5
* @productversion Flex 4.5
*/
public function deserializeData(value:Object):Object
{
return value;
}
}
}