From 1f936df3ebce73b726ed11c9fa38fd477b4b0fbd Mon Sep 17 00:00:00 2001 From: Laszlo Nemeth <57342539+donlaci@users.noreply.github.com> Date: Fri, 20 Oct 2023 14:23:25 +0200 Subject: [PATCH] [Settings]Adding a Dashboard Panel (#29023) * Dashboard: modifying page content + adding SW version button. * Visual tweaks and minor viewmodel changes * Updated spacing * Adding Settings icon * Settiing the Dashboard page as the default one. Adding functionality to switch to settings pages from the Dashboard page. Localizing texts. * fixing csproj file * Reimplementing Active modules handling, showing only the active modules (and not having invisible inactive modules). * Removing unneccessary binding * Fix text wrapping * Adding Registry previewer launch, adding activation mode for FindMyMouse and QuickAccent, modify File Locksmith description. * Spell checker fix typo * Adding GPO-blocked state, modifying buttons: adding description, icon. * Modifying dashboard button layout * Use SettingsCard instead of button * Restructuring the dashboard panel * Removing togglebuttons from the left panel. Showing only active modules. Adding key remappings (to KBM) * Removing settings buttons, removing descriptions, icons from buttons. Add update of remapped keys, shortcuts. * Refactoring dashboard * Making list always visible and fixing scrolling behavior * Adding background gradient to cards * Removing keyboard manager's key mappings, minor changes in texts, fixing enabled state when GPO-enabled. * Use ListView instead of ItemsRepeater * Updates * removing right panel with all modules. Extending "left" panel with toggleswitches, showing all modules. * Separate lists * Adding Flyout with key remappings for KBM module, adding IsLocked property, icons * Visual tweaks * Tweaks * Fixing lock icon margin * Minor fixes. * Removing unused resources * Make Dashboard default when coming from the OOBE General * Removed the Previous, Next Layout buttons from FancyZones. Added activation information --------- Co-authored-by: Niels Laute <niels.laute@live.nl> --- src/common/Common.UI/SettingsDeepLink.cs | 3 + src/runner/main.cpp | 2 +- src/runner/settings_window.cpp | 10 +- src/runner/settings_window.h | 3 +- .../Converters/ModuleItemTemplateSelector.cs | 33 + .../NegativeBoolToVisibilityConverter.cs | 37 + .../Settings.UI/PowerToys.Settings.csproj | 11 +- .../Settings.UI/SettingsXAML/App.xaml.cs | 11 +- .../Controls/KeyVisual/KeyVisual.cs | 7 +- .../Controls/KeyVisual/KeyVisual.xaml | 76 +- .../ShortcutWithTextLabelControl.xaml | 5 +- .../OOBE/Views/OobeOverview.xaml.cs | 2 +- .../OOBE/Views/OobeOverviewAlternate.xaml.cs | 2 +- .../Views/OobeOverviewPlaceholder.xaml.cs | 2 +- .../SettingsXAML/Views/DashboardPage.xaml | 446 ++++++++++ .../SettingsXAML/Views/DashboardPage.xaml.cs | 58 ++ .../Views/KeyboardManagerPage.xaml.cs | 2 +- .../SettingsXAML/Views/ShellPage.xaml | 8 +- .../SettingsXAML/Views/ShellPage.xaml.cs | 4 +- .../Settings.UI/Strings/en-us/Resources.resw | 97 ++- .../ViewModels/DashboardListItem.cs | 69 ++ .../ViewModels/DashboardModuleItem.cs | 75 ++ .../ViewModels/DashboardViewModel.cs | 803 ++++++++++++++++++ .../ViewModels/KeyboardManagerViewModel.cs | 4 +- 24 files changed, 1721 insertions(+), 49 deletions(-) create mode 100644 src/settings-ui/Settings.UI/Converters/ModuleItemTemplateSelector.cs create mode 100644 src/settings-ui/Settings.UI/Converters/NegativeBoolToVisibilityConverter.cs create mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml create mode 100644 src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs create mode 100644 src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs create mode 100644 src/settings-ui/Settings.UI/ViewModels/DashboardModuleItem.cs create mode 100644 src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs diff --git a/src/common/Common.UI/SettingsDeepLink.cs b/src/common/Common.UI/SettingsDeepLink.cs index 1a154f0a8255..97547c42920c 100644 --- a/src/common/Common.UI/SettingsDeepLink.cs +++ b/src/common/Common.UI/SettingsDeepLink.cs @@ -28,6 +28,7 @@ public enum SettingsWindow PowerOCR, RegistryPreview, CropAndLock, + Dashboard, } private static string SettingsWindowNameToString(SettingsWindow value) @@ -68,6 +69,8 @@ private static string SettingsWindowNameToString(SettingsWindow value) return "RegistryPreview"; case SettingsWindow.CropAndLock: return "CropAndLock"; + case SettingsWindow.Dashboard: + return "Dashboard"; default: { return string.Empty; diff --git a/src/runner/main.cpp b/src/runner/main.cpp index eb1fb485031b..fab4a6500b5a 100644 --- a/src/runner/main.cpp +++ b/src/runner/main.cpp @@ -81,7 +81,7 @@ inline wil::unique_mutex_nothrow create_msi_mutex() void open_menu_from_another_instance(std::optional<std::string> settings_window) { const HWND hwnd_main = FindWindowW(L"PToyTrayIconWindow", nullptr); - LPARAM msg = static_cast<LPARAM>(ESettingsWindowNames::Overview); + LPARAM msg = static_cast<LPARAM>(ESettingsWindowNames::Dashboard); if (settings_window.has_value() && settings_window.value() != "") { msg = static_cast<LPARAM>(ESettingsWindowNames_from_string(settings_window.value())); diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index bcba0915b175..f7f8d5df637a 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -596,7 +596,7 @@ void open_settings_window(std::optional<std::wstring> settings_window, bool show } else { - current_settings_ipc->send(L"{\"ShowYourself\":\"Overview\"}"); + current_settings_ipc->send(L"{\"ShowYourself\":\"Dashboard\"}"); } } } @@ -676,6 +676,8 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value) return "RegistryPreview"; case ESettingsWindowNames::CropAndLock: return "CropAndLock"; + case ESettingsWindowNames::Dashboard: + return "Dashboard"; default: { Logger::error(L"Can't convert ESettingsWindowNames value={} to string", static_cast<int>(value)); @@ -755,11 +757,15 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value) { return ESettingsWindowNames::CropAndLock; } + else if (value == "Dashboard") + { + return ESettingsWindowNames::Dashboard; + } else { Logger::error(L"Can't convert string value={} to ESettingsWindowNames", winrt::to_hstring(value)); assert(false); } - return ESettingsWindowNames::Overview; + return ESettingsWindowNames::Dashboard; } diff --git a/src/runner/settings_window.h b/src/runner/settings_window.h index 2a14ec46e04e..06aac30dc8d5 100644 --- a/src/runner/settings_window.h +++ b/src/runner/settings_window.h @@ -4,7 +4,8 @@ enum class ESettingsWindowNames { - Overview = 0, + Dashboard = 0, + Overview, Awake, ColorPicker, FancyZones, diff --git a/src/settings-ui/Settings.UI/Converters/ModuleItemTemplateSelector.cs b/src/settings-ui/Settings.UI/Converters/ModuleItemTemplateSelector.cs new file mode 100644 index 000000000000..b34331a0e7a4 --- /dev/null +++ b/src/settings-ui/Settings.UI/Converters/ModuleItemTemplateSelector.cs @@ -0,0 +1,33 @@ +// 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 Microsoft.PowerToys.Settings.UI.ViewModels; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; + +namespace Microsoft.PowerToys.Settings.UI.Converters +{ + public class ModuleItemTemplateSelector : DataTemplateSelector + { + public DataTemplate TextTemplate { get; set; } + + public DataTemplate ButtonTemplate { get; set; } + + public DataTemplate ShortcutTemplate { get; set; } + + public DataTemplate KBMTemplate { get; set; } + + protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) + { + switch (item) + { + case DashboardModuleButtonItem: return ButtonTemplate; + case DashboardModuleShortcutItem: return ShortcutTemplate; + case DashboardModuleTextItem: return TextTemplate; + case DashboardModuleKBMItem: return KBMTemplate; + default: return TextTemplate; + } + } + } +} diff --git a/src/settings-ui/Settings.UI/Converters/NegativeBoolToVisibilityConverter.cs b/src/settings-ui/Settings.UI/Converters/NegativeBoolToVisibilityConverter.cs new file mode 100644 index 000000000000..df9f02eca702 --- /dev/null +++ b/src/settings-ui/Settings.UI/Converters/NegativeBoolToVisibilityConverter.cs @@ -0,0 +1,37 @@ +// 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.Globalization; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Data; + +namespace Microsoft.PowerToys.Settings.UI.Converters +{ + public class NegativeBoolToVisibilityConverter : IValueConverter + { + object IValueConverter.Convert(object value, Type targetType, object parameter, string language) + { + if ((bool)value) + { + return Visibility.Collapsed; + } + + return Visibility.Visible; + } + + object IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language) + { + if (value is Visibility) + { + if ((Visibility)value == Visibility.Visible) + { + return false; + } + } + + return true; + } + } +} diff --git a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj index 98be30ec56c5..e601b11886d5 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -21,6 +21,9 @@ <!-- MRT from windows app sdk will search for a pri file with the same name of the module before defaulting to resources.pri --> <ProjectPriFileName>PowerToys.Settings.pri</ProjectPriFileName> </PropertyGroup> + <ItemGroup> + <None Remove="SettingsXAML\Views\DashboardPage.xaml" /> + </ItemGroup> <ItemGroup> <Page Remove="SettingsXAML\App.xaml" /> @@ -124,5 +127,11 @@ <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> </ItemGroup> + + <ItemGroup> + <Page Update="SettingsXAML\Views\DashboardPage.xaml"> + <XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime> + </Page> + </ItemGroup> -</Project> +</Project> \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs index ba9988dd2dd4..ea02e1779e74 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs @@ -60,7 +60,7 @@ private enum Arguments public bool ShowScoobe { get; set; } - public Type StartupPage { get; set; } = typeof(Views.GeneralPage); + public Type StartupPage { get; set; } = typeof(Views.DashboardPage); public static Action<string> IPCMessageReceivedCallback { get; set; } @@ -218,8 +218,8 @@ protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs ar settingsWindow.NavigateToSection(StartupPage); ShowMessageDialog("The application is running in Debug mode.", "DEBUG"); #else - /* If we try to run Settings as a standalone app, it will start PowerToys.exe if not running and open Settings again through it in the General page. */ - SettingsDeepLink.OpenSettings(SettingsDeepLink.SettingsWindow.Overview, true); + /* If we try to run Settings as a standalone app, it will start PowerToys.exe if not running and open Settings again through it in the Dashboard page. */ + SettingsDeepLink.OpenSettings(SettingsDeepLink.SettingsWindow.Dashboard, true); Exit(); #endif } @@ -380,6 +380,7 @@ public static Type GetPage(string settingWindow) { switch (settingWindow) { + case "Dashboard": return typeof(DashboardPage); case "Overview": return typeof(GeneralPage); case "AlwaysOnTop": return typeof(AlwaysOnTopPage); case "Awake": return typeof(AwakePage); @@ -404,9 +405,9 @@ public static Type GetPage(string settingWindow) case "Peek": return typeof(PeekPage); case "CropAndLock": return typeof(CropAndLockPage); default: - // Fallback to general + // Fallback to Dashboard Debug.Assert(false, "Unexpected SettingsWindow argument value"); - return typeof(GeneralPage); + return typeof(DashboardPage); } } } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.cs b/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.cs index 5e5d3ee846a3..8b3683198425 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.cs @@ -116,7 +116,7 @@ private void Update() case 91: // The left Windows key case 92: // The right Windows key - PathIcon winIcon = XamlReader.Load(@"<PathIcon xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Data=""M9,17V9h8v8ZM0,17V9H8v8ZM9,8V0h8V8ZM0,8V0H8V8Z"" />") as PathIcon; + PathIcon winIcon = XamlReader.Load(@"<PathIcon xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Data=""M683 1229H0V546h683v683zm819 0H819V546h683v683zm-819 819H0v-683h683v683zm819 0H819v-683h683v683z"" />") as PathIcon; Viewbox winIconContainer = new Viewbox(); winIconContainer.Child = winIcon; winIconContainer.HorizontalAlignment = HorizontalAlignment.Center; @@ -143,6 +143,10 @@ public Style GetStyleSize(string styleName) { return (Style)App.Current.Resources["SmallOutline" + styleName]; } + else if (VisualType == VisualType.TextOnly) + { + return (Style)App.Current.Resources["Only" + styleName]; + } else { return (Style)App.Current.Resources["Default" + styleName]; @@ -181,6 +185,7 @@ public enum VisualType { Small, SmallOutline, + TextOnly, Large, } } diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.xaml index 2d469563a233..68590a040abf 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Controls/KeyVisual/KeyVisual.xaml @@ -5,9 +5,7 @@ <x:Double x:Key="DefaultIconSize">16</x:Double> <x:Double x:Key="SmallIconSize">12</x:Double> - <Style - x:Key="DefaultTextKeyVisualStyle" - TargetType="local:KeyVisual"> + <Style x:Key="DefaultTextKeyVisualStyle" TargetType="local:KeyVisual"> <Setter Property="MinWidth" Value="56" /> <Setter Property="MinHeight" Value="48" /> <Setter Property="Background" Value="{ThemeResource AccentButtonBackground}" /> @@ -23,26 +21,6 @@ <Setter.Value> <ControlTemplate TargetType="local:KeyVisual"> <Grid> - <Grid> - <Rectangle - x:Name="ContentHolder" - Height="{TemplateBinding Height}" - MinWidth="{TemplateBinding MinWidth}" - Fill="{TemplateBinding Background}" - RadiusX="4" - RadiusY="4" - Stroke="{TemplateBinding BorderBrush}" - StrokeThickness="{TemplateBinding BorderThickness}" /> - <ContentPresenter - x:Name="KeyPresenter" - Margin="{TemplateBinding Padding}" - HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" - VerticalAlignment="Center" - Content="{TemplateBinding Content}" - FontSize="{TemplateBinding FontSize}" - FontWeight="{TemplateBinding FontWeight}" - Foreground="{TemplateBinding Foreground}" /> - </Grid> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> @@ -67,6 +45,26 @@ </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> + <Grid> + <Rectangle + x:Name="ContentHolder" + Height="{TemplateBinding Height}" + MinWidth="{TemplateBinding MinWidth}" + Fill="{TemplateBinding Background}" + RadiusX="4" + RadiusY="4" + Stroke="{TemplateBinding BorderBrush}" + StrokeThickness="{TemplateBinding BorderThickness}" /> + <ContentPresenter + x:Name="KeyPresenter" + Margin="{TemplateBinding Padding}" + HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalAlignment="Center" + Content="{TemplateBinding Content}" + FontSize="{TemplateBinding FontSize}" + FontWeight="{TemplateBinding FontWeight}" + Foreground="{TemplateBinding Foreground}" /> + </Grid> </Grid> </ControlTemplate> </Setter.Value> @@ -101,6 +99,7 @@ </Style> + <Style x:Key="DefaultIconKeyVisualStyle" BasedOn="{StaticResource DefaultTextKeyVisualStyle}" @@ -141,4 +140,35 @@ <Setter Property="FontSize" Value="9" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> </Style> + + <Style + x:Key="OnlyTextKeyVisualStyle" + BasedOn="{StaticResource DefaultTextKeyVisualStyle}" + TargetType="local:KeyVisual"> + <Setter Property="MinHeight" Value="12" /> + <Setter Property="MinWidth" Value="12" /> + <Setter Property="Background" Value="Transparent" /> + <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" /> + <Setter Property="BorderBrush" Value="Transparent" /> + <Setter Property="FontWeight" Value="Normal" /> + <Setter Property="Padding" Value="0" /> + <Setter Property="FontSize" Value="12" /> + <Setter Property="HorizontalContentAlignment" Value="Center" /> + </Style> + + <Style + x:Key="OnlyIconKeyVisualStyle" + BasedOn="{StaticResource DefaultTextKeyVisualStyle}" + TargetType="local:KeyVisual"> + <Setter Property="MinHeight" Value="10" /> + <Setter Property="MinWidth" Value="10" /> + <Setter Property="Background" Value="Transparent" /> + <Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" /> + <Setter Property="BorderBrush" Value="Transparent" /> + <Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" /> + <Setter Property="FontWeight" Value="Normal" /> + <Setter Property="Padding" Value="0,0,0,3" /> + <!--<Setter Property="FontSize" Value="9" />--> + <Setter Property="HorizontalContentAlignment" Value="Center" /> + </Style> </ResourceDictionary> \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml index 1a51b178741d..1f1fc9e071ef 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Controls/ShortcutControl/ShortcutWithTextLabelControl.xaml @@ -23,9 +23,7 @@ ItemsSource="{x:Bind Keys}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> - <StackPanel - Orientation="Horizontal" - Spacing="4" /> + <StackPanel Orientation="Horizontal" Spacing="4" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> @@ -41,7 +39,6 @@ </ItemsControl> <toolkitcontrols:MarkdownTextBlock Grid.Column="1" - Margin="8,0,0,0" VerticalAlignment="Center" Background="Transparent" Text="{x:Bind Text}" /> diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs index b86a17aa388e..d43bda83bfd2 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverview.xaml.cs @@ -25,7 +25,7 @@ private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedE { if (OobeShellPage.OpenMainWindowCallback != null) { - OobeShellPage.OpenMainWindowCallback(typeof(GeneralPage)); + OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage)); } ViewModel.LogOpeningSettingsEvent(); diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewAlternate.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewAlternate.xaml.cs index c5171f415918..d0ae488347fd 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewAlternate.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewAlternate.xaml.cs @@ -31,7 +31,7 @@ private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedE { if (OobeShellPage.OpenMainWindowCallback != null) { - OobeShellPage.OpenMainWindowCallback(typeof(GeneralPage)); + OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage)); } ViewModel.LogOpeningSettingsEvent(); diff --git a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewPlaceholder.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewPlaceholder.xaml.cs index 40dcb56aa28e..18a18189abf3 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewPlaceholder.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeOverviewPlaceholder.xaml.cs @@ -54,7 +54,7 @@ private void SettingsLaunchButton_Click(object sender, Microsoft.UI.Xaml.RoutedE { if (OobeShellPage.OpenMainWindowCallback != null) { - OobeShellPage.OpenMainWindowCallback(typeof(GeneralPage)); + OobeShellPage.OpenMainWindowCallback(typeof(DashboardPage)); } ViewModel.LogOpeningSettingsEvent(); diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml new file mode 100644 index 000000000000..cac07b5bfd6a --- /dev/null +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml @@ -0,0 +1,446 @@ +<Page + x:Class="Microsoft.PowerToys.Settings.UI.Views.DashboardPage" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:Lib="using:Microsoft.PowerToys.Settings.UI.Library" + xmlns:controls="using:CommunityToolkit.WinUI.Controls" + xmlns:converters="using:CommunityToolkit.WinUI.Converters" + xmlns:custom="using:Microsoft.PowerToys.Settings.UI.Controls" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:localConverters="using:Microsoft.PowerToys.Settings.UI.Converters" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:viewmodels="using:Microsoft.PowerToys.Settings.UI.ViewModels" + AutomationProperties.LandmarkType="Main" + DataContext="DashboardViewModel" + mc:Ignorable="d"> + + <Page.Resources> + <localConverters:ModuleItemTemplateSelector + x:Key="ModuleItemTemplateSelector" + ButtonTemplate="{StaticResource ModuleItemButtonTemplate}" + KBMTemplate="{StaticResource ModuleItemKBMTemplate}" + ShortcutTemplate="{StaticResource ModuleItemShortcutTemplate}" + TextTemplate="{StaticResource ModuleItemTextTemplate}" /> + <converters:CollectionVisibilityConverter x:Key="CollectionVisibilityConverter" /> + <Style x:Name="KeysListViewContainerStyle" TargetType="ListViewItem"> + <Setter Property="IsTabStop" Value="False" /> + </Style> + <localConverters:UpdateStateToBoolConverter x:Key="UpdateStateToBoolConverter" /> + <converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" /> + <converters:BoolNegationConverter x:Key="BoolNegationConverter" /> + <converters:BoolToVisibilityConverter + x:Key="BoolToInvertedVisibilityConverter" + FalseValue="Visible" + TrueValue="Collapsed" /> + <DataTemplate x:Key="OriginalKeyTemplate" x:DataType="x:String"> + <custom:KeyVisual Content="{Binding}" VisualType="SmallOutline" /> + </DataTemplate> + + <DataTemplate x:Key="RemappedKeyTemplate" x:DataType="x:String"> + <custom:KeyVisual Content="{Binding}" VisualType="Small" /> + </DataTemplate> + + <DataTemplate x:Key="ModuleItemTextTemplate" x:DataType="viewmodels:DashboardModuleTextItem"> + <TextBlock + Foreground="{ThemeResource TextFillColorSecondaryBrush}" + Style="{StaticResource CaptionTextBlockStyle}" + Text="{x:Bind Label, Mode=OneWay}" + TextWrapping="WrapWholeWords" /> + </DataTemplate> + + <DataTemplate x:Key="ModuleItemButtonTemplate" x:DataType="viewmodels:DashboardModuleButtonItem"> + <Button + HorizontalAlignment="Stretch" + Click="{x:Bind ButtonClickHandler, Mode=OneWay}" + Content="{x:Bind ButtonTitle}" /> + </DataTemplate> + + <DataTemplate x:Key="ModuleItemShortcutTemplate" x:DataType="viewmodels:DashboardModuleShortcutItem"> + <Grid ColumnSpacing="12"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="*" /> + </Grid.ColumnDefinitions> + <Border + Padding="8,4" + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" + BorderThickness="1" + CornerRadius="{StaticResource ControlCornerRadius}"> + <ItemsControl + AutomationProperties.AccessibilityView="Raw" + IsTabStop="False" + ItemsSource="{x:Bind Path=Shortcut, Mode=TwoWay}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" Spacing="12" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <custom:KeyVisual + VerticalAlignment="Center" + AutomationProperties.AccessibilityView="Raw" + Content="{Binding}" + IsTabStop="False" + VisualType="TextOnly" /> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Border> + + <TextBlock + Grid.Column="1" + VerticalAlignment="Center" + Foreground="{ThemeResource TextFillColorSecondaryBrush}" + Style="{StaticResource CaptionTextBlockStyle}" + Text="{x:Bind Label, Mode=OneWay}" + TextWrapping="WrapWholeWords" /> + </Grid> + </DataTemplate> + <DataTemplate x:Key="ModuleItemKBMTemplate" x:DataType="viewmodels:DashboardModuleKBMItem"> + <Button x:Uid="DashboardKBMShowMappingsButton" HorizontalAlignment="Stretch"> + <Button.Flyout> + <Flyout x:Name="DetailsFlyout" Placement="Bottom"> + <StackPanel Orientation="Vertical" Spacing="4"> + <ItemsControl ItemsSource="{x:Bind Path=RemapKeys, Mode=OneWay}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Spacing="4" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate x:DataType="Lib:KeysDataModel"> + <StackPanel Orientation="Horizontal"> + <Border + Padding="8,4" + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" + BorderThickness="1" + CornerRadius="{StaticResource ControlCornerRadius}"> + <ItemsControl + AutomationProperties.AccessibilityView="Raw" + IsTabStop="False" + ItemsSource="{x:Bind GetMappedOriginalKeys()}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" Spacing="12" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <custom:KeyVisual + VerticalAlignment="Center" + AutomationProperties.AccessibilityView="Raw" + Content="{Binding}" + IsTabStop="False" + VisualType="TextOnly" /> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Border> + <custom:IsEnabledTextBlock + x:Uid="To" + Margin="8,0,8,0" + VerticalAlignment="Center" + Style="{StaticResource SecondaryIsEnabledTextBlockStyle}" /> + <Border + Padding="8,4" + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + BorderBrush="{ThemeResource AccentFillColorDefaultBrush}" + BorderThickness="1" + CornerRadius="{StaticResource ControlCornerRadius}"> + <ItemsControl + AutomationProperties.AccessibilityView="Raw" + IsTabStop="False" + ItemsSource="{x:Bind GetMappedNewRemapKeys()}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" Spacing="12" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <custom:KeyVisual + VerticalAlignment="Center" + AutomationProperties.AccessibilityView="Raw" + Content="{Binding}" + FontSize="12" + Foreground="{ThemeResource AccentFillColorDefaultBrush}" + IsTabStop="False" + VisualType="TextOnly" /> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Border> + </StackPanel> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + <ItemsControl ItemsSource="{x:Bind Path=RemapShortcuts, Mode=OneWay}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Spacing="4" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate x:DataType="Lib:AppSpecificKeysDataModel"> + <StackPanel Orientation="Horizontal"> + <Border + Padding="8,4" + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" + BorderThickness="1" + CornerRadius="{StaticResource ControlCornerRadius}"> + <ItemsControl + AutomationProperties.AccessibilityView="Raw" + IsTabStop="False" + ItemsSource="{x:Bind GetMappedOriginalKeys()}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" Spacing="12" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <custom:KeyVisual + VerticalAlignment="Center" + AutomationProperties.AccessibilityView="Raw" + Content="{Binding}" + IsTabStop="False" + VisualType="TextOnly" /> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Border> + <custom:IsEnabledTextBlock + x:Uid="To" + Margin="8,0,8,0" + VerticalAlignment="Center" + Style="{StaticResource SecondaryIsEnabledTextBlockStyle}" /> + <Border + Padding="8,4" + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + BorderBrush="{ThemeResource AccentFillColorDefaultBrush}" + BorderThickness="1" + CornerRadius="{StaticResource ControlCornerRadius}"> + <ItemsControl + AutomationProperties.AccessibilityView="Raw" + IsTabStop="False" + ItemsSource="{x:Bind GetMappedNewRemapKeys()}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Orientation="Horizontal" Spacing="12" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + <ItemsControl.ItemTemplate> + <DataTemplate> + <custom:KeyVisual + VerticalAlignment="Center" + AutomationProperties.AccessibilityView="Raw" + Content="{Binding}" + Foreground="{ThemeResource AccentFillColorDefaultBrush}" + IsTabStop="False" + VisualType="TextOnly" /> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </Border> + <TextBlock + Margin="4,0,0,0" + VerticalAlignment="Center" + Foreground="{ThemeResource AccentFillColorDefaultBrush}" + Text="{x:Bind TargetApp}" /> + </StackPanel> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </StackPanel> + </Flyout> + </Button.Flyout> + </Button> + </DataTemplate> + </Page.Resources> + <Grid Margin="16,0,0,0" RowSpacing="24"> + <Grid.RowDefinitions> + <RowDefinition Height="Auto" /> + <RowDefinition Height="*" /> + </Grid.RowDefinitions> + <TextBlock + x:Uid="DashboardTitle" + VerticalAlignment="Center" + Style="{StaticResource TitleTextBlockStyle}" /> + + <InfoBar + x:Uid="UpdateAvailable" + Margin="0,0,16,0" + HorizontalAlignment="Right" + VerticalAlignment="Center" + CornerRadius="8" + IsClosable="False" + IsOpen="{x:Bind ViewModel.UpdateAvailable, Mode=OneWay}" + Severity="Informational"> + <InfoBar.ActionButton> + <Button x:Uid="LearnMore" Click="SWVersionButtonClicked" /> + </InfoBar.ActionButton> + </InfoBar> + + <ScrollViewer x:Name="MainScrollViewer" Grid.Row="1"> + <StackPanel Padding="0,0,16,16" Orientation="Vertical"> + <TextBlock + x:Uid="EnabledModules" + Margin="0,0,0,12" + Style="{StaticResource SubtitleTextBlockStyle}" /> + <ItemsRepeater x:Name="DashboardView" ItemsSource="{x:Bind ViewModel.ActiveModules, Mode=OneWay}"> + <ItemsRepeater.Layout> + <controls:StaggeredLayout + ColumnSpacing="8" + DesiredColumnWidth="378" + RowSpacing="8" /> + </ItemsRepeater.Layout> + <ItemsRepeater.ItemTemplate> + <DataTemplate x:DataType="viewmodels:DashboardListItem"> + <Grid + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" + BorderThickness="1" + CornerRadius="{StaticResource OverlayCornerRadius}" + RowSpacing="0"> + <Grid.RowDefinitions> + <RowDefinition /> + <RowDefinition /> + </Grid.RowDefinitions> + <Border Grid.RowSpan="2" Opacity="0.05"> + <Border.Background> + <LinearGradientBrush StartPoint="0,0" EndPoint="1,3"> + <GradientStop Offset="0.5" Color="{x:Bind AccentColor, Mode=OneWay}" /> + <GradientStop Offset="0.9" Color="Transparent" /> + </LinearGradientBrush> + </Border.Background> + </Border> + <Grid Margin="16,8,16,0" ColumnSpacing="12"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <Image Width="20" Margin="0,0,0,0"> + <Image.Source> + <BitmapImage UriSource="{x:Bind Icon, Mode=OneWay}" /> + </Image.Source> + </Image> + <TextBlock + Grid.Column="1" + VerticalAlignment="Center" + FontWeight="SemiBold" + Text="{x:Bind Label, Mode=OneWay}" + TextTrimming="CharacterEllipsis" /> + <FontIcon + Grid.Column="2" + Width="20" + Margin="0,0,-12,0" + FontSize="16" + Glyph="" + Visibility="{x:Bind IsLocked, Converter={StaticResource BoolToInvertedVisibilityConverter}, ConverterParameter=True, Mode=OneWay}"> + <ToolTipService.ToolTip> + <TextBlock x:Uid="GPO_IsSettingForcedText" TextWrapping="WrapWholeWords" /> + </ToolTipService.ToolTip> + </FontIcon> + <ToggleSwitch + Grid.Column="3" + Margin="0,-2,0,0" + HorizontalAlignment="Right" + IsEnabled="{x:Bind IsLocked, Converter={StaticResource BoolNegationConverter}, ConverterParameter=True, Mode=OneWay}" + IsOn="{x:Bind IsEnabled, Mode=TwoWay}" + OffContent="" + OnContent="" + Style="{StaticResource RightAlignedCompactToggleSwitchStyle}" /> + </Grid> + + <ItemsControl + Grid.Row="1" + Margin="16,8,16,16" + ItemTemplateSelector="{StaticResource ModuleItemTemplateSelector}" + ItemsSource="{x:Bind DashboardModuleItems, Mode=OneWay}" + Visibility="{x:Bind IsEnabled, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}"> + <ItemsControl.ItemsPanel> + <ItemsPanelTemplate> + <StackPanel Spacing="4" /> + </ItemsPanelTemplate> + </ItemsControl.ItemsPanel> + </ItemsControl> + </Grid> + </DataTemplate> + </ItemsRepeater.ItemTemplate> + </ItemsRepeater> + + <TextBlock + x:Uid="DisabledModules" + Margin="0,24,0,12" + Style="{StaticResource SubtitleTextBlockStyle}" /> + + <ItemsRepeater ItemsSource="{x:Bind ViewModel.DisabledModules, Mode=OneWay}"> + <ItemsRepeater.Layout> + <controls:StaggeredLayout + ColumnSpacing="8" + DesiredColumnWidth="378" + RowSpacing="8" /> + </ItemsRepeater.Layout> + <ItemsRepeater.ItemTemplate> + <DataTemplate x:DataType="viewmodels:DashboardListItem"> + <Grid + Padding="16,12" + Background="{ThemeResource CardBackgroundFillColorDefaultBrush}" + BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" + BorderThickness="1" + CornerRadius="{StaticResource OverlayCornerRadius}" + RowSpacing="12"> + <Grid ColumnSpacing="12"> + <Grid.ColumnDefinitions> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="*" /> + <ColumnDefinition Width="Auto" /> + <ColumnDefinition Width="Auto" /> + </Grid.ColumnDefinitions> + <Image Width="20"> + <Image.Source> + <BitmapImage UriSource="{x:Bind Icon, Mode=OneWay}" /> + </Image.Source> + </Image> + <TextBlock + Grid.Column="1" + VerticalAlignment="Center" + FontWeight="SemiBold" + Text="{x:Bind Label, Mode=OneWay}" + TextTrimming="CharacterEllipsis" /> + <FontIcon + Grid.Column="2" + Width="20" + Margin="0,0,-12,0" + FontSize="16" + Glyph="" + Visibility="{x:Bind IsLocked, Converter={StaticResource BoolToInvertedVisibilityConverter}, ConverterParameter=True, Mode=OneWay}"> + <ToolTipService.ToolTip> + <TextBlock x:Uid="GPO_IsSettingForcedText" TextWrapping="WrapWholeWords" /> + </ToolTipService.ToolTip> + </FontIcon> + <ToggleSwitch + Grid.Column="3" + Margin="0,-2,0,0" + HorizontalAlignment="Right" + IsEnabled="{x:Bind IsLocked, Converter={StaticResource BoolNegationConverter}, ConverterParameter=True, Mode=OneWay}" + IsOn="{x:Bind IsEnabled, Mode=TwoWay}" + OffContent="" + OnContent="" + Style="{StaticResource RightAlignedCompactToggleSwitchStyle}" /> + </Grid> + </Grid> + </DataTemplate> + </ItemsRepeater.ItemTemplate> + </ItemsRepeater> + </StackPanel> + + </ScrollViewer> + </Grid> +</Page> \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs new file mode 100644 index 000000000000..26f472744178 --- /dev/null +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml.cs @@ -0,0 +1,58 @@ +// 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.Threading; +using System.Threading.Tasks; +using ManagedCommon; +using Microsoft.PowerToys.Settings.UI.Helpers; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.PowerToys.Settings.UI.OOBE.Views; +using Microsoft.PowerToys.Settings.UI.ViewModels; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Windows.Storage.Pickers; + +namespace Microsoft.PowerToys.Settings.UI.Views +{ + /// <summary> + /// Dashboard Settings Page. + /// </summary> + public sealed partial class DashboardPage : Page, IRefreshablePage + { + /// <summary> + /// Gets or sets view model. + /// </summary> + public DashboardViewModel ViewModel { get; set; } + + /// <summary> + /// Initializes a new instance of the <see cref="DashboardPage"/> class. + /// Dashboard Settings page constructor. + /// </summary> + public DashboardPage() + { + InitializeComponent(); + var settingsUtils = new SettingsUtils(); + + ViewModel = new DashboardViewModel( + SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage); + DataContext = ViewModel; + } + + public void RefreshEnabledState() + { + ViewModel.ModuleEnabledChangedOnSettingsPage(); + } + + private void SWVersionButtonClicked(object sender, RoutedEventArgs e) + { + ViewModel.SWVersionButtonClicked(); + } + + private void SettingsButtonClicked(object sender, RoutedEventArgs e) + { + ViewModel.SettingsButtonClicked(sender); + } + } +} diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/KeyboardManagerPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/KeyboardManagerPage.xaml.cs index eabe0ff2dbea..9d8496820632 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/KeyboardManagerPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/KeyboardManagerPage.xaml.cs @@ -73,7 +73,7 @@ private static void CombineRemappings(List<KeysDataModel> remapKeysList, uint le } } - private int FilterRemapKeysList(List<KeysDataModel> remapKeysList) + public static int FilterRemapKeysList(List<KeysDataModel> remapKeysList) { if (remapKeysList != null) { diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml index c0b12c89143d..817b40b94ba5 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml @@ -85,10 +85,16 @@ <SolidColorBrush x:Key="NavigationViewContentGridBorderBrush" Color="Transparent" /> </NavigationView.Resources> <NavigationView.MenuItems> + <NavigationViewItem + x:Uid="Shell_Dashboard" + helpers:NavHelper.NavigateTo="views:DashboardPage" + Icon="{ui:FontIcon Glyph=}" /> + <NavigationViewItem x:Uid="Shell_General" helpers:NavHelper.NavigateTo="views:GeneralPage" - Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsSettings.png}" /> + Icon="{ui:FontIcon Glyph=}" /> + <NavigationViewItemSeparator /> <NavigationViewItem x:Uid="Shell_AlwaysOnTop" diff --git a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs index 1892091d9a6f..3fc3c1a39e60 100644 --- a/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml.cs @@ -236,7 +236,7 @@ public static void Navigate(Type type) public void Refresh() { - shellFrame.Navigate(typeof(GeneralPage)); + shellFrame.Navigate(typeof(DashboardPage)); } // Tell the current page view model to update @@ -361,7 +361,7 @@ private void ReceiveMessage(JsonObject json) internal static void EnsurePageIsSelected() { - NavigationService.EnsurePageIsSelected(typeof(GeneralPage)); + NavigationService.EnsurePageIsSelected(typeof(DashboardPage)); } private void SetTitleBar() diff --git a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw index 94d256bbdb45..02c94f968318 100644 --- a/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw +++ b/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw @@ -928,7 +928,10 @@ <value>This overrides the Windows Snap shortcut (Win + arrow) to move windows between zones</value> </data> <data name="FancyZones_ShiftDragCheckBoxControl_Header.Content" xml:space="preserve"> - <value>Hold Shift key to activate zones while dragging</value> + <value>Hold Shift key to activate zones while dragging a window</value> + </data> + <data name="FancyZones_ActivationNoShiftDrag" xml:space="preserve"> + <value>Drag windows to activate zones</value> </data> <data name="FancyZones_ShowZonesOnAllMonitorsCheckBoxControl.Content" xml:space="preserve"> <value>Show zones on all monitors while dragging a window</value> @@ -2716,6 +2719,9 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v <data name="VideoConference_DeprecationWarningButton.Content" xml:space="preserve"> <value>Learn more</value> </data> + <data name="LearnMore.Content" xml:space="preserve"> + <value>Learn more</value> + </data> <data name="VideoConference_RunAsAdminRequired.Title" xml:space="preserve"> <value>You need to run as administrator to modify these settings.</value> </data> @@ -2991,6 +2997,78 @@ Activate by holding the key for the character you want to add an accent to, then <data name="QuickAccent.SecondaryLinksHeader" xml:space="preserve"> <value>Attribution</value> </data> + <data name="AlwaysOnTop_ShortDescription" xml:space="preserve"> + <value>Pin a window</value> + </data> + <data name="Awake_ShortDescription" xml:space="preserve"> + <value>Keep your PC awake</value> + </data> + <data name="ColorPicker_ShortDescription" xml:space="preserve"> + <value>Pick a color</value> + </data> + <data name="CropAndLock_Thumbnail" xml:space="preserve"> + <value>Thumbnail</value> + </data> + <data name="CropAndLock_Reparent" xml:space="preserve"> + <value>Reparent</value> + </data> + <data name="FancyZones_OpenEditor" xml:space="preserve"> + <value>Open editor</value> + </data> + <data name="FileLocksmith_ShortDescription" xml:space="preserve"> + <value>Right-click on files or directories to show running processes</value> + </data> + <data name="FindMyMouse_ShortDescription" xml:space="preserve"> + <value>Find the mouse</value> + </data> + <data name="ImageResizer_ShortDescription" xml:space="preserve"> + <value>Select Image Resizer in the right-click context menu</value> + </data> + <data name="MouseHighlighter_ShortDescription" xml:space="preserve"> + <value>Highlight clicks</value> + </data> + <data name="MouseJump_ShortDescription" xml:space="preserve"> + <value>Quickly move the mouse pointer</value> + </data> + <data name="MouseCrosshairs_ShortDescription" xml:space="preserve"> + <value>Draw crosshairs centered on the mouse pointer</value> + </data> + <data name="MouseWithoutBorders_ShortDescription" xml:space="preserve"> + <value>Move your cursor across multiple devices</value> + </data> + <data name="PastePlain_ShortDescription" xml:space="preserve"> + <value>Paste clipboard content without formatting</value> + </data> + <data name="Peek_ShortDescription" xml:space="preserve"> + <value>Quick and easy previewer</value> + </data> + <data name="PowerRename_ShortDescription" xml:space="preserve"> + <value>Select Power Rename in right-click context menu</value> + </data> + <data name="Run_ShortDescription" xml:space="preserve"> + <value>A quick launcher</value> + </data> + <data name="PowerAccent_ShortDescription" xml:space="preserve"> + <value>An alternative way to type accented characters</value> + </data> + <data name="RegistryPreview_ShortDescription" xml:space="preserve"> + <value>Visualize and edit Windows Registry files</value> + </data> + <data name="ScreenRuler_ShortDescription" xml:space="preserve"> + <value>Measure pixels on your screen</value> + </data> + <data name="ShortcutGuide_ShortDescription" xml:space="preserve"> + <value>Show a help overlay with Windows shortcuts</value> + </data> + <data name="PowerOcr_ShortDescription" xml:space="preserve"> + <value>A convenient way to copy text from anywhere on screen</value> + </data> + <data name="Dashboard_Activation" xml:space="preserve"> + <value>Activation</value> + </data> + <data name="DashboardKBMShowMappingsButton.Content" xml:space="preserve"> + <value>Show remappings</value> + </data> <data name="Oobe_QuickAccent.Description" xml:space="preserve"> <value>Quick Accent is an easy way to write letters with accents, like on a smartphone.</value> </data> @@ -3415,7 +3493,7 @@ Activate by holding the key for the character you want to add an accent to, then <comment>This refers to directly integrating in with Windows</comment> </data> <data name="GPO_IsSettingForced.Title" xml:space="preserve"> - <value>The system administrator is forcing this setting.</value> + <value>This setting is enforced by your System Administrator.</value> </data> <data name="Hosts_AdditionalLinesPosition.Description" xml:space="preserve"> <value>Additional content includes the file header and lines that can't parse</value> @@ -3703,4 +3781,19 @@ Activate by holding the key for the character you want to add an accent to, then <value>Administrator: PowerToys Settings</value> <comment>Title of the settings window when running as administrator</comment> </data> + <data name="DashboardTitle.Text" xml:space="preserve"> + <value>Dashboard</value> + </data> + <data name="Shell_Dashboard.Content" xml:space="preserve"> + <value>Dashboard</value> + </data> + <data name="GPO_IsSettingForcedText.Text" xml:space="preserve"> + <value>This setting is enforced by your System Administrator.</value> + </data> + <data name="DisabledModules.Text" xml:space="preserve"> + <value>Disabled modules</value> + </data> + <data name="EnabledModules.Text" xml:space="preserve"> + <value>Enabled modules</value> + </data> </root> \ No newline at end of file diff --git a/src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs b/src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs new file mode 100644 index 000000000000..1efe8257d053 --- /dev/null +++ b/src/settings-ui/Settings.UI/ViewModels/DashboardListItem.cs @@ -0,0 +1,69 @@ +// 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.ObjectModel; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using Microsoft.UI; +using Windows.UI; + +namespace Microsoft.PowerToys.Settings.UI.ViewModels +{ + public class DashboardListItem : INotifyPropertyChanged + { + private bool _visible; + private bool _isEnabled; + + public string Label { get; set; } + + public string Icon { get; set; } + + public string ToolTip { get; set; } + + public string Tag { get; set; } + + public Color AccentColor { get; set; } = Colors.Transparent; + + public bool IsLocked { get; set; } + + public bool IsEnabled + { + get => _isEnabled; + set + { + if (_isEnabled != value) + { + _isEnabled = value; + OnPropertyChanged(); + EnabledChangedCallback?.Invoke(this); + } + } + } + + public Action<DashboardListItem> EnabledChangedCallback { get; set; } + + public bool Visible + { + get => _visible; + set + { + if (_visible != value) + { + _visible = value; + OnPropertyChanged(); + } + } + } + + public event PropertyChangedEventHandler PropertyChanged; + + private void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + public ObservableCollection<DashboardModuleItem> DashboardModuleItems { get; set; } = new ObservableCollection<DashboardModuleItem>(); + } +} diff --git a/src/settings-ui/Settings.UI/ViewModels/DashboardModuleItem.cs b/src/settings-ui/Settings.UI/ViewModels/DashboardModuleItem.cs new file mode 100644 index 000000000000..5032abe999a4 --- /dev/null +++ b/src/settings-ui/Settings.UI/ViewModels/DashboardModuleItem.cs @@ -0,0 +1,75 @@ +// 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.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.UI.Xaml; +using Windows.UI; + +namespace Microsoft.PowerToys.Settings.UI.ViewModels +{ +#pragma warning disable SA1402 // File may only contain a single type +#pragma warning disable SA1649 // File name should match first type name + public class DashboardModuleTextItem : DashboardModuleItem + { + } + + public class DashboardModuleButtonItem : DashboardModuleItem + { + public string ButtonTitle { get; set; } + + public bool IsButtonDescriptionVisible { get; set; } + + public string ButtonDescription { get; set; } + + public string ButtonGlyph { get; set; } + + public RoutedEventHandler ButtonClickHandler { get; set; } + } + + public class DashboardModuleShortcutItem : DashboardModuleItem + { + public List<object> Shortcut { get; set; } + } + + public class DashboardModuleKBMItem : DashboardModuleItem + { + private List<KeysDataModel> _remapKeys = new List<KeysDataModel>(); + + public List<KeysDataModel> RemapKeys + { + get => _remapKeys; + set => _remapKeys = value; + } + + private List<AppSpecificKeysDataModel> _remapShortcuts = new List<AppSpecificKeysDataModel>(); + + public List<AppSpecificKeysDataModel> RemapShortcuts + { + get => _remapShortcuts; + set => _remapShortcuts = value; + } + } + + public class DashboardModuleItem : INotifyPropertyChanged + { + public string Label { get; set; } + + public event PropertyChangedEventHandler PropertyChanged; + + internal void NotifyPropertyChanged(string propertyName) + { + OnPropertyChanged(propertyName); + } + + private void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} +#pragma warning restore SA1402 // File may only contain a single type +#pragma warning restore SA1649 // File name should match first type name diff --git a/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs new file mode 100644 index 000000000000..eedb55760f91 --- /dev/null +++ b/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs @@ -0,0 +1,803 @@ +// 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.Windows.Threading; +using global::PowerToys.GPOWrapper; +using Microsoft.PowerToys.Settings.UI.Library; +using Microsoft.PowerToys.Settings.UI.Library.Helpers; +using Microsoft.PowerToys.Settings.UI.Library.Interfaces; +using Microsoft.PowerToys.Settings.UI.Services; +using Microsoft.PowerToys.Settings.UI.Views; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Windows.UI; + +namespace Microsoft.PowerToys.Settings.UI.ViewModels +{ + public class DashboardViewModel : Observable + { + private const string JsonFileType = ".json"; + private readonly IFileSystemWatcher _watcher; + private DashboardModuleKBMItem _kbmItem; + private Dispatcher dispatcher; + + public Func<string, int> SendConfigMSG { get; } + + public ObservableCollection<DashboardListItem> ActiveModules { get; set; } = new ObservableCollection<DashboardListItem>(); + + public ObservableCollection<DashboardListItem> DisabledModules { get; set; } = new ObservableCollection<DashboardListItem>(); + + public bool UpdateAvailable { get; set; } + + private List<DashboardListItem> _allModules; + + 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 = Dispatcher.CurrentDispatcher; + _settingsRepository = settingsRepository; + generalSettingsConfig = settingsRepository.SettingsConfig; + generalSettingsConfig.AddEnabledModuleChangeNotification(ModuleEnabledChangedOnSettingsPage); + + // set the callback functions value to hangle outgoing IPC message. + SendConfigMSG = ipcMSGCallBackFunc; + + _allModules = new List<DashboardListItem>(); + + GpoRuleConfigured gpo; + gpo = GPOWrapper.GetConfiguredAlwaysOnTopEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "AlwaysOnTop", + Label = resourceLoader.GetString("AlwaysOnTop/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.AlwaysOnTop), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsAlwaysOnTop.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 74, 196, 242), // #4ac4f2 + DashboardModuleItems = GetModuleItemsAlwaysOnTop(), + }); + + gpo = GPOWrapper.GetConfiguredAwakeEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "Awake", + Label = resourceLoader.GetString("Awake/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.Awake), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsAwake.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 40, 177, 233), // #28b1e9 + DashboardModuleItems = GetModuleItemsAwake(), + }); + + gpo = GPOWrapper.GetConfiguredColorPickerEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "ColorPicker", + Label = resourceLoader.GetString("ColorPicker/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.ColorPicker), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsColorPicker.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 7, 129, 211), // #0781d3 + DashboardModuleItems = GetModuleItemsColorPicker(), + }); + + gpo = GPOWrapper.GetConfiguredCropAndLockEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "CropAndLock", + Label = resourceLoader.GetString("CropAndLock/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.CropAndLock), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsCropAndLock.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 32, 166, 228), // #20a6e4 + DashboardModuleItems = GetModuleItemsCropAndLock(), + }); + + gpo = GPOWrapper.GetConfiguredFancyZonesEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "FancyZones", + Label = resourceLoader.GetString("FancyZones/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.FancyZones), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsFancyZones.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 65, 209, 247), // #41d1f7 + DashboardModuleItems = GetModuleItemsFancyZones(), + }); + + gpo = GPOWrapper.GetConfiguredFileLocksmithEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "FileLocksmith", + Label = resourceLoader.GetString("FileLocksmith/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.FileLocksmith), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsFileLocksmith.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 245, 161, 20), // #f5a114 + DashboardModuleItems = GetModuleItemsFileLocksmith(), + }); + + gpo = GPOWrapper.GetConfiguredFindMyMouseEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "FindMyMouse", + Label = resourceLoader.GetString("MouseUtils_FindMyMouse/Header"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.FindMyMouse), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsFindMyMouse.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 104, 109, 112), // #686d70 + DashboardModuleItems = GetModuleItemsFindMyMouse(), + }); + + gpo = GPOWrapper.GetConfiguredHostsFileEditorEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "Hosts", + Label = resourceLoader.GetString("Hosts/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.Hosts), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsHosts.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 16, 132, 208), // #1084d0 + DashboardModuleItems = GetModuleItemsHosts(), + }); + + gpo = GPOWrapper.GetConfiguredImageResizerEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "ImageResizer", + Label = resourceLoader.GetString("ImageResizer/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.ImageResizer), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsImageResizer.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 85, 207, 248), // #55cff8 + DashboardModuleItems = GetModuleItemsImageResizer(), + }); + + gpo = GPOWrapper.GetConfiguredKeyboardManagerEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "KeyboardManager", + Label = resourceLoader.GetString("KeyboardManager/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.KeyboardManager), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsKeyboardManager.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 224, 231, 238), // #e0e7ee + DashboardModuleItems = GetModuleItemsKeyboardManager(), + }); + + if (gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.KeyboardManager)) + { + KeyboardManagerSettings kbmSettings = GetKBMSettings(); + _watcher = Library.Utilities.Helper.GetFileWatcher(KeyboardManagerSettings.ModuleName, kbmSettings.Properties.ActiveConfiguration.Value + JsonFileType, () => LoadKBMSettingsFromJson()); + } + + gpo = GPOWrapper.GetConfiguredMouseHighlighterEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "MouseHighlighter", + Label = resourceLoader.GetString("MouseUtils_MouseHighlighter/Header"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.MouseHighlighter), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsMouseHighlighter.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 17, 126, 199), // #117ec7 + DashboardModuleItems = GetModuleItemsMouseHighlighter(), + }); + + gpo = GPOWrapper.GetConfiguredMouseJumpEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "MouseJump", + Label = resourceLoader.GetString("MouseUtils_MouseJump/Header"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.MouseJump), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsMouseJump.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 240, 240, 239), // #f0f0ef + DashboardModuleItems = GetModuleItemsMouseJump(), + }); + + gpo = GPOWrapper.GetConfiguredMousePointerCrosshairsEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "MousePointerCrosshairs", + Label = resourceLoader.GetString("MouseUtils_MousePointerCrosshairs/Header"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.MousePointerCrosshairs), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsMouseCrosshairs.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 25, 115, 182), // #1973b6 + DashboardModuleItems = GetModuleItemsMouseCrosshairs(), + }); + + gpo = GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "MouseWithoutBorders", + Label = resourceLoader.GetString("MouseWithoutBorders/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.MouseWithoutBorders), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsMouseWithoutBorders.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 31, 164, 227), // #1fa4e3 + DashboardModuleItems = GetModuleItemsMouseWithoutBorders(), + }); + + gpo = GPOWrapper.GetConfiguredPastePlainEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "PastePlain", + Label = resourceLoader.GetString("PastePlain/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.PastePlain), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsPastePlain.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 243, 156, 16), // #f39c10 + DashboardModuleItems = GetModuleItemsPastePlain(), + }); + + gpo = GPOWrapper.GetConfiguredPeekEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "Peek", + Label = resourceLoader.GetString("Peek/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.Peek), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsPeek.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 255, 214, 103), // #ffd667 + DashboardModuleItems = GetModuleItemsPeek(), + }); + + gpo = GPOWrapper.GetConfiguredPowerRenameEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "PowerRename", + Label = resourceLoader.GetString("PowerRename/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.PowerRename), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsPowerRename.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 43, 186, 243), // #2bbaf3 + DashboardModuleItems = GetModuleItemsPowerRename(), + }); + + gpo = GPOWrapper.GetConfiguredPowerLauncherEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "PowerLauncher", + Label = resourceLoader.GetString("PowerLauncher/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.PowerLauncher), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsPowerToysRun.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 51, 191, 240), // #33bff0 + DashboardModuleItems = GetModuleItemsRun(), + }); + + gpo = GPOWrapper.GetConfiguredQuickAccentEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "PowerAccent", + Label = resourceLoader.GetString("QuickAccent/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.PowerAccent), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsPowerAccent.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 84, 89, 92), // #54595c + DashboardModuleItems = GetModuleItemsPowerAccent(), + }); + + gpo = GPOWrapper.GetConfiguredRegistryPreviewEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "RegistryPreview", + Label = resourceLoader.GetString("RegistryPreview/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.RegistryPreview), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsRegistryPreview.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 17, 80, 138), // #11508a + DashboardModuleItems = GetModuleItemsRegistryPreview(), + }); + + gpo = GPOWrapper.GetConfiguredScreenRulerEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "MeasureTool", + Label = resourceLoader.GetString("MeasureTool/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.MeasureTool), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsScreenRuler.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 135, 144, 153), // #879099 + DashboardModuleItems = GetModuleItemsScreenRuler(), + }); + + gpo = GPOWrapper.GetConfiguredShortcutGuideEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "ShortcutGuide", + Label = resourceLoader.GetString("ShortcutGuide/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.ShortcutGuide), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsShortcutGuide.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 193, 202, 209), // #c1cad1 + DashboardModuleItems = GetModuleItemsShortcutGuide(), + }); + + gpo = GPOWrapper.GetConfiguredTextExtractorEnabledValue(); + _allModules.Add(new DashboardListItem() + { + Tag = "PowerOCR", + Label = resourceLoader.GetString("TextExtractor/ModuleTitle"), + IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && generalSettingsConfig.Enabled.PowerOCR), + IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled, + Icon = "ms-appx:///Assets/Settings/FluentIcons/FluentIconsPowerOCR.png", + EnabledChangedCallback = EnabledChangedOnUI, + AccentColor = Color.FromArgb(255, 24, 153, 224), // #1899e0 + DashboardModuleItems = GetModuleItemsPowerOCR(), + }); + + ActiveModules = new ObservableCollection<DashboardListItem>(_allModules.Where(x => x.IsEnabled)); + DisabledModules = new ObservableCollection<DashboardListItem>(_allModules.Where(x => !x.IsEnabled)); + + UpdatingSettings updatingSettingsConfig = UpdatingSettings.LoadSettings(); + UpdateAvailable = updatingSettingsConfig != null && (updatingSettingsConfig.State == UpdatingSettings.UpdatingState.ReadyToInstall || updatingSettingsConfig.State == UpdatingSettings.UpdatingState.ReadyToDownload); + } + + private void LoadKBMSettingsFromJson() + { + KeyboardManagerProfile kbmProfile = GetKBMProfile(); + _kbmItem.RemapKeys = kbmProfile?.RemapKeys.InProcessRemapKeys; + _kbmItem.RemapShortcuts = KeyboardManagerViewModel.CombineShortcutLists(kbmProfile?.RemapShortcuts.GlobalRemapShortcuts, kbmProfile?.RemapShortcuts.AppSpecificRemapShortcuts); + dispatcher.Invoke(new Action(() => UpdateKBMItems())); + } + + private void UpdateKBMItems() + { + _kbmItem.NotifyPropertyChanged(nameof(_kbmItem.RemapKeys)); + _kbmItem.NotifyPropertyChanged(nameof(_kbmItem.RemapShortcuts)); + } + + private KeyboardManagerProfile GetKBMProfile() + { + KeyboardManagerSettings kbmSettings = GetKBMSettings(); + const string PowerToyName = KeyboardManagerSettings.ModuleName; + string fileName = kbmSettings.Properties.ActiveConfiguration.Value + JsonFileType; + return new SettingsUtils().GetSettingsOrDefault<KeyboardManagerProfile>(PowerToyName, fileName); + } + + private KeyboardManagerSettings GetKBMSettings() + { + var settingsUtils = new SettingsUtils(); + ISettingsRepository<KeyboardManagerSettings> moduleSettingsRepository = SettingsRepository<KeyboardManagerSettings>.GetInstance(settingsUtils); + return moduleSettingsRepository.SettingsConfig; + } + + internal void SettingsButtonClicked(object sender) + { + Button button = sender as Button; + if (button == null) + { + return; + } + + string tag = button.Tag as string; + if (tag == null) + { + return; + } + + Type type = null; + switch (tag) + { + case "AlwaysOnTop": type = typeof(AlwaysOnTopPage); break; + case "Awake": type = typeof(AwakePage); break; + case "ColorPicker": type = typeof(ColorPickerPage); break; + case "CropAndLock": type = typeof(CropAndLockPage); break; + case "FancyZones": type = typeof(FancyZonesPage); break; + case "FileLocksmith": type = typeof(FileLocksmithPage); break; + case "FindMyMouse": type = typeof(MouseUtilsPage); break; + case "Hosts": type = typeof(HostsPage); break; + case "ImageResizer": type = typeof(ImageResizerPage); break; + case "KeyboardManager": type = typeof(KeyboardManagerPage); break; + case "MouseHighlighter": type = typeof(MouseUtilsPage); break; + case "MouseJump": type = typeof(MouseUtilsPage); break; + case "MousePointerCrosshairs": type = typeof(MouseUtilsPage); break; + case "MouseWithoutBorders": type = typeof(MouseWithoutBordersPage); break; + case "PastePlain": type = typeof(PastePlainPage); break; + case "Peek": type = typeof(PeekPage); break; + case "PowerRename": type = typeof(PowerRenamePage); break; + case "PowerLauncher": type = typeof(PowerLauncherPage); break; + case "PowerAccent": type = typeof(PowerAccentPage); break; + case "RegistryPreview": type = typeof(RegistryPreviewPage); break; + case "MeasureTool": type = typeof(MeasureToolPage); break; + case "ShortcutGuide": type = typeof(ShortcutGuidePage); break; + case "PowerOCR": type = typeof(PowerOcrPage); break; + case "VideoConference": type = typeof(VideoConferencePage); break; + } + + NavigationService.Navigate(type); + } + + private void EnabledChangedOnUI(DashboardListItem dashboardListItem) + { + Views.ShellPage.UpdateGeneralSettingsCallback(dashboardListItem.Tag, dashboardListItem.IsEnabled); + } + + public void ModuleEnabledChangedOnSettingsPage() + { + ActiveModules.Clear(); + DisabledModules.Clear(); + generalSettingsConfig = _settingsRepository.SettingsConfig; + foreach (DashboardListItem item in _allModules) + { + switch (item.Tag) + { + case "AlwaysOnTop": item.IsEnabled = generalSettingsConfig.Enabled.AlwaysOnTop; break; + case "Awake": item.IsEnabled = generalSettingsConfig.Enabled.Awake; break; + case "ColorPicker": item.IsEnabled = generalSettingsConfig.Enabled.ColorPicker; break; + case "CropAndLock": item.IsEnabled = generalSettingsConfig.Enabled.CropAndLock; break; + case "FancyZones": item.IsEnabled = generalSettingsConfig.Enabled.FancyZones; break; + case "FileLocksmith": item.IsEnabled = generalSettingsConfig.Enabled.FileLocksmith; break; + case "FindMyMouse": item.IsEnabled = generalSettingsConfig.Enabled.FindMyMouse; break; + case "Hosts": item.IsEnabled = generalSettingsConfig.Enabled.Hosts; break; + case "ImageResizer": item.IsEnabled = generalSettingsConfig.Enabled.ImageResizer; break; + case "KeyboardManager": item.IsEnabled = generalSettingsConfig.Enabled.KeyboardManager; break; + case "MouseHighlighter": item.IsEnabled = generalSettingsConfig.Enabled.MouseHighlighter; break; + case "MouseJump": item.IsEnabled = generalSettingsConfig.Enabled.MouseJump; break; + case "MousePointerCrosshairs": item.IsEnabled = generalSettingsConfig.Enabled.MousePointerCrosshairs; break; + case "MouseWithoutBorders": item.IsEnabled = generalSettingsConfig.Enabled.MouseWithoutBorders; break; + case "PastePlain": item.IsEnabled = generalSettingsConfig.Enabled.PastePlain; break; + case "Peek": item.IsEnabled = generalSettingsConfig.Enabled.Peek; break; + case "PowerRename": item.IsEnabled = generalSettingsConfig.Enabled.PowerRename; break; + case "PowerLauncher": item.IsEnabled = generalSettingsConfig.Enabled.PowerLauncher; break; + case "PowerAccent": item.IsEnabled = generalSettingsConfig.Enabled.PowerAccent; break; + case "RegistryPreview": item.IsEnabled = generalSettingsConfig.Enabled.RegistryPreview; break; + case "MeasureTool": item.IsEnabled = generalSettingsConfig.Enabled.MeasureTool; break; + case "ShortcutGuide": item.IsEnabled = generalSettingsConfig.Enabled.ShortcutGuide; break; + case "PowerOCR": item.IsEnabled = generalSettingsConfig.Enabled.PowerOCR; break; + case "VideoConference": item.IsEnabled = generalSettingsConfig.Enabled.VideoConference; break; + } + + if (item.IsEnabled) + { + ActiveModules.Add(item); + } + else + { + DisabledModules.Add(item); + } + } + + OnPropertyChanged(nameof(ActiveModules)); + OnPropertyChanged(nameof(DisabledModules)); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsAlwaysOnTop() + { + ISettingsRepository<AlwaysOnTopSettings> moduleSettingsRepository = SettingsRepository<AlwaysOnTopSettings>.GetInstance(new SettingsUtils()); + var list = new List<DashboardModuleItem> + { + new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("AlwaysOnTop_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.Hotkey.Value.GetKeysList() }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsAwake() + { + var list = new List<DashboardModuleItem> + { + new DashboardModuleTextItem() { Label = resourceLoader.GetString("Awake_ShortDescription") }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsColorPicker() + { + ISettingsRepository<ColorPickerSettings> moduleSettingsRepository = SettingsRepository<ColorPickerSettings>.GetInstance(new SettingsUtils()); + 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> GetModuleItemsCropAndLock() + { + ISettingsRepository<CropAndLockSettings> moduleSettingsRepository = SettingsRepository<CropAndLockSettings>.GetInstance(new SettingsUtils()); + 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() }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsFancyZones() + { + ISettingsRepository<FancyZonesSettings> moduleSettingsRepository = SettingsRepository<FancyZonesSettings>.GetInstance(new SettingsUtils()); + var settings = moduleSettingsRepository.SettingsConfig; + string activationMode = $"{resourceLoader.GetString(settings.Properties.FancyzonesShiftDrag.Value ? "FancyZones_ShiftDragCheckBoxControl_Header/Content" : "FancyZones_ActivationNoShiftDrag")}."; + if (settings.Properties.FancyzonesMouseSwitch.Value) + { + activationMode += $" {resourceLoader.GetString("FancyZones_MouseDragCheckBoxControl_Header/Content")}."; + } + + var list = new List<DashboardModuleItem> + { + new DashboardModuleTextItem() { Label = 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 = "\uEB3C", ButtonClickHandler = FancyZoneLaunchClicked }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsFileLocksmith() + { + var list = new List<DashboardModuleItem> + { + new DashboardModuleTextItem() { Label = resourceLoader.GetString("FileLocksmith_ShortDescription") }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsFindMyMouse() + { + ISettingsRepository<FindMyMouseSettings> moduleSettingsRepository = SettingsRepository<FindMyMouseSettings>.GetInstance(new SettingsUtils()); + 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 + { + switch (activationMethod) + { + case 2: shortDescription += $". {resourceLoader.GetString("Dashboard_Activation")}: {resourceLoader.GetString("MouseUtils_FindMyMouse_ActivationShakeMouse/Content")}"; break; + case 1: shortDescription += $". {resourceLoader.GetString("Dashboard_Activation")}: {resourceLoader.GetString("MouseUtils_FindMyMouse_ActivationDoubleRightControlPress/Content")}"; break; + case 0: + default: shortDescription += $". {resourceLoader.GetString("Dashboard_Activation")}: {resourceLoader.GetString("MouseUtils_FindMyMouse_ActivationDoubleControlPress/Content")}"; break; + } + + list.Add(new DashboardModuleTextItem() { Label = shortDescription }); + } + + 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 = "\uEA37", ButtonClickHandler = HostLaunchClicked }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsImageResizer() + { + var list = new List<DashboardModuleItem> + { + new DashboardModuleTextItem() { Label = resourceLoader.GetString("ImageResizer_ShortDescription") }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsKeyboardManager() + { + KeyboardManagerProfile kbmProfile = GetKBMProfile(); + _kbmItem = new DashboardModuleKBMItem() { RemapKeys = kbmProfile?.RemapKeys.InProcessRemapKeys, RemapShortcuts = KeyboardManagerViewModel.CombineShortcutLists(kbmProfile?.RemapShortcuts.GlobalRemapShortcuts, kbmProfile?.RemapShortcuts.AppSpecificRemapShortcuts) }; + var list = new List<DashboardModuleItem> + { + _kbmItem, + new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("KeyboardManager_RemapKeyboardButton/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("KeyboardManager_RemapKeyboardButton/Description"), ButtonGlyph = "\uE92E", ButtonClickHandler = KbmKeyLaunchClicked }, + new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("KeyboardManager_RemapShortcutsButton/Header"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString("KeyboardManager_RemapShortcutsButton/Description"), ButtonGlyph = "\uE92E", ButtonClickHandler = KbmShortcutLaunchClicked }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsMouseHighlighter() + { + ISettingsRepository<MouseHighlighterSettings> moduleSettingsRepository = SettingsRepository<MouseHighlighterSettings>.GetInstance(new SettingsUtils()); + 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(new SettingsUtils()); + 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> GetModuleItemsMouseCrosshairs() + { + ISettingsRepository<MousePointerCrosshairsSettings> moduleSettingsRepository = SettingsRepository<MousePointerCrosshairsSettings>.GetInstance(new SettingsUtils()); + 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 DashboardModuleTextItem() { Label = resourceLoader.GetString("MouseWithoutBorders_ShortDescription") }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsPastePlain() + { + ISettingsRepository<PastePlainSettings> moduleSettingsRepository = SettingsRepository<PastePlainSettings>.GetInstance(new SettingsUtils()); + var list = new List<DashboardModuleItem> + { + new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("PastePlain_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsPeek() + { + ISettingsRepository<PeekSettings> moduleSettingsRepository = SettingsRepository<PeekSettings>.GetInstance(new SettingsUtils()); + 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> GetModuleItemsPowerRename() + { + var list = new List<DashboardModuleItem> + { + new DashboardModuleTextItem() { Label = resourceLoader.GetString("PowerRename_ShortDescription") }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsRun() + { + ISettingsRepository<PowerLauncherSettings> moduleSettingsRepository = SettingsRepository<PowerLauncherSettings>.GetInstance(new SettingsUtils()); + 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() + { + string shortDescription = resourceLoader.GetString("PowerAccent_ShortDescription"); + var settingsUtils = new SettingsUtils(); + PowerAccentSettings moduleSettings = settingsUtils.GetSettingsOrDefault<PowerAccentSettings>(PowerAccentSettings.ModuleName); + var activationMethod = moduleSettings.Properties.ActivationKey; + switch (activationMethod) + { + case Library.Enumerations.PowerAccentActivationKey.LeftRightArrow: shortDescription += $". {resourceLoader.GetString("Dashboard_Activation")}: {resourceLoader.GetString("QuickAccent_Activation_Key_Arrows/Content")}"; break; + case Library.Enumerations.PowerAccentActivationKey.Space: shortDescription += $". {resourceLoader.GetString("Dashboard_Activation")}: {resourceLoader.GetString("QuickAccent_Activation_Key_Space/Content")}"; break; + case Library.Enumerations.PowerAccentActivationKey.Both: shortDescription += $". {resourceLoader.GetString("Dashboard_Activation")}: {resourceLoader.GetString("QuickAccent_Activation_Key_Either/Content")}"; break; + } + + var list = new List<DashboardModuleItem> + { + new DashboardModuleTextItem() { Label = shortDescription }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsRegistryPreview() + { + var list = new List<DashboardModuleItem> + { + new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString("RegistryPreview_LaunchButtonControl/Header"), ButtonGlyph = "\uEA37", ButtonClickHandler = RegistryPreviewLaunchClicked }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsScreenRuler() + { + ISettingsRepository<MeasureToolSettings> moduleSettingsRepository = SettingsRepository<MeasureToolSettings>.GetInstance(new SettingsUtils()); + 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(new SettingsUtils()); + var list = new List<DashboardModuleItem> + { + new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("ShortcutGuide_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.OpenShortcutGuide.GetKeysList() }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerOCR() + { + ISettingsRepository<PowerOcrSettings> moduleSettingsRepository = SettingsRepository<PowerOcrSettings>.GetInstance(new SettingsUtils()); + var list = new List<DashboardModuleItem> + { + new DashboardModuleShortcutItem() { Label = resourceLoader.GetString("PowerOcr_ShortDescription"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() }, + }; + return new ObservableCollection<DashboardModuleItem>(list); + } + + internal void SWVersionButtonClicked() + { + NavigationService.Navigate(typeof(GeneralPage)); + } + + private void HostLaunchClicked(object sender, RoutedEventArgs e) + { + var settingsUtils = new SettingsUtils(); + 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 KbmKeyLaunchClicked(object sender, RoutedEventArgs e) + { + var settingsUtils = new SettingsUtils(); + var kbmViewModel = new KeyboardManagerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, KeyboardManagerPage.FilterRemapKeysList); + kbmViewModel.OnRemapKeyboard(); + } + + private void KbmShortcutLaunchClicked(object sender, RoutedEventArgs e) + { + var settingsUtils = new SettingsUtils(); + var kbmViewModel = new KeyboardManagerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, KeyboardManagerPage.FilterRemapKeysList); + kbmViewModel.OnEditShortcut(); + } + + private void RegistryPreviewLaunchClicked(object sender, RoutedEventArgs e) + { + var actionName = "Launch"; + SendConfigMSG("{\"action\":{\"RegistryPreview\":{\"action_name\":\"" + actionName + "\", \"value\":\"\"}}}"); + } + } +} diff --git a/src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs b/src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs index c4e395e99245..15c21eb423d0 100644 --- a/src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs +++ b/src/settings-ui/Settings.UI/ViewModels/KeyboardManagerViewModel.cs @@ -220,12 +220,12 @@ public List<AppSpecificKeysDataModel> RemapShortcuts public ICommand EditShortcutCommand => _editShortcutCommand ?? (_editShortcutCommand = new RelayCommand(OnEditShortcut)); - private void OnRemapKeyboard() + public void OnRemapKeyboard() { OpenEditor((int)KeyboardManagerEditorType.KeyEditor); } - private void OnEditShortcut() + public void OnEditShortcut() { OpenEditor((int)KeyboardManagerEditorType.ShortcutEditor); }