class_name GameKeyboard extends Node3D @export var animator := KeyboardAnimator.new() @export var _key_size: float = 0.25 @export var _key_gap: float = 0.025 @export_group("Node references") @export var _keys_holder: Node3D var alt_layout: bool var pressed_positions: Dictionary[Vector3, bool] @onready var _gap_to_size_ratio: float = _key_gap / _key_size @onready var _default_position: Vector3 = position func _ready() -> void: var layout_rows := LayoutConfig.layout_rows _generate_keys(layout_rows) func _process(delta: float) -> void: transform = animator.animate_keyboard(delta, _default_position, pressed_positions) func _unhandled_input(event: InputEvent) -> void: if event is not InputEventKey: return var event_key := event as InputEventKey var keycode := event_key.get_physical_keycode_with_modifiers() if ( event_key.is_pressed() and not event_key.echo and (keycode == KEY_SHIFT | KEY_MASK_ALT or keycode == KEY_ALT | KEY_MASK_SHIFT) ): alt_layout = not alt_layout print("change layout! " + str(alt_layout)) func _generate_keys(layout_rows: Array[Array]) -> void: print("LOADING LAYOUT!!!!!!") for row in layout_rows: _set_width_ratios_with_gaps(row) var rows_amount := layout_rows.size() var row_width := ( _get_row_width(layout_rows[0]) + (layout_rows[0].size() - 1) * _key_gap ) for i in range(rows_amount): var row := layout_rows[i] as Array[KeyProps] _generate_row(row as Array[KeyProps], i, row_width, rows_amount) func _generate_row( row: Array[KeyProps], row_index: int, row_width: float, rows_amount: int ) -> void: var offset_z: float = ( ((rows_amount - 1) * _key_size + (rows_amount - 1) * _key_gap) / 2 ) var key_pos_x: float = -row_width / 2 + _key_size / 2 var key_pos_z: float = row_index * _key_size + row_index * _key_gap - offset_z for key_props in row: var game_key_node := GameKey.instantiate_with_props(key_props, self) game_key_node.position.x = ( key_pos_x + (_key_size * key_props.width_ratio - _key_size) / 2 ) game_key_node.position.z = key_pos_z _keys_holder.add_child(game_key_node) key_pos_x += _key_size * key_props.width_ratio + _key_gap func _set_width_ratios_with_gaps(row: Array[KeyProps]) -> void: for key_props in row: if key_props.width_ratio_init > 1: key_props.width_ratio += ( _gap_to_size_ratio * (key_props.width_ratio_init - 1) ) func _get_row_width(row: Array[KeyProps]) -> float: var width: float = 0 for key_props in row: width += _key_size * key_props.width_ratio_init return width