using Avalonia; using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using CommunityToolkit.Mvvm.Input; using Shaker.Models; using ShakerApp.Models; using ShakerApp.Views; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Windows.Input; namespace ShakerApp.ViewModels { public class ShakerSettingViewModel : DisplayViewModelBase { public override bool CanResize => false; public override double Width => 960; public override double Height => 660; public const string LANGUAGECHANGEDEVENT = "LanguageChangedEvnet"; private static string PlugnsPath =Path.Combine(AppDomain.CurrentDomain.BaseDirectory , "Language"); public Models.WorkingMode WorkingMode { get => Model.WorkingMode; set { SetProperty(ref Model.WorkingMode, value); if(value == Models.WorkingMode.Remote) { EnabledRemote = false; if(ServieIsStart) { StopService(); } } else { } MenuViewModel.Instance["MenuManger"]!.IsVisible = value == WorkingMode.Local; MenuViewModel.Instance["MenuConnect"]!.IsVisible = value == WorkingMode.Remote; } } [PropertyAssociation(nameof(ShakerSettingModel.RemoteIP))] public string RemoteIP { get => Model.RemoteIP; set => SetProperty(ref Model.RemoteIP, value); } [PropertyAssociation(nameof(ShakerSettingModel.RemotePort))] public int RemotePort { get => Model.RemotePort; set => SetProperty(ref Model.RemotePort, value); } [PropertyAssociation(nameof(ShakerSettingModel.RemoteControlModel))] public Models.RemoteControlModel RemoteControlModel { get => Model.RemoteControlModel; set => SetProperty(ref Model.RemoteControlModel, value); } [PropertyAssociation(nameof(ShakerSettingModel.EnabledRemote))] public bool EnabledRemote { get => Model.EnabledRemote; set => SetProperty(ref Model.EnabledRemote, value); } [PropertyAssociation(nameof(ShakerSettingModel.AutoStartService))] public bool AutoStartService { get => Model.AutoStartService; set => SetProperty(ref Model.AutoStartService, value); } public bool ServieIsStart { get => servieIsStart; set =>SetProperty(ref servieIsStart ,value); } [AllowNull] private ILanguage.ILanguage currentLanguage; private bool servieIsStart = false; public AvaloniaList Languages { get; } = new AvaloniaList(); public ILanguage.ILanguage CurrentLanguage { get => currentLanguage; set { var temp = value; if (temp == null) return; if (currentLanguage == value) return; ApplyLanguage(value); SetProperty(ref currentLanguage, value); GetEvent(LANGUAGECHANGEDEVENT).Publish(this, null); if (currentLanguage != null) { Language = currentLanguage.Key; } } } public override void Init() { LoadAllLanguages(); } public ICommand SelectDirectoryCommand => new RelayCommand(SelectDirectory); private async void SelectDirectory(string? p) { if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { var folder = await TopLevel.GetTopLevel(desktop.MainWindow)!.StorageProvider.OpenFolderPickerAsync(new Avalonia.Platform.Storage.FolderPickerOpenOptions() { Title = p ==null ?"": App.Current?.FindResource(p) + "", AllowMultiple = false, }); if(folder!=null && folder.Count>0) { DataDirectory = folder.First().Path.LocalPath; } } } private void ApplyLanguage(ILanguage.ILanguage language) { var rd = Avalonia.Application.Current?.Resources; if (rd == null || language == null) return; //RemoveLangThemes(); //将资源加载在最后,优先使用; rd.MergedDictionaries.Add((ResourceDictionary)AvaloniaXamlLoader.Load(new Uri(language.ResourcePath, UriKind.Absolute))); var list = Languages.Where(x => x != language).ToList(); List removeList = new List(); foreach (var dictionary in rd.MergedDictionaries.Cast()) { bool isExists = list.Exists(x => dictionary.TryGetResource("Name", null, out var val) && val + "" == x.Name); if (isExists) { removeList.Add(dictionary); } } foreach (var val in removeList) { rd.MergedDictionaries.Remove(val); } } private void LoadAllLanguages() { Languages.Clear(); Tools.PluginsLoader.Defalut.Load(PlugnsPath) .ForEach(x => Languages.Add(x)); if (Languages.Count == 0) { MainViewModel.Default.ShowError("没有语言文件,程序错误退出"); return; } CurrentLanguage = Languages.FirstOrDefault(x => x.Key == Model.Language) ?? Languages.First(); } private readonly string ConfigPath = Path.Combine(Path.Combine(AppDomain.CurrentDomain.BaseDirectory , "Config"), "ShakerConfig.json"); [PropertyAssociation(nameof(ShakerSettingModel.Language))] public string Language { get => Model.Language; set => SetProperty(ref Model.Language, value); } [PropertyAssociation(nameof(ShakerSettingModel.DataDirectory))] public string DataDirectory { get { if(!System.IO.Directory.Exists(Model.DataDirectory)) { Directory.CreateDirectory(Model.DataDirectory); } return Model.DataDirectory; } set => SetProperty(ref Model.DataDirectory, value); } private ShakerSettingViewModel() { Content = typeof(Views.ShakerSettingView); Pages.AddRange(this.GetType().Assembly.GetTypes() .Where(x => x.GetInterface(typeof(Views.ISettingPageView).FullName!) != null && x.IsAnsiClass && !x.IsAbstract && x.GetCustomAttribute()!=null) .Select(x=> { var att = x.GetCustomAttribute(); return (att!.Index, x); }) .OrderBy(x=>x.Index) .Select(x=>x.x)); var fileinfp = new FileInfo(ConfigPath); if (!System.IO.Directory.Exists(fileinfp.DirectoryName)) Directory.CreateDirectory(fileinfp.DirectoryName!); var model = Tools.Tools.ReadConfig(ConfigPath); if (model == null) { Save(); } } static ShakerSettingViewModel() { } public AvaloniaList Pages { get; } = new AvaloniaList(); public override void InitData() { base.InitData(); } public ICommand StartServiceCommand => new RelayCommand(StartService); public ICommand StopServiceCommand => new RelayCommand(StopService); private void StartService() { CommunicationViewModel.Instance.StartService("0.0.0.0", RemotePort); } public void StopService() { CommunicationViewModel.Instance.StopService(); } protected override void Save() { base.Save(); Tools.Tools.SaveConfig(Model, ConfigPath); } protected override bool SkipProperty(string? propertyName) { return (propertyName == nameof(Pages) || propertyName == nameof(ConfigPath) || propertyName == nameof(SelectDirectoryCommand) || propertyName == nameof(ServieIsStart)); } public static ShakerSettingViewModel Instance { get; } = new ShakerSettingViewModel(); } }