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
|
extends Control
class_name PointerInputSensor
export var drag_threshold_cm: float = 0.250
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
class PointerInputData:
var target: PointerInputSensor
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 pointer: PointerInputData
var screen_dpcm: float
var on_process: FuncRef
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 _process(delta: float):
if on_process != null && on_process.is_valid():
on_process.call_func(delta, self)
func _on_enter_exit(is_inside: bool):
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
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()
emit_signal("on_press", pointer)
else:
emit_signal("on_release", pointer)
if pointer.was_dragged == false:
emit_signal("on_click", pointer)
else:
emit_signal("on_end_drag", pointer)
pointer.index = -1
pointer.was_dragged = false
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
# @DAM Instead of constantly converting the pointer distance to cm... just conver the drag_threshold_cm to pixels
if pointer.was_dragged == false && pointer.current_position.distance_to(pointer.initial_position) / screen_dpcm > drag_threshold_cm:
pointer.was_dragged = true
emit_signal("on_begin_drag", pointer)
emit_signal("on_drag", pointer)
|