Skip to content

Feature: Introduced Omnibar 1 #17023

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 1 commit 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
7 changes: 4 additions & 3 deletions src/Files.App.Controls/Omnibar/Omnibar.Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private void Omnibar_SizeChanged(object sender, SizeChangedEventArgs e)

private void AutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)
{
_isFocused = true;
IsFocused = true;

VisualStateManager.GoToState(CurrentSelectedMode, "Focused", true);
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
Expand All @@ -30,7 +30,7 @@ private void AutoSuggestBox_LostFocus(object sender, RoutedEventArgs e)
if (_textBox.ContextFlyout.IsOpen)
return;

_isFocused = false;
IsFocused = false;

if (CurrentSelectedMode?.ContentOnInactive is not null)
{
Expand Down Expand Up @@ -92,7 +92,8 @@ private void AutoSuggestBox_KeyDown(object sender, KeyRoutedEventArgs e)

private void AutoSuggestBox_TextChanged(object sender, TextChangedEventArgs e)
{
CurrentSelectedMode!.Text = _textBox.Text;
if (string.Compare(_textBox.Text, CurrentSelectedMode!.Text, StringComparison.OrdinalIgnoreCase) is not 0)
CurrentSelectedMode!.Text = _textBox.Text;

// UpdateSuggestionListView();

Expand Down
16 changes: 16 additions & 0 deletions src/Files.App.Controls/Omnibar/Omnibar.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,23 @@ public partial class Omnibar
[GeneratedDependencyProperty]
public partial OmnibarMode? CurrentSelectedMode { get; set; }

[GeneratedDependencyProperty]
public partial string? CurrentSelectedModeName { get; set; }

[GeneratedDependencyProperty]
public partial Thickness AutoSuggestBoxPadding { get; set; }

[GeneratedDependencyProperty]
public partial bool IsFocused { get; set; }

partial void OnCurrentSelectedModeChanged(OmnibarMode? newValue)
{
CurrentSelectedModeName = newValue?.ModeName;
}

partial void OnIsFocusedChanged(bool newValue)
{
//_textBox?.Focus(newValue ? FocusState.Programmatic : FocusState.Unfocused);
}
}
}
23 changes: 12 additions & 11 deletions src/Files.App.Controls/Omnibar/Omnibar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public partial class Omnibar : Control
private Border _textBoxSuggestionsContainerBorder = null!;
private ListView _textBoxSuggestionsListView = null!;

private bool _isFocused;
private string _userInput = string.Empty;
private OmnibarTextChangeReason _textChangeReason = OmnibarTextChangeReason.None;

Expand Down Expand Up @@ -148,15 +147,15 @@ public void ChangeMode(OmnibarMode modeToExpand, bool shouldFocus = false, bool
CurrentSelectedMode = modeToExpand;

_textChangeReason = OmnibarTextChangeReason.ProgrammaticChange;
_textBox.Text = CurrentSelectedMode.Text ?? string.Empty;
ChangeTextBoxText(CurrentSelectedMode.Text ?? string.Empty);

// Move cursor of the TextBox to the tail
_textBox.Select(_textBox.Text.Length, 0);

VisualStateManager.GoToState(CurrentSelectedMode, "Focused", true);
CurrentSelectedMode.OnChangingCurrentMode(true);

if (_isFocused)
if (IsFocused)
{
VisualStateManager.GoToState(CurrentSelectedMode, "Focused", true);
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
Expand All @@ -174,7 +173,7 @@ public void ChangeMode(OmnibarMode modeToExpand, bool shouldFocus = false, bool
if (shouldFocus)
_textBox.Focus(FocusState.Keyboard);

TryToggleIsSuggestionsPopupOpen(_isFocused && CurrentSelectedMode?.SuggestionItemsSource is not null);
TryToggleIsSuggestionsPopupOpen(IsFocused && CurrentSelectedMode?.SuggestionItemsSource is not null);

// Remove the reposition transition from the all modes
if (useTransition)
Expand All @@ -189,7 +188,7 @@ public void ChangeMode(OmnibarMode modeToExpand, bool shouldFocus = false, bool

public bool TryToggleIsSuggestionsPopupOpen(bool wantToOpen)
{
if (wantToOpen && (!_isFocused || CurrentSelectedMode?.SuggestionItemsSource is null))
if (wantToOpen && (!IsFocused || CurrentSelectedMode?.SuggestionItemsSource is null))
return false;

_textBoxSuggestionsPopup.IsOpen = wantToOpen;
Expand All @@ -205,10 +204,15 @@ public void ChooseSuggestionItem(object obj)
if (CurrentSelectedMode.UpdateTextOnSelect)
{
_textChangeReason = OmnibarTextChangeReason.SuggestionChosen;
_textBox.Text = GetObjectText(obj);
ChangeTextBoxText(GetObjectText(obj));
}

SuggestionChosen?.Invoke(this, new(CurrentSelectedMode, obj));
}

internal protected void ChangeTextBoxText(string text)
{
_textBox.Text = text;

// Move the cursor to the end of the TextBox
_textBox?.Select(_textBox.Text.Length, 0);
Expand All @@ -233,7 +237,7 @@ private string GetObjectText(object obj)
return obj is string text
? text
: obj is IOmnibarTextMemberPathProvider textMemberPathProvider
? textMemberPathProvider.GetTextMemberPath(CurrentSelectedMode.DisplayMemberPath ?? string.Empty)
? textMemberPathProvider.GetTextMemberPath(CurrentSelectedMode.TextMemberPath ?? string.Empty)
: obj.ToString() ?? string.Empty;
}

Expand All @@ -245,10 +249,7 @@ private void RevertTextToUserInput()
_textBoxSuggestionsListView.SelectedIndex = -1;
_textChangeReason = OmnibarTextChangeReason.ProgrammaticChange;

_textBox.Text = _userInput ?? "";

// Move the cursor to the end of the TextBox
_textBox?.Select(_textBox.Text.Length, 0);
ChangeTextBoxText(_userInput ?? "");
}
}
}
1 change: 0 additions & 1 deletion src/Files.App.Controls/Omnibar/Omnibar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@
Height="{TemplateBinding Height}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}"
TabFocusNavigation="Local">
<!-- Mode Button -->
<Border
Expand Down
13 changes: 12 additions & 1 deletion src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,20 @@ public partial class OmnibarMode
public partial DataTemplate? SuggestionItemTemplate { get; set; }

[GeneratedDependencyProperty]
public partial string? DisplayMemberPath { get; set; }
/// <remark>
/// Implement <see cref="IOmnibarTextMemberPathProvider"/> in <see cref="SuggestionItemsSource"/> to get the text member path from the suggestion item correctly.
/// </remark>
public partial string? TextMemberPath { get; set; }

[GeneratedDependencyProperty(DefaultValue = true)]
public partial bool UpdateTextOnSelect { get; set; }

partial void OnTextChanged(string? newValue)
{
if (_ownerRef is null || _ownerRef.TryGetTarget(out var owner) is false)
return;

owner.ChangeTextBoxText(newValue ?? string.Empty);
}
}
}
1 change: 1 addition & 0 deletions src/Files.App/Data/Items/NavigationBarSuggestionItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Files.App.Data.Items
{
[Obsolete("Remove once Omnibar goes out of experimental.")]
public sealed partial class NavigationBarSuggestionItem : ObservableObject
{
private string? _Text;
Expand Down
7 changes: 7 additions & 0 deletions src/Files.App/Data/Models/BreadcrumbBarItemModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

namespace Files.App.Data.Models
{
internal record BreadcrumbBarItemModel(string Text);
}
20 changes: 20 additions & 0 deletions src/Files.App/Data/Models/OmnibarPathModeSuggestionModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using Files.App.Controls;

namespace Files.App.Data.Models
{
internal record OmnibarPathModeSuggestionModel(string Path, string DisplayName) : IOmnibarTextMemberPathProvider
{
public string GetTextMemberPath(string textMemberPath)
{
return textMemberPath switch
{
nameof(Path) => Path,
nameof(DisplayName) => DisplayName,
_ => string.Empty
};
}
}
}
3 changes: 3 additions & 0 deletions src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -4199,4 +4199,7 @@
<data name="SectionsHiddenMessage" xml:space="preserve">
<value>You can add sections to the sidebar by right-clicking and selecting the sections you want to add.</value>
</data>
<data name="OmnibarPathModeTextPlaceholder" xml:space="preserve">
<value>Enter a path to navigate to...</value>
</data>
</root>
122 changes: 109 additions & 13 deletions src/Files.App/UserControls/NavigationToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
xmlns:converters="using:Files.App.Converters"
xmlns:converters1="using:CommunityToolkit.WinUI.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dataitems="using:Files.App.Data.Items"
xmlns:datamodels="using:Files.App.Data.Models"
xmlns:helpers="using:Files.App.Helpers"
xmlns:items="using:Files.App.Data.Items"
xmlns:keyboard="using:Files.App.UserControls.KeyboardShortcut"
Expand Down Expand Up @@ -211,6 +213,7 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Path Box -->
<AutoSuggestBox
Expand Down Expand Up @@ -314,23 +317,11 @@
LostFocus="SearchRegion_LostFocus"
SearchBoxViewModel="{x:Bind ViewModel.SearchBoxViewModel, Mode=OneWay}"
Visibility="{x:Bind converters:MultiBooleanConverter.OrConvertToVisibility(ShowSearchBox, ViewModel.IsSearchBoxVisible), Mode=OneWay}" />
</Grid>

<!-- Omnibar -->
<controls:Omnibar
x:Name="Omnibar"
Grid.Column="1"
x:Load="{x:Bind ViewModel.EnableOmnibar, Mode=OneWay}" />

<!-- Right Side Action Buttons -->
<StackPanel
Grid.Column="2"
Orientation="Horizontal"
Spacing="4">

<!-- Mini Search Button -->
<Button
x:Name="ShowSearchButton"
Grid.Column="2"
AccessKey="I"
AccessKeyInvoked="Button_AccessKeyInvoked"
AutomationProperties.Name="{x:Bind Commands.Search.Label, Mode=OneWay}"
Expand All @@ -342,6 +333,111 @@
<FontIcon FontSize="14" Glyph="{x:Bind ViewModel.SearchButtonGlyph, Mode=OneWay}" />
</Button>

</Grid>

<!-- Omnibar -->
<controls:Omnibar
x:Name="Omnibar"
Grid.Column="1"
x:Load="{x:Bind ViewModel.EnableOmnibar, Mode=OneWay}"
CurrentSelectedModeName="{x:Bind ViewModel.OmnibarCurrentSelectedModeName, Mode=TwoWay}"
IsFocused="{x:Bind ViewModel.IsOmnibarFocused, Mode=TwoWay}"
QuerySubmitted="Omnibar_QuerySubmitted"
SuggestionChosen="Omnibar_SuggestionChosen"
TextChanged="Omnibar_TextChanged">

<controls:OmnibarMode
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Path}, IsFilled=True}"
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Path}, IconType=Outline}"
IsDefault="True"
ModeName="Path"
PlaceholderText="{helpers:ResourceString Name=OmnibarPathModeTextPlaceholder}"
SuggestionItemsSource="{x:Bind ViewModel.PathModeSuggestionItems, Mode=OneWay}"
Text="{x:Bind ViewModel.OmnibarPathModeText, Mode=TwoWay}"
TextMemberPath="Path">
<controls:OmnibarMode.ContentOnInactive>
<controls:BreadcrumbBar
x:Name="BreadcrumbBar"
ItemClicked="BreadcrumbBar_ItemClicked"
ItemDropDownFlyoutClosed="BreadcrumbBar_ItemDropDownFlyoutClosed"
ItemDropDownFlyoutOpening="BreadcrumbBar_ItemDropDownFlyoutOpening"
ItemsSource="{x:Bind ViewModel.PathComponents, Mode=OneWay}">
<controls:BreadcrumbBar.RootItem>
<Image
Width="16"
Height="16"
Source="/Assets/FluentIcons/Home.png" />
</controls:BreadcrumbBar.RootItem>
<controls:BreadcrumbBar.ItemTemplate>
<DataTemplate x:DataType="dataitems:PathBoxItem">
<controls:BreadcrumbBarItem Content="{x:Bind Title, Mode=OneWay}" />
</DataTemplate>
</controls:BreadcrumbBar.ItemTemplate>
</controls:BreadcrumbBar>
</controls:OmnibarMode.ContentOnInactive>
<controls:OmnibarMode.SuggestionItemTemplate>
<DataTemplate x:DataType="datamodels:OmnibarPathModeSuggestionModel">
<TextBlock Text="{x:Bind DisplayName, Mode=OneWay}" />
</DataTemplate>
</controls:OmnibarMode.SuggestionItemTemplate>
</controls:OmnibarMode>

<controls:OmnibarMode
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IsFilled=True}"
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IconType=Outline}"
ModeName="Palette"
PlaceholderText="Enter a palette command...">
<!--<controls:OmnibarMode.SuggestionItemTemplate>
<DataTemplate x:DataType="data:OmnibarPaletteSuggestionItem">
<Grid Height="48" ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<controls:ThemedIcon
Width="20"
Height="20"
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>
</Grid>
</DataTemplate>
</controls:OmnibarMode.SuggestionItemTemplate>-->
</controls:OmnibarMode>

<controls:OmnibarMode
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Search}, IsFilled=True}"
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Search}, IconType=Outline}"
ModeName="Search"
PlaceholderText="Enter a search query..." />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this supposed to use a localized string?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah Ill make them string resources right before getting this ready.


</controls:Omnibar>

<!-- Right Side Action Buttons -->
<StackPanel
Grid.Column="2"
Orientation="Horizontal"
Spacing="4">

<!-- Shelf Pane -->
<ToggleButton
x:Name="ShelfPaneToggleButton"
Expand Down
Loading
Loading