/
githubmirror
/
PowerToys
Обзор
Документация
Войти
/
githubmirror
/
PowerToys
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs
916 строк
45 KB
Clint Rutkas
New module: AltWindowCycle (#48281)
31 июл 2026, 08:42
Не верифицирован
31 июл 2026, 08:42
bb99c30
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO.Abstractions; using System.Linq; using System.Threading; using System.Threading.Tasks; using CommunityToolkit.WinUI.Controls; using global::PowerToys.GPOWrapper; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Controls; using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Helpers; using Microsoft.PowerToys.Settings.UI.Library.HotkeyConflicts; using Microsoft.PowerToys.Settings.UI.Library.Interfaces; using Microsoft.PowerToys.Settings.UI.Library.Utilities; using Microsoft.PowerToys.Settings.UI.Services; using Microsoft.PowerToys.Settings.UI.Views; using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using PowerToys.Interop; using Settings.UI.Library; namespace Microsoft.PowerToys.Settings.UI.ViewModels { public partial class DashboardViewModel : PageViewModelBase { private readonly object _sortLock = new object(); protected override string ModuleName => "Dashboard"; private DispatcherQueue dispatcher; public Func<string, int> SendConfigMSG { get; } public ObservableCollection<DashboardListItem> AllModules { get; set; } = new ObservableCollection<DashboardListItem>(); public ObservableCollection<DashboardListItem> ShortcutModules { get; set; } = new ObservableCollection<DashboardListItem>(); public ObservableCollection<DashboardListItem> ActionModules { get; set; } = new ObservableCollection<DashboardListItem>(); public ObservableCollection<QuickAccessItem> QuickAccessItems => _quickAccessViewModel.Items; private readonly QuickAccessViewModel _quickAccessViewModel; // Master list of module items that is sorted and projected into AllModules. private List<DashboardListItem> _moduleItems = new List<DashboardListItem>(); // Flag to prevent circular updates when a UI toggle triggers settings changes. private bool _isUpdatingFromUI; // Flag to prevent toggle operations during sorting to avoid race conditions. private bool _isSorting; private bool _isDisposed; private AllHotkeyConflictsData _allHotkeyConflictsData = new AllHotkeyConflictsData(); public AllHotkeyConflictsData AllHotkeyConflictsData { get => _allHotkeyConflictsData; set { if (Set(ref _allHotkeyConflictsData, value)) { OnPropertyChanged(); } } } public string PowerToysVersion { get { return Helper.GetProductVersion(); } } private DashboardSortOrder _dashboardSortOrder = DashboardSortOrder.Alphabetical; public DashboardSortOrder DashboardSortOrder { get => generalSettingsConfig.DashboardSortOrder; set { if (_dashboardSortOrder != value) { _dashboardSortOrder = value; generalSettingsConfig.DashboardSortOrder = value; OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(generalSettingsConfig); SendConfigMSG(outgoing.ToString()); // Notify UI before sorting so menu updates its checked state OnPropertyChanged(nameof(DashboardSortOrder)); SortModuleList(); } } } private ISettingsRepository<GeneralSettings> _settingsRepository; private GeneralSettings generalSettingsConfig; private Windows.ApplicationModel.Resources.ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; public DashboardViewModel(ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc) { dispatcher = DispatcherQueue.GetForCurrentThread(); _settingsRepository = settingsRepository; generalSettingsConfig = settingsRepository.SettingsConfig; _settingsRepository.SettingsChanged += OnSettingsChanged; // Initialize dashboard sort order from settings _dashboardSortOrder = generalSettingsConfig.DashboardSortOrder; // set the callback functions value to handle outgoing IPC message. SendConfigMSG = ipcMSGCallBackFunc; _quickAccessViewModel = new QuickAccessViewModel( _settingsRepository, new Microsoft.PowerToys.Settings.UI.Controls.QuickAccessLauncher(App.IsElevated), moduleType => Helpers.ModuleGpoHelper.GetModuleGpoConfiguration(moduleType) == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled, moduleType => Helpers.ModuleGpoHelper.GetModuleGpoConfiguration(moduleType) == global::PowerToys.GPOWrapper.GpoRuleConfigured.Enabled, resourceLoader); BuildModuleList(); SortModuleList(); RefreshShortcutModules(); } private void OnSettingsChanged(GeneralSettings newSettings) { if (_isDisposed) { return; } dispatcher.TryEnqueue(() => { if (_isDisposed) { return; } generalSettingsConfig = newSettings; // Update local field and notify UI if sort order changed if (_dashboardSortOrder != generalSettingsConfig.DashboardSortOrder) { _dashboardSortOrder = generalSettingsConfig.DashboardSortOrder; OnPropertyChanged(nameof(DashboardSortOrder)); } ModuleEnabledChangedOnSettingsPage(); }); } protected override void OnConflictsUpdated(object sender, AllHotkeyConflictsEventArgs e) { if (_isDisposed) { return; } dispatcher.TryEnqueue(() => { if (_isDisposed) { return; } var allConflictData = e.Conflicts; foreach (var inAppConflict in allConflictData.InAppConflicts) { var hotkey = inAppConflict.Hotkey; var hotkeySetting = new HotkeySettings(hotkey.Win, hotkey.Ctrl, hotkey.Alt, hotkey.Shift, hotkey.Key); inAppConflict.ConflictIgnored = HotkeyConflictIgnoreHelper.IsIgnoringConflicts(hotkeySetting); } foreach (var systemConflict in allConflictData.SystemConflicts) { var hotkey = systemConflict.Hotkey; var hotkeySetting = new HotkeySettings(hotkey.Win, hotkey.Ctrl, hotkey.Alt, hotkey.Shift, hotkey.Key); systemConflict.ConflictIgnored = HotkeyConflictIgnoreHelper.IsIgnoringConflicts(hotkeySetting); } AllHotkeyConflictsData = e.Conflicts ?? new AllHotkeyConflictsData(); }); } private void RequestConflictData() { // Request current conflicts data GlobalHotkeyConflictManager.Instance?.RequestAllConflicts(); } /// <summary> /// Builds the master list of module items. Called once during initialization. /// Each module item contains its configuration, enabled state, and GPO lock status. /// </summary> private void BuildModuleList() { _moduleItems.Clear(); foreach (ModuleType moduleType in Enum.GetValues<ModuleType>()) { if (moduleType == ModuleType.GeneralSettings) { continue; } GpoRuleConfigured gpo = ModuleGpoHelper.GetModuleGpoConfiguration(moduleType); var newItem = new DashboardListItem() { Tag = moduleType, Label = resourceLoader.GetString(ModuleHelper.GetModuleLabelResourceName(moduleType)), IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && ModuleHelper.GetIsModuleEnabled(generalSettingsConfig, moduleType)), IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, Icon = ModuleHelper.GetModuleTypeFluentIconName(moduleType), IsNew = moduleType == ModuleType.ShortcutGuide, DashboardModuleItems = GetModuleItems(moduleType), ClickCommand = new RelayCommand<object>(DashboardListItemClick), }; newItem.EnabledChangedCallback = EnabledChangedOnUI; _moduleItems.Add(newItem); } } /// <summary> /// Sorts the module list according to the current sort order and updates the AllModules collection. /// On first call, populates AllModules. On subsequent calls, uses Move() to reorder items in-place /// to avoid destroying and recreating UI elements. /// Temporarily disables interaction on all items during sorting to prevent race conditions. /// </summary> private void SortModuleList() { if (_isSorting) { return; } lock (_sortLock) { _isSorting = true; try { var sortedItems = (DashboardSortOrder switch { DashboardSortOrder.ByStatus => _moduleItems.OrderByDescending(x => x.IsEnabled).ThenBy(x => x.Label), _ => _moduleItems.OrderBy(x => x.Label), // Default alphabetical }).ToList(); // If AllModules is empty (first load), just populate it. if (AllModules.Count == 0) { foreach (var item in sortedItems) { AllModules.Add(item); } return; } // Otherwise, update the collection in place using Move to avoid UI glitches. for (int i = 0; i < sortedItems.Count; i++) { var currentItem = sortedItems[i]; var currentIndex = AllModules.IndexOf(currentItem); if (currentIndex != -1 && currentIndex != i) { AllModules.Move(currentIndex, i); } } } finally { // Use dispatcher to reset flag after UI updates complete dispatcher.TryEnqueue(DispatcherQueuePriority.Low, () => { _isSorting = false; }); } } } /// <summary> /// Refreshes module enabled/locked states by re-reading GPO configuration. Only /// updates properties that have actually changed to minimize UI notifications /// then re-sorts the list according to the current sort order. /// </summary> private void RefreshModuleList() { foreach (var item in _moduleItems) { GpoRuleConfigured gpo = ModuleGpoHelper.GetModuleGpoConfiguration(item.Tag); // GPO can force-enable (Enabled) or force-disable (Disabled) a module. // If Enabled: module is on and the user cannot disable it. // If Disabled: module is off and the user cannot enable it. // Otherwise, the setting is unlocked and the user can enable/disable it. bool newEnabledState = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && ModuleHelper.GetIsModuleEnabled(generalSettingsConfig, item.Tag)); // Lock the toggle when GPO is controlling the module. bool newLockedState = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled; // Only update if there's an actual change to minimize UI notifications. if (item.IsEnabled != newEnabledState) { item.UpdateStatus(newEnabledState); } if (item.IsLocked != newLockedState) { item.IsLocked = newLockedState; } } SortModuleList(); } /// <summary> /// Callback invoked when a user toggles a module's enabled state in the UI. /// Sets the _isUpdatingFromUI flag to prevent circular updates, then updates /// settings, re-sorts if needed, and refreshes dependent collections. /// </summary> private void EnabledChangedOnUI(ModuleListItem item) { var dashboardListItem = (DashboardListItem)item; var isEnabled = dashboardListItem.IsEnabled; // Ignore toggle operations during sorting to prevent race conditions. // Revert the toggle state since UI already changed due to TwoWay binding. if (_isSorting) { dashboardListItem.UpdateStatus(!isEnabled); return; } _isUpdatingFromUI = true; try { // Send optimized IPC message with only the module status update // Format: {"module_status": {"ModuleName": true/false}} string moduleKey = ModuleHelper.GetModuleKey(dashboardListItem.Tag); string moduleStatusJson = $"{{\"module_status\": {{\"{moduleKey}\": {isEnabled.ToString().ToLowerInvariant()}}}}}"; SendConfigMSG(moduleStatusJson); // Update local settings config to keep UI in sync ModuleHelper.SetIsModuleEnabled(generalSettingsConfig, dashboardListItem.Tag, isEnabled); if (dashboardListItem.Tag == ModuleType.NewPlus && isEnabled == true) { var settingsUtils = SettingsUtils.Default; var settings = NewPlusViewModel.LoadSettings(settingsUtils); NewPlusViewModel.CopyTemplateExamples(settings.Properties.TemplateLocation.Value); } // Re-sort only required if sorting by enabled status. if (DashboardSortOrder == DashboardSortOrder.ByStatus) { SortModuleList(); } // Always refresh shortcuts/actions to reflect enabled state changes. RefreshShortcutModules(); // Request updated conflicts after module state change. RequestConflictData(); } finally { _isUpdatingFromUI = false; } } /// <summary> /// Callback invoked when module enabled state changes from other parts of the /// settings UI. Ignores the notification if it was triggered by a UI toggle /// we're already handling, to prevent circular updates. /// </summary> public void ModuleEnabledChangedOnSettingsPage() { if (_isDisposed) { return; } // Ignore if this was triggered by a UI change that we're already handling. if (_isUpdatingFromUI) { return; } try { RefreshModuleList(); RefreshShortcutModules(); OnPropertyChanged(nameof(ShortcutModules)); // Request updated conflicts after module state change. RequestConflictData(); } catch (Exception ex) { Logger.LogError($"Updating active/disabled modules list failed: {ex.Message}"); } } /// <summary> /// Rebuilds ShortcutModules and ActionModules collections by filtering AllModules /// to only include enabled modules and their respective shortcut/action items. /// </summary> private void RefreshShortcutModules() { if (_isDisposed) { return; } if (!dispatcher.HasThreadAccess) { _ = dispatcher.TryEnqueue(DispatcherQueuePriority.Normal, RefreshShortcutModules); return; } ShortcutModules.Clear(); ActionModules.Clear(); foreach (var x in AllModules.Where(x => x.IsEnabled)) { var filteredItems = x.DashboardModuleItems .Where(m => m is DashboardModuleShortcutItem || m is DashboardModuleActivationItem) .ToList(); if (filteredItems.Count != 0) { var newItem = new DashboardListItem { Icon = x.Icon, IsLocked = x.IsLocked, Label = x.Label, Tag = x.Tag, IsEnabled = x.IsEnabled, DashboardModuleItems = new ObservableCollection<DashboardModuleItem>(filteredItems), }; ShortcutModules.Add(newItem); newItem.EnabledChangedCallback = x.EnabledChangedCallback; } } foreach (var x in AllModules.Where(x => x.IsEnabled)) { var filteredItems = x.DashboardModuleItems .Where(m => m is DashboardModuleButtonItem) .ToList(); if (filteredItems.Count != 0) { var newItem = new DashboardListItem { Icon = x.Icon, IsLocked = x.IsLocked, Label = x.Label, Tag = x.Tag, IsEnabled = x.IsEnabled, DashboardModuleItems = new ObservableCollection<DashboardModuleItem>(filteredItems), }; ActionModules.Add(newItem); newItem.EnabledChangedCallback = x.EnabledChangedCallback; } } } private ObservableCollection<DashboardModuleItem> GetModuleItems(ModuleType moduleType) { return moduleType switch { ModuleType.AdvancedPaste => GetModuleItemsAdvancedPaste(), ModuleType.AlwaysOnTop => GetModuleItemsAlwaysOnTop(), ModuleType.CmdPal => GetModuleItemsCmdPal(), ModuleType.ColorPicker => GetModuleItemsColorPicker(), ModuleType.CropAndLock => GetModuleItemsCropAndLock(), ModuleType.EnvironmentVariables => GetModuleItemsEnvironmentVariables(), ModuleType.FancyZones => GetModuleItemsFancyZones(), ModuleType.FindMyMouse => GetModuleItemsFindMyMouse(), ModuleType.AltWindowCycle => GetModuleItemsAltWindowCycle(), ModuleType.Hosts => GetModuleItemsHosts(), ModuleType.KeyboardManager => GetModuleItemsKeyboardManager(), ModuleType.LightSwitch => GetModuleItemsLightSwitch(), ModuleType.MouseHighlighter => GetModuleItemsMouseHighlighter(), ModuleType.MouseJump => GetModuleItemsMouseJump(), ModuleType.MousePointerCrosshairs => GetModuleItemsMousePointerCrosshairs(), ModuleType.MouseWithoutBorders => GetModuleItemsMouseWithoutBorders(), ModuleType.Peek => GetModuleItemsPeek(), ModuleType.PowerDisplay => GetModuleItemsPowerDisplay(), ModuleType.PowerLauncher => GetModuleItemsPowerLauncher(), ModuleType.PowerAccent => GetModuleItemsPowerAccent(), ModuleType.Workspaces => GetModuleItemsWorkspaces(), ModuleType.GrabAndMove => new ObservableCollection<DashboardModuleItem>(), ModuleType.RegistryPreview => GetModuleItemsRegistryPreview(), ModuleType.MeasureTool => GetModuleItemsMeasureTool(), ModuleType.ShortcutGuide => GetModuleItemsShortcutGuide(), ModuleType.PowerOCR => GetModuleItemsPowerOCR(), _ => new ObservableCollection<DashboardModuleItem>(), // never called, all values listed above }; } private ObservableCollection<DashboardModuleItem> GetModuleItemsAlwaysOnTop() { ISettingsRepository<AlwaysOnTopSettings> moduleSettingsRepository = SettingsRepository<AlwaysOnTopSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("AlwaysOnTop_ActivationShortcut/Header"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.Hotkey.Value.GetKeysList() }, new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("AlwaysOnTop_IncreaseOpacityShortcut/Header"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.IncreaseOpacityHotkey.Value.GetKeysList() }, new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("AlwaysOnTop_DecreaseOpacityShortcut/Header"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.DecreaseOpacityHotkey.Value.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsCmdPal() { var hotkey = new CmdPalProperties().Hotkey; var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("CmdPal_ActivationDescription"), Shortcut = hotkey.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsColorPicker() { ISettingsRepository<ColorPickerSettings> moduleSettingsRepository = SettingsRepository<ColorPickerSettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; var hotkey = settings.Properties.ActivationShortcut; var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("ColorPicker_ShortDescription"), Shortcut = hotkey.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsLightSwitch() { ISettingsRepository<LightSwitchSettings> moduleSettingsRepository = SettingsRepository<LightSwitchSettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("LightSwitch_ForceDarkMode"), Shortcut = settings.Properties.ToggleThemeHotkey.Value.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsCropAndLock() { ISettingsRepository<CropAndLockSettings> moduleSettingsRepository = SettingsRepository<CropAndLockSettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("CropAndLock_Thumbnail"), Shortcut = settings.Properties.ThumbnailHotkey.Value.GetKeysList() }, new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("CropAndLock_Reparent"), Shortcut = settings.Properties.ReparentHotkey.Value.GetKeysList() }, new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("CropAndLock_Screenshot"), Shortcut = settings.Properties.ScreenshotHotkey.Value.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsEnvironmentVariables() { var list = new List<DashboardModuleItem> { new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("EnvironmentVariables_LaunchButtonControl/Description"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/EnvironmentVariables.png", ButtonClickHandler = EnvironmentVariablesLaunchClicked }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsFancyZones() { ISettingsRepository<FancyZonesSettings> moduleSettingsRepository = SettingsRepository<FancyZonesSettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; string activationMode = $"{resourceLoader.GetString(settings.Properties.FancyzonesShiftDrag.Value ? "FancyZones_ActivationShiftDrag" : "FancyZones_ActivationNoShiftDrag")}."; var list = new List<DashboardModuleItem> { new DashboardModuleActivationItem() { Label = resourceLoader.GetString("Activate_Zones"), Activation = activationMode }, new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("FancyZones_OpenEditor"), Shortcut = settings.Properties.FancyzonesEditorHotkey.Value.GetKeysList() }, new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("FancyZones_LaunchEditorButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("FancyZones_LaunchEditorButtonControl/Description"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/FancyZones.png", ButtonClickHandler = FancyZoneLaunchClicked }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsFindMyMouse() { ISettingsRepository<FindMyMouseSettings> moduleSettingsRepository = SettingsRepository<FindMyMouseSettings>.GetInstance(SettingsUtils.Default); string shortDescription = resourceLoader.GetString("FindMyMouse_ShortDescription"); var settings = moduleSettingsRepository.SettingsConfig; var activationMethod = settings.Properties.ActivationMethod.Value; var list = new List<DashboardModuleItem>(); if (activationMethod == 3) { var hotkey = settings.Properties.ActivationShortcut; list.Add(new DashboardModuleShortcutItem() { Label = shortDescription, Shortcut = hotkey.GetKeysList() }); } else { string activation = string.Empty; switch (activationMethod) { case 2: activation = resourceLoader.GetString("MouseUtils_FindMyMouse_ActivationShakeMouse/Content"); break; case 1: activation = resourceLoader.GetString("MouseUtils_FindMyMouse_ActivationDoubleRightControlPress/Content"); break; case 0: default: activation = resourceLoader.GetString("MouseUtils_FindMyMouse_ActivationDoubleControlPress/Content"); break; } list.Add(new DashboardModuleActivationItem() { Label = resourceLoader.GetString("Dashboard_Activation"), Activation = activation }); } return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsAltWindowCycle() { ISettingsRepository<AltWindowCycleSettings> moduleSettingsRepository = SettingsRepository<AltWindowCycleSettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("AltWindowCycle_NextWindowShortcut/Header"), Shortcut = settings.Properties.NextWindowShortcut.GetKeysList() }, new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("AltWindowCycle_PreviousWindowShortcut/Header"), Shortcut = settings.Properties.PreviousWindowShortcut.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsHosts() { var list = new List<DashboardModuleItem> { new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("Hosts_LaunchButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("Hosts_LaunchButtonControl/Description"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/Hosts.png", ButtonClickHandler = HostLaunchClicked }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsKeyboardManager() { ISettingsRepository<KeyboardManagerSettings> moduleSettingsRepository = SettingsRepository<KeyboardManagerSettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; var list = new List<DashboardModuleItem>(); if (settings.Properties.UseNewEditor) { list.Add(new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("Dashboard_KeyboardManager_OpenEditor"), Shortcut = settings.Properties.EditorShortcut.GetKeysList() }); } return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsMouseHighlighter() { ISettingsRepository<MouseHighlighterSettings> moduleSettingsRepository = SettingsRepository<MouseHighlighterSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("MouseHighlighter_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsMouseJump() { ISettingsRepository<MouseJumpSettings> moduleSettingsRepository = SettingsRepository<MouseJumpSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("MouseJump_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsMousePointerCrosshairs() { ISettingsRepository<MousePointerCrosshairsSettings> moduleSettingsRepository = SettingsRepository<MousePointerCrosshairsSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("MouseCrosshairs_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsMouseWithoutBorders() { var list = new List<DashboardModuleItem> { new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("MouseWithoutBorders_ReconnectButton/Text"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("MouseWithoutBorders_ReconnectTooltip/Text"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/MouseWithoutBorders.png", ButtonClickHandler = MouseWithoutBordersReconnectClicked, }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsAdvancedPaste() { ISettingsRepository<AdvancedPasteSettings> moduleSettingsRepository = SettingsRepository<AdvancedPasteSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("AdvancedPasteUI_Shortcut/Header"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.AdvancedPasteUIShortcut.GetKeysList() }, new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("PasteAsPlainText_Shortcut/Header"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.PasteAsPlainTextShortcut.GetKeysList() }, }; if (moduleSettingsRepository.SettingsConfig.Properties.PasteAsMarkdownShortcut.GetKeysList().Count > 0) { list.Add(new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("PasteAsMarkdown_Shortcut/Header"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.PasteAsMarkdownShortcut.GetKeysList() }); } if (moduleSettingsRepository.SettingsConfig.Properties.PasteAsJsonShortcut.GetKeysList().Count > 0) { list.Add(new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("PasteAsJson_Shortcut/Header"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.PasteAsJsonShortcut.GetKeysList() }); } return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsPeek() { ISettingsRepository<PeekSettings> moduleSettingsRepository = SettingsRepository<PeekSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("Peek_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerLauncher() { ISettingsRepository<PowerLauncherSettings> moduleSettingsRepository = SettingsRepository<PowerLauncherSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("Run_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.OpenPowerLauncher.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerAccent() { var settingsUtils = SettingsUtils.Default; PowerAccentSettings moduleSettings = settingsUtils.GetSettingsOrDefault<PowerAccentSettings>(PowerAccentSettings.ModuleName); var activationMethod = moduleSettings.Properties.ActivationKey; string activation = string.Empty; switch (activationMethod) { case Library.Enumerations.PowerAccentActivationKey.LeftRightArrow: activation = resourceLoader.GetString("QuickAccent_Activation_Key_Arrows/Content"); break; case Library.Enumerations.PowerAccentActivationKey.Space: activation = resourceLoader.GetString("QuickAccent_Activation_Key_Space/Content"); break; case Library.Enumerations.PowerAccentActivationKey.Both: activation = resourceLoader.GetString("QuickAccent_Activation_Key_Either/Content"); break; case Library.Enumerations.PowerAccentActivationKey.PressAndHold: activation = resourceLoader.GetString("QuickAccent_Activation_Key_PressAndHold/Content"); break; default: activation = string.Empty; break; } var list = new List<DashboardModuleItem> { new DashboardModuleActivationItem() { Label = resourceLoader.GetString("Dashboard_Activation"), Activation = activation }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsWorkspaces() { ISettingsRepository<WorkspacesSettings> moduleSettingsRepository = SettingsRepository<WorkspacesSettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("Workspaces_ShortDescription"), Shortcut = settings.Properties.Hotkey.Value.GetKeysList() }, new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("Workspaces_LaunchEditorButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("FancyZones_LaunchEditorButtonControl/Description"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/Workspaces.png", ButtonClickHandler = WorkspacesLaunchClicked }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsRegistryPreview() { var list = new List<DashboardModuleItem> { new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("RegistryPreview_LaunchButtonControl/Header"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/RegistryPreview.png", ButtonClickHandler = RegistryPreviewLaunchClicked }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsMeasureTool() { ISettingsRepository<MeasureToolSettings> moduleSettingsRepository = SettingsRepository<MeasureToolSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("ScreenRuler_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsShortcutGuide() { ISettingsRepository<ShortcutGuideSettings> moduleSettingsRepository = SettingsRepository<ShortcutGuideSettings>.GetInstance(SettingsUtils.Default); var shortcut = moduleSettingsRepository.SettingsConfig.Properties.OpenShortcutGuide.GetKeysList(); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("ShortcutGuide_ShortDescription"), Shortcut = shortcut }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerOCR() { ISettingsRepository<PowerOcrSettings> moduleSettingsRepository = SettingsRepository<PowerOcrSettings>.GetInstance(SettingsUtils.Default); var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("PowerOcr_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, }; return new ObservableCollection<DashboardModuleItem>(list); } private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerDisplay() { ISettingsRepository<PowerDisplaySettings> moduleSettingsRepository = SettingsRepository<PowerDisplaySettings>.GetInstance(SettingsUtils.Default); var settings = moduleSettingsRepository.SettingsConfig; var list = new List<DashboardModuleItem> { new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("PowerDisplay_ToggleWindow"), Shortcut = settings.Properties.ActivationShortcut.GetKeysList() }, new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("PowerDisplay_LaunchButtonControl/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("PowerDisplay_LaunchButtonControl/Description"), ButtonGlyph = "ms-appx:///Assets/Settings/Icons/PowerDisplay.png", ButtonClickHandler = PowerDisplayLaunchClicked }, }; return new ObservableCollection<DashboardModuleItem>(list); } internal void SWVersionButtonClicked() { NavigationService.Navigate(typeof(GeneralPage)); } private void EnvironmentVariablesLaunchClicked(object sender, RoutedEventArgs e) { var settingsUtils = SettingsUtils.Default; var environmentVariablesViewModel = new EnvironmentVariablesViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<EnvironmentVariablesSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, App.IsElevated); environmentVariablesViewModel.Launch(); } private void HostLaunchClicked(object sender, RoutedEventArgs e) { var settingsUtils = SettingsUtils.Default; var hostsViewModel = new HostsViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<HostsSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, App.IsElevated); hostsViewModel.Launch(); } private void FancyZoneLaunchClicked(object sender, RoutedEventArgs e) { // send message to launch the zones editor; SendConfigMSG("{\"action\":{\"FancyZones\":{\"action_name\":\"ToggledFZEditor\", \"value\":\"\"}}}"); } private void WorkspacesLaunchClicked(object sender, RoutedEventArgs e) { // send message to launch the Workspaces editor; SendConfigMSG("{\"action\":{\"Workspaces\":{\"action_name\":\"LaunchEditor\", \"value\":\"\"}}}"); } private void RegistryPreviewLaunchClicked(object sender, RoutedEventArgs e) { var actionName = "Launch"; SendConfigMSG("{\"action\":{\"RegistryPreview\":{\"action_name\":\"" + actionName + "\", \"value\":\"\"}}}"); } private void PowerDisplayLaunchClicked(object sender, RoutedEventArgs e) { var actionName = "Launch"; SendConfigMSG("{\"action\":{\"PowerDisplay\":{\"action_name\":\"" + actionName + "\", \"value\":\"\"}}}"); } private void MouseWithoutBordersReconnectClicked(object sender, RoutedEventArgs e) { using var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.MWBReconnectEvent()); eventHandle.Set(); } internal void DashboardListItemClick(object sender) { if (sender is ModuleType moduleType) { NavigationService.Navigate(ModuleGpoHelper.GetModulePageType(moduleType)); } } public override void Dispose() { if (_isDisposed) { return; } _isDisposed = true; base.Dispose(); if (_settingsRepository != null) { _settingsRepository.SettingsChanged -= OnSettingsChanged; } GC.SuppressFinalize(this); } } }