Skip to content

Commit 880900f

Browse files
0x5bfayaira2
andauthored
Feature: Added Tab Actions menu to the title bar (#15653)
Co-authored-by: Yair <39923744+yaira2@users.noreply.github.com>
1 parent ce5453a commit 880900f

File tree

5 files changed

+261
-63
lines changed

5 files changed

+261
-63
lines changed

src/Files.App/Strings/en-US/Resources.resw

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,4 +3866,7 @@
38663866
<value>Show Toolbar</value>
38673867
<comment>Setting that controls if the Toolbar is shown in the main view</comment>
38683868
</data>
3869+
<data name="TabActions" xml:space="preserve">
3870+
<value>Tab actions menu</value>
3871+
</data>
38693872
</root>

src/Files.App/UserControls/InnerNavigationToolbar.xaml

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,67 +1215,6 @@
12151215
Visibility="{x:Bind ShowPreviewPaneButton, Mode=OneWay}">
12161216
<local:OpacityIcon IsSelected="{x:Bind Commands.ToggleInfoPane.IsOn, Mode=OneWay}" Style="{x:Bind Commands.ToggleInfoPane.OpacityStyle}" />
12171217
</AppBarToggleButton>
1218-
1219-
<!-- 3 Dots Commands -->
1220-
<CommandBar.SecondaryCommands>
1221-
1222-
<!-- Workaround to enable displaying OpacityIcons in the menu -->
1223-
<AppBarButton Visibility="Collapsed">
1224-
<AppBarButton.Icon>
1225-
<FontIcon Glyph="&#xE737;" />
1226-
</AppBarButton.Icon>
1227-
</AppBarButton>
1228-
1229-
<!-- Open New Pane -->
1230-
<AppBarButton
1231-
x:Name="NavToolbarNewPane"
1232-
x:Load="{x:Bind Commands.OpenNewPane.IsExecutable, Mode=OneWay}"
1233-
Command="{x:Bind Commands.OpenNewPane, Mode=OneWay}"
1234-
Label="{x:Bind Commands.OpenNewPane.Label}"
1235-
ToolTipService.ToolTip="{x:Bind Commands.OpenNewPane.LabelWithHotKey, Mode=OneWay}">
1236-
<local:OpacityIcon Style="{x:Bind Commands.OpenNewPane.OpacityStyle}" />
1237-
</AppBarButton>
1238-
1239-
<!-- Close Active Pane -->
1240-
<AppBarButton
1241-
x:Name="NavToolbarCloseActivePane"
1242-
x:Load="{x:Bind Commands.CloseActivePane.IsExecutable, Mode=OneWay}"
1243-
Command="{x:Bind Commands.CloseActivePane, Mode=OneWay}"
1244-
Label="{x:Bind Commands.CloseActivePane.Label}"
1245-
ToolTipService.ToolTip="{x:Bind Commands.CloseActivePane.LabelWithHotKey, Mode=OneWay}">
1246-
<AppBarButton.Icon>
1247-
<FontIcon Foreground="{ThemeResource App.Theme.IconBaseBrush}" Glyph="{x:Bind Commands.CloseActivePane.Glyph.BaseGlyph}" />
1248-
</AppBarButton.Icon>
1249-
</AppBarButton>
1250-
1251-
<!-- New Window -->
1252-
<AppBarButton
1253-
x:Name="NavToolbarNewWindow"
1254-
Command="{x:Bind Commands.NewWindow, Mode=OneWay}"
1255-
KeyboardAcceleratorTextOverride="{x:Bind Commands.NewWindow.HotKeyText, Mode=OneWay}"
1256-
Label="{x:Bind Commands.NewWindow.Label}">
1257-
<local:OpacityIcon Style="{x:Bind Commands.NewWindow.OpacityStyle}" />
1258-
</AppBarButton>
1259-
1260-
<!-- Exter Compact Overlay -->
1261-
<AppBarButton
1262-
x:Name="NavToolbarEnterCompactOverlay"
1263-
x:Load="{x:Bind Commands.EnterCompactOverlay.IsExecutable, Mode=OneWay}"
1264-
Command="{x:Bind Commands.EnterCompactOverlay}"
1265-
Label="{x:Bind Commands.EnterCompactOverlay.Label}">
1266-
<local:OpacityIcon Style="{x:Bind Commands.EnterCompactOverlay.OpacityStyle}" />
1267-
</AppBarButton>
1268-
1269-
<!-- Exit Compact Overlay -->
1270-
<AppBarButton
1271-
x:Name="NavToolbarExitCompactOverlay"
1272-
x:Load="{x:Bind Commands.ExitCompactOverlay.IsExecutable, Mode=OneWay}"
1273-
Command="{x:Bind Commands.ExitCompactOverlay}"
1274-
Label="{x:Bind Commands.ExitCompactOverlay.Label}">
1275-
<local:OpacityIcon Style="{x:Bind Commands.ExitCompactOverlay.OpacityStyle}" />
1276-
</AppBarButton>
1277-
1278-
</CommandBar.SecondaryCommands>
12791218
</CommandBar>
12801219

12811220
</Grid>
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<!-- Copyright (c) 2024 Files Community. Licensed under the MIT License. See the LICENSE. -->
2+
<MenuFlyoutItem
3+
x:Class="Files.App.UserControls.MenuFlyoutItemWithOpacityIcon"
4+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:local="using:Files.App.UserControls"
8+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9+
d:DesignHeight="300"
10+
d:DesignWidth="400"
11+
HighContrastAdjustment="None"
12+
mc:Ignorable="d">
13+
14+
<MenuFlyoutItem.Style>
15+
<Style TargetType="local:MenuFlyoutItemWithOpacityIcon">
16+
<Setter Property="Padding" Value="{ThemeResource MenuFlyoutItemThemePadding}" />
17+
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
18+
<Setter Property="Template">
19+
<Setter.Value>
20+
<ControlTemplate TargetType="local:MenuFlyoutItemWithOpacityIcon">
21+
22+
<Grid
23+
x:Name="LayoutRoot"
24+
Margin="{StaticResource MenuFlyoutItemMargin}"
25+
Padding="{TemplateBinding Padding}"
26+
Background="{TemplateBinding Background}"
27+
BorderBrush="{TemplateBinding BorderBrush}"
28+
BorderThickness="{TemplateBinding BorderThickness}"
29+
CornerRadius="{StaticResource ControlCornerRadius}">
30+
<Grid.ColumnDefinitions>
31+
<ColumnDefinition Width="*" />
32+
<ColumnDefinition Width="Auto" />
33+
</Grid.ColumnDefinitions>
34+
35+
<Viewbox
36+
x:Name="IconRoot"
37+
Width="16"
38+
Height="16"
39+
HorizontalAlignment="Left"
40+
VerticalAlignment="Center"
41+
Visibility="Collapsed">
42+
<ContentPresenter x:Name="IconContent" Content="{TemplateBinding Icon}" />
43+
</Viewbox>
44+
45+
<Viewbox
46+
Width="16"
47+
Height="16"
48+
Margin="0"
49+
HorizontalAlignment="Left"
50+
VerticalAlignment="Center">
51+
<local:OpacityIcon Style="{TemplateBinding OpacityStyle}" />
52+
</Viewbox>
53+
54+
<TextBlock
55+
x:Name="TextBlock"
56+
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
57+
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
58+
Foreground="{TemplateBinding Foreground}"
59+
Text="{TemplateBinding Text}"
60+
TextTrimming="Clip" />
61+
62+
<TextBlock
63+
x:Name="KeyboardAcceleratorTextBlock"
64+
Grid.Column="1"
65+
MinWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.KeyboardAcceleratorTextMinWidth}"
66+
Margin="24,0,0,0"
67+
HorizontalAlignment="Right"
68+
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
69+
AutomationProperties.AccessibilityView="Raw"
70+
Foreground="{ThemeResource MenuFlyoutItemKeyboardAcceleratorTextForeground}"
71+
Style="{ThemeResource CaptionTextBlockStyle}"
72+
Text="{TemplateBinding KeyboardAcceleratorTextOverride}"
73+
Visibility="Collapsed" />
74+
75+
<VisualStateManager.VisualStateGroups>
76+
<VisualStateGroup x:Name="CommonStates">
77+
<VisualState x:Name="Normal" />
78+
<VisualState x:Name="PointerOver">
79+
<VisualState.Setters>
80+
<Setter Target="LayoutRoot.Background" Value="{ThemeResource MenuFlyoutItemBackgroundPointerOver}" />
81+
<Setter Target="TextBlock.Foreground" Value="{ThemeResource MenuFlyoutItemForegroundPointerOver}" />
82+
<Setter Target="IconContent.Foreground" Value="{ThemeResource MenuFlyoutItemForegroundPointerOver}" />
83+
<Setter Target="KeyboardAcceleratorTextBlock.Foreground" Value="{ThemeResource MenuFlyoutItemKeyboardAcceleratorTextForegroundPointerOver}" />
84+
</VisualState.Setters>
85+
</VisualState>
86+
<VisualState x:Name="Pressed">
87+
<VisualState.Setters>
88+
<Setter Target="LayoutRoot.Background" Value="{ThemeResource MenuFlyoutItemBackgroundPressed}" />
89+
<Setter Target="TextBlock.Foreground" Value="{ThemeResource MenuFlyoutItemForegroundPressed}" />
90+
<Setter Target="IconContent.Foreground" Value="{ThemeResource MenuFlyoutItemForegroundPressed}" />
91+
<Setter Target="KeyboardAcceleratorTextBlock.Foreground" Value="{ThemeResource MenuFlyoutItemKeyboardAcceleratorTextForegroundPressed}" />
92+
</VisualState.Setters>
93+
</VisualState>
94+
<VisualState x:Name="Disabled">
95+
<VisualState.Setters>
96+
<Setter Target="LayoutRoot.Background" Value="{ThemeResource MenuFlyoutItemBackgroundDisabled}" />
97+
<Setter Target="TextBlock.Foreground" Value="{ThemeResource MenuFlyoutItemForegroundDisabled}" />
98+
<Setter Target="IconContent.Foreground" Value="{ThemeResource MenuFlyoutItemForegroundDisabled}" />
99+
<Setter Target="KeyboardAcceleratorTextBlock.Foreground" Value="{ThemeResource MenuFlyoutItemKeyboardAcceleratorTextForegroundDisabled}" />
100+
</VisualState.Setters>
101+
</VisualState>
102+
</VisualStateGroup>
103+
<VisualStateGroup x:Name="CheckPlaceholderStates">
104+
<VisualState x:Name="NoPlaceholder" />
105+
<VisualState x:Name="CheckPlaceholder">
106+
<VisualState.Setters>
107+
<Setter Target="TextBlock.Margin" Value="{ThemeResource MenuFlyoutItemPlaceholderThemeThickness}" />
108+
</VisualState.Setters>
109+
</VisualState>
110+
<VisualState x:Name="IconPlaceholder">
111+
<VisualState.Setters>
112+
<Setter Target="TextBlock.Margin" Value="{ThemeResource MenuFlyoutItemPlaceholderThemeThickness}" />
113+
<Setter Target="IconRoot.Visibility" Value="Visible" />
114+
</VisualState.Setters>
115+
</VisualState>
116+
<VisualState x:Name="CheckAndIconPlaceholder">
117+
<VisualState.Setters>
118+
<Setter Target="TextBlock.Margin" Value="{ThemeResource MenuFlyoutItemDoublePlaceholderThemeThickness}" />
119+
<Setter Target="IconRoot.Margin" Value="{ThemeResource MenuFlyoutItemPlaceholderThemeThickness}" />
120+
<Setter Target="IconRoot.Visibility" Value="Visible" />
121+
</VisualState.Setters>
122+
</VisualState>
123+
</VisualStateGroup>
124+
<!-- Narrow padding is only applied when flyout was invoked with pen, mouse or keyboard. -->
125+
<!-- Default padding is applied for all other cases including touch. -->
126+
<VisualStateGroup x:Name="PaddingSizeStates">
127+
<VisualState x:Name="DefaultPadding" />
128+
<VisualState x:Name="NarrowPadding">
129+
<Storyboard>
130+
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Padding">
131+
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource MenuFlyoutItemThemePaddingNarrow}" />
132+
</ObjectAnimationUsingKeyFrames>
133+
</Storyboard>
134+
</VisualState>
135+
</VisualStateGroup>
136+
<VisualStateGroup x:Name="KeyboardAcceleratorTextVisibility">
137+
<VisualState x:Name="KeyboardAcceleratorTextCollapsed" />
138+
<VisualState x:Name="KeyboardAcceleratorTextVisible">
139+
<VisualState.Setters>
140+
<Setter Target="KeyboardAcceleratorTextBlock.Visibility" Value="Visible" />
141+
</VisualState.Setters>
142+
</VisualState>
143+
</VisualStateGroup>
144+
</VisualStateManager.VisualStateGroups>
145+
</Grid>
146+
</ControlTemplate>
147+
</Setter.Value>
148+
</Setter>
149+
</Style>
150+
</MenuFlyoutItem.Style>
151+
</MenuFlyoutItem>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2024 Files Community
2+
// Licensed under the MIT License. See the LICENSE.
3+
4+
using Microsoft.UI.Xaml;
5+
using Microsoft.UI.Xaml.Controls;
6+
7+
// The User Control element template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
8+
9+
namespace Files.App.UserControls
10+
{
11+
public sealed partial class MenuFlyoutItemWithOpacityIcon: MenuFlyoutItem
12+
{
13+
public Style OpacityStyle
14+
{
15+
get { return (Style)GetValue(OpacityStyleProperty); }
16+
set { SetValue(OpacityStyleProperty, value); }
17+
}
18+
19+
public static readonly DependencyProperty OpacityStyleProperty =
20+
DependencyProperty.Register("OpacityStyle", typeof(Style), typeof(MenuFlyoutItemWithOpacityIcon), new PropertyMetadata(null, OnOpacityStyleChanged));
21+
22+
private static void OnOpacityStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
23+
{
24+
(d as MenuFlyoutItem).Icon = e.NewValue is not null ? new IconSourceElement() : null;
25+
}
26+
27+
public MenuFlyoutItemWithOpacityIcon()
28+
{
29+
InitializeComponent();
30+
}
31+
}
32+
}

src/Files.App/UserControls/TabBar/TabBar.xaml

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
xmlns:local="using:Files.App.UserControls.TabBar"
99
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
1010
xmlns:root="using:Files.App"
11+
xmlns:usercontrols="using:Files.App.UserControls"
1112
mc:Ignorable="d">
1213

1314
<local:BaseTabBar.Resources>
@@ -58,13 +59,85 @@
5859
</ResourceDictionary>
5960
</local:BaseTabBar.Resources>
6061

61-
<Border
62+
<!-- TODO: Use TitleBar of WinAppSdk 1.6 when available -->
63+
<Grid
6264
x:Name="TitlebarArea"
6365
HorizontalAlignment="Stretch"
6466
x:FieldModifier="public"
6567
Background="Transparent">
68+
<Grid.ColumnDefinitions>
69+
<ColumnDefinition Width="Auto" />
70+
<ColumnDefinition Width="*" />
71+
</Grid.ColumnDefinitions>
72+
73+
<!-- Header Button -->
74+
<Border BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}" BorderThickness="0,0,0,1">
75+
<Button
76+
Width="30"
77+
Height="30"
78+
Margin="4,0,-4,0"
79+
Padding="0"
80+
VerticalAlignment="Bottom"
81+
AutomationProperties.Name="{helpers:ResourceString Name=TabActions}"
82+
Background="Transparent"
83+
BorderThickness="0"
84+
ToolTipService.ToolTip="{helpers:ResourceString Name=TabActions}">
85+
<PathIcon Data="M3 0C1.34315 0 0 1.34315 0 3V12C0 13.6569 1.34315 15 3 15H12C13.6569 15 15 13.6569 15 12V3C15 1.34315 13.6569 0 12 0H3ZM1 3C1 1.89543 1.89543 1 3 1H12C13.1046 1 14 1.89543 14 3V4H5.5C4.67157 4 4 4.67157 4 5.5V14H3C1.89543 14 1 13.1046 1 12V3ZM5 14H12C13.1046 14 14 13.1046 14 12V5H5.5C5.22386 5 5 5.22386 5 5.5V14Z" Foreground="{ThemeResource App.Theme.IconBaseBrush}" />
86+
87+
<Button.Flyout>
88+
<MenuFlyout Placement="BottomEdgeAlignedLeft">
89+
<!-- New Window -->
90+
<usercontrols:MenuFlyoutItemWithOpacityIcon
91+
Command="{x:Bind Commands.NewWindow}"
92+
KeyboardAcceleratorTextOverride="{x:Bind Commands.NewWindow.HotKeyText, Mode=OneWay}"
93+
OpacityStyle="{x:Bind Commands.NewWindow.OpacityStyle}"
94+
Text="{x:Bind Commands.NewWindow.Label}" />
95+
96+
<!-- Enter Compact Overlay -->
97+
<usercontrols:MenuFlyoutItemWithOpacityIcon
98+
x:Name="EnterCompactOverlay"
99+
x:Load="{x:Bind Commands.EnterCompactOverlay.IsExecutable, Mode=OneWay}"
100+
Command="{x:Bind Commands.EnterCompactOverlay}"
101+
KeyboardAcceleratorTextOverride="{x:Bind Commands.EnterCompactOverlay.HotKeyText, Mode=OneWay}"
102+
OpacityStyle="{x:Bind Commands.EnterCompactOverlay.OpacityStyle}"
103+
Text="{x:Bind Commands.EnterCompactOverlay.Label}" />
104+
105+
<!-- Exit Compact Overlay -->
106+
<usercontrols:MenuFlyoutItemWithOpacityIcon
107+
x:Name="ExitCompactOverlay"
108+
x:Load="{x:Bind Commands.ExitCompactOverlay.IsExecutable, Mode=OneWay}"
109+
Command="{x:Bind Commands.ExitCompactOverlay}"
110+
OpacityStyle="{x:Bind Commands.ExitCompactOverlay.OpacityStyle}"
111+
Text="{x:Bind Commands.ExitCompactOverlay.Label}" />
112+
113+
<!-- Open New Pane -->
114+
<usercontrols:MenuFlyoutItemWithOpacityIcon
115+
x:Name="NewPane"
116+
x:Load="{x:Bind Commands.OpenNewPane.IsExecutable, Mode=OneWay}"
117+
Command="{x:Bind Commands.OpenNewPane, Mode=OneWay}"
118+
OpacityStyle="{x:Bind Commands.OpenNewPane.OpacityStyle}"
119+
Text="{x:Bind Commands.OpenNewPane.Label}" />
120+
121+
<!-- Close active pane -->
122+
<usercontrols:MenuFlyoutItemWithOpacityIcon
123+
x:Name="CloseActivePane"
124+
x:Load="{x:Bind Commands.CloseActivePane.IsExecutable, Mode=OneWay}"
125+
Command="{x:Bind Commands.CloseActivePane}"
126+
KeyboardAcceleratorTextOverride="{x:Bind Commands.CloseActivePane.HotKeyText, Mode=OneWay}"
127+
Text="{x:Bind Commands.CloseActivePane.Label}">
128+
<MenuFlyoutItem.Icon>
129+
<FontIcon Foreground="{ThemeResource App.Theme.IconBaseBrush}" Glyph="{x:Bind Commands.CloseActivePane.Glyph.BaseGlyph}" />
130+
</MenuFlyoutItem.Icon>
131+
</usercontrols:MenuFlyoutItemWithOpacityIcon>
132+
</MenuFlyout>
133+
</Button.Flyout>
134+
</Button>
135+
</Border>
136+
137+
<!-- TabBar + Draggable Right Padding -->
66138
<TabView
67139
x:Name="HorizontalTabView"
140+
Grid.Column="1"
68141
Margin="0,10,0,0"
69142
Padding="0"
70143
VerticalAlignment="Stretch"
@@ -146,6 +219,6 @@
146219
</TabView.TabStripFooter>
147220

148221
</TabView>
149-
</Border>
222+
</Grid>
150223

151224
</local:BaseTabBar>

0 commit comments

Comments
 (0)