Console size scan
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using DeclarativeProperty;
|
||||
using FileTime.Core.Models;
|
||||
|
||||
namespace FileTime.App.ContainerSizeScanner;
|
||||
|
||||
@@ -7,7 +8,7 @@ public class ChildElementPreview : ISizePreviewItem
|
||||
public ChildElementPreview(ISizeScanElement element)
|
||||
{
|
||||
Name = element.Name;
|
||||
Size = element.Size;
|
||||
Size = new DeclarativeProperty<long>(((IElement) element).Size);
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
@@ -18,6 +18,9 @@ public record SizeScanElement : ISizeScanElement
|
||||
public required DateTime? ModifiedAt { get; init;}
|
||||
|
||||
public required IDeclarativeProperty<long> Size { get; init; }
|
||||
|
||||
long IElement.Size => Size.Value;
|
||||
|
||||
public bool IsHidden => false;
|
||||
public bool IsExists => true;
|
||||
public SupportsDelete CanDelete => SupportsDelete.False;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using DeclarativeProperty;
|
||||
using FileTime.Core.Enums;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
using FileTime.Core.Timeline;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -104,10 +103,7 @@ public class SizeScanTask : ISizeScanTask
|
||||
{
|
||||
if (_cancelled) return;
|
||||
|
||||
var fileExtension = element.GetExtension<FileExtension>();
|
||||
var size = fileExtension?.Size ?? 0;
|
||||
|
||||
var sizeProperty = new DeclarativeProperty<long>(size);
|
||||
var sizeProperty = new DeclarativeProperty<long>(element.Size);
|
||||
var childName = sizeScanContainer.FullName!.GetChild(element.Name).Path;
|
||||
|
||||
var childElement = new SizeScanElement
|
||||
|
||||
@@ -25,4 +25,9 @@
|
||||
<ProjectReference Include="..\..\Library\GeneralInputKey\GeneralInputKey.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\Traits\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace FileTime.App.Core.ViewModels;
|
||||
|
||||
public interface IElementViewModel :
|
||||
IItemViewModel,
|
||||
ISizeProvider,
|
||||
IInitable<IElement, ITabViewModel, ItemViewModelType>
|
||||
IInitable<IElement, ITabViewModel, ItemViewModelType>,
|
||||
ISizeProvider
|
||||
{
|
||||
IElement? Element { get; }
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
using InitableService;
|
||||
|
||||
namespace FileTime.App.Core.ViewModels;
|
||||
|
||||
public interface IFileViewModel : IElementViewModel, IInitable<IElement, FileExtension, ITabViewModel, ItemViewModelType>
|
||||
{
|
||||
}
|
||||
@@ -44,4 +44,5 @@
|
||||
<ProjectReference Include="..\FileTime.App.Search\FileTime.App.Search.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace FileTime.GuiApp.App.Helper;
|
||||
namespace FileTime.App.Core.Helpers;
|
||||
|
||||
public static class ColorHelper
|
||||
{
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using FileTime.App.ContainerSizeScanner;
|
||||
|
||||
namespace FileTime.App.Core.Helpers;
|
||||
|
||||
public static class SizePreviewItemHelper
|
||||
{
|
||||
public static (byte r, byte g, byte b) GetItemColor(
|
||||
ObservableCollection<ISizePreviewItem> items,
|
||||
ISizePreviewItem currentItem,
|
||||
double hueDiff = 0,
|
||||
double lightness = 0.75
|
||||
)
|
||||
{
|
||||
var i = 0;
|
||||
for (; i < items.Count; i++)
|
||||
{
|
||||
if (items[i].Name == currentItem.Name) break;
|
||||
}
|
||||
|
||||
var hue = (360d * i / (items.Count < 1 ? 1 : items.Count)) + hueDiff;
|
||||
if (hue > 360) hue -= 360;
|
||||
if (hue < 0) hue += 360;
|
||||
|
||||
return ColorHelper.HlsToRgb(hue, lightness, 1);
|
||||
}
|
||||
}
|
||||
@@ -321,7 +321,7 @@ public class NavigationUserCommandHandlerService : UserCommandHandlerServiceBase
|
||||
{
|
||||
if (_selectedTab is null || _currentItems?.Value is null) return Task.CompletedTask;
|
||||
|
||||
var newSelectedItem = getNewSelected(_currentItems.Value);
|
||||
var newSelectedItem = getNewSelected(_currentItems.Value.ToArray());
|
||||
if (newSelectedItem == null) return Task.CompletedTask;
|
||||
|
||||
if (_selectedTab.Tab is { } tab)
|
||||
|
||||
@@ -18,7 +18,6 @@ public static class Startup
|
||||
serviceCollection.TryAddTransient<ITabViewModel, TabViewModel>();
|
||||
serviceCollection.TryAddTransient<IContainerViewModel, ContainerViewModel>();
|
||||
serviceCollection.TryAddTransient<IElementViewModel, ElementViewModel>();
|
||||
serviceCollection.TryAddTransient<IFileViewModel, FileViewModel>();
|
||||
serviceCollection.TryAddTransient<IItemNameConverterService, ItemNameConverterService>();
|
||||
serviceCollection.TryAddTransient<ElementPreviewViewModel>();
|
||||
serviceCollection.TryAddSingleton<IUserCommandHandlerService, UserCommandHandlerService>();
|
||||
|
||||
@@ -4,7 +4,7 @@ using FileTime.Core.Models;
|
||||
|
||||
namespace FileTime.App.Core.ViewModels;
|
||||
|
||||
public partial class ContainerViewModel : ItemViewModel, IContainerViewModel
|
||||
public class ContainerViewModel : ItemViewModel, IContainerViewModel
|
||||
{
|
||||
public IContainer? Container => BaseItem as IContainer;
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ using FileTime.Core.Models;
|
||||
|
||||
namespace FileTime.App.Core.ViewModels;
|
||||
|
||||
public partial class ElementViewModel : ItemViewModel, IElementViewModel
|
||||
public class ElementViewModel : ItemViewModel, IElementViewModel
|
||||
{
|
||||
private readonly DeclarativeProperty<long> _size = new(0);
|
||||
public IElement? Element => BaseItem as Element;
|
||||
|
||||
public ElementViewModel(IItemNameConverterService itemNameConverterService, IAppState appState) : base(itemNameConverterService, appState)
|
||||
@@ -14,7 +15,10 @@ public partial class ElementViewModel : ItemViewModel, IElementViewModel
|
||||
}
|
||||
|
||||
public void Init(IElement item, ITabViewModel parentTab, ItemViewModelType itemViewModelType)
|
||||
=> Init((IItem)item, parentTab, itemViewModelType);
|
||||
{
|
||||
Init((IItem) item, parentTab, itemViewModelType);
|
||||
_size.SetValueSafe(item.Size);
|
||||
}
|
||||
|
||||
public IDeclarativeProperty<long> Size { get; protected set; } = new DeclarativeProperty<long>(0);
|
||||
public IDeclarativeProperty<long> Size => _size;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using DeclarativeProperty;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
|
||||
namespace FileTime.App.Core.ViewModels;
|
||||
|
||||
public partial class FileViewModel : ElementViewModel, IFileViewModel
|
||||
{
|
||||
public FileViewModel(IItemNameConverterService itemNameConverterService, IAppState appState) : base(itemNameConverterService, appState)
|
||||
{
|
||||
}
|
||||
|
||||
public void Init(IElement item, FileExtension fileExtension, ITabViewModel parentTab, ItemViewModelType itemViewModelType)
|
||||
{
|
||||
Init(item, parentTab, itemViewModelType);
|
||||
Size = new DeclarativeProperty<long>(fileExtension.Size ?? 0);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.App.Core.Services;
|
||||
using FileTime.Core.Enums;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
using FileTime.Core.Services;
|
||||
using FileTime.Core.Timeline;
|
||||
using InitableService;
|
||||
@@ -205,19 +204,6 @@ public partial class TabViewModel : ITabViewModel
|
||||
return containerViewModel;
|
||||
}
|
||||
else if (item is IElement element)
|
||||
{
|
||||
var fileExtension = element.GetExtension<FileExtension>();
|
||||
|
||||
if (fileExtension is not null)
|
||||
{
|
||||
var fileViewModel = _serviceProvider
|
||||
.GetInitableResolver<IElement, FileExtension, ITabViewModel, ItemViewModelType>(
|
||||
element, fileExtension, this, type)
|
||||
.GetRequiredService<IFileViewModel>();
|
||||
|
||||
return fileViewModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
var elementViewModel = _serviceProvider
|
||||
.GetInitableResolver<IElement, ITabViewModel, ItemViewModelType>(element, this, type)
|
||||
@@ -225,7 +211,6 @@ public partial class TabViewModel : ITabViewModel
|
||||
|
||||
return elementViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException($"{nameof(item)} is not {nameof(IContainer)} neither {nameof(IElement)}");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
using FileTime.App.Core.Models;
|
||||
using System.Collections.ObjectModel;
|
||||
using FileTime.App.ContainerSizeScanner;
|
||||
using FileTime.App.Core.Helpers;
|
||||
using FileTime.App.Core.Models;
|
||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||
using FileTime.ConsoleUI.App.Preview;
|
||||
using FileTime.ConsoleUI.App.Styling;
|
||||
using Humanizer.Bytes;
|
||||
using TerminalUI.Color;
|
||||
using TerminalUI.Controls;
|
||||
using TerminalUI.Extensions;
|
||||
using TerminalUI.Models;
|
||||
@@ -13,11 +18,18 @@ public class ItemPreviews
|
||||
{
|
||||
private readonly ITheme _theme;
|
||||
private readonly IConsoleAppState _appState;
|
||||
private readonly IColorProvider _colorProvider;
|
||||
private ItemsControl<ContainerPreview, ISizePreviewItem> _sizePreviews;
|
||||
|
||||
public ItemPreviews(ITheme theme, IConsoleAppState appState)
|
||||
public ItemPreviews(
|
||||
ITheme theme,
|
||||
IConsoleAppState appState,
|
||||
IColorProvider colorProvider
|
||||
)
|
||||
{
|
||||
_theme = theme;
|
||||
_appState = appState;
|
||||
_colorProvider = colorProvider;
|
||||
}
|
||||
|
||||
public IView<IRootViewModel> View()
|
||||
@@ -38,7 +50,11 @@ public class ItemPreviews
|
||||
fallbackValue: false)),
|
||||
ElementPreviews()
|
||||
.WithDataContextBinding<IRootViewModel, IElementPreviewViewModel>(
|
||||
dc => (IElementPreviewViewModel)dc.ItemPreviewService.ItemPreview.Value
|
||||
dc => (IElementPreviewViewModel) dc.ItemPreviewService.ItemPreview.Value
|
||||
),
|
||||
SizeContainerPreview()
|
||||
.WithDataContextBinding<IRootViewModel, ContainerPreview>(
|
||||
dc => (ContainerPreview) dc.ItemPreviewService.ItemPreview.Value
|
||||
)
|
||||
}
|
||||
};
|
||||
@@ -46,6 +62,125 @@ public class ItemPreviews
|
||||
return view;
|
||||
}
|
||||
|
||||
private IView<ContainerPreview> SizeContainerPreview()
|
||||
{
|
||||
var sizePreviews = new ItemsControl<ContainerPreview, ISizePreviewItem>
|
||||
{
|
||||
Orientation = Orientation.Horizontal,
|
||||
Margin = "0 0 0 1"
|
||||
};
|
||||
sizePreviews.Setup(c => c.Bind(
|
||||
c,
|
||||
dc => dc.TopItems,
|
||||
c => c.ItemsSource));
|
||||
|
||||
_sizePreviews = sizePreviews;
|
||||
|
||||
sizePreviews.ItemTemplate = SizeContainerItem;
|
||||
|
||||
var root = new Grid<ContainerPreview>
|
||||
{
|
||||
RowDefinitionsObject = "Auto Auto",
|
||||
ChildInitializer =
|
||||
{
|
||||
sizePreviews,
|
||||
new ItemsControl<ContainerPreview, ISizePreviewItem>
|
||||
{
|
||||
Extensions = {new GridPositionExtension(0, 1)},
|
||||
ItemTemplate = () =>
|
||||
{
|
||||
var root = new Grid<ISizePreviewItem>
|
||||
{
|
||||
ColumnDefinitionsObject = "5 11 *",
|
||||
ChildInitializer =
|
||||
{
|
||||
new Rectangle<ISizePreviewItem>
|
||||
{
|
||||
Height = 1,
|
||||
Width = 3
|
||||
}
|
||||
.Setup(r => r.Bind(
|
||||
r,
|
||||
dc => GenerateSizeBackground(_sizePreviews.DataContext.TopItems, dc),
|
||||
r => r.Fill)),
|
||||
new TextBlock<ISizePreviewItem>
|
||||
{
|
||||
Extensions = {new GridPositionExtension(1, 0)},
|
||||
TextAlignment = TextAlignment.Right,
|
||||
Margin = "0 0 1 0"
|
||||
}
|
||||
.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.Size.Value,
|
||||
t => t.Text,
|
||||
v => ByteSize.FromBytes(v).ToString())),
|
||||
new TextBlock<ISizePreviewItem>
|
||||
{
|
||||
Extensions = {new GridPositionExtension(2, 0)}
|
||||
}
|
||||
.Setup(t => t.Bind(
|
||||
t,
|
||||
dc => dc.Name,
|
||||
t => t.Text))
|
||||
}
|
||||
};
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
.Setup(c => c.Bind(
|
||||
c,
|
||||
dc => dc.TopItems,
|
||||
c => c.ItemsSource))
|
||||
}
|
||||
};
|
||||
|
||||
root.Bind(
|
||||
root,
|
||||
dc => dc.Name == ContainerPreview.PreviewName,
|
||||
r => r.IsVisible);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private Grid<ISizePreviewItem> SizeContainerItem()
|
||||
{
|
||||
var root = new Grid<ISizePreviewItem>
|
||||
{
|
||||
ChildInitializer =
|
||||
{
|
||||
new Rectangle<ISizePreviewItem>
|
||||
{
|
||||
Height = 1
|
||||
}
|
||||
.Setup(r => r.Bind(
|
||||
r,
|
||||
dc => GenerateSizeBackground(_sizePreviews.DataContext.TopItems, dc),
|
||||
r => r.Fill))
|
||||
}
|
||||
};
|
||||
|
||||
root.Bind(
|
||||
root,
|
||||
dc => GetWidth(dc.Size.Value, _sizePreviews.DataContext.TopItems, _sizePreviews.ActualWidth),
|
||||
r => r.Width);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private int? GetWidth(long sizeValue, ObservableCollection<ISizePreviewItem>? dataContextTopItems, int rootActualWidth)
|
||||
=> dataContextTopItems is null
|
||||
? 0
|
||||
: (int) Math.Floor((double) rootActualWidth * sizeValue / dataContextTopItems.Select(i => i.Size.Value).Sum());
|
||||
|
||||
private IColor? GenerateSizeBackground(ObservableCollection<ISizePreviewItem> topItems, ISizePreviewItem? dc)
|
||||
{
|
||||
if (dc is null) return null;
|
||||
var (r, g, b) = SizePreviewItemHelper.GetItemColor(topItems, dc);
|
||||
|
||||
return _colorProvider.FromRgb(new Rgb(r, g, b), ColorType.Background);
|
||||
}
|
||||
|
||||
private IView<IElementPreviewViewModel> ElementPreviews()
|
||||
{
|
||||
var view = new Grid<IElementPreviewViewModel>
|
||||
@@ -60,7 +195,6 @@ public class ItemPreviews
|
||||
t,
|
||||
dc => dc.Mode == ItemPreviewMode.Unknown,
|
||||
t => t.IsVisible,
|
||||
v => v,
|
||||
fallbackValue: false)),
|
||||
new TextBlock<IElementPreviewViewModel>
|
||||
{
|
||||
@@ -70,7 +204,6 @@ public class ItemPreviews
|
||||
t,
|
||||
dc => dc.Mode == ItemPreviewMode.Empty,
|
||||
t => t.IsVisible,
|
||||
v => v,
|
||||
fallbackValue: false)),
|
||||
new Grid<IElementPreviewViewModel>
|
||||
{
|
||||
@@ -120,7 +253,6 @@ public class ItemPreviews
|
||||
t,
|
||||
dc => dc.Mode == ItemPreviewMode.Text,
|
||||
t => t.IsVisible,
|
||||
v => v,
|
||||
fallbackValue: false)),
|
||||
}
|
||||
};
|
||||
@@ -128,8 +260,7 @@ public class ItemPreviews
|
||||
view.Bind(
|
||||
view,
|
||||
dc => dc.Name == ElementPreviewViewModel.PreviewName,
|
||||
v => v.IsVisible,
|
||||
v => v
|
||||
v => v.IsVisible
|
||||
);
|
||||
|
||||
return view;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\AppCommon\FileTime.App.ContainerSizeScanner\FileTime.App.ContainerSizeScanner.csproj" />
|
||||
<ProjectReference Include="..\..\AppCommon\FileTime.App.Core\FileTime.App.Core.csproj" />
|
||||
<ProjectReference Include="..\..\AppCommon\FileTime.App.FrequencyNavigation\FileTime.App.FrequencyNavigation.csproj" />
|
||||
<ProjectReference Include="..\..\Library\TerminalUI\TerminalUI.csproj" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Globalization;
|
||||
using FileTime.App.Core.Models.Enums;
|
||||
using FileTime.App.Core.Models.Traits;
|
||||
using FileTime.App.Core.ViewModels;
|
||||
using FileTime.ConsoleUI.App.Configuration;
|
||||
using FileTime.ConsoleUI.App.Controls;
|
||||
@@ -479,7 +480,9 @@ public class MainWindow
|
||||
|
||||
list.Bind(
|
||||
list,
|
||||
dc => dc.AppState.SelectedTab.Value.SelectedsChildren.Value.Count > 0,
|
||||
dc =>
|
||||
dc.AppState.SelectedTab.Value.SelectedsChildren.Value.Count > 0
|
||||
&& dc.ItemPreviewService.ItemPreview.Value == null,
|
||||
l => l.IsVisible,
|
||||
fallbackValue: false);
|
||||
|
||||
@@ -544,28 +547,9 @@ public class MainWindow
|
||||
if (!options.ShowAttributes) return;
|
||||
t.Bind(
|
||||
t,
|
||||
dc => ((IContainer) dc.BaseItem).Items.Count,
|
||||
tb => tb.Text,
|
||||
t => $" {t}");
|
||||
})
|
||||
}
|
||||
}
|
||||
.Setup(s => s.Bind(
|
||||
s,
|
||||
dc => dc.BaseItem.Type == AbsolutePathType.Container,
|
||||
s => s.IsVisible)),
|
||||
new StackPanel<IItemViewModel>
|
||||
{
|
||||
Extensions = {new GridPositionExtension(1, 0)},
|
||||
ChildInitializer =
|
||||
{
|
||||
new TextBlock<IItemViewModel>()
|
||||
.Setup(t =>
|
||||
{
|
||||
if (!options.ShowAttributes) return;
|
||||
t.Bind(
|
||||
t,
|
||||
dc => ((IElementViewModel) dc).Size.Value,
|
||||
dc => dc is ISizeProvider
|
||||
? ((ISizeProvider) dc).Size.Value
|
||||
: ((ISizeProvider) dc.BaseItem).Size.Value,
|
||||
tb => tb.Text,
|
||||
v =>
|
||||
{
|
||||
@@ -573,13 +557,23 @@ public class MainWindow
|
||||
|
||||
return $"{b.LargestWholeNumberValue:0.#} " + b.GetLargestWholeNumberSymbol(NumberFormatInfo.CurrentInfo).First();
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
.Setup(s => s.Bind(
|
||||
}),
|
||||
|
||||
/*new TextBlock<IItemViewModel>()
|
||||
.Setup(t =>
|
||||
{
|
||||
if (!options.ShowAttributes) return;
|
||||
t.Bind(
|
||||
t,
|
||||
dc => ((IContainer) dc.BaseItem).Items.Count,
|
||||
tb => tb.Text,
|
||||
t => $" {t,4}");
|
||||
}).Setup(s => s.Bind(
|
||||
s,
|
||||
dc => dc.BaseItem.Type == AbsolutePathType.Element,
|
||||
s => s.IsVisible))
|
||||
dc => dc.BaseItem.Type == AbsolutePathType.Container,
|
||||
s => s.IsVisible))*/
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using FileTime.App.Core;
|
||||
using FileTime.App.Core.Configuration;
|
||||
using FileTime.ConsoleUI;
|
||||
@@ -52,7 +50,6 @@ try
|
||||
}
|
||||
finally
|
||||
{
|
||||
driver?.Clear();
|
||||
driver?.SetCursorVisible(true);
|
||||
driver?.Dispose();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ public static class Startup
|
||||
{
|
||||
public static readonly Dictionary<string, Func<IConsoleDriver>> Drivers = new()
|
||||
{
|
||||
["windows"] = () => new XTermDriver(),
|
||||
["xterm"] = () => new XTermDriver(),
|
||||
["dotnet"] = () => new DotnetDriver()
|
||||
};
|
||||
public static IServiceCollection AddConsoleDriver(this IServiceCollection serviceCollection)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
namespace FileTime.Core.Models.Extensions;
|
||||
|
||||
public record FileExtension(long? Size);
|
||||
@@ -2,5 +2,5 @@ namespace FileTime.Core.Models;
|
||||
|
||||
public interface IElement : IItem
|
||||
{
|
||||
|
||||
long Size { get; }
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
using FileTime.Core.Timeline;
|
||||
|
||||
namespace FileTime.Core.Command.Copy;
|
||||
@@ -20,7 +19,7 @@ public class CalculateStrategy : ICopyStrategy
|
||||
public async Task CopyAsync(AbsolutePath from, AbsolutePath to, CopyCommandContext context)
|
||||
{
|
||||
var resolvedFrom = await from.ResolveAsync();
|
||||
_operationStatuses.Add(new OperationProgress(from.Path.Path, (resolvedFrom as IElement)?.GetExtension<FileExtension>()?.Size ?? 0L));
|
||||
_operationStatuses.Add(new OperationProgress(from.Path.Path, (resolvedFrom as IElement)?.Size ?? 0L));
|
||||
}
|
||||
|
||||
public Task CreateContainerAsync(IContainer target, string name, PointInTime currentTime) => Task.CompletedTask;
|
||||
|
||||
@@ -18,6 +18,7 @@ public record Element(
|
||||
SupportsDelete CanDelete,
|
||||
bool CanRename,
|
||||
string? Attributes,
|
||||
long Size,
|
||||
IContentProvider Provider,
|
||||
PointInTime PointInTime,
|
||||
ObservableCollection<Exception> Exceptions,
|
||||
|
||||
@@ -6,7 +6,6 @@ using DeclarativeProperty;
|
||||
using DynamicData;
|
||||
using FileTime.Core.Helper;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
using FileTime.Core.Timeline;
|
||||
using ObservableComputations;
|
||||
using IContainer = FileTime.Core.Models.IContainer;
|
||||
@@ -178,12 +177,12 @@ public class Tab : ITab
|
||||
|
||||
private static long GetSize(IItem item)
|
||||
{
|
||||
if (item is IElement element && element.GetExtension<FileExtension>() is { } fileExtension)
|
||||
if (item is IElement element)
|
||||
{
|
||||
return fileExtension.Size ?? -1;
|
||||
return element.Size;
|
||||
}
|
||||
|
||||
return -2;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static IItem MapItem(AbsolutePath item)
|
||||
|
||||
@@ -3,7 +3,7 @@ using Avalonia.Data.Converters;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Threading;
|
||||
using FileTime.App.ContainerSizeScanner;
|
||||
using FileTime.GuiApp.App.Helper;
|
||||
using FileTime.App.Core.Helpers;
|
||||
|
||||
namespace FileTime.GuiApp.App.Converters;
|
||||
|
||||
@@ -16,18 +16,12 @@ public class ItemSizeToBrushConverter : IMultiValueConverter
|
||||
{
|
||||
if (values is [ISizePreviewItem previewItem, ContainerPreview sizeContainerViewModel])
|
||||
{
|
||||
var items = sizeContainerViewModel.TopItems;
|
||||
var i = 0;
|
||||
for (; i < items.Count; i++)
|
||||
{
|
||||
if (items[i].Name == previewItem.Name) break;
|
||||
}
|
||||
|
||||
var hue = (360d * i / (items.Count < 1 ? 1 : items.Count)) + HueDiff;
|
||||
if (hue > 360) hue -= 360;
|
||||
if (hue < 0) hue += 360;
|
||||
|
||||
var (r, g, b) = ColorHelper.HlsToRgb(hue, Lightness, 1);
|
||||
var (r, g, b) = SizePreviewItemHelper.GetItemColor(
|
||||
sizeContainerViewModel.TopItems,
|
||||
previewItem,
|
||||
HueDiff,
|
||||
Lightness
|
||||
);
|
||||
|
||||
var task = Dispatcher.UIThread.InvokeAsync(() => new SolidColorBrush(Color.FromRgb(r, g, b)));
|
||||
task.Wait();
|
||||
|
||||
@@ -1,48 +1,52 @@
|
||||
<UserControl
|
||||
Background="{Binding ViewMode.Value, Converter={StaticResource ItemViewModeToBackgroundConverter}}"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
mc:Ignorable="d"
|
||||
x:Class="FileTime.GuiApp.App.Views.ItemView"
|
||||
x:CompileBindings="True"
|
||||
x:DataType="appcore:IItemViewModel"
|
||||
x:Name="ItemRoot"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:appcore="using:FileTime.App.Core.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:guiappvm="using:FileTime.GuiApp.App.ViewModels"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:traits="clr-namespace:FileTime.App.Core.Models.Traits;assembly=FileTime.App.Core.Abstraction"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
x:Name="ItemRoot"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
d:DesignHeight="450"
|
||||
d:DesignWidth="800"
|
||||
x:CompileBindings="True"
|
||||
x:DataType="appcore:IItemViewModel"
|
||||
Background="{Binding ViewMode.Value, Converter={StaticResource ItemViewModeToBackgroundConverter}}"
|
||||
mc:Ignorable="d">
|
||||
<Grid
|
||||
ColumnDefinitions="20,*,Auto"
|
||||
x:Name="RootGrid"
|
||||
Margin="3"
|
||||
x:Name="RootGrid">
|
||||
ColumnDefinitions="20,*,Auto">
|
||||
<Grid.Styles>
|
||||
<Style Selector="TextBlock">
|
||||
<Setter Property="Foreground" Value="{Binding DataContext.ViewMode.Value, Converter={StaticResource ItemViewModeToForegroundConverter}, ElementName=ItemRoot}" x:CompileBindings="False" />
|
||||
<Setter x:CompileBindings="False" Property="Foreground" Value="{Binding DataContext.ViewMode.Value, Converter={StaticResource ItemViewModeToForegroundConverter}, ElementName=ItemRoot}" />
|
||||
</Style>
|
||||
</Grid.Styles>
|
||||
<Image
|
||||
Width="18"
|
||||
Height="18"
|
||||
HorizontalAlignment="Left"
|
||||
Source="{Binding Converter={StaticResource ItemToImageConverter}}"
|
||||
VerticalAlignment="Center"
|
||||
Width="18" />
|
||||
Source="{Binding Converter={StaticResource ItemToImageConverter}}" />
|
||||
|
||||
<ItemsControl
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
Margin="5,0,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center">
|
||||
<ItemsControl.ItemsSource>
|
||||
<MultiBinding Converter="{StaticResource NamePartShrinkerConverter}">
|
||||
<MultiBinding.Bindings>
|
||||
<Binding Path="DisplayName^" />
|
||||
<Binding ElementName="RootGrid" Path="Bounds.Width" />
|
||||
<Binding ElementName="ItemRoot" Path="ShowAttributes" />
|
||||
<Binding
|
||||
ElementName="RootGrid"
|
||||
Path="Bounds.Width" />
|
||||
<Binding
|
||||
ElementName="ItemRoot"
|
||||
Path="ShowAttributes" />
|
||||
</MultiBinding.Bindings>
|
||||
</MultiBinding>
|
||||
</ItemsControl.ItemsSource>
|
||||
@@ -54,52 +58,50 @@
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="guiappvm:ItemNamePartViewModel">
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding Text}" TextDecorations="{Binding TextDecorations}" />
|
||||
<TextBlock
|
||||
Text="{Binding Text}"
|
||||
TextDecorations="{Binding TextDecorations}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
|
||||
<Grid Grid.Column="2" IsVisible="{Binding ShowAttributes, ElementName=ItemRoot}">
|
||||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
|
||||
<Grid
|
||||
Grid.Column="2"
|
||||
IsVisible="{Binding ShowAttributes, ElementName=ItemRoot}">
|
||||
<StackPanel
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
Width="50"
|
||||
Classes="SmallText"
|
||||
IsVisible="{Binding Converter={StaticResource IsTypeConverter}, ConverterParameter={x:Type appcore:IElementViewModel}}"
|
||||
Text="{Binding BaseItem.DisplayName, Converter={StaticResource GetFileExtensionConverter}}"
|
||||
Width="50" />
|
||||
<Grid DataContext="{Binding BaseItem}" IsVisible="{Binding Converter={StaticResource IsTypeConverter}, ConverterParameter={x:Type traits:ISizeProvider}}">
|
||||
Text="{Binding BaseItem.DisplayName, Converter={StaticResource GetFileExtensionConverter}}" />
|
||||
<Grid
|
||||
DataContext="{Binding BaseItem}"
|
||||
IsVisible="{Binding Converter={StaticResource IsTypeConverter}, ConverterParameter={x:Type traits:ISizeProvider}}">
|
||||
<TextBlock
|
||||
Width="60"
|
||||
x:DataType="traits:ISizeProvider"
|
||||
Classes="SmallText"
|
||||
Text="{Binding Size.Value, Converter={StaticResource FormatSizeConverter}}"
|
||||
TextAlignment="Right"
|
||||
Width="60"
|
||||
x:DataType="traits:ISizeProvider" />
|
||||
</Grid>
|
||||
<Grid IsVisible="{Binding BaseItem, Converter={StaticResource IsNotTypeConverter}, ConverterParameter={x:Type traits:ISizeProvider}}">
|
||||
|
||||
<TextBlock
|
||||
Classes="SmallText"
|
||||
IsVisible="{Binding Converter={StaticResource IsTypeConverter}, ConverterParameter={x:Type traits:ISizeProvider}}"
|
||||
Text="{Binding Size.Value, Converter={StaticResource FormatSizeConverter}}"
|
||||
TextAlignment="Right"
|
||||
Width="60"
|
||||
x:DataType="traits:ISizeProvider" />
|
||||
TextAlignment="Right" />
|
||||
</Grid>
|
||||
<TextBlock
|
||||
Width="95"
|
||||
Classes="SmallText"
|
||||
Text="{Binding ModifiedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=yyyy-MM-dd}"
|
||||
TextAlignment="Right"
|
||||
Width="95" />
|
||||
TextAlignment="Right" />
|
||||
<TextBlock
|
||||
Width="35"
|
||||
Classes="SmallText"
|
||||
Text="{Binding ModifiedAt, Converter={StaticResource DateTimeConverter}, ConverterParameter=hh:mm}"
|
||||
TextAlignment="Right"
|
||||
Width="35" />
|
||||
TextAlignment="Right" />
|
||||
<TextBlock
|
||||
Width="45"
|
||||
Classes="SmallText"
|
||||
Text="{Binding BaseItem.Attributes}"
|
||||
TextAlignment="Right"
|
||||
Width="45" />
|
||||
TextAlignment="Right" />
|
||||
|
||||
</StackPanel>
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ public class ItemPreview
|
||||
SupportsDelete.True,
|
||||
true,
|
||||
"attr",
|
||||
0,
|
||||
null!,
|
||||
PointInTime.Present,
|
||||
new ObservableCollection<Exception>(),
|
||||
|
||||
@@ -10,7 +10,6 @@ using FileTime.GuiApp.App.Font;
|
||||
using FileTime.GuiApp.App.ViewModels;
|
||||
using FileTime.GuiApp.App.Views;
|
||||
using FileTime.Server;
|
||||
using FileTime.Server.Common;
|
||||
using FileTime.Tools.Compression;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@@ -6,49 +6,24 @@ public class AnsiColorProvider : ColorProviderBase
|
||||
{
|
||||
var finalColor = ParseInternal(color, type);
|
||||
|
||||
finalColor ??= ParseHexColor(color, type);
|
||||
finalColor ??= FromRgb(color, type);
|
||||
|
||||
if (finalColor is not null) return finalColor;
|
||||
|
||||
throw new NotSupportedException($"Color can not be parsed. {color}");
|
||||
}
|
||||
|
||||
private static IColor? ParseHexColor(string color, ColorType colorType)
|
||||
private IColor? FromRgb(string color, ColorType type)
|
||||
{
|
||||
if (!color.StartsWith("#")) return null;
|
||||
if (color.Length == 4)
|
||||
if (ParseHexColor(color) is var (r, g, b))
|
||||
{
|
||||
var r = ColorCharToColorByte(color[1]);
|
||||
var g = ColorCharToColorByte(color[2]);
|
||||
var b = ColorCharToColorByte(color[3]);
|
||||
|
||||
r += (byte) (r << 4);
|
||||
g += (byte) (g << 4);
|
||||
b += (byte) (b << 4);
|
||||
|
||||
return new ColorRgb(r, g, b, colorType);
|
||||
return new ColorRgb(r, g, b, type);
|
||||
}
|
||||
|
||||
if (color.Length == 7)
|
||||
{
|
||||
var r = (byte) (ColorCharToColorByte(color[1]) << 4 | ColorCharToColorByte(color[2]));
|
||||
var g = (byte) (ColorCharToColorByte(color[3]) << 4 | ColorCharToColorByte(color[4]));
|
||||
var b = (byte) (ColorCharToColorByte(color[5]) << 4 | ColorCharToColorByte(color[6]));
|
||||
|
||||
return new ColorRgb(r, g, b, colorType);
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new NotSupportedException($"Hex color can not be parsed. {color}");
|
||||
}
|
||||
|
||||
private static byte ColorCharToColorByte(char color) =>
|
||||
color switch
|
||||
{
|
||||
>= '0' and <= '9' => (byte) (color - '0'),
|
||||
>= 'A' and <= 'F' => (byte) (color - 'A' + 10),
|
||||
>= 'a' and <= 'f' => (byte) (color - 'a' + 10),
|
||||
_ => throw new NotSupportedException($"Hex color can not be parsed. {color}")
|
||||
};
|
||||
public override IColor FromRgb(Rgb rgb, ColorType type) => new ColorRgb(rgb.R, rgb.G, rgb.B, type);
|
||||
|
||||
public override IColor BlackForeground { get; } = new Color256(0, ColorType.Foreground);
|
||||
public override IColor BlueForeground { get; } = new Color256(12, ColorType.Foreground);
|
||||
|
||||
@@ -3,6 +3,44 @@
|
||||
public abstract class ColorProviderBase : IColorProvider
|
||||
{
|
||||
public abstract IColor Parse(string color, ColorType type);
|
||||
public abstract IColor FromRgb(Rgb rgb, ColorType type);
|
||||
|
||||
protected static Rgb? ParseHexColor(string color)
|
||||
{
|
||||
if (!color.StartsWith("#")) return null;
|
||||
if (color.Length == 4)
|
||||
{
|
||||
var r = ColorCharToColorByte(color[1]);
|
||||
var g = ColorCharToColorByte(color[2]);
|
||||
var b = ColorCharToColorByte(color[3]);
|
||||
|
||||
r += (byte) (r << 4);
|
||||
g += (byte) (g << 4);
|
||||
b += (byte) (b << 4);
|
||||
|
||||
return new(r, g, b);
|
||||
}
|
||||
|
||||
if (color.Length == 7)
|
||||
{
|
||||
var r = (byte) (ColorCharToColorByte(color[1]) << 4 | ColorCharToColorByte(color[2]));
|
||||
var g = (byte) (ColorCharToColorByte(color[3]) << 4 | ColorCharToColorByte(color[4]));
|
||||
var b = (byte) (ColorCharToColorByte(color[5]) << 4 | ColorCharToColorByte(color[6]));
|
||||
|
||||
return new(r, g, b);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static byte ColorCharToColorByte(char color) =>
|
||||
color switch
|
||||
{
|
||||
>= '0' and <= '9' => (byte) (color - '0'),
|
||||
>= 'A' and <= 'F' => (byte) (color - 'A' + 10),
|
||||
>= 'a' and <= 'f' => (byte) (color - 'a' + 10),
|
||||
_ => throw new NotSupportedException($"Hex color can not be parsed. {color}")
|
||||
};
|
||||
|
||||
protected IColor? ParseInternal(string color, ColorType type)
|
||||
=> (color.ToLower(), type) switch
|
||||
|
||||
@@ -7,8 +7,8 @@ public readonly record struct ColorRgb(byte R, byte G, byte B, ColorType Type) :
|
||||
public string ToConsoleColor()
|
||||
=> Type switch
|
||||
{
|
||||
ColorType.Foreground => $"\x1b[38;2;{R};{G};{B};m",
|
||||
ColorType.Background => $"\x1b[48;2;{R};{G};{B};m",
|
||||
ColorType.Foreground => $"\x1b[38;2;{R};{G};{B}m",
|
||||
ColorType.Background => $"\x1b[48;2;{R};{G};{B}m",
|
||||
_ => throw new InvalidEnumArgumentException(nameof(Type), (int) Type, typeof(ColorType))
|
||||
};
|
||||
public IColor AsForeground() => this with {Type = ColorType.Foreground};
|
||||
|
||||
@@ -1,48 +1,143 @@
|
||||
namespace TerminalUI.Color;
|
||||
// ReSharper disable InconsistentNaming
|
||||
namespace TerminalUI.Color;
|
||||
|
||||
public class ConsoleColorProvider : ColorProviderBase
|
||||
{
|
||||
private static readonly List<(Rgb, IColor)> Foregrounds;
|
||||
private static readonly List<(Rgb, IColor)> Backgrounds;
|
||||
|
||||
static ConsoleColorProvider()
|
||||
{
|
||||
Foregrounds = new List<(Rgb, IColor)>
|
||||
{
|
||||
(new Rgb(0, 0, 0), _blackForeground),
|
||||
(new Rgb(0, 0, 128), _darkBlueForeground),
|
||||
(new Rgb(0, 128, 0), _darkGreenForeground),
|
||||
(new Rgb(0, 128, 128), _darkCyanForeground),
|
||||
(new Rgb(128, 0, 0), _darkRedForeground),
|
||||
(new Rgb(128, 0, 128), _darkMagentaForeground),
|
||||
(new Rgb(128, 128, 0), _darkYellowForeground),
|
||||
(new Rgb(192, 192, 192), _grayForeground),
|
||||
(new Rgb(128, 128, 128), _darkGrayForeground),
|
||||
(new Rgb(0, 0, 255), _blueForeground),
|
||||
(new Rgb(0, 255, 0), _greenForeground),
|
||||
(new Rgb(0, 255, 255), _cyanForeground),
|
||||
(new Rgb(255, 0, 0), _redForeground),
|
||||
(new Rgb(255, 0, 255), _magentaForeground),
|
||||
(new Rgb(255, 255, 0), _yellowForeground),
|
||||
(new Rgb(255, 255, 255), _whiteForeground),
|
||||
};
|
||||
|
||||
Backgrounds = new List<(Rgb, IColor)>
|
||||
{
|
||||
(new Rgb(0, 0, 0), _blackBackground),
|
||||
(new Rgb(0, 0, 128), _darkBlueBackground),
|
||||
(new Rgb(0, 128, 0), _darkGreenBackground),
|
||||
(new Rgb(0, 128, 128), _darkCyanBackground),
|
||||
(new Rgb(128, 0, 0), _darkRedBackground),
|
||||
(new Rgb(128, 0, 128), _darkMagentaBackground),
|
||||
(new Rgb(128, 128, 0), _darkYellowBackground),
|
||||
(new Rgb(192, 192, 192), _grayBackground),
|
||||
(new Rgb(128, 128, 128), _darkGrayBackground),
|
||||
(new Rgb(0, 0, 255), _blueBackground),
|
||||
(new Rgb(0, 255, 0), _greenBackground),
|
||||
(new Rgb(0, 255, 255), _cyanBackground),
|
||||
(new Rgb(255, 0, 0), _redBackground),
|
||||
(new Rgb(255, 0, 255), _magentaBackground),
|
||||
(new Rgb(255, 255, 0), _yellowBackground),
|
||||
(new Rgb(255, 255, 255), _whiteBackground),
|
||||
};
|
||||
}
|
||||
|
||||
public override IColor Parse(string color, ColorType type)
|
||||
{
|
||||
var finalColor = ParseInternal(color, type);
|
||||
if (finalColor is not null) return finalColor;
|
||||
|
||||
//TODO get closest color
|
||||
var rgb = ParseHexColor(color);
|
||||
|
||||
if (rgb is null)
|
||||
{
|
||||
throw new NotSupportedException($"Color can not be parsed. {color}");
|
||||
}
|
||||
|
||||
public override IColor BlackForeground { get; } = new ConsoleColor(System.ConsoleColor.Black, ColorType.Foreground);
|
||||
public override IColor BlueForeground { get; } = new ConsoleColor(System.ConsoleColor.Blue, ColorType.Foreground);
|
||||
public override IColor CyanForeground { get; } = new ConsoleColor(System.ConsoleColor.Cyan, ColorType.Foreground);
|
||||
public override IColor DarkBlueForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkBlue, ColorType.Foreground);
|
||||
public override IColor DarkCyanForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkCyan, ColorType.Foreground);
|
||||
public override IColor DarkGrayForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkGray, ColorType.Foreground);
|
||||
public override IColor DarkGreenForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkGreen, ColorType.Foreground);
|
||||
public override IColor DarkMagentaForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkMagenta, ColorType.Foreground);
|
||||
public override IColor DarkRedForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkRed, ColorType.Foreground);
|
||||
public override IColor DarkYellowForeground { get; } = new ConsoleColor(System.ConsoleColor.DarkYellow, ColorType.Foreground);
|
||||
public override IColor GrayForeground { get; } = new ConsoleColor(System.ConsoleColor.Gray, ColorType.Foreground);
|
||||
public override IColor GreenForeground { get; } = new ConsoleColor(System.ConsoleColor.Green, ColorType.Foreground);
|
||||
public override IColor MagentaForeground { get; } = new ConsoleColor(System.ConsoleColor.Magenta, ColorType.Foreground);
|
||||
public override IColor RedForeground { get; } = new ConsoleColor(System.ConsoleColor.Red, ColorType.Foreground);
|
||||
public override IColor WhiteForeground { get; } = new ConsoleColor(System.ConsoleColor.White, ColorType.Foreground);
|
||||
public override IColor YellowForeground { get; } = new ConsoleColor(System.ConsoleColor.Yellow, ColorType.Foreground);
|
||||
return FromRgb(rgb.Value, type);
|
||||
}
|
||||
|
||||
public override IColor BlackBackground => new ConsoleColor(System.ConsoleColor.Black, ColorType.Background);
|
||||
public override IColor BlueBackground => new ConsoleColor(System.ConsoleColor.Blue, ColorType.Background);
|
||||
public override IColor CyanBackground => new ConsoleColor(System.ConsoleColor.Cyan, ColorType.Background);
|
||||
public override IColor DarkBlueBackground => new ConsoleColor(System.ConsoleColor.DarkBlue, ColorType.Background);
|
||||
public override IColor DarkCyanBackground => new ConsoleColor(System.ConsoleColor.DarkCyan, ColorType.Background);
|
||||
public override IColor DarkGrayBackground => new ConsoleColor(System.ConsoleColor.DarkGray, ColorType.Background);
|
||||
public override IColor DarkGreenBackground => new ConsoleColor(System.ConsoleColor.DarkGreen, ColorType.Background);
|
||||
public override IColor DarkMagentaBackground => new ConsoleColor(System.ConsoleColor.DarkMagenta, ColorType.Background);
|
||||
public override IColor DarkRedBackground => new ConsoleColor(System.ConsoleColor.DarkRed, ColorType.Background);
|
||||
public override IColor DarkYellowBackground => new ConsoleColor(System.ConsoleColor.DarkYellow, ColorType.Background);
|
||||
public override IColor GrayBackground => new ConsoleColor(System.ConsoleColor.Gray, ColorType.Background);
|
||||
public override IColor GreenBackground => new ConsoleColor(System.ConsoleColor.Green, ColorType.Background);
|
||||
public override IColor MagentaBackground => new ConsoleColor(System.ConsoleColor.Magenta, ColorType.Background);
|
||||
public override IColor RedBackground => new ConsoleColor(System.ConsoleColor.Red, ColorType.Background);
|
||||
public override IColor WhiteBackground => new ConsoleColor(System.ConsoleColor.White, ColorType.Background);
|
||||
public override IColor YellowBackground => new ConsoleColor(System.ConsoleColor.Yellow, ColorType.Background);
|
||||
public override IColor FromRgb(Rgb rgb, ColorType type)
|
||||
=> type == ColorType.Background
|
||||
? ApproximateColor(rgb, Backgrounds)
|
||||
: ApproximateColor(rgb, Foregrounds);
|
||||
|
||||
protected IColor ApproximateColor(Rgb rgb, IEnumerable<(Rgb, IColor)> colors)
|
||||
=> colors.MinBy(c => c.Item1 - rgb).Item2;
|
||||
|
||||
public override IColor BlackForeground => _blackForeground;
|
||||
public override IColor BlueForeground => _blueForeground;
|
||||
public override IColor CyanForeground => _cyanForeground;
|
||||
public override IColor DarkBlueForeground => _darkBlueForeground;
|
||||
public override IColor DarkCyanForeground => _darkCyanForeground;
|
||||
public override IColor DarkGrayForeground => _darkGrayForeground;
|
||||
public override IColor DarkGreenForeground => _darkGreenForeground;
|
||||
public override IColor DarkMagentaForeground => _darkMagentaForeground;
|
||||
public override IColor DarkRedForeground => _darkRedForeground;
|
||||
public override IColor DarkYellowForeground => _darkYellowForeground;
|
||||
public override IColor GrayForeground => _grayForeground;
|
||||
public override IColor GreenForeground => _greenForeground;
|
||||
public override IColor MagentaForeground => _magentaForeground;
|
||||
public override IColor RedForeground => _redForeground;
|
||||
public override IColor WhiteForeground => _whiteForeground;
|
||||
public override IColor YellowForeground => _yellowForeground;
|
||||
|
||||
public override IColor BlackBackground => _blackBackground;
|
||||
public override IColor BlueBackground => _blueBackground;
|
||||
public override IColor CyanBackground => _cyanBackground;
|
||||
public override IColor DarkBlueBackground => _darkBlueBackground;
|
||||
public override IColor DarkCyanBackground => _darkCyanBackground;
|
||||
public override IColor DarkGrayBackground => _darkGrayBackground;
|
||||
public override IColor DarkGreenBackground => _darkGreenBackground;
|
||||
public override IColor DarkMagentaBackground => _darkMagentaBackground;
|
||||
public override IColor DarkRedBackground => _darkRedBackground;
|
||||
public override IColor DarkYellowBackground => _darkYellowBackground;
|
||||
public override IColor GrayBackground => _grayBackground;
|
||||
public override IColor GreenBackground => _greenBackground;
|
||||
public override IColor MagentaBackground => _magentaBackground;
|
||||
public override IColor RedBackground => _redBackground;
|
||||
public override IColor WhiteBackground => _whiteBackground;
|
||||
public override IColor YellowBackground => _yellowBackground;
|
||||
|
||||
private static readonly IColor _blackForeground = new ConsoleColor(System.ConsoleColor.Black, ColorType.Foreground);
|
||||
private static readonly IColor _blueForeground = new ConsoleColor(System.ConsoleColor.Blue, ColorType.Foreground);
|
||||
private static readonly IColor _cyanForeground = new ConsoleColor(System.ConsoleColor.Cyan, ColorType.Foreground);
|
||||
private static readonly IColor _darkBlueForeground = new ConsoleColor(System.ConsoleColor.DarkBlue, ColorType.Foreground);
|
||||
private static readonly IColor _darkCyanForeground = new ConsoleColor(System.ConsoleColor.DarkCyan, ColorType.Foreground);
|
||||
private static readonly IColor _darkGrayForeground = new ConsoleColor(System.ConsoleColor.DarkGray, ColorType.Foreground);
|
||||
private static readonly IColor _darkGreenForeground = new ConsoleColor(System.ConsoleColor.DarkGreen, ColorType.Foreground);
|
||||
private static readonly IColor _darkMagentaForeground = new ConsoleColor(System.ConsoleColor.DarkMagenta, ColorType.Foreground);
|
||||
private static readonly IColor _darkRedForeground = new ConsoleColor(System.ConsoleColor.DarkRed, ColorType.Foreground);
|
||||
private static readonly IColor _darkYellowForeground = new ConsoleColor(System.ConsoleColor.DarkYellow, ColorType.Foreground);
|
||||
private static readonly IColor _grayForeground = new ConsoleColor(System.ConsoleColor.Gray, ColorType.Foreground);
|
||||
private static readonly IColor _greenForeground = new ConsoleColor(System.ConsoleColor.Green, ColorType.Foreground);
|
||||
private static readonly IColor _magentaForeground = new ConsoleColor(System.ConsoleColor.Magenta, ColorType.Foreground);
|
||||
private static readonly IColor _redForeground = new ConsoleColor(System.ConsoleColor.Red, ColorType.Foreground);
|
||||
private static readonly IColor _whiteForeground = new ConsoleColor(System.ConsoleColor.White, ColorType.Foreground);
|
||||
private static readonly IColor _yellowForeground = new ConsoleColor(System.ConsoleColor.Yellow, ColorType.Foreground);
|
||||
|
||||
private static readonly IColor _blackBackground = new ConsoleColor(System.ConsoleColor.Black, ColorType.Background);
|
||||
private static readonly IColor _blueBackground = new ConsoleColor(System.ConsoleColor.Blue, ColorType.Background);
|
||||
private static readonly IColor _cyanBackground = new ConsoleColor(System.ConsoleColor.Cyan, ColorType.Background);
|
||||
private static readonly IColor _darkBlueBackground = new ConsoleColor(System.ConsoleColor.DarkBlue, ColorType.Background);
|
||||
private static readonly IColor _darkCyanBackground = new ConsoleColor(System.ConsoleColor.DarkCyan, ColorType.Background);
|
||||
private static readonly IColor _darkGrayBackground = new ConsoleColor(System.ConsoleColor.DarkGray, ColorType.Background);
|
||||
private static readonly IColor _darkGreenBackground = new ConsoleColor(System.ConsoleColor.DarkGreen, ColorType.Background);
|
||||
private static readonly IColor _darkMagentaBackground = new ConsoleColor(System.ConsoleColor.DarkMagenta, ColorType.Background);
|
||||
private static readonly IColor _darkRedBackground = new ConsoleColor(System.ConsoleColor.DarkRed, ColorType.Background);
|
||||
private static readonly IColor _darkYellowBackground = new ConsoleColor(System.ConsoleColor.DarkYellow, ColorType.Background);
|
||||
private static readonly IColor _grayBackground = new ConsoleColor(System.ConsoleColor.Gray, ColorType.Background);
|
||||
private static readonly IColor _greenBackground = new ConsoleColor(System.ConsoleColor.Green, ColorType.Background);
|
||||
private static readonly IColor _magentaBackground = new ConsoleColor(System.ConsoleColor.Magenta, ColorType.Background);
|
||||
private static readonly IColor _redBackground = new ConsoleColor(System.ConsoleColor.Red, ColorType.Background);
|
||||
private static readonly IColor _whiteBackground = new ConsoleColor(System.ConsoleColor.White, ColorType.Background);
|
||||
private static readonly IColor _yellowBackground = new ConsoleColor(System.ConsoleColor.Yellow, ColorType.Background);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
public interface IColorProvider
|
||||
{
|
||||
IColor Parse(string color, ColorType type);
|
||||
IColor FromRgb(Rgb rgb, ColorType type);
|
||||
|
||||
IColor BlackForeground { get; }
|
||||
IColor BlueForeground { get; }
|
||||
|
||||
33
src/Library/TerminalUI/Color/Rgb.cs
Normal file
33
src/Library/TerminalUI/Color/Rgb.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace TerminalUI.Color;
|
||||
|
||||
[DebuggerDisplay("R = {R}, G = {G}, B = {B}")]
|
||||
public readonly struct Rgb
|
||||
{
|
||||
public readonly byte R;
|
||||
public readonly byte G;
|
||||
public readonly byte B;
|
||||
|
||||
public Rgb(byte r, byte g, byte b)
|
||||
{
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
}
|
||||
|
||||
public static double operator -(Rgb left, Rgb right)
|
||||
{
|
||||
var r = Math.Abs(left.R - right.R);
|
||||
var g = Math.Abs(left.G - right.G);
|
||||
var b = Math.Abs(left.B - right.B);
|
||||
return (double)(r + g + b) / 3;
|
||||
}
|
||||
|
||||
public void Deconstruct(out byte r, out byte g, out byte b)
|
||||
{
|
||||
r = R;
|
||||
g = G;
|
||||
b = B;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public sealed class XTermDriver : DotnetDriver
|
||||
public override void ResetStyle()
|
||||
{
|
||||
Write("\x1b[0m");
|
||||
base.ResetStyle();
|
||||
}
|
||||
|
||||
public override void SetBackgroundColor(IColor background)
|
||||
|
||||
@@ -127,11 +127,18 @@ public sealed class Grid<T> : ChildCollectionView<Grid<T>, T>, IVisibilityChange
|
||||
|
||||
protected override Size CalculateSize()
|
||||
{
|
||||
return WithCalculatedSize(
|
||||
if (Width.HasValue && Height.HasValue)
|
||||
{
|
||||
return new Size(Width.Value, Height.Value);
|
||||
}
|
||||
|
||||
var size = WithCalculatedSize(
|
||||
RenderContext.Empty,
|
||||
new Option<Size>(new Size(0, 0), false),
|
||||
CalculateSizeInternal);
|
||||
|
||||
return new Size(Width ?? size.Width, Height ?? size.Height);
|
||||
|
||||
Size CalculateSizeInternal(in RenderContext _, ReadOnlySpan<int> columnWidths, ReadOnlySpan<int> rowHeights)
|
||||
{
|
||||
var width = 0;
|
||||
@@ -153,11 +160,14 @@ public sealed class Grid<T> : ChildCollectionView<Grid<T>, T>, IVisibilityChange
|
||||
|
||||
protected override bool DefaultRenderer(in RenderContext renderContext, Position position, Size size)
|
||||
{
|
||||
if (size.Width == 0 || size.Height == 0) return false;
|
||||
var width = Width ?? size.Width;
|
||||
var height = Height ?? size.Height;
|
||||
|
||||
if (width == 0 || height == 0) return false;
|
||||
|
||||
return WithCalculatedSize(
|
||||
renderContext,
|
||||
new Option<Size>(size, true),
|
||||
new Option<Size>(new Size(width, height), true),
|
||||
DefaultRendererInternal
|
||||
);
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ public sealed partial class Rectangle<T> : View<Rectangle<T>, T>, IDisplayView
|
||||
protected override bool DefaultRenderer(in RenderContext renderContext, Position position, Size size)
|
||||
{
|
||||
var fillColor = Fill ?? Background ?? renderContext.Background;
|
||||
var renderState = new RenderState(position, size, fillColor);
|
||||
var renderSize = new Size(Width ?? size.Width, Height ?? size.Height);
|
||||
var renderState = new RenderState(position, renderSize, fillColor);
|
||||
var skipRender = !renderContext.ForceRerender && !NeedsRerender(renderState);
|
||||
_lastRenderState = renderState;
|
||||
|
||||
@@ -41,7 +42,7 @@ public sealed partial class Rectangle<T> : View<Rectangle<T>, T>, IDisplayView
|
||||
RenderEmpty(
|
||||
renderContext,
|
||||
position,
|
||||
size,
|
||||
renderSize,
|
||||
skipRender,
|
||||
false
|
||||
);
|
||||
|
||||
@@ -146,8 +146,8 @@ public abstract partial class View<TConcrete, T> : IView<T> where TConcrete : Vi
|
||||
|
||||
if (!IsVisible) return false;
|
||||
|
||||
ActualWidth = size.Width;
|
||||
ActualHeight = size.Height;
|
||||
ActualWidth = Width ?? size.Width;
|
||||
ActualHeight = Height ?? size.Height;
|
||||
|
||||
if (RenderMethod is null)
|
||||
{
|
||||
@@ -167,10 +167,14 @@ public abstract partial class View<TConcrete, T> : IView<T> where TConcrete : Vi
|
||||
);
|
||||
|
||||
size = new Size(
|
||||
size.Width - Margin.Left - Margin.Right,
|
||||
size.Height - Margin.Top - Margin.Bottom
|
||||
ActualWidth - Margin.Left - Margin.Right,
|
||||
ActualHeight - Margin.Top - Margin.Bottom
|
||||
);
|
||||
}
|
||||
else if (Width.HasValue || Height.HasValue)
|
||||
{
|
||||
size = new Size(ActualWidth, ActualHeight);
|
||||
}
|
||||
|
||||
bool renderResult;
|
||||
if (Background != null || Foreground != null)
|
||||
|
||||
@@ -31,6 +31,8 @@ public class BinaryTracker : ExpressionTrackerBase
|
||||
ExpressionType.GreaterThanOrEqual => (v1, v2) => Comparer.Default.Compare(v1, v2) >= 0,
|
||||
ExpressionType.LessThan => (v1, v2) => Comparer.Default.Compare(v1, v2) < 0,
|
||||
ExpressionType.LessThanOrEqual => (v1, v2) => Comparer.Default.Compare(v1, v2) <= 0,
|
||||
ExpressionType.AndAlso => (v1, v2) => v1 is true && v2 is true,
|
||||
ExpressionType.OrElse => (v1, v2) => v1 is true || v2 is true,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace TerminalUI.ExpressionTrackers;
|
||||
|
||||
public class TypeBinaryTracker : ExpressionTrackerBase
|
||||
{
|
||||
private readonly IExpressionTracker _childExpressionTracker;
|
||||
private readonly Func<object?, bool> _computer;
|
||||
|
||||
public TypeBinaryTracker(TypeBinaryExpression typeBinaryExpression, IExpressionTracker childExpressionTracker)
|
||||
{
|
||||
_childExpressionTracker = childExpressionTracker;
|
||||
ArgumentNullException.ThrowIfNull(childExpressionTracker);
|
||||
|
||||
SubscribeToValueChanges = false;
|
||||
SubscribeToTracker(childExpressionTracker);
|
||||
|
||||
_computer = typeBinaryExpression.NodeType switch
|
||||
{
|
||||
ExpressionType.TypeIs => o => o is not null && typeBinaryExpression.TypeOperand.IsInstanceOfType(o),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
protected override object? ComputeValue()
|
||||
=> _computer(_childExpressionTracker.GetValue());
|
||||
}
|
||||
@@ -80,10 +80,11 @@ public abstract class PropertyTrackerBase<TSource, TExpressionResult>
|
||||
{
|
||||
return new ConstantTracker(constantExpression.Value);
|
||||
}
|
||||
/*else if (expression is not ConstantExpression)
|
||||
else if (expression is TypeBinaryExpression typeBinaryExpression)
|
||||
{
|
||||
Debug.Assert(false, "Unknown expression type " + expression.GetType());
|
||||
}*/
|
||||
var childExpression = FindReactiveProperties(typeBinaryExpression.Expression, parameters);
|
||||
return new TypeBinaryTracker(typeBinaryExpression, childExpression);
|
||||
}
|
||||
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ using DynamicData;
|
||||
using FileTime.Core.ContentAccess;
|
||||
using FileTime.Core.Enums;
|
||||
using FileTime.Core.Models;
|
||||
using FileTime.Core.Models.Extensions;
|
||||
using FileTime.Core.Timeline;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -356,11 +355,6 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
|
||||
var parent = new AbsolutePath(_timelessContentProvider, pointInTime, parentFullName,
|
||||
AbsolutePathType.Container);
|
||||
|
||||
var extensions = new ExtensionCollection()
|
||||
{
|
||||
new FileExtension(fileInfo.Length)
|
||||
};
|
||||
|
||||
return new Element(
|
||||
fileInfo.Name,
|
||||
fileInfo.Name,
|
||||
@@ -374,10 +368,11 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
|
||||
SupportsDelete.True,
|
||||
true,
|
||||
GetFileAttributes(fileInfo),
|
||||
fileInfo.Length,
|
||||
this,
|
||||
pointInTime,
|
||||
new ObservableCollection<Exception>(),
|
||||
extensions.AsReadOnly()
|
||||
new ExtensionCollection().AsReadOnly()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user