Skip to content

Commit fac8079

Browse files
committed
Improved the implementation
1 parent 851e7ae commit fac8079

File tree

9 files changed

+201
-62
lines changed

9 files changed

+201
-62
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ public partial class Omnibar
1616
{
1717
[GeneratedDependencyProperty]
1818
public partial IList<OmnibarMode>? Modes { get; set; }
19+
20+
[GeneratedDependencyProperty]
21+
public partial OmnibarMode? CurrentActiveMode { get; set; }
1922
}
2023
}

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

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using CommunityToolkit.WinUI;
45
using Microsoft.UI.Xaml;
56
using Microsoft.UI.Xaml.Controls;
67
using Microsoft.UI.Xaml.Media;
@@ -17,12 +18,17 @@ namespace Files.App.Controls
1718
[TemplatePart(Name = "PART_ModesHostGrid", Type = typeof(Grid))]
1819
// Visual states
1920
[TemplateVisualState(Name = "Focused", GroupName = "FocusStates")]
20-
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
21+
[TemplateVisualState(Name = "Normal", GroupName = "FocusStates")]
2122
public partial class Omnibar : Control
2223
{
2324
private const string ModesHostGrid = "PART_ModesHostGrid";
25+
private const string AutoSuggestPopup = "PART_AutoSuggestPopup";
26+
private const string AutoSuggestBoxBorder = "PART_AutoSuggestBoxBorder";
2427

2528
private Grid? _modesHostGrid;
29+
private Popup? _autoSuggestPopup;
30+
private Border? _autoSuggestBoxBorder;
31+
private bool _wasAscendantFocused;
2632
private bool _isFocused;
2733

2834
public Omnibar()
@@ -36,11 +42,19 @@ protected override void OnApplyTemplate()
3642
{
3743
_modesHostGrid = GetTemplateChild(ModesHostGrid) as Grid
3844
?? throw new MissingFieldException($"Could not find {ModesHostGrid} in the given {nameof(Omnibar)}'s style.");
45+
_autoSuggestPopup = GetTemplateChild(AutoSuggestPopup) as Popup
46+
?? throw new MissingFieldException($"Could not find {AutoSuggestPopup} in the given {nameof(Omnibar)}'s style.");
47+
_autoSuggestBoxBorder = GetTemplateChild(AutoSuggestBoxBorder) as Border
48+
?? throw new MissingFieldException($"Could not find {AutoSuggestBoxBorder} in the given {nameof(Omnibar)}'s style.");
3949

4050
if (Modes is null)
4151
return;
4252

43-
// Populate the modes1
53+
// Add shadow to the popup and set the proper width
54+
_autoSuggestBoxBorder!.Translation = new(0, 0, 32);
55+
_autoSuggestBoxBorder!.Width = _modesHostGrid!.ActualWidth;
56+
57+
// Populate the modes
4458
foreach (var mode in Modes)
4559
{
4660
// Insert a divider
@@ -63,9 +77,13 @@ protected override void OnApplyTemplate()
6377
_modesHostGrid.ColumnDefinitions.Add(new() { Width = GridLength.Auto });
6478
Grid.SetColumn(mode, _modesHostGrid.Children.Count);
6579
_modesHostGrid.Children.Add(mode);
66-
mode.Host = _modesHostGrid;
80+
mode.Host = this;
6781
}
6882

83+
_modesHostGrid.SizeChanged += _modesHostGrid_SizeChanged;
84+
85+
var parentElement = this.FindAscendant<FrameworkElement>()!;
86+
parentElement.PointerPressed += ParentElement_PointerPressed;
6987
GotFocus += Omnibar_GotFocus;
7088
LostFocus += Omnibar_LostFocus;
7189

@@ -74,7 +92,29 @@ protected override void OnApplyTemplate()
7492
base.OnApplyTemplate();
7593
}
7694

77-
// Private methods
95+
// Methods
96+
97+
internal void ChangeExpandedMode(OmnibarMode modeToExpand)
98+
{
99+
if (_modesHostGrid is null || Modes is null)
100+
throw new NullReferenceException();
101+
102+
// Reset
103+
foreach (var column in _modesHostGrid.ColumnDefinitions)
104+
column.Width = GridLength.Auto;
105+
foreach (var mode in Modes)
106+
{
107+
VisualStateManager.GoToState(mode, "InactiveIcon", true);
108+
VisualStateManager.GoToState(mode, "Collapsed", true);
109+
}
110+
111+
// Expand the given mode
112+
VisualStateManager.GoToState(modeToExpand, "ActiveIcon", true);
113+
VisualStateManager.GoToState(modeToExpand, "Visible", true);
114+
_modesHostGrid.ColumnDefinitions[_modesHostGrid.Children.IndexOf(modeToExpand)].Width = new(1, GridUnitType.Star);
115+
116+
CurrentActiveMode = modeToExpand;
117+
}
78118

79119
private void UpdateVisualStates()
80120
{
@@ -86,16 +126,45 @@ private void UpdateVisualStates()
86126

87127
// Events
88128

129+
private void _modesHostGrid_SizeChanged(object sender, SizeChangedEventArgs e)
130+
{
131+
_autoSuggestBoxBorder!.Width = _modesHostGrid!.ActualWidth;
132+
}
133+
134+
private void ParentElement_PointerPressed(object sender, PointerRoutedEventArgs e)
135+
{
136+
// Lost focus
137+
if (_isFocused)
138+
{
139+
_isFocused = _wasAscendantFocused = false;
140+
UpdateVisualStates();
141+
142+
return;
143+
}
144+
145+
_wasAscendantFocused = true;
146+
}
147+
89148
private void Omnibar_GotFocus(object sender, RoutedEventArgs e)
90149
{
150+
if (_wasAscendantFocused)
151+
{
152+
_isFocused = _wasAscendantFocused = false;
153+
return;
154+
}
155+
91156
_isFocused = true;
92157
UpdateVisualStates();
158+
159+
_autoSuggestPopup!.IsOpen = true;
93160
}
94161

95162
private void Omnibar_LostFocus(object sender, RoutedEventArgs e)
96163
{
97-
_isFocused = false;
164+
_isFocused = _wasAscendantFocused = false;
98165
UpdateVisualStates();
166+
167+
_autoSuggestPopup!.IsOpen = false;
99168
}
100169
}
101170
}

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

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,56 @@
4040
<Setter Property="Template">
4141
<Setter.Value>
4242
<ControlTemplate TargetType="local:Omnibar">
43-
<Grid
44-
x:Name="PART_RootGrid"
45-
Padding="{TemplateBinding Padding}"
46-
Background="{TemplateBinding Background}"
47-
BorderBrush="{TemplateBinding BorderBrush}"
48-
BorderThickness="{TemplateBinding BorderThickness}"
49-
CornerRadius="{TemplateBinding CornerRadius}">
50-
<Grid x:Name="PART_ModesHostGrid" />
43+
<Grid x:Name="PART_RootGrid">
44+
<Grid.RowDefinitions>
45+
<RowDefinition Height="Auto" />
46+
<RowDefinition Height="Auto" />
47+
</Grid.RowDefinitions>
48+
<!-- input area -->
49+
<Grid
50+
x:Name="PART_ModesHostGrid"
51+
Grid.Row="0"
52+
Margin="{TemplateBinding Padding}"
53+
Background="{TemplateBinding Background}"
54+
BorderBrush="{TemplateBinding BorderBrush}"
55+
BorderThickness="{TemplateBinding BorderThickness}"
56+
CornerRadius="{TemplateBinding CornerRadius}" />
57+
58+
<!-- Auto-suggest box area -->
59+
<Popup
60+
x:Name="PART_AutoSuggestPopup"
61+
Grid.Row="1"
62+
HorizontalAlignment="Stretch"
63+
ShouldConstrainToRootBounds="False">
64+
65+
<Border
66+
x:Name="PART_AutoSuggestBoxBorder"
67+
Padding="8"
68+
Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
69+
BorderBrush="{ThemeResource SurfaceStrokeColorFlyoutBrush}"
70+
BorderThickness="1"
71+
CornerRadius="{ThemeResource OverlayCornerRadius}">
72+
<Border.Shadow>
73+
<ThemeShadow />
74+
</Border.Shadow>
75+
76+
<ListView
77+
HorizontalAlignment="Stretch"
78+
IsItemClickEnabled="True"
79+
ItemTemplate="{Binding CurrentActiveMode.SuggestionItemTemplate, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
80+
81+
</Border>
82+
</Popup>
5183

5284
<VisualStateManager.VisualStateGroups>
5385

5486
<VisualStateGroup x:Name="PointerStates">
5587
<VisualState x:Name="Normal" />
5688
<VisualState x:Name="Focused">
5789
<VisualState.Setters>
58-
<Setter Target="PART_RootGrid.BorderBrush" Value="{ThemeResource AccentFillColorDefaultBrush}" />
59-
<Setter Target="PART_RootGrid.BorderThickness" Value="{StaticResource OmnibarFocusedBorderThickness}" />
60-
<Setter Target="PART_RootGrid.Margin" Value="-1" />
90+
<Setter Target="PART_ModesHostGrid.BorderBrush" Value="{ThemeResource AccentFillColorDefaultBrush}" />
91+
<Setter Target="PART_ModesHostGrid.BorderThickness" Value="{StaticResource OmnibarFocusedBorderThickness}" />
92+
<Setter Target="PART_ModesHostGrid.Margin" Value="-1" />
6193
</VisualState.Setters>
6294
</VisualState>
6395
</VisualStateGroup>

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

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

20+
[GeneratedDependencyProperty]
21+
public partial string? TextPlaceholder { get; set; }
22+
23+
[GeneratedDependencyProperty]
24+
public partial string? ToolTip { get; set; }
25+
2026
[GeneratedDependencyProperty]
2127
public partial bool HideContentOnInactive { get; set; }
2228

@@ -33,11 +39,6 @@ public partial class OmnibarMode
3339
public partial bool IsDefault { get; set; }
3440

3541
[GeneratedDependencyProperty]
36-
internal partial Grid? Host { get; set; }
37-
38-
partial void OnHostChanged(Grid? newValue)
39-
{
40-
UpdateVisualStates();
41-
}
42+
internal partial Omnibar? Host { get; set; }
4243
}
4344
}

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

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

1111
namespace Files.App.Controls
1212
{
13+
// Template parts
14+
[TemplatePart(Name = "PART_ModeClickBorder", Type = typeof(Border))]
15+
[TemplatePart(Name = "PART_ModeIconPresenter", Type = typeof(ContentPresenter))]
16+
[TemplatePart(Name = "PART_InputTextBox", Type = typeof(TextBox))]
17+
// Visual states
18+
[TemplateVisualState(GroupName = "CommonStates", Name = "PointerNormal")]
19+
[TemplateVisualState(GroupName = "CommonStates", Name = "PointerOver")]
20+
[TemplateVisualState(GroupName = "CommonStates", Name = "PointerPressed")]
21+
[TemplateVisualState(GroupName = "CommonStates", Name = "Focused")]
22+
[TemplateVisualState(GroupName = "InputVisibilityStates", Name = "Collapsed")]
23+
[TemplateVisualState(GroupName = "InputVisibilityStates", Name = "Visible")]
24+
[TemplateVisualState(GroupName = "IconStates", Name = "InactiveIcon")]
25+
[TemplateVisualState(GroupName = "IconStates", Name = "ActiveIcon")]
1326
public partial class OmnibarMode : Control
1427
{
1528
private const string ModeClickBorder = "PART_ModeClickBorder";
@@ -33,6 +46,9 @@ protected override void OnApplyTemplate()
3346
_inputTextBox = GetTemplateChild(InputTextBox) as TextBox
3447
?? throw new MissingFieldException($"Could not find {InputTextBox} in the given {nameof(OmnibarMode)}'s style.");
3548

49+
if (IsDefault)
50+
Host!.ChangeExpandedMode(this);
51+
3652
UpdateVisualStates();
3753

3854
_modeClickArea.PointerEntered += OmnibarMode_PointerEntered;
@@ -49,12 +65,6 @@ private void UpdateVisualStates()
4965
this,
5066
_isPressed ? "PointerPressed" : _isHoveredOver ? "PointerOver" : "PointerNormal",
5167
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-
}
5868
}
5969

6070
// Events
@@ -78,6 +88,9 @@ private void OmnibarMode_PointerReleased(object sender, PointerRoutedEventArgs e
7888
_isHoveredOver = true;
7989
_isPressed = false;
8090
UpdateVisualStates();
91+
92+
if (Host!.CurrentActiveMode == this)
93+
Host.ChangeExpandedMode(this);
8194
}
8295

8396
private void OmnibarMode_PointerExited(object sender, PointerRoutedEventArgs e)

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

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,26 @@
3333
Width="{StaticResource OmnibarModeDefaultClickAreaWidth}"
3434
Height="{TemplateBinding Height}"
3535
Background="Transparent"
36-
CornerRadius="{TemplateBinding CornerRadius}">
36+
CornerRadius="{TemplateBinding CornerRadius}"
37+
ToolTipService.ToolTip="{Binding ToolTip, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">
3738
<Border.BackgroundTransition>
3839
<BrushTransition Duration="0:0:0.083" />
3940
</Border.BackgroundTransition>
4041

41-
<ContentPresenter HorizontalAlignment="Center" Content="{TemplateBinding IconOnInactive}" />
42+
<ContentPresenter
43+
x:Name="PART_ModeIconPresenter"
44+
HorizontalAlignment="Center"
45+
VerticalAlignment="Center"
46+
Content="{Binding IconOnInactive, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
4247
</Border>
4348

4449
<TextBox
4550
x:Name="PART_InputTextBox"
4651
Grid.Column="1"
4752
HorizontalAlignment="Stretch"
4853
HorizontalContentAlignment="Stretch"
54+
PlaceholderText="{TemplateBinding TextPlaceholder}"
55+
Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
4956
Visibility="Collapsed">
5057
<TextBox.Resources>
5158
<SolidColorBrush x:Key="TextControlBackground" Color="Transparent" />
@@ -64,7 +71,7 @@
6471

6572
<VisualStateManager.VisualStateGroups>
6673

67-
<VisualStateGroup x:Name="CommonStates">
74+
<VisualStateGroup x:Name="PointerStates">
6875
<VisualState x:Name="PointerNormal" />
6976
<VisualState x:Name="PointerOver">
7077
<VisualState.Setters>
@@ -74,19 +81,29 @@
7481
<VisualState x:Name="PointerPressed">
7582
<VisualState.Setters>
7683
<Setter Target="PART_ModeClickBorder.Background" Value="{ThemeResource SubtleFillColorSecondaryBrush}" />
84+
<Setter Target="PART_ModeIconPresenter.Content" Value="{Binding IconOnActive, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
7785
</VisualState.Setters>
7886
</VisualState>
7987
</VisualStateGroup>
8088

8189
<VisualStateGroup x:Name="InputVisibilityStates">
82-
<VisualState x:Name="Hidden" />
90+
<VisualState x:Name="Collapsed" />
8391
<VisualState x:Name="Visible">
8492
<VisualState.Setters>
8593
<Setter Target="PART_InputTextBox.Visibility" Value="Visible" />
8694
</VisualState.Setters>
8795
</VisualState>
8896
</VisualStateGroup>
8997

98+
<VisualStateGroup x:Name="IconStates">
99+
<VisualState x:Name="InactiveIcon" />
100+
<VisualState x:Name="ActiveIcon">
101+
<VisualState.Setters>
102+
<Setter Target="PART_ModeIconPresenter.Content" Value="{Binding IconOnActive, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
103+
</VisualState.Setters>
104+
</VisualState>
105+
</VisualStateGroup>
106+
90107
</VisualStateManager.VisualStateGroups>
91108
</Grid>
92109
</ControlTemplate>

src/Files.App.Controls/ThemedIcon/ThemedIcon.Properties.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ protected virtual void OnIconColorTypePropertyChanged(ThemedIconColorType oldVal
4848
protected virtual void OnIconSizePropertyChanged(double oldValue, double newValue)
4949
{
5050
UpdateVisualStates();
51+
OnIconSizeChanged();
5152
}
5253

5354
protected virtual void OnIsToggledPropertyChanged(bool oldValue, bool newValue)

src/Files.App.Controls/ThemedIcon/ThemedIcon.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ protected override void OnApplyTemplate()
4343

4444
OnIconTypeChanged();
4545
OnIconColorTypeChanged();
46+
OnIconSizeChanged();
4647
}
4748

4849
private void GetTemplateParts()
@@ -249,5 +250,10 @@ private void OnIconColorChanged()
249250
if (GetTemplateChild(FilledIconPath) is Path fillPath)
250251
fillPath.Fill = (Brush)this.GetValue(ColorProperty);
251252
}
253+
254+
private void OnIconSizeChanged()
255+
{
256+
Height = Width = IconSize;
257+
}
252258
}
253259
}

0 commit comments

Comments
 (0)