aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--logic/database.gd60
-rw-r--r--logic/stage.gd104
-rw-r--r--main.tscn7
-rw-r--r--pointer_input_sensor.gd84
-rw-r--r--project.godot12
-rw-r--r--touch_scroll.gd125
6 files changed, 224 insertions, 168 deletions
diff --git a/logic/database.gd b/logic/database.gd
index 4f3e613..41ba679 100644
--- a/logic/database.gd
+++ b/logic/database.gd
@@ -31,7 +31,8 @@ onready var stage: Stage = get_node("/root/main/stage")
onready var delete_button: Button = get_node("actions/delete")
onready var edit_button: Button = get_node("actions/edit")
onready var add_button: Button = get_node("actions/add")
-onready var v_scroll_bar: ScrollBar = get_v_scroll()
+onready var v_scroll_bar: ScrollBar = get_v_scroll() # @DAM Stop scroll inertia when buttons are pressed.
+onready var drag_sensor: PointerInputSensor = get_node("drag_sensor")
func _init():
@@ -44,15 +45,72 @@ func _init():
func _ready():
self.connect("item_selected", self, "item_selected")
self.connect("nothing_selected", self, "clear_selection")
+
delete_button.connect("pressed", self, "delete_action")
edit_button.connect("pressed", self, "edit_action")
add_button.connect("pressed", self, "add_action")
+
stage.connect("save", self, "save")
stage.connect("discard", self, "discard")
+
+ drag_sensor.connect("on_press", self, "on_press")
+ drag_sensor.connect("on_drag", self, "on_drag")
+ drag_sensor.connect("on_end_drag", self, "on_end_drag")
+ drag_sensor.connect("on_click", self, "on_click")
+
for it in db:
self.add_item(get_entry_view(it))
+# @DAM Cleanup this code.
+export var scroll_velocity_decaying_factor: float = 2.5
+var drag_velocity := 0.0
+var is_dragging := false
+
+func _process(delta: float):
+ if is_dragging == false && abs(drag_velocity) > 0.5:
+ drag_velocity *= clamp((1.0 - scroll_velocity_decaying_factor * delta), 0.0, 1.0)
+ v_scroll_bar.value -= drag_velocity * delta
+
+func on_click(pointer: PointerInputSensor.PointerInputData):
+ var target := self
+ var position := target.get_global_mouse_position() - target.rect_global_position
+
+ var event_touch := InputEventScreenTouch.new()
+ event_touch.index = 0
+ event_touch.position = position
+
+ var event_mouse := InputEventMouseButton.new()
+ event_mouse.button_index = BUTTON_LEFT
+ event_mouse.button_mask = BUTTON_MASK_LEFT
+ event_mouse.position = position
+
+ event_mouse.pressed = true
+ event_touch.pressed = true
+ target._gui_input(event_mouse)
+ target._gui_input(event_touch)
+
+ target.grab_focus()
+
+ event_mouse.pressed = false
+ event_touch.pressed = false
+ target._gui_input(event_mouse)
+ target._gui_input(event_touch)
+
+func on_press(pointer: PointerInputSensor.PointerInputData):
+ is_dragging = true
+
+func on_end_drag(pointer: PointerInputSensor.PointerInputData):
+ is_dragging = false
+
+func on_drag(pointer: PointerInputSensor.PointerInputData):
+ is_dragging = true
+ drag_velocity = pointer.velocity.y
+ v_scroll_bar.value -= pointer.relative_position.y
+
+
+
+
func _notification(what: int):
if visible == false:
return
diff --git a/logic/stage.gd b/logic/stage.gd
index f7cced4..62e0a58 100644
--- a/logic/stage.gd
+++ b/logic/stage.gd
@@ -37,7 +37,6 @@ onready var save_button: Button = get_node("controls/save")
onready var discard_button: Button = get_node("controls/discard")
-
func _ready():
save_button.connect("pressed", self, "save_action")
discard_button.connect("pressed", self, "discard_action")
@@ -48,19 +47,82 @@ func _ready():
match it.name:
"date_picker", "save", "discard":
print("- %s" % it.name)
-
+
_:
# "first_assistant":
print("+ %s" % it.name)
- var touch_scroll = TouchScroll.new()
- touch_scroll.name = "touch_scroll"
- touch_scroll.click_target_path = "../"
- touch_scroll.scroll_target_path = "../../../"
- touch_scroll.scroll_bar_get_method = "get_v_scrollbar"
- touch_scroll.mouse_default_cursor_shape = Control.CURSOR_IBEAM
- (it as Control).add_child(touch_scroll)
- touch_scroll.anchor_right = 1.0
- touch_scroll.anchor_bottom = 1.0
+ var drag_sensor = PointerInputSensor.new()
+ drag_sensor.name = "drag_sensor"
+ drag_sensor.mouse_default_cursor_shape = Control.CURSOR_IBEAM
+ (it as Control).add_child(drag_sensor)
+ drag_sensor.anchor_right = 1.0
+ drag_sensor.anchor_bottom = 1.0
+
+ drag_sensor.connect("on_press", self, "on_press")
+ drag_sensor.connect("on_drag", self, "on_drag")
+ drag_sensor.connect("on_end_drag", self, "on_end_drag")
+ drag_sensor.connect("on_click", self, "on_click")
+ drag_sensor.on_process = funcref(self, "bazinga")
+
+
+# @DAM Cleanup this code.
+onready var v_scroll_bar: VScrollBar = get_v_scrollbar()
+export var scroll_velocity_decaying_factor: float = 2.5
+var drag_velocity := 0.0
+var is_dragging := false
+
+func bazinga(delta: float, pointer: PointerInputSensor):
+ if (pointer.get_parent() as Control).has_focus():
+ pointer.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ else:
+ pointer.mouse_filter = Control.MOUSE_FILTER_STOP
+
+func _process(delta: float):
+ if is_dragging == false && abs(drag_velocity) > 0.5:
+ drag_velocity *= clamp((1.0 - scroll_velocity_decaying_factor * delta), 0.0, 1.0)
+ v_scroll_bar.value -= drag_velocity * delta
+
+func on_click(pointer: PointerInputSensor.PointerInputData):
+ var target: Control = pointer.target.get_parent()
+ var position := target.get_global_mouse_position() - target.rect_global_position
+
+ var event_touch := InputEventScreenTouch.new()
+ event_touch.index = 0
+ event_touch.position = position
+
+ var event_mouse := InputEventMouseButton.new()
+ event_mouse.button_index = BUTTON_LEFT
+ event_mouse.button_mask = BUTTON_MASK_LEFT
+ event_mouse.position = position
+
+ event_mouse.pressed = true
+ event_touch.pressed = true
+ target._gui_input(event_mouse)
+ target._gui_input(event_touch)
+
+ target.grab_focus()
+
+ event_mouse.pressed = false
+ event_touch.pressed = false
+ target._gui_input(event_mouse)
+ target._gui_input(event_touch)
+
+func on_press(pointer: PointerInputSensor.PointerInputData):
+ is_dragging = true
+
+func on_end_drag(pointer: PointerInputSensor.PointerInputData):
+ is_dragging = false
+
+func on_drag(pointer: PointerInputSensor.PointerInputData):
+ is_dragging = true
+ drag_velocity = pointer.velocity.y
+ v_scroll_bar.value -= pointer.relative_position.y
+
+
+
+
+
+
func save_action():
@@ -91,18 +153,6 @@ func set_stage(entry: Dictionary):
func get_stage() -> Dictionary:
-
-# var entry: Dictionary = Database.instance_entry({
-# "process_id": process_id.text,
-# "surgery_id": surgery_id.text,
-# "date_year": date.get_year(),
-# "date_month": date.get_month(),
-# "date_day": date.get_day(),
-# "place": place.text,
-# "anesthetic": anesthetic.text,
-# "first_assistant": first_assistant.text,
-# "type": type.text,
-# })
# @DAM Simplify all this... avoid creating multiple entries/dictionaries.
var entry: Dictionary = {
"process_id": process_id.text,
@@ -124,14 +174,6 @@ func get_stage() -> Dictionary:
return entry
-# @DAM Testing. Needs all children controllers to have Mouse > Filter : Pass.
-#func _gui_input(event):
-# accept_event()
-# if event is InputEventScreenDrag:
-# self.scroll_vertical -= event.relative.y
-# return
-
-
func _notification(what: int):
if what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST:
discard_action()
diff --git a/main.tscn b/main.tscn
index 9cb9220..331d94d 100644
--- a/main.tscn
+++ b/main.tscn
@@ -9,7 +9,7 @@
[ext_resource path="res://icons/add.png" type="Texture" id=7]
[ext_resource path="res://icons/delete.png" type="Texture" id=8]
[ext_resource path="res://logic/stage.gd" type="Script" id=9]
-[ext_resource path="res://touch_scroll.gd" type="Script" id=10]
+[ext_resource path="res://pointer_input_sensor.gd" type="Script" id=10]
[node name="main" type="Control"]
anchor_right = 1.0
@@ -29,7 +29,7 @@ __meta__ = {
"_edit_use_anchors_": false
}
-[node name="touch_scroll" type="Control" parent="database"]
+[node name="drag_sensor" type="Control" parent="database"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_right = -8.0
@@ -37,9 +37,6 @@ script = ExtResource( 10 )
__meta__ = {
"_edit_use_anchors_": false
}
-click_target_path = "../"
-scroll_target_path = "../"
-scroll_bar_get_method = "get_v_scroll"
[node name="actions" type="VBoxContainer" parent="database"]
anchor_left = 1.0
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)
+
+
diff --git a/project.godot b/project.godot
index 703d936..f5dbe7a 100644
--- a/project.godot
+++ b/project.godot
@@ -19,17 +19,17 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://date_picker/date_picker.gd"
}, {
+"base": "Control",
+"class": "PointerInputSensor",
+"language": "GDScript",
+"path": "res://pointer_input_sensor.gd"
+}, {
"base": "ScrollContainer",
"class": "Stage",
"language": "GDScript",
"path": "res://logic/stage.gd"
}, {
"base": "Control",
-"class": "TouchScroll",
-"language": "GDScript",
-"path": "res://touch_scroll.gd"
-}, {
-"base": "Control",
"class": "ValuePicker",
"language": "GDScript",
"path": "res://date_picker/value_picker.gd"
@@ -37,8 +37,8 @@ _global_script_classes=[ {
_global_script_class_icons={
"Database": "",
"DatePicker": "",
+"PointerInputSensor": "",
"Stage": "",
-"TouchScroll": "",
"ValuePicker": ""
}
diff --git a/touch_scroll.gd b/touch_scroll.gd
deleted file mode 100644
index 7b6aefd..0000000
--- a/touch_scroll.gd
+++ /dev/null
@@ -1,125 +0,0 @@
-extends Control
-class_name TouchScroll
-
-const DRAG_THRESHOLD_CM: float = 0.250
-
-export var click_target_path: String
-export var scroll_target_path: String
-export var scroll_bar_get_method: String
-export var scroll_velocity_decaying_factor: float = 2.5
-
-var pointer: Dictionary
-var anchor: float
-var offset: float
-var screen_dpcm: float
-
-var click_target: Control
-var scroll_target: Control
-var target_scroll_bar: VScrollBar
-
-
-
-# @DAM
-# Change this into an event-driven approach by changing the touch_scroll into a signal emitter and
-# the target scrollable control a signal consumer. This way, the signal consumer will behave as the
-# central node and will have the capability to detect when different touch_scroll sensors are
-# activated and stop previous inputs (if required).
-# Signal emitters should signal:
-# - when an input drag starts
-# - when an input drag stops
-# - when an input drags
-# - when an input clicks
-
-
-func _ready():
- click_target = get_node(click_target_path)
- scroll_target = get_node(scroll_target_path)
- target_scroll_bar = scroll_target.call(scroll_bar_get_method)
- pointer = {
- index = -1,
- initial_position = Vector2.ZERO,
- current_position = Vector2.ZERO,
- relative_position = Vector2.ZERO,
- velocity = Vector2.ZERO,
- was_dragged = false,
- is_active = false,
- }
- screen_dpcm = float(OS.get_screen_dpi()) / 2.54
-
-
-func _process(delta: float):
- # @DAM This only works for the stage... for the database this hides the touch_scroll after the first click.
- if click_target.has_focus():
- mouse_filter = Control.MOUSE_FILTER_IGNORE
- else:
- mouse_filter = Control.MOUSE_FILTER_STOP
-
- if pointer.is_active:
- var dragged_distance: float = - (pointer.current_position.y - pointer.initial_position.y)
- offset = anchor + dragged_distance
-# self.target_scroll_bar.value = offset
- self.target_scroll_bar.value -= pointer.relative_position.y
- pointer.relative_position = Vector2.ZERO
- elif pointer.velocity.length() > 0.5:
- pointer.velocity *= clamp((1.0 - scroll_velocity_decaying_factor * delta), 0.0, 1.0)
- offset -= pointer.velocity.y * delta
-# self.target_scroll_bar.value = offset
- self.target_scroll_bar.value -= pointer.velocity.y * delta
-
-
-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_active == false || pointer.index == event.index):
- var touch := event as InputEventScreenTouch
- pointer.is_active = event.pressed
- pointer.current_position = get_global_mouse_position() # touch.position
- if pointer.is_active:
- pointer.index = touch.index
- pointer.initial_position = get_global_mouse_position() # touch.position
- anchor = self.target_scroll_bar.value
- else:
- if pointer.was_dragged == false: # Click detected.
- simulate_gui_click()
- 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() # drag.position
- pointer.velocity = drag.speed
- pointer.relative_position = drag.relative
- if pointer.current_position.distance_to(pointer.initial_position) / screen_dpcm > DRAG_THRESHOLD_CM:
- pointer.was_dragged = true
-
-
-func simulate_gui_click():
-
- var position := self.get_global_mouse_position() - click_target.rect_global_position
-
- var event_touch := InputEventScreenTouch.new()
- event_touch.index = 0
- event_touch.position = position
-
- var event_mouse := InputEventMouseButton.new()
- event_mouse.button_index = BUTTON_LEFT
- event_mouse.button_mask = BUTTON_MASK_LEFT
- event_mouse.position = position
-
- event_mouse.pressed = true
- event_touch.pressed = true
- click_target._gui_input(event_mouse)
- click_target._gui_input(event_touch)
-
- click_target.grab_focus()
-
- event_mouse.pressed = false
- event_touch.pressed = false
- click_target._gui_input(event_mouse)
- click_target._gui_input(event_touch)
-
-