extends SceneTree # Headless gameplay test: run with # godot --headless -s res://tests/test_icon_button_drag_cancel.gd # Verifies IconButton only counts as pressed if the finger/cursor is still # over the button when it lifts - dragging off the button before # releasing (a standard way to "cancel" a touch/click) must NOT still # trigger it, and releasing back inside the button's bounds must. var main_scene: Node var map_button: IconButton var press_count: int = 0 func _initialize() -> void: var packed: PackedScene = load("res://Main.tscn") main_scene = packed.instantiate() root.add_child(main_scene) map_button = main_scene.get_node("UI/MapButton") map_button.pressed.connect(_on_pressed) func _process(_delta: float) -> bool: var inside: Vector2 = map_button.size / 2.0 var far_outside: Vector2 = map_button.size * 10.0 # Press inside, release far outside the button's rect - must NOT fire. _touch(true, inside) _touch(false, far_outside) var cancel_ok: bool = press_count == 0 print("after_drag_off press_count=%d cancel_ok=%s" % [press_count, cancel_ok]) # Press and release both inside - must fire normally. _touch(true, inside) _touch(false, inside) var normal_press_ok: bool = press_count == 1 print("after_normal_press press_count=%d normal_press_ok=%s" % [press_count, normal_press_ok]) if cancel_ok and normal_press_ok: print("TEST_ICON_BUTTON_DRAG_CANCEL: PASS") quit(0) else: print("TEST_ICON_BUTTON_DRAG_CANCEL: FAIL") quit(1) return true func _touch(is_pressed: bool, at_position: Vector2) -> void: var ev: InputEventScreenTouch = InputEventScreenTouch.new() ev.pressed = is_pressed ev.position = at_position map_button._gui_input(ev) func _on_pressed() -> void: press_count += 1