aboutsummaryrefslogtreecommitdiff
path: root/pointer_input_sensor.gd
diff options
context:
space:
mode:
authordam <dam@gudinoff>2022-01-01 04:56:58 +0000
committerdam <dam@gudinoff>2022-01-01 04:56:58 +0000
commitc59f89e99c90c0e756cdf780bcbf04d782eb3e6f (patch)
treeafeea78d9d5f68092f61d573dff2f677b1c40aa8 /pointer_input_sensor.gd
parent7f0580b6b49a9dbafc54a0190bf573503c54417a (diff)
downloadsurgery-log-c59f89e99c90c0e756cdf780bcbf04d782eb3e6f.tar.zst
surgery-log-c59f89e99c90c0e756cdf780bcbf04d782eb3e6f.zip
Change touch scroll detection to pointer-input-sensor approach using signals/events.
Diffstat (limited to 'pointer_input_sensor.gd')
-rw-r--r--pointer_input_sensor.gd84
1 files changed, 84 insertions, 0 deletions
diff --git a/pointer_input_sensor.gd b/pointer_input_sensor.gd
new file mode 100644
index 0000000..95e1b4b
--- /dev/null
+++ b/pointer_input_sensor.gd
@@ -0,0 +1,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)
+
+