Files
Libation/Source/LibationWinForms/ProcessQueue/ProcessBookControl.cs
Michael Bucari-Tovo cdb91ae2ca Add dark mode to winforms
- Add dark theme icon variants
- Change all light theme icon fill colors to match Chardonnay

Also fixed #1460  by chaing the directory select control to DirectoryOrCustomSelectControl
2025-12-01 20:39:22 -07:00

137 lines
5.7 KiB
C#

using LibationUiBase.ProcessQueue;
using System;
using System.Drawing;
using System.Windows.Forms;
#nullable enable
namespace LibationWinForms.ProcessQueue
{
internal partial class ProcessBookControl : UserControl
{
private readonly int CancelBtnDistanceFromEdge;
private readonly int ProgressBarDistanceFromEdge;
private object? m_OldContext;
private static Color FailedColor => Application.IsDarkModeEnabled ? Color.FromArgb(0x50, 0x27, 0x27) : Color.LightCoral;
private static Color CancelledColor => Application.IsDarkModeEnabled ? Color.FromArgb(0x4e, 0x4b, 0x15) : Color.Khaki;
private static Color QueuedColor { get; } = SystemColors.Control;
private static Color SuccessColor => Application.IsDarkModeEnabled ? Color.FromArgb(0x1c, 0x3e, 0x20) : Color.PaleGreen;
public ProcessBookControl()
{
InitializeComponent();
remainingTimeLbl.Visible = false;
progressBar1.Visible = false;
etaLbl.Visible = false;
moveDownBtn.BackgroundImage = Application.IsDarkModeEnabled ? Properties.Resources.move_down_dark : Properties.Resources.move_down;
moveUpBtn.BackgroundImage = Application.IsDarkModeEnabled ? Properties.Resources.move_up_dark : Properties.Resources.move_up;
moveFirstBtn.BackgroundImage = Application.IsDarkModeEnabled ? Properties.Resources.move_first_dark : Properties.Resources.move_first;
moveLastBtn.BackgroundImage = Application.IsDarkModeEnabled ? Properties.Resources.move_last_dark : Properties.Resources.move_last;
CancelBtnDistanceFromEdge = Width - cancelBtn.Location.X;
ProgressBarDistanceFromEdge = Width - progressBar1.Location.X - progressBar1.Width;
}
protected override void OnDataContextChanged(EventArgs e)
{
if (m_OldContext is ProcessBookViewModel oldContext)
oldContext.PropertyChanged -= DataContext_PropertyChanged;
if (DataContext is ProcessBookViewModel newContext)
{
m_OldContext = newContext;
newContext.PropertyChanged += DataContext_PropertyChanged;
DataContext_PropertyChanged(DataContext, new System.ComponentModel.PropertyChangedEventArgs(null));
}
base.OnDataContextChanged(e);
}
private void DataContext_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (sender is not ProcessBookViewModel vm)
return;
SuspendLayout();
if (e.PropertyName is null or nameof(vm.Cover))
SetCover(vm.Cover as Image);
if (e.PropertyName is null or nameof(vm.Title) or nameof(vm.Author) or nameof(vm.Narrator))
SetBookInfo($"{vm.Title}\r\nBy {vm.Author}\r\nNarrated by {vm.Narrator}");
if (e.PropertyName is null or nameof(vm.Status) or nameof(vm.StatusText))
SetStatus(vm.Status, vm.StatusText);
if (e.PropertyName is null or nameof(vm.Progress))
SetProgress(vm.Progress);
if (e.PropertyName is null or nameof(vm.TimeRemaining))
SetRemainingTime(vm.TimeRemaining);
ResumeLayout();
}
private void SetCover(Image? cover) => pictureBox1.Image = cover;
private void SetBookInfo(string title) => bookInfoLbl.Text = title;
private void SetRemainingTime(TimeSpan remaining)
=> remainingTimeLbl.Text = $"{remaining:mm\\:ss}";
private void SetProgress(int progress)
{
//Disable slow fill
//https://stackoverflow.com/a/5332770/3335599
if (progress < progressBar1.Maximum)
progressBar1.Value = progress + 1;
progressBar1.Value = progress;
}
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;
moveLastBtn.Visible = status == ProcessBookStatus.Queued;
moveDownBtn.Visible = status == ProcessBookStatus.Queued;
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;
int deltaX = Width - cancelBtn.Location.X - CancelBtnDistanceFromEdge;
if (status is ProcessBookStatus.Queued or ProcessBookStatus.Working && deltaX != 0)
{
//If the last book to occupy this control before resizing was not
//queued, the buttons were not Visible so the Anchor property was
//ignored. Manually resize and reposition everything
cancelBtn.Location = new Point(cancelBtn.Location.X + deltaX, cancelBtn.Location.Y);
moveFirstBtn.Location = new Point(moveFirstBtn.Location.X + deltaX, moveFirstBtn.Location.Y);
moveUpBtn.Location = new Point(moveUpBtn.Location.X + deltaX, moveUpBtn.Location.Y);
moveDownBtn.Location = new Point(moveDownBtn.Location.X + deltaX, moveDownBtn.Location.Y);
moveLastBtn.Location = new Point(moveLastBtn.Location.X + deltaX, moveLastBtn.Location.Y);
etaLbl.Location = new Point(etaLbl.Location.X + deltaX, etaLbl.Location.Y);
remainingTimeLbl.Location = new Point(remainingTimeLbl.Location.X + deltaX, remainingTimeLbl.Location.Y);
progressBar1.Width = Width - ProgressBarDistanceFromEdge - progressBar1.Location.X;
}
if (status == ProcessBookStatus.Working)
{
bookInfoLbl.Width = cancelBtn.Location.X - bookInfoLbl.Location.X - bookInfoLbl.Padding.Left + cancelBtn.Padding.Right;
}
else
{
bookInfoLbl.Width = moveLastBtn.Location.X - bookInfoLbl.Location.X - bookInfoLbl.Padding.Left + moveLastBtn.Padding.Right;
}
}
public override string ToString() => bookInfoLbl.Text ?? "[NO TITLE]";
}
}