Jump to content

Preventing UI Click-Through


photo

Recommended Posts

Is there an easy/built-in way to prevent clicking on a UI item from passing through to the World?
-If I have an Input.MOUSE_DOWN event (new Input System) and I create a pop-up window, actions like dragging the window or clicking in a textbox fire the mouse event. This is expected, but not always desired behavior. Is there a (simple) way to detect UI hits and prevent other events from firing?      

Link to comment

Hi Silent,

In the code below the `Mouse` function will get called on any MOUSE_DOWN.
In this example I would be placing objects in the world at the mouse coordinates.
I may pop up a config window for the objects being placed. (I just use a fixed window here)
If the window is up and I click on the GUI element/Widget I don't want the placement code to run.

I'm looking for a way to do this without having to mask a lot of things or carry state variables around.

static class Program {
    public static IntPtr clickPtr;
    static WidgetWindow window = new WidgetWindow("Modes", 4, 4);

    [STAThread]
    static void Main(string[] args) {
        Engine.Init(args);

        clickPtr = AddCallback(CALLBACK_INDEX.MOUSE_DOWN, Mouse);

        window.Flags = Gui.ALIGN_OVERLAP | Gui.ALIGN_LEFT;
        window.Width = 320;
        window.Arrange();
        Gui.Get().AddChild(window);

        void Mouse(MOUSE_BUTTON button) {
            // if (clicked_on_widget) return
            PlaceNewObjectInWorld(...);
            }

        Engine.Main();
        Engine.Shutdown();
        }
    }

 

Link to comment

Hello,

In version 2.16 the GUI has a GetUnderCursorWidget() method to get the widget under the cursor. You can try to use it in this case.

public static IntPtr clickPtr;
static WidgetWindow window = new WidgetWindow("Modes", 4, 4);

public override bool Init()
{
	clickPtr = Input.AddCallback(Input.CALLBACK_INDEX.MOUSE_DOWN, Mouse);

	window.Flags = Gui.ALIGN_OVERLAP | Gui.ALIGN_LEFT;
	window.Width = 320;
	window.Arrange();
	Gui.GetCurrent().AddChild(window);

	return true;
}

void Mouse(Input.MOUSE_BUTTON button)
{
	if (Unigine.Console.Active || Gui.GetCurrent().GetUnderCursorWidget() != null)
		return;

	PlaceNewObjectInWorld(...);
}

 

  • Thanks 1
Link to comment

Yes, this method doesn't return the layout widgets (VBox, HBox, GridBox) and also ignores the console widget, the profiler widget, and widgets inside the EngineWindow as a separate window and as a group. Otherwise, we would always have a widget under the mouse, since the Gui contains the root VBox, and some widgets use layouts internally as containers.

Link to comment
×
×
  • Create New...