One mouse event being used for two (intended) mouse actions.
Asked Answered
A

11

0

I have a simple exercise where I have a row of buttons and when I click on one it copies the texture to a simple TextureRect that follows the mouse. I want to click to place the texture but the event capture I put in place to stopping tracking the mouse uses the original click on the TextureButton.
I tried adding the self.get_tree().set_input_as_handled() but that doesn't work. Also tried .accept_event() on the button after the signal is sent.
I've also blocked further propagation of mouse events using the Mouse/Filter = Stop parameter in the original TextureButton but that also doesn't work. (I guess this is for different nodes, not other parts of the same node's script.
The only thing I got to work is too much of a hack: capture a just_released event on the button then _just_pressed event when I click to drop the TextureRect.

extends Node2D

var iscarry = false
var carryicon : TextureRect

func _ready():
	pass

func _process(delta):
	if Input.is_action_pressed("quit"):
		get_tree().quit()
	if iscarry:
		if Input.is_action_just_released("drop"):
			iscarry = false
			print("dropped")
		else:
			var pos = get_global_mouse_position()
			carryicon.set_position(pos)
	else:
		pass

func _on_batteries_button_up():
	carryicon = find_node("floater")
	carryicon.texture = $Background/IconRack/batteries.texture_normal
	carryicon.visible = true
	print("down")
	self.get_tree().set_input_as_handled()
	iscarry = true
Aileenailene answered 27/2 at 3:53 Comment(0)
F
0

Aileenailene _input() handler will always be called, regardless of who else got or consumed the event. If you want to filter out events consumed by gui nodes - use _unhandled_input() instead.

Fokker answered 27/2 at 12:48 Comment(0)
A
0

Fokker
Can you show me how to edit this code; I don't understand where I am using _Input so don't know how or where to implement _unhandled_input instead. In the docs, most of the Input handling seems to be about passing/blocking those events to other nodes, not inside the same node.
thanks

Aileenailene answered 27/2 at 21:2 Comment(0)
F
0

Aileenailene Define the event handler callback instead of polling Input every frame in _process().
It's covered well in the docs

Here's a quick example. The _unhandled_input() can be in any other node's script

extends Button

func _on_pressed():  # connect button's pressed signal to this function
	print ("BUTTON PRESSED")
	
func _unhandled_input(e):
	if e is InputEventMouseButton and e.is_pressed() and e.button_index == MOUSE_BUTTON_LEFT:
		print("PRESSED OUTSIDE OF BUTTON")
Fokker answered 27/2 at 21:5 Comment(0)
A
0

Fokker
ok, that looks like a good place to start, thanks!

Aileenailene answered 27/2 at 22:30 Comment(0)
A
0

Fokker
actually, you mentioned other nodes. My example is trying to receive the same kind of input (InputEventMouseClick) in the same script in two different places. Does this affect your suggestion?

Aileenailene answered 28/2 at 22:52 Comment(0)
F
0

Aileenailene in the same script in two different places

Not sure I understand what that means. My example does exactly what you initially asked for and it's in a single script.

Fokker answered 28/2 at 23:15 Comment(0)
A
0

Fokker
Thanks for your patience!
when does _unhandled_input get called? I dropped it in as shown but without a signal or another programmed call it seems like it won't do anything. Never mind, I see this called on it's own.
Your example has the line print("PRESSED OUTSIDE OF BUTTON") but there is no circumstance where I have a problem clicking outside the button.
It might help to see my structure, perhaps it's just not a good way to do this:
--My script runs in Main (as Inventory.gd).
--You can ignore 'Background'.
--'IconRack' is just a way to hold all the inventory icons and scroll them up and down in the viewport.

I don't have any script attached to my buttons so your example has no place to go. They just send a signal to Main when clicked.
I wish I could just code "receive signal-->flush the event-->enable mouse-tracking in _process-->stop tracking when another click is performed'
Here's a screen shot of my node tree and the entire project if needed. Remember this is 3.5.3.

inventorydesign.zip
2MB
Aileenailene answered 29/2 at 1:25 Comment(0)
F
0

Aileenailene Your example has the line print("PRESSED OUTSIDE OF BUTTON") but there is no circumstance where I would replace this print statement with some action

Wasn't your original intent, as deduced from your first post this:

  • click the button to enter the drag state
  • click again anywhere to end the drag state

But you couldn't do it because your button click triggered your end drag state code.

My code does precisely that. When the button is clicked the signal handler is called. The event is here consumed so _unhandled_input() won't be called. Conversely, when the click is not on the button, the _unhandled_input() is called instead. The end result is that button click executes one piece of code and off-button click executes another.

It doesn't matter where those pieces of script are situated. The only important thing is that one is the button's signal callback and the other is _unhandled_input() callback.

Fokker answered 29/2 at 2:9 Comment(0)
A
0

Fokker
I just implemented a working solution without the unhandled input but now see what you are doing and I will try to do it properly. ( I used click down to set arm the state so that unclicking would trigger the icon-dragging activity.

Aileenailene answered 29/2 at 2:52 Comment(0)
F
0

Aileenailene Certainly doable without _unandled_input() by introducing some state flags. It's less elegant though. Event handlers are in most cases a better solution than input polling. Better to let the engine notify you than asking each frame if something happened.

You should really spend some time reading that section on input events in the docs. It'll give you good understanding of how events are handled and prioritized in the engine.

Fokker answered 29/2 at 11:2 Comment(0)
A
0

Fokker
I agree and think I know how to do it now using the _unhandled_input method. thanks!

Aileenailene answered 1/3 at 3:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.