using Content.Shared.CCVar; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.XAML; using Robust.Shared; using Robust.Shared.Configuration; namespace Content.Client.Options.UI.Tabs; [GenerateTypedNameReferences] public sealed partial class GraphicsTab : Control { [Dependency] private readonly IConfigurationManager _cfg = default!; public GraphicsTab() { IoCManager.InjectDependencies(this); RobustXamlLoader.Load(this); Control.AddOptionCheckBox(CVars.DisplayVSync, VSyncCheckBox); Control.AddOptionCheckBox(CCVars.AmbientOcclusion, AmbientOcclusionCheckBox); Control.AddOption(new OptionFullscreen(Control, _cfg, FullscreenCheckBox)); Control.AddOption(new OptionLightingQuality(Control, _cfg, DropDownLightingQuality)); Control.AddOptionDropDown( CVars.DisplayUIScale, DropDownUIScale, [ new OptionDropDownCVar.ValueOption( 0f, Loc.GetString("ui-options-scale-auto", ("scale", UserInterfaceManager.DefaultUIScale))), new OptionDropDownCVar.ValueOption(0.75f, Loc.GetString("ui-options-scale-75")), new OptionDropDownCVar.ValueOption(1.00f, Loc.GetString("ui-options-scale-100")), new OptionDropDownCVar.ValueOption(1.25f, Loc.GetString("ui-options-scale-125")), new OptionDropDownCVar.ValueOption(1.50f, Loc.GetString("ui-options-scale-150")), new OptionDropDownCVar.ValueOption(1.75f, Loc.GetString("ui-options-scale-175")), new OptionDropDownCVar.ValueOption(2.00f, Loc.GetString("ui-options-scale-200")), ]); Control.AddOptionDropDown( CCVars.ViewportScalingFilterMode, DropDownFilterMode, [ new OptionDropDownCVar.ValueOption("nearest", Loc.GetString("ui-options-filter-nearest")), new OptionDropDownCVar.ValueOption("bilinear", Loc.GetString("ui-options-filter-bilinear")), ]); var vpStretch = Control.AddOptionCheckBox(CCVars.ViewportStretch, ViewportStretchCheckBox); var vpVertFit = Control.AddOptionCheckBox(CCVars.ViewportVerticalFit, ViewportVerticalFitCheckBox); Control.AddOptionSlider( CCVars.ViewportFixedScaleFactor, ViewportScaleSlider, 1, 5, (_, value) => Loc.GetString("ui-options-vp-scale-value", ("scale", value))); vpStretch.ImmediateValueChanged += _ => UpdateViewportSettingsVisibility(); vpVertFit.ImmediateValueChanged += _ => UpdateViewportSettingsVisibility(); IntegerScalingCheckBox.OnToggled += _ => UpdateViewportSettingsVisibility(); Control.AddOptionSlider( CCVars.ViewportWidth, ViewportWidthSlider, (int)ViewportWidthSlider.Slider.MinValue, (int)ViewportWidthSlider.Slider.MaxValue); Control.AddOption(new OptionIntegerScaling(Control, _cfg, IntegerScalingCheckBox)); Control.AddOptionCheckBox(CCVars.ViewportScaleRender, ViewportLowResCheckBox, invert: true); Control.AddOptionCheckBox(CCVars.ParallaxLowQuality, ParallaxLowQualityCheckBox); Control.AddOptionCheckBox(CCVars.HudFpsCounterVisible, FpsCounterCheckBox); Control.Initialize(); _cfg.OnValueChanged(CCVars.ViewportMinimumWidth, _ => UpdateViewportWidthRange()); _cfg.OnValueChanged(CCVars.ViewportMaximumWidth, _ => UpdateViewportWidthRange()); UpdateViewportWidthRange(); UpdateViewportSettingsVisibility(); } private void UpdateViewportSettingsVisibility() { ViewportScaleSlider.Visible = !ViewportStretchCheckBox.Pressed; IntegerScalingCheckBox.Visible = ViewportStretchCheckBox.Pressed; ViewportVerticalFitCheckBox.Visible = ViewportStretchCheckBox.Pressed; ViewportWidthSlider.Visible = !ViewportStretchCheckBox.Pressed || !ViewportVerticalFitCheckBox.Pressed; DropDownFilterMode.Visible = !IntegerScalingCheckBox.Pressed && ViewportStretchCheckBox.Pressed; } private void UpdateViewportWidthRange() { var min = _cfg.GetCVar(CCVars.ViewportMinimumWidth); var max = _cfg.GetCVar(CCVars.ViewportMaximumWidth); ViewportWidthSlider.Slider.MinValue = min; ViewportWidthSlider.Slider.MaxValue = max; } private sealed class OptionLightingQuality : BaseOption { private readonly IConfigurationManager _cfg; private readonly OptionDropDown _dropDown; private const int QualityVeryLow = 0; private const int QualityLow = 1; private const int QualityMedium = 2; private const int QualityHigh = 3; private const int QualityDefault = QualityMedium; public OptionLightingQuality(OptionsTabControlRow controller, IConfigurationManager cfg, OptionDropDown dropDown) : base(controller) { _cfg = cfg; _dropDown = dropDown; var button = dropDown.Button; button.AddItem(Loc.GetString("ui-options-lighting-very-low"), QualityVeryLow); button.AddItem(Loc.GetString("ui-options-lighting-low"), QualityLow); button.AddItem(Loc.GetString("ui-options-lighting-medium"), QualityMedium); button.AddItem(Loc.GetString("ui-options-lighting-high"), QualityHigh); button.OnItemSelected += OnOptionSelected; } private void OnOptionSelected(OptionButton.ItemSelectedEventArgs obj) { _dropDown.Button.SelectId(obj.Id); ValueChanged(); } public override void LoadValue() { _dropDown.Button.SelectId(GetConfigLightingQuality()); } public override void SaveValue() { switch (_dropDown.Button.SelectedId) { case QualityVeryLow: _cfg.SetCVar(CVars.LightResolutionScale, 0.125f); _cfg.SetCVar(CVars.LightSoftShadows, false); _cfg.SetCVar(CVars.LightBlur, false); break; case QualityLow: _cfg.SetCVar(CVars.LightResolutionScale, 0.5f); _cfg.SetCVar(CVars.LightSoftShadows, false); _cfg.SetCVar(CVars.LightBlur, true); break; default: // = QualityMedium _cfg.SetCVar(CVars.LightResolutionScale, 0.5f); _cfg.SetCVar(CVars.LightSoftShadows, true); _cfg.SetCVar(CVars.LightBlur, true); break; case QualityHigh: _cfg.SetCVar(CVars.LightResolutionScale, 1); _cfg.SetCVar(CVars.LightSoftShadows, true); _cfg.SetCVar(CVars.LightBlur, true); break; } } public override void ResetToDefault() { _dropDown.Button.SelectId(QualityDefault); } public override bool IsModified() { return _dropDown.Button.SelectedId != GetConfigLightingQuality(); } public override bool IsModifiedFromDefault() { return _dropDown.Button.SelectedId != QualityDefault; } private int GetConfigLightingQuality() { var val = _cfg.GetCVar(CVars.LightResolutionScale); var soft = _cfg.GetCVar(CVars.LightSoftShadows); if (val <= 0.125) return QualityVeryLow; if ((val <= 0.5) && !soft) return QualityLow; if (val <= 0.5) return QualityMedium; return QualityHigh; } } private sealed class OptionFullscreen : BaseOptionCVar { private readonly CheckBox _checkBox; protected override int Value { get => _checkBox.Pressed ? (int) WindowMode.Fullscreen : (int) WindowMode.Windowed; set => _checkBox.Pressed = (value == (int) WindowMode.Fullscreen); } public OptionFullscreen( OptionsTabControlRow controller, IConfigurationManager cfg, CheckBox checkBox) : base(controller, cfg, CVars.DisplayWindowMode) { _checkBox = checkBox; _checkBox.OnToggled += _ => { ValueChanged(); }; } } private sealed class OptionIntegerScaling : BaseOptionCVar { private readonly CheckBox _checkBox; protected override int Value { get => _checkBox.Pressed ? CCVars.ViewportSnapToleranceMargin.DefaultValue : 0; set => _checkBox.Pressed = (value != 0); } public OptionIntegerScaling( OptionsTabControlRow controller, IConfigurationManager cfg, CheckBox checkBox) : base(controller, cfg, CCVars.ViewportSnapToleranceMargin) { _checkBox = checkBox; _checkBox.OnToggled += _ => { ValueChanged(); }; } } }