static bool SendEventToIMGUIContainer(EventBase evt, BaseVisualElementPanel panel) { if (evt.imguiEvent == null) { return(false); } // Root IMGUI is the container that handles all the GUIView/DockArea logic for EditorWindows. var rootIMGUI = panel.rootIMGUIContainer; if (rootIMGUI == null) { return(false); } // If root IMGUI doesn't use event, send it to other IMGUIs down the line. if (evt.propagateToIMGUI || evt.eventTypeId == DragExitedEvent.TypeId() || evt.eventTypeId == MouseEnterWindowEvent.TypeId() || evt.eventTypeId == MouseLeaveWindowEvent.TypeId()) { evt.skipElements.Add(evt.target); EventDispatchUtilities.PropagateToIMGUIContainer(panel.visualTree, evt); } return(IsDone(evt)); }
internal void SetElementUnderMouse(VisualElement newElementUnderMouse, EventBase triggerEvent) { if (newElementUnderMouse == topElementUnderMouse) { return; } VisualElement previousTopElementUnderMouse = topElementUnderMouse; topElementUnderMouse = newElementUnderMouse; IMouseEvent mouseEvent = triggerEvent == null ? null : triggerEvent as IMouseEvent; var mousePosition = mouseEvent == null ? MousePositionTracker.mousePosition : mouseEvent?.mousePosition ?? Vector2.zero; // mouse enter/leave must be dispatched *any* time the element under mouse changes using (new EventDispatcherGate(dispatcher)) { MouseEventsHelper.SendEnterLeave <MouseLeaveEvent, MouseEnterEvent>(previousTopElementUnderMouse, topElementUnderMouse, mouseEvent, mousePosition); } if (triggerEvent == null || triggerEvent.eventTypeId == MouseMoveEvent.TypeId() || triggerEvent.eventTypeId == MouseDownEvent.TypeId() || triggerEvent.eventTypeId == MouseUpEvent.TypeId() || triggerEvent.eventTypeId == MouseEnterWindowEvent.TypeId() || triggerEvent.eventTypeId == MouseLeaveWindowEvent.TypeId() || triggerEvent.eventTypeId == WheelEvent.TypeId()) { using (new EventDispatcherGate(dispatcher)) { MouseEventsHelper.SendMouseOverMouseOut(previousTopElementUnderMouse, topElementUnderMouse, mouseEvent, mousePosition); } } else if (triggerEvent.eventTypeId == DragUpdatedEvent.TypeId() || triggerEvent.eventTypeId == DragExitedEvent.TypeId()) { using (new EventDispatcherGate(dispatcher)) { MouseEventsHelper.SendEnterLeave <DragLeaveEvent, DragEnterEvent>(previousTopElementUnderMouse, topElementUnderMouse, mouseEvent, mousePosition); } } }
internal void SetElementUnderMouse(VisualElement newElementUnderMouse, EventBase triggerEvent) { if (newElementUnderMouse == topElementUnderMouse) { return; } VisualElement previousTopElementUnderMouse = topElementUnderMouse; topElementUnderMouse = newElementUnderMouse; if (triggerEvent == null) { using (new EventDispatcherGate(dispatcher)) { MouseEventsHelper.SendEnterLeave <MouseLeaveEvent, MouseEnterEvent>(previousTopElementUnderMouse, topElementUnderMouse, null, MousePositionTracker.mousePosition); MouseEventsHelper.SendMouseOverMouseOut(previousTopElementUnderMouse, topElementUnderMouse, null, MousePositionTracker.mousePosition); } } else if ( triggerEvent.eventTypeId == MouseMoveEvent.TypeId() || triggerEvent.eventTypeId == MouseDownEvent.TypeId() || triggerEvent.eventTypeId == MouseUpEvent.TypeId() || triggerEvent.eventTypeId == MouseEnterWindowEvent.TypeId() || triggerEvent.eventTypeId == MouseLeaveWindowEvent.TypeId() || triggerEvent.eventTypeId == WheelEvent.TypeId()) { IMouseEvent mouseEvent = triggerEvent as IMouseEvent; using (new EventDispatcherGate(dispatcher)) { MouseEventsHelper.SendEnterLeave <MouseLeaveEvent, MouseEnterEvent>(previousTopElementUnderMouse, topElementUnderMouse, mouseEvent, mouseEvent?.mousePosition ?? Vector2.zero); MouseEventsHelper.SendMouseOverMouseOut(previousTopElementUnderMouse, topElementUnderMouse, mouseEvent, mouseEvent?.mousePosition ?? Vector2.zero); } } else if (triggerEvent.eventTypeId == DragUpdatedEvent.TypeId() || triggerEvent.eventTypeId == DragExitedEvent.TypeId()) { IMouseEvent mouseEvent = triggerEvent as IMouseEvent; using (new EventDispatcherGate(dispatcher)) { MouseEventsHelper.SendEnterLeave <DragLeaveEvent, DragEnterEvent>(previousTopElementUnderMouse, topElementUnderMouse, mouseEvent, mouseEvent?.mousePosition ?? Vector2.zero); } } }
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; }
public virtual void DispatchEvent(EventBase evt, IPanel panel) { IMouseEvent mouseEvent = evt as IMouseEvent; // FIXME: we should not change hover state when capture is true. // However, when doing drag and drop, drop target should be highlighted. // TODO when EditorWindow is docked MouseLeaveWindow is not always sent // this is a problem in itself but it could leave some elements as "hover" BaseVisualElementPanel basePanel = panel as BaseVisualElementPanel; if (basePanel != null && (evt.eventTypeId == MouseLeaveWindowEvent.TypeId() || evt.eventTypeId == DragExitedEvent.TypeId())) { basePanel.SetElementUnderMouse(null, evt); } else { // update element under mouse and fire necessary events if (basePanel != null) { bool shouldRecomputeTopElementUnderMouse = true; if ((IMouseEventInternal)mouseEvent != null) { shouldRecomputeTopElementUnderMouse = ((IMouseEventInternal)mouseEvent).recomputeTopElementUnderMouse; } VisualElement elementUnderMouse = shouldRecomputeTopElementUnderMouse ? basePanel.Pick(mouseEvent.mousePosition) : basePanel.topElementUnderMouse; if (evt.target == null) { evt.target = elementUnderMouse; } // Because events are queued, we can set the element under mouse // right now, instead of waiting after the PropagateEvent() as we // did before. basePanel.SetElementUnderMouse(elementUnderMouse, evt); } if (evt.target != null) { evt.propagateToIMGUI = false; EventDispatchUtilities.PropagateEvent(evt); } } if (!evt.isPropagationStopped && panel != null) { if (evt.propagateToIMGUI || evt.eventTypeId == MouseEnterWindowEvent.TypeId() || evt.eventTypeId == MouseLeaveWindowEvent.TypeId() ) { EventDispatchUtilities.PropagateToIMGUIContainer(panel.visualTree, evt); } } evt.stopDispatch = true; }