Added VirtualFlowControl and BookQueue
This commit is contained in:
parent
24cb1aa84f
commit
763a6cb31a
175
Source/LibationWinForms/ProcessQueue/BookQueue.cs
Normal file
175
Source/LibationWinForms/ProcessQueue/BookQueue.cs
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LibationWinForms.ProcessQueue
|
||||||
|
{
|
||||||
|
internal class TrackedQueue<T> where T : class
|
||||||
|
{
|
||||||
|
public T Current { get; private set; }
|
||||||
|
private readonly LinkedList<T> Queued = new();
|
||||||
|
private readonly List<T> Completed = new();
|
||||||
|
private readonly object lockObject = new();
|
||||||
|
|
||||||
|
public int Count => Queued.Count + Completed.Count + (Current == null ? 0 : 1);
|
||||||
|
|
||||||
|
public T this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (index < Completed.Count)
|
||||||
|
return Completed[index];
|
||||||
|
index -= Completed.Count;
|
||||||
|
|
||||||
|
if (index == 0&& Current != null) return Current;
|
||||||
|
|
||||||
|
if (Current != null) index--;
|
||||||
|
|
||||||
|
if (index < Queued.Count) return Queued.ElementAt(index);
|
||||||
|
|
||||||
|
throw new IndexOutOfRangeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> QueuedItems()
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
return Queued.ToList();
|
||||||
|
}
|
||||||
|
public List<T> CompletedItems()
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
return Completed.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool QueueCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
return Queued.Count > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CompleteCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
return Completed.Count > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void ClearQueue()
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
{
|
||||||
|
Queued.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearCompleted()
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
{
|
||||||
|
Completed.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Any(Func<T, bool> predicate)
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
{
|
||||||
|
return (Current != null && predicate(Current)) || Completed.Any(predicate) || Queued.Any(predicate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueuePosition MoveQueuePosition(T item, QueuePositionRequest requestedPosition)
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
{
|
||||||
|
if (Queued.Count == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (Current != null && Current == item)
|
||||||
|
return QueuePosition.Current;
|
||||||
|
if (Completed.Contains(item))
|
||||||
|
return QueuePosition.Completed;
|
||||||
|
return QueuePosition.Absent;
|
||||||
|
}
|
||||||
|
|
||||||
|
var node = Queued.Find(item);
|
||||||
|
if (node is null) return QueuePosition.Absent;
|
||||||
|
|
||||||
|
if ((requestedPosition == QueuePositionRequest.Fisrt || requestedPosition == QueuePositionRequest.OneUp) && Queued.First.Value == item)
|
||||||
|
return QueuePosition.Fisrt;
|
||||||
|
if ((requestedPosition == QueuePositionRequest.Last || requestedPosition == QueuePositionRequest.OneDown) && Queued.Last.Value == item)
|
||||||
|
return QueuePosition.Last;
|
||||||
|
|
||||||
|
if (requestedPosition == QueuePositionRequest.OneUp)
|
||||||
|
{
|
||||||
|
var oneUp = node.Previous;
|
||||||
|
Queued.Remove(node);
|
||||||
|
Queued.AddBefore(oneUp, node.Value);
|
||||||
|
return Queued.First.Value == item? QueuePosition.Fisrt : QueuePosition.OneUp;
|
||||||
|
}
|
||||||
|
else if (requestedPosition == QueuePositionRequest.OneDown)
|
||||||
|
{
|
||||||
|
var oneDown = node.Next;
|
||||||
|
Queued.Remove(node);
|
||||||
|
Queued.AddAfter(oneDown, node.Value);
|
||||||
|
return Queued.Last.Value == item ? QueuePosition.Last : QueuePosition.OneDown;
|
||||||
|
}
|
||||||
|
else if (requestedPosition == QueuePositionRequest.Fisrt)
|
||||||
|
{
|
||||||
|
Queued.Remove(node);
|
||||||
|
Queued.AddFirst(node);
|
||||||
|
return QueuePosition.Fisrt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Queued.Remove(node);
|
||||||
|
Queued.AddLast(node);
|
||||||
|
return QueuePosition.Last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Remove(T item)
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
{
|
||||||
|
return Queued.Remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
{
|
||||||
|
if (Current != null)
|
||||||
|
Completed.Add(Current);
|
||||||
|
if (Queued.Count == 0) return false;
|
||||||
|
Current = Queued.First.Value;
|
||||||
|
Queued.RemoveFirst();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public T PeekNext()
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
return Queued.Count > 0 ? Queued.First.Value : default;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EnqueueBook(T item)
|
||||||
|
{
|
||||||
|
lock (lockObject)
|
||||||
|
Queued.AddLast(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,22 +16,39 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
None,
|
None,
|
||||||
Success,
|
Success,
|
||||||
Cancelled,
|
Cancelled,
|
||||||
|
ValidationFail,
|
||||||
FailedRetry,
|
FailedRetry,
|
||||||
FailedSkip,
|
FailedSkip,
|
||||||
FailedAbort
|
FailedAbort
|
||||||
}
|
}
|
||||||
|
public enum ProcessBookStatus
|
||||||
|
{
|
||||||
|
Queued,
|
||||||
|
Cancelled,
|
||||||
|
Working,
|
||||||
|
Completed,
|
||||||
|
Failed
|
||||||
|
}
|
||||||
|
|
||||||
internal enum QueuePosition
|
internal enum QueuePosition
|
||||||
{
|
{
|
||||||
Absent,
|
Absent,
|
||||||
|
Completed,
|
||||||
Current,
|
Current,
|
||||||
Fisrt,
|
Fisrt,
|
||||||
OneUp,
|
OneUp,
|
||||||
OneDown,
|
OneDown,
|
||||||
Last
|
Last
|
||||||
}
|
}
|
||||||
|
internal enum QueuePositionRequest
|
||||||
|
{
|
||||||
|
Fisrt,
|
||||||
|
OneUp,
|
||||||
|
OneDown,
|
||||||
|
Last
|
||||||
|
}
|
||||||
|
|
||||||
internal delegate QueuePosition ProcessControlReorderHandler(ProcessBook sender, QueuePosition arg);
|
internal delegate QueuePosition ProcessControlReorderHandler(ProcessBook sender, QueuePositionRequest arg);
|
||||||
internal delegate void ProcessControlEventArgs<T>(ProcessBook sender, T arg);
|
internal delegate void ProcessControlEventArgs<T>(ProcessBook sender, T arg);
|
||||||
internal delegate void ProcessControlEventArgs(ProcessBook sender, EventArgs arg);
|
internal delegate void ProcessControlEventArgs(ProcessBook sender, EventArgs arg);
|
||||||
|
|
||||||
@ -41,7 +58,7 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
public event ProcessControlEventArgs Cancelled;
|
public event ProcessControlEventArgs Cancelled;
|
||||||
public event ProcessControlReorderHandler RequestMove;
|
public event ProcessControlReorderHandler RequestMove;
|
||||||
public GridEntry Entry { get; }
|
public GridEntry Entry { get; }
|
||||||
public ILiberationBaseForm BookControl { get; }
|
//public ProcessBookControl BookControl { get; }
|
||||||
|
|
||||||
private Func<Processable> _makeFirstProc;
|
private Func<Processable> _makeFirstProc;
|
||||||
private Processable _firstProcessable;
|
private Processable _firstProcessable;
|
||||||
@ -55,20 +72,15 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
public ProcessBook(GridEntry entry, LogMe logme)
|
public ProcessBook(GridEntry entry, LogMe logme)
|
||||||
{
|
{
|
||||||
Entry = entry;
|
Entry = entry;
|
||||||
BookControl = new ProcessBookControl(Entry.Title, Entry.Cover);
|
//BookControl = new ProcessBookControl(Entry.Title, Entry.Cover);
|
||||||
BookControl.CancelAction = Cancel;
|
//BookControl.CancelAction = Cancel;
|
||||||
BookControl.MoveUpAction = MoveUp;
|
//BookControl.RequestMoveAction = MoveRequested;
|
||||||
BookControl.MoveDownAction = MoveDown;
|
|
||||||
Logger = logme;
|
Logger = logme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueuePosition? MoveUp()
|
public QueuePosition? MoveRequested(QueuePositionRequest requestedPosition)
|
||||||
{
|
{
|
||||||
return RequestMove?.Invoke(this, QueuePosition.OneUp);
|
return RequestMove?.Invoke(this, requestedPosition);
|
||||||
}
|
|
||||||
public QueuePosition? MoveDown()
|
|
||||||
{
|
|
||||||
return RequestMove?.Invoke(this, QueuePosition.OneDown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Cancel()
|
public void Cancel()
|
||||||
@ -94,11 +106,9 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
ProcessBookResult result = ProcessBookResult.None;
|
ProcessBookResult result = ProcessBookResult.None;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var firstProc = FirstProcessable;
|
LinkProcessable(FirstProcessable);
|
||||||
|
|
||||||
LinkProcessable(firstProc);
|
var statusHandler = await FirstProcessable.ProcessSingleAsync(Entry.LibraryBook, validate: true);
|
||||||
|
|
||||||
var statusHandler = await firstProc.ProcessSingleAsync(Entry.LibraryBook, validate: true);
|
|
||||||
|
|
||||||
|
|
||||||
if (statusHandler.IsSuccess)
|
if (statusHandler.IsSuccess)
|
||||||
@ -108,6 +118,11 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
Logger.Info($"Process was cancelled {Entry.LibraryBook.Book}");
|
Logger.Info($"Process was cancelled {Entry.LibraryBook.Book}");
|
||||||
return result = ProcessBookResult.Cancelled;
|
return result = ProcessBookResult.Cancelled;
|
||||||
}
|
}
|
||||||
|
else if (statusHandler.Errors.Contains("Validation failed"))
|
||||||
|
{
|
||||||
|
Logger.Info($"Validation failed {Entry.LibraryBook.Book}");
|
||||||
|
return result = ProcessBookResult.ValidationFail;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var errorMessage in statusHandler.Errors)
|
foreach (var errorMessage in statusHandler.Errors)
|
||||||
Logger.Error(errorMessage);
|
Logger.Error(errorMessage);
|
||||||
@ -121,7 +136,7 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
if (result == ProcessBookResult.None)
|
if (result == ProcessBookResult.None)
|
||||||
result = showRetry(Entry.LibraryBook);
|
result = showRetry(Entry.LibraryBook);
|
||||||
|
|
||||||
BookControl.SetResult(result);
|
//BookControl.SetResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -149,8 +164,8 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
|
|
||||||
private void Processable_Begin(object sender, LibraryBook libraryBook)
|
private void Processable_Begin(object sender, LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
BookControl.RegisterFileLiberator((Processable)sender, Logger);
|
//BookControl.RegisterFileLiberator((Processable)sender, Logger);
|
||||||
BookControl.Processable_Begin(sender, libraryBook);
|
//BookControl.Processable_Begin(sender, libraryBook);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Processable_Completed(object sender, LibraryBook e)
|
private async void Processable_Completed(object sender, LibraryBook e)
|
||||||
|
|||||||
@ -30,13 +30,16 @@
|
|||||||
{
|
{
|
||||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessBookControl));
|
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProcessBookControl));
|
||||||
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||||
this.bookInfoLbl = new System.Windows.Forms.Label();
|
|
||||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||||
this.remainingTimeLbl = new System.Windows.Forms.Label();
|
this.remainingTimeLbl = new System.Windows.Forms.Label();
|
||||||
this.label1 = new System.Windows.Forms.Label();
|
this.etaLbl = new System.Windows.Forms.Label();
|
||||||
this.cancelBtn = new System.Windows.Forms.Button();
|
this.cancelBtn = new System.Windows.Forms.Button();
|
||||||
|
this.statusLbl = new System.Windows.Forms.Label();
|
||||||
|
this.bookInfoLbl = new System.Windows.Forms.Label();
|
||||||
this.moveUpBtn = new System.Windows.Forms.Button();
|
this.moveUpBtn = new System.Windows.Forms.Button();
|
||||||
this.moveDownBtn = new System.Windows.Forms.Button();
|
this.moveDownBtn = new System.Windows.Forms.Button();
|
||||||
|
this.moveFirstBtn = new System.Windows.Forms.Button();
|
||||||
|
this.moveLastBtn = new System.Windows.Forms.Button();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
@ -49,18 +52,6 @@
|
|||||||
this.pictureBox1.TabIndex = 0;
|
this.pictureBox1.TabIndex = 0;
|
||||||
this.pictureBox1.TabStop = false;
|
this.pictureBox1.TabStop = false;
|
||||||
//
|
//
|
||||||
// bookInfoLbl
|
|
||||||
//
|
|
||||||
this.bookInfoLbl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
|
||||||
| System.Windows.Forms.AnchorStyles.Left)
|
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
|
||||||
this.bookInfoLbl.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
|
||||||
this.bookInfoLbl.Location = new System.Drawing.Point(89, 3);
|
|
||||||
this.bookInfoLbl.Name = "bookInfoLbl";
|
|
||||||
this.bookInfoLbl.Size = new System.Drawing.Size(255, 56);
|
|
||||||
this.bookInfoLbl.TabIndex = 1;
|
|
||||||
this.bookInfoLbl.Text = "[multi-\r\nline\r\nbook\r\n info]";
|
|
||||||
//
|
|
||||||
// progressBar1
|
// progressBar1
|
||||||
//
|
//
|
||||||
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||||
@ -81,17 +72,17 @@
|
|||||||
this.remainingTimeLbl.Text = "--:--";
|
this.remainingTimeLbl.Text = "--:--";
|
||||||
this.remainingTimeLbl.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
this.remainingTimeLbl.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||||
//
|
//
|
||||||
// label1
|
// etaLbl
|
||||||
//
|
//
|
||||||
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.etaLbl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.label1.AutoSize = true;
|
this.etaLbl.AutoSize = true;
|
||||||
this.label1.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
this.etaLbl.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||||
this.label1.Location = new System.Drawing.Point(304, 66);
|
this.etaLbl.Location = new System.Drawing.Point(304, 66);
|
||||||
this.label1.Name = "label1";
|
this.etaLbl.Name = "etaLbl";
|
||||||
this.label1.Size = new System.Drawing.Size(28, 13);
|
this.etaLbl.Size = new System.Drawing.Size(28, 13);
|
||||||
this.label1.TabIndex = 3;
|
this.etaLbl.TabIndex = 3;
|
||||||
this.label1.Text = "ETA:";
|
this.etaLbl.Text = "ETA:";
|
||||||
this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
this.etaLbl.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||||
//
|
//
|
||||||
// cancelBtn
|
// cancelBtn
|
||||||
//
|
//
|
||||||
@ -101,7 +92,7 @@
|
|||||||
this.cancelBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
|
this.cancelBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
|
||||||
this.cancelBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.cancelBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
this.cancelBtn.ForeColor = System.Drawing.SystemColors.Control;
|
this.cancelBtn.ForeColor = System.Drawing.SystemColors.Control;
|
||||||
this.cancelBtn.Location = new System.Drawing.Point(352, 3);
|
this.cancelBtn.Location = new System.Drawing.Point(348, 6);
|
||||||
this.cancelBtn.Margin = new System.Windows.Forms.Padding(0);
|
this.cancelBtn.Margin = new System.Windows.Forms.Padding(0);
|
||||||
this.cancelBtn.Name = "cancelBtn";
|
this.cancelBtn.Name = "cancelBtn";
|
||||||
this.cancelBtn.Size = new System.Drawing.Size(20, 20);
|
this.cancelBtn.Size = new System.Drawing.Size(20, 20);
|
||||||
@ -109,53 +100,100 @@
|
|||||||
this.cancelBtn.UseVisualStyleBackColor = false;
|
this.cancelBtn.UseVisualStyleBackColor = false;
|
||||||
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
|
this.cancelBtn.Click += new System.EventHandler(this.cancelBtn_Click);
|
||||||
//
|
//
|
||||||
|
// statusLbl
|
||||||
|
//
|
||||||
|
this.statusLbl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
|
this.statusLbl.AutoSize = true;
|
||||||
|
this.statusLbl.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||||
|
this.statusLbl.Location = new System.Drawing.Point(89, 66);
|
||||||
|
this.statusLbl.Name = "statusLbl";
|
||||||
|
this.statusLbl.Size = new System.Drawing.Size(50, 13);
|
||||||
|
this.statusLbl.TabIndex = 3;
|
||||||
|
this.statusLbl.Text = "[STATUS]";
|
||||||
|
this.statusLbl.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||||
|
//
|
||||||
|
// bookInfoLbl
|
||||||
|
//
|
||||||
|
this.bookInfoLbl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.bookInfoLbl.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||||
|
this.bookInfoLbl.Location = new System.Drawing.Point(89, 6);
|
||||||
|
this.bookInfoLbl.Name = "bookInfoLbl";
|
||||||
|
this.bookInfoLbl.Size = new System.Drawing.Size(219, 56);
|
||||||
|
this.bookInfoLbl.TabIndex = 1;
|
||||||
|
this.bookInfoLbl.Text = "[multi-\r\nline\r\nbook\r\n info]";
|
||||||
|
//
|
||||||
// moveUpBtn
|
// moveUpBtn
|
||||||
//
|
//
|
||||||
this.moveUpBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.moveUpBtn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
this.moveUpBtn.BackColor = System.Drawing.Color.Transparent;
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.moveUpBtn.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("moveUpBtn.BackgroundImage")));
|
this.moveUpBtn.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("moveUpBtn.BackgroundImage")));
|
||||||
this.moveUpBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
|
this.moveUpBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
|
||||||
this.moveUpBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.moveUpBtn.Location = new System.Drawing.Point(314, 24);
|
||||||
this.moveUpBtn.ForeColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.moveUpBtn.Location = new System.Drawing.Point(347, 39);
|
|
||||||
this.moveUpBtn.Margin = new System.Windows.Forms.Padding(0);
|
|
||||||
this.moveUpBtn.Name = "moveUpBtn";
|
this.moveUpBtn.Name = "moveUpBtn";
|
||||||
this.moveUpBtn.Size = new System.Drawing.Size(25, 10);
|
this.moveUpBtn.Size = new System.Drawing.Size(30, 17);
|
||||||
this.moveUpBtn.TabIndex = 4;
|
this.moveUpBtn.TabIndex = 5;
|
||||||
this.moveUpBtn.UseVisualStyleBackColor = false;
|
this.moveUpBtn.UseVisualStyleBackColor = true;
|
||||||
this.moveUpBtn.Click += new System.EventHandler(this.moveUpBtn_Click);
|
this.moveUpBtn.Click += new System.EventHandler(this.moveUpBtn_Click_1);
|
||||||
//
|
//
|
||||||
// moveDownBtn
|
// moveDownBtn
|
||||||
//
|
//
|
||||||
this.moveDownBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
this.moveDownBtn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
this.moveDownBtn.BackColor = System.Drawing.Color.Transparent;
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.moveDownBtn.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("moveDownBtn.BackgroundImage")));
|
this.moveDownBtn.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("moveDownBtn.BackgroundImage")));
|
||||||
this.moveDownBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
|
this.moveDownBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
|
||||||
this.moveDownBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
this.moveDownBtn.Location = new System.Drawing.Point(314, 40);
|
||||||
this.moveDownBtn.ForeColor = System.Drawing.SystemColors.Control;
|
|
||||||
this.moveDownBtn.Location = new System.Drawing.Point(347, 49);
|
|
||||||
this.moveDownBtn.Margin = new System.Windows.Forms.Padding(0);
|
|
||||||
this.moveDownBtn.Name = "moveDownBtn";
|
this.moveDownBtn.Name = "moveDownBtn";
|
||||||
this.moveDownBtn.Size = new System.Drawing.Size(25, 10);
|
this.moveDownBtn.Size = new System.Drawing.Size(30, 17);
|
||||||
this.moveDownBtn.TabIndex = 5;
|
this.moveDownBtn.TabIndex = 5;
|
||||||
this.moveDownBtn.UseVisualStyleBackColor = false;
|
this.moveDownBtn.UseVisualStyleBackColor = true;
|
||||||
this.moveDownBtn.Click += new System.EventHandler(this.moveDownBtn_Click);
|
this.moveDownBtn.Click += new System.EventHandler(this.moveDownBtn_Click);
|
||||||
//
|
//
|
||||||
|
// moveFirstBtn
|
||||||
|
//
|
||||||
|
this.moveFirstBtn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.moveFirstBtn.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("moveFirstBtn.BackgroundImage")));
|
||||||
|
this.moveFirstBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
|
||||||
|
this.moveFirstBtn.Location = new System.Drawing.Point(314, 3);
|
||||||
|
this.moveFirstBtn.Name = "moveFirstBtn";
|
||||||
|
this.moveFirstBtn.Size = new System.Drawing.Size(30, 17);
|
||||||
|
this.moveFirstBtn.TabIndex = 5;
|
||||||
|
this.moveFirstBtn.UseVisualStyleBackColor = true;
|
||||||
|
this.moveFirstBtn.Click += new System.EventHandler(this.moveFirstBtn_Click);
|
||||||
|
//
|
||||||
|
// moveLastBtn
|
||||||
|
//
|
||||||
|
this.moveLastBtn.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.moveLastBtn.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("moveLastBtn.BackgroundImage")));
|
||||||
|
this.moveLastBtn.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
|
||||||
|
this.moveLastBtn.Location = new System.Drawing.Point(314, 63);
|
||||||
|
this.moveLastBtn.Name = "moveLastBtn";
|
||||||
|
this.moveLastBtn.Size = new System.Drawing.Size(30, 17);
|
||||||
|
this.moveLastBtn.TabIndex = 5;
|
||||||
|
this.moveLastBtn.UseVisualStyleBackColor = true;
|
||||||
|
this.moveLastBtn.Click += new System.EventHandler(this.moveLastBtn_Click);
|
||||||
|
//
|
||||||
// ProcessBookControl
|
// ProcessBookControl
|
||||||
//
|
//
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
this.BackColor = System.Drawing.SystemColors.ControlLight;
|
this.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||||
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||||
|
this.Controls.Add(this.moveLastBtn);
|
||||||
this.Controls.Add(this.moveDownBtn);
|
this.Controls.Add(this.moveDownBtn);
|
||||||
|
this.Controls.Add(this.moveFirstBtn);
|
||||||
this.Controls.Add(this.moveUpBtn);
|
this.Controls.Add(this.moveUpBtn);
|
||||||
this.Controls.Add(this.cancelBtn);
|
this.Controls.Add(this.cancelBtn);
|
||||||
this.Controls.Add(this.label1);
|
this.Controls.Add(this.statusLbl);
|
||||||
|
this.Controls.Add(this.etaLbl);
|
||||||
this.Controls.Add(this.remainingTimeLbl);
|
this.Controls.Add(this.remainingTimeLbl);
|
||||||
this.Controls.Add(this.progressBar1);
|
this.Controls.Add(this.progressBar1);
|
||||||
this.Controls.Add(this.bookInfoLbl);
|
this.Controls.Add(this.bookInfoLbl);
|
||||||
this.Controls.Add(this.pictureBox1);
|
this.Controls.Add(this.pictureBox1);
|
||||||
this.Margin = new System.Windows.Forms.Padding(2, 1, 2, 1);
|
this.Margin = new System.Windows.Forms.Padding(2);
|
||||||
this.Name = "ProcessBookControl";
|
this.Name = "ProcessBookControl";
|
||||||
this.Size = new System.Drawing.Size(375, 86);
|
this.Size = new System.Drawing.Size(375, 86);
|
||||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||||
@ -167,12 +205,15 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private System.Windows.Forms.PictureBox pictureBox1;
|
private System.Windows.Forms.PictureBox pictureBox1;
|
||||||
private System.Windows.Forms.Label bookInfoLbl;
|
|
||||||
private System.Windows.Forms.ProgressBar progressBar1;
|
private System.Windows.Forms.ProgressBar progressBar1;
|
||||||
private System.Windows.Forms.Label remainingTimeLbl;
|
private System.Windows.Forms.Label remainingTimeLbl;
|
||||||
private System.Windows.Forms.Label label1;
|
private System.Windows.Forms.Label etaLbl;
|
||||||
private System.Windows.Forms.Button cancelBtn;
|
private System.Windows.Forms.Button cancelBtn;
|
||||||
|
private System.Windows.Forms.Label statusLbl;
|
||||||
|
private System.Windows.Forms.Label bookInfoLbl;
|
||||||
private System.Windows.Forms.Button moveUpBtn;
|
private System.Windows.Forms.Button moveUpBtn;
|
||||||
private System.Windows.Forms.Button moveDownBtn;
|
private System.Windows.Forms.Button moveDownBtn;
|
||||||
|
private System.Windows.Forms.Button moveFirstBtn;
|
||||||
|
private System.Windows.Forms.Button moveLastBtn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using System.Windows.Forms.Layout;
|
||||||
using DataLayer;
|
using DataLayer;
|
||||||
using Dinah.Core.Net.Http;
|
using Dinah.Core.Net.Http;
|
||||||
using Dinah.Core.Threading;
|
using Dinah.Core.Threading;
|
||||||
@ -11,7 +12,7 @@ using LibationWinForms.ProcessQueue;
|
|||||||
|
|
||||||
namespace LibationWinForms.ProcessQueue
|
namespace LibationWinForms.ProcessQueue
|
||||||
{
|
{
|
||||||
internal interface ILiberationBaseForm
|
internal interface ILiberatiofffnBaseForm
|
||||||
{
|
{
|
||||||
Action CancelAction { get; set; }
|
Action CancelAction { get; set; }
|
||||||
Func<QueuePosition?> MoveUpAction { get; set; }
|
Func<QueuePosition?> MoveUpAction { get; set; }
|
||||||
@ -25,11 +26,11 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
Padding Margin { get; set; }
|
Padding Margin { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal partial class ProcessBookControl : UserControl, ILiberationBaseForm
|
internal partial class ProcessBookControl : UserControl
|
||||||
{
|
{
|
||||||
|
public ProcessBookStatus Status { get; private set; } = ProcessBookStatus.Queued;
|
||||||
public Action CancelAction { get; set; }
|
public Action CancelAction { get; set; }
|
||||||
public Func<QueuePosition?> MoveUpAction { get; set; }
|
public Func<QueuePositionRequest, QueuePosition?> RequestMoveAction { get; set; }
|
||||||
public Func<QueuePosition?> MoveDownAction { get; set; }
|
|
||||||
public string DecodeActionName { get; } = "Decoding";
|
public string DecodeActionName { get; } = "Decoding";
|
||||||
private Func<byte[]> GetCoverArtDelegate;
|
private Func<byte[]> GetCoverArtDelegate;
|
||||||
protected Processable Processable { get; private set; }
|
protected Processable Processable { get; private set; }
|
||||||
@ -37,47 +38,118 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
public ProcessBookControl()
|
public ProcessBookControl()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
label1.Text = "Queued";
|
statusLbl.Text = "Queued";
|
||||||
remainingTimeLbl.Visible = false;
|
remainingTimeLbl.Visible = false;
|
||||||
progressBar1.Visible = false;
|
progressBar1.Visible = false;
|
||||||
|
etaLbl.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetResult(ProcessBookResult status)
|
public void SetCover(Image cover)
|
||||||
{
|
{
|
||||||
var statusTxt = status switch
|
pictureBox1.Image = cover;
|
||||||
{
|
}
|
||||||
ProcessBookResult.Success => "Finished",
|
public void SetTitle(string title)
|
||||||
ProcessBookResult.Cancelled => "Cancelled",
|
{
|
||||||
ProcessBookResult.FailedRetry => "Error, Retry",
|
bookInfoLbl.Text = title;
|
||||||
ProcessBookResult.FailedSkip => "Error, Skip",
|
}
|
||||||
ProcessBookResult.FailedAbort => "Error, Abort",
|
|
||||||
_ => throw new NotImplementedException(),
|
|
||||||
};
|
|
||||||
|
|
||||||
Color backColor = status switch
|
public void SetResult(ProcessBookResult result)
|
||||||
|
{
|
||||||
|
string statusText = default;
|
||||||
|
switch (result)
|
||||||
{
|
{
|
||||||
ProcessBookResult.Success => Color.PaleGreen,
|
case ProcessBookResult.Success:
|
||||||
ProcessBookResult.Cancelled => Color.Khaki,
|
statusText = "Finished";
|
||||||
ProcessBookResult.FailedRetry => Color.LightCoral,
|
Status = ProcessBookStatus.Completed;
|
||||||
ProcessBookResult.FailedSkip => Color.LightCoral,
|
break;
|
||||||
ProcessBookResult.FailedAbort => Color.Firebrick,
|
case ProcessBookResult.Cancelled:
|
||||||
_ => throw new NotImplementedException(),
|
statusText = "Cancelled";
|
||||||
};
|
Status = ProcessBookStatus.Cancelled;
|
||||||
|
break;
|
||||||
|
case ProcessBookResult.FailedRetry:
|
||||||
|
statusText = "Queued";
|
||||||
|
Status = ProcessBookStatus.Queued;
|
||||||
|
break;
|
||||||
|
case ProcessBookResult.FailedSkip:
|
||||||
|
statusText = "Error, Skip";
|
||||||
|
Status = ProcessBookStatus.Failed;
|
||||||
|
break;
|
||||||
|
case ProcessBookResult.FailedAbort:
|
||||||
|
statusText = "Error, Abort";
|
||||||
|
Status = ProcessBookStatus.Failed;
|
||||||
|
break;
|
||||||
|
case ProcessBookResult.ValidationFail:
|
||||||
|
statusText = "Validate fail";
|
||||||
|
Status = ProcessBookStatus.Failed;
|
||||||
|
break;
|
||||||
|
case ProcessBookResult.None:
|
||||||
|
statusText = "UNKNOWN";
|
||||||
|
Status = ProcessBookStatus.Failed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetStatus(Status, statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStatus(ProcessBookStatus status, string statusText)
|
||||||
|
{
|
||||||
|
Color backColor = default;
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case ProcessBookStatus.Completed:
|
||||||
|
backColor = Color.PaleGreen;
|
||||||
|
Status = ProcessBookStatus.Completed;
|
||||||
|
break;
|
||||||
|
case ProcessBookStatus.Cancelled:
|
||||||
|
backColor = Color.Khaki;
|
||||||
|
Status = ProcessBookStatus.Cancelled;
|
||||||
|
break;
|
||||||
|
case ProcessBookStatus.Queued:
|
||||||
|
backColor = SystemColors.Control;
|
||||||
|
Status = ProcessBookStatus.Queued;
|
||||||
|
break;
|
||||||
|
case ProcessBookStatus.Working:
|
||||||
|
backColor = SystemColors.Control;
|
||||||
|
Status = ProcessBookStatus.Working;
|
||||||
|
break;
|
||||||
|
case ProcessBookStatus.Failed:
|
||||||
|
backColor = Color.LightCoral;
|
||||||
|
Status = ProcessBookStatus.Failed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
this.UIThreadAsync(() =>
|
this.UIThreadAsync(() =>
|
||||||
{
|
{
|
||||||
cancelBtn.Visible = false;
|
SuspendLayout();
|
||||||
moveDownBtn.Visible = false;
|
|
||||||
moveUpBtn.Visible = false;
|
cancelBtn.Visible = Status is ProcessBookStatus.Queued or ProcessBookStatus.Working;
|
||||||
remainingTimeLbl.Visible = false;
|
moveLastBtn.Visible = Status == ProcessBookStatus.Queued;
|
||||||
progressBar1.Visible = false;
|
moveDownBtn.Visible = Status == ProcessBookStatus.Queued;
|
||||||
label1.Text = statusTxt;
|
moveUpBtn.Visible = Status == ProcessBookStatus.Queued;
|
||||||
|
moveFirstBtn.Visible = Status == ProcessBookStatus.Queued;
|
||||||
|
remainingTimeLbl.Visible = Status == ProcessBookStatus.Working;
|
||||||
|
progressBar1.Visible = Status == ProcessBookStatus.Working;
|
||||||
|
etaLbl.Visible = Status == ProcessBookStatus.Working;
|
||||||
|
statusLbl.Visible = Status != ProcessBookStatus.Working;
|
||||||
|
statusLbl.Text = statusText;
|
||||||
BackColor = backColor;
|
BackColor = backColor;
|
||||||
|
|
||||||
|
if (status == ProcessBookStatus.Working)
|
||||||
|
{
|
||||||
|
bookInfoLbl.Width += moveLastBtn.Width + moveLastBtn.Padding.Left + moveLastBtn.Padding.Right;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bookInfoLbl.Width -= moveLastBtn.Width + moveLastBtn.Padding.Left + moveLastBtn.Padding.Right;
|
||||||
|
|
||||||
|
}
|
||||||
|
ResumeLayout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProcessBookControl(string title, Image cover) : this()
|
public ProcessBookControl(string title, Image cover) : this()
|
||||||
{
|
{
|
||||||
|
this.title = title;
|
||||||
pictureBox1.Image = cover;
|
pictureBox1.Image = cover;
|
||||||
bookInfoLbl.Text = title;
|
bookInfoLbl.Text = title;
|
||||||
}
|
}
|
||||||
@ -190,14 +262,11 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
#region Processable event handlers
|
#region Processable event handlers
|
||||||
public void Processable_Begin(object sender, LibraryBook libraryBook)
|
public void Processable_Begin(object sender, LibraryBook libraryBook)
|
||||||
{
|
{
|
||||||
|
Status = ProcessBookStatus.Working;
|
||||||
|
|
||||||
LogMe.Info($"{Environment.NewLine}{Processable.Name} Step, Begin: {libraryBook.Book}");
|
LogMe.Info($"{Environment.NewLine}{Processable.Name} Step, Begin: {libraryBook.Book}");
|
||||||
|
|
||||||
this.UIThreadAsync(() =>
|
SetStatus(ProcessBookStatus.Working, "");
|
||||||
{
|
|
||||||
label1.Text = "ETA:";
|
|
||||||
remainingTimeLbl.Visible = true;
|
|
||||||
progressBar1.Visible = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
GetCoverArtDelegate = () => PictureStorage.GetPictureSynchronously(
|
GetCoverArtDelegate = () => PictureStorage.GetPictureSynchronously(
|
||||||
new PictureDefinition(
|
new PictureDefinition(
|
||||||
@ -265,38 +334,29 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
CancelAction?.Invoke();
|
CancelAction?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveUpBtn_Click(object sender, EventArgs e)
|
private void moveLastBtn_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
HandleMovePositionResult(MoveUpAction?.Invoke());
|
RequestMoveAction?.Invoke(QueuePositionRequest.Last);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void moveFirstBtn_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RequestMoveAction?.Invoke(QueuePositionRequest.Fisrt);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveUpBtn_Click_1(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
RequestMoveAction?.Invoke(QueuePositionRequest.OneUp);
|
||||||
|
}
|
||||||
|
|
||||||
private void moveDownBtn_Click(object sender, EventArgs e)
|
private void moveDownBtn_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
HandleMovePositionResult(MoveDownAction?.Invoke());
|
RequestMoveAction?.Invoke(QueuePositionRequest.OneDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleMovePositionResult(QueuePosition? result)
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (result.HasValue)
|
return title ?? "NO TITLE";
|
||||||
SetQueuePosition(result.Value);
|
|
||||||
else
|
|
||||||
SetQueuePosition(QueuePosition.Absent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetQueuePosition(QueuePosition status)
|
|
||||||
{
|
|
||||||
if (status is QueuePosition.Absent or QueuePosition.Current)
|
|
||||||
{
|
|
||||||
moveUpBtn.Visible = false;
|
|
||||||
moveDownBtn.Visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == QueuePosition.Absent)
|
|
||||||
cancelBtn.Enabled = false;
|
|
||||||
|
|
||||||
moveUpBtn.Enabled = status != QueuePosition.Fisrt;
|
|
||||||
moveDownBtn.Enabled = status != QueuePosition.Last;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,24 +57,6 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<metadata name="pictureBox1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="bookInfoLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="progressBar1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="remainingTimeLbl.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="label1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<metadata name="cancelBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
<data name="cancelBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="cancelBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
@ -737,62 +719,114 @@
|
|||||||
/x9W31o+WFcHNAAAAABJRU5ErkJggg==
|
/x9W31o+WFcHNAAAAABJRU5ErkJggg==
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="moveUpBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<data name="moveUpBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="moveUpBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="moveDownBtn.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
<data name="moveDownBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
<data name="moveDownBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
<value>
|
<value>
|
||||||
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
|
||||||
SUVORK5CYII=
|
k4jTqP3QHyOvz3tlGAnrAXoYxoYTiVOpLcF1/lw+V4YRsR6gh2EKOJU4mdoyXPXTMkN8AqwH6GGYEk6n
|
||||||
|
qwOe1+XVMkyE9QA9DFPDCcUpxTefV+XJMkyI9QA9DHPAKfXa4T/D1FgPUMMY40ENY4wHNYwxHtQwxnhQ
|
||||||
|
wxjjQQ1jjAc1jDEe1DDGiJcX/wKcO4zm90rrbQAAAABJRU5ErkJggg==
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="moveFirstBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
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
|
||||||
|
jfkqyMbMAAAAAElFTkSuQmCC
|
||||||
|
</value>
|
||||||
|
</data>
|
||||||
|
<data name="moveLastBtn.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>
|
||||||
|
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
|
||||||
|
6l8KOJAbKVKmPQAAAABJRU5ErkJggg==
|
||||||
</value>
|
</value>
|
||||||
</data>
|
</data>
|
||||||
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
|
||||||
<value>True</value>
|
|
||||||
</metadata>
|
|
||||||
</root>
|
</root>
|
||||||
@ -30,9 +30,10 @@
|
|||||||
{
|
{
|
||||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||||
this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar();
|
this.toolStripProgressBar1 = new System.Windows.Forms.ToolStripProgressBar();
|
||||||
|
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||||
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
|
this.virtualFlowControl2 = new LibationWinForms.ProcessQueue.VirtualFlowControl();
|
||||||
this.panel1 = new System.Windows.Forms.Panel();
|
this.panel1 = new System.Windows.Forms.Panel();
|
||||||
this.btnCleanFinished = new System.Windows.Forms.Button();
|
this.btnCleanFinished = new System.Windows.Forms.Button();
|
||||||
this.cancelAllBtn = new System.Windows.Forms.Button();
|
this.cancelAllBtn = new System.Windows.Forms.Button();
|
||||||
@ -40,7 +41,7 @@
|
|||||||
this.panel2 = new System.Windows.Forms.Panel();
|
this.panel2 = new System.Windows.Forms.Panel();
|
||||||
this.clearLogBtn = new System.Windows.Forms.Button();
|
this.clearLogBtn = new System.Windows.Forms.Button();
|
||||||
this.logMeTbox = new System.Windows.Forms.TextBox();
|
this.logMeTbox = new System.Windows.Forms.TextBox();
|
||||||
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
|
this.tabPage3 = new System.Windows.Forms.TabPage();
|
||||||
this.statusStrip1.SuspendLayout();
|
this.statusStrip1.SuspendLayout();
|
||||||
this.tabControl1.SuspendLayout();
|
this.tabControl1.SuspendLayout();
|
||||||
this.tabPage1.SuspendLayout();
|
this.tabPage1.SuspendLayout();
|
||||||
@ -56,7 +57,7 @@
|
|||||||
this.toolStripStatusLabel1});
|
this.toolStripStatusLabel1});
|
||||||
this.statusStrip1.Location = new System.Drawing.Point(0, 486);
|
this.statusStrip1.Location = new System.Drawing.Point(0, 486);
|
||||||
this.statusStrip1.Name = "statusStrip1";
|
this.statusStrip1.Name = "statusStrip1";
|
||||||
this.statusStrip1.Size = new System.Drawing.Size(359, 22);
|
this.statusStrip1.Size = new System.Drawing.Size(404, 22);
|
||||||
this.statusStrip1.TabIndex = 1;
|
this.statusStrip1.TabIndex = 1;
|
||||||
this.statusStrip1.Text = "statusStrip1";
|
this.statusStrip1.Text = "statusStrip1";
|
||||||
//
|
//
|
||||||
@ -65,6 +66,12 @@
|
|||||||
this.toolStripProgressBar1.Name = "toolStripProgressBar1";
|
this.toolStripProgressBar1.Name = "toolStripProgressBar1";
|
||||||
this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16);
|
this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16);
|
||||||
//
|
//
|
||||||
|
// toolStripStatusLabel1
|
||||||
|
//
|
||||||
|
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
|
||||||
|
this.toolStripStatusLabel1.Size = new System.Drawing.Size(287, 17);
|
||||||
|
this.toolStripStatusLabel1.Spring = true;
|
||||||
|
//
|
||||||
// tabControl1
|
// tabControl1
|
||||||
//
|
//
|
||||||
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
@ -72,38 +79,34 @@
|
|||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.tabControl1.Controls.Add(this.tabPage1);
|
this.tabControl1.Controls.Add(this.tabPage1);
|
||||||
this.tabControl1.Controls.Add(this.tabPage2);
|
this.tabControl1.Controls.Add(this.tabPage2);
|
||||||
|
this.tabControl1.Controls.Add(this.tabPage3);
|
||||||
this.tabControl1.Location = new System.Drawing.Point(0, 0);
|
this.tabControl1.Location = new System.Drawing.Point(0, 0);
|
||||||
this.tabControl1.Margin = new System.Windows.Forms.Padding(0);
|
this.tabControl1.Margin = new System.Windows.Forms.Padding(0);
|
||||||
this.tabControl1.Name = "tabControl1";
|
this.tabControl1.Name = "tabControl1";
|
||||||
this.tabControl1.SelectedIndex = 0;
|
this.tabControl1.SelectedIndex = 0;
|
||||||
this.tabControl1.Size = new System.Drawing.Size(360, 486);
|
this.tabControl1.Size = new System.Drawing.Size(405, 486);
|
||||||
this.tabControl1.TabIndex = 3;
|
this.tabControl1.TabIndex = 3;
|
||||||
//
|
//
|
||||||
// tabPage1
|
// tabPage1
|
||||||
//
|
//
|
||||||
this.tabPage1.Controls.Add(this.flowLayoutPanel1);
|
this.tabPage1.Controls.Add(this.virtualFlowControl2);
|
||||||
this.tabPage1.Controls.Add(this.panel1);
|
this.tabPage1.Controls.Add(this.panel1);
|
||||||
this.tabPage1.Location = new System.Drawing.Point(4, 24);
|
this.tabPage1.Location = new System.Drawing.Point(4, 24);
|
||||||
this.tabPage1.Name = "tabPage1";
|
this.tabPage1.Name = "tabPage1";
|
||||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||||
this.tabPage1.Size = new System.Drawing.Size(352, 458);
|
this.tabPage1.Size = new System.Drawing.Size(397, 458);
|
||||||
this.tabPage1.TabIndex = 0;
|
this.tabPage1.TabIndex = 0;
|
||||||
this.tabPage1.Text = "Process Queue";
|
this.tabPage1.Text = "Process Queue";
|
||||||
this.tabPage1.UseVisualStyleBackColor = true;
|
this.tabPage1.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// flowLayoutPanel1
|
// virtualFlowControl2
|
||||||
//
|
//
|
||||||
this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
this.virtualFlowControl2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
| System.Windows.Forms.AnchorStyles.Left)
|
this.virtualFlowControl2.Location = new System.Drawing.Point(3, 3);
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
this.virtualFlowControl2.Name = "virtualFlowControl2";
|
||||||
this.flowLayoutPanel1.AutoScroll = true;
|
this.virtualFlowControl2.Size = new System.Drawing.Size(391, 422);
|
||||||
this.flowLayoutPanel1.BackColor = System.Drawing.SystemColors.ControlDarkDark;
|
this.virtualFlowControl2.TabIndex = 3;
|
||||||
this.flowLayoutPanel1.Location = new System.Drawing.Point(3, 3);
|
this.virtualFlowControl2.VirtualControlCount = 0;
|
||||||
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
|
|
||||||
this.flowLayoutPanel1.Size = new System.Drawing.Size(346, 419);
|
|
||||||
this.flowLayoutPanel1.TabIndex = 0;
|
|
||||||
this.flowLayoutPanel1.ClientSizeChanged += new System.EventHandler(this.flowLayoutPanel1_ClientSizeChanged);
|
|
||||||
this.flowLayoutPanel1.Layout += new System.Windows.Forms.LayoutEventHandler(this.flowLayoutPanel1_Layout);
|
|
||||||
//
|
//
|
||||||
// panel1
|
// panel1
|
||||||
//
|
//
|
||||||
@ -113,14 +116,14 @@
|
|||||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
|
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||||
this.panel1.Location = new System.Drawing.Point(3, 425);
|
this.panel1.Location = new System.Drawing.Point(3, 425);
|
||||||
this.panel1.Name = "panel1";
|
this.panel1.Name = "panel1";
|
||||||
this.panel1.Size = new System.Drawing.Size(346, 30);
|
this.panel1.Size = new System.Drawing.Size(391, 30);
|
||||||
this.panel1.TabIndex = 2;
|
this.panel1.TabIndex = 2;
|
||||||
//
|
//
|
||||||
// btnCleanFinished
|
// btnCleanFinished
|
||||||
//
|
//
|
||||||
this.btnCleanFinished.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
this.btnCleanFinished.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
| System.Windows.Forms.AnchorStyles.Right)));
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
this.btnCleanFinished.Location = new System.Drawing.Point(253, 3);
|
this.btnCleanFinished.Location = new System.Drawing.Point(298, 3);
|
||||||
this.btnCleanFinished.Name = "btnCleanFinished";
|
this.btnCleanFinished.Name = "btnCleanFinished";
|
||||||
this.btnCleanFinished.Size = new System.Drawing.Size(90, 23);
|
this.btnCleanFinished.Size = new System.Drawing.Size(90, 23);
|
||||||
this.btnCleanFinished.TabIndex = 3;
|
this.btnCleanFinished.TabIndex = 3;
|
||||||
@ -147,7 +150,7 @@
|
|||||||
this.tabPage2.Location = new System.Drawing.Point(4, 24);
|
this.tabPage2.Location = new System.Drawing.Point(4, 24);
|
||||||
this.tabPage2.Name = "tabPage2";
|
this.tabPage2.Name = "tabPage2";
|
||||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||||
this.tabPage2.Size = new System.Drawing.Size(352, 458);
|
this.tabPage2.Size = new System.Drawing.Size(397, 458);
|
||||||
this.tabPage2.TabIndex = 1;
|
this.tabPage2.TabIndex = 1;
|
||||||
this.tabPage2.Text = "Log";
|
this.tabPage2.Text = "Log";
|
||||||
this.tabPage2.UseVisualStyleBackColor = true;
|
this.tabPage2.UseVisualStyleBackColor = true;
|
||||||
@ -159,7 +162,7 @@
|
|||||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
|
this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||||
this.panel2.Location = new System.Drawing.Point(3, 425);
|
this.panel2.Location = new System.Drawing.Point(3, 425);
|
||||||
this.panel2.Name = "panel2";
|
this.panel2.Name = "panel2";
|
||||||
this.panel2.Size = new System.Drawing.Size(346, 30);
|
this.panel2.Size = new System.Drawing.Size(391, 30);
|
||||||
this.panel2.TabIndex = 1;
|
this.panel2.TabIndex = 1;
|
||||||
//
|
//
|
||||||
// clearLogBtn
|
// clearLogBtn
|
||||||
@ -189,11 +192,15 @@
|
|||||||
this.logMeTbox.Size = new System.Drawing.Size(346, 419);
|
this.logMeTbox.Size = new System.Drawing.Size(346, 419);
|
||||||
this.logMeTbox.TabIndex = 0;
|
this.logMeTbox.TabIndex = 0;
|
||||||
//
|
//
|
||||||
// toolStripStatusLabel1
|
// tabPage3
|
||||||
//
|
//
|
||||||
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
|
this.tabPage3.Location = new System.Drawing.Point(4, 24);
|
||||||
this.toolStripStatusLabel1.Size = new System.Drawing.Size(211, 17);
|
this.tabPage3.Name = "tabPage3";
|
||||||
this.toolStripStatusLabel1.Spring = true;
|
this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
|
||||||
|
this.tabPage3.Size = new System.Drawing.Size(397, 458);
|
||||||
|
this.tabPage3.TabIndex = 2;
|
||||||
|
this.tabPage3.Text = "tabPage3";
|
||||||
|
this.tabPage3.UseVisualStyleBackColor = true;
|
||||||
//
|
//
|
||||||
// ProcessBookQueue
|
// ProcessBookQueue
|
||||||
//
|
//
|
||||||
@ -203,7 +210,7 @@
|
|||||||
this.Controls.Add(this.tabControl1);
|
this.Controls.Add(this.tabControl1);
|
||||||
this.Controls.Add(this.statusStrip1);
|
this.Controls.Add(this.statusStrip1);
|
||||||
this.Name = "ProcessBookQueue";
|
this.Name = "ProcessBookQueue";
|
||||||
this.Size = new System.Drawing.Size(359, 508);
|
this.Size = new System.Drawing.Size(404, 508);
|
||||||
this.statusStrip1.ResumeLayout(false);
|
this.statusStrip1.ResumeLayout(false);
|
||||||
this.statusStrip1.PerformLayout();
|
this.statusStrip1.PerformLayout();
|
||||||
this.tabControl1.ResumeLayout(false);
|
this.tabControl1.ResumeLayout(false);
|
||||||
@ -222,7 +229,6 @@
|
|||||||
private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1;
|
private System.Windows.Forms.ToolStripProgressBar toolStripProgressBar1;
|
||||||
private System.Windows.Forms.TabControl tabControl1;
|
private System.Windows.Forms.TabControl tabControl1;
|
||||||
private System.Windows.Forms.TabPage tabPage1;
|
private System.Windows.Forms.TabPage tabPage1;
|
||||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
|
|
||||||
private System.Windows.Forms.Panel panel1;
|
private System.Windows.Forms.Panel panel1;
|
||||||
private System.Windows.Forms.TabPage tabPage2;
|
private System.Windows.Forms.TabPage tabPage2;
|
||||||
private System.Windows.Forms.TextBox logMeTbox;
|
private System.Windows.Forms.TextBox logMeTbox;
|
||||||
@ -231,5 +237,7 @@
|
|||||||
private System.Windows.Forms.Panel panel2;
|
private System.Windows.Forms.Panel panel2;
|
||||||
private System.Windows.Forms.Button clearLogBtn;
|
private System.Windows.Forms.Button clearLogBtn;
|
||||||
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
|
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
|
||||||
|
private System.Windows.Forms.TabPage tabPage3;
|
||||||
|
private VirtualFlowControl virtualFlowControl2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,8 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
{
|
{
|
||||||
internal partial class ProcessBookQueue : UserControl, ILogForm
|
internal partial class ProcessBookQueue : UserControl, ILogForm
|
||||||
{
|
{
|
||||||
private ProcessBook CurrentBook;
|
TrackedQueue<ProcessBook> Queue = new();
|
||||||
private readonly LinkedList<ProcessBook> BookQueue = new();
|
|
||||||
private readonly List<ProcessBook> CompletedBooks = new();
|
|
||||||
private readonly LogMe Logger;
|
private readonly LogMe Logger;
|
||||||
private readonly object lockObject = new();
|
|
||||||
|
|
||||||
|
|
||||||
public Task QueueRunner { get; private set; }
|
public Task QueueRunner { get; private set; }
|
||||||
@ -29,7 +26,6 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Logger = LogMe.RegisterForm(this);
|
Logger = LogMe.RegisterForm(this);
|
||||||
|
|
||||||
|
|
||||||
this.popoutBtn.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
this.popoutBtn.DisplayStyle = ToolStripItemDisplayStyle.Text;
|
||||||
this.popoutBtn.Name = "popoutBtn";
|
this.popoutBtn.Name = "popoutBtn";
|
||||||
this.popoutBtn.Text = "Pop Out";
|
this.popoutBtn.Text = "Pop Out";
|
||||||
@ -38,17 +34,35 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
this.popoutBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
this.popoutBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||||
|
|
||||||
statusStrip1.Items.Add(popoutBtn);
|
statusStrip1.Items.Add(popoutBtn);
|
||||||
}
|
|
||||||
public async Task AddDownloadDecrypt(IEnumerable<GridEntry> entries)
|
virtualFlowControl2.RequestData += VirtualFlowControl1_RequestData;
|
||||||
{
|
|
||||||
foreach (var entry in entries)
|
|
||||||
await AddDownloadDecryptAsync(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void VirtualFlowControl1_RequestData(int firstIndex, int numVisible, IReadOnlyList<ProcessBookControl> panelsToFill)
|
||||||
|
{
|
||||||
|
int numToShow = Math.Min(numVisible, Queue.Count - firstIndex);
|
||||||
|
for (int i = 0; i < numToShow; i++)
|
||||||
|
{
|
||||||
|
var proc = Queue[firstIndex + i];
|
||||||
|
|
||||||
|
panelsToFill[i].SetCover(proc.Entry.Cover);
|
||||||
|
panelsToFill[i].SetTitle(proc.Entry.Title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddDownloadDecrypt(IEnumerable<GridEntry> entries)
|
||||||
|
{
|
||||||
|
SuspendLayout();
|
||||||
|
foreach (var entry in entries)
|
||||||
|
await AddDownloadDecryptAsync(entry);
|
||||||
|
ResumeLayout();
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
public async Task AddDownloadDecryptAsync(GridEntry gridEntry)
|
public async Task AddDownloadDecryptAsync(GridEntry gridEntry)
|
||||||
{
|
{
|
||||||
if (BookExists(gridEntry.LibraryBook))
|
//if (Queue.Any(b=> b?.Entry?.AudibleProductId == gridEntry.AudibleProductId))
|
||||||
return;
|
//return;
|
||||||
|
|
||||||
ProcessBook pbook = new ProcessBook(gridEntry, Logger);
|
ProcessBook pbook = new ProcessBook(gridEntry, Logger);
|
||||||
pbook.Completed += Pbook_Completed;
|
pbook.Completed += Pbook_Completed;
|
||||||
@ -63,24 +77,24 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
if (libStatus.PdfStatus != LiberatedStatus.Liberated)
|
if (libStatus.PdfStatus != LiberatedStatus.Liberated)
|
||||||
pbook.AddPdfProcessable();
|
pbook.AddPdfProcessable();
|
||||||
|
|
||||||
EnqueueBook(pbook);
|
Queue.EnqueueBook(pbook);
|
||||||
|
|
||||||
await AddBookControlAsync(pbook.BookControl);
|
//await AddBookControlAsync(pbook.BookControl);
|
||||||
|
count++;
|
||||||
|
|
||||||
|
virtualFlowControl2.VirtualControlCount = count;
|
||||||
|
|
||||||
if (!Running)
|
if (!Running)
|
||||||
{
|
{
|
||||||
QueueRunner = QueueLoop();
|
//QueueRunner = QueueLoop();
|
||||||
}
|
}
|
||||||
|
toolStripStatusLabel1.Text = count.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Pbook_Cancelled(ProcessBook sender, EventArgs e)
|
private async void Pbook_Cancelled(ProcessBook sender, EventArgs e)
|
||||||
{
|
{
|
||||||
lock (lockObject)
|
Queue.Remove(sender);
|
||||||
{
|
//await RemoveBookControlAsync(sender.BookControl);
|
||||||
if (BookQueue.Contains(sender))
|
|
||||||
BookQueue.Remove(sender);
|
|
||||||
}
|
|
||||||
await RemoveBookControlAsync(sender.BookControl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -89,76 +103,54 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
/// <param name="sender">The requesting <see cref="ProcessBook"/></param>
|
/// <param name="sender">The requesting <see cref="ProcessBook"/></param>
|
||||||
/// <param name="direction">The requested position</param>
|
/// <param name="direction">The requested position</param>
|
||||||
/// <returns>The resultant position</returns>
|
/// <returns>The resultant position</returns>
|
||||||
private QueuePosition RequestMove(ProcessBook sender, QueuePosition direction)
|
private QueuePosition RequestMove(ProcessBook sender, QueuePositionRequest requested)
|
||||||
{
|
{
|
||||||
var node = BookQueue.Find(sender);
|
|
||||||
|
|
||||||
if (node == null || direction == QueuePosition.Absent)
|
var direction = Queue.MoveQueuePosition(sender, requested);
|
||||||
return QueuePosition.Absent;
|
|
||||||
if (CurrentBook != null && CurrentBook == sender)
|
|
||||||
return QueuePosition.Current;
|
|
||||||
if ((direction == QueuePosition.Fisrt || direction == QueuePosition.OneUp) && BookQueue.First.Value == sender)
|
|
||||||
return QueuePosition.Fisrt;
|
|
||||||
if ((direction == QueuePosition.Last || direction == QueuePosition.OneDown) && BookQueue.Last.Value == sender)
|
|
||||||
return QueuePosition.Last;
|
|
||||||
|
|
||||||
if (direction == QueuePosition.OneUp)
|
if (direction is QueuePosition.Absent or QueuePosition.Current or QueuePosition.Completed)
|
||||||
{
|
return direction;
|
||||||
var oneUp = node.Previous;
|
return direction;
|
||||||
BookQueue.Remove(node);
|
|
||||||
BookQueue.AddBefore(oneUp, node.Value);
|
|
||||||
}
|
|
||||||
else if (direction == QueuePosition.OneDown)
|
|
||||||
{
|
|
||||||
var oneDown = node.Next;
|
|
||||||
BookQueue.Remove(node);
|
|
||||||
BookQueue.AddAfter(oneDown, node.Value);
|
|
||||||
}
|
|
||||||
else if (direction == QueuePosition.Fisrt)
|
|
||||||
{
|
|
||||||
BookQueue.Remove(node);
|
|
||||||
BookQueue.AddFirst(node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BookQueue.Remove(node);
|
|
||||||
BookQueue.AddLast(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
var index = flowLayoutPanel1.Controls.IndexOf((Control)sender.BookControl);
|
/*
|
||||||
|
|
||||||
index = direction switch
|
var firstQueue = autosizeFlowLayout1.Controls.Cast<ProcessBookControl>().FirstOrDefault(c => c.Status == ProcessBookStatus.Queued);
|
||||||
|
|
||||||
|
if (firstQueue is null) return QueuePosition.Current;
|
||||||
|
|
||||||
|
int firstQueueIndex = autosizeFlowLayout1.Controls.IndexOf(firstQueue);
|
||||||
|
|
||||||
|
var index = autosizeFlowLayout1.Controls.IndexOf(sender.BookControl);
|
||||||
|
|
||||||
|
int newIndex = direction switch
|
||||||
{
|
{
|
||||||
QueuePosition.Fisrt => 0,
|
QueuePosition.Fisrt => firstQueueIndex,
|
||||||
QueuePosition.OneUp => index - 1,
|
QueuePosition.OneUp => index - 1,
|
||||||
QueuePosition.OneDown => index + 1,
|
QueuePosition.OneDown => index + 1,
|
||||||
QueuePosition.Last => flowLayoutPanel1.Controls.Count - 1,
|
QueuePosition.Last => autosizeFlowLayout1.Controls.Count - 1,
|
||||||
_ => throw new NotImplementedException(),
|
_ => -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
flowLayoutPanel1.Controls.SetChildIndex((Control)sender.BookControl, index);
|
if (newIndex < 0) return direction;
|
||||||
|
|
||||||
|
autosizeFlowLayout1.Controls.SetChildIndex(sender.BookControl, newIndex);
|
||||||
|
|
||||||
if (index == 0) return QueuePosition.Fisrt;
|
|
||||||
if (index == flowLayoutPanel1.Controls.Count - 1) return QueuePosition.Last;
|
|
||||||
return direction;
|
return direction;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task QueueLoop()
|
private async Task QueueLoop()
|
||||||
{
|
{
|
||||||
while (MoreInQueue())
|
while (Queue.MoveNext())
|
||||||
{
|
{
|
||||||
var nextBook = NextBook();
|
var nextBook = Queue.Current;
|
||||||
nextBook.BookControl.SetQueuePosition(QueuePosition.Current);
|
|
||||||
PeekBook()?.BookControl.SetQueuePosition(QueuePosition.Fisrt);
|
|
||||||
|
|
||||||
var result = await nextBook.ProcessOneAsync();
|
var result = await nextBook.ProcessOneAsync();
|
||||||
|
|
||||||
AddCompletedBook(nextBook);
|
|
||||||
|
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case ProcessBookResult.FailedRetry:
|
case ProcessBookResult.FailedRetry:
|
||||||
EnqueueBook(nextBook);
|
Queue.EnqueueBook(nextBook);
|
||||||
break;
|
break;
|
||||||
case ProcessBookResult.FailedAbort:
|
case ProcessBookResult.FailedAbort:
|
||||||
return;
|
return;
|
||||||
@ -166,108 +158,62 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool BookExists(LibraryBook libraryBook)
|
|
||||||
{
|
|
||||||
lock (lockObject)
|
|
||||||
{
|
|
||||||
return CurrentBook?.Entry?.AudibleProductId == libraryBook.Book.AudibleProductId ||
|
|
||||||
CompletedBooks.Union(BookQueue).Any(p => p.Entry.AudibleProductId == libraryBook.Book.AudibleProductId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ProcessBook NextBook()
|
|
||||||
{
|
|
||||||
lock (lockObject)
|
|
||||||
{
|
|
||||||
CurrentBook = BookQueue.First.Value;
|
|
||||||
BookQueue.RemoveFirst();
|
|
||||||
return CurrentBook;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private ProcessBook PeekBook()
|
|
||||||
{
|
|
||||||
lock (lockObject)
|
|
||||||
return BookQueue.Count > 0 ? BookQueue.First.Value : default;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnqueueBook(ProcessBook pbook)
|
|
||||||
{
|
|
||||||
lock (lockObject)
|
|
||||||
BookQueue.AddLast(pbook);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddCompletedBook(ProcessBook pbook)
|
|
||||||
{
|
|
||||||
lock (lockObject)
|
|
||||||
CompletedBooks.Add(pbook);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool MoreInQueue()
|
|
||||||
{
|
|
||||||
lock (lockObject)
|
|
||||||
return BookQueue.Count > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void Pbook_Completed(object sender, EventArgs e)
|
private void Pbook_Completed(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (CurrentBook == sender)
|
|
||||||
CurrentBook = default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void cancelAllBtn_Click(object sender, EventArgs e)
|
private async void cancelAllBtn_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
List<ProcessBook> l1 = new();
|
List<ProcessBook> l1 = Queue.QueuedItems();
|
||||||
lock (lockObject)
|
|
||||||
{
|
|
||||||
l1.AddRange(BookQueue);
|
|
||||||
BookQueue.Clear();
|
|
||||||
}
|
|
||||||
CurrentBook?.Cancel();
|
|
||||||
CurrentBook = default;
|
|
||||||
|
|
||||||
await RemoveBookControlsAsync(l1.Select(l => l.BookControl));
|
Queue.ClearQueue();
|
||||||
|
Queue.Current?.Cancel();
|
||||||
|
|
||||||
|
//await RemoveBookControlsAsync(l1.Select(l => l.BookControl));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void btnCleanFinished_Click(object sender, EventArgs e)
|
private async void btnCleanFinished_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
List<ProcessBook> l1 = new();
|
List<ProcessBook> l1 = Queue.CompletedItems();
|
||||||
lock (lockObject)
|
Queue.ClearCompleted();
|
||||||
{
|
//await RemoveBookControlsAsync(l1.Select(l => l.BookControl));
|
||||||
l1.AddRange(CompletedBooks);
|
|
||||||
CompletedBooks.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
await RemoveBookControlsAsync(l1.Select(l => l.BookControl));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddBookControlAsync(ILiberationBaseForm control)
|
private async Task AddBookControlAsync(ProcessBookControl control)
|
||||||
{
|
{
|
||||||
await Task.Run(() => Invoke(() =>
|
await Task.Run(() => Invoke(() =>
|
||||||
{
|
{
|
||||||
SetBookControlWidth((Control)control);
|
/*
|
||||||
flowLayoutPanel1.Controls.Add((Control)control);
|
control.Width = autosizeFlowLayout1.DesiredBookControlWidth;
|
||||||
flowLayoutPanel1.SetFlowBreak((Control)control, true);
|
autosizeFlowLayout1.Controls.Add(control);
|
||||||
Refresh();
|
autosizeFlowLayout1.SetFlowBreak(control, true);
|
||||||
|
*/
|
||||||
|
//Refresh();
|
||||||
|
//System.Threading.Thread.Sleep(1000);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RemoveBookControlAsync(ILiberationBaseForm control)
|
private async Task RemoveBookControlAsync(ProcessBookControl control)
|
||||||
{
|
{
|
||||||
await Task.Run(() => Invoke(() =>
|
await Task.Run(() => Invoke(() =>
|
||||||
{
|
{
|
||||||
flowLayoutPanel1.Controls.Remove((Control)control);
|
//autosizeFlowLayout1.Controls.Remove(control);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RemoveBookControlsAsync(IEnumerable<ILiberationBaseForm> control)
|
private async Task RemoveBookControlsAsync(IEnumerable<ProcessBookControl> control)
|
||||||
{
|
{
|
||||||
await Task.Run(() => Invoke(() =>
|
await Task.Run(() => Invoke(() =>
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
SuspendLayout();
|
SuspendLayout();
|
||||||
foreach (var l in control)
|
foreach (var l in control)
|
||||||
flowLayoutPanel1.Controls.Remove((Control)l);
|
autosizeFlowLayout1.Controls.Remove(l);
|
||||||
ResumeLayout();
|
ResumeLayout();
|
||||||
|
*/
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,62 +228,5 @@ namespace LibationWinForms.ProcessQueue
|
|||||||
logMeTbox.Clear();
|
logMeTbox.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
|
|
||||||
private static extern long GetWindowLongPtr(IntPtr hWnd, int nIndex);
|
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
private static extern bool ShowScrollBar(IntPtr hWnd, SBOrientation bar, bool show);
|
|
||||||
|
|
||||||
public const int WS_VSCROLL = 0x200000;
|
|
||||||
public const int WS_HSCROLL = 0x100000;
|
|
||||||
enum SBOrientation : int
|
|
||||||
{
|
|
||||||
SB_HORZ = 0,
|
|
||||||
SB_VERT = 1,
|
|
||||||
SB_CTL = 2,
|
|
||||||
SB_BOTH = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
private void flowLayoutPanel1_ClientSizeChanged(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
ReorderControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void flowLayoutPanel1_Layout(object sender, LayoutEventArgs e)
|
|
||||||
{
|
|
||||||
ReorderControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool V_SHOWN = false;
|
|
||||||
|
|
||||||
private void ReorderControls()
|
|
||||||
{
|
|
||||||
bool hShown = (GetWindowLongPtr(flowLayoutPanel1.Handle, -16) & WS_HSCROLL) != 0;
|
|
||||||
bool vShown = (GetWindowLongPtr(flowLayoutPanel1.Handle, -16) & WS_VSCROLL) != 0;
|
|
||||||
|
|
||||||
if (hShown)
|
|
||||||
ShowScrollBar(flowLayoutPanel1.Handle, SBOrientation.SB_HORZ, false);
|
|
||||||
|
|
||||||
if (vShown != V_SHOWN)
|
|
||||||
{
|
|
||||||
flowLayoutPanel1.SuspendLayout();
|
|
||||||
|
|
||||||
foreach (Control c in flowLayoutPanel1.Controls)
|
|
||||||
SetBookControlWidth(c);
|
|
||||||
|
|
||||||
flowLayoutPanel1.ResumeLayout();
|
|
||||||
V_SHOWN = vShown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetBookControlWidth(Control book)
|
|
||||||
{
|
|
||||||
book.Width = flowLayoutPanel1.ClientRectangle.Width - book.Margin.Left - book.Margin.Right;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void toolStripSplitButton1_ButtonClick(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
Source/LibationWinForms/ProcessQueue/VirtualFlowControl.Designer.cs
generated
Normal file
58
Source/LibationWinForms/ProcessQueue/VirtualFlowControl.Designer.cs
generated
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
namespace LibationWinForms.ProcessQueue
|
||||||
|
{
|
||||||
|
partial class VirtualFlowControl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Required designer variable.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing && (components != null))
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.panel1 = new System.Windows.Forms.Panel();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// panel1
|
||||||
|
//
|
||||||
|
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Left)
|
||||||
|
| System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.panel1.BackColor = System.Drawing.Color.PaleGreen;
|
||||||
|
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.panel1.Name = "panel1";
|
||||||
|
this.panel1.Size = new System.Drawing.Size(359, 507);
|
||||||
|
this.panel1.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// VirtualFlowControl
|
||||||
|
//
|
||||||
|
this.Controls.Add(this.panel1);
|
||||||
|
this.Name = "VirtualFlowControl";
|
||||||
|
this.Size = new System.Drawing.Size(379, 507);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.Panel panel1;
|
||||||
|
}
|
||||||
|
}
|
||||||
146
Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
Normal file
146
Source/LibationWinForms/ProcessQueue/VirtualFlowControl.cs
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace LibationWinForms.ProcessQueue
|
||||||
|
{
|
||||||
|
|
||||||
|
internal delegate void RequestDataDelegate(int firstIndex, int numVisible, ProcessBookControl[] panelsToFill);
|
||||||
|
internal partial class VirtualFlowControl : UserControl
|
||||||
|
{
|
||||||
|
public event RequestDataDelegate RequestData;
|
||||||
|
public int VirtualControlCount
|
||||||
|
{
|
||||||
|
get => _virtualControlCount;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_virtualControlCount == 0)
|
||||||
|
vScrollBar1.Value = 0;
|
||||||
|
|
||||||
|
_virtualControlCount = value;
|
||||||
|
AdjustScrollBar();
|
||||||
|
DoVirtualScroll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int _virtualControlCount;
|
||||||
|
private int VirtualHeight => _virtualControlCount * CONTROL_HEIGHT - vScrollBar1.Height;
|
||||||
|
|
||||||
|
private readonly int PROCESSBOOKCONTROL_MARGIN;
|
||||||
|
private readonly int CONTROL_HEIGHT;
|
||||||
|
|
||||||
|
private const int WM_MOUSEWHEEL = 522;
|
||||||
|
private const int NUM_ACTUAL_CONTROLS = 20;
|
||||||
|
private const int SCROLL_SMALL_CHANGE = 120;
|
||||||
|
private const int SCROLL_LARGE_CHANGE = 3 * SCROLL_SMALL_CHANGE;
|
||||||
|
|
||||||
|
|
||||||
|
private readonly VScrollBar vScrollBar1;
|
||||||
|
private readonly ProcessBookControl[] BookControls = new ProcessBookControl[NUM_ACTUAL_CONTROLS];
|
||||||
|
|
||||||
|
public VirtualFlowControl()
|
||||||
|
{
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
vScrollBar1 = new VScrollBar
|
||||||
|
{
|
||||||
|
Minimum = 0,
|
||||||
|
Value = 0,
|
||||||
|
SmallChange = SCROLL_SMALL_CHANGE,
|
||||||
|
LargeChange = SCROLL_LARGE_CHANGE,
|
||||||
|
Dock = DockStyle.Right
|
||||||
|
};
|
||||||
|
|
||||||
|
Controls.Add(vScrollBar1);
|
||||||
|
|
||||||
|
panel1.Resize += (_, _) => AdjustScrollBar();
|
||||||
|
|
||||||
|
if (this.DesignMode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vScrollBar1.Scroll += (_, _) => DoVirtualScroll();
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_ACTUAL_CONTROLS; i++)
|
||||||
|
{
|
||||||
|
BookControls[i] = new ProcessBookControl();
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
PROCESSBOOKCONTROL_MARGIN = BookControls[i].Margin.Left + BookControls[i].Margin.Right;
|
||||||
|
CONTROL_HEIGHT = BookControls[i].Height + BookControls[i].Margin.Top + BookControls[i].Margin.Bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
BookControls[i].Location = new Point(2, CONTROL_HEIGHT * i);
|
||||||
|
BookControls[i].Width = panel1.ClientRectangle.Width - PROCESSBOOKCONTROL_MARGIN;
|
||||||
|
BookControls[i].Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
|
||||||
|
panel1.Controls.Add(BookControls[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
panel1.Height += SCROLL_SMALL_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void AdjustScrollBar()
|
||||||
|
{
|
||||||
|
int maxFullVisible = DisplayRectangle.Height / CONTROL_HEIGHT;
|
||||||
|
|
||||||
|
if (VirtualControlCount <= maxFullVisible)
|
||||||
|
{
|
||||||
|
vScrollBar1.Enabled = false;
|
||||||
|
|
||||||
|
for (int i = VirtualControlCount; i < NUM_ACTUAL_CONTROLS; i++)
|
||||||
|
BookControls[i].Visible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vScrollBar1.Enabled = true;
|
||||||
|
//https://stackoverflow.com/a/2882878/3335599
|
||||||
|
vScrollBar1.Maximum = VirtualHeight + vScrollBar1.LargeChange - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoVirtualScroll()
|
||||||
|
{
|
||||||
|
//https://stackoverflow.com/a/2882878/3335599
|
||||||
|
int scrollValue = Math.Max(Math.Min(VirtualHeight, vScrollBar1.Value), 0);
|
||||||
|
|
||||||
|
int position = scrollValue % CONTROL_HEIGHT;
|
||||||
|
panel1.Location = new Point(0, -position);
|
||||||
|
|
||||||
|
int firstVisible = scrollValue / CONTROL_HEIGHT;
|
||||||
|
|
||||||
|
int window = DisplayRectangle.Height;
|
||||||
|
|
||||||
|
int count = window / CONTROL_HEIGHT;
|
||||||
|
|
||||||
|
if (window % CONTROL_HEIGHT != 0)
|
||||||
|
count++;
|
||||||
|
count = Math.Min(count, VirtualControlCount);
|
||||||
|
|
||||||
|
RequestData?.Invoke(firstVisible, count, BookControls);
|
||||||
|
|
||||||
|
for (int i = 0; i < BookControls.Length; i++)
|
||||||
|
BookControls[i].Visible = i <= count && VirtualControlCount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void WndProc(ref Message m)
|
||||||
|
{
|
||||||
|
if (m.Msg == WM_MOUSEWHEEL)
|
||||||
|
{
|
||||||
|
//https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-mousewheel
|
||||||
|
int wheelDelta = -(short)(((ulong)m.WParam) >> 16 & 0xffff);
|
||||||
|
|
||||||
|
if (wheelDelta > 0)
|
||||||
|
vScrollBar1.Value = Math.Min(vScrollBar1.Value + wheelDelta, vScrollBar1.Maximum);
|
||||||
|
else
|
||||||
|
vScrollBar1.Value = Math.Max(vScrollBar1.Value + wheelDelta, vScrollBar1.Minimum);
|
||||||
|
|
||||||
|
DoVirtualScroll();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.WndProc(ref m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
60
Source/LibationWinForms/ProcessQueue/VirtualFlowControl.resx
Normal file
60
Source/LibationWinForms/ProcessQueue/VirtualFlowControl.resx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<root>
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
Loading…
x
Reference in New Issue
Block a user