feat: display settings screen with window mode and resolution picker
This commit is contained in:
144
scripts/UI/DisplaySettings.cs
Normal file
144
scripts/UI/DisplaySettings.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
public partial class DisplaySettings : Control
|
||||
{
|
||||
[Export] public OptionButton WindowModeButton { get; set; }
|
||||
[Export] public OptionButton ResolutionButton { get; set; }
|
||||
[Export] public Control DisplaySettingsControl { get; set; }
|
||||
|
||||
private UIManager UIManager => UIManager.Instance;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
PopulateWindowMode();
|
||||
PopulateResolutions();
|
||||
|
||||
WindowModeButton.ItemSelected += OnWindowModeChanged;
|
||||
ResolutionButton.ItemSelected += OnResolutionChanged;
|
||||
|
||||
LoadSettings();
|
||||
|
||||
if (InputDeviceManager.Instance != null)
|
||||
InputDeviceManager.Instance.DeviceChanged += OnDeviceChanged;
|
||||
DisplaySettingsControl.VisibilityChanged += OnVisibilityChanged;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (InputDeviceManager.Instance != null)
|
||||
InputDeviceManager.Instance.DeviceChanged -= OnDeviceChanged;
|
||||
DisplaySettingsControl.VisibilityChanged -= OnVisibilityChanged;
|
||||
SettingsManager.Instance?.SaveDisplaySettings();
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (!@event.IsActionReleased("ui_cancel")) return;
|
||||
if (!UIManager.IsScreenOnTop(DisplaySettingsControl)) return;
|
||||
|
||||
SettingsManager.Instance?.SaveDisplaySettings();
|
||||
UIManager.PopScreen();
|
||||
}
|
||||
|
||||
private void OnVisibilityChanged()
|
||||
{
|
||||
if (DisplaySettingsControl.IsVisibleInTree() && InputDeviceManager.Instance?.IsPointerless == true)
|
||||
GrabFirstFocus();
|
||||
}
|
||||
|
||||
private void OnDeviceChanged(int device)
|
||||
{
|
||||
var d = (InputDeviceManager.InputDevice)device;
|
||||
if (d != InputDeviceManager.InputDevice.Mouse && DisplaySettingsControl.IsVisibleInTree())
|
||||
GrabFirstFocus();
|
||||
}
|
||||
|
||||
private void GrabFirstFocus() => WindowModeButton.GrabFocus();
|
||||
|
||||
private void PopulateWindowMode()
|
||||
{
|
||||
WindowModeButton.Clear();
|
||||
WindowModeButton.AddItem("Fullscreen", 0);
|
||||
WindowModeButton.AddItem("Borderless", 1);
|
||||
WindowModeButton.AddItem("Windowed", 2);
|
||||
}
|
||||
|
||||
private void PopulateResolutions()
|
||||
{
|
||||
ResolutionButton.Clear();
|
||||
foreach (var res in SettingsManager.Instance.GetAllResolutions())
|
||||
{
|
||||
string label = $"{res.X}×{res.Y}";
|
||||
ResolutionButton.AddItem(label);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWindowModeChanged(long idx)
|
||||
{
|
||||
string mode = idx switch
|
||||
{
|
||||
0 => "fullscreen",
|
||||
1 => "borderless",
|
||||
_ => "windowed"
|
||||
};
|
||||
|
||||
ApplyWindowMode(mode);
|
||||
SettingsManager.Instance.WindowMode = mode;
|
||||
ResolutionButton.Disabled = mode == "fullscreen";
|
||||
SettingsManager.Instance.SaveDisplaySettings();
|
||||
}
|
||||
|
||||
private void OnResolutionChanged(long idx)
|
||||
{
|
||||
var resolutions = SettingsManager.Instance.GetAllResolutions();
|
||||
if (idx < 0 || idx >= resolutions.Count) return;
|
||||
|
||||
var res = resolutions[(int)idx];
|
||||
SettingsManager.Instance.Resolution = res;
|
||||
|
||||
var mode = SettingsManager.Instance.WindowMode;
|
||||
if (mode != "fullscreen")
|
||||
DisplayServer.WindowSetSize(res);
|
||||
|
||||
SettingsManager.Instance.SaveDisplaySettings();
|
||||
}
|
||||
|
||||
private static void ApplyWindowMode(string mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case "fullscreen":
|
||||
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
|
||||
break;
|
||||
case "borderless":
|
||||
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed);
|
||||
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, true);
|
||||
break;
|
||||
default:
|
||||
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed);
|
||||
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSettings()
|
||||
{
|
||||
var mode = SettingsManager.Instance.WindowMode;
|
||||
WindowModeButton.Selected = mode switch
|
||||
{
|
||||
"fullscreen" => 0,
|
||||
"borderless" => 1,
|
||||
_ => 2
|
||||
};
|
||||
ResolutionButton.Disabled = mode == "fullscreen";
|
||||
|
||||
var resolution = SettingsManager.Instance.Resolution;
|
||||
var resolutions = SettingsManager.Instance.GetAllResolutions();
|
||||
int resIdx = resolutions.IndexOf(resolution);
|
||||
if (resIdx >= 0)
|
||||
ResolutionButton.Selected = resIdx;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user