diff --git a/OpenRA.Game/Graphics/Renderer.cs b/OpenRA.Game/Graphics/Renderer.cs index 2d510ff999..f75316a2d9 100644 --- a/OpenRA.Game/Graphics/Renderer.cs +++ b/OpenRA.Game/Graphics/Renderer.cs @@ -39,12 +39,14 @@ namespace OpenRA.Graphics Queue> tempBuffers = new Queue>(); public Dictionary Fonts; + Stack scissorState; public Renderer() { TempBufferSize = Game.Settings.Graphics.BatchSize; TempBufferCount = Game.Settings.Graphics.NumTempBuffers; SheetSize = Game.Settings.Graphics.SheetSize; + scissorState = new Stack(); WorldSpriteRenderer = new SpriteRenderer(this, device.CreateShader("shp")); WorldRgbaSpriteRenderer = new SpriteRenderer(this, device.CreateShader("rgba")); @@ -183,16 +185,30 @@ namespace OpenRA.Graphics } } - public void EnableScissor(int left, int top, int width, int height) + public void EnableScissor(Rectangle rect) { + // Must remain inside the current scissor rect + if (scissorState.Any()) + rect.Intersect(scissorState.Peek()); + Flush(); - Device.EnableScissor(left, top, width, height); + Device.EnableScissor(rect.Left, rect.Top, rect.Width, rect.Height); + scissorState.Push(rect); } public void DisableScissor() { + scissorState.Pop(); Flush(); - Device.DisableScissor(); + + // Restore previous scissor rect + if (scissorState.Any()) + { + var rect = scissorState.Peek(); + Device.EnableScissor(rect.Left, rect.Top, rect.Width, rect.Height); + } + else + Device.DisableScissor(); } public void EnableDepthBuffer() diff --git a/OpenRA.Game/Graphics/WorldRenderer.cs b/OpenRA.Game/Graphics/WorldRenderer.cs index 281d1c0198..3712197359 100644 --- a/OpenRA.Game/Graphics/WorldRenderer.cs +++ b/OpenRA.Game/Graphics/WorldRenderer.cs @@ -115,7 +115,7 @@ namespace OpenRA.Graphics var renderables = GenerateRenderables(); var bounds = Viewport.ScissorBounds; - Game.Renderer.EnableScissor(bounds.Left, bounds.Top, bounds.Width, bounds.Height); + Game.Renderer.EnableScissor(bounds); terrainRenderer.Draw(this, Viewport); Game.Renderer.Flush(); diff --git a/OpenRA.Game/Widgets/ChatDisplayWidget.cs b/OpenRA.Game/Widgets/ChatDisplayWidget.cs index 163b6dc6a2..04e140ea73 100644 --- a/OpenRA.Game/Widgets/ChatDisplayWidget.cs +++ b/OpenRA.Game/Widgets/ChatDisplayWidget.cs @@ -38,7 +38,7 @@ namespace OpenRA.Widgets var chatpos = new int2(chatLogArea.X + 5, chatLogArea.Bottom - 5); var font = Game.Renderer.Fonts["Regular"]; - Game.Renderer.EnableScissor(chatLogArea.Left, chatLogArea.Top, chatLogArea.Width, chatLogArea.Height); + Game.Renderer.EnableScissor(chatLogArea); foreach (var line in recentLines.AsEnumerable().Reverse()) { diff --git a/OpenRA.Game/Widgets/HotkeyEntryWidget.cs b/OpenRA.Game/Widgets/HotkeyEntryWidget.cs index 714b3b1da1..3c5ffdf51d 100644 --- a/OpenRA.Game/Widgets/HotkeyEntryWidget.cs +++ b/OpenRA.Game/Widgets/HotkeyEntryWidget.cs @@ -59,6 +59,8 @@ namespace OpenRA.Widgets if (!RenderBounds.Contains(mi.Location) || !TakeKeyboardFocus()) return false; + blinkCycle = 15; + return true; } @@ -83,6 +85,18 @@ namespace OpenRA.Widgets return true; } + protected int blinkCycle = 15; + protected bool showEntry = true; + + public override void Tick() + { + if (HasKeyboardFocus && --blinkCycle <= 0) + { + blinkCycle = 15; + showEntry ^= true; + } + } + public override void Draw() { var apparentText = Key.DisplayString(); @@ -100,14 +114,18 @@ namespace OpenRA.Widgets WidgetUtils.DrawPanel(state, RenderBounds); + // Blink the current entry to indicate focus + if (HasKeyboardFocus && !showEntry) + return; + // Inset text by the margin and center vertically var textPos = pos + new int2(LeftMargin, (Bounds.Height - textSize.Y) / 2 - VisualHeight); // Scissor when the text overflows if (textSize.X > Bounds.Width - LeftMargin - RightMargin) { - Game.Renderer.EnableScissor(pos.X + LeftMargin, pos.Y, - Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom); + Game.Renderer.EnableScissor(new Rectangle(pos.X + LeftMargin, pos.Y, + Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom)); } var color = disabled ? DisabledColor : TextColor; diff --git a/OpenRA.Game/Widgets/ScrollPanelWidget.cs b/OpenRA.Game/Widgets/ScrollPanelWidget.cs index 909ba00690..878402c79a 100644 --- a/OpenRA.Game/Widgets/ScrollPanelWidget.cs +++ b/OpenRA.Game/Widgets/ScrollPanelWidget.cs @@ -115,7 +115,7 @@ namespace OpenRA.Widgets WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", DownPressed || downDisabled ? "down_pressed" : "down_arrow"), new float2(downButtonRect.Left + downOffset, downButtonRect.Top + downOffset)); - Game.Renderer.EnableScissor(backgroundRect.X + 1, backgroundRect.Y + 1, backgroundRect.Width - 2, backgroundRect.Height - 2); + Game.Renderer.EnableScissor(backgroundRect.InflateBy(-1, -1, -1, -1)); foreach (var child in Children) child.DrawOuter(); diff --git a/OpenRA.Game/Widgets/SliderWidget.cs b/OpenRA.Game/Widgets/SliderWidget.cs index 563785b506..8b9a05680f 100755 --- a/OpenRA.Game/Widgets/SliderWidget.cs +++ b/OpenRA.Game/Widgets/SliderWidget.cs @@ -82,8 +82,8 @@ namespace OpenRA.Widgets return ThumbRect.Contains(mi.Location); } - float ValueFromPx(int x) { return MinimumValue + (MaximumValue - MinimumValue) * (1f * x / RenderBounds.Width); } - protected int PxFromValue(float x) { return (int)(RenderBounds.Width * (x - MinimumValue) / (MaximumValue - MinimumValue)); } + float ValueFromPx(int x) { return MinimumValue + (MaximumValue - MinimumValue) * (x - 0.5f * RenderBounds.Height) / (RenderBounds.Width - RenderBounds.Height); } + protected int PxFromValue(float x) { return (int)(0.5f * RenderBounds.Height + (RenderBounds.Width - RenderBounds.Height) * (x - MinimumValue) / (MaximumValue - MinimumValue)); } public override Widget Clone() { return new SliderWidget(this); } @@ -109,16 +109,19 @@ namespace OpenRA.Widgets var tr = ThumbRect; var rb = RenderBounds; - var trackWidth = rb.Width; - var trackOrigin = rb.X; + var trackWidth = rb.Width - rb.Height; + var trackOrigin = rb.X + rb.Height / 2; var trackRect = new Rectangle(trackOrigin - 1, rb.Y + (rb.Height - TrackHeight) / 2, trackWidth + 2, TrackHeight); - // Tickmarks (hacked until we have real art) + // Tickmarks + var tick = ChromeProvider.GetImage("slider", "tick"); for (int i = 0; i < Ticks; i++) { - var tickRect = new Rectangle(trackOrigin - 1 + (int)(i * trackWidth * 1f / (Ticks - 1)), - rb.Y + rb.Height / 2, 2, rb.Height / 2); - WidgetUtils.DrawPanel("slider-tick", tickRect); + var tickPos = new float2( + trackOrigin + (i * (trackRect.Width - (int)tick.size.X) / (Ticks - 1)) - tick.size.X / 2, + trackRect.Bottom); + + WidgetUtils.DrawRGBA(tick, tickPos); } // Track diff --git a/OpenRA.Game/Widgets/TextFieldWidget.cs b/OpenRA.Game/Widgets/TextFieldWidget.cs index 7afcbad503..b4e8bb5d5e 100644 --- a/OpenRA.Game/Widgets/TextFieldWidget.cs +++ b/OpenRA.Game/Widgets/TextFieldWidget.cs @@ -216,8 +216,8 @@ namespace OpenRA.Widgets if (HasKeyboardFocus) textPos += new int2(Bounds.Width - LeftMargin - RightMargin - textSize.X, 0); - Game.Renderer.EnableScissor(pos.X + LeftMargin, pos.Y, - Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom); + Game.Renderer.EnableScissor(new Rectangle(pos.X + LeftMargin, pos.Y, + Bounds.Width - LeftMargin - RightMargin, Bounds.Bottom)); } var color = disabled ? DisabledColor : TextColor; diff --git a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj index b49c2f8320..7899ed9238 100644 --- a/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj +++ b/OpenRA.Mods.Cnc/OpenRA.Mods.Cnc.csproj @@ -94,7 +94,6 @@ - diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs deleted file mode 100644 index 66dbf85ffe..0000000000 --- a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs +++ /dev/null @@ -1,232 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2013 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.FileFormats; -using OpenRA.FileFormats.Graphics; -using OpenRA.GameRules; -using OpenRA.Graphics; -using OpenRA.Mods.RA; -using OpenRA.Mods.RA.Widgets; -using OpenRA.Mods.RA.Widgets.Logic; -using OpenRA.Widgets; - -namespace OpenRA.Mods.Cnc.Widgets.Logic -{ - public class CncSettingsLogic - { - enum PanelType { General, Input } - - SoundDevice soundDevice; - PanelType settingsPanel = PanelType.General; - ColorPreviewManagerWidget colorPreview; - World world; - - [ObjectCreator.UseCtor] - public CncSettingsLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer) - { - this.world = world; - var panel = widget.Get("SETTINGS_PANEL"); - - // General pane - var generalButton = panel.Get("GENERAL_BUTTON"); - generalButton.OnClick = () => settingsPanel = PanelType.General; - generalButton.IsHighlighted = () => settingsPanel == PanelType.General; - - var generalPane = panel.Get("GENERAL_CONTROLS"); - generalPane.IsVisible = () => settingsPanel == PanelType.General; - - var gameSettings = Game.Settings.Game; - var playerSettings = Game.Settings.Player; - var debugSettings = Game.Settings.Debug; - var graphicsSettings = Game.Settings.Graphics; - var soundSettings = Game.Settings.Sound; - - // Player profile - var nameTextfield = generalPane.Get("NAME_TEXTFIELD"); - nameTextfield.Text = playerSettings.Name; - - colorPreview = panel.Get("COLOR_MANAGER"); - colorPreview.Color = playerSettings.Color; - - var colorDropdown = generalPane.Get("COLOR"); - colorDropdown.OnMouseDown = _ => ShowColorPicker(colorDropdown, playerSettings); - colorDropdown.Get("COLORBLOCK").GetColor = () => playerSettings.Color.RGB; - - // Debug - var perftextCheckbox = generalPane.Get("PERFTEXT_CHECKBOX"); - perftextCheckbox.IsChecked = () => debugSettings.PerfText; - perftextCheckbox.OnClick = () => debugSettings.PerfText ^= true; - - var perfgraphCheckbox = generalPane.Get("PERFGRAPH_CHECKBOX"); - perfgraphCheckbox.IsChecked = () => debugSettings.PerfGraph; - perfgraphCheckbox.OnClick = () => debugSettings.PerfGraph ^= true; - - var checkunsyncedCheckbox = generalPane.Get("CHECKUNSYNCED_CHECKBOX"); - checkunsyncedCheckbox.IsChecked = () => debugSettings.SanityCheckUnsyncedCode; - checkunsyncedCheckbox.OnClick = () => debugSettings.SanityCheckUnsyncedCode ^= true; - - var showFatalErrorDialog = generalPane.Get("SHOW_FATAL_ERROR_DIALOG_CHECKBOX"); - showFatalErrorDialog.IsChecked = () => Game.Settings.Debug.ShowFatalErrorDialog; - showFatalErrorDialog.OnClick = () => Game.Settings.Debug.ShowFatalErrorDialog ^= true; - - // Video - var windowModeDropdown = generalPane.Get("MODE_DROPDOWN"); - windowModeDropdown.OnMouseDown = _ => SettingsMenuLogic.ShowWindowModeDropdown(windowModeDropdown, graphicsSettings); - windowModeDropdown.GetText = () => graphicsSettings.Mode == WindowMode.Windowed ? - "Windowed" : graphicsSettings.Mode == WindowMode.Fullscreen ? "Fullscreen" : "Pseudo-Fullscreen"; - - var pixelDoubleCheckbox = generalPane.Get("PIXELDOUBLE_CHECKBOX"); - pixelDoubleCheckbox.IsChecked = () => graphicsSettings.PixelDouble; - pixelDoubleCheckbox.OnClick = () => - { - graphicsSettings.PixelDouble ^= true; - worldRenderer.Viewport.Zoom = graphicsSettings.PixelDouble ? 2 : 1; - }; - - var showShellmapCheckbox = generalPane.Get("SHOW_SHELLMAP"); - showShellmapCheckbox.IsChecked = () => gameSettings.ShowShellmap; - showShellmapCheckbox.OnClick = () => gameSettings.ShowShellmap ^= true; - - generalPane.Get("WINDOW_RESOLUTION").IsVisible = () => graphicsSettings.Mode == WindowMode.Windowed; - var windowWidth = generalPane.Get("WINDOW_WIDTH"); - windowWidth.Text = graphicsSettings.WindowedSize.X.ToString(); - - var windowHeight = generalPane.Get("WINDOW_HEIGHT"); - windowHeight.Text = graphicsSettings.WindowedSize.Y.ToString(); - - var languageDropDownButton = generalPane.Get("LANGUAGE_DROPDOWNBUTTON"); - languageDropDownButton.OnMouseDown = _ => SettingsMenuLogic.ShowLanguageDropdown(languageDropDownButton); - languageDropDownButton.GetText = () => FieldLoader.Translate(Game.Settings.Graphics.Language); - - // Audio - var soundSlider = generalPane.Get("SOUND_SLIDER"); - soundSlider.OnChange += x => { soundSettings.SoundVolume = x; Sound.SoundVolume = x; }; - soundSlider.Value = soundSettings.SoundVolume; - - var musicSlider = generalPane.Get("MUSIC_SLIDER"); - musicSlider.OnChange += x => { soundSettings.MusicVolume = x; Sound.MusicVolume = x; }; - musicSlider.Value = soundSettings.MusicVolume; - - var shellmapMusicCheckbox = generalPane.Get("SHELLMAP_MUSIC"); - shellmapMusicCheckbox.IsChecked = () => soundSettings.MapMusic; - shellmapMusicCheckbox.OnClick = () => soundSettings.MapMusic ^= true; - - var devices = Sound.AvailableDevices(); - soundDevice = devices.FirstOrDefault(d => d.Engine == soundSettings.Engine && d.Device == soundSettings.Device) ?? devices.First(); - - var audioDeviceDropdown = generalPane.Get("AUDIO_DEVICE"); - audioDeviceDropdown.OnMouseDown = _ => ShowAudioDeviceDropdown(audioDeviceDropdown, soundSettings, devices); - audioDeviceDropdown.GetText = () => soundDevice.Label; - - // Input pane - var inputPane = panel.Get("INPUT_CONTROLS"); - inputPane.IsVisible = () => settingsPanel == PanelType.Input; - - var inputButton = panel.Get("INPUT_BUTTON"); - inputButton.OnClick = () => settingsPanel = PanelType.Input; - inputButton.IsHighlighted = () => settingsPanel == PanelType.Input; - - var classicMouseCheckbox = inputPane.Get("CLASSICORDERS_CHECKBOX"); - classicMouseCheckbox.IsChecked = () => gameSettings.UseClassicMouseStyle; - classicMouseCheckbox.OnClick = () => gameSettings.UseClassicMouseStyle ^= true; - - var scrollSlider = inputPane.Get("SCROLLSPEED_SLIDER"); - scrollSlider.Value = gameSettings.ViewportEdgeScrollStep; - scrollSlider.OnChange += x => gameSettings.ViewportEdgeScrollStep = x; - - var edgescrollCheckbox = inputPane.Get("EDGESCROLL_CHECKBOX"); - edgescrollCheckbox.IsChecked = () => gameSettings.ViewportEdgeScroll; - edgescrollCheckbox.OnClick = () => gameSettings.ViewportEdgeScroll ^= true; - - var mouseScrollDropdown = inputPane.Get("MOUSE_SCROLL"); - mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gameSettings); - mouseScrollDropdown.GetText = () => gameSettings.MouseScroll.ToString(); - - panel.Get("BACK_BUTTON").OnClick = () => - { - playerSettings.Name = nameTextfield.Text; - int x, y; - int.TryParse(windowWidth.Text, out x); - int.TryParse(windowHeight.Text, out y); - graphicsSettings.WindowedSize = new int2(x, y); - soundSettings.Device = soundDevice.Device; - soundSettings.Engine = soundDevice.Engine; - Game.Settings.Save(); - Ui.CloseWindow(); - onExit(); - }; - } - - static bool ShowMouseScrollDropdown(DropDownButtonWidget dropdown, GameSettings s) - { - var options = new Dictionary() - { - { "Disabled", MouseScrollType.Disabled }, - { "Standard", MouseScrollType.Standard }, - { "Inverted", MouseScrollType.Inverted }, - }; - - 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 ShowColorPicker(DropDownButtonWidget color, PlayerSettings s) - { - Action onChange = c => colorPreview.Color = c; - Action onExit = () => - { - s.Color = colorPreview.Color; - color.RemovePanel(); - }; - - var colorChooser = Game.LoadWidget(world, "COLOR_CHOOSER", null, new WidgetArgs() - { - { "onExit", onExit }, - { "onChange", onChange }, - { "initialColor", s.Color } - }); - - color.AttachPanel(colorChooser, onExit); - return true; - } - - bool ShowAudioDeviceDropdown(DropDownButtonWidget dropdown, SoundSettings s, 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; - } - } -} diff --git a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs index 336b9fa97e..cf05ad0bf6 100755 --- a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs @@ -157,7 +157,7 @@ namespace OpenRA.Mods.Cnc.Widgets new float2(rightButtonRect.Left + 2, rightButtonRect.Top + 2)); // Draw tab buttons - Game.Renderer.EnableScissor(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height); + Game.Renderer.EnableScissor(new Rectangle(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height)); var origin = new int2(leftButtonRect.Right - 1 + (int)listOffset, leftButtonRect.Y); SpriteFont font = Game.Renderer.Fonts["TinyBold"]; contentWidth = 0; diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 5e6203c3b0..5e8643fe0c 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -403,7 +403,6 @@ - @@ -472,6 +471,7 @@ + diff --git a/OpenRA.Mods.RA/Widgets/Logic/IngameMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/IngameMenuLogic.cs index aebc308fe8..d2e44b17fe 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/IngameMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/IngameMenuLogic.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic widget.Get("SETTINGS").OnClick = () => { widget.Visible = false; - Ui.OpenWindow("SETTINGS_MENU", new WidgetArgs() + Ui.OpenWindow("SETTINGS_PANEL", new WidgetArgs() { { "onExit", () => widget.Visible = true }, { "worldRenderer", worldRenderer }, diff --git a/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs index 456d7fe4ce..3c6d4a7f32 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/MainMenuButtonsLogic.cs @@ -36,7 +36,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic widget.Get("MAINMENU_BUTTON_SETTINGS").OnClick = () => { Menu = MenuType.None; - Game.OpenWindow("SETTINGS_MENU", new WidgetArgs() + Game.OpenWindow("SETTINGS_PANEL", new WidgetArgs() { { "onExit", () => Menu = MenuType.Main } }); diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs new file mode 100644 index 0000000000..bc96b5ae55 --- /dev/null +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsLogic.cs @@ -0,0 +1,448 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 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.FileFormats; +using OpenRA.FileFormats.Graphics; +using OpenRA.GameRules; +using OpenRA.Graphics; +using OpenRA.Mods.RA; +using OpenRA.Mods.RA.Widgets; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Ra.Widgets.Logic +{ + public class SettingsLogic + { + 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; + + [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](); + Game.Settings.Save(); + Ui.CloseWindow(); + onExit(); + }; + + 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, "PIXELDOUBLE_CHECKBOX", ds, "PixelDouble"); + BindCheckboxPref(panel, "FRAME_LIMIT_CHECKBOX", ds, "CapFramerate"); + BindCheckboxPref(panel, "SHOW_SHELLMAP", gs, "ShowShellmap"); + + 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"; + + // Update zoom immediately + var pixelDoubleCheckbox = panel.Get("PIXELDOUBLE_CHECKBOX"); + var oldOnClick = pixelDoubleCheckbox.OnClick; + pixelDoubleCheckbox.OnClick = () => + { + oldOnClick(); + worldRenderer.Viewport.Zoom = ds.PixelDouble ? 2 : 1; + }; + + 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(); + frameLimitTextfield.IsDisabled = () => !ds.CapFramerate; + + return () => + { + int x, y; + int.TryParse(windowWidth.Text, out x); + int.TryParse(windowHeight.Text, out y); + ds.WindowedSize = new int2(x, y); + int.TryParse(frameLimitTextfield.Text, out ds.MaxFramerate); + }; + } + + Action ResetDisplayPanel(Widget panel) + { + var ds = Game.Settings.Graphics; + var gs = Game.Settings.Game; + var dds = new GraphicSettings(); + var dgs = new GameSettings(); + 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; + worldRenderer.Viewport.Zoom = ds.PixelDouble ? 2 : 1; + }; + } + + Action InitAudioPanel(Widget panel) + { + var ss = Game.Settings.Sound; + + BindCheckboxPref(panel, "SHELLMAP_MUSIC", ss, "MapMusic"); + BindCheckboxPref(panel, "CASH_TICKS", ss, "CashTicks"); + + BindSliderPref(panel, "SOUND_VOLUME", ss, "SoundVolume"); + BindSliderPref(panel, "MUSIC_VOLUME", ss, "MusicVolume"); + BindSliderPref(panel, "VIDEO_VOLUME", ss, "VideoVolume"); + + // Update volume immediately + panel.Get("SOUND_VOLUME").OnChange += x => Sound.SoundVolume = x; + panel.Get("MUSIC_VOLUME").OnChange += x => Sound.MusicVolume = x; + panel.Get("VIDEO_VOLUME").OnChange += x => Sound.VideoVolume = x; + + var devices = 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, ss, 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.MapMusic = dss.MapMusic; + ss.SoundVolume = dss.SoundVolume; + ss.MusicVolume = dss.MusicVolume; + ss.VideoVolume = dss.VideoVolume; + ss.CashTicks = dss.CashTicks; + ss.Device = dss.Device; + ss.Engine = dss.Engine; + + panel.Get("SOUND_VOLUME").Value = ss.SoundVolume; + panel.Get("MUSIC_VOLUME").Value = ss.MusicVolume; + panel.Get("VIDEO_VOLUME").Value = ss.VideoVolume; + soundDevice = Sound.AvailableDevices().First(); + }; + } + + Action InitInputPanel(Widget panel) + { + // TODO: Extract these to a yaml file + var specialHotkeys = new Dictionary() + { + { "PauseKey", "Pause / Unpause" }, + { "CycleBaseKey", "Jump to base" }, + { "ToLastEventKey", "Jump to last radar event" }, + { "ToSelectionKey", "Jump to selection" }, + { "SellKey", "Sell mode" }, + { "PowerDownKey", "Power-down mode" }, + { "RepairKey", "Repair mode" }, + { "CycleTabsKey", "Cycle production tabs" } + }; + + var unitHotkeys = new Dictionary() + { + { "AttackMoveKey", "Attack Move" }, + { "StopKey", "Stop" }, + { "ScatterKey", "Scatter" }, + { "StanceCycleKey", "Cycle Stance" }, + { "DeployKey", "Deploy" }, + { "GuardKey", "Guard" } + }; + + var gs = Game.Settings.Game; + var ks = Game.Settings.Keys; + + BindCheckboxPref(panel, "CLASSICORDERS_CHECKBOX", gs, "UseClassicMouseStyle"); + BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll"); + BindSliderPref(panel, "SCROLLSPEED_SLIDER", gs, "ViewportEdgeScrollStep"); + + 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"); + hotkeyList.RemoveChildren(); + + var globalHeader = ScrollItemWidget.Setup(hotkeyHeader, () => true, () => {}); + globalHeader.Get("LABEL").GetText = () => "Global Commands"; + hotkeyList.AddChild(globalHeader); + + foreach (var kv in specialHotkeys) + BindHotkeyPref(kv, ks, globalTemplate, hotkeyList); + + var unitHeader = ScrollItemWidget.Setup(hotkeyHeader, () => true, () => {}); + unitHeader.Get("LABEL").GetText = () => "Unit Commands"; + hotkeyList.AddChild(unitHeader); + + foreach (var kv in unitHotkeys) + BindHotkeyPref(kv, ks, unitTemplate, hotkeyList); + + return () => + { + // Remove focus from the selected hotkey widget + // This is a bit of a hack, but works + if (Ui.KeyboardFocusWidget != null && panel.GetOrNull(Ui.KeyboardFocusWidget.Id) != null) + { + Ui.KeyboardFocusWidget.YieldKeyboardFocus(); + Ui.KeyboardFocusWidget = null; + } + }; + } + + 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.ViewportEdgeScroll = dgs.ViewportEdgeScroll; + gs.ViewportEdgeScrollStep = dgs.ViewportEdgeScrollStep; + + 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; + }; + } + + Action InitAdvancedPanel(Widget panel) + { + var ds = Game.Settings.Debug; + var ss = Game.Settings.Server; + + 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, "DEVELOPER_MENU_CHECKBOX", ds, "DeveloperMenu"); + BindCheckboxPref(panel, "CRASH_DIALOG_CHECKBOX", ds, "ShowFatalErrorDialog"); + + 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.DeveloperMenu = dds.DeveloperMenu; + ds.ShowFatalErrorDialog = dds.ShowFatalErrorDialog; + }; + } + + bool ShowMouseScrollDropdown(DropDownButtonWidget dropdown, GameSettings s) + { + var options = new Dictionary() + { + { "Disabled", MouseScrollType.Disabled }, + { "Standard", MouseScrollType.Standard }, + { "Inverted", MouseScrollType.Inverted }, + }; + + 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, SoundSettings s, 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; + } + + 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; + } + + 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; + } + } +} diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs deleted file mode 100644 index e24d0cc975..0000000000 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs +++ /dev/null @@ -1,360 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2013 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.FileFormats; -using OpenRA.FileFormats.Graphics; -using OpenRA.GameRules; -using OpenRA.Graphics; -using OpenRA.Widgets; - -namespace OpenRA.Mods.RA.Widgets.Logic -{ - public class SettingsMenuLogic - { - Widget bg; - SoundDevice soundDevice; - - [ObjectCreator.UseCtor] - public SettingsMenuLogic(Action onExit, WorldRenderer worldRenderer) - { - bg = Ui.Root.Get("SETTINGS_MENU"); - var tabs = bg.Get("TAB_CONTAINER"); - - //Tabs - tabs.Get("GENERAL").OnClick = () => FlipToTab("GENERAL_PANE"); - tabs.Get("AUDIO").OnClick = () => FlipToTab("AUDIO_PANE"); - tabs.Get("DISPLAY").OnClick = () => FlipToTab("DISPLAY_PANE"); - tabs.Get("KEYS").OnClick = () => FlipToTab("KEYS_PANE"); - tabs.Get("DEBUG").OnClick = () => FlipToTab("DEBUG_PANE"); - FlipToTab("GENERAL_PANE"); - - //General - var general = bg.Get("GENERAL_PANE"); - - var name = general.Get("NAME"); - name.Text = Game.Settings.Player.Name; - name.OnLoseFocus = () => - { - name.Text = name.Text.Trim(); - if (name.Text.Length == 0) - name.Text = Game.Settings.Player.Name; - else - Game.Settings.Player.Name = name.Text; - }; - name.OnEnterKey = () => { name.YieldKeyboardFocus(); return true; }; - - var edgescrollCheckbox = general.Get("EDGE_SCROLL"); - edgescrollCheckbox.IsChecked = () => Game.Settings.Game.ViewportEdgeScroll; - edgescrollCheckbox.OnClick = () => Game.Settings.Game.ViewportEdgeScroll ^= true; - - var edgeScrollSlider = general.Get("EDGE_SCROLL_AMOUNT"); - edgeScrollSlider.Value = Game.Settings.Game.ViewportEdgeScrollStep; - edgeScrollSlider.OnChange += x => Game.Settings.Game.ViewportEdgeScrollStep = x; - - var inversescroll = general.Get("INVERSE_SCROLL"); - inversescroll.IsChecked = () => Game.Settings.Game.MouseScroll == MouseScrollType.Inverted; - inversescroll.OnClick = () => Game.Settings.Game.MouseScroll = (Game.Settings.Game.MouseScroll == MouseScrollType.Inverted) ? MouseScrollType.Standard : MouseScrollType.Inverted; - - var showShellmapCheckbox = general.Get("SHOW_SHELLMAP"); - showShellmapCheckbox.IsChecked = () => Game.Settings.Game.ShowShellmap; - showShellmapCheckbox.OnClick = () => Game.Settings.Game.ShowShellmap ^= true; - - var useClassicMouseStyleCheckbox = general.Get("USE_CLASSIC_MOUSE_STYLE_CHECKBOX"); - useClassicMouseStyleCheckbox.IsChecked = () => Game.Settings.Game.UseClassicMouseStyle; - useClassicMouseStyleCheckbox.OnClick = () => Game.Settings.Game.UseClassicMouseStyle ^= true; - - var allowNatDiscoveryCheckbox = general.Get("ALLOW_NAT_DISCOVERY_CHECKBOX"); - allowNatDiscoveryCheckbox.IsChecked = () => Game.Settings.Server.DiscoverNatDevices; - allowNatDiscoveryCheckbox.OnClick = () => Game.Settings.Server.DiscoverNatDevices ^= true; - - // Audio - var audio = bg.Get("AUDIO_PANE"); - var soundSettings = Game.Settings.Sound; - - var soundslider = audio.Get("SOUND_VOLUME"); - soundslider.OnChange += x => Sound.SoundVolume = x; - soundslider.Value = Sound.SoundVolume; - - var musicslider = audio.Get("MUSIC_VOLUME"); - musicslider.OnChange += x => Sound.MusicVolume = x; - musicslider.Value = Sound.MusicVolume; - - var videoslider = audio.Get("VIDEO_VOLUME"); - videoslider.OnChange += x => Sound.VideoVolume = x; - videoslider.Value = Sound.VideoVolume; - - var cashTicksCheckbox = audio.Get("CASHTICK_CHECKBOX"); - cashTicksCheckbox.IsChecked = () => Game.Settings.Sound.CashTicks; - cashTicksCheckbox.OnClick = () => Game.Settings.Sound.CashTicks ^= true; - - var mapMusicCheckbox = audio.Get("MAP_MUSIC_CHECKBOX"); - mapMusicCheckbox.IsChecked = () => Game.Settings.Sound.MapMusic; - mapMusicCheckbox.OnClick = () => Game.Settings.Sound.MapMusic ^= true; - - var devices = Sound.AvailableDevices(); - soundDevice = devices.FirstOrDefault(d => d.Engine == soundSettings.Engine && d.Device == soundSettings.Device) ?? devices.First(); - - var audioDeviceDropdown = audio.Get("AUDIO_DEVICE"); - audioDeviceDropdown.OnMouseDown = _ => ShowAudioDeviceDropdown(audioDeviceDropdown, soundSettings, devices); - audioDeviceDropdown.GetText = () => soundDevice.Label; - - // Display - var display = bg.Get("DISPLAY_PANE"); - var gs = Game.Settings.Graphics; - - var windowModeDropdown = display.Get("MODE_DROPDOWN"); - windowModeDropdown.OnMouseDown = _ => ShowWindowModeDropdown(windowModeDropdown, gs); - windowModeDropdown.GetText = () => gs.Mode == WindowMode.Windowed ? - "Windowed" : gs.Mode == WindowMode.Fullscreen ? "Fullscreen" : "Pseudo-Fullscreen"; - - display.Get("WINDOW_RESOLUTION").IsVisible = () => gs.Mode == WindowMode.Windowed; - var windowWidth = display.Get("WINDOW_WIDTH"); - windowWidth.Text = gs.WindowedSize.X.ToString(); - - var windowHeight = display.Get("WINDOW_HEIGHT"); - windowHeight.Text = gs.WindowedSize.Y.ToString(); - - var pixelDoubleCheckbox = display.Get("PIXELDOUBLE_CHECKBOX"); - pixelDoubleCheckbox.IsChecked = () => gs.PixelDouble; - pixelDoubleCheckbox.OnClick = () => - { - gs.PixelDouble ^= true; - worldRenderer.Viewport.Zoom = gs.PixelDouble ? 2 : 1; - }; - - var capFrameRateCheckbox = display.Get("CAPFRAMERATE_CHECKBOX"); - capFrameRateCheckbox.IsChecked = () => gs.CapFramerate; - capFrameRateCheckbox.OnClick = () => gs.CapFramerate ^= true; - - var maxFrameRate = display.Get("MAX_FRAMERATE"); - maxFrameRate.Text = gs.MaxFramerate.ToString(); - - var languageDropDownButton = display.Get("LANGUAGE_DROPDOWNBUTTON"); - languageDropDownButton.OnMouseDown = _ => ShowLanguageDropdown(languageDropDownButton); - languageDropDownButton.GetText = () => FieldLoader.Translate(Game.Settings.Graphics.Language); - - // Keys - var keys = bg.Get("KEYS_PANE"); - var keyConfig = Game.Settings.Keys; - - var specialHotkeyList = keys.Get("SPECIALHOTKEY_LIST"); - var specialHotkeyTemplate = specialHotkeyList.Get("SPECIALHOTKEY_TEMPLATE"); - - var pauseKey = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(pauseKey, "Pause the game:", () => keyConfig.PauseKey, k => keyConfig.PauseKey = k); - specialHotkeyList.AddChild(pauseKey); - - var viewportToBase = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(viewportToBase, "Move Viewport to Base:", () => keyConfig.CycleBaseKey, k => keyConfig.CycleBaseKey = k); - specialHotkeyList.AddChild(viewportToBase); - - var lastEventKey = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(lastEventKey, "Move Viewport to Last Event:", () => keyConfig.ToLastEventKey, k => keyConfig.ToLastEventKey = k); - specialHotkeyList.AddChild(lastEventKey); - - var viewportToSelectionKey = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(viewportToSelectionKey, "Move Viewport to Selection:", () => keyConfig.ToSelectionKey, k => keyConfig.ToSelectionKey = k); - specialHotkeyList.AddChild(viewportToSelectionKey); - - var sellKey = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(sellKey, "Switch to Sell-Cursor:", () => keyConfig.SellKey, k => keyConfig.SellKey = k); - specialHotkeyList.AddChild(sellKey); - - var powerDownKey = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(powerDownKey, "Switch to Power-Down-Cursor:", () => keyConfig.PowerDownKey, k => keyConfig.PowerDownKey = k); - specialHotkeyList.AddChild(powerDownKey); - - var repairKey = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(repairKey, "Switch to Repair-Cursor:", () => keyConfig.RepairKey, k => keyConfig.RepairKey = k); - specialHotkeyList.AddChild(repairKey); - - var tabCycleKey = ScrollItemWidget.Setup(specialHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(tabCycleKey, "Cycle Tabs (+Shift to Reverse):", () => keyConfig.CycleTabsKey, k => keyConfig.CycleTabsKey = k); - specialHotkeyList.AddChild(tabCycleKey); - - var unitCommandHotkeyList = keys.Get("UNITCOMMANDHOTKEY_LIST"); - var unitCommandHotkeyTemplate = unitCommandHotkeyList.Get("UNITCOMMANDHOTKEY_TEMPLATE"); - - var attackKey = ScrollItemWidget.Setup(unitCommandHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(attackKey, "Attack Move:", () => keyConfig.AttackMoveKey, k => keyConfig.AttackMoveKey = k); - unitCommandHotkeyList.AddChild(attackKey); - - var stopKey = ScrollItemWidget.Setup(unitCommandHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(stopKey, "Stop:", () => keyConfig.StopKey, k => keyConfig.StopKey = k); - unitCommandHotkeyList.AddChild(stopKey); - - var scatterKey = ScrollItemWidget.Setup(unitCommandHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(scatterKey, "Scatter:", () => keyConfig.ScatterKey, k => keyConfig.ScatterKey = k); - unitCommandHotkeyList.AddChild(scatterKey); - - var stanceCycleKey = ScrollItemWidget.Setup(unitCommandHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(stanceCycleKey, "Cycle Stance:", () => keyConfig.StanceCycleKey, k => keyConfig.StanceCycleKey = k); - unitCommandHotkeyList.AddChild(stanceCycleKey); - - var deployKey = ScrollItemWidget.Setup(unitCommandHotkeyTemplate, () => false, () => {}); - SetupKeyBinding(deployKey, "Deploy:", () => keyConfig.DeployKey, k => keyConfig.DeployKey = k); - unitCommandHotkeyList.AddChild(deployKey); - - var guardKey = ScrollItemWidget.Setup(unitCommandHotkeyTemplate, () => false, () => { }); - SetupKeyBinding(guardKey, "Guard: ", () => keyConfig.GuardKey, k => keyConfig.GuardKey = k); - unitCommandHotkeyList.AddChild(guardKey); - - // Debug - var debug = bg.Get("DEBUG_PANE"); - - var perfgraphCheckbox = debug.Get("PERFGRAPH_CHECKBOX"); - perfgraphCheckbox.IsChecked = () => Game.Settings.Debug.PerfGraph; - perfgraphCheckbox.OnClick = () => Game.Settings.Debug.PerfGraph ^= true; - - var perftextCheckbox = debug.Get("PERFTEXT_CHECKBOX"); - perftextCheckbox.IsChecked = () => Game.Settings.Debug.PerfText; - perftextCheckbox.OnClick = () => Game.Settings.Debug.PerfText ^= true; - - var sampleSlider = debug.Get("PERFTEXT_SAMPLE_AMOUNT"); - sampleSlider.Value = sampleSlider.MaximumValue-Game.Settings.Debug.Samples; - sampleSlider.OnChange += x => Game.Settings.Debug.Samples = (int)sampleSlider.MaximumValue-(int)Math.Round(x); - - var checkunsyncedCheckbox = debug.Get("CHECKUNSYNCED_CHECKBOX"); - checkunsyncedCheckbox.IsChecked = () => Game.Settings.Debug.SanityCheckUnsyncedCode; - checkunsyncedCheckbox.OnClick = () => Game.Settings.Debug.SanityCheckUnsyncedCode ^= true; - - var botdebugCheckbox = debug.Get("BOTDEBUG_CHECKBOX"); - botdebugCheckbox.IsChecked = () => Game.Settings.Debug.BotDebug; - botdebugCheckbox.OnClick = () => Game.Settings.Debug.BotDebug ^= true; - - var verboseNatDiscoveryCheckbox = debug.Get("VERBOSE_NAT_DISCOVERY_CHECKBOX"); - verboseNatDiscoveryCheckbox.IsChecked = () => Game.Settings.Server.VerboseNatDiscovery; - verboseNatDiscoveryCheckbox.OnClick = () => Game.Settings.Server.VerboseNatDiscovery ^= true; - - var developerMenuCheckbox = debug.Get("DEVELOPER_MENU_CHECKBOX"); - developerMenuCheckbox.IsChecked = () => Game.Settings.Debug.DeveloperMenu; - developerMenuCheckbox.OnClick = () => Game.Settings.Debug.DeveloperMenu ^= true; - - var showFatalErrorDialog = debug.Get("SHOW_FATAL_ERROR_DIALOG_CHECKBOX"); - showFatalErrorDialog.IsChecked = () => Game.Settings.Debug.ShowFatalErrorDialog; - showFatalErrorDialog.OnClick = () => Game.Settings.Debug.ShowFatalErrorDialog ^= true; - - bg.Get("BUTTON_CLOSE").OnClick = () => - { - int x, y; - int.TryParse(windowWidth.Text, out x); - int.TryParse(windowHeight.Text, out y); - gs.WindowedSize = new int2(x,y); - int.TryParse(maxFrameRate.Text, out gs.MaxFramerate); - soundSettings.Device = soundDevice.Device; - soundSettings.Engine = soundDevice.Engine; - Game.Settings.Save(); - Ui.CloseWindow(); - onExit(); - }; - } - - string open = null; - - bool FlipToTab(string id) - { - if (open != null) - bg.Get(open).Visible = false; - - open = id; - bg.Get(open).Visible = true; - return true; - } - - public 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; - } - - public 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; - } - - void SetupKeyBinding(ScrollItemWidget keyWidget, string description, Func getValue, Action setValue) - { - keyWidget.Get("FUNCTION").GetText = () => description; - - var keyEntry = keyWidget.Get("HOTKEY"); - keyEntry.Key = getValue(); - keyEntry.OnLoseFocus = () => setValue(keyEntry.Key); - } - - static bool ShowRendererDropdown(DropDownButtonWidget dropdown, GraphicSettings s) - { - var options = new Dictionary() - { - { "OpenGL", "Gl" }, - { "Cg Toolkit", "Cg" }, - }; - - Func setupItem = (o, itemTemplate) => - { - var item = ScrollItemWidget.Setup(itemTemplate, - () => s.Renderer == options[o], - () => s.Renderer = options[o]); - item.Get("LABEL").GetText = () => o; - return item; - }; - - dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); - return true; - } - - bool ShowAudioDeviceDropdown(DropDownButtonWidget dropdown, SoundSettings s, 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; - } - } -} diff --git a/OpenRA.Mods.RA/Widgets/RadarWidget.cs b/OpenRA.Mods.RA/Widgets/RadarWidget.cs index ad14b6865e..eb3c518e11 100755 --- a/OpenRA.Mods.RA/Widgets/RadarWidget.cs +++ b/OpenRA.Mods.RA/Widgets/RadarWidget.cs @@ -156,7 +156,7 @@ namespace OpenRA.Mods.RA.Widgets var tl = CellToMinimapPixel(worldRenderer.Position(worldRenderer.Viewport.TopLeft).ToCPos()); var br = CellToMinimapPixel(worldRenderer.Position(worldRenderer.Viewport.BottomRight).ToCPos()); - Game.Renderer.EnableScissor(mapRect.Left, mapRect.Top, mapRect.Width, mapRect.Height); + Game.Renderer.EnableScissor(mapRect); Game.Renderer.LineRenderer.DrawRect(tl, br, Color.White); Game.Renderer.DisableScissor(); } diff --git a/mods/cnc/chrome.yaml b/mods/cnc/chrome.yaml index 936bec7c1a..dbbdd57a0a 100644 --- a/mods/cnc/chrome.yaml +++ b/mods/cnc/chrome.yaml @@ -251,17 +251,8 @@ scrollitem-selected: chrome.png corner-bl: 64,254,2,2 corner-br: 126,254,2,2 -# A copy of panel-gray -slider-tick: chrome.png - background: 66,66,60,60 - border-r: 126,66,2,60 - border-l: 64,66,2,60 - border-b: 66,126,60,2 - border-t: 66,64,60,2 - corner-tl: 64,64,2,2 - corner-tr: 126,64,2,2 - corner-bl: 64,126,2,2 - corner-br: 126,126,2,2 +slider: chrome.png + tick: 64,64,1,4 # A copy of panel-gray slider-track: chrome.png diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index 7b3b7097d6..23866996a5 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -1,313 +1,443 @@ Container@SETTINGS_PANEL: - Logic:CncSettingsLogic + Logic:SettingsLogic X:(WINDOW_RIGHT - WIDTH)/2 - Y:(WINDOW_BOTTOM - 250)/2 - Width:740 - Height:565 + Y:(WINDOW_BOTTOM - HEIGHT)/2 + Width:590 + Height:260+68 Children: - ColorPreviewManager@COLOR_MANAGER: Label@TITLE: - Width:740 + Width:590 Y:0-25 Font:BigBold Contrast:true Align:Center Text:Settings - Background@GENERAL_CONTROLS: - Width:740 - Height:320 - Background:panel-black + Container@TAB_CONTAINER: Children: - Label@TITLE: - X:15 - Y:20 - Font:Bold - Text:Player Profile - Align:Center - Width:340 - Label@NAME_LABEL: - X:15 - Y:39 - Width:45 - Height:25 - Align:Right - Text:Name: - TextField@NAME_TEXTFIELD: - X:65 - Y:40 - Width:205 - Height:25 - MaxLength:16 - DropDownButton@COLOR: - X:275 - Y:40 - Width:80 - Height:25 - IgnoreChildMouseOver: true - Children: - ColorBlock@COLORBLOCK: - X:5 - Y:6 - Width:PARENT_RIGHT-35 - Height:PARENT_BOTTOM-12 - Checkbox@SHOW_SHELLMAP: - X:15 - Y:80 - Width:200 - Height:20 - Font:Regular - Text:Show Shellmap - Checkbox@SHELLMAP_MUSIC: - X:15 - Y:110 - Width:200 - Height:20 - Font:Regular - Text:Shellmap Music - Label@DEBUG_TITLE: - X:15 - Y:180 - Width:340 - Font:Bold - Text:Debug - Align:Center - Checkbox@PERFTEXT_CHECKBOX: - X:15 - Y:200 - Width:300 - Height:20 - Font:Regular - Text:Show Performance Text - Checkbox@PERFGRAPH_CHECKBOX: - X:15 - Y:230 - Width:300 - Height:20 - Font:Regular - Text:Show Performance Graph - Checkbox@CHECKUNSYNCED_CHECKBOX: - X:15 - Y:260 - Width:300 - Height:20 - Font:Regular - Text:Check Sync around Unsynced Code - Checkbox@SHOW_FATAL_ERROR_DIALOG_CHECKBOX: - X:15 - Y:290 - Width:300 - Height:20 - Font:Regular - Text:Show Fatal Error dialog - Label@VIDEO_TITLE: - Y:20 - X:375 - Font:Bold - Text:Graphics - Align:Center - Width:340 - Label@MODE_LABEL: - X:375 - Y:39 - Width:45 - Height:25 - Align:Right - Text:Mode: - DropDownButton@MODE_DROPDOWN: - X:425 - Y:40 - Width:170 - Height:25 - Font:Regular - Text:Windowed - Container@WINDOW_RESOLUTION: - X:595 - Y:40 - Children: - Label@At: - Text:@ - Font:Bold - Y:0-1 - Height:25 - Width:25 - Align:Center - TextField@WINDOW_WIDTH: - X:25 - Width:45 - Height:25 - MaxLength:5 - Label@X: - Text:x - Font:Bold - X:70 - Y:0-1 - Height:25 - Width:15 - Align:Center - TextField@WINDOW_HEIGHT: - X:85 - Width:45 - Height:25 - MaxLength:5 - Label@LANGUAGE_LABEL: - X:375 - Y:70 - Width:75 - Height:25 - Align:Right - Text:Language: - DropDownButton@LANGUAGE_DROPDOWNBUTTON: - X:455 - Y:70 + Button@DISPLAY_TAB: Width:140 - Height:25 - Label@VIDEO_DESC: - X:375 - Y:100 - Width:340 - Height:25 - Font:Tiny - Align:Center - Text:Mode/Resolution/Language changes will be applied after the game is restarted - Checkbox@PIXELDOUBLE_CHECKBOX: - X:375 - Y:140 - Width:200 - Height:20 - Font:Regular - Text:Enable Pixel Doubling - Label@AUDIO_TITLE: - X:375 - Y:180 - Width:340 - Font:Bold - Text:Sound - Align:Center - Label@SOUND_LABEL: - X:375 - Y:194 - Width:95 - Height:25 - Align:Right - Text:Sound Volume: - Slider@SOUND_SLIDER: - X:475 - Y:200 - Width:240 - Height:20 - Ticks:5 - Label@MUSIC_LABEL: - X:375 - Y:224 - Width:95 - Height:25 - Align:Right - Text:Music Volume: - Slider@MUSIC_SLIDER: - X:475 - Y:230 - Width:240 - Height:20 - Ticks:5 - Label@AUDIO_DEVICE_LABEL: - X:375 - Y:259 - Width:75 - Height:20 - Text:Audio Device: - DropDownButton@AUDIO_DEVICE: - X:475 - Y:260 - Width:240 - Height:25 - Font:Regular - Text:Default Device - Label@AUDIO_DESC: - X:375 - Y:288 - Width:340 - Height:25 - Font:Tiny - Align:Center - Text:Device changes will be applied after the game is restarted - Background@INPUT_CONTROLS: - Width:740 - Height:290 - Background:panel-black - Visible:false - Children: - Label@MOUSE_TITLE: - Font:Bold - Text:Mouse Input - Align:Center - X:15 - Y:20 - Width:340 - Checkbox@CLASSICORDERS_CHECKBOX: - X:15 - Y:35 - Width:250 - Height:20 - Font:Regular - Text:Left-Click Orders - Label@SCROLL_TITLE: - Font:Bold - Text:Scroll Behavior - Align:Center - X:20 - Y:100 - Width:335 - Label@SCROLL_SPEED_LABEL: - X:10 - Y:115 - Width:95 - Height:25 - Text:Scroll Speed: - Slider@SCROLLSPEED_SLIDER: - X:100 - Y:120 - Width:240 - Height:20 - Ticks:5 - MinimumValue: 10 - MaximumValue: 50 - Checkbox@EDGESCROLL_CHECKBOX: - X:15 - Y:150 - Width:130 - Height:20 - Font:Regular - Text:Edge Scrolling - Label@MOUSE_SCROLL_LABEL: - X:15 - Y:180 - Width:160 - Height:20 - Font:Regular - Text:Middle-Mouse Scrolling: - Align:Right - DropDownButton@MOUSE_SCROLL: - X:180 - Y:180 - Width:100 - Height:25 - Font:Regular - Text:Enabled - Button@GENERAL_BUTTON: - Y:319 + Height:35 + Text:Display + Button@AUDIO_TAB: + X:150 + Width:140 + Height:35 + Text:Audio + Button@INPUT_TAB: + X:300 + Width:140 + Height:35 + Text:Input + Button@ADVANCED_TAB: + X:450 + Width:140 + Height:35 + Text:Advanced + Button@RESET_BUTTON: + Y:293 Width:140 Height:35 - Text:General - Button@INPUT_BUTTON: - X:150 - Y:319 - Width:140 - Height:35 - Text:Input + Text:Reset Button@BACK_BUTTON: Key:escape - X:600 - Y:319 + X:PARENT_RIGHT-WIDTH + Y:293 Width:140 Height:35 Text:Back + Background@bg: + Y:34 + Width:590 + Height:260 + Background:panel-black + Children: + Container@DISPLAY_PANEL: + Width:PARENT_RIGHT + Height:PARENT_BOTTOM + Children: + Label@VIDEO_TITLE: + Y:20 + Width:PARENT_RIGHT + Font:Bold + Text:Graphics + Align:Center + Label@MODE_LABEL: + X:120 + Y:39 + Width:45 + Height:25 + Align:Right + Text:Mode: + DropDownButton@MODE_DROPDOWN: + X:170 + Y:40 + Width:170 + Height:25 + Font:Regular + Text:Windowed + Container@WINDOW_RESOLUTION: + X:340 + Y:40 + Children: + Label@At: + Text:@ + Font:Bold + Y:0-1 + Height:25 + Width:25 + Align:Center + TextField@WINDOW_WIDTH: + X:25 + Width:45 + Height:25 + MaxLength:5 + Label@X: + Text:x + Font:Bold + X:70 + Y:0-1 + Height:25 + Width:15 + Align:Center + TextField@WINDOW_HEIGHT: + X:85 + Width:45 + Height:25 + MaxLength:5 + Label@VIDEO_DESC: + Y:60 + Width:PARENT_RIGHT + Height:25 + Font:Tiny + Align:Center + Text:Mode/Resolution changes will be applied after the game is restarted + Checkbox@FRAME_LIMIT_CHECKBOX: + X:15 + Y:100 + Width:200 + Height:20 + Font:Regular + Text:Enable Frame Limiter + Checkbox@PIXELDOUBLE_CHECKBOX: + X:310 + Y:105 + Width:200 + Height:20 + Font:Regular + Text:Enable Pixel Doubling + Label@FRAME_LIMIT_DESC_A: + X:45 + Y:132 + Width:50 + Height:25 + Text:Limit to + Align:Right + TextField@FRAME_LIMIT_TEXTFIELD: + X:100 + Y:133 + Width:45 + Height:25 + MaxLength:3 + Label@FRAME_LIMIT_DESC_B: + X:150 + Y:132 + Height:25 + Text: FPS + Checkbox@SHOW_SHELLMAP: + X:310 + Y:135 + Width:200 + Height:20 + Font:Regular + Text:Show Shellmap + Label@VIDEO_TITLE: + Y:175 + Width:PARENT_RIGHT + Font:Bold + Text:Localization + Align:Center + Label@LANGUAGE_LABEL: + X:230 - WIDTH - 5 + Y:194 + Width:75 + Height:25 + Align:Right + Text:Language: + DropDownButton@LANGUAGE_DROPDOWNBUTTON: + X:230 + Y:195 + Width:200 + Height:25 + Label@VIDEO_DESC_A: + Y:215 + Width:PARENT_RIGHT + Height:25 + Font:Tiny + Align:Center + Text:Language changes will be applied after the game is restarted + Label@VIDEO_DESC_B: + Y:230 + Width:PARENT_RIGHT + Height:25 + Font:Tiny + Align:Center + Text:Translations apply to text strings only; Speech and build icons will remain in English + Container@AUDIO_PANEL: + Width:PARENT_RIGHT + Height:PARENT_BOTTOM + Children: + Label@AUDIO_TITLE: + Y:20 + Width:PARENT_RIGHT + Font:Bold + Text:Audio + Align:Center + Checkbox@SHELLMAP_MUSIC: + X:15 + Y:40 + Width:200 + Height:20 + Font:Regular + Text:Shellmap / Mission Music + Label@SOUND_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:37 + Width:95 + Height:25 + Align:Right + Text:Sound Volume: + Slider@SOUND_VOLUME: + X:PARENT_RIGHT - WIDTH - 15 + Y:43 + Width:250 + Height:20 + Ticks:5 + Checkbox@CASH_TICKS: + X:15 + Y:70 + Width:200 + Height:20 + Font:Regular + Text:Cash Ticks + Label@MUSIC_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:67 + Width:95 + Height:25 + Align:Right + Text:Music Volume: + Slider@VIDEO_VOLUME: + X:PARENT_RIGHT - WIDTH - 15 + Y:73 + Width:250 + Height:20 + Ticks:5 + Label@VIDEO_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:97 + Width:95 + Height:25 + Align:Right + Text:Video Volume: + Slider@MUSIC_VOLUME: + X:PARENT_RIGHT - WIDTH - 15 + Y:103 + Width:250 + Height:20 + Ticks:5 + Label@AUDIO_DEVICE_LABEL: + X:190 - WIDTH - 5 + Y:194 + Width:75 + Height:25 + Align:Right + Text:Audio Device: + DropDownButton@AUDIO_DEVICE: + X:190 + Y:195 + Width:300 + Height:25 + Label@AUDIO_DEVICE_DESC: + Y:215 + Width:PARENT_RIGHT + Height:25 + Font:Tiny + Align:Center + Text:Device changes will be applied after the game is restarted + Container@INPUT_PANEL: + Width:PARENT_RIGHT + Height:PARENT_BOTTOM + Children: + Label@INPUT_TITLE: + Y:20 + Width:PARENT_RIGHT + Font:Bold + Text:Input + Align:Center + Checkbox@CLASSICORDERS_CHECKBOX: + X:15 + Y:40 + Width:250 + Height:20 + Font:Regular + Text:Left-Click Orders + Label@MOUSE_SCROLL_LABEL: + X:PARENT_RIGHT - WIDTH - 120 + Y:39 + Width:160 + Height:20 + Font:Regular + Text:Middle-Mouse Scrolling: + Align:Right + DropDownButton@MOUSE_SCROLL: + X:PARENT_RIGHT - WIDTH - 15 + Y:38 + Width:100 + Height:25 + Font:Regular + Text:Enabled + Checkbox@EDGESCROLL_CHECKBOX: + X:15 + Y:70 + Width:130 + Height:20 + Font:Regular + Text:Edge Scrolling + Label@SCROLL_SPEED_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:67 + Width:95 + Height:25 + Text:Scroll Speed: + Align:Right + Slider@SCROLLSPEED_SLIDER: + X:PARENT_RIGHT - WIDTH - 15 + Y:73 + Width:250 + Height:20 + Ticks:5 + MinimumValue: 10 + MaximumValue: 50 + Label@HOTKEY_TITLE: + Y:115 + Width:PARENT_RIGHT + Font:Bold + Text:Hotkeys + Align:Center + ScrollPanel@HOTKEY_LIST: + X:15 + Y:135 + Width:560 + ItemSpacing:4 + Height:110 + Children: + ScrollItem@HEADER: + Width:528 + Height:13 + Visible:false + Children: + Label@LABEL: + Font:TinyBold + Width:PARENT_RIGHT + Height:10 + Align:Center + Container@GLOBAL_TEMPLATE: + Width:262 + Height:25 + Visible:false + Children: + Label@FUNCTION: + Y:0-1 + Width:PARENT_RIGHT - 85 + Height:25 + Align:Right + HotkeyEntry@HOTKEY: + X:PARENT_RIGHT-WIDTH + Width:80 + Height:25 + Container@UNIT_TEMPLATE: + Width:173 + Height:25 + Visible:false + Children: + Label@FUNCTION: + Y:0-1 + Width:PARENT_RIGHT - 84 + Height:25 + Align:Right + HotkeyEntry@HOTKEY: + X:PARENT_RIGHT-WIDTH+1 + Width:80 + Height:25 + Container@ADVANCED_PANEL: + Width:PARENT_RIGHT + Height:PARENT_BOTTOM + Children: + Label@HOTKEY_TITLE: + Y:20 + Width:PARENT_RIGHT + Font:Bold + Text:Advanced + Align:Center + Checkbox@NAT_DISCOVERY: + X:15 + Y:40 + Width:200 + Height:20 + Font:Regular + Text: Enable Network Discovery (UPnP) + Checkbox@CRASH_DIALOG_CHECKBOX: + X:310 + Y:40 + Width:300 + Height:20 + Font:Regular + Text:Show Fatal Error dialog + Checkbox@PERFTEXT_CHECKBOX: + X:15 + Y:70 + Width:300 + Height:20 + Font:Regular + Text:Show Performance Text + Checkbox@PERFGRAPH_CHECKBOX: + X:310 + Y:70 + Width:300 + Height:20 + Font:Regular + Text:Show Performance Graph + Checkbox@DEVELOPER_MENU_CHECKBOX: + X:15 + Y:100 + Width:300 + Height:20 + Font:Regular + Text:Enable Asset Browser (requires restart) + Label@HOTKEY_TITLE: + Y:140 + Width:PARENT_RIGHT + Font:Bold + Text:Debug + Align:Center + Checkbox@BOTDEBUG_CHECKBOX: + X:15 + Y:160 + Width:300 + Height:20 + Font:Regular + Text:Show Bot Debug Messages + Checkbox@VERBOSE_NAT_CHECKBOX: + X:310 + Y:160 + Width:300 + Height:20 + Font:Regular + Text:Detailed NAT logging + Checkbox@CHECKUNSYNCED_CHECKBOX: + X:15 + Y:190 + Width:300 + Height:20 + Font:Regular + Text:Check Sync around Unsynced Code diff --git a/mods/d2k/chrome.yaml b/mods/d2k/chrome.yaml index 8dfc99bf51..8d8a934802 100644 --- a/mods/d2k/chrome.yaml +++ b/mods/d2k/chrome.yaml @@ -492,18 +492,8 @@ scrollpanel-bg: dialog.png corner-bl: 640,127,1,1 corner-br: 767,127,1,1 - -# A copy of dialog2 (normal button) -slider-tick: dialog.png - background: 513,1,126,126 - border-r: 639,1,1,126 - border-l: 512,1,1,126 - border-b: 513,127,126,1 - border-t: 513,0,126,1 - corner-tl: 512,0,1,1 - corner-tr: 639,0,1,1 - corner-bl: 512,127,1,1 - corner-br: 639,127,1,1 +slider: dialog.png + tick: 512,1,2,4 # A copy of dialog3 (pressed button) slider-track: dialog.png diff --git a/mods/ra/chrome.yaml b/mods/ra/chrome.yaml index 519d456674..359758abad 100644 --- a/mods/ra/chrome.yaml +++ b/mods/ra/chrome.yaml @@ -442,17 +442,8 @@ scrollpanel-bg: dialog.png corner-bl: 640,127,1,1 corner-br: 767,127,1,1 -# A copy of dialog2 (normal button) -slider-tick: dialog.png - background: 513,1,126,126 - border-r: 639,1,1,126 - border-l: 512,1,1,126 - border-b: 513,127,126,1 - border-t: 513,0,126,1 - corner-tl: 512,0,1,1 - corner-tr: 639,0,1,1 - corner-bl: 512,127,1,1 - corner-br: 639,127,1,1 +slider: dialog.png + tick: 512,1,2,4 # A copy of dialog3 (pressed button) slider-track: dialog.png diff --git a/mods/ra/chrome/settings.yaml b/mods/ra/chrome/settings.yaml index 90e404c518..e7dee6f810 100644 --- a/mods/ra/chrome/settings.yaml +++ b/mods/ra/chrome/settings.yaml @@ -1,217 +1,83 @@ -Background@SETTINGS_MENU: - Logic:SettingsMenuLogic +Background@SETTINGS_PANEL: + Logic:SettingsLogic X:(WINDOW_RIGHT - WIDTH)/2 Y:(WINDOW_BOTTOM- HEIGHT)/2 - Width: 540 - Height: 400 + Width:600 + Height:351 Children: Label@SETTINGS_LABEL_TITLE: - X:0 Y:20 - Width:540 + Width:PARENT_RIGHT Height:25 Text:Settings Align:Center Font:Bold - Button@BUTTON_CLOSE: + Button@RESET_BUTTON: + X:20 + Y:PARENT_BOTTOM - 45 + Width:160 + Height:25 + Text:Reset + Button@BACK_BUTTON: + Key:escape X:PARENT_RIGHT - 180 Y:PARENT_BOTTOM - 45 Width:160 Height:25 - Text:Close + Text:Back Font:Bold - Key:escape Container@TAB_CONTAINER: - X:0 Y:50 Width:PARENT_RIGHT Height:25 Children: - Button@GENERAL: - X:45 - Y:0 - Width:90 - Height:25 - Text:General - Font:Bold - Button@AUDIO: - X:135 - Y:0 - Width:90 - Height:25 - Text:Audio - Font:Bold - Button@DISPLAY: - X:225 - Y:0 + Button@DISPLAY_TAB: + X:115 Width:90 Height:25 Text:Display Font:Bold - Button@KEYS: - X:315 - Y:0 + Button@AUDIO_TAB: + X:205 Width:90 Height:25 - Text:Keys + Text:Audio Font:Bold - Button@DEBUG: - X:405 - Y:0 + Button@INPUT_TAB: + X:295 Width:90 Height:25 - Text:Debug + Text:Input Font:Bold - Container@GENERAL_PANE: - X:37 - Y:100 - Width:PARENT_RIGHT - 37 - Height:PARENT_BOTTOM - 100 - Visible: true - Children: - Label@SETTINGS_PLAYER_NAME: - X:0 - Y:10 - Text: Player Name: - TextField@NAME: - Text:Name - Width:139 + Button@ADVANCED_TAB: + X:385 + Width:90 Height:25 - X:90 - Y:0 - MaxLength:16 - Checkbox@EDGE_SCROLL: - X:0 - Y:30 - Width:200 - Height:20 - Text: Enable Edge Scrolling - Label@EDGE_SCROLL_AMOUNT_LABEL: - X:0 - Y:70 - Text: Scroll Speed - Slider@EDGE_SCROLL_AMOUNT: - X:130 - Y:60 - Width:250 - Height:20 - Ticks:5 - MinimumValue: 10 - MaximumValue: 50 - Checkbox@INVERSE_SCROLL: - X:0 - Y:90 - Width:200 - Height:20 - Text: Invert Mouse Drag Scrolling - Checkbox@SHOW_SHELLMAP: - X:0 - Y:150 - Width:200 - Height:20 - Text: Show Shellmap - Checkbox@USE_CLASSIC_MOUSE_STYLE_CHECKBOX: - X:0 - Y:180 - Width:200 - Height:20 - Text: Left-Click Orders - Checkbox@ALLOW_NAT_DISCOVERY_CHECKBOX: - X:0 - Y:210 - Width:200 - Height:20 - Text: Enable Network Discovery (UPnP) - Container@AUDIO_PANE: - X:37 - Y:100 - Width:PARENT_RIGHT - 37 - Height:PARENT_BOTTOM - 100 - Visible: false - Children: - Label@SOUND_VOLUME_LABEL: - X:0 - Y:10 - Text: Sound Volume - Slider@SOUND_VOLUME: - X:100 - Y:0 - Width:250 - Height:20 - Ticks:5 - Label@MUSIC_VOLUME_LABEL: - X:0 - Y:40 - Text: Music Volume - Slider@MUSIC_VOLUME: - X:100 - Y:30 - Width:250 - Height:20 - Ticks:5 - Label@VIDEO_VOLUME_LABEL: - X:0 - Y:70 - Text: Video Volume - Slider@VIDEO_VOLUME: - X:100 - Y:60 - Width:250 - Height:20 - Ticks:5 - Checkbox@CASHTICK_CHECKBOX: - X:0 - Y:90 - Width:200 - Height:20 - Text:Cash Ticks - Checkbox@MAP_MUSIC_CHECKBOX: - X:0 - Y:120 - Width:200 - Height:20 - Text: Autoplay Music After Map Load - Label@AUDIO_DEVICE_LABEL: - X:0 - Y:150 - Width:75 - Height:25 - Text:Audio Device: - DropDownButton@AUDIO_DEVICE: - X:100 - Y:150 - Width:250 - Height:25 - Font:Regular - Label@AUDIO_DESC: - Y:175 - Width:200 - Height:25 - Font:Tiny - Text:Device changes will be applied after the game is restarted. - Container@DISPLAY_PANE: - X:37 - Y:100 - Width:PARENT_RIGHT - 37 - Height:PARENT_BOTTOM - 100 - Visible: false + Text:Advanced + Font:Bold + Container@DISPLAY_PANEL: + X:5 + Y:50 + Width:PARENT_RIGHT - 10 + Height:PARENT_BOTTOM Children: Label@MODE_LABEL: - X:0 - Y:0 + X:120 + Y:39 Width:45 Height:25 + Align:Right Text:Mode: DropDownButton@MODE_DROPDOWN: - X:50 - Y:0 + X:170 + Y:40 Width:170 Height:25 Font:Regular Text:Windowed Container@WINDOW_RESOLUTION: - X:225 - Y:0 + X:340 + Y:40 Children: Label@At: Text:@ @@ -239,165 +105,328 @@ Background@SETTINGS_MENU: Height:25 MaxLength:5 Label@VIDEO_DESC: - Y:30 + Y:60 Width:PARENT_RIGHT Height:25 Font:Tiny Align:Center - Text:Mode/Resolution changes will be applied after the game is restarted. + Text:Mode/Resolution changes will be applied after the game is restarted + Checkbox@FRAME_LIMIT_CHECKBOX: + X:15 + Y:100 + Width:200 + Height:20 + Font:Regular + Text:Enable Frame Limiter Checkbox@PIXELDOUBLE_CHECKBOX: - Y:60 + X:310 + Y:105 Width:200 Height:20 Font:Regular Text:Enable Pixel Doubling - Checkbox@CAPFRAMERATE_CHECKBOX: - Y:90 - Width:200 - Height:20 - Font:Regular - Text:Cap Framerate @ - TextField@MAX_FRAMERATE: - X:150 - Y:90 + Label@FRAME_LIMIT_DESC_A: + X:45 + Y:132 + Width:50 + Height:25 + Text:Limit to + Align:Right + TextField@FRAME_LIMIT_TEXTFIELD: + X:100 + Y:133 Width:45 Height:25 MaxLength:3 + Label@FRAME_LIMIT_DESC_B: + X:150 + Y:132 + Height:25 + Text: FPS + Checkbox@SHOW_SHELLMAP: + X:310 + Y:135 + Width:200 + Height:20 + Font:Regular + Text:Show Shellmap + Label@VIDEO_TITLE: + Y:175 + Width:PARENT_RIGHT + Font:Bold + Text:Localization + Align:Center Label@LANGUAGE_LABEL: - X:0 - Y:130 + X:230 - WIDTH - 5 + Y:194 Width:75 Height:25 + Align:Right Text:Language: DropDownButton@LANGUAGE_DROPDOWNBUTTON: - X:80 - Y:130 - Width:140 + X:230 + Y:195 + Width:200 Height:25 - Label@LANGUAGE_DESC: - Y:160 + Label@VIDEO_DESC_A: + Y:215 Width:PARENT_RIGHT Height:25 Font:Tiny Align:Center - Text:Language changes will be applied after the game is restarted. - Container@KEYS_PANE: - X:37 - Y:100 - Width:PARENT_RIGHT - 37 - Height:PARENT_BOTTOM - 100 - Visible: false + Text:Language changes will be applied after the game is restarted + Label@VIDEO_DESC_B: + Y:230 + Width:PARENT_RIGHT + Height:25 + Font:Tiny + Align:Center + Text:Translations apply to text strings only; Speech and build icons will remain in English + Container@AUDIO_PANEL: + X:5 + Y:50 + Width:PARENT_RIGHT - 10 + Height:PARENT_BOTTOM Children: - Label@KEYS_SPECIALHOTKEYSHEADLINE: - X:0 - Y:0 - Text: Special Hotkeys: - Font:Bold - ScrollPanel@SPECIALHOTKEY_LIST: - X:0 - Y:20 - Width:449 - Height:85 - Children: - ScrollItem@SPECIALHOTKEY_TEMPLATE: - Width:PARENT_RIGHT-27 - Height:25 - X:2 - Y:0 - Visible:false - Children: - Label@FUNCTION: - X:10 - Width:200 - Height:25 - HotkeyEntry@HOTKEY: - X:250 - Width:139 - Height:25 - Label@KEYS_UNITCOMMANDSHEADLINE: - X:0 - Y:130 - Text: Hotkeys for Unit Commands: - Font:Bold - ScrollPanel@UNITCOMMANDHOTKEY_LIST: - X:0 - Y:150 - Width:449 - Height:85 - Children: - ScrollItem@UNITCOMMANDHOTKEY_TEMPLATE: - Width:PARENT_RIGHT-27 - Height:25 - X:2 - Y:0 - Visible:false - Children: - Label@FUNCTION: - X:10 - Width:200 - Height:25 - HotkeyEntry@HOTKEY: - X:250 - Width:139 - Height:25 - Container@DEBUG_PANE: - X:37 - Y:100 - Width:PARENT_RIGHT - 37 - Height:PARENT_BOTTOM - 100 - Visible: false - Children: - Checkbox@PERFGRAPH_CHECKBOX: - X:0 - Y:0 - Width:300 + Checkbox@SHELLMAP_MUSIC: + X:15 + Y:40 + Width:200 Height:20 - Text:Show Performance Graph - Checkbox@PERFTEXT_CHECKBOX: - X:0 - Y:30 - Width:300 - Height:20 - Text:Show Performance Text - Label@PERFTEXT_SAMPLE_LABEL: - X:30 - Y:70 - Text:Update Rate - Slider@PERFTEXT_SAMPLE_AMOUNT: - X:130 - Y:60 + Font:Regular + Text:Shellmap / Mission Music + Label@SOUND_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:37 + Width:95 + Height:25 + Align:Right + Text:Sound Volume: + Slider@SOUND_VOLUME: + X:PARENT_RIGHT - WIDTH - 15 + Y:43 Width:250 Height:20 Ticks:5 - MinimumValue: 1 - MaximumValue: 50 - Checkbox@CHECKUNSYNCED_CHECKBOX: - X:0 - Y:90 - Width:300 - Height:20 - Text:Check Sync around Unsynced Code - Checkbox@BOTDEBUG_CHECKBOX: - X:0 - Y:120 - Width:300 - Height:20 - Text:Show Bot Debug Messages - Checkbox@VERBOSE_NAT_DISCOVERY_CHECKBOX: - X:0 - Y:150 - Width:300 - Height:20 - Text:Detailed NAT logging - Checkbox@DEVELOPER_MENU_CHECKBOX: - X:0 - Y:180 - Width:300 - Height:20 - Text:Enable Asset Browser (requires restart) - Checkbox@SHOW_FATAL_ERROR_DIALOG_CHECKBOX: - X:0 - Y:210 + Checkbox@CASH_TICKS: + X:15 + Y:70 Width:200 Height:20 - Text:Show Fatal Error dialog \ No newline at end of file + Font:Regular + Text:Cash Ticks + Label@MUSIC_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:67 + Width:95 + Height:25 + Align:Right + Text:Music Volume: + Slider@VIDEO_VOLUME: + X:PARENT_RIGHT - WIDTH - 15 + Y:73 + Width:250 + Height:20 + Ticks:5 + Label@VIDEO_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:97 + Width:95 + Height:25 + Align:Right + Text:Video Volume: + Slider@MUSIC_VOLUME: + X:PARENT_RIGHT - WIDTH - 15 + Y:103 + Width:250 + Height:20 + Ticks:5 + Label@AUDIO_DEVICE_LABEL: + X:190 - WIDTH - 5 + Y:194 + Width:75 + Height:25 + Align:Right + Text:Audio Device: + DropDownButton@AUDIO_DEVICE: + X:190 + Y:195 + Width:300 + Height:25 + Label@AUDIO_DEVICE_DESC: + Y:215 + Width:PARENT_RIGHT + Height:25 + Font:Tiny + Align:Center + Text:Device changes will be applied after the game is restarted + Container@INPUT_PANEL: + X:5 + Y:50 + Width:PARENT_RIGHT - 10 + Height:PARENT_BOTTOM + Children: + Checkbox@CLASSICORDERS_CHECKBOX: + X:15 + Y:40 + Width:250 + Height:20 + Font:Regular + Text:Left-Click Orders + Label@MOUSE_SCROLL_LABEL: + X:PARENT_RIGHT - WIDTH - 120 + Y:39 + Width:160 + Height:20 + Font:Regular + Text:Middle-Mouse Scrolling: + Align:Right + DropDownButton@MOUSE_SCROLL: + X:PARENT_RIGHT - WIDTH - 15 + Y:38 + Width:100 + Height:25 + Font:Regular + Text:Enabled + Checkbox@EDGESCROLL_CHECKBOX: + X:15 + Y:70 + Width:130 + Height:20 + Font:Regular + Text:Edge Scrolling + Label@SCROLL_SPEED_LABEL: + X:PARENT_RIGHT - WIDTH - 270 + Y:67 + Width:95 + Height:25 + Text:Scroll Speed: + Align:Right + Slider@SCROLLSPEED_SLIDER: + X:PARENT_RIGHT - WIDTH - 15 + Y:73 + Width:250 + Height:20 + Ticks:5 + MinimumValue: 10 + MaximumValue: 50 + Label@HOTKEY_TITLE: + Y:115 + Width:PARENT_RIGHT + Font:Bold + Text:Hotkeys + Align:Center + ScrollPanel@HOTKEY_LIST: + X:15 + Y:135 + Width:560 + ItemSpacing:4 + Height:110 + Children: + ScrollItem@HEADER: + BaseName:scrollheader + Width:528 + Height:13 + Visible:false + Children: + Label@LABEL: + Font:TinyBold + Width:PARENT_RIGHT + Height:10 + Align:Center + Container@GLOBAL_TEMPLATE: + Width:262 + Height:25 + Visible:false + Children: + Label@FUNCTION: + Y:0-1 + Width:PARENT_RIGHT - 85 + Height:25 + Align:Right + HotkeyEntry@HOTKEY: + X:PARENT_RIGHT-WIDTH + Width:80 + Height:25 + Container@UNIT_TEMPLATE: + Width:173 + Height:25 + Visible:false + Children: + Label@FUNCTION: + Y:0-1 + Width:PARENT_RIGHT - 84 + Height:25 + Align:Right + HotkeyEntry@HOTKEY: + X:PARENT_RIGHT-WIDTH+1 + Width:80 + Height:25 + Container@ADVANCED_PANEL: + X:5 + Y:50 + Width:PARENT_RIGHT - 10 + Height:PARENT_BOTTOM + Children: + Checkbox@NAT_DISCOVERY: + X:15 + Y:40 + Width:200 + Height:20 + Font:Regular + Text: Enable Network Discovery (UPnP) + Checkbox@CRASH_DIALOG_CHECKBOX: + X:310 + Y:40 + Width:300 + Height:20 + Font:Regular + Text:Show Fatal Error dialog + Checkbox@PERFTEXT_CHECKBOX: + X:15 + Y:70 + Width:300 + Height:20 + Font:Regular + Text:Show Performance Text + Checkbox@PERFGRAPH_CHECKBOX: + X:310 + Y:70 + Width:300 + Height:20 + Font:Regular + Text:Show Performance Graph + Checkbox@DEVELOPER_MENU_CHECKBOX: + X:15 + Y:100 + Width:300 + Height:20 + Font:Regular + Text:Enable Asset Browser (requires restart) + Label@HOTKEY_TITLE: + Y:140 + Width:PARENT_RIGHT + Font:Bold + Text:Debug + Align:Center + Checkbox@BOTDEBUG_CHECKBOX: + X:15 + Y:160 + Width:300 + Height:20 + Font:Regular + Text:Show Bot Debug Messages + Checkbox@VERBOSE_NAT_CHECKBOX: + X:310 + Y:160 + Width:300 + Height:20 + Font:Regular + Text:Detailed NAT logging + Checkbox@CHECKUNSYNCED_CHECKBOX: + X:15 + Y:190 + Width:300 + Height:20 + Font:Regular + Text:Check Sync around Unsynced Code \ No newline at end of file diff --git a/mods/ts/chrome.yaml b/mods/ts/chrome.yaml index 32332bf4eb..78f590ea7e 100644 --- a/mods/ts/chrome.yaml +++ b/mods/ts/chrome.yaml @@ -436,18 +436,8 @@ scrollpanel-bg: dialog.png corner-bl: 640,127,1,1 corner-br: 767,127,1,1 - -# A copy of dialog2 (normal button) -slider-tick: dialog.png - background: 513,1,126,126 - border-r: 639,1,1,126 - border-l: 512,1,1,126 - border-b: 513,127,126,1 - border-t: 513,0,126,1 - corner-tl: 512,0,1,1 - corner-tr: 639,0,1,1 - corner-bl: 512,127,1,1 - corner-br: 639,127,1,1 +slider: dialog.png + tick: 512,1,1,4 # A copy of dialog3 (pressed button) slider-track: dialog.png