Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a function to get all Control nodes at a specific position #8408

Open
popcar2 opened this issue Nov 12, 2023 · 4 comments
Open

Add a function to get all Control nodes at a specific position #8408

popcar2 opened this issue Nov 12, 2023 · 4 comments

Comments

@popcar2
Copy link

popcar2 commented Nov 12, 2023

Describe the project you are working on

I'm creating an OS-like interface in Godot. I want to show a context menu when the player right clicks the mouse. Depending on what the player right clicks, it would show different options in the context menu.

The context menu is an autoload and I'd prefer if all the right click handling code was inside of it.

Describe the problem or limitation you are having in your project

There is no way to get the Control node(s) that the mouse right clicked. A Control node can only know when it got right clicked itself, but there's no way to globally know which Control nodes in general were clicked.

For example if I want a folder, taskbar, and window to show different context menus when right clicked, I would have to write code in each one of them to handle the right click then signal it to my context menu autoload. This isn't very intuitive or scalable.

I also needed this in other tasks, such as being able to click anywhere to de-select a folder, a very common feature in user interfaces.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

A global function to get the Control nodes under the mouse while respecting mouse_filter rules.

It could also be a more generic function to get Control nodes at any position (where I can then give it get_global_mouse_position()).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

func _input(event):
    if event is InputEventMouseButton and event.button_index == 2:
        var mouse_pos = get_global_mouse_position()
        var control_nodes = get_control_nodes_at_pos(mouse_pos)
        for node in control_nodes:
            # Do something here

If this enhancement will not be used often, can it be worked around with a few lines of script?

It's hackier than a usual workaround, but I added a component that handles right clicking of each node in a specific group. This isn't intuitive or performant.

Is there a reason why this should be core and not an add-on in the asset library?

Knowing what you clicked and haven't clicked is commonly needed when developing advanced UI. I commonly see people ask questions like "How can I tell which Control node I clicked?" and "How can I know when the user has clicked OUTSIDE of a button?", there isn't a simple way of doing this without workarounds.

A popular workaround is creating a Rect2 the same size and position as a Control node and seeing if the mouse event is inside it, but this doesn't respect mouse_filter so you'd have to implement code checking if the mouse is over it anyways.

In conclusion, I think being able to know which Control nodes got clicked and which ones weren't is very useful when building complex UI. Being able to get Control nodes at a given position is a good, generic way of creating this mechanic.

@Spartan322
Copy link

Spartan322 commented Dec 28, 2023

Why not at least expose Viewport::gui_find_control?

@Zireael07
Copy link

Zireael07 commented Dec 28, 2023

I think it's what was exposed in #85966 godotengine/godot#85966 ?

@AThousandShips
Copy link
Member

No it's what's being exposed in:

@Spartan322
Copy link

Spartan322 commented Dec 28, 2023

There is one case about this I can think in which you have multiple overlapping controls, this only gets somewhat solved by that to be fair, but gui_find_control would be preferred in most cases anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants