Rewrite C&C Settings panel.

This commit is contained in:
Paul Chote
2013-10-19 11:51:33 +13:00
parent 64a229d339
commit b278880ef6
2 changed files with 747 additions and 441 deletions

View File

@@ -25,150 +25,348 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
{ {
public class CncSettingsLogic public class CncSettingsLogic
{ {
enum PanelType { General, Input } enum PanelType { Display, Audio, Input, Advanced }
Dictionary<PanelType, Action> leavePanelActions = new Dictionary<PanelType, Action>();
Dictionary<PanelType, Action> resetPanelActions = new Dictionary<PanelType, Action>();
PanelType settingsPanel = PanelType.Display;
Widget panelContainer, tabContainer;
WorldRenderer worldRenderer;
SoundDevice soundDevice; SoundDevice soundDevice;
PanelType settingsPanel = PanelType.General;
ColorPreviewManagerWidget colorPreview;
World world;
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public CncSettingsLogic(Widget widget, World world, Action onExit, WorldRenderer worldRenderer) public CncSettingsLogic(Widget widget, Action onExit, WorldRenderer worldRenderer)
{ {
this.world = world; this.worldRenderer = worldRenderer;
var panel = widget.Get("SETTINGS_PANEL");
// General pane panelContainer = widget.Get("SETTINGS_PANEL");
var generalButton = panel.Get<ButtonWidget>("GENERAL_BUTTON"); tabContainer = panelContainer;
generalButton.OnClick = () => settingsPanel = PanelType.General;
generalButton.IsHighlighted = () => settingsPanel == PanelType.General;
var generalPane = panel.Get("GENERAL_CONTROLS"); RegisterSettingsPanel(PanelType.Display, InitDisplayPanel, ResetDisplayPanel, "DISPLAY_PANEL", "DISPLAY_TAB");
generalPane.IsVisible = () => settingsPanel == PanelType.General; 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");
var gameSettings = Game.Settings.Game; panelContainer.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
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<TextFieldWidget>("NAME_TEXTFIELD");
nameTextfield.Text = playerSettings.Name;
colorPreview = panel.Get<ColorPreviewManagerWidget>("COLOR_MANAGER");
colorPreview.Color = playerSettings.Color;
var colorDropdown = generalPane.Get<DropDownButtonWidget>("COLOR");
colorDropdown.OnMouseDown = _ => ShowColorPicker(colorDropdown, playerSettings);
colorDropdown.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => playerSettings.Color.RGB;
// Debug
var perftextCheckbox = generalPane.Get<CheckboxWidget>("PERFTEXT_CHECKBOX");
perftextCheckbox.IsChecked = () => debugSettings.PerfText;
perftextCheckbox.OnClick = () => debugSettings.PerfText ^= true;
var perfgraphCheckbox = generalPane.Get<CheckboxWidget>("PERFGRAPH_CHECKBOX");
perfgraphCheckbox.IsChecked = () => debugSettings.PerfGraph;
perfgraphCheckbox.OnClick = () => debugSettings.PerfGraph ^= true;
var checkunsyncedCheckbox = generalPane.Get<CheckboxWidget>("CHECKUNSYNCED_CHECKBOX");
checkunsyncedCheckbox.IsChecked = () => debugSettings.SanityCheckUnsyncedCode;
checkunsyncedCheckbox.OnClick = () => debugSettings.SanityCheckUnsyncedCode ^= true;
var showFatalErrorDialog = generalPane.Get<CheckboxWidget>("SHOW_FATAL_ERROR_DIALOG_CHECKBOX");
showFatalErrorDialog.IsChecked = () => Game.Settings.Debug.ShowFatalErrorDialog;
showFatalErrorDialog.OnClick = () => Game.Settings.Debug.ShowFatalErrorDialog ^= true;
// Video
var windowModeDropdown = generalPane.Get<DropDownButtonWidget>("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<CheckboxWidget>("PIXELDOUBLE_CHECKBOX");
pixelDoubleCheckbox.IsChecked = () => graphicsSettings.PixelDouble;
pixelDoubleCheckbox.OnClick = () =>
{ {
graphicsSettings.PixelDouble ^= true; leavePanelActions[settingsPanel]();
worldRenderer.Viewport.Zoom = graphicsSettings.PixelDouble ? 2 : 1;
};
var showShellmapCheckbox = generalPane.Get<CheckboxWidget>("SHOW_SHELLMAP");
showShellmapCheckbox.IsChecked = () => gameSettings.ShowShellmap;
showShellmapCheckbox.OnClick = () => gameSettings.ShowShellmap ^= true;
generalPane.Get("WINDOW_RESOLUTION").IsVisible = () => graphicsSettings.Mode == WindowMode.Windowed;
var windowWidth = generalPane.Get<TextFieldWidget>("WINDOW_WIDTH");
windowWidth.Text = graphicsSettings.WindowedSize.X.ToString();
var windowHeight = generalPane.Get<TextFieldWidget>("WINDOW_HEIGHT");
windowHeight.Text = graphicsSettings.WindowedSize.Y.ToString();
var languageDropDownButton = generalPane.Get<DropDownButtonWidget>("LANGUAGE_DROPDOWNBUTTON");
languageDropDownButton.OnMouseDown = _ => SettingsMenuLogic.ShowLanguageDropdown(languageDropDownButton);
languageDropDownButton.GetText = () => FieldLoader.Translate(Game.Settings.Graphics.Language);
// Audio
var soundSlider = generalPane.Get<SliderWidget>("SOUND_SLIDER");
soundSlider.OnChange += x => { soundSettings.SoundVolume = x; Sound.SoundVolume = x; };
soundSlider.Value = soundSettings.SoundVolume;
var musicSlider = generalPane.Get<SliderWidget>("MUSIC_SLIDER");
musicSlider.OnChange += x => { soundSettings.MusicVolume = x; Sound.MusicVolume = x; };
musicSlider.Value = soundSettings.MusicVolume;
var shellmapMusicCheckbox = generalPane.Get<CheckboxWidget>("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<DropDownButtonWidget>("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<ButtonWidget>("INPUT_BUTTON");
inputButton.OnClick = () => settingsPanel = PanelType.Input;
inputButton.IsHighlighted = () => settingsPanel == PanelType.Input;
var classicMouseCheckbox = inputPane.Get<CheckboxWidget>("CLASSICORDERS_CHECKBOX");
classicMouseCheckbox.IsChecked = () => gameSettings.UseClassicMouseStyle;
classicMouseCheckbox.OnClick = () => gameSettings.UseClassicMouseStyle ^= true;
var scrollSlider = inputPane.Get<SliderWidget>("SCROLLSPEED_SLIDER");
scrollSlider.Value = gameSettings.ViewportEdgeScrollStep;
scrollSlider.OnChange += x => gameSettings.ViewportEdgeScrollStep = x;
var edgescrollCheckbox = inputPane.Get<CheckboxWidget>("EDGESCROLL_CHECKBOX");
edgescrollCheckbox.IsChecked = () => gameSettings.ViewportEdgeScroll;
edgescrollCheckbox.OnClick = () => gameSettings.ViewportEdgeScroll ^= true;
var mouseScrollDropdown = inputPane.Get<DropDownButtonWidget>("MOUSE_SCROLL");
mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gameSettings);
mouseScrollDropdown.GetText = () => gameSettings.MouseScroll.ToString();
panel.Get<ButtonWidget>("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(); Game.Settings.Save();
Ui.CloseWindow(); Ui.CloseWindow();
onExit(); onExit();
}; };
panelContainer.Get<ButtonWidget>("RESET_BUTTON").OnClick = () =>
{
resetPanelActions[settingsPanel]();
Game.Settings.Save();
};
} }
static bool ShowMouseScrollDropdown(DropDownButtonWidget dropdown, GameSettings s) 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<CheckboxWidget>(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<SliderWidget>(id);
ss.Value = (float)field.GetValue(group);
ss.OnChange += x => field.SetValue(group, x);
}
static void BindHotkeyPref(KeyValuePair<string, string> 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<LabelWidget>("FUNCTION").GetText = () => kv.Value + ":";
var textBox = key.Get<HotkeyEntryWidget>("HOTKEY");
textBox.Key = (Hotkey)field.GetValue(ks);
textBox.OnLoseFocus = () => field.SetValue(ks, textBox.Key);
parent.AddChild(key);
}
void RegisterSettingsPanel(PanelType type, Func<Widget, Action> init, Func<Widget, Action> reset, string panelID, string buttonID)
{
var panel = panelContainer.Get(panelID);
var tab = tabContainer.Get<ButtonWidget>(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<DropDownButtonWidget>("LANGUAGE_DROPDOWNBUTTON");
languageDropDownButton.OnMouseDown = _ => SettingsMenuLogic.ShowLanguageDropdown(languageDropDownButton);
languageDropDownButton.GetText = () => FieldLoader.Translate(ds.Language);
var windowModeDropdown = panel.Get<DropDownButtonWidget>("MODE_DROPDOWN");
windowModeDropdown.OnMouseDown = _ => SettingsMenuLogic.ShowWindowModeDropdown(windowModeDropdown, ds);
windowModeDropdown.GetText = () => ds.Mode == WindowMode.Windowed ?
"Windowed" : ds.Mode == WindowMode.Fullscreen ? "Fullscreen" : "Pseudo-Fullscreen";
// Update zoom immediately
var pixelDoubleCheckbox = panel.Get<CheckboxWidget>("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<TextFieldWidget>("WINDOW_WIDTH");
windowWidth.Text = ds.WindowedSize.X.ToString();
var windowHeight = panel.Get<TextFieldWidget>("WINDOW_HEIGHT");
windowHeight.Text = ds.WindowedSize.Y.ToString();
var frameLimitTextfield = panel.Get<TextFieldWidget>("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<SliderWidget>("SOUND_VOLUME").OnChange += x => Sound.SoundVolume = x;
panel.Get<SliderWidget>("MUSIC_VOLUME").OnChange += x => Sound.MusicVolume = x;
panel.Get<SliderWidget>("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<DropDownButtonWidget>("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<SliderWidget>("SOUND_VOLUME").Value = ss.SoundVolume;
panel.Get<SliderWidget>("MUSIC_VOLUME").Value = ss.MusicVolume;
panel.Get<SliderWidget>("VIDEO_VOLUME").Value = ss.VideoVolume;
soundDevice = Sound.AvailableDevices().First();
};
}
Action InitInputPanel(Widget panel)
{
// TODO: Extract these to a yaml file
var specialHotkeys = new Dictionary<string, string>()
{
{ "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<string, string>()
{
{ "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<DropDownButtonWidget>("MOUSE_SCROLL");
mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gs);
mouseScrollDropdown.GetText = () => gs.MouseScroll.ToString();
var hotkeyList = panel.Get<ScrollPanelWidget>("HOTKEY_LIST");
hotkeyList.Layout = new GridLayout(hotkeyList);
var hotkeyHeader = hotkeyList.Get<ScrollItemWidget>("HEADER");
var globalTemplate = hotkeyList.Get("GLOBAL_TEMPLATE");
var unitTemplate = hotkeyList.Get("UNIT_TEMPLATE");
hotkeyList.RemoveChildren();
var globalHeader = ScrollItemWidget.Setup(hotkeyHeader, () => true, () => {});
globalHeader.Get<LabelWidget>("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<LabelWidget>("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<HotkeyEntryWidget>("HOTKEY").Key = value;
}
panel.Get<SliderWidget>("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<string, MouseScrollType>() var options = new Dictionary<string, MouseScrollType>()
{ {
@@ -190,26 +388,6 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
return true; return true;
} }
bool ShowColorPicker(DropDownButtonWidget color, PlayerSettings s)
{
Action<HSLColor> 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) bool ShowAudioDeviceDropdown(DropDownButtonWidget dropdown, SoundSettings s, SoundDevice[] devices)
{ {
var i = 0; var i = 0;

View File

@@ -1,313 +1,441 @@
Container@SETTINGS_PANEL: Container@SETTINGS_PANEL:
Logic:CncSettingsLogic Logic:CncSettingsLogic
X:(WINDOW_RIGHT - WIDTH)/2 X:(WINDOW_RIGHT - WIDTH)/2
Y:(WINDOW_BOTTOM - 250)/2 Y:(WINDOW_BOTTOM - HEIGHT)/2
Width:740 Width:590
Height:565 Height:260+68
Children: Children:
ColorPreviewManager@COLOR_MANAGER:
Label@TITLE: Label@TITLE:
Width:740 Width:590
Y:0-25 Y:0-25
Font:BigBold Font:BigBold
Contrast:true Contrast:true
Align:Center Align:Center
Text:Settings Text:Settings
Background@GENERAL_CONTROLS: Button@DISPLAY_TAB:
Width:740
Height:320
Background:panel-black
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
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
Width:140 Width:140
Height:35 Height:35
Text:General Text:Display
Button@INPUT_BUTTON: Button@AUDIO_TAB:
X:150 X:150
Y:319 Width:140
Height:35
Text:Audio
Button@INPUT_TAB:
X:300
Width:140 Width:140
Height:35 Height:35
Text:Input Text:Input
Button@ADVANCED_TAB:
X:450
Width:140
Height:35
Text:Advanced
Button@RESET_BUTTON:
Y:293
Width:140
Height:35
Text:Reset
Button@BACK_BUTTON: Button@BACK_BUTTON:
Key:escape Key:escape
X:600 X:PARENT_RIGHT-WIDTH
Y:319 Y:293
Width:140 Width:140
Height:35 Height:35
Text:Back 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