ShakerSettingViewModel.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. using Avalonia;
  2. using Avalonia.Collections;
  3. using Avalonia.Controls;
  4. using Avalonia.Controls.ApplicationLifetimes;
  5. using Avalonia.Markup.Xaml;
  6. using CommunityToolkit.Mvvm.Input;
  7. using Shaker.Models;
  8. using ShakerApp.Models;
  9. using ShakerApp.Views;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Diagnostics.CodeAnalysis;
  13. using System.IO;
  14. using System.Linq;
  15. using System.Reflection;
  16. using System.Windows.Input;
  17. namespace ShakerApp.ViewModels
  18. {
  19. public class ShakerSettingViewModel : ViewModelBase<Models.ShakerSettingModel>
  20. {
  21. public override bool CanResize => false;
  22. public override double Width => 960;
  23. public override double Height => 660;
  24. public const string LANGUAGECHANGEDEVENT = "LanguageChangedEvnet";
  25. private static string PlugnsPath =Path.Combine(AppDomain.CurrentDomain.BaseDirectory , "Language");
  26. public Models.WorkingMode WorkingMode
  27. {
  28. get => Model.WorkingMode;
  29. set
  30. {
  31. SetProperty(ref Model.WorkingMode, value);
  32. if(value == Models.WorkingMode.Remote)
  33. {
  34. EnabledRemote = false;
  35. if(ServieIsStart)
  36. {
  37. StopService();
  38. }
  39. }
  40. else
  41. {
  42. }
  43. }
  44. }
  45. [PropertyAssociation(nameof(ShakerSettingModel.RemoteIP))]
  46. public string RemoteIP { get => Model.RemoteIP; set => SetProperty(ref Model.RemoteIP, value); }
  47. [PropertyAssociation(nameof(ShakerSettingModel.RemotePort))]
  48. public int RemotePort { get => Model.RemotePort; set => SetProperty(ref Model.RemotePort, value); }
  49. [PropertyAssociation(nameof(ShakerSettingModel.RemoteControlModel))]
  50. public Models.RemoteControlModel RemoteControlModel { get => Model.RemoteControlModel; set => SetProperty(ref Model.RemoteControlModel, value); }
  51. [PropertyAssociation(nameof(ShakerSettingModel.EnabledRemote))]
  52. public bool EnabledRemote { get => Model.EnabledRemote; set => SetProperty(ref Model.EnabledRemote, value); }
  53. [PropertyAssociation(nameof(ShakerSettingModel.AutoStartService))]
  54. public bool AutoStartService { get => Model.AutoStartService; set => SetProperty(ref Model.AutoStartService, value); }
  55. public bool ServieIsStart { get => servieIsStart; set =>SetProperty(ref servieIsStart ,value); }
  56. [AllowNull]
  57. private ILanguage.ILanguage currentLanguage;
  58. private bool servieIsStart = false;
  59. public AvaloniaList<ILanguage.ILanguage> Languages { get; } = new AvaloniaList<ILanguage.ILanguage>();
  60. public ILanguage.ILanguage CurrentLanguage
  61. {
  62. get => currentLanguage;
  63. set
  64. {
  65. var temp = value;
  66. if (temp == null) return;
  67. if (currentLanguage == value) return;
  68. ApplyLanguage(value);
  69. SetProperty(ref currentLanguage, value);
  70. GetEvent(LANGUAGECHANGEDEVENT).Publish(this, null);
  71. if (currentLanguage != null)
  72. {
  73. Language = currentLanguage.Key;
  74. }
  75. }
  76. }
  77. public override void Init()
  78. {
  79. LoadAllLanguages();
  80. }
  81. public ICommand SelectDirectoryCommand => new RelayCommand<string?>(SelectDirectory);
  82. private async void SelectDirectory(string? p)
  83. {
  84. if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
  85. {
  86. var folder = await TopLevel.GetTopLevel(desktop.MainWindow)!.StorageProvider.OpenFolderPickerAsync(new Avalonia.Platform.Storage.FolderPickerOpenOptions()
  87. {
  88. Title = p ==null ?"": App.Current?.FindResource(p) + "",
  89. AllowMultiple = false,
  90. });
  91. if(folder!=null && folder.Count>0)
  92. {
  93. DataDirectory = folder.First().Path.LocalPath;
  94. }
  95. }
  96. }
  97. private void ApplyLanguage(ILanguage.ILanguage language)
  98. {
  99. var rd = Avalonia.Application.Current?.Resources;
  100. if (rd == null || language == null) return;
  101. //RemoveLangThemes();
  102. //将资源加载在最后,优先使用;
  103. rd.MergedDictionaries.Add((ResourceDictionary)AvaloniaXamlLoader.Load(new Uri(language.ResourcePath, UriKind.Absolute)));
  104. var list = Languages.Where(x => x != language).ToList();
  105. List<ResourceDictionary> removeList = new List<ResourceDictionary>();
  106. foreach (var dictionary in rd.MergedDictionaries.Cast<ResourceDictionary>())
  107. {
  108. bool isExists = list.Exists(x => dictionary.TryGetResource("Name", null, out var val) && val + "" == x.Name);
  109. if (isExists)
  110. {
  111. removeList.Add(dictionary);
  112. }
  113. }
  114. foreach (var val in removeList)
  115. {
  116. rd.MergedDictionaries.Remove(val);
  117. }
  118. }
  119. private void LoadAllLanguages()
  120. {
  121. Languages.Clear();
  122. Tools.PluginsLoader.Defalut.Load<ILanguage.ILanguage>(PlugnsPath)
  123. .ForEach(x => Languages.Add(x));
  124. if (Languages.Count == 0)
  125. {
  126. MainViewModel.Default.ShowError("没有语言文件,程序错误退出");
  127. return;
  128. }
  129. CurrentLanguage = Languages.FirstOrDefault(x => x.Key == Model.Language) ?? Languages.First();
  130. }
  131. private readonly string ConfigPath = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory , "Config"), "ShakerConfig.json");
  132. [PropertyAssociation(nameof(ShakerSettingModel.Language))]
  133. public string Language { get => Model.Language; set => SetProperty(ref Model.Language, value); }
  134. [PropertyAssociation(nameof(ShakerSettingModel.DataDirectory))]
  135. public string DataDirectory
  136. {
  137. get
  138. {
  139. if(!System.IO.Directory.Exists(Model.DataDirectory))
  140. {
  141. Directory.CreateDirectory(Model.DataDirectory);
  142. }
  143. return Model.DataDirectory;
  144. }
  145. set => SetProperty(ref Model.DataDirectory, value);
  146. }
  147. private ShakerSettingViewModel()
  148. {
  149. Content = typeof(Views.ShakerSettingView);
  150. Pages.AddRange(this.GetType().Assembly.GetTypes()
  151. .Where(x => x.GetInterface(typeof(Views.ISettingPageView).FullName!) != null && x.IsAnsiClass && !x.IsAbstract && x.GetCustomAttribute<SettingPageAttribute>()!=null)
  152. .Select(x=>
  153. {
  154. var att = x.GetCustomAttribute<SettingPageAttribute>();
  155. return (att!.Index, x);
  156. })
  157. .OrderBy(x=>x.Index)
  158. .Select(x=>x.x));
  159. var fileinfp = new FileInfo(ConfigPath);
  160. if (!System.IO.Directory.Exists(fileinfp.DirectoryName)) Directory.CreateDirectory(fileinfp.DirectoryName!);
  161. var model = Tools.Tools.ReadConfig<Models.ShakerSettingModel>(ConfigPath);
  162. if (model == null)
  163. {
  164. Save();
  165. }
  166. }
  167. static ShakerSettingViewModel()
  168. {
  169. }
  170. public AvaloniaList<Type> Pages { get; } = new AvaloniaList<Type>();
  171. public override void InitData()
  172. {
  173. base.InitData();
  174. }
  175. public ICommand StartServiceCommand => new RelayCommand(StartService);
  176. public ICommand StopServiceCommand => new RelayCommand(StopService);
  177. private void StartService()
  178. {
  179. CommunicationViewModel.Instance.StartService("0.0.0.0", RemotePort);
  180. }
  181. public void StopService()
  182. {
  183. CommunicationViewModel.Instance.StopService();
  184. }
  185. protected override void Save()
  186. {
  187. base.Save();
  188. Tools.Tools.SaveConfig(Model, ConfigPath);
  189. }
  190. protected override bool SkipProperty(string? propertyName)
  191. {
  192. return (propertyName == nameof(Pages)
  193. || propertyName == nameof(ConfigPath)
  194. || propertyName == nameof(SelectDirectoryCommand)
  195. || propertyName == nameof(ServieIsStart));
  196. }
  197. public static ShakerSettingViewModel Instance { get; } = new ShakerSettingViewModel();
  198. }
  199. }