ConsoleUI container size text
This commit is contained in:
@@ -98,6 +98,8 @@ public class ContainerSizeSizeScanProvider : ContentProviderBase, IContainerSize
|
|||||||
public override bool CanHandlePath(NativePath path)
|
public override bool CanHandlePath(NativePath path)
|
||||||
=> path.Path.StartsWith(ContentProviderName);
|
=> path.Path.StartsWith(ContentProviderName);
|
||||||
|
|
||||||
|
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null;
|
||||||
|
|
||||||
public ISizeScanTask StartSizeScan(IContainer scanSizeOf)
|
public ISizeScanTask StartSizeScan(IContainer scanSizeOf)
|
||||||
{
|
{
|
||||||
var searchTask = _serviceProvider
|
var searchTask = _serviceProvider
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task InitAsync()
|
||||||
|
=> await LoadStatesAsync();
|
||||||
|
|
||||||
public Task ExitAsync(CancellationToken token = default)
|
public Task ExitAsync(CancellationToken token = default)
|
||||||
{
|
{
|
||||||
SaveStates(token);
|
SaveStates(token);
|
||||||
@@ -90,7 +93,20 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
|
|
||||||
async Task CreateEmptyTab()
|
async Task CreateEmptyTab()
|
||||||
{
|
{
|
||||||
var tab = await _serviceProvider.GetAsyncInitableResolver<IContainer>(_localContentProvider)
|
IContainer? currentDirectory = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
currentDirectory = await _localContentProvider.GetItemByNativePathAsync(
|
||||||
|
new NativePath(Environment.CurrentDirectory),
|
||||||
|
PointInTime.Present
|
||||||
|
) as IContainer;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
var tab = await _serviceProvider.GetAsyncInitableResolver<IContainer>(currentDirectory ?? _localContentProvider)
|
||||||
.GetRequiredServiceAsync<ITab>();
|
.GetRequiredServiceAsync<ITab>();
|
||||||
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
|
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
|
||||||
|
|
||||||
@@ -218,7 +234,4 @@ public class TabPersistenceService : ITabPersistenceService
|
|||||||
_appState.SelectedTab.Value?.TabNumber
|
_appState.SelectedTab.Value?.TabNumber
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InitAsync()
|
|
||||||
=> await LoadStatesAsync();
|
|
||||||
}
|
}
|
||||||
@@ -77,6 +77,7 @@ public class SearchContentProvider : ContentProviderBase, ISearchContentProvider
|
|||||||
=> Task.FromResult(null as byte[]);
|
=> Task.FromResult(null as byte[]);
|
||||||
|
|
||||||
public override bool CanHandlePath(NativePath path) => path.Path.StartsWith(ContentProviderName);
|
public override bool CanHandlePath(NativePath path) => path.Path.StartsWith(ContentProviderName);
|
||||||
|
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null;
|
||||||
|
|
||||||
public async Task<ISearchTask> StartSearchAsync(ISearchMatcher matcher, IContainer searchIn)
|
public async Task<ISearchTask> StartSearchAsync(ISearchMatcher matcher, IContainer searchIn)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using FileTime.App.CommandPalette.ViewModels;
|
using DeclarativeProperty;
|
||||||
|
using FileTime.App.CommandPalette.ViewModels;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
using FileTime.App.Core.ViewModels.Timeline;
|
using FileTime.App.Core.ViewModels.Timeline;
|
||||||
using FileTime.ConsoleUI.App.Services;
|
using FileTime.ConsoleUI.App.Services;
|
||||||
using FileTime.Core.Interactions;
|
using FileTime.Core.Interactions;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
namespace FileTime.ConsoleUI.App;
|
namespace FileTime.ConsoleUI.App;
|
||||||
|
|
||||||
@@ -15,5 +17,6 @@ public interface IRootViewModel
|
|||||||
ICommandPaletteViewModel CommandPalette { get; }
|
ICommandPaletteViewModel CommandPalette { get; }
|
||||||
IDialogService DialogService { get; }
|
IDialogService DialogService { get; }
|
||||||
ITimelineViewModel TimelineViewModel { get; }
|
ITimelineViewModel TimelineViewModel { get; }
|
||||||
|
IDeclarativeProperty<VolumeSizeInfo?> VolumeSizeInfo { get; }
|
||||||
event Action<IInputElement>? FocusReadInputElement;
|
event Action<IInputElement>? FocusReadInputElement;
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ public class MainWindow
|
|||||||
private Grid<IRootViewModel> MainContent() =>
|
private Grid<IRootViewModel> MainContent() =>
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
RowDefinitionsObject = "Auto * Auto Auto Auto",
|
RowDefinitionsObject = "Auto * Auto Auto Auto Auto",
|
||||||
ChildInitializer =
|
ChildInitializer =
|
||||||
{
|
{
|
||||||
new Grid<IRootViewModel>
|
new Grid<IRootViewModel>
|
||||||
@@ -176,6 +176,38 @@ public class MainWindow
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
_timeline.View().WithExtension(new GridPositionExtension(0, 4)),
|
_timeline.View().WithExtension(new GridPositionExtension(0, 4)),
|
||||||
|
new Grid<IRootViewModel>
|
||||||
|
{
|
||||||
|
ColumnDefinitionsObject = "* Auto",
|
||||||
|
Extensions =
|
||||||
|
{
|
||||||
|
new GridPositionExtension(0, 5)
|
||||||
|
},
|
||||||
|
ChildInitializer =
|
||||||
|
{
|
||||||
|
new TextBlock<IRootViewModel>
|
||||||
|
{
|
||||||
|
Extensions = {new GridPositionExtension(1, 0)}
|
||||||
|
}
|
||||||
|
.Setup(t =>
|
||||||
|
{
|
||||||
|
t.Bind(
|
||||||
|
t,
|
||||||
|
dc => dc.VolumeSizeInfo.Value,
|
||||||
|
t => t.IsVisible,
|
||||||
|
v => v is null ? false : v.HasValue
|
||||||
|
);
|
||||||
|
t.Bind(
|
||||||
|
t,
|
||||||
|
dc => dc.VolumeSizeInfo.Value,
|
||||||
|
tb => tb.Text,
|
||||||
|
v => v.HasValue
|
||||||
|
? $"{ByteSize.FromBytes(v.Value.FreeSize)} / {ByteSize.FromBytes(v.Value.TotalSize)} free"
|
||||||
|
: string.Empty
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using FileTime.App.CommandPalette.ViewModels;
|
using DeclarativeProperty;
|
||||||
|
using FileTime.App.CommandPalette.ViewModels;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
using FileTime.App.Core.ViewModels.Timeline;
|
using FileTime.App.Core.ViewModels.Timeline;
|
||||||
using FileTime.ConsoleUI.App.Services;
|
using FileTime.ConsoleUI.App.Services;
|
||||||
using FileTime.Core.Interactions;
|
using FileTime.Core.Interactions;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
namespace FileTime.ConsoleUI.App;
|
namespace FileTime.ConsoleUI.App;
|
||||||
|
|
||||||
@@ -15,6 +17,8 @@ public class RootViewModel : IRootViewModel
|
|||||||
public ICommandPaletteViewModel CommandPalette { get; }
|
public ICommandPaletteViewModel CommandPalette { get; }
|
||||||
public IDialogService DialogService { get; }
|
public IDialogService DialogService { get; }
|
||||||
public ITimelineViewModel TimelineViewModel { get; }
|
public ITimelineViewModel TimelineViewModel { get; }
|
||||||
|
public IDeclarativeProperty<VolumeSizeInfo?> VolumeSizeInfo { get;}
|
||||||
|
|
||||||
public event Action<IInputElement>? FocusReadInputElement;
|
public event Action<IInputElement>? FocusReadInputElement;
|
||||||
|
|
||||||
public RootViewModel(
|
public RootViewModel(
|
||||||
@@ -40,5 +44,10 @@ public class RootViewModel : IRootViewModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VolumeSizeInfo = appState.SelectedTab
|
||||||
|
.Map(t => t?.CurrentLocation)
|
||||||
|
.Switch()
|
||||||
|
.Map(l => l?.Provider.GetVolumeSizeInfo(l.FullName!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@ public record Theme(
|
|||||||
public static class DefaultThemes
|
public static class DefaultThemes
|
||||||
{
|
{
|
||||||
public static Theme Color256Theme => new(
|
public static Theme Color256Theme => new(
|
||||||
DefaultForegroundColor: Color256Colors.Foregrounds.Gray,
|
DefaultForegroundColor: null,
|
||||||
DefaultForegroundAccentColor: Color256Colors.Foregrounds.Red,
|
DefaultForegroundAccentColor: Color256Colors.Foregrounds.Red,
|
||||||
DefaultBackgroundColor: null,
|
DefaultBackgroundColor: null,
|
||||||
ElementColor: Color256Colors.Foregrounds.Gray,
|
ElementColor: Color256Colors.Foregrounds.Gray,
|
||||||
@@ -67,7 +67,7 @@ public static class DefaultThemes
|
|||||||
);
|
);
|
||||||
|
|
||||||
public static Theme ConsoleColorTheme => new(
|
public static Theme ConsoleColorTheme => new(
|
||||||
DefaultForegroundColor: ConsoleColors.Foregrounds.Gray,
|
DefaultForegroundColor: null,
|
||||||
DefaultForegroundAccentColor: ConsoleColors.Foregrounds.Red,
|
DefaultForegroundAccentColor: ConsoleColors.Foregrounds.Red,
|
||||||
DefaultBackgroundColor: null,
|
DefaultBackgroundColor: null,
|
||||||
ElementColor: ConsoleColors.Foregrounds.Gray,
|
ElementColor: ConsoleColors.Foregrounds.Gray,
|
||||||
|
|||||||
@@ -28,4 +28,5 @@ public interface IContentProvider : IContainer, IOnContainerEnter
|
|||||||
Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default);
|
Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default);
|
||||||
bool CanHandlePath(NativePath path);
|
bool CanHandlePath(NativePath path);
|
||||||
bool CanHandlePath(FullName path);
|
bool CanHandlePath(FullName path);
|
||||||
|
VolumeSizeInfo? GetVolumeSizeInfo(FullName path);
|
||||||
}
|
}
|
||||||
13
src/Core/FileTime.Core.Abstraction/Models/VolumeSizeInfo.cs
Normal file
13
src/Core/FileTime.Core.Abstraction/Models/VolumeSizeInfo.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
namespace FileTime.Core.Models;
|
||||||
|
|
||||||
|
public readonly struct VolumeSizeInfo
|
||||||
|
{
|
||||||
|
public readonly long TotalSize;
|
||||||
|
public readonly long FreeSize;
|
||||||
|
|
||||||
|
public VolumeSizeInfo(long totalSize, long freeSize)
|
||||||
|
{
|
||||||
|
TotalSize = totalSize;
|
||||||
|
FreeSize = freeSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,5 +90,7 @@ public abstract class ContentProviderBase : IContentProvider
|
|||||||
|
|
||||||
public abstract bool CanHandlePath(NativePath path);
|
public abstract bool CanHandlePath(NativePath path);
|
||||||
public bool CanHandlePath(FullName path) => CanHandlePath(GetNativePath(path));
|
public bool CanHandlePath(FullName path) => CanHandlePath(GetNativePath(path));
|
||||||
|
public abstract VolumeSizeInfo? GetVolumeSizeInfo(FullName path);
|
||||||
|
|
||||||
public IItem WithParent(AbsolutePath parent) => this;
|
public IItem WithParent(AbsolutePath parent) => this;
|
||||||
}
|
}
|
||||||
@@ -85,5 +85,7 @@ public class RootContentProvider : IRootContentProvider
|
|||||||
public bool CanHandlePath(NativePath path) => throw new NotImplementedException();
|
public bool CanHandlePath(NativePath path) => throw new NotImplementedException();
|
||||||
|
|
||||||
public bool CanHandlePath(FullName path) => throw new NotImplementedException();
|
public bool CanHandlePath(FullName path) => throw new NotImplementedException();
|
||||||
public IItem WithParent(AbsolutePath parent) => this;
|
public VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => null;
|
||||||
|
|
||||||
|
public IItem WithParent(AbsolutePath parent) => this;
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using FileTime.Core.Models;
|
|
||||||
|
|
||||||
namespace FileTime.GuiApp.App.Models;
|
|
||||||
|
|
||||||
public interface IHaveFullPath
|
|
||||||
{
|
|
||||||
FullName Path { get; }
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
using FileTime.GuiApp.App.Models;
|
using FileTime.GuiApp.App.Models;
|
||||||
|
using FileTime.Providers.Local;
|
||||||
|
|
||||||
namespace FileTime.GuiApp.App.ViewModels;
|
namespace FileTime.GuiApp.App.ViewModels;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using FileTime.GuiApp.App.Models;
|
|||||||
|
|
||||||
namespace FileTime.GuiApp.App.ViewModels;
|
namespace FileTime.GuiApp.App.ViewModels;
|
||||||
|
|
||||||
public class PlaceInfo : IHaveFullPath
|
public class PlaceInfo
|
||||||
{
|
{
|
||||||
public IContainer Container { get; }
|
public IContainer Container { get; }
|
||||||
public string DisplayName { get; }
|
public string DisplayName { get; }
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
xmlns:interactions="using:FileTime.Core.Interactions"
|
xmlns:interactions="using:FileTime.Core.Interactions"
|
||||||
xmlns:itemPreview="clr-namespace:FileTime.App.Core.ViewModels.ItemPreview;assembly=FileTime.App.Core"
|
xmlns:itemPreview="clr-namespace:FileTime.App.Core.ViewModels.ItemPreview;assembly=FileTime.App.Core"
|
||||||
xmlns:local="using:FileTime.GuiApp.App.Views"
|
xmlns:local="using:FileTime.GuiApp.App.Views"
|
||||||
|
xmlns:local1="clr-namespace:FileTime.Providers.Local;assembly=FileTime.Providers.Local.Abstractions"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:sizePreview="clr-namespace:FileTime.App.ContainerSizeScanner;assembly=FileTime.App.ContainerSizeScanner"
|
xmlns:sizePreview="clr-namespace:FileTime.App.ContainerSizeScanner;assembly=FileTime.App.ContainerSizeScanner"
|
||||||
xmlns:vm="using:FileTime.GuiApp.App.ViewModels"
|
xmlns:vm="using:FileTime.GuiApp.App.ViewModels"
|
||||||
@@ -108,7 +109,7 @@
|
|||||||
|
|
||||||
<ItemsRepeater Grid.Row="1" ItemsSource="{Binding AppState.RootDriveInfos}">
|
<ItemsRepeater Grid.Row="1" ItemsSource="{Binding AppState.RootDriveInfos}">
|
||||||
<ItemsRepeater.ItemTemplate>
|
<ItemsRepeater.ItemTemplate>
|
||||||
<DataTemplate x:DataType="vm:RootDriveInfo">
|
<DataTemplate x:DataType="local1:RootDriveInfo">
|
||||||
<Grid
|
<Grid
|
||||||
Classes="SidebarContainerPresenter"
|
Classes="SidebarContainerPresenter"
|
||||||
Cursor="Hand"
|
Cursor="Hand"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using FileTime.Core.Models;
|
|||||||
using FileTime.GuiApp.App.Models;
|
using FileTime.GuiApp.App.Models;
|
||||||
using FileTime.GuiApp.App.Services;
|
using FileTime.GuiApp.App.Services;
|
||||||
using FileTime.GuiApp.App.ViewModels;
|
using FileTime.GuiApp.App.ViewModels;
|
||||||
|
using FileTime.Providers.Local;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -117,14 +118,18 @@ public partial class MainWindow : Window, IUiAccessor
|
|||||||
&& sender is StyledElement control)
|
&& sender is StyledElement control)
|
||||||
{
|
{
|
||||||
FullName? path = null;
|
FullName? path = null;
|
||||||
if (control.DataContext is IHaveFullPath {Path: { }} hasFullPath)
|
if (control.DataContext is FullName p)
|
||||||
{
|
|
||||||
path = hasFullPath.Path;
|
|
||||||
}
|
|
||||||
else if (control.DataContext is FullName p)
|
|
||||||
{
|
{
|
||||||
path = p;
|
path = p;
|
||||||
}
|
}
|
||||||
|
else if (control.DataContext is RootDriveInfo {Path: { } rootDriveInfoPath})
|
||||||
|
{
|
||||||
|
path = rootDriveInfoPath;
|
||||||
|
}
|
||||||
|
else if (control.DataContext is PlaceInfo {Path: { } placeInfoPath})
|
||||||
|
{
|
||||||
|
path = placeInfoPath;
|
||||||
|
}
|
||||||
/*else if (control.DataContext is IElement element && element.GetParent() is IContainer parentContainer)
|
/*else if (control.DataContext is IElement element && element.GetParent() is IContainer parentContainer)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using FileTime.App.Core.ViewModels;
|
|||||||
using FileTime.App.Core.ViewModels.Timeline;
|
using FileTime.App.Core.ViewModels.Timeline;
|
||||||
using FileTime.GuiApp.App.Models;
|
using FileTime.GuiApp.App.Models;
|
||||||
using FileTime.GuiApp.App.ViewModels;
|
using FileTime.GuiApp.App.ViewModels;
|
||||||
|
using FileTime.Providers.Local;
|
||||||
using MvvmGen;
|
using MvvmGen;
|
||||||
using PropertyChanged.SourceGenerator;
|
using PropertyChanged.SourceGenerator;
|
||||||
|
|
||||||
@@ -16,18 +17,19 @@ public partial class GuiAppState : AppStateBase, IGuiAppState, IDisposable
|
|||||||
{
|
{
|
||||||
private readonly BehaviorSubject<GuiPanel> _activePanel = new(GuiPanel.FileBrowser);
|
private readonly BehaviorSubject<GuiPanel> _activePanel = new(GuiPanel.FileBrowser);
|
||||||
|
|
||||||
public GuiAppState()
|
[Notify] private ObservableCollection<RootDriveInfo> _rootDriveInfos;
|
||||||
{
|
|
||||||
ActivePanel = _activePanel.AsObservable();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Notify] private ObservableCollection<RootDriveInfo> _rootDriveInfos = new();
|
|
||||||
|
|
||||||
[Notify] private IReadOnlyList<PlaceInfo> _places = new List<PlaceInfo>();
|
[Notify] private IReadOnlyList<PlaceInfo> _places = new List<PlaceInfo>();
|
||||||
public ObservableCollection<string> PopupTexts { get; } = new();
|
public ObservableCollection<string> PopupTexts { get; } = new();
|
||||||
|
|
||||||
public IObservable<GuiPanel> ActivePanel { get; }
|
public IObservable<GuiPanel> ActivePanel { get; }
|
||||||
|
|
||||||
|
public GuiAppState(IRootDriveInfoService rootDriveInfoService)
|
||||||
|
{
|
||||||
|
ActivePanel = _activePanel.AsObservable();
|
||||||
|
_rootDriveInfos = rootDriveInfoService.RootDriveInfos;
|
||||||
|
}
|
||||||
|
|
||||||
public void SetActivePanel(GuiPanel newPanel)
|
public void SetActivePanel(GuiPanel newPanel)
|
||||||
=> _activePanel.OnNext(newPanel);
|
=> _activePanel.OnNext(newPanel);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using FileTime.GuiApp.App.IconProviders;
|
|||||||
using FileTime.GuiApp.App.Logging;
|
using FileTime.GuiApp.App.Logging;
|
||||||
using FileTime.GuiApp.App.Services;
|
using FileTime.GuiApp.App.Services;
|
||||||
using FileTime.GuiApp.App.ViewModels;
|
using FileTime.GuiApp.App.ViewModels;
|
||||||
|
using FileTime.Providers.Local;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|||||||
@@ -214,7 +214,6 @@ public sealed class Grid<T> : ChildContainerView<Grid<T>, T>, IVisibilityChangeH
|
|||||||
int row,
|
int row,
|
||||||
IReadOnlyList<IView> forceRerenderChildren)
|
IReadOnlyList<IView> forceRerenderChildren)
|
||||||
{
|
{
|
||||||
if (!viewsByPosition.TryGetValue((column, row), out var children)) return false;
|
|
||||||
|
|
||||||
var width = columnWidths[column];
|
var width = columnWidths[column];
|
||||||
var height = rowHeights[row];
|
var height = rowHeights[row];
|
||||||
@@ -239,6 +238,12 @@ public sealed class Grid<T> : ChildContainerView<Grid<T>, T>, IVisibilityChangeH
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (renderSize.Width == 0 || renderSize.Height == 0) return false;
|
if (renderSize.Width == 0 || renderSize.Height == 0) return false;
|
||||||
|
|
||||||
|
if (!viewsByPosition.TryGetValue((column, row), out var children))
|
||||||
|
{
|
||||||
|
RenderEmpty(context, renderPosition, renderSize);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var needsRerender = children.Any(forceRerenderChildren.Contains);
|
var needsRerender = children.Any(forceRerenderChildren.Contains);
|
||||||
if (needsRerender)
|
if (needsRerender)
|
||||||
@@ -270,7 +275,7 @@ public sealed class Grid<T> : ChildContainerView<Grid<T>, T>, IVisibilityChangeH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return needsRerender;
|
||||||
|
|
||||||
static Position GetRenderPosition(
|
static Position GetRenderPosition(
|
||||||
Position gridPosition,
|
Position gridPosition,
|
||||||
|
|||||||
@@ -99,6 +99,35 @@ public sealed partial class StackPanel<T> : ChildContainerView<StackPanel<T>, T>
|
|||||||
: childSize.Width;
|
: childSize.Width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Orientation == Orientation.Horizontal)
|
||||||
|
{
|
||||||
|
var leftWidth = size.Width - delta;
|
||||||
|
Span<char> text = stackalloc char[leftWidth];
|
||||||
|
text.Fill(ApplicationContext!.EmptyCharacter);
|
||||||
|
|
||||||
|
SetColorsForDriver(renderContext);
|
||||||
|
RenderText(
|
||||||
|
text,
|
||||||
|
renderContext.ConsoleDriver,
|
||||||
|
position with {X = position.X + delta},
|
||||||
|
size with {Width = leftWidth}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var leftHeight = size.Height - delta;
|
||||||
|
Span<char> text = stackalloc char[size.Width];
|
||||||
|
text.Fill(ApplicationContext!.EmptyCharacter);
|
||||||
|
|
||||||
|
SetColorsForDriver(renderContext);
|
||||||
|
RenderText(
|
||||||
|
text,
|
||||||
|
renderContext.ConsoleDriver,
|
||||||
|
position with {Y = position.Y + delta},
|
||||||
|
size with {Height = leftHeight}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return neededRerender;
|
return neededRerender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,4 +15,11 @@
|
|||||||
<ProjectReference Include="..\..\AppCommon\FileTime.App.Core.Abstraction\FileTime.App.Core.Abstraction.csproj" />
|
<ProjectReference Include="..\..\AppCommon\FileTime.App.Core.Abstraction\FileTime.App.Core.Abstraction.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="PropertyChanged.SourceGenerator" Version="1.0.8">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
|
namespace FileTime.Providers.Local;
|
||||||
|
|
||||||
|
public interface IRootDriveInfoService
|
||||||
|
{
|
||||||
|
ObservableCollection<RootDriveInfo> RootDriveInfos { get; set; }
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.GuiApp.App.Models;
|
|
||||||
using PropertyChanged.SourceGenerator;
|
using PropertyChanged.SourceGenerator;
|
||||||
using IContainer = FileTime.Core.Models.IContainer;
|
using IContainer = FileTime.Core.Models.IContainer;
|
||||||
|
|
||||||
namespace FileTime.GuiApp.App.ViewModels;
|
namespace FileTime.Providers.Local;
|
||||||
|
|
||||||
public partial class RootDriveInfo : IHaveFullPath, INotifyPropertyChanged
|
public partial class RootDriveInfo
|
||||||
{
|
{
|
||||||
private readonly DriveInfo _driveInfo;
|
private readonly DriveInfo _driveInfo;
|
||||||
|
|
||||||
@@ -6,6 +6,7 @@ using FileTime.Core.Enums;
|
|||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.Core.Models.Extensions;
|
using FileTime.Core.Models.Extensions;
|
||||||
using FileTime.Core.Timeline;
|
using FileTime.Core.Timeline;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace FileTime.Providers.Local;
|
namespace FileTime.Providers.Local;
|
||||||
|
|
||||||
@@ -13,13 +14,18 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
|
|||||||
{
|
{
|
||||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||||
private readonly bool _isCaseInsensitive;
|
private readonly bool _isCaseInsensitive;
|
||||||
|
private readonly Lazy<ObservableCollection<RootDriveInfo>> _rootDriveInfos;
|
||||||
|
|
||||||
public LocalContentProvider(ITimelessContentProvider timelessContentProvider)
|
public LocalContentProvider(
|
||||||
|
ITimelessContentProvider timelessContentProvider,
|
||||||
|
IServiceProvider serviceProvider)
|
||||||
: base(LocalContentProviderConstants.ContentProviderId, timelessContentProvider)
|
: base(LocalContentProviderConstants.ContentProviderId, timelessContentProvider)
|
||||||
{
|
{
|
||||||
_timelessContentProvider = timelessContentProvider;
|
_timelessContentProvider = timelessContentProvider;
|
||||||
_isCaseInsensitive = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
_isCaseInsensitive = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
|
|
||||||
|
_rootDriveInfos = new Lazy<ObservableCollection<RootDriveInfo>>(() => serviceProvider.GetRequiredService<IRootDriveInfoService>().RootDriveInfos);
|
||||||
|
|
||||||
SupportsContentStreams = true;
|
SupportsContentStreams = true;
|
||||||
|
|
||||||
RefreshRootDirectories();
|
RefreshRootDirectories();
|
||||||
@@ -63,6 +69,16 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
|
|||||||
return rootDrive is not null;
|
return rootDrive is not null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path)
|
||||||
|
{
|
||||||
|
var rootDriveInfos = _rootDriveInfos.Value;
|
||||||
|
var rootDriveInfo = rootDriveInfos.FirstOrDefault(d => path.Path.StartsWith(d.Path.Path));
|
||||||
|
|
||||||
|
if(rootDriveInfo is null) return null;
|
||||||
|
|
||||||
|
return new VolumeSizeInfo(rootDriveInfo.Size, rootDriveInfo.Free);
|
||||||
|
}
|
||||||
|
|
||||||
public override Task<IItem> GetItemByNativePathAsync(NativePath nativePath,
|
public override Task<IItem> GetItemByNativePathAsync(NativePath nativePath,
|
||||||
PointInTime pointInTime,
|
PointInTime pointInTime,
|
||||||
bool forceResolve = false,
|
bool forceResolve = false,
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.GuiApp.App.ViewModels;
|
|
||||||
using FileTime.Providers.Local;
|
|
||||||
using ObservableComputations;
|
using ObservableComputations;
|
||||||
|
|
||||||
namespace FileTime.GuiApp.App.Services;
|
namespace FileTime.Providers.Local;
|
||||||
|
|
||||||
public class RootDriveInfoService : IExitHandler
|
public class RootDriveInfoService : IRootDriveInfoService, IExitHandler
|
||||||
{
|
{
|
||||||
private readonly ILocalContentProvider _localContentProvider;
|
private readonly ILocalContentProvider _localContentProvider;
|
||||||
private readonly List<DriveInfo> _rootDrives = new();
|
private readonly List<DriveInfo> _rootDrives = new();
|
||||||
private readonly OcConsumer _rootDriveInfosConsumer = new();
|
private readonly OcConsumer _rootDriveInfosConsumer = new();
|
||||||
|
|
||||||
public RootDriveInfoService(
|
public ObservableCollection<RootDriveInfo> RootDriveInfos { get; set; }
|
||||||
IGuiAppState guiAppState,
|
|
||||||
ILocalContentProvider localContentProvider)
|
public RootDriveInfoService(ILocalContentProvider localContentProvider)
|
||||||
{
|
{
|
||||||
_localContentProvider = localContentProvider;
|
_localContentProvider = localContentProvider;
|
||||||
InitRootDrives();
|
InitRootDrives();
|
||||||
@@ -31,11 +30,10 @@ public class RootDriveInfoService : IExitHandler
|
|||||||
|
|
||||||
rootDriveInfos.For(_rootDriveInfosConsumer);
|
rootDriveInfos.For(_rootDriveInfosConsumer);
|
||||||
|
|
||||||
guiAppState.RootDriveInfos = rootDriveInfos;
|
RootDriveInfos = rootDriveInfos;
|
||||||
|
|
||||||
void InitRootDrives()
|
void InitRootDrives()
|
||||||
{
|
{
|
||||||
var driveInfos = new List<RootDriveInfo>();
|
|
||||||
var drives = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
|
var drives = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
|
||||||
? DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.Fixed)
|
? DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.Fixed)
|
||||||
: DriveInfo.GetDrives().Where(d =>
|
: DriveInfo.GetDrives().Where(d =>
|
||||||
@@ -20,6 +20,7 @@ public static class Startup
|
|||||||
serviceCollection.TryAddSingleton<IContentReaderFactory<LocalContentProvider>>(sp => sp.GetRequiredService<IContentReaderFactory<ILocalContentProvider>>());
|
serviceCollection.TryAddSingleton<IContentReaderFactory<LocalContentProvider>>(sp => sp.GetRequiredService<IContentReaderFactory<ILocalContentProvider>>());
|
||||||
serviceCollection.TryAddSingleton<IContentWriterFactory<ILocalContentProvider>, LocalContentWriterFactory>();
|
serviceCollection.TryAddSingleton<IContentWriterFactory<ILocalContentProvider>, LocalContentWriterFactory>();
|
||||||
serviceCollection.TryAddSingleton<IContentWriterFactory<LocalContentProvider>>(sp => sp.GetRequiredService<IContentWriterFactory<ILocalContentProvider>>());
|
serviceCollection.TryAddSingleton<IContentWriterFactory<LocalContentProvider>>(sp => sp.GetRequiredService<IContentWriterFactory<ILocalContentProvider>>());
|
||||||
|
serviceCollection.TryAddSingleton<IRootDriveInfoService, RootDriveInfoService>();
|
||||||
return serviceCollection;
|
return serviceCollection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,4 +25,5 @@ public class RemoteContentProvider : ContentProviderBase, IRemoteContentProvider
|
|||||||
public override Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
public override Task<byte[]?> GetContentAsync(IElement element, int? maxLength = null, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||||
|
|
||||||
public override bool CanHandlePath(NativePath path) => throw new NotImplementedException();
|
public override bool CanHandlePath(NativePath path) => throw new NotImplementedException();
|
||||||
|
public override VolumeSizeInfo? GetVolumeSizeInfo(FullName path) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user