diff --git a/App.config b/App.config
index 8d643b8..931ba7e 100644
--- a/App.config
+++ b/App.config
@@ -22,6 +22,9 @@
True
+
+
+
\ No newline at end of file
diff --git a/MainWindow.xaml b/MainWindow.xaml
index 08a4591..d00452c 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -3,38 +3,44 @@
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:local="clr-namespace:WpfMaiTouchEmulator"
mc:Ignorable="d"
Closing="MainWindow_Closing"
- Title="MainWindow" Height="282" Width="800">
-
-
+ Title="MainWindow" Height="360" Width="500" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
+
+
+ TextWrapping="Wrap" Margin="376,34,0,219" HorizontalAlignment="Left" Width="88" />
-
-
-
-
-
-
-
-
-
-
-
-
-
+ TextWrapping="Wrap" Margin="376,121,0,129" HorizontalAlignment="Left" Width="88" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 1c2cac2..c8a6a5b 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -6,13 +6,21 @@ namespace WpfMaiTouchEmulator;
public partial class MainWindow : Window
{
private readonly MaiTouchSensorButtonStateManager buttonState;
- private MaiTouchComConnector connector;
+ private readonly MaiTouchComConnector connector;
private readonly VirtualComPortManager comPortManager;
private TouchPanel _touchPanel;
public MainWindow()
{
InitializeComponent();
+ DataContext = new MainWindowViewModel()
+ {
+ IsDebugEnabled = Properties.Settings.Default.IsDebugEnabled,
+ IsAutomaticPortConnectingEnabled = Properties.Settings.Default.IsAutomaticPortConnectingEnabled,
+ IsAutomaticPositioningEnabled = Properties.Settings.Default.IsAutomaticPositioningEnabled,
+ IsExitWithSinmaiEnabled = Properties.Settings.Default.IsExitWithSinmaiEnabled,
+ };
+
Title = "Mai Touch Emulator";
buttonState = new MaiTouchSensorButtonStateManager(buttonStateValue);
connector = new MaiTouchComConnector(buttonState);
@@ -53,6 +61,7 @@ public partial class MainWindow : Window
Properties.Settings.Default.Save();
}
+
Loaded += (s, e) => {
Logger.Info("Main window loaded, creating touch panel");
_touchPanel = new TouchPanel();
@@ -60,15 +69,9 @@ public partial class MainWindow : Window
_touchPanel.onRelease = (value) => { buttonState.ReleaseButton(value); };
_touchPanel.Show();
_touchPanel.Owner = this;
- DataContext = new MainWindowViewModel()
- {
- IsDebugEnabled = Properties.Settings.Default.IsDebugEnabled,
- IsAutomaticPortConnectingEnabled = Properties.Settings.Default.IsAutomaticPortConnectingEnabled,
- IsAutomaticPositioningEnabled = Properties.Settings.Default.IsAutomaticPositioningEnabled,
- IsExitWithSinmaiEnabled = Properties.Settings.Default.IsExitWithSinmaiEnabled
- };
var dataContext = (MainWindowViewModel)DataContext;
+
_touchPanel.SetDebugMode(dataContext.IsDebugEnabled);
if (Properties.Settings.Default.IsAutomaticPositioningEnabled)
{
@@ -81,7 +84,7 @@ public partial class MainWindow : Window
};
}
- private async void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ private async void MainWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
await connector.Disconnect();
@@ -90,7 +93,7 @@ public partial class MainWindow : Window
childWindow.Close();
}
Closing -= MainWindow_Closing;
- Close();
+ e.Cancel = false;
}
private async void ExitWithSinmaiLoop()
diff --git a/MainWindowViewModel.cs b/MainWindowViewModel.cs
index ef5d418..4d5637b 100644
--- a/MainWindowViewModel.cs
+++ b/MainWindowViewModel.cs
@@ -1,14 +1,107 @@
using System.ComponentModel;
+using System.Globalization;
+using System.Resources;
using System.Runtime.CompilerServices;
namespace WpfMaiTouchEmulator;
-internal class MainWindowViewModel : INotifyPropertyChanged
+public class MainWindowViewModel : INotifyPropertyChanged
{
+ // Language
+ public string LbAutoPortConnecting
+ {
+ get; set;
+ }
+ public string LbAutoSensorPositioning
+ {
+ get; set;
+ }
+ public string LbButtonState
+ {
+ get; set;
+ }
+ public string LbConnectionState
+ {
+ get; set;
+ }
+ public string LbConnectionStateNotConnected
+ {
+ get; set;
+ }
+ public string LbConnectToPort
+ {
+ get; set;
+ }
+ public string LbDebugMode
+ {
+ get; set;
+ }
+ public string LbExitWithSinmai
+ {
+ get; set;
+ }
+ public string LbInstallComPort
+ {
+ get; set;
+ }
+ public string LbLanguageDropdown
+ {
+ get; set;
+ }
+ public string LbListComPorts
+ {
+ get; set;
+ }
+ public string LbReceivedData
+ {
+ get; set;
+ }
+ public string LbRecievedData
+ {
+ get;
+ private set;
+ }
+ public string LbSentData
+ {
+ get; set;
+ }
+ public string LbUninstallComPort
+ {
+ get; set;
+ }
+
+
private bool _isAutomaticPortConnectingEnabled;
private bool _isDebugEnabled;
private bool _isAutomaticPositioningEnabled;
private bool _isExitWithSinmaiEnabled;
+ private CultureInfo _selectedLanguage;
+ private readonly ResourceManager resourceManager;
+ private readonly CultureInfo cultureInfo;
+
+ public List SupportedLanguages
+ {
+ get;
+ } =
+ [
+ new CultureInfo("en-US"), // English
+ new CultureInfo("zh-CN") // Chinese (Simplified)
+ ];
+
+
+ public MainWindowViewModel()
+ {
+ resourceManager = new ResourceManager("WpfMaiTouchEmulator.Properties.Resources", typeof(MainWindowViewModel).Assembly);
+ LoadLanguageSettings();
+ }
+
+ private void LoadLanguageSettings()
+ {
+ var savedLang = Properties.Settings.Default.UserLanguage;
+ var culture = string.IsNullOrEmpty(savedLang) ? CultureInfo.CurrentCulture : new CultureInfo(savedLang);
+
+ SelectedLanguage = SupportedLanguages.Contains(culture) ? culture : SupportedLanguages[0];
+ }
public bool IsDebugEnabled
{
@@ -50,6 +143,51 @@ internal class MainWindowViewModel : INotifyPropertyChanged
}
}
+ public CultureInfo SelectedLanguage
+ {
+ get => _selectedLanguage;
+ set
+ {
+ if (_selectedLanguage != value)
+ {
+ _selectedLanguage = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedLanguage)));
+ ChangeLanguage(value);
+ }
+ }
+ }
+
+ private void ChangeLanguage(CultureInfo culture)
+ {
+ Properties.Settings.Default.UserLanguage = culture.Name;
+ Properties.Settings.Default.Save();
+
+ Thread.CurrentThread.CurrentUICulture = culture;
+ ResourceManager rm = new ResourceManager(typeof(Resources.Strings));
+ UpdateLocalizedResources(rm);
+ }
+
+ private void UpdateLocalizedResources(ResourceManager resourceManager)
+ {
+ LbAutoPortConnecting = resourceManager.GetString("lbAutoPortConnecting");
+ LbAutoSensorPositioning = resourceManager.GetString("lbAutoSensorPositioning");
+ LbButtonState = resourceManager.GetString("lbButtonState");
+ LbConnectionState = resourceManager.GetString("lbConnectionState");
+ LbConnectionStateNotConnected = resourceManager.GetString("lbConnectionStateNotConnected");
+ LbConnectToPort = resourceManager.GetString("lbConnectToPort");
+ LbDebugMode = resourceManager.GetString("lbDebugMode");
+ LbExitWithSinmai = resourceManager.GetString("lbExitWithSinmai");
+ LbInstallComPort = resourceManager.GetString("lbInstallComPort");
+ LbLanguageDropdown = resourceManager.GetString("lbLanguageDropdown");
+ LbListComPorts = resourceManager.GetString("lbListComPorts");
+ LbReceivedData = resourceManager.GetString("lbReceivedData");
+ LbRecievedData = resourceManager.GetString("lbRecievedData");
+ LbSentData = resourceManager.GetString("lbSentData");
+ LbUninstallComPort = resourceManager.GetString("lbUninstallComPort");
+
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(null));
+ }
+
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs
index 6b40f06..e07e5ad 100644
--- a/Properties/Settings.Designer.cs
+++ b/Properties/Settings.Designer.cs
@@ -82,5 +82,17 @@ namespace WpfMaiTouchEmulator.Properties {
this["FirstOpen"] = value;
}
}
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("")]
+ public string UserLanguage {
+ get {
+ return ((string)(this["UserLanguage"]));
+ }
+ set {
+ this["UserLanguage"] = value;
+ }
+ }
}
}
diff --git a/Properties/Settings.settings b/Properties/Settings.settings
index cee27a0..f6efed3 100644
--- a/Properties/Settings.settings
+++ b/Properties/Settings.settings
@@ -17,5 +17,8 @@
True
+
+
+
\ No newline at end of file
diff --git a/Resources/Strings.Designer.cs b/Resources/Strings.Designer.cs
new file mode 100644
index 0000000..6026333
--- /dev/null
+++ b/Resources/Strings.Designer.cs
@@ -0,0 +1,189 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace WpfMaiTouchEmulator.Resources {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Strings {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Strings() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WpfMaiTouchEmulator.Resources.Strings", typeof(Strings).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Automatic port connecting.
+ ///
+ internal static string lbAutoPortConnecting {
+ get {
+ return ResourceManager.GetString("lbAutoPortConnecting", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Automatic sensor window positioning.
+ ///
+ internal static string lbAutoSensorPositioning {
+ get {
+ return ResourceManager.GetString("lbAutoSensorPositioning", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Button State.
+ ///
+ internal static string lbButtonState {
+ get {
+ return ResourceManager.GetString("lbButtonState", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Connection state.
+ ///
+ internal static string lbConnectionState {
+ get {
+ return ResourceManager.GetString("lbConnectionState", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Not connected.
+ ///
+ internal static string lbConnectionStateNotConnected {
+ get {
+ return ResourceManager.GetString("lbConnectionStateNotConnected", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Connect to port.
+ ///
+ internal static string lbConnectToPort {
+ get {
+ return ResourceManager.GetString("lbConnectToPort", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Debug mode.
+ ///
+ internal static string lbDebugMode {
+ get {
+ return ResourceManager.GetString("lbDebugMode", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Exit when Sinmai exits.
+ ///
+ internal static string lbExitWithSinmai {
+ get {
+ return ResourceManager.GetString("lbExitWithSinmai", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Install com port.
+ ///
+ internal static string lbInstallComPort {
+ get {
+ return ResourceManager.GetString("lbInstallComPort", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Language.
+ ///
+ internal static string lbLanguageDropdown {
+ get {
+ return ResourceManager.GetString("lbLanguageDropdown", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to List installed com ports.
+ ///
+ internal static string lbListComPorts {
+ get {
+ return ResourceManager.GetString("lbListComPorts", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Recieved.
+ ///
+ internal static string lbRecievedData {
+ get {
+ return ResourceManager.GetString("lbRecievedData", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Sent.
+ ///
+ internal static string lbSentData {
+ get {
+ return ResourceManager.GetString("lbSentData", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Uninstall com port.
+ ///
+ internal static string lbUninstallComPort {
+ get {
+ return ResourceManager.GetString("lbUninstallComPort", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/Resources/Strings.resx b/Resources/Strings.resx
new file mode 100644
index 0000000..ad4eb2f
--- /dev/null
+++ b/Resources/Strings.resx
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Automatic port connecting
+
+
+ Automatic sensor window positioning
+
+
+ Button State
+
+
+ Connection state
+
+
+ Not connected
+
+
+ Connect to port
+
+
+ Debug mode
+
+
+ Exit when Sinmai exits
+
+
+ Install com port
+
+
+ Language
+
+
+ List installed com ports
+
+
+ Recieved
+
+
+ Sent
+
+
+ Uninstall com port
+
+
\ No newline at end of file
diff --git a/Resources/Strings.zh-CN.resx b/Resources/Strings.zh-CN.resx
new file mode 100644
index 0000000..cb42c51
--- /dev/null
+++ b/Resources/Strings.zh-CN.resx
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 自动端口连接
+
+
+ 自动传感器窗口定位
+
+
+ 按钮状态
+
+
+ 连接状态
+
+
+ 未连接
+
+
+ 连接到端口
+
+
+ 调试模式
+
+
+ 随Sinmai退出
+
+
+ 安装串行端口
+
+
+ 语言
+
+
+ 列出已安装的串行端口
+
+
+ 已接收数据
+
+
+ 已发送数据
+
+
+ 卸载串行端口
+
+
\ No newline at end of file
diff --git a/WpfMaiTouchEmulator.csproj b/WpfMaiTouchEmulator.csproj
index 2a476c3..f317d68 100644
--- a/WpfMaiTouchEmulator.csproj
+++ b/WpfMaiTouchEmulator.csproj
@@ -19,6 +19,18 @@
True
Settings.settings
+
+ True
+ True
+ Strings.resx
+
+
+
+
+
+ ResXFileCodeGenerator
+ Strings.Designer.cs
+