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 --- 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 1a154f0a82..97547c4292 100644 --- a/src/common/Common.UI/SettingsDeepLink.cs +++ b/src/common/Common.UI/SettingsDeepLink.cs @@ -28,6 +28,7 @@ namespace Common.UI PowerOCR, RegistryPreview, CropAndLock, + Dashboard, } private static string SettingsWindowNameToString(SettingsWindow value) @@ -68,6 +69,8 @@ namespace Common.UI 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 eb1fb48503..fab4a6500b 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 settings_window) { const HWND hwnd_main = FindWindowW(L"PToyTrayIconWindow", nullptr); - LPARAM msg = static_cast(ESettingsWindowNames::Overview); + LPARAM msg = static_cast(ESettingsWindowNames::Dashboard); if (settings_window.has_value() && settings_window.value() != "") { msg = static_cast(ESettingsWindowNames_from_string(settings_window.value())); diff --git a/src/runner/settings_window.cpp b/src/runner/settings_window.cpp index bcba0915b1..f7f8d5df63 100644 --- a/src/runner/settings_window.cpp +++ b/src/runner/settings_window.cpp @@ -596,7 +596,7 @@ void open_settings_window(std::optional 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(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 2a14ec46e0..06aac30dc8 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 0000000000..b34331a0e7 --- /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 0000000000..df9f02eca7 --- /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 98be30ec56..e601b11886 100644 --- a/src/settings-ui/Settings.UI/PowerToys.Settings.csproj +++ b/src/settings-ui/Settings.UI/PowerToys.Settings.csproj @@ -21,6 +21,9 @@ PowerToys.Settings.pri + + + @@ -124,5 +127,11 @@ Always + + + + $(DefaultXamlRuntime) + + - + \ 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 ba9988dd2d..ea02e1779e 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 @@ namespace Microsoft.PowerToys.Settings.UI public bool ShowScoobe { get; set; } - public Type StartupPage { get; set; } = typeof(Views.GeneralPage); + public Type StartupPage { get; set; } = typeof(Views.DashboardPage); public static Action IPCMessageReceivedCallback { get; set; } @@ -218,8 +218,8 @@ namespace Microsoft.PowerToys.Settings.UI 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 @@ namespace Microsoft.PowerToys.Settings.UI { 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 @@ namespace Microsoft.PowerToys.Settings.UI 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 5e5d3ee846..8b36831984 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 @@ namespace Microsoft.PowerToys.Settings.UI.Controls case 91: // The left Windows key case 92: // The right Windows key - PathIcon winIcon = XamlReader.Load(@"") as PathIcon; + PathIcon winIcon = XamlReader.Load(@"") as PathIcon; Viewbox winIconContainer = new Viewbox(); winIconContainer.Child = winIcon; winIconContainer.HorizontalAlignment = HorizontalAlignment.Center; @@ -143,6 +143,10 @@ namespace Microsoft.PowerToys.Settings.UI.Controls { 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 @@ namespace Microsoft.PowerToys.Settings.UI.Controls { 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 2d469563a2..68590a040a 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 @@ 16 12 - + + + + + \ 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 1a51b17874..1f1fc9e071 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}"> - + @@ -41,7 +39,6 @@ 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 b86a17aa38..d43bda83bf 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 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views { 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 c5171f4159..d0ae488347 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 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views { 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 40dcb56aa2..18a18189ab 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 @@ namespace Microsoft.PowerToys.Settings.UI.OOBE.Views { 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 0000000000..cac07b5bfd --- /dev/null +++ b/src/settings-ui/Settings.UI/SettingsXAML/Views/DashboardPage.xaml @@ -0,0 +1,446 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +