76 lines
2.7 KiB
GDScript
76 lines
2.7 KiB
GDScript
extends PanelContainer
|
|||
|
|
## Always-on compact panel listing the current controls.
|
||
|
|
## Reads bindings straight from the InputMap so it stays accurate if keys are rebound.
|
||
|
|
|
||
|
|
# Each row is a friendly label plus the input action(s) that feed it.
|
||
|
|
# Grouped actions (like movement) show their keys joined together.
|
||
|
|
const ROWS := [
|
||
|
|
{ "label": "Move", "actions": ["move_forward", "move_left", "move_backward", "move_right"] },
|
||
|
|
{ "label": "Jump", "actions": ["jump"] },
|
||
|
|
{ "label": "Sprint", "actions": ["shift"] },
|
||
|
|
{ "label": "Dash", "actions": ["dash"] },
|
||
|
|
{ "label": "Attack", "actions": ["attack"] },
|
||
|
|
{ "label": "Block", "actions": ["block"] },
|
||
|
|
{ "label": "Pick Up / Drop", "actions": ["pickup"] },
|
||
|
|
{ "label": "Character Sheet", "actions": ["toggle_character_sheet"] },
|
||
|
|
{ "label": "Chat", "actions": ["toggle_chat"] },
|
||
|
|
{ "label": "Menu", "actions": ["quit"] },
|
||
|
|
]
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
_build()
|
||
|
|
|
||
|
|
func _build() -> void:
|
||
|
|
var content: VBoxContainer = $Margin/Content
|
||
|
|
|
||
|
|
var title := Label.new()
|
||
|
|
title.text = "CONTROLS"
|
||
|
|
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||
|
|
title.add_theme_font_size_override("font_size", 16)
|
||
|
|
title.add_theme_color_override("font_color", Color(1, 0.8, 0, 1))
|
||
|
|
title.add_theme_color_override("font_outline_color", Color.BLACK)
|
||
|
|
title.add_theme_constant_override("outline_size", 2)
|
||
|
|
content.add_child(title)
|
||
|
|
|
||
|
|
var grid := GridContainer.new()
|
||
|
|
grid.columns = 2
|
||
|
|
grid.add_theme_constant_override("h_separation", 12)
|
||
|
|
grid.add_theme_constant_override("v_separation", 3)
|
||
|
|
content.add_child(grid)
|
||
|
|
|
||
|
|
for row in ROWS:
|
||
|
|
var keys: Array[String] = []
|
||
|
|
for action in row["actions"]:
|
||
|
|
var k := _key_text(action)
|
||
|
|
if k != "":
|
||
|
|
keys.append(k)
|
||
|
|
if keys.is_empty():
|
||
|
|
continue
|
||
|
|
grid.add_child(_make_label(" ".join(keys), Color(1, 0.82, 0.2, 1)))
|
||
|
|
grid.add_child(_make_label(row["label"], Color.WHITE))
|
||
|
|
|
||
|
|
func _make_label(text: String, color: Color) -> Label:
|
||
|
|
var l := Label.new()
|
||
|
|
l.text = text
|
||
|
|
l.add_theme_font_size_override("font_size", 13)
|
||
|
|
l.add_theme_color_override("font_color", color)
|
||
|
|
l.add_theme_color_override("font_outline_color", Color.BLACK)
|
||
|
|
l.add_theme_constant_override("outline_size", 1)
|
||
|
|
return l
|
||
|
|
|
||
|
|
## Returns a human-readable name for the first event bound to an action.
|
||
|
|
func _key_text(action: String) -> String:
|
||
|
|
if not InputMap.has_action(action):
|
||
|
|
return ""
|
||
|
|
for ev in InputMap.action_get_events(action):
|
||
|
|
if ev is InputEventKey:
|
||
|
|
var code: int = ev.physical_keycode if ev.physical_keycode != 0 else ev.keycode
|
||
|
|
return OS.get_keycode_string(code)
|
||
|
|
elif ev is InputEventMouseButton:
|
||
|
|
match ev.button_index:
|
||
|
|
MOUSE_BUTTON_LEFT: return "LMB"
|
||
|
|
MOUSE_BUTTON_RIGHT: return "RMB"
|
||
|
|
MOUSE_BUTTON_MIDDLE: return "MMB"
|
||
|
|
_: return "Mouse %d" % ev.button_index
|
||
|
|
return ""
|