From d94d198344b4e1745905d8b5fab56a2159a541da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Kov=C3=A1cs?= Date: Tue, 24 May 2022 20:37:12 +0200 Subject: [PATCH] Navigation commands --- .../UserCommand/GoToHomeCommand.cs | 13 +++ .../UserCommand/GoToProviderCommand.cs | 13 +++ .../UserCommand/GoToRootCommand.cs | 13 +++ .../UserCommand/MoveCursorDownPageCommand.cs | 13 +++ .../UserCommand/MoveCursorToFirstCommand.cs | 13 +++ .../UserCommand/MoveCursorToLastCommand.cs | 13 +++ .../UserCommand/MoveCursorUpPageCommand.cs | 13 +++ .../NavigationUserCommandHandlerService.cs | 92 ++++++++++++++++++- ...faultIdentifiableCommandHandlerRegister.cs | 7 ++ .../Configuration/MainConfiguration.cs | 33 ++++--- 10 files changed, 206 insertions(+), 17 deletions(-) create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToHomeCommand.cs create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToProviderCommand.cs create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToRootCommand.cs create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorDownPageCommand.cs create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToFirstCommand.cs create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToLastCommand.cs create mode 100644 src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorUpPageCommand.cs diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToHomeCommand.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToHomeCommand.cs new file mode 100644 index 0000000..6d5433a --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToHomeCommand.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public class GoToHomeCommand : IIdentifiableUserCommand +{ + public const string CommandName = "go_to_home"; + public static GoToHomeCommand Instance { get; } = new GoToHomeCommand(); + + private GoToHomeCommand() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToProviderCommand.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToProviderCommand.cs new file mode 100644 index 0000000..a73c5e6 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToProviderCommand.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public class GoToProviderCommand : IIdentifiableUserCommand +{ + public const string CommandName = "go_to_provider"; + public static GoToProviderCommand Instance { get; } = new GoToProviderCommand(); + + private GoToProviderCommand() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToRootCommand.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToRootCommand.cs new file mode 100644 index 0000000..46b6840 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/GoToRootCommand.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public class GoToRootCommand : IIdentifiableUserCommand +{ + public const string CommandName = "go_to_root"; + public static GoToRootCommand Instance { get; } = new GoToRootCommand(); + + private GoToRootCommand() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorDownPageCommand.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorDownPageCommand.cs new file mode 100644 index 0000000..47f5a32 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorDownPageCommand.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public class MoveCursorDownPageCommand : IIdentifiableUserCommand +{ + public const string CommandName = "move_cursor_down_page"; + public static MoveCursorDownPageCommand Instance { get; } = new MoveCursorDownPageCommand(); + + private MoveCursorDownPageCommand() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToFirstCommand.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToFirstCommand.cs new file mode 100644 index 0000000..34c9d42 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToFirstCommand.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public class MoveCursorToFirstCommand : IIdentifiableUserCommand +{ + public const string CommandName = "move_cursor_to_first"; + public static MoveCursorToFirstCommand Instance { get; } = new MoveCursorToFirstCommand(); + + private MoveCursorToFirstCommand() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToLastCommand.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToLastCommand.cs new file mode 100644 index 0000000..97f60d5 --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorToLastCommand.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public class MoveCursorToLastCommand : IIdentifiableUserCommand +{ + public const string CommandName = "move_cursor_to_last"; + public static MoveCursorToLastCommand Instance { get; } = new MoveCursorToLastCommand(); + + private MoveCursorToLastCommand() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorUpPageCommand.cs b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorUpPageCommand.cs new file mode 100644 index 0000000..eaa7a3a --- /dev/null +++ b/src/AppCommon/FileTime.App.Core.Abstraction/UserCommand/MoveCursorUpPageCommand.cs @@ -0,0 +1,13 @@ +namespace FileTime.App.Core.UserCommand; + +public class MoveCursorUpPageCommand : IIdentifiableUserCommand +{ + public const string CommandName = "move_cursor_up_page"; + public static MoveCursorUpPageCommand Instance { get; } = new MoveCursorUpPageCommand(); + + private MoveCursorUpPageCommand() + { + } + + public string UserCommandID => CommandName; +} \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/NavigationUserCommandHandlerService.cs b/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/NavigationUserCommandHandlerService.cs index 12d8f18..298c072 100644 --- a/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/NavigationUserCommandHandlerService.cs +++ b/src/AppCommon/FileTime.App.Core/Services/UserCommandHandler/NavigationUserCommandHandlerService.cs @@ -13,6 +13,7 @@ namespace FileTime.App.Core.Services.UserCommandHandler; public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase { + private const int PageSize = 8; private readonly IAppState _appState; private readonly IServiceProvider _serviceProvider; private readonly ILocalContentProvider _localContentProvider; @@ -49,9 +50,16 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase new TypeUserCommandHandler(CloseTab), new TypeUserCommandHandler(EnterRapidTravel), new TypeUserCommandHandler(ExitRapidTravel), + new TypeUserCommandHandler(GoToHome), + new TypeUserCommandHandler(GoToProvider), + new TypeUserCommandHandler(GoToRoot), new TypeUserCommandHandler(GoUp), new TypeUserCommandHandler(MoveCursorDown), + new TypeUserCommandHandler(MoveCursorDownPage), + new TypeUserCommandHandler(MoveCursorToFirst), + new TypeUserCommandHandler(MoveCursorToLast), new TypeUserCommandHandler(MoveCursorUp), + new TypeUserCommandHandler(MoveCursorUpPage), new TypeUserCommandHandler(OpenContainer), new TypeUserCommandHandler(OpenSelected), new TypeUserCommandHandler(Refresh), @@ -59,10 +67,48 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase }); } - private async Task Refresh(RefreshCommand command) + private async Task GoToHome() + { + var path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + var resolvedPath = + await _localContentProvider.GetItemByNativePathAsync(new NativePath(path), PointInTime.Present); + if (resolvedPath is IContainer homeFolder) + { + await _userCommandHandlerService.HandleCommandAsync( + new OpenContainerCommand(new AbsolutePath(_timelessContentProvider, homeFolder))); + } + } + + private async Task GoToRoot() + { + var root = _currentLocation; + if (root is null) return; + + while (true) + { + var parent = root.Parent; + if (parent is null || string.IsNullOrWhiteSpace(parent.Path.Path)) break; + if (await parent.ResolveAsync() is not IContainer next) break; + root = next; + } + + await _userCommandHandlerService.HandleCommandAsync( + new OpenContainerCommand(new AbsolutePath(_timelessContentProvider, root))); + } + + private async Task GoToProvider() + { + if (_currentLocation is null) return; + + await _userCommandHandlerService.HandleCommandAsync( + new OpenContainerCommand(new AbsolutePath(_timelessContentProvider, _currentLocation.Provider))); + } + + private async Task Refresh() { if (_currentLocation?.FullName is null) return; - var refreshedItem = await _timelessContentProvider.GetItemByFullNameAsync(_currentLocation.FullName, PointInTime.Present); + var refreshedItem = + await _timelessContentProvider.GetItemByFullNameAsync(_currentLocation.FullName, PointInTime.Present); if (refreshedItem is not IContainer refreshedContainer) return; @@ -95,13 +141,51 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase private Task MoveCursorDown() { - SelectNewSelectedItem(i => i.SkipWhile(i => !i.EqualsTo(_currentSelectedItem)).Skip(1).FirstOrDefault()); + SelectNewSelectedItem(items => + items.SkipWhile(i => !i.EqualsTo(_currentSelectedItem)).Skip(1).FirstOrDefault()); return Task.CompletedTask; } private Task MoveCursorUp() { - SelectNewSelectedItem(i => i.TakeWhile(i => !i.EqualsTo(_currentSelectedItem)).LastOrDefault()); + SelectNewSelectedItem(items => items.TakeWhile(i => !i.EqualsTo(_currentSelectedItem)).LastOrDefault()); + return Task.CompletedTask; + } + + private Task MoveCursorDownPage() + { + SelectNewSelectedItem(items => + { + var relevantItems = items.SkipWhile(i => !i.EqualsTo(_currentSelectedItem)).ToList(); + var fallBackItems = relevantItems.Take(PageSize + 1).Reverse(); + var preferredItems = relevantItems.Skip(PageSize + 1); + + return preferredItems.Concat(fallBackItems).FirstOrDefault(); + }); + return Task.CompletedTask; + } + + private Task MoveCursorUpPage() + { + SelectNewSelectedItem(items => + { + var relevantItems = items.TakeWhile(i => !i.EqualsTo(_currentSelectedItem)).Reverse().ToList(); + var fallBackItems = relevantItems.Take(PageSize).Reverse(); + var preferredItems = relevantItems.Skip(PageSize); + return preferredItems.Concat(fallBackItems).FirstOrDefault(); + }); + return Task.CompletedTask; + } + + private Task MoveCursorToFirst() + { + SelectNewSelectedItem(items => items.FirstOrDefault()); + return Task.CompletedTask; + } + + private Task MoveCursorToLast() + { + SelectNewSelectedItem(items => items.LastOrDefault()); return Task.CompletedTask; } diff --git a/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs b/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs index 192109a..9ee1e88 100644 --- a/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs +++ b/src/AppCommon/FileTime.App.Core/StartupServices/DefaultIdentifiableCommandHandlerRegister.cs @@ -17,10 +17,17 @@ public class DefaultIdentifiableCommandHandlerRegister : IStartupHandler AddUserCommand(CreateElement.Instance); AddUserCommand(EnterRapidTravelCommand.Instance); AddUserCommand(ExitRapidTravelCommand.Instance); + AddUserCommand(GoToHomeCommand.Instance); + AddUserCommand(GoToProviderCommand.Instance); + AddUserCommand(GoToRootCommand.Instance); AddUserCommand(GoUpCommand.Instance); AddUserCommand(MarkCommand.Instance); AddUserCommand(MoveCursorDownCommand.Instance); + AddUserCommand(MoveCursorDownPageCommand.Instance); + AddUserCommand(MoveCursorToFirstCommand.Instance); + AddUserCommand(MoveCursorToLastCommand.Instance); AddUserCommand(MoveCursorUpCommand.Instance); + AddUserCommand(MoveCursorUpPageCommand.Instance); AddUserCommand(OpenSelectedCommand.Instance); AddUserCommand(PasteCommand.Merge); AddUserCommand(PasteCommand.Overwrite); diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs b/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs index cf6349d..c5a363f 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.Abstractions/Configuration/MainConfiguration.cs @@ -13,16 +13,19 @@ public static class MainConfiguration { Configuration = new(); PopulateDefaultEditorPrograms(Configuration); - PopulateDefaultKeyBindings(Configuration, _defaultKeybindings.Value, SectionNames.KeybindingSectionName + ":" + nameof(KeyBindingConfiguration.DefaultKeyBindings)); + PopulateDefaultKeyBindings(Configuration, _defaultKeybindings.Value, + SectionNames.KeybindingSectionName + ":" + nameof(KeyBindingConfiguration.DefaultKeyBindings)); } - private static void PopulateDefaultKeyBindings(Dictionary configuration, List commandBindingConfigs, string basePath) + private static void PopulateDefaultKeyBindings(Dictionary configuration, + List commandBindingConfigs, string basePath) { for (var i = 0; i < commandBindingConfigs.Count; i++) { var baseKey = basePath + $":[{i}]:"; var commandBindingConfig = commandBindingConfigs[i]; - configuration.Add(baseKey + nameof(CommandBindingConfiguration.Command), commandBindingConfig.Command.ToString()); + configuration.Add(baseKey + nameof(CommandBindingConfiguration.Command), + commandBindingConfig.Command.ToString()); for (var j = 0; j < commandBindingConfig.Keys.Count; j++) { @@ -52,18 +55,18 @@ public static class MainConfiguration new CommandBindingConfiguration(CreateElement.CommandName, new[] { Key.C, Key.E }), //new CommandBindingConfiguration(ConfigCommand.Cut, new[] { Key.D, Key.D }), //new CommandBindingConfiguration(ConfigCommand.Edit, new KeyConfig(Key.F4)), - new CommandBindingConfiguration(EnterRapidTravelCommand.CommandName, new KeyConfig(Key.OemComma, shift: true)), + new CommandBindingConfiguration(EnterRapidTravelCommand.CommandName,new KeyConfig(Key.OemComma, shift: true)), //new CommandBindingConfiguration(ConfigCommand.FindByName, new[] { Key.F, Key.N }), //new CommandBindingConfiguration(ConfigCommand.FindByNameRegex, new[] { Key.F, Key.R }), - //new CommandBindingConfiguration(ConfigCommand.GoToHome, new[] { Key.G, Key.H }), + new CommandBindingConfiguration(GoToHomeCommand.CommandName, new[] { Key.G, Key.H }), //new CommandBindingConfiguration(ConfigCommand.GoToPath, new KeyConfig(Key.L, ctrl: true)), //new CommandBindingConfiguration(ConfigCommand.GoToPath, new[] { Key.G, Key.P }), - //new CommandBindingConfiguration(ConfigCommand.GoToProvider, new[] { Key.G, Key.T }), - //new CommandBindingConfiguration(ConfigCommand.GoToRoot, new[] { Key.G, Key.R }), + new CommandBindingConfiguration(GoToProviderCommand.CommandName, new[] { Key.G, Key.T }), + new CommandBindingConfiguration(GoToRootCommand.CommandName, new[] { Key.G, Key.R }), //new CommandBindingConfiguration(ConfigCommand.HardDelete, new[] { new KeyConfig(Key.D,shift: true), new KeyConfig(Key.D, shift: true) }), new CommandBindingConfiguration(MarkCommand.CommandName, Key.Space), - //new CommandBindingConfiguration(ConfigCommand.MoveToLast, new KeyConfig(Key.G, shift: true)), - //new CommandBindingConfiguration(ConfigCommand.MoveToFirst, new[] { Key.G, Key.G }), + new CommandBindingConfiguration(MoveCursorToLastCommand.CommandName, new KeyConfig(Key.G, shift: true)), + new CommandBindingConfiguration(MoveCursorToFirstCommand.CommandName, new[] { Key.G, Key.G }), //new CommandBindingConfiguration(ConfigCommand.NextTimelineBlock, Key.L ), //new CommandBindingConfiguration(ConfigCommand.NextTimelineCommand, Key.J ), //new CommandBindingConfiguration(ConfigCommand.OpenInFileBrowser, new[] { Key.O, Key.E }), @@ -98,8 +101,8 @@ public static class MainConfiguration //new CommandBindingConfiguration(ConfigCommand.OpenOrRun, Key.Enter), new CommandBindingConfiguration(MoveCursorUpCommand.CommandName, Key.Up), new CommandBindingConfiguration(MoveCursorDownCommand.CommandName, Key.Down), - //new CommandBindingConfiguration(ConfigCommand.MoveCursorUpPage, Key.PageUp), - //new CommandBindingConfiguration(ConfigCommand.MoveCursorDownPage, Key.PageDown), + new CommandBindingConfiguration(MoveCursorUpPageCommand.CommandName, Key.PageUp), + new CommandBindingConfiguration(MoveCursorDownPageCommand.CommandName, Key.PageDown), }; } @@ -114,11 +117,15 @@ public static class MainConfiguration for (var i = 0; i < editorPrograms.Count; i++) { if (editorPrograms[i].Path is not string path) continue; - configuration.Add($"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Path)}", path); + configuration.Add( + $"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Path)}", + path); if (editorPrograms[i].Arguments is string arguments) { - configuration.Add($"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Arguments)}", arguments); + configuration.Add( + $"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Arguments)}", + arguments); } } }