Esempio n. 1
0
        static internal Stack <HtmlCanvasElement> SearchElement(HtmlCanvas canvas, HtmlCanvasElement elem)
        {
            // Store the path to the current element:
            var path = new Stack <HtmlCanvasElement>();

            // Same as above, but stores the path in an alternative way, that is, by storing the index of each element in the parent collection:
            var currentPathIndexes = new Stack <int>();

            // Work with every Canvas child:
            for (int i = 0; i < canvas.Children.Count; ++i)
            {
                // Start the traversal by inserting the first element:
                path.Push(canvas.Children[i]);
                currentPathIndexes.Push(0);

                while (path.Count > 0)
                {
                    HtmlCanvasElement currentElement = path.Peek();
                    int index = currentPathIndexes.Pop(); // The current index inside the Children collection of the "currentElement"

                    // Return 'path' if the element was found
                    if (currentElement == elem)
                    {
                        return(path);
                    }

                    if (currentElement.IsHitTestVisible && currentElement is ContainerElement && index < ((ContainerElement)currentElement).Children.Count)
                    {
                        // Increment the last element of the "currentPathIndexes":
                        currentPathIndexes.Push(index + 1);

                        // Add the child:
                        path.Push(((ContainerElement)currentElement).Children[index]);
                        currentPathIndexes.Push(0);
                    }
                    else
                    {
                        // Remove the last element from the paths to "go up":
                        path.Pop();
                    }
                }
            }
            return(null);
        }
Esempio n. 2
0
        /// <summary>
        /// Return the path to the topmost element that is under the pointer
        /// </summary>
        /// <param name="canvas">The container of the elements</param>
        /// <returns>The path to the topmost element that is under the pointer</returns>
        static internal Stack <HtmlCanvasElement> GetPointedElements(HtmlCanvas canvas, double x, double y)
        {
            // Store the path to the element that is the topmost element. During traversal, this contains the path to the element that is considered topmost, until replaced by another element that is even more in the foreground:
            var finalPath = new Stack <HtmlCanvasElement>();

            // Store the path to the current element:
            var currentPath = new Stack <HtmlCanvasElement>();

            // Same as above, but stores the path in an alternative way, that is, by storing the index of each element in the parent collection:
            var currentPathIndexes = new Stack <int>();

            // Work with every Canvas child:
            for (int i = 0; i < canvas.Children.Count; ++i)
            {
                // Note: currentPath should be empty at this point.

                // Start the traversal by inserting the first element:
                currentPath.Push(canvas.Children[i]);
                currentPathIndexes.Push(0);

                while (currentPath.Count > 0)
                {
                    HtmlCanvasElement currentElement = currentPath.Peek();
                    int index = currentPathIndexes.Pop(); // The current index inside the Children collection of the "currentElement"

                    // Refresh 'finalPath' if another element is found under the cursor
                    if (currentElement.IsHitTestVisible && currentElement.Visibility == Visibility.Visible && currentElement.IsPointed(x, y) &&
                        Array.IndexOf(finalPath.ToArray(), currentElement) == -1)
                    {
                        finalPath.Clear();
                        var path = currentPath.ToArray();          // Right now some methods for the Stack are not implemented in JSIL
                        for (int j = path.Length - 1; j >= 0; --j) // so we use a ToArray() method, which is not the best option for performances
                        {
                            finalPath.Push(path[j]);
                        }
                    }

                    if (currentElement.IsHitTestVisible && currentElement.Visibility == Visibility.Visible &&
                        currentElement is ContainerElement && index < ((ContainerElement)currentElement).Children.Count)
                    {
                        // Increment the last element of the "currentPathIndexes":
                        currentPathIndexes.Push(index + 1);

                        // Move x and y relative to the last element position
                        x -= currentElement.X;
                        y -= currentElement.Y;
                        // Add the child:
                        currentPath.Push(((ContainerElement)currentElement).Children[index]);
                        currentPathIndexes.Push(0);
                    }
                    else
                    {
                        // Remove the last element from the paths to "go up":
                        currentPath.Pop();
                        if (currentPath.Count > 0)
                        {
                            // Remove x and y relative to the last element position
                            x += currentPath.Peek().X;
                            y += currentPath.Peek().Y;
                        }
                    }
                }
            }
            return(finalPath);
        }