Skip to content
36 changes: 20 additions & 16 deletions src/Files.App.Controls/Omnibar/Omnibar.Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@ private void Omnibar_SizeChanged(object sender, SizeChangedEventArgs e)
_textBoxSuggestionsContainerBorder.Width = ActualWidth;
}

private void AutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)
private void AutoSuggestBox_GettingFocus(UIElement sender, GettingFocusEventArgs args)
{
IsFocused = true;
if (args.OldFocusedElement is null)
return;

VisualStateManager.GoToState(CurrentSelectedMode, "Focused", true);
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
_previouslyFocusedElement = new(args.OldFocusedElement as UIElement);
}

TryToggleIsSuggestionsPopupOpen(true);
private void AutoSuggestBox_GotFocus(object sender, RoutedEventArgs e)
{
IsFocused = true;
_textBox.SelectAll();
}

private void AutoSuggestBox_LostFocus(object sender, RoutedEventArgs e)
Expand All @@ -31,14 +35,6 @@ private void AutoSuggestBox_LostFocus(object sender, RoutedEventArgs e)
return;

IsFocused = false;

if (CurrentSelectedMode?.ContentOnInactive is not null)
{
VisualStateManager.GoToState(CurrentSelectedMode, "CurrentUnfocused", true);
VisualStateManager.GoToState(_textBox, "InputAreaCollapsed", true);
}

TryToggleIsSuggestionsPopupOpen(false);
}

private void AutoSuggestBox_KeyDown(object sender, KeyRoutedEventArgs e)
Expand Down Expand Up @@ -77,12 +73,20 @@ private void AutoSuggestBox_KeyDown(object sender, KeyRoutedEventArgs e)
ChooseSuggestionItem(_textBoxSuggestionsListView.SelectedItem);
}
}
else if (e.Key == VirtualKey.Escape && _textBoxSuggestionsPopup.IsOpen)
else if (e.Key == VirtualKey.Escape)
{
e.Handled = true;

RevertTextToUserInput();
_textBoxSuggestionsPopup.IsOpen = false;
if (_textBoxSuggestionsPopup.IsOpen)
{
RevertTextToUserInput();
_textBoxSuggestionsPopup.IsOpen = false;
}
else
{
_previouslyFocusedElement.TryGetTarget(out var previouslyFocusedElement);
previouslyFocusedElement?.Focus(FocusState.Programmatic);
}
}
else
{
Expand Down
42 changes: 39 additions & 3 deletions src/Files.App.Controls/Omnibar/Omnibar.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,50 @@ public partial class Omnibar
[GeneratedDependencyProperty]
public partial bool IsFocused { get; set; }

partial void OnCurrentSelectedModeChanged(OmnibarMode? newValue)
partial void OnCurrentSelectedModePropertyChanged(DependencyPropertyChangedEventArgs e)
{
CurrentSelectedModeName = newValue?.ModeName;
if (e.NewValue is not OmnibarMode newMode)
return;

ChangeMode(e.OldValue as OmnibarMode, newMode);
CurrentSelectedModeName = newMode.ModeName;
}

partial void OnCurrentSelectedModeNameChanged(string? newValue)
{
if (string.IsNullOrEmpty(newValue) ||
string.IsNullOrEmpty(CurrentSelectedMode?.Name) ||
CurrentSelectedMode.Name.Equals(newValue) ||
Modes is null)
return;

var newMode = Modes.Where(x => x.Name?.Equals(newValue) ?? false).FirstOrDefault();
if (newMode is null)
return;

CurrentSelectedMode = newMode;
}

partial void OnIsFocusedChanged(bool newValue)
{
//_textBox?.Focus(newValue ? FocusState.Programmatic : FocusState.Unfocused);
if (CurrentSelectedMode is null || _textBox is null)
return;

if (newValue)
{
VisualStateManager.GoToState(CurrentSelectedMode, "Focused", true);
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
}
else
{
if (CurrentSelectedMode?.ContentOnInactive is not null)
{
VisualStateManager.GoToState(CurrentSelectedMode, "CurrentUnfocused", true);
VisualStateManager.GoToState(_textBox, "InputAreaCollapsed", true);
}
}

TryToggleIsSuggestionsPopupOpen(newValue);
}
}
}
88 changes: 44 additions & 44 deletions src/Files.App.Controls/Omnibar/Omnibar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public partial class Omnibar : Control
private string _userInput = string.Empty;
private OmnibarTextChangeReason _textChangeReason = OmnibarTextChangeReason.None;

private WeakReference<UIElement?> _previouslyFocusedElement = new(null);

// Events

public event TypedEventHandler<Omnibar, OmnibarQuerySubmittedEventArgs>? QuerySubmitted;
Expand Down Expand Up @@ -67,6 +69,7 @@ protected override void OnApplyTemplate()
PopulateModes();

SizeChanged += Omnibar_SizeChanged;
_textBox.GettingFocus += AutoSuggestBox_GettingFocus;
_textBox.GotFocus += AutoSuggestBox_GotFocus;
_textBox.LostFocus += AutoSuggestBox_LostFocus;
_textBox.KeyDown += AutoSuggestBox_KeyDown;
Expand Down Expand Up @@ -104,27 +107,23 @@ public void PopulateModes()
}
}

public void ChangeMode(OmnibarMode modeToExpand, bool shouldFocus = false, bool useTransition = true)
protected void ChangeMode(OmnibarMode? oldMode, OmnibarMode newMode)
{
if (_modesHostGrid is null || Modes is null)
if (_modesHostGrid is null || Modes is null || CurrentSelectedMode is null)
return;

foreach (var mode in Modes)
{
// Add the reposition transition to the all modes
if (useTransition)
{
mode.Transitions = [new RepositionThemeTransition()];
mode.UpdateLayout();
}

mode.OnChangingCurrentMode(false);
mode.Transitions = [new RepositionThemeTransition()];
mode.UpdateLayout();
mode.IsTabStop = true;
}

var index = _modesHostGrid.Children.IndexOf(modeToExpand);
var index = _modesHostGrid.Children.IndexOf(newMode);

if (CurrentSelectedMode is not null)
VisualStateManager.GoToState(CurrentSelectedMode, "Unfocused", true);
if (oldMode is not null)
VisualStateManager.GoToState(oldMode, "Unfocused", true);

// Reset
foreach (var column in _modesHostGrid.ColumnDefinitions)
Expand All @@ -134,8 +133,8 @@ public void ChangeMode(OmnibarMode modeToExpand, bool shouldFocus = false, bool
_modesHostGrid.ColumnDefinitions[index].Width = new(1, GridUnitType.Star);

var itemCount = Modes.Count;
var itemIndex = Modes.IndexOf(modeToExpand);
var modeButtonWidth = modeToExpand.ActualWidth;
var itemIndex = Modes.IndexOf(newMode);
var modeButtonWidth = newMode.ActualWidth;
var modeSeparatorWidth = itemCount is not 0 or 1 ? _modesHostGrid.Children[1] is FrameworkElement frameworkElement ? frameworkElement.ActualWidth : 0 : 0;

var leftPadding = (itemIndex + 1) * modeButtonWidth + modeSeparatorWidth * itemIndex;
Expand All @@ -144,51 +143,52 @@ public void ChangeMode(OmnibarMode modeToExpand, bool shouldFocus = false, bool
// Set the correct AutoSuggestBox cursor position
AutoSuggestBoxPadding = new(leftPadding, 0, rightPadding, 0);

CurrentSelectedMode = modeToExpand;

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

// Move cursor of the TextBox to the tail
_textBox.Select(_textBox.Text.Length, 0);
ChangeTextBoxText(newMode.Text ?? string.Empty);

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

if (IsFocused)
{
VisualStateManager.GoToState(CurrentSelectedMode, "Focused", true);
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
}
else if (CurrentSelectedMode?.ContentOnInactive is not null)
VisualStateManager.GoToState(newMode, "Focused", true);
newMode.IsTabStop = false;
if (newMode.IsAutoFocusEnabled)
{
VisualStateManager.GoToState(CurrentSelectedMode, "CurrentUnfocused", true);
VisualStateManager.GoToState(_textBox, "InputAreaCollapsed", true);
_textBox.Focus(FocusState.Pointer);
}
else
{
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
}

if (shouldFocus)
_textBox.Focus(FocusState.Keyboard);
if (IsFocused)
{
VisualStateManager.GoToState(newMode, "Focused", true);
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
}
else if (newMode?.ContentOnInactive is not null)
{
VisualStateManager.GoToState(newMode, "CurrentUnfocused", true);
VisualStateManager.GoToState(_textBox, "InputAreaCollapsed", true);
}
else
{
VisualStateManager.GoToState(_textBox, "InputAreaVisible", true);
}

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

// Remove the reposition transition from the all modes
if (useTransition)
foreach (var mode in Modes)
{
foreach (var mode in Modes)
{
mode.Transitions.Clear();
mode.UpdateLayout();
}
mode.Transitions.Clear();
mode.UpdateLayout();
}
}

internal protected void FocusTextBox()
{
_textBox.Focus(FocusState.Keyboard);
}

public bool TryToggleIsSuggestionsPopupOpen(bool wantToOpen)
{
if (wantToOpen && (!IsFocused || CurrentSelectedMode?.SuggestionItemsSource is null || (CurrentSelectedMode?.SuggestionItemsSource is IList collection && collection.Count is 0)))
if (wantToOpen && (!IsFocused || CurrentSelectedMode?.SuggestionItemsSource is null || (CurrentSelectedMode?.SuggestionItemsSource is IList collection && collection.Count is 0)) ||
_textBoxSuggestionsPopup is null)
return false;

_textBoxSuggestionsPopup.IsOpen = wantToOpen;
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App.Controls/Omnibar/OmnibarMode.Events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ private void ModeButton_PointerReleased(object sender, PointerRoutedEventArgs e)
VisualStateManager.GoToState(this, "PointerOver", true);

// Change the current mode
owner.ChangeMode(this);
owner.CurrentSelectedMode = this;
}

private void ModeButton_PointerExited(object sender, PointerRoutedEventArgs e)
Expand Down
3 changes: 3 additions & 0 deletions src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public partial class OmnibarMode
[GeneratedDependencyProperty(DefaultValue = true)]
public partial bool UpdateTextOnSelect { get; set; }

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

partial void OnTextChanged(string? newValue)
{
if (_ownerRef is null || _ownerRef.TryGetTarget(out var owner) is false)
Expand Down
10 changes: 3 additions & 7 deletions src/Files.App.Controls/Omnibar/OmnibarMode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ protected override void OnKeyUp(KeyRoutedEventArgs args)
VisualStateManager.GoToState(this, "PointerPressed", true);

// Change the current mode
owner.ChangeMode(this, true);
owner.CurrentSelectedMode = this;
owner.FocusTextBox();

VisualStateManager.GoToState(this, "PointerNormal", true);
}
Expand All @@ -69,19 +70,14 @@ private void OmnibarMode_Loaded(object sender, RoutedEventArgs e)
{
// Set this mode as the current mode if it is the default mode
if (IsDefault && _ownerRef is not null && _ownerRef.TryGetTarget(out var owner))
owner.ChangeMode(this);
owner.CurrentSelectedMode = this;
}

public void SetOwner(Omnibar owner)
{
_ownerRef = new(owner);
}

public void OnChangingCurrentMode(bool isCurrentMode)
{
_modeButton.IsTabStop = !isCurrentMode;
}

public override string ToString()
{
return ModeName ?? string.Empty;
Expand Down
12 changes: 9 additions & 3 deletions src/Files.App/Actions/Global/EditPathAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ namespace Files.App.Actions
{
internal sealed class EditPathAction : IAction
{
private readonly IContentPageContext context;
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
private readonly IGeneralSettingsService GeneralSettingsService = Ioc.Default.GetRequiredService<IGeneralSettingsService>();

public string Label
=> Strings.EditPath.GetLocalizedResource();
Expand All @@ -21,13 +22,18 @@ public HotKey SecondHotKey

public EditPathAction()
{
context = Ioc.Default.GetRequiredService<IContentPageContext>();

}

public Task ExecuteAsync(object? parameter = null)
{
if (context.ShellPage is not null)
context.ShellPage.ToolbarViewModel.IsEditModeEnabled = true;
{
if (GeneralSettingsService.EnableOmnibar)
context.ShellPage!.ToolbarViewModel.SwitchToPathMode();
else
context.ShellPage.ToolbarViewModel.IsEditModeEnabled = true;
}

return Task.CompletedTask;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Actions/Global/SearchAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public SearchAction()

public Task ExecuteAsync(object? parameter = null)
{
context.ShellPage!.ToolbarViewModel.SwitchSearchBoxVisibility();
context.ShellPage!.ToolbarViewModel.SwitchToSearchMode();

return Task.CompletedTask;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Actions/Open/OpenCommandPaletteAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public OpenCommandPaletteAction()

public Task ExecuteAsync(object? parameter = null)
{
_context.ShellPage?.ToolbarViewModel.OpenCommandPalette();
_context.ShellPage?.ToolbarViewModel.SwitchToCommandPaletteMode();

return Task.CompletedTask;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Files.App/Data/Contracts/IAddressToolbarViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public interface IAddressToolbarViewModel

public event EventHandler RefreshWidgetsRequested;

public void SwitchSearchBoxVisibility();
public void SwitchToSearchMode();

public ISearchBoxViewModel SearchBox { get; }
}
Expand Down
4 changes: 3 additions & 1 deletion src/Files.App/UserControls/NavigationToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -321,9 +321,9 @@
Grid.Column="1"
x:Load="{x:Bind ViewModel.EnableOmnibar, Mode=OneWay}"
CurrentSelectedMode="{x:Bind ViewModel.OmnibarCurrentSelectedMode, Mode=TwoWay}"
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
Expand Down Expand Up @@ -367,6 +367,7 @@
x:Name="OmnibarCommandPaletteMode"
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IsFilled=True}"
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Commands}, IconType=Outline}"
IsAutoFocusEnabled="True"
ModeName="{x:Bind Commands.OpenCommandPalette.LabelWithHotKey, Mode=OneWay}"
PlaceholderText="{helpers:ResourceString Name=OmnibarCommandPaletteModeTextPlaceholder}"
SuggestionItemsSource="{x:Bind ViewModel.OmnibarCommandPaletteModeSuggestionItems, Mode=OneWay}"
Expand Down Expand Up @@ -418,6 +419,7 @@
x:Name="OmnibarSearchMode"
IconOnActive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Search}, IsFilled=True}"
IconOnInactive="{controls:ThemedIconMarkup Style={StaticResource App.ThemedIcons.Omnibar.Search}, IconType=Outline}"
IsAutoFocusEnabled="True"
ModeName="{x:Bind Commands.Search.LabelWithHotKey, Mode=OneWay}"
PlaceholderText="{helpers:ResourceString Name=OmnibarSearchModeTextPlaceholder}" />

Expand Down
Loading
Loading