Skip to content

Feature: Introduced Omnibar #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 5 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Files Community
// Licensed under the MIT License.

using CommunityToolkit.WinUI;

namespace Files.App.Controls
{
public partial class MenuFlyoutItemHeader : MenuFlyoutItem
{
[GeneratedDependencyProperty]
public partial bool Header { get; set; }

public MenuFlyoutItemHeader()
{
//this.InitializeComponent();
}
}
}
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
};
}
}
}
61 changes: 32 additions & 29 deletions src/Files.App/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -2141,9 +2141,6 @@
<data name="SplittingSize" xml:space="preserve">
<value>Splitting size</value>
</data>
<data name="DoNotSplit" xml:space="preserve">
<value>Do not split</value>
</data>
<data name="CD" xml:space="preserve">
<value>CD</value>
</data>
Expand Down Expand Up @@ -2198,15 +2195,6 @@
<data name="EditSettingsFile" xml:space="preserve">
<value>Edit settings file</value>
</data>
<data name="EditSettingsFileDescription" xml:space="preserve">
<value>Open settings file in your default editor</value>
</data>
<data name="ReleaseNotes" xml:space="preserve">
<value>Release Notes</value>
</data>
<data name="ReleaseNotesDescription" xml:space="preserve">
<value>Open Release Notes</value>
</data>
<data name="CannotCreateShortcutDialogTitle" xml:space="preserve">
<value>Creating a shortcut in this location requires administrator privileges</value>
</data>
Expand Down Expand Up @@ -3508,7 +3496,7 @@
<data name="StatusCenter_GitCloneInProgress_SubHeader" xml:space="preserve">
<value>Cloning {0} from "{1}" to "{2}"</value>
<comment>Shown in a StatusCenter card.</comment>
</data>
</data>
<data name="StatusCenter_InstallFontCanceled_Header" xml:space="preserve">
<value>Canceled installing {0} fonts</value>
<comment>Shown in a StatusCenter card.</comment>
Expand Down Expand Up @@ -3540,7 +3528,7 @@
<data name="StatusCenter_InstallFontInProgress_SubHeader" xml:space="preserve">
<value>Installing {0} font(s) from "{1}"</value>
<comment>Shown in a StatusCenter card.</comment>
</data>
</data>
<data name="StatusCenter_CopyCanceled_Header" xml:space="preserve">
<value>Canceled copying {0} item(s) to "{1}"</value>
<comment>Shown in a StatusCenter card.</comment>
Expand Down Expand Up @@ -3700,9 +3688,6 @@
<data name="FailedToSetBackground" xml:space="preserve">
<value>Failed to set the background wallpaper</value>
</data>
<data name="FailedToOpenSettingsFile" xml:space="preserve">
<value>Failed to open the settings file</value>
</data>
<data name="GitDeleteBranch" xml:space="preserve">
<value>Delete Git branch</value>
</data>
Expand Down Expand Up @@ -4122,18 +4107,6 @@
<value>Add to shelf</value>
<comment>Tooltip that displays when dragging items to the Shelf Pane</comment>
</data>
<data name="EnterHashToCompare" xml:space="preserve">
<value>Enter a hash to compare</value>
<comment>Placeholder that appears in the compare hash text box</comment>
</data>
<data name="HashesMatch" xml:space="preserve">
<value>Matches {0}</value>
<comment>Appears when two compared hashes match, e.g. "Matches SHA256"</comment>
</data>
<data name="HashesDoNotMatch" xml:space="preserve">
<value>No matches found</value>
<comment>Appears when two compared hashes don't match</comment>
</data>
<data name="PathOrAlias" xml:space="preserve">
<value>Path or alias</value>
</data>
Expand Down Expand Up @@ -4177,6 +4150,33 @@
<value>Cannot clone repo</value>
<comment>Cannot clone repo dialog title</comment>
</data>
<data name="DoNotSplit" xml:space="preserve">
<value>Do not split</value>
</data>
<data name="EditSettingsFileDescription" xml:space="preserve">
<value>Open settings file in your default editor</value>
</data>
<data name="ReleaseNotes" xml:space="preserve">
<value>Release Notes</value>
</data>
<data name="ReleaseNotesDescription" xml:space="preserve">
<value>Open Release Notes</value>
</data>
<data name="FailedToOpenSettingsFile" xml:space="preserve">
<value>Failed to open the settings file</value>
</data>
<data name="EnterHashToCompare" xml:space="preserve">
<value>Enter a hash to compare</value>
<comment>Placeholder that appears in the compare hash text box</comment>
</data>
<data name="HashesMatch" xml:space="preserve">
<value>Matches {0}</value>
<comment>Appears when two compared hashes match, e.g. "Matches SHA256"</comment>
</data>
<data name="HashesDoNotMatch" xml:space="preserve">
<value>No matches found</value>
<comment>Appears when two compared hashes don't match</comment>
</data>
<data name="CompareFile" xml:space="preserve">
<value>Compare a file</value>
<comment>Button that appears in file hash properties that allows the user to compare two files</comment>
Expand All @@ -4193,4 +4193,7 @@
<data name="EnableOmnibar" xml:space="preserve">
<value>Enable Omnibar</value>
</data>
<data name="OmnibarPathModeTextPlaceholder" xml:space="preserve">
<value>Enter a path to navigate to...</value>
</data>
</root>
Loading
Loading