136 lines
4.9 KiB
C#
136 lines
4.9 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
|
||
namespace Ashwild.Settings
|
||
{
|
||
/// <summary>
|
||
/// Binds the display widgets (resolution, fullscreen mode, monitor, brightness) to the
|
||
/// <see cref="SettingsManager"/>. The panel builds the dropdown option lists from the current
|
||
/// hardware and converts the fullscreen dropdown index to and from <see cref="FullScreenMode"/>;
|
||
/// the brightness slider is configured from the authored <see cref="SettingsDefinition"/>. The
|
||
/// widgets themselves stay pure UI.
|
||
/// </summary>
|
||
public class DisplaySettingsSubPanel : SettingsSubPanel
|
||
{
|
||
#region Serialized Fields
|
||
|
||
[Header("Widgets")]
|
||
[SerializeField] private SettingDropdownWidget resolutionDropdown;
|
||
[SerializeField] private SettingDropdownWidget fullscreenDropdown;
|
||
[SerializeField] private SettingDropdownWidget monitorDropdown;
|
||
[SerializeField] private SettingSliderWidget brightnessSlider;
|
||
|
||
#endregion
|
||
|
||
#region Unity Lifecycle
|
||
|
||
/// <summary>
|
||
/// Initializes each display widget with its apply action (brightness range from the definition).
|
||
/// </summary>
|
||
private void Awake()
|
||
{
|
||
SettingsManager s = SettingsManager.Instance;
|
||
if (s == null || s.Definition == null)
|
||
{
|
||
Debug.LogError($"[DisplaySettingsSubPanel] SettingsManager/Definition unavailable on '{name}'.", this);
|
||
return;
|
||
}
|
||
SettingsDefinition def = s.Definition;
|
||
|
||
resolutionDropdown.Init(v => s.SetResolution(v));
|
||
fullscreenDropdown.Init(v => s.SetFullscreenMode(IndexToMode(v)));
|
||
monitorDropdown.Init(v => s.SetMonitor(v));
|
||
brightnessSlider.Init(def.Brightness.Min, def.Brightness.Max, def.Brightness.LabelScale, def.Brightness.LabelFormat, v => s.SetBrightness(v));
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Public API
|
||
|
||
/// <summary>
|
||
/// Rebuilds the dropdown options from current hardware and pushes the manager's values.
|
||
/// </summary>
|
||
public override void Refresh()
|
||
{
|
||
SettingsManager s = SettingsManager.Instance;
|
||
if (s == null) return;
|
||
|
||
resolutionDropdown.SetOptions(BuildResolutionOptions());
|
||
resolutionDropdown.SetValue(s.ResolutionIndex);
|
||
|
||
fullscreenDropdown.SetOptions(FullscreenOptions);
|
||
fullscreenDropdown.SetValue(ModeToIndex(s.FullscreenMode));
|
||
|
||
monitorDropdown.SetOptions(BuildMonitorOptions());
|
||
monitorDropdown.SetValue(s.MonitorIndex);
|
||
|
||
brightnessSlider.SetValue(s.Brightness);
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Internal Helpers
|
||
|
||
private static readonly string[] FullscreenOptions =
|
||
{
|
||
"Exclusive Fullscreen",
|
||
"Borderless Window",
|
||
"Maximized Window",
|
||
"Windowed"
|
||
};
|
||
|
||
/// <summary>
|
||
/// Builds the human-readable resolution list from the monitor's supported modes.
|
||
/// </summary>
|
||
private static List<string> BuildResolutionOptions()
|
||
{
|
||
List<string> options = new List<string>();
|
||
foreach (Resolution r in Screen.resolutions)
|
||
options.Add($"{r.width}×{r.height} @{Mathf.RoundToInt((float)r.refreshRateRatio.value)}Hz");
|
||
return options;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Builds the monitor list from the current display layout.
|
||
/// </summary>
|
||
private static List<string> BuildMonitorOptions()
|
||
{
|
||
List<DisplayInfo> displays = new List<DisplayInfo>();
|
||
Screen.GetDisplayLayout(displays);
|
||
List<string> options = new List<string>();
|
||
for (int i = 0; i < displays.Count; i++)
|
||
{
|
||
string label = string.IsNullOrEmpty(displays[i].name) ? $"Monitor {i + 1}" : displays[i].name;
|
||
options.Add($"{label} ({displays[i].width}×{displays[i].height})");
|
||
}
|
||
return options;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Maps a fullscreen mode to its dropdown index.
|
||
/// </summary>
|
||
private static int ModeToIndex(FullScreenMode mode) => mode switch
|
||
{
|
||
FullScreenMode.ExclusiveFullScreen => 0,
|
||
FullScreenMode.FullScreenWindow => 1,
|
||
FullScreenMode.MaximizedWindow => 2,
|
||
FullScreenMode.Windowed => 3,
|
||
_ => 1
|
||
};
|
||
|
||
/// <summary>
|
||
/// Maps a dropdown index back to its fullscreen mode.
|
||
/// </summary>
|
||
private static FullScreenMode IndexToMode(int index) => index switch
|
||
{
|
||
0 => FullScreenMode.ExclusiveFullScreen,
|
||
1 => FullScreenMode.FullScreenWindow,
|
||
2 => FullScreenMode.MaximizedWindow,
|
||
3 => FullScreenMode.Windowed,
|
||
_ => FullScreenMode.FullScreenWindow
|
||
};
|
||
|
||
#endregion
|
||
}
|
||
}
|