Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Added a Command Palette #12977

Merged
merged 15 commits into from
Jul 28, 2023
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
7 changes: 6 additions & 1 deletion specs/RichCommand/CommandList.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This is the list of all commands defined in `CommandCodes` enum except `None`.
| | RestoreRecycleBin | Restore | Restore selected item(s) from recycle bin | |
| | RestoreAllRecycleBin | Restore All Items | Restore all items from recycle bin | |
| | OpenItem | Open | Open item(s) | Enter |
| | OpenItemWithApplicationPicker | Open With | Open item(s) with selected application | |
| | OpenItemWithApplicationPicker | Open with | Open item(s) with selected application | |
| | OpenParentFolder | Open parent folder | Open parent folder of searched item | |
| | OpenFileLocation | Open file location | Open the item's location | |
| | RefreshItems | Refresh | Refresh page contents | Ctrl+R, F5 |
Expand Down Expand Up @@ -73,6 +73,7 @@ This is the list of all commands defined in `CommandCodes` enum except `None`.
| | OpenSettings | Settings | Open settings page | Ctrl+, |
| | OpenTerminal | Open in terminal | Open folder in terminal | Ctrl+\` |
| | OpenTerminalAsAdmin | Open in terminal as administrator | Open folder in terminal as administrator | Ctrl+Shift+\` |
| | OpenCommandPalette | Command palette | Open command palette | Ctrl+Shift+P |
| Layout | LayoutDecreaseSize | Decrease size | Decrease icon size in grid view | Ctrl+- |
| | LayoutIncreaseSize | Increase size | Increase icon size in grid view | Ctrl++ |
| | LayoutDetails | Details | Switch to details view | Ctrl+Shift+1 |
Expand Down Expand Up @@ -131,6 +132,9 @@ This is the list of all commands defined in `CommandCodes` enum except `None`.
| | CloseTabsToTheRightSelected | Close tabs to the right | Close tabs to the right of selected tab | |
| | CloseOtherTabsCurrent | Close other tabs | Close tabs other than current tab | |
| | CloseOtherTabsSelected | Close other tabs | Close tabs other than selected tab | |
| | OpenDirectoryInNewPane | Open in new pane | Open directory in new pane | |
| | OpenDirectoryInNewTab | Open in new tab | Open directory in new tab | |
| | OpenInNewWindowItem | Open in new window | Open directory in new window | |
| | ReopenClosedTab | Reopen closed tab | Reopen last closed tab | Ctrl+Shift+T |
| | PreviousTab | Moves to the previous tab | Move to the previous tab | Ctrl+Shift+Tab |
| | NextTab | Moves to the next tab | Move to the next tab | Ctrl+Tab |
Expand All @@ -143,3 +147,4 @@ This is the list of all commands defined in `CommandCodes` enum except `None`.
| | GitPull | Pull | Run git pull | |
| | GitPush | Push | Run git push | |
| | GitSync | Sync | Run git pull and then git push | |
| Tags | OpenAllTaggedItems | Open all | Open all tagged items | |
31 changes: 31 additions & 0 deletions src/Files.App/Actions/Open/OpenCommandPaletteAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

namespace Files.App.Actions
{
internal class OpenCommandPaletteAction : IAction
{
private readonly IContentPageContext _context;

public string Label
=> "CommandPalette".GetLocalizedResource();

public string Description
=> "OpenCommandPaletteDescription".GetLocalizedResource();

public HotKey HotKey
=> new(Keys.P, KeyModifiers.CtrlShift);

public OpenCommandPaletteAction()
{
_context = Ioc.Default.GetRequiredService<IContentPageContext>();
}

public Task ExecuteAsync()
{
_context.ShellPage?.ToolbarViewModel.OpenCommandPalette();

return Task.CompletedTask;
}
}
}
1 change: 1 addition & 0 deletions src/Files.App/Data/Commands/CommandCodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public enum CommandCodes
OpenSettings,
OpenTerminal,
OpenTerminalAsAdmin,
OpenCommandPalette,

// Layout
LayoutDecreaseSize,
Expand Down
16 changes: 16 additions & 0 deletions src/Files.App/Data/Commands/Manager/CommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ internal class CommandManager : ICommandManager
private IImmutableDictionary<HotKey, IRichCommand> hotKeys = new Dictionary<HotKey, IRichCommand>().ToImmutableDictionary();

public IRichCommand this[CommandCodes code] => commands.TryGetValue(code, out var command) ? command : None;
public IRichCommand this[string code]
{
get
{
try
{
return commands[Enum.Parse<CommandCodes>(code, true)];
}
catch
{
return None;
}
}
}
public IRichCommand this[HotKey hotKey]
=> hotKeys.TryGetValue(hotKey with { IsVisible = true }, out var command) ? command
: hotKeys.TryGetValue(hotKey with { IsVisible = false }, out command) ? command
Expand Down Expand Up @@ -91,6 +105,7 @@ public IRichCommand this[HotKey hotKey]
public IRichCommand OpenSettings => commands[CommandCodes.OpenSettings];
public IRichCommand OpenTerminal => commands[CommandCodes.OpenTerminal];
public IRichCommand OpenTerminalAsAdmin => commands[CommandCodes.OpenTerminalAsAdmin];
public IRichCommand OpenCommandPalette => commands[CommandCodes.OpenCommandPalette];
public IRichCommand LayoutDecreaseSize => commands[CommandCodes.LayoutDecreaseSize];
public IRichCommand LayoutIncreaseSize => commands[CommandCodes.LayoutIncreaseSize];
public IRichCommand LayoutDetails => commands[CommandCodes.LayoutDetails];
Expand Down Expand Up @@ -252,6 +267,7 @@ public CommandManager()
[CommandCodes.OpenSettings] = new OpenSettingsAction(),
[CommandCodes.OpenTerminal] = new OpenTerminalAction(),
[CommandCodes.OpenTerminalAsAdmin] = new OpenTerminalAsAdminAction(),
[CommandCodes.OpenCommandPalette] = new OpenCommandPaletteAction(),
[CommandCodes.LayoutDecreaseSize] = new LayoutDecreaseSizeAction(),
[CommandCodes.LayoutIncreaseSize] = new LayoutIncreaseSizeAction(),
[CommandCodes.LayoutDetails] = new LayoutDetailsAction(),
Expand Down
2 changes: 2 additions & 0 deletions src/Files.App/Data/Commands/Manager/ICommandManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Files.App.Data.Commands
public interface ICommandManager : IEnumerable<IRichCommand>
{
IRichCommand this[CommandCodes code] { get; }
IRichCommand this[string code] { get; }
IRichCommand this[HotKey customHotKey] { get; }

IRichCommand None { get; }
Expand Down Expand Up @@ -89,6 +90,7 @@ public interface ICommandManager : IEnumerable<IRichCommand>
IRichCommand OpenSettings { get; }
IRichCommand OpenTerminal { get; }
IRichCommand OpenTerminalAsAdmin { get; }
IRichCommand OpenCommandPalette { get; }

IRichCommand LayoutDecreaseSize { get; }
IRichCommand LayoutIncreaseSize { get; }
Expand Down
38 changes: 38 additions & 0 deletions src/Files.App/Data/Items/NavigationBarSuggestionItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

using Microsoft.UI.Xaml.Media;

namespace Files.App.Data.Items
{
public class NavigationBarSuggestionItem : ObservableObject
hishitetsu marked this conversation as resolved.
Show resolved Hide resolved
{
private string? _Text;
public string? Text
{
get => _Text;
set => SetProperty(ref _Text, value);
}

private string? _PrimaryDisplay;
public string? PrimaryDisplay
hishitetsu marked this conversation as resolved.
Show resolved Hide resolved
{
get => _PrimaryDisplay;
set => SetProperty(ref _PrimaryDisplay, value);
}

private string? _SecondaryDisplay;
public string? SecondaryDisplay
{
get => _SecondaryDisplay;
set => SetProperty(ref _SecondaryDisplay, value);
}

private string? _SupplementaryDisplay;
public string? SupplementaryDisplay
{
get => _SupplementaryDisplay;
set => SetProperty(ref _SupplementaryDisplay, value);
}
}
}
20 changes: 19 additions & 1 deletion src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
<value>Clear all items</value>
</data>
<data name="NavigationToolbarVisiblePath.PlaceholderText" xml:space="preserve">
<value>Enter a path</value>
<value>Enter a path to navigate to or type ">" to open the command palette</value>
</data>
<data name="Search" xml:space="preserve">
<value>Search</value>
Expand Down Expand Up @@ -3404,4 +3404,22 @@
<data name="OpenAllTaggedItemsDescription" xml:space="preserve">
<value>Open all tagged items</value>
</data>
<data name="InvalidCommand" xml:space="preserve">
<value>Invalid command</value>
</data>
<data name="InvalidCommandContent" xml:space="preserve">
<value>'{0}' is not recognized as a command.</value>
</data>
<data name="CommandNotExecutable" xml:space="preserve">
<value>Command not executable</value>
</data>
<data name="CommandNotExecutableContent" xml:space="preserve">
<value>The '{0}' command is not ready to be executed.</value>
</data>
<data name="CommandPalette" xml:space="preserve">
<value>Command palette</value>
</data>
<data name="OpenCommandPaletteDescription" xml:space="preserve">
<value>Open command palette</value>
</data>
</root>
43 changes: 40 additions & 3 deletions src/Files.App/UserControls/AddressToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:extensions="using:CommunityToolkit.WinUI.UI"
xmlns:helpers="using:Files.App.Helpers"
xmlns:items="using:Files.App.Data.Items"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:triggers="using:CommunityToolkit.WinUI.UI.Triggers"
xmlns:uc="using:Files.App.UserControls"
Expand All @@ -23,6 +24,7 @@

<UserControl.Resources>
<ResourceDictionary>
<converters:NullToTrueConverter x:Key="NullToFalseConverter" Inverse="True" />
<converters1:BoolNegationConverter x:Key="BoolNegationConverter" />

<ResourceDictionary.MergedDictionaries>
Expand Down Expand Up @@ -124,7 +126,6 @@
BorderBrush="{ThemeResource SystemBaseMediumLowColor}"
BorderThickness="{ThemeResource TextControlBorderThemeThickness}"
CornerRadius="{StaticResource ControlCornerRadius}"
DisplayMemberPath="Name"
FocusDisengaged="VisiblePath_LostFocus"
FontWeight="SemiBold"
ItemsSource="{x:Bind ViewModel.NavigationBarSuggestions, Mode=OneWay}"
Expand All @@ -137,8 +138,44 @@
ScrollViewer.VerticalScrollBarVisibility="Hidden"
Text="{x:Bind ViewModel.PathText, Mode=OneWay}"
TextChanged="{x:Bind ViewModel.VisiblePath_TextChanged, Mode=OneWay}"
TextMemberPath="ItemPath"
Visibility="{x:Bind converters:MultiBooleanConverter.OrNotConvertToVisibility(ShowSearchBox, ViewModel.IsSearchBoxVisible), Mode=OneWay}" />
TextMemberPath="Text"
Visibility="{x:Bind converters:MultiBooleanConverter.OrNotConvertToVisibility(ShowSearchBox, ViewModel.IsSearchBoxVisible), Mode=OneWay}">
<AutoSuggestBox.ItemTemplate>
<DataTemplate x:DataType="items:NavigationBarSuggestionItem">
<StackPanel Margin="0,4">
<Grid>
<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}"
Text="{x:Bind PrimaryDisplay, Mode=OneWay}" />

<!-- Supplementary Display -->
<!-- This is used to display command hotkeys. -->
<TextBlock
hishitetsu marked this conversation as resolved.
Show resolved Hide resolved
Grid.Column="1"
FontWeight="Normal"
Foreground="{ThemeResource TextFillColorTertiaryBrush}"
Text="{x:Bind SupplementaryDisplay, Mode=OneWay}" />
</Grid>

<!-- 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}" />
</StackPanel>
</DataTemplate>
</AutoSuggestBox.ItemTemplate>
</AutoSuggestBox>

<Grid
x:Name="ClickablePath"
Expand Down
14 changes: 8 additions & 6 deletions src/Files.App/UserControls/AddressToolbar.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
// Copyright (c) 2023 Files Community
// Licensed under the MIT License. See the LICENSE.

using CommunityToolkit.Mvvm.DependencyInjection;
using Files.App.Data.Commands;
using Files.App.ViewModels;
using Files.Core.Services.Settings;
using Microsoft.UI.Input;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using System.Windows.Input;
using Windows.System;
using FocusManager = Microsoft.UI.Xaml.Input.FocusManager;

Expand Down Expand Up @@ -72,7 +67,14 @@ private void VisiblePath_Loaded(object _, RoutedEventArgs e)
{
// AutoSuggestBox won't receive focus unless it's fully loaded
VisiblePath.Focus(FocusState.Programmatic);
DependencyObjectHelpers.FindChild<TextBox>(VisiblePath)?.SelectAll();

if (DependencyObjectHelpers.FindChild<TextBox>(VisiblePath) is TextBox textBox)
{
if (textBox.Text.StartsWith(">"))
textBox.Select(1, textBox.Text.Length - 1);
else
textBox.SelectAll();
}
}

private void ManualPathEntryItem_Click(object _, PointerRoutedEventArgs e)
Expand Down
Loading