This is an automated email from the ASF dual-hosted git repository.

aharui pushed a commit to branch feature/MXRoyale
in repository https://gitbox.apache.org/repos/asf/royale-asjs.git

commit e6629b7c2f54d33fdd023a9f5db22d576df59f33
Author: Alex Harui <[email protected]>
AuthorDate: Tue Apr 3 12:04:57 2018 -0700

    FocusManager is needed to run tests because fake mouse clicks won't set 
focus
---
 .../src/main/royale/mx/managers/FocusManager.as    | 2388 ++++++++++++++++++++
 .../royale/mx/managers/IActiveWindowManager.as     |  100 +
 .../mx/managers/IFocusManagerComplexComponent.as   |   82 +
 .../royale/mx/managers/IFocusManagerComponent.as   |  193 ++
 .../royale/mx/managers/IFocusManagerContainer.as   |  129 ++
 .../main/royale/mx/managers/IFocusManagerGroup.as  |   85 +
 6 files changed, 2977 insertions(+)

diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/FocusManager.as 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/FocusManager.as
new file mode 100644
index 0000000..eb0fa37
--- /dev/null
+++ b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/FocusManager.as
@@ -0,0 +1,2388 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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
+{
+
+COMPILE::SWF
+{
+import flash.display.DisplayObject;
+import flash.display.DisplayObjectContainer;
+import flash.display.InteractiveObject;
+import flash.display.Sprite;
+import flash.display.Stage;
+import flash.events.Event;
+import flash.events.FocusEvent;
+import flash.events.KeyboardEvent;
+import flash.system.Capabilities;
+import flash.system.IME;
+import flash.text.TextField;
+import flash.ui.Keyboard;
+}
+
+//import mx.core.IButton;
+import mx.core.IChildList;
+import mx.core.IUIComponent;
+import mx.core.mx_internal;
+import mx.events.FlexEvent;
+//import mx.utils.Platform;
+
+use namespace mx_internal;
+
+import org.apache.royale.events.EventDispatcher;
+import org.apache.royale.events.MouseEvent;
+import mx.core.UIComponent;
+
+/**
+ *  The FocusManager class manages the focus on components in response to mouse
+ *  activity or keyboard activity (Tab key).  There can be several FocusManager
+ *  instances in an application.  Each FocusManager instance 
+ *  is responsible for a set of components that comprise a "tab loop".  If you
+ *  hit Tab enough times, focus traverses through a set of components and
+ *  eventually get back to the first component that had focus.  That is a "tab 
loop"
+ *  and a FocusManager instance manages that loop.  If there are popup windows
+ *  with their own set of components in a "tab loop" those popup windows will 
have
+ *  their own FocusManager instances.  The main application always has a
+ *  FocusManager instance.
+ *
+ *  <p>The FocusManager manages focus from the "component level".
+ *  In Flex, a UITextField in a component is the only way to allow keyboard 
entry
+ *  of text. To the Flash Player or AIR, that UITextField has focus. However, 
from the 
+ *  FocusManager's perspective the component that parents the UITextField has 
focus.
+ *  Thus there is a distinction between component-level focus and player-level 
focus.
+ *  Application developers generally only have to deal with component-level 
focus while
+ *  component developers must understand player-level focus.</p>
+ *
+ *  <p>All components that can be managed by the FocusManager must implement
+ *  mx.managers.IFocusManagerComponent, whereas objects managed by 
player-level focus do not.</p>  
+ *
+ *  <p>The FocusManager also managers the concept of a defaultButton, which is
+ *  the Button on a form that dispatches a click event when the Enter key is 
pressed
+ *  depending on where focus is at that time.</p>
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+COMPILE::SWF
+public class FocusManager extends EventDispatcher implements IFocusManager
+{
+
+       
//--------------------------------------------------------------------------
+       //
+       //  Class constants
+       //
+       
//--------------------------------------------------------------------------
+
+       /**
+        * @private
+        * 
+        * Default value of parameter, ignore. 
+        */
+       private static const FROM_INDEX_UNSPECIFIED:int = -2;
+       
+       
//--------------------------------------------------------------------------
+       //
+       //  Class variables
+       //
+       
//--------------------------------------------------------------------------
+
+       /**
+        * @private
+        * 
+        * Place to hook in additional classes
+        */
+       public static var mixins:Array;
+
+    // flag to turn on/off some ie specific behavior
+    mx_internal static var ieshifttab:Boolean = true;
+
+    
//--------------------------------------------------------------------------
+    //
+    //  Constructor
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  Constructor.
+     *
+     *  <p>A FocusManager manages the focus within the children of an 
IFocusManagerContainer.
+     *  It installs itself in the IFocusManagerContainer during execution
+     *  of the constructor.</p>
+     *
+     *  @param container An IFocusManagerContainer that hosts the FocusManager.
+     *
+     *  @param popup If <code>true</code>, indicates that the container
+     *  is a popup component and not the main application.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function FocusManager(container:IFocusManagerContainer, 
popup:Boolean = false)
+    {
+        super();
+
+               this.popup = popup;
+
+        IMEEnabled = true;
+        
+        /*
+               // Only <= IE8 supported focus cycling out of the SWF
+        browserMode = Capabilities.playerType == "ActiveX" && !popup;
+        desktopMode = Platform.isAir && !popup;
+        // Flash main windows come up activated, AIR main windows don't
+        windowActivated = !desktopMode;
+        */
+        
+        container.focusManager = this; // this property name is reserved in 
the parent
+
+        // trace("FocusManager constructor " + container + ".focusManager");
+        
+        _form = container;
+        
+        focusableObjects = [];
+
+        focusPane = new Sprite();
+        focusPane.name = "focusPane";
+
+        addFocusables(DisplayObject(container));
+        
+        // Listen to the stage so we know when the root application is loaded.
+        container.addEventListener(Event.ADDED, addedHandler);
+        container.addEventListener(Event.REMOVED, removedHandler);
+        container.addEventListener(FlexEvent.SHOW, showHandler);
+        container.addEventListener(FlexEvent.HIDE, hideHandler);
+        container.addEventListener(FlexEvent.HIDE, childHideHandler, true);
+        container.addEventListener("_navigationChange_",viewHideHandler, true);
+        
+        /*
+        //special case application and window
+        if (container.systemManager is SystemManager)
+        {
+            // special case application.  It shouldn't need to be made
+            // active and because we defer appCreationComplete, this 
+            // would steal focus back from any popups created during
+            // instantiation
+            if (container != 
SystemManager(container.systemManager).application)
+                container.addEventListener(FlexEvent.CREATION_COMPLETE,
+                                       creationCompleteHandler);
+        }
+        */
+        
+               if (mixins)
+               {
+                       var n:int = mixins.length;
+                       for (var i:int = 0; i < n; i++)
+                       {
+                               new mixins[i](this);
+                       }
+               }
+
+        // Make sure the SystemManager is running so it can tell us about
+        // mouse clicks and stage size changes.
+               try
+               {
+            /*
+                       var awm:IActiveWindowManager = 
+                               
IActiveWindowManager(container.systemManager.getImplementation("mx.managers::IActiveWindowManager"));
+                       if (awm)
+                       awm.addFocusManager(container); // build a message that 
does the equal
+            */
+            if (hasEventListener("initialize"))
+                       dispatchEvent(new Event("initialize"));
+
+               }
+               catch (e:Error)
+               {
+                       // ignore null pointer errors caused by container using 
a 
+                       // systemManager from another sandbox.
+               }
+        
+        // may need to remove this and use ActiveWindowManager
+        activate();
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    //  Variables
+    //
+    
//--------------------------------------------------------------------------
+
+    private var LARGE_TAB_INDEX:int = 99999;
+
+    mx_internal var calculateCandidates:Boolean = true;
+
+       /**
+        * @private
+        * 
+        * True if this focus manager is a popup, false if it is a main 
application.
+        * 
+        */
+       mx_internal var popup:Boolean;
+
+    /**
+     * @private
+     * 
+     * True if this focus manager will try to enable/disable the IME based on
+     * whether the focused control uses IME.  Leaving this as a backdoor just 
in case.
+     * 
+     */
+    mx_internal var IMEEnabled:Boolean;
+
+    /**
+     *  @private
+     *  We track whether we've been last activated or saw a TAB
+     *  This is used in browser tab management
+     */
+    mx_internal var lastAction:String;
+
+    /**
+     *  @private
+     *  Tab management changes based on whether were in a browser or not
+     *  This value is also affected by whether you are a modal dialog or not
+     */
+    public var browserMode:Boolean;
+
+    /**
+     *  @private
+     *  Activation changes depending on whether we're running in AIR or not
+     */
+    public var desktopMode:Boolean;
+
+    /**
+     *  @private
+     *  Tab management changes based on whether were in a browser or not
+     *  If non-null, this is the object that will
+     *  lose focus to the browser
+     */
+    private var browserFocusComponent:InteractiveObject;
+
+    /**
+     *  @private
+     *  Total set of all objects that can receive focus
+     *  but might be disabled or invisible.
+     */
+    mx_internal var focusableObjects:Array;
+    
+    /**
+     *  @private
+     *  Filtered set of objects that can receive focus right now.
+     */
+    private var focusableCandidates:Array;
+
+    /**
+     *  @private
+     */
+    private var activated:Boolean;
+    /**
+     *  @private
+     */
+    private var windowActivated:Boolean;
+    
+    /**
+     *         @private
+     * 
+     *         true if focus was changed to one of focusable objects. False if 
focus passed to 
+     *         the browser.
+     */
+       mx_internal var focusChanged:Boolean;
+
+    /**
+        *      @private
+        * 
+        *      if non-null, the location to move focus from instead of the 
object 
+        *  that has focus in the stage.
+        */
+       mx_internal var fauxFocus:DisplayObject;
+        
+        
+       
//--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    
//--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  showFocusIndicator
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the showFocusIndicator property.
+     */
+    mx_internal var _showFocusIndicator:Boolean = false;
+    
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get showFocusIndicator():Boolean
+    {
+        return _showFocusIndicator;
+    }
+    
+    /**
+     *  @private
+     */
+    public function set showFocusIndicator(value:Boolean):void
+    {
+        var changed:Boolean = _showFocusIndicator != value;
+        // trace("FM " + this + " showFocusIndicator = " + value);
+        _showFocusIndicator = value;
+
+        if (hasEventListener("showFocusIndicator"))
+            dispatchEvent(new Event("showFocusIndicator"));
+    }
+
+    //----------------------------------
+    //  defaultButton
+    //----------------------------------
+
+    /**
+     *  @private
+     *  The current default button.
+     */
+    //private var defButton:IButton;
+
+    /**
+     *  @private
+     */
+    //private var _defaultButton:IButton;
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    //public function get defaultButton():IButton
+    //{
+       //      return _defaultButton;
+    //}
+
+    /**
+     *  @private
+     *  We don't type the value as Button for dependency reasons
+    public function set defaultButton(value:IButton):void
+    {
+               var button:IButton = value ? IButton(value) : null;
+
+        if (button != _defaultButton)
+        {
+            if (_defaultButton)
+                _defaultButton.emphasized = false;
+            
+            if (defButton)  
+                defButton.emphasized = false;
+            
+            _defaultButton = button;
+            
+            if (defButton != _lastFocus || _lastFocus == _defaultButton)
+            {
+               defButton = button;
+            
+                       if (button)
+                       button.emphasized = true;
+               }
+       }
+    }
+     */
+
+    //----------------------------------
+    //  defaultButtonEnabled
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the defaultButtonEnabled property.
+     */
+    //private var _defaultButtonEnabled:Boolean = true;
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+    public function get defaultButtonEnabled():Boolean
+    {
+        return _defaultButtonEnabled;
+    }
+     */
+    
+    /**
+     *  @private
+    public function set defaultButtonEnabled(value:Boolean):void
+    {
+        _defaultButtonEnabled = value;
+        
+        // Synchronize with the new value. We ensure that our 
+        // default button is de-emphasized if defaultButtonEnabled
+        // is false.
+        if (defButton)
+            defButton.emphasized = value;
+    }
+     */
+    
+    //----------------------------------
+    //  focusPane
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the focusPane property.
+     */
+    private var _focusPane:Sprite;
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get focusPane():Sprite
+    {
+        return _focusPane;
+    }
+
+    /**
+     *  @private
+     */
+    public function set focusPane(value:Sprite):void
+    {
+        _focusPane = value;
+    }
+
+    //----------------------------------
+    //  form
+    //----------------------------------
+
+    /**
+     *  @private
+     *  Storage for the form property.
+     */
+    private var _form:IFocusManagerContainer;
+    
+    /**
+     *  @private
+     *  The form is the property where we store the IFocusManagerContainer
+     *  that hosts this FocusManager.
+     */
+    mx_internal function get form():IFocusManagerContainer
+    {
+        return _form;
+    }
+    
+    /**
+     *  @private
+     */
+    mx_internal function set form (value:IFocusManagerContainer):void
+    {
+        _form = value;
+    }
+
+
+    //----------------------------------
+    //  _lastFocus
+    //----------------------------------
+    
+    /**
+     *  @private
+     *  the object that last had focus
+     */
+    private var _lastFocus:IFocusManagerComponent;
+
+
+       /**
+        *      @private
+        */
+       mx_internal function get lastFocus():IFocusManagerComponent
+       {
+               return _lastFocus;
+       }
+        
+       /**
+        *      @private
+        */
+       mx_internal function set lastFocus(value:IFocusManagerComponent):void
+       {
+               _lastFocus = value;
+       }
+
+    //----------------------------------
+    //  nextTabIndex
+    //----------------------------------
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function get nextTabIndex():int
+    {
+        return getMaxTabIndex() + 1;
+    }
+
+    /**
+     *  Gets the highest tab index currently used in this Focus Manager's form 
or subform.
+     *
+     *  @return Highest tab index currently used.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    private function getMaxTabIndex():int
+    {
+        var z:Number = 0;
+
+        var n:int = focusableObjects.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            var t:Number = focusableObjects[i].tabIndex;
+            if (!isNaN(t))
+                z = Math.max(z, t);
+        }
+        
+        return z;
+    }
+
+    
//--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function getFocus():IFocusManagerComponent
+    {
+        var stage:Stage = Sprite(form)./*systemManager.*/stage;
+        
+        if (!stage)
+            return null;
+            
+        var o:InteractiveObject = stage.focus;
+        
+        // If a Stage* object (such as StageText or StageWebView) has focus,
+        // stage.focus will be set to null. Much of the focus framework is not
+        // set up to handle this. So, if stage.focus is null, we return the 
last
+        // IFocusManagerComponent that had focus.  In ADL, focus works slightly
+        // different than it does on device when using StageText.  In ADL, when
+        // the focus is a StageText component, a TextField whose parent is the 
+        // stage is assigned focus.  
+        if ((!o && _lastFocus) || (o is TextField && o.parent == stage))
+            return _lastFocus;
+        
+        return findFocusManagerComponent(o);
+    }
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function setFocus(o:IFocusManagerComponent):void
+    {
+        // trace("FM " + this + " setting focus to " + o);
+
+        o.setFocus();
+        
+        if (hasEventListener("setFocus"))
+               dispatchEvent(new Event("setFocus"));
+        // trace("FM set focus");
+    }
+
+    /**
+     *  @private
+     */
+    private function focusInHandler(event:FocusEvent):void
+    {
+        var target:InteractiveObject = InteractiveObject(event.target);
+        // trace("FocusManager focusInHandler in  = " + 
this._form.systemManager.loaderInfo.url);
+        // trace("FM " + this + " focusInHandler " + target);
+
+               // dispatch cancelable FocusIn to see if Marshal Plan mixin 
wants it
+        if (hasEventListener(FocusEvent.FOCUS_IN))
+               if (!dispatchEvent(new FocusEvent(FocusEvent.FOCUS_IN, false, 
true, target)))
+                       return;
+
+        if (isParent(DisplayObjectContainer(form), target))
+        {
+            /*
+            if (_defaultButton)
+            {
+                if (target is IButton && target != _defaultButton 
+                    && !(target is IToggleButton))
+                    _defaultButton.emphasized = false;
+                else if (_defaultButtonEnabled)
+                    _defaultButton.emphasized = true;
+            }
+            */
+            
+            // trace("FM " + this + " setting last focus " + target);
+            _lastFocus = findFocusManagerComponent(InteractiveObject(target));
+            
+            /*
+                       if (Capabilities.hasIME)
+            {
+                var usesIME:Boolean;
+                if (_lastFocus is IIMESupport)
+                {
+                    var imeFocus:IIMESupport = IIMESupport(_lastFocus);
+                    if (imeFocus.enableIME)
+                        usesIME = true;
+                }
+                if (IMEEnabled)
+                    IME.enabled = usesIME;
+            }
+            */
+            
+            /*
+                       // handle default button here
+                       // we can't check for Button because of 
cross-versioning so
+                       // for now we just check for an emphasized property
+            if (_lastFocus is IButton && !(_lastFocus is IToggleButton))
+                       {
+                defButton = _lastFocus as IButton;
+                       }
+                       else
+                       {
+                               // restore the default button to be the 
original one
+                               if (defButton && defButton != _defaultButton)
+                                       defButton = _defaultButton;
+                       }
+            */
+               }
+       }
+
+    /**
+     *  @private  Useful for debugging
+     */
+    private function focusOutHandler(event:FocusEvent):void
+    {
+        var target:InteractiveObject = InteractiveObject(event.target);
+        // trace("FocusManager focusOutHandler in  = " + 
this._form.systemManager.loaderInfo.url);
+        // trace("FM " + this + " focusOutHandler " + target);
+    }
+
+    /**
+     *  @private
+     *  restore focus to whoever had it last
+     */
+    private function activateHandler(event:Event):void
+    {
+//        var target:InteractiveObject = InteractiveObject(event.target);
+        // trace("FM " + this + " activateHandler ", _lastFocus);
+               
+        // if we were the active FM when we were deactivated
+        // and we're not running in AIR, then dispatch the event now
+        // otherwise wait for the AIR events to fire
+        if (activated && !desktopMode)
+        {
+            dispatchEvent(new FlexEvent(FlexEvent.FLEX_WINDOW_ACTIVATE));
+                   // restore focus if this focus manager had last focus
+            if (_lastFocus && (!browserMode || ieshifttab))
+                   _lastFocus.setFocus();
+               lastAction = "ACTIVATE";
+        }
+    }
+
+    /**
+     *  @private  
+     *  Dispatch event if we're not running in AIR.  AIR will
+     *  dispatch windowDeactivate that we respond to instead
+     */
+    private function deactivateHandler(event:Event):void
+    {
+        // var target:InteractiveObject = InteractiveObject(event.target);
+        // trace("FM " + this + " deactivateHandler ", _lastFocus);
+
+        // if we are the active FM when we were deactivated
+        // and we're not running in AIR, then dispatch the event now
+        // otherwise wait for the AIR events to fire
+        if (activated && !desktopMode)
+        {
+            dispatchEvent(new FlexEvent(FlexEvent.FLEX_WINDOW_DEACTIVATE));
+        }
+    }
+
+    /**
+     *  @private
+     *  restore focus to whoever had it last
+     */
+    private function activateWindowHandler(event:Event):void
+    {
+//        var target:InteractiveObject = InteractiveObject(event.target);
+        // trace("FM " + this + " activateWindowHandler ", _lastFocus);
+               
+        windowActivated = true;
+
+        if (activated)
+        {
+            dispatchEvent(new FlexEvent(FlexEvent.FLEX_WINDOW_ACTIVATE));
+                   // restore focus if this focus manager had last focus
+               if (_lastFocus && !browserMode)
+                   _lastFocus.setFocus();
+               lastAction = "ACTIVATE";
+        }
+    }
+
+    /**
+     *  @private  
+     *  If we're responsible for the focused control, remove focus from it
+     *  so it gets the same events as it would if the whole app lost focus
+     */
+    private function deactivateWindowHandler(event:Event):void
+    {
+        // var target:InteractiveObject = InteractiveObject(event.target);
+        // trace("FM " + this + " deactivateWindowHandler ", _lastFocus);
+
+        /*
+        windowActivated = false;
+
+        if (activated)
+        {
+            dispatchEvent(new FlexEvent(FlexEvent.FLEX_WINDOW_DEACTIVATE));
+            if (form.systemManager.stage)
+                form.systemManager.stage.focus = null;
+        }
+        */
+    }   
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function showFocus():void
+    {
+        /*
+        if (!showFocusIndicator)
+        {
+            showFocusIndicator = true;
+            if (_lastFocus)
+                _lastFocus.drawFocus(true);
+        }
+        */
+    }
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function hideFocus():void
+    {
+        // trace("FOcusManger " + this + " Hide Focus");
+        /*
+        if (showFocusIndicator)
+        {
+            showFocusIndicator = false;
+            if (_lastFocus)
+                _lastFocus.drawFocus(false);
+        }
+        */
+        // trace("END FOcusManger Hide Focus");
+    }
+    
+    /**
+     *  The SystemManager activates and deactivates a FocusManager
+     *  if more than one IFocusManagerContainer is visible at the same time.
+     *  If the mouse is clicked in an IFocusManagerContainer with a deactivated
+     *  FocusManager, the SystemManager will call 
+     *  the <code>activate()</code> method on that FocusManager.
+     *  The FocusManager that was activated will have its 
<code>deactivate()</code> method
+     *  called prior to the activation of another FocusManager.
+     *
+     *  <p>The FocusManager adds event handlers that allow it to monitor
+     *  focus related keyboard and mouse activity.</p>
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function activate():void
+    {
+        // we can get a double activation if we're popping up and becoming 
visible
+        // like the second time a menu appears
+        if (activated)
+        {
+               // trace("FocusManager is already active " + this);
+            return;
+        }
+
+        // trace("FocusManager activating = " + 
this._form.systemManager.loaderInfo.url);
+        // trace("FocusManager activating " + this);
+
+        // listen for focus changes, use weak references for the stage
+               // form.systemManager can be null if the form is created in a 
sandbox and 
+               // added as a child to the root system manager.
+               var sm:ISystemManager = form.systemManager;
+               if (sm)
+               {
+            /*
+                       if (sm.isTopLevelRoot())
+                       {
+                       
sm.stage.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, 
mouseFocusChangeHandler, false, 0, true);
+                       sm.stage.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, 
keyFocusChangeHandler, false, 0, true);
+                   sm.stage.addEventListener(Event.ACTIVATE, activateHandler, 
false, 0, true);
+                       sm.stage.addEventListener(Event.DEACTIVATE, 
deactivateHandler, false, 0, true);
+                       }
+                       else
+                       {
+            */
+                       sm.addEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, 
mouseFocusChangeHandler, false, 0, true);
+                       sm.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, 
keyFocusChangeHandler, false, 0, true);
+                   sm.addEventListener(Event.ACTIVATE, activateHandler, false, 
0, true);
+                       sm.addEventListener(Event.DEACTIVATE, 
deactivateHandler, false, 0, true);                               
+                       //}
+               }      
+               
+        form.addEventListener(FocusEvent.FOCUS_IN, focusInHandler, true);
+        form.addEventListener(FocusEvent.FOCUS_OUT, focusOutHandler, true);
+        form.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); 
+        form.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownCaptureHandler, 
true); 
+        //form.addEventListener(KeyboardEvent.KEY_DOWN, 
defaultButtonKeyHandler);
+        form.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, true);
+        if (sm)
+        {
+            // AIR Window events, but don't want to link in AIREvent
+            // use capture phase because these get sent by the main Window
+            // and we might be managing a popup in that window
+            sm.addEventListener("windowActivate", activateWindowHandler, true, 
0, true);
+            sm.addEventListener("windowDeactivate", deactivateWindowHandler, 
true, 0, true);
+        }
+
+        activated = true;
+        dispatchEvent(new FlexEvent(FlexEvent.FLEX_WINDOW_ACTIVATE));
+        
+        // Restore focus to the last control that had it if there was one.
+        if (_lastFocus)
+            setFocus(_lastFocus);
+
+        if (hasEventListener("activateFM"))
+               dispatchEvent(new Event("activateFM"));
+
+    }
+
+    /**
+     *  The SystemManager activates and deactivates a FocusManager
+     *  if more than one IFocusManagerContainer is visible at the same time.
+     *  If the mouse is clicked in an IFocusManagerContainer with a deactivated
+     *  FocusManager, the SystemManager will call 
+     *  the <code>activate()</code> method on that FocusManager.
+     *  The FocusManager that was activated will have its 
<code>deactivate()</code> method
+     *  called prior to the activation of another FocusManager.
+     *
+     *  <p>The FocusManager removes event handlers that allow it to monitor
+     *  focus related keyboard and mouse activity.</p>
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function deactivate():void
+    {
+        // trace("FocusManager deactivating " + this);
+        // trace("FocusManager deactivating = " + 
this._form.systemManager.loaderInfo.url);
+         
+        // listen for focus changes
+               var sm:ISystemManager = form.systemManager;
+        if (sm)
+        {
+            /*
+                       if (sm.isTopLevelRoot())
+                       {
+                       
sm.stage.removeEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, 
mouseFocusChangeHandler);
+                       
sm.stage.removeEventListener(FocusEvent.KEY_FOCUS_CHANGE, 
keyFocusChangeHandler);
+                   sm.stage.removeEventListener(Event.ACTIVATE, 
activateHandler);
+                       sm.stage.removeEventListener(Event.DEACTIVATE, 
deactivateHandler);
+                       }
+                       else
+                       {
+            */
+                       sm.removeEventListener(FocusEvent.MOUSE_FOCUS_CHANGE, 
mouseFocusChangeHandler);
+                       sm.removeEventListener(FocusEvent.KEY_FOCUS_CHANGE, 
keyFocusChangeHandler);
+                   sm.removeEventListener(Event.ACTIVATE, activateHandler);
+                       sm.removeEventListener(Event.DEACTIVATE, 
deactivateHandler);                            
+                       //}
+        }
+
+        form.removeEventListener(FocusEvent.FOCUS_IN, focusInHandler, true);
+        form.removeEventListener(FocusEvent.FOCUS_OUT, focusOutHandler, true);
+        form.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); 
+        form.removeEventListener(MouseEvent.MOUSE_DOWN, 
mouseDownCaptureHandler, true); 
+        //form.removeEventListener(KeyboardEvent.KEY_DOWN, 
defaultButtonKeyHandler);
+        // stop listening for default button in Capture phase
+        form.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler, true);
+
+        activated = false;
+        dispatchEvent(new FlexEvent(FlexEvent.FLEX_WINDOW_DEACTIVATE));
+
+        if (hasEventListener("deactivateFM"))
+               dispatchEvent(new Event("deactivateFM"));
+    }
+
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function findFocusManagerComponent(
+                            o:InteractiveObject):IFocusManagerComponent
+    {
+       return findFocusManagerComponent2(o) as IFocusManagerComponent;
+    }
+    
+    
+    /**
+    * @private
+    * 
+    * This version of the method differs from the old one to support SWFLoader
+    * being in the focusableObjects list but not being a component that
+    * gets focus. SWFLoader is in the list of focusable objects so
+    * focus may be passed over a bridge to the components on the other
+    * side of the bridge.
+    */
+    private function findFocusManagerComponent2(
+                            o:InteractiveObject):DisplayObject
+
+    {
+       try
+       {
+               while (o)
+               {
+                   if ((o is IFocusManagerComponent && 
IFocusManagerComponent(o).focusEnabled) /*||
+                        o is ISWFLoader*/)
+                       return o;
+                   
+                   o = o.parent;
+               }
+           }
+           catch (error:SecurityError)
+           {
+               // can happen in a loaded child swf
+               // trace("findFocusManagerComponent: handling security error");
+           }
+
+        // tab was set somewhere else
+        return null;
+    }
+
+    /**
+     *  @private
+     *  Returns true if p is a parent of o.
+     */
+    private function isParent(p:DisplayObjectContainer, 
o:DisplayObject):Boolean
+    {
+        if (p == o)
+            return false;
+        
+        //if (p is IRawChildrenContainer)
+        //    return IRawChildrenContainer(p).rawChildren.contains(o);
+        
+        return p.contains(o);
+    }
+    
+    private function isEnabledAndVisible(o:DisplayObject):Boolean
+    {
+        var formParent:DisplayObjectContainer = DisplayObjectContainer(form);
+        
+        while (o != formParent)
+        {
+            if (o is IUIComponent)
+                if (!IUIComponent(o).enabled)
+                    return false;
+            
+            /*
+            if (o is IVisualElement)
+                if (IVisualElement(o).designLayer && 
!IVisualElement(o).designLayer.effectiveVisibility)
+                    return false;
+            */
+            
+            if (!o.visible) 
+                return false;
+            o = o.parent;
+
+            // if no parent, then not on display list
+            if (!o)
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     *  @private
+     */
+    private function sortByTabIndex(a:InteractiveObject, 
b:InteractiveObject):int
+    {
+        var aa:int = a.tabIndex;
+        var bb:int = b.tabIndex;
+
+        if (aa == -1)
+            aa = int.MAX_VALUE;
+        if (bb == -1)
+            bb = int.MAX_VALUE;
+
+        return (aa > bb ? 1 :
+                aa < bb ? -1 : sortByDepth(DisplayObject(a), 
DisplayObject(b)));
+    }
+
+    /**
+     *  @private
+     */
+    private function sortFocusableObjectsTabIndex():void
+    {
+        // trace("FocusableObjectsTabIndex");
+        
+        focusableCandidates = [];
+        
+        var n:int = focusableObjects.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            var c:IFocusManagerComponent = focusableObjects[i] as 
IFocusManagerComponent;
+            if ((c && c.tabIndex && !isNaN(Number(c.tabIndex))) /*||
+                 focusableObjects[i] is ISWFLoader*/)
+            {
+                // if we get here, it is a candidate
+                focusableCandidates.push(focusableObjects[i]);
+            }
+        }
+        
+        focusableCandidates.sort(sortByTabIndex);
+    }
+
+    /**
+     *  @private
+     */
+    private function sortByDepth(aa:DisplayObject, bb:DisplayObject):Number
+    {
+        var val1:String = "";
+        var val2:String = "";
+        var index:int;
+        var tmp:String;
+        var tmp2:String;
+        var zeros:String = "0000";
+
+        var a:DisplayObject = DisplayObject(aa);
+        var b:DisplayObject = DisplayObject(bb);
+
+               // TODO (egreenfi):  If a component lives inside of a group, we 
care about not its display object index, but
+               // its index within the group. See SDK-25144
+               
+        while (a != DisplayObject(form) && a.parent)
+        {
+            index = getChildIndex(a.parent, a);
+            tmp = index.toString(16);
+            if (tmp.length < 4)
+            {
+                tmp2 = zeros.substring(0, 4 - tmp.length) + tmp;
+            }
+            val1 = tmp2 + val1;
+            a = a.parent;
+        }
+        
+        while (b != DisplayObject(form) && b.parent)
+        {
+            index = getChildIndex(b.parent, b);
+            tmp = index.toString(16);
+            if (tmp.length < 4)
+            {
+                tmp2 = zeros.substring(0, 4 - tmp.length) + tmp;
+            }
+            val2 = tmp2 + val2;
+            b = b.parent;
+        }
+
+        return val1 > val2 ? 1 : val1 < val2 ? -1 : 0;
+    }
+
+    private function getChildIndex(parent:DisplayObjectContainer, 
child:DisplayObject):int
+    {
+        try 
+        {
+            return parent.getChildIndex(child);
+        }
+        catch(e:Error)
+        {
+            //if (parent is IRawChildrenContainer)
+           //     return 
IRawChildrenContainer(parent).rawChildren.getChildIndex(child);
+            throw e;
+        }
+        throw new Error("FocusManager.getChildIndex failed");   // shouldn't 
ever get here
+    }
+
+    /**
+     *  @private
+     *  Calculate what focusableObjects are valid tab candidates.
+     */
+    private function sortFocusableObjects():void
+    {
+        // trace("FocusableObjects " + focusableObjects.length.toString());
+        focusableCandidates = [];
+        
+        var n:int = focusableObjects.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            var c:InteractiveObject = focusableObjects[i];
+            // trace("  " + c);
+            if (c.tabIndex && !isNaN(Number(c.tabIndex)) && c.tabIndex > 0)
+            {
+                sortFocusableObjectsTabIndex();
+                return;
+            }
+            focusableCandidates.push(c);
+        }
+        
+        focusableCandidates.sort(sortByDepth);
+    }
+
+    /**
+     *  Call this method to make the system
+     *  think the Enter key was pressed and the defaultButton was clicked
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+    mx_internal function sendDefaultButtonEvent():void
+    {
+        // trace("FocusManager.sendDefaultButtonEvent " + defButton);
+        defButton.dispatchEvent(new MouseEvent("click"));
+    }
+     */
+
+    /**
+     *  @private
+     *  Do a tree walk and add all children you can find.
+     */
+    mx_internal function addFocusables(o:DisplayObject, skipTopLevel:Boolean = 
false):void
+    {
+        // trace(">>addFocusables " + o);
+        if ((o is IFocusManagerComponent) && !skipTopLevel)
+        {
+                       
+                       var addToFocusables:Boolean = false;
+               if (o is IFocusManagerComponent)
+               {
+                   var focusable:IFocusManagerComponent = 
IFocusManagerComponent(o);
+                   if (focusable.focusEnabled)
+                   {
+                       if (focusable.tabFocusEnabled && isTabVisible(o))
+                       {
+                                               addToFocusables = true;         
                
+                       }
+                }
+            }
+
+                       if (addToFocusables)
+                       {            
+                       if (focusableObjects.indexOf(o) == -1)
+               {
+                    focusableObjects.push(o);
+                       calculateCandidates = true;
+                   // trace("FM added " + o);
+               }
+                       }
+            o.addEventListener("tabFocusEnabledChange", 
tabFocusEnabledChangeHandler);
+            o.addEventListener("tabIndexChange", tabIndexChangeHandler);
+
+        }
+        
+        if (o is DisplayObjectContainer)
+        {
+            var doc:DisplayObjectContainer = DisplayObjectContainer(o);
+            // Even if they aren't focusable now,
+            // listen in case they become later.
+            var checkChildren:Boolean;
+
+            if (o is IFocusManagerComponent)
+            {
+                o.addEventListener("hasFocusableChildrenChange", 
hasFocusableChildrenChangeHandler);
+                checkChildren = IFocusManagerComponent(o).hasFocusableChildren;
+            }
+            else
+            {
+                o.addEventListener("tabChildrenChange", 
tabChildrenChangeHandler);
+                checkChildren = doc.tabChildren;
+            }
+
+            var i:int;
+            if (checkChildren)
+            {
+                /*
+                if (o is IRawChildrenContainer)
+                {
+                    // trace("using view rawChildren");
+                    var rawChildren:IChildList = 
IRawChildrenContainer(o).rawChildren;
+                    // recursively visit and add children of components
+                    // we don't do this for containers because we get 
individual
+                    // adds for the individual children
+                    for (i = 0; i < rawChildren.numChildren; i++)
+                    {
+                        try
+                        {
+                            addFocusables(rawChildren.getChildAt(i));
+                        }
+                        catch(error:SecurityError)
+                        {
+                            // Ignore this child if we can't access it
+                            // trace("addFocusables: ignoring security error 
getting child from rawChildren: " + error);
+                        }
+                    }
+
+                }
+                else
+                {
+                */
+                    // trace("using container's children");
+                    // recursively visit and add children of components
+                    // we don't do this for containers because we get 
individual
+                    // adds for the individual children
+                    for (i = 0; i < doc.numChildren; i++)
+                    {
+                        try
+                        {
+                            addFocusables(doc.getChildAt(i));
+                        }
+                        catch(error:SecurityError)
+                        {
+                            // Ignore this child if we can't access it
+                            // trace("addFocusables: ignoring security error 
getting child at document." + error);
+                        }
+                    }
+                //}
+            }
+        }
+        // trace("<<addFocusables " + o);
+    }
+
+    /**
+     *  @private
+     *  is it really tabbable?
+     */
+    private function isTabVisible(o:DisplayObject):Boolean
+    {
+        var s:DisplayObject = DisplayObject(form.systemManager);
+        if (!s) return false;
+
+        var p:DisplayObjectContainer = o.parent;
+        while (p && p != s)
+        {
+            if (!p.tabChildren)
+                return false;
+            if (p is IFocusManagerComponent && 
!(IFocusManagerComponent(p).hasFocusableChildren))
+                return false;
+            p = p.parent;
+        }
+        return true;
+    }
+
+    private function isValidFocusCandidate(o:DisplayObject, g:String):Boolean
+    {
+        if (o is IFocusManagerComponent)
+            if (!IFocusManagerComponent(o).focusEnabled)
+                return false;
+
+        if (!isEnabledAndVisible(o))
+            return false;
+
+        if (o is IFocusManagerGroup)
+        {
+            // reject if it is in the same tabgroup
+            var tg:IFocusManagerGroup = IFocusManagerGroup(o);
+            if (g == tg.groupName) return false;
+        }
+        return true;
+    }
+    
+    private function getIndexOfFocusedObject(o:DisplayObject):int
+    {
+        if (!o)
+            return -1;
+
+        var n:int = focusableCandidates.length;
+        // trace(" focusableCandidates " + n);
+        var i:int = 0;
+        for (i = 0; i < n; i++)
+        {
+            // trace(" comparing " + focusableCandidates[i]);
+            if (focusableCandidates[i] == o)
+                return i;
+        }
+
+        // no match?  try again with a slower match for certain
+        // cases like DG editors
+        for (i = 0; i < n; i++)
+        {
+            var iui:IUIComponent = focusableCandidates[i] as IUIComponent;
+            if (iui && iui.owns(o as IUIComponent))
+                return i;
+        }
+
+        return -1;
+    }
+
+
+    private function getIndexOfNextObject(i:int, shiftKey:Boolean, 
bSearchAll:Boolean, groupName:String):int
+    {
+        var n:int = focusableCandidates.length;
+        var start:int = i;
+
+        while (true)
+        {
+            if (shiftKey)
+                i--;
+            else
+                i++;
+            if (bSearchAll)
+            {
+                if (shiftKey && i < 0)
+                    break;
+                if (!shiftKey && i == n)
+                    break;
+            }
+            else
+            {
+                i = (i + n) % n;
+                // came around and found the original
+                if (start == i)
+                    break;
+                // if start is -1, set start to first valid value of i
+                if (start == -1)
+                    start = i;
+            }
+            // trace("testing " + focusableCandidates[i]);
+            if (isValidFocusCandidate(focusableCandidates[i], groupName))
+            {
+                // trace(" stopped at " + i);
+                var o:DisplayObject = 
DisplayObject(findFocusManagerComponent2(focusableCandidates[i]));     
+                if (o is IFocusManagerGroup)
+                {
+                    
+                    // when landing on an element that is part of group, try to
+                    // advance selection to the selected group element
+                    var j:int;
+                    var obj:DisplayObject;
+                    var tg1:IFocusManagerGroup = IFocusManagerGroup(o);
+                    var tg2:IFocusManagerGroup;
+                    
+                    // normalize the "no selected group element" case
+                    // to the "first group element selected" case
+                    // (respecting the tab direction)
+                    var groupElementToFocus:IFocusManagerGroup = null;
+                    for (j = 0; j < focusableCandidates.length; j++)
+                    {
+                        obj = focusableCandidates[j];
+                        if (obj is IFocusManagerGroup)
+                        {
+                            tg2 = IFocusManagerGroup(obj);
+                            if (tg2.groupName == tg1.groupName && 
isEnabledAndVisible(obj) &&
+                                tg2["document"] == tg1["document"])
+                            {
+                                if (tg2.selected) 
+                                {
+                                    groupElementToFocus = tg2;
+                                    break;
+                                }
+                                if ((!shiftKey && groupElementToFocus == null) 
|| shiftKey)
+                                    groupElementToFocus = tg2;
+                            }
+                        }
+                    }
+                    
+                    if (tg1 != groupElementToFocus)
+                    {
+                        var foundAnotherGroup:Boolean = false;
+                        // cycle the entire focusable candidates array forward 
or backward,
+                        // wrapping around boundaries, searching for our focus 
candidate
+                        j = i;
+                        for (var k:int = 0; k < focusableCandidates.length - 
1; k++)
+                        {
+                            
+                            if (!shiftKey) 
+                            {
+                                j++;
+                                if (j == focusableCandidates.length)
+                                    j = 0;
+                            }
+                            else
+                            {
+                                j--;
+                                if (j == -1)
+                                    j = focusableCandidates.length - 1;
+                            }
+                            
+                            obj = focusableCandidates[j];
+                            if (isEnabledAndVisible(obj))
+                            {
+                                if (foundAnotherGroup)
+                                {
+                                    // we're now just trying to find a 
selected member of this group
+                                    if (obj is IFocusManagerGroup)
+                                    {
+                                        tg2 = IFocusManagerGroup(obj);
+                                        if (tg2.groupName == tg1.groupName && 
tg2["document"] == tg1["document"])
+                                        {
+                                            if (tg2.selected)
+                                            {
+                                                i = j;
+                                                break;
+                                            }
+                                        }
+                                    }
+                                }
+                                else if (obj is IFocusManagerGroup)
+                                {
+                                    tg2 = IFocusManagerGroup(obj);
+                                    if (tg2.groupName == tg1.groupName && 
tg2["document"] == tg1["document"])
+                                    {
+                                        if (tg2 == groupElementToFocus)
+                                        {
+                                            // if objects of same group have 
different tab index
+                                            // skip you aren't selected.
+                                            if 
(InteractiveObject(obj).tabIndex != InteractiveObject(o).tabIndex && 
!tg1.selected)
+                                                return getIndexOfNextObject(i, 
shiftKey, bSearchAll, groupName);
+                                            i = j;
+                                            break;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        // switch to new group and hunt for 
selected item
+                                        tg1 = tg2;
+                                        i = j;
+                                        // element is part of another group, 
stop if selected
+                                        if (tg2.selected)
+                                            break;
+                                        else
+                                            foundAnotherGroup = true;
+                                    }
+                                }
+                                else
+                                {
+                                    // element isn't part of any group, stop
+                                    i = j;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+                return i;
+            }
+        }
+        return i;
+    }
+
+    /**
+     *  @private
+     */
+    private function setFocusToNextObject(event:FocusEvent):void
+    {
+       focusChanged = false;
+        if (focusableObjects.length == 0)
+            return;
+
+               var focusInfo:FocusInfo = 
getNextFocusManagerComponent2(event.shiftKey, fauxFocus);
+               // trace("winner = ", focusInfo.displayObject);
+
+               // If we are about to wrap focus around, send focus back to the 
parent.
+               if (!popup && (focusInfo.wrapped || !focusInfo.displayObject))
+               {
+            if (hasEventListener("focusWrapping"))
+                       if (!dispatchEvent(new FocusEvent("focusWrapping", 
false, true, null, event.shiftKey)))
+                               return;
+               }
+               
+               if (!focusInfo.displayObject)
+               {
+                       event.preventDefault();
+                       return;
+               }
+
+               setFocusToComponent(focusInfo.displayObject, event.shiftKey);   
        
+       }
+
+       private function setFocusToComponent(o:Object, shiftKey:Boolean):void
+       {
+               focusChanged = false;
+               if (o)
+               {
+            if (hasEventListener("setFocusToComponent"))
+                       if (!dispatchEvent(new 
FocusEvent("setFocusToComponent", false, true, InteractiveObject(o), shiftKey)))
+                               return;
+
+                       if (o is IFocusManagerComplexComponent)
+                       {
+                               
IFocusManagerComplexComponent(o).assignFocus(shiftKey ? "bottom" : "top");
+                               focusChanged = true;
+                       }
+                       else if (o is IFocusManagerComponent)
+                       {
+                               setFocus(IFocusManagerComponent(o));
+                               focusChanged = true;
+                       }
+                               
+               }
+               
+       }
+
+       /**
+        *  @private
+        */
+       mx_internal function setFocusToNextIndex(index:int, 
shiftKey:Boolean):void
+       {
+               if (focusableObjects.length == 0)
+                       return;
+                       
+        // I think we'll have time to do this here instead of at creation time
+        // this makes and orders the focusableCandidates array
+        if (calculateCandidates)
+        {
+            sortFocusableObjects();
+            calculateCandidates = false;
+        }
+
+               var focusInfo:FocusInfo = 
getNextFocusManagerComponent2(shiftKey, null, index);                 
+
+               // If we are about to wrap focus around, send focus back to the 
parent.
+               if (!popup && focusInfo.wrapped)
+               {
+            if (hasEventListener("setFocusToNextIndex"))
+                       if (!dispatchEvent(new 
FocusEvent("setFocusToNextIndex", false, true, null, shiftKey)))
+                               return;
+               }
+               
+               setFocusToComponent(focusInfo.displayObject, shiftKey);
+       }
+       
+    /**
+     *  @inheritDoc
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    public function getNextFocusManagerComponent(
+                            backward:Boolean = false):IFocusManagerComponent
+       {
+        const focusInfo:FocusInfo = getNextFocusManagerComponent2(backward, 
fauxFocus); 
+        return focusInfo ? focusInfo.displayObject as IFocusManagerComponent : 
null; 
+       }
+       
+       /**
+        * Find the next object to set focus to.
+        * 
+        * @param backward true if moving in the backwards in the tab order, 
false if moving forward.
+        * @param fromObject object to move focus from, if null move from the 
current focus.
+        * @param formIndex index to move focus from, if specified use 
fromIndex to find the 
+        *                                      object, not fromObject.
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+       private function getNextFocusManagerComponent2(
+                            backward:Boolean = false, 
+                            fromObject:DisplayObject = null,
+                            fromIndex:int = FROM_INDEX_UNSPECIFIED):FocusInfo
+                            
+    {
+        if (focusableObjects.length == 0)
+            return null;
+
+        // I think we'll have time to do this here instead of at creation time
+        // this makes and orders the focusableCandidates array
+        if (calculateCandidates)
+        {
+            sortFocusableObjects();
+            calculateCandidates = false;
+        }
+
+        // trace("focus was at " + fromObject);
+        // trace("focusableObjects " + focusableObjects.length);
+        var i:int = fromIndex;
+        if (fromIndex == FROM_INDEX_UNSPECIFIED)
+        {
+               // if there is no passed in object, then get the object that 
has the focus
+           var o:DisplayObject = fromObject; 
+               if (!o)
+                       o = Sprite(form)./*systemManager,*/stage.focus;
+            else if (o == Sprite(form)./*systemManager.*/stage)
+                o == null;
+        
+               o = 
DisplayObject(findFocusManagerComponent2(InteractiveObject(o)));
+       
+               var g:String = "";
+               if (o is IFocusManagerGroup)
+               {
+                   var tg:IFocusManagerGroup = IFocusManagerGroup(o);
+                   g = tg.groupName;
+               }
+               i = getIndexOfFocusedObject(o);
+        }
+        
+        // trace(" starting at " + i);
+        var bSearchAll:Boolean = false;
+        var start:int = i;
+        if (i == -1) // we didn't find it
+        {
+            if (backward)
+                i = focusableCandidates.length;
+            bSearchAll = true;
+            // trace("search all " + i);
+        }
+
+        var j:int = getIndexOfNextObject(i, backward, bSearchAll, g);
+
+        // if we wrapped around, get if we have a parent we should pass
+        // focus to.
+        var wrapped:Boolean = false;
+        if (backward)
+        {
+               if (j >= i)
+                       wrapped = true;
+        }
+        else if (j <= i)
+               wrapped = true;
+
+               var focusInfo:FocusInfo = new FocusInfo();
+               
+               focusInfo.displayObject = 
findFocusManagerComponent2(focusableCandidates[j]);
+               focusInfo.wrapped = wrapped;
+               
+        return focusInfo;
+    }
+
+
+    /**
+     *  @private
+     */
+    private function 
getTopLevelFocusTarget(o:InteractiveObject):InteractiveObject
+    {
+        while (o != InteractiveObject(form))
+        {
+            if (o is IFocusManagerComponent &&
+                IFocusManagerComponent(o).focusEnabled &&
+                /*IFocusManagerComponent(o).mouseFocusEnabled &&*/
+                (o is IUIComponent ? IUIComponent(o).enabled : true))
+                return o;
+
+            if (hasEventListener("getTopLevelFocusTarget"))
+                       if (!dispatchEvent(new 
FocusEvent("getTopLevelFocusTarget", false, true, o.parent)))
+                               return null;
+
+            o = o.parent;
+
+            if (o == null)
+                break;
+        }
+
+        return null;
+    }
+
+    /**
+     *  Returns a String representation of the component hosting the 
FocusManager object, 
+     *  with the String <code>".focusManager"</code> appended to the end of 
the String.
+     *
+     *  @return Returns a String representation of the component hosting the 
FocusManager object, 
+     *  with the String <code>".focusManager"</code> appended to the end of 
the String.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    override public function toString():String
+    {
+        return Object(form).toString() + ".focusManager";
+    }
+    
+    /**
+     *  @private
+     * 
+     *  Clear the browser focus component and undo any tab index we may have 
set.
+     */
+    private function clearBrowserFocusComponent():void
+    {
+        if (browserFocusComponent)
+        {
+            if (browserFocusComponent.tabIndex == LARGE_TAB_INDEX)
+                browserFocusComponent.tabIndex = -1;
+            
+            browserFocusComponent = null;
+        }
+    }
+    
+    
//--------------------------------------------------------------------------
+    //
+    //  Event handlers
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  @private
+     *  Listen for children being added
+     *  and see if they are focus candidates.
+     */
+    private function addedHandler(event:Event):void
+    {
+        var target:DisplayObject = DisplayObject(event.target);
+        
+        // trace("FM: addedHandler: got added for " + target);
+        
+        // if it is truly parented, add it, otherwise it will get added when 
the top of the tree
+        // gets parented.
+        if (target.stage)
+        {
+            // trace("FM: addedHandler: adding focusables");
+            addFocusables(DisplayObject(event.target));
+        }
+    }
+
+    /**
+     *  @private
+     *  Listen for children being removed.
+     */
+    private function removedHandler(event:Event):void
+    {
+        var i:int;
+        var o:DisplayObject = DisplayObject(event.target);
+        var focusPaneParent:DisplayObject = focusPane ? focusPane.parent : 
null;
+
+        // Remove the focusPane to allow the focusOwner to be garbage 
collected.
+        // Avoid recursion by not processing the removal of the focusPane 
itself.    
+        /*
+        if (focusPaneParent && o != focusPane)
+        {
+            if (o is DisplayObjectContainer && 
+                isParent(DisplayObjectContainer(o), focusPane))
+            {
+                if (focusPaneParent is ISystemManager)
+                    ISystemManager(focusPaneParent).focusPane = null;
+                else
+                    IUIComponent(focusPaneParent).focusPane = null;
+            }
+        }
+        */
+        
+        // trace("FM got added for " + event.target);
+
+        if (o is IFocusManagerComponent)
+        {
+            for (i = 0; i < focusableObjects.length; i++)
+            {
+                if (o == focusableObjects[i])
+                {
+                    /*
+                    if (o == _lastFocus)
+                    {
+                        _lastFocus.drawFocus(false);
+                        _lastFocus = null;
+                    }
+                    */
+                    // trace("FM removed " + o);
+                    focusableObjects.splice(i, 1);
+                    focusableCandidates = [];
+                    calculateCandidates = true;                 
+                    break;
+                }
+            }
+            o.removeEventListener("tabFocusEnabledChange", 
tabFocusEnabledChangeHandler);
+            o.removeEventListener("tabIndexChange", tabIndexChangeHandler);
+        }
+        removeFocusables(o, false);
+    }
+
+    /**
+     *  @private
+     */
+    private function removeFocusables(o:DisplayObject, 
dontRemoveTabChildrenHandler:Boolean):void
+    {
+        var i:int;
+        if (o is DisplayObjectContainer)
+        {
+            if (!dontRemoveTabChildrenHandler)
+            {
+                o.removeEventListener("tabChildrenChange", 
tabChildrenChangeHandler);
+                o.removeEventListener("hasFocusableChildrenChange", 
hasFocusableChildrenChangeHandler);
+            }
+
+            for (i = 0; i < focusableObjects.length; i++)
+            {
+                if (isParent(DisplayObjectContainer(o), focusableObjects[i]))
+                {
+                    /*
+                    if (focusableObjects[i] == _lastFocus)
+                    {
+                        _lastFocus.drawFocus(false);
+                        _lastFocus = null;
+                    }
+                    */
+                    // trace("FM removed " + focusableObjects[i]);
+                    focusableObjects[i].removeEventListener(
+                        "tabFocusEnabledChange", tabFocusEnabledChangeHandler);
+                    focusableObjects[i].removeEventListener(
+                        "tabIndexChange", tabIndexChangeHandler);
+                    focusableObjects.splice(i, 1);
+                    i = i - 1;  // because increment would skip one
+                    
+                    focusableCandidates = [];
+                    calculateCandidates = true;                 
+                }
+            }
+        }
+    }
+
+    /**
+     *  @private
+     */
+    private function showHandler(event:Event):void
+    {
+        /*
+               var awm:IActiveWindowManager = 
+                       
IActiveWindowManager(form.systemManager.getImplementation("mx.managers::IActiveWindowManager"));
+               if (awm)
+               awm.activate(form); // build a message that does the equal
+        */
+    }
+
+    /**
+     *  @private
+     */
+    private function hideHandler(event:Event):void
+    {
+        /*
+               var awm:IActiveWindowManager = 
+                       
IActiveWindowManager(form.systemManager.getImplementation("mx.managers::IActiveWindowManager"));
+               if (awm)
+               awm.deactivate(form); // build a message that does the equal
+        */
+    }
+
+    /**
+     *  @private
+     */
+    private function childHideHandler(event:Event):void
+    {
+        var target:DisplayObject = DisplayObject(event.target);
+        // trace("FocusManager focusInHandler in  = " + 
this._form.systemManager.loaderInfo.url);
+        // trace("FM " + this + " focusInHandler " + target);
+
+        if (lastFocus && !isEnabledAndVisible(DisplayObject(lastFocus)) && 
DisplayObject(form).stage)
+        {
+            DisplayObject(form).stage.focus = null;
+            lastFocus = null;
+        }
+    }
+    
+    /**
+     *  @private
+     */
+    private function viewHideHandler(event:Event):void
+    {
+        // Target is the active view that is about to be hidden
+        var target:DisplayObjectContainer = event.target as 
DisplayObjectContainer;
+        var lastFocusDO:DisplayObject = lastFocus as DisplayObject;
+       
+        // If the lastFocus is in the view about to be hidden, clear focus
+        if (target && lastFocusDO && target.contains(lastFocusDO))
+            lastFocus = null;
+    }
+
+    /**
+     *  @private
+     */
+    private function creationCompleteHandler(event:FlexEvent):void
+    {
+        /*
+        var o:DisplayObject = DisplayObject(form);
+        if (o.parent && o.visible && !activated)
+               {
+                       var awm:IActiveWindowManager = 
+                               
IActiveWindowManager(form.systemManager.getImplementation("mx.managers::IActiveWindowManager"));
+                       if (awm)
+                       awm.activate(form); // build a message that does the 
equal
+               }
+        */
+    }
+
+    /**
+     *  @private
+     *  Add or remove if tabbing properties change.
+     */
+    private function tabIndexChangeHandler(event:Event):void
+    {
+        calculateCandidates = true;
+    }
+
+    /**
+     *  @private
+     *  Add or remove if tabbing properties change.
+     */
+    private function tabFocusEnabledChangeHandler(event:Event):void
+    {
+        calculateCandidates = true;
+
+        var o:IFocusManagerComponent = IFocusManagerComponent(event.target);
+        var n:int = focusableObjects.length;
+        for (var i:int = 0; i < n; i++)
+        {
+            if (focusableObjects[i] == o)
+                break;
+        }
+        if (o.tabFocusEnabled)
+        {
+            if (i == n && isTabVisible(DisplayObject(o)))
+            {
+                // trace("FM tpc added " + o);
+                // add it if were not already
+                       if (focusableObjects.indexOf(o) == -1)
+                       focusableObjects.push(o);
+            }
+        }
+        else
+        {
+            // remove it
+            if (i < n)
+            {
+                // trace("FM tpc removed " + o);
+                focusableObjects.splice(i, 1);
+            }
+        }
+    }
+
+    /**
+     *  @private
+     *  Add or remove if tabbing properties change.
+     */
+    private function tabChildrenChangeHandler(event:Event):void
+    {
+        if (event.target != event.currentTarget)
+            return;
+
+        calculateCandidates = true;
+
+        var o:DisplayObjectContainer = DisplayObjectContainer(event.target);
+        if (o.tabChildren)
+        {
+            addFocusables(o, true);
+        }
+        else
+        {
+            removeFocusables(o, true);
+        }
+    }
+
+    /**
+     *  @private
+     *  Add or remove if tabbing properties change.
+     */
+    private function hasFocusableChildrenChangeHandler(event:Event):void
+    {
+        if (event.target != event.currentTarget)
+            return;
+
+        calculateCandidates = true;
+
+        var o:IFocusManagerComponent = IFocusManagerComponent(event.target);
+        if (o.hasFocusableChildren)
+        {
+            addFocusables(DisplayObject(o), true);
+        }
+        else
+        {
+            removeFocusables(DisplayObject(o), true);
+        }
+    }
+
+    /**
+     *  @private
+     *  This gets called when mouse clicks on a focusable object.
+     *  We block player behavior
+     */
+    private function mouseFocusChangeHandler(event:FocusEvent):void
+    {
+        // trace("FocusManager: mouseFocusChangeHandler  in  = " + 
this._form.systemManager.loaderInfo.url);
+       // trace("FocusManager: mouseFocusChangeHandler " + event);
+        
+        if (event.isDefaultPrevented())
+            return;
+
+        // If relatedObject is null because we don't have access to the 
+        // object getting focus then allow the Player to set focus
+        // to the object. The isRelatedObjectInaccessible property is 
+        // Player 10 only so we have to test if it is available. We
+        // will only see isRelatedObjectInaccessible if we are a version "10" 
swf
+        // (-target-player=10). Version "9" swfs will not see the property
+        // even if running in Player 10.
+        if (event.relatedObject == null && 
+            "isRelatedObjectInaccessible" in event &&
+            event["isRelatedObjectInaccessible"] == true)
+        {
+            // lost focus to a control in different sandbox.
+            return;
+        }
+        
+        if (event.relatedObject is TextField)
+        {
+            var tf:TextField = event.relatedObject as TextField;
+            if (tf.type == "input" || tf.selectable)
+            {
+                return; // pass it on
+            }
+        }
+
+        event.preventDefault();
+    }
+
+    /**
+     *  @private
+     *  This gets called when the tab key is hit.
+     */
+    mx_internal function keyFocusChangeHandler(event:FocusEvent):void
+    {
+        // trace("keyFocusChangeHandler handled by " + this);
+       // trace("keyFocusChangeHandler event = " + event);
+       
+       var sm:ISystemManager = form.systemManager;
+
+        if (hasEventListener("keyFocusChange"))
+               if (!dispatchEvent(new FocusEvent("keyFocusChange", false, 
true, InteractiveObject(event.target))))
+                       return;
+
+        showFocusIndicator = true;
+               focusChanged = false;
+
+        var haveBrowserFocusComponent:Boolean = (browserFocusComponent != 
null);
+        if (browserFocusComponent)
+            clearBrowserFocusComponent();
+        
+        // see if we got here from a tab.  We also need to check for 
+        // keyCode == 0 because in IE sometimes the first time you tab 
+        // in to the flash player, you get keyCode == 0 instead of TAB.
+        // Flash Player bug #2295688.
+        if ((event.keyCode == Keyboard.TAB || (browserMode && event.keyCode == 
0)) 
+                && !event.isDefaultPrevented())
+        {
+            if (haveBrowserFocusComponent)
+            {
+                if (hasEventListener("browserFocusComponent"))
+                               dispatchEvent(new 
FocusEvent("browserFocusComponent", false, false, 
InteractiveObject(event.target)));
+                               
+                return;
+            }
+
+            /*
+            if (ieshifttab && lastAction == "ACTIVATE")
+            {
+                // IE seems to now require that we set focus to something 
during activate
+                // but then we get this keyFocusChange event.  I think we used 
to not
+                // need to set focus on activate and we still got the 
keyFocusChange
+                // and then stage.focus was null and we'd use the 
keyFocusChange event
+                // to determine which control (first or last) got focus based 
on
+                // the shift key.
+                // If we set focus on activate, then we get this 
keyFocusChange which moves
+                // the focus somewhere else, so we set fauxFocus to the stage 
as a signal
+                // to the setFocusToNextObject logic that it shouldn't use the 
stage.focus
+                // as the starting point.
+                fauxFocus = sm.stage;
+            }
+            */
+            // trace("tabHandled by " + this);
+            setFocusToNextObject(event);
+            if (ieshifttab && lastAction == "ACTIVATE")
+            {
+                fauxFocus = null;
+            }
+
+            // if we changed focus or if we're the main app
+            // eat the event
+            /*
+                       if (focusChanged || sm == sm.getTopLevelRoot())
+               event.preventDefault();
+            */
+        }
+    }
+
+    /**
+     *  @private
+     *  Watch for TAB keys.
+     */
+    mx_internal function keyDownHandler(event:KeyboardEvent):void
+    {
+        // trace("onKeyDown handled by " + this);
+       // trace("onKeyDown event = " + event);
+               // if the target is in a bridged application, let it handle the 
click.
+               var sm:ISystemManager = form.systemManager;
+
+        if (hasEventListener("keyDownFM"))
+               if (!dispatchEvent(new FocusEvent("keyDownFM", false, true, 
InteractiveObject(event.target))))
+                       return;
+
+        /*
+        if (sm is SystemManager)
+            SystemManager(sm).idleCounter = 0;
+        */
+        
+        if (event.keyCode == Keyboard.TAB)
+        {
+            lastAction = "KEY";
+
+            // I think we'll have time to do this here instead of at creation 
time
+            // this makes and orders the focusableCandidates array
+            if (calculateCandidates)
+            {
+                sortFocusableObjects();
+                calculateCandidates = false;
+            }
+        }
+
+        /*
+        if (browserMode)
+        {
+            if (browserFocusComponent)
+                clearBrowserFocusComponent();
+            
+            if (event.keyCode == Keyboard.TAB && focusableCandidates.length > 
0)
+            {
+                // get the object that has the focus
+                var o:DisplayObject = fauxFocus;
+                               if (!o)
+                               {
+                                       o = form.systemManager.stage.focus;
+                               }
+                               
+                // trace("focus was at " + o);
+                // trace("focusableObjects " + focusableObjects.length);
+                o = 
DisplayObject(findFocusManagerComponent2(InteractiveObject(o)));
+                var g:String = "";
+                if (o is IFocusManagerGroup)
+                {
+                    var tg:IFocusManagerGroup = IFocusManagerGroup(o);
+                    g = tg.groupName;
+                }
+
+                var i:int = getIndexOfFocusedObject(o);
+                var j:int = getIndexOfNextObject(i, event.shiftKey, false, g);
+                if (event.shiftKey)
+                {
+                    if (j >= i)
+                    {
+                        // we wrapped so let browser have it
+                        browserFocusComponent = 
getBrowserFocusComponent(event.shiftKey);
+                        if (browserFocusComponent.tabIndex == -1)
+                            browserFocusComponent.tabIndex = 0;
+                    }
+                }
+                else
+                {
+                    if (j <= i)
+                    {
+                        // we wrapped so let browser have it
+                        browserFocusComponent = 
getBrowserFocusComponent(event.shiftKey);
+                        if (browserFocusComponent.tabIndex == -1)
+                            browserFocusComponent.tabIndex = LARGE_TAB_INDEX;
+                    }
+                }
+            }
+        }
+        */
+    }
+
+    /**
+     *  @private
+     *  Watch for ENTER key.
+    private function defaultButtonKeyHandler(event:KeyboardEvent):void
+    {        
+        var sm:ISystemManager = form.systemManager;
+        if (hasEventListener("defaultButtonKeyHandler"))
+               if (!dispatchEvent(new FocusEvent("defaultButtonKeyHandler", 
false, true)))
+                       return;
+            
+        if (defaultButtonEnabled && event.keyCode == Keyboard.ENTER &&
+                       defButton && defButton.enabled)
+        {
+            sendDefaultButtonEvent();
+       }
+    }
+     */
+
+    /**
+     *  @private
+     *  This gets called when the focus changes due to a mouse click.
+     *
+     *  Note: If the focus is changing to a TextField, we don't call
+     *  setFocus() on it because the player handles it;
+     *  calling setFocus() on a TextField which has scrollable text
+     *  causes the text to autoscroll to the end, making the
+     *  mouse click set the insertion point in the wrong place.
+     */
+    private function mouseDownCaptureHandler(event:MouseEvent):void
+    {
+        // trace("FocusManager mouseDownCaptureHandler in  = " + 
this._form.systemManager.loaderInfo.url);
+        // trace("FocusManager mouseDownCaptureHandler target " + 
event.target);
+        showFocusIndicator = false;
+    }
+
+    /**
+     *  @private
+     *  This gets called when the focus changes due to a mouse click.
+     *
+     *  Note: If the focus is changing to a TextField, we don't call
+     *  setFocus() on it because the player handles it;
+     *  calling setFocus() on a TextField which has scrollable text
+     *  causes the text to autoscroll to the end, making the
+     *  mouse click set the insertion point in the wrong place.
+     */
+    private function mouseDownHandler(event:MouseEvent):void
+    {
+        // trace("FocusManager mouseDownHandler in  = " + 
this._form.systemManager.loaderInfo.url);
+        // trace("FocusManager mouseDownHandler target " + event.target);
+        
+               // if the target is in a bridged application, let it handle the 
click.
+               var sm:ISystemManager = form.systemManager;
+        var o:DisplayObject = getTopLevelFocusTarget(
+            InteractiveObject(event.target));
+
+        if (!o)
+            return;
+
+        // trace("FocusManager mouseDownHandler on " + o);
+        
+        // Make sure the containing component gets notified.
+        // As the note above says, we don't set focus to a TextField ever
+        // because the player already did and took care of where
+        // the insertion point is, and we also don't call setfocus
+        // on a component that last the last focused object unless
+        // the last action was just to activate the player and didn't
+        // involve tabbing or clicking on a component
+        if ((o != _lastFocus || lastAction == "ACTIVATE") && !(o is TextField))
+            setFocus(IFocusManagerComponent(o));
+               else if (_lastFocus)
+               {
+                       // trace("FM: skipped setting focus to " + _lastFocus);
+               }
+               
+        if (hasEventListener("mouseDownFM"))
+               dispatchEvent(new FocusEvent("mouseDownFM", false, false, 
InteractiveObject(o)));
+
+        lastAction = "MOUSEDOWN";
+       
+    }
+       
+    /*
+       private function 
getBrowserFocusComponent(shiftKey:Boolean):InteractiveObject
+       {
+       var focusComponent:InteractiveObject = form.systemManager.stage.focus;
+               
+               // if the focus is null it means focus is in an application we
+               // don't have access to. Use either the last object or the first
+               // object in this focus manager's list.
+               if (!focusComponent)
+               {
+                       var index:int = shiftKey ? 0 : 
focusableCandidates.length - 1;
+                       focusComponent = focusableCandidates[index];
+               }
+               
+               return focusComponent;
+    }
+    */
+}
+
+COMPILE::JS
+public class FocusManager extends EventDispatcher implements IFocusManager
+{
+    public function FocusManager(container:IFocusManagerContainer, 
popup:Boolean = false)
+    {
+        super();
+        
+        form = container;
+        form.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownCaptureHandler, 
true); 
+    }
+    
+    private var form:IFocusManagerContainer;
+    
+    private function mouseDownCaptureHandler(event:MouseEvent):void
+    {
+        var target:Object = event.target;
+        if (target is UIComponent)
+            target["element"].focus();
+    }
+}
+
+}
+
+COMPILE::SWF
+{
+import flash.display.DisplayObject;
+}
+
+/** 
+ * @private
+ * 
+ *  Plain old class to return multiple items of info about the potential
+ *  change in focus.
+ */
+COMPILE::SWF
+class FocusInfo
+{
+       public var displayObject:DisplayObject; // object to get focus
+       public var wrapped:Boolean;                             // true if 
focus wrapped around
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IActiveWindowManager.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IActiveWindowManager.as
new file mode 100644
index 0000000..2c36b0c
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IActiveWindowManager.as
@@ -0,0 +1,100 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 mx.managers.IFocusManagerContainer;
+
+[ExcludeClass]
+
+/**
+ *  Interface for subsystem that manages which focus manager is active
+ *  when there is more than one IFocusManagerContainer on screen.
+ */
+public interface IActiveWindowManager
+{
+       
//--------------------------------------------------------------------------
+       //
+       //  Properties
+       //
+       
//--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  numModalWindows
+    //----------------------------------
+
+       /**
+        *  The number of modal windows.  
+        *
+        *  <p>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 destroy modal windows.</p>
+        */
+       function get numModalWindows():int;
+
+       /**
+        *  @private
+        */
+       function set numModalWindows(value:int):void;
+
+
+       
//--------------------------------------------------------------------------
+       //
+       //  Methods
+       //
+       
//--------------------------------------------------------------------------
+
+       /**
+        *  Registers a top-level window containing a FocusManager.
+        *  Called by the FocusManager, generally not called by application 
code.
+        *
+        *  @param f The top-level window in the application.
+        */
+       function addFocusManager(f:IFocusManagerContainer):void;
+
+       /**
+        *  Unregisters a top-level window containing a FocusManager.
+        *  Called by the FocusManager, generally not called by application 
code.
+        *
+        *  @param f The top-level window in the application.
+        */
+       function removeFocusManager(f:IFocusManagerContainer):void;
+
+       /**
+        *  Activates the FocusManager in an IFocusManagerContainer.
+        * 
+        *  @param f IFocusManagerContainer the top-level window
+        *  whose FocusManager should be activated.
+        */
+       function activate(f:Object):void;
+       
+       /**
+        *  Deactivates the FocusManager in an IFocusManagerContainer, and 
activate
+        *  the FocusManager of the next highest window that is an 
IFocusManagerContainer.
+        * 
+        *  @param f IFocusManagerContainer the top-level window
+        *  whose FocusManager should be deactivated.
+        */
+       function deactivate(f:Object):void;
+
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerComplexComponent.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerComplexComponent.as
new file mode 100644
index 0000000..c6400ee
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerComplexComponent.as
@@ -0,0 +1,82 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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
+{
+
+/**
+ *  The IFocusManagerComplexComponent interface defines the interface 
+ *  that components that can have more than one internal focus target
+ *  should implement in order to
+ *  receive focus from the FocusManager.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public interface IFocusManagerComplexComponent extends IFocusManagerComponent
+{
+       
//--------------------------------------------------------------------------
+       //
+       //  Properties
+       //
+       
//--------------------------------------------------------------------------
+
+       //----------------------------------
+       //  hasFocusableContent
+       //----------------------------------
+
+       /**
+        *  A flag that indicates whether the component currently has internal
+        *  focusable targets
+        * 
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+       function get hasFocusableContent():Boolean;
+       
+       
//--------------------------------------------------------------------------
+       //
+       //  Methods
+       //
+       
//--------------------------------------------------------------------------
+
+       /**
+        *  Called by the FocusManager when the component receives focus.
+        *  The component may in turn set focus to an internal component.
+        *  The components setFocus() method will still be called when focused 
by
+        *  the mouse, but this method will be used when focus changes via the
+        *  keyboard
+        *
+        *  @param direction "bottom" if TAB used with SHIFT key, "top" 
otherwise
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+       function assignFocus(direction:String):void;
+
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerComponent.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerComponent.as
new file mode 100644
index 0000000..a9087df
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerComponent.as
@@ -0,0 +1,193 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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
+{
+
+/**
+ *  The IFocusManagerComponent interface defines the interface 
+ *  that focusable components must implement in order to
+ *  receive focus from the FocusManager.
+ *  The base implementations of this interface are in the UIComponent class, 
+ *  but UIComponent does not implement the full IFocusManagerComponent 
interface 
+ *  since some UIComponents are not intended to receive focus.
+ *  Therefore, to make a UIComponent-derived component be a valid focusable
+ *  component, you simply add "implements IFocusManagerComponent" to the class
+ *  definition.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public interface IFocusManagerComponent
+{
+    
//--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    
//--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  focusEnabled
+    //----------------------------------
+
+    /**
+     *  A flag that indicates whether the component can receive focus when 
selected.
+     * 
+     *  <p>As an optimization, if a child component in your component 
+     *  implements the IFocusManagerComponent interface, and you
+     *  never want it to receive focus,
+     *  you can set <code>focusEnabled</code>
+     *  to <code>false</code> before calling <code>addChild()</code>
+     *  on the child component.</p>
+     * 
+     *  <p>This will cause the FocusManager to ignore this component
+     *  and not monitor it for changes to the <code>tabFocusEnabled</code>,
+     *  <code>hasFocusableChildren</code>, and <code>mouseFocusEnabled</code> 
properties.
+     *  This also means you cannot change this value after
+     *  <code>addChild()</code> and expect the FocusManager to notice.</p>
+     *
+     *  <p>Note: It does not mean that you cannot give this object focus
+     *  programmatically in your <code>setFocus()</code> method;
+     *  it just tells the FocusManager to ignore this IFocusManagerComponent
+     *  component in the Tab and mouse searches.</p>
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    function get focusEnabled():Boolean;
+    
+    /**
+     *  @private
+     */
+    function set focusEnabled(value:Boolean):void;
+
+    //----------------------------------
+    //  hasFocusableChildren
+    //----------------------------------
+
+    /**
+     *  @copy mx.core.UIComponent#hasFocusableChildren
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    function get hasFocusableChildren():Boolean;
+    
+    /**
+     *  @private
+     */
+    function set hasFocusableChildren(value:Boolean):void;
+
+    //----------------------------------
+    //  mouseFocusEnabled
+    //----------------------------------
+
+    /**
+     *  A flag that indicates whether the component can receive focus 
+     *  when selected with the mouse.
+     *  If <code>false</code>, focus will be transferred to
+     *  the first parent that is <code>mouseFocusEnabled</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    //function get mouseFocusEnabled():Boolean;
+
+    //----------------------------------
+    //  tabFocusEnabled
+    //----------------------------------
+
+    /**
+     *  A flag that indicates whether pressing the Tab key eventually 
+     *  moves focus to this component.
+     *  Even if <code>false</code>, you can still be given focus
+     *  by being selected with the mouse or via a call to
+     *  <code>setFocus()</code>.  This property replaces 
+     *  InteractiveObject.tabEnabled which must be set to true
+     *  in Flex apps.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 10
+     *  @playerversion AIR 1.5
+     *  @productversion Flex 4
+     */
+    function get tabFocusEnabled():Boolean;
+
+    //----------------------------------
+    //  tabIndex
+    //----------------------------------
+
+    /**
+     *  If <code>tabFocusEnabled</code>, the order in which the component 
receives focus.
+     *  If -1, then the component receives focus based on z-order.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    function get tabIndex():int;
+
+    /**
+     *  @private
+     */
+    function set tabIndex(value:int):void;
+
+    
//--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  Called by the FocusManager when the component receives focus.
+     *  The component may in turn set focus to an internal component.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    function setFocus():void;
+
+    /**
+     *  Called by the FocusManager when the component receives focus.
+     *  The component should draw or hide a graphic 
+     *  that indicates that the component has focus.
+     *
+     *  @param isFocused If <code>true</code>, draw the focus indicator,
+     *  otherwise hide it.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    //function drawFocus(isFocused:Boolean):void;
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerContainer.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerContainer.as
new file mode 100644
index 0000000..def7434
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerContainer.as
@@ -0,0 +1,129 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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 org.apache.royale.events.IEventDispatcher;
+import mx.core.IFlexDisplayObject;
+import mx.managers.IFocusManager;
+import mx.managers.ISystemManager;
+
+/**
+ *  The IFocusManagerContainer interface defines the interface that 
+ *  containers implement to host a FocusManager.
+ *  The PopUpManager automatically installs a FocusManager
+ *  in any IFocusManagerContainer it pops up.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public interface IFocusManagerContainer extends IEventDispatcher 
+{
+    
//--------------------------------------------------------------------------
+    //
+    //  Properties
+    //
+    
//--------------------------------------------------------------------------
+
+    //----------------------------------
+    //  focusManager
+    //----------------------------------
+
+    /**
+     *  The FocusManager for this component. 
+     *  The FocusManager must be in a <code>focusManager</code> property.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    function get focusManager():IFocusManager;
+    
+    /**
+     *  @private
+     */
+    function set focusManager(value:IFocusManager):void;
+
+    //----------------------------------
+    //  defaultButton
+    //----------------------------------
+    
+    /**
+     *  The Button control designated as the default button
+     *  for the container.
+     *  When controls in the container have focus, pressing the
+     *  Enter key is the same as clicking this Button control.
+     *
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     *  @default null
+     */
+    //function get defaultButton():IFlexDisplayObject;
+    
+    /**
+     *  @private
+     */
+    //function set defaultButton(value:IFlexDisplayObject):void;
+    
+    //----------------------------------
+    //  systemManager
+    //----------------------------------
+
+    /**
+     *  @copy mx.core.UIComponent#systemManager
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    function get systemManager():ISystemManager;
+
+    
//--------------------------------------------------------------------------
+    //
+    //  Methods
+    //
+    
//--------------------------------------------------------------------------
+
+    /**
+     *  Determines whether the specified display object is a child 
+     *  of the container instance or the instance itself. 
+     *  The search includes the entire display list including this container 
instance. 
+     *  Grandchildren, great-grandchildren, and so on each return 
<code>true</code>.
+     *
+     *  @param child The child object to test.
+     *
+     *  @return <code>true</code> if the child object is a child of the 
container 
+     *  or the container itself; otherwise <code>false</code>.
+     *  
+     *  @langversion 3.0
+     *  @playerversion Flash 9
+     *  @playerversion AIR 1.1
+     *  @productversion Flex 3
+     */
+    //function contains(child:DisplayObject):Boolean;
+}
+
+}
diff --git 
a/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerGroup.as
 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerGroup.as
new file mode 100644
index 0000000..97192bd
--- /dev/null
+++ 
b/frameworks/projects/MXRoyale/src/main/royale/mx/managers/IFocusManagerGroup.as
@@ -0,0 +1,85 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+//  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
+{
+
+/**
+ *  The IFocusManagerGroup interface defines the interface that 
+ *  any component must implement if it is grouped in sets,
+ *  where only one member of the set can be selected at any given time.
+ *  For example, a RadioButton implements IFocusManagerGroup
+ *  because a set of RadioButtons in the same group 
+ *  can only have one RadioButton selected at any one time,
+ *  and the FocusManager will make sure not to give focus to the RadioButtons
+ *  that are not selected in response to moving focus via the Tab key.
+ *  
+ *  @langversion 3.0
+ *  @playerversion Flash 9
+ *  @playerversion AIR 1.1
+ *  @productversion Flex 3
+ */
+public interface IFocusManagerGroup
+{
+       
//--------------------------------------------------------------------------
+       //
+       //  Properties
+       //
+       
//--------------------------------------------------------------------------
+
+       //----------------------------------
+       //  groupName
+       //----------------------------------
+
+       /**
+        *      The name of the group of controls to which the control belongs.
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+       function get groupName():String;
+
+       /**
+        *  @private
+        */
+       function set groupName(value:String):void;
+
+       //----------------------------------
+       //  selected
+       //----------------------------------
+
+       /**
+        *      A flag that indicates whether this control is selected.
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+       function get selected():Boolean;
+
+       /**
+        *  @private
+        */
+       function set selected(value:Boolean):void;
+}
+
+}

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to