|
|
|
|
Reply From: |
avencherus |
If you want to use the provided Buttons they have and Action Mode property you can set to “Button Press”. You can also connect to the signal button_down()
to execute logic right as it goes down.
If you’re looking for something a bit more custom, it’ll probably be most straight forward to write your own UI widgets that track and handle input logic to get a specific behavior.
Hi avencherus,
yes, the buttons are indeed easy to implement and basically do what they are supposed to. I can press them and hold them, have them trigger at release and all that. The only thing they just don’t seem to support is a proper “your pressed mouse cursor just crossed the border to the outside of the button”-signal. (At least I can’t figure out how to implement this.)
As I say, it works with a collision shape, but not with a button.What I’m aiming at is a button which I can hold down and then (instead of releasing) slide off of, to “abort the operation”. The button goes back to normal without triggering and my mouse-release outside the button doesn’t do anything as well. As “if I change my mind”, I want to “slide-off-cancel”.
Actually, “mouse_exited” does work with buttons, but only with mouse-over, not when being pressed down! Weirdly enough, “mouse_entered” does work while being pressed down…
I did build my very own buttons with Area2Ds and CollisionShape2Ds and they do all I want in the way I want them to. There only occasionally pop up some issues here and there in combination with other things (like overlapping control nodes), where “normal” buttons don’t bother, so I thought building my own stuff on top of on-board-buttons would be perfect. Alas!
pferft | 2020-11-24 19:18
In my experience the built-in Controls work well for only the most straight forward usages, and even then you’ll find awkward holes in their functionality.
A lot of what you’re wanting does exist in the CPP implementation, but isn’t exposed.
It often ends up being best to go the route of writing your own. If you use Area2Ds and need to have legitimate overlapping of controls, you’ll want to keep and list and implement a priority (height) check of your own. This isn’t implemented in the engine currently.
To go down the path of repurposing the built-in Controls… it tends to venture into hacking territory. I have an example below, that responds to holding a click while hovering over a Button.
It only gets your part the way there. You’d have to ignore the pressed signal and implement your own pressed signal based around internal flags and such.
This code exploits calling into the virtual function to call into some of the desired internal functions. There are side effects, so a lot of the other functionality will likely misbehave or stop working. You’d have to work around that too.
That said, it may be more work, but writing your own widgets over something like the code below is probably the better bet.
extends Button
func _ready() -> void:
connect("mouse_entered", self, "check_press")
connect("mouse_exited", self, "clear_press")
func clear_press() -> void:
if(pressed):
set_faux_press(false)
func check_press() -> void:
if(Input.is_mouse_button_pressed(BUTTON_LEFT)):
set_faux_press(true)
func _physics_process(delta: float) -> void:
if(pressed and not Input.is_mouse_button_pressed(BUTTON_LEFT)):
set_faux_press(false)
func set_faux_press(p_state : bool) -> void:
var e = InputEventMouseButton.new()
e.button_index = BUTTON_LEFT
e.pressed = p_state
_gui_input(e)
func _gui_input(e) -> void:
._gui_input(e) # Hacky, be careful here.
avencherus | 2020-11-25 10:52