Show children
This commit is contained in:
@@ -12,7 +12,8 @@ namespace FileTime.App.Core.ViewModels
|
|||||||
IObservable<bool> IsSelected { get; }
|
IObservable<bool> IsSelected { get; }
|
||||||
IObservable<IContainer?> CurrentLocation { get; }
|
IObservable<IContainer?> CurrentLocation { get; }
|
||||||
IObservable<IItemViewModel?> CurrentSelectedItem { get; }
|
IObservable<IItemViewModel?> CurrentSelectedItem { get; }
|
||||||
IObservable<IEnumerable<IItemViewModel>> CurrentItems { get; }
|
IObservable<IReadOnlyList<IItemViewModel>> CurrentItems { get; }
|
||||||
IObservable<IEnumerable<FullName>> MarkedItems { get; }
|
IObservable<IEnumerable<FullName>> MarkedItems { get; }
|
||||||
|
IObservable<IReadOnlyList<IItemViewModel>?> SelectedsChildren { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Reactive.Linq;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.Extensions
|
||||||
|
{
|
||||||
|
public static class ObservableExtensions
|
||||||
|
{
|
||||||
|
public static IObservable<T> WhereNotNull<T>(this IObservable<T?> source) => source.Where(c => c != null)!;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="morelinq" Version="3.3.2" />
|
<PackageReference Include="morelinq" Version="3.3.2" />
|
||||||
<PackageReference Include="MvvmGen" Version="1.1.5" />
|
<PackageReference Include="MvvmGen" Version="1.1.5" />
|
||||||
|
<PackageReference Include="System.Interactive.Async" Version="6.0.1" />
|
||||||
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
<PackageReference Include="System.Reactive" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ namespace FileTime.App.Core.Services
|
|||||||
|
|
||||||
private async Task GoUp()
|
private async Task GoUp()
|
||||||
{
|
{
|
||||||
if (_currentLocation?.Parent is not IAbsolutePath parentPath || await parentPath.ResolveAsync() is not IContainer newContainer) return;
|
if (_currentLocation?.Parent is not IAbsolutePath parentPath || await parentPath.ResolveAsyncSafe() is not IContainer newContainer) return;
|
||||||
_selectedTab?.Tab?.SetCurrentLocation(newContainer);
|
_selectedTab?.Tab?.SetCurrentLocation(newContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Reactive.Subjects;
|
using System.Reactive.Subjects;
|
||||||
|
using FileTime.App.Core.Extensions;
|
||||||
using FileTime.App.Core.Models.Enums;
|
using FileTime.App.Core.Models.Enums;
|
||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
|
using FileTime.Core.Enums;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.Core.Services;
|
using FileTime.Core.Services;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
@@ -24,8 +26,9 @@ namespace FileTime.App.Core.ViewModels
|
|||||||
|
|
||||||
public IObservable<IContainer?> CurrentLocation { get; private set; } = null!;
|
public IObservable<IContainer?> CurrentLocation { get; private set; } = null!;
|
||||||
public IObservable<IItemViewModel?> CurrentSelectedItem { get; private set; } = null!;
|
public IObservable<IItemViewModel?> CurrentSelectedItem { get; private set; } = null!;
|
||||||
public IObservable<IEnumerable<IItemViewModel>> CurrentItems { get; private set; } = null!;
|
public IObservable<IReadOnlyList<IItemViewModel>> CurrentItems { get; private set; } = null!;
|
||||||
public IObservable<IEnumerable<FullName>> MarkedItems { get; }
|
public IObservable<IEnumerable<FullName>> MarkedItems { get; }
|
||||||
|
public IObservable<IReadOnlyList<IItemViewModel>?> SelectedsChildren { get; private set; } = null!;
|
||||||
|
|
||||||
public TabViewModel(
|
public TabViewModel(
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
@@ -46,7 +49,7 @@ namespace FileTime.App.Core.ViewModels
|
|||||||
TabNumber = tabNumber;
|
TabNumber = tabNumber;
|
||||||
|
|
||||||
CurrentLocation = tab.CurrentLocation.AsObservable();
|
CurrentLocation = tab.CurrentLocation.AsObservable();
|
||||||
CurrentItems = tab.CurrentItems.Select(items => items.Select(MapItemToViewModel).ToList()).Publish(Enumerable.Empty<IItemViewModel>()).RefCount();
|
CurrentItems = tab.CurrentItems.Select(items => items.Select(MapItemToViewModel).ToList()).Publish(new List<IItemViewModel>()).RefCount();
|
||||||
CurrentSelectedItem =
|
CurrentSelectedItem =
|
||||||
Observable.CombineLatest(
|
Observable.CombineLatest(
|
||||||
CurrentItems,
|
CurrentItems,
|
||||||
@@ -55,7 +58,34 @@ namespace FileTime.App.Core.ViewModels
|
|||||||
)
|
)
|
||||||
.Publish(null)
|
.Publish(null)
|
||||||
.RefCount();
|
.RefCount();
|
||||||
|
|
||||||
|
var currentSelectedItemThrottled = CurrentSelectedItem.Throttle(TimeSpan.FromMilliseconds(250)).Publish(null).RefCount();
|
||||||
|
SelectedsChildren = Observable.Merge(
|
||||||
|
currentSelectedItemThrottled
|
||||||
|
.WhereNotNull()
|
||||||
|
.OfType<IContainerViewModel>()
|
||||||
|
.Where(c => c?.Container is not null)
|
||||||
|
.Select(c => c.Container!.Items)
|
||||||
|
.Switch()
|
||||||
|
.Select(items => Observable.FromAsync(async () => await Map(items)))
|
||||||
|
.Switch()
|
||||||
|
.Select(items => items?.Select(MapItemToViewModel).ToList()),
|
||||||
|
currentSelectedItemThrottled
|
||||||
|
.Where(c => c is null || c is not IContainerViewModel)
|
||||||
|
.Select(_ => (IReadOnlyList<IItemViewModel>?)null)
|
||||||
|
);
|
||||||
|
|
||||||
tab.CurrentLocation.Subscribe((_) => _markedItems.OnNext(Enumerable.Empty<FullName>()));
|
tab.CurrentLocation.Subscribe((_) => _markedItems.OnNext(Enumerable.Empty<FullName>()));
|
||||||
|
|
||||||
|
static async Task<List<IItem>?> Map(IEnumerable<IAbsolutePath>? items)
|
||||||
|
{
|
||||||
|
if (items == null) return null;
|
||||||
|
|
||||||
|
return await items
|
||||||
|
.ToAsyncEnumerable()
|
||||||
|
.SelectAwait(async i => await i.ResolveAsync(true))
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IItemViewModel MapItemToViewModel(IItem item, int index)
|
private IItemViewModel MapItemToViewModel(IItem item, int index)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace FileTime.Core.Models
|
|||||||
FullName Path { get; }
|
FullName Path { get; }
|
||||||
AbsolutePathType Type { get; }
|
AbsolutePathType Type { get; }
|
||||||
|
|
||||||
Task<IItem> ResolveAsync();
|
Task<IItem> ResolveAsync(bool forceResolve = false);
|
||||||
|
Task<IItem?> ResolveAsyncSafe(bool forceResolve = false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ namespace FileTime.Core.Models
|
|||||||
{
|
{
|
||||||
public interface IContainer : IItem
|
public interface IContainer : IItem
|
||||||
{
|
{
|
||||||
IObservable<IReadOnlyList<IAbsolutePath>> Items { get; }
|
IObservable<IEnumerable<IAbsolutePath>?> Items { get; }
|
||||||
IObservable<bool> IsLoading { get; }
|
IObservable<bool> IsLoading { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,5 +18,6 @@ namespace FileTime.Core.Models
|
|||||||
IContentProvider Provider { get; }
|
IContentProvider Provider { get; }
|
||||||
string? Attributes { get; }
|
string? Attributes { get; }
|
||||||
AbsolutePathType Type { get; }
|
AbsolutePathType Type { get; }
|
||||||
|
IObservable<IEnumerable<Exception>> Exceptions { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
using FileTime.Core.Behaviors;
|
using FileTime.Core.Behaviors;
|
||||||
|
using FileTime.Core.Enums;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
namespace FileTime.Core.Services
|
namespace FileTime.Core.Services
|
||||||
{
|
{
|
||||||
public interface IContentProvider : IContainer, IOnContainerEnter
|
public interface IContentProvider : IContainer, IOnContainerEnter
|
||||||
{
|
{
|
||||||
Task<IItem> GetItemByFullNameAsync(FullName fullName);
|
Task<IItem> GetItemByFullNameAsync(FullName fullName, bool forceResolve = false, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown);
|
||||||
Task<IItem> GetItemByNativePathAsync(NativePath nativePath);
|
Task<IItem> GetItemByNativePathAsync(NativePath nativePath, bool forceResolve = false, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown);
|
||||||
Task<List<IAbsolutePath>> GetItemsByContainerAsync(FullName fullName);
|
Task<List<IAbsolutePath>> GetItemsByContainerAsync(FullName fullName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using InitableService;
|
using InitableService;
|
||||||
using System.Reactive.Subjects;
|
|
||||||
|
|
||||||
namespace FileTime.Core.Services
|
namespace FileTime.Core.Services
|
||||||
{
|
{
|
||||||
@@ -8,7 +7,7 @@ namespace FileTime.Core.Services
|
|||||||
{
|
{
|
||||||
IObservable<IContainer?> CurrentLocation { get; }
|
IObservable<IContainer?> CurrentLocation { get; }
|
||||||
IObservable<IAbsolutePath?> CurrentSelectedItem { get; }
|
IObservable<IAbsolutePath?> CurrentSelectedItem { get; }
|
||||||
IObservable<IEnumerable<IItem>> CurrentItems { get; }
|
IObservable<IEnumerable<IItem>?> CurrentItems { get; }
|
||||||
|
|
||||||
void SetCurrentLocation(IContainer newLocation);
|
void SetCurrentLocation(IContainer newLocation);
|
||||||
void AddSelectedItemsTransformator(ItemsTransformator transformator);
|
void AddSelectedItemsTransformator(ItemsTransformator transformator);
|
||||||
|
|||||||
@@ -19,10 +19,19 @@ namespace FileTime.Core.Models
|
|||||||
Type = type;
|
Type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IItem> ResolveAsync()
|
public async Task<IItem> ResolveAsync(bool forceResolve = false)
|
||||||
{
|
{
|
||||||
var provider = VirtualContentProvider ?? ContentProvider;
|
var provider = VirtualContentProvider ?? ContentProvider;
|
||||||
return await provider.GetItemByFullNameAsync(Path);
|
return await provider.GetItemByFullNameAsync(Path, forceResolve, Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IItem?> ResolveAsyncSafe(bool forceResolve = false)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await ResolveAsync(forceResolve);
|
||||||
|
}
|
||||||
|
catch { return null; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,8 @@ namespace FileTime.Core.Models
|
|||||||
bool CanRename,
|
bool CanRename,
|
||||||
string? Attributes,
|
string? Attributes,
|
||||||
IContentProvider Provider,
|
IContentProvider Provider,
|
||||||
IObservable<IReadOnlyList<IAbsolutePath>> Items) : IContainer
|
IObservable<IEnumerable<Exception>> Exceptions,
|
||||||
|
IObservable<IEnumerable<IAbsolutePath>?> Items) : IContainer
|
||||||
{
|
{
|
||||||
BehaviorSubject<bool> IsLoading { get; } = new BehaviorSubject<bool>(false);
|
BehaviorSubject<bool> IsLoading { get; } = new BehaviorSubject<bool>(false);
|
||||||
IObservable<bool> IContainer.IsLoading => IsLoading.AsObservable();
|
IObservable<bool> IContainer.IsLoading => IsLoading.AsObservable();
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ namespace FileTime.Core.Models
|
|||||||
SupportsDelete CanDelete,
|
SupportsDelete CanDelete,
|
||||||
bool CanRename,
|
bool CanRename,
|
||||||
string? Attributes,
|
string? Attributes,
|
||||||
IContentProvider Provider) : IElement
|
IContentProvider Provider,
|
||||||
|
IObservable<IEnumerable<Exception>> Exceptions) : IElement
|
||||||
{
|
{
|
||||||
public AbsolutePathType Type => AbsolutePathType.Element;
|
public AbsolutePathType Type => AbsolutePathType.Element;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace FileTime.Core.Models
|
|||||||
bool CanRename,
|
bool CanRename,
|
||||||
string? Attributes,
|
string? Attributes,
|
||||||
IContentProvider Provider,
|
IContentProvider Provider,
|
||||||
|
IObservable<IEnumerable<Exception>> Exceptions,
|
||||||
long Size)
|
long Size)
|
||||||
: Element(
|
: Element(
|
||||||
Name,
|
Name,
|
||||||
@@ -29,6 +30,7 @@ namespace FileTime.Core.Models
|
|||||||
CanDelete,
|
CanDelete,
|
||||||
CanRename,
|
CanRename,
|
||||||
Attributes,
|
Attributes,
|
||||||
Provider
|
Provider,
|
||||||
|
Exceptions
|
||||||
), IFileElement;
|
), IFileElement;
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ namespace FileTime.Core.Services
|
|||||||
{
|
{
|
||||||
protected BehaviorSubject<IReadOnlyList<IAbsolutePath>> Items { get; } = new BehaviorSubject<IReadOnlyList<IAbsolutePath>>(new List<IAbsolutePath>());
|
protected BehaviorSubject<IReadOnlyList<IAbsolutePath>> Items { get; } = new BehaviorSubject<IReadOnlyList<IAbsolutePath>>(new List<IAbsolutePath>());
|
||||||
|
|
||||||
IObservable<IReadOnlyList<IAbsolutePath>> IContainer.Items => Items;
|
IObservable<IEnumerable<IAbsolutePath>> IContainer.Items => Items;
|
||||||
|
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
|
|
||||||
@@ -41,14 +41,17 @@ namespace FileTime.Core.Services
|
|||||||
|
|
||||||
public AbsolutePathType Type => AbsolutePathType.Container;
|
public AbsolutePathType Type => AbsolutePathType.Container;
|
||||||
|
|
||||||
|
public IObservable<IEnumerable<Exception>> Exceptions => Observable.Return(Enumerable.Empty<Exception>());
|
||||||
|
|
||||||
protected ContentProviderBase(string name)
|
protected ContentProviderBase(string name)
|
||||||
{
|
{
|
||||||
DisplayName = Name = name;
|
DisplayName = Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Task OnEnter() => Task.CompletedTask;
|
public virtual Task OnEnter() => Task.CompletedTask;
|
||||||
public virtual async Task<IItem> GetItemByFullNameAsync(FullName fullName) => await GetItemByNativePathAsync(GetNativePath(fullName));
|
public virtual async Task<IItem> GetItemByFullNameAsync(FullName fullName, bool forceResolve = false, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown)
|
||||||
public abstract Task<IItem> GetItemByNativePathAsync(NativePath nativePath);
|
=> await GetItemByNativePathAsync(GetNativePath(fullName), forceResolve, forceResolvePathType);
|
||||||
|
public abstract Task<IItem> GetItemByNativePathAsync(NativePath nativePath, bool forceResolve = false, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown);
|
||||||
public abstract Task<List<IAbsolutePath>> GetItemsByContainerAsync(FullName fullName);
|
public abstract Task<List<IAbsolutePath>> GetItemsByContainerAsync(FullName fullName);
|
||||||
public abstract NativePath GetNativePath(FullName fullName);
|
public abstract NativePath GetNativePath(FullName fullName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace FileTime.Core.Services
|
|||||||
private readonly List<ItemsTransformator> _transformators = new();
|
private readonly List<ItemsTransformator> _transformators = new();
|
||||||
private IAbsolutePath? _currentSelectedItemCached;
|
private IAbsolutePath? _currentSelectedItemCached;
|
||||||
public IObservable<IContainer?> CurrentLocation { get; }
|
public IObservable<IContainer?> CurrentLocation { get; }
|
||||||
public IObservable<IEnumerable<IItem>> CurrentItems { get; }
|
public IObservable<IEnumerable<IItem>?> CurrentItems { get; }
|
||||||
public IObservable<IAbsolutePath?> CurrentSelectedItem { get; }
|
public IObservable<IAbsolutePath?> CurrentSelectedItem { get; }
|
||||||
|
|
||||||
public Tab()
|
public Tab()
|
||||||
@@ -23,7 +23,7 @@ namespace FileTime.Core.Services
|
|||||||
.Where(c => c is not null)
|
.Where(c => c is not null)
|
||||||
.Select(c => c!.Items)
|
.Select(c => c!.Items)
|
||||||
.Switch()
|
.Switch()
|
||||||
.Select(i => Observable.FromAsync(async () => await MapItems(i)))
|
.Select(i => i == null ? Observable.Return<IEnumerable<IItem>?>(null) : Observable.FromAsync(async () => await MapItems(i)))
|
||||||
.Switch(),
|
.Switch(),
|
||||||
CurrentLocation
|
CurrentLocation
|
||||||
.Where(c => c is null)
|
.Where(c => c is null)
|
||||||
@@ -43,21 +43,11 @@ namespace FileTime.Core.Services
|
|||||||
CurrentSelectedItem.Subscribe(s => _currentSelectedItemCached = s);
|
CurrentSelectedItem.Subscribe(s => _currentSelectedItemCached = s);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<IItem>> MapItems(IReadOnlyList<IAbsolutePath> items)
|
private async Task<IEnumerable<IItem>> MapItems(IEnumerable<IAbsolutePath> items)
|
||||||
{
|
{
|
||||||
IEnumerable<IItem> resolvedItems = await items
|
IEnumerable<IItem> resolvedItems = await items
|
||||||
.ToAsyncEnumerable()
|
.ToAsyncEnumerable()
|
||||||
.SelectAwait(
|
.SelectAwait(async i => await i.ResolveAsync(true))
|
||||||
async i =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//TODO: force create by AbsolutePath name
|
|
||||||
return await i.ContentProvider.GetItemByFullNameAsync(i.Path);
|
|
||||||
}
|
|
||||||
catch { return null!; }
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.Where(i => i != null)
|
.Where(i => i != null)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
@@ -79,7 +69,7 @@ namespace FileTime.Core.Services
|
|||||||
private IObservable<IAbsolutePath?> GetSelectedItemByLocation(IContainer? currentLocation)
|
private IObservable<IAbsolutePath?> GetSelectedItemByLocation(IContainer? currentLocation)
|
||||||
{
|
{
|
||||||
//TODO:
|
//TODO:
|
||||||
return currentLocation?.Items?.Select(i => i.Count == 0 ? null : i[0]) ?? Observable.Return((IAbsolutePath?)null);
|
return currentLocation?.Items?.Select(i => i.FirstOrDefault()) ?? Observable.Return((IAbsolutePath?)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetCurrentLocation(IContainer newLocation) => _currentLocation.OnNext(newLocation);
|
public void SetCurrentLocation(IContainer newLocation) => _currentLocation.OnNext(newLocation);
|
||||||
|
|||||||
@@ -1,218 +1,185 @@
|
|||||||
<Application xmlns="https://github.com/avaloniaui"
|
<Application
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
x:Class="FileTime.GuiApp.App"
|
||||||
xmlns:local="using:FileTime.GuiApp"
|
xmlns="https://github.com/avaloniaui"
|
||||||
x:Class="FileTime.GuiApp.App"
|
xmlns:converters="using:FileTime.GuiApp.Converters"
|
||||||
xmlns:converters="using:FileTime.GuiApp.Converters">
|
xmlns:local="using:FileTime.GuiApp"
|
||||||
<Application.Resources>
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<ResourceDictionary>
|
<Application.Resources>
|
||||||
<Color x:Key="AppBackgroundColor">#E7073642</Color>
|
<ResourceDictionary>
|
||||||
<Color x:Key="ContainerBackgroundColor">#083e4c</Color>
|
<Color x:Key="AppBackgroundColor">#E7073642</Color>
|
||||||
<Color x:Key="TransparentContainerBackgroundColor">#D0083e4c</Color>
|
<Color x:Key="ContainerBackgroundColor">#083e4c</Color>
|
||||||
<Color x:Key="BarelyTransparentBackgroundColor">#80083e4c</Color>
|
<Color x:Key="TransparentContainerBackgroundColor">#D0083e4c</Color>
|
||||||
|
<Color x:Key="BarelyTransparentBackgroundColor">#80083e4c</Color>
|
||||||
|
|
||||||
<Color x:Key="ItemBackgroundColor">#00000000</Color>
|
<Color x:Key="ItemBackgroundColor">#00000000</Color>
|
||||||
<Color x:Key="AlternativeItemBackgroundColor">#10000000</Color>
|
<Color x:Key="AlternativeItemBackgroundColor">#10000000</Color>
|
||||||
<Color x:Key="SelectedItemBackgroundColor">#93a1a1</Color>
|
<Color x:Key="SelectedItemBackgroundColor">#93a1a1</Color>
|
||||||
<Color x:Key="MarkedItemBackgroundColor">#00000000</Color>
|
<Color x:Key="MarkedItemBackgroundColor">#00000000</Color>
|
||||||
<Color x:Key="MarkedAlternativeItemBackgroundColor">#10000000</Color>
|
<Color x:Key="MarkedAlternativeItemBackgroundColor">#10000000</Color>
|
||||||
<Color x:Key="MarkedSelectedItemBackgroundColor">#b58900</Color>
|
<Color x:Key="MarkedSelectedItemBackgroundColor">#b58900</Color>
|
||||||
|
|
||||||
<Color x:Key="ForegroundColor">#93a1a1</Color>
|
<Color x:Key="ForegroundColor">#93a1a1</Color>
|
||||||
<Color x:Key="AccentColor">#268bd2</Color>
|
<Color x:Key="AccentColor">#268bd2</Color>
|
||||||
<Color x:Key="AccentComplementColor">#fdf6e3</Color>
|
<Color x:Key="AccentComplementColor">#fdf6e3</Color>
|
||||||
<Color x:Key="LightForegroundColor">#7793a1a1</Color>
|
<Color x:Key="LightForegroundColor">#7793a1a1</Color>
|
||||||
<Color x:Key="AlternativeItemForegroundColor">#93a1a1</Color>
|
<Color x:Key="AlternativeItemForegroundColor">#93a1a1</Color>
|
||||||
<Color x:Key="SelectedItemForegroundColor">#073642</Color>
|
<Color x:Key="SelectedItemForegroundColor">#073642</Color>
|
||||||
<Color x:Key="MarkedItemForegroundColor">#b58900</Color>
|
<Color x:Key="MarkedItemForegroundColor">#b58900</Color>
|
||||||
<Color x:Key="MarkedAlternativeItemForegroundColor">#b58900</Color>
|
<Color x:Key="MarkedAlternativeItemForegroundColor">#b58900</Color>
|
||||||
<Color x:Key="MarkedSelectedItemForegroundColor">#002b36</Color>
|
<Color x:Key="MarkedSelectedItemForegroundColor">#002b36</Color>
|
||||||
|
|
||||||
<Color x:Key="ErrorColor">#dc322f</Color>
|
<Color x:Key="ErrorColor">#dc322f</Color>
|
||||||
|
|
||||||
<LinearGradientBrush x:Key="ContentSeparatorBrush">
|
<LinearGradientBrush x:Key="ContentSeparatorBrush">
|
||||||
<GradientStop Offset="0" Color="#0093a1a1" />
|
<GradientStop Color="#0093a1a1" Offset="0" />
|
||||||
<GradientStop Offset="0.5" Color="#93a1a1" />
|
<GradientStop Color="#93a1a1" Offset="0.5" />
|
||||||
<GradientStop Offset="1" Color="#0093a1a1" />
|
<GradientStop Color="#0093a1a1" Offset="1" />
|
||||||
</LinearGradientBrush>
|
</LinearGradientBrush>
|
||||||
|
|
||||||
<LinearGradientBrush x:Key="ContainerGradientBackgroundBrush">
|
<LinearGradientBrush x:Key="ContainerGradientBackgroundBrush">
|
||||||
<GradientStop Offset="0" Color="#00b58900" />
|
<GradientStop Color="#00b58900" Offset="0" />
|
||||||
<GradientStop Offset="0.4" Color="#CCb58900" />
|
<GradientStop Color="#CCb58900" Offset="0.4" />
|
||||||
<GradientStop Offset="0.6" Color="#CCb58900" />
|
<GradientStop Color="#CCb58900" Offset="0.6" />
|
||||||
<GradientStop Offset="1" Color="#00b58900" />
|
<GradientStop Color="#00b58900" Offset="1" />
|
||||||
</LinearGradientBrush>
|
</LinearGradientBrush>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<SolidColorBrush
|
<SolidColorBrush Color="{DynamicResource AppBackgroundColor}" x:Key="AppBackgroundBrush" />
|
||||||
x:Key="AppBackgroundBrush"
|
<SolidColorBrush Color="{DynamicResource ContainerBackgroundColor}" x:Key="ContainerBackgroundBrush" />
|
||||||
Color="{DynamicResource AppBackgroundColor}" />
|
<SolidColorBrush Color="{DynamicResource TransparentContainerBackgroundColor}" x:Key="TransparentContainerBackgroundBrush" />
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="ContainerBackgroundBrush"
|
|
||||||
Color="{DynamicResource ContainerBackgroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="TransparentContainerBackgroundBrush"
|
|
||||||
Color="{DynamicResource TransparentContainerBackgroundColor}" />
|
|
||||||
|
|
||||||
<SolidColorBrush
|
<SolidColorBrush Color="{DynamicResource ItemBackgroundColor}" x:Key="ItemBackgroundBrush" />
|
||||||
x:Key="ItemBackgroundBrush"
|
<SolidColorBrush Color="{DynamicResource AlternativeItemBackgroundColor}" x:Key="AlternativeItemBackgroundBrush" />
|
||||||
Color="{DynamicResource ItemBackgroundColor}" />
|
<SolidColorBrush Color="{DynamicResource SelectedItemBackgroundColor}" x:Key="SelectedItemBackgroundBrush" />
|
||||||
<SolidColorBrush
|
<SolidColorBrush Color="{DynamicResource MarkedItemBackgroundColor}" x:Key="MarkedItemBackgroundBrush" />
|
||||||
x:Key="AlternativeItemBackgroundBrush"
|
<SolidColorBrush Color="{DynamicResource MarkedSelectedItemBackgroundColor}" x:Key="MarkedSelectedItemBackgroundBrush" />
|
||||||
Color="{DynamicResource AlternativeItemBackgroundColor}" />
|
<SolidColorBrush Color="{DynamicResource MarkedAlternativeItemBackgroundColor}" x:Key="MarkedAlternativeItemBackgroundBrush" />
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="SelectedItemBackgroundBrush"
|
|
||||||
Color="{DynamicResource SelectedItemBackgroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="MarkedItemBackgroundBrush"
|
|
||||||
Color="{DynamicResource MarkedItemBackgroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="MarkedSelectedItemBackgroundBrush"
|
|
||||||
Color="{DynamicResource MarkedSelectedItemBackgroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="MarkedAlternativeItemBackgroundBrush"
|
|
||||||
Color="{DynamicResource MarkedAlternativeItemBackgroundColor}" />
|
|
||||||
|
|
||||||
<SolidColorBrush
|
<SolidColorBrush Color="{DynamicResource ForegroundColor}" x:Key="ForegroundBrush" />
|
||||||
x:Key="ForegroundBrush"
|
<SolidColorBrush Color="{DynamicResource AccentColor}" x:Key="AccentBrush" />
|
||||||
Color="{DynamicResource ForegroundColor}" />
|
<SolidColorBrush Color="{DynamicResource AccentComplementColor}" x:Key="AccentComplementBrush" />
|
||||||
<SolidColorBrush
|
<SolidColorBrush Color="{DynamicResource LightForegroundColor}" x:Key="LightForegroundBrush" />
|
||||||
x:Key="AccentBrush"
|
<SolidColorBrush Color="{DynamicResource AlternativeItemForegroundColor}" x:Key="AlternativeItemForegroundBrush" />
|
||||||
Color="{DynamicResource AccentColor}" />
|
<SolidColorBrush Color="{DynamicResource SelectedItemForegroundColor}" x:Key="SelectedItemForegroundBrush" />
|
||||||
<SolidColorBrush
|
<SolidColorBrush Color="{DynamicResource MarkedItemForegroundColor}" x:Key="MarkedItemForegroundBrush" />
|
||||||
x:Key="AccentComplementBrush"
|
<SolidColorBrush Color="{DynamicResource MarkedAlternativeItemForegroundColor}" x:Key="MarkedAlternativeItemForegroundBrush" />
|
||||||
Color="{DynamicResource AccentComplementColor}" />
|
<SolidColorBrush Color="{DynamicResource MarkedSelectedItemForegroundColor}" x:Key="MarkedSelectedItemForegroundBrush" />
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="LightForegroundBrush"
|
|
||||||
Color="{DynamicResource LightForegroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="AlternativeItemForegroundBrush"
|
|
||||||
Color="{DynamicResource AlternativeItemForegroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="SelectedItemForegroundBrush"
|
|
||||||
Color="{DynamicResource SelectedItemForegroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="MarkedItemForegroundBrush"
|
|
||||||
Color="{DynamicResource MarkedItemForegroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="MarkedAlternativeItemForegroundBrush"
|
|
||||||
Color="{DynamicResource MarkedAlternativeItemForegroundColor}" />
|
|
||||||
<SolidColorBrush
|
|
||||||
x:Key="MarkedSelectedItemForegroundBrush"
|
|
||||||
Color="{DynamicResource MarkedSelectedItemForegroundColor}" />
|
|
||||||
|
|
||||||
<SolidColorBrush
|
<SolidColorBrush Color="{DynamicResource ErrorColor}" x:Key="ErrorBrush" />
|
||||||
x:Key="ErrorBrush"
|
|
||||||
Color="{DynamicResource ErrorColor}" />
|
|
||||||
|
|
||||||
|
|
||||||
<SolidColorBrush x:Key="SystemControlHighlightListAccentLowBrush" Color="{DynamicResource SelectedItemBackgroundColor}" />
|
<SolidColorBrush Color="{DynamicResource SelectedItemBackgroundColor}" x:Key="SystemControlHighlightListAccentLowBrush" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<converters:ItemViewModeToBrushConverter
|
<converters:ItemViewModeToBrushConverter
|
||||||
x:Key="ItemViewModeToForegroundConverter"
|
AlternativeBrush="{StaticResource AlternativeItemForegroundBrush}"
|
||||||
DefaultBrush="{StaticResource ForegroundBrush}"
|
DefaultBrush="{StaticResource ForegroundBrush}"
|
||||||
AlternativeBrush="{StaticResource AlternativeItemForegroundBrush}"
|
MarkedAlternativeBrush="{StaticResource MarkedAlternativeItemForegroundBrush}"
|
||||||
SelectedBrush="{StaticResource SelectedItemForegroundBrush}"
|
MarkedBrush="{StaticResource MarkedItemForegroundBrush}"
|
||||||
MarkedBrush="{StaticResource MarkedItemForegroundBrush}"
|
MarkedSelectedBrush="{StaticResource MarkedSelectedItemForegroundBrush}"
|
||||||
MarkedAlternativeBrush="{StaticResource MarkedAlternativeItemForegroundBrush}"
|
SelectedBrush="{StaticResource SelectedItemForegroundBrush}"
|
||||||
MarkedSelectedBrush="{StaticResource MarkedSelectedItemForegroundBrush}"/>
|
x:Key="ItemViewModeToForegroundConverter" />
|
||||||
<converters:ItemViewModeToBrushConverter
|
<converters:ItemViewModeToBrushConverter
|
||||||
x:Key="ItemViewModeToBackgroundConverter"
|
AlternativeBrush="{StaticResource AlternativeItemBackgroundBrush}"
|
||||||
DefaultBrush="{StaticResource ItemBackgroundBrush}"
|
DefaultBrush="{StaticResource ItemBackgroundBrush}"
|
||||||
AlternativeBrush="{StaticResource AlternativeItemBackgroundBrush}"
|
MarkedAlternativeBrush="{StaticResource MarkedAlternativeItemBackgroundBrush}"
|
||||||
SelectedBrush="{StaticResource SelectedItemBackgroundBrush}"
|
MarkedBrush="{StaticResource MarkedItemBackgroundBrush}"
|
||||||
MarkedBrush="{StaticResource MarkedItemBackgroundBrush}"
|
MarkedSelectedBrush="{StaticResource MarkedSelectedItemBackgroundBrush}"
|
||||||
MarkedAlternativeBrush="{StaticResource MarkedAlternativeItemBackgroundBrush}"
|
SelectedBrush="{StaticResource SelectedItemBackgroundBrush}"
|
||||||
MarkedSelectedBrush="{StaticResource MarkedSelectedItemBackgroundBrush}"/>
|
x:Key="ItemViewModeToBackgroundConverter" />
|
||||||
<converters:NamePartShrinkerConverter x:Key="NamePartShrinkerConverter"/>
|
<converters:NamePartShrinkerConverter x:Key="NamePartShrinkerConverter" />
|
||||||
<converters:ItemViewModelIsAttributeTypeConverter x:Key="ItemViewModelIsAttributeTypeConverter"/>
|
<converters:ItemViewModelIsAttributeTypeConverter x:Key="ItemViewModelIsAttributeTypeConverter" />
|
||||||
<converters:ItemViewModelIsAttributeTypeConverter x:Key="ItemViewModelIsNotAttributeTypeConverter" Invert="true"/>
|
<converters:ItemViewModelIsAttributeTypeConverter Invert="true" x:Key="ItemViewModelIsNotAttributeTypeConverter" />
|
||||||
<converters:GetFileExtensionConverter x:Key="GetFileExtensionConverter"/>
|
<converters:GetFileExtensionConverter x:Key="GetFileExtensionConverter" />
|
||||||
<converters:FormatSizeConverter x:Key="FormatSizeConverter"/>
|
<converters:FormatSizeConverter x:Key="FormatSizeConverter" />
|
||||||
<converters:DateTimeConverter x:Key="DateTimeConverter"/>
|
<converters:DateTimeConverter x:Key="DateTimeConverter" />
|
||||||
<converters:SplitStringConverter x:Key="SplitStringConverter" />
|
<converters:SplitStringConverter x:Key="SplitStringConverter" />
|
||||||
<converters:CompareConverter x:Key="EqualityConverter"/>
|
<converters:CompareConverter x:Key="EqualityConverter" />
|
||||||
<converters:CompareConverter x:Key="NotEqualsConverter" ComparisonCondition="{x:Static converters:ComparisonCondition.NotEqual}"/>
|
<converters:CompareConverter ComparisonCondition="{x:Static converters:ComparisonCondition.NotEqual}" x:Key="NotEqualsConverter" />
|
||||||
</ResourceDictionary>
|
<converters:ExceptionToStringConverter x:Key="ExceptionToStringConverter" />
|
||||||
</Application.Resources>
|
</ResourceDictionary>
|
||||||
|
</Application.Resources>
|
||||||
|
|
||||||
<Application.Styles>
|
<Application.Styles>
|
||||||
<FluentTheme Mode="Dark"/>
|
<FluentTheme Mode="Dark" />
|
||||||
|
|
||||||
<Style Selector="TextBlock">
|
<Style Selector="TextBlock">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource ForegroundBrush}"/>
|
<Setter Property="Foreground" Value="{DynamicResource ForegroundBrush}" />
|
||||||
<Setter Property="FontSize" Value="16"/>
|
<Setter Property="FontSize" Value="16" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="TextBlock.SmallText">
|
<Style Selector="TextBlock.SmallText">
|
||||||
<Setter Property="FontSize" Value="12"/>
|
<Setter Property="FontSize" Value="12" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="TextBlock.ExtraSmallText">
|
<Style Selector="TextBlock.ExtraSmallText">
|
||||||
<Setter Property="FontSize" Value="11"/>
|
<Setter Property="FontSize" Value="11" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="TextBox">
|
<Style Selector="TextBox">
|
||||||
<Setter Property="Foreground" Value="{DynamicResource ForegroundBrush}"/>
|
<Setter Property="Foreground" Value="{DynamicResource ForegroundBrush}" />
|
||||||
<Setter Property="Background" Value="{DynamicResource ContainerBackgroundBrush}"/>
|
<Setter Property="Background" Value="{DynamicResource ContainerBackgroundBrush}" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="ListBox.ContentListView">
|
<Style Selector="ListBox.ContentListView">
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
<Setter Property="Background" Value="Transparent" />
|
||||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="ListBox.ContentListView > ListBoxItem">
|
<Style Selector="ListBox.ContentListView > ListBoxItem">
|
||||||
<Setter Property="Margin" Value="0"/>
|
<Setter Property="Margin" Value="0" />
|
||||||
<Setter Property="Padding" Value="0"/>
|
<Setter Property="Padding" Value="0" />
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
<Setter Property="Background" Value="Transparent" />
|
||||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
<!--Setter Property="ContextMenu">
|
<!--Setter Property="ContextMenu">
|
||||||
<ContextMenu Items="{Binding Converter={StaticResource ContextMenuGenerator}}"/>
|
<ContextMenu Items="{Binding Converter={StaticResource ContextMenuGenerator}}"/>
|
||||||
</Setter-->
|
</Setter-->
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Grid.SidebarContainerPresenter">
|
<Style Selector="Grid.SidebarContainerPresenter">
|
||||||
<Setter Property="Background" Value="#01000000"/>
|
<Setter Property="Background" Value="#01000000" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Grid.SidebarContainerPresenter:pointerover">
|
<Style Selector="Grid.SidebarContainerPresenter:pointerover">
|
||||||
<Setter Property="Background" Value="{DynamicResource AppBackgroundColor}"/>
|
<Setter Property="Background" Value="{DynamicResource AppBackgroundColor}" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Border.SelectedTimelineCommand">
|
<Style Selector="Border.SelectedTimelineCommand">
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource ForegroundBrush}"/>
|
<Setter Property="BorderBrush" Value="{DynamicResource ForegroundBrush}" />
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="ListBox.RadioButtonListBox">
|
<Style Selector="ListBox.RadioButtonListBox">
|
||||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
<Setter Property="BorderBrush" Value="Transparent" />
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
<Setter Property="Background" Value="Transparent" />
|
||||||
</Style>
|
</Style>
|
||||||
<Style Selector="ListBox.RadioButtonListBox ListBoxItem">
|
<Style Selector="ListBox.RadioButtonListBox ListBoxItem">
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Border>
|
<Border>
|
||||||
<RadioButton
|
<RadioButton
|
||||||
Content="{TemplateBinding ContentPresenter.Content}"
|
Content="{TemplateBinding ContentPresenter.Content}"
|
||||||
VerticalAlignment="Center"
|
Foreground="{DynamicResource ForegroundBrush}"
|
||||||
IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"
|
IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
||||||
Foreground="{DynamicResource ForegroundBrush}"/>
|
VerticalAlignment="Center" />
|
||||||
</Border>
|
</Border>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Image.LoadingAnimation">
|
<Style Selector="Image.LoadingAnimation">
|
||||||
<Style.Animations>
|
<Style.Animations>
|
||||||
<Animation Duration="0:0:2" IterationCount="INFINITE" Easing="QuadraticEaseInOut">
|
<Animation
|
||||||
<KeyFrame Cue="0%">
|
Duration="0:0:2"
|
||||||
<Setter Property="RotateTransform.Angle" Value="45"/>
|
Easing="QuadraticEaseInOut"
|
||||||
</KeyFrame>
|
IterationCount="INFINITE">
|
||||||
<KeyFrame Cue="100%">
|
<KeyFrame Cue="0%">
|
||||||
<Setter Property="RotateTransform.Angle" Value="405"/>
|
<Setter Property="RotateTransform.Angle" Value="45" />
|
||||||
</KeyFrame>
|
</KeyFrame>
|
||||||
</Animation>
|
<KeyFrame Cue="100%">
|
||||||
</Style.Animations>
|
<Setter Property="RotateTransform.Angle" Value="405" />
|
||||||
</Style>
|
</KeyFrame>
|
||||||
</Application.Styles>
|
</Animation>
|
||||||
|
</Style.Animations>
|
||||||
|
</Style>
|
||||||
|
</Application.Styles>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using Avalonia.Data.Converters;
|
||||||
|
|
||||||
|
namespace FileTime.GuiApp.Converters
|
||||||
|
{
|
||||||
|
public class ExceptionToStringConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string TraverseInnerException(Exception e)
|
||||||
|
{
|
||||||
|
string s = "";
|
||||||
|
if (e.InnerException != null) s += TraverseInnerException(e.InnerException) + Environment.NewLine;
|
||||||
|
else return FormatException(e);
|
||||||
|
|
||||||
|
s += "In: " + FormatException(e);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,145 +1,208 @@
|
|||||||
<Window xmlns="https://github.com/avaloniaui"
|
<Window
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
Background="Transparent"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
ExtendClientAreaToDecorationsHint="True"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
Icon="/Assets/filetime.ico"
|
||||||
xmlns:vm="using:FileTime.GuiApp.ViewModels"
|
InputElement.KeyDown="OnKeyDown"
|
||||||
xmlns:corevm="using:FileTime.App.Core.ViewModels"
|
Opened="OnWindowOpened"
|
||||||
xmlns:local="using:FileTime.GuiApp.Views"
|
Title="FileTime"
|
||||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
TransparencyLevelHint="Blur"
|
||||||
InputElement.KeyDown="OnKeyDown"
|
d:DesignHeight="450"
|
||||||
Opened="OnWindowOpened"
|
d:DesignWidth="800"
|
||||||
x:Class="FileTime.GuiApp.Views.MainWindow"
|
mc:Ignorable="d"
|
||||||
Icon="/Assets/filetime.ico"
|
x:Class="FileTime.GuiApp.Views.MainWindow"
|
||||||
Title="FileTime"
|
x:CompileBindings="True"
|
||||||
TransparencyLevelHint="Blur"
|
x:DataType="vm:IMainWindowViewModelBase"
|
||||||
Background="Transparent"
|
xmlns="https://github.com/avaloniaui"
|
||||||
ExtendClientAreaToDecorationsHint="True"
|
xmlns:corevm="using:FileTime.App.Core.ViewModels"
|
||||||
x:DataType="vm:IMainWindowViewModelBase"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
x:CompileBindings="True">
|
xmlns:local="using:FileTime.GuiApp.Views"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:vm="using:FileTime.GuiApp.ViewModels"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Design.DataContext>
|
||||||
|
<vm:MainWindowViewModel />
|
||||||
|
</Design.DataContext>
|
||||||
|
|
||||||
<Grid Background="{DynamicResource AppBackgroundBrush}">
|
<Grid Background="{DynamicResource AppBackgroundBrush}">
|
||||||
<Grid IsVisible="{Binding Loading, Converter={x:Static BoolConverters.Not}}" x:DataType="vm:MainWindowViewModel">
|
<Grid IsVisible="{Binding Loading, Converter={x:Static BoolConverters.Not}}" x:DataType="vm:MainWindowViewModel">
|
||||||
<Grid ColumnDefinitions="250,*" RowDefinitions="Auto,*">
|
<Grid ColumnDefinitions="250,*" RowDefinitions="Auto,*">
|
||||||
<Grid PointerPressed="HeaderPointerPressed">
|
<Grid PointerPressed="HeaderPointerPressed">
|
||||||
<Rectangle Fill="#01000000"/>
|
<Rectangle Fill="#01000000" />
|
||||||
<TextBlock Margin="15,10" Text="{Binding Title}"/>
|
<TextBlock Margin="15,10" Text="{Binding Title}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid Grid.Column="1" PointerPressed="HeaderPointerPressed">
|
<Grid Grid.Column="1" PointerPressed="HeaderPointerPressed">
|
||||||
<Rectangle Fill="#01000000"/>
|
<Rectangle Fill="#01000000" />
|
||||||
|
|
||||||
<StackPanel Margin="20,10" Orientation="Horizontal">
|
<StackPanel Margin="20,10" Orientation="Horizontal">
|
||||||
<!--local:PathPresenter DataContext="{Binding AppState.SelectedTab^.CurrentLocation^.FullName.Path,Converter={StaticResource PathPreformatter}}"/-->
|
<!-- local:PathPresenter DataContext="{Binding AppState.SelectedTab^.CurrentLocation^.FullName.Path,Converter={StaticResource PathPreformatter}}"/ -->
|
||||||
<TextBlock
|
<TextBlock Foreground="{StaticResource AccentBrush}" Text="{Binding AppState.SelectedTab^.CurrentSelectedItem^.DisplayNameText}" />
|
||||||
Text="{Binding AppState.SelectedTab^.CurrentSelectedItem^.DisplayNameText}" Foreground="{StaticResource AccentBrush}" />
|
</StackPanel>
|
||||||
</StackPanel>
|
</Grid>
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Grid Grid.Column="1" Grid.Row="1" RowDefinitions="Auto,40,*,Auto">
|
<Grid
|
||||||
|
Grid.Column="1"
|
||||||
|
Grid.Row="1"
|
||||||
|
RowDefinitions="Auto,40,*,Auto">
|
||||||
|
|
||||||
<ItemsControl
|
<ItemsControl Grid.Row="1" Items="{Binding AppState.Tabs}">
|
||||||
Grid.Row="1"
|
<ItemsControl.ItemsPanel>
|
||||||
Items="{Binding AppState.Tabs}">
|
<ItemsPanelTemplate>
|
||||||
<ItemsControl.ItemsPanel>
|
<StackPanel Orientation="Horizontal" />
|
||||||
<ItemsPanelTemplate>
|
</ItemsPanelTemplate>
|
||||||
<StackPanel Orientation="Horizontal" />
|
</ItemsControl.ItemsPanel>
|
||||||
</ItemsPanelTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
</ItemsControl.ItemsPanel>
|
<DataTemplate>
|
||||||
<ItemsControl.ItemTemplate>
|
<Grid RowDefinitions="Auto,1">
|
||||||
<DataTemplate>
|
<StackPanel Margin="20,0,20,0" Orientation="Horizontal">
|
||||||
<Grid RowDefinitions="Auto,1">
|
|
||||||
<StackPanel Orientation="Horizontal" Margin="20,0,20,0">
|
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock Text="{Binding TabNumber, StringFormat=({0})}" VerticalAlignment="Center" />
|
||||||
VerticalAlignment="Center" Text="{Binding TabNumber,StringFormat=({0})}" />
|
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center" Margin="5,0,0,0" Text="{Binding CurrentLocation^.Name}" />
|
Margin="5,0,0,0"
|
||||||
</StackPanel>
|
Text="{Binding CurrentLocation^.Name}"
|
||||||
|
VerticalAlignment="Center" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<Rectangle Fill="{DynamicResource ForegroundBrush}" Grid.Row="1" IsVisible="{Binding IsSelected^}"/>
|
<Rectangle
|
||||||
</Grid>
|
Fill="{DynamicResource ForegroundBrush}"
|
||||||
</DataTemplate>
|
Grid.Row="1"
|
||||||
</ItemsControl.ItemTemplate>
|
IsVisible="{Binding IsSelected^}" />
|
||||||
</ItemsControl>
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
<Grid
|
<Grid Grid.Row="2" Margin="20,0,0,0">
|
||||||
Grid.Row="2"
|
<Grid>
|
||||||
Margin="20,0,0,0">
|
<Grid.ColumnDefinitions>
|
||||||
<Grid>
|
<ColumnDefinition Width="15*" />
|
||||||
<Grid.ColumnDefinitions>
|
<ColumnDefinition Width="10" />
|
||||||
<ColumnDefinition Width="15*" />
|
<ColumnDefinition Width="40*" />
|
||||||
<ColumnDefinition Width="10" />
|
<ColumnDefinition Width="10" />
|
||||||
<ColumnDefinition Width="40*" />
|
<ColumnDefinition Width="45*" />
|
||||||
<ColumnDefinition Width="10" />
|
</Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="45*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
|
|
||||||
<Rectangle
|
<Rectangle
|
||||||
Grid.Column="1"
|
Fill="{DynamicResource ContentSeparatorBrush}"
|
||||||
Width="1"
|
Grid.Column="1"
|
||||||
Margin="0,10,0,10"
|
HorizontalAlignment="Center"
|
||||||
HorizontalAlignment="Center"
|
Margin="0,10,0,10"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Fill="{DynamicResource ContentSeparatorBrush}" />
|
Width="1" />
|
||||||
|
|
||||||
|
|
||||||
<Grid Grid.Column="2" RowDefinitions="Auto,*">
|
<Grid Grid.Column="2" RowDefinitions="Auto,*">
|
||||||
<Grid IsVisible="{Binding AppState.SelectedTab^.CurrentLocation^.IsLoading^}">
|
<Grid IsVisible="{Binding AppState.SelectedTab^.CurrentLocation^.IsLoading^}">
|
||||||
<Image Width="40" Height="40" Source="{SvgImage /Assets/loading.svg}" Classes="LoadingAnimation"/>
|
<Image
|
||||||
</Grid>
|
Classes="LoadingAnimation"
|
||||||
<ListBox
|
Height="40"
|
||||||
Grid.Row="1"
|
Source="{SvgImage /Assets/loading.svg}"
|
||||||
x:Name="CurrentItems"
|
Width="40" />
|
||||||
x:CompileBindings="False"
|
</Grid>
|
||||||
AutoScrollToSelectedItem="True"
|
<ListBox
|
||||||
IsTabStop="True"
|
AutoScrollToSelectedItem="True"
|
||||||
Items="{Binding AppState.SelectedTab^.CurrentItems^}"
|
Classes="ContentListView"
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
|
Grid.Row="1"
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
IsTabStop="True"
|
||||||
Classes="ContentListView">
|
Items="{Binding AppState.SelectedTab^.CurrentItems^}"
|
||||||
<ListBox.ItemTemplate>
|
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
|
||||||
<DataTemplate x:DataType="corevm:IItemViewModel">
|
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||||
<local:ItemView HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"/>
|
x:CompileBindings="False"
|
||||||
</DataTemplate>
|
x:Name="CurrentItems">
|
||||||
</ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
</ListBox>
|
<DataTemplate x:DataType="corevm:IItemViewModel">
|
||||||
|
<local:ItemView HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="1"
|
FontWeight="Bold"
|
||||||
x:CompileBindings="False"
|
Foreground="{DynamicResource ErrorBrush}"
|
||||||
x:Name="CurrentEmpty"
|
Grid.Row="1"
|
||||||
Margin="10"
|
HorizontalAlignment="Center"
|
||||||
HorizontalAlignment="Center"
|
IsVisible="{Binding AppState.SelectedTab^.CurrentLocation^.Items^.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}"
|
||||||
FontWeight="Bold"
|
Margin="10"
|
||||||
Foreground="{DynamicResource ErrorBrush}"
|
x:CompileBindings="False"
|
||||||
IsVisible="{Binding AppState.SelectedTab^.CurrentLocation^.Items^.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}">
|
x:Name="CurrentEmpty">
|
||||||
Empty
|
Empty
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Rectangle
|
<Rectangle
|
||||||
Grid.Column="3"
|
Fill="{DynamicResource ContentSeparatorBrush}"
|
||||||
Width="1"
|
Grid.Column="3"
|
||||||
Margin="0,10,0,10"
|
HorizontalAlignment="Center"
|
||||||
HorizontalAlignment="Center"
|
Margin="0,10,0,10"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Fill="{DynamicResource ContentSeparatorBrush}" />
|
Width="1" />
|
||||||
|
|
||||||
</Grid>
|
<Grid Grid.Column="4">
|
||||||
</Grid>
|
<Grid IsVisible="{Binding AppState.SelectedTab^.SelectedsChildren^, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||||
</Grid>
|
<ListBox
|
||||||
</Grid>
|
AutoScrollToSelectedItem="True"
|
||||||
<!--Borders-->
|
Classes="ContentListView"
|
||||||
|
IsVisible="{Binding AppState.SelectedTab^.SelectedsChildren^.Count, Converter={StaticResource NotEqualsConverter}, ConverterParameter=0}"
|
||||||
|
Items="{Binding AppState.SelectedTab^.SelectedsChildren^}"
|
||||||
|
x:CompileBindings="False"
|
||||||
|
x:Name="ChildItems">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate x:DataType="corevm:IItemViewModel">
|
||||||
|
<local:ItemView />
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
|
||||||
</Grid>
|
<TextBlock
|
||||||
|
FontWeight="Bold"
|
||||||
|
Foreground="{DynamicResource ErrorBrush}"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
IsVisible="{Binding AppState.SelectedTab^.SelectedsChildren^.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}"
|
||||||
|
Margin="10"
|
||||||
|
x:CompileBindings="False"
|
||||||
|
x:Name="ChildEmpty">
|
||||||
|
Empty
|
||||||
|
</TextBlock>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<Grid IsVisible="{Binding Loading}">
|
<Grid IsVisible="{Binding AppState.SelectedTab^.SelectedsChildren^, Converter={x:Static ObjectConverters.IsNull}, ConverterParameter=0}" RowDefinitions="Auto, Auto">
|
||||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
<TextBlock
|
||||||
<Image Source="/Assets/filetime.ico" Width="128" Height="128"/>
|
Foreground="{DynamicResource ErrorBrush}"
|
||||||
<TextBlock Text="Loading..." HorizontalAlignment="Center" Margin="50"/>
|
HorizontalAlignment="Center"
|
||||||
</StackPanel>
|
Margin="0,0,0,10"
|
||||||
</Grid>
|
Text="There were some errors while opening container."
|
||||||
</Grid>
|
TextWrapping="Wrap" />
|
||||||
</Window>
|
|
||||||
|
<ItemsRepeater Grid.Row="1" Items="{Binding AppState.SelectedTab^.CurrentSelectedItem^.BaseItem.Exceptions^}">
|
||||||
|
<ItemsRepeater.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Margin="5,0,5,10" Text="{Binding Converter={StaticResource ExceptionToStringConverter}}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsRepeater.ItemTemplate>
|
||||||
|
</ItemsRepeater>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<!-- Borders -->
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid IsVisible="{Binding Loading}">
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<Image
|
||||||
|
Height="128"
|
||||||
|
Source="/Assets/filetime.ico"
|
||||||
|
Width="128" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="50"
|
||||||
|
Text="Loading..." />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
@@ -31,23 +31,80 @@ namespace FileTime.Providers.Local
|
|||||||
Items.OnNext(rootDirectories.Select(DirectoryToAbsolutePath).ToList());
|
Items.OnNext(rootDirectories.Select(DirectoryToAbsolutePath).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<IItem> GetItemByNativePathAsync(NativePath nativePath)
|
public override Task<IItem> GetItemByNativePathAsync(NativePath nativePath, bool forceResolve = false, AbsolutePathType forceResolvePathType = AbsolutePathType.Unknown)
|
||||||
{
|
{
|
||||||
var path = nativePath.Path;
|
var path = nativePath.Path;
|
||||||
if ((path?.Length ?? 0) == 0)
|
try
|
||||||
{
|
{
|
||||||
return Task.FromResult((IItem)this);
|
if ((path?.Length ?? 0) == 0)
|
||||||
}
|
{
|
||||||
else if (Directory.Exists(path))
|
return Task.FromResult((IItem)this);
|
||||||
{
|
}
|
||||||
return Task.FromResult((IItem)DirectoryToContainer(new DirectoryInfo(path!.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar)));
|
else if (Directory.Exists(path))
|
||||||
}
|
{
|
||||||
else if (File.Exists(path))
|
return Task.FromResult((IItem)DirectoryToContainer(new DirectoryInfo(path!.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar)));
|
||||||
{
|
}
|
||||||
return Task.FromResult((IItem)FileToElement(new FileInfo(path)));
|
else if (File.Exists(path))
|
||||||
}
|
{
|
||||||
|
return Task.FromResult((IItem)FileToElement(new FileInfo(path)));
|
||||||
|
}
|
||||||
|
|
||||||
throw new FileNotFoundException("Directory or file not found", path);
|
var type = forceResolvePathType switch
|
||||||
|
{
|
||||||
|
AbsolutePathType.Container => "Directory",
|
||||||
|
AbsolutePathType.Element => "File",
|
||||||
|
_ => "Directory or file"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (forceResolvePathType == AbsolutePathType.Container) throw new DirectoryNotFoundException($"{type} not found: '{path}'");
|
||||||
|
throw new FileNotFoundException(type + " not found", path);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (!forceResolve) throw new Exception($"Could not resolve path '{nativePath.Path}' and {nameof(forceResolve)} is false.", e);
|
||||||
|
|
||||||
|
return forceResolvePathType switch
|
||||||
|
{
|
||||||
|
AbsolutePathType.Container => Task.FromResult((IItem)CreateEmptyContainer(nativePath, Observable.Return(new List<Exception>() { e }))),
|
||||||
|
AbsolutePathType.Element => Task.FromResult(CreateEmptyElement(nativePath)),
|
||||||
|
_ => throw new Exception($"Could not resolve path '{nativePath.Path}' and could not force create, because {nameof(forceResolvePathType)} is {nameof(AbsolutePathType.Unknown)}.", e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Container CreateEmptyContainer(NativePath nativePath, IObservable<IEnumerable<Exception>>? exceptions = null)
|
||||||
|
{
|
||||||
|
var nonNullExceptions = exceptions ?? Observable.Return(Enumerable.Empty<Exception>());
|
||||||
|
var name = nativePath.Path.Split(Path.DirectorySeparatorChar).LastOrDefault() ?? "???";
|
||||||
|
var fullName = GetFullName(nativePath);
|
||||||
|
|
||||||
|
var parentFullName = fullName.GetParent();
|
||||||
|
var parent = new AbsolutePath(
|
||||||
|
this,
|
||||||
|
parentFullName ?? new FullName(""),
|
||||||
|
AbsolutePathType.Container);
|
||||||
|
|
||||||
|
return new Container(
|
||||||
|
name,
|
||||||
|
name,
|
||||||
|
fullName,
|
||||||
|
nativePath,
|
||||||
|
parent,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
DateTime.MinValue,
|
||||||
|
SupportsDelete.False,
|
||||||
|
false,
|
||||||
|
"???",
|
||||||
|
this,
|
||||||
|
nonNullExceptions,
|
||||||
|
Observable.Return<IEnumerable<IAbsolutePath>?>(null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IItem CreateEmptyElement(NativePath nativePath)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<List<IAbsolutePath>> GetItemsByContainerAsync(FullName fullName) => Task.FromResult(GetItemsByContainer(fullName));
|
public override Task<List<IAbsolutePath>> GetItemsByContainerAsync(FullName fullName) => Task.FromResult(GetItemsByContainer(fullName));
|
||||||
@@ -88,6 +145,7 @@ namespace FileTime.Providers.Local
|
|||||||
true,
|
true,
|
||||||
GetDirectoryAttributes(directoryInfo),
|
GetDirectoryAttributes(directoryInfo),
|
||||||
this,
|
this,
|
||||||
|
Observable.Return(Enumerable.Empty<Exception>()),
|
||||||
Observable.Return(GetItemsByContainer(directoryInfo))
|
Observable.Return(GetItemsByContainer(directoryInfo))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -110,7 +168,8 @@ namespace FileTime.Providers.Local
|
|||||||
SupportsDelete.True,
|
SupportsDelete.True,
|
||||||
true,
|
true,
|
||||||
GetFileAttributes(fileInfo),
|
GetFileAttributes(fileInfo),
|
||||||
this
|
this,
|
||||||
|
Observable.Return(Enumerable.Empty<Exception>())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
src/Settings.XamlStyler
Normal file
42
src/Settings.XamlStyler
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"AttributesTolerance": 1,
|
||||||
|
"KeepFirstAttributeOnSameLine": false,
|
||||||
|
"MaxAttributeCharactersPerLine": 0,
|
||||||
|
"MaxAttributesPerLine": 1,
|
||||||
|
"NewlineExemptionElements": "RadialGradientBrush, GradientStop, LinearGradientBrush, ScaleTransform, SkewTransform, RotateTransform, TranslateTransform, Trigger, Condition, Setter",
|
||||||
|
"SeparateByGroups": false,
|
||||||
|
"AttributeIndentation": 0,
|
||||||
|
"AttributeIndentationStyle": 1,
|
||||||
|
"RemoveDesignTimeReferences": false,
|
||||||
|
"EnableAttributeReordering": true,
|
||||||
|
"AttributeOrderingRuleGroups": [
|
||||||
|
"x:Class",
|
||||||
|
"xmlns, xmlns:x",
|
||||||
|
"xmlns:*",
|
||||||
|
"x:Key, Key, x:Name, Name, x:Uid, Uid, Title",
|
||||||
|
"DataContext",
|
||||||
|
"Grid.Row, Grid.RowSpan, Grid.Column, Grid.ColumnSpan, Canvas.Left, Canvas.Top, Canvas.Right, Canvas.Bottom",
|
||||||
|
"Width, Height, MinWidth, MinHeight, MaxWidth, MaxHeight",
|
||||||
|
"Margin, Padding, HorizontalAlignment, VerticalAlignment, HorizontalContentAlignment, VerticalContentAlignment, Panel.ZIndex",
|
||||||
|
"*:*, *",
|
||||||
|
"PageSource, PageIndex, Offset, Color, TargetName, Property, Value, StartPoint, EndPoint",
|
||||||
|
"mc:Ignorable, d:IsDataSource, d:LayoutOverrides, d:IsStaticText",
|
||||||
|
"Storyboard.*, From, To, Duration"
|
||||||
|
],
|
||||||
|
"FirstLineAttributes": "",
|
||||||
|
"OrderAttributesByName": true,
|
||||||
|
"PutEndingBracketOnNewLine": false,
|
||||||
|
"RemoveEndingTagOfEmptyElement": true,
|
||||||
|
"SpaceBeforeClosingSlash": true,
|
||||||
|
"RootElementLineBreakRule": 0,
|
||||||
|
"ReorderVSM": 2,
|
||||||
|
"ReorderGridChildren": false,
|
||||||
|
"ReorderCanvasChildren": false,
|
||||||
|
"ReorderSetters": 0,
|
||||||
|
"FormatMarkupExtension": true,
|
||||||
|
"NoNewLineMarkupExtensions": "x:Bind, Binding",
|
||||||
|
"ThicknessSeparator": 2,
|
||||||
|
"ThicknessAttributes": "Margin, Padding, BorderThickness, ThumbnailClipMargin",
|
||||||
|
"FormatOnSave": true,
|
||||||
|
"CommentPadding": 2,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user