File scoped namespace
This commit is contained in:
@@ -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