public FocusChangeDirection GetFocusChangeDirection(Focusable currentFocusable, EventBase e)
        {
            FocusChangeDirection result;

            if (currentFocusable is IMGUIContainer && e.imguiEvent != null)
            {
                result = FocusChangeDirection.none;
            }
            else
            {
                if (e.GetEventTypeId() == EventBase <KeyDownEvent> .TypeId())
                {
                    KeyDownEvent   keyDownEvent = e as KeyDownEvent;
                    EventModifiers modifiers    = keyDownEvent.modifiers;
                    if (keyDownEvent.character == '\t')
                    {
                        if (currentFocusable == null)
                        {
                            result = FocusChangeDirection.none;
                            return(result);
                        }
                        if ((modifiers & EventModifiers.Shift) == EventModifiers.None)
                        {
                            result = VisualElementFocusChangeDirection.right;
                            return(result);
                        }
                        result = VisualElementFocusChangeDirection.left;
                        return(result);
                    }
                }
                result = FocusChangeDirection.none;
            }
            return(result);
        }
Example #2
0
 private static void AboutToReleaseFocus(Focusable focusable, Focusable willGiveFocusTo, FocusChangeDirection direction)
 {
     using (FocusOutEvent pooled = FocusEventBase <FocusOutEvent> .GetPooled(focusable, willGiveFocusTo, direction))
     {
         UIElementsUtility.eventDispatcher.DispatchEvent(pooled, null);
     }
 }
Example #3
0
 private static void AboutToGrabFocus(Focusable focusable, Focusable willTakeFocusFrom, FocusChangeDirection direction)
 {
     using (FocusInEvent pooled = FocusEventBase <FocusInEvent> .GetPooled(focusable, willTakeFocusFrom, direction))
     {
         UIElementsUtility.eventDispatcher.DispatchEvent(pooled, null);
     }
 }
        public FocusChangeDirection GetFocusChangeDirection(Focusable currentFocusable, EventBase e)
        {
            FocusChangeDirection none;

            if (currentFocusable is IMGUIContainer && e.imguiEvent != null)
            {
                none = FocusChangeDirection.none;
            }
            else
            {
                if (e.GetEventTypeId() == EventBase <KeyDownEvent> .TypeId())
                {
                    KeyDownEvent   keyDownEvent = e as KeyDownEvent;
                    EventModifiers modifiers    = keyDownEvent.modifiers;
                    if (keyDownEvent.keyCode == KeyCode.Tab)
                    {
                        if (currentFocusable == null)
                        {
                            return(FocusChangeDirection.none);
                        }
                        if ((modifiers & EventModifiers.Shift) == EventModifiers.None)
                        {
                            return(VisualElementFocusChangeDirection.right);
                        }
                        return(VisualElementFocusChangeDirection.left);
                    }
                }
                none = FocusChangeDirection.none;
            }
            return(none);
        }
        private static void GrabFocus(Focusable focusable, Focusable willTakeFocusFrom, FocusChangeDirection direction)
        {
            FocusEvent pooled = FocusEventBase <FocusEvent> .GetPooled(focusable, willTakeFocusFrom, direction);

            UIElementsUtility.eventDispatcher.DispatchEvent(pooled, null);
            EventBase <FocusEvent> .ReleasePooled(pooled);
        }
Example #6
0
        void SwitchFocus(Focusable newFocusedElement, FocusChangeDirection direction)
        {
            if (newFocusedElement == focusedElement)
            {
                return;
            }

            var oldFocusedElement = focusedElement;

            if (newFocusedElement == null || !newFocusedElement.canGrabFocus)
            {
                if (oldFocusedElement != null)
                {
                    AboutToReleaseFocus(oldFocusedElement, newFocusedElement, direction);
                    ReleaseFocus(oldFocusedElement, newFocusedElement, direction);
                }
            }
            else if (newFocusedElement != oldFocusedElement)
            {
                if (oldFocusedElement != null)
                {
                    AboutToReleaseFocus(oldFocusedElement, newFocusedElement, direction);
                }

                AboutToGrabFocus(newFocusedElement, oldFocusedElement, direction);

                if (oldFocusedElement != null)
                {
                    ReleaseFocus(oldFocusedElement, newFocusedElement, direction);
                }

                GrabFocus(newFocusedElement, oldFocusedElement, direction);
            }
        }
        private static void ReleaseFocus(Focusable focusable, Focusable willGiveFocusTo, FocusChangeDirection direction)
        {
            BlurEvent pooled = FocusEventBase <BlurEvent> .GetPooled(focusable, willGiveFocusTo, direction);

            UIElementsUtility.eventDispatcher.DispatchEvent(pooled, null);
            EventBase <BlurEvent> .ReleasePooled(pooled);
        }
Example #8
0
 void ReleaseFocus(Focusable focusable, Focusable willGiveFocusTo, FocusChangeDirection direction)
 {
     using (BlurEvent e = BlurEvent.GetPooled(focusable, willGiveFocusTo, direction, this))
     {
         focusable.SendEvent(e);
     }
 }
Example #9
0
 void GrabFocus(Focusable focusable, Focusable willTakeFocusFrom, FocusChangeDirection direction)
 {
     using (FocusEvent e = FocusEvent.GetPooled(focusable, willTakeFocusFrom, direction, this))
     {
         focusable.SendEvent(e);
     }
 }
 private void SwitchFocus(Focusable newFocusedElement, FocusChangeDirection direction)
 {
     if (newFocusedElement != this.focusedElement)
     {
         Focusable focusedElement = this.focusedElement;
         if (newFocusedElement == null || !newFocusedElement.canGrabFocus)
         {
             if (focusedElement != null)
             {
                 FocusController.AboutToReleaseFocus(focusedElement, newFocusedElement, direction);
                 this.focusedElement = null;
                 FocusController.ReleaseFocus(focusedElement, newFocusedElement, direction);
             }
         }
         else if (newFocusedElement != focusedElement)
         {
             if (focusedElement != null)
             {
                 FocusController.AboutToReleaseFocus(focusedElement, newFocusedElement, direction);
             }
             FocusController.AboutToGrabFocus(newFocusedElement, focusedElement, direction);
             this.focusedElement = newFocusedElement;
             if (focusedElement != null)
             {
                 FocusController.ReleaseFocus(focusedElement, newFocusedElement, direction);
             }
             FocusController.GrabFocus(newFocusedElement, focusedElement, direction);
         }
     }
 }
 static void GrabFocus(Focusable focusable, Focusable willTakeFocusFrom, FocusChangeDirection direction)
 {
     using (FocusEvent e = FocusEvent.GetPooled(focusable, willTakeFocusFrom, direction))
     {
         UIElementsUtility.eventDispatcher.DispatchEvent(e, null);
     }
 }
 static void ReleaseFocus(Focusable focusable, Focusable willGiveFocusTo, FocusChangeDirection direction)
 {
     using (BlurEvent e = BlurEvent.GetPooled(focusable, willGiveFocusTo, direction))
     {
         UIElementsUtility.eventDispatcher.DispatchEvent(e, null);
     }
 }
        public static T GetPooled(IEventHandler target, Focusable relatedTarget, FocusChangeDirection direction)
        {
            T pooled = EventBase <T> .GetPooled();

            pooled.target        = target;
            pooled.relatedTarget = relatedTarget;
            pooled.direction     = direction;
            return(pooled);
        }
        public void SwitchFocusOnEvent(EventBase e)
        {
            FocusChangeDirection focusChangeDirection = this.focusRing.GetFocusChangeDirection(this.focusedElement, e);

            if (focusChangeDirection != FocusChangeDirection.none)
            {
                Focusable nextFocusable = this.focusRing.GetNextFocusable(this.focusedElement, focusChangeDirection);
                this.SwitchFocus(nextFocusable, focusChangeDirection);
            }
        }
Example #15
0
        public void SwitchFocusOnEvent(EventBase e)
        {
            FocusChangeDirection direction = focusRing.GetFocusChangeDirection(focusedElement, e);

            if (direction != FocusChangeDirection.none)
            {
                Focusable f = focusRing.GetNextFocusable(focusedElement, direction);
                SwitchFocus(f, direction);
            }
        }
Example #16
0
        internal void SyncIMGUIFocus(int imguiKeyboardControlID, Focusable imguiContainerHavingKeyboardControl)
        {
            imguiKeyboardControl = imguiKeyboardControlID;

            if (imguiKeyboardControl != 0)
            {
                SwitchFocus(imguiContainerHavingKeyboardControl, FocusChangeDirection.unspecified);
            }
            else
            {
                SwitchFocus(null, FocusChangeDirection.unspecified);
            }
        }
 private int GetFocusableInternalIndex(Focusable f)
 {
     if (f != null)
     {
         for (int i = 0; i < this.m_FocusRing.Count; i++)
         {
             if (f == this.m_FocusRing[i].m_Focusable)
             {
                 return(i);
             }
         }
     }
     return(-1);
 }
        private int GetFocusableInternalIndex(Focusable f)
        {
            int result;

            if (f != null)
            {
                for (int i = 0; i < this.m_FocusRing.Count; i++)
                {
                    if (f == this.m_FocusRing[i].m_Focusable)
                    {
                        result = i;
                        return(result);
                    }
                }
            }
            result = -1;
            return(result);
        }
        public Focusable GetNextFocusable(Focusable currentFocusable, FocusChangeDirection direction)
        {
            Focusable result;

            if (direction == FocusChangeDirection.none || direction == FocusChangeDirection.unspecified)
            {
                result = currentFocusable;
            }
            else
            {
                this.DoUpdate();
                if (this.m_FocusRing.Count == 0)
                {
                    result = null;
                }
                else
                {
                    int num = 0;
                    if (direction == VisualElementFocusChangeDirection.right)
                    {
                        num = this.GetFocusableInternalIndex(currentFocusable) + 1;
                        if (num == this.m_FocusRing.Count)
                        {
                            num = 0;
                        }
                    }
                    else if (direction == VisualElementFocusChangeDirection.left)
                    {
                        num = this.GetFocusableInternalIndex(currentFocusable) - 1;
                        if (num == -1)
                        {
                            num = this.m_FocusRing.Count - 1;
                        }
                    }
                    result = this.m_FocusRing[num].m_Focusable;
                }
            }
            return(result);
        }
Example #20
0
        public FocusChangeDirection GetFocusChangeDirection(Focusable currentFocusable, EventBase e)
        {
            // FUTURE:
            // We could implement an extendable adapter system to convert event to a focus change direction.
            // This would enable new event sources to change the focus.

            if (currentFocusable as IMGUIContainer != null && e.imguiEvent != null)
            {
                // Let IMGUIContainer manage the focus change.
                return(FocusChangeDirection.none);
            }

            if (e.GetEventTypeId() == KeyDownEvent.TypeId())
            {
                KeyDownEvent   kde       = e as KeyDownEvent;
                EventModifiers modifiers = kde.modifiers;

                if (kde.character == '\t')
                {
                    if (currentFocusable == null)
                    {
                        // Dont start going around a focus ring if there is no current focused element.
                        return(FocusChangeDirection.none);
                    }
                    else if ((modifiers & EventModifiers.Shift) == 0)
                    {
                        return(VisualElementFocusChangeDirection.right);
                    }
                    else
                    {
                        return(VisualElementFocusChangeDirection.left);
                    }
                }
            }

            return(FocusChangeDirection.none);
        }
Example #21
0
        public Focusable GetNextFocusable(Focusable currentFocusable, FocusChangeDirection direction)
        {
            if (direction == FocusChangeDirection.none || direction == FocusChangeDirection.unspecified)
            {
                return(currentFocusable);
            }
            else
            {
                DoUpdate();

                if (m_FocusRing.Count == 0)
                {
                    return(null);
                }

                int index = 0;
                if (direction == VisualElementFocusChangeDirection.right)
                {
                    index = GetFocusableInternalIndex(currentFocusable) + 1;
                    if (index == m_FocusRing.Count)
                    {
                        index = 0;
                    }
                }
                else if (direction == VisualElementFocusChangeDirection.left)
                {
                    index = GetFocusableInternalIndex(currentFocusable) - 1;
                    if (index == -1)
                    {
                        index = m_FocusRing.Count - 1;
                    }
                }

                return(m_FocusRing[index].m_Focusable);
            }
        }
        private void DoOnGUI(Event evt)
        {
            if (m_OnGUIHandler == null ||
                panel == null)
            {
                return;
            }

            // Save the GUIClip count to make sanity checks after calling the OnGUI handler
            int guiClipCount = GUIClip.Internal_GetCount();

            SaveGlobals();

            UIElementsUtility.BeginContainerGUI(cache, evt, this);

            if (evt.type != EventType.Layout)
            {
                if (lostFocus)
                {
                    if (focusController != null)
                    {
                        // We dont want to clear the GUIUtility.keyboardControl if another IMGUIContainer
                        // just set it in the if (receivedFocus) block below. So we only clear it if either
                        //
                        // - there is no focused element
                        // - we are the currently focused element (that would be surprising)
                        // - the currently focused element is not an IMGUIContainer (in this case,
                        //   GUIUtility.keyboardControl should be 0).
                        if (focusController.focusedElement == null || focusController.focusedElement == this || !(focusController.focusedElement is IMGUIContainer))
                        {
                            GUIUtility.keyboardControl           = 0;
                            focusController.imguiKeyboardControl = 0;
                        }
                    }
                    lostFocus = false;
                }

                if (receivedFocus)
                {
                    // If we just received the focus and GUIUtility.keyboardControl is not already one of our control,
                    // set the GUIUtility.keyboardControl to our first or last focusable control.
                    if (focusChangeDirection != FocusChangeDirection.unspecified && focusChangeDirection != FocusChangeDirection.none)
                    {
                        // We assume we are using the VisualElementFocusRing.
                        if (focusChangeDirection == VisualElementFocusChangeDirection.left)
                        {
                            GUIUtility.SetKeyboardControlToLastControlId();
                        }
                        else if (focusChangeDirection == VisualElementFocusChangeDirection.right)
                        {
                            GUIUtility.SetKeyboardControlToFirstControlId();
                        }
                    }
                    receivedFocus        = false;
                    focusChangeDirection = FocusChangeDirection.unspecified;
                    if (focusController != null)
                    {
                        focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                    }
                }
                // We intentionally don't send the NewKeuboardFocus command here since it creates an issue with the AutomatedWindow
                // newKeyboardFocusControlID = GUIUtility.keyboardControl;
            }

            GUIDepth = GUIUtility.Internal_GetGUIDepth();
            EventType originalEventType = Event.current.type;

            bool isExitGUIException = false;

            try
            {
                // On a layout event, we should not try to get the worldTransform... it is dependant on the layout, which is being calculated (thus, not good)
                if (originalEventType != EventType.Layout)
                {
                    Matrix4x4 currentTransform;
                    Rect      clippingRect;
                    GetCurrentTransformAndClip(this, evt, out currentTransform, out clippingRect);

                    // Push UIElements matrix in GUIClip to make mouse position relative to the IMGUIContainer top left
                    using (new GUIClip.ParentClipScope(currentTransform, clippingRect))
                    {
                        m_OnGUIHandler();
                    }
                }
                else
                {
                    m_OnGUIHandler();
                }
            }
            catch (Exception exception)
            {
                // only for layout events: we always intercept any exceptions to not interrupt event processing
                if (originalEventType == EventType.Layout)
                {
                    isExitGUIException = GUIUtility.IsExitGUIException(exception);
                    if (!isExitGUIException)
                    {
                        Debug.LogException(exception);
                    }
                }
                else
                {
                    // rethrow event if not in layout
                    throw;
                }
            }
            finally
            {
                if (evt.type != EventType.Layout)
                {
                    int currentKeyboardFocus = GUIUtility.keyboardControl;
                    int result = GUIUtility.CheckForTabEvent(evt);
                    if (focusController != null)
                    {
                        if (result < 0)
                        {
                            // If CheckForTabEvent returns -1 or -2, we have reach the end/beginning of its control list.
                            // We should switch the focus to the next VisualElement.
                            Focusable currentFocusedElement = focusController.focusedElement;
                            using (KeyDownEvent e = KeyDownEvent.GetPooled('\t', KeyCode.Tab, result == -1 ? EventModifiers.None : EventModifiers.Shift))
                            {
                                focusController.SwitchFocusOnEvent(e);
                            }

                            if (currentFocusedElement == this)
                            {
                                if (focusController.focusedElement == this)
                                {
                                    // We still have the focus. We should cycle around our controls.
                                    if (result == -2)
                                    {
                                        GUIUtility.SetKeyboardControlToLastControlId();
                                    }
                                    else if (result == -1)
                                    {
                                        GUIUtility.SetKeyboardControlToFirstControlId();
                                    }

                                    newKeyboardFocusControlID            = GUIUtility.keyboardControl;
                                    focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                                }
                                else
                                {
                                    // We lost the focus. Set the focused element ID to 0 until next
                                    // IMGUIContainer have a chance to set it to its own control.
                                    // Doing this will ensure we draw ourselves without any focused control.
                                    GUIUtility.keyboardControl           = 0;
                                    focusController.imguiKeyboardControl = 0;
                                }
                            }
                        }
                        else if (result > 0)
                        {
                            // A positive result indicates that the focused control has changed to one of our elements; result holds the control id.
                            focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                            newKeyboardFocusControlID            = GUIUtility.keyboardControl;
                        }
                        else if (result == 0)
                        {
                            // This means the event is not a tab. Synchronize our focus info with IMGUI.
                            if (currentKeyboardFocus != GUIUtility.keyboardControl || originalEventType == EventType.MouseDown)
                            {
                                focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this);
                            }
                        }
                    }

                    // Cache the fact that we have focusable controls or not.
                    hasFocusableControls = GUIUtility.HasFocusableControls();
                }
            }

            // The Event will probably be nuked with the next function call, so we get its type now.
            EventType eventType = Event.current.type;

            UIElementsUtility.EndContainerGUI();
            RestoreGlobals();

            if (!isExitGUIException)
            {
                // This is the same logic as GUIClipState::EndOnGUI
                if (eventType != EventType.Ignore && eventType != EventType.Used)
                {
                    int currentCount = GUIClip.Internal_GetCount();
                    if (currentCount > guiClipCount)
                    {
                        Debug.LogError("GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced)");
                    }
                    else if (currentCount < guiClipCount)
                    {
                        Debug.LogError("GUI Error: You are popping more GUIClips than you are pushing. Make sure they are balanced)");
                    }
                }
            }

            // Clear extraneous GUIClips
            while (GUIClip.Internal_GetCount() > guiClipCount)
            {
                GUIClip.Internal_Pop();
            }

            if (eventType == EventType.Used)
            {
                Dirty(ChangeType.Repaint);
            }
        }
Example #23
0
 private void DoOnGUI(Event evt)
 {
     if (this.m_OnGUIHandler != null && base.panel != null)
     {
         int num = GUIClip.Internal_GetCount();
         this.SaveGlobals();
         UIElementsUtility.BeginContainerGUI(this.cache, evt, this);
         if (evt.type != EventType.Layout)
         {
             if (this.lostFocus)
             {
                 if (this.focusController != null)
                 {
                     if (this.focusController.focusedElement == null || this.focusController.focusedElement == this || !(this.focusController.focusedElement is IMGUIContainer))
                     {
                         GUIUtility.keyboardControl = 0;
                         this.focusController.imguiKeyboardControl = 0;
                     }
                 }
                 this.lostFocus = false;
             }
             if (this.receivedFocus)
             {
                 if (this.focusChangeDirection != FocusChangeDirection.unspecified && this.focusChangeDirection != FocusChangeDirection.none)
                 {
                     if (this.focusChangeDirection == VisualElementFocusChangeDirection.left)
                     {
                         GUIUtility.SetKeyboardControlToLastControlId();
                     }
                     else if (this.focusChangeDirection == VisualElementFocusChangeDirection.right)
                     {
                         GUIUtility.SetKeyboardControlToFirstControlId();
                     }
                 }
                 this.receivedFocus        = false;
                 this.focusChangeDirection = FocusChangeDirection.unspecified;
                 if (this.focusController != null)
                 {
                     this.focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                 }
             }
         }
         this.GUIDepth = GUIUtility.Internal_GetGUIDepth();
         EventType type = Event.current.type;
         bool      flag = false;
         try
         {
             Matrix4x4 objectTransform;
             Rect      clipRect;
             IMGUIContainer.GetCurrentTransformAndClip(this, evt, out objectTransform, out clipRect);
             using (new GUIClip.ParentClipScope(objectTransform, clipRect))
             {
                 this.m_OnGUIHandler();
             }
         }
         catch (Exception exception)
         {
             if (type != EventType.Layout)
             {
                 throw;
             }
             flag = GUIUtility.IsExitGUIException(exception);
             if (!flag)
             {
                 Debug.LogException(exception);
             }
         }
         finally
         {
             if (evt.type != EventType.Layout)
             {
                 int keyboardControl = GUIUtility.keyboardControl;
                 int num2            = GUIUtility.CheckForTabEvent(evt);
                 if (this.focusController != null)
                 {
                     if (num2 < 0)
                     {
                         Focusable focusedElement = this.focusController.focusedElement;
                         using (KeyDownEvent pooled = KeyboardEventBase <KeyDownEvent> .GetPooled('\t', KeyCode.Tab, (num2 != -1) ? EventModifiers.Shift : EventModifiers.None))
                         {
                             this.focusController.SwitchFocusOnEvent(pooled);
                         }
                         if (focusedElement == this)
                         {
                             if (this.focusController.focusedElement == this)
                             {
                                 if (num2 == -2)
                                 {
                                     GUIUtility.SetKeyboardControlToLastControlId();
                                 }
                                 else if (num2 == -1)
                                 {
                                     GUIUtility.SetKeyboardControlToFirstControlId();
                                 }
                                 this.newKeyboardFocusControlID            = GUIUtility.keyboardControl;
                                 this.focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                             }
                             else
                             {
                                 GUIUtility.keyboardControl = 0;
                                 this.focusController.imguiKeyboardControl = 0;
                             }
                         }
                     }
                     else if (num2 > 0)
                     {
                         this.focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                         this.newKeyboardFocusControlID            = GUIUtility.keyboardControl;
                     }
                     else if (num2 == 0)
                     {
                         if (keyboardControl != GUIUtility.keyboardControl || type == EventType.MouseDown)
                         {
                             this.focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this);
                         }
                     }
                 }
                 this.hasFocusableControls = GUIUtility.HasFocusableControls();
             }
         }
         EventType type2 = Event.current.type;
         UIElementsUtility.EndContainerGUI();
         this.RestoreGlobals();
         if (!flag)
         {
             if (type2 != EventType.Ignore && type2 != EventType.Used)
             {
                 int num3 = GUIClip.Internal_GetCount();
                 if (num3 > num)
                 {
                     Debug.LogError("GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced)");
                 }
                 else if (num3 < num)
                 {
                     Debug.LogError("GUI Error: You are popping more GUIClips than you are pushing. Make sure they are balanced)");
                 }
             }
         }
         while (GUIClip.Internal_GetCount() > num)
         {
             GUIClip.Internal_Pop();
         }
         if (type2 == EventType.Used)
         {
             base.Dirty(ChangeType.Repaint);
         }
     }
 }
Example #24
0
 internal void DoFocusChange(Focusable f)
 {
     focusedElement = f;
 }
 internal void SwitchFocus(Focusable newFocusedElement)
 {
     this.SwitchFocus(newFocusedElement, FocusChangeDirection.unspecified);
 }
Example #26
0
        private void DoOnGUI(Event evt, Matrix4x4 worldTransform, Rect clippingRect, bool isComputingLayout = false)
        {
            // Extra checks are needed here because client code might have changed the IMGUIContainer
            // since we enter HandleIMGUIEvent()
            if (m_OnGUIHandler == null ||
                panel == null)
            {
                return;
            }

            // Save the GUIClip count to make sanity checks after calling the OnGUI handler
            int guiClipCount = GUIClip.Internal_GetCount();

            SaveGlobals();

            UIElementsUtility.BeginContainerGUI(cache, evt, this);

            // For the IMGUI, we need to update the GUI.color with the actual play mode tint ...
            // In fact, this is taken from EditorGUIUtility.ResetGUIState().
            // Here, the play mode tint is either white (no tint, or not in play mode) or the right color (if in play mode)
            GUI.color = UIElementsUtility.editorPlayModeTintColor;
            // From now on, Event.current is either evt or a copy of evt.
            // Since Event.current may change while being processed, we do not rely on evt below but use Event.current instead.

            if (Event.current.type != EventType.Layout)
            {
                if (lostFocus)
                {
                    if (focusController != null)
                    {
                        // We dont want to clear the GUIUtility.keyboardControl if another IMGUIContainer
                        // just set it in the if (receivedFocus) block below. So we only clear it if either
                        //
                        // - there is no focused element
                        // - we are the currently focused element (that would be surprising)
                        // - the currently focused element is not an IMGUIContainer (in this case,
                        //   GUIUtility.keyboardControl should be 0).
                        if (focusController.focusedElement == null || focusController.focusedElement == this || !(focusController.focusedElement is IMGUIContainer) || useUIElementsFocusStyle)
                        {
                            GUIUtility.keyboardControl           = 0;
                            focusController.imguiKeyboardControl = 0;
                        }
                    }
                    lostFocus = false;
                }

                if (receivedFocus)
                {
                    // If we just received the focus and GUIUtility.keyboardControl is not already one of our control,
                    // set the GUIUtility.keyboardControl to our first or last focusable control.
                    if (focusChangeDirection != FocusChangeDirection.unspecified && focusChangeDirection != FocusChangeDirection.none)
                    {
                        // We assume we are using the VisualElementFocusRing.
                        if (focusChangeDirection == VisualElementFocusChangeDirection.left)
                        {
                            GUIUtility.SetKeyboardControlToLastControlId();
                        }
                        else if (focusChangeDirection == VisualElementFocusChangeDirection.right)
                        {
                            GUIUtility.SetKeyboardControlToFirstControlId();
                        }
                    }
                    else if (useUIElementsFocusStyle)
                    {
                        // When the direction is not set, this is because we are coming back to this specific IMGUIContainer
                        // with a mean other than TAB, we need to make sure to return to the element that was focused before...
                        if ((focusController == null) || (focusController.imguiKeyboardControl == 0))
                        {
                            GUIUtility.SetKeyboardControlToFirstControlId();
                        }
                        else
                        {
                            GUIUtility.keyboardControl = focusController.imguiKeyboardControl;
                        }
                    }

                    receivedFocus        = false;
                    focusChangeDirection = FocusChangeDirection.unspecified;
                    if (focusController != null)
                    {
                        focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                    }
                }
                // We intentionally don't send the NewKeuboardFocus command here since it creates an issue with the AutomatedWindow
                // newKeyboardFocusControlID = GUIUtility.keyboardControl;
            }

            EventType originalEventType = Event.current.type;

            bool isExitGUIException = false;

            try
            {
                // If we are computing the layout, we should not try to get the worldTransform...
                // it is dependant on the layout, which is being calculated (thus, not good)
                if (!isComputingLayout)
                {
                    // Push UIElements matrix in GUIClip to make mouse position relative to the IMGUIContainer top left
                    using (new GUIClip.ParentClipScope(worldTransform, clippingRect))
                    {
                        m_OnGUIHandler();
                    }
                }
                else
                {
                    m_OnGUIHandler();
                }
            }
            catch (Exception exception)
            {
                // only for layout events: we always intercept any exceptions to not interrupt event processing
                if (originalEventType == EventType.Layout)
                {
                    isExitGUIException = GUIUtility.IsExitGUIException(exception);
                    if (!isExitGUIException)
                    {
                        Debug.LogException(exception);
                    }
                }
                else
                {
                    // rethrow event if not in layout
                    throw;
                }
            }
            finally
            {
                if (Event.current.type != EventType.Layout)
                {
                    int currentKeyboardFocus = GUIUtility.keyboardControl;
                    int result = GUIUtility.CheckForTabEvent(Event.current);
                    if (focusController != null)
                    {
                        if (result < 0)
                        {
                            // If CheckForTabEvent returns -1 or -2, we have reach the end/beginning of its control list.
                            // We should switch the focus to the next VisualElement.
                            Focusable currentFocusedElement = focusController.focusedElement;
                            using (KeyDownEvent e = KeyDownEvent.GetPooled('\t', KeyCode.Tab, result == -1 ? EventModifiers.None : EventModifiers.Shift))
                            {
                                focusController.SwitchFocusOnEvent(e);
                            }

                            if (currentFocusedElement == this)
                            {
                                if (focusController.focusedElement == this)
                                {
                                    // We still have the focus. We should cycle around our controls.
                                    if (result == -2)
                                    {
                                        GUIUtility.SetKeyboardControlToLastControlId();
                                    }
                                    else if (result == -1)
                                    {
                                        GUIUtility.SetKeyboardControlToFirstControlId();
                                    }

                                    newKeyboardFocusControlID            = GUIUtility.keyboardControl;
                                    focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                                }
                                else
                                {
                                    // We lost the focus. Set the focused element ID to 0 until next
                                    // IMGUIContainer have a chance to set it to its own control.
                                    // Doing this will ensure we draw ourselves without any focused control.
                                    GUIUtility.keyboardControl           = 0;
                                    focusController.imguiKeyboardControl = 0;
                                }
                            }
                        }
                        else if (result > 0)
                        {
                            // A positive result indicates that the focused control has changed to one of our elements; result holds the control id.
                            focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                            newKeyboardFocusControlID            = GUIUtility.keyboardControl;
                        }
                        else if (result == 0)
                        {
                            // This means the event is not a tab. Synchronize our focus info with IMGUI.
                            if ((currentKeyboardFocus != GUIUtility.keyboardControl) || (originalEventType == EventType.MouseDown))
                            {
                                focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this);
                            }
                            else if (GUIUtility.keyboardControl != focusController.imguiKeyboardControl)
                            {
                                // Here we want to resynchronize our internal state ...
                                newKeyboardFocusControlID = GUIUtility.keyboardControl;

                                if (focusController.focusedElement == this)
                                {
                                    // In this case, the focused element is the right one in the Focus Controller... we are just updating the internal imguiKeyboardControl
                                    focusController.imguiKeyboardControl = GUIUtility.keyboardControl;
                                }
                                else
                                {
                                    // In this case, the focused element is NOT the right one in the Focus Controller... we also have to refocus...
                                    focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this);
                                }
                            }
                        }
                    }
                    // Cache the fact that we have focusable controls or not.
                    hasFocusableControls = GUIUtility.HasFocusableControls();
                }
            }

            // This will copy Event.current into evt.
            UIElementsUtility.EndContainerGUI(evt);
            RestoreGlobals();

            if (!isExitGUIException)
            {
                // This is the same logic as GUIClipState::EndOnGUI
                if (evt.type != EventType.Ignore && evt.type != EventType.Used)
                {
                    int currentCount = GUIClip.Internal_GetCount();
                    if (currentCount > guiClipCount)
                    {
                        Debug.LogError("GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced.");
                    }
                    else if (currentCount < guiClipCount)
                    {
                        Debug.LogError("GUI Error: You are popping more GUIClips than you are pushing. Make sure they are balanced.");
                    }
                }
            }

            // Clear extraneous GUIClips
            while (GUIClip.Internal_GetCount() > guiClipCount)
            {
                GUIClip.Internal_Pop();
            }

            if (evt.type == EventType.Used)
            {
                IncrementVersion(VersionChangeType.Repaint);
            }
        }