From 7f0580b6b49a9dbafc54a0190bf573503c54417a Mon Sep 17 00:00:00 2001 From: dam Date: Fri, 31 Dec 2021 15:41:10 +0000 Subject: Prototype implementation of touch scroll on database and stage screens. --- date_picker/date_picker.tscn | 1 - logic/database.gd | 7 +++-- logic/stage.gd | 47 ++++++++++++++++++++++++++++---- main.tscn | 25 ++++++++--------- project.godot | 6 ++++ touch_scroll.gd | 65 ++++++++++++++++++++++++++++++++++---------- 6 files changed, 114 insertions(+), 37 deletions(-) diff --git a/date_picker/date_picker.tscn b/date_picker/date_picker.tscn index 21573dc..54b2b82 100644 --- a/date_picker/date_picker.tscn +++ b/date_picker/date_picker.tscn @@ -6,7 +6,6 @@ [node name="date_picker" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 -mouse_filter = 2 script = ExtResource( 2 ) __meta__ = { "_edit_use_anchors_": false diff --git a/logic/database.gd b/logic/database.gd index ea02324..4f3e613 100644 --- a/logic/database.gd +++ b/logic/database.gd @@ -27,11 +27,11 @@ var db: Array var selected_idx: int var staged_idx: int +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 stage: Stage = get_node("/root/main/stage") +onready var v_scroll_bar: ScrollBar = get_v_scroll() func _init(): @@ -111,7 +111,7 @@ func add_action(): func scroll_down(): - get_v_scroll().value = get_v_scroll().max_value + v_scroll_bar.value = v_scroll_bar.max_value func save(database_entry: Dictionary): @@ -129,6 +129,7 @@ func save(database_entry: Dictionary): store_database() select(next_selected_idx) item_selected(next_selected_idx) # Calling "select" does not trigger the "item_selected" signal. + v_scroll_bar.value = float(next_selected_idx)/float(db.size()) * v_scroll_bar.max_value - (v_scroll_bar.page * 0.5) staged_idx = -1 self.visible = true diff --git a/logic/stage.gd b/logic/stage.gd index ac5e9aa..f7cced4 100644 --- a/logic/stage.gd +++ b/logic/stage.gd @@ -4,6 +4,22 @@ class_name Stage signal save # (database_entry: Dictionary) signal discard # () +#onready var process_id: LineEdit = get_node("touch_scroll/controls/process_id") +#onready var surgery_id: LineEdit = get_node("touch_scroll/controls/surgery_id") +#onready var date: DatePicker = get_node("touch_scroll/controls/date_picker") +#onready var place: LineEdit = get_node("touch_scroll/controls/place") +#onready var anesthetic: LineEdit = get_node("touch_scroll/controls/anesthetic") +#onready var first_assistant: LineEdit = get_node("touch_scroll/controls/first_assistant") +#onready var type: LineEdit = get_node("touch_scroll/controls/type") +#onready var sub_type: LineEdit = get_node("touch_scroll/controls/sub_type") +#onready var sub_sub_type: LineEdit = get_node("touch_scroll/controls/sub_sub_type") +#onready var pathology: LineEdit = get_node("touch_scroll/controls/pathology") +#onready var intervention: LineEdit = get_node("touch_scroll/controls/intervention") +#onready var is_urgency: Button = get_node("touch_scroll/controls/is_urgency") +#onready var notes: LineEdit = get_node("touch_scroll/controls/notes") +#onready var save_button: Button = get_node("touch_scroll/controls/save") +#onready var discard_button: Button = get_node("touch_scroll/controls/discard") + onready var process_id: LineEdit = get_node("controls/process_id") onready var surgery_id: LineEdit = get_node("controls/surgery_id") onready var date: DatePicker = get_node("controls/date_picker") @@ -21,9 +37,30 @@ 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") + + + for it in get_node("controls").get_children(): +# print("%s" % it.name) + 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 func save_action(): @@ -88,11 +125,11 @@ func get_stage() -> Dictionary: # @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 _gui_input(event): +# accept_event() +# if event is InputEventScreenDrag: +# self.scroll_vertical -= event.relative.y +# return func _notification(what: int): diff --git a/main.tscn b/main.tscn index b584c88..9cb9220 100644 --- a/main.tscn +++ b/main.tscn @@ -37,6 +37,9 @@ 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 @@ -100,9 +103,6 @@ margin_right = 1080.0 margin_bottom = 1860.0 size_flags_horizontal = 3 size_flags_vertical = 3 -__meta__ = { -"_edit_use_anchors_": false -} [node name="process_id" type="LineEdit" parent="stage/controls"] margin_right = 1080.0 @@ -126,7 +126,6 @@ margin_top = 112.0 margin_right = 1080.0 margin_bottom = 312.0 rect_min_size = Vector2( 400, 200 ) -mouse_filter = 0 [node name="place" type="LineEdit" parent="stage/controls"] margin_top = 316.0 @@ -206,33 +205,33 @@ placeholder_text = "Notas" caret_blink = true caret_blink_speed = 0.5 -[node name="save" type="Button" parent="stage/controls"] -margin_top = 874.0 +[node name="discard" type="Button" parent="stage/controls"] +margin_top = 928.0 margin_right = 1080.0 -margin_bottom = 924.0 +margin_bottom = 978.0 grow_horizontal = 2 grow_vertical = 2 rect_min_size = Vector2( 0, 50 ) -text = "save" +text = "discard" __meta__ = { "_edit_use_anchors_": false } -[node name="discard" type="Button" parent="stage/controls"] -margin_top = 928.0 +[node name="save" type="Button" parent="stage/controls"] +margin_top = 874.0 margin_right = 1080.0 -margin_bottom = 978.0 +margin_bottom = 924.0 grow_horizontal = 2 grow_vertical = 2 rect_min_size = Vector2( 0, 50 ) -text = "discard" +text = "save" __meta__ = { "_edit_use_anchors_": false } [node name="menu" type="MenuButton" parent="."] anchor_right = 1.0 -margin_bottom = 48.0 +margin_bottom = 60.0 text = "≡" align = 2 script = ExtResource( 4 ) diff --git a/project.godot b/project.godot index 3df8f21..703d936 100644 --- a/project.godot +++ b/project.godot @@ -25,6 +25,11 @@ _global_script_classes=[ { "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" @@ -33,6 +38,7 @@ _global_script_class_icons={ "Database": "", "DatePicker": "", "Stage": "", +"TouchScroll": "", "ValuePicker": "" } diff --git a/touch_scroll.gd b/touch_scroll.gd index f2aeca7..7b6aefd 100644 --- a/touch_scroll.gd +++ b/touch_scroll.gd @@ -1,22 +1,45 @@ extends Control +class_name TouchScroll -const VELOCITY_DECAYING_FACTOR: float = 5.5 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 -onready var target: Control = get_parent() -onready var target_scroll: VScrollBar = get_parent().get_v_scroll() +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, @@ -25,14 +48,23 @@ func _ready(): 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.value = offset +# 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 - VELOCITY_DECAYING_FACTOR * delta), 0.0, 1.0) + pointer.velocity *= clamp((1.0 - scroll_velocity_decaying_factor * delta), 0.0, 1.0) offset -= pointer.velocity.y * delta - self.target_scroll.value = offset +# self.target_scroll_bar.value = offset + self.target_scroll_bar.value -= pointer.velocity.y * delta func _gui_input(event: InputEvent): @@ -45,11 +77,11 @@ func _gui_input(event: InputEvent): 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 = touch.position + pointer.current_position = get_global_mouse_position() # touch.position if pointer.is_active: pointer.index = touch.index - pointer.initial_position = touch.position - anchor = self.target_scroll.value + 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() @@ -58,15 +90,16 @@ func _gui_input(event: InputEvent): if event is InputEventScreenDrag && event.index == pointer.index: var drag := event as InputEventScreenDrag - pointer.current_position = drag.position + 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() - target.rect_global_position + var position := self.get_global_mouse_position() - click_target.rect_global_position var event_touch := InputEventScreenTouch.new() event_touch.index = 0 @@ -79,12 +112,14 @@ func simulate_gui_click(): event_mouse.pressed = true event_touch.pressed = true - target._gui_input(event_mouse) - target._gui_input(event_touch) + click_target._gui_input(event_mouse) + click_target._gui_input(event_touch) + click_target.grab_focus() + event_mouse.pressed = false event_touch.pressed = false - target._gui_input(event_mouse) - target._gui_input(event_touch) + click_target._gui_input(event_mouse) + click_target._gui_input(event_touch) -- cgit v1.2.3