internal void SetPanel(BaseVisualElementPanel p) { if (panel == p) { return; } //We now gather all Elements in order to dispatch events in an efficient manner List <VisualElement> elements = VisualElementListPool.Get(); try { elements.Add(this); GatherAllChildren(elements); EventDispatcher.Gate?pDispatcherGate = null; if (p?.dispatcher != null) { pDispatcherGate = new EventDispatcher.Gate(p.dispatcher); } EventDispatcher.Gate?panelDispatcherGate = null; if (panel?.dispatcher != null && panel.dispatcher != p?.dispatcher) { panelDispatcherGate = new EventDispatcher.Gate(panel.dispatcher); } using (pDispatcherGate) using (panelDispatcherGate) { foreach (var e in elements) { e.ChangePanel(p); } } } finally { VisualElementListPool.Release(elements); } }
private static bool DoDispatch(BaseVisualElementPanel panel) { bool result; if (UIElementsUtility.s_EventInstance.type == EventType.Repaint) { panel.Repaint(UIElementsUtility.s_EventInstance); result = (panel.IMGUIContainersCount > 0); } else { panel.ValidateLayout(); EventPropagation eventPropagation = UIElementsUtility.s_EventDispatcher.DispatchEvent(UIElementsUtility.s_EventInstance, panel); if (eventPropagation == EventPropagation.Stop) { panel.visualTree.Dirty(ChangeType.Repaint); } result = (eventPropagation == EventPropagation.Stop); } return(result); }
void ChangePanel(BaseVisualElementPanel p) { if (panel == p) { return; } if (panel != null) { using (var e = DetachFromPanelEvent.GetPooled(panel, p)) { e.target = this; elementPanel.SendEvent(e, DispatchMode.Immediate); } } IPanel prevPanel = panel; elementPanel = p; if (panel != null) { using (var e = AttachToPanelEvent.GetPooled(prevPanel, p)) { e.target = this; elementPanel.SendEvent(e, DispatchMode.Immediate); } } // styles are dependent on topology IncrementVersion(VersionChangeType.StyleSheet | VersionChangeType.Layout | VersionChangeType.Transform); // persistent data key may have changed or needs initialization if (!string.IsNullOrEmpty(persistenceKey)) { IncrementVersion(VersionChangeType.PersistentData); } }
internal virtual void ChangePanel(BaseVisualElementPanel p) { if (panel == p) { return; } if (panel != null) { using (var e = DetachFromPanelEvent.GetPooled()) { e.target = this; UIElementsUtility.eventDispatcher.DispatchEvent(e, panel); } } elementPanel = p; if (panel != null) { using (var e = AttachToPanelEvent.GetPooled()) { e.target = this; UIElementsUtility.eventDispatcher.DispatchEvent(e, panel); } } Dirty(ChangeType.Styles); if (m_Children != null && m_Children.Count > 0) { for (var index = 0; index < m_Children.Count; index++) { var child = m_Children[index]; child.ChangePanel(p); } } }
public EventPropagation DispatchEvent(Event e, BaseVisualElementPanel panel) { EventPropagation result; if (e.type == EventType.Repaint) { Debug.Log("Repaint should be handled by Panel before Dispatcher"); result = EventPropagation.Continue; } else { bool flag = false; if (panel.panelDebug != null && panel.panelDebug.enabled && panel.panelDebug.interceptEvents != null && panel.panelDebug.interceptEvents(e)) { result = EventPropagation.Stop; } else { if (this.capture != null && this.capture.panel == null) { Debug.Log(string.Format("Capture has no panel, forcing removal (capture={0} eventType={1})", this.capture, e.type)); this.RemoveCapture(); } if (this.capture != null) { if (this.capture.panel.contextType != panel.contextType) { result = EventPropagation.Continue; return(result); } VisualElement visualElement = this.capture as VisualElement; if (visualElement != null) { e.mousePosition = visualElement.GlobalToBound(e.mousePosition); } else { IManipulator manipulator = this.capture as IManipulator; if (manipulator != null) { e.mousePosition = manipulator.target.GlobalToBound(e.mousePosition); } } flag = true; if (this.capture.HandleEvent(e, this.capture as VisualElement) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } if (e.isKey) { flag = true; if (panel.focusedElement != null) { if (this.PropagateEvent(panel.focusedElement, e) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } else if (this.SendEventToIMGUIContainers(panel.visualTree, e, panel.focusedElement) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } else if (e.isMouse || e.isScrollWheel || e.type == EventType.DragUpdated || e.type == EventType.DragPerform || e.type == EventType.DragExited) { if (e.type == EventType.MouseLeaveWindow) { this.elementUnderMouse = null; } else { this.elementUnderMouse = panel.Pick(e.mousePosition); } if (e.type == EventType.MouseDown && this.elementUnderMouse != null && this.elementUnderMouse.enabled) { this.SetFocusedElement(panel, this.elementUnderMouse); } if (this.elementUnderMouse != null) { flag = true; if (this.PropagateEvent(this.elementUnderMouse, e) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } if (e.type == EventType.MouseEnterWindow || e.type == EventType.MouseLeaveWindow) { flag = true; if (this.SendEventToIMGUIContainers(panel.visualTree, e, null) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } } if (e.type == EventType.ExecuteCommand || e.type == EventType.ValidateCommand) { flag = true; if (panel.focusedElement != null && this.PropagateEvent(panel.focusedElement, e) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } if (this.SendEventToIMGUIContainers(panel.visualTree, e, panel.focusedElement) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } if (e.type == EventType.Used) { flag = true; if (this.SendEventToIMGUIContainers(panel.visualTree, e, null) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } if (!flag) { if (this.SendEventToIMGUIContainers(panel.visualTree, e, null) == EventPropagation.Stop) { result = EventPropagation.Stop; return(result); } } result = EventPropagation.Continue; } } return(result); }
void ProcessEvent(EventBase evt, IPanel panel) { using (new Gate(this)) { evt.PreDispatch(); var panelDebug = (panel as BaseVisualElementPanel)?.panelDebug; if (panelDebug != null && panelDebug.showOverlay) { if (panelDebug.InterceptEvents(evt.imguiEvent)) { evt.StopPropagation(); evt.PostDispatch(); return; } } IMouseEvent mouseEvent = evt as IMouseEvent; IMouseEventInternal mouseEventInternal = evt as IMouseEventInternal; if (mouseEvent != null && mouseEventInternal != null && mouseEventInternal.hasUnderlyingPhysicalEvent) { m_LastMousePositionPanel = panel; m_LastMousePosition = mouseEvent.mousePosition; } bool eventHandled = false; // Release mouse capture if capture element is not in a panel. VisualElement captureVE = MouseCaptureController.mouseCapture as VisualElement; if (evt.GetEventTypeId() != MouseCaptureOutEvent.TypeId() && captureVE != null && captureVE.panel == null) { Event e = evt.imguiEvent; Debug.Log(String.Format("Capture has no panel, forcing removal (capture={0} eventType={1})", MouseCaptureController.mouseCapture, e != null ? e.type.ToString() : "null")); MouseCaptureController.ReleaseMouse(); } // Send all IMGUI events (for backward compatibility) and MouseEvents with null target (because thats what we want to do in the new system) // to the capture, if there is one. Note that events coming from IMGUI have their target set to null. bool sendEventToMouseCapture = false; bool mouseEventWasCaptured = false; if (MouseCaptureController.mouseCapture != null) { if (evt.imguiEvent != null && evt.target == null) { // Non exclusive processing by capturing element. sendEventToMouseCapture = true; mouseEventWasCaptured = false; } if (mouseEvent != null && (evt.target == null || evt.target == MouseCaptureController.mouseCapture)) { // Exclusive processing by capturing element. sendEventToMouseCapture = true; mouseEventWasCaptured = true; } if (panel != null) { if (captureVE != null && captureVE.panel.contextType != panel.contextType) { // Capturing element is not in the right context. Ignore it. sendEventToMouseCapture = false; mouseEventWasCaptured = false; } } if (evt.GetEventTypeId() == WheelEvent.TypeId()) { sendEventToMouseCapture = false; mouseEventWasCaptured = false; } } evt.skipElement = null; if (sendEventToMouseCapture) { BaseVisualElementPanel basePanel = panel as BaseVisualElementPanel; if (mouseEvent != null && basePanel != null) { VisualElement currentTopElementUnderMouse = basePanel.topElementUnderMouse; if (evt.target == null) { basePanel.topElementUnderMouse = basePanel.Pick(mouseEvent.mousePosition); } DispatchEnterLeaveEvents(currentTopElementUnderMouse, basePanel.topElementUnderMouse, evt); } IEventHandler originalCaptureElement = MouseCaptureController.mouseCapture; eventHandled = true; evt.dispatch = true; evt.target = MouseCaptureController.mouseCapture; evt.currentTarget = MouseCaptureController.mouseCapture; evt.propagationPhase = PropagationPhase.AtTarget; MouseCaptureController.mouseCapture.HandleEvent(evt); // Do further processing with a target computed the usual way. // However, if mouseEventWasCaptured, the only thing remaining to do is ExecuteDefaultAction, // which whould be done with mouseCapture as the target. if (!mouseEventWasCaptured) { evt.target = null; } evt.currentTarget = null; evt.propagationPhase = PropagationPhase.None; evt.dispatch = false; // Do not call HandleEvent again for this element. evt.skipElement = originalCaptureElement; } if (!mouseEventWasCaptured && !evt.isPropagationStopped) { if (evt is IKeyboardEvent && panel != null) { eventHandled = true; if (panel.focusController.focusedElement != null) { IMGUIContainer imguiContainer = panel.focusController.focusedElement as IMGUIContainer; if (imguiContainer != null) { // THINK ABOUT THIS PF: shoudln't we allow for the TrickleDown dispatch phase? if (imguiContainer != evt.skipElement && imguiContainer.HandleIMGUIEvent(evt.imguiEvent)) { evt.StopPropagation(); evt.PreventDefault(); } } else { evt.target = panel.focusController.focusedElement; PropagateEvent(evt); } } else { evt.target = panel.visualTree; PropagateEvent(evt); if (!evt.isPropagationStopped) { PropagateToIMGUIContainer(panel.visualTree, evt); } } } else if (mouseEvent != null) { // 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.GetEventTypeId() == MouseLeaveWindowEvent.TypeId()) { VisualElement currentTopElementUnderMouse = basePanel.topElementUnderMouse; basePanel.topElementUnderMouse = null; DispatchMouseEnterMouseLeave(currentTopElementUnderMouse, basePanel.topElementUnderMouse, mouseEvent); DispatchMouseOverMouseOut(currentTopElementUnderMouse, basePanel.topElementUnderMouse, mouseEvent); } else if (basePanel != null && evt.GetEventTypeId() == DragExitedEvent.TypeId()) { VisualElement currentTopElementUnderMouse = basePanel.topElementUnderMouse; basePanel.topElementUnderMouse = null; DispatchDragEnterDragLeave(currentTopElementUnderMouse, basePanel.topElementUnderMouse, mouseEvent); } // update element under mouse and fire necessary events else { VisualElement currentTopElementUnderMouse = null; if (evt.target == null && basePanel != null) { currentTopElementUnderMouse = basePanel.topElementUnderMouse; basePanel.topElementUnderMouse = panel.Pick(mouseEvent.mousePosition); evt.target = basePanel.topElementUnderMouse; } if (evt.target != null) { eventHandled = true; PropagateEvent(evt); } if (basePanel != null) { DispatchEnterLeaveEvents(currentTopElementUnderMouse, basePanel.topElementUnderMouse, evt); } } } else if (panel != null && evt is ICommandEvent) { IMGUIContainer imguiContainer = panel.focusController.focusedElement as IMGUIContainer; eventHandled = true; if (imguiContainer != null) { if (imguiContainer != evt.skipElement && imguiContainer.HandleIMGUIEvent(evt.imguiEvent)) { evt.StopPropagation(); evt.PreventDefault(); } } else if (panel.focusController.focusedElement != null) { evt.target = panel.focusController.focusedElement; PropagateEvent(evt); } else { PropagateToIMGUIContainer(panel.visualTree, evt); } } else if (evt is IPropagatableEvent || evt is IFocusEvent || evt is IChangeEvent || evt.GetEventTypeId() == InputEvent.TypeId() || evt.GetEventTypeId() == GeometryChangedEvent.TypeId()) { Debug.Assert(evt.target != null); eventHandled = true; PropagateEvent(evt); } } if (!mouseEventWasCaptured && !evt.isPropagationStopped && panel != null) { Event e = evt.imguiEvent; if (!eventHandled || (e != null && e.type == EventType.Used) || evt.GetEventTypeId() == MouseEnterWindowEvent.TypeId() || evt.GetEventTypeId() == MouseLeaveWindowEvent.TypeId()) { PropagateToIMGUIContainer(panel.visualTree, evt); } } if (evt.target == null && panel != null) { evt.target = panel.visualTree; } ExecuteDefaultAction(evt); evt.PostDispatch(); } }