SettingsViewModel.cs
1 // Copyright (c) Microsoft Corporation 2 // The Microsoft Corporation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Collections.ObjectModel; 6 using System.ComponentModel; 7 using Microsoft.CmdPal.UI.ViewModels.Services; 8 using Microsoft.CmdPal.UI.ViewModels.Settings; 9 using Microsoft.CommandPalette.Extensions.Toolkit; 10 11 namespace Microsoft.CmdPal.UI.ViewModels; 12 13 public partial class SettingsViewModel : INotifyPropertyChanged 14 { 15 private static readonly List<TimeSpan> AutoGoHomeIntervals = 16 [ 17 Timeout.InfiniteTimeSpan, 18 TimeSpan.Zero, 19 TimeSpan.FromSeconds(10), 20 TimeSpan.FromSeconds(20), 21 TimeSpan.FromSeconds(30), 22 TimeSpan.FromSeconds(60), 23 TimeSpan.FromSeconds(90), 24 TimeSpan.FromSeconds(120), 25 TimeSpan.FromSeconds(180), 26 ]; 27 28 private readonly SettingsModel _settings; 29 private readonly TopLevelCommandManager _topLevelCommandManager; 30 31 public event PropertyChangedEventHandler? PropertyChanged; 32 33 public AppearanceSettingsViewModel Appearance { get; } 34 35 public HotkeySettings? Hotkey 36 { 37 get => _settings.Hotkey; 38 set 39 { 40 _settings.Hotkey = value ?? SettingsModel.DefaultActivationShortcut; 41 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Hotkey))); 42 Save(); 43 } 44 } 45 46 public bool UseLowLevelGlobalHotkey 47 { 48 get => _settings.UseLowLevelGlobalHotkey; 49 set 50 { 51 _settings.UseLowLevelGlobalHotkey = value; 52 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Hotkey))); 53 Save(); 54 } 55 } 56 57 public bool AllowExternalReload 58 { 59 get => _settings.AllowExternalReload; 60 set 61 { 62 _settings.AllowExternalReload = value; 63 Save(); 64 } 65 } 66 67 public bool ShowAppDetails 68 { 69 get => _settings.ShowAppDetails; 70 set 71 { 72 _settings.ShowAppDetails = value; 73 Save(); 74 } 75 } 76 77 public bool BackspaceGoesBack 78 { 79 get => _settings.BackspaceGoesBack; 80 set 81 { 82 _settings.BackspaceGoesBack = value; 83 Save(); 84 } 85 } 86 87 public bool SingleClickActivates 88 { 89 get => _settings.SingleClickActivates; 90 set 91 { 92 _settings.SingleClickActivates = value; 93 Save(); 94 } 95 } 96 97 public bool HighlightSearchOnActivate 98 { 99 get => _settings.HighlightSearchOnActivate; 100 set 101 { 102 _settings.HighlightSearchOnActivate = value; 103 Save(); 104 } 105 } 106 107 public int MonitorPositionIndex 108 { 109 get => (int)_settings.SummonOn; 110 set 111 { 112 _settings.SummonOn = (MonitorBehavior)value; 113 Save(); 114 } 115 } 116 117 public bool ShowSystemTrayIcon 118 { 119 get => _settings.ShowSystemTrayIcon; 120 set 121 { 122 _settings.ShowSystemTrayIcon = value; 123 Save(); 124 } 125 } 126 127 public bool IgnoreShortcutWhenFullscreen 128 { 129 get => _settings.IgnoreShortcutWhenFullscreen; 130 set 131 { 132 _settings.IgnoreShortcutWhenFullscreen = value; 133 Save(); 134 } 135 } 136 137 public bool DisableAnimations 138 { 139 get => _settings.DisableAnimations; 140 set 141 { 142 _settings.DisableAnimations = value; 143 Save(); 144 } 145 } 146 147 public int AutoGoBackIntervalIndex 148 { 149 get 150 { 151 var index = AutoGoHomeIntervals.IndexOf(_settings.AutoGoHomeInterval); 152 return index >= 0 ? index : 0; 153 } 154 155 set 156 { 157 if (value >= 0 && value < AutoGoHomeIntervals.Count) 158 { 159 _settings.AutoGoHomeInterval = AutoGoHomeIntervals[value]; 160 } 161 162 Save(); 163 } 164 } 165 166 public int EscapeKeyBehaviorIndex 167 { 168 get => (int)_settings.EscapeKeyBehaviorSetting; 169 set 170 { 171 _settings.EscapeKeyBehaviorSetting = (EscapeKeyBehavior)value; 172 Save(); 173 } 174 } 175 176 public ObservableCollection<ProviderSettingsViewModel> CommandProviders { get; } = new(); 177 178 public ObservableCollection<FallbackSettingsViewModel> FallbackRankings { get; set; } = new(); 179 180 public SettingsExtensionsViewModel Extensions { get; } 181 182 public SettingsViewModel(SettingsModel settings, TopLevelCommandManager topLevelCommandManager, TaskScheduler scheduler, IThemeService themeService) 183 { 184 _settings = settings; 185 _topLevelCommandManager = topLevelCommandManager; 186 187 Appearance = new AppearanceSettingsViewModel(themeService, _settings); 188 189 var activeProviders = GetCommandProviders(); 190 var allProviderSettings = _settings.ProviderSettings; 191 192 var fallbacks = new List<FallbackSettingsViewModel>(); 193 var currentRankings = _settings.FallbackRanks; 194 var needsSave = false; 195 196 foreach (var item in activeProviders) 197 { 198 var providerSettings = settings.GetProviderSettings(item); 199 200 var settingsModel = new ProviderSettingsViewModel(item, providerSettings, _settings); 201 CommandProviders.Add(settingsModel); 202 203 fallbacks.AddRange(settingsModel.FallbackCommands); 204 } 205 206 var fallbackRankings = new List<Scored<FallbackSettingsViewModel>>(fallbacks.Count); 207 foreach (var fallback in fallbacks) 208 { 209 var index = currentRankings.IndexOf(fallback.Id); 210 var score = fallbacks.Count; 211 212 if (index >= 0) 213 { 214 score = index; 215 } 216 217 fallbackRankings.Add(new Scored<FallbackSettingsViewModel>() { Item = fallback, Score = score }); 218 219 if (index == -1) 220 { 221 needsSave = true; 222 } 223 } 224 225 FallbackRankings = new ObservableCollection<FallbackSettingsViewModel>(fallbackRankings.OrderBy(o => o.Score).Select(fr => fr.Item)); 226 Extensions = new SettingsExtensionsViewModel(CommandProviders, scheduler); 227 228 if (needsSave) 229 { 230 ApplyFallbackSort(); 231 } 232 } 233 234 private IEnumerable<CommandProviderWrapper> GetCommandProviders() 235 { 236 var allProviders = _topLevelCommandManager.CommandProviders; 237 return allProviders; 238 } 239 240 public void ApplyFallbackSort() 241 { 242 _settings.FallbackRanks = FallbackRankings.Select(s => s.Id).ToArray(); 243 Save(); 244 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FallbackRankings))); 245 } 246 247 private void Save() => SettingsModel.SaveSettings(_settings); 248 }