// 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.ComponentModel.Design; using Windows.System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Markup; 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 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(@"") 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 { 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, Large, } }