Skip to content

Commit f79243a

Browse files
committed
Fix the focus issue partly
There still are two issues: - Even if you try to unfocus clicking on the parent control, Omnibar still has focus - Pressing on a mode control may lose Omnibar's focus
1 parent 38663aa commit f79243a

File tree

5 files changed

+74
-26
lines changed

5 files changed

+74
-26
lines changed

src/Files.App.Controls/Omnibar/Omnibar.cs

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ namespace Files.App.Controls
1818
[TemplatePart(Name = "PART_ModesHostGrid", Type = typeof(Grid))]
1919
// Visual states
2020
[TemplateVisualState(Name = "Focused", GroupName = "FocusStates")]
21-
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
21+
[TemplateVisualState(Name = "Normal", GroupName = "FocusStates")]
2222
public partial class Omnibar : Control
2323
{
2424
private const string ModesHostGrid = "PART_ModesHostGrid";
2525

2626
private Grid? _modesHostGrid;
27+
private bool _wasAscendantFocused;
2728
private bool _isFocused;
2829

2930
public Omnibar()
@@ -64,13 +65,12 @@ protected override void OnApplyTemplate()
6465
_modesHostGrid.ColumnDefinitions.Add(new() { Width = GridLength.Auto });
6566
Grid.SetColumn(mode, _modesHostGrid.Children.Count);
6667
_modesHostGrid.Children.Add(mode);
67-
mode.Host = _modesHostGrid;
68+
mode.Host = this;
6869
}
6970

7071
var parentElement = this.FindAscendant<FrameworkElement>()!;
71-
parentElement.GettingFocus += ParentElement_GettingFocus;
72-
parentElement.GotFocus += ParentElement_GotFocus;
73-
GettingFocus += Omnibar_GettingFocus;
72+
parentElement.PointerPressed += ParentElement_PointerPressed;
73+
7474
GotFocus += Omnibar_GotFocus;
7575
LostFocus += Omnibar_LostFocus;
7676

@@ -79,7 +79,23 @@ protected override void OnApplyTemplate()
7979
base.OnApplyTemplate();
8080
}
8181

82-
// Private methods
82+
// Methods
83+
84+
internal void ChangeExpandedMode(OmnibarMode modeToExpand)
85+
{
86+
if (_modesHostGrid is null || Modes is null)
87+
throw new NullReferenceException();
88+
89+
// Reset
90+
foreach (var column in _modesHostGrid.ColumnDefinitions)
91+
column.Width = GridLength.Auto;
92+
foreach (var mode in Modes)
93+
VisualStateManager.GoToState(mode, "Collapsed", true);
94+
95+
// Expand the given mode
96+
VisualStateManager.GoToState(modeToExpand, "Visible", true);
97+
_modesHostGrid.ColumnDefinitions[_modesHostGrid.Children.IndexOf(modeToExpand)].Width = new(1, GridUnitType.Star);
98+
}
8399

84100
private void UpdateVisualStates()
85101
{
@@ -91,27 +107,35 @@ private void UpdateVisualStates()
91107

92108
// Events
93109

94-
private void Omnibar_GettingFocus(UIElement sender, GettingFocusEventArgs args)
110+
private void ParentElement_PointerPressed(object sender, PointerRoutedEventArgs e)
95111
{
96-
}
112+
// Lost focus
113+
if (_isFocused)
114+
{
115+
_isFocused = _wasAscendantFocused = false;
116+
UpdateVisualStates();
97117

98-
private void ParentElement_GettingFocus(UIElement sender, GettingFocusEventArgs args)
99-
{
100-
}
118+
return;
119+
}
101120

102-
private void ParentElement_GotFocus(object sender, RoutedEventArgs e)
103-
{
121+
_wasAscendantFocused = true;
104122
}
105123

106124
private void Omnibar_GotFocus(object sender, RoutedEventArgs e)
107125
{
126+
if (_wasAscendantFocused)
127+
{
128+
_isFocused = _wasAscendantFocused = false;
129+
return;
130+
}
131+
108132
_isFocused = true;
109133
UpdateVisualStates();
110134
}
111135

112136
private void Omnibar_LostFocus(object sender, RoutedEventArgs e)
113137
{
114-
_isFocused = false;
138+
_isFocused = _wasAscendantFocused = false;
115139
UpdateVisualStates();
116140
}
117141
}

src/Files.App.Controls/Omnibar/OmnibarMode.Properties.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public partial class OmnibarMode
1717
[GeneratedDependencyProperty]
1818
public partial string? Text { get; set; }
1919

20+
[GeneratedDependencyProperty]
21+
public partial string? TextPlaceholder { get; set; }
22+
2023
[GeneratedDependencyProperty]
2124
public partial bool HideContentOnInactive { get; set; }
2225

@@ -33,9 +36,18 @@ public partial class OmnibarMode
3336
public partial bool IsDefault { get; set; }
3437

3538
[GeneratedDependencyProperty]
36-
internal partial Grid? Host { get; set; }
39+
internal partial Omnibar? Host { get; set; }
40+
41+
[GeneratedDependencyProperty]
42+
internal partial bool IsHostFocused { get; set; }
43+
44+
//partial void OnHostChanged(Grid? newValue)
45+
//{
46+
// if (_isHostInitialized)
47+
// throw new InvalidOperationException("Host is already set and cannot be changed again.");
48+
//}
3749

38-
partial void OnHostChanged(Grid? newValue)
50+
partial void OnIsHostFocusedChanged(bool newValue)
3951
{
4052
UpdateVisualStates();
4153
}

src/Files.App.Controls/Omnibar/OmnibarMode.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
namespace Files.App.Controls
1212
{
13+
// Template parts
14+
[TemplatePart(Name = "PART_ModeClickBorder", Type = typeof(Border))]
15+
[TemplatePart(Name = "PART_InputTextBox", Type = typeof(TextBox))]
16+
// Visual states
17+
[TemplateVisualState(Name = "Collapsed", GroupName = "InputVisibilityStates")]
18+
[TemplateVisualState(Name = "Visible", GroupName = "InputVisibilityStates")]
1319
public partial class OmnibarMode : Control
1420
{
1521
private const string ModeClickBorder = "PART_ModeClickBorder";
@@ -18,6 +24,7 @@ public partial class OmnibarMode : Control
1824
private Border? _modeClickArea;
1925
private TextBox? _inputTextBox;
2026

27+
private bool _isHostInitialized;
2128
private bool _isHoveredOver;
2229
private bool _isPressed;
2330

@@ -33,6 +40,9 @@ protected override void OnApplyTemplate()
3340
_inputTextBox = GetTemplateChild(InputTextBox) as TextBox
3441
?? throw new MissingFieldException($"Could not find {InputTextBox} in the given {nameof(OmnibarMode)}'s style.");
3542

43+
if (IsDefault)
44+
Host!.ChangeExpandedMode(this);
45+
3646
UpdateVisualStates();
3747

3848
_modeClickArea.PointerEntered += OmnibarMode_PointerEntered;
@@ -49,12 +59,6 @@ private void UpdateVisualStates()
4959
this,
5060
_isPressed ? "PointerPressed" : _isHoveredOver ? "PointerOver" : "PointerNormal",
5161
true);
52-
53-
if (IsDefault && Host is not null)
54-
{
55-
VisualStateManager.GoToState(this, "Visible",true);
56-
Host.ColumnDefinitions[Host.Children.IndexOf(this)].Width = new(1, GridUnitType.Star);
57-
}
5862
}
5963

6064
// Events
@@ -78,6 +82,8 @@ private void OmnibarMode_PointerReleased(object sender, PointerRoutedEventArgs e
7882
_isHoveredOver = true;
7983
_isPressed = false;
8084
UpdateVisualStates();
85+
86+
Host!.ChangeExpandedMode(this);
8187
}
8288

8389
private void OmnibarMode_PointerExited(object sender, PointerRoutedEventArgs e)

src/Files.App.Controls/Omnibar/OmnibarMode.xaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
Grid.Column="1"
4747
HorizontalAlignment="Stretch"
4848
HorizontalContentAlignment="Stretch"
49+
PlaceholderText="{TemplateBinding TextPlaceholder}"
50+
Text="{TemplateBinding Text}"
4951
Visibility="Collapsed">
5052
<TextBox.Resources>
5153
<SolidColorBrush x:Key="TextControlBackground" Color="Transparent" />
@@ -79,7 +81,7 @@
7981
</VisualStateGroup>
8082

8183
<VisualStateGroup x:Name="InputVisibilityStates">
82-
<VisualState x:Name="Hidden" />
84+
<VisualState x:Name="Collapsed" />
8385
<VisualState x:Name="Visible">
8486
<VisualState.Setters>
8587
<Setter Target="PART_InputTextBox.Visibility" Value="Visible" />

tests/Files.App.UITests/Views/OmnibarPage.xaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@
6767
<controls:OmnibarMode
6868
HideContentOnInactive="True"
6969
IsDefault="True"
70-
Text="A">
70+
Text="Path..."
71+
TextPlaceholder="Enter text...">
7172
<controls:OmnibarMode.IconOnActive>
7273
<controls:ThemedIcon
7374
Width="16"
@@ -82,7 +83,10 @@
8283
Style="{StaticResource App.ThemedIcons.Omnibar.Path}" />
8384
</controls:OmnibarMode.IconOnInactive>
8485
</controls:OmnibarMode>
85-
<controls:OmnibarMode HideContentOnInactive="True" Text="B">
86+
<controls:OmnibarMode
87+
HideContentOnInactive="True"
88+
Text="Palette..."
89+
TextPlaceholder="Enter a palette command...">
8690
<controls:OmnibarMode.IconOnActive>
8791
<controls:ThemedIcon
8892
Width="16"
@@ -97,7 +101,7 @@
97101
Style="{StaticResource App.ThemedIcons.Omnibar.Commands}" />
98102
</controls:OmnibarMode.IconOnInactive>
99103
</controls:OmnibarMode>
100-
<controls:OmnibarMode Text="C">
104+
<controls:OmnibarMode Text="Search..." TextPlaceholder="Enter a search query...">
101105
<controls:OmnibarMode.IconOnActive>
102106
<controls:ThemedIcon
103107
Width="16"

0 commit comments

Comments
 (0)