| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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.managers |
| { |
| |
| import flash.display.DisplayObject; |
| import flash.display.DisplayObjectContainer; |
| import flash.display.Graphics; |
| import flash.display.InteractiveObject; |
| import flash.display.Loader; |
| import flash.display.LoaderInfo; |
| import flash.display.MovieClip; |
| import flash.display.Sprite; |
| import flash.display.Stage; |
| import flash.display.StageAlign; |
| import flash.display.StageScaleMode; |
| import flash.events.Event; |
| import flash.events.IEventDispatcher; |
| import flash.events.MouseEvent; |
| import flash.geom.Point; |
| import flash.geom.Rectangle; |
| import flash.net.getClassByAlias; |
| import flash.net.registerClassAlias; |
| import flash.system.ApplicationDomain; |
| import flash.text.Font; |
| import flash.text.TextFormat; |
| import flash.ui.ContextMenu; |
| import flash.utils.ByteArray; |
| import flash.utils.Dictionary; |
| |
| import mx.core.EventPriority; |
| import mx.core.FlexSprite; |
| import mx.core.IChildList; |
| import mx.core.IFlexDisplayObject; |
| import mx.core.IFlexModule; |
| import mx.core.IFlexModuleFactory; |
| import mx.core.IUIComponent; |
| import mx.core.RSLData; |
| import mx.core.Singleton; |
| import mx.core.IWindow; |
| import mx.core.mx_internal; |
| import mx.events.SandboxMouseEvent; |
| import mx.events.DynamicEvent; |
| import mx.events.FlexEvent; |
| import mx.events.EventListenerRequest; |
| import mx.events.Request; |
| import mx.managers.systemClasses.ChildManager; |
| import mx.styles.ISimpleStyleClient; |
| import mx.styles.IStyleClient; |
| import mx.utils.NameUtil; |
| import mx.utils.ObjectUtil; |
| |
| use namespace mx_internal; |
| |
| /** |
| * The WindowedSystemManager class manages any non-Application windows in a |
| * Flex-based AIR application. This includes all windows that are instances of |
| * the Window component or a Window subclass, but not a WindowedApplication |
| * window. For those windows, the WindowedSystemManager serves the same role |
| * that a SystemManager serves for a WindowedApplication instance or an |
| * Application instance in a browser-based Flex application. |
| * |
| * <p>As this comparison suggests, the WindowedSystemManager class serves |
| * many roles. For instance, it is the root display object of a Window, and |
| * manages tooltips, cursors, popups, and other content for the Window.</p> |
| * |
| * @see mx.managers.SystemManager |
| * |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public class WindowedSystemManager extends MovieClip implements ISystemManager |
| { |
| |
| public function WindowedSystemManager(rootObj:IUIComponent) |
| { |
| super(); |
| _topLevelSystemManager = this; |
| topLevelWindow = rootObj; |
| SystemManagerGlobals.topLevelSystemManagers.push(this); |
| childManager = new ChildManager(this); |
| //docFrameHandler(null); |
| addEventListener(Event.ADDED, docFrameHandler); |
| } |
| |
| mx_internal var topLevel:Boolean = true; |
| |
| private var initialized:Boolean = false; |
| |
| /** |
| * @private |
| * The top level window. |
| */ |
| mx_internal var topLevelWindow:IUIComponent; |
| |
| /** |
| * @private |
| * pointer to Window, for cleanup |
| */ |
| private var myWindow:IWindow; |
| |
| /** |
| * @private |
| */ |
| private var _topLevelSystemManager:ISystemManager; |
| |
| /** |
| * @private |
| * The childAdded/removed code |
| */ |
| mx_internal var childManager:ISystemManagerChildManager; |
| |
| /** |
| * @private |
| * Whether we are the stage root or not. |
| * We are only the stage root if we were the root |
| * of the first SWF that got loaded by the player. |
| * Otherwise we could be top level but not stage root |
| * if we are loaded by some other non-Flex shell |
| * or are sandboxed. |
| */ |
| private var isStageRoot:Boolean = true; |
| |
| /** |
| * @private |
| * Number of frames since the last mouse or key activity. |
| */ |
| mx_internal var idleCounter:int = 0; |
| |
| /** |
| * @private |
| * Whether we are the first SWF loaded into a bootstrap |
| * and therefore, the topLevelRoot |
| */ |
| private var isBootstrapRoot:Boolean = false; |
| |
| /** |
| * Depth of this object in the containment hierarchy. |
| * This number is used by the measurement and layout code. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| mx_internal var nestLevel:int = 0; |
| |
| /** |
| * @private |
| * The mouseCatcher is the 0th child of the SystemManager, |
| * behind the application, which is child 1. |
| * It is the same size as the stage and is filled with |
| * transparent pixels; i.e., they've been drawn, but with alpha 0. |
| * |
| * Its purpose is to make every part of the stage |
| * able to detect the mouse. |
| * For example, a Button puts a mouseUp handler on the SystemManager |
| * in order to capture mouseUp events that occur outside the Button. |
| * But if the children of the SystemManager don't have "drawn-on" |
| * pixels everywhere, the player won't dispatch the mouseUp. |
| * We can't simply fill the SystemManager itself with |
| * transparent pixels, because the player's pixel detection |
| * logic doesn't look at pixels drawn into the root DisplayObject. |
| * |
| * Here is an example of what would happen without the mouseCatcher: |
| * Run a fixed-size Application (e.g. width="600" height="600") |
| * in the standalone player. Make the player window larger |
| * to reveal part of the stage. Press a Button, drag off it |
| * into the stage area, and release the mouse button. |
| * Without the mouseCatcher, the Button wouldn't return to its "up" state. |
| */ |
| private var mouseCatcher:Sprite; |
| |
| //---------------------------------- |
| // applicationIndex |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the applicationIndex property. |
| */ |
| private var _applicationIndex:int = 1; |
| |
| /** |
| * @private |
| * The index of the main mx.core.Application window, which is |
| * effectively its z-order. |
| */ |
| mx_internal function get applicationIndex():int |
| { |
| return _applicationIndex; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function set applicationIndex(value:int):void |
| { |
| _applicationIndex = value; |
| } |
| |
| |
| //----------------------------------- |
| // ISystemManager implementations |
| //----------------------------------- |
| |
| //---------------------------------- |
| // allowDomainsInNewRSLs |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _allowDomainsInNewRSLs:Boolean = true; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10.2 |
| * @playerversion AIR 2.6 |
| * @productversion Flex 4.5 |
| */ |
| public function get allowDomainsInNewRSLs():Boolean |
| { |
| return _allowDomainsInNewRSLs; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set allowDomainsInNewRSLs(value:Boolean):void |
| { |
| _allowDomainsInNewRSLs = value; |
| } |
| |
| //---------------------------------- |
| // allowInsecureDomainsInNewRSLs |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _allowInsecureDomainsInNewRSLs:Boolean = true; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10.2 |
| * @playerversion AIR 2.6 |
| * @productversion Flex 4.5 |
| */ |
| public function get allowInsecureDomainsInNewRSLs():Boolean |
| { |
| return _allowInsecureDomainsInNewRSLs; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set allowInsecureDomainsInNewRSLs(value:Boolean):void |
| { |
| _allowInsecureDomainsInNewRSLs = value; |
| } |
| |
| //---------------------------------- |
| // cursorChildren |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the cursorChildren property. |
| */ |
| private var _cursorChildren:WindowedSystemChildrenList; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get cursorChildren():IChildList |
| { |
| if (!topLevel) |
| return _topLevelSystemManager.cursorChildren; |
| |
| if (!_cursorChildren) |
| { |
| _cursorChildren = new WindowedSystemChildrenList(this, |
| new QName(mx_internal, "toolTipIndex"), |
| new QName(mx_internal, "cursorIndex")); |
| } |
| |
| return _cursorChildren; |
| } |
| |
| //---------------------------------- |
| // cursorIndex |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the toolTipIndex property. |
| */ |
| private var _cursorIndex:int = 0; |
| |
| /** |
| * @private |
| * The index of the highest child that is a cursor. |
| */ |
| mx_internal function get cursorIndex():int |
| { |
| return _cursorIndex; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function set cursorIndex(value:int):void |
| { |
| var delta:int = value - _cursorIndex; |
| _cursorIndex = value; |
| } |
| |
| //---------------------------------- |
| // document |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the document property. |
| */ |
| private var _document:Object; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get document():Object |
| { |
| return _document; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set document(value:Object):void |
| { |
| _document = value; |
| } |
| |
| //---------------------------------- |
| // embeddedFontList |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the fontList property. |
| */ |
| private var _fontList:Object = null; |
| |
| /** |
| * A table of embedded fonts in this application. The |
| * object is a table indexed by the font name. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get embeddedFontList():Object |
| { |
| if (_fontList == null) |
| { |
| _fontList = {}; |
| |
| var o:Object = info()["fonts"]; |
| |
| var p:String; |
| |
| for (p in o) |
| { |
| _fontList[p] = o[p]; |
| } |
| |
| // Top level systemManager may not be defined if SWF is loaded |
| // as a background image in download progress bar. |
| if (!topLevel && _topLevelSystemManager) |
| { |
| var fl:Object = _topLevelSystemManager.embeddedFontList; |
| for (p in fl) |
| { |
| _fontList[p] = fl[p]; |
| } |
| } |
| } |
| |
| return _fontList; |
| } |
| |
| //---------------------------------- |
| // focusPane |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _focusPane:Sprite; |
| |
| /** |
| * @copy mx.core.UIComponent#focusPane |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get focusPane():Sprite |
| { |
| return _focusPane; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set focusPane(value:Sprite):void |
| { |
| if (value) |
| { |
| addChild(value); |
| |
| value.x = 0; |
| value.y = 0; |
| value.scrollRect = null; |
| |
| _focusPane = value; |
| } |
| else |
| { |
| removeChild(_focusPane); |
| |
| _focusPane = null; |
| } |
| } |
| |
| //---------------------------------- |
| // isProxy |
| //---------------------------------- |
| |
| /** |
| * True if SystemManager is a proxy and not a root class |
| */ |
| public function get isProxy():Boolean |
| { |
| return false; |
| } |
| |
| //---------------------------------- |
| // $numChildren |
| //---------------------------------- |
| |
| /** |
| * @private |
| * This property allows access to the Player's native implementation |
| * of the numChildren property, which can be useful since components |
| * can override numChildren and thereby hide the native implementation. |
| * Note that this "base property" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function get $numChildren():int |
| { |
| return super.numChildren; |
| } |
| |
| //---------------------------------- |
| // numModalWindows |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the numModalWindows property. |
| */ |
| private var _numModalWindows:int = 0; |
| |
| /** |
| * The number of modal windows. Modal windows don't allow |
| * clicking in another windows which would normally |
| * activate the FocusManager in that window. The PopUpManager |
| * modifies this count as it creates and destroys modal windows. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get numModalWindows():int |
| { |
| return _numModalWindows; |
| } |
| |
| /** |
| * @private |
| */ |
| public function set numModalWindows(value:int):void |
| { |
| _numModalWindows = value; |
| } |
| //---------------------------------- |
| // popUpChildren |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the popUpChildren property. |
| */ |
| private var _popUpChildren:WindowedSystemChildrenList; |
| |
| //---------------------------------- |
| // preloadedRSLs |
| //---------------------------------- |
| |
| /** |
| * @private |
| * |
| * This is a stub to satisfy the IFlexModuleFactory interface. |
| */ |
| public function get preloadedRSLs():Dictionary |
| { |
| return null; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get popUpChildren():IChildList |
| { |
| if (!topLevel) |
| return _topLevelSystemManager.popUpChildren; |
| |
| if (!_popUpChildren) |
| { |
| _popUpChildren = new WindowedSystemChildrenList(this, |
| new QName(mx_internal, "noTopMostIndex"), |
| new QName(mx_internal, "topMostIndex")); |
| } |
| |
| return _popUpChildren; |
| } |
| |
| //---------------------------------- |
| // noTopMostIndex |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the noTopMostIndex property. |
| */ |
| private var _noTopMostIndex:int = 0; |
| |
| /** |
| * @private |
| * The index of the highest child that isn't a topmost/popup window |
| */ |
| mx_internal function get noTopMostIndex():int |
| { |
| return _noTopMostIndex; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function set noTopMostIndex(value:int):void |
| { |
| var delta:int = value - _noTopMostIndex; |
| _noTopMostIndex = value; |
| topMostIndex += delta; |
| } |
| //---------------------------------- |
| // rawChildren |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the rawChildren property. |
| */ |
| private var _rawChildren:WindowedSystemRawChildrenList; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get rawChildren():IChildList |
| { |
| if (!topLevel) |
| return _topLevelSystemManager.rawChildren; |
| |
| if (!_rawChildren) |
| _rawChildren = new WindowedSystemRawChildrenList(this); |
| |
| return _rawChildren; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // screen |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * Storage for the screen property. |
| */ |
| mx_internal var _screen:Rectangle; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get screen():Rectangle |
| { |
| if (!_screen) |
| _screen = new Rectangle(); |
| _screen.x = 0; |
| _screen.y = 0; |
| _screen.width = stage.stageWidth; //Capabilities.screenResolutionX; |
| _screen.height = stage.stageHeight; //Capabilities.screenResolutionY; |
| |
| |
| return _screen; |
| } |
| |
| //---------------------------------- |
| // toolTipChildren |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the toolTipChildren property. |
| */ |
| private var _toolTipChildren:WindowedSystemChildrenList; |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get toolTipChildren():IChildList |
| { |
| if (!topLevel) |
| return _topLevelSystemManager.toolTipChildren; |
| |
| if (!_toolTipChildren) |
| { |
| _toolTipChildren = new WindowedSystemChildrenList(this, |
| new QName(mx_internal, "topMostIndex"), |
| new QName(mx_internal, "toolTipIndex")); |
| } |
| |
| return _toolTipChildren; |
| } |
| //---------------------------------- |
| // toolTipIndex |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the toolTipIndex property. |
| */ |
| private var _toolTipIndex:int = 0; |
| |
| /** |
| * @private |
| * The index of the highest child that is a tooltip |
| */ |
| mx_internal function get toolTipIndex():int |
| { |
| return _toolTipIndex; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function set toolTipIndex(value:int):void |
| { |
| var delta:int = value - _toolTipIndex; |
| _toolTipIndex = value; |
| cursorIndex += delta; |
| } |
| |
| //---------------------------------- |
| // topLevelSystemManager |
| //---------------------------------- |
| |
| /** |
| * Returns the SystemManager responsible for the application window. This will be |
| * the same SystemManager unless this application has been loaded into another |
| * application. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get topLevelSystemManager():ISystemManager |
| { |
| if (topLevel) |
| return this; |
| |
| return _topLevelSystemManager; |
| } |
| |
| //---------------------------------- |
| // topMostIndex |
| //---------------------------------- |
| |
| /** |
| * @private |
| * Storage for the topMostIndex property. |
| */ |
| private var _topMostIndex:int = 0; |
| |
| /** |
| * @private |
| * The index of the highest child that is a topmost/popup window |
| */ |
| mx_internal function get topMostIndex():int |
| { |
| return _topMostIndex; |
| } |
| |
| mx_internal function set topMostIndex(value:int):void |
| { |
| var delta:int = value - _topMostIndex; |
| _topMostIndex = value; |
| toolTipIndex += delta; |
| } |
| |
| //---------------------------------- |
| // width |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _width:Number; |
| |
| /** |
| * The width of this object. For the SystemManager |
| * this should always be the width of the stage unless the application was loaded |
| * into another application. If the application was not loaded |
| * into another application, setting this value will have no effect. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get width():Number |
| { |
| return _width; |
| } |
| |
| //---------------------------------- |
| // window |
| //---------------------------------- |
| /** |
| * @private |
| */ |
| private var _window:IWindow = null; |
| |
| mx_internal function get window():IWindow |
| { |
| return _window; |
| } |
| |
| mx_internal function set window(value:IWindow):void |
| { |
| _window = value; |
| } |
| |
| |
| //---------------------------------- |
| // height |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| private var _height:Number; |
| |
| /** |
| * The height of this object. For the SystemManager |
| * this should always be the width of the stage unless the application was loaded |
| * into another application. If the application was not loaded |
| * into another application, setting this value has no effect. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get height():Number |
| { |
| return _height; |
| } |
| |
| /** |
| * @inheritdoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get childAllowsParent():Boolean |
| { |
| try |
| { |
| return loaderInfo.childAllowsParent; |
| } |
| catch (error:Error) |
| { |
| //Error #2099: The loading object is not sufficiently loaded to provide this information. |
| } |
| |
| return false; // assume the worst |
| } |
| |
| /** |
| * @inheritdoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function get parentAllowsChild():Boolean |
| { |
| try |
| { |
| return loaderInfo.parentAllowsChild; |
| } |
| catch (error:Error) |
| { |
| //Error #2099: The loading object is not sufficiently loaded to provide this information. |
| } |
| |
| return false; // assume the worst |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Access to overridden methods of base classes |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of addChild(), which can be useful since components |
| * can override addChild() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $addChild(child:DisplayObject):DisplayObject |
| { |
| return super.addChild(child); |
| } |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of addChildAt(), which can be useful since components |
| * can override addChildAt() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $addChildAt(child:DisplayObject, |
| index:int):DisplayObject |
| { |
| return super.addChildAt(child, index); |
| } |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of removeChild(), which can be useful since components |
| * can override removeChild() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $removeChild(child:DisplayObject):DisplayObject |
| { |
| return super.removeChild(child); |
| } |
| |
| /** |
| * @private |
| * This method allows access to the Player's native implementation |
| * of removeChildAt(), which can be useful since components |
| * can override removeChildAt() and thereby hide the native implementation. |
| * Note that this "base method" is final and cannot be overridden, |
| * so you can count on it to reflect what is happening at the player level. |
| */ |
| mx_internal final function $removeChildAt(index:int):DisplayObject |
| { |
| return super.removeChildAt(index); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Initialization |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * This method should not be called on WindowedSystemManager. |
| * It is here as part of the contract for IFlexModuleFactory. |
| */ |
| public function callInContext(fn:Function, thisArg:Object, |
| argArray:Array, returns:Boolean = true):* |
| { |
| if (returns) |
| return fn.apply(thisArg, argArray); |
| else |
| fn.apply(thisArg, argArray); |
| } |
| |
| /** |
| * This method is overridden in the autogenerated subclass. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function create(... params):Object |
| { |
| var mainClassName:String = String(params[0]); |
| |
| var mainClass:Class = Class(getDefinitionByName(mainClassName)); |
| if (!mainClass) |
| throw new Error("Class '" + mainClassName + "' not found."); |
| |
| var instance:Object = new mainClass(); |
| if (instance is IFlexModule) |
| (IFlexModule(instance)).moduleFactory = this; |
| return instance; |
| } |
| |
| /** |
| * @private |
| * This is attached as the framescript at the end of frame 2. |
| * When this function is called, we know that the application |
| * class has been defined and read in by the Player. |
| */ |
| protected function docFrameHandler(event:Event = null):void |
| { |
| removeEventListener(Event.ADDED, docFrameHandler); |
| |
| // Register singleton classes. |
| // Note: getDefinitionByName() will return null |
| // if the class can't be found. |
| /* |
| Singleton.registerClass("mx.managers::ICursorManager", |
| Class(getDefinitionByName("mx.managers::CursorManagerImpl"))); |
| |
| Singleton.registerClass("mx.managers::IDragManager", |
| Class(getDefinitionByName("mx.managers::DragManagerImpl"))); |
| |
| Singleton.registerClass("mx.managers::IHistoryManager", |
| Class(getDefinitionByName("mx.managers::HistoryManagerImpl"))); |
| |
| Singleton.registerClass("mx.managers::ILayoutManager", |
| Class(getDefinitionByName("mx.managers::LayoutManager"))); |
| |
| Singleton.registerClass("mx.managers::IPopUpManager", |
| Class(getDefinitionByName("mx.managers::PopUpManagerImpl"))); |
| |
| Singleton.registerClass("mx.styles::IStyleManager", |
| Class(getDefinitionByName("mx.styles::StyleManagerImpl"))); |
| |
| Singleton.registerClass("mx.styles::IStyleManager2", |
| Class(getDefinitionByName("mx.styles::StyleManagerImpl"))); |
| |
| Singleton.registerClass("mx.managers::IToolTipManager2", |
| Class(getDefinitionByName("mx.managers::ToolTipManagerImpl")));*/ |
| |
| // executeCallbacks(); |
| // doneExecutingInitCallbacks = true; |
| |
| // Loaded SWFs don't get a stage right away |
| // and shouldn't override the main SWF's setting anyway. |
| if (stage) |
| { |
| stage.scaleMode = StageScaleMode.NO_SCALE; |
| stage.align = StageAlign.TOP_LEFT; |
| } |
| |
| var mixinList:Array = info()["mixins"]; |
| if (mixinList && mixinList.length > 0) |
| { |
| var n:int = mixinList.length; |
| for (var i:int = 0; i < n; ++i) |
| { |
| // trace("initializing mixin " + mixinList[i]); |
| var c:Class = Class(getDefinitionByName(mixinList[i])); |
| c["init"](this); |
| } |
| } |
| |
| c = Singleton.getClass("mx.managers::IActiveWindowManager"); |
| if (c) |
| { |
| registerImplementation("mx.managers::IActiveWindowManager", new c(this)); |
| } |
| |
| // depends on having IActiveWindowManager installed first |
| c = Singleton.getClass("mx.managers::IMarshalSystemManager"); |
| if (c) |
| { |
| registerImplementation("mx.managers::IMarshalSystemManager", new c(this)); |
| } |
| |
| // installCompiledResourceBundles(); |
| |
| initializeTopLevelWindow(null); |
| |
| if (Singleton.getClass("mx.managers::IDragManager").getInstance() is NativeDragManagerImpl) |
| NativeDragManagerImpl(Singleton.getClass("mx.managers::IDragManager").getInstance()).registerSystemManager(this); |
| } |
| |
| /** |
| * @private |
| * Instantiates an instance of the top level window |
| * and adds it as a child of the SystemManager. |
| */ |
| protected function initializeTopLevelWindow(event:Event):void |
| { |
| initialized = true; |
| |
| // This listener is intended to run before any other KeyboardEvent listeners |
| // so that it can redispatch a cancelable=true copy of the event. |
| if (getSandboxRoot() == this) |
| { |
| // keydown events on AIR are cancelable so we don't need to add a listener. |
| addEventListener(MouseEvent.MOUSE_WHEEL, mouseEventHandler, true, 1000); |
| addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, true, 1000); |
| } |
| if (isTopLevelRoot() && stage) |
| { |
| // keydown events on AIR are cancelable so we don't need to add a listener. |
| stage.addEventListener(MouseEvent.MOUSE_WHEEL, mouseEventHandler, false, 1000); |
| stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseEventHandler, false, 1000); |
| } |
| |
| if (!parent) |
| return; |
| |
| initContextMenu(); |
| if (!topLevel) |
| { |
| // We are not top-level and don't have a parent. This can happen |
| // when the application has already been unloaded by the time |
| // we get to this point. |
| if (!parent) |
| return; |
| |
| var obj:DisplayObjectContainer = parent.parent; |
| |
| // if there is no grandparent at this point, we might have been removed and |
| // are about to be killed so just bail. Other code that runs after |
| // this point expects us to be grandparented. Another scenario |
| // is that someone loaded us but not into a parented loader, but that |
| // is not allowed. |
| if (!obj) |
| return; |
| |
| while (obj) |
| { |
| if (obj is IUIComponent) |
| { |
| _topLevelSystemManager = IUIComponent(obj).systemManager; |
| break; |
| } |
| obj = obj.parent; |
| } |
| } |
| |
| // if (topLevel && stage) |
| stage.addEventListener(Event.RESIZE, Stage_resizeHandler, false, 0, true); |
| |
| var app:IUIComponent; |
| // Create a new instance of the toplevel class |
| document = app = topLevelWindow;// = IUIComponent(create()); |
| |
| if (document) |
| { |
| if (topLevel && stage) |
| { |
| // LoaderConfig._url = loaderInfo.url; |
| // LoaderConfig._parameters = loaderInfo.parameters; |
| |
| // stageWidth/stageHeight may have changed between initialize() and now, |
| // so refresh our _width and _height here. |
| _width = stage.stageWidth; |
| _height = stage.stageHeight; |
| //trace("width", _width); |
| |
| IFlexDisplayObject(app).setActualSize(stage.stageWidth, stage.stageHeight); |
| } |
| else |
| { |
| IFlexDisplayObject(app).setActualSize(loaderInfo.width, loaderInfo.height); |
| } |
| |
| // Wait for the app to finish its initialization sequence |
| // before doing an addChild(). |
| // Otherwise, the measurement/layout code will cause the |
| // player to do a bunch of unnecessary screen repaints, |
| // which slows application startup time. |
| |
| // Pass in the application instance to the preloader using registerApplication |
| // preloader.registerApplication(app); |
| |
| // The Application doesn't get added to the SystemManager in the standard way. |
| // We want to recursively create the entire application subtree and process |
| // it with the LayoutManager before putting the Application on the display list. |
| // So here we what would normally happen inside an override of addChild(). |
| // Leter, when we actually attach the Application instance, |
| // we call super.addChild(), which is the bare player method. |
| addingChild(DisplayObject(app)); |
| childAdded(DisplayObject(app)); // calls app.createChildren() |
| } |
| else |
| { |
| document = this; |
| } |
| |
| // because we have no preload done handler, we need to |
| // do that work elsewhere |
| addChildAndMouseCatcher(); |
| } |
| |
| /** |
| * @private |
| * Same as SystemManager's preload done handler. It adds |
| * the window to the application (and a mouse catcher) |
| * |
| * Called from initializeTopLevelWindow() |
| */ |
| private function addChildAndMouseCatcher():void |
| { |
| var app:IUIComponent = topLevelWindow; |
| // Add the mouseCatcher as child 0. |
| mouseCatcher = new FlexSprite(); |
| mouseCatcher.name = "mouseCatcher"; |
| |
| // Must use addChildAt because a creationComplete handler can create a |
| // dialog and insert it at 0. |
| noTopMostIndex++; |
| super.addChildAt(mouseCatcher, 0); |
| resizeMouseCatcher(); |
| |
| // topLevel seems to always be true, but keeping it here just in case |
| if (!topLevel) |
| { |
| mouseCatcher.visible = false; |
| mask = mouseCatcher; |
| } |
| |
| noTopMostIndex++; |
| super.addChild(DisplayObject(app)); |
| } |
| |
| |
| //---------------------------------- |
| // info |
| //---------------------------------- |
| |
| /** |
| * @private |
| */ |
| public function info():Object |
| { |
| return { |
| currentDomain: ApplicationDomain.currentDomain |
| }; |
| } |
| |
| |
| /** |
| * @private |
| * Disable all the built-in items except "Print...". |
| */ |
| private function initContextMenu():void |
| { |
| var defaultMenu:ContextMenu = new ContextMenu(); |
| defaultMenu.hideBuiltInItems(); |
| defaultMenu.builtInItems.print = true; |
| contextMenu = defaultMenu; |
| } |
| |
| /** |
| * @inheritdoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function isTopLevelRoot():Boolean |
| { |
| return isStageRoot || isBootstrapRoot; |
| } |
| |
| |
| /** |
| * Go up our parent chain to get the top level system manager. |
| * |
| * returns null if we are not on the display list or we don't have |
| * access to the top level system manager. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getTopLevelRoot():DisplayObject |
| { |
| // work our say up the parent chain to the root. This way we |
| // don't have to rely on this object being added to the stage. |
| try |
| { |
| var sm:ISystemManager = this; |
| if (sm.topLevelSystemManager) |
| sm = ISystemManager(sm.topLevelSystemManager); |
| var parent:DisplayObject = DisplayObject(sm).parent; |
| var lastParent:DisplayObject = DisplayObject(sm); |
| while (parent) |
| { |
| if (parent is Stage) |
| return lastParent; |
| lastParent = parent; |
| parent = parent.parent; |
| } |
| } |
| catch (error:SecurityError) |
| { |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Go up our parent chain to get the top level system manager in this |
| * SecurityDomain |
| * |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getSandboxRoot():DisplayObject |
| { |
| // work our say up the parent chain to the root. This way we |
| // don't have to rely on this object being added to the stage. |
| var sm:ISystemManager = this; |
| |
| try |
| { |
| if (sm.topLevelSystemManager) |
| sm = ISystemManager(sm.topLevelSystemManager); |
| var parent:DisplayObject = DisplayObject(sm).parent; |
| if (parent is Stage) |
| return DisplayObject(sm); |
| // test to see if parent is a Bootstrap |
| if (parent && !parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true))) |
| return this; |
| var lastParent:DisplayObject = this; |
| while (parent) |
| { |
| if (parent is Stage) |
| return lastParent; |
| // test to see if parent is a Bootstrap |
| if (!parent.dispatchEvent(new Event("mx.managers.SystemManager.isBootstrapRoot", false, true))) |
| return lastParent; |
| |
| // Test if the childAllowsParent so we know there is mutual trust between |
| // the sandbox root and this sm. |
| // The parentAllowsChild is taken care of by the player because it returns null |
| // for the parent if we do not have access. |
| if (parent is Loader) |
| { |
| var loader:Loader = Loader(parent); |
| var loaderInfo:LoaderInfo = loader.contentLoaderInfo; |
| if (!loaderInfo.childAllowsParent) |
| return loaderInfo.content; |
| } |
| |
| // If an object is listening for system manager request we assume it is a sandbox |
| // root. If not, don't assign lastParent to this parent because it may be a |
| // non-Flex application. We only want Flex apps to be returned as sandbox roots. |
| if (parent.hasEventListener("systemManagerRequest")) |
| lastParent = parent; |
| parent = parent.parent; |
| } |
| } |
| catch (error:Error) |
| { |
| // Either we don't have security access to a parent or |
| // the swf is unloaded and loaderInfo.childAllowsParent is throwing Error #2099. |
| } |
| |
| return lastParent != null ? lastParent : DisplayObject(sm); |
| } |
| |
| /** |
| * @private |
| * A map of fully-qualified interface names, |
| * such as "mx.managers::IPopUpManager", |
| * to implementation classes which produce singleton instances, |
| * such as mx.managers.PopUpManagerImpl. |
| */ |
| private var implMap:Object = {}; |
| |
| /** |
| * @private |
| * Adds an interface-name-to-implementation-class mapping to the registry, |
| * if a class hasn't already been registered for the specified interface. |
| * The class must implement a getInstance() method which returns |
| * its singleton instance. |
| */ |
| public function registerImplementation(interfaceName:String, |
| impl:Object):void |
| { |
| var c:Object = implMap[interfaceName]; |
| if (!c) |
| implMap[interfaceName] = impl; |
| } |
| |
| /** |
| * @private |
| * Returns the singleton instance of the implementation class |
| * that was registered for the specified interface, |
| * by looking up the class in the registry |
| * and calling its getInstance() method. |
| * |
| * This method should not be called at static initialization time, |
| * because the factory class may not have called registerClass() yet. |
| */ |
| public function getImplementation(interfaceName:String):Object |
| { |
| var c:Object = implMap[interfaceName]; |
| return c; |
| } |
| |
| /** |
| * @inheritdoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getVisibleApplicationRect(bounds:Rectangle = null, skipToSandboxRoot:Boolean = false):Rectangle |
| { |
| var request:Request = new Request("getVisibleApplicationRect", false, true); |
| if (!dispatchEvent(request)) |
| return Rectangle(request.value); |
| |
| if (skipToSandboxRoot && !topLevel) |
| return topLevelSystemManager.getVisibleApplicationRect(bounds, skipToSandboxRoot); |
| |
| if (!bounds) |
| { |
| bounds = getBounds(DisplayObject(this)); |
| |
| var s:Rectangle = screen; |
| var pt:Point = new Point(Math.max(0, bounds.x), Math.max(0, bounds.y)); |
| pt = localToGlobal(pt); |
| bounds.x = pt.x; |
| bounds.y = pt.y; |
| bounds.width = s.width; |
| bounds.height = s.height; |
| } |
| |
| if (!topLevel) |
| { |
| var obj:DisplayObjectContainer = parent.parent; |
| |
| if ("getVisibleApplicationRect" in obj) |
| { |
| var visibleRect:Rectangle = obj["getVisibleApplicationRect"](true); |
| bounds = bounds.intersection(visibleRect); |
| } |
| } |
| |
| return bounds; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function deployMouseShields(deploy:Boolean):void |
| { |
| var dynamicEvent:DynamicEvent = new DynamicEvent("deployMouseShields"); |
| dynamicEvent.deploy = deploy; |
| dispatchEvent(dynamicEvent); |
| } |
| |
| /** |
| * @private |
| * |
| * This is a stub to satisfy the IFlexModuleFactory interface. |
| */ |
| public function addPreloadedRSL(loaderInfo:LoaderInfo, rsl:Vector.<RSLData>):void |
| { |
| } |
| |
| /** |
| * @private |
| * |
| * This is a stub to satisfy the IFlexModuleFactory interface. |
| * |
| * Calls Security.allowDomain() for the SWF associated with this SystemManager |
| * plus all the SWFs assocatiated with RSLs preloaded by this SystemManager. |
| * |
| */ |
| public function allowDomain(... domains):void |
| { |
| } |
| |
| /** |
| * @private |
| * |
| * This is a stub to satisfy the IFlexModuleFactory interface. |
| * |
| * Calls Security.allowInsecureDomain() for the SWF associated with this SystemManager |
| * plus all the SWFs assocatiated with RSLs preloaded by this SystemManager. |
| * |
| */ |
| public function allowInsecureDomain(... domains):void |
| { |
| } |
| |
| /** |
| * Returns <code>true</code> if the given DisplayObject is the |
| * top-level window. |
| * |
| * @param object |
| * |
| * @return <code>true</code> if the given DisplayObject is the |
| * top-level window. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function isTopLevelWindow(object:DisplayObject):Boolean |
| { |
| return object is IUIComponent && |
| IUIComponent(object) == topLevelWindow; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getDefinitionByName(name:String):Object |
| { |
| var domain:ApplicationDomain = ApplicationDomain.currentDomain; |
| !topLevel && parent is Loader ? |
| Loader(parent).contentLoaderInfo.applicationDomain : |
| info()["currentDomain"] as ApplicationDomain; |
| |
| //trace("SysMgr.getDefinitionByName domain",domain,"currentDomain",info()["currentDomain"]); |
| |
| var definition:Object; |
| |
| if (domain.hasDefinition(name)) |
| { |
| definition = domain.getDefinition(name); |
| //trace("SysMgr.getDefinitionByName got definition",definition,"name",name); |
| } |
| |
| return definition; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function isTopLevel():Boolean |
| { |
| return topLevel; |
| } |
| |
| /** |
| * @inheritDoc |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function isFontFaceEmbedded(textFormat:TextFormat):Boolean |
| { |
| var fontName:String = textFormat.font; |
| |
| var fl:Array = Font.enumerateFonts(); |
| for (var f:int = 0; f < fl.length; ++f) |
| { |
| var font:Font = Font(fl[f]); |
| if (font.fontName == fontName) |
| { |
| var style:String = "regular"; |
| if (textFormat.bold && textFormat.italic) |
| style = "boldItalic"; |
| else if (textFormat.bold) |
| style = "bold"; |
| else if (textFormat.italic) |
| style = "italic"; |
| |
| if (font.fontStyle == style) |
| return true; |
| } |
| } |
| |
| if (!fontName || |
| !embeddedFontList || |
| !embeddedFontList[fontName]) |
| { |
| return false; |
| } |
| |
| var info:Object = embeddedFontList[fontName]; |
| |
| return !((textFormat.bold && !info.bold) || |
| (textFormat.italic && !info.italic) || |
| (!textFormat.bold && !textFormat.italic && |
| !info.regular)); |
| } |
| |
| |
| /** |
| * @private |
| * Keep track of the size and position of the stage. |
| */ |
| private function Stage_resizeHandler(event:Event = null):void |
| { |
| var w:Number = stage.stageWidth; |
| var h:Number = stage.stageHeight; |
| |
| var y:Number = 0; |
| var x:Number = 0; |
| |
| if (!_screen) |
| _screen = new Rectangle(); |
| _screen.x = x; |
| _screen.y = y; |
| _screen.width = w; |
| _screen.height = h; |
| |
| |
| _width = stage.stageWidth; |
| _height = stage.stageHeight; |
| |
| //trace(_width, event.type); |
| if (event) |
| { |
| resizeMouseCatcher(); |
| dispatchEvent(event); |
| } |
| } |
| |
| |
| /** |
| * @private |
| * |
| * Get the index of an object in a given child list. |
| * |
| * @return index of f in childList, -1 if f is not in childList. |
| */ |
| private static function getChildListIndex(childList:IChildList, f:Object):int |
| { |
| var index:int = -1; |
| try |
| { |
| index = childList.getChildIndex(DisplayObject(f)); |
| } |
| catch (e:ArgumentError) |
| { |
| // index has been preset to -1 so just continue. |
| } |
| |
| return index; |
| } |
| |
| |
| /** |
| * @private |
| * Makes the mouseCatcher the same size as the stage, |
| * filling it with transparent pixels. |
| */ |
| private function resizeMouseCatcher():void |
| { |
| if (mouseCatcher) |
| { |
| var g:Graphics = mouseCatcher.graphics; |
| g.clear(); |
| g.beginFill(0x000000, 0); |
| g.drawRect(0, 0, stage.stageWidth, stage.stageHeight); |
| g.endFill(); |
| } |
| } |
| |
| /** |
| * @private |
| * |
| * true if redipatching a resize event. |
| */ |
| private var isDispatchingResizeEvent:Boolean; |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden methods: EventDispatcher |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| * allows marshal implementation to add events |
| */ |
| mx_internal final function $addEventListener(type:String, listener:Function, |
| useCapture:Boolean = false, |
| priority:int = 0, |
| useWeakReference:Boolean = false):void |
| { |
| super.addEventListener(type, listener, useCapture, priority, useWeakReference); |
| } |
| |
| /** |
| * @private |
| * Only create idle events if someone is listening. |
| */ |
| override public function addEventListener(type:String, listener:Function, |
| useCapture:Boolean = false, |
| priority:int = 0, |
| useWeakReference:Boolean = false):void |
| { |
| if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN |
| || type == Event.ACTIVATE || type == Event.DEACTIVATE) |
| { |
| // also listen to stage if allowed |
| try |
| { |
| if (stage) |
| { |
| // Use weak listener because we don't always know when we |
| // no longer need this listener |
| stage.addEventListener(type, stageEventHandler, false, 0, true); |
| } |
| } |
| catch (error:SecurityError) |
| { |
| } |
| } |
| |
| if (hasEventListener("addEventListener")) |
| { |
| var request:DynamicEvent = new DynamicEvent("addEventListener", false, true); |
| request.eventType = type; |
| request.listener = listener; |
| request.useCapture = useCapture; |
| request.priority = priority; |
| request.useWeakReference = useWeakReference; |
| if (!dispatchEvent(request)) |
| return; |
| } |
| |
| if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE) |
| { |
| // If someone wants this event, also listen for mouseLeave. |
| // Use weak listener because we don't always know when we |
| // no longer need this listener |
| try |
| { |
| if (stage) |
| { |
| stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true); |
| } |
| else |
| { |
| super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true); |
| } |
| } |
| catch (error:SecurityError) |
| { |
| super.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true); |
| } |
| } |
| |
| // These two events will dispatched to applications in sandboxes. |
| if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME) |
| { |
| if (type == FlexEvent.RENDER) |
| type = Event.RENDER; |
| else |
| type = Event.ENTER_FRAME; |
| |
| try |
| { |
| if (stage) |
| stage.addEventListener(type, listener, useCapture, priority, useWeakReference); |
| else |
| super.addEventListener(type, listener, useCapture, priority, useWeakReference); |
| } |
| catch (error:SecurityError) |
| { |
| super.addEventListener(type, listener, useCapture, priority, useWeakReference); |
| } |
| |
| if (stage && type == Event.RENDER) |
| stage.invalidate(); |
| |
| return; |
| } |
| |
| super.addEventListener(type, listener, useCapture, priority, useWeakReference); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal final function $removeEventListener(type:String, listener:Function, |
| useCapture:Boolean = false):void |
| { |
| super.removeEventListener(type, listener, useCapture); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function removeEventListener(type:String, listener:Function, |
| useCapture:Boolean = false):void |
| { |
| if (hasEventListener("removeEventListener")) |
| { |
| var request:DynamicEvent = new DynamicEvent("removeEventListener", false, true); |
| request.eventType = type; |
| request.listener = listener; |
| request.useCapture = useCapture; |
| if (!dispatchEvent(request)) |
| return; |
| } |
| |
| // These two events will dispatched to applications in sandboxes. |
| if (type == FlexEvent.RENDER || type == FlexEvent.ENTER_FRAME) |
| { |
| if (type == FlexEvent.RENDER) |
| type = Event.RENDER; |
| else |
| type = Event.ENTER_FRAME; |
| |
| try |
| { |
| if (stage) |
| stage.removeEventListener(type, listener, useCapture); |
| } |
| catch (error:SecurityError) |
| { |
| } |
| // Remove both listeners in case the system manager was added |
| // or removed from the stage after the listener was added. |
| super.removeEventListener(type, listener, useCapture); |
| |
| return; |
| } |
| |
| super.removeEventListener(type, listener, useCapture); |
| |
| if (type == MouseEvent.MOUSE_MOVE || type == MouseEvent.MOUSE_UP || type == MouseEvent.MOUSE_DOWN |
| || type == Event.ACTIVATE || type == Event.DEACTIVATE) |
| { |
| if (!hasEventListener(type)) |
| { |
| // also listen to stage if allowed |
| try |
| { |
| if (stage) |
| { |
| stage.removeEventListener(type, stageEventHandler, false); |
| } |
| } |
| catch (error:SecurityError) |
| { |
| } |
| } |
| } |
| |
| if (type == SandboxMouseEvent.MOUSE_UP_SOMEWHERE) |
| { |
| if (!hasEventListener(SandboxMouseEvent.MOUSE_UP_SOMEWHERE)) |
| { |
| // nobody wants this event any more for now |
| try |
| { |
| if (stage) |
| { |
| stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler); |
| } |
| } |
| catch (error:SecurityError) |
| { |
| } |
| // Remove both listeners in case the system manager was added |
| // or removed from the stage after the listener was added. |
| super.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler); |
| } |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Overridden methods: DisplayObjectContainer |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| override public function addChild(child:DisplayObject):DisplayObject |
| { |
| // Adjust the partition indexes |
| // before the "added" event is dispatched. |
| noTopMostIndex++; |
| |
| return rawChildren_addChildAt(child, noTopMostIndex - 1); |
| } |
| |
| //---------------------------------- |
| // numChildren |
| //---------------------------------- |
| |
| /** |
| * The number of non-floating windows. This is the main application window |
| * plus any other windows added to the SystemManager that are not popups, |
| * tooltips or cursors. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| override public function get numChildren():int |
| { |
| return noTopMostIndex - applicationIndex; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function addChildAt(child:DisplayObject, |
| index:int):DisplayObject |
| { |
| // Adjust the partition indexes |
| // before the "added" event is dispatched. |
| noTopMostIndex++; |
| |
| return rawChildren_addChildAt(child, applicationIndex + index); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function removeChild(child:DisplayObject):DisplayObject |
| { |
| // Adjust the partition indexes |
| // before the "removed" event is dispatched. |
| noTopMostIndex--; |
| |
| return rawChildren_removeChild(child); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function removeChildAt(index:int):DisplayObject |
| { |
| // Adjust the partition indexes |
| // before the "removed" event is dispatched. |
| noTopMostIndex--; |
| |
| return rawChildren_removeChildAt(applicationIndex + index); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function getChildAt(index:int):DisplayObject |
| { |
| return super.getChildAt(applicationIndex + index); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function getChildByName(name:String):DisplayObject |
| { |
| return super.getChildByName(name); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function getChildIndex(child:DisplayObject):int |
| { |
| return super.getChildIndex(child) - applicationIndex; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function setChildIndex(child:DisplayObject, newIndex:int):void |
| { |
| super.setChildIndex(child, applicationIndex + newIndex); |
| } |
| |
| /** |
| * @private |
| */ |
| override public function getObjectsUnderPoint(point:Point):Array |
| { |
| var children:Array = []; |
| |
| // Get all the children that aren't tooltips and cursors. |
| var n:int = topMostIndex; |
| for (var i:int = 0; i < n; i++) |
| { |
| var child:DisplayObject = super.getChildAt(i); |
| if (child is DisplayObjectContainer) |
| { |
| var temp:Array = |
| DisplayObjectContainer(child).getObjectsUnderPoint(point); |
| |
| if (temp) |
| children = children.concat(temp); |
| } |
| } |
| |
| return children; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Child management |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| mx_internal function addingChild(child:DisplayObject):void |
| { |
| var newNestLevel:int = 1; |
| if (!topLevel) |
| { |
| // non-topLevel SystemManagers are buried by Flash.display.Loader and |
| // other non-framework layers so we have to figure out the nestlevel |
| // by searching up the parent chain. |
| var obj:DisplayObjectContainer = parent.parent; |
| while (obj) |
| { |
| if (obj is ILayoutManagerClient) |
| { |
| newNestLevel = ILayoutManagerClient(obj).nestLevel + 1; |
| break; |
| } |
| obj = obj.parent; |
| } |
| } |
| nestLevel = newNestLevel; |
| |
| if (child is IUIComponent) |
| IUIComponent(child).systemManager = this; |
| |
| // Local variables for certain classes we need to check against below. |
| // This is the backdoor way around linking in the class in question. |
| var uiComponentClassName:Class = |
| Class(getDefinitionByName("mx.core.UIComponent")); |
| |
| // If the document property isn't already set on the child, |
| // set it to be the same as this component's document. |
| // The document setter will recursively set it on any |
| // descendants of the child that exist. |
| if (child is IUIComponent && |
| !IUIComponent(child).document) |
| { |
| IUIComponent(child).document = document; |
| } |
| |
| // Set the nestLevel of the child to be one greater |
| // than the nestLevel of this component. |
| // The nestLevel setter will recursively set it on any |
| // descendants of the child that exist. |
| if (child is ILayoutManagerClient) |
| ILayoutManagerClient(child).nestLevel = nestLevel + 1; |
| |
| if (child is InteractiveObject) |
| if (doubleClickEnabled) |
| InteractiveObject(child).doubleClickEnabled = true; |
| |
| if (child is IUIComponent) |
| IUIComponent(child).parentChanged(this); |
| |
| // Sets up the inheritingStyles and nonInheritingStyles objects |
| // and their proto chains so that getStyle() works. |
| // If this object already has some children, |
| // then reinitialize the children's proto chains. |
| if (child is IStyleClient) |
| IStyleClient(child).regenerateStyleCache(true); |
| |
| if (child is ISimpleStyleClient) |
| ISimpleStyleClient(child).styleChanged(null); |
| |
| if (child is IStyleClient) |
| IStyleClient(child).notifyStyleChangeInChildren(null, true); |
| |
| // Need to check to see if the child is an UIComponent |
| // without actually linking in the UIComponent class. |
| if (uiComponentClassName && child is uiComponentClassName) |
| uiComponentClassName(child).initThemeColor(); |
| |
| // Inform the component that it's style properties |
| // have been fully initialized. Most components won't care, |
| // but some need to react to even this early change. |
| if (uiComponentClassName && child is uiComponentClassName) |
| uiComponentClassName(child).stylesInitialized(); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function childAdded(child:DisplayObject):void |
| { |
| if (child.hasEventListener(FlexEvent.ADD)) |
| child.dispatchEvent(new FlexEvent(FlexEvent.ADD)); |
| |
| if (child is IUIComponent) |
| IUIComponent(child).initialize(); // calls child.createChildren() |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function removingChild(child:DisplayObject):void |
| { |
| if (child.hasEventListener(FlexEvent.REMOVE)) |
| child.dispatchEvent(new FlexEvent(FlexEvent.REMOVE)); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function childRemoved(child:DisplayObject):void |
| { |
| if (child is IUIComponent) |
| IUIComponent(child).parentChanged(null); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Methods: Support for rawChildren access |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_addChild(child:DisplayObject):DisplayObject |
| { |
| childManager.addingChild(child); |
| |
| super.addChild(child); |
| |
| childManager.childAdded(child); // calls child.createChildren() |
| |
| return child; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_addChildAt(child:DisplayObject, |
| index:int):DisplayObject |
| { |
| // preloader goes through here before childManager is set up |
| if (childManager) |
| childManager.addingChild(child); |
| |
| super.addChildAt(child, index); |
| |
| if (childManager) |
| childManager.childAdded(child); // calls child.createChildren() |
| |
| return child; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_removeChild(child:DisplayObject):DisplayObject |
| { |
| childManager.removingChild(child); |
| super.removeChild(child); |
| childManager.childRemoved(child); |
| |
| return child; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_removeChildAt(index:int):DisplayObject |
| { |
| var child:DisplayObject = super.getChildAt(index); |
| |
| childManager.removingChild(child); |
| |
| super.removeChildAt(index); |
| |
| childManager.childRemoved(child); |
| |
| return child; |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_getChildAt(index:int):DisplayObject |
| { |
| return super.getChildAt(index); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_getChildByName(name:String):DisplayObject |
| { |
| return super.getChildByName(name); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_getChildIndex(child:DisplayObject):int |
| { |
| return super.getChildIndex(child); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_setChildIndex(child:DisplayObject, newIndex:int):void |
| { |
| super.setChildIndex(child, newIndex); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_getObjectsUnderPoint(pt:Point):Array |
| { |
| return super.getObjectsUnderPoint(pt); |
| } |
| |
| /** |
| * @private |
| */ |
| mx_internal function rawChildren_contains(child:DisplayObject):Boolean |
| { |
| return super.contains(child); |
| } |
| |
| // fake out mouseX/mouseY |
| mx_internal var _mouseX:*; |
| mx_internal var _mouseY:*; |
| |
| |
| /** |
| * @private |
| */ |
| override public function get mouseX():Number |
| { |
| if (_mouseX === undefined) |
| return super.mouseX; |
| return _mouseX; |
| } |
| |
| /** |
| * @private |
| */ |
| override public function get mouseY():Number |
| { |
| if (_mouseY === undefined) |
| return super.mouseY; |
| return _mouseY; |
| } |
| |
| /** |
| * Return the object the player sees as having focus. |
| * |
| * @return An object of type InteractiveObject that the |
| * player sees as having focus. If focus is currently |
| * in a sandbox the caller does not have access to |
| * null will be returned. |
| * |
| * @langversion 3.0 |
| * @playerversion AIR 1.1 |
| * @productversion Flex 3 |
| */ |
| public function getFocus():InteractiveObject |
| { |
| try |
| { |
| return stage.focus; |
| } |
| catch (e:SecurityError) |
| { |
| // trace("SM getFocus(): ignoring security error " + e); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * @private |
| * Cleans up references to Window. Also removes self from topLevelSystemManagers list. |
| */ |
| mx_internal function cleanup(e:Event):void |
| { |
| if (Singleton.getClass("mx.managers::IDragManager").getInstance() |
| is NativeDragManagerImpl) |
| NativeDragManagerImpl(Singleton.getClass("mx.managers::IDragManager").getInstance()).unregisterSystemManager(this); |
| SystemManagerGlobals.topLevelSystemManagers.splice(SystemManagerGlobals.topLevelSystemManagers.indexOf(this), 1); |
| myWindow.nativeWindow.removeEventListener(Event.CLOSE, cleanup); |
| myWindow = null; |
| } |
| |
| /** |
| * @private |
| * only registers Window for later cleanup. |
| */ |
| mx_internal function addWindow(win:IWindow):void |
| { |
| myWindow = win; |
| myWindow.nativeWindow.addEventListener(Event.CLOSE, cleanup); |
| } |
| |
| /** |
| * @private |
| * dispatch certain stage events from sandbox root |
| */ |
| private function stageEventHandler(event:Event):void |
| { |
| if (event.target is Stage) |
| dispatchEvent(event); |
| } |
| |
| /** |
| * @private |
| * convert MOUSE_LEAVE to MOUSE_UP_SOMEWHERE |
| */ |
| private function mouseLeaveHandler(event:Event):void |
| { |
| dispatchEvent(new SandboxMouseEvent(SandboxMouseEvent.MOUSE_UP_SOMEWHERE)); |
| } |
| |
| /** |
| * Attempts to notify the parent SWFLoader that the |
| * Application's size has may have changed. Not needed |
| * for WindowedSystemManager so does nothing |
| * |
| * @langversion 3.0 |
| * @playerversion Flash 10 |
| * @playerversion AIR 1.5 |
| * @productversion Flex 4 |
| */ |
| public function invalidateParentSizeAndDisplayList():void |
| { |
| } |
| |
| //-------------------------------------------------------------------------- |
| // |
| // Event Handlers |
| // |
| //-------------------------------------------------------------------------- |
| |
| /** |
| * NOTE: The keyDownHandler in SystemManager is not needed in AIR because |
| * AIR keyDown events are cancelable. |
| */ |
| |
| /** |
| * @private |
| * We want to re-dispatch |
| * mouse events that are cancellable. Currently we are only doing |
| * this for a few mouse events and not all of them (MOUSE_WHEEL and |
| * MOUSE_DOWN). |
| */ |
| private function mouseEventHandler(e:MouseEvent):void |
| { |
| if (!e.cancelable) |
| { |
| e.stopImmediatePropagation(); |
| var cancelableEvent:MouseEvent = new MouseEvent(e.type, e.bubbles, |
| true, e.localX, |
| e.localY, e.relatedObject, e.ctrlKey, e.altKey, |
| e.shiftKey, e.buttonDown, e.delta, |
| e.commandKey, e.controlKey, e.clickCount); |
| |
| e.target.dispatchEvent(cancelableEvent); |
| } |
| } |
| |
| |
| } |
| } |