public override void ExecuteDefaultActionAtTarget(EventBase evt) { base.ExecuteDefaultActionAtTarget(evt); if (evt.eventTypeId == MouseDownEvent.TypeId()) { OnMouseDown(evt as MouseDownEvent); } else if (evt.eventTypeId == MouseUpEvent.TypeId()) { OnMouseUp(evt as MouseUpEvent); } else if (evt.eventTypeId == MouseMoveEvent.TypeId()) { OnMouseMove(evt as MouseMoveEvent); } else if (evt.eventTypeId == KeyDownEvent.TypeId()) { OnKeyDown(evt as KeyDownEvent); } else if (evt.eventTypeId == ValidateCommandEvent.TypeId()) { OnValidateCommandEvent(evt as ValidateCommandEvent); } else if (evt.eventTypeId == ExecuteCommandEvent.TypeId()) { OnExecuteCommandEvent(evt as ExecuteCommandEvent); } }
protected override void ExecuteDefaultActionAtTarget(EventBase evt) { base.ExecuteDefaultActionAtTarget(evt); elementPanel?.contextualMenuManager?.DisplayMenuIfEventMatches(evt, this); if (evt?.eventTypeId == ContextualMenuPopulateEvent.TypeId()) { ContextualMenuPopulateEvent e = evt as ContextualMenuPopulateEvent; int count = e.menu.MenuItems().Count; BuildContextualMenu(e); if (count > 0 && e.menu.MenuItems().Count > count) { e.menu.InsertSeparator(null, count); } } else if (evt.eventTypeId == FocusInEvent.TypeId()) { SaveValueAndText(); } else if (evt.eventTypeId == KeyDownEvent.TypeId()) { KeyDownEvent keyDownEvt = evt as KeyDownEvent; if (keyDownEvt?.keyCode == KeyCode.Escape) { RestoreValueAndText(); parent.Focus(); } } editorEventHandler.ExecuteDefaultActionAtTarget(evt); }
internal static FocusChangeDirection GetKeyDownFocusChangeDirection(EventBase e) { if (e.eventTypeId == KeyDownEvent.TypeId()) { KeyDownEvent kde = e as KeyDownEvent; // Important: using KeyDownEvent.character for focus prevents a TextField bug. // IMGUI sends KeyDownEvent with keyCode != None, then it sends another one with character != '\0'. // If we use keyCode instead of character, TextField will receive focus on the first KeyDownEvent, // then text will become selected and, in the case of multiline, the KeyDownEvent with character = '\t' // will immediately overwrite the text with a single Tab string. 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); }
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) == 0) { return(VisualElementFocusChangeDirection.right); } return(VisualElementFocusChangeDirection.left); } } return(FocusChangeDirection.none); }
protected override void ExecuteDefaultActionAtTarget(EventBase evt) { base.ExecuteDefaultActionAtTarget(evt); if (evt == null) { return; } if (evt.eventTypeId == KeyDownEvent.TypeId()) { KeyDownEvent kde = evt as KeyDownEvent; if (!parentTextField.isDelayed || (!multiline && ((kde?.keyCode == KeyCode.KeypadEnter) || (kde?.keyCode == KeyCode.Return)))) { parentTextField.value = text; } if (multiline) { if (kde?.character == '\t' && kde.modifiers == EventModifiers.None) { kde?.StopPropagation(); kde?.PreventDefault(); } else if (((kde?.character == 3) && (kde?.shiftKey == true)) || // KeyCode.KeypadEnter ((kde?.character == '\n') && (kde?.shiftKey == true))) // KeyCode.Return { parent.Focus(); evt.StopPropagation(); evt.PreventDefault(); } } else if ((kde?.character == 3) || // KeyCode.KeypadEnter (kde?.character == '\n')) // KeyCode.Return { parent.Focus(); evt.StopPropagation(); evt.PreventDefault(); } } else if (evt.eventTypeId == ExecuteCommandEvent.TypeId()) { ExecuteCommandEvent commandEvt = evt as ExecuteCommandEvent; string cmdName = commandEvt.commandName; if (!parentTextField.isDelayed && (cmdName == EventCommandNames.Paste || cmdName == EventCommandNames.Cut)) { parentTextField.value = text; } } // Prevent duplicated navigation events, since we're observing KeyDownEvents instead else if (evt.eventTypeId == NavigationSubmitEvent.TypeId() || evt.eventTypeId == NavigationCancelEvent.TypeId() || evt.eventTypeId == NavigationMoveEvent.TypeId()) { evt.StopPropagation(); evt.PreventDefault(); } }
protected override void ExecuteDefaultActionAtTarget(EventBase evt) { base.ExecuteDefaultActionAtTarget(evt); bool hasChanged = false; if (evt.eventTypeId == KeyDownEvent.TypeId()) { KeyDownEvent kde = evt as KeyDownEvent; if ((kde?.character == 3) || // KeyCode.KeypadEnter (kde?.character == '\n')) // KeyCode.Return { if (textEdition.hasFocus) { Focus(); } else { textInputBase.textElement.Focus(); } evt.StopPropagation(); evt.PreventDefault(); } else if (!isReadOnly) { hasChanged = true; } } else if (!isReadOnly && evt.eventTypeId == ExecuteCommandEvent.TypeId()) { ExecuteCommandEvent commandEvt = evt as ExecuteCommandEvent; string cmdName = commandEvt.commandName; if (cmdName == EventCommandNames.Paste || cmdName == EventCommandNames.Cut) { hasChanged = true; } } if (!isDelayed && hasChanged) { // Prevent text from changing when the value change // This allow expression (2+2) or string like 00123 to remain as typed in the TextField until enter is pressed m_UpdateTextFromValue = false; try { textInputBase.UpdateValueFromText(); } finally { m_UpdateTextFromValue = true; } } }
protected internal override void ExecuteDefaultActionAtTarget(EventBase evt) { base.ExecuteDefaultActionAtTarget(evt); if (evt == null) { return; } if (evt.eventTypeId == KeyDownEvent.TypeId()) { KeyDownEvent kde = evt as KeyDownEvent; if (!parentTextField.isDelayed || (!multiline && ((kde?.keyCode == KeyCode.KeypadEnter) || (kde?.keyCode == KeyCode.Return)))) { parentTextField.value = text; } if (multiline) { if (kde?.character == '\t') { kde?.StopPropagation(); kde?.PreventDefault(); } else if (((kde?.character == 3) && (kde?.shiftKey == true)) || // KeyCode.KeypadEnter ((kde?.character == '\n') && (kde?.shiftKey == true))) // KeyCode.Return { parent.Focus(); } } else if ((kde?.character == 3) || // KeyCode.KeypadEnter (kde?.character == '\n')) // KeyCode.Return { parent.Focus(); } } else if (evt.eventTypeId == ExecuteCommandEvent.TypeId()) { ExecuteCommandEvent commandEvt = evt as ExecuteCommandEvent; string cmdName = commandEvt.commandName; if (!parentTextField.isDelayed && (cmdName == EventCommandNames.Paste || cmdName == EventCommandNames.Cut)) { parentTextField.value = text; } } }
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(); } } }
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); } }
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; }
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; } } }