#region Copyright & License Information /* * Copyright 2007-2015 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, * see COPYING. */ #endregion using System; using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic { public class SettingsLogic : ChromeLogic { enum PanelType { Display, Audio, Input, Advanced } Dictionary leavePanelActions = new Dictionary(); Dictionary resetPanelActions = new Dictionary(); PanelType settingsPanel = PanelType.Display; Widget panelContainer, tabContainer; WorldRenderer worldRenderer; SoundDevice soundDevice; static readonly string OriginalSoundDevice; static readonly string OriginalSoundEngine; static readonly WindowMode OriginalGraphicsMode; static readonly string OriginalGraphicsRenderer; static readonly int2 OriginalGraphicsWindowedSize; static readonly int2 OriginalGraphicsFullscreenSize; static SettingsLogic() { var original = Game.Settings; OriginalSoundDevice = original.Sound.Device; OriginalSoundEngine = original.Sound.Engine; OriginalGraphicsMode = original.Graphics.Mode; OriginalGraphicsRenderer = original.Graphics.Renderer; OriginalGraphicsWindowedSize = original.Graphics.WindowedSize; OriginalGraphicsFullscreenSize = original.Graphics.FullscreenSize; } [ObjectCreator.UseCtor] public SettingsLogic(Widget widget, Action onExit, WorldRenderer worldRenderer) { this.worldRenderer = worldRenderer; panelContainer = widget.Get("SETTINGS_PANEL"); tabContainer = widget.Get("TAB_CONTAINER"); RegisterSettingsPanel(PanelType.Display, InitDisplayPanel, ResetDisplayPanel, "DISPLAY_PANEL", "DISPLAY_TAB"); RegisterSettingsPanel(PanelType.Audio, InitAudioPanel, ResetAudioPanel, "AUDIO_PANEL", "AUDIO_TAB"); RegisterSettingsPanel(PanelType.Input, InitInputPanel, ResetInputPanel, "INPUT_PANEL", "INPUT_TAB"); RegisterSettingsPanel(PanelType.Advanced, InitAdvancedPanel, ResetAdvancedPanel, "ADVANCED_PANEL", "ADVANCED_TAB"); panelContainer.Get("BACK_BUTTON").OnClick = () => { leavePanelActions[settingsPanel](); var current = Game.Settings; current.Save(); Action closeAndExit = () => { Ui.CloseWindow(); onExit(); }; if (OriginalSoundDevice != current.Sound.Device || OriginalSoundEngine != current.Sound.Engine || OriginalGraphicsMode != current.Graphics.Mode || OriginalGraphicsRenderer != current.Graphics.Renderer || OriginalGraphicsWindowedSize != current.Graphics.WindowedSize || OriginalGraphicsFullscreenSize != current.Graphics.FullscreenSize) ConfirmationDialogs.PromptConfirmAction( title: "Restart Now?", text: "Some changes will not be applied until\nthe game is restarted. Restart now?", onConfirm: Game.Restart, onCancel: closeAndExit, confirmText: "Restart Now", cancelText: "Restart Later"); else closeAndExit(); }; panelContainer.Get("RESET_BUTTON").OnClick = () => { resetPanelActions[settingsPanel](); Game.Settings.Save(); }; } static void BindCheckboxPref(Widget parent, string id, object group, string pref) { var field = group.GetType().GetField(pref); if (field == null) throw new InvalidOperationException("{0} does not contain a preference type {1}".F(group.GetType().Name, pref)); var cb = parent.Get(id); cb.IsChecked = () => (bool)field.GetValue(group); cb.OnClick = () => field.SetValue(group, cb.IsChecked() ^ true); } static void BindSliderPref(Widget parent, string id, object group, string pref) { var field = group.GetType().GetField(pref); if (field == null) throw new InvalidOperationException("{0} does not contain a preference type {1}".F(group.GetType().Name, pref)); var ss = parent.Get(id); ss.Value = (float)field.GetValue(group); ss.OnChange += x => field.SetValue(group, x); } static void BindHotkeyPref(KeyValuePair kv, KeySettings ks, Widget template, Widget parent) { var key = template.Clone() as Widget; key.Id = kv.Key; key.IsVisible = () => true; var field = ks.GetType().GetField(kv.Key); if (field == null) throw new InvalidOperationException("Game.Settings.Keys does not contain {1}".F(kv.Key)); key.Get("FUNCTION").GetText = () => kv.Value + ":"; var textBox = key.Get("HOTKEY"); textBox.Key = (Hotkey)field.GetValue(ks); textBox.OnLoseFocus = () => field.SetValue(ks, textBox.Key); parent.AddChild(key); } void RegisterSettingsPanel(PanelType type, Func init, Func reset, string panelID, string buttonID) { var panel = panelContainer.Get(panelID); var tab = tabContainer.Get(buttonID); panel.IsVisible = () => settingsPanel == type; tab.IsHighlighted = () => settingsPanel == type; tab.OnClick = () => { leavePanelActions[settingsPanel](); Game.Settings.Save(); settingsPanel = type; }; leavePanelActions.Add(type, init(panel)); resetPanelActions.Add(type, reset(panel)); } Action InitDisplayPanel(Widget panel) { var ds = Game.Settings.Graphics; var gs = Game.Settings.Game; BindCheckboxPref(panel, "HARDWARECURSORS_CHECKBOX", ds, "HardwareCursors"); BindCheckboxPref(panel, "PIXELDOUBLE_CHECKBOX", ds, "PixelDouble"); BindCheckboxPref(panel, "CURSORDOUBLE_CHECKBOX", ds, "CursorDouble"); BindCheckboxPref(panel, "FRAME_LIMIT_CHECKBOX", ds, "CapFramerate"); BindCheckboxPref(panel, "SHOW_SHELLMAP", gs, "ShowShellmap"); BindCheckboxPref(panel, "DISPLAY_TARGET_LINES_CHECKBOX", gs, "DrawTargetLine"); BindCheckboxPref(panel, "TEAM_HEALTH_COLORS_CHECKBOX", gs, "TeamHealthColors"); var languageDropDownButton = panel.Get("LANGUAGE_DROPDOWNBUTTON"); languageDropDownButton.OnMouseDown = _ => ShowLanguageDropdown(languageDropDownButton); languageDropDownButton.GetText = () => FieldLoader.Translate(ds.Language); var windowModeDropdown = panel.Get("MODE_DROPDOWN"); windowModeDropdown.OnMouseDown = _ => ShowWindowModeDropdown(windowModeDropdown, ds); windowModeDropdown.GetText = () => ds.Mode == WindowMode.Windowed ? "Windowed" : ds.Mode == WindowMode.Fullscreen ? "Fullscreen" : "Pseudo-Fullscreen"; var statusBarsDropDown = panel.Get("STATUS_BAR_DROPDOWN"); statusBarsDropDown.OnMouseDown = _ => ShowStatusBarsDropdown(statusBarsDropDown, gs); statusBarsDropDown.GetText = () => gs.StatusBars.ToString() == "Standard" ? "Standard" : gs.StatusBars.ToString() == "DamageShow" ? "Show On Damage" : "Always Show"; // Update zoom immediately var pixelDoubleCheckbox = panel.Get("PIXELDOUBLE_CHECKBOX"); var pixelDoubleOnClick = pixelDoubleCheckbox.OnClick; pixelDoubleCheckbox.OnClick = () => { pixelDoubleOnClick(); worldRenderer.Viewport.Zoom = ds.PixelDouble ? 2 : 1; }; // Cursor doubling is only supported with software cursors and when pixel doubling is enabled var cursorDoubleCheckbox = panel.Get("CURSORDOUBLE_CHECKBOX"); cursorDoubleCheckbox.IsDisabled = () => !ds.PixelDouble || Game.Cursor is HardwareCursor; var cursorDoubleIsChecked = cursorDoubleCheckbox.IsChecked; cursorDoubleCheckbox.IsChecked = () => !cursorDoubleCheckbox.IsDisabled() && cursorDoubleIsChecked(); panel.Get("WINDOW_RESOLUTION").IsVisible = () => ds.Mode == WindowMode.Windowed; var windowWidth = panel.Get("WINDOW_WIDTH"); windowWidth.Text = ds.WindowedSize.X.ToString(); var windowHeight = panel.Get("WINDOW_HEIGHT"); windowHeight.Text = ds.WindowedSize.Y.ToString(); var frameLimitTextfield = panel.Get("FRAME_LIMIT_TEXTFIELD"); frameLimitTextfield.Text = ds.MaxFramerate.ToString(); var escPressed = false; frameLimitTextfield.OnLoseFocus = () => { if (escPressed) { escPressed = false; return; } int fps; Exts.TryParseIntegerInvariant(frameLimitTextfield.Text, out fps); ds.MaxFramerate = fps.Clamp(1, 1000); frameLimitTextfield.Text = ds.MaxFramerate.ToString(); }; frameLimitTextfield.OnEnterKey = () => { frameLimitTextfield.YieldKeyboardFocus(); return true; }; frameLimitTextfield.OnEscKey = () => { frameLimitTextfield.Text = ds.MaxFramerate.ToString(); escPressed = true; frameLimitTextfield.YieldKeyboardFocus(); return true; }; frameLimitTextfield.IsDisabled = () => !ds.CapFramerate; // Player profile var ps = Game.Settings.Player; var nameTextfield = panel.Get("PLAYERNAME"); nameTextfield.IsDisabled = () => worldRenderer.World.Type != WorldType.Shellmap; nameTextfield.Text = Settings.SanitizedPlayerName(ps.Name); nameTextfield.OnLoseFocus = () => { if (escPressed) { escPressed = false; return; } nameTextfield.Text = nameTextfield.Text.Trim(); if (nameTextfield.Text.Length == 0) nameTextfield.Text = Settings.SanitizedPlayerName(ps.Name); else { nameTextfield.Text = Settings.SanitizedPlayerName(nameTextfield.Text); ps.Name = nameTextfield.Text; } }; nameTextfield.OnEnterKey = () => { nameTextfield.YieldKeyboardFocus(); return true; }; nameTextfield.OnEscKey = () => { nameTextfield.Text = Settings.SanitizedPlayerName(ps.Name); escPressed = true; nameTextfield.YieldKeyboardFocus(); return true; }; var colorPreview = panel.Get("COLOR_MANAGER"); colorPreview.Color = ps.Color; var colorDropdown = panel.Get("PLAYERCOLOR"); colorDropdown.IsDisabled = () => worldRenderer.World.Type != WorldType.Shellmap; colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, worldRenderer.World); colorDropdown.Get("COLORBLOCK").GetColor = () => ps.Color.RGB; return () => { int x, y; Exts.TryParseIntegerInvariant(windowWidth.Text, out x); Exts.TryParseIntegerInvariant(windowHeight.Text, out y); ds.WindowedSize = new int2(x, y); frameLimitTextfield.YieldKeyboardFocus(); nameTextfield.YieldKeyboardFocus(); }; } Action ResetDisplayPanel(Widget panel) { var ds = Game.Settings.Graphics; var gs = Game.Settings.Game; var ps = Game.Settings.Player; var dds = new GraphicSettings(); var dgs = new GameSettings(); var dps = new PlayerSettings(); return () => { gs.ShowShellmap = dgs.ShowShellmap; ds.CapFramerate = dds.CapFramerate; ds.MaxFramerate = dds.MaxFramerate; ds.Language = dds.Language; ds.Mode = dds.Mode; ds.WindowedSize = dds.WindowedSize; ds.PixelDouble = dds.PixelDouble; ds.CursorDouble = dds.CursorDouble; worldRenderer.Viewport.Zoom = ds.PixelDouble ? 2 : 1; ps.Color = dps.Color; ps.Name = dps.Name; }; } Action InitAudioPanel(Widget panel) { var ss = Game.Settings.Sound; BindCheckboxPref(panel, "CASH_TICKS", ss, "CashTicks"); BindCheckboxPref(panel, "MUTE_SOUND", ss, "Mute"); BindSliderPref(panel, "SOUND_VOLUME", ss, "SoundVolume"); BindSliderPref(panel, "MUSIC_VOLUME", ss, "MusicVolume"); BindSliderPref(panel, "VIDEO_VOLUME", ss, "VideoVolume"); var muteCheckbox = panel.Get("MUTE_SOUND"); var muteCheckboxOnClick = muteCheckbox.OnClick; muteCheckbox.OnClick = () => { muteCheckboxOnClick(); if (ss.Mute) Game.Sound.MuteAudio(); else Game.Sound.UnmuteAudio(); }; if (!ss.Mute) { panel.Get("SOUND_VOLUME").OnChange += x => Game.Sound.SoundVolume = x; panel.Get("MUSIC_VOLUME").OnChange += x => Game.Sound.MusicVolume = x; panel.Get("VIDEO_VOLUME").OnChange += x => Game.Sound.VideoVolume = x; } var devices = Game.Sound.AvailableDevices(); soundDevice = devices.FirstOrDefault(d => d.Engine == ss.Engine && d.Device == ss.Device) ?? devices.First(); var audioDeviceDropdown = panel.Get("AUDIO_DEVICE"); audioDeviceDropdown.OnMouseDown = _ => ShowAudioDeviceDropdown(audioDeviceDropdown, devices); audioDeviceDropdown.GetText = () => soundDevice.Label; return () => { ss.Device = soundDevice.Device; ss.Engine = soundDevice.Engine; }; } Action ResetAudioPanel(Widget panel) { var ss = Game.Settings.Sound; var dss = new SoundSettings(); return () => { ss.SoundVolume = dss.SoundVolume; ss.MusicVolume = dss.MusicVolume; ss.VideoVolume = dss.VideoVolume; ss.CashTicks = dss.CashTicks; ss.Mute = dss.Mute; ss.Device = dss.Device; ss.Engine = dss.Engine; panel.Get("SOUND_VOLUME").Value = ss.SoundVolume; Game.Sound.SoundVolume = ss.SoundVolume; panel.Get("MUSIC_VOLUME").Value = ss.MusicVolume; Game.Sound.MusicVolume = ss.MusicVolume; panel.Get("VIDEO_VOLUME").Value = ss.VideoVolume; Game.Sound.VideoVolume = ss.VideoVolume; Game.Sound.UnmuteAudio(); soundDevice = Game.Sound.AvailableDevices().First(); }; } Action InitInputPanel(Widget panel) { var gs = Game.Settings.Game; var ks = Game.Settings.Keys; BindCheckboxPref(panel, "CLASSICORDERS_CHECKBOX", gs, "UseClassicMouseStyle"); BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll"); BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow"); BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep"); BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed"); // Apply mouse focus preferences immediately var lockMouseCheckbox = panel.Get("LOCKMOUSE_CHECKBOX"); var oldOnClick = lockMouseCheckbox.OnClick; lockMouseCheckbox.OnClick = () => { // Still perform the old behaviour for clicking the checkbox, before // applying the changes live. oldOnClick(); MakeMouseFocusSettingsLive(); }; var mouseScrollDropdown = panel.Get("MOUSE_SCROLL"); mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gs); mouseScrollDropdown.GetText = () => gs.MouseScroll.ToString(); var hotkeyList = panel.Get("HOTKEY_LIST"); hotkeyList.Layout = new GridLayout(hotkeyList); var hotkeyHeader = hotkeyList.Get("HEADER"); var globalTemplate = hotkeyList.Get("GLOBAL_TEMPLATE"); var unitTemplate = hotkeyList.Get("UNIT_TEMPLATE"); var productionTemplate = hotkeyList.Get("PRODUCTION_TEMPLATE"); var developerTemplate = hotkeyList.Get("DEVELOPER_TEMPLATE"); hotkeyList.RemoveChildren(); Func returnTrue = () => true; Action doNothing = () => { }; // Game { var hotkeys = new Dictionary() { { "CycleBaseKey", "Jump to base" }, { "ToLastEventKey", "Jump to last radar event" }, { "ToSelectionKey", "Jump to selection" }, { "SelectAllUnitsKey", "Select all combat units" }, { "SelectUnitsByTypeKey", "Select units by type" }, { "PlaceBeaconKey", "Place beacon" }, { "PauseKey", "Pause / Unpause" }, { "SellKey", "Sell mode" }, { "PowerDownKey", "Power-down mode" }, { "RepairKey", "Repair mode" }, { "NextProductionTabKey", "Next production tab" }, { "PreviousProductionTabKey", "Previous production tab" }, { "CycleProductionBuildingsKey", "Cycle production facilities" }, { "CycleStatusBarsKey", "Cycle status bars display" }, { "TogglePixelDoubleKey", "Toggle pixel doubling" }, { "ToggleMuteKey", "Toggle audio mute" }, { "MapScrollUp", "Map scroll up" }, { "MapScrollDown", "Map scroll down" }, { "MapScrollLeft", "Map scroll left" }, { "MapScrollRight", "Map scroll right" } }; var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); header.Get("LABEL").GetText = () => "Game Commands"; hotkeyList.AddChild(header); foreach (var kv in hotkeys) BindHotkeyPref(kv, ks, globalTemplate, hotkeyList); } // Observer { var hotkeys = new Dictionary() { { "ObserverCombinedView", "All Players" }, { "ObserverWorldView", "Disable Shroud" } }; var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); header.Get("LABEL").GetText = () => "Observer Commands"; hotkeyList.AddChild(header); foreach (var kv in hotkeys) BindHotkeyPref(kv, ks, globalTemplate, hotkeyList); } // Unit { var hotkeys = new Dictionary() { { "AttackMoveKey", "Attack Move" }, { "StopKey", "Stop" }, { "ScatterKey", "Scatter" }, { "StanceCycleKey", "Cycle Stance" }, { "DeployKey", "Deploy" }, { "GuardKey", "Guard" } }; var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); header.Get("LABEL").GetText = () => "Unit Commands"; hotkeyList.AddChild(header); foreach (var kv in hotkeys) BindHotkeyPref(kv, ks, unitTemplate, hotkeyList); } // Production { var hotkeys = new Dictionary() { { "ProductionTypeBuildingKey", "Building Tab" }, { "ProductionTypeDefenseKey", "Defense Tab" }, { "ProductionTypeInfantryKey", "Infantry Tab" }, { "ProductionTypeVehicleKey", "Vehicle Tab" }, { "ProductionTypeAircraftKey", "Aircraft Tab" }, { "ProductionTypeNavalKey", "Naval Tab" }, { "ProductionTypeTankKey", "Tank Tab" }, { "ProductionTypeMerchantKey", "Starport Tab" }, { "ProductionTypeUpgradeKey", "Upgrade Tab" } }; for (var i = 1; i <= 24; i++) hotkeys.Add("Production{0:D2}Key".F(i), "Slot {0}".F(i)); var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); header.Get("LABEL").GetText = () => "Production Commands"; hotkeyList.AddChild(header); foreach (var kv in hotkeys) BindHotkeyPref(kv, ks, productionTemplate, hotkeyList); } // Support powers { var hotkeys = new Dictionary(); for (var i = 1; i <= 6; i++) hotkeys.Add("SupportPower{0:D2}Key".F(i), "Slot {0}".F(i)); var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); header.Get("LABEL").GetText = () => "Support Power Commands"; hotkeyList.AddChild(header); foreach (var kv in hotkeys) BindHotkeyPref(kv, ks, productionTemplate, hotkeyList); } // Developer { var hotkeys = new Dictionary() { { "DevReloadChromeKey", "Reload Chrome" }, { "HideUserInterfaceKey", "Hide UI" }, { "TakeScreenshotKey", "Take screenshot" } }; var header = ScrollItemWidget.Setup(hotkeyHeader, returnTrue, doNothing); header.Get("LABEL").GetText = () => "Developer commands"; hotkeyList.AddChild(header); foreach (var kv in hotkeys) BindHotkeyPref(kv, ks, developerTemplate, hotkeyList); } return () => { }; } Action ResetInputPanel(Widget panel) { var gs = Game.Settings.Game; var ks = Game.Settings.Keys; var dgs = new GameSettings(); var dks = new KeySettings(); return () => { gs.UseClassicMouseStyle = dgs.UseClassicMouseStyle; gs.MouseScroll = dgs.MouseScroll; gs.LockMouseWindow = dgs.LockMouseWindow; gs.ViewportEdgeScroll = dgs.ViewportEdgeScroll; gs.ViewportEdgeScrollStep = dgs.ViewportEdgeScrollStep; gs.UIScrollSpeed = dgs.UIScrollSpeed; foreach (var f in ks.GetType().GetFields()) { var value = (Hotkey)f.GetValue(dks); f.SetValue(ks, value); panel.Get(f.Name).Get("HOTKEY").Key = value; } panel.Get("SCROLLSPEED_SLIDER").Value = gs.ViewportEdgeScrollStep; panel.Get("UI_SCROLLSPEED_SLIDER").Value = gs.UIScrollSpeed; MakeMouseFocusSettingsLive(); }; } Action InitAdvancedPanel(Widget panel) { var ds = Game.Settings.Debug; var ss = Game.Settings.Server; var gs = Game.Settings.Game; BindCheckboxPref(panel, "NAT_DISCOVERY", ss, "DiscoverNatDevices"); BindCheckboxPref(panel, "VERBOSE_NAT_CHECKBOX", ss, "VerboseNatDiscovery"); BindCheckboxPref(panel, "PERFTEXT_CHECKBOX", ds, "PerfText"); BindCheckboxPref(panel, "PERFGRAPH_CHECKBOX", ds, "PerfGraph"); BindCheckboxPref(panel, "CHECKUNSYNCED_CHECKBOX", ds, "SanityCheckUnsyncedCode"); BindCheckboxPref(panel, "BOTDEBUG_CHECKBOX", ds, "BotDebug"); BindCheckboxPref(panel, "FETCH_NEWS_CHECKBOX", gs, "FetchNews"); BindCheckboxPref(panel, "LUADEBUG_CHECKBOX", ds, "LuaDebug"); return () => { }; } Action ResetAdvancedPanel(Widget panel) { var ds = Game.Settings.Debug; var ss = Game.Settings.Server; var dds = new DebugSettings(); var dss = new ServerSettings(); return () => { ss.DiscoverNatDevices = dss.DiscoverNatDevices; ss.VerboseNatDiscovery = dss.VerboseNatDiscovery; ds.PerfText = dds.PerfText; ds.PerfGraph = dds.PerfGraph; ds.SanityCheckUnsyncedCode = dds.SanityCheckUnsyncedCode; ds.BotDebug = dds.BotDebug; ds.LuaDebug = dds.LuaDebug; }; } static bool ShowMouseScrollDropdown(DropDownButtonWidget dropdown, GameSettings s) { var options = new Dictionary() { { "Disabled", MouseScrollType.Disabled }, { "Standard", MouseScrollType.Standard }, { "Inverted", MouseScrollType.Inverted }, { "Joystick", MouseScrollType.Joystick }, }; Func setupItem = (o, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => s.MouseScroll == options[o], () => s.MouseScroll = options[o]); item.Get("LABEL").GetText = () => o; return item; }; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); return true; } bool ShowAudioDeviceDropdown(DropDownButtonWidget dropdown, SoundDevice[] devices) { var i = 0; var options = devices.ToDictionary(d => (i++).ToString(), d => d); Func setupItem = (o, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => soundDevice == options[o], () => soundDevice = options[o]); item.Get("LABEL").GetText = () => options[o].Label; return item; }; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); return true; } static bool ShowWindowModeDropdown(DropDownButtonWidget dropdown, GraphicSettings s) { var options = new Dictionary() { { "Pseudo-Fullscreen", WindowMode.PseudoFullscreen }, { "Fullscreen", WindowMode.Fullscreen }, { "Windowed", WindowMode.Windowed }, }; Func setupItem = (o, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => s.Mode == options[o], () => s.Mode = options[o]); item.Get("LABEL").GetText = () => o; return item; }; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); return true; } static bool ShowLanguageDropdown(DropDownButtonWidget dropdown) { Func setupItem = (o, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => Game.Settings.Graphics.Language == o, () => Game.Settings.Graphics.Language = o); item.Get("LABEL").GetText = () => FieldLoader.Translate(o); return item; }; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, Game.ModData.Languages, setupItem); return true; } static bool ShowStatusBarsDropdown(DropDownButtonWidget dropdown, GameSettings s) { var options = new Dictionary() { { "Standard", StatusBarsType.Standard }, { "Show On Damage", StatusBarsType.DamageShow }, { "Always Show", StatusBarsType.AlwaysShow }, }; Func setupItem = (o, itemTemplate) => { var item = ScrollItemWidget.Setup(itemTemplate, () => s.StatusBars == options[o], () => s.StatusBars = options[o]); item.Get("LABEL").GetText = () => o; return item; }; dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); return true; } void MakeMouseFocusSettingsLive() { var gameSettings = Game.Settings.Game; if (gameSettings.LockMouseWindow) Game.Renderer.GrabWindowMouseFocus(); else Game.Renderer.ReleaseWindowMouseFocus(); } } }