diff --git a/battle/ui/action/ActionBox.gd b/battle/ui/action/ActionBox.gd index 2447eb9..43f1e77 100644 --- a/battle/ui/action/ActionBox.gd +++ b/battle/ui/action/ActionBox.gd @@ -15,24 +15,33 @@ enum Action { signal action(action:Action) func _ready() -> void: - btnAttack.pressed.connect(func(): - action.emit(Action.ATTACK) - ) - btnMagic.pressed.connect(func(): - action.emit(Action.MAGIC) - ) - btnItem.pressed.connect(func(): - action.emit(Action.ITEM) - ) - btnBack.pressed.connect(func(): - action.emit(Action.BACK) - ) + btnAttack.pressed.connect(func(): action.emit(Action.ATTACK)) + btnMagic.pressed.connect(func(): action.emit(Action.MAGIC)) + btnItem.pressed.connect(func(): action.emit(Action.ITEM)) + btnBack.pressed.connect(func(): action.emit(Action.BACK)) self.visible = false +func _unhandled_input(event:InputEvent) -> void: + if !visible: + return + if event.is_action_pressed("ui_cancel"): + action.emit(Action.BACK) + get_viewport().set_input_as_handled() + func getAction(fighter:BattleFighter) -> Action: btnAttack.disabled = fighter.movePrimary == null || !fighter.movePrimary.canFighterUse(fighter) btnMagic.disabled = fighter.movesMagical.size() == 0 - btnItem.disabled = false # TODO: check if items available? + btnItem.disabled = false + + # Focus the first available button so the controller can navigate immediately. + if !btnAttack.disabled: + btnAttack.grab_focus() + elif !btnMagic.disabled: + btnMagic.grab_focus() + elif !btnItem.disabled: + btnItem.grab_focus() + else: + btnBack.grab_focus() var act = await action return act diff --git a/project.godot b/project.godot index 6d5b913..fed116f 100644 --- a/project.godot +++ b/project.godot @@ -138,6 +138,47 @@ camera_orbit_down={ "events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) ] } +ui_accept={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null) +] +} +ui_cancel={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194305,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":false,"script":null) +] +} +ui_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) +] +} +ui_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +] +} +ui_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":13,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) +] +} +ui_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":14,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) +] +} [internationalization] diff --git a/ui/mainmenu/MainMenu.gd b/ui/mainmenu/MainMenu.gd index 107d196..15548ba 100644 --- a/ui/mainmenu/MainMenu.gd +++ b/ui/mainmenu/MainMenu.gd @@ -8,11 +8,27 @@ class_name MainMenu extends Control func _ready() -> void: btnNewGame.pressed.connect(onNewGamePressed) btnSettings.pressed.connect(onSettingsPressed) + settingsMenu.opened.connect(_onSettingsOpened) + settingsMenu.closed.connect(_onSettingsClosed) + btnNewGame.grab_focus() + +func _onSettingsOpened() -> void: + # Move focus into the settings panel so the controller can navigate it. + # The SettingsMenu grabs its own internal focus via _notification. + pass + +func _onSettingsClosed() -> void: + btnSettings.grab_focus() + +func _unhandled_input(event:InputEvent) -> void: + if event.is_action_pressed("ui_cancel"): + if settingsMenu.isOpen: + settingsMenu.close() + get_viewport().set_input_as_handled() func onNewGamePressed() -> void: SCENE.setScene(SceneSingleton.SceneType.OVERWORLD) OVERWORLD.mapChange(newGameScene, "PlayerSpawnPoint") func onSettingsPressed() -> void: - print("Settings button pressed") settingsMenu.isOpen = true diff --git a/ui/pause/PauseMain.gd b/ui/pause/PauseMain.gd index 6ea764d..eb568d5 100644 --- a/ui/pause/PauseMain.gd +++ b/ui/pause/PauseMain.gd @@ -4,11 +4,12 @@ func _ready() -> void: visible = false $HBoxContainer/ItemList.item_selected.connect(onItemSelected) -func open(): +func open() -> void: visible = true $HBoxContainer/ItemList.clear() + $HBoxContainer/ItemList.grab_focus() -func close(): +func close() -> void: visible = false func isOpen() -> bool: diff --git a/ui/pause/PauseMenu.gd b/ui/pause/PauseMenu.gd index d65bc0e..e06e97c 100644 --- a/ui/pause/PauseMenu.gd +++ b/ui/pause/PauseMenu.gd @@ -17,3 +17,14 @@ func close() -> void: visible = false MAIN.close() SETTINGS.close() + +func _unhandled_input(event:InputEvent) -> void: + if !visible: + return + if event.is_action_pressed("ui_cancel"): + if SETTINGS.isOpen(): + SETTINGS.close() + MAIN.open() + else: + close() + get_viewport().set_input_as_handled() diff --git a/ui/settings/SettingsMenu.gd b/ui/settings/SettingsMenu.gd index 9f812b2..fb10da3 100644 --- a/ui/settings/SettingsMenu.gd +++ b/ui/settings/SettingsMenu.gd @@ -7,9 +7,12 @@ func _ready() -> void: tabs.tab_changed.connect(onTabChanged) onTabChanged(tabs.current_tab) +func _notification(what:int) -> void: + if what == NOTIFICATION_VISIBILITY_CHANGED and visible: + tabs.grab_focus() + func onTabChanged(tabIndex:int) -> void: for control in tabControls: control.visible = false - if tabIndex >= 0 and tabIndex < tabControls.size(): tabControls[tabIndex].visible = true