//////////////////////////////////////////////////////////////////////////////// // // 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 mx.core { import flash.desktop.DockIcon; import flash.desktop.NativeApplication; import flash.desktop.SystemTrayIcon; import flash.display.DisplayObject; import flash.display.Graphics; import flash.display.NativeWindow; import flash.display.NativeWindowDisplayState; import flash.display.NativeWindowResize; import flash.display.NativeWindowSystemChrome; import flash.display.NativeWindowType; import flash.display.Screen; import flash.display.Sprite; import flash.display.StageDisplayState; import flash.events.Event; import flash.events.FullScreenEvent; import flash.events.InvokeEvent; import flash.events.MouseEvent; import flash.events.NativeWindowBoundsEvent; import flash.events.NativeWindowDisplayStateEvent; import flash.filesystem.File; import flash.geom.Point; import flash.geom.Rectangle; import flash.system.Capabilities; import mx.controls.Alert; import mx.controls.Button; import mx.controls.FlexNativeMenu; import mx.controls.HTML; import mx.core.windowClasses.StatusBar; import mx.core.windowClasses.TitleBar; import mx.events.AIREvent; import mx.events.EffectEvent; import mx.events.FlexEvent; import mx.events.FlexNativeWindowBoundsEvent; import mx.managers.DragManager; import mx.managers.NativeDragManagerImpl; import mx.managers.SystemManagerGlobals; import mx.styles.CSSStyleDeclaration; import mx.styles.StyleManager; import mx.styles.StyleProxy; use namespace mx_internal; //-------------------------------------- // Events //-------------------------------------- /** * Dispatched when this application is activated. * * @eventType mx.events.AIREvent.APPLICATION_ACTIVATE * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="applicationActivate", type="mx.events.AIREvent")] /** * Dispatched when this application is deactivated. * * @eventType mx.events.AIREvent.APPLICATION_DEACTIVATE * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="applicationDeactivate", type="mx.events.AIREvent")] /** * Dispatched after this application window has been activated. * * @eventType mx.events.AIREvent.WINDOW_ACTIVATE * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="windowActivate", type="mx.events.AIREvent")] /** * Dispatched after this application window has been deactivated. * * @eventType mx.events.AIREvent.WINDOW_DEACTIVATE * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="windowDeactivate", type="mx.events.AIREvent")] /** * Dispatched after this application window has been closed. * * @eventType flash.events.Event.CLOSE * * @see flash.display.NativeWindow * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="close", type="flash.events.Event")] /** * Dispatched before the WindowedApplication window closes. * Cancelable. * * @eventType flash.events.Event.CLOSING * * @see flash.display.NativeWindow * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [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.1 * @productversion Flex 3 */ [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.1 * @productversion Flex 3 */ [Event(name="displayStateChanging", type="flash.events.NativeWindowDisplayStateEvent")] /** * Dispatched when an application is invoked. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="invoke", type="flash.events.InvokeEvent")] /** * Dispatched before the WindowedApplication object moves, * or while the WindowedApplication object is being dragged. * * @eventType flash.events.NativeWindowBoundsEvent.MOVING * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [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.1 * @productversion Flex 3 */ [Event(name="networkChange", type="flash.events.Event")] /** * Dispatched before the WindowedApplication object is resized, * or while the WindowedApplication object boundaries are being dragged. * * @eventType flash.events.NativeWindowBoundsEvent.RESIZING * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="resizing", type="flash.events.NativeWindowBoundsEvent")] /** * Dispatched when the WindowedApplication completes its initial layout. * By default, the WindowedApplication will be visbile at this time. * * @eventType mx.events.AIREvent.WINDOW_COMPLETE * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="windowComplete", type="mx.events.AIREvent")] /** * Dispatched after the WindowedApplication object moves. * * @eventType mx.events.FlexNativeWindowBoundsEvent.WINDOW_MOVE * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="windowMove", type="mx.events.FlexNativeWindowBoundsEvent")] /** * Dispatched after the underlying NativeWindow object is resized. * * @eventType mx.events.FlexNativeWindowBoundsEvent.WINDOW_RESIZE * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="windowResize", type="mx.events.FlexNativeWindowBoundsEvent")] //-------------------------------------- // Styles //-------------------------------------- /** * Position of buttons in title bar. Possible values: "left", * "right", "auto". * *

A value of "left" means the buttons are aligned * at the left of the title bar. * A value of "right" means the buttons are aligned * at the right of the title bar. * A value of "auto" means the buttons are aligned * at the left of the title bar on Mac OS X and on the * right on Windows.

* * @default "auto" * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="buttonAlignment", type="String", enumeration="left,right,auto", inherit="yes")] /** * Defines the distance between the titleBar buttons. * * @default 2 * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="buttonPadding", type="Number", inherit="yes")] /** * Skin for close button when using Flex chrome. * * @default mx.skins.halo.WindowCloseButtonSkin * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="closeButtonSkin", type="Class", inherit="no",states="up, over, down, disabled")] /** * The extra space around the gripper. The total area of the gripper * plus the padding around the edges is the hit area for the gripper resizing. * * @default 3 * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="gripperPadding", type="Number", format="Length", inherit="no")] /** * Style declaration for the skin of the gripper. * * @default "gripperStyle" * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="gripperStyleName", type="String", inherit="no")] /** * The explicit height of the header. If this style is not set, the header * height is calculated from the largest of the text height, the button * heights, and the icon height. * * @default undefined * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="headerHeight", type="Number", format="Length", inherit="no")] /** * Skin for maximize button when using Flex chrome. * * @default mx.skins.halo.WindowMaximizeButtonSkin * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="maximizeButtonSkin", type="Class", inherit="no",states="up, over, down, disabled")] /** * Skin for minimize button when using Flex chrome. * * @default mx.skins.halo.WindowMinimizeButtonSkin * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="minimizeButtonSkin", type="Class", inherit="no",states="up, over, down, disabled")] /** * Skin for restore button when using Flex chrome. * This style is ignored for Mac OS X. * * @default mx.skins.halo.WindowRestoreButtonSkin * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="restoreButtonSkin", type="Class", inherit="no",states="up, over, down, disabled")] /** * Determines whether the window draws its own Flex Chrome or depends on the developer * to draw chrome. Changing this style once the window is open has no effect. * * @default true * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="showFlexChrome", type="Boolean", inherit="no")] /** * The status bar background skin. * * @default mx.skins.halo.StatusBarBackgroundSkin * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="statusBarBackgroundSkin", type="Class", inherit="yes")] /** * The colors used to draw the status bar. * * @default 0xC0C0C0 * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="statusBarBackgroundColor", type="uint", format="Color", inherit="yes")] /** * Style declaration for the status text. * * @default undefined * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="statusTextStyleName", type="String", inherit="yes")] /** * Position of the title in title bar. * The possible values are "left", * "center", "auto" * *

A value of "left" means the title is aligned * at the left of the title bar. * A value of "center" means the title is aligned * at the center of the title bar. * A value of "auto" means the title is aligned * at the left on Windows and at the center on Mac OS X.

* * @default "auto" * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="titleAlignment", type="String", enumeration="left,center,auto", inherit="yes")] /** * The title background skin. * * @default mx.skins.halo.ApplicationTitleBarBackgroundSkin * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="titleBarBackgroundSkin", type="Class", inherit="yes")] /** * The distance between the furthest out title bar button and the * edge of the title bar. * * @default 5 * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="titleBarButtonPadding", type="Number", inherit="true")] /** * An array of two colors used to draw the header. * The first color is the top color. * The second color is the bottom color. * The default values are undefined, which * makes the header background the same as the * panel background. * * @default [ 0x000000, 0x000000 ] * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="titleBarColors", type="Array", arrayType="uint", format="Color", inherit="yes")] /** * The style name for the title text. * * @default undefined * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Style(name="titleTextStyleName", type="String", inherit="yes")] //-------------------------------------- // Effects //-------------------------------------- /** * Played when the window is closed. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Effect(name="closeEffect", event="windowClose")] /** * Played when the component is minimized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Effect(name="minimizeEffect", event="windowMinimize")] /** * Played when the component is unminimized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Effect(name="unminimizeEffect", event="windowUnminimize")] //-------------------------------------- // Excluded APIs //-------------------------------------- [Exclude(name="moveEffect", kind="effect")] [Exclude(name="scriptTimeLimit", kind="property")] //-------------------------------------- // Other metadata //-------------------------------------- [ResourceBundle("core")] [Alternative(replacement="spark.components.WindowedApplication", since="4.0")] /** * The WindowedApplication defines the application container * that you use to create Flex applications for AIR applications. * *

The WindowedApplication serves two roles. It is a replacement for the <mx:Application> * tag, functioning as the entry point to a Flex-based AIR application. In addition, * as a container the WindowedApplication defines the layout of the initial window * of a Flex AIR application -- any visual controls defined in the WindowedApplication * become the content of the initial window loaded by the AIR application.

* *

A WindowedApplication is the top-level application of a Flex-based AIR application. It is not * designed to be loaded by other Flex applications. If a WindowedApplication needs to load other * applications, use the Application class as container for those applications. If other windows * are required, use the Window class as a container for those windows.

* *

Note that because * the WindowedApplication only represents the visual content of a single window, and not * all the windows in a multi-window application, a WindowedApplication instance only dispatches * display-related events (events that the WindowedApplication class inherits from display object base * classes such as InteractiveObject or UIComponent) for its own stage and window, and not for * events that occur on other windows in the application. This differs from a browser-based application, * where an Application container dispatches events for all the windows in the application (because * technically those windows are all display objects rendered on the single Application stage).

* * @mxml * *

The <mx:WindowedApplication> tag inherits all of the tag * attributes of its superclass and adds the following tag attributes:

* *
 *  <mx:WindowedApplication
 *    Properties
 *    alwaysInFront="false"
 *    autoExit="true"
 *    backgroundFrameRate="-1"
 *    dockIconMenu="null"
 *    maxHeight="2880 less the height of the system chrome"
 *    maxWidth="2880 less the width of the system chrome"
 *    menu="null"
 *    minHeight="dependent on the operating system and the AIR systemChrome setting"
 *    minWidth="dependent on the operating system and the AIR systemChrome setting"
 *    showGripper="true"
 *    showStatusBar="true"
 *    showTitleBar="true"
 *    status=""
 *    statusBarFactory="mx.core.ClassFactory"
 *    systemTrayIconMenu="null"
 *    title=""
 *    titleBarFactory="mx.core.ClassFactory"
 *    titleIcon="null"
 *    useNativeDragManager="true"
 * 
 *    Styles
 *    buttonAlignment="auto"
 *    buttonPadding="2"
 *    closeButtonSkin="mx.skins.halo.windowCloseButtonSkin"
 *    gripperPadding="3"
 *    gripperStyleName="gripperStyle"
 *    headerHeight="undefined"
 *    maximizeButtonSkin="mx.skins.halo.WindowMaximizeButtonSkin"
 *    minimizeButtonSkin="mx.skins.halo.WindowMinimizeButtonSkin"
 *    restoreButtonSkin="mx.skins.halo.WindowRestoreButtonSkin"
 *    showFlexChrome="true"
 *    statusBarBackgroundColor="0xC0C0C0"
 *    statusBarBackgroundSkin="mx.skins.halo.StatusBarBackgroundSkin"
 *    statusTextStyleName="undefined"
 *    titleAlignment="auto"
 *    titleBarBackgroundSkin="mx.skins.halo.ApplicationTitleBarBackgroundSkin"
 *    titleBarButtonPadding="5"
 *    titleBarColors="[ 0x000000, 0x000000 ]"
 *    titleTextStyleName="undefined"
 * 
 *    Effects
 *    closeEffect="No default"
 *    minimizeEffect="No default"
 *    unminimizeEffect="No default"
 * 
 *    Events
 *    applicationActivate="No default"
 *    applicationDeactivate="No default"
 *    closing="No default"
 *    displayStateChange="No default"
 *    displayStateChanging="No default"
 *    invoke="No default"
 *    moving="No default"
 *    networkChange="No default"
 *    resizing="No default"
 *    windowComplete="No default"
 *    windowMove="No default"
 *    windowResize="No default"
 *  />
 *  
* * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class WindowedApplication extends Application implements IWindow { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Class constants // //-------------------------------------------------------------------------- /** * @private */ private static const HEADER_PADDING:Number = 4; /** * @private */ private static const MOUSE_SLACK:Number = 5; //-------------------------------------------------------------------------- // // Class variables // //-------------------------------------------------------------------------- /** * @private * This is here to force linkage of NativeDragManagerImpl. */ private static var _forceLinkNDMI:NativeDragManagerImpl; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function WindowedApplication() { super(); addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); addEventListener(FlexEvent.PREINITIALIZE, preinitializeHandler); addEventListener(FlexEvent.UPDATE_COMPLETE, updateComplete_handler); addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler); var nativeApplication:NativeApplication = NativeApplication.nativeApplication; nativeApplication.addEventListener(Event.ACTIVATE, nativeApplication_activateHandler); nativeApplication.addEventListener(Event.DEACTIVATE, nativeApplication_deactivateHandler); nativeApplication.addEventListener(Event.NETWORK_CHANGE, dispatchEvent); nativeApplication.addEventListener(InvokeEvent.INVOKE, nativeApplication_invokeHandler); initialInvokes = new Array(); //Force DragManager to instantiate so that it can handle drags from //outside the app. DragManager.isDragging; } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private */ private var _nativeWindow:NativeWindow; /** * @private */ private var _nativeWindowVisible:Boolean = true; /** * @private */ private var toMax:Boolean = false; /** * @private */ private var appViewMetrics:EdgeMetrics; /** * @private */ private var gripper:Button; /** * @private */ private var gripperHit:Sprite; /** * @private */ private var _gripperPadding:Number = 3; /** * @private */ private var initialInvokes:Array; /** * @private */ private var invokesPending:Boolean = true; /** * @private */ private var lastDisplayState:String = StageDisplayState.NORMAL; /** * @private */ private var shouldShowTitleBar:Boolean; /** * @private * A reference to this Application's title bar skin. * This is a child of the titleBar. */ mx_internal var titleBarBackground:IFlexDisplayObject; /** * @private * A reference to this Application's status bar skin. * This is a child of the statusBar. */ mx_internal var statusBarBackground:IFlexDisplayObject; /** * @private */ private var oldX:Number; /** * @private */ private var oldY:Number; /** * @private */ private var prevX:Number; /** * @private */ private var prevY:Number; /** * @private */ private var windowBoundsChanged:Boolean = true; /** * @private */ private var prevActiveFrameRate:Number = -1; /** * @private * Determines whether the WindowedApplication opens in an active state. * If you are opening up other windows at startup that should be active, * this will ensure that the WindowedApplication does not steal focus. * * @default true */ private var activateOnOpen:Boolean = true; /** * @private */ private var ucCount:Number = 0; //-------------------------------------------------------------------------- // // 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(); invalidateViewMetricsAndPadding(); // the heightChanged event is dispatched in commitProperties instead of // here because it can change based on user-interaction with the window // size and _height is set in there so don't want to prematurely // dispatch here yet } //---------------------------------- // 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.1 * @productversion Flex 3 */ 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.1 * @productversion Flex 3 */ 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.1 * @productversion Flex 3 */ 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.1 * @productversion Flex 3 */ 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 * Also sets the NativeWindow's visibility. */ override public function get visible():Boolean { if (nativeWindow && nativeWindow.closed) return false; if (nativeWindow) return nativeWindow.visible; else return _nativeWindowVisible; } /** * @private */ override public function set visible(value:Boolean):void { setVisible(value); } /** * @private * We override setVisible because there's the flash display object concept * of visibility and also the nativeWindow concept of visibility. */ override public function setVisible(value:Boolean, noEvent:Boolean = false):void { // first handle the native window stuff if (!_nativeWindow) { _nativeWindowVisible = value; invalidateProperties(); } else if (!_nativeWindow.closed) { if (value) { _nativeWindow.visible = value; } else { // in the conditions below we will play an effect if (getStyle("hideEffect") && initialized && $visible != value) addEventListener(EffectEvent.EFFECT_END, hideEffectEndHandler); else _nativeWindow.visible = value; } } // now call super.setVisible super.setVisible(value, noEvent); } //---------------------------------- // width //---------------------------------- [Bindable("widthChanged")] [Inspectable(category="General")] [PercentProxy("percentWidth")] /** * @private */ override public function get width():Number { return _bounds.width; } /** * @private * Also sets the stage's width. */ override public function set width(value:Number):void { if (value < minWidth) value = minWidth; else if (value > maxWidth) value = maxWidth; _bounds.width = value; boundsChanged = true; invalidateProperties(); invalidateSize(); invalidateViewMetricsAndPadding(); // the widthChanged event is dispatched in commitProperties instead of // here because it can change based on user-interaction with the window // size and _width is set in there so don't want to prematurely // dispatch here yet } //-------------------------------------------------------------------------- // // Overridden properties: Container // //-------------------------------------------------------------------------- //---------------------------------- // viewMetrics //---------------------------------- /** * @private */ override public function get viewMetrics():EdgeMetrics { var bm:EdgeMetrics = super.viewMetrics; var vm:EdgeMetrics = new EdgeMetrics(bm.left, bm.top, bm.right, bm.bottom); // Since the header covers the solid portion of the border, // we need to use the larger of borderThickness or headerHeight if (showTitleBar) { var hHeight:Number = getHeaderHeight(); if (!isNaN(hHeight)) vm.top += hHeight; } if (_showStatusBar) { var sHeight:Number = getStatusBarHeight(); if (!isNaN(sHeight)) vm.bottom += sHeight; } return vm; } //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // applicationID //---------------------------------- /** * The identifier that AIR uses to identify the application. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get applicationID():String { return nativeApplication.applicationID; } //---------------------------------- // alwaysInFront //---------------------------------- /** * @private * Storage for the alwaysInFront property. */ private var _alwaysInFront:Boolean = false; /** * Determines whether the underlying NativeWindow is always in front of other windows. * * @default false * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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; } //---------------------------------- // autoExit //---------------------------------- /** * Specifies whether the AIR application will quit when the last * window closes or will continue running in the background. * * @default true * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get autoExit():Boolean { return nativeApplication.autoExit; } /** * @private */ public function set autoExit(value:Boolean):void { nativeApplication.autoExit = value; } //---------------------------------- // backgroundFrameRate //---------------------------------- /** * @private * Storage for the backgroundFrameRate property. */ private var _backgroundFrameRate:Number = -1; /** * Specifies the frame rate to use when the application is inactive. * When set to -1, no background frame rate throttling occurs. * * @default -1 * * @langversion 3.0 * @playerversion AIR 1.5 * @productversion Flex 4 */ public function get backgroundFrameRate():Number { return _backgroundFrameRate; } /** * @private */ public function set backgroundFrameRate(frameRate:Number):void { _backgroundFrameRate = frameRate; } //---------------------------------- // bounds //---------------------------------- /** * @private * Storage for the bounds property. */ private var _bounds:Rectangle = new Rectangle(0,0,0,0); /** * @private */ private var boundsChanged:Boolean = false; /** * @private * Storage for the height and width */ protected function get bounds():Rectangle { return nativeWindow.bounds; } /** * @private */ protected function set bounds(value:Rectangle):void { nativeWindow.bounds = value; boundsChanged = true; invalidateProperties(); invalidateSize(); invalidateViewMetricsAndPadding(); } //---------------------------------- // closed //---------------------------------- /** * Returns true when the underlying window has been closed. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get closed():Boolean { return nativeWindow.closed; } //---------------------------------- // dockIconMenu //---------------------------------- /** * @private * Storage for the dockIconMenu property. */ private var _dockIconMenu:FlexNativeMenu; /** * The dock icon menu. Some operating systems do not support dock icon menus. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get dockIconMenu():FlexNativeMenu { return _dockIconMenu; } /** * @private */ public function set dockIconMenu(value:FlexNativeMenu):void { _dockIconMenu = value; if (NativeApplication.supportsDockIcon) { if (nativeApplication.icon is DockIcon) DockIcon(nativeApplication.icon).menu = value.nativeMenu; } } //---------------------------------- // maximizable //---------------------------------- /** * Specifies whether the window can be maximized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get maximizable():Boolean { if (!nativeWindow.closed) return nativeWindow.maximizable; else return false; } //---------------------------------- // minimizable //---------------------------------- /** * Specifies whether the window can be minimized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get minimizable():Boolean { if (!nativeWindow.closed) return nativeWindow.minimizable; else return false; } //---------------------------------- // menu //---------------------------------- /** * @private * Storage for the menu property. */ private var _menu:FlexNativeMenu; /** * @private */ private var menuChanged:Boolean = false; /** * The application menu for operating systems that support an application menu, * or the window menu of the application's initial window for operating * systems that support window menus. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get menu():FlexNativeMenu { return _menu; } /** * @private */ 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; } } //---------------------------------- // nativeWindow //---------------------------------- /** * The NativeWindow used by this WindowedApplication component (the initial * native window of the application). * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get nativeWindow():NativeWindow { if ((systemManager != null) && (systemManager.stage != null)) return systemManager.stage.nativeWindow; return null; } //--------------------------------- // resizable //--------------------------------- /** * Specifies whether the window can be resized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get resizable():Boolean { if (nativeWindow.closed) return false; return nativeWindow.resizable; } //---------------------------------- // nativeApplication //---------------------------------- /** * The NativeApplication object representing the AIR application. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get nativeApplication():NativeApplication { return NativeApplication.nativeApplication; } //---------------------------------- // showGripper //---------------------------------- /** * @private * Storage for the showGripper property. */ private var _showGripper:Boolean = true; /** * @private */ private var showGripperChanged:Boolean = true; /** * If true, the gripper is visible. * *

On Mac OS X a window with systemChrome * set to "standard" * always has an operating system gripper, so this property is ignored * in that case.

* * @default true * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get showGripper():Boolean { return _showGripper; } /** * @private */ public function set showGripper(value:Boolean):void { if (_showGripper == value) return; _showGripper = value; showGripperChanged = true; invalidateProperties(); invalidateDisplayList(); } //--------------------------------- // showStatusBar //---------------------------------- /** * @private * Storage for the showStatusBar property. */ private var _showStatusBar:Boolean = true; /** * @private */ private var showStatusBarChanged:Boolean = true; /** * If true, the status bar is visible. * * @default true * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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(); } //---------------------------------- // showTitleBar //---------------------------------- /** * @private * Storage for the showTitleBar property. */ private var _showTitleBar:Boolean = true; /** * @private */ private var showTitleBarChanged:Boolean = true; /** * If true, the window's title bar is visible. * * @default true * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get showTitleBar():Boolean { return _showTitleBar; } /** * @private */ public function set showTitleBar(value:Boolean):void { if (_showTitleBar == value) return; _showTitleBar = value; showTitleBarChanged = 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.1 * @productversion Flex 3 */ public function get status():String { return _status; } /** * @private */ public function set status(value:String):void { _status = value; statusChanged = true; invalidateProperties(); invalidateSize(); invalidateViewMetricsAndPadding(); dispatchEvent(new Event("statusChanged")); } //---------------------------------- // statusBar //---------------------------------- /** * @private * Storage for the statusBar property. */ private var _statusBar:UIComponent; /** * The UIComponent that displays the status bar. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get statusBar():UIComponent { return _statusBar; } //---------------------------------- // statusBarFactory //---------------------------------- /** * @private * Storage for the statusBarFactory property */ private var _statusBarFactory:IFactory = new ClassFactory(StatusBar); /** * @private */ private var statusBarFactoryChanged:Boolean = false; [Bindable("statusBarFactoryChanged")] /** * The IFactory that creates an instance to use * as the status bar. * The default value is an IFactory for StatusBar. * *

If you write a custom status bar class, it should expose * a public property named status.

* * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get statusBarFactory():IFactory { return _statusBarFactory; } /** * @private */ public function set statusBarFactory(value:IFactory):void { _statusBarFactory = value; statusBarFactoryChanged = true; invalidateProperties(); dispatchEvent(new Event("statusBarFactoryChanged")); } //---------------------------------- // statusBarStyleFilters //---------------------------------- private static var _statusBarStyleFilters:Object = { "statusBarBackgroundColor" : "statusBarBackgroundColor", "statusBarBackgroundSkin" : "statusBarBackgroundSkin", "statusTextStyleName" : "statusTextStyleName" }; /** * Set of styles to pass from the WindowedApplication to the status bar. * * @see mx.styles.StyleProxy * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get statusBarStyleFilters():Object { return _statusBarStyleFilters; } //---------------------------------- // systemChrome //---------------------------------- private var _systemChrome:String = NativeWindowSystemChrome.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. * * @see flash.display.NativeWindow#systemChrome * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get systemChrome():String { return _systemChrome; } //---------------------------------- // systemTrayIconMenu //---------------------------------- /** * @private * Storage for the systemTrayIconMenu property. */ private var _systemTrayIconMenu:FlexNativeMenu; /** * The system tray icon menu. Some operating systems do not support system tray icon menus. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get systemTrayIconMenu():FlexNativeMenu { return _systemTrayIconMenu; } /** * @private */ public function set systemTrayIconMenu(value:FlexNativeMenu):void { _systemTrayIconMenu = value; if (NativeApplication.supportsSystemTrayIcon) { if (nativeApplication.icon is SystemTrayIcon) SystemTrayIcon(nativeApplication.icon).menu = value.nativeMenu; } } //---------------------------------- // title //---------------------------------- /** * @private * Storage for the title property. */ private var _title:String = ""; /** * @private */ private var titleChanged:Boolean = false; [Bindable("titleChanged")] /** * The title that appears in the window title bar and * the taskbar. * * If you are using system chrome and you set this property to something * different than the <title> tag in your application.xml, * you may see the title from the XML file appear briefly first. * * @default "" * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get title():String { return _title; } /** * @private */ public function set title(value:String):void { _title = value; titleChanged = true; invalidateProperties(); invalidateSize(); invalidateViewMetricsAndPadding(); invalidateDisplayList(); dispatchEvent(new Event("titleChanged")); } //---------------------------------- // titleBar //---------------------------------- /** * @private * Storage for the titleBar property. */ private var _titleBar:UIComponent; /** * The UIComponent that displays the title bar. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get titleBar():UIComponent { return _titleBar; } //---------------------------------- // titleBarFactory //---------------------------------- /** * @private * Storage for the titleBarFactory property */ private var _titleBarFactory:IFactory = new ClassFactory(TitleBar); /** * @private */ private var titleBarFactoryChanged:Boolean = false; [Bindable("titleBarFactoryChanged")] /** * The IFactory that creates an instance to use * as the title bar. * The default value is an IFactory for TitleBar. * *

If you write a custom title bar class, it should expose * public properties named titleIcon * and title.

* * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get titleBarFactory():IFactory { return _titleBarFactory; } /** * @private */ public function set titleBarFactory(value:IFactory):void { _titleBarFactory = value; titleBarFactoryChanged = true; invalidateProperties(); dispatchEvent(new Event("titleBarFactoryChanged")); } //---------------------------------- // titleBarStyleFilters //---------------------------------- private static var _titleBarStyleFilters:Object = { "buttonAlignment" : "buttonAlignment", "buttonPadding" : "buttonPadding", "closeButtonSkin" : "closeButtonSkin", "cornerRadius" : "cornerRadius", "headerHeight" : "headerHeight", "maximizeButtonSkin" : "maximizeButtonSkin", "minimizeButtonSkin" : "minimizeButtonSkin", "restoreButtonSkin" : "restoreButtonSkin", "titleAlignment" : "titleAlignment", "titleBarBackgroundSkin" : "titleBarBackgroundSkin", "titleBarButtonPadding" : "titleBarButtonPadding", "titleBarColors" : "titleBarColors", "titleTextStyleName" : "titleTextStyleName" }; /** * Set of styles to pass from the WindowedApplication to the titleBar. * @see mx.styles.StyleProxy * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ protected function get titleBarStyleFilters():Object { return _titleBarStyleFilters; } //---------------------------------- // titleIcon //---------------------------------- /** * @private * A reference to this container's title icon. */ private var _titleIcon:Class; /** * @private */ private var titleIconChanged:Boolean = false; [Bindable("titleIconChanged")] /** * The Class (usually an image) used to draw the title bar icon. * * @default null * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get titleIcon():Class { return _titleIcon; } /** * @private */ public function set titleIcon(value:Class):void { _titleIcon = value; titleIconChanged = true; invalidateProperties(); invalidateSize(); invalidateViewMetricsAndPadding(); invalidateDisplayList(); dispatchEvent(new Event("titleIconChanged")); } //---------------------------------- // transparent //---------------------------------- /** * Specifies whether the window is transparent. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get transparent():Boolean { if (nativeWindow.closed) return false; return nativeWindow.transparent; } //---------------------------------- // type //---------------------------------- /** * Specifies the type of NativeWindow that this component * represents. The set of possible values is defined by the constants * in the NativeWindowType class. * * @see flash.display.NativeWindowType * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get type():String { return NativeWindowType.NORMAL; } //---------------------------------- // useNativeDragManager //---------------------------------- [Inspectable(defaultValue="true")] /** * If true, the DragManager should use the NativeDragManagerImpl implementation class. * If false, then the DragManagerImpl class will be used. * *

Note: This property cannot be set by ActionScript code; it must be set in MXML code. * That means you cannot change its value at run time.

* *

By default, the DragManager for AIR applications built in Flex uses the * NativeDragManagerImpl class as the implementation class. * Flash Player applications build in Flex use the DragManagerImpl class.

* *

The NativeDragManagerImpl class is a bridge between the AIR NativeDragManager API * and the Flex DragManager API. * The AIR NativeDragManager class uses the operating system's drag and drop APIs. * It supports dragging between AIR windows and between the operating system and AIR. * Because the operating system controls the drag-and-drop operation, * it is not possible to customize the cursors during a drag. * Also, you have no control over the drop animation. * The behavior is dependent upon the operating system and has some inconsistencies across different platforms.

* *

The DragManagerImpl class does not use the operating system for drag-and-drop. * Instead, it controls the entire drag-and-drop process. * It supports customizing the cursors and provides a drop animation. * However, it does not allow dragging between AIR windows and between the operating system or AIR window.

* * @default true * * @langversion 3.0 * @playerversion Flash 10 * @playerversion AIR 1.5 * @productversion Flex 4 */ /* This property is not directly read by the systemManager. It is here so that it gets * picked up by the compiler and included in the info() structure * for the generated system manager. */ public var useNativeDragManager:Boolean = true; //-------------------------------------------------------------------------- // // Overridden methods: UIComponent // //-------------------------------------------------------------------------- /** * @private */ override protected function createChildren():void { super.createChildren(); if (getStyle("showFlexChrome") == false || getStyle("showFlexChrome") == "false") { setStyle("borderStyle", "none"); setStyle("backgroundAlpha", 0); return; } if (!_statusBar) { _statusBar = statusBarFactory.newInstance(); _statusBar.styleName = new StyleProxy(this, statusBarStyleFilters); rawChildren.addChild(DisplayObject(_statusBar)); showStatusBarChanged = true; statusBarFactoryChanged = false; } if (systemManager.stage.nativeWindow.systemChrome != "none") { setStyle("borderStyle", "none"); return; } if (!_titleBar) { _titleBar = titleBarFactory.newInstance(); _titleBar.styleName = new StyleProxy(this, titleBarStyleFilters); rawChildren.addChild(DisplayObject(titleBar)); showTitleBarChanged = true; titleBarFactoryChanged = false; } if (!gripper) { gripper = new Button(); var gripSkin:String = getStyle("gripperStyleName"); if (gripSkin) { var tmp:CSSStyleDeclaration = styleManager.getStyleDeclaration("." + gripSkin); gripper.styleName = gripSkin; } gripper.skinLayoutDirection = undefined; rawChildren.addChild(gripper); gripperHit = new Sprite(); gripperHit.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); rawChildren.addChild(gripperHit); } } /** * @private */ override protected function commitProperties():void { super.commitProperties(); // AIR won't allow you to set the min width greater than the current // max width (same is true for height). You also can't set the max // width less than the current min width (same is true for height). // This makes the updating of the new minSize and maxSize a bit tricky. if (minWidthChanged || minHeightChanged || maxWidthChanged || maxHeightChanged) { var minSize:Point = nativeWindow.minSize; var maxSize:Point = nativeWindow.maxSize; var newMinWidth:Number = minWidthChanged ? _minWidth + chromeWidth() : minSize.x; var newMinHeight:Number = minHeightChanged ? _minHeight + chromeHeight() : minSize.y; var newMaxWidth:Number = maxWidthChanged ? _maxWidth + chromeWidth() : maxSize.x; var newMaxHeight:Number = maxHeightChanged ? _maxHeight + chromeHeight() : maxSize.y; if (minWidthChanged || minHeightChanged) { // If the new min size is greater than the old max size, then // we need to set the new max size now. if ((maxWidthChanged && newMinWidth > minSize.x) || (maxHeightChanged && newMinHeight > minSize.y)) { nativeWindow.maxSize = new Point(newMaxWidth, newMaxHeight); } nativeWindow.minSize = new Point(newMinWidth, newMinHeight); } // Set the max width or height if it is not already set. The max // width and height could have been set above when setting minSize // but the max size would have been rejected by AIR if it were less // than the old min size. if (newMaxWidth != maxSize.x || newMaxHeight != maxSize.y) nativeWindow.maxSize = new Point(newMaxWidth, newMaxHeight); } // minimum width and height if (minWidthChanged || minHeightChanged) { if (minWidthChanged) { minWidthChanged = false; if (width < minWidth) width = minWidth; dispatchEvent(new Event("minWidthChanged")); } if (minHeightChanged) { minHeightChanged = false; if (height < minHeight) height = minHeight; dispatchEvent(new Event("minHeightChanged")); } } // maximum width and height if (maxWidthChanged || maxHeightChanged) { windowBoundsChanged = true; if (maxWidthChanged) { maxWidthChanged = false; if (width > maxWidth) width = maxWidth; dispatchEvent(new Event("maxWidthChanged")); } if (maxHeightChanged) { maxHeightChanged = false; if (height > maxHeight) height = maxHeight; dispatchEvent(new Event("maxHeightChanged")); } } if (boundsChanged) { // Work around an AIR issue setting the stageHeight to zero when // using system chrome. The set of the stage.stageHeight property // is rejected unless the nativeWindow is first set to the proper height. // Don't perform this workaround if the window has zero height due // to being minimized. Setting the nativeWindow height to non-zero // causes AIR to restore the window. if (_bounds.height == 0 && nativeWindow.displayState != NativeWindowDisplayState.MINIMIZED && systemChrome == NativeWindowSystemChrome.STANDARD) nativeWindow.height = chromeHeight() + _bounds.height; systemManager.stage.stageWidth = _bounds.width; systemManager.stage.stageHeight = _bounds.height; // Set _width and _height. This will update the mirroring // transform if applicable. setActualSize(_bounds.width, _bounds.height); boundsChanged = false; } if (windowBoundsChanged) { _bounds.width = systemManager.stage.stageWidth; _bounds.height = systemManager.stage.stageHeight; // Set _width and _height. This will update the mirroring // transform if applicable. setActualSize(_bounds.width, _bounds.height); windowBoundsChanged = false; } if (menuChanged && !nativeWindow.closed) { menuChanged = false; if (menu == null) { if (NativeApplication.supportsMenu) nativeApplication.menu = null; else if (NativeWindow.supportsMenu) nativeWindow.menu = null; } else if (menu.nativeMenu) { if (NativeApplication.supportsMenu) nativeApplication.menu = menu.nativeMenu; else if (NativeWindow.supportsMenu) nativeWindow.menu = menu.nativeMenu; } dispatchEvent(new Event("menuChanged")); } if (titleBarFactoryChanged) { if (_titleBar) { // Remove old titleBar. rawChildren.removeChild(DisplayObject(titleBar)); _titleBar = null; } _titleBar = titleBarFactory.newInstance(); _titleBar.styleName = new StyleProxy(this, titleBarStyleFilters); rawChildren.addChild(DisplayObject(titleBar)); titleBarFactoryChanged = false; invalidateDisplayList(); } if (showTitleBarChanged) { if (titleBar) titleBar.visible = _showTitleBar; showTitleBarChanged = false; } if (titleIconChanged) { if (_titleBar && "titleIcon" in _titleBar) _titleBar["titleIcon"] = _titleIcon; titleIconChanged = false; } if (titleChanged) { if (!nativeWindow.closed) systemManager.stage.nativeWindow.title = _title; if (_titleBar && "title" in _titleBar) _titleBar["title"] = _title; titleChanged = false; } if (statusBarFactoryChanged) { if (_statusBar) { // Remove old statusBar. rawChildren.removeChild(DisplayObject(_statusBar)); _statusBar = null } _statusBar = statusBarFactory.newInstance(); _statusBar.styleName = new StyleProxy(this, statusBarStyleFilters); // Add it underneath the gripper. rawChildren.addChild(DisplayObject(_statusBar)); if (gripper) { var gripperIndex:int = rawChildren.getChildIndex(DisplayObject(gripper)); rawChildren.setChildIndex(DisplayObject(_statusBar), gripperIndex); } statusBarFactoryChanged = false; showStatusBarChanged = true; statusChanged = true; invalidateDisplayList(); } if (showStatusBarChanged) { if (_statusBar) _statusBar.visible = _showStatusBar; showStatusBarChanged = false; } if (statusChanged) { if (_statusBar && "status" in _statusBar) _statusBar["status"] = _status; statusChanged = false; } if (showGripperChanged) { if (gripper) { gripper.visible = _showGripper; gripperHit.visible = _showGripper; } showGripperChanged = false; } if (toMax) { toMax = false; if (!nativeWindow.closed) nativeWindow.maximize(); } } /** * @private */ override public function initialize():void { // initialize _nativeWindow as soon as possible and // get the value of systemChrome. _nativeWindow = systemManager.stage.nativeWindow; _systemChrome = _nativeWindow.systemChrome; super.initialize(); } /** * @private */ override public function validateDisplayList():void { super.validateDisplayList(); if (!nativeWindow.closed) { if (Capabilities.os.substring(0, 3) == "Mac" && systemChrome == "standard") { //need to move the scroll bars to not overlap the systemChrome gripper //if both scrollbars are already visible, this has been done for us if ((horizontalScrollBar || verticalScrollBar) && !(horizontalScrollBar && verticalScrollBar) && !showStatusBar) { if (!whiteBox) { whiteBox = new FlexShape(); whiteBox.name = "whiteBox"; var g:Graphics = whiteBox.graphics; g.beginFill(0xFFFFFF); g.drawRect(0, 0, verticalScrollBar ? verticalScrollBar.minWidth : 15, horizontalScrollBar ? horizontalScrollBar.minHeight : 15); g.endFill() rawChildren.addChild(whiteBox); } whiteBox.visible = true; if (horizontalScrollBar) { horizontalScrollBar.setActualSize( horizontalScrollBar.width - whiteBox.width, horizontalScrollBar.height); } if (verticalScrollBar) { verticalScrollBar.setActualSize( verticalScrollBar.width, verticalScrollBar.height - whiteBox.height); } whiteBox.x = systemManager.stage.stageWidth - whiteBox.width; whiteBox.y = systemManager.stage.stageHeight - whiteBox.height; } else if (!(horizontalScrollBar && verticalScrollBar)) { if (whiteBox) { rawChildren.removeChild(whiteBox); whiteBox = null; } } } else if (gripper && showGripper && !showStatusBar) { //see if there are both scrollbars if (whiteBox) { whiteBox.visible = false; //if gripper + padding > whiteBox size, we need to move scrollbars //this is, um, generally non-optimal looking if (gripperHit.height > whiteBox.height) verticalScrollBar.setActualSize(verticalScrollBar.width, verticalScrollBar.height - (gripperHit.height - whiteBox.height)); if (gripperHit.width > whiteBox.width) horizontalScrollBar.setActualSize( horizontalScrollBar.width - (gripperHit.width - whiteBox.height), horizontalScrollBar.height); } else if (horizontalScrollBar) { horizontalScrollBar.setActualSize( horizontalScrollBar.width - gripperHit.width, horizontalScrollBar.height); } else if (verticalScrollBar) { verticalScrollBar.setActualSize( verticalScrollBar.width, verticalScrollBar.height - gripperHit.height); } } else if (whiteBox)//if there's no gripper, we need to show the white box, if appropriate whiteBox.visible = true; } } /** * @private */ override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { if (!nativeWindow.closed) { super.updateDisplayList(unscaledWidth, unscaledHeight); var bm:EdgeMetrics = borderMetrics; var leftOffset:Number = 10; var rightOffset:Number = 10; if (_statusBar) { _statusBar.move(bm.left, unscaledHeight - bm.bottom - getStatusBarHeight()); _statusBar.setActualSize(unscaledWidth - bm.left - bm.right, getStatusBarHeight()); } if (systemManager.stage.nativeWindow.systemChrome != "none" || systemManager.stage.nativeWindow.closed) return; var buttonAlign:String = String(getStyle("buttonAlignment")); if (titleBar) { titleBar.move(bm.left, bm.top); titleBar.setActualSize(unscaledWidth - bm.left - bm.right, getHeaderHeight()); } if (titleBar && controlBar) controlBar.move(0, titleBar.height); if (gripper && showGripper) { _gripperPadding = getStyle("gripperPadding"); gripper.setActualSize(gripper.measuredWidth, gripper.measuredHeight); gripperHit.graphics.beginFill(0xffffff, .0001); gripperHit.graphics.drawRect(0, 0, gripper.width + (2 * _gripperPadding), gripper.height + (2 * _gripperPadding)); gripper.move(unscaledWidth - gripper.measuredWidth - _gripperPadding, unscaledHeight - gripper.measuredHeight - _gripperPadding); gripperHit.x = gripper.x - _gripperPadding; gripperHit.y = gripper.y - _gripperPadding; } } } /** * @private */ override public function styleChanged(styleProp:String):void { super.styleChanged(styleProp); if (!nativeWindow.closed) { if (!(getStyle("showFlexChrome") == "false" || getStyle("showFlexChrome") == false)) { if (styleProp == null || styleProp == "headerHeight" || styleProp == "gripperPadding") { invalidateViewMetricsAndPadding(); invalidateDisplayList(); invalidateSize(); } } } } /** * @private */ override public function move(x:Number, y:Number):void { if (nativeWindow && !nativeWindow.closed) { var tmp:Rectangle = nativeWindow.bounds; tmp.x = x; tmp.y = y; nativeWindow.bounds = tmp; } } /** * @private * Called when the "View Source" item in the application's context menu * is selected. * * Opens the window where AIR decides, sized to the parent application. * It will close when the parent WindowedApplication closes. */ override protected function menuItemSelectHandler(event:Event):void { const vsLoc:File = File.applicationDirectory.resolvePath(viewSourceURL); if (vsLoc.exists) { const screenRect:Rectangle = flash.display.Screen.mainScreen.visibleBounds; const screenWidth:int = screenRect.width; const screenHeight:int = screenRect.height; // roughly golden-ratio based on 90% of the smaller screen dimension // should be pleasing to the eye... const minDim:Number = Math.min(screenWidth, screenHeight); const winWidth:int = minDim * 0.9; const winHeight:int = winWidth * 0.618; const winX:int = (screenWidth - winWidth) / 2; const winY:int = (screenHeight - winHeight) / 2; const html:HTML = new HTML(); { html.width = winWidth; html.height = winHeight; html.location = vsLoc.url; } const win:Window = new Window(); { win.type = NativeWindowType.UTILITY; win.systemChrome = NativeWindowSystemChrome.STANDARD; win.title = resourceManager.getString("core", "viewSource"); win.width = winWidth; win.height = winHeight; win.addChild(html); // handle resizing since the HTML should take the whole stage win.addEventListener( FlexNativeWindowBoundsEvent.WINDOW_RESIZE, viewSourceResizeHandler(html), false, 0, true); // links should open in the system web browser (e.g. the .zip links) html.htmlLoader.navigateInSystemBrowser = true; // close the View Source window when this WindowedApp closes addEventListener(Event.CLOSING, viewSourceCloseHandler(win), false, 0, true); } // make it so win.open(); win.move(winX, winY); } else { Alert.show(resourceManager.getString("core", "badFile")); } } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * Activates the underlying NativeWindow (even if this application is not the active one). * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function activate():void { if (!systemManager.stage.nativeWindow.closed) { systemManager.stage.nativeWindow.activate(); // activate makes the native window visible so this // component should become visible as well. visible = true; } } /** * Closes the application's NativeWindow (the initial native window opened by the application). This action is cancelable. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function close():void { if (!nativeWindow.closed) { var e:Event = new Event("closing", true, true); stage.nativeWindow.dispatchEvent(e); if (!e.isDefaultPrevented()) stage.nativeWindow.close(); } } /** * Closes the window and exits the application. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function exit():void { nativeApplication.exit(); } /** * @private * Returns the height of the header. */ private function getHeaderHeight():Number { if (!nativeWindow.closed) { if (getStyle("headerHeight") != null) return getStyle("headerHeight"); if (systemManager.stage.nativeWindow.systemChrome != "none") return 0; if (titleBar) return(titleBar.getExplicitOrMeasuredHeight()); } return 0; } /** * @private * Returns the height of the statusBar. */ public function getStatusBarHeight():Number { if (_statusBar) return _statusBar.getExplicitOrMeasuredHeight(); return 0; } /** * Maximizes the window, or does nothing if it's already maximized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function maximize():void { if (!nativeWindow || !nativeWindow.maximizable || nativeWindow.closed) return; if (systemManager.stage.nativeWindow.displayState!= NativeWindowDisplayState.MAXIMIZED) { var f:NativeWindowDisplayStateEvent = new NativeWindowDisplayStateEvent( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, false, true, systemManager.stage.nativeWindow.displayState, NativeWindowDisplayState.MAXIMIZED); systemManager.stage.nativeWindow.dispatchEvent(f); if (!f.isDefaultPrevented()) { invalidateProperties(); invalidateSize(); invalidateDisplayList(); toMax = true; } } } /** * Minimizes the window. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function minimize():void { if (!minimizable) return; if (!nativeWindow.closed) { var e:NativeWindowDisplayStateEvent = new NativeWindowDisplayStateEvent( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, false, true, nativeWindow.displayState, NativeWindowDisplayState.MINIMIZED) stage.nativeWindow.dispatchEvent(e); if (!e.isDefaultPrevented()) stage.nativeWindow.minimize(); } } /** * Restores the window (unmaximizes it if it's maximized, or * unminimizes it if it's minimized). * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function restore():void { if (!nativeWindow.closed) { var e:NativeWindowDisplayStateEvent; if (stage.nativeWindow.displayState == NativeWindowDisplayState.MAXIMIZED) { e = new NativeWindowDisplayStateEvent( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, false, true, NativeWindowDisplayState.MAXIMIZED, NativeWindowDisplayState.NORMAL); stage.nativeWindow.dispatchEvent(e); if (!e.isDefaultPrevented()) nativeWindow.restore(); } else if (stage.nativeWindow.displayState == NativeWindowDisplayState.MINIMIZED) { e = new NativeWindowDisplayStateEvent( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, false, true, NativeWindowDisplayState.MINIMIZED, NativeWindowDisplayState.NORMAL); stage.nativeWindow.dispatchEvent(e); if (!e.isDefaultPrevented()) nativeWindow.restore(); } } } /** * 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 succesfully sent behind; * false if the window is invisible or minimized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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 succesfully sent in front; * false if the window is invisible or minimized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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 succesfully sent to the back; * false if the window is invisible or minimized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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 succesfully sent to the front; * false if the window is invisible or minimized. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function orderToFront():Boolean { if (nativeWindow && !nativeWindow.closed) return nativeWindow.orderToFront(); else return false; } /** * @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 move. */ private function startMove(event:MouseEvent):void { addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); prevX = event.stageX; prevY = event.stageY; } /** * @private * Starts a system resize. */ protected function startResize(start:String):void { if (!nativeWindow.closed) if (nativeWindow.resizable) stage.nativeWindow.startResize(start); } //-------------------------------------------------------------------------- // // Event handlers // //-------------------------------------------------------------------------- /** * @private */ private function creationCompleteHandler(event:Event):void { addEventListener(Event.ENTER_FRAME, enterFrameHandler); } /** * @private */ private function enterFrameHandler(e:Event):void { if (!stage) return; removeEventListener(Event.ENTER_FRAME, enterFrameHandler); // If nativeApplication.nativeApplication.exit() has been called, // the window will already be closed. if (stage.nativeWindow.closed) return; //window properties that have been stored till window exists //now get applied to window stage.nativeWindow.visible = _nativeWindowVisible; dispatchEvent(new AIREvent(AIREvent.WINDOW_COMPLETE)); // Now let any invoke events received from nativeApplication // during initialization, flow to our listeners. dispatchPendingInvokes(); if (_nativeWindowVisible && activateOnOpen) stage.nativeWindow.activate(); stage.nativeWindow.alwaysInFront = _alwaysInFront; } /** * @private */ private function dispatchPendingInvokes():void { invokesPending = false; for each (var event:InvokeEvent in initialInvokes) dispatchEvent(event); initialInvokes = null; } /** * @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 { dispatchEvent(new FlexNativeWindowBoundsEvent(FlexNativeWindowBoundsEvent.WINDOW_MOVE, event.bubbles, event.cancelable, event.beforeBounds, event.afterBounds)); } /** * @private */ private function window_displayStateChangeHandler( event:NativeWindowDisplayStateEvent):void { // Redispatch event. dispatchEvent(event); height = systemManager.stage.stageHeight; width = systemManager.stage.stageWidth; // Restored from a minimized state. if (event.beforeDisplayState == NativeWindowDisplayState.MINIMIZED) { addEventListener(EffectEvent.EFFECT_END, windowUnminimizeHandler); dispatchEvent(new Event("windowUnminimize")); } } /** * @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.1 * @productversion Flex 3 */ protected function mouseDownHandler(event:MouseEvent):void { if (systemManager.stage.nativeWindow.systemChrome != "none") return; if (event.target == gripperHit) { startResize(layoutDirection == "rtl" ? NativeWindowResize.BOTTOM_LEFT : NativeWindowResize.BOTTOM_RIGHT); event.stopPropagation(); } else { var dragWidth:int = Number(getStyle("borderThickness")) + 6; var cornerSize:int = 12; // we short the top a little if (event.stageY < Number(getStyle("borderThickness"))) { if (event.stageX < cornerSize) startResize(NativeWindowResize.TOP_LEFT); else if (event.stageX > width - cornerSize) startResize(NativeWindowResize.TOP_RIGHT); else startResize(NativeWindowResize.TOP); } else if (event.stageY > (height - dragWidth)) { if (event.stageX < cornerSize) startResize(NativeWindowResize.BOTTOM_LEFT); else if (event.stageX > width - cornerSize) startResize(NativeWindowResize.BOTTOM_RIGHT); else startResize(NativeWindowResize.BOTTOM); } else if (event.stageX < dragWidth ) { if (event.stageY < cornerSize) startResize(NativeWindowResize.TOP_LEFT); else if (event.stageY > height - cornerSize) startResize(NativeWindowResize.BOTTOM_LEFT); else startResize(NativeWindowResize.LEFT); event.stopPropagation(); } else if (event.stageX > width - dragWidth) { if (event.stageY < cornerSize) startResize(NativeWindowResize.TOP_RIGHT); else if (event.stageY > height - cornerSize) startResize(NativeWindowResize.BOTTOM_RIGHT); else startResize(NativeWindowResize.RIGHT); } } } /** * @private */ private function closeButton_clickHandler(event:Event):void { stage.nativeWindow.close(); } /** * @private */ private function preinitializeHandler(event:Event = null):void { systemManager.stage.nativeWindow.addEventListener( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, window_displayStateChangingHandler); systemManager.stage.nativeWindow.addEventListener( NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, window_displayStateChangeHandler) systemManager.stage.nativeWindow.addEventListener( "closing", window_closingHandler); systemManager.stage.nativeWindow.addEventListener( "close", window_closeHandler, false, 0, true); // For the edge case, e.g. visible is set to true in // AIR xml file, we fabricate an activate event, since Flex // comes in late to the show. if (systemManager.stage.nativeWindow.active) dispatchEvent(new AIREvent(AIREvent.WINDOW_ACTIVATE)); systemManager.stage.nativeWindow.addEventListener( "activate", nativeWindow_activateHandler, false, 0, true); systemManager.stage.nativeWindow.addEventListener( "deactivate", nativeWindow_deactivateHandler, 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); systemManager.stage.addEventListener( FullScreenEvent.FULL_SCREEN, stage_fullScreenHandler); } /** * @private */ private function mouseMoveHandler(event:MouseEvent):void { stage.nativeWindow.x += event.stageX - prevX; stage.nativeWindow.y += event.stageY - prevY; } /** * @private */ private function mouseUpHandler(event:MouseEvent):void { removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); } /** * @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; windowBoundsChanged = true; invalidateProperties(); } } oldX = newBounds.x; oldY = newBounds.y; } /** * @private */ private function stage_fullScreenHandler(event:FullScreenEvent):void { //work around double events if (stage.displayState != lastDisplayState) { lastDisplayState = stage.displayState; if (stage.displayState == StageDisplayState.FULL_SCREEN || stage.displayState == StageDisplayState.FULL_SCREEN_INTERACTIVE) { shouldShowTitleBar = showTitleBar; showTitleBar = false; } else showTitleBar = shouldShowTitleBar; } } /** * @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")); } /** * @private */ private function window_resizeHandler(event:NativeWindowBoundsEvent):void { // Only validateNow if we don't already have a window bounds // update pending. Otherwise, we'll miss a chance to layout with // the modified bounds. ** We really should revisit why we call // validateNow here to begin with **. if (!windowBoundsChanged) { windowBoundsChanged= true; invalidateProperties(); invalidateViewMetricsAndPadding(); invalidateDisplayList(); validateNow(); } var e:FlexNativeWindowBoundsEvent = new FlexNativeWindowBoundsEvent(FlexNativeWindowBoundsEvent.WINDOW_RESIZE, event.bubbles, event.cancelable, event.beforeBounds, event.afterBounds); dispatchEvent(e); } /** * @private */ private function nativeApplication_activateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.APPLICATION_ACTIVATE)); // Only the initial WindowedApplication instance manages background framerate. var isPrimaryApplication:Boolean = SystemManagerGlobals.topLevelSystemManagers[0] == systemManager; // Restore throttled framerate if appropriate when application is activated. if (prevActiveFrameRate >= 0 && stage && isPrimaryApplication) { stage.frameRate = prevActiveFrameRate; prevActiveFrameRate = -1; } } /** * @private */ private function nativeApplication_deactivateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.APPLICATION_DEACTIVATE)); // Only the initial WindowedApplication instance manages background framerate. var isPrimaryApplication:Boolean = SystemManagerGlobals.topLevelSystemManagers[0] == systemManager; // Throttle framerate if appropriate when application is deactivated. // Ensure we've received an updateComplete on the chance our layout // manager is using phased instantiation (we don't wish to store a // maxed out (1000fps) framerate). if ((_backgroundFrameRate >= 0) && (ucCount > 0) && stage && isPrimaryApplication) { prevActiveFrameRate = stage.frameRate; stage.frameRate = _backgroundFrameRate; } } /** * @private */ private function nativeApplication_invokeHandler(event:InvokeEvent):void { // Because of the behavior with the nativeApplication invoke event // we queue events up until windowComplete if (invokesPending) initialInvokes.push(event); else dispatchEvent(event); } /** * @private */ private function nativeWindow_activateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.WINDOW_ACTIVATE)); } /** * @private */ private function nativeWindow_deactivateHandler(event:Event):void { dispatchEvent(new AIREvent(AIREvent.WINDOW_DEACTIVATE)); } /** * This is a temporary event handler which dispatches a initialLayoutComplete event after * two updateCompletes. This event will only be dispatched after either setting the bounds or * maximizing the window at startup. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ private function updateComplete_handler(event:FlexEvent):void { if (ucCount == 1) { dispatchEvent(new Event("initialLayoutComplete")); removeEventListener(FlexEvent.UPDATE_COMPLETE, updateComplete_handler); } else { ucCount++; } } /** * @private * Returns a Function handler that resizes the view source HTML component with the stage. */ private function viewSourceResizeHandler(html:HTML):Function { return function (e:FlexNativeWindowBoundsEvent):void { const win:DisplayObject = e.target; html.width = win.width; html.height = win.height; }; } /** * @private * Returns a Function handler that closes the View Source window when the parent closes. */ private function viewSourceCloseHandler(win:Window):Function { return function ():void { win.close(); }; } } }