Player1444 commited on
Commit
fabaa79
·
verified ·
1 Parent(s): 190df91

Upload message.txt

Browse files
Files changed (1) hide show
  1. message.txt +430 -0
message.txt ADDED
@@ -0,0 +1,430 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ extends CanvasLayer
2
+
3
+ const CONFIG_PATH = "user://touch_layout.cfg"
4
+
5
+ var edit_btn: Button
6
+ var is_edit_mode = false
7
+ var dragged_node = null
8
+ var drag_offset = Vector2.ZERO
9
+ var selected_node: Node = null
10
+
11
+ var total_drag_distance = 0.0
12
+ var last_drag_pos = Vector2.ZERO
13
+
14
+ var touch_events = {}
15
+ var initial_distance = 0.0
16
+ var initial_scale = Vector2.ONE
17
+ var is_scaling = false
18
+
19
+ var ui_panel: Panel
20
+ var label_name: Label
21
+ var slider_container: VBoxContainer
22
+ var slider_scale: HSlider
23
+ var slider_opacity: HSlider
24
+ var selection_box: ReferenceRect
25
+
26
+
27
+ func _ready():
28
+ # Force controls to sit on top of UI overlays & keep working if paused
29
+ layer = 128
30
+ pause_mode = Node.PAUSE_MODE_PROCESS
31
+
32
+ # Override gui_disable_input if a splash screen turned it on
33
+ get_tree().get_root().gui_disable_input = false
34
+
35
+ # Fix full-screen overlays when window resizes or scenes load
36
+ get_tree().connect("screen_resized", self, "_unblock_scene_overlays")
37
+
38
+ _create_selection_box()
39
+ _create_edit_button()
40
+ _create_edit_ui_panel()
41
+
42
+ Input.connect("joy_connection_changed", self, "_on_joy_connection_changed")
43
+ _load_layout()
44
+ _check_gamepad_presence()
45
+
46
+ # Give the scene tree a frame to load before running overlay fix
47
+ yield(get_tree(), "idle_frame")
48
+ _unblock_scene_overlays()
49
+
50
+
51
+ func _process(_delta):
52
+ # Keep input alive across scene transitions
53
+ if get_tree().get_root().gui_disable_input:
54
+ get_tree().get_root().gui_disable_input = false
55
+
56
+
57
+ # Prevents full-screen ColorRects / Panels in cutscenes from swallowing touch events
58
+ func _unblock_scene_overlays():
59
+ _recursive_unblock(get_tree().root)
60
+
61
+
62
+ func _recursive_unblock(node: Node):
63
+ if node == self or is_a_parent_of(node):
64
+ return
65
+
66
+ if node is Control:
67
+ if node.mouse_filter == Control.MOUSE_FILTER_STOP:
68
+ node.mouse_filter = Control.MOUSE_FILTER_PASS
69
+
70
+ for child in node.get_children():
71
+ _recursive_unblock(child)
72
+
73
+
74
+ func _input(event):
75
+ if not is_edit_mode:
76
+ return
77
+
78
+ var event_pos = event.position if "position" in event else Vector2.ZERO
79
+
80
+ if ui_panel.visible and ui_panel.get_global_rect().has_point(event_pos):
81
+ return
82
+
83
+ if event is InputEventScreenTouch or (event is InputEventMouseButton and event.button_index == BUTTON_LEFT):
84
+ if event.pressed:
85
+ var index = event.index if "index" in event else 0
86
+ touch_events[index] = event
87
+
88
+ total_drag_distance = 0.0
89
+ last_drag_pos = event_pos
90
+
91
+ if touch_events.size() == 1:
92
+ var children = get_children()
93
+ for i in range(children.size() - 1, -1, -1):
94
+ var child = children[i]
95
+ if not _is_editable_node(child): 
96
+ continue
97
+
98
+ var rect = _get_node_rect(child)
99
+ if rect.has_point(event_pos):
100
+ dragged_node = child
101
+ selected_node = child
102
+ drag_offset = event_pos - rect.position
103
+ _update_ui_for_selected()
104
+ _update_selection_box()
105
+ get_tree().set_input_as_handled()
106
+ break
107
+
108
+ elif touch_events.size() == 2 and dragged_node:
109
+ is_scaling = true
110
+ var points = touch_events.values()
111
+ initial_distance = points[0].position.distance_to(points[1].position)
112
+ initial_scale = dragged_node.scale if dragged_node is TouchScreenButton else dragged_node.rect_scale
113
+
114
+ else:
115
+ var index = event.index if "index" in event else 0
116
+ touch_events.erase(index)
117
+
118
+ if dragged_node == edit_btn and total_drag_distance < 15.0:
119
+ _on_EditButton_pressed()
120
+ get_tree().set_input_as_handled()
121
+ return
122
+
123
+ if touch_events.size() < 2: 
124
+ is_scaling = false
125
+
126
+ if touch_events.size() == 0:
127
+ if dragged_node and dragged_node != edit_btn:
128
+ _save_layout()
129
+ dragged_node = null
130
+
131
+ elif event is InputEventScreenDrag or (event is InputEventMouseMotion and Input.is_mouse_button_pressed(BUTTON_LEFT)):
132
+ var index = event.index if "index" in event else 0
133
+ if touch_events.has(index):
134
+ touch_events[index] = event
135
+
136
+ total_drag_distance += last_drag_pos.distance_to(event_pos)
137
+ last_drag_pos = event_pos
138
+
139
+ if is_scaling and dragged_node and touch_events.size() == 2:
140
+ var points = touch_events.values()
141
+ var current_distance = points[0].position.distance_to(points[1].position)
142
+
143
+ if initial_distance > 0:
144
+ var factor = current_distance / initial_distance
145
+ var new_scale = initial_scale * factor
146
+ new_scale.x = clamp(new_scale.x, 0.4, 4.0)
147
+ new_scale.y = clamp(new_scale.y, 0.4, 4.0)
148
+
149
+ if dragged_node is TouchScreenButton: 
150
+ dragged_node.scale = new_scale
151
+ elif dragged_node is Control: 
152
+ dragged_node.rect_scale = new_scale
153
+
154
+ if slider_scale.value != new_scale.x: 
155
+ slider_scale.value = new_scale.x
156
+
157
+ _update_selection_box()
158
+
159
+ elif dragged_node and not is_scaling:
160
+ var new_pos = event_pos - drag_offset
161
+ if dragged_node is TouchScreenButton: 
162
+ dragged_node.position = new_pos
163
+ elif dragged_node is Control: 
164
+ dragged_node.rect_position = new_pos
165
+
166
+ _update_selection_box()
167
+ get_tree().set_input_as_handled()
168
+
169
+
170
+ func _set_gameplay_active(active: bool):
171
+ for child in get_children():
172
+ if child == ui_panel or child == selection_box or child == edit_btn: 
173
+ continue
174
+
175
+ if child is TouchScreenButton:
176
+ child.set_block_signals(!active)
177
+ if not active:
178
+ if child.action != "":
179
+ child.set_meta("saved_action", child.action)
180
+ child.action = ""
181
+ else:
182
+ if child.has_meta("saved_action"):
183
+ child.action = child.get_meta("saved_action")
184
+
185
+ elif child is Control:
186
+ child.set_block_signals(!active)
187
+ if not active:
188
+ child.set_meta("saved_filter", child.mouse_filter)
189
+ child.mouse_filter = Control.MOUSE_FILTER_IGNORE
190
+ else:
191
+ if child.has_meta("saved_filter"):
192
+ child.mouse_filter = child.get_meta("saved_filter")
193
+
194
+
195
+ func _is_editable_node(node) -> bool:
196
+ if node == ui_panel or node == selection_box: 
197
+ return false
198
+ if not (node is TouchScreenButton or node is Control): 
199
+ return false
200
+ return true
201
+
202
+
203
+ func _get_node_rect(node) -> Rect2:
204
+ var pos = node.global_position if node is TouchScreenButton else node.rect_global_position
205
+ var scale = node.scale if node is TouchScreenButton else node.rect_scale
206
+ var size = Vector2(64, 64)
207
+
208
+ if node is Control: 
209
+ size = node.rect_size
210
+ elif node is TouchScreenButton and node.normal: 
211
+ size = node.normal.get_size()
212
+
213
+ return Rect2(pos, size * scale)
214
+
215
+
216
+ func _create_selection_box():
217
+ selection_box = ReferenceRect.new()
218
+ selection_box.border_color = Color(1.0, 0.8, 0.0, 1.0)
219
+ selection_box.border_width = 3.0
220
+ selection_box.editor_only = false
221
+ selection_box.mouse_filter = Control.MOUSE_FILTER_IGNORE
222
+ selection_box.hide()
223
+ add_child(selection_box)
224
+
225
+
226
+ func _create_edit_button():
227
+ edit_btn = Button.new()
228
+ edit_btn.text = "EDIT"
229
+ edit_btn.rect_min_size = Vector2(100, 50)
230
+ edit_btn.rect_position = Vector2(20, 20)
231
+ add_child(edit_btn)
232
+ edit_btn.connect("pressed", self, "_on_EditButton_pressed")
233
+
234
+
235
+ func _create_edit_ui_panel():
236
+ ui_panel = Panel.new()
237
+ ui_panel.rect_size = Vector2(280, 150)
238
+ ui_panel.set_anchors_and_margins_preset(Control.PRESET_CENTER_TOP)
239
+ ui_panel.margin_top = 20
240
+ ui_panel.hide()
241
+ add_child(ui_panel)
242
+
243
+ var vbox = VBoxContainer.new()
244
+ vbox.set_anchors_and_margins_preset(Control.PRESET_WIDE)
245
+ vbox.margin_left = 10
246
+ vbox.margin_right = -10
247
+ vbox.margin_top = 10
248
+ vbox.margin_bottom = -10
249
+ ui_panel.add_child(vbox)
250
+
251
+ label_name = Label.new()
252
+ label_name.align = Label.ALIGN_CENTER
253
+ label_name.text = "Tap a button to configure"
254
+ vbox.add_child(label_name)
255
+ vbox.add_child(HSeparator.new())
256
+
257
+ slider_container = VBoxContainer.new()
258
+ slider_container.hide()
259
+ vbox.add_child(slider_container)
260
+
261
+ var label_scale = Label.new()
262
+ label_scale.text = "Button Size:"
263
+ slider_container.add_child(label_scale)
264
+
265
+ slider_scale = HSlider.new()
266
+ slider_scale.min_value = 0.5
267
+ slider_scale.max_value = 4.0
268
+ slider_scale.step = 0.1
269
+ slider_scale.connect("value_changed", self, "_on_scale_changed")
270
+ slider_container.add_child(slider_scale)
271
+
272
+ var label_opacity = Label.new()
273
+ label_opacity.text = "Opacity (0 = Hidden):"
274
+ slider_container.add_child(label_opacity)
275
+
276
+ slider_opacity = HSlider.new()
277
+ slider_opacity.min_value = 0.0
278
+ slider_opacity.max_value = 1.0
279
+ slider_opacity.step = 0.1
280
+ slider_opacity.connect("value_changed", self, "_on_opacity_changed")
281
+ slider_container.add_child(slider_opacity)
282
+
283
+
284
+ func _update_ui_for_selected():
285
+ label_name.text = "Settings: " + selected_node.name
286
+ slider_container.show()
287
+
288
+ slider_scale.disconnect("value_changed", self, "_on_scale_changed")
289
+ slider_opacity.disconnect("value_changed", self, "_on_opacity_changed")
290
+
291
+ slider_scale.value = selected_node.scale.x if selected_node is TouchScreenButton else selected_node.rect_scale.x
292
+ slider_opacity.value = selected_node.get_meta("target_opacity") if selected_node.has_meta("target_opacity") else selected_node.modulate.a
293
+
294
+ slider_scale.connect("value_changed", self, "_on_scale_changed")
295
+ slider_opacity.connect("value_changed", self, "_on_opacity_changed")
296
+
297
+
298
+ func _update_selection_box():
299
+ if selected_node:
300
+ var rect = _get_node_rect(selected_node)
301
+ selection_box.rect_global_position = rect.position
302
+ selection_box.rect_size = rect.size
303
+ selection_box.show()
304
+
305
+
306
+ func _on_scale_changed(value):
307
+ if selected_node and not is_scaling:
308
+ var new_scale = Vector2(value, value)
309
+ if selected_node is TouchScreenButton: 
310
+ selected_node.scale = new_scale
311
+ elif selected_node is Control: 
312
+ selected_node.rect_scale = new_scale
313
+
314
+ _update_selection_box()
315
+ _save_layout()
316
+
317
+
318
+ func _on_opacity_changed(value):
319
+ if selected_node:
320
+ selected_node.set_meta("target_opacity", value)
321
+ if value == 0.0:
322
+ selected_node.modulate = Color(1.0, 0.2, 0.2, 0.4)
323
+ else:
324
+ selected_node.modulate = Color(1.0, 1.0, 1.0, value)
325
+ _save_layout()
326
+
327
+
328
+ func _on_EditButton_pressed():
329
+ is_edit_mode = !is_edit_mode
330
+
331
+ if is_edit_mode:
332
+ edit_btn.text = "SAVE"
333
+ edit_btn.modulate = Color(0.5, 1.0, 0.5)
334
+ ui_panel.show()
335
+ slider_container.hide()
336
+ label_name.text = "Tap a button to configure"
337
+
338
+ _set_gameplay_active(false)
339
+
340
+ for child in get_children():
341
+ if not _is_editable_node(child): 
342
+ continue
343
+ child.visible = true
344
+ var opa = child.get_meta("target_opacity") if child.has_meta("target_opacity") else child.modulate.a
345
+ if opa == 0.0:
346
+ child.modulate = Color(1.0, 0.2, 0.2, 0.4)
347
+ else:
348
+ child.modulate = Color(1.0, 1.0, 1.0, opa)
349
+ else:
350
+ edit_btn.text = "EDIT"
351
+ edit_btn.modulate = Color(1.0, 1.0, 1.0)
352
+ ui_panel.hide()
353
+ selection_box.hide()
354
+ selected_node = null
355
+ dragged_node = null
356
+ touch_events.clear()
357
+
358
+ _set_gameplay_active(true)
359
+
360
+ for child in get_children():
361
+ if not _is_editable_node(child): 
362
+ continue
363
+ var opa = child.get_meta("target_opacity") if child.has_meta("target_opacity") else 1.0
364
+
365
+ if opa == 0.0:
366
+ child.visible = false
367
+ else:
368
+ child.visible = true
369
+ child.modulate = Color(1.0, 1.0, 1.0, opa)
370
+
371
+ _save_layout()
372
+ _check_gamepad_presence()
373
+
374
+
375
+ func _save_layout():
376
+ var config = ConfigFile.new()
377
+ for child in get_children():
378
+ if not _is_editable_node(child): 
379
+ continue
380
+ var node_name = child.name
381
+ config.set_value("Layout", node_name + "_pos", child.position if child is TouchScreenButton else child.rect_position)
382
+ config.set_value("Layout", node_name + "_scale", child.scale if child is TouchScreenButton else child.rect_scale)
383
+ config.set_value("Layout", node_name + "_opacity", child.get_meta("target_opacity") if child.has_meta("target_opacity") else child.modulate.a)
384
+ config.save(CONFIG_PATH)
385
+
386
+
387
+ func _load_layout():
388
+ var config = ConfigFile.new()
389
+ if config.load(CONFIG_PATH) == OK:
390
+ for child in get_children():
391
+ if not _is_editable_node(child): 
392
+ continue
393
+ var node_name = child.name
394
+
395
+ if config.has_section_key("Layout", node_name + "_pos"):
396
+ if child is TouchScreenButton: 
397
+ child.position = config.get_value("Layout", node_name + "_pos")
398
+ else: 
399
+ child.rect_position = config.get_value("Layout", node_name + "_pos")
400
+
401
+ if config.has_section_key("Layout", node_name + "_scale"):
402
+ if child is TouchScreenButton: 
403
+ child.scale = config.get_value("Layout", node_name + "_scale")
404
+ else: 
405
+ child.rect_scale = config.get_value("Layout", node_name + "_scale")
406
+
407
+ if config.has_section_key("Layout", node_name + "_opacity"):
408
+ var saved_opa = config.get_value("Layout", node_name + "_opacity")
409
+ child.set_meta("target_opacity", saved_opa)
410
+
411
+ if saved_opa == 0.0:
412
+ child.visible = false
413
+ else:
414
+ child.visible = true
415
+ child.modulate = Color(1.0, 1.0, 1.0, saved_opa)
416
+
417
+
418
+ func _on_joy_connection_changed(_device_id, _connected):
419
+ if not is_edit_mode: 
420
+ _check_gamepad_presence()
421
+
422
+
423
+ func _check_gamepad_presence():
424
+ if is_edit_mode: 
425
+ return
426
+ var is_gamepad = Input.get_connected_joypads().size() > 0
427
+ for child in get_children():
428
+ if not _is_editable_node(child): 
429
+ continue
430
+ child.visible = !is_gamepad