Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Files.App/Data/Commands/HotKey/HotKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ namespace Files.App.Data.Commands
[DebuggerDisplay("{Code}")]
public readonly struct HotKey : IEquatable<HotKey>
{
private static readonly FrozenDictionary<KeyModifiers, string> modifiers = new Dictionary<KeyModifiers, string>()
public static readonly FrozenDictionary<KeyModifiers, string> modifiers = new Dictionary<KeyModifiers, string>()
{
[KeyModifiers.Menu] = GetKeyString("Menu"),
[KeyModifiers.Ctrl] = GetKeyString("Control"),
[KeyModifiers.Shift] = GetKeyString("Shift"),
[KeyModifiers.Win] = GetKeyString("Windows"),
}.ToFrozenDictionary();

private static readonly FrozenDictionary<Keys, string> keys = new Dictionary<Keys, string>()
public static readonly FrozenDictionary<Keys, string> keys = new Dictionary<Keys, string>()
{
[Keys.Enter] = GetKeyString("Enter"),
[Keys.Space] = GetKeyString("Space"),
Expand Down
7 changes: 7 additions & 0 deletions src/Files.App/Data/Items/NavigationBarSuggestionItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ public string? SupplementaryDisplay
set => SetProperty(ref _SupplementaryDisplay, value);
}

private HotKeyCollection _HotKeys = new();
public HotKeyCollection HotKeys
{
get => _HotKeys;
set => SetProperty(ref _HotKeys, value);
}

private void UpdatePrimaryDisplay()
{
if (SearchText is null || PrimaryDisplay is null)
Expand Down
42 changes: 25 additions & 17 deletions src/Files.App/UserControls/AddressToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
xmlns:extensions="using:CommunityToolkit.WinUI.UI"
xmlns:helpers="using:Files.App.Helpers"
xmlns:items="using:Files.App.Data.Items"
xmlns:keyboard="using:Files.App.UserControls.KeyboardShortcut"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:triggers="using:CommunityToolkit.WinUI.UI.Triggers"
xmlns:uc="using:Files.App.UserControls"
Expand All @@ -28,6 +29,8 @@
<converters1:BoolNegationConverter x:Key="BoolNegationConverter" />

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///UserControls/KeyboardShortcut/KeyboardShortcut.xaml" />

<ResourceDictionary>
<SolidColorBrush x:Key="ButtonBorderBrushDisabled" Color="Transparent" />
<SolidColorBrush x:Key="ButtonBackgroundDisabled" Color="Transparent" />
Expand Down Expand Up @@ -313,34 +316,39 @@
<AutoSuggestBox.ItemTemplate>
<DataTemplate x:DataType="items:NavigationBarSuggestionItem">
<StackPanel Margin="0,4">
<Grid>
<Grid ColumnSpacing="8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

<!-- Primary Display -->
<!-- This is used to display paths or command descriptions. -->
<TextBlock Grid.Column="0" Foreground="{ThemeResource TextFillColorPrimaryBrush}">
<!-- Primary Title -->
<TextBlock
x:Name="PrimaryDisplayBlock"
Grid.Column="0"
Foreground="{ThemeResource TextFillColorPrimaryBrush}"
MaxLines="1"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap">
<Run FontWeight="Normal" Text="{x:Bind PrimaryDisplayPreMatched, Mode=OneWay}" /><Run FontWeight="Bold" Text="{x:Bind PrimaryDisplayMatched, Mode=OneWay}" /><Run FontWeight="Normal" Text="{x:Bind PrimaryDisplayPostMatched, Mode=OneWay}" />
</TextBlock>

<!-- Supplementary Display -->
<!-- This is used to display command hotkeys. -->
<!-- Secondary Title -->
<TextBlock
Grid.Column="1"
x:Name="SecondaryDisplayBlock"
Grid.Column="0"
x:Load="{x:Bind SecondaryDisplay, Mode=OneWay, Converter={StaticResource NullToFalseConverter}}"
FontWeight="Normal"
Foreground="{ThemeResource TextFillColorTertiaryBrush}"
Text="{x:Bind SupplementaryDisplay, Mode=OneWay}" />
</Grid>
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind SecondaryDisplay, Mode=OneWay}" />

<!-- Secondary Display -->
<TextBlock
x:Name="SecondaryDisplayBlock"
x:Load="{x:Bind SecondaryDisplay, Mode=OneWay, Converter={StaticResource NullToFalseConverter}}"
FontWeight="Normal"
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Text="{x:Bind SecondaryDisplay, Mode=OneWay}" />
<!-- Keyboard Shortcuts -->
<keyboard:KeyboardShortcut
x:Name="RightAlignedKeyboardShortcut"
Grid.Column="1"
HotKeys="{x:Bind HotKeys, Mode=OneWay}" />

</Grid>
</StackPanel>
</DataTemplate>
</AutoSuggestBox.ItemTemplate>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace Files.App.UserControls.KeyboardShortcut
{
public sealed partial class KeyboardShortcut
{
public static readonly DependencyProperty ItemTypeProperty =
DependencyProperty.Register(
nameof(ItemType),
typeof(KeyboardShortcutItemKind),
typeof(KeyboardShortcutItem),
new PropertyMetadata(defaultValue: KeyboardShortcutItemKind.Outlined, (d, e) => ((KeyboardShortcutItem)d).OnItemTypePropertyChanged()));

public KeyboardShortcutItemKind ItemType
{
get => (KeyboardShortcutItemKind)GetValue(ItemTypeProperty);
set => SetValue(ItemTypeProperty, value);
}

public static readonly DependencyProperty SizeProperty =
DependencyProperty.Register(
nameof(Size),
typeof(KeyboardShortcutItemSize),
typeof(KeyboardShortcutItem),
new PropertyMetadata(defaultValue: KeyboardShortcutItemSize.Small, (d, e) => ((KeyboardShortcutItem)d).OnSizePropertyChanged()));

public KeyboardShortcutItemSize Size
{
get => (KeyboardShortcutItemSize)GetValue(SizeProperty);
set => SetValue(SizeProperty, value);
}

public static readonly DependencyProperty HotKeysProperty =
DependencyProperty.Register(
nameof(HotKeys),
typeof(HotKeyCollection),
typeof(KeyboardShortcut),
new PropertyMetadata(defaultValue: new(), (d, e) => ((KeyboardShortcut)d).OnHotKeysPropertyChanged()));

public HotKeyCollection HotKeys
{
get => (HotKeyCollection)GetValue(HotKeysProperty);
set => SetValue(HotKeysProperty, value);
}

public void OnItemTypePropertyChanged()
{
OnItemTypeChanged();
}

public void OnSizePropertyChanged()
{
OnSizeChanged();
}

private void OnHotKeysPropertyChanged()
{
OnHotKeysChanged();
}
}
}
103 changes: 103 additions & 0 deletions src/Files.App/UserControls/KeyboardShortcut/KeyboardShortcut.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

using CommunityToolkit.WinUI.UI;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Automation;
using Microsoft.UI.Xaml.Automation.Peers;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;

namespace Files.App.UserControls.KeyboardShortcut
{
public sealed partial class KeyboardShortcut : Control
{
internal const string KeyboardShortcutItemsControl = "PART_KeyboardShortcutItemsControl";

public KeyboardShortcut()
{
DefaultStyleKey = typeof(KeyboardShortcut);
}

private void OnItemTypeChanged()
{
}

private void OnSizeChanged()
{
}

private void OnHotKeysChanged()
{
if (HotKeys.IsEmpty)
return;

List<KeyboardShortcutItem> items = new();

foreach (var item in HotKeys)
{
if (items.Any())
{
items.Add(new() { Text = ",", ItemType = KeyboardShortcutItemKind.TextOnly, Size = Size });
}

switch(item.Key, item.Modifier)
{
// No keys or modifiers specified
case (Keys.None, KeyModifiers.None):
break;

// Key modifiers only
case (Keys.None, _):
GetModifierCode(item.Modifier);
items.RemoveAt(items.Count - 1);
break;

// Keys only
case (_, KeyModifiers.None):
var key = HotKey.keys[item.Key];
items.Add(new() { Text = key, ItemType = ItemType, Size = Size });
break;

// Others
default:
GetModifierCode(item.Modifier);
key = HotKey.keys[item.Key];
items.Add(new() { Text = key, ItemType = ItemType, Size = Size });
break;
}

void GetModifierCode(KeyModifiers modifier)
{
if (modifier.HasFlag(KeyModifiers.Menu))
{
items.Add(new() { Text = HotKey.modifiers[KeyModifiers.Menu], ItemType = ItemType, Size = Size });
items.Add(new() { Text = "+", ItemType = KeyboardShortcutItemKind.TextOnly, Size = Size });
}
if (modifier.HasFlag(KeyModifiers.Ctrl))
{
items.Add(new() { Text = HotKey.modifiers[KeyModifiers.Ctrl], ItemType = ItemType, Size = Size });
items.Add(new() { Text = "+", ItemType = KeyboardShortcutItemKind.TextOnly, Size = Size });
}
if (modifier.HasFlag(KeyModifiers.Shift))
{
items.Add(new() { Text = HotKey.modifiers[KeyModifiers.Shift], ItemType = ItemType, Size = Size });
items.Add(new() { Text = "+", ItemType = KeyboardShortcutItemKind.TextOnly, Size = Size });
}
if (modifier.HasFlag(KeyModifiers.Win))
{
items.Add(new() { Text = HotKey.modifiers[KeyModifiers.Win], ItemType = ItemType, Size = Size });
items.Add(new() { Text = "+", ItemType = KeyboardShortcutItemKind.TextOnly, Size = Size });
}
}
}

// Set value
if (GetTemplateChild(KeyboardShortcutItemsControl) is ItemsControl keyboardShortcutItemsControl)
{
keyboardShortcutItemsControl.ItemsSource = items;
}
}
}
}
Loading