////////////////////////////////////////////////////////////////////////////////
//
// 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.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 flash.system.Capabilities;
import mx.controls.Button;
import mx.controls.FlexNativeMenu;
import mx.core.FlexGlobals;
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.events.WindowExistenceEvent;
import mx.managers.CursorManagerImpl;
import mx.managers.FocusManager;
import mx.managers.IActiveWindowManager;
import mx.managers.ICursorManager;
import mx.managers.ISystemManager;
import mx.managers.SystemManagerGlobals;
import mx.managers.WindowedSystemManager;
import mx.managers.systemClasses.ActiveWindowManager;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
import mx.styles.StyleProxy;
use namespace mx_internal;
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when this application gets 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 gets 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 the 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 the 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 the 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 window closes.
* This event is 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 before the window moves,
* and while the window 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 underlying NativeWindow is resized, or
* while the Window 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 Window completes its initial layout
* and opens the underlying NativeWindow.
*
* @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 window 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 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.
"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.
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")]
//--------------------------------------
// Other metadata
//--------------------------------------
/**
* The frameworks must be initialized by SystemManager.
* This factoryClass will be automatically subclassed by any
* MXML applications that don't explicitly specify a different
* factoryClass.
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
[Frame(factoryClass="mx.managers.WindowedSystemManager")]
[IconFile("Window.png")]
[ResourceBundle("core")]
[Alternative(replacement="spark.components.Window", since="4.0")]
/**
* 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 mx: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 <mx: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 <mx:Window>
tag inherits all of the tag
* attributes of its superclass and adds the following tag attributes:
* <mx:Window * Properties * alwaysInFront="false" * height="100" * maxHeight="2880 less the height of the system chrome" * maximizable="true" * maxWidth="2880 less the width of the system chrome" * menu="null" * minHeight="dependent on the operating system and the AIR systemChrome setting" * minimizable="true" * minWidth="dependent on the operating system and the AIR systemChrome setting" * resizable="true" * showGripper="true" * showStatusBar="true" * showTitleBar="true" * status="" * statusBarFactory="mx.core.ClassFactory" * systemChrome="standard" * title="" * titleBarFactory="mx.core.ClassFactory" * titleIcon="null" * transparent="false" * type="normal" * visible="true" * width="100" * * 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" * moving="No default" * networkChange="No default" * resizing="No default" * windowComplete="No default" * windowMove="No default" * windowResize="No default" * /> ** * @see mx.core.WindowedApplication * * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class Window extends LayoutContainer implements IWindow { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Class constants // //-------------------------------------------------------------------------- /** * @private */ private static const HEADER_PADDING:Number = 4; /** * @private */ private static const MOUSE_SLACK:Number = 5; /** * 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 The Window to which a component is parented. * * @langversion 3.0 * @playerversion AIR 1.1 * @productversion Flex 3 */ 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.1 * @productversion Flex 3 */ 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 */ private var appViewMetrics:EdgeMetrics; /** * @private * Ensures that the Window has finished drawing * before it becomes visible. */ private var frameCounter:int = 0; /** * @private */ private var gripper:Button; /** * @private */ private var gripperHit:Sprite; /** * @private */ private var flagForOpen:Boolean = false; /** * @private */ private var openActive:Boolean = true; /** * @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 resizeHandlerAdded:Boolean = false; /** * @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; //-------------------------------------------------------------------------- // // 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(); 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.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 * 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.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;
}
//----------------------------------
// 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();
invalidateViewMetricsAndPadding();
}
//----------------------------------
// closed
//----------------------------------
/**
* A flag indicating whether the window has been closed.
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get closed():Boolean
{
return nativeWindow.closed;
}
//----------------------------------
// controlBar
//----------------------------------
/**
* The ApplicationControlBar for this Window.
*
* @see mx.containers.ApplicationControlBar
* @default null
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public var controlBar:IUIComponent;
//----------------------------------
// 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.1
* @productversion Flex 3
*/
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.1
* @productversion Flex 3
*/
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.1
* @productversion Flex 3
*/
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.1
* @productversion Flex 3
*/
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.1
* @productversion Flex 3
*/
public function get nativeWindow():NativeWindow
{
if (systemManager && systemManager.stage)
return systemManager.stage.nativeWindow;
return null;
}
//----------------------------------
// 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.1
* @productversion Flex 3
*/
public function get resizable():Boolean
{
return _resizable;
}
/**
* @private
*/
public function set resizable(value:Boolean):void
{
if (!_nativeWindow)
{
_resizable = value;
invalidateProperties();
}
}
//----------------------------------
// 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.
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
//----------------------------------
/**
* Storage for the showTitleBar property.
*
* @langversion 3.0
* @playerversion AIR 1.1
* @productversion Flex 3
*/
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
.
This property is read-only once the window has been opened.
* *The default value is NativeWindowSystemChrome.STANDARD
.
If you write a custom title bar class, it should expose
* public properties named titleIcon
* and title
.
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.1 * @productversion Flex 3 */ 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.1
* @productversion Flex 3
*/
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 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.
*/
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"));
}
}
/**
* @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
{
if (!nativeWindow.closed)
stage.nativeWindow.close();
}
/**
* @private
* Triggered by a resize event of the stage.
* Sets the new width and height.
* After the SystemManager performs its function,
* it is only necessary to notify the children of the change.
*/
private function resizeHandler(event:Event):void
{
// When user has not specified any width/height,
// application assumes the size of the stage.
// If developer has specified width/height,
// the application will not resize.
// If developer has specified percent width/height,
// application will resize to the required value
// based on the current stage width/height.
// If developer has specified min/max values,
// then application will not resize beyond those values.
var w:Number;
var h:Number
if (resizeWidth)
{
if (isNaN(percentWidth))
{
w = DisplayObject(systemManager).width;
}
else
{
super.percentWidth = Math.max(percentWidth, 0);
super.percentWidth = Math.min(percentWidth, 100);
w = percentWidth*screen.width/100;
}
if (!isNaN(explicitMaxWidth))
w = Math.min(w, explicitMaxWidth);
if (!isNaN(explicitMinWidth))
w = Math.max(w, explicitMinWidth);
}
else
{
w = width;
}
if (resizeHeight)
{
if (isNaN(percentHeight))
{
h = DisplayObject(systemManager).height;
}
else
{
super.percentHeight = Math.max(percentHeight, 0);
super.percentHeight = Math.min(percentHeight, 100);
h = percentHeight*screen.height/100;
}
if (!isNaN(explicitMaxHeight))
h = Math.min(h, explicitMaxHeight);
if (!isNaN(explicitMinHeight))
h = Math.max(h, explicitMinHeight);
}
else
{
h = height;
}
if (w != width || h != height)
{
invalidateProperties();
invalidateSize();
}
setActualSize(w, h);
invalidateDisplayList();
}
/**
* @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 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;
}
}
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
{
invalidateViewMetricsAndPadding();
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;
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));
}
/**
* @private
*/
private function nativeWindow_deactivateHandler(event:Event):void
{
dispatchEvent(new AIREvent(AIREvent.WINDOW_DEACTIVATE));
}
/**
* @private
*/
private function nativeApplication_networkChangeHandler(event:Event):void
{
dispatchEvent(event);
}
}
}