diff --git a/src/Files.App/Actions/Content/Background/BaseSetAsAction.cs b/src/Files.App/Actions/Content/Background/BaseSetAsAction.cs new file mode 100644 index 000000000000..7eebe5545330 --- /dev/null +++ b/src/Files.App/Actions/Content/Background/BaseSetAsAction.cs @@ -0,0 +1,54 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.DependencyInjection; +using Files.App.Commands; +using Files.App.Contexts; +using System.ComponentModel; +using System.Linq; +using System.Threading.Tasks; + +namespace Files.App.Actions +{ + internal abstract class BaseSetAsAction : ObservableObject, IAction + { + protected readonly IContentPageContext context = Ioc.Default.GetRequiredService(); + + public abstract string Label { get; } + + public abstract string Description { get; } + + public abstract RichGlyph Glyph { get; } + + public virtual bool IsExecutable => context.ShellPage is not null && + context.PageType is not ContentPageTypes.RecycleBin and not ContentPageTypes.ZipFolder && + (context.ShellPage?.SlimContentPage?.SelectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false); + + public BaseSetAsAction() + { + context.PropertyChanged += Context_PropertyChanged; + } + + private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e) + { + switch (e.PropertyName) + { + case nameof(IContentPageContext.PageType): + OnPropertyChanged(nameof(IsExecutable)); + break; + case nameof(IContentPageContext.SelectedItem): + case nameof(IContentPageContext.SelectedItems): + if (context.ShellPage is not null && context.ShellPage.SlimContentPage is not null) + { + var viewModel = context.ShellPage.SlimContentPage.SelectedItemsPropertiesViewModel; + var extensions = context.SelectedItems.Select(selectedItem => selectedItem.FileExtension).Distinct().ToList(); + + viewModel.CheckAllFileExtensions(extensions); + } + + OnPropertyChanged(nameof(IsExecutable)); + break; + } + } + + public abstract Task ExecuteAsync(); + } +} diff --git a/src/Files.App/Actions/Content/Background/SetAsLockscreenBackgroundAction.cs b/src/Files.App/Actions/Content/Background/SetAsLockscreenBackgroundAction.cs index 85ffeb67e78f..0b2508c37042 100644 --- a/src/Files.App/Actions/Content/Background/SetAsLockscreenBackgroundAction.cs +++ b/src/Files.App/Actions/Content/Background/SetAsLockscreenBackgroundAction.cs @@ -1,54 +1,28 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.DependencyInjection; -using Files.App.Commands; -using Files.App.Contexts; +using Files.App.Commands; using Files.App.Extensions; using Files.App.Helpers; using Files.Shared.Enums; -using System.ComponentModel; using System.Threading.Tasks; namespace Files.App.Actions { - internal class SetAsLockscreenBackgroundAction : ObservableObject, IAction + internal class SetAsLockscreenBackgroundAction : BaseSetAsAction { - private readonly IContentPageContext context = Ioc.Default.GetRequiredService(); + public override string Label { get; } = "SetAsLockscreen".GetLocalizedResource(); - public string Label { get; } = "SetAsLockscreen".GetLocalizedResource(); + public override string Description => "TODO: Need to be described."; - public string Description => "TODO: Need to be described."; + public override RichGlyph Glyph { get; } = new("\uEE3F"); - public RichGlyph Glyph { get; } = new("\uEE3F"); + public override bool IsExecutable => base.IsExecutable && + context.SelectedItem is not null; - private bool isExecutable; - public bool IsExecutable => isExecutable; - - public SetAsLockscreenBackgroundAction() - { - isExecutable = GetIsExecutable(); - context.PropertyChanged += Context_PropertyChanged; - } - - public Task ExecuteAsync() + public override Task ExecuteAsync() { if (context.SelectedItem is not null) WallpaperHelpers.SetAsBackground(WallpaperType.LockScreen, context.SelectedItem.ItemPath); - return Task.CompletedTask; - } - - private bool GetIsExecutable() => context.ShellPage is not null && context.SelectedItem is not null - && context.PageType is not ContentPageTypes.RecycleBin and not ContentPageTypes.ZipFolder - && (context.ShellPage?.SlimContentPage?.SelectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false); - private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e) - { - switch (e.PropertyName) - { - case nameof(IContentPageContext.PageType): - case nameof(IContentPageContext.SelectedItem): - SetProperty(ref isExecutable, GetIsExecutable(), nameof(IsExecutable)); - break; - } + return Task.CompletedTask; } } } diff --git a/src/Files.App/Actions/Content/Background/SetAsSlideshowBackgroundAction.cs b/src/Files.App/Actions/Content/Background/SetAsSlideshowBackgroundAction.cs index 754789fdd6db..00cef0fb9727 100644 --- a/src/Files.App/Actions/Content/Background/SetAsSlideshowBackgroundAction.cs +++ b/src/Files.App/Actions/Content/Background/SetAsSlideshowBackgroundAction.cs @@ -1,55 +1,28 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.DependencyInjection; -using Files.App.Commands; -using Files.App.Contexts; +using Files.App.Commands; using Files.App.Extensions; using Files.App.Helpers; -using System.ComponentModel; using System.Linq; using System.Threading.Tasks; namespace Files.App.Actions { - internal class SetAsSlideshowBackgroundAction : ObservableObject, IAction + internal class SetAsSlideshowBackgroundAction : BaseSetAsAction { - private readonly IContentPageContext context = Ioc.Default.GetRequiredService(); + public override string Label { get; } = "SetAsSlideshow".GetLocalizedResource(); - public string Label { get; } = "SetAsSlideshow".GetLocalizedResource(); + public override string Description => "TODO: Need to be described."; - public string Description => "TODO: Need to be described."; + public override RichGlyph Glyph { get; } = new("\uE91B"); - public RichGlyph Glyph { get; } = new("\uE91B"); + public override bool IsExecutable => base.IsExecutable && + context.SelectedItems.Count > 1; - private bool isExecutable; - public bool IsExecutable => isExecutable; - - public SetAsSlideshowBackgroundAction() - { - isExecutable = GetIsExecutable(); - context.PropertyChanged += Context_PropertyChanged; - } - - public Task ExecuteAsync() + public override Task ExecuteAsync() { var paths = context.SelectedItems.Select(item => item.ItemPath).ToArray(); WallpaperHelpers.SetSlideshow(paths); return Task.CompletedTask; } - - private bool GetIsExecutable() => context.ShellPage is not null && context.SelectedItems.Count > 1 - && context.PageType is not ContentPageTypes.RecycleBin and not ContentPageTypes.ZipFolder - && (context.ShellPage?.SlimContentPage?.SelectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false); - - private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e) - { - switch (e.PropertyName) - { - case nameof(IContentPageContext.PageType): - case nameof(IContentPageContext.SelectedItems): - SetProperty(ref isExecutable, GetIsExecutable(), nameof(IsExecutable)); - break; - } - } } } diff --git a/src/Files.App/Actions/Content/Background/SetAsWallpaperBackgroundAction.cs b/src/Files.App/Actions/Content/Background/SetAsWallpaperBackgroundAction.cs index ac3837b8648c..9d1da6a814d0 100644 --- a/src/Files.App/Actions/Content/Background/SetAsWallpaperBackgroundAction.cs +++ b/src/Files.App/Actions/Content/Background/SetAsWallpaperBackgroundAction.cs @@ -1,54 +1,28 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.DependencyInjection; -using Files.App.Commands; -using Files.App.Contexts; +using Files.App.Commands; using Files.App.Extensions; using Files.App.Helpers; using Files.Shared.Enums; -using System.ComponentModel; using System.Threading.Tasks; namespace Files.App.Actions { - internal class SetAsWallpaperBackgroundAction : ObservableObject, IAction + internal class SetAsWallpaperBackgroundAction : BaseSetAsAction { - private readonly IContentPageContext context = Ioc.Default.GetRequiredService(); + public override string Label { get; } = "SetAsBackground".GetLocalizedResource(); - public string Label { get; } = "SetAsBackground".GetLocalizedResource(); + public override string Description => "TODO: Need to be described."; - public string Description => "TODO: Need to be described."; + public override RichGlyph Glyph { get; } = new("\uE91B"); - public RichGlyph Glyph { get; } = new("\uE91B"); + public override bool IsExecutable => base.IsExecutable && + context.SelectedItem is not null; - private bool isExecutable; - public bool IsExecutable => isExecutable; - - public SetAsWallpaperBackgroundAction() - { - isExecutable = GetIsExecutable(); - context.PropertyChanged += Context_PropertyChanged; - } - - public Task ExecuteAsync() + public override Task ExecuteAsync() { if (context.SelectedItem is not null) WallpaperHelpers.SetAsBackground(WallpaperType.Desktop, context.SelectedItem.ItemPath); - return Task.CompletedTask; - } - - private bool GetIsExecutable() => context.ShellPage is not null && context.SelectedItem is not null - && context.PageType is not ContentPageTypes.RecycleBin and not ContentPageTypes.ZipFolder - && (context.ShellPage?.SlimContentPage?.SelectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false); - private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e) - { - switch (e.PropertyName) - { - case nameof(IContentPageContext.PageType): - case nameof(IContentPageContext.SelectedItem): - SetProperty(ref isExecutable, GetIsExecutable(), nameof(IsExecutable)); - break; - } + return Task.CompletedTask; } } } diff --git a/src/Files.App/Actions/Content/ImageEdition/RotateRightAction.cs b/src/Files.App/Actions/Content/ImageEdition/RotateRightAction.cs deleted file mode 100644 index 82877a2d42df..000000000000 --- a/src/Files.App/Actions/Content/ImageEdition/RotateRightAction.cs +++ /dev/null @@ -1,65 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.DependencyInjection; -using Files.App.Commands; -using Files.App.Contexts; -using Files.App.Extensions; -using Files.App.Helpers; -using Files.App.ViewModels; -using System.ComponentModel; -using System.Linq; -using System.Threading.Tasks; -using Windows.Graphics.Imaging; - -namespace Files.App.Actions -{ - internal class RotateRightAction : ObservableObject, IAction - { - private readonly IContentPageContext context = Ioc.Default.GetRequiredService(); - - public string Label { get; } = "RotateRight".GetLocalizedResource(); - - public string Description => "TODO: Need to be described."; - - public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconRotateRight"); - - public bool IsExecutable => IsContextPageTypeAdaptedToCommand() - && (context.ShellPage?.SlimContentPage?.SelectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false); - - public RotateRightAction() - { - context.PropertyChanged += Context_PropertyChanged; - } - - public async Task ExecuteAsync() - { - foreach (var image in context.SelectedItems) - await BitmapHelper.Rotate(PathNormalization.NormalizePath(image.ItemPath), BitmapRotation.Clockwise90Degrees); - - context.ShellPage?.SlimContentPage?.ItemManipulationModel?.RefreshItemsThumbnail(); - Ioc.Default.GetRequiredService().UpdateSelectedItemPreview(); - } - - private bool IsContextPageTypeAdaptedToCommand() - { - return context.PageType is not ContentPageTypes.RecycleBin - and not ContentPageTypes.ZipFolder - and not ContentPageTypes.None; - } - - private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e) - { - if (e.PropertyName is nameof(IContentPageContext.HasSelection)) - { - if (context.ShellPage is not null && context.ShellPage.SlimContentPage is not null) - { - var viewModel = context.ShellPage.SlimContentPage.SelectedItemsPropertiesViewModel; - var extensions = context.SelectedItems.Select(selectedItem => selectedItem.FileExtension).Distinct().ToList(); - - viewModel.CheckAllFileExtensions(extensions); - } - - OnPropertyChanged(nameof(IsExecutable)); - } - } - } -} diff --git a/src/Files.App/Actions/Content/ImageEdition/RotateLeftAction.cs b/src/Files.App/Actions/Content/ImageManipulation/BaseRotateAction.cs similarity index 74% rename from src/Files.App/Actions/Content/ImageEdition/RotateLeftAction.cs rename to src/Files.App/Actions/Content/ImageManipulation/BaseRotateAction.cs index f3d620179261..863581f0352b 100644 --- a/src/Files.App/Actions/Content/ImageEdition/RotateLeftAction.cs +++ b/src/Files.App/Actions/Content/ImageManipulation/BaseRotateAction.cs @@ -2,7 +2,6 @@ using CommunityToolkit.Mvvm.DependencyInjection; using Files.App.Commands; using Files.App.Contexts; -using Files.App.Extensions; using Files.App.Helpers; using Files.App.ViewModels; using System.ComponentModel; @@ -12,20 +11,22 @@ namespace Files.App.Actions { - internal class RotateLeftAction : ObservableObject, IAction + internal abstract class BaseRotateAction : ObservableObject, IAction { private readonly IContentPageContext context = Ioc.Default.GetRequiredService(); - public string Label { get; } = "RotateLeft".GetLocalizedResource(); + public abstract string Label { get; } - public string Description => "TODO: Need to be described."; + public abstract string Description { get; } - public RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconRotateLeft"); + public abstract RichGlyph Glyph { get; } - public bool IsExecutable => IsContextPageTypeAdaptedToCommand() - && (context.ShellPage?.SlimContentPage?.SelectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false); + protected abstract BitmapRotation Rotation { get; } - public RotateLeftAction() + public bool IsExecutable => IsContextPageTypeAdaptedToCommand() && + (context.ShellPage?.SlimContentPage?.SelectedItemsPropertiesViewModel?.IsSelectedItemImage ?? false); + + public BaseRotateAction() { context.PropertyChanged += Context_PropertyChanged; } @@ -33,7 +34,7 @@ public RotateLeftAction() public async Task ExecuteAsync() { foreach (var image in context.SelectedItems) - await BitmapHelper.Rotate(PathNormalization.NormalizePath(image.ItemPath), BitmapRotation.Clockwise270Degrees); + await BitmapHelper.Rotate(PathNormalization.NormalizePath(image.ItemPath), Rotation); context.ShellPage?.SlimContentPage?.ItemManipulationModel?.RefreshItemsThumbnail(); Ioc.Default.GetRequiredService().UpdateSelectedItemPreview(); @@ -48,7 +49,7 @@ and not ContentPageTypes.ZipFolder private void Context_PropertyChanged(object? sender, PropertyChangedEventArgs e) { - if (e.PropertyName is nameof(IContentPageContext.HasSelection)) + if (e.PropertyName is nameof(IContentPageContext.SelectedItem)) { if (context.ShellPage is not null && context.ShellPage.SlimContentPage is not null) { diff --git a/src/Files.App/Actions/Content/ImageManipulation/RotateLeftAction.cs b/src/Files.App/Actions/Content/ImageManipulation/RotateLeftAction.cs new file mode 100644 index 000000000000..a1594277b831 --- /dev/null +++ b/src/Files.App/Actions/Content/ImageManipulation/RotateLeftAction.cs @@ -0,0 +1,17 @@ +using Files.App.Commands; +using Files.App.Extensions; +using Windows.Graphics.Imaging; + +namespace Files.App.Actions +{ + internal class RotateLeftAction : BaseRotateAction + { + public override string Label { get; } = "RotateLeft".GetLocalizedResource(); + + public override string Description => "TODO: Need to be described."; + + public override RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconRotateLeft"); + + protected override BitmapRotation Rotation => BitmapRotation.Clockwise270Degrees; + } +} diff --git a/src/Files.App/Actions/Content/ImageManipulation/RotateRightAction.cs b/src/Files.App/Actions/Content/ImageManipulation/RotateRightAction.cs new file mode 100644 index 000000000000..4c4861807f22 --- /dev/null +++ b/src/Files.App/Actions/Content/ImageManipulation/RotateRightAction.cs @@ -0,0 +1,17 @@ +using Files.App.Commands; +using Files.App.Extensions; +using Windows.Graphics.Imaging; + +namespace Files.App.Actions +{ + internal class RotateRightAction : BaseRotateAction + { + public override string Label { get; } = "RotateRight".GetLocalizedResource(); + + public override string Description => "TODO: Need to be described."; + + public override RichGlyph Glyph { get; } = new RichGlyph(opacityStyle: "ColorIconRotateRight"); + + protected override BitmapRotation Rotation => BitmapRotation.Clockwise90Degrees; + } +} diff --git a/src/Files.App/Commands/CommandCodes.cs b/src/Files.App/Commands/CommandCodes.cs index 2b27fddbfa2a..bb22de7c876b 100644 --- a/src/Files.App/Commands/CommandCodes.cs +++ b/src/Files.App/Commands/CommandCodes.cs @@ -77,7 +77,7 @@ public enum CommandCodes DecompressArchiveHere, DecompressArchiveToChildFolder, - // Image Edition + // Image Manipulation RotateLeft, RotateRight,