From 1e976507fd790092b315938d783df3ca25f4da05 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Fri, 17 Apr 2020 05:23:17 +0100 Subject: [PATCH] Implement BlockMap using Avalonia. --- .idea/.idea.Aaru/.idea/contentModel.xml | 485 +++++++++--------- Aaru.Gui/Controls/BlockMap.cs | 465 ++++++++++++++--- .../ViewModels/Windows/MediaScanViewModel.cs | 97 ++-- Aaru.Gui/Views/Windows/MediaScan.xaml | 8 +- 4 files changed, 689 insertions(+), 366 deletions(-) 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 @@ - +