Added right key visuals and fixed some UI bugs

This commit is contained in:
Noraa Junker
2025-10-27 23:36:17 +01:00
parent f867323677
commit f537c43139
9 changed files with 152 additions and 47 deletions

View File

@@ -84,6 +84,9 @@ namespace ShortcutGuide.Converters
case "Back":
shortcutList.Add(8); // The Back key or button.
break;
case "<TASKBAR1-9>":
shortcutList.Add("Num");
break;
default:
shortcutList.Add(key); // Add other keys as strings.
break;

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.UI.Xaml.Markup;
namespace ShortcutGuide.Helpers
{
[MarkupExtensionReturnType(ReturnType = typeof(string))]
public partial class StringResourceExtension : MarkupExtension
{
public enum SpecialTreatment
{
None,
FirstCharOnly,
EverythingExceptFirstChar,
}
public string Key { get; set; } = string.Empty;
public SpecialTreatment Treatment { get; set; } = SpecialTreatment.None;
protected override object ProvideValue() => Treatment switch
{
SpecialTreatment.FirstCharOnly => ResourceLoaderInstance.ResourceLoader.GetString(Key)[0].ToString(),
SpecialTreatment.EverythingExceptFirstChar => ResourceLoaderInstance.ResourceLoader.GetString(Key)[1..],
_ => ResourceLoaderInstance.ResourceLoader.GetString(Key),
};
}
}

View File

@@ -3,10 +3,12 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ShortcutGuide.Controls"
xmlns:helpers="using:ShortcutGuide.Helpers"
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" />
@@ -32,6 +34,27 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="UnderlinedLetterKeyCharPresenterStyle"
BasedOn="{StaticResource DefaultKeyCharPresenterStyle}"
TargetType="local:KeyCharPresenter">
<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}"
TextLineBounds="Tight">
<Run Text="{helpers:StringResourceExtension Key='UnderlinedKeyChar/Text', Treatment=FirstCharOnly}" TextDecorations="Underline" /><Run Text="{helpers:StringResourceExtension Key='UnderlinedKeyChar/Text', Treatment=EverythingExceptFirstChar}"/>
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="WindowsKeyCharPresenterStyle"
BasedOn="{StaticResource DefaultKeyCharPresenterStyle}"

View File

@@ -6,12 +6,14 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Windows.Markup;
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;
using ShortcutGuide.Helpers;
namespace ShortcutGuide.Controls;

View File

@@ -98,20 +98,30 @@ namespace ShortcutGuide.Controls
if (Content is string key)
{
switch (key)
SetGlyphOrText(key switch
{
case "<Copilot>":
_keyPresenter.Style = (Style)Application.Current.Resources["CopilotKeyCharPresenterStyle"];
break;
"<TASKBAR1-9>" => "Num",
"<Left>" => "\uE0E2",
"<Right>" => "\uE0E3",
"<Up>" => "\uE0E4",
"<Down>" => "\uE0E5",
"<ArrowUD>" => "\uE0E4\uE0E5",
"<ArrowLR>" => "\uE0E2\uE0E3",
"<Arrow>" => "\uE0E2\uE0E3\uE0E4\uE0E5",
"<Enter>" => "\uE751",
"<Backspace>" => "\uE750",
"<Escape>" => "Esc",
string s when s.StartsWith('<') => s.Trim('<', '>'),
_ => key,
});
case "<Office>":
_keyPresenter.Style = (Style)Application.Current.Resources["OfficeKeyCharPresenterStyle"];
break;
default:
_keyPresenter.Style = (Style)Application.Current.Resources["DefaultKeyCharPresenterStyle"];
break;
}
_keyPresenter.Style = key switch
{
"<Copilot>" => (Style)Application.Current.Resources["CopilotKeyCharPresenterStyle"],
"<Office>" => (Style)Application.Current.Resources["OfficeKeyCharPresenterStyle"],
"<Underlined letter>" => (Style)Application.Current.Resources["UnderlinedLetterKeyCharPresenterStyle"],
_ => _keyPresenter.Style,
};
return;
}
@@ -122,33 +132,33 @@ namespace ShortcutGuide.Controls
switch (virtualKey)
{
case VirtualKey.Enter:
SetGlyphOrText("\uE751", virtualKey);
SetGlyphOrText("\uE751");
break;
case VirtualKey.Back:
SetGlyphOrText("\uE750", virtualKey);
SetGlyphOrText("\uE750");
break;
case VirtualKey.Shift:
case (VirtualKey)160: // Left Shift
case (VirtualKey)161: // Right Shift
SetGlyphOrText("\uE752", virtualKey);
SetGlyphOrText("\uE752");
break;
case VirtualKey.Up:
_keyPresenter.Content = "\uE0E4";
SetGlyphOrText("\uE0E4");
break;
case VirtualKey.Down:
_keyPresenter.Content = "\uE0E5";
SetGlyphOrText("\uE0E5");
break;
case VirtualKey.Left:
_keyPresenter.Content = "\uE0E2";
SetGlyphOrText("\uE0E2");
break;
case VirtualKey.Right:
_keyPresenter.Content = "\uE0E3";
SetGlyphOrText("\uE0E3");
break;
case VirtualKey.LeftWindows:
@@ -156,8 +166,7 @@ namespace ShortcutGuide.Controls
_keyPresenter.Style = (Style)Application.Current.Resources["WindowsKeyCharPresenterStyle"];
break;
default: // For all other keys, we will use the key name.
_keyPresenter.Content = virtualKey.ToString();
_keyPresenter.Style = (Style)Application.Current.Resources["DefaultKeyCharPresenterStyle"];
SetGlyphOrText(virtualKey.ToString());
break;
}
@@ -167,18 +176,14 @@ namespace ShortcutGuide.Controls
Visibility = Visibility.Collapsed;
}
private void SetGlyphOrText(string glyph, VirtualKey key)
private void SetGlyphOrText(string glyphOrText)
{
if (RenderKeyAsGlyph)
{
_keyPresenter.Content = glyph;
_keyPresenter.Style = (Style)Application.Current.Resources["GlyphKeyCharPresenterStyle"];
}
else
{
_keyPresenter.Content = key.ToString();
_keyPresenter.Style = (Style)Application.Current.Resources["DefaultKeyCharPresenterStyle"];
}
RenderKeyAsGlyph = ((glyphOrText[0] >> 12) & 0xF) is 0xE or 0xF;
_keyPresenter.Content = glyphOrText;
_keyPresenter.Style = RenderKeyAsGlyph
? (Style)Application.Current.Resources["GlyphKeyCharPresenterStyle"]
: (Style)Application.Current.Resources["DefaultKeyCharPresenterStyle"];
}
private void KeyVisual_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)

View File

@@ -23,7 +23,8 @@
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TitleBar x:Uid="TitleBar">
<TitleBar.Content>
<!--<TitleBar.Content>
<AutoSuggestBox
x:Name="SearchBox"
x:Uid="SearchBox"
@@ -41,12 +42,12 @@
<DataTemplate x:DataType="models:ShortcutEntry">
<Grid>
<TextBlock Text="{x:Bind Name}" />
<!-- TO DO: Add shortcuts / description -->
TO DO: Add shortcuts / description
</Grid>
</DataTemplate>
</AutoSuggestBox.ItemTemplate>
</AutoSuggestBox>
</TitleBar.Content>
</TitleBar.Content>-->
</TitleBar>
<NavigationView
@@ -54,11 +55,19 @@
Grid.Row="1"
IsBackButtonVisible="Collapsed"
IsSettingsVisible="False"
IsPaneToggleButtonVisible="False"
SelectionChanged="WindowSelector_SelectionChanged"
Style="{StaticResource RailNavigationViewStyle}">
<NavigationView.MenuItems />
<NavigationView.FooterMenuItems>
<!-- TO DO: SOME WEIRD VISUAL GLITCH WITH THE ICON BEING CLIPPED -->
<!-- If footer only has one item, a visual bug can occur. This fake settings button will have set height to zero as soon as the content is loaded -->
<NavigationViewItem
x:Name="FakeSettingsButton"
Content="Settings"
Icon="Setting"
SelectsOnInvoked="False"
Tag="Settings"
Tapped="Settings_Tapped" />
<NavigationViewItem
Content="Settings"
Icon="Setting"
@@ -66,21 +75,22 @@
Tag="Settings"
Tapped="Settings_Tapped" />
</NavigationView.FooterMenuItems>
<NavigationView
<NavigationView.Content>
<NavigationView
x:Name="SubNav"
IsBackButtonVisible="Collapsed"
IsSettingsVisible="False"
PaneDisplayMode="Top"
SelectionChanged="SubNav_SelectionChanged">
<Frame
<Frame
x:Name="ContentFrame"
Margin="4,8,0,0"
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="8,0,0,0" />
</NavigationView>
</NavigationView>
</NavigationView.Content>
<NavigationView.Resources>
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
<SolidColorBrush x:Key="NavigationViewContentGridBorderBrush" Color="Transparent" />

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Common.UI;
using ManagedCommon;
using Microsoft.UI.Windowing;
@@ -117,6 +118,12 @@ namespace ShortcutGuide
// The code below sets the position of the window to the center of the monitor, but only if it hasn't been set before.
if (!_setPosition)
{
Content.GettingFocus += (_, _) =>
{
FakeSettingsButton.Height = 10;
FakeSettingsButton.Height = 0;
};
SetWindowPosition();
_setPosition = true;
@@ -166,10 +173,21 @@ namespace ShortcutGuide
{
var hwnd = WindowNative.GetWindowHandle(this);
Rect monitorRect = DisplayHelper.GetWorkAreaForDisplayWithWindow(hwnd);
this.MoveAndResize((int)monitorRect.X, (int)monitorRect.Y, Width, monitorRect.Height);
if (App.TaskBarWindow.AppWindow.IsVisible && App.TaskBarWindow.AppWindow.Position.X <= AppWindow.Position.X + Width)
{
MaxHeight = App.TaskBarWindow.AppWindow.Position.Y / DpiHelper.GetDPIScaleForWindow(hwnd.ToInt32());
MinHeight = MaxHeight;
Height = MaxHeight;
return;
}
this.MoveAndResize((int)monitorRect.X, (int)monitorRect.Y, Width, monitorRect.Height / DpiHelper.GetDPIScaleForWindow(hwnd.ToInt32()));
MaxHeight = monitorRect.Height / DpiHelper.GetDPIScaleForWindow(hwnd.ToInt32());
MinHeight = MaxHeight;
Height = MaxHeight;
}
private void SearchBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
/*private void SearchBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
// TO DO: should the results of this be shown on a separate results page? Or as part of the suggested items of the search box?
// The current UX is a bit weird as search is about the content that is selected on the page, vs. global search (which a search box in the title bar communicates).
@@ -193,7 +211,7 @@ namespace ShortcutGuide
private void SearchBox_KeyboardAcceleratorInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
SearchBox.Focus(FocusState.Programmatic);
}
}*/
private void WindowSelector_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
@@ -257,13 +275,15 @@ namespace ShortcutGuide
selectedPage = typeof(OverviewPage);
// We only show the taskbar button window when the overview page of Windows is selected.
if (_selectedAppName == ManifestInterpreter.GetIndexYamlFile().DefaultShellName)
if (_shortcutFile is not null && _shortcutFile.Value.Shortcuts.Any(c => c.SectionName.Contains("<TASKBAR1-9>")))
{
_taskBarWindowActivated = true;
App.TaskBarWindow.Activate();
}
}
// Set window position so that the taskbar window does not potentially clip into the main window
SetWindowPosition();
ContentFrame.Navigate(selectedPage, new ShortcutPageNavParam() { ShortcutFile = file, PageIndex = param, AppName = _selectedAppName });
}
}

View File

@@ -126,9 +126,11 @@
<TextBlock
x:Name="TaskbarHeaderTxt"
x:Uid="TaskbarHeaderTxt"
Margin="16,24,16,8"
FontWeight="SemiBold"
Text="Taskbar shortcuts" />
Margin="16,24,16,2"
FontWeight="SemiBold" />
<TextBlock
x:Uid="TaskbarDescriptionTxt"
Margin="16,2,16,12" />
<ItemsRepeater
x:Name="TaskbarShortcutsListView"
ItemTemplate="{StaticResource ShortcutItemTemplate}"

View File

@@ -197,4 +197,14 @@
<value>Shortcut Guide</value>
<comment>Shortcut refers to a keyboard shortcut</comment>
</data>
<data name="TaskbarDescriptionTxt.Text" xml:space="preserve">
<value>In combination with the number shown above the taskbar</value>
</data>
<data name="UnderlinedKeyChar.Text" xml:space="preserve">
<value>Underlined character</value>
<comment>character meaning a letter</comment>
</data>
<data name="Settings" xml:space="preserve">
<value>Settings</value>
</data>
</root>