Skip to content

Code Quality: Implemented Command Palette mode in Omnibar #17104

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

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
22 changes: 21 additions & 1 deletion src/Files.App/Data/Items/NavigationBarSuggestionItem.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using Files.App.Controls;

namespace Files.App.Data.Items
{
[Obsolete("Remove once Omnibar goes out of experimental.")]
public sealed partial class NavigationBarSuggestionItem : ObservableObject
public sealed partial class NavigationBarSuggestionItem : ObservableObject, IOmnibarTextMemberPathProvider
{
private object? _Icon;
public object? Icon
{
get => _Icon;
set => SetProperty(ref _Icon, value);
}

private string? _Text;
public string? Text
{
Expand Down Expand Up @@ -88,5 +97,16 @@ private void UpdatePrimaryDisplay()
}
}
}

public string GetTextMemberPath(string textMemberPath)
{
return textMemberPath switch
{
nameof(Text) => Text,
nameof(PrimaryDisplay) => PrimaryDisplay,
nameof(SearchText) => SearchText,
_ => string.Empty
};
}
}
}
61 changes: 33 additions & 28 deletions src/Files.App/UserControls/NavigationToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -383,42 +383,47 @@
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IsFilled=True}"
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IconType=Outline}"
ModeName="{helpers:ResourceString Name=CommandPalette}"
PlaceholderText="{helpers:ResourceString Name=OmnibarCommandPaletteModeTextPlaceholder}">
<!--<controls:OmnibarMode.SuggestionItemTemplate>
<DataTemplate x:DataType="data:OmnibarPaletteSuggestionItem">
<Grid Height="48" ColumnSpacing="12">
PlaceholderText="{helpers:ResourceString Name=OmnibarCommandPaletteModeTextPlaceholder}"
SuggestionItemsSource="{x:Bind ViewModel.OmnibarCommandPaletteModeSuggestionItems, Mode=OneWay}"
Text="{x:Bind ViewModel.OmnibarCommandPaletteModeText, Mode=TwoWay}"
TextMemberPath="Text">
<controls:OmnibarMode.SuggestionItemTemplate>
<DataTemplate x:DataType="dataitems:NavigationBarSuggestionItem">
<Grid ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<controls:ThemedIcon
Width="20"
Height="20"

<Viewbox
Grid.Column="0"
Width="16"
Height="16">
<ContentPresenter Content="{x:Bind Icon, Mode=OneWay}" />
</Viewbox>

<!-- Primary Title -->
<TextBlock
x:Name="PrimaryDisplayBlock"
Grid.Column="1"
VerticalAlignment="Center"
Style="{StaticResource App.ThemedIcons.Actions.Copying}" />
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock
Style="{StaticResource BodyStrongTextBlockStyle}"
Text="{x:Bind Title}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
<TextBlock
Foreground="{ThemeResource TextFillColorSecondaryBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{x:Bind Description}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
</StackPanel>
<StackPanel Grid.Column="2" VerticalAlignment="Center">
<TextBlock
Text="{x:Bind HotKeys}"
TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap" />
</StackPanel>
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>

<!-- Keyboard Shortcuts -->
<keyboard:KeyboardShortcut
x:Name="RightAlignedKeyboardShortcut"
Grid.Column="2"
VerticalAlignment="Center"
HotKeys="{x:Bind HotKeys, Mode=OneWay}" />
</Grid>
</DataTemplate>
</controls:OmnibarMode.SuggestionItemTemplate>-->
</controls:OmnibarMode.SuggestionItemTemplate>
</controls:OmnibarMode>

<controls:OmnibarMode
Expand Down
38 changes: 33 additions & 5 deletions src/Files.App/UserControls/NavigationToolbar.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,19 +256,47 @@ private void ClickablePath_GettingFocus(UIElement sender, GettingFocusEventArgs

private async void Omnibar_QuerySubmitted(Omnibar sender, OmnibarQuerySubmittedEventArgs args)
{
await ViewModel.HandleItemNavigationAsync(args.Text);
if (Omnibar.CurrentSelectedMode == OmnibarPathMode)
{
await ViewModel.HandleItemNavigationAsync(args.Text);
}
else if (Omnibar.CurrentSelectedMode == OmnibarCommandPaletteMode)
{
}
else if (Omnibar.CurrentSelectedMode == OmnibarSearchMode)
{
}
}

private async void Omnibar_SuggestionChosen(Omnibar sender, OmnibarSuggestionChosenEventArgs args)
{
if (args.SelectedItem is OmnibarPathModeSuggestionModel item &&
!string.IsNullOrEmpty(item.Path))
await ViewModel.HandleItemNavigationAsync(item.Path);
if (Omnibar.CurrentSelectedMode == OmnibarPathMode)
{
if (args.SelectedItem is OmnibarPathModeSuggestionModel item &&
!string.IsNullOrEmpty(item.Path))
await ViewModel.HandleItemNavigationAsync(item.Path);
}
else if (Omnibar.CurrentSelectedMode == OmnibarCommandPaletteMode)
{
}
else if (Omnibar.CurrentSelectedMode == OmnibarSearchMode)
{
}
}

private async void Omnibar_TextChanged(Omnibar sender, OmnibarTextChangedEventArgs args)
{
await ViewModel.PopulateOmnibarSuggestionsForPathMode();
if (Omnibar.CurrentSelectedMode == OmnibarPathMode)
{
await ViewModel.PopulateOmnibarSuggestionsForPathMode();
}
else if (Omnibar.CurrentSelectedMode == OmnibarCommandPaletteMode)
{
ViewModel.PopulateOmnibarSuggestionsForCommandPaletteMode();
}
else if (Omnibar.CurrentSelectedMode == OmnibarSearchMode)
{
}
}

private async void BreadcrumbBar_ItemClicked(Controls.BreadcrumbBar sender, Controls.BreadcrumbBarItemClickedEventArgs args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ public sealed partial class NavigationToolbarViewModel : ObservableObject, IAddr

internal ObservableCollection<OmnibarPathModeSuggestionModel> PathModeSuggestionItems { get; } = [];

internal ObservableCollection<NavigationBarSuggestionItem> OmnibarCommandPaletteModeSuggestionItems { get; } = [];

public bool IsSingleItemOverride { get; set; }

public bool SearchHasFocus { get; private set; }
Expand Down Expand Up @@ -218,6 +220,8 @@ public string? PathText
}
}

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

private bool _IsOmnibarFocused;
public bool IsOmnibarFocused
Expand All @@ -239,6 +243,8 @@ public bool IsOmnibarFocused
_ = PopulateOmnibarSuggestionsForPathMode();
break;
case OmnibarPaletteModeName:
if (OmnibarCommandPaletteModeSuggestionItems.Count is 0)
PopulateOmnibarSuggestionsForCommandPaletteMode();
break;
case OmnibarSearchModeName:
break;
Expand Down Expand Up @@ -1126,6 +1132,32 @@ void AddNoResultsItem()
}
}

public void PopulateOmnibarSuggestionsForCommandPaletteMode()
{
OmnibarCommandPaletteModeText ??= string.Empty;

OmnibarCommandPaletteModeSuggestionItems.Clear();

IList<NavigationBarSuggestionItem>? suggestions = null;

suggestions = [.. Commands.Where(command =>
command.IsExecutable &&
command.IsAccessibleGlobally &&
(command.Description.Contains(OmnibarCommandPaletteModeText, StringComparison.OrdinalIgnoreCase) ||
command.Code.ToString().Contains(OmnibarCommandPaletteModeText, StringComparison.OrdinalIgnoreCase)))
.Select(command => new NavigationBarSuggestionItem()
{
Icon = command.Icon,
Text = command.Code.ToString(),
PrimaryDisplay = command.Description,
HotKeys = command.HotKeys,
SearchText = OmnibarCommandPaletteModeText,
})];

foreach (var suggestionItem in suggestions)
OmnibarCommandPaletteModeSuggestionItems.Add(suggestionItem);
}

[Obsolete("Remove once Omnibar goes out of experimental.")]
public async Task SetAddressBarSuggestionsAsync(AutoSuggestBox sender, IShellPage shellpage)
{
Expand Down