aboutsummaryrefslogtreecommitdiff
path: root/ui/touch_vertical_container/touch_vertical_container.gd
diff options
context:
space:
mode:
authordam <dam@gudinoff>2022-04-18 09:06:19 +0000
committerdam <dam@gudinoff>2022-04-18 09:06:19 +0000
commit79691f93bab7aa093bb606bfb80d2b4b236ee091 (patch)
tree6e90c6601893895d7640f478f0cad402cc7590b4 /ui/touch_vertical_container/touch_vertical_container.gd
parent697e1ba3c4cb0a96c4584f1553de368d46287ab7 (diff)
parentee31a9a3d387121030a5f4503adeac5816d7726f (diff)
downloadsurgery-log-1.0.tar.zst
surgery-log-1.0.zip
Merge godot branch.v1.0
Diffstat (limited to 'ui/touch_vertical_container/touch_vertical_container.gd')
-rw-r--r--ui/touch_vertical_container/touch_vertical_container.gd118
1 files changed, 118 insertions, 0 deletions
diff --git a/ui/touch_vertical_container/touch_vertical_container.gd b/ui/touch_vertical_container/touch_vertical_container.gd
new file mode 100644
index 0000000..8f87338
--- /dev/null
+++ b/ui/touch_vertical_container/touch_vertical_container.gd
@@ -0,0 +1,118 @@
+extends ScrollContainer
+class_name TouchVerticalContainer
+
+const POINTER_VELOCITY_DECAYING_FACTOR: float = PI
+const POINTER_VELOCITY_BOOST_FACTOR: float = 1.25
+
+var is_pointer_dragging := false
+var pointer_drag_velocity := 0.0
+var when_last_dragged := 0
+var exclude_controls := []
+
+onready var controls = get_node("controls")
+
+
+func _ready():
+ assert(controls != null, "TouchVerticalContainer failed to get 'controls' node.")
+
+ var item_list_separation := float(controls.get_constant("separation"))
+
+ for it in controls.get_children():
+ it = it as Control
+ if exclude_controls.has(it.name):
+ continue
+
+ var sensor = PointerInputSensor.new()
+ it.add_child(sensor)
+
+ sensor.name = "sensor"
+ sensor.anchor_right = 1.0
+ sensor.anchor_bottom = 1.0
+ sensor.margin_top = - item_list_separation / 2.0
+ sensor.margin_bottom = item_list_separation / 2.0
+
+ sensor.connect("on_press", self, "pointer_input_on_press_handler")
+ sensor.connect("on_drag", self, "pointer_input_on_drag_handler")
+ sensor.connect("on_end_drag", self, "pointer_input_on_end_drag_handler")
+ sensor.connect("on_click", self, "pointer_input_on_click_handler")
+ sensor.connect("on_scroll", self, "pointer_input_on_scroll_handler")
+
+
+func _process(delta: float):
+ # 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)
+ self.scroll_vertical -= pointer_drag_velocity * delta
+
+
+func pointer_input_on_press_handler(pointer: PointerInputSensor.PointerInputData):
+ is_pointer_dragging = true
+ grab_focus()
+
+
+func pointer_input_on_drag_handler(pointer: PointerInputSensor.PointerInputData):
+ is_pointer_dragging = true
+ var reported_velocity_abs := abs(pointer.velocity.y)
+ var relative_velocity := pointer.relative_position.y * Engine.get_frames_per_second()
+ var relative_velocity_abs := abs(relative_velocity)
+ pointer_drag_velocity = pointer.velocity.y if reported_velocity_abs > relative_velocity_abs else relative_velocity
+ self.scroll_vertical -= pointer.relative_position.y
+ when_last_dragged = OS.get_ticks_msec()
+
+
+func pointer_input_on_end_drag_handler(pointer: PointerInputSensor.PointerInputData):
+ is_pointer_dragging = false
+ if OS.get_ticks_msec() - when_last_dragged > 20:
+ pointer_drag_velocity = 0.0
+ else:
+ pointer_drag_velocity *= POINTER_VELOCITY_BOOST_FACTOR
+
+
+func pointer_input_on_click_handler(pointer: PointerInputSensor.PointerInputData):
+ # Get last leaf node.
+ var root := pointer.target.get_parent() as Control
+ var leaf := root as Node
+ while leaf.get_child_count() > 0:
+ leaf = leaf.get_child(leaf.get_child_count() - 1)
+
+ # Navigate backwards from leaf to root until we find a node accepting the input.
+ var tried_leaf_as_root := false
+ while leaf != root || tried_leaf_as_root == false:
+ tried_leaf_as_root = leaf == root # Allow a final iteration cycle when leaf reaches root.
+ var node := leaf
+
+ if node is PointerInputSensor \
+ || node is Control == false \
+ || node.mouse_filter == MOUSE_FILTER_IGNORE \
+ || node.visible == false \
+ || node.get_global_rect().has_point(pointer.current_position) == false:
+ # Get next node to be processed.
+ var leaf_index_in_parent := leaf.get_position_in_parent()
+ var parent := leaf.get_parent()
+ if leaf_index_in_parent == 0:
+ leaf = parent
+ else:
+ leaf = parent.get_child(leaf_index_in_parent - 1)
+ # Drill down into the new tree branch.
+ while leaf.get_child_count() > 0:
+ leaf = leaf.get_child(leaf.get_child_count() - 1)
+ continue
+
+ var control: Control = node
+ if control is CheckBox || control is CheckButton || (control is Button && control.toggle_mode == true):
+ control.pressed = !control.pressed
+
+ control.grab_focus()
+ control.emit_signal("button_down")
+ control.emit_signal("pressed")
+ control.emit_signal("button_up")
+ control.connect("focus_exited", pointer.target, "set_visible", [true], CONNECT_ONESHOT)
+ pointer.target.visible = false
+ break
+
+
+func pointer_input_on_scroll_handler(pointer: PointerInputSensor.PointerInputData):
+ var target := self
+ target._gui_input(pointer.event)
+
+