void DispatchMouseOverMouseOut(VisualElement previousTopElementUnderMouse, VisualElement currentTopElementUnderMouse, IMouseEvent triggerEvent)
        {
            if (previousTopElementUnderMouse == currentTopElementUnderMouse)
            {
                return;
            }

            // Send MouseOut event for element no longer under the mouse.
            if (previousTopElementUnderMouse != null && previousTopElementUnderMouse.panel != null)
            {
                using (var outEvent = (triggerEvent == null) ? MouseOutEvent.GetPooled(m_LastMousePosition) : MouseOutEvent.GetPooled(triggerEvent))
                {
                    outEvent.target = previousTopElementUnderMouse;
                    previousTopElementUnderMouse.SendEvent(outEvent);
                }
            }

            // Send MouseOver event for element now under the mouse
            if (currentTopElementUnderMouse != null)
            {
                using (var overEvent = (triggerEvent == null) ? MouseOverEvent.GetPooled(m_LastMousePosition) : MouseOverEvent.GetPooled(triggerEvent))
                {
                    overEvent.target = currentTopElementUnderMouse;
                    currentTopElementUnderMouse.SendEvent(overEvent);
                }
            }
        }
Exemple #2
0
        private void UpdateSubTree(VisualElement root)
        {
            Rect yogaRect    = new Rect(root.yogaNode.LayoutX, root.yogaNode.LayoutY, root.yogaNode.LayoutWidth, root.yogaNode.LayoutHeight);
            Rect lastRect    = root.renderData.lastLayout;
            bool rectChanged = lastRect != yogaRect;

            // If the last layout rect is different than the current one we must dirty transform on children
            if (rectChanged)
            {
                if (yogaRect.position != lastRect.position)
                {
                    root.IncrementVersion(VersionChangeType.Transform);
                }
                root.IncrementVersion(VersionChangeType.Clip);
                root.renderData.lastLayout = yogaRect;
            }

            // ignore clean sub trees
            bool hasNewLayout = root.yogaNode.HasNewLayout;

            if (hasNewLayout)
            {
                for (int i = 0; i < root.shadow.childCount; ++i)
                {
                    UpdateSubTree(root.shadow[i]);
                }
            }

            if (rectChanged)
            {
                using (var evt = GeometryChangedEvent.GetPooled(lastRect, yogaRect))
                {
                    evt.target = root;
                    root.SendEvent(evt);
                }
            }

            if (hasNewLayout)
            {
                root.yogaNode.MarkLayoutSeen();
                // Layout change require a repaint
                root.IncrementVersion(VersionChangeType.Repaint);
            }
        }
        void DispatchEnterLeave(VisualElement previousTopElementUnderMouse, VisualElement currentTopElementUnderMouse, Func <EventBase> getEnterEventFunc, Func <EventBase> getLeaveEventFunc)
        {
            if (previousTopElementUnderMouse == currentTopElementUnderMouse)
            {
                return;
            }

            if (previousTopElementUnderMouse != null && previousTopElementUnderMouse.panel == null)
            {
                // If previousTopElementUnderMouse has been removed from panel,
                // do as if there is no element under the mouse.
                previousTopElementUnderMouse = null;
            }

            // We want to find the common ancestor CA of previousTopElementUnderMouse and currentTopElementUnderMouse,
            // send Leave (MouseLeave or DragLeave) events to elements between CA and previousTopElementUnderMouse
            // and send Enter (MouseEnter or DragEnter) events to elements between CA and currentTopElementUnderMouse.

            int prevDepth = 0;
            var p         = previousTopElementUnderMouse;

            while (p != null)
            {
                prevDepth++;
                p = p.shadow.parent;
            }

            int currDepth = 0;
            var c         = currentTopElementUnderMouse;

            while (c != null)
            {
                currDepth++;
                c = c.shadow.parent;
            }

            p = previousTopElementUnderMouse;
            c = currentTopElementUnderMouse;

            while (prevDepth > currDepth)
            {
                using (var leaveEvent = getLeaveEventFunc())
                {
                    leaveEvent.target = p;
                    p.SendEvent(leaveEvent);
                }

                prevDepth--;
                p = p.shadow.parent;
            }

            // We want to send enter events after all the leave events.
            // We will store the elements being entered in this list.
            List <VisualElement> enteringElements = VisualElementListPool.Get(currDepth);

            while (currDepth > prevDepth)
            {
                enteringElements.Add(c);

                currDepth--;
                c = c.shadow.parent;
            }

            // Now p and c are at the same depth. Go up the tree until p == c.
            while (p != c)
            {
                using (var leaveEvent = getLeaveEventFunc())
                {
                    leaveEvent.target = p;
                    p.SendEvent(leaveEvent);
                }

                enteringElements.Add(c);

                p = p.shadow.parent;
                c = c.shadow.parent;
            }

            for (var i = enteringElements.Count - 1; i >= 0; i--)
            {
                using (var enterEvent = getEnterEventFunc())
                {
                    enterEvent.target = enteringElements[i];
                    enteringElements[i].SendEvent(enterEvent);
                }
            }
            VisualElementListPool.Release(enteringElements);
        }