feat: gamepad/keyboard UI navigation on all menus

This commit is contained in:
2026-03-19 03:26:50 +01:00
parent 2bc0b76050
commit 3b18e328b2
5 changed files with 137 additions and 0 deletions

View File

@@ -16,19 +16,44 @@ public partial class AudioSettings : Control
public override void _Ready() public override void _Ready()
{ {
MasterVolumeSlider.FocusMode = Control.FocusModeEnum.All;
MusicVolumeSlider.FocusMode = Control.FocusModeEnum.All;
SfxVolumeSlider.FocusMode = Control.FocusModeEnum.All;
Initialize(); Initialize();
MasterVolumeSlider.ValueChanged += OnMasterVolumeChanged; MasterVolumeSlider.ValueChanged += OnMasterVolumeChanged;
MusicVolumeSlider.ValueChanged += OnMusicVolumeChanged; MusicVolumeSlider.ValueChanged += OnMusicVolumeChanged;
SfxVolumeSlider.ValueChanged += OnSfxVolumeChanged; SfxVolumeSlider.ValueChanged += OnSfxVolumeChanged;
LoadSettings(); LoadSettings();
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
AudioSettingsControl.VisibilityChanged += OnVisibilityChanged;
} }
public override void _ExitTree() public override void _ExitTree()
{ {
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
SaveSettings(); SaveSettings();
} }
private void OnVisibilityChanged()
{
if (AudioSettingsControl.IsVisibleInTree() && InputDeviceManager.Instance?.IsPointerless == true)
GrabFirstFocus();
}
private void OnDeviceChanged(int device)
{
var d = (InputDeviceManager.InputDevice)device;
if (d != InputDeviceManager.InputDevice.Mouse && AudioSettingsControl.IsVisibleInTree())
GrabFirstFocus();
}
private void GrabFirstFocus() => MasterVolumeSlider.GrabFocus();
public override void _UnhandledInput(InputEvent @event) public override void _UnhandledInput(InputEvent @event)
{ {
if (!@event.IsActionReleased("ui_cancel")) return; if (!@event.IsActionReleased("ui_cancel")) return;

View File

@@ -13,8 +13,27 @@ public partial class GameOverScreen : Control
public override void _Ready() public override void _Ready()
{ {
RestartButton.FocusMode = Control.FocusModeEnum.All;
MainMenuButton.FocusMode = Control.FocusModeEnum.All;
RestartButton.Pressed += OnRestartClicked; RestartButton.Pressed += OnRestartClicked;
MainMenuButton.Pressed += OnMainMenuClicked; MainMenuButton.Pressed += OnMainMenuClicked;
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
}
public override void _ExitTree()
{
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
}
private void OnDeviceChanged(int device)
{
var d = (InputDeviceManager.InputDevice)device;
if (d != InputDeviceManager.InputDevice.Mouse && GameOverPanel.IsVisibleInTree())
RestartButton.GrabFocus();
} }
private void OnMainMenuClicked() private void OnMainMenuClicked()
@@ -33,5 +52,7 @@ public partial class GameOverScreen : Control
if (GameStateStore.Instance?.Player.Lives != 0) return; if (GameStateStore.Instance?.Player.Lives != 0) return;
GameOverPanel.Show(); GameOverPanel.Show();
if (InputDeviceManager.Instance?.IsPointerless == true)
RestartButton.GrabFocus();
} }
} }

View File

@@ -21,6 +21,11 @@ public partial class MainMenu : Control
public override void _Ready() public override void _Ready()
{ {
NewGameButton.FocusMode = Control.FocusModeEnum.All;
ContinueButton.FocusMode = Control.FocusModeEnum.All;
SettingsButton.FocusMode = Control.FocusModeEnum.All;
CreditsButton.FocusMode = Control.FocusModeEnum.All;
ExitButton.FocusMode = Control.FocusModeEnum.All;
NewGameButton.Pressed += OnNewGamePressed; NewGameButton.Pressed += OnNewGamePressed;
ContinueButton.Pressed += OnContinuePressed; ContinueButton.Pressed += OnContinuePressed;
@@ -31,6 +36,34 @@ public partial class MainMenu : Control
VersionLabel.Text = $"v. {ProjectSettings.GetSetting("application/config/version")}"; VersionLabel.Text = $"v. {ProjectSettings.GetSetting("application/config/version")}";
ContinueButton.Disabled = !SaveSystem.CheckSaveExists(); ContinueButton.Disabled = !SaveSystem.CheckSaveExists();
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
VisibilityChanged += OnVisibilityChanged;
GrabFirstFocus();
}
public override void _ExitTree()
{
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
}
private void OnVisibilityChanged()
{
if (IsVisibleInTree() && InputDeviceManager.Instance?.IsPointerless == true)
GrabFirstFocus();
}
private void OnDeviceChanged(int device)
{
var d = (InputDeviceManager.InputDevice)device;
if (d != InputDeviceManager.InputDevice.Mouse && IsVisibleInTree())
GrabFirstFocus();
}
private void GrabFirstFocus()
{
if (SaveSystem.CheckSaveExists()) if (SaveSystem.CheckSaveExists())
ContinueButton.GrabFocus(); ContinueButton.GrabFocus();
else else

View File

@@ -18,6 +18,10 @@ public partial class PauseMenu : Control
public override void _Ready() public override void _Ready()
{ {
ResumeButton.FocusMode = Control.FocusModeEnum.All;
MainMenuButton.FocusMode = Control.FocusModeEnum.All;
QuitButton.FocusMode = Control.FocusModeEnum.All;
SettingsButton.FocusMode = Control.FocusModeEnum.All;
ResumeButton.Pressed += OnResumePressed; ResumeButton.Pressed += OnResumePressed;
MainMenuButton.Pressed += OnMainMenuPressed; MainMenuButton.Pressed += OnMainMenuPressed;
@@ -25,8 +29,33 @@ public partial class PauseMenu : Control
SettingsButton.Pressed += OnSettingsPressed; SettingsButton.Pressed += OnSettingsPressed;
PauseMenuControl.Hide(); PauseMenuControl.Hide();
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
PauseMenuControl.VisibilityChanged += OnVisibilityChanged;
} }
public override void _ExitTree()
{
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
}
private void OnVisibilityChanged()
{
if (PauseMenuControl.IsVisibleInTree() && InputDeviceManager.Instance?.IsPointerless == true)
GrabFirstFocus();
}
private void OnDeviceChanged(int device)
{
var d = (InputDeviceManager.InputDevice)device;
if (d != InputDeviceManager.InputDevice.Mouse && PauseMenuControl.IsVisibleInTree())
GrabFirstFocus();
}
private void GrabFirstFocus() => ResumeButton.GrabFocus();
public override void _UnhandledInput(InputEvent @event) public override void _UnhandledInput(InputEvent @event)
{ {
if (!@event.IsActionPressed("pause")) return; if (!@event.IsActionPressed("pause")) return;

View File

@@ -19,6 +19,10 @@ public partial class SettingsMenu : Control
public override void _Ready() public override void _Ready()
{ {
InputSettingsButton.FocusMode = Control.FocusModeEnum.All;
AudioSettingsButton.FocusMode = Control.FocusModeEnum.All;
DisplaySettingsButton.FocusMode = Control.FocusModeEnum.All;
GameplaySettingsButton.FocusMode = Control.FocusModeEnum.All;
InputSettingsButton.Pressed += OnInputSettingsPressed; InputSettingsButton.Pressed += OnInputSettingsPressed;
AudioSettingsButton.Pressed += OnAudioSettingsPressed; AudioSettingsButton.Pressed += OnAudioSettingsPressed;
@@ -29,8 +33,33 @@ public partial class SettingsMenu : Control
AudioSettingsControl?.Hide(); AudioSettingsControl?.Hide();
DisplaySettingsControl?.Hide(); DisplaySettingsControl?.Hide();
GameplaySettingsControl?.Hide(); GameplaySettingsControl?.Hide();
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
VisibilityChanged += OnVisibilityChanged;
} }
public override void _ExitTree()
{
if (InputDeviceManager.Instance != null)
InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
}
private void OnVisibilityChanged()
{
if (IsVisibleInTree() && InputDeviceManager.Instance?.IsPointerless == true)
GrabFirstFocus();
}
private void OnDeviceChanged(int device)
{
var d = (InputDeviceManager.InputDevice)device;
if (d != InputDeviceManager.InputDevice.Mouse && IsVisibleInTree())
GrabFirstFocus();
}
private void GrabFirstFocus() => InputSettingsButton.GrabFocus();
public override void _UnhandledInput(InputEvent @event) public override void _UnhandledInput(InputEvent @event)
{ {
if (!@event.IsActionPressed("ui_cancel")) return; if (!@event.IsActionPressed("ui_cancel")) return;