Move common things to AppCore from GuiApp
This commit is contained in:
@@ -1,91 +0,0 @@
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace FileTime.GuiApp.App.Configuration;
|
||||
|
||||
public class CommandBindingConfiguration
|
||||
{
|
||||
public List<KeyConfig> Keys { get; set; }
|
||||
|
||||
public string Command { get; set; }
|
||||
|
||||
public string KeysDisplayText => GetKeysDisplayText();
|
||||
|
||||
public CommandBindingConfiguration()
|
||||
{
|
||||
Command = null!;
|
||||
Keys = null!;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration(string command, IEnumerable<KeyConfig> keys)
|
||||
{
|
||||
Keys = new List<KeyConfig>(keys);
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration(string command, KeyConfig key)
|
||||
{
|
||||
Keys = new List<KeyConfig>() { key };
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration(string command, IEnumerable<Key> keys)
|
||||
{
|
||||
Keys = keys.Select(k => new KeyConfig(k)).ToList();
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration(string command, Key key)
|
||||
{
|
||||
Keys = new List<KeyConfig>() { new KeyConfig(key) };
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public string GetKeysDisplayText()
|
||||
{
|
||||
var s = "";
|
||||
|
||||
foreach (var k in Keys)
|
||||
{
|
||||
var keyString = k.Key.ToString();
|
||||
|
||||
if (keyString.Length == 1)
|
||||
{
|
||||
s += AddKeyWithCtrlOrAlt(k, s, (_, _, _) => k.Shift ? keyString.ToUpper() : keyString.ToLower());
|
||||
}
|
||||
else
|
||||
{
|
||||
s += AddKeyWithCtrlOrAlt(k, s, AddSpecialKey);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string AddKeyWithCtrlOrAlt(KeyConfig key, string currentText, Func<KeyConfig, string, bool, string> keyProcessor)
|
||||
{
|
||||
var s = "";
|
||||
|
||||
var ctrlOrAlt = key.Ctrl || key.Alt;
|
||||
|
||||
if (ctrlOrAlt && currentText.Length > 0 && currentText.Last() != ' ') s += " ";
|
||||
|
||||
if (key.Ctrl) s += "CTRL+";
|
||||
if (key.Alt) s += "ALT+";
|
||||
s += keyProcessor(key, currentText, ctrlOrAlt);
|
||||
|
||||
if (ctrlOrAlt) s += " ";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private static string AddSpecialKey(KeyConfig key, string currentText, bool wasCtrlOrAlt)
|
||||
{
|
||||
var s = "";
|
||||
|
||||
if (currentText.Length > 0 && currentText.Last() != ' ' && !wasCtrlOrAlt) s += " ";
|
||||
s += key.Key.ToString();
|
||||
if (!wasCtrlOrAlt) s += " ";
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace FileTime.GuiApp.App.Configuration;
|
||||
|
||||
public class KeyBindingConfiguration
|
||||
{
|
||||
public bool UseDefaultBindings { get; set; } = true;
|
||||
public List<CommandBindingConfiguration> DefaultKeyBindings { get; set; } = new();
|
||||
public List<CommandBindingConfiguration> KeyBindings { get; set; } = new();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace FileTime.GuiApp.App.Configuration;
|
||||
|
||||
public class KeyConfig
|
||||
{
|
||||
public Key Key { get; set; }
|
||||
public bool Shift { get; set; }
|
||||
public bool Alt { get; set; }
|
||||
public bool Ctrl { get; set; }
|
||||
|
||||
public KeyConfig() { }
|
||||
|
||||
public KeyConfig(
|
||||
Key key,
|
||||
bool shift = false,
|
||||
bool alt = false,
|
||||
bool ctrl = false)
|
||||
{
|
||||
Key = key;
|
||||
Shift = shift;
|
||||
Alt = alt;
|
||||
Ctrl = ctrl;
|
||||
}
|
||||
|
||||
public bool AreEquals(KeyConfig otherKeyConfig) =>
|
||||
Key == otherKeyConfig.Key
|
||||
&& Alt == otherKeyConfig.Alt
|
||||
&& Shift == otherKeyConfig.Shift
|
||||
&& Ctrl == otherKeyConfig.Ctrl;
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.UserCommand;
|
||||
using FileTime.Providers.LocalAdmin;
|
||||
|
||||
namespace FileTime.GuiApp.App.Configuration;
|
||||
|
||||
public static class MainConfiguration
|
||||
{
|
||||
private static readonly Lazy<List<CommandBindingConfiguration>> _defaultKeybindings = new(InitDefaultKeyBindings);
|
||||
|
||||
public static Dictionary<string, string?> Configuration { get; }
|
||||
|
||||
static MainConfiguration()
|
||||
{
|
||||
Configuration = new()
|
||||
{
|
||||
{AdminElevationConfiguration.SectionName + ":" + nameof(AdminElevationConfiguration.ServerExecutablePath), "FileTime.Server.exe"},
|
||||
};
|
||||
|
||||
PopulateDefaultEditorPrograms(Configuration);
|
||||
PopulateDefaultKeyBindings(Configuration, _defaultKeybindings.Value,
|
||||
SectionNames.KeybindingSectionName + ":" + nameof(KeyBindingConfiguration.DefaultKeyBindings));
|
||||
}
|
||||
|
||||
private static void PopulateDefaultKeyBindings(Dictionary<string, string?> configuration,
|
||||
List<CommandBindingConfiguration> 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());
|
||||
|
||||
for (var j = 0; j < commandBindingConfig.Keys.Count; j++)
|
||||
{
|
||||
var key = commandBindingConfig.Keys[j];
|
||||
var keyBaseKey = baseKey + $"keys:[{j}]:";
|
||||
configuration.Add(keyBaseKey + nameof(KeyConfig.Key), key.Key.ToString());
|
||||
configuration.Add(keyBaseKey + nameof(KeyConfig.Shift), key.Shift.ToString());
|
||||
configuration.Add(keyBaseKey + nameof(KeyConfig.Alt), key.Alt.ToString());
|
||||
configuration.Add(keyBaseKey + nameof(KeyConfig.Ctrl), key.Ctrl.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<CommandBindingConfiguration> InitDefaultKeyBindings() =>
|
||||
new List<CommandBindingConfiguration>
|
||||
{
|
||||
//new CommandBindingConfiguration(ConfigCommand.AutoRefresh, new KeyConfig(Key.R, shift: true)),
|
||||
//new CommandBindingConfiguration(ConfigCommand.ChangeTimelineMode, new[] { Key.T, Key.M }),
|
||||
new(CloseTabCommand.CommandName, Key.Q),
|
||||
//new CommandBindingConfiguration(ConfigCommand.Compress, new[] { Key.Y, Key.C }),
|
||||
new(CopyBase64Command.CommandName, new[] {Key.C, Key.B}),
|
||||
new(CopyCommand.CommandName, new[] {Key.Y, Key.Y}),
|
||||
//new CommandBindingConfiguration(ConfigCommand.CopyHash, new[] { Key.C, Key.H }),
|
||||
new(CopyNativePathCommand.CommandName, new[] {Key.C, Key.P}),
|
||||
new(CopyFilesToClipboardCommand.CommandName, new[] {Key.Y, Key.C}),
|
||||
new(CreateContainer.CommandName, Key.F7),
|
||||
new(CreateContainer.CommandName, new[] {Key.C, Key.C}),
|
||||
new(CreateElementCommand.CommandName, new[] {Key.C, Key.E}),
|
||||
//new CommandBindingConfiguration(ConfigCommand.Cut, new[] { Key.D, Key.D }),
|
||||
//new CommandBindingConfiguration(ConfigCommand.Edit, new KeyConfig(Key.F4)),
|
||||
new(EnterRapidTravelCommand.CommandName, new KeyConfig(Key.OemComma, shift: true)),
|
||||
new(EnterRapidTravelCommand.CommandName, new KeyConfig(Key.OemQuestion, shift: true)),
|
||||
new(GoBackCommand.CommandName, new KeyConfig(Key.Left, alt: true)),
|
||||
new(GoByFrequencyCommand.CommandName, Key.Z),
|
||||
new(GoForwardCommand.CommandName, new KeyConfig(Key.Right, alt: true)),
|
||||
new(GoToHomeCommand.CommandName, new[] {Key.G, Key.H}),
|
||||
new(GoToPathCommand.CommandName, new KeyConfig(Key.L, ctrl: true)),
|
||||
new(GoToPathCommand.CommandName, new[] {Key.G, Key.P}),
|
||||
new(GoToProviderCommand.CommandName, new[] {Key.G, Key.T}),
|
||||
new(GoToRootCommand.CommandName, new[] {Key.G, Key.R}),
|
||||
new(GoUpCommand.CommandName, Key.Left),
|
||||
new(DeleteCommand.HardDeleteCommandName, new[] {new KeyConfig(Key.D, shift: true), new KeyConfig(Key.D, shift: true)}),
|
||||
new(MarkCommand.CommandName, Key.Space),
|
||||
new(MoveCursorToLastCommand.CommandName, new KeyConfig(Key.G, shift: true)),
|
||||
new(MoveCursorToFirstCommand.CommandName, new[] {Key.G, Key.G}),
|
||||
new(MoveCursorUpCommand.CommandName, Key.Up),
|
||||
new(MoveCursorDownCommand.CommandName, Key.Down),
|
||||
new(MoveCursorUpPageCommand.CommandName, Key.PageUp),
|
||||
new(MoveCursorDownPageCommand.CommandName, Key.PageDown),
|
||||
//new CommandBindingConfiguration(ConfigCommand.NextTimelineBlock, Key.L ),
|
||||
//new CommandBindingConfiguration(ConfigCommand.NextTimelineCommand, Key.J ),
|
||||
new(OpenSelectedCommand.CommandName, Key.Right),
|
||||
new(OpenCommandPaletteCommand.CommandName, new[] {Key.F1}),
|
||||
new(OpenCommandPaletteCommand.CommandName, new[] {new KeyConfig(Key.P, ctrl: true, shift: true)}),
|
||||
new(OpenInDefaultFileExplorerCommand.CommandName, new[] {Key.O, Key.E}),
|
||||
new(PasteCommand.PasteMergeCommandName, new[] {Key.P, Key.P}),
|
||||
new(PasteCommand.PasteOverwriteCommandName, new[] {Key.P, Key.O}),
|
||||
new(PasteCommand.PasteSkipCommandName, new[] {Key.P, Key.S}),
|
||||
new(PasteFilesFromClipboardCommand.PasteMergeCommandName, new[] {new KeyConfig(Key.V, ctrl: true)}),
|
||||
new(PasteFilesFromClipboardCommand.PasteOverwriteCommandName, new[] {new KeyConfig(Key.V, ctrl: true, shift: true)}),
|
||||
//new CommandBindingConfiguration(ConfigCommand.PinFavorite, new[] { Key.F, Key.P }),
|
||||
//new CommandBindingConfiguration(ConfigCommand.PreviousTimelineBlock, Key.H ),
|
||||
//new CommandBindingConfiguration(ConfigCommand.PreviousTimelineCommand, Key.K ),
|
||||
new(RefreshCommand.CommandName, Key.R),
|
||||
new(RenameCommand.CommandName, Key.F2),
|
||||
new(RenameCommand.CommandName, new[] {Key.C, Key.W}),
|
||||
new(IdentifiableRunOrOpenCommand.CommandName, Key.Enter),
|
||||
//new CommandBindingConfiguration(ConfigCommand.RunCommand, new KeyConfig(Key.D4, shift: true)),
|
||||
//new CommandBindingConfiguration(ConfigCommand.ScanContainerSize, new[] { Key.C, Key.S }),
|
||||
//new CommandBindingConfiguration(ConfigCommand.ShowAllShortcut, Key.F1),
|
||||
new(DeleteCommand.SoftDeleteCommandName, new[] {new KeyConfig(Key.D), new KeyConfig(Key.D, shift: true)}),
|
||||
new(IdentifiableSearchCommand.SearchByNameContainsCommandName, new[] {Key.S, Key.N}),
|
||||
new(SwitchToTabCommand.SwitchToLastTabCommandName, new[] {new KeyConfig(Key.D9, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab1CommandName, new[] {new KeyConfig(Key.D1, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab2CommandName, new[] {new KeyConfig(Key.D2, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab3CommandName, new[] {new KeyConfig(Key.D3, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab4CommandName, new[] {new KeyConfig(Key.D4, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab5CommandName, new[] {new KeyConfig(Key.D5, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab6CommandName, new[] {new KeyConfig(Key.D6, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab7CommandName, new[] {new KeyConfig(Key.D7, alt: true)}),
|
||||
new(SwitchToTabCommand.SwitchToTab8CommandName, new[] {new KeyConfig(Key.D8, alt: true)}),
|
||||
new(PauseCommandSchedulerCommand.CommandName, new[] {Key.T, Key.P}),
|
||||
//new CommandBindingConfiguration(ConfigCommand.TimelineRefresh, new[] { Key.T, Key.R }),
|
||||
new(StartCommandSchedulerCommand.CommandName, new[] {Key.T, Key.S}),
|
||||
//new CommandBindingConfiguration(ConfigCommand.ToggleAdvancedIcons, new[] { Key.Z, Key.I }),
|
||||
};
|
||||
|
||||
private static void PopulateDefaultEditorPrograms(Dictionary<string, string?> configuration)
|
||||
{
|
||||
var editorPrograms = new List<ProgramConfiguration>()
|
||||
{
|
||||
new ProgramConfiguration(@"c:\Program Files\Notepad++\notepad++.exe"),
|
||||
new ProgramConfiguration("notepad.exe"),
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
if (editorPrograms[i].Arguments is string arguments)
|
||||
{
|
||||
configuration.Add(
|
||||
$"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Arguments)}",
|
||||
arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
namespace FileTime.GuiApp.App.Configuration;
|
||||
|
||||
public class ProgramConfiguration
|
||||
{
|
||||
public string? Path { get; set; }
|
||||
public string? Arguments { get; set; }
|
||||
|
||||
public ProgramConfiguration() { }
|
||||
|
||||
public ProgramConfiguration(string? path, string? arguments = null)
|
||||
{
|
||||
Path = path;
|
||||
Arguments = arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace FileTime.GuiApp.App.Configuration;
|
||||
|
||||
public class ProgramsConfiguration
|
||||
{
|
||||
public List<ProgramConfiguration> DefaultEditorPrograms { get; set; } = new();
|
||||
public List<ProgramConfiguration> EditorPrograms { get; set; } = new();
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace FileTime.GuiApp.App.Configuration;
|
||||
|
||||
public static class SectionNames
|
||||
{
|
||||
public const string KeybindingSectionName = "KeyBindings";
|
||||
public const string ProgramsSectionName = "Programs";
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace FileTime.GuiApp.App.Models;
|
||||
|
||||
public class KeyNotSupportedException : Exception
|
||||
{
|
||||
private readonly Key _key;
|
||||
|
||||
public KeyNotSupportedException(Key key) : base($"Key {key} is not supported.")
|
||||
{
|
||||
_key = key;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using FileTime.GuiApp.App.Configuration;
|
||||
|
||||
namespace FileTime.GuiApp.App.Services;
|
||||
|
||||
public interface IKeyboardConfigurationService
|
||||
{
|
||||
IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
|
||||
IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
|
||||
IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using FileTime.App.Core.Configuration;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.GuiApp.App.Configuration;
|
||||
using FileTime.GuiApp.App.Models;
|
||||
|
||||
namespace FileTime.GuiApp.App.ViewModels;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.GuiApp.App.ViewModels;
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using FileTime.GuiApp.App.Configuration;
|
||||
|
||||
namespace FileTime.GuiApp.App.Extensions;
|
||||
|
||||
public static class KeyConfigExtensions
|
||||
{
|
||||
public static bool AreKeysEqual(this IReadOnlyList<KeyConfig> collection1, IReadOnlyList<KeyConfig> collection2)
|
||||
=> collection1.Count == collection2.Count && collection1.Zip(collection2).All(t => t.First.AreEquals(t.Second));
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.Services;
|
||||
|
||||
namespace FileTime.GuiApp.App.Extensions;
|
||||
|
||||
public static class KeyEventArgsExtension
|
||||
{
|
||||
public static GeneralKeyEventArgs? ToGeneralKeyEventArgs(this KeyEventArgs args, IAppKeyService<Key> appKeyService)
|
||||
{
|
||||
var maybeKey = appKeyService.MapKey(args.Key);
|
||||
if (maybeKey is not {} key1) return null;
|
||||
return new GeneralKeyEventArgs(h => args.Handled = h)
|
||||
{
|
||||
Key = key1
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,13 @@ using FileTime.App.Core.ViewModels;
|
||||
using FileTime.Core.Extensions;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
using FileTime.GuiApp.App.Configuration;
|
||||
using FileTime.GuiApp.App.Extensions;
|
||||
using FileTime.GuiApp.App.Models;
|
||||
using FileTime.GuiApp.App.ViewModels;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using DeclarativeProperty;
|
||||
using FileTime.App.Core.Configuration;
|
||||
using FileTime.App.Core.Extensions;
|
||||
using FileTime.App.Core.Models;
|
||||
|
||||
namespace FileTime.GuiApp.App.Services;
|
||||
|
||||
@@ -24,6 +25,7 @@ public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
|
||||
private readonly ILogger<DefaultModeKeyInputHandler> _logger;
|
||||
private readonly IUserCommandHandlerService _userCommandHandlerService;
|
||||
private readonly IIdentifiableUserCommandService _identifiableUserCommandService;
|
||||
private readonly IAppKeyService<Key> _appKeyService;
|
||||
private readonly BindedCollection<IModalViewModel> _openModals;
|
||||
|
||||
public DefaultModeKeyInputHandler(
|
||||
@@ -32,10 +34,12 @@ public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
|
||||
IKeyboardConfigurationService keyboardConfigurationService,
|
||||
ILogger<DefaultModeKeyInputHandler> logger,
|
||||
IUserCommandHandlerService userCommandHandlerService,
|
||||
IIdentifiableUserCommandService identifiableUserCommandService)
|
||||
IIdentifiableUserCommandService identifiableUserCommandService,
|
||||
IAppKeyService<Key> appKeyService)
|
||||
{
|
||||
_appState = appState;
|
||||
_identifiableUserCommandService = identifiableUserCommandService;
|
||||
_appKeyService = appKeyService;
|
||||
_keyboardConfigurationService = keyboardConfigurationService;
|
||||
_logger = logger;
|
||||
_modalService = modalService;
|
||||
@@ -47,25 +51,26 @@ public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
|
||||
|
||||
_openModals = modalService.OpenModals.ToBindedCollection();
|
||||
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.Up)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.Down)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.Tab)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.PageDown)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.PageUp)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.F4, alt: true)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.LWin)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Key.RWin)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.Up)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.Down)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.Tab)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.PageDown)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.PageUp)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.F4, alt: true)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.LWin)});
|
||||
_keysToSkip.Add(new[] {new KeyConfig(Keys.RWin)});
|
||||
}
|
||||
|
||||
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
public async Task HandleInputKey(Key key2, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
{
|
||||
if (_appKeyService.MapKey(key2) is not { } key) return;
|
||||
var keyWithModifiers = new KeyConfig(key, shift: specialKeysStatus.IsShiftPressed, alt: specialKeysStatus.IsAltPressed, ctrl: specialKeysStatus.IsCtrlPressed);
|
||||
_appState.PreviousKeys.Add(keyWithModifiers);
|
||||
|
||||
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(_appState.PreviousKeys));
|
||||
selectedCommandBinding ??= _keyboardConfigurationService.CommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(_appState.PreviousKeys));
|
||||
|
||||
if (key == Key.Escape)
|
||||
if (key == Keys.Escape)
|
||||
{
|
||||
var doGeneralReset = _appState.PreviousKeys.Count > 1 || _appState.IsAllShortcutVisible;
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.GuiApp.App.Models;
|
||||
|
||||
namespace FileTime.GuiApp.App.Services;
|
||||
|
||||
public class GuiAppKeyService : IAppKeyService<Key>
|
||||
{
|
||||
private static readonly Dictionary<Key, Keys> KeyMapping;
|
||||
|
||||
//TODO: write test for this. Test if every enum value is present in the dictionary.
|
||||
public static ReadOnlyDictionary<Key, Keys> KeyMappingReadOnly { get; }
|
||||
|
||||
static GuiAppKeyService()
|
||||
{
|
||||
KeyMapping = new Dictionary<Key, Keys>
|
||||
{
|
||||
{Key.A, Keys.A},
|
||||
{Key.B, Keys.B},
|
||||
{Key.C, Keys.C},
|
||||
{Key.D, Keys.D},
|
||||
{Key.E, Keys.E},
|
||||
{Key.F, Keys.F},
|
||||
{Key.G, Keys.G},
|
||||
{Key.H, Keys.H},
|
||||
{Key.I, Keys.I},
|
||||
{Key.J, Keys.J},
|
||||
{Key.K, Keys.K},
|
||||
{Key.L, Keys.L},
|
||||
{Key.M, Keys.M},
|
||||
{Key.N, Keys.N},
|
||||
{Key.O, Keys.O},
|
||||
{Key.P, Keys.P},
|
||||
{Key.Q, Keys.Q},
|
||||
{Key.R, Keys.R},
|
||||
{Key.S, Keys.S},
|
||||
{Key.T, Keys.T},
|
||||
{Key.U, Keys.U},
|
||||
{Key.V, Keys.V},
|
||||
{Key.W, Keys.W},
|
||||
{Key.X, Keys.X},
|
||||
{Key.Y, Keys.Y},
|
||||
{Key.Z, Keys.Z},
|
||||
{Key.F1, Keys.F1},
|
||||
{Key.F2, Keys.F2},
|
||||
{Key.F3, Keys.F3},
|
||||
{Key.F4, Keys.F4},
|
||||
{Key.F5, Keys.F5},
|
||||
{Key.F6, Keys.F6},
|
||||
{Key.F7, Keys.F7},
|
||||
{Key.F8, Keys.F8},
|
||||
{Key.F9, Keys.F9},
|
||||
{Key.F10, Keys.F10},
|
||||
{Key.F11, Keys.F11},
|
||||
{Key.F12, Keys.F12},
|
||||
{Key.Up, Keys.Up},
|
||||
{Key.Down, Keys.Down},
|
||||
{Key.Left, Keys.Left},
|
||||
{Key.Right, Keys.Right},
|
||||
{Key.Enter, Keys.Enter},
|
||||
{Key.Escape, Keys.Escape},
|
||||
{Key.Back, Keys.Back},
|
||||
{Key.Space, Keys.Space},
|
||||
{Key.PageUp, Keys.PageUp},
|
||||
{Key.PageDown, Keys.PageDown},
|
||||
{Key.OemComma, Keys.Comma},
|
||||
{Key.OemQuestion, Keys.Question},
|
||||
{Key.Tab, Keys.Tab},
|
||||
{Key.LWin, Keys.LWin},
|
||||
{Key.RWin, Keys.RWin},
|
||||
};
|
||||
|
||||
KeyMappingReadOnly = new(KeyMapping);
|
||||
}
|
||||
|
||||
public Keys? MapKey(Key key)
|
||||
{
|
||||
if (!KeyMapping.TryGetValue(key, out var mappedKey)) return null;
|
||||
return mappedKey;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using FileTime.App.Core.UserCommand;
|
||||
using FileTime.GuiApp.App.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FileTime.GuiApp.App.Services;
|
||||
|
||||
public class KeyboardConfigurationService : IKeyboardConfigurationService
|
||||
{
|
||||
public IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
|
||||
public IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
|
||||
public IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
|
||||
|
||||
public KeyboardConfigurationService(IOptions<KeyBindingConfiguration> keyBindingConfiguration)
|
||||
{
|
||||
IEnumerable<CommandBindingConfiguration> keyBindings = keyBindingConfiguration.Value.KeyBindings;
|
||||
|
||||
if (keyBindingConfiguration.Value.UseDefaultBindings)
|
||||
{
|
||||
keyBindings = keyBindings.Concat(keyBindingConfiguration.Value.DefaultKeyBindings);
|
||||
}
|
||||
|
||||
var commandBindings = new List<CommandBindingConfiguration>();
|
||||
var universalCommandBindings = new List<CommandBindingConfiguration>();
|
||||
foreach (var keyBinding in keyBindings)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keyBinding.Command))
|
||||
{
|
||||
throw new FormatException($"No command is set in keybinding for keys '{keyBinding.KeysDisplayText}'");
|
||||
}
|
||||
else if (keyBinding.Keys.Count == 0)
|
||||
{
|
||||
throw new FormatException($"No keys set in keybinding for command '{keyBinding.Command}'.");
|
||||
}
|
||||
|
||||
if (IsUniversal(keyBinding))
|
||||
{
|
||||
universalCommandBindings.Add(keyBinding);
|
||||
}
|
||||
else
|
||||
{
|
||||
commandBindings.Add(keyBinding);
|
||||
}
|
||||
}
|
||||
|
||||
CommandBindings = commandBindings.AsReadOnly();
|
||||
UniversalCommandBindings = universalCommandBindings.AsReadOnly();
|
||||
AllShortcut = new List<CommandBindingConfiguration>(UniversalCommandBindings.Concat(CommandBindings)).AsReadOnly();
|
||||
}
|
||||
|
||||
private static bool IsUniversal(CommandBindingConfiguration keyMapping)
|
||||
{
|
||||
return keyMapping.Command is
|
||||
GoUpCommand.CommandName
|
||||
or OpenSelectedCommand.CommandName
|
||||
or MoveCursorDownCommand.CommandName
|
||||
or MoveCursorDownPageCommand.CommandName
|
||||
or MoveCursorUpCommand.CommandName
|
||||
or MoveCursorUpPageCommand.CommandName
|
||||
or IdentifiableRunOrOpenCommand.CommandName;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.Core.Extensions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FileTime.GuiApp.App.Services;
|
||||
|
||||
public class LifecycleService
|
||||
{
|
||||
private readonly IEnumerable<IExitHandler> _exitHandlers;
|
||||
private readonly IEnumerable<IStartupHandler> _startupHandlers;
|
||||
private readonly ILogger<LifecycleService> _logger;
|
||||
|
||||
public LifecycleService(
|
||||
IEnumerable<IStartupHandler> startupHandlers,
|
||||
IEnumerable<IExitHandler> exitHandlers,
|
||||
ILogger<LifecycleService> logger)
|
||||
{
|
||||
_exitHandlers = exitHandlers;
|
||||
_startupHandlers = startupHandlers;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task InitStartupHandlersAsync()
|
||||
{
|
||||
foreach (var startupHandler in _startupHandlers)
|
||||
{
|
||||
try
|
||||
{
|
||||
await startupHandler.InitAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while running startup handler {Handler}", startupHandler?.GetType().FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ExitAsync()
|
||||
{
|
||||
var exitCancellation = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
||||
var exitHandlerTasks = _exitHandlers.Select(e =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return e.ExitAsync(exitCancellation.Token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error while running exit handler {Handler}", e.GetType().FullName);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(exitHandlerTasks).TimeoutAfter(10000);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
exitCancellation.Cancel();
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using DynamicData;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.GuiApp.App.Services;
|
||||
|
||||
public class ModalService : IModalService
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly SourceList<IModalViewModel> _openModals = new();
|
||||
public IObservable<IChangeSet<IModalViewModel>> OpenModals { get; }
|
||||
public event EventHandler? AllModalClosed;
|
||||
|
||||
public ModalService(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
OpenModals = _openModals.Connect().StartWithEmpty();
|
||||
}
|
||||
|
||||
public void OpenModal(IModalViewModel modalToOpen) => _openModals.Add(modalToOpen);
|
||||
|
||||
public void CloseModal(IModalViewModel modalToClose)
|
||||
{
|
||||
_openModals.Remove(modalToClose);
|
||||
if (_openModals.Count == 0)
|
||||
{
|
||||
AllModalClosed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public T OpenModal<T>() where T : IModalViewModel
|
||||
{
|
||||
var modal = _serviceProvider.GetRequiredService<T>();
|
||||
OpenModal(modal);
|
||||
|
||||
return modal;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.Configuration;
|
||||
using FileTime.App.Core.Extensions;
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.UserCommand;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.Core.Extensions;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Services;
|
||||
using FileTime.GuiApp.App.Configuration;
|
||||
using FileTime.GuiApp.App.Extensions;
|
||||
using FileTime.GuiApp.App.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -22,6 +22,7 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
private readonly IUserCommandHandlerService _userCommandHandlerService;
|
||||
private readonly ILogger<RapidTravelModeKeyInputHandler> _logger;
|
||||
private readonly IIdentifiableUserCommandService _identifiableUserCommandService;
|
||||
private readonly IAppKeyService<Key> _appKeyService;
|
||||
private readonly BindedCollection<IModalViewModel> _openModals;
|
||||
private ITabViewModel? _selectedTab;
|
||||
|
||||
@@ -31,7 +32,8 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
IKeyboardConfigurationService keyboardConfigurationService,
|
||||
IUserCommandHandlerService userCommandHandlerService,
|
||||
ILogger<RapidTravelModeKeyInputHandler> logger,
|
||||
IIdentifiableUserCommandService identifiableUserCommandService)
|
||||
IIdentifiableUserCommandService identifiableUserCommandService,
|
||||
IAppKeyService<Key> appKeyService)
|
||||
{
|
||||
_appState = appState;
|
||||
_modalService = modalService;
|
||||
@@ -39,6 +41,7 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
_userCommandHandlerService = userCommandHandlerService;
|
||||
_logger = logger;
|
||||
_identifiableUserCommandService = identifiableUserCommandService;
|
||||
_appKeyService = appKeyService;
|
||||
|
||||
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
||||
|
||||
@@ -56,11 +59,12 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
});
|
||||
}
|
||||
|
||||
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
public async Task HandleInputKey(Key key2, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
{
|
||||
if (_appKeyService.MapKey(key2) is not { } key) return;
|
||||
var keyString = key.ToString();
|
||||
|
||||
if (key == Key.Escape)
|
||||
if (key == Keys.Escape)
|
||||
{
|
||||
setHandled(true);
|
||||
if ((_openModals.Collection?.Count ?? 0) > 0)
|
||||
@@ -72,7 +76,7 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
await CallCommandAsync(ExitRapidTravelCommand.Instance);
|
||||
}
|
||||
}
|
||||
else if (key == Key.Back)
|
||||
else if (key == Keys.Back)
|
||||
{
|
||||
if (_appState.RapidTravelText.Value!.Length > 0)
|
||||
{
|
||||
@@ -91,7 +95,7 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentKeyAsList = new List<KeyConfig>() {new KeyConfig(key)};
|
||||
var currentKeyAsList = new List<KeyConfig> {new(key)};
|
||||
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => c.Keys.AreKeysEqual(currentKeyAsList));
|
||||
if (selectedCommandBinding != null)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using DeclarativeProperty;
|
||||
using FileTime.App.CommandPalette.Services;
|
||||
using FileTime.App.CommandPalette.Services;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.App.FrequencyNavigation.Services;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace FileTime.GuiApp.App.ViewModels;
|
||||
[Inject(typeof(ILogger<MainWindowViewModel>), PropertyName = "_logger")]
|
||||
[Inject(typeof(IKeyInputHandlerService), PropertyName = "_keyInputHandlerService")]
|
||||
[Inject(typeof(IUserCommandHandlerService), PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(LifecycleService), PropertyName = "_lifecycleService")]
|
||||
[Inject(typeof(ILifecycleService), PropertyName = "_lifecycleService")]
|
||||
[Inject(typeof(IItemPreviewService), PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(IDialogService), PropertyAccessModifier = AccessModifier.Public)]
|
||||
[Inject(typeof(ITimelessContentProvider), PropertyName = "_timelessContentProvider")]
|
||||
|
||||
@@ -2,11 +2,16 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.CommandPalette.ViewModels;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.GuiApp.App.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.GuiApp.App.Views;
|
||||
|
||||
public partial class CommandPalette : UserControl
|
||||
{
|
||||
private readonly Lazy<IAppKeyService<Key>> _appKeyService = new(() => DI.ServiceProvider.GetRequiredService<IAppKeyService<Key>>());
|
||||
|
||||
public CommandPalette()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -34,14 +39,18 @@ public partial class CommandPalette : UserControl
|
||||
}
|
||||
else
|
||||
{
|
||||
viewModel.HandleKeyDown(e);
|
||||
if (e.ToGeneralKeyEventArgs(_appKeyService.Value) is not { } eventArgs) return;
|
||||
|
||||
viewModel.HandleKeyDown(eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
private void Search_OnKeyUp(object? sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Handled) return;
|
||||
if (DataContext is not ICommandPaletteViewModel viewModel) return;
|
||||
viewModel.HandleKeyUp(e);
|
||||
if (e.Handled
|
||||
|| DataContext is not ICommandPaletteViewModel viewModel) return;
|
||||
|
||||
if (e.ToGeneralKeyEventArgs(_appKeyService.Value) is not { } eventArgs) return;
|
||||
viewModel.HandleKeyUp(eventArgs);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,17 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.App.FrequencyNavigation.ViewModels;
|
||||
using FileTime.GuiApp.App.Extensions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.GuiApp.App.Views;
|
||||
|
||||
public partial class FrequencyNavigation : UserControl
|
||||
{
|
||||
private readonly Lazy<IAppKeyService<Key>> _appKeyService = new(() => DI.ServiceProvider.GetRequiredService<IAppKeyService<Key>>());
|
||||
|
||||
public FrequencyNavigation()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -34,14 +39,18 @@ public partial class FrequencyNavigation : UserControl
|
||||
}
|
||||
else
|
||||
{
|
||||
viewModel.HandleKeyDown(e);
|
||||
if (e.ToGeneralKeyEventArgs(_appKeyService.Value) is not { } eventArgs) return;
|
||||
|
||||
viewModel.HandleKeyDown(eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
private void Search_OnKeyUp(object? sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Handled) return;
|
||||
if (DataContext is not IFrequencyNavigationViewModel viewModel) return;
|
||||
viewModel.HandleKeyUp(e);
|
||||
if (e.Handled
|
||||
|| DataContext is not IFrequencyNavigationViewModel viewModel) return;
|
||||
|
||||
if (e.ToGeneralKeyEventArgs(_appKeyService.Value) is not { } eventArgs) return;
|
||||
viewModel.HandleKeyUp(eventArgs);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
xmlns:appCoreModels="using:FileTime.App.Core.Models"
|
||||
xmlns:appInteractions="using:FileTime.App.Core.Interactions"
|
||||
xmlns:config="using:FileTime.GuiApp.App.Configuration"
|
||||
xmlns:configuration="clr-namespace:FileTime.App.Core.Configuration;assembly=FileTime.App.Core.Abstraction"
|
||||
xmlns:corevm="using:FileTime.App.Core.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
|
||||
@@ -764,7 +765,7 @@
|
||||
|
||||
<ItemsRepeater Grid.Row="1" ItemsSource="{Binding AppState.PossibleCommands}">
|
||||
<ItemsRepeater.ItemTemplate>
|
||||
<DataTemplate x:DataType="config:CommandBindingConfiguration">
|
||||
<DataTemplate x:DataType="configuration:CommandBindingConfiguration">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200" />
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.Configuration;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.App.Core.ViewModels.Timeline;
|
||||
using FileTime.GuiApp.App.Configuration;
|
||||
using FileTime.GuiApp.App.Models;
|
||||
using FileTime.GuiApp.App.ViewModels;
|
||||
using MvvmGen;
|
||||
|
||||
@@ -3,7 +3,7 @@ using FileTime.GuiApp.App.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.GuiApp.Font;
|
||||
namespace FileTime.GuiApp.App.Font;
|
||||
|
||||
public static class Startup
|
||||
{
|
||||
|
||||
@@ -6,9 +6,9 @@ using FileTime.App.DependencyInjection;
|
||||
using FileTime.App.FrequencyNavigation;
|
||||
using FileTime.App.Search;
|
||||
using FileTime.GuiApp.App;
|
||||
using FileTime.GuiApp.App.Font;
|
||||
using FileTime.GuiApp.App.ViewModels;
|
||||
using FileTime.GuiApp.App.Views;
|
||||
using FileTime.GuiApp.Font;
|
||||
using FileTime.Server.Common;
|
||||
using FileTime.Tools.Compression;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.Configuration;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.Core.Interactions;
|
||||
@@ -54,14 +56,13 @@ public static class Startup
|
||||
serviceCollection.TryAddSingleton<IDefaultModeKeyInputHandler, DefaultModeKeyInputHandler>();
|
||||
serviceCollection.TryAddSingleton<IKeyboardConfigurationService, KeyboardConfigurationService>();
|
||||
serviceCollection.TryAddSingleton<IRapidTravelModeKeyInputHandler, RapidTravelModeKeyInputHandler>();
|
||||
serviceCollection.TryAddSingleton<LifecycleService>();
|
||||
serviceCollection.TryAddSingleton<IIconProvider, MaterialIconProvider>();
|
||||
serviceCollection.TryAddSingleton<IModalService, ModalService>();
|
||||
serviceCollection.TryAddSingleton<IDialogService, DialogService>();
|
||||
serviceCollection.TryAddSingleton<SystemClipboardService>();
|
||||
serviceCollection.TryAddSingleton<ISystemClipboardService>(sp => sp.GetRequiredService<SystemClipboardService>());
|
||||
serviceCollection.TryAddSingleton<ToastMessageSink>();
|
||||
serviceCollection.TryAddSingleton<IUserCommunicationService>(s => s.GetRequiredService<IDialogService>());
|
||||
serviceCollection.TryAddSingleton<IAppKeyService<Key>, GuiAppKeyService>();
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user