public FocusChangeDirection GetFocusChangeDirection(Focusable currentFocusable, EventBase e) { if (e == null) { throw new ArgumentNullException(nameof(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 is IMGUIContainer && e.imguiEvent != null) { // Let IMGUIContainer manage the focus change. return(FocusChangeDirection.none); } if (e.eventTypeId == KeyDownEvent.TypeId()) { KeyDownEvent kde = e as KeyDownEvent; if (kde.character == (char)25 || kde.character == '\t') { if (kde.modifiers == EventModifiers.Shift) { return(VisualElementFocusChangeDirection.left); } if (kde.modifiers == EventModifiers.None) { return(VisualElementFocusChangeDirection.right); } } } return(FocusChangeDirection.none); }
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) { // 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(); } } receivedFocus = false; focusChangeDirection = FocusChangeDirection.unspecified; if (focusController != null) { if (focusController.imguiKeyboardControl != GUIUtility.keyboardControl) { newKeyboardFocusControlID = GUIUtility.keyboardControl; } focusController.imguiKeyboardControl = GUIUtility.keyboardControl; } } // 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)) { 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 = null; using (KeyDownEvent e = KeyDownEvent.GetPooled('\t', KeyCode.Tab, result == -1 ? EventModifiers.None : EventModifiers.Shift)) { nextFocusedElement = focusController.SwitchFocusOnEvent(e); } 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 (!isComputingLayout && evt.type == EventType.Layout && (!Mathf.Approximately(previousMeasuredWidth, layoutMeasuredWidth) || !Mathf.Approximately(previousMeasuredHeight, layoutMeasuredHeight))) { 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); } }
public void ReplayEvents(List <EventDebuggerEventRecord> eventBases) { if (eventBases == null) { return; } foreach (var eventBase in eventBases) { Event newEvent = new Event { button = eventBase.button, clickCount = eventBase.clickCount, modifiers = eventBase.modifiers, mousePosition = eventBase.mousePosition, }; if (eventBase.eventTypeId == MouseMoveEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseMove; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseMove), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseDownEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseDown; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseDown), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseUpEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseUp; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseUp), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == ContextClickEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.ContextClick; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ContextClick), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseEnterWindowEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseEnterWindow; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseEnterWindow), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseLeaveWindowEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseLeaveWindow; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseLeaveWindow), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == WheelEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.ScrollWheel; newEvent.delta = eventBase.delta; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ScrollWheel), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == KeyDownEvent.TypeId()) { newEvent.type = EventType.KeyDown; newEvent.character = eventBase.character; newEvent.keyCode = eventBase.keyCode; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.KeyDown), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == KeyUpEvent.TypeId()) { newEvent.type = EventType.KeyUp; newEvent.character = eventBase.character; newEvent.keyCode = eventBase.keyCode; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.KeyUp), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == DragUpdatedEvent.TypeId()) { newEvent.type = EventType.DragUpdated; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.DragUpdated), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == DragPerformEvent.TypeId()) { newEvent.type = EventType.DragPerform; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.DragPerform), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == DragExitedEvent.TypeId()) { newEvent.type = EventType.DragExited; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.DragExited), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == ValidateCommandEvent.TypeId()) { newEvent.type = EventType.ValidateCommand; newEvent.commandName = eventBase.commandName; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ValidateCommand), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == ExecuteCommandEvent.TypeId()) { newEvent.type = EventType.ExecuteCommand; newEvent.commandName = eventBase.commandName; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ExecuteCommand), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == IMGUIEvent.TypeId()) { Debug.Log("Skipped IMGUI event (" + eventBase.eventBaseName + "): " + eventBase); continue; } else { Debug.Log("Skipped event (" + eventBase.eventBaseName + "): " + eventBase); continue; } Debug.Log("Replayed event (" + eventBase.eventBaseName + "): " + newEvent); } }
void OnKeyDown(KeyDownEvent evt) { if (!textInputField.hasFocus) { return; } textInputField.SyncTextEngine(); m_Changed = false; // Check for action keys. if (editorEngine.HandleKeyEvent(evt.imguiEvent, textInputField.isReadOnly)) { if (textInputField.text != editorEngine.text) { m_Changed = true; } evt.StopPropagation(); } else { char c = evt.character; // Ignore tab & shift-tab in single-line text fields if (!editorEngine.multiline && (evt.keyCode == KeyCode.Tab || c == '\t')) { return; } // Ignore modifier+tab in multiline text fields if (editorEngine.multiline && (evt.keyCode == KeyCode.Tab || c == '\t') && evt.modifiers != EventModifiers.None) { return; } evt.StopPropagation(); if (c == '\n' && !editorEngine.multiline && !evt.altKey) { return; } // When the newline character is sent, we have to check if the shift key is down also... // In the multiline case, this is like a return on a single line if (c == '\n' && editorEngine.multiline && evt.shiftKey) { return; } if (!textInputField.AcceptCharacter(c)) { return; } // Simplest test: only allow the character if the display font supports it. Font font = editorEngine.style.font; if (font != null && font.HasCharacter(c) || c == '\n' || c == '\t') { // Input event editorEngine.Insert(c); m_Changed = true; } // On windows, key presses also send events with keycode but no character. Eat them up here. else if (c == 0) { // if we have a composition string, make sure we clear the previous selection. if (!string.IsNullOrEmpty(GUIUtility.compositionString)) { editorEngine.ReplaceSelection(""); m_Changed = true; } } } if (m_Changed) { editorEngine.text = textInputField.CullString(editorEngine.text); textInputField.UpdateText(editorEngine.text); } // Scroll offset might need to be updated editorEngine.UpdateScrollOffset(); }
// In order for tests to run without an EditorWindow but still be able to send // events, we sometimes need to force the event type. IMGUI::GetEventType() (native) will // return the event type as Ignore if the proper views haven't yet been // initialized. This (falsely) breaks tests that rely on the event type. So for tests, we // just ensure the event type is what we originally set it to when we sent it. internal static EventBase CreateEvent(Event systemEvent, EventType eventType) { switch (eventType) { case EventType.MouseMove: case EventType.TouchMove: return(PointerMoveEvent.GetPooled(systemEvent)); case EventType.MouseDrag: return(PointerMoveEvent.GetPooled(systemEvent)); case EventType.MouseDown: case EventType.TouchDown: // If some buttons are already down, we generate PointerMove/MouseDown events. // Otherwise we generate PointerDown/MouseDown events. // See W3C pointer events recommendation: https://www.w3.org/TR/pointerevents2 // Note: sometimes systemEvent.button is already pressed (systemEvent is processed multiple times). if (PointerDeviceState.HasAdditionalPressedButtons(PointerId.mousePointerId, systemEvent.button)) { return(PointerMoveEvent.GetPooled(systemEvent)); } else { return(PointerDownEvent.GetPooled(systemEvent)); } case EventType.MouseUp: case EventType.TouchUp: // If more buttons are still down, we generate PointerMove/MouseUp events. // Otherwise we generate PointerUp/MouseUp events. // See W3C pointer events recommendation: https://www.w3.org/TR/pointerevents2 if (PointerDeviceState.HasAdditionalPressedButtons(PointerId.mousePointerId, systemEvent.button)) { return(PointerMoveEvent.GetPooled(systemEvent)); } else { return(PointerUpEvent.GetPooled(systemEvent)); } case EventType.ContextClick: return(ContextClickEvent.GetPooled(systemEvent)); case EventType.MouseEnterWindow: return(MouseEnterWindowEvent.GetPooled(systemEvent)); case EventType.MouseLeaveWindow: return(MouseLeaveWindowEvent.GetPooled(systemEvent)); case EventType.ScrollWheel: return(WheelEvent.GetPooled(systemEvent)); case EventType.KeyDown: return(KeyDownEvent.GetPooled(systemEvent)); case EventType.KeyUp: return(KeyUpEvent.GetPooled(systemEvent)); case EventType.DragUpdated: return(DragUpdatedEvent.GetPooled(systemEvent)); case EventType.DragPerform: return(DragPerformEvent.GetPooled(systemEvent)); case EventType.DragExited: return(DragExitedEvent.GetPooled(systemEvent)); case EventType.ValidateCommand: return(ValidateCommandEvent.GetPooled(systemEvent)); case EventType.ExecuteCommand: return(ExecuteCommandEvent.GetPooled(systemEvent)); default: // Layout, Ignore, Used return(IMGUIEvent.GetPooled(systemEvent)); } }
void OnKeyDown(KeyDownEvent evt) { if (!textElement.edition.hasFocus) { return; } m_Changed = false; if (evt.keyCode == KeyCode.Escape) { textElement.edition.RestoreValueAndText(); textElement.parent.Focus(); } evt.GetEquivalentImguiEvent(m_ImguiEvent); if (editingUtilities.HandleKeyEvent(m_ImguiEvent, false)) { if (textElement.text != editingUtilities.text) { m_Changed = true; } evt.StopPropagation(); } else { char c = evt.character; // Ignore command and control keys, but not AltGr characters if (evt.actionKey && !(evt.altKey && c != '\0')) { return; } // Ignore tab & shift-tab in single-line text fields if (!textElement.edition.multiline && (evt.keyCode == KeyCode.Tab || c == '\t')) { return; } // Ignore modifier+tab in multiline text fields if ((evt.keyCode == KeyCode.Tab || c == '\t') && evt.modifiers != EventModifiers.None) { return; } evt.StopPropagation(); if ((c == '\n' || c == '\r' || c == k_LineFeed) && !textElement.edition.multiline && !evt.altKey) { return; } // When the newline character is sent, we have to check if the shift key is down also... // In the multiline case, this is like a return on a single line if (c == '\n' && textElement.edition.multiline && evt.shiftKey) { return; } if (!textElement.edition.AcceptCharacter(c)) { return; } if (c >= k_Space || c == '\t' || c == '\n' || c == '\r' || c == k_LineFeed) { editingUtilities.Insert(c); m_Changed = true; } // On windows, key presses also send events with keycode but no character. Eat them up here. else { // if we have a composition string, make sure we clear the previous selection. if (editingUtilities.UpdateImeState()) { m_Changed = true; } } } if (m_Changed) { UpdateLabel(); // UpdateScrollOffset needs the new geometry of the text to compute the new scrollOffset. textElement.uitkTextHandle.Update(); } // Scroll offset might need to be updated textElement.edition.UpdateScrollOffset?.Invoke(); }
private IEnumerator DoReplayEvents(IEnumerable <EventDebuggerEventRecord> eventBases, Action <int, int> refreshList) { var sortedEvents = eventBases.OrderBy(e => e.timestamp).ToList(); var sortedEventsCount = sortedEvents.Count; IEnumerator AwaitForNextEvent(int currentIndex) { if (currentIndex == sortedEvents.Count - 1) { yield break; } var deltaTimestampMs = sortedEvents[currentIndex + 1].timestamp - sortedEvents[currentIndex].timestamp; var timeMs = 0.0f; while (timeMs < deltaTimestampMs) { if (isPlaybackPaused) { yield return(null); } else { var time = Panel.TimeSinceStartupMs(); yield return(null); var delta = Panel.TimeSinceStartupMs() - time; timeMs += delta * playbackSpeed; } } } for (var i = 0; i < sortedEventsCount; i++) { if (!isReplaying) { break; } var eventBase = sortedEvents[i]; var newEvent = new Event { button = eventBase.button, clickCount = eventBase.clickCount, modifiers = eventBase.modifiers, mousePosition = eventBase.mousePosition, }; if (eventBase.eventTypeId == MouseMoveEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseMove; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseMove), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseDownEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseDown; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseDown), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseUpEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseUp; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseUp), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == ContextClickEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.ContextClick; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ContextClick), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseEnterWindowEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseEnterWindow; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseEnterWindow), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == MouseLeaveWindowEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseLeaveWindow; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseLeaveWindow), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == PointerMoveEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseMove; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseMove), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == PointerDownEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseDown; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseDown), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == PointerUpEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.MouseUp; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.MouseUp), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == WheelEvent.TypeId() && eventBase.hasUnderlyingPhysicalEvent) { newEvent.type = EventType.ScrollWheel; newEvent.delta = eventBase.delta; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ScrollWheel), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == KeyDownEvent.TypeId()) { newEvent.type = EventType.KeyDown; newEvent.character = eventBase.character; newEvent.keyCode = eventBase.keyCode; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.KeyDown), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == KeyUpEvent.TypeId()) { newEvent.type = EventType.KeyUp; newEvent.character = eventBase.character; newEvent.keyCode = eventBase.keyCode; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.KeyUp), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == NavigationMoveEvent.TypeId()) { panel.dispatcher.Dispatch(NavigationMoveEvent.GetPooled(eventBase.navigationDirection, eventBase.deviceType, eventBase.modifiers), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == NavigationSubmitEvent.TypeId()) { panel.dispatcher.Dispatch(NavigationSubmitEvent.GetPooled(eventBase.deviceType, eventBase.modifiers), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == NavigationCancelEvent.TypeId()) { panel.dispatcher.Dispatch(NavigationCancelEvent.GetPooled(eventBase.deviceType, eventBase.modifiers), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == DragUpdatedEvent.TypeId()) { newEvent.type = EventType.DragUpdated; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.DragUpdated), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == DragPerformEvent.TypeId()) { newEvent.type = EventType.DragPerform; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.DragPerform), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == DragExitedEvent.TypeId()) { newEvent.type = EventType.DragExited; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.DragExited), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == ValidateCommandEvent.TypeId()) { newEvent.type = EventType.ValidateCommand; newEvent.commandName = eventBase.commandName; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ValidateCommand), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == ExecuteCommandEvent.TypeId()) { newEvent.type = EventType.ExecuteCommand; newEvent.commandName = eventBase.commandName; panel.dispatcher.Dispatch(UIElementsUtility.CreateEvent(newEvent, EventType.ExecuteCommand), panel, DispatchMode.Default); } else if (eventBase.eventTypeId == IMGUIEvent.TypeId()) { Debug.Log("Skipped IMGUI event (" + eventBase.eventBaseName + "): " + eventBase); var awaitSkipped = AwaitForNextEvent(i); while (awaitSkipped.MoveNext()) { yield return(null); } continue; } else { Debug.Log("Skipped event (" + eventBase.eventBaseName + "): " + eventBase); var awaitSkipped = AwaitForNextEvent(i); while (awaitSkipped.MoveNext()) { yield return(null); } continue; } refreshList?.Invoke(i, sortedEventsCount); Debug.Log($"Replayed event {eventBase.eventId.ToString()} ({eventBase.eventBaseName}): {newEvent}"); var await = AwaitForNextEvent(i); while (await.MoveNext()) { yield return(null); } } isReplaying = false; }
public void OnKeyDown(KeyDownEvent evt) { if (evt == null || !HasValidDataAndBindings()) { return; } bool shouldStopPropagation = true; bool shouldScroll = true; switch (evt.keyCode) { case KeyCode.UpArrow: if (selectedIndex > 0) { selectedIndex = selectedIndex - 1; } break; case KeyCode.DownArrow: if (selectedIndex + 1 < itemsSource.Count) { selectedIndex = selectedIndex + 1; } break; case KeyCode.Home: selectedIndex = 0; break; case KeyCode.End: selectedIndex = itemsSource.Count - 1; break; case KeyCode.Return: if (onItemChosen != null) { onItemChosen.Invoke(m_ItemsSource[selectedIndex]); } break; case KeyCode.PageDown: selectedIndex = Math.Min(itemsSource.Count - 1, selectedIndex + (int)(m_LastHeight / itemHeight)); break; case KeyCode.PageUp: selectedIndex = Math.Max(0, selectedIndex - (int)(m_LastHeight / itemHeight)); break; case KeyCode.A: if (evt.actionKey) { SelectAll(); shouldScroll = false; } break; case KeyCode.Escape: ClearSelection(); shouldScroll = false; break; default: shouldStopPropagation = false; shouldScroll = false; break; } if (shouldStopPropagation) { evt.StopPropagation(); } if (shouldScroll) { ScrollToItem(selectedIndex); } }
private void OnKeyDown(KeyDownEvent evt) { bool flag = !base.textInputField.hasFocus; if (!flag) { base.textInputField.SyncTextEngine(); this.m_Changed = false; evt.GetEquivalentImguiEvent(this.m_ImguiEvent); bool flag2 = base.editorEngine.HandleKeyEvent(this.m_ImguiEvent, base.textInputField.isReadOnly); if (flag2) { bool flag3 = base.textInputField.text != base.editorEngine.text; if (flag3) { this.m_Changed = true; } evt.StopPropagation(); } else { char character = evt.character; bool flag4 = !base.editorEngine.multiline && (evt.keyCode == KeyCode.Tab || character == '\t'); if (flag4) { return; } bool flag5 = base.editorEngine.multiline && (evt.keyCode == KeyCode.Tab || character == '\t') && evt.modifiers > EventModifiers.None; if (flag5) { return; } bool flag6 = evt.actionKey && (!evt.altKey || character == '\0'); if (flag6) { return; } evt.StopPropagation(); bool flag7 = character == '\n' && !base.editorEngine.multiline && !evt.altKey; if (flag7) { return; } bool flag8 = character == '\n' && base.editorEngine.multiline && evt.shiftKey; if (flag8) { return; } bool flag9 = !base.textInputField.AcceptCharacter(character); if (flag9) { return; } Font font = base.editorEngine.style.font; bool flag10 = (font != null && font.HasCharacter(character)) || character == '\n' || character == '\t'; if (flag10) { base.editorEngine.Insert(character); this.m_Changed = true; } else { bool flag11 = character == '\0'; if (flag11) { bool flag12 = !string.IsNullOrEmpty(GUIUtility.compositionString); if (flag12) { base.editorEngine.ReplaceSelection(""); this.m_Changed = true; } } } } bool changed = this.m_Changed; if (changed) { base.editorEngine.text = base.textInputField.CullString(base.editorEngine.text); base.textInputField.UpdateText(base.editorEngine.text); } base.editorEngine.UpdateScrollOffset(); } }
protected override void ExecuteDefaultActionAtTarget(EventBase evt) { base.ExecuteDefaultActionAtTarget(evt); if (evt == null) { return; } if (evt.eventTypeId == KeyDownEvent.TypeId()) { KeyDownEvent keyDownEvt = evt as KeyDownEvent; // We must handle the ETX (char 3) or the \n instead of the KeypadEnter or Return because the focus will // have the drawback of having the second event to be handled by the focused field. if ((keyDownEvt?.character == 3) || // KeyCode.KeypadEnter (keyDownEvt?.character == '\n')) // KeyCode.Return { visualInput?.Focus(); } } // The following code is to help achieve the following behaviour: // On IMGUI, on any text input field in focused-non-edit-mode, doing a TAB will allow the user to get to the next control... // To mimic that behaviour in UIE, when in focused-non-edit-mode, we have to make sure the input is not "tabbable". // So, each time, either the main TextField or the Label is receiving the focus, we remove the tabIndex on // the input, and we put it back when the BlurEvent is received. else if (evt.eventTypeId == FocusInEvent.TypeId()) { if (evt.leafTarget == this || evt.leafTarget == labelElement) { m_VisualInputTabIndex = visualInput.tabIndex; visualInput.tabIndex = -1; } } // The following code was added to help achieve the following behaviour: // On IMGUI, doing a Return, Shift+Return or Escape will get out of the Edit mode, but stay on the control. To allow a // focused-non-edit-mode, we remove the delegateFocus when we start editing to allow focusing on the parent, // and we restore it when we exit the control, to prevent coming in a semi-focused state from outside the control. else if (evt.eventTypeId == FocusEvent.TypeId()) { delegatesFocus = false; } else if (evt.eventTypeId == BlurEvent.TypeId()) { delegatesFocus = true; if (evt.leafTarget == this || evt.leafTarget == labelElement) { visualInput.tabIndex = m_VisualInputTabIndex; } } // The following code is to help achieve the following behaviour: // On IMGUI, on any text input field in focused-non-edit-mode, doing a TAB will allow the user to get to the next control... // To mimic that behaviour in UIE, when in focused-non-edit-mode, we have to make sure the input is not "tabbable". // So, each time, either the main TextField or the Label is receiving the focus, we remove the tabIndex on // the input, and we put it back when the BlurEvent is received. else if (evt.eventTypeId == FocusInEvent.TypeId()) { if (showMixedValue) { m_TextInputBase.ResetValueAndText(); } if (evt.leafTarget == this || evt.leafTarget == labelElement) { m_VisualInputTabIndex = visualInput.tabIndex; visualInput.tabIndex = -1; } } // The following code was added to help achieve the following behaviour: // On IMGUI, doing a Return, Shift+Return or Escape will get out of the Edit mode, but stay on the control. To allow a // focused-non-edit-mode, we remove the delegateFocus when we start editing to allow focusing on the parent, // and we restore it when we exit the control, to prevent coming in a semi-focused state from outside the control. else if (evt.eventTypeId == FocusEvent.TypeId()) { delegatesFocus = false; } else if (evt.eventTypeId == BlurEvent.TypeId()) { delegatesFocus = true; if (evt.leafTarget == this || evt.leafTarget == labelElement) { visualInput.tabIndex = m_VisualInputTabIndex; } } }
private NavigationDirection GetNavigationDirection(KeyDownEvent keyDownEvent) { EventInterpreter.< > c__DisplayClass4_0 <> c__DisplayClass4_;
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); } } }
protected override void ExecuteDefaultActionAtTarget(EventBase evt) { base.ExecuteDefaultActionAtTarget(evt); bool flag = evt == null; if (!flag) { bool flag2 = evt.eventTypeId == EventBase <KeyDownEvent> .TypeId(); if (flag2) { KeyDownEvent keyDownEvent = evt as KeyDownEvent; bool flag3 = !this.parentTextField.isDelayed || (!this.multiline && ((keyDownEvent != null && keyDownEvent.keyCode == KeyCode.KeypadEnter) || (keyDownEvent != null && keyDownEvent.keyCode == KeyCode.Return))); if (flag3) { this.parentTextField.value = base.text; } bool multiline = this.multiline; if (multiline) { char?c = (keyDownEvent != null) ? new char?(keyDownEvent.character) : null; int? num = c.HasValue ? new int?((int)c.GetValueOrDefault()) : null; int num2 = 9; bool flag4 = (num.GetValueOrDefault() == num2 & num.HasValue) && keyDownEvent.modifiers == EventModifiers.None; if (flag4) { if (keyDownEvent != null) { keyDownEvent.StopPropagation(); } if (keyDownEvent != null) { keyDownEvent.PreventDefault(); } } else { c = ((keyDownEvent != null) ? new char?(keyDownEvent.character) : null); num = (c.HasValue ? new int?((int)c.GetValueOrDefault()) : null); num2 = 3; bool arg_1EE_0; if (!(num.GetValueOrDefault() == num2 & num.HasValue) || keyDownEvent == null || !keyDownEvent.shiftKey) { c = ((keyDownEvent != null) ? new char?(keyDownEvent.character) : null); num = (c.HasValue ? new int?((int)c.GetValueOrDefault()) : null); num2 = 10; arg_1EE_0 = ((num.GetValueOrDefault() == num2 & num.HasValue) && keyDownEvent != null && keyDownEvent.shiftKey); } else { arg_1EE_0 = true; } bool flag5 = arg_1EE_0; if (flag5) { base.parent.Focus(); } } } else { char?c = (keyDownEvent != null) ? new char?(keyDownEvent.character) : null; int? num = c.HasValue ? new int?((int)c.GetValueOrDefault()) : null; int num2 = 3; bool arg_2B8_0; if (!(num.GetValueOrDefault() == num2 & num.HasValue)) { c = ((keyDownEvent != null) ? new char?(keyDownEvent.character) : null); num = (c.HasValue ? new int?((int)c.GetValueOrDefault()) : null); num2 = 10; arg_2B8_0 = (num.GetValueOrDefault() == num2 & num.HasValue); } else { arg_2B8_0 = true; } bool flag6 = arg_2B8_0; if (flag6) { base.parent.Focus(); } } } else { bool flag7 = evt.eventTypeId == EventBase <ExecuteCommandEvent> .TypeId(); if (flag7) { ExecuteCommandEvent executeCommandEvent = evt as ExecuteCommandEvent; string commandName = executeCommandEvent.commandName; bool flag8 = !this.parentTextField.isDelayed && (commandName == "Paste" || commandName == "Cut"); if (flag8) { this.parentTextField.value = base.text; } } else { NavigationDirection navigationDirection; bool flag9 = base.eventInterpreter.IsActivationEvent(evt) || base.eventInterpreter.IsCancellationEvent(evt) || (base.eventInterpreter.IsNavigationEvent(evt, out navigationDirection) && navigationDirection != NavigationDirection.Previous && navigationDirection != NavigationDirection.Next); if (flag9) { evt.StopPropagation(); evt.PreventDefault(); } } } } }