void ReleaseFocus(Focusable focusable, Focusable willGiveFocusTo, FocusChangeDirection direction) { using (BlurEvent e = BlurEvent.GetPooled(focusable, willGiveFocusTo, direction, this)) { focusable.SendEvent(e); } }
internal Focusable FocusNextInDirection(FocusChangeDirection direction) { Focusable f = focusRing.GetNextFocusable(GetLeafFocusedElement(), direction); direction.ApplyTo(this, f); return(f); }
private void ReleaseFocus(Focusable focusable, Focusable willGiveFocusTo, FocusChangeDirection direction) { using (BlurEvent pooled = FocusEventBase <BlurEvent> .GetPooled(focusable, willGiveFocusTo, direction, this, false)) { focusable.SendEvent(pooled); } }
void AboutToReleaseFocus(Focusable focusable, Focusable willGiveFocusTo, FocusChangeDirection direction, DispatchMode dispatchMode) { using (FocusOutEvent e = FocusOutEvent.GetPooled(focusable, willGiveFocusTo, direction, this)) { focusable.SendEvent(e, dispatchMode); } }
void AboutToGrabFocus(Focusable focusable, Focusable willTakeFocusFrom, FocusChangeDirection direction) { using (FocusInEvent e = FocusInEvent.GetPooled(focusable, willTakeFocusFrom, direction, this)) { focusable.SendEvent(e); } }
internal Focusable SwitchFocusOnEvent(EventBase e) { bool processedByFocusController = e.processedByFocusController; Focusable result; if (processedByFocusController) { result = this.GetLeafFocusedElement(); } else { using (FocusChangeDirection focusChangeDirection = this.focusRing.GetFocusChangeDirection(this.GetLeafFocusedElement(), e)) { bool flag = focusChangeDirection != FocusChangeDirection.none; if (flag) { Focusable nextFocusable = this.focusRing.GetNextFocusable(this.GetLeafFocusedElement(), focusChangeDirection); focusChangeDirection.ApplyTo(this, nextFocusable); e.processedByFocusController = true; result = nextFocusable; return(result); } } result = this.GetLeafFocusedElement(); } return(result); }
void GrabFocus(Focusable focusable, Focusable willTakeFocusFrom, FocusChangeDirection direction, bool bIsFocusDelegated = false) { using (FocusEvent e = FocusEvent.GetPooled(focusable, willTakeFocusFrom, direction, this, bIsFocusDelegated)) { focusable.SendEvent(e); } }
public virtual Focusable GetNextFocusable(Focusable currentFocusable, FocusChangeDirection direction) { if (direction == Up || direction == Down || direction == Right || direction == Left) { return(GetNextFocusable2D(currentFocusable, (ChangeDirection)direction)); } return(m_Ring.GetNextFocusable(currentFocusable, direction)); }
protected override void ExecuteDefaultAction(EventBase evt) { bool flag = evt == null; if (!flag) { bool flag2 = evt.eventTypeId == EventBase <BlurEvent> .TypeId(); if (flag2) { this.lostFocus = true; base.IncrementVersion(VersionChangeType.Repaint); } else { bool flag3 = evt.eventTypeId == EventBase <FocusEvent> .TypeId(); if (flag3) { FocusEvent focusEvent = evt as FocusEvent; this.receivedFocus = true; this.focusChangeDirection = focusEvent.direction; this.m_IsFocusDelegated = focusEvent.IsFocusDelegated; } else { bool flag4 = evt.eventTypeId == EventBase <DetachFromPanelEvent> .TypeId(); if (flag4) { bool flag5 = base.elementPanel != null; if (flag5) { BaseVisualElementPanel expr_9F = base.elementPanel; int iMGUIContainersCount = expr_9F.IMGUIContainersCount; expr_9F.IMGUIContainersCount = iMGUIContainersCount - 1; } } else { bool flag6 = evt.eventTypeId == EventBase <AttachToPanelEvent> .TypeId(); if (flag6) { bool flag7 = base.elementPanel != null; if (flag7) { BaseVisualElementPanel expr_DF = base.elementPanel; int iMGUIContainersCount = expr_DF.IMGUIContainersCount; expr_DF.IMGUIContainersCount = iMGUIContainersCount + 1; } } } } } } }
public static T GetPooled(IEventHandler target, Focusable relatedTarget, FocusChangeDirection direction, FocusController focusController, bool bIsFocusDelegated = false) { T pooled = EventBase <T> .GetPooled(); pooled.target = target; pooled.relatedTarget = relatedTarget; pooled.direction = direction; pooled.focusController = focusController; pooled.IsFocusDelegated = bIsFocusDelegated; return(pooled); }
protected override void ExecuteDefaultAction(EventBase evt) { if (evt == null) { return; } // no call to base.ExecuteDefaultAction(evt): // - we dont want mouse click to directly give focus to IMGUIContainer: // they should be handled by IMGUI and if an IMGUI control grabs the // keyboard, the IMGUIContainer will gain focus via FocusController.SyncIMGUIFocus. // - same thing for tabs: IMGUI should handle them. // - we dont want to set the PseudoState.Focus flag on IMGUIContainer. // They are focusable, but only for the purpose of focusing their children. // Here, we set flags that will be acted upon in DoOnGUI(), since we need to change IMGUI state. if (evt.eventTypeId == BlurEvent.TypeId()) { // A lost focus event is ... a lost focus event. // The specific handling of the IMGUI will be done in the DoOnGUI() above... lostFocus = true; // On lost focus, we need to repaint to remove any focused element blue borders. IncrementVersion(VersionChangeType.Repaint); } else if (evt.eventTypeId == FocusEvent.TypeId()) { FocusEvent fe = evt as FocusEvent; receivedFocus = true; focusChangeDirection = fe.direction; m_IsFocusDelegated = fe.IsFocusDelegated; } else if (evt.eventTypeId == DetachFromPanelEvent.TypeId()) { if (elementPanel != null) { elementPanel.IMGUIContainersCount--; } } else if (evt.eventTypeId == AttachToPanelEvent.TypeId()) { if (elementPanel != null) { elementPanel.IMGUIContainersCount++; // Set class names for foldout depth. SetFoldoutDepthClass(); } } }
internal Focusable SwitchFocusOnEvent(EventBase e) { FocusChangeDirection direction = focusRing.GetFocusChangeDirection(GetLeafFocusedElement(), e); if (direction != FocusChangeDirection.none) { Focusable f = focusRing.GetNextFocusable(GetLeafFocusedElement(), direction); SwitchFocus(f, direction); // f does not have the focus yet. It will when the series of focus events will have been handled. return(f); } return(GetLeafFocusedElement()); }
internal void SwitchFocus(Focusable newFocusedElement, FocusChangeDirection direction, bool bIsFocusDelegated = false, DispatchMode dispatchMode = DispatchMode.Default) { m_LastFocusedElement = newFocusedElement; var oldFocusedElement = m_PendingFocusCount > 0 ? m_LastPendingFocusedElement : GetLeafFocusedElement(); if (oldFocusedElement == newFocusedElement) { return; } if (newFocusedElement == null || !newFocusedElement.canGrabFocus) { if (oldFocusedElement != null) { m_LastPendingFocusedElement = null; m_PendingFocusCount++; // ReleaseFocus will always trigger DoFocusChange AboutToReleaseFocus(oldFocusedElement, null, direction, dispatchMode); ReleaseFocus(oldFocusedElement, null, direction, dispatchMode); } } else if (newFocusedElement != oldFocusedElement) { // Retarget event.relatedTarget so it is in the same tree as event.target. var retargetedNewFocusedElement = (newFocusedElement as VisualElement)?.RetargetElement(oldFocusedElement as VisualElement) ?? newFocusedElement; var retargetedOldFocusedElement = (oldFocusedElement as VisualElement)?.RetargetElement(newFocusedElement as VisualElement) ?? oldFocusedElement; m_LastPendingFocusedElement = newFocusedElement; m_PendingFocusCount++; // GrabFocus will always trigger DoFocusChange, but ReleaseFocus won't if (oldFocusedElement != null) { AboutToReleaseFocus(oldFocusedElement, retargetedNewFocusedElement, direction, dispatchMode); } AboutToGrabFocus(newFocusedElement, retargetedOldFocusedElement, direction, dispatchMode); if (oldFocusedElement != null) { // Since retargetedNewFocusedElement != null, so ReleaseFocus will not trigger DoFocusChange ReleaseFocus(oldFocusedElement, retargetedNewFocusedElement, direction, dispatchMode); } GrabFocus(newFocusedElement, retargetedOldFocusedElement, direction, bIsFocusDelegated, dispatchMode); } }
internal void SwitchFocus(Focusable newFocusedElement, FocusChangeDirection direction, bool bIsFocusDelegated = false) { bool flag = this.GetLeafFocusedElement() == newFocusedElement; if (!flag) { Focusable leafFocusedElement = this.GetLeafFocusedElement(); bool flag2 = newFocusedElement == null || !newFocusedElement.canGrabFocus; if (flag2) { bool flag3 = leafFocusedElement != null; if (flag3) { this.AboutToReleaseFocus(leafFocusedElement, null, direction); this.ReleaseFocus(leafFocusedElement, null, direction); } } else { bool flag4 = newFocusedElement != leafFocusedElement; if (flag4) { VisualElement expr_67 = newFocusedElement as VisualElement; VisualElement willGiveFocusTo = (expr_67 != null) ? expr_67.RetargetElement(leafFocusedElement as VisualElement) : null; VisualElement expr_81 = leafFocusedElement as VisualElement; VisualElement willTakeFocusFrom = (expr_81 != null) ? expr_81.RetargetElement(newFocusedElement as VisualElement) : null; bool flag5 = leafFocusedElement != null; if (flag5) { this.AboutToReleaseFocus(leafFocusedElement, willGiveFocusTo, direction); } this.AboutToGrabFocus(newFocusedElement, willTakeFocusFrom, direction); bool flag6 = leafFocusedElement != null; if (flag6) { this.ReleaseFocus(leafFocusedElement, willGiveFocusTo, direction); } this.GrabFocus(newFocusedElement, willTakeFocusFrom, direction, bIsFocusDelegated); } } } }
internal Focusable SwitchFocusOnEvent(EventBase e) { if (e.processedByFocusController) { return(GetLeafFocusedElement()); } using (FocusChangeDirection direction = focusRing.GetFocusChangeDirection(GetLeafFocusedElement(), e)) { if (direction != FocusChangeDirection.none) { Focusable f = FocusNextInDirection(direction); e.processedByFocusController = true; // f does not have the focus yet. It will when the series of focus events will have been handled. return(f); } } return(GetLeafFocusedElement()); }
void SwitchFocus(Focusable newFocusedElement, FocusChangeDirection direction, bool bIsFocusDelegated = false) { if (GetLeafFocusedElement() == newFocusedElement) { return; } var oldFocusedElement = GetLeafFocusedElement(); if (newFocusedElement == null || !newFocusedElement.canGrabFocus) { if (oldFocusedElement != null) { AboutToReleaseFocus(oldFocusedElement, null, direction); ReleaseFocus(oldFocusedElement, null, direction); } } else if (newFocusedElement != oldFocusedElement) { // Retarget event.relatedTarget so it is in the same tree as event.target. var retargetedNewFocusedElement = (newFocusedElement as VisualElement)?.RetargetElement(oldFocusedElement as VisualElement); var retargetedOldFocusedElement = (oldFocusedElement as VisualElement)?.RetargetElement(newFocusedElement as VisualElement); if (oldFocusedElement != null) { AboutToReleaseFocus(oldFocusedElement, retargetedNewFocusedElement, direction); } AboutToGrabFocus(newFocusedElement, retargetedOldFocusedElement, direction); if (oldFocusedElement != null) { ReleaseFocus(oldFocusedElement, retargetedNewFocusedElement, direction); } GrabFocus(newFocusedElement, retargetedOldFocusedElement, direction, bIsFocusDelegated); } }
public Focusable GetNextFocusable(Focusable currentFocusable, FocusChangeDirection direction) { bool flag = direction == FocusChangeDirection.none || direction == FocusChangeDirection.unspecified; Focusable result; if (flag) { result = currentFocusable; } else { VisualElementFocusChangeTarget visualElementFocusChangeTarget = direction as VisualElementFocusChangeTarget; bool flag2 = visualElementFocusChangeTarget != null; if (flag2) { result = visualElementFocusChangeTarget.target; } else { this.DoUpdate(); bool flag3 = this.m_FocusRing.Count == 0; if (flag3) { result = null; } else { int num = 0; bool flag4 = direction == VisualElementFocusChangeDirection.right; if (flag4) { num = this.GetFocusableInternalIndex(currentFocusable) + 1; bool flag5 = currentFocusable != null && num == 0; if (flag5) { result = VisualElementFocusRing.GetNextFocusableInTree(currentFocusable as VisualElement); return(result); } bool flag6 = num == this.m_FocusRing.Count; if (flag6) { num = 0; } while (this.m_FocusRing[num].m_Focusable.delegatesFocus) { num++; bool flag7 = num == this.m_FocusRing.Count; if (flag7) { result = null; return(result); } } } else { bool flag8 = direction == VisualElementFocusChangeDirection.left; if (flag8) { num = this.GetFocusableInternalIndex(currentFocusable) - 1; bool flag9 = currentFocusable != null && num == -2; if (flag9) { result = VisualElementFocusRing.GetPreviousFocusableInTree(currentFocusable as VisualElement); return(result); } bool flag10 = num < 0; if (flag10) { num = this.m_FocusRing.Count - 1; } while (this.m_FocusRing[num].m_Focusable.delegatesFocus) { num--; bool flag11 = num == -1; if (flag11) { result = null; return(result); } } } } result = this.m_FocusRing[num].m_Focusable; } } } return(result); }
private void AboutToGrabFocus(Focusable focusable, Focusable willTakeFocusFrom, FocusChangeDirection direction) { using (FocusInEvent pooled = FocusEventBase <FocusInEvent> .GetPooled(focusable, willTakeFocusFrom, direction, this, false)) { focusable.SendEvent(pooled); } }
private void DoOnGUI(Event evt, Matrix4x4 parentTransform, Rect clippingRect, bool isComputingLayout, Rect layoutSize, Action onGUIHandler, bool canAffectFocus = true) { bool flag = onGUIHandler == null || base.panel == null; if (!flag) { int num = GUIClip.Internal_GetCount(); this.SaveGlobals(); float layoutMeasuredWidth = this.layoutMeasuredWidth; float layoutMeasuredHeight = this.layoutMeasuredHeight; UIElementsUtility.BeginContainerGUI(this.cache, evt, this); GUI.color = UIElementsUtility.editorPlayModeTintColor; bool flag2 = Event.current.type != EventType.Layout; if (flag2) { bool flag3 = this.lostFocus; if (flag3) { bool flag4 = this.focusController != null; if (flag4) { bool flag5 = GUIUtility.OwnsId(GUIUtility.keyboardControl); if (flag5) { GUIUtility.keyboardControl = 0; this.focusController.imguiKeyboardControl = 0; } } this.lostFocus = false; } bool flag6 = this.receivedFocus; if (flag6) { bool flag7 = this.hasFocusableControls; if (flag7) { bool flag8 = this.focusChangeDirection != FocusChangeDirection.unspecified && this.focusChangeDirection != FocusChangeDirection.none; if (flag8) { bool flag9 = this.focusChangeDirection == VisualElementFocusChangeDirection.left; if (flag9) { GUIUtility.SetKeyboardControlToLastControlId(); } else { bool flag10 = this.focusChangeDirection == VisualElementFocusChangeDirection.right; if (flag10) { GUIUtility.SetKeyboardControlToFirstControlId(); } } } else { bool flag11 = GUIUtility.keyboardControl == 0 && this.m_IsFocusDelegated; if (flag11) { GUIUtility.SetKeyboardControlToFirstControlId(); } } } bool flag12 = this.focusController != null; if (flag12) { bool flag13 = this.focusController.imguiKeyboardControl != GUIUtility.keyboardControl && this.focusChangeDirection != FocusChangeDirection.unspecified; if (flag13) { this.newKeyboardFocusControlID = GUIUtility.keyboardControl; } this.focusController.imguiKeyboardControl = GUIUtility.keyboardControl; } this.receivedFocus = false; this.focusChangeDirection = FocusChangeDirection.unspecified; } } EventType type = Event.current.type; bool flag14 = false; try { using (new GUIClip.ParentClipScope(parentTransform, clippingRect)) { onGUIHandler(); } } catch (Exception exception) { bool flag15 = type == EventType.Layout; if (!flag15) { throw; } flag14 = GUIUtility.IsExitGUIException(exception); bool flag16 = !flag14; if (flag16) { Debug.LogException(exception); } } finally { bool flag17 = Event.current.type != EventType.Layout & canAffectFocus; if (flag17) { int keyboardControl = GUIUtility.keyboardControl; int num2 = GUIUtility.CheckForTabEvent(Event.current); bool flag18 = this.focusController != null; if (flag18) { bool flag19 = num2 < 0; if (flag19) { Focusable leafFocusedElement = this.focusController.GetLeafFocusedElement(); Focusable focusable = null; using (KeyDownEvent pooled = KeyboardEventBase <KeyDownEvent> .GetPooled('\t', KeyCode.Tab, (num2 == -1) ? EventModifiers.None : EventModifiers.Shift)) { focusable = this.focusController.SwitchFocusOnEvent(pooled); } bool flag20 = leafFocusedElement == this; if (flag20) { bool flag21 = focusable == this; if (flag21) { bool flag22 = num2 == -2; if (flag22) { GUIUtility.SetKeyboardControlToLastControlId(); } else { bool flag23 = num2 == -1; if (flag23) { GUIUtility.SetKeyboardControlToFirstControlId(); } } this.newKeyboardFocusControlID = GUIUtility.keyboardControl; this.focusController.imguiKeyboardControl = GUIUtility.keyboardControl; } else { GUIUtility.keyboardControl = 0; this.focusController.imguiKeyboardControl = 0; } } } else { bool flag24 = num2 > 0; if (flag24) { this.focusController.imguiKeyboardControl = GUIUtility.keyboardControl; this.newKeyboardFocusControlID = GUIUtility.keyboardControl; } else { bool flag25 = num2 == 0; if (flag25) { bool flag26 = type == EventType.MouseDown && !this.focusOnlyIfHasFocusableControls; if (flag26) { this.focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this, true); } else { bool flag27 = keyboardControl != GUIUtility.keyboardControl || type == EventType.MouseDown; if (flag27) { this.focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this, false); } else { bool flag28 = GUIUtility.keyboardControl != this.focusController.imguiKeyboardControl; if (flag28) { this.newKeyboardFocusControlID = GUIUtility.keyboardControl; bool flag29 = this.focusController.GetLeafFocusedElement() == this; if (flag29) { this.focusController.imguiKeyboardControl = GUIUtility.keyboardControl; } else { this.focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this, false); } } } } } } } } this.hasFocusableControls = GUIUtility.HasFocusableControls(); } } UIElementsUtility.EndContainerGUI(evt, layoutSize); this.RestoreGlobals(); bool flag30 = evt.type == EventType.Layout && (!Mathf.Approximately(layoutMeasuredWidth, this.layoutMeasuredWidth) || !Mathf.Approximately(layoutMeasuredHeight, this.layoutMeasuredHeight)); if (flag30) { bool flag31 = isComputingLayout && clippingRect == Rect.zero; if (flag31) { base.schedule.Execute(delegate { base.IncrementVersion(VersionChangeType.Layout); }); } else { base.IncrementVersion(VersionChangeType.Layout); } } bool flag32 = !flag14; if (flag32) { bool flag33 = evt.type != EventType.Ignore && evt.type != EventType.Used; if (flag33) { int num3 = GUIClip.Internal_GetCount(); bool flag34 = num3 > num; if (flag34) { Debug.LogError("GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced."); } else { bool flag35 = num3 < num; if (flag35) { 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(); } bool flag36 = evt.type == EventType.Used; if (flag36) { base.IncrementVersion(VersionChangeType.Repaint); } } }
/// <summary> /// Get the next element in the given direction. /// </summary> public Focusable GetNextFocusable(Focusable currentFocusable, FocusChangeDirection direction) { if (direction == FocusChangeDirection.none || direction == FocusChangeDirection.unspecified) { return(currentFocusable); } if (direction is VisualElementFocusChangeTarget changeTarget) { return(changeTarget.target); } DoUpdate(); if (m_FocusRing.Count == 0) { return(null); } int index = 0; if (direction == VisualElementFocusChangeDirection.right) { index = GetFocusableInternalIndex(currentFocusable) + 1; if (currentFocusable != null && index == 0) { // currentFocusable was not found in the ring. Use the element tree to find the next focusable. return(GetNextFocusableInTree(currentFocusable as VisualElement)); } if (index == m_FocusRing.Count) { index = 0; } // FIXME: Element could be unrelated to delegator; should we detect this case and return null? // Spec is not very clear on this. while (m_FocusRing[index].m_Focusable.delegatesFocus) { index++; if (index == m_FocusRing.Count) { return(null); } } } else if (direction == VisualElementFocusChangeDirection.left) { index = GetFocusableInternalIndex(currentFocusable) - 1; if (currentFocusable != null && index == -2) { // currentFocusable was not found in the ring. Use the element tree to find the previous focusable. return(GetPreviousFocusableInTree(currentFocusable as VisualElement)); } if (index < 0) { index = m_FocusRing.Count - 1; } while (m_FocusRing[index].m_Focusable.delegatesFocus) { index--; if (index == -1) { return(null); } } } return(m_FocusRing[index].m_Focusable); }
private void DoOnGUI(Event evt, Matrix4x4 parentTransform, Rect clippingRect, bool isComputingLayout, Rect layoutSize, Action onGUIHandler, bool canAffectFocus = true) { // Extra checks are needed here because client code might have changed the IMGUIContainer // since we enter HandleIMGUIEvent() if (onGUIHandler == null || panel == null) { return; } // Save the GUIClip count to make sanity checks after calling the OnGUI handler int guiClipCount = GUIClip.Internal_GetCount(); SaveGlobals(); // Save a copy of the container size. var previousMeasuredWidth = layoutMeasuredWidth; var previousMeasuredHeight = layoutMeasuredHeight; 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 own it. if (GUIUtility.OwnsId(GUIUtility.keyboardControl)) { GUIUtility.keyboardControl = 0; focusController.imguiKeyboardControl = 0; } } lostFocus = false; } if (receivedFocus) { if (hasFocusableControls) { if (focusChangeDirection != FocusChangeDirection.unspecified && focusChangeDirection != FocusChangeDirection.none) { // We got here by tabbing. // We assume we are using the VisualElementFocusRing. if (focusChangeDirection == VisualElementFocusChangeDirection.left) { GUIUtility.SetKeyboardControlToLastControlId(); } else if (focusChangeDirection == VisualElementFocusChangeDirection.right) { GUIUtility.SetKeyboardControlToFirstControlId(); } } else if (GUIUtility.keyboardControl == 0 && m_IsFocusDelegated) { // Since GUIUtility.keyboardControl == 0, we got focused in some other way than by clicking inside us // (for example it could be by clicking in an element that delegates focus to us). // Give GUIUtility.keyboardControl to our first control. GUIUtility.SetKeyboardControlToFirstControlId(); } } if (focusController != null) { if (focusController.imguiKeyboardControl != GUIUtility.keyboardControl && focusChangeDirection != FocusChangeDirection.unspecified) { newKeyboardFocusControlID = GUIUtility.keyboardControl; } focusController.imguiKeyboardControl = GUIUtility.keyboardControl; } receivedFocus = false; focusChangeDirection = FocusChangeDirection.unspecified; } // We intentionally don't send the NewKeyboardFocus command here since it creates an issue with the AutomatedWindow // newKeyboardFocusControlID = GUIUtility.keyboardControl; } EventType originalEventType = Event.current.type; bool isExitGUIException = false; try { using (new GUIClip.ParentClipScope(parentTransform, clippingRect)) { using (k_OnGUIMarker.Auto()) { 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 && canAffectFocus) { 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.GetLeafFocusedElement(); Focusable nextFocusedElement = focusController.FocusNextInDirection(result == -1 ? VisualElementFocusChangeDirection.right : VisualElementFocusChangeDirection.left); if (currentFocusedElement == this) { if (nextFocusedElement == this) { // We will 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 will lose 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 (originalEventType == EventType.MouseDown && !focusOnlyIfHasFocusableControls) { focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this, true); } else if ((currentKeyboardFocus != GUIUtility.keyboardControl) || (originalEventType == EventType.MouseDown)) { focusController.SyncIMGUIFocus(GUIUtility.keyboardControl, this, false); } else if (GUIUtility.keyboardControl != focusController.imguiKeyboardControl) { // Here we want to resynchronize our internal state ... newKeyboardFocusControlID = GUIUtility.keyboardControl; if (focusController.GetLeafFocusedElement() == 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, false); } } } } // Cache the fact that we have focusable controls or not. hasFocusableControls = GUIUtility.HasFocusableControls(); } } // This will copy Event.current into evt. UIElementsUtility.EndContainerGUI(evt, layoutSize); RestoreGlobals(); // See if the container size has changed. This is to make absolutely sure the VisualElement resizes // if the IMGUI content resizes. if (evt.type == EventType.Layout && (!Mathf.Approximately(previousMeasuredWidth, layoutMeasuredWidth) || !Mathf.Approximately(previousMeasuredHeight, layoutMeasuredHeight))) { if (isComputingLayout && clippingRect == Rect.zero) { this.schedule.Execute(() => IncrementVersion(VersionChangeType.Layout)); } else { IncrementVersion(VersionChangeType.Layout); } } 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); } }