Jump to content

GetUnderCursorWidget Z Order


photo

Recommended Posts

Posted

`GetUnderCursorWidget()` seems to return the back (WidgetWindow) widget even when over a child widget. Is this the expected behavior? If so, what is the best way to get the actual top widget?

Here I have a Button that extends past the  WidgetWindow.
Clicking:
WidgetWindow => WidgetWindow
WidgetButton in area over WidgetWindow => WIdgetWindow
WidgetButton in area outside of WIdgetWindow => WidgetButton
 

// Test Window and Button
static void AddGuiTestWindow() {
  Gui gui = Gui.GetCurrent();
  WidgetWindow window = new(gui, "Test", 100, 100);
  WidgetButton button = new("Click");
  button.SetPosition(50, 50);  button.Height = 400;  button.Width = 200;
  button.EventClicked.Connect(() => { Unigine.Console.WriteLine("Button clicked"); });
  window.AddChild(button, Gui.ALIGN_OVERLAP);
  gui.AddChild(window, Gui.ALIGN_OVERLAP);
}

// Test Event
Input.EventMouseDown.Connect(()=>{
  Widget widget = Gui.GetCurrent().GetUnderCursorWidget();
  Unigine.Console.WriteLine(widget);
});

 

Posted

Hello.

Yes, at the moment this is the expected behavior. The first widget from the hierarchy that is under the cursor is returned. For your task, you can implement a different hierarchy traversal.

public static Widget GetUnderCursorWidget()
{
	Gui currentGui = Gui.GetUnderCursorGui();
	if (currentGui == null)
		return null;

	return GetHierarchyIntersection(currentGui.VBox);
}

public static Widget GetHierarchyIntersection(Widget rootWidget)
{
	if (rootWidget == null)
		return null;

	// focused and overlapping widget
	for (int i = 0; i < rootWidget.NumChildren; i++)
	{
		Widget child = rootWidget.GetChild(i);
		if (child.IsFocused() == 1 && child.IsOverlapped)
		{
			Widget ret = GetHierarchyIntersection(child);
			if (ret != null)
				return ret;
			break;
		}
	}

	// overlapping widgets
	for (int i = rootWidget.NumChildren - 1; 0 <= i; i--)
	{
		Widget child = rootWidget.GetChild(i);
		if (child.IsOverlapped)
		{
			Widget ret = GetHierarchyIntersection(child);
			if (ret != null)
				return ret;
		}
	}

	// non-background widgets
	for (int i = 0; i < rootWidget.NumChildren; i++)
	{
		Widget child = rootWidget.GetChild(i);
		if (child.IsOverlapped == false && child.IsBackground == false)
		{
			Widget ret = GetHierarchyIntersection(child);
			if (ret != null)
				return ret;
		}
	}

	// background widgets
	for (int i = rootWidget.NumChildren - 1; 0 <= i; i--)
	{
		Widget child = rootWidget.GetChild(i);
		if (child.IsOverlapped == false && child.IsBackground)
		{
			Widget ret = GetHierarchyIntersection(child);
			if (ret != null)
				return ret;
		}
	}

	if (rootWidget.GetIntersection(rootWidget.MouseX, rootWidget.MouseY))
		return rootWidget;
	return null;
}

 

  • Like 1
×
×
  • Create New...