////////////////////////////////////////////////////////////////////////////////
//
// 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.desktop.NativeApplication;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.NativeWindow;
import flash.display.NativeWindowDisplayState;
import flash.display.NativeWindowInitOptions;
import flash.display.NativeWindowResize;
import flash.display.NativeWindowSystemChrome;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.NativeWindowBoundsEvent;
import flash.events.NativeWindowDisplayStateEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.controls.FlexNativeMenu;
import mx.core.ContainerCreationPolicy;
import mx.core.FlexGlobals;
import mx.core.IVisualElement;
import mx.core.IWindow;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.AIREvent;
import mx.events.EffectEvent;
import mx.events.FlexEvent;
import mx.events.FlexNativeWindowBoundsEvent;
import mx.events.WindowExistenceEvent;
import mx.managers.CursorManagerImpl;
import mx.managers.DragManager;
import mx.managers.FocusManager;
import mx.managers.IActiveWindowManager;
import mx.managers.ICursorManager;
import mx.managers.ISystemManager;
import mx.managers.NativeDragManagerImpl;
import mx.managers.SystemManagerGlobals;
import mx.managers.WindowedSystemManager;
import mx.managers.systemClasses.ActiveWindowManager;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
import spark.components.supportClasses.TextBase;
import spark.components.windowClasses.TitleBar;
use namespace mx_internal;
//--------------------------------------
// Styles
//--------------------------------------
/**
* Alpha level of the color defined by the backgroundColor
* property.
*
* @default 1.0
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="backgroundAlpha", type="Number", inherit="no")]
/**
* The background color of the application. This color is used as the stage color for the
* application and the background color for the HTML embed tag.
*
* @default 0xFFFFFF
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="backgroundColor", type="uint", format="Color", inherit="no")]
/**
* Provides a margin of error around a window's border so a resize
* can be more easily started. A click on a window is considered a
* click on the window's border if the click occurs with the resizeAffordance
* number of pixels from the outside edge of the window.
*
* @default 6
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Style(name="resizeAffordanceWidth", type="Number", format="length", inherit="no")]
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when this application gets activated.
*
* @eventType mx.events.AIREvent.APPLICATION_ACTIVATE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="applicationActivate", type="mx.events.AIREvent")]
/**
* Dispatched when this application gets deactivated.
*
* @eventType mx.events.AIREvent.APPLICATION_DEACTIVATE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="applicationDeactivate", type="mx.events.AIREvent")]
/**
* Dispatched after the window has been activated.
*
* @eventType mx.events.AIREvent.WINDOW_ACTIVATE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="windowActivate", type="mx.events.AIREvent")]
/**
* Dispatched after the window has been deactivated.
*
* @eventType mx.events.AIREvent.WINDOW_DEACTIVATE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="windowDeactivate", type="mx.events.AIREvent")]
/**
* Dispatched after the window has been closed.
*
* @eventType flash.events.Event.CLOSE
*
* @see flash.display.NativeWindow
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="close", type="flash.events.Event")]
/**
* Dispatched before the window closes.
* This event is cancelable.
*
* @eventType flash.events.Event.CLOSING
*
* @see flash.display.NativeWindow
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="closing", type="flash.events.Event")]
/**
* Dispatched after the display state changes
* to minimize, maximize or restore.
*
* @eventType flash.events.NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="displayStateChange", type="flash.events.NativeWindowDisplayStateEvent")]
/**
* Dispatched before the display state changes
* to minimize, maximize or restore.
*
* @eventType flash.events.NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="displayStateChanging", type="flash.events.NativeWindowDisplayStateEvent")]
/**
* Dispatched before the window moves,
* and while the window is being dragged.
*
* @eventType flash.events.NativeWindowBoundsEvent.MOVING
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="moving", type="flash.events.NativeWindowBoundsEvent")]
/**
* Dispatched when the computer connects to or disconnects from the network.
*
* @eventType flash.events.Event.NETWORK_CHANGE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="networkChange", type="flash.events.Event")]
/**
* Dispatched before the underlying NativeWindow is resized, or
* while the Window object boundaries are being dragged.
*
* @eventType flash.events.NativeWindowBoundsEvent.RESIZING
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="resizing", type="flash.events.NativeWindowBoundsEvent")]
/**
* Dispatched when the Window completes its initial layout
* and opens the underlying NativeWindow.
*
* @eventType mx.events.AIREvent.WINDOW_COMPLETE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="windowComplete", type="mx.events.AIREvent")]
/**
* Dispatched after the window moves.
*
* @eventType mx.events.FlexNativeWindowBoundsEvent.WINDOW_MOVE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="windowMove", type="mx.events.FlexNativeWindowBoundsEvent")]
/**
* Dispatched after the underlying NativeWindow is resized.
*
* @eventType mx.events.FlexNativeWindowBoundsEvent.WINDOW_RESIZE
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="windowResize", type="mx.events.FlexNativeWindowBoundsEvent")]
//--------------------------------------
// Effects
//--------------------------------------
/**
* Played when the window is closed.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Effect(name="closeEffect", event="windowClose")]
/**
* Played when the component is minimized.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Effect(name="minimizeEffect", event="windowMinimize")]
/**
* Played when the component is unminimized.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Effect(name="unminimizeEffect", event="windowUnminimize")]
//--------------------------------------
// Excluded APIs
//--------------------------------------
[Exclude(name="moveEffect", kind="effect")]
//--------------------------------------
// SkinStates
//--------------------------------------
/**
* The application is enabled and inactive.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[SkinState("normalAndInactive")]
/**
* The application is disabled and inactive.
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[SkinState("disabledAndInactive")]
//--------------------------------------
// Other metadata
//--------------------------------------
/**
* The frameworks must be initialized by WindowedSystemManager.
* This factoryClass will be automatically subclassed by any
* MXML applications that don't explicitly specify a different
* factoryClass.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Frame(factoryClass="mx.managers.WindowedSystemManager")]
[IconFile("Window.png")]
[ResourceBundle("core")]
/**
* The Window is a top-level container for additional windows
* in an AIR desktop application.
*
*
The Window container is a special kind of container in the sense * that it cannot be used within other layout containers. An spark.components.Window * component must be the top-level component in its MXML document.
* *The easiest way to use a Window component to define a native window is to
* create an MXML document with an <s:Window>
tag
* as the top-level tag in the document. You use the Window component
* just as you do any other container, including specifying the layout
* type, defining child controls, and so forth. Like any other custom
* MXML component, when your application is compiled your MXML document
* is compiled into a custom class that is a subclass of the Window
* component.
In your application code, to make an instance of
* your Window subclass appear on the screen you first create an instance
* of the class in code (by defining a variable and calling the new
* MyWindowClass()
constructor. Next you set any properties you wish
* to specify for the new window. Finally you call your Window component's
* open()
method to open the window on the screen.
Note that several of the Window class's properties can only be set
* before calling the open()
method to open
* the window. Once the underlying NativeWindow is created, these initialization
* properties can be read but cannot be changed. This restriction applies to
* the following properties:
maximizable
minimizable
resizable
systemChrome
transparent
type
The <s:Window>
tag inherits all of the tag
* attributes of its superclass and adds the following tag attributes:
* <s:Window * Properties * alwaysInFront="false" * colorCorrection="default" * maximizable="true" * menu="null" * minimizable="true" * resizable="true" * showStatusBar="true" * status="" * systemChrome="standard" * title="" * titleIcon="null" * transparent="false" * type="normal" * * Styles * backgroundAlpha="1.0" * backgroundColor="0xFFFFFF" * resizeAffordanceWidth="6" * * Effects * closeEffect="No default" * minimizeEffect="No default" * unminimizeEffect="No default" * * Events * applicationActivate="No default" * applicationDeactivate="No default" * close="No default" * closing="No default" * displayStateChange="No default" * displayStateChanging="No default" * moving="No default" * networkChange="No default" * resizing="No default" * windowActivate="No default" * windowComplete="No default" * windowDeactivate="No default" * windowMove="No default" * windowResize="No default" * /> ** * @see spark.components.WindowedApplication * * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public class Window extends SkinnableContainer implements IWindow { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Class constants // //-------------------------------------------------------------------------- /** * The default height for a window (SDK-14399) * @private */ private static const DEFAULT_WINDOW_HEIGHT:Number = 100; /** * The default width for a window (SDK-14399) * @private */ private static const DEFAULT_WINDOW_WIDTH:Number = 100; //-------------------------------------------------------------------------- // // Class methods // //-------------------------------------------------------------------------- /** * @private */ private static function weakDependency():void { ActiveWindowManager }; /** * Returns the Window to which a component is parented. * * @param component The component whose Window you wish to find. * * @return An IWindow object. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public static function getWindow(component:UIComponent):IWindow { if (component.systemManager is WindowedSystemManager) return WindowedSystemManager(component.systemManager).window; return null; } //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function Window() { super(); addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler); addEventListener(FlexEvent.PREINITIALIZE, preinitializeHandler); invalidateProperties(); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private */ private var _nativeWindow:NativeWindow; /** * @private */ private var _nativeWindowVisible:Boolean = true; /** * @private */ private var maximized:Boolean = false; /** * @private */ private var _cursorManager:ICursorManager; /** * @private */ private var toMax:Boolean = false; /** * @private * Ensures that the Window has finished drawing * before it becomes visible. */ private var frameCounter:int = 0; /** * @private */ private var flagForOpen:Boolean = false; /** * @private */ private var openActive:Boolean = true; /** * @private */ private var oldX:Number; /** * @private */ private var oldY:Number; /** * @private */ private var prevX:Number; /** * @private */ private var prevY:Number; /** * @private * This flag indicates whether the width of the Application instance * can change or has been explicitly set by the developer. * When the stage is resized we use this flag to know whether the * width of the Application should be modified. */ private var resizeWidth:Boolean = true; /** * @private * This flag indicates whether the height of the Application instance * can change or has been explicitly set by the developer. * When the stage is resized we use this flag to know whether the * height of the Application should be modified. */ private var resizeHeight:Boolean = true; //-------------------------------------------------------------------------- // // Skin Parts // //-------------------------------------------------------------------------- //---------------------------------- // gripper //---------------------------------- /** * The skin part that defines the gripper button used to resize the window. * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="false")] public var gripper:Button; //---------------------------------- // statusBar //---------------------------------- /** * The skin part that defines the display of the status bar. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required = "false")] public var statusBar:IVisualElement; //---------------------------------- // statusText //---------------------------------- /** * The skin part that defines the display of the status bar's text. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="false")] public var statusText:TextBase; //---------------------------------- // titleBar //---------------------------------- /** * The skin part that defines the title bar. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ [SkinPart (required="false")] public var titleBar:TitleBar; //-------------------------------------------------------------------------- // // Overridden properties: UIComponent // //-------------------------------------------------------------------------- //---------------------------------- // height //---------------------------------- [Bindable("heightChanged")] [Inspectable(category="General")] [PercentProxy("percentHeight")] /** * @private */ override public function get height():Number { return _bounds.height; } /** * @private * Also sets the stage's height. */ override public function set height(value:Number):void { if (value < minHeight) value = minHeight; else if (value > maxHeight) value = maxHeight; _bounds.height = value; boundsChanged = true; invalidateProperties(); invalidateSize(); dispatchEvent(new Event("heightChanged")); // also dispatched in the resizeHandler } //---------------------------------- // maxHeight //---------------------------------- /** * @private * Storage for the maxHeight property. */ private var _maxHeight:Number = 2880; /** * @private * Keeps track of whether maxHeight property changed so we can * handle it in commitProperties. */ private var maxHeightChanged:Boolean = false; [Bindable("maxHeightChanged")] [Bindable("windowComplete")] /** * @private */ override public function get maxHeight():Number { if (nativeWindow && !maxHeightChanged) return nativeWindow.maxSize.y - chromeHeight(); else return _maxHeight; } /** * @private * Specifies the maximum height of the application's window. * * @default dependent on the operating system and the AIR systemChrome setting. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ override public function set maxHeight(value:Number):void { _maxHeight = value; maxHeightChanged = true; invalidateProperties(); } //---------------------------------- // maxWidth //---------------------------------- /** * @private * Storage for the maxWidth property. */ private var _maxWidth:Number = 2880; /** * @private * Keeps track of whether maxWidth property changed so we can * handle it in commitProperties. */ private var maxWidthChanged:Boolean = false; [Bindable("maxWidthChanged")] [Bindable("windowComplete")] /** * @private */ override public function get maxWidth():Number { if (nativeWindow && !maxWidthChanged) return nativeWindow.maxSize.x - chromeWidth(); else return _maxWidth; } /** * @private * Specifies the maximum width of the application's window. * * @default dependent on the operating system and the AIR systemChrome setting. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ override public function set maxWidth(value:Number):void { _maxWidth = value; maxWidthChanged = true; invalidateProperties(); } //--------------------------------- // minHeight //--------------------------------- /** * @private */ private var _minHeight:Number = 0; /** * @private * Keeps track of whether minHeight property changed so we can * handle it in commitProperties. */ private var minHeightChanged:Boolean = false; [Bindable("minHeightChanged")] [Bindable("windowComplete")] /** * @private * Specifies the minimum height of the application's window. * * @default dependent on the operating system and the AIR systemChrome setting. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ override public function get minHeight():Number { if (nativeWindow && !minHeightChanged) return nativeWindow.minSize.y - chromeHeight(); else return _minHeight; } /** * @private */ override public function set minHeight(value:Number):void { _minHeight = value; minHeightChanged = true; invalidateProperties(); } //--------------------------------- // minWidth //--------------------------------- /** * @private * Storage for the minWidth property. */ private var _minWidth:Number = 0; /** * @private * Keeps track of whether minWidth property changed so we can * handle it in commitProperties. */ private var minWidthChanged:Boolean = false; [Bindable("minWidthChanged")] [Bindable("windowComplete")] /** * @private * Specifies the minimum width of the application's window. * * @default dependent on the operating system and the AIR systemChrome setting. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ override public function get minWidth():Number { if (nativeWindow && !minWidthChanged) return nativeWindow.minSize.x - chromeWidth(); else return _minWidth; } /** * @private */ override public function set minWidth(value:Number):void { _minWidth = value; minWidthChanged = true; invalidateProperties(); } //---------------------------------- // visible //---------------------------------- [Bindable("hide")] [Bindable("show")] [Bindable("windowComplete")] /** * @private * Controls the window's visibility. Unlike the *
UIComponent.visible
property of most Flex
* visual components, this property affects the visibility
* of the underlying NativeWindow (including operating system
* chrome) as well as the visibility of the Window's child
* controls.
*
* When this property changes, Flex dispatches a show
* or hide
event.
alwaysInFront
property of the
* underlying NativeWindow. See the NativeWindow.alwaysInFront
* property description for details of how this affects window stacking
* order.
*
* @see flash.display.NativeWindow#alwaysInFront
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function get alwaysInFront():Boolean
{
if (_nativeWindow && !_nativeWindow.closed)
return nativeWindow.alwaysInFront;
else
return _alwaysInFront;
}
/**
* @private
*/
public function set alwaysInFront(value:Boolean):void
{
_alwaysInFront = value;
if (_nativeWindow && !_nativeWindow.closed)
nativeWindow.alwaysInFront = value;
}
//----------------------------------
// bounds
//----------------------------------
/**
* @private
* Storage for the bounds property.
*/
private var _bounds:Rectangle = new Rectangle(0, 0, DEFAULT_WINDOW_WIDTH, DEFAULT_WINDOW_HEIGHT);
/**
* @private
*/
private var boundsChanged:Boolean = false;
/**
* @private
* A Rectangle specifying the window's bounds
* relative to the screen.
*/
protected function get bounds():Rectangle
{
return _bounds;
}
/**
* @private
*/
protected function set bounds(value:Rectangle):void
{
_bounds = value;
boundsChanged = true;
invalidateProperties();
invalidateSize();
}
//----------------------------------
// closed
//----------------------------------
/**
* A flag indicating whether the window has been closed.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function get closed():Boolean
{
return nativeWindow.closed;
}
//----------------------------------
// colorCorrection
//----------------------------------
[Inspectable(enumeration="default,off,on", defaultValue="default" )]
/**
* The value of the stage's colorCorrection
property. If this application
* does not have access to the stage's colorCorrection
property,
* the value of the colorCorrection
property will be reported as
* null. Only the main application is allowed to set the colorCorrection
* property. If a sub-application's needs to set the color correction property it will
* need to set it via the main application's instance, either directly using an object
* instance or via an event (there is no framework event for this purpose).
*
* @default ColorCorrection.DEFAULT
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function get colorCorrection():String
{
try
{
var sm:ISystemManager = systemManager;
if (sm && sm.stage)
return sm.stage.colorCorrection;
}
catch (e:SecurityError)
{
// ignore error if this application is not allow
// to view the colorCorrection property.
}
return null;
}
/**
* @private
*/
public function set colorCorrection(value:String):void
{
// Since only the main application is allowed to change the value this property, there
// is no need to catch security violations like in the getter.
var sm:ISystemManager = systemManager;
if (sm && sm.stage && sm.isTopLevelRoot())
sm.stage.colorCorrection = value;
}
//----------------------------------
// maximizable
//----------------------------------
/**
* @private
* Storage for the maximizable property.
*/
private var _maximizable:Boolean = true;
/**
* Specifies whether the window can be maximized.
* This property's value is read-only after the window
* has been opened.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function get maximizable():Boolean
{
return _maximizable;
}
/**
* @private
*/
public function set maximizable(value:Boolean):void
{
if (!_nativeWindow)
{
_maximizable = value;
invalidateProperties();
}
}
//----------------------------------
// menu
//----------------------------------
/**
* @private
* Storage for the menu property.
*/
private var _menu:FlexNativeMenu;
//----------------------------------
// cursorManager
//----------------------------------
/**
* @private
* Returns the cursor manager for this Window.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
override public function get cursorManager():ICursorManager
{
return _cursorManager;
}
/**
* @private
*/
private var menuChanged:Boolean = false;
/**
* @private
*/
public function get menu():FlexNativeMenu
{
return _menu;
}
/**
* The window menu for this window.
* Some operating systems do not support window menus,
* in which case this property is ignored.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function set menu(value:FlexNativeMenu):void
{
if (_menu)
{
_menu.automationParent = null;
_menu.automationOwner = null;
}
_menu = value;
menuChanged = true;
if (_menu)
{
menu.automationParent = this;
menu.automationOwner = this;
}
}
//----------------------------------
// minimizable
//----------------------------------
/**
* @private
* Storage for the minimizable property.
*/
private var _minimizable:Boolean = true;
/**
* Specifies whether the window can be minimized.
* This property is read-only after the window has
* been opened.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function get minimizable():Boolean
{
return _minimizable;
}
/**
* @private
*/
public function set minimizable(value:Boolean):void
{
if (!_nativeWindow)
{
_minimizable = value;
invalidateProperties();
}
}
//----------------------------------
// nativeWindow
//----------------------------------
/**
* The underlying NativeWindow that this Window component uses.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function get nativeWindow():NativeWindow
{
if (systemManager && systemManager.stage)
return systemManager.stage.nativeWindow;
return null;
}
//----------------------------------
// renderMode
//----------------------------------
/**
* @private
* Storage for the renderMode property.
*/
private var _renderMode:String = "auto";
[Inspectable(category="General", enumeration="auto,cpu,direct")]
/**
* Specifies the render mode of the NativeWindow object.
* Constants for the valid values of this property are defined in the NativeWindowRenderMode class
* If not specified, the default value for renderMode
is NativeWindowRenderMode.AUTO.
*
* This property is read-only after the window has been opened.
* * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get renderMode():String { return _renderMode; } /** * @private */ public function set renderMode(value:String):void { if (!_nativeWindow) { _renderMode = value; invalidateProperties(); } } //---------------------------------- // resizable //---------------------------------- /** * @private * Storage for the resizable property. */ private var _resizable:Boolean = true; /** * Specifies whether the window can be resized. * This property is read-only after the window * has been opened. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get resizable():Boolean { return _resizable; } /** * @private */ public function set resizable(value:Boolean):void { if (!_nativeWindow) { _resizable = value; invalidateProperties(); } } //---------------------------------- // showStatusBar //---------------------------------- /** * Storage for the showStatusBar property. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ private var _showStatusBar:Boolean = true; /** * @private */ private var showStatusBarChanged:Boolean = true; /** * Iftrue
, the status bar is visible.
*
* The status bar only appears when you use the WindowedApplicationSkin * class or the SparkChromeWindowedApplicationSkin class as the skin for * your application or any of your application's windows.
* * @default true * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get showStatusBar():Boolean { return _showStatusBar; } /** * @private */ public function set showStatusBar(value:Boolean):void { if (_showStatusBar == value) return; _showStatusBar = value; showStatusBarChanged = true; invalidateProperties(); invalidateDisplayList(); } //---------------------------------- // status //---------------------------------- /** * @private * Storage for the status property. */ private var _status:String = ""; /** * @private */ private var statusChanged:Boolean = false; [Bindable("statusChanged")] /** * The string that appears in the status bar, if it is visible. * * @default "" * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get status():String { return _status; } /** * @private */ public function set status(value:String):void { _status = value; statusChanged = true; invalidateProperties(); invalidateSize(); dispatchEvent(new Event("statusChanged")); } //---------------------------------- // systemChrome //---------------------------------- /** * @private * Storage for the systemChrome property. */ private var _systemChrome:String = NativeWindowSystemChrome.STANDARD; [Inspectable(enumeration="none,standard", defaultValue="standard" )] /** * Specifies the type of system chrome (if any) the window has. * The set of possible values is defined by the constants * in the NativeWindowSystemChrome class. * *This property is read-only once the window has been opened.
* *The default value is NativeWindowSystemChrome.STANDARD
.
true
for a window that uses
* system chrome is not supported.
*
* This property is read-only after the window has been opened.
* * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get transparent():Boolean { return _transparent; } /** * @private */ public function set transparent(value:Boolean):void { if (!_nativeWindow) { _transparent = value; invalidateProperties(); } } //---------------------------------- // type //---------------------------------- /** * @private * Storage for the type property. */ private var _type:String = "normal"; /** * Specifies the type of NativeWindow that this component * represents. The set of possible values is defined by the constants * in the NativeWindowType class. * *This property is read-only once the window has been opened.
* *The default value is NativeWindowType.NORMAL
.
true
.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function open(openWindowActive:Boolean = true):void
{
// Event for Automation so we know when windows
// are created or destroyed.
if (FlexGlobals.topLevelApplication)
{
FlexGlobals.topLevelApplication.dispatchEvent(
new WindowExistenceEvent(WindowExistenceEvent.WINDOW_CREATING,
false, false, this));
}
flagForOpen = true;
openActive = openWindowActive;
commitProperties();
}
/**
* Orders the window just behind another. To order the window behind
* a NativeWindow that does not implement IWindow, use this window's
* nativeWindow's orderInBackOf()
method.
*
* @param window The IWindow (Window or WindowedAplication)
* to order this window behind.
*
* @return true
if the window was successfully sent behind;
* false
if the window is invisible or minimized.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function orderInBackOf(window:IWindow):Boolean
{
if (nativeWindow && !nativeWindow.closed)
return nativeWindow.orderInBackOf(window.nativeWindow);
else
return false;
}
/**
* Orders the window just in front of another. To order the window
* in front of a NativeWindow that does not implement IWindow, use this
* window's nativeWindow's orderInFrontOf()
method.
*
* @param window The IWindow (Window or WindowedAplication)
* to order this window in front of.
*
* @return true
if the window was successfully sent in front;
* false
if the window is invisible or minimized.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function orderInFrontOf(window:IWindow):Boolean
{
if (nativeWindow && !nativeWindow.closed)
return nativeWindow.orderInFrontOf(window.nativeWindow);
else
return false;
}
/**
* Orders the window behind all others in the same application.
*
* @return true
if the window was successfully sent to the back;
* false
if the window is invisible or minimized.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function orderToBack():Boolean
{
if (nativeWindow && !nativeWindow.closed)
return nativeWindow.orderToBack();
else
return false;
}
/**
* Orders the window in front of all others in the same application.
*
* @return true
if the window was successfully sent to the front;
* false
if the window is invisible or minimized.
*
* @langversion 3.0
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function orderToFront():Boolean
{
if (nativeWindow && !nativeWindow.closed)
return nativeWindow.orderToFront();
else
return false;
}
//--------------------------------------------------------------------------
//
// Skin states support
//
//--------------------------------------------------------------------------
/**
* @private
* Returns the name of the state to be applied to the skin. For example, a
* Button component could return the String "up", "down", "over", or "disabled"
* to specify the state.
*
* A subclass of SkinnableComponent must override this method to return a value.
* * @return A string specifying the name of the state to apply to the skin. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ override protected function getCurrentSkinState():String { if (nativeWindow.closed) return "disabled"; if (nativeWindow.active) return enabled ? "normal" : "disabled"; else return enabled ? "normalAndInactive" : "disabledAndInactive"; } /** * @private * Returns the width of the chrome for the window */ private function chromeWidth():Number { return nativeWindow.width - systemManager.stage.stageWidth; } /** * @private * Returns the height of the chrome for the window */ private function chromeHeight():Number { return nativeWindow.height - systemManager.stage.stageHeight; } /** * @private * Starts a system resize. */ private function startResize(start:String):void { if (resizable && !nativeWindow.closed) stage.nativeWindow.startResize(start); } //-------------------------------------------------------------------------- // // Event handlers // //-------------------------------------------------------------------------- /** * @private */ private function enterFrameHandler(e:Event):void { if (frameCounter == 2) { removeEventListener(Event.ENTER_FRAME, enterFrameHandler); _nativeWindow.visible = _nativeWindowVisible; dispatchEvent(new AIREvent(AIREvent.WINDOW_COMPLETE)); // Event for Automation so we know when windows // are created or destroyed. if (FlexGlobals.topLevelApplication) { FlexGlobals.topLevelApplication.dispatchEvent( new WindowExistenceEvent(WindowExistenceEvent.WINDOW_CREATE, false, false, this)); } if (_nativeWindow.visible) { if (openActive) _nativeWindow.activate(); } } frameCounter++; } /** * @private */ private function hideEffectEndHandler(event:Event):void { if (!_nativeWindow.closed) _nativeWindow.visible = false; removeEventListener(EffectEvent.EFFECT_END, hideEffectEndHandler); } /** * @private */ private function windowMinimizeHandler(event:Event):void { if (!nativeWindow.closed) stage.nativeWindow.minimize(); removeEventListener(EffectEvent.EFFECT_END, windowMinimizeHandler); } /** * @private */ private function windowUnminimizeHandler(event:Event):void { removeEventListener(EffectEvent.EFFECT_END, windowUnminimizeHandler); } /** * @private */ private function window_moveHandler(event:NativeWindowBoundsEvent):void { var newEvent:FlexNativeWindowBoundsEvent = new FlexNativeWindowBoundsEvent( FlexNativeWindowBoundsEvent.WINDOW_MOVE, event.bubbles, event.cancelable, event.beforeBounds, event.afterBounds); dispatchEvent(newEvent); } /** * @private */ private function window_displayStateChangeHandler( event:NativeWindowDisplayStateEvent):void { // Redispatch event . dispatchEvent(event); height = stage.stageHeight; width = stage.stageWidth; // Restored from a minimized state. if (event.beforeDisplayState == NativeWindowDisplayState.MINIMIZED) { addEventListener(EffectEvent.EFFECT_END, windowUnminimizeHandler); dispatchEvent(new Event("windowUnminimize")); } // If we have been maximized or restored then invalidate so we can // resize. if (event.afterDisplayState == NativeWindowDisplayState.MAXIMIZED || event.afterDisplayState == NativeWindowDisplayState.NORMAL) { invalidateSize(); invalidateDisplayList(); } } /** * @private */ private function window_displayStateChangingHandler( event:NativeWindowDisplayStateEvent):void { // Redispatch event for cancellation purposes. dispatchEvent(event); if (event.isDefaultPrevented()) return; if (event.afterDisplayState == NativeWindowDisplayState.MINIMIZED) { if (getStyle("minimizeEffect")) { event.preventDefault(); addEventListener(EffectEvent.EFFECT_END, windowMinimizeHandler); dispatchEvent(new Event("windowMinimize")); } } } /** * @private * Manages mouse down events on the window border. * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ protected function mouseDownHandler(event:MouseEvent):void { if (event.target == gripper) { startResize(layoutDirection == "rtl" ? NativeWindowResize.BOTTOM_LEFT : NativeWindowResize.BOTTOM_RIGHT); event.stopPropagation(); return; } if (systemManager.stage.nativeWindow.systemChrome != "none") return; var edgeOrCorner:String = hitTestResizeEdge(event); if (edgeOrCorner != NativeWindowResize.NONE) { startResize(edgeOrCorner); event.stopPropagation(); } } /** * @private * * Perform a hit test to determine if an edge or corner of the application * was clicked. * * @param event The mouse event to hit test. * * @return If an edge or corner was click return one of the constants from * the NativeWindowResize to indicate the edit or corner that was clicked. If * no edge or corner were clicked then return NativeWindowResize.NONE. */ mx_internal function hitTestResizeEdge(event:MouseEvent):String { // If we clicked on a child of the contentGroup, then don't resize if (event.target is DisplayObject && event.target != contentGroup) { var o:DisplayObject = DisplayObject(event.target); while (o && o != contentGroup && o != this) o = o.parent; if (o == null || o == contentGroup) return NativeWindowResize.NONE; } var hitTestResults:String = NativeWindowResize.NONE; var resizeAfforanceWidth:Number = getStyle("resizeAffordanceWidth"); var borderWidth:int = resizeAfforanceWidth; var cornerSize:int = resizeAfforanceWidth * 2; if (event.stageY < borderWidth) { if (event.stageX < cornerSize) hitTestResults = NativeWindowResize.TOP_LEFT; else if (event.stageX > width - cornerSize) hitTestResults = NativeWindowResize.TOP_RIGHT; else hitTestResults = NativeWindowResize.TOP; } else if (event.stageY > (height - borderWidth)) { if (event.stageX < cornerSize) hitTestResults = NativeWindowResize.BOTTOM_LEFT; else if (event.stageX > width - cornerSize) hitTestResults = NativeWindowResize.BOTTOM_RIGHT; else hitTestResults = NativeWindowResize.BOTTOM; } else if (event.stageX < borderWidth ) { if (event.stageY < cornerSize) hitTestResults = NativeWindowResize.TOP_LEFT; else if (event.stageY > height - cornerSize) hitTestResults = NativeWindowResize.BOTTOM_LEFT; else hitTestResults = NativeWindowResize.LEFT; } else if (event.stageX > width - borderWidth) { if (event.stageY < cornerSize) hitTestResults = NativeWindowResize.TOP_RIGHT; else if (event.stageY > height - cornerSize) hitTestResults = NativeWindowResize.BOTTOM_RIGHT; else hitTestResults = NativeWindowResize.RIGHT; } return hitTestResults; } /** * @private */ private function creationCompleteHandler(event:Event = null):void { systemManager.stage.nativeWindow.addEventListener( "closing", window_closingHandler); systemManager.stage.nativeWindow.addEventListener( "close", window_closeHandler, false, 0, true); systemManager.stage.nativeWindow.addEventListener( NativeWindowBoundsEvent.MOVING, window_boundsHandler); systemManager.stage.nativeWindow.addEventListener( NativeWindowBoundsEvent.MOVE, window_moveHandler); systemManager.stage.nativeWindow.addEventListener( NativeWindowBoundsEvent.RESIZING, window_boundsHandler); systemManager.stage.nativeWindow.addEventListener( NativeWindowBoundsEvent.RESIZE, window_resizeHandler); } /** * @private */ private function preinitializeHandler(event:FlexEvent):void { systemManager.stage.nativeWindow.addEventListener( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, window_displayStateChangingHandler); systemManager.stage.nativeWindow.addEventListener( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, window_displayStateChangeHandler); } /** * @private */ private function window_boundsHandler(event:NativeWindowBoundsEvent):void { var newBounds:Rectangle = event.afterBounds; var r:Rectangle; if (event.type == NativeWindowBoundsEvent.MOVING) { dispatchEvent(event); if (event.isDefaultPrevented()) return; } else //event is resizing { dispatchEvent(event); if (event.isDefaultPrevented()) return; var cancel:Boolean = false; if (newBounds.width < nativeWindow.minSize.x) { cancel = true; if (newBounds.x != event.beforeBounds.x && !isNaN(oldX)) newBounds.x = oldX; newBounds.width = nativeWindow.minSize.x; } else if (newBounds.width > nativeWindow.maxSize.x) { cancel = true; if (newBounds.x != event.beforeBounds.x && !isNaN(oldX)) newBounds.x = oldX; newBounds.width = nativeWindow.maxSize.x; } if (newBounds.height < nativeWindow.minSize.y) { cancel = true; if (event.afterBounds.y != event.beforeBounds.y && !isNaN(oldY)) newBounds.y = oldY; newBounds.height = nativeWindow.minSize.y; } else if (newBounds.height > nativeWindow.maxSize.y) { cancel = true; if (event.afterBounds.y != event.beforeBounds.y && !isNaN(oldY)) newBounds.y = oldY; newBounds.height = nativeWindow.maxSize.y; } if (cancel) { event.preventDefault(); stage.nativeWindow.bounds = newBounds; } } oldX = newBounds.x; oldY = newBounds.y; } /** * @private */ private function window_closeEffectEndHandler(event:Event):void { removeEventListener(EffectEvent.EFFECT_END, window_closeEffectEndHandler); if (!nativeWindow.closed) stage.nativeWindow.close(); } /** * @private */ private function window_closingHandler(event:Event):void { var e:Event = new Event("closing", true, true); dispatchEvent(e); if (e.isDefaultPrevented()) { event.preventDefault(); } else if (getStyle("closeEffect") && stage.nativeWindow.transparent == true) { addEventListener(EffectEvent.EFFECT_END, window_closeEffectEndHandler); dispatchEvent(new Event("windowClose")); event.preventDefault(); } } /** * @private */ private function window_closeHandler(event:Event):void { dispatchEvent(new Event("close")); // Event for Automation so we know when windows // are created or destroyed. if (FlexGlobals.topLevelApplication) { FlexGlobals.topLevelApplication.dispatchEvent( new WindowExistenceEvent(WindowExistenceEvent.WINDOW_CLOSE, false, false, this)); } } /** * @private */ private function window_resizeHandler(event:NativeWindowBoundsEvent):void { if (stage == null) return; invalidateDisplayList(); var dispatchWidthChangeEvent:Boolean = (bounds.width != stage.stageWidth); var dispatchHeightChangeEvent:Boolean = (bounds.height != stage.stageHeight); bounds.x = stage.x; bounds.y = stage.y; bounds.width = stage.stageWidth; bounds.height = stage.stageHeight; // Set _width and _height. This will update the mirroring // transform if applicable. setActualSize(_bounds.width, _bounds.height); validateNow(); var e:FlexNativeWindowBoundsEvent = new FlexNativeWindowBoundsEvent(FlexNativeWindowBoundsEvent.WINDOW_RESIZE, event.bubbles, event.cancelable, event.beforeBounds, event.afterBounds); dispatchEvent(e); if (dispatchWidthChangeEvent) dispatchEvent(new Event("widthChanged")); if (dispatchHeightChangeEvent) dispatchEvent(new Event("heightChanged")); } /** * @private */ private function nativeApplication_activateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.APPLICATION_ACTIVATE)); } /** * @private */ private function nativeApplication_deactivateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.APPLICATION_DEACTIVATE)); } /** * @private */ private function nativeWindow_activateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.WINDOW_ACTIVATE)); invalidateSkinState(); } /** * @private */ private function nativeWindow_deactivateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.WINDOW_DEACTIVATE)); invalidateSkinState(); } } }