mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-10-16 23:49:19 +02:00
Show the eu07.ini key on every settings row
This commit is contained in:
37
StarterNG.Tests/SettingKeyCatalogTests.cs
Normal file
37
StarterNG.Tests/SettingKeyCatalogTests.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using StarterNG.Infrastructure.Settings;
|
||||
|
||||
namespace StarterNG.Tests;
|
||||
|
||||
public class SettingKeyCatalogTests
|
||||
{
|
||||
[Fact]
|
||||
public void A_clamped_key_is_annotated_with_its_default_and_range()
|
||||
{
|
||||
Assert.Equal("dynamiclights = 7 (0-7)", SettingKeyCatalog.Annotate("dynamiclights"));
|
||||
Assert.Equal("starter.bufferscale = 100 (50-200)", SettingKeyCatalog.Annotate("starter.bufferscale"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void An_unclamped_key_is_annotated_with_its_default_alone()
|
||||
{
|
||||
Assert.Equal("maxtexturesize = 4096", SettingKeyCatalog.Annotate("maxtexturesize"));
|
||||
Assert.Equal("vsync = false", SettingKeyCatalog.Annotate("vsync"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_composite_or_unknown_key_is_shown_as_written()
|
||||
{
|
||||
Assert.Equal("shadowtune", SettingKeyCatalog.Annotate("shadowtune"));
|
||||
Assert.Equal("", SettingKeyCatalog.Annotate(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void The_annotation_matches_what_the_serializer_actually_defaults_to()
|
||||
{
|
||||
var settings = new StarterNG.Domain.Settings.SimulatorSettings();
|
||||
new SettingsSerializer().Read(settings, new StarterNG.Classes.ConfigFile());
|
||||
|
||||
Assert.Equal($"maxtexturesize = {settings.MaxTextureSize}", SettingKeyCatalog.Annotate("maxtexturesize"));
|
||||
Assert.Equal($"fieldofview = {settings.FieldOfView} (15-75)", SettingKeyCatalog.Annotate("fieldofview"));
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@ namespace StarterNG.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// One line of the settings panel: label on the left, the control itself in the
|
||||
/// middle, a value read-out on the right and an optional description underneath.
|
||||
/// middle, a value read-out on the right, and underneath the eu07.ini key this
|
||||
/// row writes plus an optional description.
|
||||
/// Replaces the hand-rolled StackPanel/DockPanel pattern that used to be repeated
|
||||
/// for every setting.
|
||||
/// </summary>
|
||||
@@ -17,6 +18,15 @@ public class SettingRow : ContentControl
|
||||
public static readonly StyledProperty<string?> DescriptionProperty =
|
||||
AvaloniaProperty.Register<SettingRow, string?>(nameof(Description));
|
||||
|
||||
/// <summary>
|
||||
/// The eu07.ini key this row reads and writes, shown verbatim so a user can
|
||||
/// match what they see here against the file, the wiki or a forum post. Rows
|
||||
/// that are starter-only preferences carry their "starter.*" key just the
|
||||
/// same; rows that write no key at all leave this empty.
|
||||
/// </summary>
|
||||
public static readonly StyledProperty<string?> ConfigKeyProperty =
|
||||
AvaloniaProperty.Register<SettingRow, string?>(nameof(ConfigKey));
|
||||
|
||||
public static readonly StyledProperty<string?> ValueTextProperty =
|
||||
AvaloniaProperty.Register<SettingRow, string?>(nameof(ValueText));
|
||||
|
||||
@@ -32,6 +42,12 @@ public class SettingRow : ContentControl
|
||||
set => SetValue(DescriptionProperty, value);
|
||||
}
|
||||
|
||||
public string? ConfigKey
|
||||
{
|
||||
get => GetValue(ConfigKeyProperty);
|
||||
set => SetValue(ConfigKeyProperty, value);
|
||||
}
|
||||
|
||||
public string? ValueText
|
||||
{
|
||||
get => GetValue(ValueTextProperty);
|
||||
@@ -49,6 +65,7 @@ public class SettingRow : ContentControl
|
||||
|
||||
if (change.Property == LabelProperty ||
|
||||
change.Property == DescriptionProperty ||
|
||||
change.Property == ConfigKeyProperty ||
|
||||
change.Property == ValueTextProperty ||
|
||||
change.Property == ContentProperty)
|
||||
UpdatePseudoClasses();
|
||||
@@ -62,6 +79,7 @@ public class SettingRow : ContentControl
|
||||
{
|
||||
PseudoClasses.Set(":no-label", string.IsNullOrEmpty(Label));
|
||||
PseudoClasses.Set(":no-description", string.IsNullOrEmpty(Description));
|
||||
PseudoClasses.Set(":no-key", string.IsNullOrEmpty(ConfigKey));
|
||||
PseudoClasses.Set(":no-value", string.IsNullOrEmpty(ValueText));
|
||||
// A read-only row is a label and a reading with no widget between them. The
|
||||
// reading then takes the middle column too, so a long path ellipsises instead
|
||||
|
||||
121
StarterNG/Infrastructure/Settings/SettingKeyCatalog.cs
Normal file
121
StarterNG/Infrastructure/Settings/SettingKeyCatalog.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace StarterNG.Infrastructure.Settings;
|
||||
|
||||
/// <summary>What the settings screen can state about a key without describing it.</summary>
|
||||
/// <param name="Key">The eu07.ini key itself.</param>
|
||||
/// <param name="Default">The value the simulator assumes when the key is absent.</param>
|
||||
/// <param name="Range">"lo-hi" when the starter clamps the value, otherwise null.</param>
|
||||
public readonly record struct SettingKeyInfo(string Key, string? Default, string? Range);
|
||||
|
||||
/// <summary>
|
||||
/// The default and the accepted range of every eu07.ini key the starter writes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Read straight off <see cref="SettingsSerializer"/> - these are the same
|
||||
/// literals that method defaults and clamps with - so the settings screen can
|
||||
/// state a fact about each key rather than a description of it. If a default or
|
||||
/// a clamp changes in the serializer, it changes here too.
|
||||
/// </remarks>
|
||||
public static class SettingKeyCatalog
|
||||
{
|
||||
private static readonly Dictionary<string, SettingKeyInfo> Entries = new()
|
||||
{
|
||||
["ai.trainman"] = new("ai.trainman", "true", null),
|
||||
["anisotropicfiltering"] = new("anisotropicfiltering", "8", null),
|
||||
["async.trainThreads"] = new("async.trainThreads", "0", null),
|
||||
["brakespeed"] = new("brakespeed", "3.0", null),
|
||||
["brakestep"] = new("brakestep", "1.0", null),
|
||||
["compresstex"] = new("compresstex", "true", null),
|
||||
["convertmodels"] = new("convertmodels", "0", null),
|
||||
["crashdamage"] = new("crashdamage", "true", null),
|
||||
["debugmode"] = new("debugmode", "false", null),
|
||||
["dynamiclights"] = new("dynamiclights", "7", "0-7"),
|
||||
["enabletraction"] = new("enabletraction", "true", null),
|
||||
["feedbackmode"] = new("feedbackmode", "1", "0-5"),
|
||||
["feedbackport"] = new("feedbackport", "888", null),
|
||||
["fieldofview"] = new("fieldofview", "45", "15-75"),
|
||||
["fpslimit"] = new("fpslimit", "30", "1-100"),
|
||||
["friction"] = new("friction", "1.0", null),
|
||||
["fullphysics"] = new("fullphysics", "true", null),
|
||||
["fullscreen"] = new("fullscreen", "false", null),
|
||||
["fullscreenwindowed"] = new("fullscreenwindowed", "false", null),
|
||||
["gfx.drawrange.factor.max"] = new("gfx.drawrange.factor.max", "3.0", null),
|
||||
["gfx.envmap.enabled"] = new("gfx.envmap.enabled", "true", null),
|
||||
["gfx.extraeffects"] = new("gfx.extraeffects", "true", null),
|
||||
["gfx.postfx.chromaticaberration.enabled"] = new("gfx.postfx.chromaticaberration.enabled", "true", null),
|
||||
["gfx.postfx.motionblur.enabled"] = new("gfx.postfx.motionblur.enabled", "true", null),
|
||||
["gfx.reflections.fidelity"] = new("gfx.reflections.fidelity", "0", "0-2"),
|
||||
["gfx.reflections.framerate"] = new("gfx.reflections.framerate", "60", null),
|
||||
["gfx.resource.move"] = new("gfx.resource.move", "false", null),
|
||||
["gfx.resource.sweep"] = new("gfx.resource.sweep", "true", null),
|
||||
["gfx.shadergamma"] = new("gfx.shadergamma", "false", null),
|
||||
["gfx.shadow.angle.min"] = new("gfx.shadow.angle.min", "0.2", null),
|
||||
["gfx.shadow.rank.cutoff"] = new("gfx.shadow.rank.cutoff", "3", null),
|
||||
["gfx.shadows.cab.range"] = new("gfx.shadows.cab.range", "0", null),
|
||||
["gfx.skippipeline"] = new("gfx.skippipeline", "false", null),
|
||||
["gfx.skiprendering"] = new("gfx.skiprendering", "false", null),
|
||||
["gfx.smoke"] = new("gfx.smoke", "true", null),
|
||||
["gfx.smoke.fidelity"] = new("gfx.smoke.fidelity", "1", "1-4"),
|
||||
["gfx.usegles"] = new("gfx.usegles", "false", null),
|
||||
["height"] = new("height", "720", null),
|
||||
["inactivepause"] = new("inactivepause", "true", null),
|
||||
["input.gamepad"] = new("input.gamepad", "true", null),
|
||||
["lang"] = new("lang", "en", null),
|
||||
["livetraction"] = new("livetraction", "true", null),
|
||||
["maxcabtexturesize"] = new("maxcabtexturesize", "4096", null),
|
||||
["maxtexturesize"] = new("maxtexturesize", "4096", null),
|
||||
["multiplelogs"] = new("multiplelogs", "false", null),
|
||||
["multisampling"] = new("multisampling", "2", "0-3"),
|
||||
["pause"] = new("pause", "false", null),
|
||||
["physicslog"] = new("physicslog", "false", null),
|
||||
["python.enabled"] = new("python.enabled", "true", null),
|
||||
["python.mipmaps"] = new("python.mipmaps", "true", null),
|
||||
["python.threadedupload"] = new("python.threadedupload", "true", null),
|
||||
["python.updatetime"] = new("python.updatetime", "200", null),
|
||||
["scalespeculars"] = new("scalespeculars", "true", null),
|
||||
["shadows"] = new("shadows", "true", null),
|
||||
["sound.volume"] = new("sound.volume", "1.0", null),
|
||||
["sound.volume.ambient"] = new("sound.volume.ambient", "1.0", null),
|
||||
["sound.volume.positional"] = new("sound.volume.positional", "1.0", null),
|
||||
["sound.volume.radio"] = new("sound.volume.radio", "0.75", null),
|
||||
["sound.volume.vehicle"] = new("sound.volume.vehicle", "1.0", null),
|
||||
["soundenabled"] = new("soundenabled", "true", null),
|
||||
["splinefidelity"] = new("splinefidelity", "1", "1-4"),
|
||||
["starter.autoclose"] = new("starter.autoclose", "false", null),
|
||||
["starter.batterydefault"] = new("starter.batterydefault", "0", "0-2"),
|
||||
["starter.bufferscale"] = new("starter.bufferscale", "100", "50-200"),
|
||||
["starter.drivableonly"] = new("starter.drivableonly", "true", null),
|
||||
["starter.exe.auto"] = new("starter.exe.auto", "true", null),
|
||||
["starter.exe.path"] = new("starter.exe.path", "eu07.exe", null),
|
||||
["starter.expandtree"] = new("starter.expandtree", "false", null),
|
||||
["starter.hide.archivalvehicles"] = new("starter.hide.archivalvehicles", "true", null),
|
||||
["starter.ignoreirrelevant"] = new("starter.ignoreirrelevant", "false", null),
|
||||
["starter.largethumbnails"] = new("starter.largethumbnails", "false", null),
|
||||
["starter.last.scenery"] = new("starter.last.scenery", null, null),
|
||||
["starter.logmissingvehicles"] = new("starter.logmissingvehicles", "false", null),
|
||||
["starter.show.ai"] = new("starter.show.ai", "true", null),
|
||||
["starter.show.archival"] = new("starter.show.archival", "true", null),
|
||||
["starter.window.maximized"] = new("starter.window.maximized", "false", null),
|
||||
["uart"] = new("uart", null, null),
|
||||
["uartdebug"] = new("uartdebug", "false", null),
|
||||
["uarttune"] = new("uarttune", null, null),
|
||||
["usevbo"] = new("usevbo", "true", null),
|
||||
["vsync"] = new("vsync", "false", null),
|
||||
["width"] = new("width", "1280", null),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The key annotation for a settings row: the key, its default and its range,
|
||||
/// e.g. "dynamiclights = 7 (0-7)". Empty for a key we know nothing about, and
|
||||
/// for the composite keys a row only partly owns.
|
||||
/// </summary>
|
||||
public static string Annotate(string? key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key) || !Entries.TryGetValue(key, out var info))
|
||||
return key ?? "";
|
||||
|
||||
string text = info.Default is null ? info.Key : $"{info.Key} = {info.Default}";
|
||||
return info.Range is null ? text : $"{text} ({info.Range})";
|
||||
}
|
||||
}
|
||||
@@ -53,13 +53,25 @@
|
||||
VerticalAlignment="Center"
|
||||
Margin="12,0,0,0" />
|
||||
|
||||
<TextBlock Name="PART_Description"
|
||||
Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Text="{TemplateBinding Description}"
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource CarbonFgDim}"
|
||||
TextWrapping="Wrap"
|
||||
Margin="0,3,0,0" />
|
||||
<!-- Second line: the eu07.ini key this row writes, then the
|
||||
explanation. The key is monospaced and selectable so it
|
||||
can be matched against the file itself. -->
|
||||
<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Orientation="Horizontal" Spacing="8" Margin="0,3,0,0">
|
||||
<SelectableTextBlock Name="PART_ConfigKey"
|
||||
Text="{TemplateBinding ConfigKey}"
|
||||
FontFamily="Consolas, DejaVu Sans Mono, Liberation Mono, Menlo, Courier New"
|
||||
FontSize="11"
|
||||
Foreground="{StaticResource CarbonAccentBright}"
|
||||
Opacity="0.75"
|
||||
VerticalAlignment="Top" />
|
||||
<TextBlock Name="PART_Description"
|
||||
Text="{TemplateBinding Description}"
|
||||
FontSize="12"
|
||||
Foreground="{StaticResource CarbonFgDim}"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Top" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
@@ -67,6 +79,9 @@
|
||||
<Style Selector="^:no-description /template/ TextBlock#PART_Description">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^:no-key /template/ SelectableTextBlock#PART_ConfigKey">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^:no-value /template/ TextBlock#PART_Value">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
|
||||
@@ -79,29 +79,29 @@
|
||||
Text="{Binding [General], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ctl:SettingsSection Header="{Binding [General], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Label="{Binding [Language], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="lang" Label="{Binding [Language], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="ChangeLanguageCb"
|
||||
SelectionChanged="LanguageComboBox_OnSelectionChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="fullscreen">
|
||||
<CheckBox x:Name="FullscreenCb" Content="{Binding [Fullscreen], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="inactivepause">
|
||||
<CheckBox x:Name="PauseInactiveCb" Content="{Binding [PauseSimInactive], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="pause">
|
||||
<CheckBox x:Name="PauseStartCb" Content="{Binding [PauseSimStart], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="CursorSensitivityRow"
|
||||
<ctl:SettingRow ConfigKey="mousescale" x:Name="CursorSensitivityRow"
|
||||
Label="{Binding [CursorSensitivity], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider x:Name="CursorSensitivitySlider" Minimum="1" Maximum="5" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="3"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="mousescale">
|
||||
<CheckBox x:Name="MouseHorInvertCb" Content="{Binding [MouseHorInvert], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="mousescale">
|
||||
<CheckBox x:Name="MouseVertInvertCb" Content="{Binding [MouseVertInvert], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
</StackPanel>
|
||||
@@ -109,16 +109,16 @@
|
||||
|
||||
<ctl:SettingsSection Header="{Binding [Starter], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="starter.autoclose">
|
||||
<CheckBox x:Name="AutoCloseStarterCb" Content="{Binding [AutoCloseStarter], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="starter.largethumbnails">
|
||||
<CheckBox x:Name="LargeThumbnailsCb" Content="{Binding [LargeThumbnails], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="starter.expandtree">
|
||||
<CheckBox x:Name="AutoExpandTreeCb" Content="{Binding [AutoExpandSceneryTree], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [BatteryDefault], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="starter.batterydefault" Label="{Binding [BatteryDefault], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [BatteryDefaultDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="BatteryDefaultCb" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [BatteryDefaultScenario], Source={x:Static starterNg:App.Loc}}" />
|
||||
@@ -131,16 +131,16 @@
|
||||
|
||||
<ctl:SettingsSection Header="{Binding [Others], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Label="{Binding [SelectEXE], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="starter.exe.path" Label="{Binding [SelectEXE], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="SelectExeCb" SelectedIndex="0" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="debugmode">
|
||||
<CheckBox x:Name="DebugModeCb" Content="{Binding [DebugMode], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [VirtualShuntingDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="ai.trainman" Description="{Binding [VirtualShuntingDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="VirtualShuntingCb" Content="{Binding [VirtualShunting], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [LogMissingVehicleFilesDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="starter.logmissingvehicles" Description="{Binding [LogMissingVehicleFilesDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="LogMissingVehicleFilesCb" Content="{Binding [LogMissingVehicleFiles], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
</StackPanel>
|
||||
@@ -153,7 +153,7 @@
|
||||
Text="{Binding [Graphic], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ctl:SettingsSection Header="{Binding [GfxColResolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Label="{Binding [Resolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="width, height" Label="{Binding [Resolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="ResolutionCb" SelectedIndex="0">
|
||||
<ComboBoxItem>3840x2160</ComboBoxItem>
|
||||
<ComboBoxItem>2560x1440</ComboBoxItem>
|
||||
@@ -163,49 +163,49 @@
|
||||
<ComboBoxItem>1280x720</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="fullscreenwindowed">
|
||||
<CheckBox x:Name="FullscreenWindowedCb" Content="{Binding [FullscreenWindowed], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [BufforResolution], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="starter.bufferscale" Label="{Binding [BufforResolution], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [BufforResolutionDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #bufferScale.Value, StringFormat='{}{0:0}%'}">
|
||||
<Slider Name="bufferScale" Minimum="50" Maximum="200" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="TexResolutionRow"
|
||||
<ctl:SettingRow ConfigKey="maxtexturesize" x:Name="TexResolutionRow"
|
||||
Label="{Binding [MaxTexResolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider Name="textureResolutionSlider" Minimum="9" Maximum="14" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="12"
|
||||
ValueChanged="TextureResolutionSlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="CabTexResolutionRow"
|
||||
<ctl:SettingRow ConfigKey="maxcabtexturesize" x:Name="CabTexResolutionRow"
|
||||
Label="{Binding [MaxTexCabResolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider Name="cabTextureResolutionSlider" Minimum="9" Maximum="14" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="12"
|
||||
ValueChanged="CabTextureResolutionSlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="TexFilteringRow"
|
||||
<ctl:SettingRow ConfigKey="anisotropicfiltering" x:Name="TexFilteringRow"
|
||||
Label="{Binding [TexFilteringQuality], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [TexFilteringQualityDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider x:Name="TexFilteringSlider" Minimum="1" Maximum="5" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="4"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="MultisamplingRow"
|
||||
<ctl:SettingRow ConfigKey="multisampling" x:Name="MultisamplingRow"
|
||||
Label="{Binding [Multisampling], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [MultisamplingDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider x:Name="MultisamplingSlider" Minimum="1" Maximum="4" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="3"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="TrackCurvesRow"
|
||||
<ctl:SettingRow ConfigKey="splinefidelity" x:Name="TrackCurvesRow"
|
||||
Label="{Binding [TrackCurvesQuality], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [TrackCurvesQualityDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider x:Name="TrackCurvesSlider" Minimum="1" Maximum="4" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="4"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="RenderRangeRow"
|
||||
<ctl:SettingRow ConfigKey="gfx.drawrange.factor.max" x:Name="RenderRangeRow"
|
||||
Label="{Binding [RenderRange], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [RenderRangeDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider x:Name="RenderRangeSlider" Minimum="1" Maximum="3" TickFrequency="1"
|
||||
@@ -217,7 +217,7 @@
|
||||
|
||||
<ctl:SettingsSection Header="{Binding [GfxColRendering], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Label="{Binding [RenderEngine], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="gfxrenderer" Label="{Binding [RenderEngine], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [RenderEngineDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="RenderEngineCb" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [REFull], Source={x:Static starterNg:App.Loc}}" />
|
||||
@@ -228,42 +228,42 @@
|
||||
<ComboBoxItem Content="{Binding [REExperimental], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [RenderAngleVulkanDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="gfx.angleplatform" Description="{Binding [RenderAngleVulkanDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RenderAngleVulkanCb" Content="{Binding [RenderAngleVulkan], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.extraeffects">
|
||||
<CheckBox x:Name="AdditionalShadersCb" Content="{Binding [AdditionalShadersEffects], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.chromaticaberration.enabled">
|
||||
<CheckBox x:Name="ChromaticAberrationCb" Content="{Binding [ChromaticAberration], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.postfx.motionblur.enabled">
|
||||
<CheckBox x:Name="MotionBlurCb" Content="{Binding [MotionBlur], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [SkipPipelineDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="gfx.skippipeline" Description="{Binding [SkipPipelineDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="SkipPipelineCb" Content="{Binding [SkipPipeline], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [RenderVBODesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="usevbo" Description="{Binding [RenderVBODesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RenderVBOCb" Content="{Binding [RenderVBO], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [VSyncDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="vsync" Description="{Binding [VSyncDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="VSyncCb" Content="{Binding [VSync], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
|
||||
<ctl:SettingRow Margin="0,0,0,4"
|
||||
<ctl:SettingRow ConfigKey="fpslimit" Margin="0,0,0,4"
|
||||
ValueText="{Binding #FpsLimitSlider.Value, StringFormat='{}{0:0} FPS'}">
|
||||
<CheckBox x:Name="FpsLimitEnableCb" Content="{Binding [FpsLimitEnable], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="fpslimit">
|
||||
<Slider x:Name="FpsLimitSlider" Minimum="1" Maximum="100" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="30"
|
||||
IsEnabled="{Binding #FpsLimitEnableCb.IsChecked}" />
|
||||
</ctl:SettingRow>
|
||||
|
||||
<ctl:SettingRow Margin="0,0,0,4">
|
||||
<ctl:SettingRow ConfigKey="gfx.smoke" Margin="0,0,0,4">
|
||||
<CheckBox x:Name="SmokeDisplayCb" Content="{Binding [SmokeDisplay], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="SmokeParticlesRow"
|
||||
<ctl:SettingRow ConfigKey="gfx.smoke.fidelity" x:Name="SmokeParticlesRow"
|
||||
Label="{Binding [SmokeParticlesMultiplier], Source={x:Static starterNg:App.Loc}}"
|
||||
IsEnabled="{Binding #SmokeDisplayCb.IsChecked}">
|
||||
<Slider x:Name="SmokeParticlesSlider" Minimum="1" Maximum="4" TickFrequency="1"
|
||||
@@ -271,12 +271,12 @@
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
|
||||
<ctl:SettingRow Label="{Binding [DynamicLights], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="dynamiclights" Label="{Binding [DynamicLights], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #DynamicLightsSlider.Value, StringFormat='{}{0:0}'}">
|
||||
<Slider x:Name="DynamicLightsSlider" Minimum="0" Maximum="7" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="7" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [FieldOfView], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="fieldofview" Label="{Binding [FieldOfView], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [FieldOfViewDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #fovSlider.Value, StringFormat='{}{0:0}°'}">
|
||||
<Slider Name="fovSlider" Minimum="15" Maximum="75" TickFrequency="5"
|
||||
@@ -291,33 +291,33 @@
|
||||
Content="{Binding [RenderShadows], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingsSection.Toggle>
|
||||
<StackPanel IsEnabled="{Binding #RenderShadowsCb.IsChecked}">
|
||||
<ctl:SettingRow Label="{Binding [ShadowDisplay], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="gfx.shadow.rank.cutoff" Label="{Binding [ShadowDisplay], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="ShadowDisplayCb" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [CSROnlyImportant], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [CSRLimited], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [CSRAll], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="ShadowResolutionRow"
|
||||
<ctl:SettingRow ConfigKey="shadowtune" x:Name="ShadowResolutionRow"
|
||||
Label="{Binding [ShadowsResolution], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider Name="shaderResolutionSlider" Minimum="9" Maximum="14" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="12"
|
||||
ValueChanged="shaderResolutionSlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="ShadowRangeRow"
|
||||
<ctl:SettingRow ConfigKey="shadowtune" x:Name="ShadowRangeRow"
|
||||
Label="{Binding [ShaderRange], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider Name="shaderRange" Minimum="25" Maximum="400" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="150"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="CabShadowRangeRow"
|
||||
<ctl:SettingRow ConfigKey="gfx.shadows.cab.range" x:Name="CabShadowRangeRow"
|
||||
Label="{Binding [CabShadowsRange], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [CabShadowsRangeDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider Name="cabShaderSourceRange" Minimum="0" Maximum="100" TickFrequency="10"
|
||||
IsSnapToTickEnabled="True" Value="30"
|
||||
ValueChanged="QualitySlider_OnValueChanged" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [ShadowAngleLimit], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="gfx.shadow.angle.min" Label="{Binding [ShadowAngleLimit], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [ShadowAngleLimitDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #ShadowAngleLimitSlider.Value, StringFormat='{}{0:0.0}'}">
|
||||
<StackPanel>
|
||||
@@ -336,10 +336,10 @@
|
||||
|
||||
<ctl:SettingsSection Header="{Binding [GfxColReflections], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Description="{Binding [ReflectionsCubeMapDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="gfx.envmap.enabled" Description="{Binding [ReflectionsCubeMapDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="ReflectionsCubeMapCb" Content="{Binding [ReflectionsCubeMap], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [ReflectionsDetails], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="gfx.reflections.fidelity" Label="{Binding [ReflectionsDetails], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [ReflectionsDetailsDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="ReflectionsDetailsCb" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [RDTerrain], Source={x:Static starterNg:App.Loc}}" />
|
||||
@@ -347,7 +347,7 @@
|
||||
<ComboBoxItem Content="{Binding [RDTerrainModelsVehicles], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="ReflectionsFramerateRow"
|
||||
<ctl:SettingRow ConfigKey="gfx.reflections.framerate" x:Name="ReflectionsFramerateRow"
|
||||
Label="{Binding [ReflectionsFramerate], Source={x:Static starterNg:App.Loc}}">
|
||||
<Slider Name="reflectionsFramerate" Minimum="5" Maximum="120" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="30"
|
||||
@@ -358,13 +358,13 @@
|
||||
|
||||
<ctl:SettingsSection Header="{Binding [GfxColScripts], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Description="{Binding [RenderScreensDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="python.enabled" Description="{Binding [RenderScreensDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="RenderScreensCb" Content="{Binding [RenderScreens], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="python.threadedupload">
|
||||
<CheckBox x:Name="RenderScreensThreadCb" Content="{Binding [RenderScreensThread], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [PyScreenPriority], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="python.updatetime" Label="{Binding [PyScreenPriority], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [PyScreenPriorityDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="PyScreenPriorityCb">
|
||||
<ComboBoxItem Tag="200" Content="{Binding [PyPriorityNormal], Source={x:Static starterNg:App.Loc}}" />
|
||||
@@ -387,27 +387,27 @@
|
||||
Content="{Binding [EnableSounds], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingsSection.Toggle>
|
||||
<StackPanel IsEnabled="{Binding #EnableSoundsCb.IsChecked}">
|
||||
<ctl:SettingRow Label="{Binding [Volume], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="sound.volume" Label="{Binding [Volume], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #VolumeSlider.Value, StringFormat='{}{0:0}%'}">
|
||||
<Slider x:Name="VolumeSlider" Minimum="1" Maximum="100" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [RadiophoneVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="sound.volume.radio" Label="{Binding [RadiophoneVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #RadioVolumeSlider.Value, StringFormat='{}{0:0}%'}">
|
||||
<Slider x:Name="RadioVolumeSlider" Minimum="1" Maximum="100" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [VehiclesVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="sound.volume.vehicle" Label="{Binding [VehiclesVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #VehiclesVolumeSlider.Value, StringFormat='{}{0:0}%'}">
|
||||
<Slider x:Name="VehiclesVolumeSlider" Minimum="1" Maximum="100" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [PositionedSoundsVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="sound.volume.positional" Label="{Binding [PositionedSoundsVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #PositionalVolumeSlider.Value, StringFormat='{}{0:0}%'}">
|
||||
<Slider x:Name="PositionalVolumeSlider" Minimum="1" Maximum="100" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [AmbientVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="sound.volume.ambient" Label="{Binding [AmbientVolume], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #AmbientVolumeSlider.Value, StringFormat='{}{0:0}%'}">
|
||||
<Slider x:Name="AmbientVolumeSlider" Minimum="1" Maximum="100" TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
@@ -422,45 +422,45 @@
|
||||
Text="{Binding [Physics], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ctl:SettingsSection Header="{Binding [Physics], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Description="{Binding [PhysicsAccuracyIncreasedDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="fullphysics" Description="{Binding [PhysicsAccuracyIncreasedDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="PhysicsAccuracyCb" Content="{Binding [PhysicsAccuracyIncreased], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [BreakingPantographPossibilityDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="enabletraction" Description="{Binding [BreakingPantographPossibilityDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="PantographBreakCb" Content="{Binding [BreakingPantographPossibility], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Description="{Binding [PowerOverheadLineOnlyDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="livetraction" Description="{Binding [PowerOverheadLineOnlyDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="OverheadOnlyCb" Content="{Binding [PowerOverheadLineOnly], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="physicslog">
|
||||
<CheckBox x:Name="SpeedometerTapesCb" Content="{Binding [SaveSpeedometerTapes], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="debuglog">
|
||||
<CheckBox x:Name="SimLogsCb" Content="{Binding [SaveSimLogs], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="multiplelogs">
|
||||
<CheckBox x:Name="KeepLogsCb" Content="{Binding [KeepPrevLogs], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="gfx.skiprendering">
|
||||
<CheckBox x:Name="DisplaySimulationCb" Content="{Binding [DisplaySimulation], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="debuglog">
|
||||
<CheckBox x:Name="DebugLogVisibleCb" Content="{Binding [DebugLogVisible], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow>
|
||||
<ctl:SettingRow ConfigKey="crashdamage">
|
||||
<CheckBox x:Name="CrashDamageCb" Content="{Binding [CrashDamage], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
|
||||
<ctl:SettingRow Label="{Binding [Friction], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="friction" Label="{Binding [Friction], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [FrictionDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #FrictionSlider.Value, StringFormat='{}{0:0.00}'}">
|
||||
<Slider x:Name="FrictionSlider" Minimum="0.1" Maximum="3.0" TickFrequency="0.1" Value="1.0" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [BrakeStep], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="brakestep" Label="{Binding [BrakeStep], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [BrakeStepDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #BrakeStepSlider.Value, StringFormat='{}{0:0.00}'}">
|
||||
<Slider x:Name="BrakeStepSlider" Minimum="0.4" Maximum="3.0" TickFrequency="0.1" Value="1.0" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [BrakeSpeed], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="brakespeed" Label="{Binding [BrakeSpeed], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [BrakeSpeedDesc], Source={x:Static starterNg:App.Loc}}"
|
||||
ValueText="{Binding #BrakeSpeedSlider.Value, StringFormat='{}{0:0.00}'}">
|
||||
<Slider x:Name="BrakeSpeedSlider" Minimum="0.4" Maximum="3.0" TickFrequency="0.1" Value="1.0" />
|
||||
@@ -475,10 +475,10 @@
|
||||
Text="{Binding [Communication], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ctl:SettingsSection Header="{Binding [Communication], Source={x:Static starterNg:App.Loc}}">
|
||||
<StackPanel>
|
||||
<ctl:SettingRow Description="{Binding [GamepadSignalIgnoreDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ctl:SettingRow ConfigKey="input.gamepad" Description="{Binding [GamepadSignalIgnoreDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<CheckBox x:Name="GamepadIgnoreCb" Content="{Binding [GamepadSignalIgnore], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow Label="{Binding [Feedback], Source={x:Static starterNg:App.Loc}}"
|
||||
<ctl:SettingRow ConfigKey="feedbackmode" Label="{Binding [Feedback], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [FeedbackDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<ComboBox x:Name="FeedbackCb" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [FeedbackOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
@@ -489,13 +489,13 @@
|
||||
<ComboBoxItem Tag="5" Content="{Binding [FeedbackSP], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="FeedbackPortRow" IsVisible="False"
|
||||
<ctl:SettingRow ConfigKey="feedbackport" x:Name="FeedbackPortRow" IsVisible="False"
|
||||
Label="{Binding [FeedbackPort], Source={x:Static starterNg:App.Loc}}"
|
||||
Description="{Binding [FeedbackPortDesc], Source={x:Static starterNg:App.Loc}}">
|
||||
<NumericUpDown x:Name="FeedbackPortNud" Minimum="0" Maximum="65535" Value="888"
|
||||
Increment="1" FormatString="0" />
|
||||
</ctl:SettingRow>
|
||||
<ctl:SettingRow x:Name="ComButtonRow" IsVisible="False">
|
||||
<ctl:SettingRow ConfigKey="uart" x:Name="ComButtonRow" IsVisible="False">
|
||||
<Button x:Name="ComButton" Classes="Flat" Cursor="Hand"
|
||||
HorizontalContentAlignment="Center"
|
||||
Click="ComButton_OnClick"
|
||||
|
||||
@@ -15,6 +15,7 @@ using Avalonia.Markup.Xaml.Styling;
|
||||
using Avalonia.Media;
|
||||
using StarterNG.Classes;
|
||||
using StarterNG.Controls;
|
||||
using StarterNG.Infrastructure.Settings;
|
||||
using StarterNG.Infrastructure;
|
||||
using StarterNG.Services;
|
||||
|
||||
@@ -64,6 +65,7 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
|
||||
AppServices.Current.SettingsStore.RegisterCapture(this);
|
||||
|
||||
AnnotateConfigKeys();
|
||||
PopulateProfileCombo();
|
||||
ApplyToUi();
|
||||
|
||||
@@ -160,6 +162,19 @@ public partial class Settings : UserControl, ISettingsCapture
|
||||
|
||||
public void ReloadFromSettings() => ApplyToUi();
|
||||
|
||||
/// <summary>
|
||||
/// Expands each row's eu07.ini key into "key = default (range)", so the line
|
||||
/// under a setting says what the file holds rather than paraphrasing what the
|
||||
/// setting does.
|
||||
/// </summary>
|
||||
private void AnnotateConfigKeys()
|
||||
{
|
||||
// Logical, not visual: the rows exist as soon as the XAML is loaded,
|
||||
// while categories that are not on screen yet have no visual tree.
|
||||
foreach (var row in this.GetLogicalDescendants().OfType<SettingRow>())
|
||||
row.ConfigKey = SettingKeyCatalog.Annotate(row.ConfigKey);
|
||||
}
|
||||
|
||||
private void ApplyToUi()
|
||||
{
|
||||
var s = AppServices.Current.Settings;
|
||||
|
||||
Reference in New Issue
Block a user