mirror of
https://github.com/MaSzyna-EU07/StarterNG.git
synced 2026-11-01 04:19:07 +01:00
Complete UI rebuild
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:sukiUi="clr-namespace:SukiUI.Controls;assembly=SukiUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:starterNg="clr-namespace:StarterNG"
|
||||
xmlns:views="clr-namespace:StarterNG.Views"
|
||||
x:CompileBindings="True"
|
||||
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="700"
|
||||
x:Class="StarterNG.Views.Depot">
|
||||
<Grid Margin="16" ColumnSpacing="16" RowSpacing="16">
|
||||
<Grid Margin="0" ColumnSpacing="8" RowSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="340" />
|
||||
<ColumnDefinition />
|
||||
@@ -20,29 +19,47 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Vehicle database browser (left, rows 0-1) -->
|
||||
<sukiUi:GroupBox Grid.RowSpan="2"
|
||||
Header="{Binding [VehicleDatabase], Source={x:Static starterNg:App.Loc}}">
|
||||
<HeaderedContentControl Grid.RowSpan="2" Theme="{StaticResource GroupBox}"
|
||||
Header="{Binding [VehicleDatabase], Source={x:Static starterNg:App.Loc}}">
|
||||
<DockPanel LastChildFill="True">
|
||||
<Grid DockPanel.Dock="Top" ColumnDefinitions="*,*" ColumnSpacing="6" Margin="0,0,0,6">
|
||||
<ComboBox Name="categoryCombo" Grid.Column="0" HorizontalAlignment="Stretch"
|
||||
PlaceholderText="{Binding [Category], Source={x:Static starterNg:App.Loc}}"
|
||||
SelectionChanged="CategoryCombo_OnSelectionChanged" />
|
||||
<ComboBox Name="classCombo" Grid.Column="1" HorizontalAlignment="Stretch"
|
||||
PlaceholderText="{Binding [Class], Source={x:Static starterNg:App.Loc}}"
|
||||
SelectionChanged="ClassCombo_OnSelectionChanged" />
|
||||
</Grid>
|
||||
<TextBox Name="searchBox" DockPanel.Dock="Top" Margin="0,0,0,8"
|
||||
Watermark="{Binding [Search], Source={x:Static starterNg:App.Loc}}"
|
||||
TextChanged="SearchBox_OnTextChanged" />
|
||||
<!-- Folded groups (built in code-behind); collapsed groups hold no
|
||||
controls, so the list stays light and scrolls smoothly. -->
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
|
||||
<StackPanel Name="browserStack" Spacing="2" />
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- Mini preview of the selected entry + the single Add button.
|
||||
Both are docked at the bottom, under the flat vehicle list. -->
|
||||
<Button Name="addVehicleButton" DockPanel.Dock="Bottom" Classes="Flat Accent"
|
||||
HorizontalAlignment="Stretch" HorizontalContentAlignment="Center"
|
||||
Margin="0,8,0,0" IsEnabled="False" Cursor="Hand"
|
||||
Click="AddVehicleButton_OnClick"
|
||||
Content="{Binding [AddVehicle], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Border Name="miniPreviewPanel" DockPanel.Dock="Bottom" Height="62" Margin="0,6,0,0"
|
||||
Background="{StaticResource CarbonInputBg}"
|
||||
BorderBrush="{StaticResource CarbonBorderLight}" BorderThickness="1"
|
||||
CornerRadius="2">
|
||||
<Image Name="miniPreview" Stretch="Uniform" Margin="6" />
|
||||
</Border>
|
||||
|
||||
<!-- Flat list of vehicle entries (plain text, no expanders).
|
||||
Selecting one shows its mini and enables Add; double-click
|
||||
replaces the selected consist vehicle. -->
|
||||
<ListBox Name="vehicleListBox" Classes="Compact"
|
||||
SelectionChanged="VehicleListBox_OnSelectionChanged"
|
||||
DoubleTapped="VehicleListBox_OnDoubleTapped" />
|
||||
</DockPanel>
|
||||
</sukiUi:GroupBox>
|
||||
</HeaderedContentControl>
|
||||
|
||||
<!-- Scenery + load consist (top-right) -->
|
||||
<sukiUi:GroupBox Grid.Column="1" Grid.Row="0"
|
||||
Header="{Binding [LoadFromScenery], Source={x:Static starterNg:App.Loc}}">
|
||||
<HeaderedContentControl Grid.Column="1" Grid.Row="0" Theme="{StaticResource GroupBox}"
|
||||
Header="{Binding [LoadFromScenery], Source={x:Static starterNg:App.Loc}}">
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto" ColumnSpacing="8" RowSpacing="6">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{Binding [Scenery], Source={x:Static starterNg:App.Loc}}" />
|
||||
@@ -54,11 +71,11 @@
|
||||
DropDownOpened="SceneryConsistCombo_OnDropDownOpened"
|
||||
SelectionChanged="SceneryConsistCombo_OnSelectionChanged" />
|
||||
</Grid>
|
||||
</sukiUi:GroupBox>
|
||||
</HeaderedContentControl>
|
||||
|
||||
<!-- Brakes / Loads editor (middle-right) -->
|
||||
<sukiUi:GroupBox Grid.Column="1" Grid.Row="1"
|
||||
Header="{Binding [SelectedVehicle], Source={x:Static starterNg:App.Loc}}">
|
||||
<HeaderedContentControl Grid.Column="1" Grid.Row="1" Theme="{StaticResource GroupBox}"
|
||||
Header="{Binding [SelectedVehicle], Source={x:Static starterNg:App.Loc}}">
|
||||
<DockPanel LastChildFill="True">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Spacing="8" Margin="0,0,0,8">
|
||||
<Button Name="newConsistButton" Classes="Flat" Cursor="Hand"
|
||||
@@ -81,11 +98,11 @@
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</sukiUi:GroupBox>
|
||||
</HeaderedContentControl>
|
||||
|
||||
<!-- Consist (full-width bottom, horizontally scrollable) -->
|
||||
<sukiUi:GroupBox Grid.Row="2" Grid.ColumnSpan="2"
|
||||
Header="{Binding [Consist], Source={x:Static starterNg:App.Loc}}">
|
||||
<HeaderedContentControl Grid.Row="2" Grid.ColumnSpan="2" Theme="{StaticResource GroupBox}"
|
||||
Header="{Binding [Consist], Source={x:Static starterNg:App.Loc}}">
|
||||
<Panel>
|
||||
<TextBlock Name="emptyHint" VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
TextWrapping="Wrap" MaxWidth="520" Opacity="0.6" TextAlignment="Center"
|
||||
@@ -95,6 +112,6 @@
|
||||
VerticalAlignment="Center" Spacing="0" />
|
||||
</ScrollViewer>
|
||||
</Panel>
|
||||
</sukiUi:GroupBox>
|
||||
</HeaderedContentControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -29,8 +29,7 @@ public partial class Depot : UserControl
|
||||
|
||||
// Shared, size-limited thumbnail cache (decoded down to display height).
|
||||
private readonly Dictionary<string, Bitmap?> _miniCache = new();
|
||||
private const int BrowserThumbHeight = 38;
|
||||
private const int ConsistThumbHeight = 50;
|
||||
private const int ConsistThumbHeight = 34;
|
||||
|
||||
private readonly Cursor _hand = new(StandardCursorType.Hand);
|
||||
private int _nameCounter;
|
||||
@@ -44,18 +43,21 @@ public partial class Depot : UserControl
|
||||
// scenery-consist previews are built lazily on first dropdown open
|
||||
private bool _consistPreviewsBuilt;
|
||||
|
||||
// auto-expand search results only when there are few of them
|
||||
private const int AutoExpandLimit = 40;
|
||||
private const int MaxRowsPerGroup = 250;
|
||||
|
||||
// active database filters
|
||||
private Func<string?, bool>? _categoryFilter; // matches a category letter, null = all
|
||||
private string? _classFilter; // group mini (e.g. EU07), null = all
|
||||
private Func<string?, bool>? _categoryFilter; // matches a category letter, null = none chosen
|
||||
private string? _classFilter; // group mini (e.g. EU07), null = all in category
|
||||
|
||||
// the vehicle currently highlighted in the flat list (drives the mini preview
|
||||
// and the single Add button)
|
||||
private VehicleTexture? _browserSelected;
|
||||
|
||||
// hard cap on how many entries the flat list shows at once
|
||||
private const int MaxListRows = 2000;
|
||||
|
||||
// card highlight brushes (theme-neutral overlays)
|
||||
private static readonly IBrush CardBorder = new SolidColorBrush(Color.Parse("#33888888"));
|
||||
private static readonly IBrush CardBorderSel = new SolidColorBrush(Color.Parse("#AA4D8BFF"));
|
||||
private static readonly IBrush CardBgSel = new SolidColorBrush(Color.Parse("#224D8BFF"));
|
||||
private static readonly IBrush CardBorderSel = new SolidColorBrush(Color.Parse("#AA41C400"));
|
||||
private static readonly IBrush CardBgSel = new SolidColorBrush(Color.Parse("#2241C400"));
|
||||
private static readonly IBrush Placeholder = new SolidColorBrush(Color.Parse("#22808080"));
|
||||
|
||||
// Vehicle types, keyed by the JSON "category" letter. Powered/technical
|
||||
@@ -132,7 +134,7 @@ public partial class Depot : UserControl
|
||||
_searchTimer.Tick += (_, _) =>
|
||||
{
|
||||
_searchTimer!.Stop();
|
||||
BuildBrowser();
|
||||
BuildList();
|
||||
};
|
||||
|
||||
// Defer population so the tab renders immediately, then fills in.
|
||||
@@ -275,12 +277,13 @@ public partial class Depot : UserControl
|
||||
|
||||
private void PopulateCategoryCombo()
|
||||
{
|
||||
// No "All" entry: nothing is selected by default, so the list starts empty
|
||||
// (matching the original Starter's depot).
|
||||
_suppress = true;
|
||||
categoryCombo.Items.Clear();
|
||||
categoryCombo.Items.Add(new ComboBoxItem { Content = App.Loc["All"], Tag = null });
|
||||
foreach (var (locKey, match) in CategoryDefs)
|
||||
categoryCombo.Items.Add(new ComboBoxItem { Content = App.Loc[locKey], Tag = match });
|
||||
categoryCombo.SelectedIndex = 0;
|
||||
categoryCombo.SelectedIndex = -1;
|
||||
_suppress = false;
|
||||
|
||||
_categoryFilter = null;
|
||||
@@ -289,18 +292,16 @@ public partial class Depot : UserControl
|
||||
|
||||
private void RebuildClassCombo()
|
||||
{
|
||||
// No "All" entry: an unselected class means "every class in the category".
|
||||
_suppress = true;
|
||||
classCombo.Items.Clear();
|
||||
classCombo.Items.Add(new ComboBoxItem { Content = App.Loc["All"], Tag = null });
|
||||
|
||||
foreach (string cls in ClassesForCategory(_categoryFilter))
|
||||
classCombo.Items.Add(new ComboBoxItem { Content = cls, Tag = cls });
|
||||
|
||||
classCombo.SelectedIndex = 0;
|
||||
classCombo.SelectedIndex = -1;
|
||||
_suppress = false;
|
||||
|
||||
_classFilter = null;
|
||||
BuildBrowser();
|
||||
BuildList();
|
||||
}
|
||||
|
||||
private IEnumerable<string> ClassesForCategory(Func<string?, bool>? category) =>
|
||||
@@ -322,87 +323,83 @@ public partial class Depot : UserControl
|
||||
{
|
||||
if (_suppress) return;
|
||||
_classFilter = (classCombo.SelectedItem as ComboBoxItem)?.Tag as string;
|
||||
BuildBrowser();
|
||||
BuildList();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- vehicle browser
|
||||
|
||||
// Browser groups by the JSON "group" field, rendered as collapsed expanders.
|
||||
// Collapsed groups hold no controls, so the list stays light and smooth.
|
||||
private void BuildBrowser()
|
||||
// Flat list of plain-text vehicle entries (no expanders, like the original
|
||||
// Starter). Empty by default: an entry only appears once a category is chosen
|
||||
// or a search is typed. Picking one drives the mini preview and Add button.
|
||||
private void BuildList()
|
||||
{
|
||||
browserStack.Children.Clear();
|
||||
// reset selection-dependent UI
|
||||
_browserSelected = null;
|
||||
miniPreview.Source = null;
|
||||
addVehicleButton.IsEnabled = false;
|
||||
|
||||
vehicleListBox.Items.Clear();
|
||||
|
||||
string search = searchBox.Text?.Trim() ?? "";
|
||||
bool hasSearch = search.Length > 0;
|
||||
|
||||
var matched = _db.Textures.Where(t => PassesFilters(t, search, hasSearch)).ToList();
|
||||
// nothing selected and nothing searched -> keep the list empty
|
||||
if (_categoryFilter == null && !hasSearch)
|
||||
return;
|
||||
|
||||
// Only auto-open groups when the search is specific. A broad search keeps
|
||||
// groups folded (just headers + counts) so we never realize thousands of
|
||||
// rows / decode thousands of bitmaps at once.
|
||||
bool autoExpand = hasSearch && matched.Count <= AutoExpandLimit;
|
||||
var matched = _db.Textures
|
||||
.Where(t => PassesFilters(t, search, hasSearch))
|
||||
.OrderBy(t => t.TextureMini ?? t.Skinfile, StringComparer.OrdinalIgnoreCase)
|
||||
.Take(MaxListRows)
|
||||
.ToList();
|
||||
|
||||
// fold by class (the group's mini)
|
||||
var grouped = matched
|
||||
.GroupBy(ClassOf)
|
||||
.OrderBy(g => g.Key, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var group in grouped)
|
||||
foreach (var texture in matched)
|
||||
{
|
||||
var list = group
|
||||
.OrderBy(t => t.TextureMini ?? t.Skinfile, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
string header = string.IsNullOrEmpty(group.Key)
|
||||
? App.Loc["Others"]
|
||||
: group.Key;
|
||||
|
||||
var content = new StackPanel { Spacing = 2 };
|
||||
var expander = new Expander
|
||||
vehicleListBox.Items.Add(new ListBoxItem
|
||||
{
|
||||
Header = $"{header} ({list.Count})",
|
||||
IsExpanded = autoExpand, // folded by default
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch
|
||||
};
|
||||
expander.Content = content;
|
||||
|
||||
bool populated = false;
|
||||
void Populate()
|
||||
{
|
||||
if (populated) return;
|
||||
populated = true;
|
||||
|
||||
int shown = Math.Min(list.Count, MaxRowsPerGroup);
|
||||
for (int i = 0; i < shown; i++)
|
||||
content.Children.Add(BuildBrowserItem(list[i]));
|
||||
|
||||
if (list.Count > shown)
|
||||
content.Children.Add(new TextBlock
|
||||
{
|
||||
Text = $"… +{list.Count - shown}",
|
||||
Opacity = 0.6,
|
||||
Margin = new Thickness(6, 2)
|
||||
});
|
||||
}
|
||||
|
||||
if (expander.IsExpanded)
|
||||
Populate();
|
||||
expander.Expanded += (_, _) => Populate();
|
||||
|
||||
browserStack.Children.Add(expander);
|
||||
}
|
||||
|
||||
if (browserStack.Children.Count == 0)
|
||||
{
|
||||
browserStack.Children.Add(new TextBlock
|
||||
{
|
||||
Text = App.Loc["NoVehicles"],
|
||||
Opacity = 0.6,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Margin = new Thickness(4)
|
||||
Content = BrowserLabel(texture, _db.ResolveSet(texture)),
|
||||
Tag = texture
|
||||
});
|
||||
}
|
||||
|
||||
if (vehicleListBox.Items.Count == 0)
|
||||
vehicleListBox.Items.Add(new ListBoxItem
|
||||
{
|
||||
Content = App.Loc["NoVehicles"],
|
||||
IsEnabled = false
|
||||
});
|
||||
}
|
||||
|
||||
// Selecting an entry shows its mini preview and enables the Add button.
|
||||
private void VehicleListBox_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (vehicleListBox.SelectedItem is ListBoxItem { Tag: VehicleTexture texture })
|
||||
{
|
||||
_browserSelected = texture;
|
||||
miniPreview.Source = GetMiniBitmap(_db.ResolveMiniName(texture), 54);
|
||||
addVehicleButton.IsEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_browserSelected = null;
|
||||
miniPreview.Source = null;
|
||||
addVehicleButton.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Double-click an entry to replace the selected consist vehicle.
|
||||
private void VehicleListBox_OnDoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
|
||||
{
|
||||
if (_browserSelected != null)
|
||||
ReplaceSelected(_browserSelected);
|
||||
}
|
||||
|
||||
// The single Add button inserts the highlighted vehicle after the selected
|
||||
// consist vehicle (or at the end when nothing is selected).
|
||||
private void AddVehicleButton_OnClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
if (_browserSelected != null)
|
||||
AddTexture(_browserSelected);
|
||||
}
|
||||
|
||||
private bool PassesFilters(VehicleTexture t, string search, bool hasSearch)
|
||||
@@ -428,54 +425,6 @@ public partial class Depot : UserControl
|
||||
|| C(t.Meta?.Vehicle) || C(t.Meta?.Operator) || C(ClassOf(t));
|
||||
}
|
||||
|
||||
private Control BuildBrowserItem(VehicleTexture texture)
|
||||
{
|
||||
// Grid with a star label column keeps the label width constrained so it
|
||||
// wraps instead of overlapping the Add button.
|
||||
var grid = new Grid
|
||||
{
|
||||
Margin = new Thickness(2, 1),
|
||||
ColumnDefinitions = new ColumnDefinitions("Auto,*,Auto")
|
||||
};
|
||||
ToolTip.SetTip(grid, texture.FullPath);
|
||||
|
||||
var thumb = CreateLazyMini(_db.ResolveMiniName(texture), BrowserThumbHeight, 64);
|
||||
thumb.VerticalAlignment = VerticalAlignment.Center;
|
||||
Grid.SetColumn(thumb, 0);
|
||||
|
||||
var set = _db.ResolveSet(texture);
|
||||
var label = new TextBlock
|
||||
{
|
||||
Text = BrowserLabel(texture, set),
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
FontSize = 12,
|
||||
TextWrapping = TextWrapping.Wrap,
|
||||
Margin = new Thickness(8, 0, 8, 0)
|
||||
};
|
||||
Grid.SetColumn(label, 1);
|
||||
|
||||
var add = new Button
|
||||
{
|
||||
Content = App.Loc["AddVehicle"],
|
||||
FontSize = 11,
|
||||
Padding = new Thickness(10, 3),
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Cursor = _hand
|
||||
};
|
||||
add.Classes.Add("Flat");
|
||||
ToolTip.SetTip(add, set != null ? App.Loc["TipAddUnit"] : App.Loc["TipAddVehicle"]);
|
||||
add.Click += (_, _) => AddTexture(texture);
|
||||
Grid.SetColumn(add, 2);
|
||||
|
||||
grid.Children.Add(thumb);
|
||||
grid.Children.Add(label);
|
||||
grid.Children.Add(add);
|
||||
|
||||
// double-click the row to replace the selected consist vehicle
|
||||
grid.DoubleTapped += (_, _) => ReplaceSelected(texture);
|
||||
return grid;
|
||||
}
|
||||
|
||||
// Replaces the selected consist unit with this vehicle/unit (keeping its
|
||||
// slot, crew and orientation). Falls back to appending if nothing is selected.
|
||||
private void ReplaceSelected(VehicleTexture texture)
|
||||
@@ -506,29 +455,6 @@ public partial class Depot : UserControl
|
||||
RebuildConsist();
|
||||
}
|
||||
|
||||
// An image that decodes its mini only while it is on screen, and releases it
|
||||
// when scrolled out of view, so an open group never holds every bitmap at once.
|
||||
private Image CreateLazyMini(string? miniName, int height, double width)
|
||||
{
|
||||
var img = new Image { Height = height, Width = width, Stretch = Stretch.Uniform };
|
||||
bool loaded = false;
|
||||
img.EffectiveViewportChanged += (_, e) =>
|
||||
{
|
||||
bool visible = e.EffectiveViewport.Width > 0 && e.EffectiveViewport.Height > 0;
|
||||
if (visible && !loaded)
|
||||
{
|
||||
img.Source = GetMiniBitmap(miniName, height);
|
||||
loaded = true;
|
||||
}
|
||||
else if (!visible && loaded)
|
||||
{
|
||||
img.Source = null;
|
||||
loaded = false;
|
||||
}
|
||||
};
|
||||
return img;
|
||||
}
|
||||
|
||||
private string BrowserLabel(VehicleTexture texture, IReadOnlyList<VehicleTexture>? set)
|
||||
{
|
||||
string name = !string.IsNullOrEmpty(texture.TextureMini)
|
||||
@@ -644,13 +570,13 @@ public partial class Depot : UserControl
|
||||
|
||||
foreach (var v in trainset.Vehicles)
|
||||
{
|
||||
var bmp = GetMiniBitmap(_db.MiniForSkin(v.SkinFile) ?? v.MiniName, 28);
|
||||
var bmp = GetMiniBitmap(_db.MiniForSkin(v.SkinFile) ?? v.MiniName, 20);
|
||||
if (bmp != null)
|
||||
minis.Children.Add(new Image { Source = bmp, Height = 28, Stretch = Stretch.Uniform });
|
||||
minis.Children.Add(new Image { Source = bmp, Height = 20, Stretch = Stretch.Uniform });
|
||||
else
|
||||
minis.Children.Add(new Border
|
||||
{
|
||||
Height = 28, Width = 46, Background = Placeholder, CornerRadius = new CornerRadius(3)
|
||||
Height = 20, Width = 32, Background = Placeholder, CornerRadius = new CornerRadius(3)
|
||||
});
|
||||
|
||||
names.Children.Add(new TextBlock { Text = v.SkinFile, FontSize = 10, Opacity = 0.8 });
|
||||
|
||||
@@ -1,68 +1,161 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:sukiUi="clr-namespace:SukiUI.Controls;assembly=SukiUI"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:starterNg="clr-namespace:StarterNG"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="StarterNG.Views.Scenarios"
|
||||
x:CompileBindings="True">
|
||||
<Grid Margin="16" ColumnSpacing="16" RowSpacing="16">
|
||||
<Grid Margin="0" ColumnSpacing="8" RowSpacing="8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="300" />
|
||||
<ColumnDefinition Width="280" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="280" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="100" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="78" />
|
||||
</Grid.RowDefinitions>
|
||||
<sukiUi:GroupBox Grid.RowSpan="2" Header="{Binding [Sceneries], Source={x:Static starterNg:App.Loc}}">
|
||||
<TreeView Name="sceneryList" SelectionChanged="SceneryList_OnSelectionChanged">
|
||||
|
||||
</TreeView>
|
||||
</sukiUi:GroupBox>
|
||||
<sukiUi:GroupBox Grid.Column="1" Header="{Binding [Vehicles], Source={x:Static starterNg:App.Loc}}">
|
||||
<ListBox Name="vehicleList" SelectionChanged="VehicleList_OnSelectionChanged">
|
||||
</ListBox>
|
||||
</sukiUi:GroupBox>
|
||||
<sukiUi:GroupBox Grid.Column="1" Grid.Row="1" Header="{Binding [ScenarioDescription], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock TextWrapping="Wrap" Name="missionDescription">
|
||||
</TextBlock>
|
||||
<!-- Scenery tree (left) -->
|
||||
<HeaderedContentControl Grid.Column="0" Grid.Row="0" Theme="{StaticResource GroupBox}"
|
||||
Classes="Compact"
|
||||
Header="{Binding [Sceneries], Source={x:Static starterNg:App.Loc}}">
|
||||
<TreeView Name="sceneryList" SelectionChanged="SceneryList_OnSelectionChanged" />
|
||||
</HeaderedContentControl>
|
||||
|
||||
<!-- Centre: trainsets list (compact, fills) + description/weather/timetable tabs -->
|
||||
<Grid Grid.Column="1" Grid.Row="0" RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="2*" />
|
||||
<RowDefinition Height="3*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<HeaderedContentControl Grid.Row="0" Theme="{StaticResource GroupBox}"
|
||||
Header="{Binding [Vehicles], Source={x:Static starterNg:App.Loc}}">
|
||||
<ListBox Name="vehicleList" Classes="Compact"
|
||||
SelectionChanged="VehicleList_OnSelectionChanged" />
|
||||
</HeaderedContentControl>
|
||||
|
||||
<TabControl Grid.Row="1">
|
||||
<TabItem Header="{Binding [TabDescription], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock TextWrapping="Wrap" Name="missionDescription" Margin="4" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem Header="{Binding [Weather], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Name="weatherForm" Margin="8" Spacing="8" IsEnabled="False">
|
||||
<Grid ColumnDefinitions="130,*" RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{Binding [Time], Source={x:Static starterNg:App.Loc}}" />
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Name="weatherTime" Width="90"
|
||||
HorizontalAlignment="Left" Watermark="hh:mm"
|
||||
LostFocus="Weather_OnChanged" />
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{Binding [Season], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" Name="weatherSeason" Width="180"
|
||||
HorizontalAlignment="Left"
|
||||
SelectionChanged="WeatherSeason_OnChanged">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [SeasonNow], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="113" Content="{Binding [SeasonSpring], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="204" Content="{Binding [SeasonSummer], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="297" Content="{Binding [SeasonAutumn], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="15" Content="{Binding [SeasonWinter], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{Binding [Day], Source={x:Static starterNg:App.Loc}}" />
|
||||
<NumericUpDown Grid.Row="2" Grid.Column="1" Name="weatherDay" Width="140"
|
||||
HorizontalAlignment="Left" Minimum="0" Maximum="366"
|
||||
Increment="1" FormatString="0"
|
||||
ValueChanged="WeatherDay_OnChanged" />
|
||||
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{Binding [Temperature], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Grid.Row="3" Grid.Column="1" Orientation="Horizontal" Spacing="8">
|
||||
<Slider Name="weatherTemp" Minimum="-20" Maximum="40" Width="220"
|
||||
TickFrequency="1" IsSnapToTickEnabled="True"
|
||||
ValueChanged="Weather_OnSliderChanged" />
|
||||
<TextBlock Name="weatherTempLabel" VerticalAlignment="Center" MinWidth="48" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{Binding [Visibility], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Grid.Row="4" Grid.Column="1" Orientation="Horizontal" Spacing="8">
|
||||
<Slider Name="weatherFog" Minimum="50" Maximum="2500" Width="220"
|
||||
TickFrequency="50" IsSnapToTickEnabled="True"
|
||||
ValueChanged="Weather_OnSliderChanged" />
|
||||
<TextBlock Name="weatherFogLabel" VerticalAlignment="Center" MinWidth="56" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" VerticalAlignment="Center"
|
||||
Text="{Binding [Overcast], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox Grid.Row="5" Grid.Column="1" Name="weatherOvercast" Width="220"
|
||||
HorizontalAlignment="Left"
|
||||
SelectionChanged="Weather_OnSelectionChanged">
|
||||
<ComboBoxItem Tag="-1.5" Content="{Binding [OvercastClear], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="0" Content="{Binding [OvercastFair], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="0.3" Content="{Binding [OvercastLight], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="0.7" Content="{Binding [OvercastModerate], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [OvercastHeavy], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1.1" Content="{Binding [OvercastCloudy], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1.5" Content="{Binding [OvercastStorm], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Name="weatherHint" Opacity="0.6" FontSize="11" TextWrapping="Wrap"
|
||||
Text="{Binding [WeatherHint], Source={x:Static starterNg:App.Loc}}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem Header="{Binding [Timetable], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||
<TextBlock Name="timetableContent" Margin="4" FontFamily="Consolas, monospace"
|
||||
FontSize="12" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
|
||||
<!-- Right: scenery image (//$i) + scenery description (//$d) -->
|
||||
<Grid Grid.Column="2" Grid.Row="0" RowSpacing="8">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0" ClipToBounds="True" VerticalAlignment="Top"
|
||||
Background="{StaticResource CarbonPanelBg}"
|
||||
BorderBrush="{StaticResource CarbonBorderLight}" BorderThickness="1"
|
||||
Height="{Binding $self.Bounds.Width}">
|
||||
<Image Name="sceneryImage" Stretch="Uniform" Margin="2" />
|
||||
</Border>
|
||||
|
||||
<HeaderedContentControl Grid.Row="1" Theme="{StaticResource GroupBox}"
|
||||
Header="{Binding [SceneryDescription], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock TextWrapping="Wrap" Name="sceneryDescription" />
|
||||
</ScrollViewer>
|
||||
</HeaderedContentControl>
|
||||
</Grid>
|
||||
|
||||
<!-- Consist preview (full-width bottom, horizontally scrollable) -->
|
||||
<HeaderedContentControl Grid.Row="1" Grid.ColumnSpan="3" Theme="{StaticResource GroupBox}"
|
||||
Header="{Binding [Consist], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Name="consistStack" />
|
||||
</ScrollViewer>
|
||||
|
||||
</sukiUi:GroupBox>
|
||||
|
||||
<!-- Scenery image (//$i) shown as a 1:1 square thumbnail -->
|
||||
<Border Grid.Column="2" Grid.Row="0" ClipToBounds="True" VerticalAlignment="Top"
|
||||
Height="{Binding $self.Bounds.Width}">
|
||||
<Image Name="sceneryImage" Stretch="Uniform" />
|
||||
</Border>
|
||||
<!-- Scenery description (//$d), distinct from the scenario/consist description -->
|
||||
<sukiUi:GroupBox Grid.Column="2" Grid.Row="1" Header="{Binding [SceneryDescription], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<TextBlock TextWrapping="Wrap" Name="sceneryDescription">
|
||||
</TextBlock>
|
||||
</ScrollViewer>
|
||||
</sukiUi:GroupBox>
|
||||
|
||||
<sukiUi:GroupBox Header="{Binding [Consist], Source={x:Static starterNg:App.Loc}}" Grid.Row="2" Grid.ColumnSpan="3">
|
||||
<ScrollViewer VerticalAlignment="Bottom"
|
||||
HorizontalScrollBarVisibility="Auto"
|
||||
VerticalScrollBarVisibility="Disabled">
|
||||
<StackPanel Orientation="Horizontal" Name="consistStack">
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</sukiUi:GroupBox>
|
||||
|
||||
<Button Grid.Column="0" Height="36" Classes="Flat"
|
||||
VerticalAlignment="Bottom" Grid.Row="3" Grid.ColumnSpan="3"
|
||||
Click="StartButton_OnClick"
|
||||
Content="{Binding [Start], Source={x:Static starterNg:App.Loc}}">
|
||||
|
||||
</Button>
|
||||
</HeaderedContentControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -16,6 +17,11 @@ public partial class Scenarios : UserControl
|
||||
{
|
||||
public List<Scenery> Sceneries;
|
||||
|
||||
// scenery whose weather the form is currently editing
|
||||
private Scenery? _currentScenery;
|
||||
// suppresses weather change handlers while the form is being populated
|
||||
private bool _loadingWeather;
|
||||
|
||||
public Scenarios()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -76,6 +82,11 @@ public partial class Scenarios : UserControl
|
||||
|
||||
// scenery-level info (distinct from the per-consist scenario description)
|
||||
ShowSceneryInfo(selectedScn);
|
||||
ShowWeather(selectedScn);
|
||||
|
||||
// no consist chosen yet for this scenery
|
||||
missionDescription.Text = "";
|
||||
timetableContent.Text = App.Loc["NoTimetable"];
|
||||
|
||||
// add all trainsets to list
|
||||
for (int i = 0; i < selectedScn.Trainsets.Count; i++)
|
||||
@@ -136,6 +147,135 @@ public partial class Scenarios : UserControl
|
||||
AppState.Instance.CurrentTrainset = selectedTrainset;
|
||||
|
||||
ShowConsist(selectedTrainset);
|
||||
ShowTimetable(selectedScn, selectedTrainset);
|
||||
}
|
||||
|
||||
// Loads the scenery's weather into the editable form (Weather tab). Editing a
|
||||
// control writes the value back onto the scenery and marks it dirty, so the
|
||||
// change is injected into the exported .scn's config block on launch.
|
||||
private void ShowWeather(Scenery scenery)
|
||||
{
|
||||
_currentScenery = scenery;
|
||||
_loadingWeather = true;
|
||||
try
|
||||
{
|
||||
weatherForm.IsEnabled = true;
|
||||
weatherTime.Text = scenery.WeatherTime;
|
||||
weatherDay.Value = scenery.Day;
|
||||
weatherTemp.Value = scenery.Temperature;
|
||||
weatherFog.Value = System.Math.Clamp(scenery.FogEnd, 50, 2500);
|
||||
SelectByTag(weatherSeason, scenery.Day.ToString());
|
||||
SelectByTag(weatherOvercast, scenery.Overcast.ToString(CultureInfo.InvariantCulture));
|
||||
UpdateWeatherLabels();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_loadingWeather = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Reads the form back into the current scenery and flags it for export rewrite.
|
||||
private void CaptureWeather()
|
||||
{
|
||||
if (_loadingWeather || _currentScenery is null)
|
||||
return;
|
||||
|
||||
var scn = _currentScenery;
|
||||
if (!string.IsNullOrWhiteSpace(weatherTime.Text))
|
||||
scn.WeatherTime = weatherTime.Text!.Trim();
|
||||
scn.Day = (int)(weatherDay.Value ?? 0);
|
||||
scn.Temperature = weatherTemp.Value;
|
||||
scn.FogEnd = (int)weatherFog.Value;
|
||||
if ((weatherOvercast.SelectedItem as ComboBoxItem)?.Tag is string ov &&
|
||||
double.TryParse(ov, System.Globalization.NumberStyles.Float, CultureInfo.InvariantCulture, out double oc))
|
||||
scn.Overcast = oc;
|
||||
|
||||
scn.WeatherDirty = true;
|
||||
UpdateWeatherLabels();
|
||||
}
|
||||
|
||||
private void UpdateWeatherLabels()
|
||||
{
|
||||
weatherTempLabel.Text = $"{(int)weatherTemp.Value} °C";
|
||||
weatherFogLabel.Text = $"{(int)weatherFog.Value} m";
|
||||
}
|
||||
|
||||
private static void SelectByTag(ComboBox combo, string tag)
|
||||
{
|
||||
foreach (var obj in combo.Items)
|
||||
if (obj is ComboBoxItem item && (item.Tag as string) == tag)
|
||||
{
|
||||
combo.SelectedItem = item;
|
||||
return;
|
||||
}
|
||||
combo.SelectedItem = null;
|
||||
}
|
||||
|
||||
// --- weather form event handlers ---
|
||||
private void Weather_OnChanged(object? sender, RoutedEventArgs e) => CaptureWeather();
|
||||
|
||||
private void Weather_OnSelectionChanged(object? sender, SelectionChangedEventArgs e) => CaptureWeather();
|
||||
|
||||
private void Weather_OnSliderChanged(object? sender, Avalonia.Controls.Primitives.RangeBaseValueChangedEventArgs e) => CaptureWeather();
|
||||
|
||||
private void WeatherDay_OnChanged(object? sender, NumericUpDownValueChangedEventArgs e) => CaptureWeather();
|
||||
|
||||
// Picking a season presets the day-of-year, then captures the form.
|
||||
private void WeatherSeason_OnChanged(object? sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (_loadingWeather)
|
||||
return;
|
||||
if ((weatherSeason.SelectedItem as ComboBoxItem)?.Tag is string tag &&
|
||||
int.TryParse(tag, out int day))
|
||||
{
|
||||
_loadingWeather = true;
|
||||
weatherDay.Value = day;
|
||||
_loadingWeather = false;
|
||||
}
|
||||
CaptureWeather();
|
||||
}
|
||||
|
||||
// Reads and shows the timetable file referenced by the trainset (its first
|
||||
// "trainset" token is the timetable name). Shows a note when none is set or
|
||||
// the file cannot be found.
|
||||
private void ShowTimetable(Scenery scenery, Trainset trainset)
|
||||
{
|
||||
string? path = ResolveTimetablePath(scenery, trainset.Name);
|
||||
if (path is null)
|
||||
{
|
||||
timetableContent.Text = App.Loc["NoTimetable"];
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
timetableContent.Text = File.ReadAllText(path, Encoding.GetEncoding(1250));
|
||||
}
|
||||
catch
|
||||
{
|
||||
timetableContent.Text = App.Loc["NoTimetable"];
|
||||
}
|
||||
}
|
||||
|
||||
// Probes the usual locations for a timetable file named after the trainset.
|
||||
private static string? ResolveTimetablePath(Scenery scenery, string? name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name) ||
|
||||
name.Equals("none", System.StringComparison.OrdinalIgnoreCase))
|
||||
return null;
|
||||
|
||||
string scnDir = Path.GetDirectoryName(scenery.Path) ?? "."; // scenery/
|
||||
string root = Path.GetDirectoryName(scnDir) ?? "."; // MaSzyna root
|
||||
|
||||
var candidates = new[]
|
||||
{
|
||||
Path.Combine(root, "timetables", name + ".txt"),
|
||||
Path.Combine(scnDir, name + ".txt"),
|
||||
Path.Combine(root, "scenario", name + ".txt"),
|
||||
Path.Combine(root, "timetables", name),
|
||||
Path.Combine(scnDir, name),
|
||||
};
|
||||
return candidates.FirstOrDefault(File.Exists);
|
||||
}
|
||||
|
||||
// Renders the consist preview for a trainset (re-reads its current vehicles
|
||||
@@ -156,7 +296,7 @@ public partial class Scenarios : UserControl
|
||||
consistStack.Children.Add(new Image
|
||||
{
|
||||
Source = new Bitmap(path),
|
||||
Height = 45,
|
||||
Height = 32,
|
||||
Stretch = Avalonia.Media.Stretch.Uniform,
|
||||
Margin = new Thickness(0)
|
||||
});
|
||||
@@ -171,49 +311,4 @@ public partial class Scenarios : UserControl
|
||||
if (AppState.Instance.CurrentTrainset is { } trainset)
|
||||
ShowConsist(trainset);
|
||||
}
|
||||
|
||||
// Exports the (possibly depot-modified) scenery to a $-prefixed copy and
|
||||
// launches the game on it with the selected consist's driven vehicle.
|
||||
private void StartButton_OnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var scenery = AppState.Instance.CurrentScenery;
|
||||
if (scenery is null)
|
||||
return;
|
||||
var trainset = AppState.Instance.CurrentTrainset;
|
||||
|
||||
// write scenery/$<name>.scn with the replaced trainsets
|
||||
string dir = System.IO.Path.GetDirectoryName(scenery.Path) ?? "scenery";
|
||||
string exportName = "$" + System.IO.Path.GetFileName(scenery.Path);
|
||||
string exportPath = System.IO.Path.Combine(dir, exportName);
|
||||
try
|
||||
{
|
||||
File.WriteAllText(exportPath, scenery.BuildExportContent(), Encoding.GetEncoding(1250));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return; // couldn't write the scenery file
|
||||
}
|
||||
|
||||
// the player's vehicle is the node name of the driven car in the consist
|
||||
string? vehicle = trainset?.Vehicles
|
||||
.FirstOrDefault(v => v.DriverType is eDriverType.Headdriver or eDriverType.Reardriver)?.Name
|
||||
?? trainset?.Vehicles.FirstOrDefault()?.Name;
|
||||
|
||||
// make sure the latest settings are on disk before the sim reads them
|
||||
StarterNG.Classes.Settings.Instance.CaptureAndSave();
|
||||
|
||||
// launch the game: -s $<name>.scn -v <vehicle>
|
||||
try
|
||||
{
|
||||
Process.Start(new ProcessStartInfo(StarterNG.Classes.Settings.Instance.ExecutablePath)
|
||||
{
|
||||
Arguments = $"-s {exportName} -v {vehicle}",
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
// executable not found / not configured yet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:suki="clr-namespace:SukiUI.Controls;assembly=SukiUI"
|
||||
xmlns:objectModel="clr-namespace:System.Collections.ObjectModel;assembly=System.ObjectModel"
|
||||
xmlns:starterNg="clr-namespace:StarterNG"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="StarterNG.Views.Settings"
|
||||
x:CompileBindings="True">
|
||||
<DockPanel>
|
||||
<!-- Save / reset bar -->
|
||||
<Border DockPanel.Dock="Bottom" Padding="16,10" Background="#11000000">
|
||||
<Border DockPanel.Dock="Bottom" Padding="16,10" Background="{StaticResource CarbonPanelBg}"
|
||||
BorderBrush="{StaticResource CarbonBorderLight}" BorderThickness="0,1,0,0">
|
||||
<StackPanel Orientation="Horizontal" Spacing="12" HorizontalAlignment="Right">
|
||||
<TextBlock x:Name="SaveStatus" VerticalAlignment="Center" Opacity="0.8" Text="" />
|
||||
<Button x:Name="ResetButton" Classes="Flat" Click="ResetButton_OnClick"
|
||||
@@ -20,380 +19,281 @@
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<suki:SettingsLayout>
|
||||
<suki:SettingsLayout.Items>
|
||||
<objectModel:ObservableCollection x:TypeArguments="suki:SettingsLayoutItem">
|
||||
<suki:SettingsLayoutItem Header="{Binding [General], Source={x:Static starterNg:App.Loc}}">
|
||||
<suki:SettingsLayoutItem.Content>
|
||||
<StackPanel Spacing="8" Orientation="Vertical">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label Content="{Binding [Language], Source={x:Static starterNg:App.Loc}}" VerticalAlignment="Center" FontSize="14"/>
|
||||
<ComboBox x:Name="ChangeLanguageCb" MinWidth="350" MaxWidth="350" SelectedIndex="1" SelectionChanged="LanguageComboBox_OnSelectionChanged">
|
||||
<ComboBoxItem>Polski</ComboBoxItem>
|
||||
<ComboBoxItem>English</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<TabControl TabStripPlacement="Left">
|
||||
<!-- General -->
|
||||
<TabItem Header="{Binding [General], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="8" Orientation="Vertical" Margin="12">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label Content="{Binding [Language], Source={x:Static starterNg:App.Loc}}" VerticalAlignment="Center" FontSize="14" />
|
||||
<ComboBox x:Name="ChangeLanguageCb" MinWidth="350" MaxWidth="350" SelectedIndex="1" SelectionChanged="LanguageComboBox_OnSelectionChanged">
|
||||
<ComboBoxItem>Polski</ComboBoxItem>
|
||||
<ComboBoxItem>English</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="FullscreenCb" Content="{Binding [Fullscreen], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<CheckBox x:Name="FullscreenCb" Content="{Binding [Fullscreen], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="PauseInactiveCb" Content="{Binding [PauseSimInactive], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="PauseStartCb" Content="{Binding [PauseSimStart], Source={x:Static starterNg:App.Loc}}" />
|
||||
|
||||
<CheckBox x:Name="PauseInactiveCb" Content="{Binding [PauseSimInactive], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [CursorSensitivity], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="CursorSensitivitySlider" Minimum="1" Maximum="5" TickFrequency="1" MinWidth="200" MaxWidth="200"
|
||||
IsSnapToTickEnabled="True" Value="3" />
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="PauseStartCb" Content="{Binding [PauseSimStart], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="MouseHorInvertCb" Content="{Binding [MouseHorInvert], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="MouseVertInvertCb" Content="{Binding [MouseVertInvert], Source={x:Static starterNg:App.Loc}}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [CursorSensitivity], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="CursorSensitivitySlider" Minimum="1" Maximum="5" TickFrequency="1" MinWidth="200" MaxWidth="200"
|
||||
IsSnapToTickEnabled="True" Value="3">
|
||||
</Slider>
|
||||
</StackPanel>
|
||||
<!-- Communication -->
|
||||
<TabItem Header="{Binding [Communication], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="8" Orientation="Vertical" Margin="12">
|
||||
<CheckBox x:Name="GamepadIgnoreCb" Content="{Binding [GamepadSignalIgnore], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [Feedback], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="FeedbackCb" MinWidth="350" MaxWidth="350" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [FeedbackOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="1" Content="{Binding [FeedbackCASHP], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="2" Content="{Binding [FeedbackCA], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="3" Content="{Binding [FeedbackLPT], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="4" Content="{Binding [FeedbackPoKeys], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Tag="5" Content="{Binding [FeedbackSP], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<CheckBox x:Name="MouseHorInvertCb" Content="{Binding [MouseHorInvert], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<CheckBox x:Name="MouseVertInvertCb" Content="{Binding [MouseVertInvert], Source={x:Static starterNg:App.Loc}}" />
|
||||
</StackPanel>
|
||||
</suki:SettingsLayoutItem.Content>
|
||||
</suki:SettingsLayoutItem>
|
||||
<suki:SettingsLayoutItem Header="{Binding [Communication], Source={x:Static starterNg:App.Loc}}">
|
||||
<suki:SettingsLayoutItem.Content>
|
||||
<StackPanel Spacing="8" Orientation="Vertical">
|
||||
<CheckBox x:Name="GamepadIgnoreCb" Content="{Binding [GamepadSignalIgnore], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<!-- Others -->
|
||||
<TabItem Header="{Binding [Others], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="8" Orientation="Vertical" Margin="12">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [SelectEXE], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="SelectExeCb" MinWidth="350" MaxWidth="350" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [SelectEXEAuto], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem>eu07.exe</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="DebugModeCb" Content="{Binding [DebugMode], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="VirtualShuntingCb" Content="{Binding [VirtualShunting], Source={x:Static starterNg:App.Loc}}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [Feedback], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBox x:Name="FeedbackCb" MinWidth="350" MaxWidth="350" SelectedIndex="0">
|
||||
<ComboBoxItem Tag="0" Content="{Binding [FeedbackOff], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Tag="1" Content="{Binding [FeedbackCASHP], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Tag="2" Content="{Binding [FeedbackCA], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Tag="3" Content="{Binding [FeedbackLPT], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Tag="4" Content="{Binding [FeedbackPoKeys], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Tag="5" Content="{Binding [FeedbackSP], Source={x:Static starterNg:App.Loc}}"/>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<!-- Graphic -->
|
||||
<TabItem Header="{Binding [Graphic], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="8" Orientation="Vertical" Margin="12">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [RenderEngine], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="RenderEngineCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [REFull], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [REOld], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [RESimpShader], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [RESimp], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [REOff], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [REExperimental], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [Resolution], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="ResolutionCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
<ComboBoxItem>3840x2160</ComboBoxItem>
|
||||
<ComboBoxItem>2560x1440</ComboBoxItem>
|
||||
<ComboBoxItem>1920x1080</ComboBoxItem>
|
||||
<ComboBoxItem>1600x900</ComboBoxItem>
|
||||
<ComboBoxItem>1366x768</ComboBoxItem>
|
||||
<ComboBoxItem>1280x720</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [BufforResolution], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="bufferScale" Minimum="50" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="200" TickFrequency="1" IsSnapToTickEnabled="True" Value="100" />
|
||||
<TextBlock VerticalAlignment="Center" Text="{Binding #bufferScale.Value, StringFormat='{}{0}%'}" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [MaxTexResolution], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="textureResolutionSlider" Minimum="9" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="14" ValueChanged="TextureResolutionSlider_OnValueChanged"
|
||||
TickFrequency="1" IsSnapToTickEnabled="True" Value="12" />
|
||||
<TextBlock Name="texResolution" VerticalAlignment="Center" Text="4096" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [MaxTexCabResolution], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="cabTextureResolutionSlider" Minimum="9" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="14" ValueChanged="CabTextureResolutionSlider_OnValueChanged"
|
||||
TickFrequency="1" IsSnapToTickEnabled="True" Value="12" />
|
||||
<TextBlock Name="cabTexResolution" VerticalAlignment="Center" Text="4096" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [TexFilteringQuality], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="TexFilteringSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="5" TickFrequency="1" IsSnapToTickEnabled="True" Value="4" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [Multisampling], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="MultisamplingSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="4" TickFrequency="1" IsSnapToTickEnabled="True" Value="3" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [RenderRange], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="RenderRangeSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="3" Value="1" />
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="VSyncCb" Content="{Binding [VSync], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="SmokeDisplayCb" Content="{Binding [SmokeDisplay], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [SmokeParticlesMultiplier], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="SmokeParticlesSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="4" TickFrequency="1" IsSnapToTickEnabled="True" Value="2" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [Postprocessing], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="PostprocessingCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [PPReinhard], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [PPACES], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="ChromaticAberrationCb" Content="{Binding [ChromaticAberration], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="MotionBlurCb" Content="{Binding [MotionBlur], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="AdditionalShadersCb" Content="{Binding [AdditionalShadersEffects], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="ReflectionsCubeMapCb" Content="{Binding [ReflectionsCubeMap], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="RenderVBOCb" Content="{Binding [RenderVBO], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="RenderShadowsCb" Content="{Binding [RenderShadows], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ReflectionsFramerate], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="reflectionsFramerate" Minimum="5" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="120" TickFrequency="5" IsSnapToTickEnabled="True" Value="30" />
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding #reflectionsFramerate.Value, StringFormat='{}{0} FPS'}" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShadowsResolution], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="shaderResolutionSlider" Minimum="9" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="14" ValueChanged="shaderResolutionSlider_OnValueChanged"
|
||||
TickFrequency="1" IsSnapToTickEnabled="True" Value="12" />
|
||||
<TextBlock Name="shaderResolution" VerticalAlignment="Center" Text="4096 px" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShaderRange], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="shaderRange" Minimum="25" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="400" TickFrequency="5" IsSnapToTickEnabled="True" Value="150" />
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding #shaderRange.Value, StringFormat='{}{0} m'}" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [CabShadowsRange], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="cabShaderSourceRange" Minimum="0" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100" TickFrequency="10" IsSnapToTickEnabled="True" Value="30" />
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding #cabShaderSourceRange.Value, StringFormat='{}{0} m'}" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShadowDisplay], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="ShadowDisplayCb" MinWidth="150" MaxWidth="150" 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>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ReflectionsDetails], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBox x:Name="ReflectionsDetailsCb" MinWidth="350" MaxWidth="350" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [RDTerrain], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [RDTerrainModels], Source={x:Static starterNg:App.Loc}}" />
|
||||
<ComboBoxItem Content="{Binding [RDTerrainModelsVehicles], Source={x:Static starterNg:App.Loc}}" />
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShadowsCabRange], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider Name="fovSlider" Minimum="5" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="110" TickFrequency="5" IsSnapToTickEnabled="True" Value="30" />
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding #fovSlider.Value, StringFormat='{}{0} stopni'}" />
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="RenderScreensCb" Content="{Binding [RenderScreens], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="RenderScreensThreadCb" Content="{Binding [RenderScreensThread], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [RenderScreensFramerate], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="RenderScreensFramerateSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="5" TickFrequency="1" IsSnapToTickEnabled="True" Value="5" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
</StackPanel>
|
||||
</suki:SettingsLayoutItem.Content>
|
||||
</suki:SettingsLayoutItem>
|
||||
<!-- Physics -->
|
||||
<TabItem Header="{Binding [Physics], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="8" Orientation="Vertical" Margin="12">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [TrackCurvesQuality], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="TrackCurvesSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="4" TickFrequency="1" IsSnapToTickEnabled="True" Value="4" />
|
||||
</StackPanel>
|
||||
<CheckBox x:Name="PhysicsAccuracyCb" Content="{Binding [PhysicsAccuracyIncreased], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="PantographBreakCb" Content="{Binding [BreakingPantographPossibility], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="OverheadOnlyCb" Content="{Binding [PowerOverheadLineOnly], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="SpeedometerTapesCb" Content="{Binding [SaveSpeedometerTapes], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="SimLogsCb" Content="{Binding [SaveSimLogs], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="KeepLogsCb" Content="{Binding [KeepPrevLogs], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="DisplaySimulationCb" Content="{Binding [DisplaySimulation], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="CrashDamageCb" Content="{Binding [CrashDamage], Source={x:Static starterNg:App.Loc}}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<suki:SettingsLayoutItem Header="{Binding [Others], Source={x:Static starterNg:App.Loc}}">
|
||||
<suki:SettingsLayoutItem.Content>
|
||||
<StackPanel Spacing="8" Orientation="Vertical">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [SelectEXE], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBox x:Name="SelectExeCb" MinWidth="350" MaxWidth="350" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [SelectEXEAuto], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem>eu07.exe</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<!-- Sounds -->
|
||||
<TabItem Header="{Binding [Sounds], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="8" Orientation="Vertical" Margin="12">
|
||||
<CheckBox x:Name="EnableSoundsCb" Content="{Binding [EnableSounds], Source={x:Static starterNg:App.Loc}}" />
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [Volume], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="VolumeSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100" TickFrequency="5" IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [RadiophoneVolume], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="RadioVolumeSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100" TickFrequency="5" IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [VehiclesVolume], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="VehiclesVolumeSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100" TickFrequency="5" IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [PositionedSoundsVolume], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="PositionalVolumeSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100" TickFrequency="5" IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [AmbientVolume], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="AmbientVolumeSlider" Minimum="1" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100" TickFrequency="5" IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [VolumeDuringPause], Source={x:Static starterNg:App.Loc}}" />
|
||||
<Slider x:Name="PauseVolumeSlider" Minimum="0" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100" TickFrequency="5" IsSnapToTickEnabled="True" Value="0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<CheckBox x:Name="DebugModeCb" Content="{Binding [DebugMode], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="VirtualShuntingCb" Content="{Binding [VirtualShunting], Source={x:Static starterNg:App.Loc}}"/>
|
||||
</StackPanel>
|
||||
</suki:SettingsLayoutItem.Content>
|
||||
</suki:SettingsLayoutItem>
|
||||
|
||||
<suki:SettingsLayoutItem Header="{Binding [Graphic], Source={x:Static starterNg:App.Loc}}">
|
||||
<suki:SettingsLayoutItem.Content>
|
||||
<StackPanel Spacing="8" Orientation="Vertical">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [RenderEngine], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBox x:Name="RenderEngineCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [REFull], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [REOld], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [RESimpShader], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [RESimp], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [REOff], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [REExperimental], Source={x:Static starterNg:App.Loc}}"/>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<Label VerticalAlignment="Center" FontSize="14" Content="{Binding [Resolution], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBox x:Name="ResolutionCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
<ComboBoxItem>3840x2160</ComboBoxItem>
|
||||
<ComboBoxItem>2560x1440</ComboBoxItem>
|
||||
<ComboBoxItem>1920x1080</ComboBoxItem>
|
||||
<ComboBoxItem>1600x900</ComboBoxItem>
|
||||
<ComboBoxItem>1366x768</ComboBoxItem>
|
||||
<ComboBoxItem>1280x720</ComboBoxItem>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [BufforResolution], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="bufferScale" Minimum="50" MaxWidth="400" HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="200" TickFrequency="1" IsSnapToTickEnabled="True"
|
||||
Value="100" />
|
||||
<TextBlock VerticalAlignment="Center"
|
||||
Text="{Binding #bufferScale.Value, StringFormat='{}{0}%'}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [MaxTexResolution], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="textureResolutionSlider" Minimum="9" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="14"
|
||||
ValueChanged="TextureResolutionSlider_OnValueChanged" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="12" />
|
||||
<TextBlock Name="texResolution" VerticalAlignment="Center" Text="4096" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [MaxTexCabResolution], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="cabTextureResolutionSlider" Minimum="9" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="14"
|
||||
ValueChanged="CabTextureResolutionSlider_OnValueChanged" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="12" />
|
||||
<TextBlock Name="cabTexResolution" VerticalAlignment="Center" Text="4096" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [TexFilteringQuality], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="TexFilteringSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="5"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="4" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [Multisampling], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="MultisamplingSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="4"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="3" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [RenderRange], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="RenderRangeSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="3" Value="1" />
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="VSyncCb" Content="{Binding [VSync], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="SmokeDisplayCb" Content="{Binding [SmokeDisplay], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [SmokeParticlesMultiplier], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="SmokeParticlesSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="4"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="2" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [Postprocessing], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBox x:Name="PostprocessingCb" MinWidth="150" MaxWidth="150" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [PPReinhard], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [PPACES], Source={x:Static starterNg:App.Loc}}"/>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="ChromaticAberrationCb" Content="{Binding [ChromaticAberration], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="MotionBlurCb" Content="{Binding [MotionBlur], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="AdditionalShadersCb" Content="{Binding [AdditionalShadersEffects], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="ReflectionsCubeMapCb" Content="{Binding [ReflectionsCubeMap], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="RenderVBOCb" Content="{Binding [RenderVBO], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="RenderShadowsCb" Content="{Binding [RenderShadows], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ReflectionsFramerate], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="reflectionsFramerate" Minimum="5" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="120"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="30" />
|
||||
<Label VerticalAlignment="Center" FontSize="14"
|
||||
Content="{Binding #reflectionsFramerate.Value, StringFormat='{}{0} FPS'}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShadowsResolution], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="shaderResolutionSlider" Minimum="9" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="14"
|
||||
ValueChanged="shaderResolutionSlider_OnValueChanged" TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="12" />
|
||||
<TextBlock Name="shaderResolution" VerticalAlignment="Center" Text="4096 px" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShaderRange], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="shaderRange" Minimum="25" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="400"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="150" />
|
||||
<Label VerticalAlignment="Center" FontSize="14"
|
||||
Content="{Binding #shaderRange.Value, StringFormat='{}{0} m'}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [CabShadowsRange], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="cabShaderSourceRange" Minimum="0" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100"
|
||||
TickFrequency="10"
|
||||
IsSnapToTickEnabled="True" Value="30" />
|
||||
<Label VerticalAlignment="Center" FontSize="14"
|
||||
Content="{Binding #cabShaderSourceRange.Value, StringFormat='{}{0} m'}" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShadowDisplay], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBox x:Name="ShadowDisplayCb" MinWidth="150" MaxWidth="150" 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>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ReflectionsDetails], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBox x:Name="ReflectionsDetailsCb" MinWidth="350" MaxWidth="350" SelectedIndex="0">
|
||||
<ComboBoxItem Content="{Binding [RDTerrain], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [RDTerrainModels], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<ComboBoxItem Content="{Binding [RDTerrainModelsVehicles], Source={x:Static starterNg:App.Loc}}"/>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [ShadowsCabRange], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider Name="fovSlider" Minimum="5" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="110"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="30" />
|
||||
<Label VerticalAlignment="Center" FontSize="14"
|
||||
Content="{Binding #fovSlider.Value, StringFormat='{}{0} stopni'}" />
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="RenderScreensCb" Content="{Binding [RenderScreens], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<CheckBox x:Name="RenderScreensThreadCb" Content="{Binding [RenderScreensThread], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [RenderScreensFramerate], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="RenderScreensFramerateSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="5"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="5" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</suki:SettingsLayoutItem.Content>
|
||||
</suki:SettingsLayoutItem>
|
||||
|
||||
<suki:SettingsLayoutItem Header="{Binding [Physics], Source={x:Static starterNg:App.Loc}}">
|
||||
<suki:SettingsLayoutItem.Content>
|
||||
<StackPanel Spacing="8" Orientation="Vertical">
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [TrackCurvesQuality], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="TrackCurvesSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="4"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True" Value="4" />
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="PhysicsAccuracyCb" Content="{Binding [PhysicsAccuracyIncreased], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="PantographBreakCb" Content="{Binding [BreakingPantographPossibility], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="OverheadOnlyCb" Content="{Binding [PowerOverheadLineOnly], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="SpeedometerTapesCb" Content="{Binding [SaveSpeedometerTapes], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="SimLogsCb" Content="{Binding [SaveSimLogs], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="KeepLogsCb" Content="{Binding [KeepPrevLogs], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="DisplaySimulationCb" Content="{Binding [DisplaySimulation], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<CheckBox x:Name="CrashDamageCb" Content="{Binding [CrashDamage], Source={x:Static starterNg:App.Loc}}"/>
|
||||
</StackPanel>
|
||||
</suki:SettingsLayoutItem.Content>
|
||||
</suki:SettingsLayoutItem>
|
||||
|
||||
<suki:SettingsLayoutItem Header="{Binding [Sounds], Source={x:Static starterNg:App.Loc}}">
|
||||
<suki:SettingsLayoutItem.Content>
|
||||
<StackPanel Spacing="8" Orientation="Vertical">
|
||||
<CheckBox x:Name="EnableSoundsCb" Content="{Binding [EnableSounds], Source={x:Static starterNg:App.Loc}}"/>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [Volume], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="VolumeSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [RadiophoneVolume], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="RadioVolumeSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [VehiclesVolume], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="VehiclesVolumeSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [PositionedSoundsVolume], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="PositionalVolumeSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [AmbientVolume], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="AmbientVolumeSlider" Minimum="1" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="100" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Spacing="8" Orientation="Horizontal">
|
||||
<TextBlock VerticalAlignment="Center" FontSize="14" Text="{Binding [VolumeDuringPause], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<Slider x:Name="PauseVolumeSlider" Minimum="0" MaxWidth="400"
|
||||
HorizontalAlignment="Left"
|
||||
MinWidth="250" Maximum="100"
|
||||
TickFrequency="5"
|
||||
IsSnapToTickEnabled="True" Value="0" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</suki:SettingsLayoutItem.Content>
|
||||
</suki:SettingsLayoutItem>
|
||||
|
||||
<suki:SettingsLayoutItem Header="{Binding [Starter], Source={x:Static starterNg:App.Loc}}">
|
||||
<suki:SettingsLayoutItem.Content>
|
||||
<StackPanel Spacing="8" Orientation="Vertical">
|
||||
<CheckBox x:Name="AutoCloseStarterCb" Content="{Binding [AutoCloseStarter], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<CheckBox x:Name="LargeThumbnailsCb" Content="{Binding [LargeThumbnails], Source={x:Static starterNg:App.Loc}}"/>
|
||||
<CheckBox x:Name="AutoExpandTreeCb" Content="{Binding [AutoExpandSceneryTree], Source={x:Static starterNg:App.Loc}}"/>
|
||||
</StackPanel>
|
||||
</suki:SettingsLayoutItem.Content>
|
||||
</suki:SettingsLayoutItem>
|
||||
</objectModel:ObservableCollection>
|
||||
</suki:SettingsLayout.Items>
|
||||
</suki:SettingsLayout>
|
||||
<!-- Starter -->
|
||||
<TabItem Header="{Binding [Starter], Source={x:Static starterNg:App.Loc}}">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Spacing="8" Orientation="Vertical" Margin="12">
|
||||
<CheckBox x:Name="AutoCloseStarterCb" Content="{Binding [AutoCloseStarter], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="LargeThumbnailsCb" Content="{Binding [LargeThumbnails], Source={x:Static starterNg:App.Loc}}" />
|
||||
<CheckBox x:Name="AutoExpandTreeCb" Content="{Binding [AutoExpandSceneryTree], Source={x:Static starterNg:App.Loc}}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</DockPanel>
|
||||
</UserControl>
|
||||
|
||||
Reference in New Issue
Block a user