Page 1 of 1

Over Noesis GUI

Posted: 19 Apr 2015, 05:19
by cosmo
I am attempting to figure out an easy way to tell if the mouse is currently over any noesis gui element.

The reason for this is because I have an RTS style game with a selection box, I want to draw the selection box if I am not over a control, if i am over a control I want the control behavior to work.

Is there any easy way to tell when the mouse is clicked if it was clicked over a control or not?

The basic layout I have is a grid control with the background set to transparent. There are controls on the bottom and top. If the mouse is over one of these controls then I would not want the game event to occur and instead would like the gui event to occur.

I have a few poor workarounds atm such as whenever the mouse is clicked I iterate over the entire control hiearchy and check each control bounds to see if he mouse is over it. It seems to work but seems horribly inefficient.

Re: Over Noesis GUI

Posted: 20 Apr 2015, 12:04
by sfernandez
Hi,

You can use VisualTreeHelper::HitTest() to check if mouse is over any UI element. You only need to provide the root of the UI tree and mouse position:
Ptr<FrameworkElement> xaml = GUI::LoadXaml<FrameworkElement>("MainWindow.xaml");
Ptr<IRenderer> uiRenderer = GUI::CreateRenderer(xaml.GetPtr());
...
Visual* root = VisualTreeHelper::GetRoot(uiRenderer->GetContent());
HitTestResult hit = VisualTreeHelper::HitTest(root, Point(mousePosX, mousePosY));
if (hit.visualHit != 0)
{
    // Mouse is over a UI element
}

Re: Over Noesis GUI

Posted: 18 May 2015, 14:46
by cosmo
I am having trouble utilizing this. It works on an individual item but not on that items parent.

For Example.

If I have a button in a grid and the mouse is hovering over the button.
I hit test the grid, the element returned from the hit test is null.
I hit test the button itself then the element returned from the hit test is the button.

Is the intended functionality to have to hit test each item looping through the user interface or should I be able to hit test the grid and it returns the button.

I can provide an example if needed to clarify.

Re: Over Noesis GUI

Posted: 18 May 2015, 20:22
by sfernandez
If you call VisualTreeHelper::GetRoot() on the Grid or the Button before calling HitTest() the result must be the same, because the root is the same for both.

And the provided point must be in the surface coordinate system.

You need to convert screen mouse position to window client rect surface, then call VisualTreeHelper::GetRoot() to get the root of the UI tree, and finally call VisualTreeHelper::HitTest().

Have you tried this way?

Re: Over Noesis GUI

Posted: 21 May 2015, 15:15
by cosmo
This did end up working, I didn't convert the coordinate system from unity to wpf coordinate in my first attempt.

Here is the working code.
        private Visual _mainContent;

        public bool OverUIElement
        {
            get
            {
                if (_mainContent == null)
                {
                    var panel = Camera.main.GetComponent<NoesisGUIPanel>();
                    _mainContent = VisualTreeHelper.GetRoot(panel.GetContent());
                }
                var x = Input.mousePosition.x;
                var y = Screen.height - Input.mousePosition.y;
                var hitTestResult = VisualTreeHelper.HitTest(_mainContent, new Point(x, y));
                if (hitTestResult.visualHit != null)
                {
                    return true;
                }
                return false;
            }
        }