aboutsummaryrefslogtreecommitdiff
path: root/touch_vertical_container/touch_vertical_container.gd
blob: 7c2ba84ae7d0cd2a3db7a7aa7f75871866d1178c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
extends ScrollContainer
class_name TouchVerticalContainer

const POINTER_VELOCITY_DECAYING_FACTOR: float = 2.5

var is_pointer_dragging		:= false
var pointer_drag_velocity	:= 0.0
var exclude_controls		:= []


func _ready():
	
	for it in get_node("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.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")
		
#		it.connect("focus_entered", sensor, "set_visible", [false])
#		it.connect("focus_exited", sensor, "set_visible", [true])


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
	pointer_drag_velocity = pointer.velocity.y
	self.scroll_vertical -= pointer.relative_position.y


func pointer_input_on_end_drag_handler(pointer: PointerInputSensor.PointerInputData):
	is_pointer_dragging = false


func pointer_input_on_click_handler(pointer: PointerInputSensor.PointerInputData):
	propagate_click(pointer.target.get_parent(), pointer)


# @DAM Maybe replace this with a stack of next items to process approach.
func propagate_click(control: Control, pointer: PointerInputSensor.PointerInputData) -> bool:
	if control is PointerInputSensor || control.mouse_filter == MOUSE_FILTER_IGNORE || control.visible == false:
		return false
	var click_processed := false
	if control.get_global_rect().has_point(pointer.current_position):
		var children = control.get_children()
		children.invert() # @DAM Use inverted index for loop to avoid invert() operation.
		for child in children:
			if child is Control:
				click_processed = click_processed || propagate_click(child, pointer)
			if click_processed == true:
				break
		
		if click_processed == false:
			if control is CheckBox || control is CheckButton:
				control.pressed = !control.pressed
			control.grab_focus()
			control.emit_signal("button_down")
			control.emit_signal("pressed")
			control.emit_signal("button_up")
			click_processed = true
			pointer.target.visible = false
			control.connect("focus_exited", pointer.target, "set_visible", [true])
	
	return click_processed