diff --git a/.idea/.idea.Aaru/.idea/contentModel.xml b/.idea/.idea.Aaru/.idea/contentModel.xml
index 7cd9b730f..9fcd5f6eb 100644
--- a/.idea/.idea.Aaru/.idea/contentModel.xml
+++ b/.idea/.idea.Aaru/.idea/contentModel.xml
@@ -1,28 +1,27 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -71,13 +70,6 @@
-
-
-
-
-
-
-
@@ -88,12 +80,18 @@
+
+
+
+
+
+
@@ -102,14 +100,6 @@
-
-
-
-
-
-
-
-
@@ -117,11 +107,19 @@
+
+
+
+
+
+
+
+
@@ -180,6 +178,13 @@
+
+
+
+
+
+
+
@@ -200,19 +205,10 @@
-
-
-
-
-
-
-
-
-
@@ -221,6 +217,7 @@
+
@@ -238,6 +235,7 @@
+
@@ -258,8 +256,8 @@
-
+
@@ -269,11 +267,11 @@
-
+
-
+
@@ -287,17 +285,17 @@
-
-
+
+
-
+
@@ -317,12 +315,19 @@
-
+
+
+
+
+
+
+
+
@@ -339,68 +344,61 @@
-
-
-
-
-
-
-
-
+
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
@@ -425,7 +423,6 @@
-
@@ -437,11 +434,12 @@
+
-
+
@@ -463,9 +461,9 @@
+
-
@@ -495,6 +493,13 @@
+
+
+
+
+
+
+
@@ -558,11 +563,11 @@
+
-
@@ -582,17 +587,10 @@
-
-
-
-
-
-
-
-
+
@@ -649,6 +647,13 @@
+
+
+
+
+
+
+
@@ -661,28 +666,17 @@
-
+
-
-
-
-
-
-
-
-
+
-
-
-
-
@@ -690,13 +684,16 @@
+
+
+
-
-
+
+
@@ -732,11 +729,13 @@
+
-
+
+
@@ -744,11 +743,14 @@
-
+
+
+
+
@@ -788,8 +790,8 @@
-
+
@@ -798,8 +800,8 @@
-
+
@@ -808,8 +810,8 @@
-
+
@@ -836,8 +838,15 @@
-
+
+
+
+
+
+
+
+
@@ -855,11 +864,11 @@
-
+
@@ -882,34 +891,17 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
@@ -917,12 +909,18 @@
+
+
+
+
+
+
@@ -1016,6 +1014,12 @@
+
+
+
+
+
+
@@ -1040,12 +1044,6 @@
-
-
-
-
-
-
@@ -1128,6 +1126,8 @@
+
+
@@ -1143,6 +1143,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1155,18 +1167,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1175,14 +1175,14 @@
-
-
+
+
@@ -1205,12 +1205,10 @@
-
-
-
+
@@ -1222,8 +1220,8 @@
-
+
@@ -1246,6 +1244,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -1368,17 +1376,6 @@
-
-
-
-
-
-
-
-
-
-
-
@@ -1387,6 +1384,7 @@
+
@@ -1394,10 +1392,6 @@
-
-
-
-
@@ -1405,6 +1399,9 @@
+
+
+
@@ -1487,16 +1484,7 @@
-
-
-
-
-
-
-
-
-
-
+
@@ -1518,6 +1506,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -1551,16 +1549,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -1598,6 +1586,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -1688,8 +1686,8 @@
-
+
@@ -1723,16 +1721,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -1744,6 +1732,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1926,16 +1931,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -1946,6 +1941,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -1964,14 +1969,6 @@
-
-
-
-
-
-
-
-
@@ -1979,6 +1976,7 @@
+
@@ -1986,6 +1984,13 @@
+
+
+
+
+
+
+
@@ -1995,20 +2000,11 @@
-
-
-
-
-
-
-
-
-
+
-
@@ -2017,19 +2013,13 @@
+
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -2063,8 +2053,8 @@
-
+
@@ -2072,7 +2062,7 @@
-
+
@@ -2095,7 +2085,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Aaru.Gui/Controls/BlockMap.cs b/Aaru.Gui/Controls/BlockMap.cs
index 0e32cf97d..fcb35fd21 100644
--- a/Aaru.Gui/Controls/BlockMap.cs
+++ b/Aaru.Gui/Controls/BlockMap.cs
@@ -31,124 +31,435 @@
// ****************************************************************************/
using System;
-using System.Collections.ObjectModel;
+using System.Collections.Generic;
using System.Collections.Specialized;
-using System.Linq;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.LogicalTree;
+using Avalonia.Media;
+using Avalonia.Media.Imaging;
+using Avalonia.Platform;
+using Avalonia.Threading;
namespace Aaru.Gui.Controls
{
- public class BlockMap : ColoredGrid
+ // TODO: Partially fill clusters
+ // TODO: React to size changes
+ // TODO: Optimize block size to viewport
+ // TODO: Writing one more than it should
+ public class BlockMap : ItemsControl
{
- ulong _sectors;
- public uint blocksToRead;
+ const int _blockSize = 15;
+ public static readonly StyledProperty BlocksProperty =
+ AvaloniaProperty.Register(nameof(Blocks));
- public uint sectorsToRead;
+ public static readonly StyledProperty SuperFastColorProperty =
+ AvaloniaProperty.Register(nameof(SuperFastColor), Brushes.LightGreen);
- public BlockMap()
+ public static readonly StyledProperty FastColorProperty =
+ AvaloniaProperty.Register(nameof(FastColor), Brushes.Green);
+
+ public static readonly StyledProperty AverageColorProperty =
+ AvaloniaProperty.Register(nameof(AverageColor), Brushes.DarkGreen);
+
+ public static readonly StyledProperty SlowColorProperty =
+ AvaloniaProperty.Register(nameof(SlowColor), Brushes.Yellow);
+
+ public static readonly StyledProperty SuperSlowColorProperty =
+ AvaloniaProperty.Register(nameof(SuperSlowColor), Brushes.Orange);
+
+ public static readonly StyledProperty ProblematicColorProperty =
+ AvaloniaProperty.Register(nameof(ProblematicColor), Brushes.Red);
+
+ public static readonly StyledProperty SuperFastMaxTimeProperty =
+ AvaloniaProperty.Register(nameof(SuperFastMaxTime), 3);
+
+ public static readonly StyledProperty FastMaxTimeProperty =
+ AvaloniaProperty.Register(nameof(FastMaxTime), 10);
+
+ public static readonly StyledProperty AverageMaxTimeProperty =
+ AvaloniaProperty.Register(nameof(AverageMaxTime), 50);
+
+ public static readonly StyledProperty SlowMaxTimeProperty =
+ AvaloniaProperty.Register(nameof(SlowMaxTime), 150);
+
+ public static readonly StyledProperty SuperSlowMaxTimeProperty =
+ AvaloniaProperty.Register(nameof(SuperSlowMaxTime), 500);
+ RenderTargetBitmap _bitmap;
+ ulong _clusterSize;
+ ulong _maxBlocks;
+
+ public double SuperFastMaxTime
{
- ColoredSectors = new ObservableCollection();
- ColoredSectors.CollectionChanged += OnColoredSectorsChanged;
+ get => GetValue(SuperFastMaxTimeProperty);
+ set => SetValue(SuperFastMaxTimeProperty, value);
}
- public ulong Sectors
+ public double FastMaxTime
{
- get => _sectors;
- set
+ get => GetValue(FastMaxTimeProperty);
+ set => SetValue(FastMaxTimeProperty, value);
+ }
+
+ public double AverageMaxTime
+ {
+ get => GetValue(AverageMaxTimeProperty);
+ set => SetValue(AverageMaxTimeProperty, value);
+ }
+
+ public double SlowMaxTime
+ {
+ get => GetValue(SlowMaxTimeProperty);
+ set => SetValue(SlowMaxTimeProperty, value);
+ }
+
+ public double SuperSlowMaxTime
+ {
+ get => GetValue(SuperSlowMaxTimeProperty);
+ set => SetValue(SuperSlowMaxTimeProperty, value);
+ }
+
+ public IBrush SuperFastColor
+ {
+ get => GetValue(SuperFastColorProperty);
+ set => SetValue(SuperFastColorProperty, value);
+ }
+
+ public IBrush FastColor
+ {
+ get => GetValue(FastColorProperty);
+ set => SetValue(FastColorProperty, value);
+ }
+
+ public IBrush AverageColor
+ {
+ get => GetValue(AverageColorProperty);
+ set => SetValue(AverageColorProperty, value);
+ }
+
+ public IBrush SlowColor
+ {
+ get => GetValue(SlowColorProperty);
+ set => SetValue(SlowColorProperty, value);
+ }
+
+ public IBrush SuperSlowColor
+ {
+ get => GetValue(SuperSlowColorProperty);
+ set => SetValue(SuperSlowColorProperty, value);
+ }
+
+ public IBrush ProblematicColor
+ {
+ get => GetValue(ProblematicColorProperty);
+ set => SetValue(ProblematicColorProperty, value);
+ }
+
+ public ulong Blocks
+ {
+ get => GetValue(BlocksProperty);
+ set => SetValue(BlocksProperty, value);
+ }
+
+ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e)
+ {
+ base.OnPropertyChanged(e);
+
+ switch(e.Property.Name)
{
- _sectors = value;
- CalculateBoundaries();
- Invalidate();
+ case nameof(Blocks):
+ if(_maxBlocks == 0)
+ _maxBlocks = (ulong)((Width / _blockSize) * (Height / _blockSize));
+
+ if(Blocks > _maxBlocks)
+ {
+ _clusterSize = Blocks / _maxBlocks;
+
+ if(Blocks % _maxBlocks > 0)
+ _clusterSize++;
+
+ if(Blocks / _clusterSize < _maxBlocks)
+ {
+ _maxBlocks = Blocks / _clusterSize;
+
+ if(Blocks % _clusterSize > 0)
+ _maxBlocks++;
+ }
+ }
+ else
+ {
+ _clusterSize = 1;
+ _maxBlocks = Blocks;
+ }
+
+ CreateBitmap();
+ DrawGrid();
+ RedrawAll();
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+
+ break;
+ case nameof(SuperFastMaxTime):
+ case nameof(FastMaxTime):
+ case nameof(AverageMaxTime):
+ case nameof(SlowMaxTime):
+ case nameof(SuperSlowMaxTime):
+ case nameof(SuperFastColor):
+ case nameof(FastColor):
+ case nameof(AverageColor):
+ case nameof(SlowColor):
+ case nameof(SuperSlowColor):
+ case nameof(ProblematicColor):
+
+ CreateBitmap();
+ DrawGrid();
+ RedrawAll();
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+
+ break;
}
}
- public ulong SectorsPerBlock { get; private set; }
-
- public uint SectorsToRead
+ public override void Render(DrawingContext context)
{
- get => sectorsToRead;
- set
+ if((int?)_bitmap?.Size.Height != (int)Height ||
+ (int?)_bitmap?.Size.Width != (int)Width)
{
- sectorsToRead = value;
- blocksToRead = (uint)(sectorsToRead / SectorsPerBlock);
-
- if(sectorsToRead % SectorsPerBlock > 0)
- blocksToRead++;
+ _maxBlocks = (ulong)((Width / _blockSize) * (Height / _blockSize));
+ CreateBitmap();
}
+
+ context.DrawImage(_bitmap, 1, new Rect(0, 0, Width, Height), new Rect(0, 0, Width, Height));
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+ base.Render(context);
}
- public ObservableCollection ColoredSectors { get; }
-
- void OnColoredSectorsChanged(object sender, NotifyCollectionChangedEventArgs args)
+ protected override void ItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
- switch(args.Action)
+ base.ItemsCollectionChanged(sender, e);
+
+ switch(e.Action)
{
case NotifyCollectionChangedAction.Add:
- foreach(object item in args.NewItems)
- {
- if(!(item is ColoredBlock block))
- continue;
-
- for(ulong i = 0; i < blocksToRead; i++)
- ColoredBlocks.Add(new ColoredBlock((block.Block / SectorsPerBlock) + i, block.Color));
- }
-
- break;
- case NotifyCollectionChangedAction.Move: break;
- case NotifyCollectionChangedAction.Remove:
- foreach(object item in args.OldItems)
- {
- if(!(item is ColoredBlock block))
- continue;
-
- for(ulong i = 0; i < blocksToRead; i++)
- ColoredBlocks.Remove(ColoredBlocks.FirstOrDefault(t => t.Block == (block.Block /
- SectorsPerBlock) + i));
- }
-
- break;
case NotifyCollectionChangedAction.Replace:
- foreach(object item in args.OldItems)
- {
- if(!(item is ColoredBlock block))
- continue;
+ {
+ if(!(e.NewItems is { } items))
+ throw new ArgumentException("Invalid list of items");
- for(ulong i = 0; i < blocksToRead; i++)
- ColoredBlocks.Remove(ColoredBlocks.FirstOrDefault(t => t.Block == (block.Block /
- SectorsPerBlock) + i));
+ using IDrawingContextImpl ctxi = _bitmap.CreateDrawingContext(null);
+ using var ctx = new DrawingContext(ctxi, false);
+
+ foreach(object item in items)
+ {
+ if(!(item is ValueTuple block))
+ throw new ArgumentException("Invalid item in list", nameof(Items));
+
+ DrawCluster(block.Item1, block.Item2, false, ctx);
}
- foreach(object item in args.NewItems)
- {
- if(!(item is ColoredBlock block))
- continue;
-
- for(ulong i = 0; i < blocksToRead; i++)
- ColoredBlocks.Add(new ColoredBlock((block.Block / SectorsPerBlock) + i, block.Color));
- }
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
break;
+ }
+ case NotifyCollectionChangedAction.Remove:
+ case NotifyCollectionChangedAction.Move:
+ {
+ if(!(e.NewItems is { } newItems) ||
+ !(e.OldItems is { } oldItems))
+ throw new ArgumentException("Invalid list of items");
+
+ using IDrawingContextImpl ctxi = _bitmap.CreateDrawingContext(null);
+ using var ctx = new DrawingContext(ctxi, false);
+
+ foreach(object item in oldItems)
+ {
+ if(!(item is ValueTuple block))
+ throw new ArgumentException("Invalid item in list", nameof(Items));
+
+ DrawCluster(block.Item1, block.Item2, false, ctx);
+ }
+
+ foreach(object item in newItems)
+ {
+ if(!(item is ValueTuple block))
+ throw new ArgumentException("Invalid item in list", nameof(Items));
+
+ DrawCluster(block.Item1, block.Item2, false, ctx);
+ }
+
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+
+ break;
+ }
case NotifyCollectionChangedAction.Reset:
- ColoredBlocks.Clear();
+ CreateBitmap();
+ DrawGrid();
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
break;
default: throw new ArgumentOutOfRangeException();
}
}
- void CalculateBoundaries()
+ void RedrawAll()
{
- SectorsPerBlock = Blocks == 0 ? 0 : _sectors / Blocks;
- ColoredBlocks.Clear();
-
- if(SectorsPerBlock > 0)
+ if(Items is null)
return;
- SectorsPerBlock = 1;
+ using IDrawingContextImpl ctxi = _bitmap.CreateDrawingContext(null);
+ using var ctx = new DrawingContext(ctxi, false);
- for(ulong i = Sectors; i < Blocks; i++)
- ColoredBlocks.Add(new ColoredBlock(i, GridColor));
+ foreach(object item in Items)
+ {
+ if(!(item is ValueTuple block))
+ throw new ArgumentException("Invalid item in list", nameof(Items));
+
+ DrawCluster(block.Item1, block.Item2, false, ctx);
+ }
+
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
}
- public void Clear() => ColoredSectors.Clear();
+ void DrawCluster(ulong block, double duration, bool clear = false, DrawingContext ctx = null)
+ {
+ if(double.IsNegative(duration) ||
+ double.IsInfinity(duration))
+ throw new ArgumentException("Duration cannot be negative or infinite", nameof(duration));
+
+ bool newContext = ctx is null;
+ ulong clustersPerRow = (ulong)Width / _blockSize;
+ ulong cluster = block / _clusterSize;
+ ulong row = cluster / clustersPerRow;
+ ulong column = cluster % clustersPerRow;
+ ulong x = column * _blockSize;
+ ulong y = row * _blockSize;
+ var pen = new Pen(Foreground);
+
+ IBrush brush;
+
+ if(clear)
+ brush = Background;
+ else if(duration < SuperFastMaxTime)
+ brush = SuperFastColor;
+ else if(duration >= SuperFastMaxTime &&
+ duration < FastMaxTime)
+ brush = FastColor;
+ else if(duration >= FastMaxTime &&
+ duration < AverageMaxTime)
+ brush = AverageColor;
+ else if(duration >= AverageMaxTime &&
+ duration < SlowMaxTime)
+ brush = SlowColor;
+ else if(duration >= SlowMaxTime &&
+ duration < SuperSlowMaxTime)
+ brush = SuperSlowColor;
+ else if(duration >= SuperSlowMaxTime ||
+ double.IsNaN(duration))
+ brush = ProblematicColor;
+ else
+ brush = Background;
+
+ if(newContext)
+ {
+ using IDrawingContextImpl ctxi = _bitmap.CreateDrawingContext(null);
+ ctx = new DrawingContext(ctxi, false);
+ }
+
+ ctx.FillRectangle(brush, new Rect(x, y, _blockSize, _blockSize));
+ ctx.DrawRectangle(pen, new Rect(x, y, _blockSize, _blockSize));
+
+ if(double.IsNaN(duration))
+ {
+ ctx.DrawLine(pen, new Point(x, y), new Point(x + _blockSize, y + _blockSize));
+ ctx.DrawLine(pen, new Point(x, y + _blockSize), new Point(x + _blockSize, y));
+ }
+
+ if(newContext)
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+ }
+
+ protected override void ItemsChanged(AvaloniaPropertyChangedEventArgs e)
+ {
+ if(e.NewValue != null &&
+ !(e.NewValue is IList<(ulong, double)>))
+ {
+ throw new
+ ArgumentException("Items must be a IList<(ulong, double)> with ulong being the block and double being the time spent reading it, or NaN for an error.");
+ }
+
+ base.ItemsChanged(e);
+
+ CreateBitmap();
+ DrawGrid();
+ RedrawAll();
+ Dispatcher.UIThread.Post(InvalidateVisual, DispatcherPriority.Background);
+ }
+
+ void CreateBitmap()
+ {
+ if(_maxBlocks == 0)
+ _maxBlocks = (ulong)((Width / _blockSize) * (Height / _blockSize));
+
+ _bitmap?.Dispose();
+
+ _bitmap = new RenderTargetBitmap(new PixelSize((int)Width, (int)Height), new Vector(96, 96));
+
+ using IDrawingContextImpl ctxi = _bitmap.CreateDrawingContext(null);
+ using var ctx = new DrawingContext(ctxi, false);
+
+ ctx.FillRectangle(Background, new Rect(0, 0, Width, Height));
+ }
+
+ void DrawGrid()
+ {
+ using IDrawingContextImpl ctxi = _bitmap.CreateDrawingContext(null);
+ using var ctx = new DrawingContext(ctxi, false);
+
+ ulong clustersPerRow = (ulong)Width / _blockSize;
+
+ bool allBlocksDrawn = false;
+
+ for(ulong y = 0; y < Height && !allBlocksDrawn; y += _blockSize)
+ {
+ for(ulong x = 0; x < Width; x += _blockSize)
+ {
+ ulong currentBlockValue = ((y * clustersPerRow) / _blockSize) + (x / _blockSize);
+
+ if(currentBlockValue >= _maxBlocks ||
+ currentBlockValue >= Blocks)
+ {
+ allBlocksDrawn = true;
+
+ break;
+ }
+
+ ctx.DrawRectangle(new Pen(Foreground), new Rect(x, y, _blockSize, _blockSize));
+ }
+ }
+ }
+
+ protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ if(Width < 1 ||
+ Height < 1 ||
+ double.IsNaN(Width) ||
+ double.IsNaN(Height))
+ {
+ base.OnAttachedToLogicalTree(e);
+
+ return;
+ }
+
+ CreateBitmap();
+ DrawGrid();
+
+ base.OnAttachedToLogicalTree(e);
+ }
+
+ protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
+ {
+ _bitmap.Dispose();
+ _bitmap = null;
+ base.OnDetachedFromLogicalTree(e);
+ }
}
}
\ No newline at end of file
diff --git a/Aaru.Gui/ViewModels/Windows/MediaScanViewModel.cs b/Aaru.Gui/ViewModels/Windows/MediaScanViewModel.cs
index a920f26ab..67927d45d 100644
--- a/Aaru.Gui/ViewModels/Windows/MediaScanViewModel.cs
+++ b/Aaru.Gui/ViewModels/Windows/MediaScanViewModel.cs
@@ -1,3 +1,4 @@
+using System.Collections.ObjectModel;
using System.Reactive;
using System.Threading;
using Aaru.Core;
@@ -19,43 +20,36 @@ namespace Aaru.Gui.ViewModels.Windows
string _a;
string _avgSpeed;
string _b;
- ulong _blocksToRead;
- string _c;
- bool _closeVisible;
- string _d;
- string _devicePath;
- string _e;
- string _f;
- ScanResults _localResults;
- string _maxSpeed;
- string _minSpeed;
- bool _progress1Visible;
- string _progress2Indeterminate;
- string _progress2MaxValue;
- string _progress2Text;
- string _progress2Value;
- string _progress2Visible;
- bool _progressIndeterminate;
- double _progressMaxValue;
- string _progressText;
- double _progressValue;
- bool _progressVisible;
- bool _resultsVisible;
- MediaScan _scanner;
- bool _startVisible;
- string _stopEnabled;
- bool _stopVisible;
- string _totalTime;
- string _unreadableSectors;
- /*
- static readonly Color LightGreen = Color.FromRgb(0x00FF00);
- static readonly Color Green = Color.FromRgb(0x006400);
- static readonly Color DarkGreen = Color.FromRgb(0x003200);
- static readonly Color Yellow = Color.FromRgb(0xFFA500);
- static readonly Color Orange = Color.FromRgb(0xFF4500);
- static readonly Color Red = Color.FromRgb(0x800000);
- static Color LightRed = Color.FromRgb(0xFF0000);
- */
+
+ ulong _blocks;
+ ulong _blocksToRead;
+ string _c;
+ bool _closeVisible;
+ string _d;
+ string _devicePath;
+ string _e;
+ string _f;
+ ScanResults _localResults;
+ string _maxSpeed;
+ string _minSpeed;
+ bool _progress1Visible;
+ string _progress2Indeterminate;
+ string _progress2MaxValue;
+ string _progress2Text;
+ string _progress2Value;
+ string _progress2Visible;
+ bool _progressIndeterminate;
+ double _progressMaxValue;
+ string _progressText;
+ double _progressValue;
+ bool _progressVisible;
+ bool _resultsVisible;
+ MediaScan _scanner;
+ bool _startVisible;
+ string _stopEnabled;
+ bool _stopVisible;
+ string _totalTime;
+ string _unreadableSectors;
public MediaScanViewModel(string devicePath, DeviceInfo deviceInfo, Window view, ScsiInfo scsiInfo = null)
{
@@ -67,6 +61,7 @@ namespace Aaru.Gui.ViewModels.Windows
StopCommand = ReactiveCommand.Create(ExecuteStopCommand);
StartVisible = true;
CloseVisible = true;
+ BlockMapList = new ObservableCollection<(ulong block, double duration)>();
/*
lineChart.AbsoluteMargins = true;
@@ -80,6 +75,23 @@ namespace Aaru.Gui.ViewModels.Windows
lineChart.LineColor = Colors.Yellow;
*/
}
+ /*
+ static readonly Color LightGreen = Color.FromRgb(0x00FF00);
+ static readonly Color Green = Color.FromRgb(0x006400);
+ static readonly Color DarkGreen = Color.FromRgb(0x003200);
+ static readonly Color Yellow = Color.FromRgb(0xFFA500);
+ static readonly Color Orange = Color.FromRgb(0xFF4500);
+ static readonly Color Red = Color.FromRgb(0x800000);
+ static Color LightRed = Color.FromRgb(0xFF0000);
+ */
+
+ public ObservableCollection<(ulong block, double duration)> BlockMapList { get; }
+
+ public ulong Blocks
+ {
+ get => _blocks;
+ set => this.RaiseAndSetIfChanged(ref _blocks, value);
+ }
public string A
{
@@ -331,10 +343,10 @@ namespace Aaru.Gui.ViewModels.Windows
async void InitBlockMap(ulong blocks, ulong blocksize, ulong blockstoread, ushort currentProfile) =>
await Dispatcher.UIThread.InvokeAsync(() =>
{
- /* TODO: BlockMap
- blockMap.Sectors = blocks;
- blockMap.SectorsToRead = (uint)blockstoread;
- blocksToRead = blockstoread;
+ Blocks = blocks / blockstoread;
+ _blocksToRead = blockstoread;
+
+ /* TODO: Chart
lineChart.MinX = 0;
lineChart.MinY = 0;
@@ -488,6 +500,7 @@ namespace Aaru.Gui.ViewModels.Windows
{
_localResults.Errored += _blocksToRead;
UnreadableSectors = $"{_localResults.Errored} sectors could not be read.";
+ BlockMapList.Add((sector / _blocksToRead, double.NaN));
/* TODO: Blockmap
blockMap.ColoredSectors.Add(new ColoredBlock(sector, LightGreen));
*/
@@ -495,6 +508,8 @@ namespace Aaru.Gui.ViewModels.Windows
async void OnScanTime(ulong sector, double duration) => await Dispatcher.UIThread.InvokeAsync(() =>
{
+ BlockMapList.Add((sector / _blocksToRead, duration));
+
if(duration < 3)
{
_localResults.A += _blocksToRead;
diff --git a/Aaru.Gui/Views/Windows/MediaScan.xaml b/Aaru.Gui/Views/Windows/MediaScan.xaml
index 049b4e9c0..49c01bfeb 100644
--- a/Aaru.Gui/Views/Windows/MediaScan.xaml
+++ b/Aaru.Gui/Views/Windows/MediaScan.xaml
@@ -1,9 +1,9 @@
+ xmlns:windows="clr-namespace:Aaru.Gui.ViewModels.Windows" xmlns:controls="clr-namespace:Aaru.Gui.Controls"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Aaru.Gui.Views.Windows.MediaScan"
+ Icon="/Assets/aaru-logo.png" Title="{Binding Title}">
@@ -27,7 +27,7 @@
-
+