diff --git a/CRSim.Core/CRSim.Core.csproj b/CRSim.Core/CRSim.Core.csproj
index c7a5d96..403739f 100644
--- a/CRSim.Core/CRSim.Core.csproj
+++ b/CRSim.Core/CRSim.Core.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/CRSim.Core/Converters/ColorJsonConverter.cs b/CRSim.Core/Converters/ColorJsonConverter.cs
new file mode 100644
index 0000000..258078b
--- /dev/null
+++ b/CRSim.Core/Converters/ColorJsonConverter.cs
@@ -0,0 +1,22 @@
+using System.Drawing;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+namespace CRSim.Core.Converters
+{
+ public class ColorJsonConverter : JsonConverter
+ {
+ public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ // 从十六进制字符串(如 "#FF00BE")读取并转换回 Color
+ string? hex = reader.GetString();
+ return hex == null ? Color.Empty : ColorTranslator.FromHtml(hex);
+ }
+
+ public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options)
+ {
+ // 将 Color 转换为十六进制字符串格式写入 JSON
+ if (value.IsEmpty) writer.WriteNullValue();
+ else writer.WriteStringValue($"#{value.R:X2}{value.G:X2}{value.B:X2}");
+ }
+ }
+}
diff --git a/CRSim.Core/Models/Json.cs b/CRSim.Core/Models/Json.cs
index 6e0ab43..14041fe 100644
--- a/CRSim.Core/Models/Json.cs
+++ b/CRSim.Core/Models/Json.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace CRSim.Core.Models
+namespace CRSim.Core.Models
{
public class Json
{
diff --git a/CRSim.Core/Models/PlatformDiagram/TrainColor.cs b/CRSim.Core/Models/PlatformDiagram/TrainColor.cs
new file mode 100644
index 0000000..a8e7070
--- /dev/null
+++ b/CRSim.Core/Models/PlatformDiagram/TrainColor.cs
@@ -0,0 +1,14 @@
+using CRSim.Core.Converters;
+using System.Drawing;
+using System.Text.Json.Serialization;
+
+namespace CRSim.Core.Models.PlatformDiagram
+{
+ public class TrainColor
+ {
+ public required string Prefix { get; set; }
+
+ [JsonConverter(typeof(ColorJsonConverter))]
+ public required Color Color { get; set; }
+ }
+}
diff --git a/CRSim.Core/Models/Settings.cs b/CRSim.Core/Models/Settings.cs
index aafc984..a5a47ff 100644
--- a/CRSim.Core/Models/Settings.cs
+++ b/CRSim.Core/Models/Settings.cs
@@ -1,5 +1,8 @@
using CRSim.Core.Abstractions;
+using CRSim.Core.Converters;
+using CRSim.Core.Models.PlatformDiagram;
using CRSim.Core.Services;
+using System.Drawing;
using System.Text.Json.Serialization;
namespace CRSim.Core.Models
@@ -29,5 +32,18 @@ namespace CRSim.Core.Models
public string UserKey { get; set; } = "";
public bool LoadTodayOnly { get; set; } = false;
public bool ReopenUnclosedScreensOnLoad { get; set; } = true;
+
+ public List TrainColors { get; set; } =
+ [
+ new TrainColor { Prefix = "G", Color = Color.Magenta },
+ new TrainColor { Prefix = "D", Color = Color.SteelBlue },
+ new TrainColor { Prefix = "C", Color = Color.Teal },
+ new TrainColor { Prefix = "T", Color = Color.Blue },
+ new TrainColor { Prefix = "Z", Color = Color.SaddleBrown },
+ new TrainColor { Prefix = "K", Color = Color.Red },
+ new TrainColor { Prefix = "Y", Color = Color.Red },
+ new TrainColor { Prefix = "L", Color = Color.Green },
+ new TrainColor { Prefix = "默认", Color = Color.Green }
+ ];
}
}
diff --git a/CRSim.Core/Models/Simulator/Station.cs b/CRSim.Core/Models/Simulator/Station.cs
index c45fb08..bcd2273 100644
--- a/CRSim.Core/Models/Simulator/Station.cs
+++ b/CRSim.Core/Models/Simulator/Station.cs
@@ -1,11 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.Json.Serialization;
-using System.Threading.Tasks;
-
-namespace CRSim.Core.Models
+namespace CRSim.Core.Models
{
public class Station
{
diff --git a/CRSim.PlatformDiagram/PlatformDiagram.cs b/CRSim.PlatformDiagram/PlatformDiagram.cs
index d6ab7df..f94bb0b 100644
--- a/CRSim.PlatformDiagram/PlatformDiagram.cs
+++ b/CRSim.PlatformDiagram/PlatformDiagram.cs
@@ -1,5 +1,6 @@
-// Trigger CI build
+using CRSim.Core.Abstractions;
using CRSim.Core.Models;
+using CRSim.Core.Models.PlatformDiagram;
using iText.IO.Font;
using iText.Kernel.Colors;
using iText.Kernel.Font;
@@ -15,7 +16,7 @@ namespace CRSim.PlatformDiagram
{
public class Generator
{
- public static void Generate(Station station, string savePath, float pageWidth)
+ public static void Generate(Station station, string savePath, float pageWidth,List trainColors)
{
float Padding = 40;
float HeaderHeight = 16;
@@ -168,27 +169,14 @@ namespace CRSim.PlatformDiagram
TimeSpan arrival = (TimeSpan)(train.ArrivalTime ?? train.DepartureTime - fixedDuration);
TimeSpan departure = (TimeSpan)(train.DepartureTime ?? train.ArrivalTime + fixedDuration);
- var trainColors = new Dictionary
- {
- { "G", "FF00BE" }, // pink
- { "D", "004C99" }, // deep blue
- { "C", "009999" }, // cyan
- { "T", "0000FF" }, // blue
- { "Z", "804000" }, // brown
- { "K", "FF0000" }, // red
- { "Y", "FF0000" }, // red
- { "L", "008000" }, // dark green
- { "default", "008000" } // dark green
- };
- string firstChar = train.Number[..1].ToUpper();
- string colorHex = trainColors.TryGetValue(firstChar, out string? value) ? value : trainColors["default"];
- var color = new DeviceRgb(
- Convert.ToInt32(colorHex[..2], 16),
- Convert.ToInt32(colorHex.Substring(2, 2), 16),
- Convert.ToInt32(colorHex.Substring(4, 2), 16)
- );
- canvas.SetFillColor(color);
- canvas.SetStrokeColor(color);
+ var matchedColor = trainColors
+ .Where(tc => train.Number.StartsWith(tc.Prefix))
+ .OrderByDescending(tc => tc.Prefix.Length)
+ .FirstOrDefault();
+ var color = matchedColor?.Color ?? trainColors.FirstOrDefault(x => x.Prefix == "默认").Color;
+ Color itextColor = new DeviceRgb(color.R, color.G, color.B);
+ canvas.SetFillColor(itextColor);
+ canvas.SetStrokeColor(itextColor);
// 检查是否跨零点
if (departure < arrival)
diff --git a/CRSim.ScreenSimulator/CRSim.ScreenSimulator.csproj b/CRSim.ScreenSimulator/CRSim.ScreenSimulator.csproj
index e3a4558..b2c2b72 100644
--- a/CRSim.ScreenSimulator/CRSim.ScreenSimulator.csproj
+++ b/CRSim.ScreenSimulator/CRSim.ScreenSimulator.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/CRSim/CRSim.csproj b/CRSim/CRSim.csproj
index 10c8c93..da95ca0 100644
--- a/CRSim/CRSim.csproj
+++ b/CRSim/CRSim.csproj
@@ -12,6 +12,7 @@
true
enable
preview
+ true
@@ -40,13 +41,14 @@
-
-
-
-
+
+
+
+
+
-
-
+
+
diff --git a/CRSim/Converters/DrawingToUIColorConverter.cs b/CRSim/Converters/DrawingToUIColorConverter.cs
new file mode 100644
index 0000000..079efe1
--- /dev/null
+++ b/CRSim/Converters/DrawingToUIColorConverter.cs
@@ -0,0 +1,24 @@
+using Microsoft.UI.Xaml.Data;
+namespace CRSim.Converters
+{
+ public partial class DrawingToUIColorConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, string language)
+ {
+ if (value is System.Drawing.Color sColor)
+ {
+ return Windows.UI.Color.FromArgb(sColor.A, sColor.R, sColor.G, sColor.B);
+ }
+ return Windows.UI.Color.FromArgb(0,0,0,0);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, string language)
+ {
+ if (value is Windows.UI.Color wColor)
+ {
+ return System.Drawing.Color.FromArgb(wColor.A, wColor.R, wColor.G, wColor.B);
+ }
+ return System.Drawing.Color.FromArgb(0, 0, 0, 0);
+ }
+ }
+}
diff --git a/CRSim/Properties/GlobalUsing.cs b/CRSim/Properties/GlobalUsing.cs
index 3e4086d..1e77abc 100644
--- a/CRSim/Properties/GlobalUsing.cs
+++ b/CRSim/Properties/GlobalUsing.cs
@@ -28,6 +28,7 @@ global using CRSim.PlatformDiagram;
global using CRSim.WebsiteSimulator;
global using CRSim.Core.Utils;
global using CRSim.Core.Models;
+global using CRSim.Core.Models.PlatformDiagram;
global using CRSim.Core.Services;
global using CRSim.Core.Abstractions;
diff --git a/CRSim/Services/DialogService.cs b/CRSim/Services/DialogService.cs
index 9956f19..19b5ec9 100644
--- a/CRSim/Services/DialogService.cs
+++ b/CRSim/Services/DialogService.cs
@@ -1,7 +1,5 @@
-using CRSim.Core.Models;
+using CRSim.Views.DialogContents;
using Microsoft.Win32;
-using Windows.Storage;
-using Windows.Storage.Pickers;
namespace CRSim.Services
{
@@ -275,5 +273,28 @@ namespace CRSim.Services
}
return null;
}
+
+ public async Task?> EditTrainColorsAsync(List trainColors)
+ {
+ ContentDialog dialog = new()
+ {
+ XamlRoot = XamlRoot,
+ Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style,
+ Title = "编辑颜色配置",
+ PrimaryButtonText = "确定",
+ CloseButtonText = "取消",
+ DefaultButton = ContentDialogButton.Primary,
+ IsPrimaryButtonEnabled = false
+ };
+ var trainColorsDialog = new TrainColorsDialog(trainColors, isValid => dialog.IsPrimaryButtonEnabled = isValid);
+ dialog.Content = trainColorsDialog;
+ var result = await dialog.ShowAsync();
+ if (result == ContentDialogResult.Primary)
+ {
+ var inputDialog = dialog.Content as TrainColorsDialog;
+ return [.. inputDialog.TrainColors];
+ }
+ return null;
+ }
}
}
diff --git a/CRSim/Services/IDialogService.cs b/CRSim/Services/IDialogService.cs
index 1468e9c..33e4236 100644
--- a/CRSim/Services/IDialogService.cs
+++ b/CRSim/Services/IDialogService.cs
@@ -14,6 +14,7 @@
Task GetInputTrainStopAsync(List waitingAreas, List platforms);
Task EditInputTrainStopAsync(List waitingAreas, List platforms, TrainStop trainStop);
Task?> GetInputPlatformAsync();
+ Task?> EditTrainColorsAsync(List trainColors);
XamlRoot? XamlRoot { get; set; }
}
}
diff --git a/CRSim/ViewModels/PlatformDiagramPageViewModel.cs b/CRSim/ViewModels/PlatformDiagramPageViewModel.cs
index 2900902..caa0d5f 100644
--- a/CRSim/ViewModels/PlatformDiagramPageViewModel.cs
+++ b/CRSim/ViewModels/PlatformDiagramPageViewModel.cs
@@ -3,6 +3,8 @@
public partial class PlatformDiagramPageViewModel(IDialogService _dialogService, IDatabaseService _databaseService) : ObservableObject
{
public string PageTitle = "生成站台占用图";
+ private readonly ISettingsService _settingsService = App.GetService();
+
public Station? SelectedStation;
public List Stations => _databaseService.GetAllStations();
@@ -35,7 +37,7 @@ public partial class PlatformDiagramPageViewModel(IDialogService _dialogService,
}
var path = _dialogService.SaveFile(".pdf", $"{SelectedStation.Name}站台占用图");
if(string.IsNullOrEmpty(path) || SelectedStation == null) return;
- await Task.Run(() => Generator.Generate(SelectedStation, path,PageWidth));
+ await Task.Run(() => Generator.Generate(SelectedStation, path,PageWidth, _settingsService.GetSettings().TrainColors));
}
public static bool CheckStation(Station station,out string detail)
diff --git a/CRSim/ViewModels/SettingsPageViewModel.cs b/CRSim/ViewModels/SettingsPageViewModel.cs
index 20cf36d..06b62a0 100644
--- a/CRSim/ViewModels/SettingsPageViewModel.cs
+++ b/CRSim/ViewModels/SettingsPageViewModel.cs
@@ -1,10 +1,4 @@
-using Downloader;
-using System.Diagnostics;
-using System.Diagnostics.Metrics;
-using System.IO.Packaging;
-using System.Reflection;
-using System.Security.Policy;
-using Windows.System;
+using Windows.System;
namespace CRSim.ViewModels
{
@@ -62,6 +56,10 @@ namespace CRSim.ViewModels
[ObservableProperty]
public partial bool ReopenUnclosedScreensOnLoad { get; set; }
+
+ [ObservableProperty]
+ public partial List TrainColors { get; set; }
+
#endregion
public SettingsPageViewModel(ISettingsService settingsService, IDatabaseService databaseService, IDialogService dialogService, INetworkService networkService)
{
@@ -69,10 +67,8 @@ namespace CRSim.ViewModels
_databaseService = databaseService;
_dialogService = dialogService;
_networkService = networkService;
- var version = Assembly.GetExecutingAssembly().GetName().Version;
- AppVersion = $"Version {version}";
+ AppVersion = $"Version {App.AppVersion}";
LoadSettings();
-
}
private void LoadSettings()
@@ -89,6 +85,7 @@ namespace CRSim.ViewModels
UserKey = _settings.UserKey;
LoadTodayOnly = _settings.LoadTodayOnly;
ReopenUnclosedScreensOnLoad = _settings.ReopenUnclosedScreensOnLoad;
+ TrainColors = _settings.TrainColors;
}
[RelayCommand]
@@ -105,6 +102,7 @@ namespace CRSim.ViewModels
_settings.LoadTodayOnly = LoadTodayOnly;
_settings.ReopenUnclosedScreensOnLoad = ReopenUnclosedScreensOnLoad;
_settings.Api = Api;
+ _settings.TrainColors = TrainColors;
_settingsService.SaveSettings();
}
private static void UpdateSettings(string input, bool allowNegative, Action updateAction)
@@ -155,5 +153,14 @@ namespace CRSim.ViewModels
_databaseService.ImportData(path);
await _databaseService.SaveData();
}
+ [RelayCommand]
+ public async Task EditTrainColors()
+ {
+ var trainColors = await _dialogService.EditTrainColorsAsync(TrainColors);
+ if (trainColors is not null)
+ {
+ TrainColors = trainColors;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/CRSim/Views/DialogContents/CreateStationDialog.xaml b/CRSim/Views/DialogContents/CreateStationDialog.xaml
index 0d38f1d..1ed0317 100644
--- a/CRSim/Views/DialogContents/CreateStationDialog.xaml
+++ b/CRSim/Views/DialogContents/CreateStationDialog.xaml
@@ -1,9 +1,9 @@
diff --git a/CRSim/Views/DialogContents/CreateStationDialog.xaml.cs b/CRSim/Views/DialogContents/CreateStationDialog.xaml.cs
index a5aa66b..b96e8c7 100644
--- a/CRSim/Views/DialogContents/CreateStationDialog.xaml.cs
+++ b/CRSim/Views/DialogContents/CreateStationDialog.xaml.cs
@@ -1,4 +1,4 @@
-namespace CRSim.Views;
+namespace CRSim.Views.DialogContents;
public sealed partial class CreateStationDialog : Page
{
diff --git a/CRSim/Views/DialogContents/InputDialog.xaml b/CRSim/Views/DialogContents/InputDialog.xaml
index a298cd9..89b4e67 100644
--- a/CRSim/Views/DialogContents/InputDialog.xaml
+++ b/CRSim/Views/DialogContents/InputDialog.xaml
@@ -1,9 +1,9 @@
diff --git a/CRSim/Views/DialogContents/InputDialog.xaml.cs b/CRSim/Views/DialogContents/InputDialog.xaml.cs
index d5de69f..5636866 100644
--- a/CRSim/Views/DialogContents/InputDialog.xaml.cs
+++ b/CRSim/Views/DialogContents/InputDialog.xaml.cs
@@ -1,4 +1,4 @@
-namespace CRSim.Views;
+namespace CRSim.Views.DialogContents;
public sealed partial class InputDialog : Page
{
public string InputText { get; set; }
diff --git a/CRSim/Views/DialogContents/PlatformDialog.xaml b/CRSim/Views/DialogContents/PlatformDialog.xaml
index 7291872..f92f70d 100644
--- a/CRSim/Views/DialogContents/PlatformDialog.xaml
+++ b/CRSim/Views/DialogContents/PlatformDialog.xaml
@@ -1,9 +1,9 @@
diff --git a/CRSim/Views/DialogContents/PlatformDialog.xaml.cs b/CRSim/Views/DialogContents/PlatformDialog.xaml.cs
index 58a32c9..c7028ef 100644
--- a/CRSim/Views/DialogContents/PlatformDialog.xaml.cs
+++ b/CRSim/Views/DialogContents/PlatformDialog.xaml.cs
@@ -1,4 +1,4 @@
-namespace CRSim.Views;
+namespace CRSim.Views.DialogContents;
public sealed partial class PlatformDialog : Page
{
private readonly Action _onValidityChanged;
diff --git a/CRSim/Views/DialogContents/TextDialog.xaml b/CRSim/Views/DialogContents/TextDialog.xaml
index 61163c3..3d27cb4 100644
--- a/CRSim/Views/DialogContents/TextDialog.xaml
+++ b/CRSim/Views/DialogContents/TextDialog.xaml
@@ -1,9 +1,9 @@
diff --git a/CRSim/Views/DialogContents/TextDialog.xaml.cs b/CRSim/Views/DialogContents/TextDialog.xaml.cs
index 0879263..9a9a7bb 100644
--- a/CRSim/Views/DialogContents/TextDialog.xaml.cs
+++ b/CRSim/Views/DialogContents/TextDialog.xaml.cs
@@ -1,4 +1,4 @@
-namespace CRSim.Views;
+namespace CRSim.Views.DialogContents;
public sealed partial class TextDialog : Page
{
private string _text { get; set; }
diff --git a/CRSim/Views/DialogContents/TrainColorsDialog.xaml b/CRSim/Views/DialogContents/TrainColorsDialog.xaml
new file mode 100644
index 0000000..3ab600d
--- /dev/null
+++ b/CRSim/Views/DialogContents/TrainColorsDialog.xaml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CRSim/Views/DialogContents/TrainColorsDialog.xaml.cs b/CRSim/Views/DialogContents/TrainColorsDialog.xaml.cs
new file mode 100644
index 0000000..1fb652a
--- /dev/null
+++ b/CRSim/Views/DialogContents/TrainColorsDialog.xaml.cs
@@ -0,0 +1,55 @@
+using System.Drawing;
+
+namespace CRSim.Views.DialogContents;
+public sealed partial class TrainColorsDialog : Page
+{
+ public ObservableCollection TrainColors = [];
+
+ private readonly Action _onValidityChanged;
+
+ public TrainColorsDialog(List trainColors, Action onValidityChanged)
+ {
+ TrainColors = new ObservableCollection(trainColors);
+ InitializeComponent();
+ _onValidityChanged = onValidityChanged;
+ Validate(this, EventArgs.Empty);
+ }
+
+ private void Add(object sender, RoutedEventArgs e)
+ {
+ TrainColors.Add(new TrainColor() { Color = Color.Red, Prefix = string.Empty });
+ Validate(this, EventArgs.Empty);
+ }
+
+ private void Delete(object sender, RoutedEventArgs e)
+ {
+ if (TrainColorsGrid.SelectedValue is TrainColor trainColor && trainColor.Prefix != "默认")
+ {
+ TrainColors.Remove(trainColor);
+ }
+ Validate(this, EventArgs.Empty);
+ }
+
+ private void Reset(object sender, RoutedEventArgs e)
+ {
+ TrainColors.Clear();
+ foreach (var trainColor in new Settings().TrainColors)
+ {
+ TrainColors.Add(trainColor);
+ }
+ Validate(this, EventArgs.Empty);
+ }
+
+ private void Validate(object sender, object e)
+ {
+ if(TrainColorsGrid is null) { return; } //检查是否初始化完成
+ if (TrainColors.Any(x => x.Prefix == string.Empty) || TrainColors.GroupBy(x => x.Prefix).Any(g => g.Count() > 1) || !TrainColors.Any(x=>x.Prefix=="默认"))
+ {
+ _onValidityChanged(false);
+ }
+ else
+ {
+ _onValidityChanged(true);
+ }
+ }
+}
diff --git a/CRSim/Views/DialogContents/TrainNumberStopDialog.xaml b/CRSim/Views/DialogContents/TrainNumberStopDialog.xaml
index 0fd6ca5..56c8670 100644
--- a/CRSim/Views/DialogContents/TrainNumberStopDialog.xaml
+++ b/CRSim/Views/DialogContents/TrainNumberStopDialog.xaml
@@ -1,9 +1,9 @@
+
diff --git a/CRSim/Views/SettingsPage.xaml b/CRSim/Views/SettingsPage.xaml
index 58cfdc3..0eaad48 100644
--- a/CRSim/Views/SettingsPage.xaml
+++ b/CRSim/Views/SettingsPage.xaml
@@ -85,6 +85,12 @@
+
+
+
+
+
+