Timeline command visual navigation
This commit is contained in:
@@ -12,7 +12,9 @@ namespace FileTime.Core.Timeline
|
|||||||
|
|
||||||
private bool _resourceIsInUse;
|
private bool _resourceIsInUse;
|
||||||
private readonly List<Thread> _commandRunners = new();
|
private readonly List<Thread> _commandRunners = new();
|
||||||
private bool _enableRunning = true;
|
private bool _enableRunning; //= true;
|
||||||
|
|
||||||
|
private IReadOnlyList<ReadOnlyParallelCommands> _parallelCommands = new List<ReadOnlyParallelCommands>();
|
||||||
|
|
||||||
public bool EnableRunning
|
public bool EnableRunning
|
||||||
{
|
{
|
||||||
@@ -29,11 +31,17 @@ namespace FileTime.Core.Timeline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<ReadOnlyParallelCommands> ParallelCommands { get; private set; } = new List<ReadOnlyParallelCommands>().AsReadOnly();
|
public async Task<IReadOnlyList<ReadOnlyParallelCommands>> GetParallelCommandsAsync()
|
||||||
|
{
|
||||||
|
IReadOnlyList<ReadOnlyParallelCommands> parallelCommands = new List<ReadOnlyParallelCommands>();
|
||||||
|
await RunWithLockAsync(() => parallelCommands = _parallelCommands);
|
||||||
|
|
||||||
|
return parallelCommands;
|
||||||
|
}
|
||||||
|
|
||||||
public AsyncEventHandler<AbsolutePath> RefreshContainer { get; } = new AsyncEventHandler<AbsolutePath>();
|
public AsyncEventHandler<AbsolutePath> RefreshContainer { get; } = new AsyncEventHandler<AbsolutePath>();
|
||||||
|
|
||||||
public event EventHandler? CommandsChanged;
|
public AsyncEventHandler CommandsChangedAsync { get; } = new();
|
||||||
|
|
||||||
public TimeRunner(CommandExecutor commandExecutor)
|
public TimeRunner(CommandExecutor commandExecutor)
|
||||||
{
|
{
|
||||||
@@ -162,12 +170,12 @@ namespace FileTime.Core.Timeline
|
|||||||
|
|
||||||
private async Task RefreshCommands(PointInTime? fullStartTime = null)
|
private async Task RefreshCommands(PointInTime? fullStartTime = null)
|
||||||
{
|
{
|
||||||
var curretnTime = fullStartTime ?? _commandsToRun[0].Result;
|
var currentTime = fullStartTime ?? _commandsToRun[0].Result;
|
||||||
var startIndex = fullStartTime == null ? 1 : 0;
|
var startIndex = fullStartTime == null ? 1 : 0;
|
||||||
|
|
||||||
for (var i = startIndex; i < _commandsToRun.Count; i++)
|
for (var i = startIndex; i < _commandsToRun.Count; i++)
|
||||||
{
|
{
|
||||||
curretnTime = await _commandsToRun[i].RefreshResult(curretnTime);
|
currentTime = await _commandsToRun[i].RefreshResult(currentTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,8 +184,8 @@ namespace FileTime.Core.Timeline
|
|||||||
var wait = false;
|
var wait = false;
|
||||||
await RunWithLockAsync(() => wait = _commandsToRun.Count == 1);
|
await RunWithLockAsync(() => wait = _commandsToRun.Count == 1);
|
||||||
if (wait) await Task.Delay(100);
|
if (wait) await Task.Delay(100);
|
||||||
await RunWithLockAsync(() => ParallelCommands = _commandsToRun.ConvertAll(c => new ReadOnlyParallelCommands(c)).AsReadOnly());
|
await RunWithLockAsync(() => _parallelCommands = _commandsToRun.ConvertAll(c => new ReadOnlyParallelCommands(c)).AsReadOnly());
|
||||||
CommandsChanged?.Invoke(this, EventArgs.Empty);
|
await CommandsChangedAsync.InvokeAsync(this, AsyncEventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RunWithLockAsync(Action action)
|
private async Task RunWithLockAsync(Action action)
|
||||||
|
|||||||
@@ -163,6 +163,14 @@
|
|||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Grid.RootDriveInfo">
|
||||||
|
<Setter Property="Background" Value="#01000000"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Grid.RootDriveInfo:pointerover">
|
||||||
|
<Setter Property="Background" Value="{DynamicResource AppBackgroundColor}"/>
|
||||||
|
</Style>
|
||||||
|
|
||||||
<Style Selector="Grid.PlacesItem">
|
<Style Selector="Grid.PlacesItem">
|
||||||
<Setter Property="Background" Value="#01000000"/>
|
<Setter Property="Background" Value="#01000000"/>
|
||||||
</Style>
|
</Style>
|
||||||
@@ -170,5 +178,9 @@
|
|||||||
<Style Selector="Grid.PlacesItem:pointerover">
|
<Style Selector="Grid.PlacesItem:pointerover">
|
||||||
<Setter Property="Background" Value="{DynamicResource AppBackgroundColor}"/>
|
<Setter Property="Background" Value="{DynamicResource AppBackgroundColor}"/>
|
||||||
</Style>
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="Border.SelectedTimelineCommand">
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource ForegroundBrush}"/>
|
||||||
|
</Style>
|
||||||
</Application.Styles>
|
</Application.Styles>
|
||||||
</Application>
|
</Application>
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ namespace FileTime.Avalonia.Models
|
|||||||
private readonly DriveInfo _driveInfo;
|
private readonly DriveInfo _driveInfo;
|
||||||
private readonly IContainer _container;
|
private readonly IContainer _container;
|
||||||
|
|
||||||
|
public IContainer Container => _container;
|
||||||
|
|
||||||
[Property]
|
[Property]
|
||||||
private string _name;
|
private string _name;
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ using Syroot.Windows.IO;
|
|||||||
using FileTime.Avalonia.IconProviders;
|
using FileTime.Avalonia.IconProviders;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using AsyncEvent;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace FileTime.Avalonia.ViewModels
|
namespace FileTime.Avalonia.ViewModels
|
||||||
{
|
{
|
||||||
@@ -99,7 +101,7 @@ namespace FileTime.Avalonia.ViewModels
|
|||||||
App.ServiceProvider.GetService<TopContainer>();
|
App.ServiceProvider.GetService<TopContainer>();
|
||||||
await StatePersistence.LoadStatesAsync();
|
await StatePersistence.LoadStatesAsync();
|
||||||
|
|
||||||
_timeRunner.CommandsChanged += UpdateParalellCommands;
|
_timeRunner.CommandsChangedAsync.Add(UpdateParalellCommands);
|
||||||
InitCommandBindings();
|
InitCommandBindings();
|
||||||
|
|
||||||
_keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(Key.Up) });
|
_keysToSkip.Add(new KeyWithModifiers[] { new KeyWithModifiers(Key.Up) });
|
||||||
@@ -211,9 +213,11 @@ namespace FileTime.Avalonia.ViewModels
|
|||||||
_logger?.LogInformation($"{nameof(MainPageViewModel)} initialized.");
|
_logger?.LogInformation($"{nameof(MainPageViewModel)} initialized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateParalellCommands(object? sender, EventArgs e)
|
private async Task UpdateParalellCommands(object? sender, AsyncEventArgs e, CancellationToken token)
|
||||||
{
|
{
|
||||||
foreach (var parallelCommand in _timeRunner.ParallelCommands)
|
var parallelCommands = await _timeRunner.GetParallelCommandsAsync();
|
||||||
|
|
||||||
|
foreach (var parallelCommand in parallelCommands)
|
||||||
{
|
{
|
||||||
if (!TimelineCommands.Any(c => c.Id == parallelCommand.Id))
|
if (!TimelineCommands.Any(c => c.Id == parallelCommand.Id))
|
||||||
{
|
{
|
||||||
@@ -223,7 +227,7 @@ namespace FileTime.Avalonia.ViewModels
|
|||||||
var itemsToRemove = new List<ParallelCommandsViewModel>();
|
var itemsToRemove = new List<ParallelCommandsViewModel>();
|
||||||
foreach (var parallelCommandVm in TimelineCommands)
|
foreach (var parallelCommandVm in TimelineCommands)
|
||||||
{
|
{
|
||||||
if (!_timeRunner.ParallelCommands.Any(c => c.Id == parallelCommandVm.Id))
|
if (!parallelCommands.Any(c => c.Id == parallelCommandVm.Id))
|
||||||
{
|
{
|
||||||
itemsToRemove.Add(parallelCommandVm);
|
itemsToRemove.Add(parallelCommandVm);
|
||||||
}
|
}
|
||||||
@@ -234,6 +238,33 @@ namespace FileTime.Avalonia.ViewModels
|
|||||||
itemsToRemove[i].Dispose();
|
itemsToRemove[i].Dispose();
|
||||||
TimelineCommands.Remove(itemsToRemove[i]);
|
TimelineCommands.Remove(itemsToRemove[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var parallelCommand in parallelCommands)
|
||||||
|
{
|
||||||
|
var parallelCommandsVM = TimelineCommands.First(t => t.Id == parallelCommand.Id);
|
||||||
|
foreach (var command in parallelCommand.Commands)
|
||||||
|
{
|
||||||
|
if (!parallelCommandsVM.ParallelCommands.Any(c => c.CommandTimeState.Command == command.Command))
|
||||||
|
{
|
||||||
|
parallelCommandsVM.ParallelCommands.Add(new ParallelCommandViewModel(command));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var commandVMsToRemove = new List<ParallelCommandViewModel>();
|
||||||
|
foreach (var commandVM in parallelCommandsVM.ParallelCommands)
|
||||||
|
{
|
||||||
|
if (!parallelCommand.Commands.Any(c => c.Command == commandVM.CommandTimeState.Command))
|
||||||
|
{
|
||||||
|
commandVMsToRemove.Add(commandVM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < commandVMsToRemove.Count; i++)
|
||||||
|
{
|
||||||
|
commandVMsToRemove[i].Dispose();
|
||||||
|
parallelCommandsVM.ParallelCommands.Remove(commandVMsToRemove[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IContainer?> GetContainerForWindowsDrive(DriveInfo drive)
|
private async Task<IContainer?> GetContainerForWindowsDrive(DriveInfo drive)
|
||||||
@@ -771,6 +802,66 @@ namespace FileTime.Avalonia.ViewModels
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task SelectPreviousTimelineBlock()
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task SelectNextTimelineCommand()
|
||||||
|
{
|
||||||
|
var currentSelected = GetSelectedTimelineCommandOrSelectFirst();
|
||||||
|
if (currentSelected == null) return Task.CompletedTask;
|
||||||
|
|
||||||
|
ParallelCommandViewModel? lastCommand = null;
|
||||||
|
var any = false;
|
||||||
|
foreach (var command in TimelineCommands.SelectMany(t => t.ParallelCommands))
|
||||||
|
{
|
||||||
|
var isSelected = lastCommand == currentSelected;
|
||||||
|
command.IsSelected = isSelected;
|
||||||
|
any = any || isSelected;
|
||||||
|
lastCommand = command;
|
||||||
|
}
|
||||||
|
if (!any && lastCommand != null) lastCommand.IsSelected = true;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task SelectPreviousTimelineCommand()
|
||||||
|
{
|
||||||
|
var currentSelected = GetSelectedTimelineCommandOrSelectFirst();
|
||||||
|
if (currentSelected == null) return Task.CompletedTask;
|
||||||
|
|
||||||
|
ParallelCommandViewModel? lastCommand = null;
|
||||||
|
foreach (var command in TimelineCommands.SelectMany(t => t.ParallelCommands))
|
||||||
|
{
|
||||||
|
if (lastCommand != null)
|
||||||
|
{
|
||||||
|
lastCommand.IsSelected = command == currentSelected;
|
||||||
|
}
|
||||||
|
lastCommand = command;
|
||||||
|
}
|
||||||
|
if (lastCommand != null) lastCommand.IsSelected = false;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task SelectNextTimelineBlock()
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParallelCommandViewModel? GetSelectedTimelineCommandOrSelectFirst()
|
||||||
|
{
|
||||||
|
var currentSelected = TimelineCommands.SelectMany(t => t.ParallelCommands).FirstOrDefault(c => c.IsSelected);
|
||||||
|
if (currentSelected != null) return currentSelected;
|
||||||
|
|
||||||
|
var firstCommand = TimelineCommands.SelectMany(t => t.ParallelCommands).FirstOrDefault();
|
||||||
|
if (firstCommand != null)
|
||||||
|
{
|
||||||
|
firstCommand.IsSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
[Command]
|
[Command]
|
||||||
public async void ProcessInputs()
|
public async void ProcessInputs()
|
||||||
{
|
{
|
||||||
@@ -1195,18 +1286,37 @@ namespace FileTime.Avalonia.ViewModels
|
|||||||
FileTime.App.Core.Command.Commands.Dummy,
|
FileTime.App.Core.Command.Commands.Dummy,
|
||||||
new KeyWithModifiers[] { new KeyWithModifiers(Key.D4, shift: true) },
|
new KeyWithModifiers[] { new KeyWithModifiers(Key.D4, shift: true) },
|
||||||
RunCommandInContainer),
|
RunCommandInContainer),
|
||||||
|
new CommandBinding(
|
||||||
|
"copy path",
|
||||||
|
FileTime.App.Core.Command.Commands.Dummy,
|
||||||
|
new KeyWithModifiers[] { new KeyWithModifiers(Key.C), new KeyWithModifiers(Key.P) },
|
||||||
|
CopyPath),
|
||||||
|
new CommandBinding(
|
||||||
|
"select previous timeline block",
|
||||||
|
FileTime.App.Core.Command.Commands.Dummy,
|
||||||
|
new KeyWithModifiers[] { new KeyWithModifiers(Key.H) },
|
||||||
|
SelectPreviousTimelineBlock),
|
||||||
|
new CommandBinding(
|
||||||
|
"select next timeline command",
|
||||||
|
FileTime.App.Core.Command.Commands.Dummy,
|
||||||
|
new KeyWithModifiers[] { new KeyWithModifiers(Key.J) },
|
||||||
|
SelectNextTimelineCommand),
|
||||||
|
new CommandBinding(
|
||||||
|
"select previous timeline command",
|
||||||
|
FileTime.App.Core.Command.Commands.Dummy,
|
||||||
|
new KeyWithModifiers[] { new KeyWithModifiers(Key.K) },
|
||||||
|
SelectPreviousTimelineCommand),
|
||||||
|
new CommandBinding(
|
||||||
|
"select next timeline block",
|
||||||
|
FileTime.App.Core.Command.Commands.Dummy,
|
||||||
|
new KeyWithModifiers[] { new KeyWithModifiers(Key.L) },
|
||||||
|
SelectNextTimelineBlock),
|
||||||
//TODO REMOVE
|
//TODO REMOVE
|
||||||
new CommandBinding(
|
new CommandBinding(
|
||||||
"open in default file browser",
|
"open in default file browser",
|
||||||
FileTime.App.Core.Command.Commands.Dummy,
|
FileTime.App.Core.Command.Commands.Dummy,
|
||||||
new KeyWithModifiers[] { new KeyWithModifiers(Key.O), new KeyWithModifiers(Key.E) },
|
new KeyWithModifiers[] { new KeyWithModifiers(Key.O), new KeyWithModifiers(Key.E) },
|
||||||
OpenInDefaultFileExplorer),
|
OpenInDefaultFileExplorer),
|
||||||
//TODO REMOVE
|
|
||||||
new CommandBinding(
|
|
||||||
"copy path",
|
|
||||||
FileTime.App.Core.Command.Commands.Dummy,
|
|
||||||
new KeyWithModifiers[] { new KeyWithModifiers(Key.C), new KeyWithModifiers(Key.P) },
|
|
||||||
CopyPath),
|
|
||||||
};
|
};
|
||||||
var universalCommandBindings = new List<CommandBinding>()
|
var universalCommandBindings = new List<CommandBinding>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,18 +2,23 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System;
|
using System;
|
||||||
using FileTime.Core.Timeline;
|
using FileTime.Core.Timeline;
|
||||||
|
using MvvmGen;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
namespace FileTime.Avalonia.ViewModels
|
namespace FileTime.Avalonia.ViewModels
|
||||||
{
|
{
|
||||||
public class ParallelCommandsViewModel : IDisposable
|
[ViewModel]
|
||||||
|
public partial class ParallelCommandsViewModel : IDisposable
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
public IReadOnlyCollection<ParallelCommandViewModel> ParallelCommands { get; }
|
|
||||||
|
[Property]
|
||||||
|
private ObservableCollection<ParallelCommandViewModel> _parallelCommands;
|
||||||
public ushort Id { get; }
|
public ushort Id { get; }
|
||||||
|
|
||||||
public ParallelCommandsViewModel(ReadOnlyParallelCommands parallelCommands)
|
public ParallelCommandsViewModel(ReadOnlyParallelCommands parallelCommands)
|
||||||
{
|
{
|
||||||
ParallelCommands = parallelCommands.Commands.Select(c => new ParallelCommandViewModel(c)).ToList().AsReadOnly();
|
_parallelCommands = new ObservableCollection<ParallelCommandViewModel>(parallelCommands.Commands.Select(c => new ParallelCommandViewModel(c)));
|
||||||
Id = parallelCommands.Id;
|
Id = parallelCommands.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,16 @@ namespace FileTime.Avalonia.ViewModels
|
|||||||
public partial class ParallelCommandViewModel : IDisposable
|
public partial class ParallelCommandViewModel : IDisposable
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly ReadOnlyCommandTimeState _commandTimeState;
|
|
||||||
|
[Property]
|
||||||
|
private ReadOnlyCommandTimeState _commandTimeState;
|
||||||
|
|
||||||
[Property]
|
[Property]
|
||||||
private int _progress;
|
private int _progress;
|
||||||
|
|
||||||
|
[Property]
|
||||||
|
private bool _isSelected;
|
||||||
|
|
||||||
public CanCommandRun CanRun => _commandTimeState.CanRun;
|
public CanCommandRun CanRun => _commandTimeState.CanRun;
|
||||||
public bool ForceRun => _commandTimeState.ForceRun;
|
public bool ForceRun => _commandTimeState.ForceRun;
|
||||||
|
|
||||||
|
|||||||
@@ -53,60 +53,61 @@
|
|||||||
Items="{Binding RootDriveInfos}">
|
Items="{Binding RootDriveInfos}">
|
||||||
<ItemsRepeater.ItemTemplate>
|
<ItemsRepeater.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid Margin="0,5" ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,Auto">
|
<Grid Classes="RootDriveInfo" PointerPressed="OnRootDrivePointerPressed" Cursor="Hand">
|
||||||
<Image
|
<Grid Margin="0,5" ColumnDefinitions="Auto,*,Auto" RowDefinitions="Auto,Auto">
|
||||||
Grid.RowSpan="2"
|
<Image
|
||||||
Width="20"
|
Grid.RowSpan="2"
|
||||||
Height="20"
|
Width="20"
|
||||||
HorizontalAlignment="Left"
|
Height="20"
|
||||||
VerticalAlignment="Center"
|
HorizontalAlignment="Left"
|
||||||
Source="{SvgImage /Assets/material/folder.svg}" />
|
|
||||||
|
|
||||||
<StackPanel
|
|
||||||
Grid.Column="1"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
|
|
||||||
<TextBlock
|
|
||||||
Margin="5,0,0,0"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{Binding FullName}" />
|
Source="{SvgImage /Assets/material/folder.svg}" />
|
||||||
|
|
||||||
<TextBlock
|
<StackPanel
|
||||||
Margin="5,0,0,0"
|
Grid.Column="1"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Classes="ExtraSmallText"
|
HorizontalAlignment="Stretch"
|
||||||
Text="{Binding Label}" IsVisible="{Binding Label,Converter={StaticResource IsNotEmptyConverter}}" />
|
Orientation="Horizontal">
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<StackPanel
|
<TextBlock
|
||||||
HorizontalAlignment="Right"
|
Margin="5,0,0,0"
|
||||||
Grid.Column="2"
|
VerticalAlignment="Center"
|
||||||
Orientation="Horizontal"
|
Text="{Binding FullName}" />
|
||||||
VerticalAlignment="Center">
|
|
||||||
|
|
||||||
<TextBlock Classes="SmallText" VerticalAlignment="Center" Text="{Binding Free, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}">
|
<TextBlock
|
||||||
</TextBlock>
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Classes="ExtraSmallText"
|
||||||
|
Text="{Binding Label}" IsVisible="{Binding Label,Converter={StaticResource IsNotEmptyConverter}}" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
<TextBlock Classes="SmallText" VerticalAlignment="Center" Text=" / ">
|
<StackPanel
|
||||||
</TextBlock>
|
HorizontalAlignment="Right"
|
||||||
|
Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
|
||||||
<TextBlock Classes="SmallText" VerticalAlignment="Center" Text="{Binding Size, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}">
|
<TextBlock Classes="SmallText" VerticalAlignment="Center" Text="{Binding Free, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}">
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
</StackPanel>
|
|
||||||
|
|
||||||
<ProgressBar
|
<TextBlock Classes="SmallText" VerticalAlignment="Center" Text=" / ">
|
||||||
Margin="5,0,0,0"
|
</TextBlock>
|
||||||
Grid.Column="1"
|
|
||||||
Grid.ColumnSpan="2"
|
<TextBlock Classes="SmallText" VerticalAlignment="Center" Text="{Binding Size, Converter={StaticResource FormatSizeConverter}, ConverterParameter=0}">
|
||||||
Grid.Row="1"
|
</TextBlock>
|
||||||
MinWidth="100"
|
</StackPanel>
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
Maximum="100"
|
<ProgressBar
|
||||||
Value="{Binding UsedPercentage}" />
|
Margin="5,0,0,0"
|
||||||
|
Grid.Column="1"
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
Grid.Row="1"
|
||||||
|
MinWidth="100"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Maximum="100"
|
||||||
|
Value="{Binding UsedPercentage}" />
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsRepeater.ItemTemplate>
|
</ItemsRepeater.ItemTemplate>
|
||||||
</ItemsRepeater>
|
</ItemsRepeater>
|
||||||
@@ -160,10 +161,12 @@
|
|||||||
<ItemsControl Items="{Binding ParallelCommands}">
|
<ItemsControl Items="{Binding ParallelCommands}">
|
||||||
<ItemsControl.ItemTemplate>
|
<ItemsControl.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<StackPanel>
|
<Border BorderThickness="1" Classes="TimelineCommand" Classes.SelectedTimelineCommand="{Binding IsSelected}">
|
||||||
<TextBlock Text="{Binding Name}"/>
|
<StackPanel>
|
||||||
<ProgressBar Margin="0,5,0,0" Maximum="100" Value="{Binding Progress}"/>
|
<TextBlock Text="{Binding Name}"/>
|
||||||
</StackPanel>
|
<ProgressBar Margin="0,5,0,0" Maximum="100" Value="{Binding Progress}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ItemsControl.ItemTemplate>
|
</ItemsControl.ItemTemplate>
|
||||||
</ItemsControl>
|
</ItemsControl>
|
||||||
|
|||||||
@@ -106,6 +106,18 @@ namespace FileTime.Avalonia.Views
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnRootDrivePointerPressed(object sender, PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.Handled
|
||||||
|
&& ViewModel != null
|
||||||
|
&& e.GetCurrentPoint(this).Properties.IsLeftButtonPressed
|
||||||
|
&& sender is StyledElement control
|
||||||
|
&& control.DataContext is RootDriveInfo rootDriveInfo)
|
||||||
|
{
|
||||||
|
ViewModel.OpenContainer(rootDriveInfo.Container);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
private void OnWindowClosed(object sender, EventArgs e)
|
private void OnWindowClosed(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
Reference in New Issue
Block a user