File scoped namespace
This commit is contained in:
@@ -1,89 +1,88 @@
|
||||
using Avalonia.Input;
|
||||
using FileTime.App.Core.Command;
|
||||
|
||||
namespace FileTime.GuiApp.Configuration
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public class CommandBindingConfiguration
|
||||
{
|
||||
public class CommandBindingConfiguration
|
||||
public List<KeyConfig> Keys { get; set; } = new List<KeyConfig>();
|
||||
|
||||
public Commands Command { get; set; } = Commands.None;
|
||||
|
||||
public string KeysDisplayText => GetKeysDisplayText();
|
||||
|
||||
public CommandBindingConfiguration() { }
|
||||
|
||||
public CommandBindingConfiguration(Commands command, IEnumerable<KeyConfig> keys)
|
||||
{
|
||||
public List<KeyConfig> Keys { get; set; } = new List<KeyConfig>();
|
||||
Keys = new List<KeyConfig>(keys);
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public Commands Command { get; set; } = Commands.None;
|
||||
public CommandBindingConfiguration(Commands command, KeyConfig key)
|
||||
{
|
||||
Keys = new List<KeyConfig>() { key };
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public string KeysDisplayText => GetKeysDisplayText();
|
||||
public CommandBindingConfiguration(Commands command, IEnumerable<Key> keys)
|
||||
{
|
||||
Keys = keys.Select(k => new KeyConfig(k)).ToList();
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration() { }
|
||||
public CommandBindingConfiguration(Commands command, Key key)
|
||||
{
|
||||
Keys = new List<KeyConfig>() { new KeyConfig(key) };
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration(Commands command, IEnumerable<KeyConfig> keys)
|
||||
public string GetKeysDisplayText()
|
||||
{
|
||||
var s = "";
|
||||
|
||||
foreach (var k in Keys)
|
||||
{
|
||||
Keys = new List<KeyConfig>(keys);
|
||||
Command = command;
|
||||
}
|
||||
var keyString = k.Key.ToString();
|
||||
|
||||
public CommandBindingConfiguration(Commands command, KeyConfig key)
|
||||
{
|
||||
Keys = new List<KeyConfig>() { key };
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration(Commands command, IEnumerable<Key> keys)
|
||||
{
|
||||
Keys = keys.Select(k => new KeyConfig(k)).ToList();
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public CommandBindingConfiguration(Commands command, Key key)
|
||||
{
|
||||
Keys = new List<KeyConfig>() { new KeyConfig(key) };
|
||||
Command = command;
|
||||
}
|
||||
|
||||
public string GetKeysDisplayText()
|
||||
{
|
||||
var s = "";
|
||||
|
||||
foreach (var k in Keys)
|
||||
if (keyString.Length == 1)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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 = "";
|
||||
return s;
|
||||
}
|
||||
|
||||
bool ctrlOrAlt = key.Ctrl || key.Alt;
|
||||
private static string AddKeyWithCtrlOrAlt(KeyConfig key, string currentText, Func<KeyConfig, string, bool, string> keyProcessor)
|
||||
{
|
||||
var s = "";
|
||||
|
||||
if (ctrlOrAlt && currentText.Length > 0 && currentText.Last() != ' ') s += " ";
|
||||
bool ctrlOrAlt = key.Ctrl || key.Alt;
|
||||
|
||||
if (key.Ctrl) s += "CTRL+";
|
||||
if (key.Alt) s += "ALT+";
|
||||
s += keyProcessor(key, currentText, ctrlOrAlt);
|
||||
if (ctrlOrAlt && currentText.Length > 0 && currentText.Last() != ' ') s += " ";
|
||||
|
||||
if (ctrlOrAlt) s += " ";
|
||||
if (key.Ctrl) s += "CTRL+";
|
||||
if (key.Alt) s += "ALT+";
|
||||
s += keyProcessor(key, currentText, ctrlOrAlt);
|
||||
|
||||
return s;
|
||||
}
|
||||
if (ctrlOrAlt) s += " ";
|
||||
|
||||
private static string AddSpecialKey(KeyConfig key, string currentText, bool wasCtrlOrAlt)
|
||||
{
|
||||
var s = "";
|
||||
return s;
|
||||
}
|
||||
|
||||
if (currentText.Length > 0 && currentText.Last() != ' ' && !wasCtrlOrAlt) s += " ";
|
||||
s += key.Key.ToString();
|
||||
if (!wasCtrlOrAlt) s += " ";
|
||||
private static string AddSpecialKey(KeyConfig key, string currentText, bool wasCtrlOrAlt)
|
||||
{
|
||||
var s = "";
|
||||
|
||||
return s;
|
||||
}
|
||||
if (currentText.Length > 0 && currentText.Last() != ' ' && !wasCtrlOrAlt) s += " ";
|
||||
s += key.Key.ToString();
|
||||
if (!wasCtrlOrAlt) s += " ";
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
namespace FileTime.GuiApp.Configuration
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public class KeyBindingConfiguration
|
||||
{
|
||||
public class KeyBindingConfiguration
|
||||
{
|
||||
public bool UseDefaultBindings { get; set; } = true;
|
||||
public List<CommandBindingConfiguration> DefaultKeyBindings { get; set; } = new();
|
||||
public List<CommandBindingConfiguration> KeyBindings { get; set; } = new();
|
||||
}
|
||||
public bool UseDefaultBindings { get; set; } = true;
|
||||
public List<CommandBindingConfiguration> DefaultKeyBindings { get; set; } = new();
|
||||
public List<CommandBindingConfiguration> KeyBindings { get; set; } = new();
|
||||
}
|
||||
@@ -1,32 +1,31 @@
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace FileTime.GuiApp.Configuration
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public class KeyConfig
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
@@ -3,125 +3,124 @@ using FileTime.App.Core.Command;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FileTime.GuiApp.Configuration
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public static class MainConfiguration
|
||||
{
|
||||
public static class MainConfiguration
|
||||
private static readonly Lazy<List<CommandBindingConfiguration>> _defaultKeybindings = new(InitDefaultKeyBindings);
|
||||
|
||||
public static Dictionary<string, string> Configuration { get; }
|
||||
|
||||
static MainConfiguration()
|
||||
{
|
||||
private static readonly Lazy<List<CommandBindingConfiguration>> _defaultKeybindings = new(InitDefaultKeyBindings);
|
||||
Configuration = new();
|
||||
PopulateDefaultEditorPrograms(Configuration);
|
||||
PopulateDefaultKeyBindings(Configuration, _defaultKeybindings.Value, SectionNames.KeybindingSectionName + ":" + nameof(KeyBindingConfiguration.DefaultKeyBindings));
|
||||
}
|
||||
|
||||
public static Dictionary<string, string> Configuration { get; }
|
||||
|
||||
static MainConfiguration()
|
||||
private static void PopulateDefaultKeyBindings(Dictionary<string, string> configuration, List<CommandBindingConfiguration> commandBindingConfigs, string basePath)
|
||||
{
|
||||
for (var i = 0; i < commandBindingConfigs.Count; i++)
|
||||
{
|
||||
Configuration = new();
|
||||
PopulateDefaultEditorPrograms(Configuration);
|
||||
PopulateDefaultKeyBindings(Configuration, _defaultKeybindings.Value, SectionNames.KeybindingSectionName + ":" + nameof(KeyBindingConfiguration.DefaultKeyBindings));
|
||||
}
|
||||
var baseKey = basePath + $":[{i}]:";
|
||||
var commandBindingConfig = commandBindingConfigs[i];
|
||||
configuration.Add(baseKey + nameof(CommandBindingConfiguration.Command), commandBindingConfig.Command.ToString());
|
||||
|
||||
private static void PopulateDefaultKeyBindings(Dictionary<string, string> configuration, List<CommandBindingConfiguration> commandBindingConfigs, string basePath)
|
||||
{
|
||||
for (var i = 0; i < commandBindingConfigs.Count; i++)
|
||||
for (var j = 0; j < commandBindingConfig.Keys.Count; j++)
|
||||
{
|
||||
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());
|
||||
}
|
||||
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()
|
||||
private static List<CommandBindingConfiguration> InitDefaultKeyBindings()
|
||||
{
|
||||
return new List<CommandBindingConfiguration>()
|
||||
{
|
||||
return new List<CommandBindingConfiguration>()
|
||||
{
|
||||
new CommandBindingConfiguration(Commands.AutoRefresh, new KeyConfig(Key.R, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.ChangeTimelineMode, new[] { Key.T, Key.M }),
|
||||
new CommandBindingConfiguration(Commands.CloseTab, Key.Q),
|
||||
new CommandBindingConfiguration(Commands.Compress, new[] { Key.Y, Key.C }),
|
||||
new CommandBindingConfiguration(Commands.Copy, new[] { Key.Y, Key.Y }),
|
||||
new CommandBindingConfiguration(Commands.CopyHash, new[] { Key.C, Key.H }),
|
||||
new CommandBindingConfiguration(Commands.CopyPath, new[] { Key.C, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.CreateContainer, Key.F7),
|
||||
new CommandBindingConfiguration(Commands.CreateContainer, new[] { Key.C, Key.C }),
|
||||
new CommandBindingConfiguration(Commands.CreateElement, new[] { Key.C, Key.E }),
|
||||
new CommandBindingConfiguration(Commands.Cut, new[] { Key.D, Key.D }),
|
||||
new CommandBindingConfiguration(Commands.Edit, new KeyConfig(Key.F4)),
|
||||
new CommandBindingConfiguration(Commands.EnterRapidTravel, new KeyConfig(Key.OemComma, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.FindByName, new[] { Key.F, Key.N }),
|
||||
new CommandBindingConfiguration(Commands.FindByNameRegex, new[] { Key.F, Key.R }),
|
||||
new CommandBindingConfiguration(Commands.GoToHome, new[] { Key.G, Key.H }),
|
||||
new CommandBindingConfiguration(Commands.GoToPath, new KeyConfig(Key.L, ctrl: true)),
|
||||
new CommandBindingConfiguration(Commands.GoToPath, new[] { Key.G, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.GoToProvider, new[] { Key.G, Key.T }),
|
||||
new CommandBindingConfiguration(Commands.GoToRoot, new[] { Key.G, Key.R }),
|
||||
new CommandBindingConfiguration(Commands.HardDelete, new[] { new KeyConfig(Key.D,shift: true), new KeyConfig(Key.D, shift: true) }),
|
||||
new CommandBindingConfiguration(Commands.Mark, Key.Space),
|
||||
new CommandBindingConfiguration(Commands.MoveToLast, new KeyConfig(Key.G, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.MoveToFirst, new[] { Key.G, Key.G }),
|
||||
new CommandBindingConfiguration(Commands.NextTimelineBlock, Key.L ),
|
||||
new CommandBindingConfiguration(Commands.NextTimelineCommand, Key.J ),
|
||||
new CommandBindingConfiguration(Commands.OpenInFileBrowser, new[] { Key.O, Key.E }),
|
||||
new CommandBindingConfiguration(Commands.PasteMerge, new[] { Key.P, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.PasteOverwrite, new[] { Key.P, Key.O }),
|
||||
new CommandBindingConfiguration(Commands.PasteSkip, new[] { Key.P, Key.S }),
|
||||
new CommandBindingConfiguration(Commands.PinFavorite, new[] { Key.F, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.PreviousTimelineBlock, Key.H ),
|
||||
new CommandBindingConfiguration(Commands.PreviousTimelineCommand, Key.K ),
|
||||
new CommandBindingConfiguration(Commands.Refresh, Key.R),
|
||||
new CommandBindingConfiguration(Commands.Rename, Key.F2),
|
||||
new CommandBindingConfiguration(Commands.Rename, new[] { Key.C, Key.W }),
|
||||
new CommandBindingConfiguration(Commands.RunCommand, new KeyConfig(Key.D4, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.ScanContainerSize, new[] { Key.C, Key.S }),
|
||||
new CommandBindingConfiguration(Commands.ShowAllShotcut, Key.F1),
|
||||
new CommandBindingConfiguration(Commands.SoftDelete, new[] { new KeyConfig(Key.D), new KeyConfig(Key.D, shift: true) }),
|
||||
new CommandBindingConfiguration(Commands.SwitchToLastTab, Key.D9),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab1, Key.D1),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab2, Key.D2),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab3, Key.D3),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab4, Key.D4),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab5, Key.D5),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab6, Key.D6),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab7, Key.D7),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab8, Key.D8),
|
||||
new CommandBindingConfiguration(Commands.TimelinePause, new[] { Key.T, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.TimelineRefresh, new[] { Key.T, Key.R }),
|
||||
new CommandBindingConfiguration(Commands.TimelineStart, new[] { Key.T, Key.S }),
|
||||
new CommandBindingConfiguration(Commands.ToggleAdvancedIcons, new[] { Key.Z, Key.I }),
|
||||
new CommandBindingConfiguration(Commands.GoUp, Key.Left),
|
||||
new CommandBindingConfiguration(Commands.Open, Key.Right),
|
||||
new CommandBindingConfiguration(Commands.OpenOrRun, Key.Enter),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorUp, Key.Up),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorDown, Key.Down),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorUpPage, Key.PageUp),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorDownPage, Key.PageDown),
|
||||
};
|
||||
}
|
||||
new CommandBindingConfiguration(Commands.AutoRefresh, new KeyConfig(Key.R, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.ChangeTimelineMode, new[] { Key.T, Key.M }),
|
||||
new CommandBindingConfiguration(Commands.CloseTab, Key.Q),
|
||||
new CommandBindingConfiguration(Commands.Compress, new[] { Key.Y, Key.C }),
|
||||
new CommandBindingConfiguration(Commands.Copy, new[] { Key.Y, Key.Y }),
|
||||
new CommandBindingConfiguration(Commands.CopyHash, new[] { Key.C, Key.H }),
|
||||
new CommandBindingConfiguration(Commands.CopyPath, new[] { Key.C, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.CreateContainer, Key.F7),
|
||||
new CommandBindingConfiguration(Commands.CreateContainer, new[] { Key.C, Key.C }),
|
||||
new CommandBindingConfiguration(Commands.CreateElement, new[] { Key.C, Key.E }),
|
||||
new CommandBindingConfiguration(Commands.Cut, new[] { Key.D, Key.D }),
|
||||
new CommandBindingConfiguration(Commands.Edit, new KeyConfig(Key.F4)),
|
||||
new CommandBindingConfiguration(Commands.EnterRapidTravel, new KeyConfig(Key.OemComma, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.FindByName, new[] { Key.F, Key.N }),
|
||||
new CommandBindingConfiguration(Commands.FindByNameRegex, new[] { Key.F, Key.R }),
|
||||
new CommandBindingConfiguration(Commands.GoToHome, new[] { Key.G, Key.H }),
|
||||
new CommandBindingConfiguration(Commands.GoToPath, new KeyConfig(Key.L, ctrl: true)),
|
||||
new CommandBindingConfiguration(Commands.GoToPath, new[] { Key.G, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.GoToProvider, new[] { Key.G, Key.T }),
|
||||
new CommandBindingConfiguration(Commands.GoToRoot, new[] { Key.G, Key.R }),
|
||||
new CommandBindingConfiguration(Commands.HardDelete, new[] { new KeyConfig(Key.D,shift: true), new KeyConfig(Key.D, shift: true) }),
|
||||
new CommandBindingConfiguration(Commands.Mark, Key.Space),
|
||||
new CommandBindingConfiguration(Commands.MoveToLast, new KeyConfig(Key.G, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.MoveToFirst, new[] { Key.G, Key.G }),
|
||||
new CommandBindingConfiguration(Commands.NextTimelineBlock, Key.L ),
|
||||
new CommandBindingConfiguration(Commands.NextTimelineCommand, Key.J ),
|
||||
new CommandBindingConfiguration(Commands.OpenInFileBrowser, new[] { Key.O, Key.E }),
|
||||
new CommandBindingConfiguration(Commands.PasteMerge, new[] { Key.P, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.PasteOverwrite, new[] { Key.P, Key.O }),
|
||||
new CommandBindingConfiguration(Commands.PasteSkip, new[] { Key.P, Key.S }),
|
||||
new CommandBindingConfiguration(Commands.PinFavorite, new[] { Key.F, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.PreviousTimelineBlock, Key.H ),
|
||||
new CommandBindingConfiguration(Commands.PreviousTimelineCommand, Key.K ),
|
||||
new CommandBindingConfiguration(Commands.Refresh, Key.R),
|
||||
new CommandBindingConfiguration(Commands.Rename, Key.F2),
|
||||
new CommandBindingConfiguration(Commands.Rename, new[] { Key.C, Key.W }),
|
||||
new CommandBindingConfiguration(Commands.RunCommand, new KeyConfig(Key.D4, shift: true)),
|
||||
new CommandBindingConfiguration(Commands.ScanContainerSize, new[] { Key.C, Key.S }),
|
||||
new CommandBindingConfiguration(Commands.ShowAllShotcut, Key.F1),
|
||||
new CommandBindingConfiguration(Commands.SoftDelete, new[] { new KeyConfig(Key.D), new KeyConfig(Key.D, shift: true) }),
|
||||
new CommandBindingConfiguration(Commands.SwitchToLastTab, Key.D9),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab1, Key.D1),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab2, Key.D2),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab3, Key.D3),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab4, Key.D4),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab5, Key.D5),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab6, Key.D6),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab7, Key.D7),
|
||||
new CommandBindingConfiguration(Commands.SwitchToTab8, Key.D8),
|
||||
new CommandBindingConfiguration(Commands.TimelinePause, new[] { Key.T, Key.P }),
|
||||
new CommandBindingConfiguration(Commands.TimelineRefresh, new[] { Key.T, Key.R }),
|
||||
new CommandBindingConfiguration(Commands.TimelineStart, new[] { Key.T, Key.S }),
|
||||
new CommandBindingConfiguration(Commands.ToggleAdvancedIcons, new[] { Key.Z, Key.I }),
|
||||
new CommandBindingConfiguration(Commands.GoUp, Key.Left),
|
||||
new CommandBindingConfiguration(Commands.Open, Key.Right),
|
||||
new CommandBindingConfiguration(Commands.OpenOrRun, Key.Enter),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorUp, Key.Up),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorDown, Key.Down),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorUpPage, Key.PageUp),
|
||||
new CommandBindingConfiguration(Commands.MoveCursorDownPage, Key.PageDown),
|
||||
};
|
||||
}
|
||||
|
||||
private static void PopulateDefaultEditorPrograms(Dictionary<string, string> configuration)
|
||||
private static void PopulateDefaultEditorPrograms(Dictionary<string, string> configuration)
|
||||
{
|
||||
var editorPrograms = new List<ProgramConfiguration>()
|
||||
{
|
||||
var editorPrograms = new List<ProgramConfiguration>()
|
||||
{
|
||||
new ProgramConfiguration(@"c:\Program Files\Notepad++\notepad++.exe"),
|
||||
new ProgramConfiguration("notepad.exe"),
|
||||
};
|
||||
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);
|
||||
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);
|
||||
}
|
||||
if (editorPrograms[i].Arguments is string arguments)
|
||||
{
|
||||
configuration.Add($"{SectionNames.ProgramsSectionName}:{nameof(ProgramsConfiguration.DefaultEditorPrograms)}:[{i}]:{nameof(ProgramConfiguration.Arguments)}", arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
namespace FileTime.GuiApp.Configuration
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public class ProgramConfiguration
|
||||
{
|
||||
public class ProgramConfiguration
|
||||
public string? Path { get; set; }
|
||||
public string? Arguments { get; set; }
|
||||
|
||||
public ProgramConfiguration() { }
|
||||
|
||||
public ProgramConfiguration(string? path, string? arguments = null)
|
||||
{
|
||||
public string? Path { get; set; }
|
||||
public string? Arguments { get; set; }
|
||||
|
||||
public ProgramConfiguration() { }
|
||||
|
||||
public ProgramConfiguration(string? path, string? arguments = null)
|
||||
{
|
||||
Path = path;
|
||||
Arguments = arguments;
|
||||
}
|
||||
Path = path;
|
||||
Arguments = arguments;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FileTime.GuiApp.Configuration
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public class ProgramsConfiguration
|
||||
{
|
||||
public class ProgramsConfiguration
|
||||
{
|
||||
public List<ProgramConfiguration> DefaultEditorPrograms { get; set; } = new();
|
||||
public List<ProgramConfiguration> EditorPrograms { get; set; } = new();
|
||||
}
|
||||
public List<ProgramConfiguration> DefaultEditorPrograms { get; set; } = new();
|
||||
public List<ProgramConfiguration> EditorPrograms { get; set; } = new();
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
namespace FileTime.GuiApp.Configuration
|
||||
namespace FileTime.GuiApp.Configuration;
|
||||
|
||||
public static class SectionNames
|
||||
{
|
||||
public static class SectionNames
|
||||
{
|
||||
public const string KeybindingSectionName = "KeyBindings";
|
||||
public const string ProgramsSectionName = "Programs";
|
||||
}
|
||||
public const string KeybindingSectionName = "KeyBindings";
|
||||
public const string ProgramsSectionName = "Programs";
|
||||
}
|
||||
@@ -6,6 +6,10 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="0.10.13" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
namespace FileTime.GuiApp.Models
|
||||
{
|
||||
public record SpecialKeysStatus(bool IsAltPressed, bool IsShiftPressed, bool IsCtrlPressed);
|
||||
}
|
||||
namespace FileTime.GuiApp.Models;
|
||||
|
||||
public record SpecialKeysStatus(bool IsAltPressed, bool IsShiftPressed, bool IsCtrlPressed);
|
||||
@@ -1,4 +1,3 @@
|
||||
namespace FileTime.GuiApp.Services
|
||||
{
|
||||
public interface IDefaultModeKeyInputHandler : IKeyInputHandler { }
|
||||
}
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public interface IDefaultModeKeyInputHandler : IKeyInputHandler { }
|
||||
@@ -1,10 +1,9 @@
|
||||
using Avalonia.Input;
|
||||
using FileTime.GuiApp.Models;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public interface IKeyInputHandler
|
||||
{
|
||||
public interface IKeyInputHandler
|
||||
{
|
||||
Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled);
|
||||
}
|
||||
Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled);
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using Avalonia.Input;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public interface IKeyInputHandlerService
|
||||
{
|
||||
public interface IKeyInputHandlerService
|
||||
{
|
||||
Task ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled);
|
||||
}
|
||||
Task ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled);
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
using FileTime.GuiApp.Configuration;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public interface IKeyboardConfigurationService
|
||||
{
|
||||
public interface IKeyboardConfigurationService
|
||||
{
|
||||
IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
|
||||
IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
|
||||
IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
|
||||
}
|
||||
IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
|
||||
IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
|
||||
IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
namespace FileTime.GuiApp.Services
|
||||
{
|
||||
public interface IRapidTravelModeKeyInputHandler : IKeyInputHandler { }
|
||||
}
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public interface IRapidTravelModeKeyInputHandler : IKeyInputHandler { }
|
||||
@@ -1,14 +1,13 @@
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.GuiApp.Configuration;
|
||||
|
||||
namespace FileTime.GuiApp.ViewModels
|
||||
namespace FileTime.GuiApp.ViewModels;
|
||||
|
||||
public interface IGuiAppState : IAppState
|
||||
{
|
||||
public interface IGuiAppState : IAppState
|
||||
{
|
||||
List<KeyConfig> PreviousKeys { get; }
|
||||
bool IsAllShortcutVisible { get; set; }
|
||||
bool NoCommandFound { get; set; }
|
||||
string? MessageBoxText { get; set; }
|
||||
List<CommandBindingConfiguration> PossibleCommands { get; set; }
|
||||
}
|
||||
List<KeyConfig> PreviousKeys { get; }
|
||||
bool IsAllShortcutVisible { get; set; }
|
||||
bool NoCommandFound { get; set; }
|
||||
string? MessageBoxText { get; set; }
|
||||
List<CommandBindingConfiguration> PossibleCommands { get; set; }
|
||||
}
|
||||
@@ -7,40 +7,39 @@ using FileTime.GuiApp.Views;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FileTime.GuiApp
|
||||
namespace FileTime.GuiApp;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public partial class App : Application
|
||||
static App()
|
||||
{
|
||||
static App()
|
||||
{
|
||||
DI.ServiceProvider ??= DependencyInjection
|
||||
.RegisterDefaultServices()
|
||||
.AddConfiguration()
|
||||
.RegisterLogging()
|
||||
.RegisterServices()
|
||||
.AddViewModels()
|
||||
.BuildServiceProvider()
|
||||
.InitSerilog();
|
||||
DI.ServiceProvider ??= DependencyInjection
|
||||
.RegisterDefaultServices()
|
||||
.AddConfiguration()
|
||||
.RegisterLogging()
|
||||
.RegisterServices()
|
||||
.AddViewModels()
|
||||
.BuildServiceProvider()
|
||||
.InitSerilog();
|
||||
|
||||
var logger = DI.ServiceProvider.GetRequiredService<ILogger<App>>();
|
||||
logger.LogInformation("App initialization completed");
|
||||
}
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
var logger = DI.ServiceProvider.GetRequiredService<ILogger<App>>();
|
||||
logger.LogInformation("App initialization completed");
|
||||
}
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
public override void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
desktop.MainWindow = new MainWindow
|
||||
{
|
||||
desktop.MainWindow = new MainWindow
|
||||
{
|
||||
DataContext = new MainWindowLoadingViewModel(),
|
||||
};
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
DataContext = new MainWindowLoadingViewModel(),
|
||||
};
|
||||
}
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,11 @@
|
||||
<ApplicationIcon>filetime.ico</ApplicationIcon>
|
||||
<Version>0.0.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="filetime.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -3,19 +3,19 @@ using System.IO;
|
||||
using Avalonia;
|
||||
using Avalonia.ReactiveUI;
|
||||
|
||||
namespace FileTime.GuiApp
|
||||
namespace FileTime.GuiApp;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static class Program
|
||||
public static string AppDataRoot { get; }
|
||||
public static string EnvironmentName { get; }
|
||||
|
||||
static Program()
|
||||
{
|
||||
public static string AppDataRoot { get; }
|
||||
public static string EnvironmentName { get; }
|
||||
|
||||
static Program()
|
||||
{
|
||||
#if DEBUG
|
||||
EnvironmentName = "Development";
|
||||
EnvironmentName = "Development";
|
||||
|
||||
AppDataRoot = Path.Combine(Environment.CurrentDirectory, "appdata");
|
||||
AppDataRoot = Path.Combine(Environment.CurrentDirectory, "appdata");
|
||||
#else
|
||||
EnvironmentName = "Release";
|
||||
|
||||
@@ -43,20 +43,19 @@ namespace FileTime.GuiApp
|
||||
if (appDataRoot == null) throw new UnauthorizedAccessException();
|
||||
AppDataRoot = appDataRoot;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.UseReactiveUI()
|
||||
.LogToTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialization code. Don't use any Avalonia, third-party APIs or any
|
||||
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
|
||||
// yet and stuff might break.
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.UseReactiveUI()
|
||||
.LogToTrace();
|
||||
}
|
||||
@@ -11,70 +11,69 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using Serilog.Configuration;
|
||||
|
||||
namespace FileTime.GuiApp
|
||||
namespace FileTime.GuiApp;
|
||||
|
||||
public static class Startup
|
||||
{
|
||||
public static class Startup
|
||||
internal static IServiceCollection AddViewModels(this IServiceCollection serviceCollection)
|
||||
{
|
||||
internal static IServiceCollection AddViewModels(this IServiceCollection serviceCollection)
|
||||
{
|
||||
return serviceCollection
|
||||
.AddSingleton<MainWindowViewModel>()
|
||||
.AddSingleton<GuiAppState>()
|
||||
.AddSingleton<IAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>())
|
||||
.AddSingleton<IGuiAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>());
|
||||
}
|
||||
internal static IServiceCollection RegisterServices(this IServiceCollection serviceCollection)
|
||||
{
|
||||
return serviceCollection
|
||||
.AddSingleton<IRxSchedulerService, AvaloniaRxSchedulerService>()
|
||||
.AddSingleton<IKeyInputHandlerService, KeyInputHandlerService>()
|
||||
.AddSingleton<IDefaultModeKeyInputHandler, DefaultModeKeyInputHandler>()
|
||||
.AddSingleton<IKeyboardConfigurationService, KeyboardConfigurationService>()
|
||||
.AddSingleton<IRapidTravelModeKeyInputHandler, RapidTravelModeKeyInputHandler>();
|
||||
}
|
||||
return serviceCollection
|
||||
.AddSingleton<MainWindowViewModel>()
|
||||
.AddSingleton<GuiAppState>()
|
||||
.AddSingleton<IAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>())
|
||||
.AddSingleton<IGuiAppState, GuiAppState>(s => s.GetRequiredService<GuiAppState>());
|
||||
}
|
||||
internal static IServiceCollection RegisterServices(this IServiceCollection serviceCollection)
|
||||
{
|
||||
return serviceCollection
|
||||
.AddSingleton<IRxSchedulerService, AvaloniaRxSchedulerService>()
|
||||
.AddSingleton<IKeyInputHandlerService, KeyInputHandlerService>()
|
||||
.AddSingleton<IDefaultModeKeyInputHandler, DefaultModeKeyInputHandler>()
|
||||
.AddSingleton<IKeyboardConfigurationService, KeyboardConfigurationService>()
|
||||
.AddSingleton<IRapidTravelModeKeyInputHandler, RapidTravelModeKeyInputHandler>();
|
||||
}
|
||||
|
||||
internal static IServiceCollection RegisterLogging(this IServiceCollection serviceCollection)
|
||||
{
|
||||
return serviceCollection.AddLogging(loggingBuilder =>
|
||||
loggingBuilder.AddSerilog(dispose: true)
|
||||
);
|
||||
}
|
||||
internal static IServiceCollection RegisterLogging(this IServiceCollection serviceCollection)
|
||||
{
|
||||
return serviceCollection.AddLogging(loggingBuilder =>
|
||||
loggingBuilder.AddSerilog(dispose: true)
|
||||
);
|
||||
}
|
||||
|
||||
internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(MainConfiguration.Configuration)
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.AddJsonFile($"appsettings.{Program.EnvironmentName}.json", true)
|
||||
.Build();
|
||||
internal static IServiceCollection AddConfiguration(this IServiceCollection serviceCollection)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(MainConfiguration.Configuration)
|
||||
.AddJsonFile("appsettings.json", optional: true)
|
||||
.AddJsonFile($"appsettings.{Program.EnvironmentName}.json", true)
|
||||
.Build();
|
||||
|
||||
return serviceCollection
|
||||
.Configure<ProgramsConfiguration>(configuration.GetSection(SectionNames.ProgramsSectionName))
|
||||
.Configure<KeyBindingConfiguration>(configuration.GetSection(SectionNames.KeybindingSectionName))
|
||||
.AddSingleton<IConfiguration>(configuration);
|
||||
}
|
||||
return serviceCollection
|
||||
.Configure<ProgramsConfiguration>(configuration.GetSection(SectionNames.ProgramsSectionName))
|
||||
.Configure<KeyBindingConfiguration>(configuration.GetSection(SectionNames.KeybindingSectionName))
|
||||
.AddSingleton<IConfiguration>(configuration);
|
||||
}
|
||||
|
||||
internal static IServiceProvider InitSerilog(this IServiceProvider serviceProvider)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.ReadFrom.Configuration(serviceProvider.GetService<IConfiguration>())
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.File(
|
||||
Path.Combine(Program.AppDataRoot, "logs", "appLog.log"),
|
||||
fileSizeLimitBytes: 10 * 1024 * 1024,
|
||||
rollOnFileSizeLimit: true,
|
||||
rollingInterval: RollingInterval.Day)
|
||||
.WriteTo.MessageBoxSink(serviceProvider)
|
||||
.CreateLogger();
|
||||
internal static IServiceProvider InitSerilog(this IServiceProvider serviceProvider)
|
||||
{
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.ReadFrom.Configuration(serviceProvider.GetService<IConfiguration>())
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.File(
|
||||
Path.Combine(Program.AppDataRoot, "logs", "appLog.log"),
|
||||
fileSizeLimitBytes: 10 * 1024 * 1024,
|
||||
rollOnFileSizeLimit: true,
|
||||
rollingInterval: RollingInterval.Day)
|
||||
.WriteTo.MessageBoxSink(serviceProvider)
|
||||
.CreateLogger();
|
||||
|
||||
return serviceProvider;
|
||||
}
|
||||
return serviceProvider;
|
||||
}
|
||||
|
||||
internal static LoggerConfiguration MessageBoxSink(
|
||||
this LoggerSinkConfiguration loggerConfiguration,
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
return loggerConfiguration.Sink(serviceProvider.GetService<ToastMessageSink>());
|
||||
}
|
||||
internal static LoggerConfiguration MessageBoxSink(
|
||||
this LoggerSinkConfiguration loggerConfiguration,
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
return loggerConfiguration.Sink(serviceProvider.GetService<ToastMessageSink>());
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,10 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\AppCommon\FileTime.App.Core\FileTime.App.Core.csproj" />
|
||||
<ProjectReference Include="..\FileTime.GuiApp.Abstractions\FileTime.GuiApp.Abstractions.csproj" />
|
||||
|
||||
@@ -2,23 +2,22 @@ using FileTime.App.Core.ViewModels;
|
||||
using FileTime.GuiApp.Configuration;
|
||||
using MvvmGen;
|
||||
|
||||
namespace FileTime.GuiApp.ViewModels
|
||||
namespace FileTime.GuiApp.ViewModels;
|
||||
|
||||
[ViewModel]
|
||||
public partial class GuiAppState : AppStateBase, IGuiAppState
|
||||
{
|
||||
[ViewModel]
|
||||
public partial class GuiAppState : AppStateBase, IGuiAppState
|
||||
{
|
||||
[Property]
|
||||
private bool _isAllShortcutVisible;
|
||||
[Property]
|
||||
private bool _isAllShortcutVisible;
|
||||
|
||||
[Property]
|
||||
private bool _noCommandFound;
|
||||
[Property]
|
||||
private bool _noCommandFound;
|
||||
|
||||
[Property]
|
||||
private string? _messageBoxText;
|
||||
[Property]
|
||||
private string? _messageBoxText;
|
||||
|
||||
[Property]
|
||||
private List<CommandBindingConfiguration> _possibleCommands = new();
|
||||
[Property]
|
||||
private List<CommandBindingConfiguration> _possibleCommands = new();
|
||||
|
||||
public List<KeyConfig> PreviousKeys { get; } = new();
|
||||
}
|
||||
public List<KeyConfig> PreviousKeys { get; } = new();
|
||||
}
|
||||
@@ -1,54 +1,53 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public enum ComparisonCondition
|
||||
{
|
||||
public enum ComparisonCondition
|
||||
Equal,
|
||||
GreaterThan,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
NotEqual,
|
||||
GreaterThanOrEqual
|
||||
}
|
||||
|
||||
public class CompareConverter : IValueConverter
|
||||
{
|
||||
public ComparisonCondition ComparisonCondition { get; set; } = ComparisonCondition.Equal;
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
Equal,
|
||||
GreaterThan,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
NotEqual,
|
||||
GreaterThanOrEqual
|
||||
return Compare(value, parameter);
|
||||
}
|
||||
|
||||
public class CompareConverter : IValueConverter
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
public ComparisonCondition ComparisonCondition { get; set; } = ComparisonCondition.Equal;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
private bool Compare(object? value, object? parameter)
|
||||
{
|
||||
if (ComparisonCondition == ComparisonCondition.GreaterThan)
|
||||
{
|
||||
return Compare(value, parameter);
|
||||
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt > parameterInt;
|
||||
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble > parameterDouble;
|
||||
else throw new NotSupportedException();
|
||||
}
|
||||
else if (ComparisonCondition == ComparisonCondition.NotEqual)
|
||||
{
|
||||
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt != parameterInt;
|
||||
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble != parameterDouble;
|
||||
return value != parameter;
|
||||
}
|
||||
else if (ComparisonCondition == ComparisonCondition.Equal)
|
||||
{
|
||||
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt == parameterInt;
|
||||
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble == parameterDouble;
|
||||
else if (value?.GetType().IsEnum ?? false && Enum.TryParse(value.GetType(), parameter?.ToString(), out var _)) return value.ToString() == parameter?.ToString();
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private bool Compare(object? value, object? parameter)
|
||||
{
|
||||
if (ComparisonCondition == ComparisonCondition.GreaterThan)
|
||||
{
|
||||
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt > parameterInt;
|
||||
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble > parameterDouble;
|
||||
else throw new NotSupportedException();
|
||||
}
|
||||
else if (ComparisonCondition == ComparisonCondition.NotEqual)
|
||||
{
|
||||
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt != parameterInt;
|
||||
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble != parameterDouble;
|
||||
return value != parameter;
|
||||
}
|
||||
else if (ComparisonCondition == ComparisonCondition.Equal)
|
||||
{
|
||||
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt == parameterInt;
|
||||
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble == parameterDouble;
|
||||
else if (value?.GetType().IsEnum ?? false && Enum.TryParse(value.GetType(), parameter?.ToString(), out var _)) return value.ToString() == parameter?.ToString();
|
||||
}
|
||||
|
||||
return value == parameter;
|
||||
}
|
||||
return value == parameter;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,17 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
{
|
||||
public class DateTimeConverter : IValueConverter
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
|
||||
value is DateTime dateTime && parameter is string parameterS
|
||||
? dateTime.ToString(parameterS)
|
||||
: value;
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public class DateTimeConverter : IValueConverter
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) =>
|
||||
value is DateTime dateTime && parameter is string parameterS
|
||||
? dateTime.ToString(parameterS)
|
||||
: value;
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,44 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public class ExceptionToStringConverter : IValueConverter
|
||||
{
|
||||
public class ExceptionToStringConverter : IValueConverter
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
if (value is not Exception e) return value;
|
||||
|
||||
if (e is UnauthorizedAccessException)
|
||||
{
|
||||
if (value is not Exception e) return value;
|
||||
|
||||
if (e is UnauthorizedAccessException)
|
||||
{
|
||||
return e.Message;
|
||||
}
|
||||
else if (e.InnerException != null)
|
||||
{
|
||||
return TraverseInnerException(e);
|
||||
}
|
||||
|
||||
return FormatException(e);
|
||||
return e.Message;
|
||||
}
|
||||
else if (e.InnerException != null)
|
||||
{
|
||||
return TraverseInnerException(e);
|
||||
}
|
||||
|
||||
private static string TraverseInnerException(Exception e)
|
||||
{
|
||||
string s = "";
|
||||
if (e.InnerException != null) s += TraverseInnerException(e.InnerException) + Environment.NewLine;
|
||||
else return FormatException(e);
|
||||
return FormatException(e);
|
||||
}
|
||||
|
||||
s += "In: " + FormatException(e);
|
||||
private static string TraverseInnerException(Exception e)
|
||||
{
|
||||
string s = "";
|
||||
if (e.InnerException != null) s += TraverseInnerException(e.InnerException) + Environment.NewLine;
|
||||
else return FormatException(e);
|
||||
|
||||
return s;
|
||||
}
|
||||
s += "In: " + FormatException(e);
|
||||
|
||||
private static string FormatException(Exception e)
|
||||
{
|
||||
return $"{e.Message} ({e.GetType().FullName})";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
private static string FormatException(Exception e)
|
||||
{
|
||||
return $"{e.Message} ({e.GetType().FullName})";
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,46 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public class FormatSizeConverter : IValueConverter
|
||||
{
|
||||
public class FormatSizeConverter : IValueConverter
|
||||
private const long OneKiloByte = 1024;
|
||||
private const long OneMegaByte = OneKiloByte * 1024;
|
||||
private const long OneGigaByte = OneMegaByte * 1024;
|
||||
private const long OneTerraByte = OneGigaByte * 1024;
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
private const long OneKiloByte = 1024;
|
||||
private const long OneMegaByte = OneKiloByte * 1024;
|
||||
private const long OneGigaByte = OneMegaByte * 1024;
|
||||
private const long OneTerraByte = OneGigaByte * 1024;
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
return (value, int.TryParse(parameter?.ToString(), out var prec)) switch
|
||||
{
|
||||
return (value, int.TryParse(parameter?.ToString(), out var prec)) switch
|
||||
{
|
||||
(long size, true) => ToSizeString(size, prec),
|
||||
(long size, false) => ToSizeString(size),
|
||||
(null, _) => "...",
|
||||
_ => value
|
||||
};
|
||||
}
|
||||
(long size, true) => ToSizeString(size, prec),
|
||||
(long size, false) => ToSizeString(size),
|
||||
(null, _) => "...",
|
||||
_ => value
|
||||
};
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public static string ToSizeString(long fileSize, int precision = 1)
|
||||
{
|
||||
var fileSizeD = (decimal)fileSize;
|
||||
var (size, suffix) = fileSize switch
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
> OneTerraByte => (fileSizeD / OneTerraByte, "T"),
|
||||
> OneGigaByte => (fileSizeD / OneGigaByte, "G"),
|
||||
> OneMegaByte => (fileSizeD / OneMegaByte, "M"),
|
||||
> OneKiloByte => (fileSizeD / OneKiloByte, "K"),
|
||||
_ => (fileSizeD, "B")
|
||||
};
|
||||
|
||||
public static string ToSizeString(long fileSize, int precision = 1)
|
||||
{
|
||||
var fileSizeD = (decimal)fileSize;
|
||||
var (size, suffix) = fileSize switch
|
||||
{
|
||||
> OneTerraByte => (fileSizeD / OneTerraByte, "T"),
|
||||
> OneGigaByte => (fileSizeD / OneGigaByte, "G"),
|
||||
> OneMegaByte => (fileSizeD / OneMegaByte, "M"),
|
||||
> OneKiloByte => (fileSizeD / OneKiloByte, "K"),
|
||||
_ => (fileSizeD, "B")
|
||||
};
|
||||
var result = string.Format("{0:N" + precision + "}", size).Replace(',', '.');
|
||||
|
||||
var result = string.Format("{0:N" + precision + "}", size).Replace(',', '.');
|
||||
|
||||
if (result.Contains('.')) result = result.TrimEnd('0').TrimEnd('.');
|
||||
return result + " " + suffix;
|
||||
}
|
||||
if (result.Contains('.')) result = result.TrimEnd('0').TrimEnd('.');
|
||||
return result + " " + suffix;
|
||||
}
|
||||
}
|
||||
@@ -3,22 +3,21 @@ using Avalonia.Data.Converters;
|
||||
using FileTime.App.Core.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public class GetFileExtensionConverter : IValueConverter
|
||||
{
|
||||
public class GetFileExtensionConverter : IValueConverter
|
||||
private IItemNameConverterService? _itemNameConverterService;
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
private IItemNameConverterService? _itemNameConverterService;
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not string fullName) return value;
|
||||
_itemNameConverterService ??= DI.ServiceProvider.GetRequiredService<IItemNameConverterService>();
|
||||
if (value is not string fullName) return value;
|
||||
_itemNameConverterService ??= DI.ServiceProvider.GetRequiredService<IItemNameConverterService>();
|
||||
|
||||
return _itemNameConverterService.GetFileExtension(fullName);
|
||||
}
|
||||
return _itemNameConverterService.GetFileExtension(fullName);
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -3,39 +3,38 @@ using Avalonia.Data.Converters;
|
||||
using Avalonia.Media;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public class ItemViewModeToBrushConverter : IValueConverter
|
||||
{
|
||||
public class ItemViewModeToBrushConverter : IValueConverter
|
||||
public Brush? DefaultBrush { get; set; }
|
||||
public Brush? AlternativeBrush { get; set; }
|
||||
public Brush? SelectedBrush { get; set; }
|
||||
public Brush? MarkedBrush { get; set; }
|
||||
public Brush? MarkedSelectedBrush { get; set; }
|
||||
public Brush? MarkedAlternativeBrush { get; set; }
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
public Brush? DefaultBrush { get; set; }
|
||||
public Brush? AlternativeBrush { get; set; }
|
||||
public Brush? SelectedBrush { get; set; }
|
||||
public Brush? MarkedBrush { get; set; }
|
||||
public Brush? MarkedSelectedBrush { get; set; }
|
||||
public Brush? MarkedAlternativeBrush { get; set; }
|
||||
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
if (value is ItemViewMode viewMode)
|
||||
{
|
||||
if (value is ItemViewMode viewMode)
|
||||
return viewMode switch
|
||||
{
|
||||
return viewMode switch
|
||||
{
|
||||
ItemViewMode.Default => DefaultBrush,
|
||||
ItemViewMode.Alternative => AlternativeBrush,
|
||||
ItemViewMode.Selected => SelectedBrush,
|
||||
ItemViewMode.Marked => MarkedBrush,
|
||||
ItemViewMode.MarkedSelected => MarkedSelectedBrush,
|
||||
ItemViewMode.MarkedAlternative => MarkedAlternativeBrush,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
return value;
|
||||
ItemViewMode.Default => DefaultBrush,
|
||||
ItemViewMode.Alternative => AlternativeBrush,
|
||||
ItemViewMode.Selected => SelectedBrush,
|
||||
ItemViewMode.Marked => MarkedBrush,
|
||||
ItemViewMode.MarkedSelected => MarkedSelectedBrush,
|
||||
ItemViewMode.MarkedAlternative => MarkedAlternativeBrush,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -3,35 +3,34 @@ using Avalonia.Data.Converters;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public class ItemViewModelIsAttributeTypeConverter : IValueConverter
|
||||
{
|
||||
public class ItemViewModelIsAttributeTypeConverter : IValueConverter
|
||||
public bool Invert { get; set; }
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
public bool Invert { get; set; }
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
var attributeType = GetAttributeType(value);
|
||||
if (parameter == null) return attributeType;
|
||||
var result = parameter is ItemAttributeType targetAttribute && attributeType == targetAttribute;
|
||||
if (Invert && parameter is ItemAttributeType) result = !result;
|
||||
return result;
|
||||
}
|
||||
var attributeType = GetAttributeType(value);
|
||||
if (parameter == null) return attributeType;
|
||||
var result = parameter is ItemAttributeType targetAttribute && attributeType == targetAttribute;
|
||||
if (Invert && parameter is ItemAttributeType) result = !result;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ItemAttributeType? GetAttributeType(object? value)
|
||||
private static ItemAttributeType? GetAttributeType(object? value)
|
||||
{
|
||||
return value switch
|
||||
{
|
||||
return value switch
|
||||
{
|
||||
IFileViewModel => ItemAttributeType.File,
|
||||
IContainerSizeContainerViewModel => ItemAttributeType.SizeContainer,
|
||||
IElementViewModel => ItemAttributeType.Element,
|
||||
IContainerViewModel => ItemAttributeType.Container,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
IFileViewModel => ItemAttributeType.File,
|
||||
IContainerSizeContainerViewModel => ItemAttributeType.SizeContainer,
|
||||
IElementViewModel => ItemAttributeType.Element,
|
||||
IContainerViewModel => ItemAttributeType.Container,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -4,112 +4,111 @@ using Avalonia.Media;
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.GuiApp.ViewModels;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public class NamePartShrinkerConverter : IMultiValueConverter
|
||||
{
|
||||
public class NamePartShrinkerConverter : IMultiValueConverter
|
||||
private const int PixelPerChar = 8;
|
||||
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
private const int PixelPerChar = 8;
|
||||
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
|
||||
if (values.Count > 0 && values[0] is IList<ItemNamePart> nameParts)
|
||||
{
|
||||
if (values.Count > 0 && values[0] is IList<ItemNamePart> nameParts)
|
||||
var attributeWidth = values[2] is bool b && b ? 340 : 0;
|
||||
var newNameParts = nameParts;
|
||||
if (values.Count > 1 && values[1] is double width && width > 0)
|
||||
{
|
||||
var attributeWidth = values[2] is bool b && b ? 340 : 0;
|
||||
var newNameParts = nameParts;
|
||||
if (values.Count > 1 && values[1] is double width && width > 0)
|
||||
{
|
||||
newNameParts = GetNamePartsForWidth(nameParts, width - attributeWidth);
|
||||
}
|
||||
|
||||
return newNameParts.Select(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)).ToList();
|
||||
newNameParts = GetNamePartsForWidth(nameParts, width - attributeWidth);
|
||||
}
|
||||
return null;
|
||||
|
||||
return newNameParts.Select(p => new ItemNamePartViewModel(p.Text, p.IsSpecial ? TextDecorations.Underline : null)).ToList();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<ItemNamePart> GetNamePartsForWidth(IList<ItemNamePart> nameParts, double maxWidth)
|
||||
{
|
||||
//Best case, we are in the range
|
||||
var textLength = nameParts.Select(p => p.Text.Length).Sum();
|
||||
if (textLength * PixelPerChar <= maxWidth)
|
||||
{
|
||||
return nameParts.ToList();
|
||||
}
|
||||
|
||||
private static List<ItemNamePart> GetNamePartsForWidth(IList<ItemNamePart> nameParts, double maxWidth)
|
||||
//Trying at least with the special parts
|
||||
var newNameParts = new ItemNamePart?[nameParts.Count];
|
||||
for (var i = 0; i < nameParts.Count; i++)
|
||||
{
|
||||
//Best case, we are in the range
|
||||
var textLength = nameParts.Select(p => p.Text.Length).Sum();
|
||||
if (textLength * PixelPerChar <= maxWidth)
|
||||
if (nameParts[i].IsSpecial)
|
||||
{
|
||||
return nameParts.ToList();
|
||||
newNameParts[i] = nameParts[i];
|
||||
}
|
||||
|
||||
//Trying at least with the special parts
|
||||
var newNameParts = new ItemNamePart?[nameParts.Count];
|
||||
for (var i = 0; i < nameParts.Count; i++)
|
||||
{
|
||||
if (nameParts[i].IsSpecial)
|
||||
{
|
||||
newNameParts[i] = nameParts[i];
|
||||
}
|
||||
}
|
||||
|
||||
return GetNamePartsForWidthOptimistic(nameParts, newNameParts, maxWidth);
|
||||
}
|
||||
|
||||
private static List<ItemNamePart> GetNamePartsForWidthOptimistic(IList<ItemNamePart> nameParts, ItemNamePart?[] newNameParts, double maxWidth)
|
||||
return GetNamePartsForWidthOptimistic(nameParts, newNameParts, maxWidth);
|
||||
}
|
||||
|
||||
private static List<ItemNamePart> GetNamePartsForWidthOptimistic(IList<ItemNamePart> nameParts, ItemNamePart?[] newNameParts, double maxWidth)
|
||||
{
|
||||
var trimmedIndexes = new List<int>();
|
||||
for (var i = 0; i < newNameParts.Length; i++)
|
||||
{
|
||||
var trimmedIndexes = new List<int>();
|
||||
for (var i = 0; i < newNameParts.Length; i++)
|
||||
if (newNameParts[i] == null)
|
||||
{
|
||||
if (newNameParts[i] == null)
|
||||
{
|
||||
trimmedIndexes.Add(i);
|
||||
newNameParts[i] = new ItemNamePart("...");
|
||||
}
|
||||
trimmedIndexes.Add(i);
|
||||
newNameParts[i] = new ItemNamePart("...");
|
||||
}
|
||||
|
||||
var textLength = newNameParts.Select(p => p?.Text.Length ?? 0).Sum();
|
||||
if (textLength * PixelPerChar > maxWidth)
|
||||
{
|
||||
return GetNamePartsForWidthPessimistic(nameParts, maxWidth);
|
||||
}
|
||||
|
||||
foreach (var trimmedIndex in trimmedIndexes)
|
||||
{
|
||||
var baseTextLength = newNameParts.Select((p, i) => i == trimmedIndex ? 0 : (p?.Text.Length ?? 0)).Sum();
|
||||
var proposedText = nameParts[trimmedIndex].Text;
|
||||
var trimmed = false;
|
||||
while ((baseTextLength + proposedText.Length + (trimmed ? 3 : 0)) * PixelPerChar > maxWidth)
|
||||
{
|
||||
proposedText = proposedText[0..^1];
|
||||
trimmed = true;
|
||||
}
|
||||
newNameParts[trimmedIndex] = new ItemNamePart(proposedText + (trimmed ? "..." : ""));
|
||||
if (trimmed) break;
|
||||
}
|
||||
|
||||
return newNameParts.Where(f => f is not null).ToList()!;
|
||||
}
|
||||
|
||||
private static List<ItemNamePart> GetNamePartsForWidthPessimistic(IList<ItemNamePart> nameParts, double maxWidth)
|
||||
var textLength = newNameParts.Select(p => p?.Text.Length ?? 0).Sum();
|
||||
if (textLength * PixelPerChar > maxWidth)
|
||||
{
|
||||
var newNameParts = new List<ItemNamePart>(nameParts);
|
||||
foreach (var namePart in nameParts)
|
||||
{
|
||||
var baseTextLength = newNameParts.Select(p => p.Text.Length).Sum();
|
||||
var proposedText = namePart.Text;
|
||||
var trimmed = false;
|
||||
|
||||
while ((baseTextLength + 3) * PixelPerChar > maxWidth && proposedText != "")
|
||||
{
|
||||
proposedText = proposedText[0..^1];
|
||||
trimmed = true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(proposedText)) newNameParts.Add(new ItemNamePart(proposedText, namePart.IsSpecial));
|
||||
if (trimmed) break;
|
||||
}
|
||||
if (newNameParts.Last().IsSpecial)
|
||||
{
|
||||
newNameParts.Add(new ItemNamePart("..."));
|
||||
}
|
||||
else
|
||||
{
|
||||
var last = newNameParts.Last();
|
||||
last.Text += "...";
|
||||
}
|
||||
return newNameParts;
|
||||
return GetNamePartsForWidthPessimistic(nameParts, maxWidth);
|
||||
}
|
||||
|
||||
foreach (var trimmedIndex in trimmedIndexes)
|
||||
{
|
||||
var baseTextLength = newNameParts.Select((p, i) => i == trimmedIndex ? 0 : (p?.Text.Length ?? 0)).Sum();
|
||||
var proposedText = nameParts[trimmedIndex].Text;
|
||||
var trimmed = false;
|
||||
while ((baseTextLength + proposedText.Length + (trimmed ? 3 : 0)) * PixelPerChar > maxWidth)
|
||||
{
|
||||
proposedText = proposedText[0..^1];
|
||||
trimmed = true;
|
||||
}
|
||||
newNameParts[trimmedIndex] = new ItemNamePart(proposedText + (trimmed ? "..." : ""));
|
||||
if (trimmed) break;
|
||||
}
|
||||
|
||||
return newNameParts.Where(f => f is not null).ToList()!;
|
||||
}
|
||||
|
||||
private static List<ItemNamePart> GetNamePartsForWidthPessimistic(IList<ItemNamePart> nameParts, double maxWidth)
|
||||
{
|
||||
var newNameParts = new List<ItemNamePart>(nameParts);
|
||||
foreach (var namePart in nameParts)
|
||||
{
|
||||
var baseTextLength = newNameParts.Select(p => p.Text.Length).Sum();
|
||||
var proposedText = namePart.Text;
|
||||
var trimmed = false;
|
||||
|
||||
while ((baseTextLength + 3) * PixelPerChar > maxWidth && proposedText != "")
|
||||
{
|
||||
proposedText = proposedText[0..^1];
|
||||
trimmed = true;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(proposedText)) newNameParts.Add(new ItemNamePart(proposedText, namePart.IsSpecial));
|
||||
if (trimmed) break;
|
||||
}
|
||||
if (newNameParts.Last().IsSpecial)
|
||||
{
|
||||
newNameParts.Add(new ItemNamePart("..."));
|
||||
}
|
||||
else
|
||||
{
|
||||
var last = newNameParts.Last();
|
||||
last.Text += "...";
|
||||
}
|
||||
return newNameParts;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,26 @@
|
||||
using System.Globalization;
|
||||
using Avalonia.Data.Converters;
|
||||
|
||||
namespace FileTime.GuiApp.Converters
|
||||
namespace FileTime.GuiApp.Converters;
|
||||
|
||||
public class SplitStringConverter : IValueConverter
|
||||
{
|
||||
public class SplitStringConverter : IValueConverter
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
if (value is string path && parameter is string separator)
|
||||
{
|
||||
if (value is string path && parameter is string separator)
|
||||
{
|
||||
return path.Split(separator);
|
||||
}
|
||||
else if (value is string path2 && parameter is char separator2)
|
||||
{
|
||||
return path2.Split(separator2);
|
||||
}
|
||||
|
||||
return value;
|
||||
return path.Split(separator);
|
||||
}
|
||||
else if (value is string path2 && parameter is char separator2)
|
||||
{
|
||||
return path2.Split(separator2);
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace FileTime.GuiApp
|
||||
namespace FileTime.GuiApp;
|
||||
|
||||
public static class DI
|
||||
{
|
||||
public static class DI
|
||||
{
|
||||
public static IServiceProvider ServiceProvider { get; set; } = null!;
|
||||
}
|
||||
public static IServiceProvider ServiceProvider { get; set; } = null!;
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using FileTime.GuiApp.Configuration;
|
||||
|
||||
namespace FileTime.GuiApp.Extensions
|
||||
namespace FileTime.GuiApp.Extensions;
|
||||
|
||||
public static class KeyConfigExtensions
|
||||
{
|
||||
public static class KeyConfigExtensions
|
||||
{
|
||||
public static bool AreKeysEqual(this IReadOnlyList<KeyConfig> collection1, IReadOnlyList<KeyConfig> collection2)
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,10 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Assets\filetime.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace FileTime.GuiApp.Logging
|
||||
namespace FileTime.GuiApp.Logging;
|
||||
|
||||
public class ToastMessageSink : ILogEventSink
|
||||
{
|
||||
public class ToastMessageSink : ILogEventSink
|
||||
//private readonly IDialogService dialogService;
|
||||
|
||||
public ToastMessageSink(/*IDialogService dialogService*/)
|
||||
{
|
||||
//private readonly IDialogService dialogService;
|
||||
|
||||
public ToastMessageSink(/*IDialogService dialogService*/)
|
||||
{
|
||||
//this.dialogService = dialogService;
|
||||
}
|
||||
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
/*if (logEvent.Level >= LogEventLevel.Error)
|
||||
{
|
||||
var message = logEvent.RenderMessage();
|
||||
dialogService.ShowToastMessage(message);
|
||||
}*/
|
||||
}
|
||||
//this.dialogService = dialogService;
|
||||
}
|
||||
}
|
||||
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
/*if (logEvent.Level >= LogEventLevel.Error)
|
||||
{
|
||||
var message = logEvent.RenderMessage();
|
||||
dialogService.ShowToastMessage(message);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,19 @@
|
||||
namespace FileTime.GuiApp.Models
|
||||
namespace FileTime.GuiApp.Models;
|
||||
|
||||
public class InputElementWrapper
|
||||
{
|
||||
public class InputElementWrapper
|
||||
/*public InputElement InputElement { get; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public object? Option { get; set; }
|
||||
|
||||
public char? PasswordChar { get; set; }
|
||||
|
||||
public InputElementWrapper(InputElement inputElement, string? defaultValue = null)
|
||||
{
|
||||
/*public InputElement InputElement { get; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public object? Option { get; set; }
|
||||
|
||||
public char? PasswordChar { get; set; }
|
||||
|
||||
public InputElementWrapper(InputElement inputElement, string? defaultValue = null)
|
||||
{
|
||||
InputElement = inputElement;
|
||||
Value = defaultValue ?? "";
|
||||
PasswordChar = inputElement.InputType == InputType.Password ? '*' : null;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
InputElement = inputElement;
|
||||
Value = defaultValue ?? "";
|
||||
PasswordChar = inputElement.InputType == InputType.Password ? '*' : null;
|
||||
}*/
|
||||
}
|
||||
@@ -2,12 +2,11 @@ using System.Reactive.Concurrency;
|
||||
using FileTime.App.Core.Services;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
{
|
||||
public class AvaloniaRxSchedulerService : IRxSchedulerService
|
||||
{
|
||||
public IScheduler GetUIScheduler() => RxApp.MainThreadScheduler;
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public IScheduler GetWorkerScheduler() => RxApp.TaskpoolScheduler;
|
||||
}
|
||||
public class AvaloniaRxSchedulerService : IRxSchedulerService
|
||||
{
|
||||
public IScheduler GetUIScheduler() => RxApp.MainThreadScheduler;
|
||||
|
||||
public IScheduler GetWorkerScheduler() => RxApp.TaskpoolScheduler;
|
||||
}
|
||||
@@ -10,142 +10,141 @@ using FileTime.GuiApp.Models;
|
||||
using FileTime.GuiApp.ViewModels;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
|
||||
{
|
||||
public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
|
||||
private readonly IGuiAppState _appState;
|
||||
private readonly IKeyboardConfigurationService _keyboardConfigurationService;
|
||||
private readonly List<KeyConfig[]> _keysToSkip = new();
|
||||
private ITabViewModel? _selectedTab;
|
||||
private IContainer? _currentLocation;
|
||||
private readonly ILogger<DefaultModeKeyInputHandler> _logger;
|
||||
private readonly ICommandHandlerService _commandHandlerService;
|
||||
|
||||
public DefaultModeKeyInputHandler(
|
||||
IGuiAppState appState,
|
||||
IKeyboardConfigurationService keyboardConfigurationService,
|
||||
ILogger<DefaultModeKeyInputHandler> logger,
|
||||
ICommandHandlerService commandHandlerService)
|
||||
{
|
||||
private readonly IGuiAppState _appState;
|
||||
private readonly IKeyboardConfigurationService _keyboardConfigurationService;
|
||||
private readonly List<KeyConfig[]> _keysToSkip = new();
|
||||
private ITabViewModel? _selectedTab;
|
||||
private IContainer? _currentLocation;
|
||||
private readonly ILogger<DefaultModeKeyInputHandler> _logger;
|
||||
private readonly ICommandHandlerService _commandHandlerService;
|
||||
_appState = appState;
|
||||
_keyboardConfigurationService = keyboardConfigurationService;
|
||||
_logger = logger;
|
||||
_commandHandlerService = commandHandlerService;
|
||||
|
||||
public DefaultModeKeyInputHandler(
|
||||
IGuiAppState appState,
|
||||
IKeyboardConfigurationService keyboardConfigurationService,
|
||||
ILogger<DefaultModeKeyInputHandler> logger,
|
||||
ICommandHandlerService commandHandlerService)
|
||||
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
||||
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation!).Switch().Subscribe(l => _currentLocation = l);
|
||||
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Up) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Down) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Tab) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageDown) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageUp) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.F4, alt: true) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.LWin) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.RWin) });
|
||||
}
|
||||
|
||||
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
{
|
||||
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)
|
||||
{
|
||||
_appState = appState;
|
||||
_keyboardConfigurationService = keyboardConfigurationService;
|
||||
_logger = logger;
|
||||
_commandHandlerService = commandHandlerService;
|
||||
|
||||
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
||||
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation!).Switch().Subscribe(l => _currentLocation = l);
|
||||
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Up) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Down) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Tab) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageDown) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.PageUp) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.F4, alt: true) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.LWin) });
|
||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.RWin) });
|
||||
}
|
||||
|
||||
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
{
|
||||
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)
|
||||
var doGeneralReset = false;
|
||||
if (_appState.PreviousKeys.Count > 1 || _appState.IsAllShortcutVisible || _appState.MessageBoxText != null)
|
||||
{
|
||||
var doGeneralReset = false;
|
||||
if (_appState.PreviousKeys.Count > 1 || _appState.IsAllShortcutVisible || _appState.MessageBoxText != null)
|
||||
{
|
||||
doGeneralReset = true;
|
||||
}
|
||||
/*else if (_currentLocation.Container.CanHandleEscape)
|
||||
{
|
||||
var escapeResult = await _currentLocation.Container.HandleEscape();
|
||||
if (escapeResult.NavigateTo != null)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.PreviousKeys.Clear();
|
||||
await _appState.SelectedTab.OpenContainer(escapeResult.NavigateTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (escapeResult.Handled)
|
||||
{
|
||||
_appState.PreviousKeys.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
doGeneralReset = true;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (doGeneralReset)
|
||||
doGeneralReset = true;
|
||||
}
|
||||
/*else if (_currentLocation.Container.CanHandleEscape)
|
||||
{
|
||||
var escapeResult = await _currentLocation.Container.HandleEscape();
|
||||
if (escapeResult.NavigateTo != null)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.IsAllShortcutVisible = false;
|
||||
_appState.MessageBoxText = null;
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
}
|
||||
}
|
||||
else if (key == Key.Enter
|
||||
&& _appState.MessageBoxText != null)
|
||||
{
|
||||
_appState.PreviousKeys.Clear();
|
||||
//_dialogService.ProcessMessageBox();
|
||||
setHandled(true);
|
||||
}
|
||||
else if (selectedCommandBinding != null)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
await CallCommandAsync(selectedCommandBinding.Command);
|
||||
}
|
||||
else if (_keysToSkip.Any(k => k.AreKeysEqual(_appState.PreviousKeys)))
|
||||
{
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
return;
|
||||
}
|
||||
else if (_appState.PreviousKeys.Count == 2)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.NoCommandFound = true;
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
}
|
||||
else
|
||||
{
|
||||
setHandled(true);
|
||||
var possibleCommands = _keyboardConfigurationService.AllShortcut.Where(c => c.Keys[0].AreEquals(keyWithModifiers)).ToList();
|
||||
|
||||
if (possibleCommands.Count == 0)
|
||||
{
|
||||
_appState.NoCommandFound = true;
|
||||
_appState.PreviousKeys.Clear();
|
||||
await _appState.SelectedTab.OpenContainer(escapeResult.NavigateTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
_appState.PossibleCommands = possibleCommands;
|
||||
if (escapeResult.Handled)
|
||||
{
|
||||
_appState.PreviousKeys.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
doGeneralReset = true;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (doGeneralReset)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.IsAllShortcutVisible = false;
|
||||
_appState.MessageBoxText = null;
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CallCommandAsync(Commands command)
|
||||
else if (key == Key.Enter
|
||||
&& _appState.MessageBoxText != null)
|
||||
{
|
||||
try
|
||||
_appState.PreviousKeys.Clear();
|
||||
//_dialogService.ProcessMessageBox();
|
||||
setHandled(true);
|
||||
}
|
||||
else if (selectedCommandBinding != null)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
await CallCommandAsync(selectedCommandBinding.Command);
|
||||
}
|
||||
else if (_keysToSkip.Any(k => k.AreKeysEqual(_appState.PreviousKeys)))
|
||||
{
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
return;
|
||||
}
|
||||
else if (_appState.PreviousKeys.Count == 2)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.NoCommandFound = true;
|
||||
_appState.PreviousKeys.Clear();
|
||||
_appState.PossibleCommands = new();
|
||||
}
|
||||
else
|
||||
{
|
||||
setHandled(true);
|
||||
var possibleCommands = _keyboardConfigurationService.AllShortcut.Where(c => c.Keys[0].AreEquals(keyWithModifiers)).ToList();
|
||||
|
||||
if (possibleCommands.Count == 0)
|
||||
{
|
||||
await _commandHandlerService.HandleCommandAsync(command);
|
||||
_appState.NoCommandFound = true;
|
||||
_appState.PreviousKeys.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
else
|
||||
{
|
||||
_logger.LogError(e, "Unknown error while running command. {Command} {Error}", command, e);
|
||||
_appState.PossibleCommands = possibleCommands;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CallCommandAsync(Commands command)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _commandHandlerService.HandleCommandAsync(command);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Unknown error while running command. {Command} {Error}", command, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,53 +4,52 @@ using FileTime.GuiApp.Configuration;
|
||||
using FileTime.GuiApp.Models;
|
||||
using FileTime.GuiApp.ViewModels;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
{
|
||||
public class KeyInputHandlerService : IKeyInputHandlerService
|
||||
{
|
||||
private readonly IGuiAppState _appState;
|
||||
private readonly IDefaultModeKeyInputHandler _defaultModeKeyInputHandler;
|
||||
private readonly IRapidTravelModeKeyInputHandler _rapidTravelModeKeyInputHandler;
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public KeyInputHandlerService(
|
||||
IGuiAppState appState,
|
||||
IDefaultModeKeyInputHandler defaultModeKeyInputHandler,
|
||||
IRapidTravelModeKeyInputHandler rapidTravelModeKeyInputHandler
|
||||
)
|
||||
public class KeyInputHandlerService : IKeyInputHandlerService
|
||||
{
|
||||
private readonly IGuiAppState _appState;
|
||||
private readonly IDefaultModeKeyInputHandler _defaultModeKeyInputHandler;
|
||||
private readonly IRapidTravelModeKeyInputHandler _rapidTravelModeKeyInputHandler;
|
||||
|
||||
public KeyInputHandlerService(
|
||||
IGuiAppState appState,
|
||||
IDefaultModeKeyInputHandler defaultModeKeyInputHandler,
|
||||
IRapidTravelModeKeyInputHandler rapidTravelModeKeyInputHandler
|
||||
)
|
||||
{
|
||||
_appState = appState;
|
||||
_defaultModeKeyInputHandler = defaultModeKeyInputHandler;
|
||||
_rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler;
|
||||
}
|
||||
|
||||
public async Task ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
|
||||
{
|
||||
if (key == Key.LeftAlt
|
||||
|| key == Key.RightAlt
|
||||
|| key == Key.LeftShift
|
||||
|| key == Key.RightShift
|
||||
|| key == Key.LeftCtrl
|
||||
|| key == Key.RightCtrl)
|
||||
{
|
||||
_appState = appState;
|
||||
_defaultModeKeyInputHandler = defaultModeKeyInputHandler;
|
||||
_rapidTravelModeKeyInputHandler = rapidTravelModeKeyInputHandler;
|
||||
return;
|
||||
}
|
||||
|
||||
public async Task ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
|
||||
//_appState.NoCommandFound = false;
|
||||
|
||||
var isAltPressed = (keyModifiers & KeyModifiers.Alt) == KeyModifiers.Alt;
|
||||
var isShiftPressed = (keyModifiers & KeyModifiers.Shift) == KeyModifiers.Shift;
|
||||
var isCtrlPressed = (keyModifiers & KeyModifiers.Control) == KeyModifiers.Control;
|
||||
|
||||
var specialKeyStatus = new SpecialKeysStatus(isAltPressed, isShiftPressed, isCtrlPressed);
|
||||
|
||||
if (_appState.ViewMode == ViewMode.Default)
|
||||
{
|
||||
if (key == Key.LeftAlt
|
||||
|| key == Key.RightAlt
|
||||
|| key == Key.LeftShift
|
||||
|| key == Key.RightShift
|
||||
|| key == Key.LeftCtrl
|
||||
|| key == Key.RightCtrl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//_appState.NoCommandFound = false;
|
||||
|
||||
var isAltPressed = (keyModifiers & KeyModifiers.Alt) == KeyModifiers.Alt;
|
||||
var isShiftPressed = (keyModifiers & KeyModifiers.Shift) == KeyModifiers.Shift;
|
||||
var isCtrlPressed = (keyModifiers & KeyModifiers.Control) == KeyModifiers.Control;
|
||||
|
||||
var specialKeyStatus = new SpecialKeysStatus(isAltPressed, isShiftPressed, isCtrlPressed);
|
||||
|
||||
if (_appState.ViewMode == ViewMode.Default)
|
||||
{
|
||||
await _defaultModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _rapidTravelModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
|
||||
}
|
||||
await _defaultModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _rapidTravelModeKeyInputHandler.HandleInputKey(key, specialKeyStatus, setHandled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,60 +2,59 @@ using FileTime.App.Core.Command;
|
||||
using FileTime.GuiApp.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
public class KeyboardConfigurationService : IKeyboardConfigurationService
|
||||
{
|
||||
public class KeyboardConfigurationService : IKeyboardConfigurationService
|
||||
public IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
|
||||
public IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
|
||||
public IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
|
||||
|
||||
public KeyboardConfigurationService(IOptions<KeyBindingConfiguration> keyBindingConfiguration)
|
||||
{
|
||||
public IReadOnlyList<CommandBindingConfiguration> CommandBindings { get; }
|
||||
public IReadOnlyList<CommandBindingConfiguration> UniversalCommandBindings { get; }
|
||||
public IReadOnlyList<CommandBindingConfiguration> AllShortcut { get; }
|
||||
var commandBindings = new List<CommandBindingConfiguration>();
|
||||
var universalCommandBindings = new List<CommandBindingConfiguration>();
|
||||
IEnumerable<CommandBindingConfiguration> keyBindings = keyBindingConfiguration.Value.KeyBindings;
|
||||
|
||||
public KeyboardConfigurationService(IOptions<KeyBindingConfiguration> keyBindingConfiguration)
|
||||
if (keyBindingConfiguration.Value.UseDefaultBindings)
|
||||
{
|
||||
var commandBindings = new List<CommandBindingConfiguration>();
|
||||
var universalCommandBindings = new List<CommandBindingConfiguration>();
|
||||
IEnumerable<CommandBindingConfiguration> keyBindings = keyBindingConfiguration.Value.KeyBindings;
|
||||
|
||||
if (keyBindingConfiguration.Value.UseDefaultBindings)
|
||||
{
|
||||
keyBindings = keyBindings.Concat(keyBindingConfiguration.Value.DefaultKeyBindings);
|
||||
}
|
||||
|
||||
foreach (var keyBinding in keyBindings)
|
||||
{
|
||||
if (keyBinding.Command == Commands.None)
|
||||
{
|
||||
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>(CommandBindings.Concat(UniversalCommandBindings)).AsReadOnly();
|
||||
keyBindings = keyBindings.Concat(keyBindingConfiguration.Value.DefaultKeyBindings);
|
||||
}
|
||||
|
||||
private static bool IsUniversal(CommandBindingConfiguration keyMapping)
|
||||
foreach (var keyBinding in keyBindings)
|
||||
{
|
||||
return keyMapping.Command == Commands.GoUp
|
||||
|| keyMapping.Command == Commands.Open
|
||||
|| keyMapping.Command == Commands.OpenOrRun
|
||||
|| keyMapping.Command == Commands.MoveCursorUp
|
||||
|| keyMapping.Command == Commands.MoveCursorDown
|
||||
|| keyMapping.Command == Commands.MoveCursorUpPage
|
||||
|| keyMapping.Command == Commands.MoveCursorDownPage;
|
||||
if (keyBinding.Command == Commands.None)
|
||||
{
|
||||
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>(CommandBindings.Concat(UniversalCommandBindings)).AsReadOnly();
|
||||
}
|
||||
|
||||
private static bool IsUniversal(CommandBindingConfiguration keyMapping)
|
||||
{
|
||||
return keyMapping.Command == Commands.GoUp
|
||||
|| keyMapping.Command == Commands.Open
|
||||
|| keyMapping.Command == Commands.OpenOrRun
|
||||
|| keyMapping.Command == Commands.MoveCursorUp
|
||||
|| keyMapping.Command == Commands.MoveCursorDown
|
||||
|| keyMapping.Command == Commands.MoveCursorUpPage
|
||||
|| keyMapping.Command == Commands.MoveCursorDownPage;
|
||||
}
|
||||
}
|
||||
@@ -1,88 +1,87 @@
|
||||
using Avalonia.Input;
|
||||
using FileTime.GuiApp.Models;
|
||||
|
||||
namespace FileTime.GuiApp.Services
|
||||
{
|
||||
public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
{
|
||||
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
{
|
||||
/*var keyString = key.ToString();
|
||||
var updateRapidTravelFilter = false;
|
||||
namespace FileTime.GuiApp.Services;
|
||||
|
||||
if (key == Key.Escape)
|
||||
public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
||||
{
|
||||
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||
{
|
||||
/*var keyString = key.ToString();
|
||||
var updateRapidTravelFilter = false;
|
||||
|
||||
if (key == Key.Escape)
|
||||
{
|
||||
setHandled(true);
|
||||
if (_appState.IsAllShortcutVisible)
|
||||
{
|
||||
setHandled(true);
|
||||
if (_appState.IsAllShortcutVisible)
|
||||
{
|
||||
_appState.IsAllShortcutVisible = false;
|
||||
}
|
||||
else if (_appState.MessageBoxText != null)
|
||||
{
|
||||
_appState.MessageBoxText = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
await _appState.ExitRapidTravelMode();
|
||||
}
|
||||
_appState.IsAllShortcutVisible = false;
|
||||
}
|
||||
else if (key == Key.Back)
|
||||
else if (_appState.MessageBoxText != null)
|
||||
{
|
||||
if (_appState.RapidTravelText.Length > 0)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.RapidTravelText = _appState.RapidTravelText.Substring(0, _appState.RapidTravelText.Length - 1);
|
||||
updateRapidTravelFilter = true;
|
||||
}
|
||||
}
|
||||
else if (keyString.Length == 1)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.RapidTravelText += keyString.ToLower();
|
||||
updateRapidTravelFilter = true;
|
||||
_appState.MessageBoxText = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentKeyAsList = new List<KeyConfig>() { new KeyConfig(key) };
|
||||
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => AreKeysEqual(c.Keys, currentKeyAsList));
|
||||
if (selectedCommandBinding != null)
|
||||
{
|
||||
setHandled(true);
|
||||
await CallCommandAsync(selectedCommandBinding.Command);
|
||||
}
|
||||
await _appState.ExitRapidTravelMode();
|
||||
}
|
||||
|
||||
if (updateRapidTravelFilter)
|
||||
{
|
||||
var currentLocation = await _appState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(MainPageViewModel.RAPIDTRAVEL);
|
||||
var newLocation = new VirtualContainer(
|
||||
currentLocation,
|
||||
new List<Func<IEnumerable<IContainer>, IEnumerable<IContainer>>>()
|
||||
{
|
||||
container => container.Where(c => c.Name.ToLower().Contains(_appState.RapidTravelText))
|
||||
},
|
||||
new List<Func<IEnumerable<IElement>, IEnumerable<IElement>>>()
|
||||
{
|
||||
element => element.Where(e => e.Name.ToLower().Contains(_appState.RapidTravelText))
|
||||
},
|
||||
virtualContainerName: MainPageViewModel.RAPIDTRAVEL
|
||||
);
|
||||
|
||||
await newLocation.Init();
|
||||
|
||||
await _appState.SelectedTab.OpenContainer(newLocation);
|
||||
|
||||
var selectedItemName = _appState.SelectedTab.SelectedItem?.Item.Name;
|
||||
var currentLocationItems = await _appState.SelectedTab.CurrentLocation.GetItems();
|
||||
if (currentLocationItems.FirstOrDefault(i => string.Equals(i.Item.Name, _appState.RapidTravelText, StringComparison.OrdinalIgnoreCase)) is IItemViewModel matchItem)
|
||||
{
|
||||
await _appState.SelectedTab.SetCurrentSelectedItem(matchItem.Item);
|
||||
}
|
||||
else if (!currentLocationItems.Select(i => i.Item.Name).Any(n => n == selectedItemName))
|
||||
{
|
||||
await _appState.SelectedTab.MoveCursorToFirst();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else if (key == Key.Back)
|
||||
{
|
||||
if (_appState.RapidTravelText.Length > 0)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.RapidTravelText = _appState.RapidTravelText.Substring(0, _appState.RapidTravelText.Length - 1);
|
||||
updateRapidTravelFilter = true;
|
||||
}
|
||||
}
|
||||
else if (keyString.Length == 1)
|
||||
{
|
||||
setHandled(true);
|
||||
_appState.RapidTravelText += keyString.ToLower();
|
||||
updateRapidTravelFilter = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentKeyAsList = new List<KeyConfig>() { new KeyConfig(key) };
|
||||
var selectedCommandBinding = _keyboardConfigurationService.UniversalCommandBindings.FirstOrDefault(c => AreKeysEqual(c.Keys, currentKeyAsList));
|
||||
if (selectedCommandBinding != null)
|
||||
{
|
||||
setHandled(true);
|
||||
await CallCommandAsync(selectedCommandBinding.Command);
|
||||
}
|
||||
}
|
||||
|
||||
if (updateRapidTravelFilter)
|
||||
{
|
||||
var currentLocation = await _appState.SelectedTab.CurrentLocation.Container.WithoutVirtualContainer(MainPageViewModel.RAPIDTRAVEL);
|
||||
var newLocation = new VirtualContainer(
|
||||
currentLocation,
|
||||
new List<Func<IEnumerable<IContainer>, IEnumerable<IContainer>>>()
|
||||
{
|
||||
container => container.Where(c => c.Name.ToLower().Contains(_appState.RapidTravelText))
|
||||
},
|
||||
new List<Func<IEnumerable<IElement>, IEnumerable<IElement>>>()
|
||||
{
|
||||
element => element.Where(e => e.Name.ToLower().Contains(_appState.RapidTravelText))
|
||||
},
|
||||
virtualContainerName: MainPageViewModel.RAPIDTRAVEL
|
||||
);
|
||||
|
||||
await newLocation.Init();
|
||||
|
||||
await _appState.SelectedTab.OpenContainer(newLocation);
|
||||
|
||||
var selectedItemName = _appState.SelectedTab.SelectedItem?.Item.Name;
|
||||
var currentLocationItems = await _appState.SelectedTab.CurrentLocation.GetItems();
|
||||
if (currentLocationItems.FirstOrDefault(i => string.Equals(i.Item.Name, _appState.RapidTravelText, StringComparison.OrdinalIgnoreCase)) is IItemViewModel matchItem)
|
||||
{
|
||||
await _appState.SelectedTab.SetCurrentSelectedItem(matchItem.Item);
|
||||
}
|
||||
else if (!currentLocationItems.Select(i => i.Item.Name).Any(n => n == selectedItemName))
|
||||
{
|
||||
await _appState.SelectedTab.MoveCursorToFirst();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace FileTime.GuiApp.ViewModels
|
||||
namespace FileTime.GuiApp.ViewModels;
|
||||
|
||||
public interface IMainWindowViewModelBase
|
||||
{
|
||||
public interface IMainWindowViewModelBase
|
||||
{
|
||||
bool Loading { get; }
|
||||
}
|
||||
bool Loading { get; }
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace FileTime.GuiApp.ViewModels
|
||||
{
|
||||
public class ItemNamePartViewModel
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public TextDecorationCollection? TextDecorations { get; set; }
|
||||
namespace FileTime.GuiApp.ViewModels;
|
||||
|
||||
public ItemNamePartViewModel(string text, TextDecorationCollection? textDecorations)
|
||||
{
|
||||
Text = text;
|
||||
TextDecorations = textDecorations;
|
||||
}
|
||||
public class ItemNamePartViewModel
|
||||
{
|
||||
public string Text { get; set; }
|
||||
public TextDecorationCollection? TextDecorations { get; set; }
|
||||
|
||||
public ItemNamePartViewModel(string text, TextDecorationCollection? textDecorations)
|
||||
{
|
||||
Text = text;
|
||||
TextDecorations = textDecorations;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace FileTime.GuiApp.ViewModels
|
||||
namespace FileTime.GuiApp.ViewModels;
|
||||
|
||||
public class MainWindowLoadingViewModel : IMainWindowViewModelBase
|
||||
{
|
||||
public class MainWindowLoadingViewModel : IMainWindowViewModelBase
|
||||
{
|
||||
public bool Loading => true;
|
||||
}
|
||||
public bool Loading => true;
|
||||
}
|
||||
@@ -11,49 +11,48 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MvvmGen;
|
||||
|
||||
namespace FileTime.GuiApp.ViewModels
|
||||
namespace FileTime.GuiApp.ViewModels;
|
||||
|
||||
[ViewModel]
|
||||
[Inject(typeof(IAppState), "_appState")]
|
||||
[Inject(typeof(ILocalContentProvider), "_localContentProvider")]
|
||||
[Inject(typeof(IServiceProvider), PropertyName = "_serviceProvider")]
|
||||
[Inject(typeof(ILogger<MainWindowViewModel>), PropertyName = "_logger")]
|
||||
[Inject(typeof(IKeyInputHandlerService), PropertyName = "_keyInputHandlerService")]
|
||||
public partial class MainWindowViewModel : IMainWindowViewModelBase
|
||||
{
|
||||
[ViewModel]
|
||||
[Inject(typeof(IAppState), "_appState")]
|
||||
[Inject(typeof(ILocalContentProvider), "_localContentProvider")]
|
||||
[Inject(typeof(IServiceProvider), PropertyName = "_serviceProvider")]
|
||||
[Inject(typeof(ILogger<MainWindowViewModel>), PropertyName = "_logger")]
|
||||
[Inject(typeof(IKeyInputHandlerService), PropertyName = "_keyInputHandlerService")]
|
||||
public partial class MainWindowViewModel : IMainWindowViewModelBase
|
||||
public bool Loading => false;
|
||||
public IAppState AppState => _appState;
|
||||
public string Title { get; private set; }
|
||||
|
||||
partial void OnInitialize()
|
||||
{
|
||||
public bool Loading => false;
|
||||
public IAppState AppState => _appState;
|
||||
public string Title { get; private set; }
|
||||
_logger?.LogInformation($"Starting {nameof(MainWindowViewModel)} initialization...");
|
||||
|
||||
partial void OnInitialize()
|
||||
var version = Assembly.GetEntryAssembly()!.GetName().Version;
|
||||
var versionString = "Unknwon version";
|
||||
if (version != null)
|
||||
{
|
||||
_logger?.LogInformation($"Starting {nameof(MainWindowViewModel)} initialization...");
|
||||
|
||||
var version = Assembly.GetEntryAssembly()!.GetName().Version;
|
||||
var versionString = "Unknwon version";
|
||||
if (version != null)
|
||||
versionString = $"{version.Major}.{version.Minor}.{version.Build}";
|
||||
if (version.Revision != 0)
|
||||
{
|
||||
versionString = $"{version.Major}.{version.Minor}.{version.Build}";
|
||||
if (version.Revision != 0)
|
||||
{
|
||||
versionString += $" ({version.Revision})";
|
||||
}
|
||||
}
|
||||
Title = "FileTime " + versionString;
|
||||
|
||||
//TODO: refactor
|
||||
if (AppState.Tabs.Count == 0)
|
||||
{
|
||||
var tab = _serviceProvider.GetInitableResolver<IContainer>(_localContentProvider).GetRequiredService<ITab>();
|
||||
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
|
||||
|
||||
_appState.AddTab(tabViewModel);
|
||||
versionString += $" ({version.Revision})";
|
||||
}
|
||||
}
|
||||
Title = "FileTime " + versionString;
|
||||
|
||||
public void ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
|
||||
//TODO: refactor
|
||||
if (AppState.Tabs.Count == 0)
|
||||
{
|
||||
_keyInputHandlerService.ProcessKeyDown(key, keyModifiers, setHandled);
|
||||
var tab = _serviceProvider.GetInitableResolver<IContainer>(_localContentProvider).GetRequiredService<ITab>();
|
||||
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
|
||||
|
||||
_appState.AddTab(tabViewModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessKeyDown(Key key, KeyModifiers keyModifiers, Action<bool> setHandled)
|
||||
{
|
||||
_keyInputHandlerService.ProcessKeyDown(key, keyModifiers, setHandled);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,20 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace FileTime.GuiApp.Views
|
||||
namespace FileTime.GuiApp.Views;
|
||||
|
||||
public partial class ItemView : UserControl
|
||||
{
|
||||
public partial class ItemView : UserControl
|
||||
public static readonly StyledProperty<bool> ShowAttributesProperty = AvaloniaProperty.Register<ItemView, bool>(nameof(ShowAttributes), true);
|
||||
|
||||
public bool ShowAttributes
|
||||
{
|
||||
public static readonly StyledProperty<bool> ShowAttributesProperty = AvaloniaProperty.Register<ItemView, bool>(nameof(ShowAttributes), true);
|
||||
|
||||
public bool ShowAttributes
|
||||
{
|
||||
get => GetValue(ShowAttributesProperty);
|
||||
set => SetValue(ShowAttributesProperty, value);
|
||||
}
|
||||
|
||||
public ItemView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
get => GetValue(ShowAttributesProperty);
|
||||
set => SetValue(ShowAttributesProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
public ItemView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -7,66 +7,65 @@ using FileTime.GuiApp.ViewModels;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace FileTime.GuiApp.Views
|
||||
namespace FileTime.GuiApp.Views;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
private readonly ILogger<MainWindow>? _logger;
|
||||
private InputElementWrapper? _inputElementWrapper;
|
||||
|
||||
public MainWindowViewModel? ViewModel
|
||||
{
|
||||
private readonly ILogger<MainWindow>? _logger;
|
||||
private InputElementWrapper? _inputElementWrapper;
|
||||
|
||||
public MainWindowViewModel? ViewModel
|
||||
get => DataContext as MainWindowViewModel;
|
||||
set
|
||||
{
|
||||
get => DataContext as MainWindowViewModel;
|
||||
set
|
||||
if (value != DataContext)
|
||||
{
|
||||
if (value != DataContext)
|
||||
{
|
||||
DataContext = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
_logger = DI.ServiceProvider.GetService<ILogger<MainWindow>>();
|
||||
_logger?.LogInformation($"Starting {nameof(MainWindow)} initialization...");
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnWindowOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (DataContext is not MainWindowViewModel)
|
||||
{
|
||||
_logger?.LogInformation($"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization...");
|
||||
ViewModel = DI.ServiceProvider.GetRequiredService<MainWindowViewModel>();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (_inputElementWrapper == null)
|
||||
{
|
||||
ViewModel?.ProcessKeyDown(e.Key, e.KeyModifiers, h => e.Handled = h);
|
||||
}
|
||||
}
|
||||
|
||||
private void HeaderPointerPressed(object sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (e.ClickCount == 2)
|
||||
{
|
||||
if (WindowState == WindowState.Maximized)
|
||||
{
|
||||
WindowState = WindowState.Normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowState = WindowState.Maximized;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
DataContext = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
_logger = DI.ServiceProvider.GetService<ILogger<MainWindow>>();
|
||||
_logger?.LogInformation($"Starting {nameof(MainWindow)} initialization...");
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void OnWindowOpened(object sender, EventArgs e)
|
||||
{
|
||||
if (DataContext is not MainWindowViewModel)
|
||||
{
|
||||
_logger?.LogInformation($"{nameof(MainWindow)} opened, starting {nameof(MainWindowViewModel)} initialization...");
|
||||
ViewModel = DI.ServiceProvider.GetRequiredService<MainWindowViewModel>();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (_inputElementWrapper == null)
|
||||
{
|
||||
ViewModel?.ProcessKeyDown(e.Key, e.KeyModifiers, h => e.Handled = h);
|
||||
}
|
||||
}
|
||||
|
||||
private void HeaderPointerPressed(object sender, PointerPressedEventArgs e)
|
||||
{
|
||||
if (e.ClickCount == 2)
|
||||
{
|
||||
if (WindowState == WindowState.Maximized)
|
||||
{
|
||||
WindowState = WindowState.Normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowState = WindowState.Maximized;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BeginMoveDrag(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user