#A bit inaccurate outer click signal

59 messages · Page 1 of 1 (latest)

steel thistle
steel thistle
#

No one???

#

I'm talking about this piece:

func _input(event):
    if is_open && !_busy && (event is InputEventMouseButton) and event.pressed:
        var ev_local = make_input_local(event)
        if !Rect2(Vector2(0, 0), size).has_point(ev_local.position):
            outer_click.emit()
steel thistle
#

Anyone?

honest moss
#

Could you make a screen recording or something to demonstrate the problem?

steel thistle
steel thistle
honest moss
steel thistle
#

Oopsie, found it at same time, thaanks!

honest moss
#

I recreated your code, and it works, but I don't know what your intended behavior is. The click only registers if it's outside the panel.

extends Panel

func _input(event):
    if event is InputEventMouseButton and event.pressed:
        event = make_input_local(event)
        if !Rect2(Vector2(0, 0), size).has_point(event.position):
            print(event)
steel thistle
#

It is, if a click happens outside of a panel, the panel is closed.

#

ShareX isn't seeming to work. Anyway, to clarify, what's happening is, the panel is closing even if the click is within its borders. Only "outside" clicks must cause the panel to collapse...

#

So something is wrong with that condition !Rect2(...).has_point.

#

Sadly ShareX isn't responding :/

honest moss
#

Add print statements on ev_local.position

#

Maybe the visual size of the panel is larger than its Control size

steel thistle
#

The panel (BaseAnimatedPanel) contains all itself. Also, its border uses content margins and not expand margins.

#

Not sure if I should try logging the mouse position to see its value...

steel thistle
#

@honest moss I decided to record with OBS Studio. As you can see, the panel should close when you click outside of it (e.g., in other part of the screen); however, it also closes when you click its bottom border.
https://streamable.com/j59951

balmy sorrel
#

i've noticed this too
the bottom and right margin are considered outside of it - probably a bug

#

you can probably just add your margins to size when testing the click pos
i didn't try it myself yet

steel thistle
#

I see. I'll see if there is an issue in the GE repository

balmy sorrel
#

now i can't reproduce
seems like the cursor's visual border had tricked me

steel thistle
#

Yeah, sometimes it happens, sometimes not. Also the tendency is that it happens at the bottom of the panel.

balmy sorrel
#

make sure you have either set mouse_filter = MouseFilter.MOUSE_FILTER_STOP or call get_viewport().set_input_as_handled()

steel thistle
#

Hmm, gonna try, thanks... This outclick code I pratically copy-pasted from the Q&A site, but this second line you gave goes to the _input method?

balmy sorrel
#

anything that processes an input event, yeah

#

also in control signal handlers like gui_input

#

i'd much prefer an event.handled() kinda api

steel thistle
#

I see! So I tried that after emitting the outclick signal and it didn't have effect. I also checked what the panel's root Control's mouse_filter option was set to (and it's stop indeed)

balmy sorrel
#

with that the event shouldn't end up getting processed by elements behind the one processing it

#

but if i understand correctly, you are processing the click event in the element that is not being clicked? why is that

steel thistle
#

Actually I want to process the click for the element that is visually the most over the other panels. When I run get_viewport().set_input_as_handled() not only after emitting the outclick signal, but also everytime, it simply stops responding clicks

balmy sorrel
#

get_viewport().set_input_as_handled() is like ev.stopPropagation() in js, in case you are familiar with that

steel thistle
#

Yeah, I used it a few times, but Godot seems a bit different

balmy sorrel
#

oh i see, _input(ev) gets called on any node in the tree if it defines the method
i think your code is fine then 🤔

#

did you try logging whether it's a hit or miss?

#

e.g. func _input(event): if is_open && !_busy && (event is InputEventMouseButton) and event.pressed: var ev_local = make_input_local(event) if !Rect2(Vector2(0, 0), size).has_point(ev_local.position): print("outside") outer_click.emit() else: print("inside")

#

just to know for certain

steel thistle
#

Okk, lemme see

#

It's very strange actually. I tried opening a subpanel and it logged both miss and hit without an outside click

#

Just to clear the confusion, I'm going to update these prints

#

So, I tried opening a subpanel and, when I click anywhere in it, it logs both outside and inside without even closing the panel

#

Aah

balmy sorrel
#

do you have multiple of these in your tree?

steel thistle
#

Yeah, a child instantiated scene contains other child instantiated scenes. I just call them "panels", but they're Control scenes

balmy sorrel
#

i'm not sure if the order these _input methods get invoked in is deterministic, or something one should rely on

steel thistle
#

Hmm, by what I'm observing, I didn't lock the panels that are behind

balmy sorrel
#

the first one of them to call get_viewport().set_input_as_handled() prevents the others from getting called

steel thistle
#

So maybe they're in a conflict? Even if I call that, there'll be issues. I guess I should somehow lock what's behind...

balmy sorrel
#

yeah you could do that

#

e.g. have an is_active flag that updates as you open/close stuff

steel thistle
#

Yeah, actually I allow to freeze a panel, but I didn't remember to freeze it if it's not the innermost

balmy sorrel
#

there's also set_process_input(true/false)

steel thistle
#

This is applicable to a node? Could help I guess

balmy sorrel
#

yeah it's a Node method

#

what i don't know is if it prevents child nodes' handlers

steel thistle
#

I see, thanks! If I restart the project, I may take that into consideration