Пример #1
0
        private void ProcessMouseInput()
        {
            // if element does not have state requested -> hover flag, drag listener, pointer events = none, don't add
            // buckets feel like a lot of overhead
            // for each element, track if has overflowing children
            // if it does not and element is culled, skip directly to children's children and repeat
            // if aabb yMin is below screen height or aabb ymax is less than 0 -> cull

            // broadphase culling and input querying are related
            // neither uses render bounds, just obb and aabb
            // if dragging only attempt intersections with elements who have drag responders
            // if not dragging only attempt intersections with elements who have hover state (if mouse is present) or drag create or mouse / touch interactions

            LightList <UIElement> queryResults = (LightList <UIElement>)m_LayoutSystem.QueryPoint(mouseState.mousePosition, LightList <UIElement> .Get());

            // todo -- bug!
            queryResults.Sort((a, b) => {
                int viewDepthComparison = b.View.Depth - a.View.Depth;
                if (viewDepthComparison != 0)
                {
                    return(viewDepthComparison);
                }

                if (b.layoutBox.layer != a.layoutBox.layer)
                {
                    return(b.layoutBox.layer - a.layoutBox.layer);
                }

                if (b.layoutBox.zIndex != a.layoutBox.zIndex)
                {
                    return(b.layoutBox.zIndex - a.layoutBox.zIndex);
                }

                return(b.layoutBox.traversalIndex - a.layoutBox.traversalIndex);
            });

            m_AllElementsThisFrame.Clear();
            m_AllElementsThisFrame.AddRange(queryResults);

            if (!IsDragging)
            {
                LightList <UIElement> ancestorElements = LightList <UIElement> .Get();

                if (queryResults.size > 0)
                {
                    /*
                     * Every following element must be a parent of the first.
                     * This makes no sense for drag events but a lot for every other.
                     */
                    UIElement firstElement = queryResults[0];
                    ancestorElements.Add(firstElement);

                    for (int index = 1; index < queryResults.size; index++)
                    {
                        UIElement element = queryResults[index];
                        if (IsParentOf(element, firstElement))
                        {
                            ancestorElements.Add(element);
                        }
                    }

                    LightList <UIElement> .Release(ref queryResults);

                    queryResults = ancestorElements;
                }
            }

            bool didMouseMove = mouseState.DidMove;

            if (didMouseMove)
            {
                for (int i = 0; i < hoveredElements.size; i++)
                {
                    UIElement element = hoveredElements.array[i];

                    if ((element.flags & UIElementFlags.EnabledFlagSet) != UIElementFlags.EnabledFlagSet)
                    {
                        hoveredElements.RemoveAt(i--);
                        continue;
                    }

                    if (!queryResults.Contains(element))
                    {
                        hoveredElements.RemoveAt(i--);
                        element.style.ExitState(StyleState.Hover);
                    }
                }

                for (int i = 0; i < queryResults.Count; i++)
                {
                    UIElement element = queryResults.array[i];

                    if ((element.style.currentState & StyleState.Hover) == 0)
                    {
                        hoveredElements.Add(element);
                        element.style.EnterState(StyleState.Hover);
                    }
                }
            }

            for (int i = 0; i < queryResults.Count; i++)
            {
                UIElement element = queryResults[i];

                m_ElementsThisFrame.Add(element);

                if (!m_ElementsLastFrame.Contains(element))
                {
                    m_EnteredElements.Add(element);
                }

                if (IsMouseLeftDownThisFrame)
                {
                    element.style?.EnterState(StyleState.Active);
                    m_ActiveElements.Add(element);
                }
            }

            for (int i = 0; i < m_ElementsLastFrame.Count; i++)
            {
                if (!m_ElementsThisFrame.Contains(m_ElementsLastFrame[i]))
                {
                    m_ExitedElements.Add(m_ElementsLastFrame[i]);
                }
            }

            if (IsMouseLeftUpThisFrame)
            {
                for (int i = 0; i < m_ActiveElements.Count; i++)
                {
                    m_ActiveElements[i].style?.ExitState(StyleState.Active);
                }

                m_ActiveElements.Clear();
            }

            if (!IsDragging)
            {
                CursorStyle newCursor = null;
                if (m_ElementsThisFrame.Count > 0)
                {
                    for (int i = 0; i < m_ElementsThisFrame.Count; i++)
                    {
                        UIElement element = m_ElementsThisFrame[i];
                        if (element.isDestroyed)
                        {
                            continue;
                        }

                        if (element.style.IsDefined(StylePropertyId.Cursor))
                        {
                            newCursor = element.style.Cursor;
                            if (!newCursor.Equals(currentCursor))
                            {
                                Cursor.SetCursor(newCursor.texture, newCursor.hotSpot, CursorMode.Auto);
                            }

                            break;
                        }
                    }
                }

                if (currentCursor != null && newCursor == null)
                {
                    Cursor.SetCursor(null, new Vector2(0, 0), CursorMode.Auto);
                }

                currentCursor = newCursor;

                if (mouseState.AnyMouseDownThisFrame)
                {
                    m_MouseDownElements.AddRange(m_ElementsThisFrame);
                }
            }

            LightList <UIElement> .Release(ref queryResults);
        }
Пример #2
0
        public static void Tessellate(LightList <float> input, LightList <int> holeIndices, LightList <int> output)
        {
            float[] data     = input.Array;
            bool    hasHoles = holeIndices.Count > 0;
            int     outerLen = hasHoles ? holeIndices[0] * 2 : input.Count;

            Node outerNode = LinkedList(data, 0, outerLen, true);

            LightList <int> triangles = output ?? new LightList <int>();

            if (outerNode == null)
            {
                return;
            }

            float minX    = float.PositiveInfinity;
            float minY    = float.PositiveInfinity;
            float maxX    = float.NegativeInfinity;
            float maxY    = float.NegativeInfinity;
            float invSize = default(float);


            if (hasHoles)
            {
                outerNode = EliminateHoles(input, holeIndices, outerNode);
            }

            // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
            if (input.Count > 80 * 2)
            {
                for (int i = 0; i < outerLen; i += 2)
                {
                    float x = data[i];
                    float y = data[i + 1];

                    if (x < minX)
                    {
                        minX = x;
                    }

                    if (y < minY)
                    {
                        minY = y;
                    }

                    if (x > maxX)
                    {
                        maxX = x;
                    }

                    if (y > maxY)
                    {
                        maxY = y;
                    }
                }

                // minX, minY and invSize are later used to transform coords into integers for z-order calculation
                invSize = Math.Max(maxX - minX, maxY - minY);
                invSize = invSize != 0 ? 1 / invSize : 0;
            }

            EarcutLinked(outerNode, triangles, minX, minY, invSize);

            // pooling clears on Get, not release so we don't need to re-iterate the list
            inactive.AddRange(active);
            active.QuickClear();
        }