UI/Modals/SettingsModal.razor
@namespace sGBA
@inherits PanelComponent
<root class="@(IsVisible ? "visible" : "")">
<div class="modal-backdrop" onclick=@HideWithMouse />
<div class="settings-modal">
<div class="settings-title">#settings.title</div>
<div class="settings-subtitle">#settings.sub</div>
<div class="dialog-body">
<div class="toggle-list">
<SettingsToggleRow Label="#settings.classicfeel" Active=@IsClassicFeelFocused [email protected] RingAlpha=@_ringAlpha Hovered=@(() => SelectAction(ClassicFeelAction)) Clicked=@ToggleClassicFeelWithMouse />
<div class="settings-row-divider" />
<SettingsToggleRow Label="#settings.smallscreen" Active=@IsSmallScreenFocused [email protected] RingAlpha=@_ringAlpha Hovered=@(() => SelectAction(SmallScreenAction)) Clicked=@ToggleSmallScreenWithMouse />
</div>
</div>
</div>
</root>
@code
{
private const int ClassicFeelAction = 0;
private const int SmallScreenAction = 1;
public static SettingsModal Current { get; private set; }
public bool IsVisible { get; private set; }
private int _selectedIndex = ClassicFeelAction;
private readonly FocusInput _input = new();
private bool _openedThisFrame;
private float _ringAlpha;
private bool IsClassicFeelFocused => _input.UseGamepad && _selectedIndex == ClassicFeelAction;
private bool IsSmallScreenFocused => _input.UseGamepad && _selectedIndex == SmallScreenAction;
protected override void OnTreeFirstBuilt()
{
Current = this;
}
protected override void OnDestroy()
{
if (Current == this)
Current = null;
}
public void Show(bool useGamepad = false)
{
Current = this;
IsVisible = true;
_openedThisFrame = true;
_selectedIndex = ClassicFeelAction;
_ringAlpha = 0f;
_input.Begin(useGamepad);
Sound.Play("ui.popup.message.open");
StateHasChanged();
}
public void Hide()
{
IsVisible = false;
_ringAlpha = 0f;
var wasGamepad = _input.UseGamepad;
_input.End();
HomeScreen.Current?.FocusSettingsAction(wasGamepad);
Sound.Play("ui.popup.message.close");
StateHasChanged();
}
private void SelectAction(int action)
{
_input.ForceMouseMode();
_selectedIndex = action;
}
private void HideWithMouse()
{
_input.ForceMouseMode();
Hide();
}
private void ToggleClassicFeel(bool playSound = true)
{
if (playSound)
Sound.Play("ui.button.press");
GamePreferences.SetReproduceClassicFeel(!GamePreferences.ReproduceClassicFeel);
StateHasChanged();
}
private void ToggleClassicFeelWithMouse()
{
_input.ForceMouseMode();
ToggleClassicFeel();
}
private void ToggleSmallScreen(bool playSound = true)
{
if (playSound)
Sound.Play("ui.button.press");
GamePreferences.SetDisplayWithSmallScreen(!GamePreferences.DisplayWithSmallScreen);
StateHasChanged();
}
private void ToggleSmallScreenWithMouse()
{
_input.ForceMouseMode();
ToggleSmallScreen();
}
private void SetGamepadMode() => _input.ForceGamepadMode();
protected override void OnUpdate()
{
if (!IsVisible)
return;
if (new Game.Overlay().IsOpen)
return;
float nextRingAlpha = MathF.Min(1f, _ringAlpha + Time.Delta / 0.16f);
if (MathF.Abs(nextRingAlpha - _ringAlpha) > 0.001f)
{
_ringAlpha = nextRingAlpha;
StateHasChanged();
}
if (_openedThisFrame)
{
_openedThisFrame = false;
return;
}
var nav = _input.TickRepeating();
if (nav.Up) NavigateUp();
if (nav.Down) NavigateDown();
if (Input.Pressed("GBA_A"))
{
SetGamepadMode();
Sound.Play("ui.button.press");
if (_selectedIndex == ClassicFeelAction)
ToggleClassicFeel(playSound: false);
else
ToggleSmallScreen(playSound: false);
}
if (Input.Pressed("GBA_B"))
{
SetGamepadMode();
Sound.Play("ui.button.press");
Hide();
}
}
private void NavigateUp()
{
SetGamepadMode();
if (_selectedIndex > ClassicFeelAction)
{
_selectedIndex--;
Sound.Play("ui.button.over");
}
}
private void NavigateDown()
{
SetGamepadMode();
if (_selectedIndex < SmallScreenAction)
{
_selectedIndex++;
Sound.Play("ui.button.over");
}
}
protected override int BuildHash()
{
return HashCode.Combine(IsVisible, _selectedIndex, _input.UseGamepad, _openedThisFrame, _ringAlpha, GamePreferences.ReproduceClassicFeel, GamePreferences.DisplayWithSmallScreen);
}
}