WIP CommandScheduler UI
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
namespace FileTime.App.Core.UserCommand;
|
||||||
|
|
||||||
|
public class PauseCommandSchedulerCommand : IIdentifiableUserCommand
|
||||||
|
{
|
||||||
|
public const string CommandName = "pause_command_scheduler";
|
||||||
|
public static PauseCommandSchedulerCommand Instance { get; } = new();
|
||||||
|
|
||||||
|
private PauseCommandSchedulerCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UserCommandID => CommandName;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace FileTime.App.Core.UserCommand;
|
||||||
|
|
||||||
|
public sealed class StartCommandSchedulerCommand : IIdentifiableUserCommand
|
||||||
|
{
|
||||||
|
public const string CommandName = "start_command_scheduler";
|
||||||
|
public static StartCommandSchedulerCommand Instance { get; } = new();
|
||||||
|
|
||||||
|
private StartCommandSchedulerCommand()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string UserCommandID => CommandName;
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Reactive.Subjects;
|
|
||||||
using FileTime.App.Core.Models.Enums;
|
using FileTime.App.Core.Models.Enums;
|
||||||
using FileTime.Core.Timeline;
|
using FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
|
||||||
namespace FileTime.App.Core.ViewModels;
|
namespace FileTime.App.Core.ViewModels;
|
||||||
|
|
||||||
@@ -13,6 +12,7 @@ public interface IAppState
|
|||||||
IObservable<ViewMode> ViewMode { get; }
|
IObservable<ViewMode> ViewMode { get; }
|
||||||
string RapidTravelText { get; set; }
|
string RapidTravelText { get; set; }
|
||||||
ITabViewModel? CurrentSelectedTab { get; }
|
ITabViewModel? CurrentSelectedTab { get; }
|
||||||
|
ITimelineViewModel TimelineViewModel { get; }
|
||||||
|
|
||||||
void AddTab(ITabViewModel tabViewModel);
|
void AddTab(ITabViewModel tabViewModel);
|
||||||
void RemoveTab(ITabViewModel tabViewModel);
|
void RemoveTab(ITabViewModel tabViewModel);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
|
||||||
|
public interface ICommandTimeStateViewModel
|
||||||
|
{
|
||||||
|
IObservable<int> TotalProgress { get; }
|
||||||
|
IObservable<string> DisplayLabel { get; }
|
||||||
|
IObservable<bool> IsSelected { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using FileTime.Core.Models;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
|
||||||
|
public interface IParallelCommandsViewModel
|
||||||
|
{
|
||||||
|
BindedCollection<ICommandTimeStateViewModel> Commands { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
|
||||||
|
public interface ITimelineViewModel
|
||||||
|
{
|
||||||
|
BindedCollection<IParallelCommandsViewModel> ParallelCommandsGroups { get; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using FileTime.App.Core.UserCommand;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.Services.UserCommandHandler;
|
||||||
|
|
||||||
|
public class CommandSchedulerUserCommandHandlerService : UserCommandHandlerServiceBase
|
||||||
|
{
|
||||||
|
private readonly ICommandScheduler _commandScheduler;
|
||||||
|
|
||||||
|
public CommandSchedulerUserCommandHandlerService(ICommandScheduler commandScheduler)
|
||||||
|
{
|
||||||
|
_commandScheduler = commandScheduler;
|
||||||
|
AddCommandHandlers(new IUserCommandHandler[]
|
||||||
|
{
|
||||||
|
new TypeUserCommandHandler<PauseCommandSchedulerCommand>(PauseCommandScheduler),
|
||||||
|
new TypeUserCommandHandler<StartCommandSchedulerCommand>(StartCommandScheduler),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task PauseCommandScheduler()
|
||||||
|
=> await _commandScheduler.SetRunningEnabledAsync(false);
|
||||||
|
|
||||||
|
private async Task StartCommandScheduler()
|
||||||
|
=> await _commandScheduler.SetRunningEnabledAsync(true);
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@ public class ItemManipulationUserCommandHandlerService : UserCommandHandlerServi
|
|||||||
SaveCurrentLocation(l => _currentLocation = l);
|
SaveCurrentLocation(l => _currentLocation = l);
|
||||||
SaveCurrentSelectedItem(i => _currentSelectedItem = i);
|
SaveCurrentSelectedItem(i => _currentSelectedItem = i);
|
||||||
|
|
||||||
_markedItems = new BindedCollection<FullName>(appState.SelectedTab.Select(t => t?.MarkedItems));
|
_markedItems = appState.SelectedTab.Select(t => t?.MarkedItems).ToBindedCollection();
|
||||||
|
|
||||||
AddCommandHandlers(new IUserCommandHandler[]
|
AddCommandHandlers(new IUserCommandHandler[]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using FileTime.App.Core.Services.UserCommandHandler;
|
|||||||
using FileTime.App.Core.StartupServices;
|
using FileTime.App.Core.StartupServices;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
using FileTime.App.Core.ViewModels.ItemPreview;
|
using FileTime.App.Core.ViewModels.ItemPreview;
|
||||||
|
using FileTime.App.Core.ViewModels.Timeline;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ public static class Startup
|
|||||||
serviceCollection.TryAddSingleton<IClipboardService, ClipboardService>();
|
serviceCollection.TryAddSingleton<IClipboardService, ClipboardService>();
|
||||||
serviceCollection.TryAddSingleton<IIdentifiableUserCommandService, IdentifiableUserCommandService>();
|
serviceCollection.TryAddSingleton<IIdentifiableUserCommandService, IdentifiableUserCommandService>();
|
||||||
serviceCollection.TryAddSingleton<IItemPreviewService, ItemPreviewService>();
|
serviceCollection.TryAddSingleton<IItemPreviewService, ItemPreviewService>();
|
||||||
|
serviceCollection.TryAddSingleton<ITimelineViewModel, TimelineViewModel>();
|
||||||
|
|
||||||
return serviceCollection
|
return serviceCollection
|
||||||
.AddCommandHandlers()
|
.AddCommandHandlers()
|
||||||
@@ -35,6 +37,7 @@ public static class Startup
|
|||||||
return serviceCollection
|
return serviceCollection
|
||||||
.AddSingleton<IUserCommandHandler, NavigationUserCommandHandlerService>()
|
.AddSingleton<IUserCommandHandler, NavigationUserCommandHandlerService>()
|
||||||
.AddSingleton<IUserCommandHandler, ItemManipulationUserCommandHandlerService>()
|
.AddSingleton<IUserCommandHandler, ItemManipulationUserCommandHandlerService>()
|
||||||
.AddSingleton<IUserCommandHandler, ToolUserCommandHandlerService>();
|
.AddSingleton<IUserCommandHandler, ToolUserCommandHandlerService>()
|
||||||
|
.AddSingleton<IUserCommandHandler, CommandSchedulerUserCommandHandlerService>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,9 @@ public class DefaultIdentifiableCommandHandlerRegister : IStartupHandler
|
|||||||
AddUserCommand(PasteCommand.Merge);
|
AddUserCommand(PasteCommand.Merge);
|
||||||
AddUserCommand(PasteCommand.Overwrite);
|
AddUserCommand(PasteCommand.Overwrite);
|
||||||
AddUserCommand(PasteCommand.Skip);
|
AddUserCommand(PasteCommand.Skip);
|
||||||
|
AddUserCommand(PauseCommandSchedulerCommand.Instance);
|
||||||
AddUserCommand(RefreshCommand.Instance);
|
AddUserCommand(RefreshCommand.Instance);
|
||||||
|
AddUserCommand(StartCommandSchedulerCommand.Instance);
|
||||||
AddUserCommand(SwitchToTabCommand.SwitchToLastTab);
|
AddUserCommand(SwitchToTabCommand.SwitchToLastTab);
|
||||||
AddUserCommand(SwitchToTabCommand.SwitchToTab1);
|
AddUserCommand(SwitchToTabCommand.SwitchToTab1);
|
||||||
AddUserCommand(SwitchToTabCommand.SwitchToTab2);
|
AddUserCommand(SwitchToTabCommand.SwitchToTab2);
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ using System.Reactive.Linq;
|
|||||||
using System.Reactive.Subjects;
|
using System.Reactive.Subjects;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using FileTime.App.Core.Models.Enums;
|
using FileTime.App.Core.Models.Enums;
|
||||||
|
using FileTime.App.Core.ViewModels.Timeline;
|
||||||
using MvvmGen;
|
using MvvmGen;
|
||||||
using MoreLinq;
|
using MoreLinq;
|
||||||
|
|
||||||
namespace FileTime.App.Core.ViewModels;
|
namespace FileTime.App.Core.ViewModels;
|
||||||
|
|
||||||
[ViewModel]
|
[ViewModel]
|
||||||
|
[Inject(typeof(ITimelineViewModel), "TimelineViewModel", PropertyAccessModifier = AccessModifier.Public)]
|
||||||
public abstract partial class AppStateBase : IAppState
|
public abstract partial class AppStateBase : IAppState
|
||||||
{
|
{
|
||||||
private readonly BehaviorSubject<string?> _searchText = new(null);
|
private readonly BehaviorSubject<string?> _searchText = new(null);
|
||||||
@@ -76,7 +78,10 @@ public abstract partial class AppStateBase : IAppState
|
|||||||
|
|
||||||
private ITabViewModel? GetSelectedTab(IEnumerable<ITabViewModel> tabs, ITabViewModel? expectedSelectedTab)
|
private ITabViewModel? GetSelectedTab(IEnumerable<ITabViewModel> tabs, ITabViewModel? expectedSelectedTab)
|
||||||
{
|
{
|
||||||
var (preferred, others) = tabs.OrderBy(t => t.TabNumber).Partition(t => t.TabNumber >= (expectedSelectedTab?.TabNumber ?? 0));
|
var (preferred, others) =
|
||||||
|
tabs
|
||||||
|
.OrderBy(t => t.TabNumber)
|
||||||
|
.Partition(t => t.TabNumber >= (expectedSelectedTab?.TabNumber ?? 0));
|
||||||
return preferred.Concat(others.Reverse()).FirstOrDefault();
|
return preferred.Concat(others.Reverse()).FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System.Reactive.Subjects;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
|
||||||
|
public class CommandTimeStateViewModel : ICommandTimeStateViewModel
|
||||||
|
{
|
||||||
|
public IObservable<int> TotalProgress { get; }
|
||||||
|
|
||||||
|
public IObservable<string> DisplayLabel { get; }
|
||||||
|
|
||||||
|
public IObservable<bool> IsSelected { get; }
|
||||||
|
|
||||||
|
public CommandTimeStateViewModel(CommandTimeState commandTimeState)
|
||||||
|
{
|
||||||
|
DisplayLabel = commandTimeState.Command.DisplayLabel;
|
||||||
|
TotalProgress = commandTimeState.Command.TotalProgress;
|
||||||
|
//TODO
|
||||||
|
IsSelected = new BehaviorSubject<bool>(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using DynamicData.Alias;
|
||||||
|
using FileTime.Core.Extensions;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
|
||||||
|
public class ParallelCommandsViewModel : IParallelCommandsViewModel
|
||||||
|
{
|
||||||
|
public BindedCollection<ICommandTimeStateViewModel> Commands { get; }
|
||||||
|
|
||||||
|
public ParallelCommandsViewModel(ParallelCommands parallelCommands)
|
||||||
|
{
|
||||||
|
Commands = parallelCommands
|
||||||
|
.Commands
|
||||||
|
.Select(c => new CommandTimeStateViewModel(c) as ICommandTimeStateViewModel)
|
||||||
|
.ToBindedCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using DynamicData.Alias;
|
||||||
|
using FileTime.Core.Extensions;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
|
||||||
|
public class TimelineViewModel : ITimelineViewModel
|
||||||
|
{
|
||||||
|
public BindedCollection<IParallelCommandsViewModel> ParallelCommandsGroups { get; }
|
||||||
|
|
||||||
|
public TimelineViewModel(ICommandScheduler commandScheduler)
|
||||||
|
{
|
||||||
|
ParallelCommandsGroups =
|
||||||
|
commandScheduler
|
||||||
|
.CommandsToRun
|
||||||
|
.Select(p => new ParallelCommandsViewModel(p) as IParallelCommandsViewModel)
|
||||||
|
.ToBindedCollection();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ namespace FileTime.Core.Command;
|
|||||||
|
|
||||||
public enum ExecutionState
|
public enum ExecutionState
|
||||||
{
|
{
|
||||||
|
Initializing,
|
||||||
Waiting,
|
Waiting,
|
||||||
Running,
|
Running,
|
||||||
Finished
|
Finished
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ namespace FileTime.Core.Command;
|
|||||||
|
|
||||||
public interface ICommand
|
public interface ICommand
|
||||||
{
|
{
|
||||||
|
IObservable<string> DisplayLabel { get; }
|
||||||
|
IObservable<int> TotalProgress { get; }
|
||||||
|
IObservable<int> CurrentProgress { get; }
|
||||||
|
|
||||||
Task<CanCommandRun> CanRun(PointInTime currentTime);
|
Task<CanCommandRun> CanRun(PointInTime currentTime);
|
||||||
Task<PointInTime> SimulateCommand(PointInTime currentTime);
|
Task<PointInTime> SimulateCommand(PointInTime currentTime);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using DynamicData;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
|
namespace FileTime.Core.Extensions;
|
||||||
|
|
||||||
|
public static class BindedCollectionExtensions
|
||||||
|
{
|
||||||
|
public static BindedCollection<T> ToBindedCollection<T>(this IObservable<IChangeSet<T>> source)
|
||||||
|
{
|
||||||
|
return new BindedCollection<T>(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BindedCollection<T> ToBindedCollection<T>(this IObservable<IObservable<IChangeSet<T>>?> source)
|
||||||
|
{
|
||||||
|
return new BindedCollection<T>(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BindedCollection<T, TKey> ToBindedCollection<T, TKey>(this IObservable<IChangeSet<T, TKey>> source) where TKey : notnull
|
||||||
|
{
|
||||||
|
return new BindedCollection<T, TKey>(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BindedCollection<T, TKey> ToBindedCollection<T, TKey>(this IObservable<IObservable<IChangeSet<T, TKey>>?> source) where TKey : notnull
|
||||||
|
{
|
||||||
|
return new BindedCollection<T, TKey>(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ public static class DynamicDataExtensions
|
|||||||
this IObservable<IChangeSet<AbsolutePath, string>> stream)
|
this IObservable<IChangeSet<AbsolutePath, string>> stream)
|
||||||
=> await GetItemsAsync(stream.ToCollection());
|
=> await GetItemsAsync(stream.ToCollection());
|
||||||
|
|
||||||
private static Task<IEnumerable<AbsolutePath>?> GetItemsAsync(
|
public static Task<IEnumerable<AbsolutePath>?> GetItemsAsync(
|
||||||
this IObservable<IReadOnlyCollection<AbsolutePath>> stream)
|
this IObservable<IReadOnlyCollection<AbsolutePath>> stream)
|
||||||
{
|
{
|
||||||
var taskCompletionSource = new TaskCompletionSource<IEnumerable<AbsolutePath>?>();
|
var taskCompletionSource = new TaskCompletionSource<IEnumerable<AbsolutePath>?>();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.ComponentModel;
|
|||||||
using DynamicData;
|
using DynamicData;
|
||||||
using PropertyChanged.SourceGenerator;
|
using PropertyChanged.SourceGenerator;
|
||||||
|
|
||||||
namespace FileTime.App.Core.Models;
|
namespace FileTime.Core.Models;
|
||||||
|
|
||||||
public partial class BindedCollection<T> : IDisposable, INotifyPropertyChanged
|
public partial class BindedCollection<T> : IDisposable, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
@@ -4,18 +4,50 @@ namespace FileTime.Core.Timeline;
|
|||||||
|
|
||||||
public class CommandTimeState
|
public class CommandTimeState
|
||||||
{
|
{
|
||||||
|
private object _executionStateLock = new object();
|
||||||
|
private ExecutionState _executionState;
|
||||||
public ICommand Command { get; }
|
public ICommand Command { get; }
|
||||||
public CanCommandRun CanRun { get; private set; } = CanCommandRun.False;
|
public CanCommandRun CanRun { get; private set; } = CanCommandRun.False;
|
||||||
public bool ForceRun { get; set; }
|
public bool ForceRun { get; set; }
|
||||||
public ExecutionState ExecutionState { get; set; }
|
|
||||||
|
public ExecutionState ExecutionState
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_executionStateLock)
|
||||||
|
{
|
||||||
|
return _executionState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock (_executionStateLock)
|
||||||
|
{
|
||||||
|
_executionState = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public CommandTimeState(ICommand command)
|
public CommandTimeState(ICommand command)
|
||||||
{
|
{
|
||||||
Command = command;
|
Command = command;
|
||||||
|
SetToWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateStateAsync(PointInTime? startPoint)
|
public async Task UpdateStateAsync(PointInTime? startPoint)
|
||||||
{
|
{
|
||||||
CanRun = startPoint == null ? CanCommandRun.False : await Command.CanRun(startPoint);
|
CanRun = startPoint == null ? CanCommandRun.False : await Command.CanRun(startPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void SetToWait()
|
||||||
|
{
|
||||||
|
// This command won't be shown in the scheduler until this timeout is over
|
||||||
|
// Short living commands while not "blink on" the list
|
||||||
|
await Task.Delay(100);
|
||||||
|
lock (_executionStateLock)
|
||||||
|
{
|
||||||
|
if (_executionState == ExecutionState.Initializing)
|
||||||
|
_executionState = ExecutionState.Waiting;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using DynamicData;
|
||||||
using FileTime.Core.Command;
|
using FileTime.Core.Command;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
@@ -7,5 +8,8 @@ public interface ICommandScheduler
|
|||||||
{
|
{
|
||||||
Task AddCommand(ICommand command, int? batchId = null, bool toNewBatch = false);
|
Task AddCommand(ICommand command, int? batchId = null, bool toNewBatch = false);
|
||||||
IObservable<FullName> ContainerToRefresh { get; }
|
IObservable<FullName> ContainerToRefresh { get; }
|
||||||
|
IObservable<IChangeSet<ParallelCommands>> CommandsToRun { get; }
|
||||||
|
bool IsRunningEnabled { get; }
|
||||||
void RefreshContainer(FullName container);
|
void RefreshContainer(FullName container);
|
||||||
|
Task SetRunningEnabledAsync(bool value);
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,32 @@
|
|||||||
|
using DynamicData;
|
||||||
using FileTime.Core.Command;
|
using FileTime.Core.Command;
|
||||||
|
using FileTime.Core.Extensions;
|
||||||
|
using FileTime.Core.Models;
|
||||||
|
|
||||||
namespace FileTime.Core.Timeline;
|
namespace FileTime.Core.Timeline;
|
||||||
|
|
||||||
public class ParallelCommands
|
public class ParallelCommands : IDisposable
|
||||||
{
|
{
|
||||||
private static ushort _idCounter;
|
private static ushort _idCounter;
|
||||||
private List<CommandTimeState> _commands;
|
private readonly SourceList<CommandTimeState> _commands;
|
||||||
|
private PointInTime? _startTime;
|
||||||
|
|
||||||
public ushort Id { get; }
|
public ushort Id { get; }
|
||||||
public IReadOnlyList<CommandTimeState> Commands { get; }
|
|
||||||
|
public IObservable<IChangeSet<CommandTimeState>> Commands { get; }
|
||||||
|
|
||||||
|
public BindedCollection<CommandTimeState> CommandsCollection { get; }
|
||||||
|
|
||||||
public PointInTime? Result { get; private set; }
|
public PointInTime? Result { get; private set; }
|
||||||
|
|
||||||
|
public PointInTime? StartTime => _startTime;
|
||||||
|
|
||||||
|
public async Task<PointInTime?> SetStartTimeAsync(PointInTime? startTime)
|
||||||
|
{
|
||||||
|
_startTime = startTime;
|
||||||
|
return await RefreshResult();
|
||||||
|
}
|
||||||
|
|
||||||
public ParallelCommands(PointInTime? result)
|
public ParallelCommands(PointInTime? result)
|
||||||
: this(new List<CommandTimeState>(), result)
|
: this(new List<CommandTimeState>(), result)
|
||||||
{
|
{
|
||||||
@@ -19,8 +36,10 @@ public class ParallelCommands
|
|||||||
{
|
{
|
||||||
Id = _idCounter++;
|
Id = _idCounter++;
|
||||||
|
|
||||||
_commands = commands;
|
_commands = new SourceList<CommandTimeState>();
|
||||||
Commands = _commands.AsReadOnly();
|
_commands.Edit((innerList) => innerList.AddRange(commands));
|
||||||
|
Commands = _commands.Connect();
|
||||||
|
CommandsCollection = Commands.ToBindedCollection();
|
||||||
|
|
||||||
Result = result;
|
Result = result;
|
||||||
}
|
}
|
||||||
@@ -63,10 +82,17 @@ public class ParallelCommands
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PointInTime?> RefreshResult(PointInTime? startPoint)
|
public async Task RemoveCommand(ICommand command)
|
||||||
{
|
{
|
||||||
var result = startPoint;
|
var commandTimeState = _commands.Items.First(c => c.Command == command);
|
||||||
foreach (var commandTimeState in _commands)
|
_commands.Remove(commandTimeState);
|
||||||
|
await RefreshResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PointInTime?> RefreshResult()
|
||||||
|
{
|
||||||
|
var result = StartTime;
|
||||||
|
foreach (var commandTimeState in _commands.Items)
|
||||||
{
|
{
|
||||||
await commandTimeState.UpdateStateAsync(result);
|
await commandTimeState.UpdateStateAsync(result);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
@@ -87,7 +113,8 @@ public class ParallelCommands
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveAt(int number) => _commands.RemoveAt(number);
|
public void Dispose()
|
||||||
|
{
|
||||||
internal void Remove(CommandTimeState command) => _commands.Remove(command);
|
CommandsCollection.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
36
src/Core/FileTime.Core.Command/CommandBase.cs
Normal file
36
src/Core/FileTime.Core.Command/CommandBase.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Subjects;
|
||||||
|
using FileTime.Core.Timeline;
|
||||||
|
|
||||||
|
namespace FileTime.Core.Command;
|
||||||
|
|
||||||
|
public abstract class CommandBase : ICommand
|
||||||
|
{
|
||||||
|
private readonly BehaviorSubject<string> _displayLabel;
|
||||||
|
private readonly BehaviorSubject<int> _totalProgress;
|
||||||
|
private readonly BehaviorSubject<int> _currentProgress;
|
||||||
|
|
||||||
|
public IObservable<string> DisplayLabel { get; }
|
||||||
|
public IObservable<int> TotalProgress { get; }
|
||||||
|
public IObservable<int> CurrentProgress { get; }
|
||||||
|
|
||||||
|
protected CommandBase(string displayLabel = "", int totalProgress = 0, int currentProgress = 0)
|
||||||
|
{
|
||||||
|
_displayLabel = new(displayLabel);
|
||||||
|
_totalProgress = new(totalProgress);
|
||||||
|
_currentProgress = new(currentProgress);
|
||||||
|
|
||||||
|
DisplayLabel = _displayLabel.AsObservable();
|
||||||
|
TotalProgress = _totalProgress.AsObservable();
|
||||||
|
CurrentProgress = _currentProgress.AsObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Task<CanCommandRun> CanRun(PointInTime currentTime);
|
||||||
|
public abstract Task<PointInTime> SimulateCommand(PointInTime currentTime);
|
||||||
|
|
||||||
|
protected void SetDisplayLabel(string displayLabel) => _displayLabel.OnNext(displayLabel);
|
||||||
|
|
||||||
|
protected void SetTotalProgress(int totalProgress) => _totalProgress.OnNext(totalProgress);
|
||||||
|
|
||||||
|
protected void SetCurrentProgress(int currentProgress) => _currentProgress.OnNext(currentProgress);
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ using FileTime.Core.Timeline;
|
|||||||
|
|
||||||
namespace FileTime.Core.Command.Copy;
|
namespace FileTime.Core.Command.Copy;
|
||||||
|
|
||||||
public class CopyCommand : ITransportationCommand
|
public class CopyCommand : CommandBase, ITransportationCommand
|
||||||
{
|
{
|
||||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||||
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
|
private readonly ICommandSchedulerNotifier _commandSchedulerNotifier;
|
||||||
@@ -22,18 +22,19 @@ public class CopyCommand : ITransportationCommand
|
|||||||
public CopyCommand(
|
public CopyCommand(
|
||||||
ITimelessContentProvider timelessContentProvider,
|
ITimelessContentProvider timelessContentProvider,
|
||||||
ICommandSchedulerNotifier commandSchedulerNotifier)
|
ICommandSchedulerNotifier commandSchedulerNotifier)
|
||||||
|
: base("Copy")
|
||||||
{
|
{
|
||||||
_timelessContentProvider = timelessContentProvider;
|
_timelessContentProvider = timelessContentProvider;
|
||||||
_commandSchedulerNotifier = commandSchedulerNotifier;
|
_commandSchedulerNotifier = commandSchedulerNotifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<CanCommandRun> CanRun(PointInTime currentTime)
|
public override Task<CanCommandRun> CanRun(PointInTime currentTime)
|
||||||
{
|
{
|
||||||
//TODO:
|
//TODO:
|
||||||
return Task.FromResult(CanCommandRun.True);
|
return Task.FromResult(CanCommandRun.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PointInTime> SimulateCommand(PointInTime currentTime)
|
public override async Task<PointInTime> SimulateCommand(PointInTime currentTime)
|
||||||
{
|
{
|
||||||
if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null");
|
if (Sources == null) throw new ArgumentException(nameof(Sources) + " can not be null");
|
||||||
if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null");
|
if (Target == null) throw new ArgumentException(nameof(Target) + " can not be null");
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using InitableService;
|
|||||||
|
|
||||||
namespace FileTime.Core.Command.Create;
|
namespace FileTime.Core.Command.Create;
|
||||||
|
|
||||||
public abstract class CreateItemBase : IExecutableCommand, IInitable<FullName, string>
|
public abstract class CreateItemBase : CommandBase, IExecutableCommand, IInitable<FullName, string>
|
||||||
{
|
{
|
||||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||||
@@ -17,12 +17,13 @@ public abstract class CreateItemBase : IExecutableCommand, IInitable<FullName, s
|
|||||||
protected CreateItemBase(
|
protected CreateItemBase(
|
||||||
ITimelessContentProvider timelessContentProvider,
|
ITimelessContentProvider timelessContentProvider,
|
||||||
IContentAccessorFactory contentAccessorFactory)
|
IContentAccessorFactory contentAccessorFactory)
|
||||||
|
: base("Create")
|
||||||
{
|
{
|
||||||
_timelessContentProvider = timelessContentProvider;
|
_timelessContentProvider = timelessContentProvider;
|
||||||
_contentAccessorFactory = contentAccessorFactory;
|
_contentAccessorFactory = contentAccessorFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CanCommandRun> CanRun(PointInTime currentTime)
|
public override async Task<CanCommandRun> CanRun(PointInTime currentTime)
|
||||||
{
|
{
|
||||||
if (Parent is null)
|
if (Parent is null)
|
||||||
{
|
{
|
||||||
@@ -49,7 +50,7 @@ public abstract class CreateItemBase : IExecutableCommand, IInitable<FullName, s
|
|||||||
return existingItem switch
|
return existingItem switch
|
||||||
{
|
{
|
||||||
null => CanCommandRun.True,
|
null => CanCommandRun.True,
|
||||||
{ Type: AbsolutePathType.Container } => CanCommandRun.Forcable,
|
{Type: AbsolutePathType.Container} => CanCommandRun.Forcable,
|
||||||
_ => CanCommandRun.False
|
_ => CanCommandRun.False
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -60,7 +61,7 @@ public abstract class CreateItemBase : IExecutableCommand, IInitable<FullName, s
|
|||||||
return CanCommandRun.False;
|
return CanCommandRun.False;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<PointInTime> SimulateCommand(PointInTime currentTime)
|
public override Task<PointInTime> SimulateCommand(PointInTime currentTime)
|
||||||
{
|
{
|
||||||
if (Parent is null)
|
if (Parent is null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using FileTime.Core.Timeline;
|
|||||||
|
|
||||||
namespace FileTime.Core.Command.Delete;
|
namespace FileTime.Core.Command.Delete;
|
||||||
|
|
||||||
public class DeleteCommand : IExecutableCommand
|
public class DeleteCommand : CommandBase, IExecutableCommand
|
||||||
{
|
{
|
||||||
private readonly IContentAccessorFactory _contentAccessorFactory;
|
private readonly IContentAccessorFactory _contentAccessorFactory;
|
||||||
private readonly ITimelessContentProvider _timelessContentProvider;
|
private readonly ITimelessContentProvider _timelessContentProvider;
|
||||||
@@ -15,18 +15,19 @@ public class DeleteCommand : IExecutableCommand
|
|||||||
public DeleteCommand(
|
public DeleteCommand(
|
||||||
IContentAccessorFactory contentAccessorFactory,
|
IContentAccessorFactory contentAccessorFactory,
|
||||||
ITimelessContentProvider timelessContentProvider)
|
ITimelessContentProvider timelessContentProvider)
|
||||||
|
: base("Delete")
|
||||||
{
|
{
|
||||||
_contentAccessorFactory = contentAccessorFactory;
|
_contentAccessorFactory = contentAccessorFactory;
|
||||||
_timelessContentProvider = timelessContentProvider;
|
_timelessContentProvider = timelessContentProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<CanCommandRun> CanRun(PointInTime currentTime)
|
public override Task<CanCommandRun> CanRun(PointInTime currentTime)
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
return Task.FromResult(CanCommandRun.True);
|
return Task.FromResult(CanCommandRun.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<PointInTime> SimulateCommand(PointInTime currentTime)
|
public override Task<PointInTime> SimulateCommand(PointInTime currentTime)
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
return Task.FromResult(currentTime);
|
return Task.FromResult(currentTime);
|
||||||
@@ -38,8 +39,8 @@ public class DeleteCommand : IExecutableCommand
|
|||||||
|
|
||||||
//Delete
|
//Delete
|
||||||
await TraverseTree(
|
await TraverseTree(
|
||||||
PointInTime.Present,
|
PointInTime.Present,
|
||||||
ItemsToDelete,
|
ItemsToDelete,
|
||||||
new Dictionary<string, IItemDeleter>(),
|
new Dictionary<string, IItemDeleter>(),
|
||||||
new DeleteStrategy()
|
new DeleteStrategy()
|
||||||
);
|
);
|
||||||
@@ -69,9 +70,9 @@ public class DeleteCommand : IExecutableCommand
|
|||||||
if (itemToDelete is IContainer container)
|
if (itemToDelete is IContainer container)
|
||||||
{
|
{
|
||||||
await TraverseTree(
|
await TraverseTree(
|
||||||
currentTime,
|
currentTime,
|
||||||
(await container.Items.GetItemsAsync())?.Select(i => i.Path) ?? Enumerable.Empty<FullName>(),
|
(await container.Items.GetItemsAsync())?.Select(i => i.Path) ?? Enumerable.Empty<FullName>(),
|
||||||
itemDeleters,
|
itemDeleters,
|
||||||
deleteStrategy
|
deleteStrategy
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,28 +13,31 @@ public class CommandScheduler : ICommandScheduler
|
|||||||
private readonly Subject<FullName> _containerToRefresh = new();
|
private readonly Subject<FullName> _containerToRefresh = new();
|
||||||
|
|
||||||
private readonly object _guard = new();
|
private readonly object _guard = new();
|
||||||
private bool _enableRunning = true;
|
private bool _isRunningEnabled = true;
|
||||||
private bool _resourceIsInUse;
|
private bool _resourceIsInUse;
|
||||||
|
|
||||||
public IObservable<FullName> ContainerToRefresh { get; }
|
public IObservable<FullName> ContainerToRefresh { get; }
|
||||||
|
|
||||||
public bool EnableRunning
|
public bool IsRunningEnabled => _isRunningEnabled;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var result = true;
|
|
||||||
RunWithLock(() => result = _enableRunning);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
set { RunWithLock(() => _enableRunning = value); }
|
public async Task SetRunningEnabledAsync(bool value)
|
||||||
|
{
|
||||||
|
_isRunningEnabled = value;
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
await RunWithLockAsync(ExecuteCommands);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IObservable<IChangeSet<ParallelCommands>> CommandsToRun { get; }
|
||||||
|
|
||||||
public CommandScheduler(ILocalCommandExecutor localExecutor)
|
public CommandScheduler(ILocalCommandExecutor localExecutor)
|
||||||
{
|
{
|
||||||
|
CommandsToRun = _commandsToRun.Connect();
|
||||||
|
|
||||||
ContainerToRefresh = _containerToRefresh.AsObservable();
|
ContainerToRefresh = _containerToRefresh.AsObservable();
|
||||||
|
|
||||||
localExecutor.CommandFinished += LocalExecutorOnCommandFinished;
|
localExecutor.CommandFinished += ExecutorOnCommandFinished;
|
||||||
_commandExecutors.Add(localExecutor);
|
_commandExecutors.Add(localExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +49,7 @@ public class CommandScheduler : ICommandScheduler
|
|||||||
|
|
||||||
if (_commandsToRun.Count == 0)
|
if (_commandsToRun.Count == 0)
|
||||||
{
|
{
|
||||||
|
//TODO: Add event handler to update
|
||||||
batchToAdd = new ParallelCommands(PointInTime.CreateEmpty());
|
batchToAdd = new ParallelCommands(PointInTime.CreateEmpty());
|
||||||
_commandsToRun.Add(batchToAdd);
|
_commandsToRun.Add(batchToAdd);
|
||||||
}
|
}
|
||||||
@@ -82,13 +86,11 @@ public class CommandScheduler : ICommandScheduler
|
|||||||
|
|
||||||
private void ExecuteCommands()
|
private void ExecuteCommands()
|
||||||
{
|
{
|
||||||
if (!_enableRunning) return;
|
if (!_isRunningEnabled) return;
|
||||||
|
|
||||||
var parallelCommandsToExecute = _commandsToRun.Items.FirstOrDefault();
|
var commandsToExecute = _commandsToRun.Items.FirstOrDefault()?.CommandsCollection.Collection;
|
||||||
if (parallelCommandsToExecute is null ||
|
if (commandsToExecute is null || commandsToExecute.All(c => c.ExecutionState != ExecutionState.Initializing && c.ExecutionState != ExecutionState.Waiting)) return;
|
||||||
parallelCommandsToExecute.Commands.All(c => c.ExecutionState != ExecutionState.Waiting)) return;
|
|
||||||
|
|
||||||
var commandsToExecute = parallelCommandsToExecute.Commands;
|
|
||||||
|
|
||||||
foreach (var commandToExecute in commandsToExecute)
|
foreach (var commandToExecute in commandsToExecute)
|
||||||
{
|
{
|
||||||
@@ -108,15 +110,20 @@ public class CommandScheduler : ICommandScheduler
|
|||||||
return _commandExecutors[0];
|
return _commandExecutors[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LocalExecutorOnCommandFinished(object? sender, ICommand command)
|
private async void ExecutorOnCommandFinished(object? sender, ICommand command)
|
||||||
{
|
{
|
||||||
var parallelCommandsToExecute = _commandsToRun.Items.FirstOrDefault();
|
var firstCommandBlock = _commandsToRun
|
||||||
if (parallelCommandsToExecute is null) return;
|
.Items
|
||||||
|
.FirstOrDefault();
|
||||||
|
var state = firstCommandBlock
|
||||||
|
?.CommandsCollection
|
||||||
|
.Collection
|
||||||
|
?.FirstOrDefault(c => c.Command == command);
|
||||||
|
|
||||||
var state = parallelCommandsToExecute.Commands.FirstOrDefault(c => c.Command == command);
|
|
||||||
if (state is null) return;
|
if (state is null) return;
|
||||||
|
|
||||||
state.ExecutionState = ExecutionState.Finished;
|
state.ExecutionState = ExecutionState.Finished;
|
||||||
|
if (firstCommandBlock is not null) await firstCommandBlock.RemoveCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshCommands()
|
private async Task RefreshCommands()
|
||||||
@@ -125,7 +132,7 @@ public class CommandScheduler : ICommandScheduler
|
|||||||
|
|
||||||
foreach (var batch in _commandsToRun.Items)
|
foreach (var batch in _commandsToRun.Items)
|
||||||
{
|
{
|
||||||
currentTime = await batch.RefreshResult(currentTime);
|
currentTime = await batch.SetStartTimeAsync(currentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace FileTime.Core.Timeline;
|
|||||||
public class LocalCommandExecutor : ILocalCommandExecutor
|
public class LocalCommandExecutor : ILocalCommandExecutor
|
||||||
{
|
{
|
||||||
private readonly ICommandRunner _commandRunner;
|
private readonly ICommandRunner _commandRunner;
|
||||||
public event EventHandler<ICommand> CommandFinished;
|
public event EventHandler<ICommand>? CommandFinished;
|
||||||
|
|
||||||
public LocalCommandExecutor(ICommandRunner commandRunner)
|
public LocalCommandExecutor(ICommandRunner commandRunner)
|
||||||
{
|
{
|
||||||
@@ -15,7 +15,7 @@ public class LocalCommandExecutor : ILocalCommandExecutor
|
|||||||
public void ExecuteCommand(ICommand command)
|
public void ExecuteCommand(ICommand command)
|
||||||
{
|
{
|
||||||
var context = new CommandRunnerContext(command);
|
var context = new CommandRunnerContext(command);
|
||||||
var thread = new Thread(new ParameterizedThreadStart(RunCommand));
|
var thread = new Thread(RunCommand);
|
||||||
thread.Start(context);
|
thread.Start(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +29,6 @@ public class LocalCommandExecutor : ILocalCommandExecutor
|
|||||||
}
|
}
|
||||||
catch (Exception ex) { }
|
catch (Exception ex) { }
|
||||||
|
|
||||||
CommandFinished.Invoke(this, context.Command);
|
CommandFinished?.Invoke(this, context.Command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,7 @@ public static class MainConfiguration
|
|||||||
//new CommandBindingConfiguration(ConfigCommand.Cut, new[] { Key.D, Key.D }),
|
//new CommandBindingConfiguration(ConfigCommand.Cut, new[] { Key.D, Key.D }),
|
||||||
//new CommandBindingConfiguration(ConfigCommand.Edit, new KeyConfig(Key.F4)),
|
//new CommandBindingConfiguration(ConfigCommand.Edit, new KeyConfig(Key.F4)),
|
||||||
new(EnterRapidTravelCommand.CommandName,new KeyConfig(Key.OemComma, shift: true)),
|
new(EnterRapidTravelCommand.CommandName,new KeyConfig(Key.OemComma, shift: true)),
|
||||||
|
new(EnterRapidTravelCommand.CommandName,new KeyConfig(Key.OemQuestion, shift: true)),
|
||||||
//new CommandBindingConfiguration(ConfigCommand.FindByName, new[] { Key.F, Key.N }),
|
//new CommandBindingConfiguration(ConfigCommand.FindByName, new[] { Key.F, Key.N }),
|
||||||
//new CommandBindingConfiguration(ConfigCommand.FindByNameRegex, new[] { Key.F, Key.R }),
|
//new CommandBindingConfiguration(ConfigCommand.FindByNameRegex, new[] { Key.F, Key.R }),
|
||||||
new(GoToHomeCommand.CommandName, new[] { Key.G, Key.H }),
|
new(GoToHomeCommand.CommandName, new[] { Key.G, Key.H }),
|
||||||
@@ -92,9 +93,9 @@ public static class MainConfiguration
|
|||||||
new(SwitchToTabCommand.SwitchToTab6CommandName, Key.D6),
|
new(SwitchToTabCommand.SwitchToTab6CommandName, Key.D6),
|
||||||
new(SwitchToTabCommand.SwitchToTab7CommandName, Key.D7),
|
new(SwitchToTabCommand.SwitchToTab7CommandName, Key.D7),
|
||||||
new(SwitchToTabCommand.SwitchToTab8CommandName, Key.D8),
|
new(SwitchToTabCommand.SwitchToTab8CommandName, Key.D8),
|
||||||
//new CommandBindingConfiguration(ConfigCommand.TimelinePause, new[] { Key.T, Key.P }),
|
new (PauseCommandSchedulerCommand.CommandName, new[] { Key.T, Key.P }),
|
||||||
//new CommandBindingConfiguration(ConfigCommand.TimelineRefresh, new[] { Key.T, Key.R }),
|
//new CommandBindingConfiguration(ConfigCommand.TimelineRefresh, new[] { Key.T, Key.R }),
|
||||||
//new CommandBindingConfiguration(ConfigCommand.TimelineStart, new[] { Key.T, Key.S }),
|
new (StartCommandSchedulerCommand.CommandName, new[] { Key.T, Key.S }),
|
||||||
//new CommandBindingConfiguration(ConfigCommand.ToggleAdvancedIcons, new[] { Key.Z, Key.I }),
|
//new CommandBindingConfiguration(ConfigCommand.ToggleAdvancedIcons, new[] { Key.Z, Key.I }),
|
||||||
new(GoUpCommand.CommandName, Key.Left),
|
new(GoUpCommand.CommandName, Key.Left),
|
||||||
new(OpenSelectedCommand.CommandName, Key.Right),
|
new(OpenSelectedCommand.CommandName, Key.Right),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using FileTime.App.Core.Models;
|
using FileTime.App.Core.Models;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
|
using FileTime.Core.Models;
|
||||||
using FileTime.GuiApp.Configuration;
|
using FileTime.GuiApp.Configuration;
|
||||||
|
|
||||||
namespace FileTime.GuiApp.ViewModels;
|
namespace FileTime.GuiApp.ViewModels;
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using FileTime.App.Core.Models;
|
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
|
using FileTime.App.Core.ViewModels.Timeline;
|
||||||
|
using FileTime.Core.Models;
|
||||||
using FileTime.GuiApp.Configuration;
|
using FileTime.GuiApp.Configuration;
|
||||||
using FileTime.GuiApp.ViewModels;
|
using FileTime.GuiApp.ViewModels;
|
||||||
using MvvmGen;
|
using MvvmGen;
|
||||||
|
|
||||||
namespace FileTime.GuiApp.CustomImpl.ViewModels;
|
namespace FileTime.GuiApp.CustomImpl.ViewModels;
|
||||||
|
|
||||||
[ViewModel]
|
[ViewModel(GenerateConstructor = false)]
|
||||||
public partial class GuiAppState : AppStateBase, IGuiAppState
|
public partial class GuiAppState : AppStateBase, IGuiAppState
|
||||||
{
|
{
|
||||||
|
public GuiAppState(ITimelineViewModel timelineViewModel) : base(timelineViewModel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
[Property] private bool _isAllShortcutVisible;
|
[Property] private bool _isAllShortcutVisible;
|
||||||
|
|
||||||
[Property] private bool _noCommandFound;
|
[Property] private bool _noCommandFound;
|
||||||
@@ -18,7 +23,7 @@ public partial class GuiAppState : AppStateBase, IGuiAppState
|
|||||||
|
|
||||||
[Property] private BindedCollection<RootDriveInfo, string> _rootDriveInfos = new();
|
[Property] private BindedCollection<RootDriveInfo, string> _rootDriveInfos = new();
|
||||||
|
|
||||||
[Property] private IReadOnlyList<PlaceInfo> _places;
|
[Property] private IReadOnlyList<PlaceInfo> _places = new List<PlaceInfo>();
|
||||||
|
|
||||||
public List<KeyConfig> PreviousKeys { get; } = new();
|
public List<KeyConfig> PreviousKeys { get; } = new();
|
||||||
public ObservableCollection<string> PopupTexts { get; } = new();
|
public ObservableCollection<string> PopupTexts { get; } = new();
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<Styles xmlns="https://github.com/avaloniaui"
|
<Styles
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<Styles.Resources>
|
<Styles.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Converters.axaml"></ResourceInclude>
|
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Converters.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Styles.Resources>
|
</Styles.Resources>
|
||||||
@@ -28,7 +29,7 @@
|
|||||||
<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" />
|
||||||
@@ -61,10 +62,10 @@
|
|||||||
<ControlTemplate>
|
<ControlTemplate>
|
||||||
<Border>
|
<Border>
|
||||||
<RadioButton
|
<RadioButton
|
||||||
|
VerticalAlignment="Center"
|
||||||
Content="{TemplateBinding ContentPresenter.Content}"
|
Content="{TemplateBinding ContentPresenter.Content}"
|
||||||
Foreground="{DynamicResource ForegroundBrush}"
|
Foreground="{DynamicResource ForegroundBrush}"
|
||||||
IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
|
IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />
|
||||||
VerticalAlignment="Center" />
|
|
||||||
</Border>
|
</Border>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
@@ -74,9 +75,9 @@
|
|||||||
<Style Selector="Image.LoadingAnimation">
|
<Style Selector="Image.LoadingAnimation">
|
||||||
<Style.Animations>
|
<Style.Animations>
|
||||||
<Animation
|
<Animation
|
||||||
Duration="0:0:2"
|
|
||||||
Easing="QuadraticEaseInOut"
|
Easing="QuadraticEaseInOut"
|
||||||
IterationCount="INFINITE">
|
IterationCount="INFINITE"
|
||||||
|
Duration="0:0:2">
|
||||||
<KeyFrame Cue="0%">
|
<KeyFrame Cue="0%">
|
||||||
<Setter Property="RotateTransform.Angle" Value="45" />
|
<Setter Property="RotateTransform.Angle" Value="45" />
|
||||||
</KeyFrame>
|
</KeyFrame>
|
||||||
@@ -86,4 +87,8 @@
|
|||||||
</Animation>
|
</Animation>
|
||||||
</Style.Animations>
|
</Style.Animations>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Border.SelectedTimelineCommand">
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ForegroundBrush}" />
|
||||||
|
</Style>
|
||||||
</Styles>
|
</Styles>
|
||||||
@@ -4,6 +4,7 @@ using FileTime.App.Core.Models;
|
|||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
using FileTime.App.Core.UserCommand;
|
using FileTime.App.Core.UserCommand;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
|
using FileTime.Core.Extensions;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.GuiApp.Configuration;
|
using FileTime.GuiApp.Configuration;
|
||||||
using FileTime.GuiApp.Extensions;
|
using FileTime.GuiApp.Extensions;
|
||||||
@@ -43,8 +44,8 @@ public class DefaultModeKeyInputHandler : IDefaultModeKeyInputHandler
|
|||||||
|
|
||||||
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
||||||
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation!).Switch().Subscribe(l => _currentLocation = l);
|
_appState.SelectedTab.Select(t => t == null ? Observable.Return<IContainer?>(null) : t.CurrentLocation!).Switch().Subscribe(l => _currentLocation = l);
|
||||||
|
|
||||||
_openModals = new BindedCollection<IModalViewModel>(modalService.OpenModals);
|
_openModals = modalService.OpenModals.ToBindedCollection();
|
||||||
|
|
||||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Up) });
|
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Up) });
|
||||||
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Down) });
|
_keysToSkip.Add(new KeyConfig[] { new KeyConfig(Key.Down) });
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using FileTime.App.Core.Models;
|
|||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
using FileTime.App.Core.UserCommand;
|
using FileTime.App.Core.UserCommand;
|
||||||
using FileTime.App.Core.ViewModels;
|
using FileTime.App.Core.ViewModels;
|
||||||
|
using FileTime.Core.Extensions;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.Core.Services;
|
using FileTime.Core.Services;
|
||||||
using FileTime.GuiApp.Configuration;
|
using FileTime.GuiApp.Configuration;
|
||||||
@@ -42,7 +43,7 @@ public class RapidTravelModeKeyInputHandler : IRapidTravelModeKeyInputHandler
|
|||||||
|
|
||||||
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
_appState.SelectedTab.Subscribe(t => _selectedTab = t);
|
||||||
|
|
||||||
_openModals = new BindedCollection<IModalViewModel>(modalService.OpenModals);
|
_openModals = modalService.OpenModals.ToBindedCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
public async Task HandleInputKey(Key key, SpecialKeysStatus specialKeysStatus, Action<bool> setHandled)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using DynamicData;
|
|||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using FileTime.App.Core.Models;
|
using FileTime.App.Core.Models;
|
||||||
using FileTime.App.Core.Services;
|
using FileTime.App.Core.Services;
|
||||||
|
using FileTime.Core.Extensions;
|
||||||
using FileTime.Core.Models;
|
using FileTime.Core.Models;
|
||||||
using FileTime.Core.Timeline;
|
using FileTime.Core.Timeline;
|
||||||
using FileTime.GuiApp.ViewModels;
|
using FileTime.GuiApp.ViewModels;
|
||||||
@@ -16,7 +17,7 @@ public class RootDriveInfoService : IStartupHandler
|
|||||||
private readonly SourceList<DriveInfo> _rootDrives = new();
|
private readonly SourceList<DriveInfo> _rootDrives = new();
|
||||||
|
|
||||||
public RootDriveInfoService(
|
public RootDriveInfoService(
|
||||||
IGuiAppState guiAppState,
|
IGuiAppState guiAppState,
|
||||||
ILocalContentProvider localContentProvider,
|
ILocalContentProvider localContentProvider,
|
||||||
ITimelessContentProvider timelessContentProvider)
|
ITimelessContentProvider timelessContentProvider)
|
||||||
{
|
{
|
||||||
@@ -53,7 +54,7 @@ public class RootDriveInfoService : IStartupHandler
|
|||||||
.Transform(t => new RootDriveInfo(t.Drive, t.Container))
|
.Transform(t => new RootDriveInfo(t.Drive, t.Container))
|
||||||
.Sort(SortExpressionComparer<RootDriveInfo>.Ascending(d => d.Name));
|
.Sort(SortExpressionComparer<RootDriveInfo>.Ascending(d => d.Name));
|
||||||
|
|
||||||
guiAppState.RootDriveInfos = new BindedCollection<RootDriveInfo, string>(rootDriveInfos);
|
guiAppState.RootDriveInfos = rootDriveInfos.ToBindedCollection();
|
||||||
|
|
||||||
void InitRootDrives()
|
void InitRootDrives()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,35 +2,35 @@
|
|||||||
x:Class="FileTime.GuiApp.Views.MainWindow"
|
x:Class="FileTime.GuiApp.Views.MainWindow"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:appCoreModels="using:FileTime.App.Core.Models"
|
||||||
|
xmlns:config="using:FileTime.GuiApp.Configuration"
|
||||||
xmlns:corevm="using:FileTime.App.Core.ViewModels"
|
xmlns:corevm="using:FileTime.App.Core.ViewModels"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:interactions="using:FileTime.Core.Interactions"
|
||||||
xmlns:local="using:FileTime.GuiApp.Views"
|
xmlns:local="using:FileTime.GuiApp.Views"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:vm="using:FileTime.GuiApp.ViewModels"
|
xmlns:vm="using:FileTime.GuiApp.ViewModels"
|
||||||
xmlns:config="using:FileTime.GuiApp.Configuration"
|
|
||||||
xmlns:appCoreModels="using:FileTime.App.Core.Models"
|
|
||||||
xmlns:interactions="using:FileTime.Core.Interactions"
|
|
||||||
MinHeight="600"
|
|
||||||
MinWidth="800"
|
|
||||||
Title="FileTime"
|
Title="FileTime"
|
||||||
|
MinWidth="800"
|
||||||
|
MinHeight="600"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
x:CompileBindings="True"
|
x:CompileBindings="True"
|
||||||
x:DataType="vm:IMainWindowViewModelBase"
|
x:DataType="vm:IMainWindowViewModelBase"
|
||||||
Background="Transparent"
|
Background="Transparent"
|
||||||
|
Closed="OnWindowClosed"
|
||||||
ExtendClientAreaToDecorationsHint="True"
|
ExtendClientAreaToDecorationsHint="True"
|
||||||
Icon="/Assets/filetime.ico"
|
Icon="/Assets/filetime.ico"
|
||||||
InputElement.KeyDown="OnKeyDown"
|
InputElement.KeyDown="OnKeyDown"
|
||||||
Opened="OnWindowOpened"
|
Opened="OnWindowOpened"
|
||||||
Closed="OnWindowClosed"
|
|
||||||
TransparencyLevelHint="Blur"
|
TransparencyLevelHint="Blur"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/SolarizedDarkTheme.axaml"></ResourceInclude>
|
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/SolarizedDarkTheme.axaml" />
|
||||||
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Brushes.axaml"></ResourceInclude>
|
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Brushes.axaml" />
|
||||||
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Converters.axaml"></ResourceInclude>
|
<ResourceInclude Source="avares://FileTime.GuiApp/Resources/Converters.axaml" />
|
||||||
</ResourceDictionary.MergedDictionaries>
|
</ResourceDictionary.MergedDictionaries>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
@@ -62,18 +62,22 @@
|
|||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="20,10"
|
Margin="20,10"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<local:PathPresenter
|
<local:PathPresenter DataContext="{Binding AppState.SelectedTab^.CurrentLocation^.FullName.Path, Converter={StaticResource PathPreformatter}}" />
|
||||||
DataContext="{Binding AppState.SelectedTab^.CurrentLocation^.FullName.Path,Converter={StaticResource PathPreformatter}}" />
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Foreground="{StaticResource AccentBrush}"
|
Foreground="{StaticResource AccentBrush}"
|
||||||
Text="{Binding AppState.SelectedTab^.CurrentSelectedItem^.DisplayNameText}" />
|
Text="{Binding AppState.SelectedTab^.CurrentSelectedItem^.DisplayNameText}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid Grid.Row="1" RowDefinitions="Auto,Auto,Auto,Auto">
|
<Grid
|
||||||
|
Grid.Row="1"
|
||||||
|
RowDefinitions="Auto,Auto,Auto,Auto">
|
||||||
|
|
||||||
<Border CornerRadius="10" Background="{DynamicResource ContainerBackgroundBrush}" Padding="10"
|
<Border
|
||||||
Margin="10">
|
Margin="10"
|
||||||
|
Padding="10"
|
||||||
|
Background="{DynamicResource ContainerBackgroundBrush}"
|
||||||
|
CornerRadius="10">
|
||||||
<Grid RowDefinitions="Auto,Auto">
|
<Grid RowDefinitions="Auto,Auto">
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -85,10 +89,14 @@
|
|||||||
Items="{Binding AppState.RootDriveInfos.Collection}">
|
Items="{Binding AppState.RootDriveInfos.Collection}">
|
||||||
<ItemsRepeater.ItemTemplate>
|
<ItemsRepeater.ItemTemplate>
|
||||||
<DataTemplate x:DataType="vm:RootDriveInfo">
|
<DataTemplate x:DataType="vm:RootDriveInfo">
|
||||||
<Grid Classes="SidebarContainerPresenter"
|
<Grid
|
||||||
PointerPressed="OnHasContainerPointerPressed" Cursor="Hand">
|
Classes="SidebarContainerPresenter"
|
||||||
<Grid Margin="0,5" ColumnDefinitions="Auto,*,Auto"
|
Cursor="Hand"
|
||||||
RowDefinitions="Auto,Auto">
|
PointerPressed="OnHasContainerPointerPressed">
|
||||||
|
<Grid
|
||||||
|
Margin="0,5"
|
||||||
|
ColumnDefinitions="Auto,*,Auto"
|
||||||
|
RowDefinitions="Auto,Auto">
|
||||||
<Image
|
<Image
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
Width="20"
|
Width="20"
|
||||||
@@ -99,8 +107,8 @@
|
|||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -112,35 +120,38 @@
|
|||||||
Margin="5,0,0,0"
|
Margin="5,0,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="ExtraSmallText"
|
Classes="ExtraSmallText"
|
||||||
Text="{Binding Label}"
|
IsVisible="{Binding Label, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
|
||||||
IsVisible="{Binding Label,Converter={x:Static StringConverters.IsNotNullOrEmpty}}" />
|
Text="{Binding Label}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Orientation="Horizontal"
|
HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
|
||||||
<TextBlock Classes="SmallText" VerticalAlignment="Center"
|
<TextBlock
|
||||||
Text="{Binding Free, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}">
|
VerticalAlignment="Center"
|
||||||
</TextBlock>
|
Classes="SmallText"
|
||||||
|
Text="{Binding Free, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}" />
|
||||||
|
|
||||||
<TextBlock Classes="SmallText" VerticalAlignment="Center"
|
<TextBlock
|
||||||
Text=" / ">
|
VerticalAlignment="Center"
|
||||||
</TextBlock>
|
Classes="SmallText"
|
||||||
|
Text=" / " />
|
||||||
|
|
||||||
<TextBlock Classes="SmallText" VerticalAlignment="Center"
|
<TextBlock
|
||||||
Text="{Binding Size, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}">
|
VerticalAlignment="Center"
|
||||||
</TextBlock>
|
Classes="SmallText"
|
||||||
|
Text="{Binding Size, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
Margin="5,0,0,0"
|
Grid.Row="1"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.ColumnSpan="2"
|
Grid.ColumnSpan="2"
|
||||||
Grid.Row="1"
|
|
||||||
MinWidth="100"
|
MinWidth="100"
|
||||||
|
Margin="5,0,0,0"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Maximum="100"
|
Maximum="100"
|
||||||
Value="{Binding UsedPercentage}" />
|
Value="{Binding UsedPercentage}" />
|
||||||
@@ -152,8 +163,12 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border Grid.Row="1" CornerRadius="10" Background="{DynamicResource ContainerBackgroundBrush}"
|
<Border
|
||||||
Padding="0,10" Margin="10">
|
Grid.Row="1"
|
||||||
|
Margin="10"
|
||||||
|
Padding="0,10"
|
||||||
|
Background="{DynamicResource ContainerBackgroundBrush}"
|
||||||
|
CornerRadius="10">
|
||||||
<Grid RowDefinitions="Auto,Auto">
|
<Grid RowDefinitions="Auto,Auto">
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
@@ -165,15 +180,19 @@
|
|||||||
Items="{Binding AppState.Places}">
|
Items="{Binding AppState.Places}">
|
||||||
<ItemsRepeater.ItemTemplate>
|
<ItemsRepeater.ItemTemplate>
|
||||||
<DataTemplate x:DataType="vm:PlaceInfo">
|
<DataTemplate x:DataType="vm:PlaceInfo">
|
||||||
<Grid Classes="SidebarContainerPresenter"
|
<Grid
|
||||||
PointerPressed="OnHasContainerPointerPressed" Cursor="Hand">
|
Classes="SidebarContainerPresenter"
|
||||||
<StackPanel Orientation="Horizontal" Margin="10,5"
|
Cursor="Hand"
|
||||||
HorizontalAlignment="Stretch">
|
PointerPressed="OnHasContainerPointerPressed">
|
||||||
|
<StackPanel
|
||||||
|
Margin="10,5"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Orientation="Horizontal">
|
||||||
<Image
|
<Image
|
||||||
Width="20"
|
Width="20"
|
||||||
Height="20"
|
Height="20"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Source="{Binding Container,Converter={StaticResource ItemToImageConverter}}" />
|
Source="{Binding Container, Converter={StaticResource ItemToImageConverter}}" />
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="5,0,0,0"
|
Margin="5,0,0,0"
|
||||||
@@ -258,6 +277,46 @@
|
|||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
RowDefinitions="Auto,40,*,Auto">
|
RowDefinitions="Auto,40,*,Auto">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<ItemsControl Items="{Binding AppState.TimelineViewModel.ParallelCommandsGroups.Collection}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border
|
||||||
|
MaxHeight="200"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Padding="5"
|
||||||
|
Background="{DynamicResource ContainerBackgroundColor}"
|
||||||
|
CornerRadius="10">
|
||||||
|
<ScrollViewer>
|
||||||
|
<ItemsControl Items="{Binding Commands.Collection}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border
|
||||||
|
BorderThickness="1"
|
||||||
|
Classes.SelectedTimelineCommand="{Binding IsSelected}">
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="{Binding DisplayLabel^}" />
|
||||||
|
<ProgressBar
|
||||||
|
Margin="0,5,0,0"
|
||||||
|
Maximum="100"
|
||||||
|
Value="{Binding TotalProgress^}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
<ItemsControl
|
<ItemsControl
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Items="{Binding AppState.Tabs}">
|
Items="{Binding AppState.Tabs}">
|
||||||
@@ -308,9 +367,9 @@
|
|||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate x:DataType="corevm:IItemViewModel">
|
<DataTemplate x:DataType="corevm:IItemViewModel">
|
||||||
<local:ItemView
|
<local:ItemView
|
||||||
ShowAttributes="False"
|
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
HorizontalContentAlignment="Stretch" />
|
HorizontalContentAlignment="Stretch"
|
||||||
|
ShowAttributes="False" />
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
</ListBox>
|
</ListBox>
|
||||||
@@ -326,8 +385,7 @@
|
|||||||
<Grid
|
<Grid
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
RowDefinitions="Auto,*">
|
RowDefinitions="Auto,*">
|
||||||
<Grid
|
<Grid IsVisible="{Binding AppState.SelectedTab^.CurrentLocation^.IsLoading^, FallbackValue=False}">
|
||||||
IsVisible="{Binding AppState.SelectedTab^.CurrentLocation^.IsLoading^, FallbackValue=False}">
|
|
||||||
<Image
|
<Image
|
||||||
Width="40"
|
Width="40"
|
||||||
Height="40"
|
Height="40"
|
||||||
@@ -341,9 +399,9 @@
|
|||||||
Classes="ContentListView"
|
Classes="ContentListView"
|
||||||
IsTabStop="True"
|
IsTabStop="True"
|
||||||
Items="{Binding AppState.SelectedTab^.CurrentItemsCollection.Collection}"
|
Items="{Binding AppState.SelectedTab^.CurrentItemsCollection.Collection}"
|
||||||
SelectedItem="{Binding AppState.SelectedTab^.CurrentSelectedItem^}"
|
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
|
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Visible">
|
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||||
|
SelectedItem="{Binding AppState.SelectedTab^.CurrentSelectedItem^}">
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate x:DataType="corevm:IItemViewModel">
|
<DataTemplate x:DataType="corevm:IItemViewModel">
|
||||||
<local:ItemView
|
<local:ItemView
|
||||||
@@ -375,10 +433,8 @@
|
|||||||
Fill="{DynamicResource ContentSeparatorBrush}" />
|
Fill="{DynamicResource ContentSeparatorBrush}" />
|
||||||
|
|
||||||
<Grid Grid.Column="4">
|
<Grid Grid.Column="4">
|
||||||
<Grid
|
<Grid IsVisible="{Binding ItemPreviewService.ItemPreview^, Converter={x:Static ObjectConverters.IsNull}}">
|
||||||
IsVisible="{Binding ItemPreviewService.ItemPreview^,Converter={x:Static ObjectConverters.IsNull}}">
|
<Grid IsVisible="{Binding AppState.SelectedTab^.SelectedsChildrenCollection.Collection, Converter={x:Static ObjectConverters.IsNotNull}, FallbackValue=False}">
|
||||||
<Grid
|
|
||||||
IsVisible="{Binding AppState.SelectedTab^.SelectedsChildrenCollection.Collection, Converter={x:Static ObjectConverters.IsNotNull}, FallbackValue=False}">
|
|
||||||
<ListBox
|
<ListBox
|
||||||
x:Name="ChildItems"
|
x:Name="ChildItems"
|
||||||
x:CompileBindings="False"
|
x:CompileBindings="False"
|
||||||
@@ -428,26 +484,31 @@
|
|||||||
</ItemsRepeater>
|
</ItemsRepeater>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid
|
<Grid IsVisible="{Binding ItemPreviewService.ItemPreview^, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||||
IsVisible="{Binding ItemPreviewService.ItemPreview^,Converter={x:Static ObjectConverters.IsNotNull}}">
|
<TextBlock
|
||||||
<TextBlock HorizontalAlignment="Center" Text="Don't know how to preview this item."
|
HorizontalAlignment="Center"
|
||||||
IsVisible="{Binding ItemPreviewService.ItemPreview^.Mode, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static appCoreModels:ItemPreviewMode.Unknown},FallbackValue={x:Static appCoreModels:ItemPreviewMode.Unknown}}" />
|
IsVisible="{Binding ItemPreviewService.ItemPreview^.Mode, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static appCoreModels:ItemPreviewMode.Unknown}, FallbackValue={x:Static appCoreModels:ItemPreviewMode.Unknown}}"
|
||||||
<TextBlock HorizontalAlignment="Center" Text="Empty"
|
Text="Don't know how to preview this item." />
|
||||||
IsVisible="{Binding ItemPreviewService.ItemPreview^.Mode, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static appCoreModels:ItemPreviewMode.Empty},FallbackValue={x:Static appCoreModels:ItemPreviewMode.Unknown}}" />
|
<TextBlock
|
||||||
<ScrollViewer
|
HorizontalAlignment="Center"
|
||||||
IsVisible="{Binding ItemPreviewService.ItemPreview^.Mode, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static appCoreModels:ItemPreviewMode.Text},FallbackValue={x:Static appCoreModels:ItemPreviewMode.Unknown}}">
|
IsVisible="{Binding ItemPreviewService.ItemPreview^.Mode, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static appCoreModels:ItemPreviewMode.Empty}, FallbackValue={x:Static appCoreModels:ItemPreviewMode.Unknown}}"
|
||||||
|
Text="Empty" />
|
||||||
|
<ScrollViewer IsVisible="{Binding ItemPreviewService.ItemPreview^.Mode, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static appCoreModels:ItemPreviewMode.Text}, FallbackValue={x:Static appCoreModels:ItemPreviewMode.Unknown}}">
|
||||||
<TextBox
|
<TextBox
|
||||||
IsReadOnly="True"
|
|
||||||
x:CompileBindings="False"
|
x:CompileBindings="False"
|
||||||
|
IsReadOnly="True"
|
||||||
Text="{Binding ItemPreviewService.ItemPreview^.TextContent}" />
|
Text="{Binding ItemPreviewService.ItemPreview^.TextContent}" />
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<ItemsRepeater Items="{Binding AppState.PopupTexts}" Margin="0,0,0,20"
|
<ItemsRepeater
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Top"
|
Margin="0,0,0,20"
|
||||||
IsVisible="{Binding AppState.PopupTexts.Count,Converter={StaticResource NotEqualsConverter}, ConverterParameter=0}">
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
IsVisible="{Binding AppState.PopupTexts.Count, Converter={StaticResource NotEqualsConverter}, ConverterParameter=0}"
|
||||||
|
Items="{Binding AppState.PopupTexts}">
|
||||||
<ItemsRepeater.Styles>
|
<ItemsRepeater.Styles>
|
||||||
<Style Selector="TextBlock">
|
<Style Selector="TextBlock">
|
||||||
<Style.Animations>
|
<Style.Animations>
|
||||||
@@ -464,11 +525,14 @@
|
|||||||
</ItemsRepeater.Styles>
|
</ItemsRepeater.Styles>
|
||||||
<ItemsRepeater.ItemTemplate>
|
<ItemsRepeater.ItemTemplate>
|
||||||
<DataTemplate x:DataType="x:String">
|
<DataTemplate x:DataType="x:String">
|
||||||
<Border Background="{DynamicResource ContainerGradientBackgroundBrush}" Margin="5"
|
<Border
|
||||||
Padding="5">
|
Margin="5"
|
||||||
<TextBlock Text="{Binding}"
|
Padding="5"
|
||||||
Foreground="{DynamicResource AccentComplementBrush}"
|
Background="{DynamicResource ContainerGradientBackgroundBrush}">
|
||||||
HorizontalAlignment="Center" />
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Foreground="{DynamicResource AccentComplementBrush}"
|
||||||
|
Text="{Binding}" />
|
||||||
</Border>
|
</Border>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsRepeater.ItemTemplate>
|
</ItemsRepeater.ItemTemplate>
|
||||||
@@ -477,7 +541,7 @@
|
|||||||
|
|
||||||
<Grid Grid.Row="3">
|
<Grid Grid.Row="3">
|
||||||
<Grid
|
<Grid
|
||||||
IsVisible="{Binding AppState.ViewMode^, Converter={StaticResource EqualityConverter},ConverterParameter=RapidTravel}"
|
IsVisible="{Binding AppState.ViewMode^, Converter={StaticResource EqualityConverter}, ConverterParameter=RapidTravel}"
|
||||||
RowDefinitions="1,Auto">
|
RowDefinitions="1,Auto">
|
||||||
|
|
||||||
<Rectangle
|
<Rectangle
|
||||||
@@ -502,8 +566,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid
|
<Grid IsVisible="{Binding AppState.PossibleCommands.Count, Converter={StaticResource NotEqualsConverter}, ConverterParameter=0}">
|
||||||
IsVisible="{Binding AppState.PossibleCommands.Count, Converter={StaticResource NotEqualsConverter}, ConverterParameter=0}">
|
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="1" />
|
<RowDefinition Height="1" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
@@ -528,8 +591,9 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<TextBlock Text="{Binding KeysDisplayText}" />
|
<TextBlock Text="{Binding KeysDisplayText}" />
|
||||||
<TextBlock Grid.Column="1"
|
<TextBlock
|
||||||
Text="{Binding Command, Converter={StaticResource CommandToCommandNameConverter}}" />
|
Grid.Column="1"
|
||||||
|
Text="{Binding Command, Converter={StaticResource CommandToCommandNameConverter}}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsRepeater.ItemTemplate>
|
</ItemsRepeater.ItemTemplate>
|
||||||
@@ -540,15 +604,15 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Border
|
<Border
|
||||||
Background="{DynamicResource BarelyTransparentBackgroundColor}"
|
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
|
Background="{DynamicResource BarelyTransparentBackgroundColor}"
|
||||||
IsVisible="{Binding DialogService.ReadInput^, Converter={x:Static ObjectConverters.IsNotNull}}">
|
IsVisible="{Binding DialogService.ReadInput^, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||||
<Border
|
<Border
|
||||||
Background="{DynamicResource ContainerBackgroundBrush}"
|
|
||||||
Padding="20"
|
Padding="20"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center"
|
||||||
|
Background="{DynamicResource ContainerBackgroundBrush}">
|
||||||
<Grid RowDefinitions="Auto,Auto">
|
<Grid RowDefinitions="Auto,Auto">
|
||||||
|
|
||||||
<ItemsControl
|
<ItemsControl
|
||||||
@@ -556,22 +620,26 @@
|
|||||||
Items="{Binding DialogService.ReadInput^.Inputs}">
|
Items="{Binding DialogService.ReadInput^.Inputs}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid MinWidth="500" ColumnDefinitions="250,*" Margin="10,5" x:Name="ItemRoot">
|
<Grid
|
||||||
|
x:Name="ItemRoot"
|
||||||
|
MinWidth="500"
|
||||||
|
Margin="10,5"
|
||||||
|
ColumnDefinitions="250,*">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Text="{Binding Label}" />
|
Text="{Binding Label}" />
|
||||||
<Grid Grid.Column="1">
|
<Grid Grid.Column="1">
|
||||||
<TextBox
|
<TextBox
|
||||||
|
VerticalAlignment="Top"
|
||||||
x:DataType="interactions:TextInputElement"
|
x:DataType="interactions:TextInputElement"
|
||||||
IsVisible="{Binding Type, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static interactions:InputType.Text}}"
|
IsVisible="{Binding Type, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static interactions:InputType.Text}}"
|
||||||
VerticalAlignment="Top"
|
|
||||||
Text="{Binding Value, Mode=TwoWay}" />
|
Text="{Binding Value, Mode=TwoWay}" />
|
||||||
<TextBox
|
<TextBox
|
||||||
|
VerticalAlignment="Top"
|
||||||
x:DataType="interactions:PasswordInputElement"
|
x:DataType="interactions:PasswordInputElement"
|
||||||
IsVisible="{Binding Type, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static interactions:InputType.Password}}"
|
IsVisible="{Binding Type, Converter={StaticResource EqualityConverter}, ConverterParameter={x:Static interactions:InputType.Password}}"
|
||||||
PasswordChar="{Binding PasswordChar}"
|
PasswordChar="{Binding PasswordChar}"
|
||||||
VerticalAlignment="Top"
|
|
||||||
Text="{Binding Value, Mode=TwoWay}" />
|
Text="{Binding Value, Mode=TwoWay}" />
|
||||||
<ListBox
|
<ListBox
|
||||||
x:DataType="interactions:IOptionsInputElement"
|
x:DataType="interactions:IOptionsInputElement"
|
||||||
@@ -587,17 +655,17 @@
|
|||||||
<StackPanel
|
<StackPanel
|
||||||
DataContext="{Binding DialogService.ReadInput^}"
|
DataContext="{Binding DialogService.ReadInput^}"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Orientation="Horizontal"
|
Margin="0,10,0,0"
|
||||||
Margin="0,10,0,0">
|
Orientation="Horizontal">
|
||||||
<Button
|
<Button
|
||||||
HorizontalContentAlignment="Center"
|
|
||||||
Width="80"
|
Width="80"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
Command="{Binding ProcessCommand}"
|
Command="{Binding ProcessCommand}"
|
||||||
Content="Ok" />
|
Content="Ok" />
|
||||||
<Button
|
<Button
|
||||||
HorizontalContentAlignment="Center"
|
|
||||||
Width="80"
|
Width="80"
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
Command="{Binding CancelCommand}"
|
Command="{Binding CancelCommand}"
|
||||||
Content="Cancel" />
|
Content="Cancel" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -606,32 +674,32 @@
|
|||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
<Border
|
<Border
|
||||||
Background="{DynamicResource BarelyTransparentBackgroundColor}"
|
DataContext="{Binding DialogService.LastMessageBox^}"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
DataContext="{Binding DialogService.LastMessageBox^}"
|
Background="{DynamicResource BarelyTransparentBackgroundColor}"
|
||||||
IsVisible="{Binding Converter={x:Static ObjectConverters.IsNotNull}, FallbackValue=False}">
|
IsVisible="{Binding Converter={x:Static ObjectConverters.IsNotNull}, FallbackValue=False}">
|
||||||
<Border
|
<Border
|
||||||
Background="{DynamicResource ContainerBackgroundBrush}"
|
Padding="20"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Padding="20">
|
Background="{DynamicResource ContainerBackgroundBrush}">
|
||||||
<Grid RowDefinitions="Auto,Auto">
|
<Grid RowDefinitions="Auto,Auto">
|
||||||
|
|
||||||
<TextBlock Text="{Binding Text}" />
|
<TextBlock Text="{Binding Text}" />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Orientation="Horizontal"
|
Margin="0,10,0,0"
|
||||||
Margin="0,10,0,0">
|
Orientation="Horizontal">
|
||||||
<Button
|
<Button
|
||||||
HorizontalContentAlignment="Center"
|
|
||||||
Width="80"
|
Width="80"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
Command="{Binding OkCommand}"
|
Command="{Binding OkCommand}"
|
||||||
Content="Yes" />
|
Content="Yes" />
|
||||||
<Button
|
<Button
|
||||||
HorizontalContentAlignment="Center"
|
|
||||||
Width="80"
|
Width="80"
|
||||||
Margin="10,0,0,0"
|
Margin="10,0,0,0"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
Command="{Binding CancelCommand}"
|
Command="{Binding CancelCommand}"
|
||||||
Content="No" />
|
Content="No" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|||||||
@@ -232,30 +232,32 @@ public sealed partial class LocalContentProvider : ContentProviderBase, ILocalCo
|
|||||||
pointInTime,
|
pointInTime,
|
||||||
exceptions,
|
exceptions,
|
||||||
new ExtensionCollection().AsReadOnly(),
|
new ExtensionCollection().AsReadOnly(),
|
||||||
Observable.FromAsync(async () => await Task.Run(InitChildren))
|
//Observable.FromAsync(async () => await Task.Run(InitChildrenHelper)
|
||||||
|
Observable.Return(InitChildren())
|
||||||
);
|
);
|
||||||
|
|
||||||
Task<IObservable<IChangeSet<AbsolutePath, string>>?> InitChildren()
|
Task<IObservable<IChangeSet<AbsolutePath, string>>?> InitChildrenHelper() => Task.FromResult(InitChildren());
|
||||||
|
|
||||||
|
IObservable<IChangeSet<AbsolutePath, string>>? InitChildren()
|
||||||
{
|
{
|
||||||
|
if (!initializeChildren) return null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var items = initializeChildren ? (List<AbsolutePath>?) GetItemsByContainer(directoryInfo, pointInTime) : null;
|
var items = GetItemsByContainer(directoryInfo, pointInTime);
|
||||||
if (items != null)
|
var result = new SourceCache<AbsolutePath, string>(i => i.Path.Path);
|
||||||
{
|
|
||||||
var result = new SourceCache<AbsolutePath, string>(i => i.Path.Path);
|
|
||||||
|
|
||||||
if (items.Count == 0) return Task.FromResult((IObservable<IChangeSet<AbsolutePath, string>>?) result.Connect().StartWithEmpty());
|
if (items.Count == 0) return (IObservable<IChangeSet<AbsolutePath, string>>?) result.Connect().StartWithEmpty();
|
||||||
|
|
||||||
result.AddOrUpdate(items);
|
result.AddOrUpdate(items);
|
||||||
return Task.FromResult((IObservable<IChangeSet<AbsolutePath, string>>?) result.Connect());
|
return (IObservable<IChangeSet<AbsolutePath, string>>?) result.Connect();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
exceptions.OnNext(new List<Exception>() {e});
|
exceptions.OnNext(new List<Exception> {e});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult((IObservable<IChangeSet<AbsolutePath, string>>?) null);
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user