1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
extends Control
class_name PointerInputSensor
# All on_ACTION signals have a single argument of type PointerInputData.
signal on_press
signal on_release
#signal on_release_outside
signal on_click
signal on_enter
signal on_exit
#signal on_exit_app_window
signal on_begin_drag
signal on_drag
signal on_end_drag
signal on_scroll
enum PointerInputAction {
UNDEFINED,
ON_PRESS,
ON_RELEASE,
# ON_RELEASE_OUTSIDE,
ON_CLICK,
ON_ENTER,
ON_EXIT,
# ON_EXIT_APP_WINDOW,
ON_BEGIN_DRAG,
ON_DRAG,
ON_END_DRAG,
ON_SCROLL,
}
class PointerInputData:
var target: PointerInputSensor
var event: InputEvent
var index := -1
var initial_position := Vector2.ZERO
var current_position := Vector2.ZERO
var relative_position := Vector2.ZERO
var velocity := Vector2.ZERO
var was_dragged := false
var is_pressed := false
var scroll := 0.0
var action: int = PointerInputAction.UNDEFINED
export var drag_threshold_cm: float = 0.250
var pointer: PointerInputData
var screen_dpcm: float
func _ready():
screen_dpcm = float(OS.get_screen_dpi()) / 2.54
pointer = PointerInputData.new()
pointer.target = self
connect("mouse_entered", self, "_on_enter_exit", [true])
connect("mouse_entered", self, "_on_enter_exit", [false])
func _on_enter_exit(is_inside: bool):
pointer.action = PointerInputAction.ON_ENTER if is_inside else PointerInputAction.ON_EXIT
emit_signal("on_enter" if is_inside else "on_exit", pointer)
func _gui_input(event: InputEvent):
# @DAM A bug on GODOT-3.X makes events from non-mouse-emulated pointers (index > 0) unreliable.
if event is InputEventScreenTouch || event is InputEventScreenDrag:
if event.index != 0:
return
pointer.event = event
# pointer.index = -1
# pointer.scroll = 0.0
# pointer.action = PointerInputAction.UNDEFINED
# pointer.velocity = Vector2.ZERO
if event is InputEventScreenTouch && (pointer.is_pressed == false || pointer.index == event.index):
var touch := event as InputEventScreenTouch
pointer.is_pressed = event.pressed
pointer.current_position = get_global_mouse_position()
if pointer.is_pressed:
pointer.index = touch.index
pointer.initial_position = get_global_mouse_position()
pointer.action = PointerInputAction.ON_PRESS
emit_signal("on_press", pointer)
else:
pointer.action = PointerInputAction.ON_RELEASE
emit_signal("on_release", pointer)
if pointer.was_dragged == false:
pointer.action = PointerInputAction.ON_CLICK
emit_signal("on_click", pointer)
else:
pointer.action = PointerInputAction.ON_END_DRAG
emit_signal("on_end_drag", pointer)
pointer.index = -1
pointer.was_dragged = false
# @DAM Maybe add this.
# pointer.initial_position = Vector2.ZERO
# pointer.current_position = Vector2.ZERO
# pointer.relative_position = Vector2.ZERO
if event is InputEventScreenDrag && event.index == pointer.index:
var drag := event as InputEventScreenDrag
pointer.current_position = get_global_mouse_position()
pointer.velocity = drag.speed
pointer.relative_position = drag.relative
if pointer.was_dragged == false && pointer.current_position.distance_to(pointer.initial_position) > drag_threshold_cm * screen_dpcm:
pointer.was_dragged = true
pointer.action = PointerInputAction.ON_BEGIN_DRAG
emit_signal("on_begin_drag", pointer)
pointer.action = PointerInputAction.ON_DRAG
emit_signal("on_drag", pointer)
# @DAM Clean this code please.
if event is InputEventMouseButton && event.is_pressed():
if event.button_index == BUTTON_WHEEL_UP || event.button_index == BUTTON_WHEEL_DOWN:
pointer.scroll = -1.0 if event.button_index == BUTTON_WHEEL_UP else 1.0
pointer.action = PointerInputAction.ON_SCROLL
emit_signal("on_scroll", pointer)
|