diff options
| -rw-r--r-- | logic/database.gd | 144 | ||||
| -rw-r--r-- | logic/stage.gd | 150 | ||||
| -rw-r--r-- | main.tscn | 61 | ||||
| -rw-r--r-- | pointer_input_sensor.gd | 38 | ||||
| -rw-r--r-- | readme.md | 18 |
5 files changed, 192 insertions, 219 deletions
diff --git a/logic/database.gd b/logic/database.gd index 41ba679..c492321 100644 --- a/logic/database.gd +++ b/logic/database.gd @@ -22,16 +22,19 @@ const ENTRY_PROTOTYPE: Dictionary = { "is_urgency": false, "notes": "", } +const POINTER_VELOCITY_DECAYING_FACTOR: float = 2.5 var db: Array var selected_idx: int var staged_idx: int +var is_pointer_dragging := false +var pointer_drag_velocity := 0.0 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() # @DAM Stop scroll inertia when buttons are pressed. +onready var v_scroll_bar: ScrollBar = get_v_scroll() onready var drag_sensor: PointerInputSensor = get_node("drag_sensor") @@ -53,66 +56,25 @@ func _ready(): 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") + drag_sensor.connect("on_press", self, "pointer_input_handler") + drag_sensor.connect("on_drag", self, "pointer_input_handler") + drag_sensor.connect("on_end_drag", self, "pointer_input_handler") + drag_sensor.connect("on_click", self, "pointer_input_handler") 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 - - + # Apply drag movement inertia. + if is_pointer_dragging == false && abs(pointer_drag_velocity) > 0.5: + pointer_drag_velocity *= clamp((1.0 - POINTER_VELOCITY_DECAYING_FACTOR * delta), 0.0, 1.0) + v_scroll_bar.value -= pointer_drag_velocity * delta func _notification(what: int): - if visible == false: + # @DAM Yet to be polished. + if visible == false || has_focus() == false: return if what == MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST: @@ -127,11 +89,7 @@ func get_entry_view(database_entry: Dictionary) -> String: func item_selected(index: int): - if selected_idx >= 0: - set_item_text(selected_idx, get_entry_view(db[selected_idx])) selected_idx = index - set_item_text(selected_idx, "> " + get_entry_view(db[selected_idx]) + " <") - func clear_selection(): @@ -223,40 +181,6 @@ func load_database(file_path: String = DATABASE_FILE_PATH): db.append(entry) fake_database() - return - - db = [ - instance_entry({ - "process_id": "000001", - "surgery_id": "100000", - "place": "central", - "date": "2020-01-31", - }), - instance_entry({ - "process_id": "000002", - "surgery_id": "200000", - "place": "central", - "date": "2020-02-31", - }), - instance_entry({ - "process_id": "000003", - "surgery_id": "300000", - "place": "central", - "date": "2020-03-31", - }), - instance_entry({ - "process_id": "000004", - "surgery_id": "400000", - "place": "central", - "date": "2020-04-31", - }), - instance_entry({ - "process_id": "000012", - "surgery_id": "210000", - "place": "central", - "date": "2020-12-31", - }), - ] func store_database(file_path: String = DATABASE_FILE_PATH): @@ -321,3 +245,43 @@ func fake_database(): "date": "%04d-%02d-%02d" % [date_year, date_month, date_day] })) + +func pointer_input_handler(pointer: PointerInputSensor.PointerInputData): + match pointer.action: + PointerInputSensor.PointerInputAction.ON_PRESS: + is_pointer_dragging = true + + PointerInputSensor.PointerInputAction.ON_DRAG: + is_pointer_dragging = true + pointer_drag_velocity = pointer.velocity.y + v_scroll_bar.value -= pointer.relative_position.y + + PointerInputSensor.PointerInputAction.ON_END_DRAG: + is_pointer_dragging = false + + PointerInputSensor.PointerInputAction.ON_CLICK: + 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) + + diff --git a/logic/stage.gd b/logic/stage.gd index 62e0a58..27962c6 100644 --- a/logic/stage.gd +++ b/logic/stage.gd @@ -4,21 +4,10 @@ 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") +const POINTER_VELOCITY_DECAYING_FACTOR: float = 2.5 + +var is_pointer_dragging := false +var pointer_drag_velocity := 0.0 onready var process_id: LineEdit = get_node("controls/process_id") onready var surgery_id: LineEdit = get_node("controls/surgery_id") @@ -35,94 +24,46 @@ onready var is_urgency: Button = get_node("controls/is_urgency") onready var notes: LineEdit = get_node("controls/notes") onready var save_button: Button = get_node("controls/save") onready var discard_button: Button = get_node("controls/discard") +onready var v_scroll_bar: VScrollBar = get_v_scrollbar() 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) + it = it as Control match it.name: "date_picker", "save", "discard": - print("- %s" % it.name) - + pass + _: -# "first_assistant": - print("+ %s" % it.name) var drag_sensor = PointerInputSensor.new() + it.add_child(drag_sensor) + 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 + drag_sensor.connect("on_press", self, "pointer_input_handler") + drag_sensor.connect("on_drag", self, "pointer_input_handler") + drag_sensor.connect("on_end_drag", self, "pointer_input_handler") + drag_sensor.connect("on_click", self, "pointer_input_handler") + + it.connect("focus_entered", drag_sensor, "set_mouse_filter", [Control.MOUSE_FILTER_IGNORE]) + it.connect("focus_entered", drag_sensor, "mouse_default_cursor_shape", [Control.CURSOR_IBEAM]) + it.connect("focus_exited", drag_sensor, "set_mouse_filter", [Control.MOUSE_FILTER_STOP]) + it.connect("focus_exited", drag_sensor, "mouse_default_cursor_shape", [Control.CURSOR_ARROW]) + + if it is LineEdit: + it.connect("focus_exited", it, "deselect") -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 - - - - - - + # Apply drag movement inertia. + if is_pointer_dragging == false && abs(pointer_drag_velocity) > 0.5: + pointer_drag_velocity *= clamp((1.0 - POINTER_VELOCITY_DECAYING_FACTOR * delta), 0.0, 1.0) + v_scroll_bar.value -= pointer_drag_velocity * delta func save_action(): @@ -179,3 +120,42 @@ func _notification(what: int): discard_action() +func pointer_input_handler(pointer: PointerInputSensor.PointerInputData): + match pointer.action: + PointerInputSensor.PointerInputAction.ON_PRESS: + is_pointer_dragging = true + + PointerInputSensor.PointerInputAction.ON_DRAG: + is_pointer_dragging = true + pointer_drag_velocity = pointer.velocity.y + v_scroll_bar.value -= pointer.relative_position.y + + PointerInputSensor.PointerInputAction.ON_END_DRAG: + is_pointer_dragging = false + + PointerInputSensor.PointerInputAction.ON_CLICK: + 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) + + @@ -24,6 +24,7 @@ __meta__ = { anchor_right = 1.0 anchor_bottom = 1.0 margin_top = 60.0 +mouse_filter = 2 script = ExtResource( 5 ) __meta__ = { "_edit_use_anchors_": false @@ -103,15 +104,15 @@ size_flags_vertical = 3 [node name="process_id" type="LineEdit" parent="stage/controls"] margin_right = 1080.0 -margin_bottom = 52.0 +margin_bottom = 49.0 placeholder_text = "Nº Processo" caret_blink = true caret_blink_speed = 0.5 [node name="surgery_id" type="LineEdit" parent="stage/controls"] -margin_top = 56.0 +margin_top = 53.0 margin_right = 1080.0 -margin_bottom = 108.0 +margin_bottom = 102.0 placeholder_text = "Nº Cirurgia" caret_blink = true caret_blink_speed = 0.5 @@ -119,93 +120,93 @@ caret_blink_speed = 0.5 [node name="date_picker" parent="stage/controls" instance=ExtResource( 2 )] anchor_right = 0.0 anchor_bottom = 0.0 -margin_top = 112.0 +margin_top = 106.0 margin_right = 1080.0 -margin_bottom = 312.0 +margin_bottom = 306.0 rect_min_size = Vector2( 400, 200 ) [node name="place" type="LineEdit" parent="stage/controls"] -margin_top = 316.0 +margin_top = 310.0 margin_right = 1080.0 -margin_bottom = 368.0 +margin_bottom = 359.0 placeholder_text = "Local" caret_blink = true caret_blink_speed = 0.5 [node name="anesthetic" type="LineEdit" parent="stage/controls"] -margin_top = 372.0 +margin_top = 363.0 margin_right = 1080.0 -margin_bottom = 424.0 -placeholder_text = "Anesthesics" +margin_bottom = 412.0 +placeholder_text = "Anestesia" caret_blink = true caret_blink_speed = 0.5 [node name="first_assistant" type="LineEdit" parent="stage/controls"] -margin_top = 428.0 +margin_top = 416.0 margin_right = 1080.0 -margin_bottom = 480.0 +margin_bottom = 465.0 placeholder_text = "1º Ajudante" caret_blink = true caret_blink_speed = 0.5 [node name="type" type="LineEdit" parent="stage/controls"] -margin_top = 484.0 +margin_top = 469.0 margin_right = 1080.0 -margin_bottom = 536.0 +margin_bottom = 518.0 placeholder_text = "Tipo" caret_blink = true caret_blink_speed = 0.5 [node name="sub_type" type="LineEdit" parent="stage/controls"] -margin_top = 540.0 +margin_top = 522.0 margin_right = 1080.0 -margin_bottom = 592.0 +margin_bottom = 571.0 placeholder_text = "Subtipo" caret_blink = true caret_blink_speed = 0.5 [node name="sub_sub_type" type="LineEdit" parent="stage/controls"] -margin_top = 596.0 +margin_top = 575.0 margin_right = 1080.0 -margin_bottom = 648.0 +margin_bottom = 624.0 placeholder_text = "Sub-Subtipo" caret_blink = true caret_blink_speed = 0.5 [node name="pathology" type="LineEdit" parent="stage/controls"] -margin_top = 652.0 +margin_top = 628.0 margin_right = 1080.0 -margin_bottom = 704.0 +margin_bottom = 677.0 placeholder_text = "Patologia" caret_blink = true caret_blink_speed = 0.5 [node name="intervention" type="LineEdit" parent="stage/controls"] -margin_top = 708.0 +margin_top = 681.0 margin_right = 1080.0 -margin_bottom = 760.0 +margin_bottom = 730.0 placeholder_text = "Intervenção" caret_blink = true caret_blink_speed = 0.5 [node name="is_urgency" type="CheckBox" parent="stage/controls"] -margin_top = 764.0 +margin_top = 734.0 margin_right = 1080.0 -margin_bottom = 814.0 +margin_bottom = 781.0 text = "Urgência" [node name="notes" type="LineEdit" parent="stage/controls"] -margin_top = 818.0 +margin_top = 785.0 margin_right = 1080.0 -margin_bottom = 870.0 +margin_bottom = 834.0 placeholder_text = "Notas" caret_blink = true caret_blink_speed = 0.5 [node name="discard" type="Button" parent="stage/controls"] -margin_top = 928.0 +margin_top = 838.0 margin_right = 1080.0 -margin_bottom = 978.0 +margin_bottom = 888.0 grow_horizontal = 2 grow_vertical = 2 rect_min_size = Vector2( 0, 50 ) @@ -215,9 +216,9 @@ __meta__ = { } [node name="save" type="Button" parent="stage/controls"] -margin_top = 874.0 +margin_top = 892.0 margin_right = 1080.0 -margin_bottom = 924.0 +margin_bottom = 942.0 grow_horizontal = 2 grow_vertical = 2 rect_min_size = Vector2( 0, 50 ) diff --git a/pointer_input_sensor.gd b/pointer_input_sensor.gd index 95e1b4b..27f257c 100644 --- a/pointer_input_sensor.gd +++ b/pointer_input_sensor.gd @@ -1,8 +1,7 @@ extends Control class_name PointerInputSensor -export var drag_threshold_cm: float = 0.250 - +# All on_ACTION signals have a single argument of type PointerInputData. signal on_press signal on_release #signal on_release_outside @@ -14,19 +13,35 @@ signal on_begin_drag signal on_drag signal on_end_drag +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, +} + class PointerInputData: var target: PointerInputSensor var index := -1 var initial_position := Vector2.ZERO var current_position := Vector2.ZERO - var relative_position = Vector2.ZERO + var relative_position := Vector2.ZERO var velocity := Vector2.ZERO var was_dragged := false var is_pressed := false + var action: int = PointerInputAction.UNDEFINED + +export var drag_threshold_cm: float = 0.250 var pointer: PointerInputData var screen_dpcm: float -var on_process: FuncRef func _ready(): @@ -37,12 +52,8 @@ func _ready(): 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): + pointer.action = PointerInputAction.ON_ENTER if is_inside else PointerInputAction.ON_EXIT emit_signal("on_enter" if is_inside else "on_exit", pointer) @@ -60,12 +71,16 @@ func _gui_input(event: InputEvent): 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 @@ -75,10 +90,11 @@ func _gui_input(event: InputEvent): 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: + 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) @@ -10,15 +10,27 @@ Surgery Log - [x] Solve how entries are shared across db_screen and stage_screen; - [x] Remove db_entry; - [x] Rename db script/node to database; -- [ ] Input form fields is a column of input items; each input item has (from left to right) a 'LineEdit' and a 'Button'; pressing the button shows a list with possible entries for that field, and selecting an entry will coyp that entry text to the 'LineEdit'; if the 'LineEdit' has text, it's 'Clear Button Enabled' is set and the 'Button' should become smaller (to allow more text to be visible. +- [x] scrolling down on the database screen jumps to the end of the list immediatelly; +- [ ] load/store database CSV file; +- [ ] load/store filters CSV file; +- [ ] add auto-fill button buttons on stage screen: + - should show a pop-up with multiple options filtered according to current filters; + - allow options to be scrolled by dragging; + - selecting option puts that text on the associated LineEdit; +- [ ] on stage screen: if a LineEdit is has text, it's "Clear Button Enabled" is set and the auto-entry-button should become smaller to allow more text to be visible; +- [ ] fix back button: + - on stage screen should show pop-up asking it changes are to be discarded; + - on file-pickers screen should close them; + - on about screen should close it; + - on auto-fill pop-up, should close it; + - on database screen, should deselect selected item, otherwise should quit the app; +- [ ] add pop-up asking if changes are to be discarded once the stage screen's discard button is pressed; - [ ] Share DB: - share db via html email with db inserted in encoded downliadable field; - Use this to send email: https://docs.godotengine.org/en/stable/classes/class_os.html#class-os-method-shell-open -- [ ] File dialogs should be dismissed when back button is pressed (instead of closing the app); - [ ] Translations: - https://docs.godotengine.org/en/stable/getting_started/workflow/assets/importing_translations.html - https://docs.godotengine.org/en/stable/tutorials/i18n/internationalizing_games.html#introduction -- [ ] Set tabs titles dynamically: https://docs.godotengine.org/en/stable/classes/class_tabcontainer.html?highlight=tabcontainer#class-tabcontainer-method-set-tab-title - [ ] Create two themes: - [ ] theme_light - [ ] theme_dark |
