mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-02-18 00:17:43 +01:00
Address rmcrackan comments and refactor
This commit is contained in:
@@ -7,6 +7,7 @@ using Avalonia.Threading;
|
|||||||
using DataLayer;
|
using DataLayer;
|
||||||
using LibationUiBase;
|
using LibationUiBase;
|
||||||
using LibationUiBase.Forms;
|
using LibationUiBase.Forms;
|
||||||
|
using LibationUiBase.ProcessQueue;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -31,9 +32,9 @@ public partial class FindBetterQualityBooksDialog : DialogWindow
|
|||||||
};
|
};
|
||||||
VM.Books[0].AvailableCodec = "xHE-AAC";
|
VM.Books[0].AvailableCodec = "xHE-AAC";
|
||||||
VM.Books[0].AvailableBitrate = 256;
|
VM.Books[0].AvailableBitrate = 256;
|
||||||
VM.Books[0].ScanStatus = BookScanStatus.Completed;
|
VM.Books[0].ScanStatus = ProcessBookStatus.Completed;
|
||||||
VM.Books[1].ScanStatus = BookScanStatus.Error;
|
VM.Books[1].ScanStatus = ProcessBookStatus.Failed;
|
||||||
VM.Books[2].ScanStatus = BookScanStatus.Cancelled;
|
VM.Books[2].ScanStatus = ProcessBookStatus.Cancelled;
|
||||||
VM.SignificantCount = 1;
|
VM.SignificantCount = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -49,7 +50,13 @@ public partial class FindBetterQualityBooksDialog : DialogWindow
|
|||||||
|
|
||||||
private async void Opened_ShowInitialMessage(object? sender, System.EventArgs e)
|
private async void Opened_ShowInitialMessage(object? sender, System.EventArgs e)
|
||||||
{
|
{
|
||||||
await MessageBox.Show(this, FindBetterQualityBooksViewModel.InitialMessage, Title ?? "", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
if (!VM.ShowFindBetterQualityBooksHelp)
|
||||||
|
return;
|
||||||
|
var result = await MessageBox.Show(this, FindBetterQualityBooksViewModel.InitialMessage, Title ?? "", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
|
||||||
|
if (result == DialogResult.No)
|
||||||
|
{
|
||||||
|
VM.ShowFindBetterQualityBooksHelp = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Opened_LoadLibrary(object? sender, System.EventArgs e)
|
private async void Opened_LoadLibrary(object? sender, System.EventArgs e)
|
||||||
@@ -102,7 +109,7 @@ public partial class FindBetterQualityBooksDialog : DialogWindow
|
|||||||
if (VM.IsScanning)
|
if (VM.IsScanning)
|
||||||
VM.StopScan();
|
VM.StopScan();
|
||||||
else
|
else
|
||||||
await Task.Run(VM.ScanAsync);
|
await VM.ScanAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -138,15 +145,15 @@ public partial class FindBetterQualityBooksDialog : DialogWindow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FuncValueConverter<BookScanStatus, IBrush?> RowConverter { get; } = new(status =>
|
public static FuncValueConverter<ProcessBookStatus, IBrush?> RowConverter { get; } = new(status =>
|
||||||
{
|
{
|
||||||
var brush = status switch
|
var brush = status switch
|
||||||
{
|
{
|
||||||
BookScanStatus.Completed => "ProcessQueueBookCompletedBrush",
|
ProcessBookStatus.Completed => "ProcessQueueBookCompletedBrush",
|
||||||
BookScanStatus.Cancelled => "ProcessQueueBookCancelledBrush",
|
ProcessBookStatus.Cancelled => "ProcessQueueBookCancelledBrush",
|
||||||
BookScanStatus.Error => "ProcessQueueBookFailedBrush",
|
ProcessBookStatus.Failed => "ProcessQueueBookFailedBrush",
|
||||||
_ => null,
|
_ => null,
|
||||||
};
|
};
|
||||||
return brush is not null && App.Current.TryGetResource(brush, App.Current.ActualThemeVariant, out var res) ? res as Brush : null;
|
return brush is not null && App.Current.TryGetResource(brush, App.Current.ActualThemeVariant, out var res) ? res as Brush : null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
using DataLayer;
|
using DataLayer;
|
||||||
|
using LibationUiBase.ProcessQueue;
|
||||||
|
|
||||||
namespace LibationUiBase;
|
namespace LibationUiBase;
|
||||||
|
|
||||||
public enum BookScanStatus
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Error,
|
|
||||||
Cancelled,
|
|
||||||
Completed,
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BookDataViewModel : ReactiveObject
|
public class BookDataViewModel : ReactiveObject
|
||||||
{
|
{
|
||||||
public LibraryBook LibraryBook { get; }
|
public LibraryBook LibraryBook { get; }
|
||||||
@@ -48,6 +41,6 @@ public class BookDataViewModel : ReactiveObject
|
|||||||
public string? BitrateString { get => field; private set => RaiseAndSetIfChanged(ref field, value); }
|
public string? BitrateString { get => field; private set => RaiseAndSetIfChanged(ref field, value); }
|
||||||
public string? AvailableBitrateString { get => field; private set => RaiseAndSetIfChanged(ref field, value); }
|
public string? AvailableBitrateString { get => field; private set => RaiseAndSetIfChanged(ref field, value); }
|
||||||
public bool IsSignificant { get => field; private set => RaiseAndSetIfChanged(ref field, value); }
|
public bool IsSignificant { get => field; private set => RaiseAndSetIfChanged(ref field, value); }
|
||||||
public BookScanStatus ScanStatus { get => field; set => RaiseAndSetIfChanged(ref field, value); }
|
public ProcessBookStatus ScanStatus { get => field; set => RaiseAndSetIfChanged(ref field, value); }
|
||||||
private static string? GetBitrateString(int bitrate) => bitrate > 0 ? $"{bitrate} kbps" : null;
|
private static string? GetBitrateString(int bitrate) => bitrate > 0 ? $"{bitrate} kbps" : null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using DataLayer;
|
|||||||
using Dinah.Core;
|
using Dinah.Core;
|
||||||
using Dinah.Core.Net.Http;
|
using Dinah.Core.Net.Http;
|
||||||
using LibationFileManager;
|
using LibationFileManager;
|
||||||
|
using LibationUiBase.ProcessQueue;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -34,11 +35,13 @@ public class FindBetterQualityBooksViewModel : ReactiveObject
|
|||||||
When done, click the 'Mark X books as Not Liberated' to allow Libation to re-download those books in the higher.
|
When done, click the 'Mark X books as Not Liberated' to allow Libation to re-download those books in the higher.
|
||||||
|
|
||||||
Note: make sure you adjust your download quality settings before re-liberating the books.
|
Note: make sure you adjust your download quality settings before re-liberating the books.
|
||||||
|
|
||||||
|
Display this help message again in the future?
|
||||||
""";
|
""";
|
||||||
|
|
||||||
public event EventHandler<BookDataViewModel>? BookScanned;
|
public event EventHandler<BookDataViewModel>? BookScanned;
|
||||||
public IList<BookDataViewModel>? Books { get => field; set => RaiseAndSetIfChanged(ref field, value); }
|
public IList<BookDataViewModel>? Books { get => field; set => RaiseAndSetIfChanged(ref field, value); }
|
||||||
|
public bool ShowFindBetterQualityBooksHelp { get => Configuration.Instance.GetNonString(defaultValue: true); set => Configuration.Instance.SetNonString(value); }
|
||||||
public bool ScanWidevine { get; set; }
|
public bool ScanWidevine { get; set; }
|
||||||
public int SignificantCount
|
public int SignificantCount
|
||||||
{
|
{
|
||||||
@@ -93,7 +96,7 @@ public class FindBetterQualityBooksViewModel : ReactiveObject
|
|||||||
{
|
{
|
||||||
b.AvailableBitrate = 0;
|
b.AvailableBitrate = 0;
|
||||||
b.AvailableCodec = null;
|
b.AvailableCodec = null;
|
||||||
b.ScanStatus = BookScanStatus.None;
|
b.ScanStatus = ProcessBookStatus.Queued;
|
||||||
}
|
}
|
||||||
ScanCount = $"0 of {Books.Count:N0} scanned";
|
ScanCount = $"0 of {Books.Count:N0} scanned";
|
||||||
|
|
||||||
@@ -104,19 +107,20 @@ public class FindBetterQualityBooksViewModel : ReactiveObject
|
|||||||
for (int i = 0; i < Books.Count; i++)
|
for (int i = 0; i < Books.Count; i++)
|
||||||
{
|
{
|
||||||
var b = Books[i];
|
var b = Books[i];
|
||||||
var url = GetUrl(b.LibraryBook);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
cts.Token.ThrowIfCancellationRequested();
|
||||||
|
var url = GetUrl(b.LibraryBook);
|
||||||
//Don't re-scan a file if we have already loaded existing audio codec and bitrate.
|
//Don't re-scan a file if we have already loaded existing audio codec and bitrate.
|
||||||
if (b.Bitrate == 0 && b.Codec == null)
|
if (b.Bitrate == 0 && b.Codec == null)
|
||||||
{
|
{
|
||||||
var (file, bestformat) = FindHighestExistingFormat(b.LibraryBook);
|
var (file, bestFormat) = FindHighestExistingFormat(b.LibraryBook);
|
||||||
|
|
||||||
if (file is not null)
|
if (file is not null)
|
||||||
{
|
{
|
||||||
b.FoundFile = Configuration.Instance.Books?.Path is string booksDir ? Path.GetRelativePath(booksDir, file) : file;
|
b.FoundFile = Configuration.Instance.Books?.Path is string booksDir ? Path.GetRelativePath(booksDir, file) : file;
|
||||||
b.Bitrate = bestformat.BitRate;
|
b.Bitrate = bestFormat.BitRate;
|
||||||
b.Codec = bestformat.CodecString;
|
b.Codec = bestFormat.CodecString;
|
||||||
}
|
}
|
||||||
else if (b.LibraryBook.Book.UserDefinedItem.LastDownloadedFormat is not null)
|
else if (b.LibraryBook.Book.UserDefinedItem.LastDownloadedFormat is not null)
|
||||||
{
|
{
|
||||||
@@ -127,7 +131,7 @@ public class FindBetterQualityBooksViewModel : ReactiveObject
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
b.FoundFile = "File not found and no 'Last Downloaded' format found.";
|
b.FoundFile = "File not found and no 'Last Downloaded' format found.";
|
||||||
b.ScanStatus = BookScanStatus.Error;
|
b.ScanStatus = ProcessBookStatus.Failed;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,18 +141,18 @@ public class FindBetterQualityBooksViewModel : ReactiveObject
|
|||||||
|
|
||||||
b.AvailableCodec = codecString;
|
b.AvailableCodec = codecString;
|
||||||
b.AvailableBitrate = bitrate;
|
b.AvailableBitrate = bitrate;
|
||||||
b.ScanStatus = BookScanStatus.Completed;
|
b.ScanStatus = ProcessBookStatus.Completed;
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
b.ScanStatus = BookScanStatus.Cancelled;
|
b.ScanStatus = ProcessBookStatus.Cancelled;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Serilog.Log.Logger.Error(ex, "Error checking for better quality for {@Asin}", b.Asin);
|
Serilog.Log.Logger.Error(ex, "Error checking for better quality for {@Asin}", b.Asin);
|
||||||
b.FoundFile = $"Error: {ex.Message}";
|
b.FoundFile = $"Error: {ex.Message}";
|
||||||
b.ScanStatus = BookScanStatus.Error;
|
b.ScanStatus = ProcessBookStatus.Failed;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -168,20 +172,20 @@ public class FindBetterQualityBooksViewModel : ReactiveObject
|
|||||||
|
|
||||||
private static (string? file, AudioFormat format) FindHighestExistingFormat(LibraryBook libraryBook)
|
private static (string? file, AudioFormat format) FindHighestExistingFormat(LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
var largestfile
|
var largestFile
|
||||||
= AudibleFileStorage.Audio
|
= AudibleFileStorage.Audio
|
||||||
.GetPaths(libraryBook.Book.AudibleProductId)
|
.GetPaths(libraryBook.Book.AudibleProductId)
|
||||||
.Select(p => new FileInfo(p))
|
.Select(p => new FileInfo(p))
|
||||||
.Where(f => f.Exists && f.Extension.EqualsInsensitive(".m4b"))
|
.Where(f => f.Exists && f.Extension.EqualsInsensitive(".m4b"))
|
||||||
.OrderByDescending(f => f.Length)
|
.OrderByDescending(f => f.Length)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault()
|
||||||
|
?.FullName;
|
||||||
|
|
||||||
if (largestfile is null)
|
return largestFile is null ? (null, AudioFormat.Default)
|
||||||
return (null, AudioFormat.Default);
|
: (largestFile, AudioFormatDecoder.FromMpeg4(largestFile));
|
||||||
return (largestfile.FullName, AudioFormatDecoder.FromMpeg4(largestfile.FullName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async Task<(string codec, int bitrate)> ReadAudioInfoAsync(HttpResponseMessage response)
|
private static async Task<(string codec, int bitrate)> ReadAudioInfoAsync(HttpResponseMessage response)
|
||||||
{
|
{
|
||||||
var data = await response.Content.ReadAsJObjectAsync();
|
var data = await response.Content.ReadAsJObjectAsync();
|
||||||
var totalLengthMs = data["content_metadata"]?["chapter_info"]?.Value<long>("runtime_length_ms") ?? throw new InvalidDataException("Missing runtime length");
|
var totalLengthMs = data["content_metadata"]?["chapter_info"]?.Value<long>("runtime_length_ms") ?? throw new InvalidDataException("Missing runtime length");
|
||||||
@@ -202,12 +206,12 @@ public class FindBetterQualityBooksViewModel : ReactiveObject
|
|||||||
return (codecString, bitrate);
|
return (codecString, bitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetUrl(LibraryBook libraryBook)
|
private string GetUrl(LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
var drm_type = ScanWidevine ? "Widevine" : "Adrm";
|
var drm_type = ScanWidevine ? "Widevine" : "Adrm";
|
||||||
var locale = AudibleApi.Localization.Get(libraryBook.Book.Locale);
|
var locale = AudibleApi.Localization.Get(libraryBook.Book.Locale);
|
||||||
return string.Format(BaseUrl, locale.TopDomain, libraryBook.Book.AudibleProductId, drm_type);
|
return string.Format(BaseUrl, locale.TopDomain, libraryBook.Book.AudibleProductId, drm_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
const string BaseUrl = "ht" + "tps://api.audible.{0}/1.0/content/{1}/metadata?response_groups=chapter_info,content_reference&quality=High&drm_type={2}";
|
private const string BaseUrl = "ht" + "tps://api.audible.{0}/1.0/content/{1}/metadata?response_groups=chapter_info,content_reference&quality=High&drm_type={2}";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ partial class FindBetterQualityBooksDialog
|
|||||||
dataGridView1.RowHeadersVisible = false;
|
dataGridView1.RowHeadersVisible = false;
|
||||||
dataGridView1.Size = new System.Drawing.Size(897, 397);
|
dataGridView1.Size = new System.Drawing.Size(897, 397);
|
||||||
dataGridView1.TabIndex = 0;
|
dataGridView1.TabIndex = 0;
|
||||||
dataGridView1.CellFormatting += dataGridView1_CellFormatting;
|
|
||||||
//
|
//
|
||||||
// asinDataGridViewTextBoxColumn
|
// asinDataGridViewTextBoxColumn
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using ApplicationServices;
|
using ApplicationServices;
|
||||||
using LibationUiBase;
|
using LibationUiBase;
|
||||||
|
using LibationUiBase.ProcessQueue;
|
||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
@@ -34,12 +36,23 @@ public partial class FindBetterQualityBooksDialog : Form
|
|||||||
Shown += Shown_LoadLibrary;
|
Shown += Shown_LoadLibrary;
|
||||||
Shown += Shown_ShowInitialMessage;
|
Shown += Shown_ShowInitialMessage;
|
||||||
FormClosing += FindBetterQualityBooksDialog_FormClosing;
|
FormClosing += FindBetterQualityBooksDialog_FormClosing;
|
||||||
|
SetDoubleBuffer(dataGridView1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SetDoubleBuffer(Control control, bool DoubleBuffered)
|
||||||
|
{
|
||||||
|
typeof(Control).InvokeMember("DoubleBuffered", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, control, [DoubleBuffered]);
|
||||||
|
}
|
||||||
|
|
||||||
private void Shown_ShowInitialMessage(object? sender, EventArgs e)
|
private void Shown_ShowInitialMessage(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
MessageBox.Show(this, FindBetterQualityBooksViewModel.InitialMessage, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
|
if (!VM.ShowFindBetterQualityBooksHelp)
|
||||||
|
return;
|
||||||
|
var result = MessageBox.Show(this, FindBetterQualityBooksViewModel.InitialMessage, Text, MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
|
||||||
|
if (result == DialogResult.No)
|
||||||
|
{
|
||||||
|
VM.ShowFindBetterQualityBooksHelp = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Shown_LoadLibrary(object? sender, EventArgs e)
|
private async void Shown_LoadLibrary(object? sender, EventArgs e)
|
||||||
@@ -51,7 +64,13 @@ public partial class FindBetterQualityBooksDialog : Form
|
|||||||
Invoke(() =>
|
Invoke(() =>
|
||||||
{
|
{
|
||||||
bookDataViewModelBindingSource.DataSource = VM.Books;
|
bookDataViewModelBindingSource.DataSource = VM.Books;
|
||||||
|
foreach (DataGridViewRow r in dataGridView1.Rows)
|
||||||
|
{
|
||||||
|
//Force creation of DefaultCellStyle to speed up later coloring
|
||||||
|
//_ = r.DefaultCellStyle;
|
||||||
|
}
|
||||||
btnScan.Enabled = true;
|
btnScan.Enabled = true;
|
||||||
|
dataGridView1.CellFormatting += dataGridView1_CellFormatting;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +106,8 @@ public partial class FindBetterQualityBooksDialog : Form
|
|||||||
{
|
{
|
||||||
await scanTask;
|
await scanTask;
|
||||||
scanTask = null;
|
scanTask = null;
|
||||||
|
//give the UI a moment to update after cancelling the first close
|
||||||
|
await Task.Delay(100);
|
||||||
Invoke(Close);
|
Invoke(Close);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,7 +169,7 @@ public partial class FindBetterQualityBooksDialog : Form
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
|
private void dataGridView1_CellFormatting(object? sender, DataGridViewCellFormattingEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.RowIndex < 0 || e.RowIndex >= dataGridView1.Rows.Count)
|
if (e.RowIndex < 0 || e.RowIndex >= dataGridView1.Rows.Count)
|
||||||
return;
|
return;
|
||||||
@@ -156,18 +177,7 @@ public partial class FindBetterQualityBooksDialog : Form
|
|||||||
var row = dataGridView1.Rows[e.RowIndex];
|
var row = dataGridView1.Rows[e.RowIndex];
|
||||||
if (row.DataBoundItem is BookDataViewModel bvm)
|
if (row.DataBoundItem is BookDataViewModel bvm)
|
||||||
{
|
{
|
||||||
///yes, this is tight coupling and bad practice.
|
row.DefaultCellStyle.BackColor = bvm.ScanStatus.GetColor();
|
||||||
///If we ever need tese colors in a third place,
|
|
||||||
///consider moving them to a shared location like
|
|
||||||
///App.axaml in LibationAvalonia
|
|
||||||
var color = bvm.ScanStatus switch
|
|
||||||
{
|
|
||||||
BookScanStatus.Completed => ProcessQueue.ProcessBookControl.SuccessColor,
|
|
||||||
BookScanStatus.Cancelled => ProcessQueue.ProcessBookControl.CancelledColor,
|
|
||||||
BookScanStatus.Error => ProcessQueue.ProcessBookControl.FailedColor,
|
|
||||||
_ => ProcessQueue.ProcessBookControl.QueuedColor,
|
|
||||||
};
|
|
||||||
row.DefaultCellStyle.BackColor = color;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,11 +12,6 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
private readonly int ProgressBarDistanceFromEdge;
|
private readonly int ProgressBarDistanceFromEdge;
|
||||||
private object? m_OldContext;
|
private object? m_OldContext;
|
||||||
|
|
||||||
public static Color FailedColor => Application.IsDarkModeEnabled ? Color.FromArgb(0x50, 0x27, 0x27) : Color.LightCoral;
|
|
||||||
public static Color CancelledColor => Application.IsDarkModeEnabled ? Color.FromArgb(0x4e, 0x4b, 0x15) : Color.Khaki;
|
|
||||||
public static Color QueuedColor { get; } = SystemColors.Control;
|
|
||||||
public static Color SuccessColor => Application.IsDarkModeEnabled ? Color.FromArgb(0x1c, 0x3e, 0x20) : Color.PaleGreen;
|
|
||||||
|
|
||||||
public ProcessBookControl()
|
public ProcessBookControl()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -82,15 +77,6 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
|
|
||||||
private void SetStatus(ProcessBookStatus status, string statusText)
|
private void SetStatus(ProcessBookStatus status, string statusText)
|
||||||
{
|
{
|
||||||
Color backColor = status switch
|
|
||||||
{
|
|
||||||
ProcessBookStatus.Completed => SuccessColor,
|
|
||||||
ProcessBookStatus.Cancelled => CancelledColor,
|
|
||||||
ProcessBookStatus.Queued => QueuedColor,
|
|
||||||
ProcessBookStatus.Working => QueuedColor,
|
|
||||||
_ => FailedColor
|
|
||||||
};
|
|
||||||
|
|
||||||
cancelBtn.Visible = status is ProcessBookStatus.Queued or ProcessBookStatus.Working;
|
cancelBtn.Visible = status is ProcessBookStatus.Queued or ProcessBookStatus.Working;
|
||||||
moveLastBtn.Visible = status == ProcessBookStatus.Queued;
|
moveLastBtn.Visible = status == ProcessBookStatus.Queued;
|
||||||
moveDownBtn.Visible = status == ProcessBookStatus.Queued;
|
moveDownBtn.Visible = status == ProcessBookStatus.Queued;
|
||||||
@@ -101,7 +87,7 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
etaLbl.Visible = status == ProcessBookStatus.Working;
|
etaLbl.Visible = status == ProcessBookStatus.Working;
|
||||||
statusLbl.Visible = status != ProcessBookStatus.Working;
|
statusLbl.Visible = status != ProcessBookStatus.Working;
|
||||||
statusLbl.Text = statusText;
|
statusLbl.Text = statusText;
|
||||||
BackColor = backColor;
|
BackColor = status.GetColor();
|
||||||
|
|
||||||
int deltaX = Width - cancelBtn.Location.X - CancelBtnDistanceFromEdge;
|
int deltaX = Width - cancelBtn.Location.X - CancelBtnDistanceFromEdge;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Drawing;
|
using LibationUiBase.ProcessQueue;
|
||||||
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace LibationWinForms;
|
namespace LibationWinForms;
|
||||||
@@ -9,6 +10,13 @@ internal static class ThemeExtensions
|
|||||||
private static readonly Color LinkLabelVisited = Color.FromKnownColor(KnownColor.Purple);
|
private static readonly Color LinkLabelVisited = Color.FromKnownColor(KnownColor.Purple);
|
||||||
private static readonly Color LinkLabelNew_Dark = Color.FromKnownColor(KnownColor.CornflowerBlue);
|
private static readonly Color LinkLabelNew_Dark = Color.FromKnownColor(KnownColor.CornflowerBlue);
|
||||||
private static readonly Color LinkLabelVisited_Dark = Color.FromKnownColor(KnownColor.Orchid);
|
private static readonly Color LinkLabelVisited_Dark = Color.FromKnownColor(KnownColor.Orchid);
|
||||||
|
private static readonly Color FailedColor = Color.LightCoral;
|
||||||
|
private static readonly Color FailedColor_Dark = Color.FromArgb(0x50, 0x27, 0x27);
|
||||||
|
private static readonly Color CancelledColor = Color.Khaki;
|
||||||
|
private static readonly Color CancelledColor_Dark = Color.FromArgb(0x4e, 0x4b, 0x15);
|
||||||
|
private static readonly Color SuccessColor = Color.PaleGreen;
|
||||||
|
private static readonly Color SuccessColor_Dark = Color.FromArgb(0x1c, 0x3e, 0x20);
|
||||||
|
|
||||||
public static Color LinkColor => Application.IsDarkModeEnabled ? LinkLabelNew_Dark : LinkLabelNew;
|
public static Color LinkColor => Application.IsDarkModeEnabled ? LinkLabelNew_Dark : LinkLabelNew;
|
||||||
public static Color VisitedLinkColor => Application.IsDarkModeEnabled ? LinkLabelVisited_Dark : LinkLabelVisited;
|
public static Color VisitedLinkColor => Application.IsDarkModeEnabled ? LinkLabelVisited_Dark : LinkLabelVisited;
|
||||||
extension(LinkLabel ll)
|
extension(LinkLabel ll)
|
||||||
@@ -19,4 +27,16 @@ internal static class ThemeExtensions
|
|||||||
ll.LinkColor = LinkColor;
|
ll.LinkColor = LinkColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension(ProcessBookStatus status)
|
||||||
|
{
|
||||||
|
public Color GetColor() => status switch
|
||||||
|
{
|
||||||
|
ProcessBookStatus.Completed => Application.IsDarkModeEnabled ? SuccessColor_Dark : SuccessColor,
|
||||||
|
ProcessBookStatus.Cancelled => Application.IsDarkModeEnabled ? CancelledColor_Dark : CancelledColor,
|
||||||
|
ProcessBookStatus.Queued => SystemColors.Control,
|
||||||
|
ProcessBookStatus.Working => SystemColors.Control,
|
||||||
|
_ => Application.IsDarkModeEnabled ? FailedColor_Dark : FailedColor
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user