From d812ec296aa337fc6698a6e5af1e3c0ba7b85700 Mon Sep 17 00:00:00 2001 From: sydneyowl <84191144+SydneyOwl@users.noreply.github.com> Date: Sun, 11 Aug 2024 13:30:46 +0800 Subject: [PATCH] :art: shx8800pro works (ui) --- Constants/Shx8800Pro/DTMF_CHOICE.cs | 16 ++ Constants/Shx8800Pro/FUNCTION_CHOICE.cs | 175 ++++++++++++++++++++++ DataModels/Gt12/FMChannel.cs | 2 +- DataModels/Shx8800Pro/AppData.cs | 6 +- DataModels/Shx8800Pro/DTMF.cs | 14 +- Views/Shx8800Pro/DTMFWindow.axaml | 51 +++++++ Views/Shx8800Pro/DTMFWindow.axaml.cs | 131 +++++++++++++++++ Views/Shx8800Pro/FMWindow.axaml | 38 +++++ Views/Shx8800Pro/FMWindow.axaml.cs | 142 ++++++++++++++++++ Views/Shx8800Pro/MainWindow.axaml.cs | 14 +- Views/Shx8800Pro/OptionalWindow.axaml | 177 +++++++++++++++++++++++ Views/Shx8800Pro/OptionalWindow.axaml.cs | 61 ++++++++ 12 files changed, 800 insertions(+), 27 deletions(-) create mode 100644 Constants/Shx8800Pro/DTMF_CHOICE.cs create mode 100644 Constants/Shx8800Pro/FUNCTION_CHOICE.cs create mode 100644 Views/Shx8800Pro/DTMFWindow.axaml create mode 100644 Views/Shx8800Pro/DTMFWindow.axaml.cs create mode 100644 Views/Shx8800Pro/FMWindow.axaml create mode 100644 Views/Shx8800Pro/FMWindow.axaml.cs create mode 100644 Views/Shx8800Pro/OptionalWindow.axaml create mode 100644 Views/Shx8800Pro/OptionalWindow.axaml.cs diff --git a/Constants/Shx8800Pro/DTMF_CHOICE.cs b/Constants/Shx8800Pro/DTMF_CHOICE.cs new file mode 100644 index 0000000..918e7d4 --- /dev/null +++ b/Constants/Shx8800Pro/DTMF_CHOICE.cs @@ -0,0 +1,16 @@ +using System.Collections.ObjectModel; + +namespace SenhaixFreqWriter.Constants.Shx8800Pro; + +public class DtmfChoice +{ + public static ObservableCollection Time = new() + { + "50 ms", "100 ms", "200 ms", "300 ms", "500 ms" + }; + + public static ObservableCollection SendID = new() + { + "关", "按下PPT", "松开PPT", "两者" + }; +} \ No newline at end of file diff --git a/Constants/Shx8800Pro/FUNCTION_CHOICE.cs b/Constants/Shx8800Pro/FUNCTION_CHOICE.cs new file mode 100644 index 0000000..eff446d --- /dev/null +++ b/Constants/Shx8800Pro/FUNCTION_CHOICE.cs @@ -0,0 +1,175 @@ +using System.Collections.ObjectModel; + +namespace SenhaixFreqWriter.Constants.Shx8800Pro; + +public class FunctionChoice +{ + public static ObservableCollection Sql = new() + { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" + }; + + public static ObservableCollection TxTimeout = new() + { + "关", "30s", "60s", "90s", "120s", "150s", "180s", "210s", "240s" + }; + + public static ObservableCollection SaveMode = new() + { + "关", "普通省电","超级省电","深度省电" + }; + + public static ObservableCollection Vox = new() + { + "高灵敏度", "中灵敏度", "低灵敏度" + }; + + public static ObservableCollection VoiceSW = new() + { + "关", "开" + }; + + public static ObservableCollection VoxDelay = new() + { + "0.5s", "0.6s", "0.7s", "0.8s", "0.9s", "1.0s", "1.1s", "1.2s", "1.3s", "1.4s", + "1.5s", "1.6s", "1.7s", "1.8s", "1.9s", "2.0s" + }; + + public static ObservableCollection DoubleWait = new() + { + "关", "开" + }; + + public static ObservableCollection Tone = new() + { + "1000Hz", "1450Hz", "1750Hz", "2100Hz" + }; + + public static ObservableCollection SideTone = new() + { + "关", "按键侧音","身份码侧音","两者" + }; + + public static ObservableCollection TailClear = new() + { + "关", "开" + }; + + public static ObservableCollection PowerOnDisplay = new() + { + "LOGO", "电池电压" + }; + + public static ObservableCollection Beep = new() + { + "关", "开" + }; + + public static ObservableCollection Roger = new() + { + "关", "开" + }; + + public static ObservableCollection BtMicGain = new() + { + "1", "2", "3", "4", "5" + }; + + public static ObservableCollection MicGain = new() + { + "低增益", "中增益", "高增益" + }; + + public static ObservableCollection ScanMode = new() + { + "时间扫描", "载波扫描", "搜索扫描" + }; + + public static ObservableCollection Sos = new() + { + "现场报警", "发射报警音", "发射报警码" + }; + + public static ObservableCollection SosVoice = new() + { + "关","开" + }; + + public static ObservableCollection KeyLock = new() + { + "关", "开" + }; + + public static ObservableCollection Fm = new() + { + "允许", "禁止" + }; + + public static ObservableCollection AutoLock = new() + { + "关", "5 s", "10 s", "15 s" + }; + + public static ObservableCollection AutoQuit = new() + { + "5 s", "10 s", "15 s", "20 s", "25 s", "30 s", "35 s", "40 s", "45 s", "50 s", + "60 s" + }; + + public static ObservableCollection BackgroundLightTime = new() + { + "常开", "5 s", "10 s", "15 s", "20 s", "30 s", "1 min", "2 min", "3 min" + }; + + public static ObservableCollection SendCodeDelay = new() + { + "0 ms", "100 ms", "200 ms", "400 ms", "600 ms", "800 ms" + }; + + public static ObservableCollection DisplayType = new() + { + "信道名称", "频率", "信道号" + }; + + public static ObservableCollection WorkMode = new() + { + "频率模式", "信道模式" + }; + + public static ObservableCollection KeyFunc = new() + { + "收音机", "监听", "扫描", "扫频", "天气预报" + }; + + public static ObservableCollection RptTailClear = new() + { + "0", "100 ms", "200 ms", "300 ms", "400 ms", "500 ms", "600 ms", "700 ms", "800 ms", "900 ms", "1000 ms" + }; + + public static ObservableCollection RptDetectTail = new() + { + "0", "100 ms", "200 ms", "300 ms", "400 ms", "500 ms", "600 ms", "700 ms", "800 ms", "900 ms", "1000 ms" + }; + + public static ObservableCollection VoxSwitch = new() + { + "关", "开" + }; + + public static ObservableCollection PowerUpDisplayTime = new() + { + "0.2 s", "0.4 s", "0.6 s", "0.8 s", "1.0 s", "1.2 s", "1.4 s", "1.6 s", "1.8 s", "2.0 s", + "2.2 s", "2.4 s", "2.6 s", "2.8 s", "3.0 s" + }; + + public static ObservableCollection BtGain = new() + { + "1", "2", "3", "4", "5" + }; + + public static ObservableCollection CurBank = new() + { + "1", "2", "3", "4", "5", + "6", "7", "8" + }; +} \ No newline at end of file diff --git a/DataModels/Gt12/FMChannel.cs b/DataModels/Gt12/FMChannel.cs index d461bd8..2908a73 100644 --- a/DataModels/Gt12/FMChannel.cs +++ b/DataModels/Gt12/FMChannel.cs @@ -4,7 +4,7 @@ namespace SenhaixFreqWriter.DataModels.Gt12; public partial class FmChannel : ObservableObject { - [ObservableProperty] private int[] _channels = new int[15]; + [ObservableProperty] private int[] _channels = new int[30]; [ObservableProperty] private int _curFreq = 904; } diff --git a/DataModels/Shx8800Pro/AppData.cs b/DataModels/Shx8800Pro/AppData.cs index afa73cc..6421cb5 100644 --- a/DataModels/Shx8800Pro/AppData.cs +++ b/DataModels/Shx8800Pro/AppData.cs @@ -10,11 +10,9 @@ public class AppData { [JsonIgnore] public static AppData Instance; - public string[] BankName = new string[30] + public string[] BankName = new string[8] { - "区域一", "区域二", "区域三", "区域四", "区域五", "区域六", "区域七", "区域八", "区域九", "区域十", - "区域十一", "区域十二", "区域十三", "区域十四", "区域十五", "区域十六", "区域十七", "区域十八", "区域十九", "区域二十", - "区域二十一", "区域二十二", "区域二十三", "区域二十四", "区域二十五", "区域二十六", "区域二十七", "区域二十八", "区域二十九", "区域三十" + "区域一", "区域二", "区域三", "区域四", "区域五", "区域六", "区域七", "区域八", };// public Channel[][] ChannelList = new Channel[8][];// diff --git a/DataModels/Shx8800Pro/DTMF.cs b/DataModels/Shx8800Pro/DTMF.cs index a91bb72..921652f 100644 --- a/DataModels/Shx8800Pro/DTMF.cs +++ b/DataModels/Shx8800Pro/DTMF.cs @@ -4,8 +4,8 @@ namespace SenhaixFreqWriter.DataModels.Shx8800Pro; public partial class Dtmf : ObservableObject { - [ObservableProperty] private string[] _group = new string[20]; - [ObservableProperty] private string[] _groupName = new string[20]; + [ObservableProperty] private string[] _group = new string[15]; + [ObservableProperty] private string[] _groupName = new string[15]; //seems useless... [ObservableProperty] private int _idleTime = 1; [ObservableProperty] private string _localId = "100"; [ObservableProperty] private int _wordTime = 1; @@ -43,16 +43,6 @@ public Dtmf() GroupName[13] = "成员14"; Group[14] = "115"; GroupName[14] = "成员15"; - Group[15] = "116"; - GroupName[15] = "成员16"; - Group[16] = "117"; - GroupName[16] = "成员17"; - Group[17] = "118"; - GroupName[17] = "成员18"; - Group[18] = "119"; - GroupName[18] = "成员19"; - Group[19] = "120"; - GroupName[19] = "成员20"; } } diff --git a/Views/Shx8800Pro/DTMFWindow.axaml b/Views/Shx8800Pro/DTMFWindow.axaml new file mode 100644 index 0000000..d5a1653 --- /dev/null +++ b/Views/Shx8800Pro/DTMFWindow.axaml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Views/Shx8800Pro/DTMFWindow.axaml.cs b/Views/Shx8800Pro/DTMFWindow.axaml.cs new file mode 100644 index 0000000..68c0371 --- /dev/null +++ b/Views/Shx8800Pro/DTMFWindow.axaml.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.ObjectModel; +using System.Text; +using Avalonia.Controls; +using MsBox.Avalonia; +using SenhaixFreqWriter.DataModels.Shx8800Pro; +using SenhaixFreqWriter.Views.Common; + +namespace SenhaixFreqWriter.Views.Shx8800Pro; + +public partial class DtmfWindow : Window +{ + private ObservableCollection _dtmfs = new(); + + private int _idleTime = AppData.GetInstance().Dtmfs.IdleTime; + + private string _myId = AppData.GetInstance().Dtmfs.LocalId; + + private int _wordTime = AppData.GetInstance().Dtmfs.WordTime; + + private int _pttid = AppData.GetInstance().Dtmfs.Pttid; + + public DtmfWindow() + { + InitializeComponent(); + DataContext = this; + var dtmfOrig = AppData.GetInstance().Dtmfs; + for (var i = 0; i < 15; i++) + { + var tmp = new DtmpObject(); + tmp.Id = (i + 1).ToString(); + tmp.GroupName = dtmfOrig.GroupName[i]; + tmp.Group = dtmfOrig.Group[i]; + Dtmfs.Add(tmp); + } + + // Closing += async (sender, args) => + // { + // for (var i = 0; i < 20; i++) + // if (string.IsNullOrEmpty(Dtmfs[i].Group) || string.IsNullOrEmpty(Dtmfs[i].GroupName)) + // { + // args.Cancel = true; + // DebugWindow.GetInstance().updateDebugContent("阻止窗口关闭:有空字段"); + // await MessageBoxManager.GetMessageBoxStandard("注意", "未填写完整,不能有为空的字段!") + // .ShowWindowDialogAsync(this); + // return; + // } + // + // for (var j = 0; j < 20; j++) + // { + // AppData.GetInstance().Dtmfs.Group[j] = Dtmfs[j].Group; + // AppData.GetInstance().Dtmfs.GroupName[j] = Dtmfs[j].GroupName; + // } + // }; + } + + public int PttID + { + get => _pttid; + set + { + _pttid = value; + AppData.GetInstance().Dtmfs.Pttid = value; + } + } + + public int WordTime + { + get => _wordTime; + set + { + _wordTime = value; + AppData.GetInstance().Dtmfs.WordTime = value; + } + } + + public int IdleTime + { + get => _idleTime; + set + { + _idleTime = value; + AppData.GetInstance().Dtmfs.IdleTime = value; + } + } + + + public string MyId + { + get => _myId; + set + { + _myId = value ?? throw new ArgumentNullException(nameof(value)); + AppData.GetInstance().Dtmfs.LocalId = value; + } + } + + public ObservableCollection Dtmfs + { + get => _dtmfs; + set => _dtmfs = value ?? throw new ArgumentNullException(nameof(value)); + } + + private void GroupCodeInputElement_OnLostFocus(object? sender, TextChangedEventArgs e) + { + var textbox = (TextBox)sender; + var inputText = textbox.Text; + if (inputText.Length > 8) + { + MessageBoxManager.GetMessageBoxStandard("注意", "最多8位!").ShowWindowDialogAsync(this); + textbox.Text = ""; + return; + } + + foreach (var c in inputText) + if ((c < '0' || c > '9') && (c < 'A' || c > 'D') && c != '*' && c != '#') + { + MessageBoxManager.GetMessageBoxStandard("注意", "码只能是数字、大写字母以及*#").ShowWindowDialogAsync(this); + textbox.Text = ""; + return; + } + } + + private void GroupNameInputElement_OnLostFocus(object? sender, TextChangedEventArgs e) + { + var textbox = (TextBox)sender; + var inputText = textbox.Text; + var bytes = Encoding.GetEncoding("gb2312").GetBytes(inputText); + if (bytes.Length > 12) textbox.Text = Encoding.GetEncoding("gb2312").GetString(bytes, 0, 12); + } +} \ No newline at end of file diff --git a/Views/Shx8800Pro/FMWindow.axaml b/Views/Shx8800Pro/FMWindow.axaml new file mode 100644 index 0000000..0c151f4 --- /dev/null +++ b/Views/Shx8800Pro/FMWindow.axaml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Views/Shx8800Pro/FMWindow.axaml.cs b/Views/Shx8800Pro/FMWindow.axaml.cs new file mode 100644 index 0000000..fe875e4 --- /dev/null +++ b/Views/Shx8800Pro/FMWindow.axaml.cs @@ -0,0 +1,142 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Avalonia; +using Avalonia.Controls; +using MsBox.Avalonia; +using SenhaixFreqWriter.DataModels.Shx8800Pro; + +namespace SenhaixFreqWriter.Views.Shx8800Pro; + +public partial class FmWindow : Window +{ + public FmWindow() + { + InitializeComponent(); + DataContext = this; + for (var i = 0; i < AppData.GetInstance().Fms.Channels.Length; i++) + { + var tmp = new FmObject(); + tmp.Id = i + 1; + var freq = AppData.GetInstance().Fms.Channels[i].ToString(); + if (freq != "0") + { + tmp.Freq = freq.Insert(freq.Length - 1, "."); + ; + } + + Fmchannels.Add(tmp); + } + + ; + Closing += (sender, args) => + { + for (var i = 0; i < AppData.GetInstance().Fms.Channels.Length; i++) + { + var tmp = Fmchannels[i].Freq.Replace(".", ""); + int cache; + if (!int.TryParse(tmp, out cache)) continue; + AppData.GetInstance().Fms.Channels[i] = cache; + } + + if (string.IsNullOrEmpty(CurFreq)) return; + AppData.GetInstance().Fms.CurFreq = int.Parse(CurFreq.Replace(".", "")); + }; + } + + public ObservableCollection Fmchannels { get; set; } = new(); + + public string CurFreq { get; set; } = AppData.GetInstance().Fms.CurFreq.ToString() + .Insert(AppData.GetInstance().Fms.CurFreq.ToString().Length - 1, "."); + + private void CalcSeq() + { + for (var i = 0; i < AppData.GetInstance().Fms.Channels.Length; i++) Fmchannels[i].Id = i; + } + + private void Freq_OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) + { + } + + private void FreqInputElement_OnLostFocus(object? sender, TextChangedEventArgs e) + { + var textBox = (TextBox)sender; + var dataContext = textBox.DataContext as FmObject; + var text = dataContext.Freq; + double fmfreq; + if (string.IsNullOrEmpty(text)) return; + if (!double.TryParse(text, out fmfreq)) + { + MessageBoxManager.GetMessageBoxStandard("注意", "频率格式错误!").ShowWindowDialogAsync(this); + textBox.Text = ""; + return; + } + + if (text.Length < 2 || (text.Length == 2 && text.StartsWith("10"))) return; + text = fmfreq.ToString("0.0"); + + var array = text.Split('.'); + var list = new List(); + int num3; + list.Add(int.Parse(array[0])); + if (array.Length > 1) + { + list.Add(int.Parse(array[1])); + num3 = list[0] * 10 + list[1]; + } + else + { + num3 = list[0] * 10; + } + + if (num3 < 650 || num3 > 1080) + { + MessageBoxManager.GetMessageBoxStandard("注意", "频率要在65.0-108.0之间").ShowWindowDialogAsync(this); + textBox.Text = ""; + return; + } + + text = num3.ToString(); + textBox.Text = text.Insert(text.Length - 1, "."); + } + + private void currFreqInputElement_OnLostFocus(object? sender, TextChangedEventArgs e) + { + var textBox = (TextBox)sender; + var text = textBox.Text; + double fmfreq; + if (string.IsNullOrEmpty(text)) return; + if (!double.TryParse(text, out fmfreq)) + { + MessageBoxManager.GetMessageBoxStandard("注意", "频率格式错误!").ShowWindowDialogAsync(this); + textBox.Text = ""; + return; + } + + if (text.Length < 2 || (text.Length == 2 && text.StartsWith("10"))) return; + text = fmfreq.ToString("0.0"); + + var array = text.Split('.'); + var list = new List(); + int num3; + list.Add(int.Parse(array[0])); + if (array.Length > 1) + { + list.Add(int.Parse(array[1])); + num3 = list[0] * 10 + list[1]; + } + else + { + num3 = list[0] * 10; + } + + if (num3 < 650 || num3 > 1080) + { + MessageBoxManager.GetMessageBoxStandard("注意", "频率要在65.0-108.0之间").ShowWindowDialogAsync(this); + textBox.Text = ""; + return; + } + + text = num3.ToString(); + textBox.Text = text.Insert(text.Length - 1, "."); + } +} \ No newline at end of file diff --git a/Views/Shx8800Pro/MainWindow.axaml.cs b/Views/Shx8800Pro/MainWindow.axaml.cs index efb6a74..c79f105 100644 --- a/Views/Shx8800Pro/MainWindow.axaml.cs +++ b/Views/Shx8800Pro/MainWindow.axaml.cs @@ -375,17 +375,17 @@ private void VfoMenuItem_OnClick(object? sender, RoutedEventArgs e) private void OptionalMenuItem_OnClick(object? sender, RoutedEventArgs e) { - // new OptionalWindow().ShowDialog(this); + new OptionalWindow().ShowDialog(this); } private void FMMenuItem_OnClick(object? sender, RoutedEventArgs e) { - // new FmWindow().ShowDialog(this); + new FmWindow().ShowDialog(this); } private void DTMFMenuItem_OnClick(object? sender, RoutedEventArgs e) { - // new DtmfWindow().ShowDialog(this); + new DtmfWindow().ShowDialog(this); } private async void NewFileMenuItem_OnClick(object? sender, RoutedEventArgs e) @@ -423,7 +423,7 @@ private async void SaveAsMenuItem_OnClick(object? sender, RoutedEventArgs e) var file = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions { Title = "保存配置文件", - SuggestedFileName = "Backup-GT12-" + ts + ".dat" + SuggestedFileName = "Backup-shx8800pro-" + ts + ".dat" }); if (file is not null) { @@ -498,12 +498,6 @@ private void InsertNewChannel(string rx, string dec, string tx, string enc, stri ListItems[lastEmptyIndex] = data; } - private async void BLEMenuItem_OnClick(object? sender, RoutedEventArgs e) - { - await MessageBoxManager.GetMessageBoxStandard("注意", "GT12的蓝牙写频真的超慢,不知道为啥:(建议用写频线").ShowWindowDialogAsync(this); - new BluetoothDeviceSelectionWindow(SHX_DEVICE.GT12).ShowDialog(this); - } - private void DebugWindowMenuItem_OnClick(object? sender, RoutedEventArgs e) { DebugWindow.GetInstance().Show(); diff --git a/Views/Shx8800Pro/OptionalWindow.axaml b/Views/Shx8800Pro/OptionalWindow.axaml new file mode 100644 index 0000000..ae97c0d --- /dev/null +++ b/Views/Shx8800Pro/OptionalWindow.axaml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Views/Shx8800Pro/OptionalWindow.axaml.cs b/Views/Shx8800Pro/OptionalWindow.axaml.cs new file mode 100644 index 0000000..f766f3b --- /dev/null +++ b/Views/Shx8800Pro/OptionalWindow.axaml.cs @@ -0,0 +1,61 @@ +using Avalonia.Controls; +using MsBox.Avalonia; +using SenhaixFreqWriter.DataModels.Shx8800Pro; + +namespace SenhaixFreqWriter.Views.Shx8800Pro; + +public partial class OptionalWindow : Window +{ + public OptionalWindow() + { + InitializeComponent(); + DataContext = this; + } + + public Function Func { get; set; } = AppData.GetInstance().FunCfgs; + public Mdc1200 Mdc { get; set; } = AppData.GetInstance().Mdcs; + + + private void CallsignInputElement_OnLostFocus(object? sender, TextChangedEventArgs e) + { + var textbox = (TextBox)sender; + var cont = textbox.Text; + if (cont.Length > 6) + { + MessageBoxManager.GetMessageBoxStandard("注意", "最多6位!").ShowWindowDialogAsync(this); + textbox.Text = ""; + return; + } + + foreach (var c in cont) + if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z'))) + { + MessageBoxManager.GetMessageBoxStandard("注意", "呼号错误!").ShowWindowDialogAsync(this); + textbox.Text = ""; + return; + } + + textbox.Text = textbox.Text.ToUpper(); + } + + private void MDCInputElement_OnLostFocus(object? sender, TextChangedEventArgs e) + { + var textbox = (TextBox)sender; + var cont = textbox.Text; + if (cont.Length > 4) + { + MessageBoxManager.GetMessageBoxStandard("注意", "最多4位!").ShowWindowDialogAsync(this); + textbox.Text = ""; + return; + } + + foreach (var c in cont) + if ((c < '0' || c > '9') && (c < 'A' || c > 'F')) + { + MessageBoxManager.GetMessageBoxStandard("注意", "只能是数字或大写字母!").ShowWindowDialogAsync(this); + textbox.Text = ""; + return; + } + } +} \ No newline at end of file