Files
Blockline/scripts/controls_editor.gd

131 lines
4.8 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class_name ControlsEditor
extends PanelContainer
var ui: GameUI
var settings_path := ControlBindings.PATH
var rows := VBoxContainer.new()
var notice := Label.new()
var pending_action := ""
var pending_slot := 0
var candidate: Dictionary = {}
var swap_button := Button.new()
func _ready() -> void:
set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
var background := StyleBoxFlat.new()
background.bg_color = Color("101d26")
add_theme_stylebox_override("panel", background)
var margin := MarginContainer.new()
for side: String in ["left", "right", "top", "bottom"]: margin.add_theme_constant_override("margin_" + side, 24)
add_child(margin)
var column := VBoxContainer.new()
column.add_theme_constant_override("separation", 12)
margin.add_child(column)
var heading := Label.new()
heading.text = "STEUERUNG / TASTENBELEGUNG"
heading.add_theme_font_size_override("font_size", 28)
column.add_child(heading)
notice.text = "Belegung anklicken, dann Taste oder Maustaste drücken. Esc bricht die Eingabe ab."
notice.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
column.add_child(notice)
swap_button.text = "BELEGUNGEN TAUSCHEN"
swap_button.hide()
swap_button.pressed.connect(func(): finish(true))
column.add_child(swap_button)
var scroll := ScrollContainer.new()
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
column.add_child(scroll)
rows.size_flags_horizontal = Control.SIZE_EXPAND_FILL
scroll.add_child(rows)
rebuild()
var footer := HBoxContainer.new()
column.add_child(footer)
var reset := Button.new()
reset.text = "STANDARD WIEDERHERSTELLEN"
reset.pressed.connect(func():
pending_action = ""
swap_button.hide()
ControlBindings.defaults()
persist()
rebuild())
footer.add_child(reset)
var back := Button.new()
back.text = "← ZURÜCK"
back.pressed.connect(ui.settings_menu)
footer.add_child(back)
func rebuild() -> void:
for child in rows.get_children():
rows.remove_child(child)
child.queue_free()
for index in ControlBindings.ACTIONS.size():
var action: String = ControlBindings.ACTIONS[index]
var row := HBoxContainer.new()
rows.add_child(row)
var label := Label.new()
label.text = ControlBindings.LABELS[index]
label.custom_minimum_size.x = 300
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.add_child(label)
for slot in 2:
var button := Button.new()
button.text = ControlBindings.label(ControlBindings.bindings[action][slot])
button.custom_minimum_size = Vector2(180, 40)
button.pressed.connect(func():
pending_action = action
pending_slot = slot
candidate = {}
swap_button.hide()
notice.text = "%s: neue Taste / Maustaste drücken … (Esc: abbrechen)" % ControlBindings.LABELS[index])
row.add_child(button)
var clear := Button.new()
clear.text = "×"
clear.tooltip_text = "Diese Belegung entfernen"
clear.pressed.connect(func():
pending_action = ""
swap_button.hide()
if ControlBindings.assign(action, slot, {}):
persist()
rebuild()
else: notice.text = "Für das Menü muss mindestens eine Taste belegt bleiben.")
row.add_child(clear)
func _input(event: InputEvent) -> void:
if pending_action.is_empty(): return
if not (event is InputEventKey or event is InputEventMouseButton): return
if not event.is_pressed() or event.is_echo(): return
# A pending conflict has explicit buttons; don't capture their mouse clicks.
if swap_button.visible:
if event is InputEventKey and event.keycode == KEY_ESCAPE:
pending_action = ""
swap_button.hide()
notice.text = "Abgebrochen. Die bisherigen Belegungen bleiben bestehen."
get_viewport().set_input_as_handled()
return
get_viewport().set_input_as_handled()
if event is InputEventKey and event.keycode == KEY_ESCAPE:
pending_action = ""
notice.text = "Eingabe abgebrochen."
return
candidate = ControlBindings.encode(event)
if candidate.is_empty(): return
var conflicts := ControlBindings.conflicts(pending_action, pending_slot, candidate)
if not conflicts.is_empty():
var names := PackedStringArray()
for conflict in conflicts: names.append(ControlBindings.LABELS[ControlBindings.ACTIONS.find(conflict.action)])
notice.text = "%s ist bereits belegt: %s. Tauschen oder mit Esc abbrechen." % [ControlBindings.label(candidate), ", ".join(names)]
swap_button.show()
else: finish(false)
func finish(swap: bool) -> void:
if ControlBindings.assign(pending_action, pending_slot, candidate, swap):
persist()
else:
notice.text = "Diese Belegung ist nicht möglich: gehaltene Aktionen brauchen eine Taste / Maustaste; das Menü muss erreichbar bleiben."
pending_action = ""
swap_button.hide()
rebuild()
func persist() -> void:
notice.text = "Gespeichert. Die Steuerung ist sofort aktiv." if ControlBindings.save(settings_path) == OK else "Speichern fehlgeschlagen. Die Änderung ist nur für diese Sitzung aktiv."