Skip to content

Commit 6774a19

Browse files
authored
Rich Commands: Rotate image as Rich Commands (#11633)
1 parent 38b897d commit 6774a19

File tree

11 files changed

+123
-59
lines changed

11 files changed

+123
-59
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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 Files.App.Helpers;
7+
using Files.App.ViewModels;
8+
using System.ComponentModel;
9+
using System.Linq;
10+
using System.Threading.Tasks;
11+
using Windows.Graphics.Imaging;
12+
13+
namespace Files.App.Actions.Content.ImageEdition
14+
{
15+
internal class RotateLeftAction : ObservableObject, IAction
16+
{
17+
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
18+
19+
public string Label { get; } = "RotateLeft".GetLocalizedResource();
20+
21+
public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconRotateLeft");
22+
23+
public bool IsExecutable => context.ShellPage.SlimContentPage.SelectedItemsPropertiesViewModel.IsSelectedItemImage;
24+
25+
public RotateLeftAction()
26+
{
27+
context.PropertyChanged += Context_PropertyChanged;
28+
}
29+
30+
public async Task ExecuteAsync()
31+
{
32+
foreach (var image in context.SelectedItems)
33+
await BitmapHelper.Rotate(PathNormalization.NormalizePath(image.ItemPath), BitmapRotation.Clockwise270Degrees);
34+
35+
context.ShellPage.SlimContentPage.ItemManipulationModel.RefreshItemsThumbnail();
36+
App.PreviewPaneViewModel.UpdateSelectedItemPreview();
37+
}
38+
39+
public void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
40+
{
41+
if (e.PropertyName is nameof(IContentPageContext.HasSelection))
42+
{
43+
context.ShellPage.SlimContentPage.SelectedItemsPropertiesViewModel.CheckAllFileExtensions(context.SelectedItems.Select(selectedItem => selectedItem?.FileExtension).ToList<string>());
44+
OnPropertyChanged(nameof(IsExecutable));
45+
}
46+
}
47+
}
48+
}
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 Files.App.Helpers;
7+
using System.ComponentModel;
8+
using System.Linq;
9+
using System.Threading.Tasks;
10+
using Windows.Graphics.Imaging;
11+
12+
namespace Files.App.Actions.Content.ImageEdition
13+
{
14+
internal class RotateRightAction : ObservableObject, IAction
15+
{
16+
private readonly IContentPageContext context = Ioc.Default.GetRequiredService<IContentPageContext>();
17+
18+
public string Label { get; } = "RotateRight".GetLocalizedResource();
19+
20+
public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconRotateRight");
21+
22+
public bool IsExecutable => context.ShellPage.SlimContentPage.SelectedItemsPropertiesViewModel.IsSelectedItemImage;
23+
24+
public RotateRightAction()
25+
{
26+
context.PropertyChanged += Context_PropertyChanged;
27+
}
28+
29+
public async Task ExecuteAsync()
30+
{
31+
foreach (var image in context.SelectedItems)
32+
await BitmapHelper.Rotate(PathNormalization.NormalizePath(image.ItemPath), BitmapRotation.Clockwise90Degrees);
33+
34+
context.ShellPage.SlimContentPage.ItemManipulationModel.RefreshItemsThumbnail();
35+
App.PreviewPaneViewModel.UpdateSelectedItemPreview();
36+
}
37+
38+
public void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e)
39+
{
40+
if (e.PropertyName is nameof(IContentPageContext.HasSelection))
41+
{
42+
context.ShellPage.SlimContentPage.SelectedItemsPropertiesViewModel.CheckAllFileExtensions(context.SelectedItems.Select(selectedItem => selectedItem?.FileExtension).ToList<string>());
43+
OnPropertyChanged(nameof(IsExecutable));
44+
}
45+
}
46+
}
47+
}

src/Files.App/Commands/CommandCodes.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,13 @@ public enum CommandCodes
4747
RunAsAdmin,
4848
RunAsAnotherUser,
4949

50-
// Archives
50+
// Archives
5151
CompressIntoArchive,
5252
CompressIntoSevenZip,
53-
CompressIntoZip
53+
CompressIntoZip,
54+
55+
// Image Edition
56+
RotateLeft,
57+
RotateRight
5458
}
5559
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Files.App.Actions;
44
using Files.App.Actions.Content.Archives;
55
using Files.App.Actions.Content.Background;
6+
using Files.App.Actions.Content.ImageEdition;
67
using Files.App.Actions.Favorites;
78
using Files.App.UserControls;
89
using Microsoft.UI.Xaml;
@@ -61,6 +62,8 @@ internal class CommandManager : ICommandManager
6162
public IRichCommand CompressIntoArchive => commands[CommandCodes.CompressIntoArchive];
6263
public IRichCommand CompressIntoSevenZip => commands[CommandCodes.CompressIntoSevenZip];
6364
public IRichCommand CompressIntoZip => commands[CommandCodes.CompressIntoZip];
65+
public IRichCommand RotateLeft => commands[CommandCodes.RotateLeft];
66+
public IRichCommand RotateRight => commands[CommandCodes.RotateRight];
6467

6568
public CommandManager()
6669
{
@@ -109,7 +112,9 @@ public CommandManager()
109112
[CommandCodes.RunAsAnotherUser] = new RunAsAnotherUserAction(),
110113
[CommandCodes.CompressIntoArchive] = new CompressIntoArchiveAction(),
111114
[CommandCodes.CompressIntoSevenZip] = new CompressIntoSevenZipAction(),
112-
[CommandCodes.CompressIntoZip] = new CompressIntoZipAction()
115+
[CommandCodes.CompressIntoZip] = new CompressIntoZipAction(),
116+
[CommandCodes.RotateLeft] = new RotateLeftAction(),
117+
[CommandCodes.RotateRight] = new RotateRightAction()
113118
};
114119

115120
[DebuggerDisplay("Command None")]

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,8 @@ public interface ICommandManager : IEnumerable<IRichCommand>
4848
IRichCommand CompressIntoArchive { get; }
4949
IRichCommand CompressIntoSevenZip { get; }
5050
IRichCommand CompressIntoZip { get; }
51+
52+
IRichCommand RotateLeft { get; }
53+
IRichCommand RotateRight { get; }
5154
}
5255
}

src/Files.App/Helpers/ContextFlyoutItemHelper.cs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -692,28 +692,14 @@ public static List<ContextMenuFlyoutItemViewModel> GetBaseItemMenuItems(
692692
}.Build(),
693693
}
694694
},
695-
new ContextMenuFlyoutItemViewModel
695+
new ContextMenuFlyoutItemViewModelBuilder(commands.RotateLeft)
696696
{
697-
Text = "RotateLeft".GetLocalizedResource(),
698-
OpacityIcon = new OpacityIconModel()
699-
{
700-
OpacityIconStyle = "ColorIconRotateLeft"
701-
},
702-
Command = commandsViewModel.RotateImageLeftCommand,
703-
ShowInSearchPage = true,
704-
ShowItem = selectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false
705-
},
706-
new ContextMenuFlyoutItemViewModel
697+
IsVisible = selectedItemsPropertiesViewModel.IsSelectedItemImage
698+
}.Build(),
699+
new ContextMenuFlyoutItemViewModelBuilder(commands.RotateRight)
707700
{
708-
Text = "RotateRight".GetLocalizedResource(),
709-
OpacityIcon = new OpacityIconModel()
710-
{
711-
OpacityIconStyle = "ColorIconRotateRight"
712-
},
713-
Command = commandsViewModel.RotateImageRightCommand,
714-
ShowInSearchPage = true,
715-
ShowItem = selectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false
716-
},
701+
IsVisible = selectedItemsPropertiesViewModel.IsSelectedItemImage
702+
}.Build(),
717703
new ContextMenuFlyoutItemViewModelBuilder(commands.RunAsAdmin).Build(),
718704
new ContextMenuFlyoutItemViewModelBuilder(commands.RunAsAnotherUser).Build(),
719705
new ContextMenuFlyoutItemViewModel()

src/Files.App/Interacts/BaseLayoutCommandImplementationModel.cs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -598,24 +598,6 @@ public async Task InstallInfDriver()
598598
await Win32API.InstallInf(selectedItem.ItemPath);
599599
}
600600

601-
public async Task RotateImageLeft()
602-
{
603-
foreach (var image in SlimContentPage.SelectedItems)
604-
await BitmapHelper.Rotate(PathNormalization.NormalizePath(image.ItemPath), BitmapRotation.Clockwise270Degrees);
605-
606-
SlimContentPage.ItemManipulationModel.RefreshItemsThumbnail();
607-
App.PreviewPaneViewModel.UpdateSelectedItemPreview();
608-
}
609-
610-
public async Task RotateImageRight()
611-
{
612-
foreach (var image in SlimContentPage.SelectedItems)
613-
await BitmapHelper.Rotate(PathNormalization.NormalizePath(image.ItemPath), BitmapRotation.Clockwise90Degrees);
614-
615-
SlimContentPage.ItemManipulationModel.RefreshItemsThumbnail();
616-
App.PreviewPaneViewModel.UpdateSelectedItemPreview();
617-
}
618-
619601
public Task InstallFont()
620602
{
621603
foreach (ListedItem selectedItem in SlimContentPage.SelectedItems)

src/Files.App/Interacts/BaseLayoutCommandsViewModel.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ private void InitializeCommands()
5353
DecompressArchiveHereCommand = new AsyncRelayCommand(CommandsModel.DecompressArchiveHere);
5454
DecompressArchiveToChildFolderCommand = new AsyncRelayCommand(CommandsModel.DecompressArchiveToChildFolder);
5555
InstallInfDriver = new AsyncRelayCommand(CommandsModel.InstallInfDriver);
56-
RotateImageLeftCommand = new AsyncRelayCommand(CommandsModel.RotateImageLeft);
57-
RotateImageRightCommand = new AsyncRelayCommand(CommandsModel.RotateImageRight);
5856
InstallFontCommand = new AsyncRelayCommand(CommandsModel.InstallFont);
5957
PlayAllCommand = new AsyncRelayCommand(CommandsModel.PlayAll);
6058
FormatDriveCommand = new RelayCommand<ListedItem>(CommandsModel.FormatDrive);
@@ -116,10 +114,6 @@ private void InitializeCommands()
116114

117115
public ICommand InstallInfDriver { get; set; }
118116

119-
public ICommand RotateImageLeftCommand { get; private set; }
120-
121-
public ICommand RotateImageRightCommand { get; private set; }
122-
123117
public ICommand InstallFontCommand { get; private set; }
124118

125119
public ICommand PlayAllCommand { get; private set; }

src/Files.App/Interacts/IBaseLayoutCommandImplementationModel.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ public interface IBaseLayoutCommandImplementationModel : IDisposable
6161

6262
Task InstallInfDriver();
6363

64-
Task RotateImageLeft();
65-
66-
Task RotateImageRight();
67-
6864
Task InstallFont();
6965

7066
Task PlayAll();

src/Files.App/UserControls/InnerNavigationToolbar.xaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,8 @@
341341
<AppBarButton
342342
x:Name="RotateImageLeftButton"
343343
x:Load="{x:Bind ViewModel.IsImage, Mode=OneWay, FallbackValue=False}"
344-
Command="{x:Bind ViewModel.RotateImageLeftCommand, Mode=OneWay}"
345-
Label="{helpers:ResourceString Name=RotateLeft}"
344+
Command="{x:Bind Commands.RotateLeft, Mode=OneWay}"
345+
Label="{x:Bind Commands.RotateLeft.Label}"
346346
LabelPosition="Default"
347347
ToolTipService.ToolTip="{helpers:ResourceString Name=RotateLeft}">
348348

@@ -351,8 +351,8 @@
351351
<AppBarButton
352352
x:Name="RotateImageRightButton"
353353
x:Load="{x:Bind ViewModel.IsImage, Mode=OneWay, FallbackValue=False}"
354-
Command="{x:Bind ViewModel.RotateImageRightCommand, Mode=OneWay}"
355-
Label="{helpers:ResourceString Name=RotateRight}"
354+
Command="{x:Bind Commands.RotateRight, Mode=OneWay}"
355+
Label="{x:Bind Commands.RotateRight.Label}"
356356
LabelPosition="Default"
357357
ToolTipService.ToolTip="{helpers:ResourceString Name=RotateRight}">
358358

src/Files.App/Views/BaseShellPage.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@ public abstract class BaseShellPage : Page, IShellPage, INotifyPropertyChanged
5858

5959
protected readonly IUpdateService updateSettingsService = Ioc.Default.GetRequiredService<IUpdateService>();
6060

61+
protected readonly ICommandManager commands = Ioc.Default.GetRequiredService<ICommandManager>();
62+
6163
public ToolbarViewModel ToolbarViewModel { get; } = new ToolbarViewModel();
6264

6365
public IBaseLayout SlimContentPage => ContentPage;
6466

65-
public ICommandManager commands = Ioc.Default.GetRequiredService<ICommandManager>();
6667
public IFilesystemHelpers FilesystemHelpers { get; protected set; }
6768

6869
public Type CurrentPageType => ItemDisplay.SourcePageType;
@@ -638,9 +639,7 @@ protected void InitToolbarCommands()
638639
ToolbarViewModel.ExtractCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DecompressArchiveCommand.Execute(null));
639640
ToolbarViewModel.ExtractHereCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DecompressArchiveHereCommand.Execute(null));
640641
ToolbarViewModel.ExtractToCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.DecompressArchiveToChildFolderCommand.Execute(null));
641-
ToolbarViewModel.InstallInfCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.InstallInfDriver.Execute(null));
642-
ToolbarViewModel.RotateImageLeftCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.RotateImageLeftCommand.Execute(null), () => SlimContentPage?.CommandsViewModel.RotateImageLeftCommand.CanExecute(null) == true);
643-
ToolbarViewModel.RotateImageRightCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.RotateImageRightCommand.Execute(null), () => SlimContentPage?.CommandsViewModel.RotateImageRightCommand.CanExecute(null) == true);
642+
ToolbarViewModel.InstallInfCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.InstallInfDriver.Execute(null));;
644643
ToolbarViewModel.InstallFontCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.InstallFontCommand.Execute(null));
645644
ToolbarViewModel.UpdateCommand = new AsyncRelayCommand(async () => await updateSettingsService.DownloadUpdates());
646645
ToolbarViewModel.PlayAllCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.PlayAllCommand.Execute(null));

0 commit comments

Comments
 (0)