Skip to content

Commit 82aec13

Browse files
RichCommands: Open & Close Pane (#12002)
1 parent e61ffa2 commit 82aec13

File tree

15 files changed

+146
-89
lines changed

15 files changed

+146
-89
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using CommunityToolkit.Mvvm.ComponentModel;
2+
using CommunityToolkit.Mvvm.DependencyInjection;
3+
using Files.App.Commands;
4+
using Files.App.Contexts;
5+
using Files.App.Extensions;
6+
using System.ComponentModel;
7+
using System.Threading.Tasks;
8+
9+
namespace Files.App.Actions
10+
{
11+
internal class ClosePaneAction : ObservableObject, IAction
12+
{
13+
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
14+
15+
public string Label { get; } = "NavigationToolbarClosePane/Label".GetLocalizedResource();
16+
17+
public string Description { get; } = "TODO: Need to be described.";
18+
19+
public HotKey HotKey { get; } = new(Keys.W, KeyModifiers.CtrlShift);
20+
21+
public RichGlyph Glyph { get; } = new("\uE89F");
22+
23+
public bool IsExecutable => context.IsMultiPaneActive;
24+
25+
public ClosePaneAction()
26+
{
27+
context.PropertyChanged += Context_PropertyChanged;
28+
}
29+
30+
public Task ExecuteAsync()
31+
{
32+
context.ShellPage!.PaneHolder.CloseActivePane();
33+
return Task.CompletedTask;
34+
}
35+
36+
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
37+
{
38+
switch (e.PropertyName)
39+
{
40+
case nameof(IContentPageContext.ShellPage):
41+
case nameof(IContentPageContext.IsMultiPaneActive):
42+
OnPropertyChanged(nameof(IsExecutable));
43+
break;
44+
}
45+
}
46+
}
47+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using CommunityToolkit.Mvvm.ComponentModel;
2+
using CommunityToolkit.Mvvm.DependencyInjection;
3+
using Files.App.Commands;
4+
using Files.App.Contexts;
5+
using Files.App.Extensions;
6+
using System.ComponentModel;
7+
using System.Threading.Tasks;
8+
9+
namespace Files.App.Actions
10+
{
11+
internal class OpenNewPaneAction : ObservableObject, IAction
12+
{
13+
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
14+
15+
public string Label { get; } = "NavigationToolbarNewPane/Label".GetLocalizedResource();
16+
17+
public string Description { get; } = "TODO: Need to be described.";
18+
19+
public HotKey HotKey { get; } = new(Keys.OemPlus, KeyModifiers.MenuShift);
20+
21+
public HotKey SecondHotKey { get; } = new(Keys.Add, KeyModifiers.MenuShift);
22+
23+
public RichGlyph Glyph { get; } = new(opacityStyle: "ColorIconRightPane");
24+
25+
public bool IsExecutable => context.IsMultiPaneEnabled && !context.IsMultiPaneActive;
26+
27+
public OpenNewPaneAction()
28+
{
29+
context.PropertyChanged += Context_PropertyChanged;
30+
}
31+
32+
public Task ExecuteAsync()
33+
{
34+
context.ShellPage!.PaneHolder.OpenPathInNewPane("Home");
35+
return Task.CompletedTask;
36+
}
37+
38+
private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
39+
{
40+
switch (e.PropertyName)
41+
{
42+
case nameof(IContentPageContext.IsMultiPaneEnabled):
43+
case nameof(IContentPageContext.IsMultiPaneActive):
44+
OnPropertyChanged(nameof(IsExecutable));
45+
break;
46+
}
47+
}
48+
}
49+
}

src/Files.App/Commands/CommandCodes.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,7 @@ public enum CommandCodes
150150
PreviousTab,
151151
NextTab,
152152
CloseSelectedTab,
153+
OpenNewPane,
154+
ClosePane,
153155
}
154156
}

src/Files.App/Commands/Manager/CommandManager.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ internal class CommandManager : ICommandManager
132132
public IRichCommand PreviousTab => commands[CommandCodes.PreviousTab];
133133
public IRichCommand NextTab => commands[CommandCodes.NextTab];
134134
public IRichCommand CloseSelectedTab => commands[CommandCodes.CloseSelectedTab];
135+
public IRichCommand OpenNewPane => commands[CommandCodes.OpenNewPane];
136+
public IRichCommand ClosePane => commands[CommandCodes.ClosePane];
135137

136138
public CommandManager()
137139
{
@@ -270,6 +272,8 @@ public CommandManager()
270272
[CommandCodes.PreviousTab] = new PreviousTabAction(),
271273
[CommandCodes.NextTab] = new NextTabAction(),
272274
[CommandCodes.CloseSelectedTab] = new CloseSelectedTabAction(),
275+
[CommandCodes.OpenNewPane] = new OpenNewPaneAction(),
276+
[CommandCodes.ClosePane] = new ClosePaneAction(),
273277
};
274278

275279
[DebuggerDisplay("Command None")]

src/Files.App/Commands/Manager/ICommandManager.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,5 +133,7 @@ public interface ICommandManager : IEnumerable<IRichCommand>
133133
IRichCommand PreviousTab { get; }
134134
IRichCommand NextTab { get; }
135135
IRichCommand CloseSelectedTab { get; }
136+
IRichCommand OpenNewPane { get; }
137+
IRichCommand ClosePane { get; }
136138
}
137139
}

src/Files.App/Contexts/ContentPage/ContentPageContext.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,20 @@ internal class ContentPageContext : ObservableObject, IContentPageContext
3737
private IReadOnlyList<ListedItem> selectedItems = emptyItems;
3838
public IReadOnlyList<ListedItem> SelectedItems => selectedItems;
3939

40-
public bool CanRefresh => ShellPage is not null && ShellPage.ToolbarViewModel.CanRefresh;
40+
public bool CanRefresh => ShellPage is not null && ShellPage.ToolbarViewModel.CanRefresh;
4141

4242
public bool CanGoBack => ShellPage is not null && ShellPage.ToolbarViewModel.CanGoBack;
43-
43+
4444
public bool CanGoForward => ShellPage is not null && ShellPage.ToolbarViewModel.CanGoForward;
4545

4646
public bool CanNavigateToParent => ShellPage is not null && ShellPage.ToolbarViewModel.CanNavigateToParent;
4747

4848
public bool IsSearchBoxVisible => ShellPage is not null && ShellPage.ToolbarViewModel.IsSearchBoxVisible;
4949

50+
public bool IsMultiPaneEnabled => ShellPage is not null && ShellPage.PaneHolder is not null && ShellPage.PaneHolder.IsMultiPaneEnabled;
51+
52+
public bool IsMultiPaneActive => ShellPage is not null && ShellPage.PaneHolder is not null && ShellPage.PaneHolder.IsMultiPaneActive;
53+
5054
public ContentPageContext()
5155
{
5256
context.Changing += Context_Changing;
@@ -62,6 +66,9 @@ private void Context_Changing(object? sender, EventArgs e)
6266
page.ContentChanged -= Page_ContentChanged;
6367
page.InstanceViewModel.PropertyChanged -= InstanceViewModel_PropertyChanged;
6468
page.ToolbarViewModel.PropertyChanged -= ToolbarViewModel_PropertyChanged;
69+
70+
if (page.PaneHolder is not null)
71+
page.PaneHolder.PropertyChanged -= PaneHolder_PropertyChanged;
6572
}
6673

6774
if (filesystemViewModel is not null)
@@ -78,6 +85,9 @@ private void Context_Changed(object? sender, EventArgs e)
7885
page.ContentChanged += Page_ContentChanged;
7986
page.InstanceViewModel.PropertyChanged += InstanceViewModel_PropertyChanged;
8087
page.ToolbarViewModel.PropertyChanged += ToolbarViewModel_PropertyChanged;
88+
89+
if (page.PaneHolder is not null)
90+
page.PaneHolder.PropertyChanged += PaneHolder_PropertyChanged;
8191
}
8292

8393
filesystemViewModel = ShellPage?.FilesystemViewModel;
@@ -95,11 +105,26 @@ private void Page_PropertyChanged(object? sender, PropertyChangedEventArgs e)
95105
case nameof(ShellPage.CurrentPageType):
96106
OnPropertyChanged(nameof(PageLayoutType));
97107
break;
108+
case nameof(ShellPage.PaneHolder):
109+
OnPropertyChanged(nameof(IsMultiPaneEnabled));
110+
OnPropertyChanged(nameof(IsMultiPaneActive));
111+
break;
98112
}
99113
}
100114

101115
private void Page_ContentChanged(object? sender, TabItemArguments e) => Update();
102116

117+
private void PaneHolder_PropertyChanged(object? sender, PropertyChangedEventArgs e)
118+
{
119+
switch (e.PropertyName)
120+
{
121+
case nameof(IPaneHolder.IsMultiPaneEnabled):
122+
case nameof(IPaneHolder.IsMultiPaneActive):
123+
OnPropertyChanged(e.PropertyName);
124+
break;
125+
}
126+
}
127+
103128
private void InstanceViewModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
104129
{
105130
switch (e.PropertyName)
@@ -152,6 +177,8 @@ private void Update()
152177
OnPropertyChanged(nameof(CanGoForward));
153178
OnPropertyChanged(nameof(CanNavigateToParent));
154179
OnPropertyChanged(nameof(CanRefresh));
180+
OnPropertyChanged(nameof(IsMultiPaneEnabled));
181+
OnPropertyChanged(nameof(IsMultiPaneActive));
155182
}
156183

157184
private void UpdatePageType()

src/Files.App/Contexts/ContentPage/IContentPageContext.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,8 @@ public interface IContentPageContext : INotifyPropertyChanged
2626
bool CanNavigateToParent { get; }
2727

2828
bool IsSearchBoxVisible { get; }
29+
30+
bool IsMultiPaneEnabled { get; }
31+
bool IsMultiPaneActive { get; }
2932
}
3033
}

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,12 +1845,6 @@
18451845
<data name="Home" xml:space="preserve">
18461846
<value>Home</value>
18471847
</data>
1848-
<data name="NavigationToolbarNewPane.KeyboardAcceleratorTextOverride" xml:space="preserve">
1849-
<value>Alt+Shift++</value>
1850-
</data>
1851-
<data name="NavigationToolbarClosePane.KeyboardAcceleratorTextOverride" xml:space="preserve">
1852-
<value>Ctrl+Shift+W</value>
1853-
</data>
18541848
<data name="NavigationToolbarNewWindow.KeyboardAcceleratorTextOverride" xml:space="preserve">
18551849
<value>Ctrl+N</value>
18561850
</data>

src/Files.App/UserControls/InnerNavigationToolbar.xaml

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -812,34 +812,21 @@
812812
<CommandBar.SecondaryCommands>
813813
<AppBarButton
814814
x:Name="NavToolbarNewPane"
815-
x:Load="{x:Bind converters:MultiBooleanConverter.AndNotConvert(ShowMultiPaneControls, IsMultiPaneActive), Mode=OneWay}"
816-
Command="{x:Bind ViewModel.OpenNewPaneCommand, Mode=OneWay}"
817-
KeyboardAcceleratorTextOverride="{helpers:ResourceString Name=NavigationToolbarNewPane/KeyboardAcceleratorTextOverride}"
818-
Label="{helpers:ResourceString Name=NavigationToolbarNewPane/Label}">
819-
820-
<local:OpacityIcon Style="{StaticResource ColorIconRightPane}" />
821-
<AppBarButton.KeyboardAccelerators>
822-
<KeyboardAccelerator
823-
Key="Add"
824-
IsEnabled="False"
825-
Modifiers="Menu,Shift" />
826-
</AppBarButton.KeyboardAccelerators>
815+
x:Load="{x:Bind Commands.OpenNewPane.IsExecutable, Mode=OneWay}"
816+
Command="{x:Bind Commands.OpenNewPane, Mode=OneWay}"
817+
Label="{x:Bind Commands.OpenNewPane.Label}"
818+
ToolTipService.ToolTip="{x:Bind Commands.OpenNewPane.LabelWithHotKey, Mode=OneWay}">
819+
<local:OpacityIcon Style="{x:Bind Commands.OpenNewPane.OpacityStyle}" />
827820
</AppBarButton>
828821
<AppBarButton
829822
x:Name="NavToolbarClosePane"
830-
x:Load="{x:Bind IsMultiPaneActive, Mode=OneWay}"
831-
Command="{x:Bind ViewModel.ClosePaneCommand, Mode=OneWay}"
832-
KeyboardAcceleratorTextOverride="{helpers:ResourceString Name=NavigationToolbarClosePane/KeyboardAcceleratorTextOverride}"
833-
Label="{helpers:ResourceString Name=NavigationToolbarClosePane/Label}">
823+
x:Load="{x:Bind Commands.ClosePane.IsExecutable, Mode=OneWay}"
824+
Command="{x:Bind Commands.ClosePane, Mode=OneWay}"
825+
Label="{x:Bind Commands.ClosePane.Label}"
826+
ToolTipService.ToolTip="{x:Bind Commands.ClosePane.LabelWithHotKey, Mode=OneWay}">
834827
<AppBarButton.Icon>
835-
<FontIcon Glyph="&#xE89F;" />
828+
<FontIcon Glyph="{x:Bind Commands.ClosePane.Glyph.BaseGlyph}" />
836829
</AppBarButton.Icon>
837-
<AppBarButton.KeyboardAccelerators>
838-
<KeyboardAccelerator
839-
Key="W"
840-
IsEnabled="False"
841-
Modifiers="Control,Shift" />
842-
</AppBarButton.KeyboardAccelerators>
843830
</AppBarButton>
844831
<AppBarButton
845832
x:Name="NavToolbarNewWindow"

src/Files.App/UserControls/InnerNavigationToolbar.xaml.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,27 +52,6 @@ public bool ShowPreviewPaneButton
5252
// Using a DependencyProperty as the backing store for ShowPreviewPaneButton. This enables animation, styling, binding, etc...
5353
public static readonly DependencyProperty ShowPreviewPaneButtonProperty =
5454
DependencyProperty.Register("ShowPreviewPaneButton", typeof(bool), typeof(AddressToolbar), new PropertyMetadata(null));
55-
56-
public bool ShowMultiPaneControls
57-
{
58-
get => (bool)GetValue(ShowMultiPaneControlsProperty);
59-
set => SetValue(ShowMultiPaneControlsProperty, value);
60-
}
61-
62-
// Using a DependencyProperty as the backing store for ShowMultiPaneControls. This enables animation, styling, binding, etc...
63-
public static readonly DependencyProperty ShowMultiPaneControlsProperty =
64-
DependencyProperty.Register(nameof(ShowMultiPaneControls), typeof(bool), typeof(AddressToolbar), new PropertyMetadata(null));
65-
66-
public bool IsMultiPaneActive
67-
{
68-
get { return (bool)GetValue(IsMultiPaneActiveProperty); }
69-
set { SetValue(IsMultiPaneActiveProperty, value); }
70-
}
71-
72-
// Using a DependencyProperty as the backing store for IsMultiPaneActive. This enables animation, styling, binding, etc...
73-
public static readonly DependencyProperty IsMultiPaneActiveProperty =
74-
DependencyProperty.Register("IsMultiPaneActive", typeof(bool), typeof(AddressToolbar), new PropertyMetadata(false));
75-
7655
private void NewEmptySpace_Opening(object sender, object e)
7756
{
7857
if (!ViewModel.InstanceViewModel.CanCreateFileInPage)

src/Files.App/ViewModels/ToolbarViewModel.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,10 +567,6 @@ private void SearchRegion_Escaped(object? sender, ISearchBox searchBox)
567567

568568
public IAsyncRelayCommand? OpenNewWindowCommand { get; set; }
569569

570-
public ICommand? OpenNewPaneCommand { get; set; }
571-
572-
public ICommand? ClosePaneCommand { get; set; }
573-
574570
public ICommand? CreateNewFileCommand { get; set; }
575571

576572
public ICommand? Share { get; set; }

src/Files.App/Views/BaseShellPage.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,8 +604,6 @@ protected virtual void ShellPage_NavigationRequested(object sender, PathNavigati
604604
protected void InitToolbarCommands()
605605
{
606606
ToolbarViewModel.OpenNewWindowCommand = new AsyncRelayCommand(NavigationHelpers.LaunchNewWindowAsync);
607-
ToolbarViewModel.OpenNewPaneCommand = new RelayCommand(() => PaneHolder?.OpenPathInNewPane("Home".GetLocalizedResource()));
608-
ToolbarViewModel.ClosePaneCommand = new RelayCommand(() => PaneHolder?.CloseActivePane());
609607
ToolbarViewModel.CreateNewFileCommand = new RelayCommand<ShellNewEntry>(x => UIFilesystemHelpers.CreateFileFromDialogResultType(AddItemDialogItemType.File, x, this));
610608
ToolbarViewModel.PropertiesCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.ShowPropertiesCommand.Execute(null));
611609
ToolbarViewModel.UpdateCommand = new AsyncRelayCommand(async () => await updateSettingsService.DownloadUpdates());

src/Files.App/Views/MainPage.xaml.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,7 @@ private void UpdateNavToolbarProperties()
196196
NavToolbar.ViewModel = SidebarAdaptiveViewModel.PaneHolder?.ActivePaneOrColumn.ToolbarViewModel;
197197

198198
if (InnerNavigationToolbar is not null)
199-
{
200199
InnerNavigationToolbar.ViewModel = SidebarAdaptiveViewModel.PaneHolder?.ActivePaneOrColumn.ToolbarViewModel;
201-
InnerNavigationToolbar.ShowMultiPaneControls = SidebarAdaptiveViewModel.PaneHolder?.IsMultiPaneEnabled ?? false;
202-
InnerNavigationToolbar.IsMultiPaneActive = SidebarAdaptiveViewModel.PaneHolder?.IsMultiPaneActive ?? false;
203-
}
204200
}
205201

206202
protected override void OnNavigatedTo(NavigationEventArgs e)

src/Files.App/Views/PaneHolderPage.xaml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,6 @@
4646
Key="Right"
4747
Invoked="KeyboardAccelerator_Invoked"
4848
Modifiers="Control,Shift" />
49-
<KeyboardAccelerator
50-
Key="W"
51-
Invoked="KeyboardAccelerator_Invoked"
52-
Modifiers="Control,Shift" />
53-
<KeyboardAccelerator
54-
Key="Add"
55-
Invoked="KeyboardAccelerator_Invoked"
56-
Modifiers="Menu,Shift" />
57-
<KeyboardAccelerator
58-
Key="{x:Bind local:PaneHolderPage.PlusKey}"
59-
Invoked="KeyboardAccelerator_Invoked"
60-
Modifiers="Menu,Shift" />
6149
</Page.KeyboardAccelerators>
6250

6351
<Grid x:Name="RootGrid">

src/Files.App/Views/PaneHolderPage.xaml.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,6 @@ public bool IsCurrentInstance
191191
}
192192
}
193193

194-
public const VirtualKey PlusKey = (VirtualKey)187;
195-
196194
public PaneHolderPage()
197195
{
198196
InitializeComponent();
@@ -297,19 +295,6 @@ private void KeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcc
297295
IsRightPaneVisible = true;
298296
ActivePane = PaneRight;
299297
break;
300-
301-
case (true, true, false, VirtualKey.W): // ctrl + shift + "W" close right pane
302-
IsRightPaneVisible = false;
303-
break;
304-
305-
case (false, true, true, VirtualKey.Add): // alt + shift + "+" open pane
306-
case (false, true, true, PlusKey):
307-
if (string.IsNullOrEmpty(NavParamsRight?.NavPath))
308-
{
309-
NavParamsRight = new NavigationParams { NavPath = "Home" };
310-
}
311-
IsRightPaneVisible = true;
312-
break;
313298
}
314299
}
315300

0 commit comments

Comments
 (0)