using System.Collections.Generic; using UnityEngine; namespace Ashwild.Settings { /// /// Binds the display widgets (resolution, fullscreen mode, monitor, brightness) to the /// . The panel builds the dropdown option lists from the current /// hardware and converts the fullscreen dropdown index to and from ; /// the brightness slider is configured from the authored . The /// widgets themselves stay pure UI. /// 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 /// /// Initializes each display widget with its apply action (brightness range from the definition). /// 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 /// /// Rebuilds the dropdown options from current hardware and pushes the manager's values. /// 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" }; /// /// Builds the human-readable resolution list from the monitor's supported modes. /// private static List BuildResolutionOptions() { List options = new List(); foreach (Resolution r in Screen.resolutions) options.Add($"{r.width}×{r.height} @{Mathf.RoundToInt((float)r.refreshRateRatio.value)}Hz"); return options; } /// /// Builds the monitor list from the current display layout. /// private static List BuildMonitorOptions() { List displays = new List(); Screen.GetDisplayLayout(displays); List options = new List(); 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; } /// /// Maps a fullscreen mode to its dropdown index. /// private static int ModeToIndex(FullScreenMode mode) => mode switch { FullScreenMode.ExclusiveFullScreen => 0, FullScreenMode.FullScreenWindow => 1, FullScreenMode.MaximizedWindow => 2, FullScreenMode.Windowed => 3, _ => 1 }; /// /// Maps a dropdown index back to its fullscreen mode. /// private static FullScreenMode IndexToMode(int index) => index switch { 0 => FullScreenMode.ExclusiveFullScreen, 1 => FullScreenMode.FullScreenWindow, 2 => FullScreenMode.MaximizedWindow, 3 => FullScreenMode.Windowed, _ => FullScreenMode.FullScreenWindow }; #endregion } }