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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user