[UX] New dashboard & refactored KeyVisual (#40214)

### Updated `KeyVisual` and `Shortcut` control
- Refactoring `KeyVisual` to remove redundant properties and UI
elements, and using Styles for better customization.
- Shortcut control now shows a "Configure shortcut" label when there's
no shortcut configured.

### Other changes
- Consolidated converters that were used across pages in `App.xaml.cs`
with consistent naming.
- Renamed templated controls (from `.cs` to `.xaml.cs`) and moving those
to the `Controls` root folder vs. individual folders for a better
overview.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

Closes #39520
Closes #32944

---------

Co-authored-by: Jay <65828559+Jay-o-Way@users.noreply.github.com>
Co-authored-by: Jaylyn Barbee <51131738+Jaylyn-Barbee@users.noreply.github.com>
This commit is contained in:
Niels Laute
2025-08-05 01:33:19 +02:00
committed by GitHub
parent fdd1f47d85
commit c91bef1517
43 changed files with 1415 additions and 1220 deletions

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="Microsoft.PowerToys.Settings.UI.Controls.Card"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Padding="8"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="{StaticResource OverlayCornerRadius}"
mc:Ignorable="d">
<Grid
VerticalAlignment="{x:Bind VerticalContentAlignment, Mode=OneWay}"
Background="{x:Bind Background, Mode=OneWay}"
BorderBrush="{x:Bind BorderBrush, Mode=OneWay}"
BorderThickness="{x:Bind BorderThickness, Mode=OneWay}"
CornerRadius="{x:Bind CornerRadius, Mode=OneWay}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="44" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="TitleGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Margin="16,0,0,0"
VerticalAlignment="Center"
FontSize="16"
FontWeight="SemiBold"
Text="{x:Bind Title, Mode=OneWay}" />
<ContentPresenter
Grid.Column="2"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Content="{x:Bind TitleContent, Mode=OneWay}" />
</Grid>
<Rectangle
x:Name="Divider"
Grid.Row="1"
Height="1"
HorizontalAlignment="Stretch"
Fill="{ThemeResource DividerStrokeColorDefaultBrush}"
Visibility="{x:Bind DividerVisibility, Mode=OneWay}" />
<ContentPresenter
Grid.Row="2"
Margin="{x:Bind Padding, Mode=OneWay}"
HorizontalAlignment="{x:Bind HorizontalContentAlignment, Mode=OneWay}"
VerticalAlignment="{x:Bind VerticalContentAlignment, Mode=OneWay}"
Content="{x:Bind Content, Mode=OneWay}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="TitleGridVisibilityStates">
<VisualState x:Name="TitleGridVisible" />
<VisualState x:Name="TitleGridCollapsed">
<VisualState.Setters>
<Setter Target="TitleGrid.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>

View File

@@ -0,0 +1,73 @@
// 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.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
public sealed partial class Card : UserControl
{
public static readonly DependencyProperty TitleContentProperty = DependencyProperty.Register(nameof(TitleContent), typeof(object), typeof(Card), new PropertyMetadata(defaultValue: null, OnVisualPropertyChanged));
public object TitleContent
{
get => (object)GetValue(TitleContentProperty);
set => SetValue(TitleContentProperty, value);
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(nameof(Title), typeof(string), typeof(Card), new PropertyMetadata(defaultValue: null, OnVisualPropertyChanged));
public string Title
{
get => (string)GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public static new readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(object), typeof(Card), new PropertyMetadata(defaultValue: null));
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1061:Do not hide base class methods", Justification = "We need to hide the base class method")]
public new object Content
{
get => (object)GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty DividerVisibilityProperty = DependencyProperty.Register(nameof(DividerVisibility), typeof(Visibility), typeof(Card), new PropertyMetadata(defaultValue: null));
public Visibility DividerVisibility
{
get => (Visibility)GetValue(DividerVisibilityProperty);
set => SetValue(DividerVisibilityProperty, value);
}
public Card()
{
InitializeComponent();
SetVisualStates();
}
private static void OnVisualPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is Card card)
{
card.SetVisualStates();
}
}
private void SetVisualStates()
{
if (string.IsNullOrEmpty(Title) && TitleContent == null)
{
VisualStateManager.GoToState(this, "TitleGridCollapsed", true);
DividerVisibility = Visibility.Collapsed;
}
else
{
VisualStateManager.GoToState(this, "TitleGridVisible", true);
DividerVisibility = Visibility.Visible;
}
}
}
}

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="Microsoft.PowerToys.Settings.UI.Controls.CheckUpdateControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal">
<Button
Click="SWVersionButtonClicked"
Style="{StaticResource SubtleButtonStyle}"
Visibility="{x:Bind UpdateAvailable, Mode=OneWay}">
<Grid ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border
Width="20"
Height="20"
CornerRadius="10">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0.5,1">
<GradientStop Offset="0.0" Color="#239DE0" />
<GradientStop Offset="1.0" Color="#037CD6" />
</LinearGradientBrush>
</Border.Background>
<FontIcon
AutomationProperties.AccessibilityView="Raw"
FontSize="11"
Foreground="White"
Glyph="&#xE895;" />
</Border>
<StackPanel Grid.Column="1" Orientation="Vertical">
<TextBlock x:Uid="UpdateAvailableTextBlock" FontWeight="SemiBold" />
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}">
<Run x:Uid="GeneralVersion" />
<Run Text="{x:Bind UpdateSettingsConfig.NewVersion, Mode=OneWay}" />
</TextBlock>
</StackPanel>
</Grid>
</Button>
<Grid
Padding="0,0,4,0"
VerticalAlignment="Center"
ColumnSpacing="16"
Visibility="{x:Bind UpdateAvailable, Converter={StaticResource ReverseBoolToVisibilityConverter}, Mode=OneWay}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border
Width="20"
Height="20"
CornerRadius="10">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0.5,1">
<GradientStop Offset="0.0" Color="#6FB538" />
<GradientStop Offset="1.0" Color="#397A24" />
</LinearGradientBrush>
</Border.Background>
<FontIcon
AutomationProperties.AccessibilityView="Raw"
FontSize="11"
Foreground="White"
Glyph="&#xE73E;" />
</Border>
<StackPanel Grid.Column="1" Orientation="Vertical">
<TextBlock x:Uid="YoureUpToDate" FontWeight="SemiBold" />
<TextBlock Foreground="{ThemeResource TextFillColorSecondaryBrush}" Style="{StaticResource CaptionTextBlockStyle}">
<Run x:Uid="General_VersionLastChecked" />
<Run Text="{x:Bind UpdateSettingsConfig.LastCheckedDateLocalized, Mode=OneWay}" />
</TextBlock>
</StackPanel>
</Grid>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,30 @@
// 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.Library;
using Microsoft.PowerToys.Settings.UI.Services;
using Microsoft.PowerToys.Settings.UI.Views;
using Microsoft.UI.Xaml.Controls;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
public sealed partial class CheckUpdateControl : UserControl
{
public bool UpdateAvailable { get; set; }
public UpdatingSettings UpdateSettingsConfig { get; set; }
public CheckUpdateControl()
{
InitializeComponent();
UpdateSettingsConfig = UpdatingSettings.LoadSettings();
UpdateAvailable = UpdateSettingsConfig != null && (UpdateSettingsConfig.State == UpdatingSettings.UpdatingState.ReadyToInstall || UpdateSettingsConfig.State == UpdatingSettings.UpdatingState.ReadyToDownload);
}
private void SWVersionButtonClicked(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
NavigationService.Navigate(typeof(GeneralPage));
}
}
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<UserControl
x:Class="Microsoft.PowerToys.Settings.UI.Controls.ShortcutConflictControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Button Click="ShortcutConflictBtn_Click" Style="{StaticResource SubtleButtonStyle}">
<Grid ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<FontIcon
AutomationProperties.AccessibilityView="Raw"
FontSize="20"
Foreground="{ThemeResource SystemFillColorCriticalBrush}"
Glyph="&#xE814;" />
<StackPanel Grid.Column="1" Orientation="Vertical">
<TextBlock FontWeight="SemiBold" Text="Shortcut conflicts" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="2 conflicts found" />
</StackPanel>
</Grid>
</Button>
</Grid>
</UserControl>

View File

@@ -0,0 +1,40 @@
// 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.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Windows.Foundation.Collections;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
public sealed partial class ShortcutConflictControl : UserControl
{
public ShortcutConflictControl()
{
InitializeComponent();
GetShortcutConflicts();
}
private void GetShortcutConflicts()
{
// TO DO: Implement the logic to retrieve and display shortcut conflicts. Make sure to Collapse this control if not conflicts are found.
}
private void ShortcutConflictBtn_Click(object sender, RoutedEventArgs e)
{
// TO DO: Handle the button click event to show the shortcut conflicts window.
}
}
}

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Controls"
xmlns:ui="using:CommunityToolkit.WinUI">
<Style BasedOn="{StaticResource DefaultKeyCharPresenterStyle}" TargetType="local:KeyCharPresenter" />
<Style x:Key="DefaultKeyCharPresenterStyle" TargetType="local:KeyCharPresenter">
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KeyCharPresenter">
<Grid Height="{TemplateBinding FontSize}">
<TextBlock
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
Text="{TemplateBinding Content}"
TextLineBounds="Tight" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="WindowsKeyCharPresenterStyle"
BasedOn="{StaticResource DefaultKeyCharPresenterStyle}"
TargetType="local:KeyCharPresenter">
<!-- Scale to visually align the height of the Windows logo and text -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KeyCharPresenter">
<Grid Height="{TemplateBinding FontSize}">
<Viewbox>
<PathIcon Data="M9 20H0V11H9V20ZM20 20H11V11H20V20ZM9 9H0V0H9V9ZM20 9H11V0H20V9Z" />
</Viewbox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="GlyphKeyCharPresenterStyle"
BasedOn="{StaticResource DefaultKeyCharPresenterStyle}"
TargetType="local:KeyCharPresenter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KeyCharPresenter">
<Grid>
<Viewbox>
<FontIcon
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
Glyph="{TemplateBinding Content}" />
</Viewbox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

View File

@@ -0,0 +1,32 @@
// 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.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Documents;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
namespace Microsoft.PowerToys.Settings.UI.Controls;
public sealed partial class KeyCharPresenter : Control
{
public KeyCharPresenter()
{
DefaultStyleKey = typeof(KeyCharPresenter);
}
public object Content
{
get => (object)GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(object), typeof(KeyCharPresenter), new PropertyMetadata(default(string)));
}

View File

@@ -1,191 +0,0 @@
// 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.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Markup;
using Windows.System;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
[TemplatePart(Name = KeyPresenter, Type = typeof(ContentPresenter))]
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Default", GroupName = "StateStates")]
[TemplateVisualState(Name = "Error", GroupName = "StateStates")]
public sealed partial class KeyVisual : Control
{
private const string KeyPresenter = "KeyPresenter";
private KeyVisual _keyVisual;
private ContentPresenter _keyPresenter;
public object Content
{
get => (object)GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(KeyVisual), new PropertyMetadata(default(string), OnContentChanged));
public VisualType VisualType
{
get => (VisualType)GetValue(VisualTypeProperty);
set => SetValue(VisualTypeProperty, value);
}
public static readonly DependencyProperty VisualTypeProperty = DependencyProperty.Register("VisualType", typeof(VisualType), typeof(KeyVisual), new PropertyMetadata(default(VisualType), OnSizeChanged));
public bool IsError
{
get => (bool)GetValue(IsErrorProperty);
set => SetValue(IsErrorProperty, value);
}
public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register("IsError", typeof(bool), typeof(KeyVisual), new PropertyMetadata(false, OnIsErrorChanged));
public KeyVisual()
{
this.DefaultStyleKey = typeof(KeyVisual);
this.Style = GetStyleSize("TextKeyVisualStyle");
}
protected override void OnApplyTemplate()
{
IsEnabledChanged -= KeyVisual_IsEnabledChanged;
_keyVisual = (KeyVisual)this;
_keyPresenter = (ContentPresenter)_keyVisual.GetTemplateChild(KeyPresenter);
Update();
SetEnabledState();
SetErrorState();
IsEnabledChanged += KeyVisual_IsEnabledChanged;
base.OnApplyTemplate();
}
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((KeyVisual)d).Update();
}
private static void OnSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((KeyVisual)d).Update();
}
private static void OnIsErrorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((KeyVisual)d).SetErrorState();
}
private void Update()
{
if (_keyVisual == null)
{
return;
}
if (_keyVisual.Content != null)
{
if (_keyVisual.Content.GetType() == typeof(string))
{
_keyVisual.Style = GetStyleSize("TextKeyVisualStyle");
_keyVisual._keyPresenter.Content = _keyVisual.Content;
}
else
{
_keyVisual.Style = GetStyleSize("IconKeyVisualStyle");
switch ((int)_keyVisual.Content)
{
/* We can enable other glyphs in the future
case 13: // The Enter key or button.
_keyVisual._keyPresenter.Content = "\uE751"; break;
case 8: // The Back key or button.
_keyVisual._keyPresenter.Content = "\uE750"; break;
case 16: // The right Shift key or button.
case 160: // The left Shift key or button.
case 161: // The Shift key or button.
_keyVisual._keyPresenter.Content = "\uE752"; break; */
case 38: _keyVisual._keyPresenter.Content = "\uE0E4"; break; // The Up Arrow key or button.
case 40: _keyVisual._keyPresenter.Content = "\uE0E5"; break; // The Down Arrow key or button.
case 37: _keyVisual._keyPresenter.Content = "\uE0E2"; break; // The Left Arrow key or button.
case 39: _keyVisual._keyPresenter.Content = "\uE0E3"; break; // The Right Arrow key or button.
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=""M683 1229H0V546h683v683zm819 0H819V546h683v683zm-819 819H0v-683h683v683zm819 0H819v-683h683v683z"" />") as PathIcon;
Viewbox winIconContainer = new Viewbox();
winIconContainer.Child = winIcon;
winIconContainer.HorizontalAlignment = HorizontalAlignment.Center;
winIconContainer.VerticalAlignment = VerticalAlignment.Center;
double iconDimensions = GetIconSize();
winIconContainer.Height = iconDimensions;
winIconContainer.Width = iconDimensions;
_keyVisual._keyPresenter.Content = winIconContainer;
break;
default: _keyVisual._keyPresenter.Content = ((VirtualKey)_keyVisual.Content).ToString(); break;
}
}
}
}
public Style GetStyleSize(string styleName)
{
if (VisualType == VisualType.Small)
{
return (Style)App.Current.Resources["Small" + styleName];
}
else if (VisualType == VisualType.SmallOutline)
{
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];
}
}
public double GetIconSize()
{
if (VisualType == VisualType.Small || VisualType == VisualType.SmallOutline)
{
return (double)App.Current.Resources["SmallIconSize"];
}
else
{
return (double)App.Current.Resources["DefaultIconSize"];
}
}
private void KeyVisual_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
SetEnabledState();
}
private void SetErrorState()
{
VisualStateManager.GoToState(this, IsError ? "Error" : "Default", true);
}
private void SetEnabledState()
{
VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
}
}
public enum VisualType
{
Small,
SmallOutline,
TextOnly,
Large,
}
}

View File

@@ -1,66 +1,70 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PowerToys.Settings.UI.Controls">
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Controls">
<x:Double x:Key="DefaultIconSize">16</x:Double>
<x:Double x:Key="SmallIconSize">12</x:Double>
<Style x:Key="DefaultTextKeyVisualStyle" TargetType="controls:KeyVisual">
<Setter Property="MinWidth" Value="56" />
<Setter Property="MinHeight" Value="48" />
<Setter Property="Background" Value="{ThemeResource AccentButtonBackground}" />
<Setter Property="Foreground" Value="{ThemeResource AccentButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource AccentButtonBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}" />
<Setter Property="Padding" Value="16,8,16,8" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Style BasedOn="{StaticResource DefaultKeyVisualStyle}" TargetType="local:KeyVisual" />
<Style x:Key="DefaultKeyVisualStyle" TargetType="local:KeyVisual">
<Setter Property="MinWidth" Value="16" />
<Setter Property="AutomationProperties.AccessibilityView" Value="Raw" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="MinHeight" Value="16" />
<Setter Property="Background" Value="{ThemeResource SubtleFillColorTransparentBrush}" />
<Setter Property="Foreground" Value="{ThemeResource TextFillColorPrimaryBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource ControlStrokeColorDefaultBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Padding" Value="4,4,4,4" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="14" />
<Setter Property="CornerRadius" Value="2" />
<Setter Property="BackgroundSizing" Value="InnerBorderEdge" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls: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>
<ControlTemplate TargetType="local:KeyVisual">
<Grid
x:Name="KeyHolder"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid.BackgroundTransition>
<BrushTransition Duration="0:0:0.083" />
</Grid.BackgroundTransition>
<local:KeyCharPresenter
x:Name="KeyPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Content}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="ContentHolder.Fill" Value="{ThemeResource AccentButtonBackgroundDisabled}" />
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource AccentButtonForegroundDisabled}" />
<Setter Target="ContentHolder.Stroke" Value="{ThemeResource AccentButtonBorderBrushDisabled}" />
<!--<Setter Target="ContentHolder.StrokeThickness" Value="{TemplateBinding BorderThickness}" />-->
<Setter Target="KeyHolder.Background" Value="{ThemeResource SubtleFillColorTransparentBrush}" />
<Setter Target="KeyHolder.BorderBrush" Value="{ThemeResource CardStrokeColorDefaultSolidBrush}" />
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource ControlStrokeColorDefaultBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="StateStates">
<VisualState x:Name="Default" />
<VisualState x:Name="Error">
<VisualState x:Name="Invalid">
<VisualState.Setters>
<Setter Target="ContentHolder.Fill" Value="{ThemeResource InfoBarErrorSeverityBackgroundBrush}" />
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource InfoBarErrorSeverityIconBackground}" />
<Setter Target="ContentHolder.Stroke" Value="{ThemeResource InfoBarErrorSeverityIconBackground}" />
<Setter Target="ContentHolder.StrokeThickness" Value="2" />
<Setter Target="KeyHolder.Background" Value="{ThemeResource SystemFillColorCriticalBackgroundBrush}" />
<Setter Target="KeyHolder.BorderBrush" Value="{ThemeResource SystemFillColorCriticalBrush}" />
<Setter Target="KeyHolder.BorderThickness" Value="2" />
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource SystemFillColorCriticalBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
@@ -72,103 +76,116 @@
</Style>
<Style
x:Key="SmallTextKeyVisualStyle"
BasedOn="{StaticResource DefaultTextKeyVisualStyle}"
TargetType="controls:KeyVisual">
<Setter Property="MinWidth" Value="40" />
<Setter Property="Height" Value="36" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Padding" Value="12,0,12,2" />
<Setter Property="FontSize" Value="14" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
x:Key="SubtleKeyVisualStyle"
BasedOn="{StaticResource DefaultKeyVisualStyle}"
TargetType="local:KeyVisual">
<Setter Property="Background" Value="{ThemeResource SubtleFillColorTransparentBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource SubtleFillColorTransparentBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KeyVisual">
<Grid
x:Name="KeyHolder"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid.BackgroundTransition>
<BrushTransition Duration="0:0:0.083" />
</Grid.BackgroundTransition>
<local:KeyCharPresenter
x:Name="KeyPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Content}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Invalid">
<VisualState.Setters>
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource SystemFillColorCriticalBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="SmallOutlineTextKeyVisualStyle"
BasedOn="{StaticResource DefaultTextKeyVisualStyle}"
TargetType="controls:KeyVisual">
<Setter Property="MinWidth" Value="40" />
<Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
<Setter Property="Height" Value="36" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Padding" Value="8,0,8,2" />
<Setter Property="FontSize" Value="13" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
x:Key="AccentKeyVisualStyle"
BasedOn="{StaticResource DefaultKeyVisualStyle}"
TargetType="local:KeyVisual">
<Setter Property="Background" Value="{ThemeResource AccentFillColorDefaultBrush}" />
<Setter Property="Foreground" Value="{ThemeResource TextOnAccentFillColorPrimaryBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource AccentControlElevationBorderBrush}" />
<Setter Property="BackgroundSizing" Value="OuterBorderEdge" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:KeyVisual">
<Grid
x:Name="KeyHolder"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
AutomationProperties.AccessibilityView="Raw"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid.BackgroundTransition>
<BrushTransition Duration="0:0:0.083" />
</Grid.BackgroundTransition>
<local:KeyCharPresenter
x:Name="KeyPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
FontSize="{TemplateBinding FontSize}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Target="KeyHolder.Background" Value="{ThemeResource AccentButtonBackgroundDisabled}" />
<Setter Target="KeyHolder.BorderBrush" Value="{ThemeResource AccentButtonBorderBrushDisabled}" />
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource AccentButtonForegroundDisabled}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Invalid">
<VisualState.Setters>
<Setter Target="KeyHolder.Background" Value="{ThemeResource SystemFillColorCriticalBackgroundBrush}" />
<Setter Target="KeyHolder.BorderBrush" Value="{ThemeResource SystemFillColorCriticalBrush}" />
<Setter Target="KeyHolder.BorderThickness" Value="2" />
<Setter Target="KeyPresenter.Foreground" Value="{ThemeResource SystemFillColorCriticalBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="DefaultIconKeyVisualStyle"
BasedOn="{StaticResource DefaultTextKeyVisualStyle}"
TargetType="controls:KeyVisual">
<Setter Property="MinWidth" Value="56" />
<Setter Property="MinHeight" Value="48" />
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
<Setter Property="Padding" Value="16,8,16,8" />
<Setter Property="FontSize" Value="14" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style
x:Key="SmallIconKeyVisualStyle"
BasedOn="{StaticResource DefaultTextKeyVisualStyle}"
TargetType="controls:KeyVisual">
<Setter Property="MinWidth" Value="40" />
<Setter Property="Height" Value="36" />
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="Padding" Value="0" />
<Setter Property="FontSize" Value="10" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style
x:Key="SmallOutlineIconKeyVisualStyle"
BasedOn="{StaticResource DefaultTextKeyVisualStyle}"
TargetType="controls:KeyVisual">
<Setter Property="MinWidth" Value="40" />
<Setter Property="Background" Value="{ThemeResource ButtonBackground}" />
<Setter Property="Foreground" Value="{ThemeResource ButtonForeground}" />
<Setter Property="BorderBrush" Value="{ThemeResource ButtonBorderBrush}" />
<Setter Property="FontFamily" Value="{ThemeResource SymbolThemeFontFamily}" />
<Setter Property="Height" Value="36" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="Padding" Value="0" />
<Setter Property="FontSize" Value="9" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style
x:Key="OnlyTextKeyVisualStyle"
BasedOn="{StaticResource DefaultTextKeyVisualStyle}"
TargetType="controls: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="controls: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>
</ResourceDictionary>

View File

@@ -0,0 +1,166 @@
// 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.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Windows.System;
namespace Microsoft.PowerToys.Settings.UI.Controls
{
[TemplatePart(Name = KeyPresenter, Type = typeof(KeyCharPresenter))]
[TemplateVisualState(Name = NormalState, GroupName = "CommonStates")]
[TemplateVisualState(Name = DisabledState, GroupName = "CommonStates")]
[TemplateVisualState(Name = InvalidState, GroupName = "CommonStates")]
public sealed partial class KeyVisual : Control
{
private const string KeyPresenter = "KeyPresenter";
private const string NormalState = "Normal";
private const string DisabledState = "Disabled";
private const string InvalidState = "Invalid";
private KeyCharPresenter _keyPresenter;
public object Content
{
get => (object)GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public static readonly DependencyProperty ContentProperty = DependencyProperty.Register(nameof(Content), typeof(object), typeof(KeyVisual), new PropertyMetadata(default(string), OnContentChanged));
public bool IsInvalid
{
get => (bool)GetValue(IsInvalidProperty);
set => SetValue(IsInvalidProperty, value);
}
public static readonly DependencyProperty IsInvalidProperty = DependencyProperty.Register(nameof(IsInvalid), typeof(bool), typeof(KeyVisual), new PropertyMetadata(false, OnIsInvalidChanged));
public bool RenderKeyAsGlyph
{
get => (bool)GetValue(RenderKeyAsGlyphProperty);
set => SetValue(RenderKeyAsGlyphProperty, value);
}
public static readonly DependencyProperty RenderKeyAsGlyphProperty = DependencyProperty.Register(nameof(RenderKeyAsGlyph), typeof(bool), typeof(KeyVisual), new PropertyMetadata(false, OnContentChanged));
public KeyVisual()
{
this.DefaultStyleKey = typeof(KeyVisual);
}
protected override void OnApplyTemplate()
{
IsEnabledChanged -= KeyVisual_IsEnabledChanged;
_keyPresenter = (KeyCharPresenter)this.GetTemplateChild(KeyPresenter);
Update();
SetVisualStates();
IsEnabledChanged += KeyVisual_IsEnabledChanged;
base.OnApplyTemplate();
}
private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((KeyVisual)d).SetVisualStates();
}
private static void OnIsInvalidChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((KeyVisual)d).SetVisualStates();
}
private void SetVisualStates()
{
if (this != null)
{
if (IsInvalid)
{
VisualStateManager.GoToState(this, InvalidState, true);
}
else if (!IsEnabled)
{
VisualStateManager.GoToState(this, DisabledState, true);
}
else
{
VisualStateManager.GoToState(this, NormalState, true);
}
}
}
private void Update()
{
if (Content == null)
{
return;
}
if (Content is string)
{
_keyPresenter.Style = (Style)Application.Current.Resources["DefaultKeyCharPresenterStyle"];
return;
}
if (Content is int keyCode)
{
VirtualKey virtualKey = (VirtualKey)keyCode;
switch (virtualKey)
{
case VirtualKey.Enter:
SetGlyphOrText("\uE751", virtualKey);
break;
case VirtualKey.Back:
SetGlyphOrText("\uE750", virtualKey);
break;
case VirtualKey.Shift:
case (VirtualKey)160: // Left Shift
case (VirtualKey)161: // Right Shift
SetGlyphOrText("\uE752", virtualKey);
break;
case VirtualKey.Up:
_keyPresenter.Content = "\uE0E4";
break;
case VirtualKey.Down:
_keyPresenter.Content = "\uE0E5";
break;
case VirtualKey.Left:
_keyPresenter.Content = "\uE0E2";
break;
case VirtualKey.Right:
_keyPresenter.Content = "\uE0E3";
break;
case VirtualKey.LeftWindows:
case VirtualKey.RightWindows:
_keyPresenter.Style = (Style)Application.Current.Resources["WindowsKeyCharPresenterStyle"];
break;
}
}
}
private void SetGlyphOrText(string glyph, VirtualKey key)
{
if (RenderKeyAsGlyph)
{
_keyPresenter.Content = glyph;
_keyPresenter.Style = (Style)Application.Current.Resources["GlyphKeyCharPresenterStyle"];
}
else
{
_keyPresenter.Content = key.ToString();
_keyPresenter.Style = (Style)Application.Current.Resources["DefaultKeyCharPresenterStyle"];
}
}
private void KeyVisual_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
SetVisualStates();
}
}
}

View File

@@ -31,8 +31,7 @@
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Content="{Binding}"
IsTabStop="False"
VisualType="SmallOutline" />
IsTabStop="False" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

View File

@@ -6,20 +6,12 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:tkconverters="using:CommunityToolkit.WinUI.Converters"
Loaded="UserControl_Loaded"
mc:Ignorable="d">
<UserControl.Resources>
<x:Double x:Key="PageMaxWidth">1000</x:Double>
<x:Double x:Key="PageHeaderMaxWidth">1020</x:Double>
<tkconverters:DoubleToVisibilityConverter
x:Name="doubleToVisibilityConverter"
FalseValue="Collapsed"
GreaterThan="0"
TrueValue="Visible" />
</UserControl.Resources>
<Grid Padding="20,0,0,0" RowSpacing="24">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@@ -62,7 +54,7 @@
MaxWidth="160"
HorizontalAlignment="Left"
VerticalAlignment="Top"
CornerRadius="4">
CornerRadius="{StaticResource OverlayCornerRadius}">
<Image AutomationProperties.AccessibilityView="Raw">
<Image.Source>
<BitmapImage UriSource="{x:Bind ModuleImageSource}" />
@@ -113,7 +105,7 @@
MaxWidth="{StaticResource PageMaxWidth}"
AutomationProperties.Name="{x:Bind SecondaryLinksHeader}"
Orientation="Vertical"
Visibility="{x:Bind SecondaryLinks.Count, Converter={StaticResource doubleToVisibilityConverter}}">
Visibility="{x:Bind SecondaryLinks.Count, Converter={StaticResource DoubleToVisibilityConverter}}">
<TextBlock
Margin="2,8,0,0"
AutomationProperties.HeadingLevel="Level2"

View File

@@ -11,43 +11,74 @@
mc:Ignorable="d">
<Grid HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal">
<Button
x:Name="EditButton"
Padding="0"
Click="OpenDialogButton_Click"
CornerRadius="8">
<Button
x:Name="EditButton"
Padding="0"
HorizontalAlignment="Right"
Click="OpenDialogButton_Click"
Style="{StaticResource SubtleButtonStyle}">
<StackPanel Orientation="Horizontal" Spacing="8">
<ItemsControl
x:Name="PreviewKeysControl"
Margin="2"
VerticalAlignment="Center"
IsEnabled="{Binding ElementName=EditButton, Path=IsEnabled}"
IsTabStop="False"
Visibility="Collapsed">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:KeyVisual
Padding="12,8,12,8"
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Content="{Binding}"
CornerRadius="{StaticResource ControlCornerRadius}"
FontWeight="SemiBold"
IsTabStop="False"
Style="{StaticResource AccentKeyVisualStyle}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel
Margin="12,6,12,6"
x:Name="PlaceholderPanel"
Padding="8,4"
BorderThickness="1"
CornerRadius="{StaticResource ControlCornerRadius}"
Orientation="Horizontal"
Spacing="16">
<ItemsControl
x:Name="PreviewKeysControl"
Spacing="8">
<!--<FontIcon
AutomationProperties.AccessibilityView="Raw"
FontSize="12"
Glyph="&#xEDA7;" />-->
<TextBlock
x:Uid="ConfigureShortcutText"
VerticalAlignment="Center"
IsEnabled="{Binding ElementName=EditButton, Path=IsEnabled}"
IsTabStop="False">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="4" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:KeyVisual
VerticalAlignment="Center"
AutomationProperties.AccessibilityView="Raw"
Content="{Binding}"
IsTabStop="False"
VisualType="Small" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<FontIcon
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="16"
Glyph="&#xE70F;" />
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
</Button>
</StackPanel>
<FontIcon
Margin="0,0,4,0"
AutomationProperties.Name=""
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="14"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Glyph="&#xE70F;" />
</StackPanel>
</Button>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Configured">
<VisualState.Setters>
<Setter Target="PlaceholderPanel.Visibility" Value="Collapsed" />
<Setter Target="PreviewKeysControl.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</UserControl>

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System;
using CommunityToolkit.WinUI;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
@@ -11,6 +10,7 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Automation;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.Windows.ApplicationModel.Resources;
using Windows.System;
namespace Microsoft.PowerToys.Settings.UI.Controls
@@ -36,6 +36,8 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
public static readonly DependencyProperty AllowDisableProperty = DependencyProperty.Register("AllowDisable", typeof(bool), typeof(ShortcutControl), new PropertyMetadata(false, OnAllowDisableChanged));
private static ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
private static void OnAllowDisableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var me = d as ShortcutControl;
@@ -50,8 +52,6 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
return;
}
var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
var newValue = (bool)(e?.NewValue ?? false);
var text = newValue ? resourceLoader.GetString("Activation_Shortcut_With_Disable_Description") : resourceLoader.GetString("Activation_Shortcut_Description");
@@ -103,8 +103,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
{
hotkeySettings = value;
SetValue(HotkeySettingsProperty, value);
PreviewKeysControl.ItemsSource = HotkeySettings.GetKeysList();
AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString());
SetKeys();
c.Keys = HotkeySettings.GetKeysList();
}
}
@@ -118,8 +117,6 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
this.Unloaded += ShortcutControl_Unloaded;
this.Loaded += ShortcutControl_Loaded;
var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;
// We create the Dialog in C# because doing it in XAML is giving WinUI/XAML Island bugs when using dark theme.
shortcutDialog = new ContentDialog
{
@@ -433,11 +430,9 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
hotkeySettings = null;
SetValue(HotkeySettingsProperty, hotkeySettings);
PreviewKeysControl.ItemsSource = HotkeySettings.GetKeysList();
SetKeys();
lastValidSettings = hotkeySettings;
AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString());
shortcutDialog.Hide();
}
@@ -448,8 +443,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
HotkeySettings = lastValidSettings with { };
}
PreviewKeysControl.ItemsSource = hotkeySettings.GetKeysList();
AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString());
SetKeys();
shortcutDialog.Hide();
}
@@ -462,9 +456,7 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
var empty = new HotkeySettings();
HotkeySettings = empty;
PreviewKeysControl.ItemsSource = HotkeySettings.GetKeysList();
AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString());
SetKeys();
shortcutDialog.Hide();
}
@@ -525,5 +517,22 @@ namespace Microsoft.PowerToys.Settings.UI.Controls
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
private void SetKeys()
{
var keys = HotkeySettings.GetKeysList();
if (keys != null && keys.Count > 0)
{
VisualStateManager.GoToState(this, "Configured", true);
PreviewKeysControl.ItemsSource = keys;
AutomationProperties.SetHelpText(EditButton, HotkeySettings.ToString());
}
else
{
VisualStateManager.GoToState(this, "Normal", true);
AutomationProperties.SetHelpText(EditButton, resourceLoader.GetString("ConfigureShortcut"));
}
}
}
}

View File

@@ -14,9 +14,6 @@
<RowDefinition MinHeight="110" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" />
<ItemsControl
x:Name="KeysControl"
Grid.Row="1"
@@ -34,12 +31,15 @@
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:KeyVisual
Height="56"
Padding="20,16"
AutomationProperties.AccessibilityView="Raw"
Content="{Binding}"
IsError="{Binding ElementName=ShortcutContentControl, Path=IsError, Mode=OneWay}"
CornerRadius="{StaticResource ControlCornerRadius}"
FontSize="16"
FontWeight="SemiBold"
IsInvalid="{Binding ElementName=ShortcutContentControl, Path=IsError, Mode=OneWay}"
IsTabStop="False"
VisualType="Large" />
Style="{StaticResource AccentKeyVisualStyle}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
@@ -51,14 +51,12 @@
Orientation="Vertical"
Spacing="8">
<Grid Height="62">
<InfoBar
x:Uid="InvalidShortcut"
IsClosable="False"
IsOpen="{Binding ElementName=ShortcutContentControl, Path=IsError, Mode=OneWay}"
IsTabStop="{Binding ElementName=ShortcutContentControl, Path=IsError, Mode=OneWay}"
Severity="Error" />
<InfoBar
x:Uid="WarningShortcutAltGr"
IsClosable="False"

View File

@@ -28,11 +28,11 @@
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:KeyVisual
VerticalAlignment="Center"
Padding="12,8,12,8"
AutomationProperties.AccessibilityView="Raw"
Content="{Binding}"
IsTabStop="False"
VisualType="SmallOutline" />
FontSize="12"
IsTabStop="False" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>