[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>
This commit is contained in:
Laszlo Nemeth 2023-10-20 14:23:25 +02:00 committed by GitHub
parent 8c22f0c485
commit 1f936df3eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 1721 additions and 49 deletions

View File

@ -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;

View File

@ -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()));

View File

@ -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;
}

View File

@ -4,7 +4,8 @@
enum class ESettingsWindowNames
{
Overview = 0,
Dashboard = 0,
Overview,
Awake,
ColorPicker,
FancyZones,

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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>

View File

@ -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<string> 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);
}
}
}

View File

@ -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(@"<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 @@ 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,
}
}

View File

@ -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>

View File

@ -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}" />

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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="&#xE72E;"
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="&#xE72E;"
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>

View File

@ -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);
}
}
}

View File

@ -73,7 +73,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
}
}
private int FilterRemapKeysList(List<KeysDataModel> remapKeysList)
public static int FilterRemapKeysList(List<KeysDataModel> remapKeysList)
{
if (remapKeysList != null)
{

View File

@ -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=&#xE80F;}" />
<NavigationViewItem
x:Uid="Shell_General"
helpers:NavHelper.NavigateTo="views:GeneralPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/FluentIcons/FluentIconsSettings.png}" />
Icon="{ui:FontIcon Glyph=&#xE713;}" />
<NavigationViewItemSeparator />
<NavigationViewItem
x:Uid="Shell_AlwaysOnTop"

View File

@ -236,7 +236,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
public void Refresh()
{
shellFrame.Navigate(typeof(GeneralPage));
shellFrame.Navigate(typeof(DashboardPage));
}
// Tell the current page view model to update
@ -361,7 +361,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
internal static void EnsurePageIsSelected()
{
NavigationService.EnsurePageIsSelected(typeof(GeneralPage));
NavigationService.EnsurePageIsSelected(typeof(DashboardPage));
}
private void SetTitleBar()

View File

@ -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>

View File

@ -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>();
}
}

View File

@ -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

View File

@ -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\":\"\"}}}");
}
}
}

View File

@ -220,12 +220,12 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
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);
}