Improve styles and fix sotring of podcasts when they are collapsed.

This commit is contained in:
Michael Bucari-Tovo 2022-07-12 22:01:11 -06:00
parent 6e091230cf
commit 6182b2bcee
12 changed files with 266 additions and 137 deletions

View File

@ -12,5 +12,6 @@
<StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
<StyleInclude Source="/AvaloniaUI/Assets/DataGridTheme.xaml"/>
<StyleInclude Source="/AvaloniaUI/Assets/LibationStyles.xaml"/>
</Application.Styles>
</Application>

View File

@ -1,12 +1,20 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using LibationWinForms.AvaloniaUI.Views;
namespace LibationWinForms.AvaloniaUI
{
public class App : Application
{
public static IBrush ProcessQueueBookFailedBrush { get; private set; }
public static IBrush ProcessQueueBookCompletedBrush { get; private set; }
public static IBrush ProcessQueueBookCancelledBrush { get; private set; }
public static IBrush ProcessQueueBookDefaultBrush { get; private set; }
public static IBrush SeriesEntryGridBackgroundBrush { get; private set; }
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
@ -14,6 +22,8 @@ namespace LibationWinForms.AvaloniaUI
public override void OnFrameworkInitializationCompleted()
{
LoadStyles();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var mainWindow = new MainWindow();
@ -23,5 +33,14 @@ namespace LibationWinForms.AvaloniaUI
base.OnFrameworkInitializationCompleted();
}
private void LoadStyles()
{
ProcessQueueBookFailedBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookFailedBrush");
ProcessQueueBookCompletedBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookCompletedBrush");
ProcessQueueBookCancelledBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookCancelledBrush");
ProcessQueueBookDefaultBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookDefaultBrush");
SeriesEntryGridBackgroundBrush = AvaloniaUtils.GetBrushFromResources("SeriesEntryGridBackgroundBrush");
}
}
}

View File

@ -0,0 +1,12 @@
<Styles xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Styles.Resources>
<Color x:Key="SeriesEntryGridBackgroundColor">#FFE6FFE6</Color>
<SolidColorBrush x:Key="SeriesEntryGridBackgroundBrush" Color="{StaticResource SeriesEntryGridBackgroundColor}" />
<SolidColorBrush x:Key="ProcessQueueBookFailedBrush" Color="LightCoral" />
<SolidColorBrush x:Key="ProcessQueueBookCompletedBrush" Color="PaleGreen" />
<SolidColorBrush x:Key="ProcessQueueBookCancelledBrush" Color="Khaki" />
<SolidColorBrush x:Key="ProcessQueueBookDefaultBrush" Color="{StaticResource SystemAltHighColor}" />
<SolidColorBrush x:Key="ProcessQueueBookBorderBrush" Color="Gray" />
</Styles.Resources>
</Styles>

View File

@ -0,0 +1,22 @@
using Avalonia.Media;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LibationWinForms.AvaloniaUI
{
internal static class AvaloniaUtils
{
public static IBrush GetBrushFromResources(string name)
=> GetBrushFromResources(name, Brushes.Transparent);
public static IBrush GetBrushFromResources(string name, IBrush defaultBrush)
{
if (App.Current.Styles.TryGetResource(name, out var value) && value is IBrush brush)
return brush;
return defaultBrush;
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApplicationServices;
using Avalonia.Media;
using Avalonia.Media.Imaging;
using DataLayer;
using Dinah.Core;
@ -63,12 +64,12 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
public bool IsDownloading => Status is ProcessBookStatus.Working;
public bool Queued => Status is ProcessBookStatus.Queued;
public string BackgroundColor => Status switch
public IBrush BackgroundColor => Status switch
{
ProcessBookStatus.Cancelled => "Khaki",
ProcessBookStatus.Completed => "PaleGreen",
ProcessBookStatus.Failed => "LightCoral",
_ => "White",
ProcessBookStatus.Cancelled => App.ProcessQueueBookCancelledBrush,
ProcessBookStatus.Completed => App.ProcessQueueBookCompletedBrush,
ProcessBookStatus.Failed => App.ProcessQueueBookFailedBrush,
_ => App.ProcessQueueBookDefaultBrush,
};
public string StatusText => Result switch
{
@ -83,6 +84,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
#endregion
private TimeSpan TimeRemaining { set { ETA = $"ETA: {value:mm\\:ss}"; } }
private Processable CurrentProcessable => _currentProcessable ??= Processes.Dequeue().Invoke();
private Processable NextProcessable() => _currentProcessable = null;
@ -107,6 +109,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
// Mutable property. Set the field so PropertyChanged isn't fired.
using var ms = new System.IO.MemoryStream(picture);
_cover = new Bitmap(ms);
}
private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e)

View File

@ -9,13 +9,25 @@
mc:Ignorable="d" d:DesignWidth="2000" d:DesignHeight="700"
x:Class="LibationWinForms.AvaloniaUI.Views.MainWindow" Title="MainWindow">
<Border BorderBrush="Gray" BorderThickness="2" Padding="15">
<Grid RowDefinitions="30,40,1*,30">
<Grid Grid.Row="0" ColumnDefinitions="1*, 200">
<Border BorderBrush="{DynamicResource DataGridGridLinesBrush}" BorderThickness="2" Padding="15">
<Grid RowDefinitions="Auto,Auto,*,Auto">
<Grid Grid.Row="0" ColumnDefinitions="1*, Auto">
<!-- Menu Strip -->
<Menu Grid.Column="0">
<MenuItem Name="importToolStripMenuItem" Header="_Import">
<Menu Grid.Column="0" VerticalAlignment="Top">
<!-- Decrease height of menu strop -->
<Menu.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="25"/>
</Style>
</Menu.Styles>
<MenuItem Header="_Import">
<!-- Remove height style property for menu item -->
<MenuItem.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="NaN"/>
</Style>
</MenuItem.Styles>
<MenuItem Name="autoScanLibraryToolStripMenuItem" Click="autoScanLibraryToolStripMenuItem_Click" Header="A_uto Scan Library">
<MenuItem.Icon>
<CheckBox Name="autoScanLibraryToolStripMenuItemCheckbox" BorderThickness="0" IsHitTestVisible="False">Toggle _Me0</CheckBox>
@ -30,16 +42,34 @@
<MenuItem Name="removeSomeAccountsToolStripMenuItem" Click="removeSomeAccountsToolStripMenuItem_Click" Header="Some Accounts" />
</MenuItem>
</MenuItem>
<MenuItem Name="liberateToolStripMenuItem" Header="_Liberate">
<MenuItem Header="_Liberate">
<!-- Remove height style property for menu item -->
<MenuItem.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="NaN"/>
</Style>
</MenuItem.Styles>
<controls:FormattableMenuItem Name="beginBookBackupsToolStripMenuItem" Click="beginBookBackupsToolStripMenuItem_Click" FormatText="Begin _Book and PDF Backups: {0}" />
<controls:FormattableMenuItem Name="beginPdfBackupsToolStripMenuItem" Click="beginPdfBackupsToolStripMenuItem_Click" FormatText="Begin _PDF Only Backups: {0}" />
<MenuItem Name="convertAllM4bToMp3ToolStripMenuItem" Click="convertAllM4bToMp3ToolStripMenuItem_Click" Header="Convert all _M4b to Mp3 [Long-running]..." />
<MenuItem Click="convertAllM4bToMp3ToolStripMenuItem_Click" Header="Convert all _M4b to Mp3 [Long-running]..." />
<controls:FormattableMenuItem Name="liberateVisibleToolStripMenuItem_LiberateMenu" Click="liberateVisible" FormatText="Liberate _Visible Books: {0}" />
</MenuItem>
<MenuItem Name="exportToolStripMenuItem" Header="E_xport">
<MenuItem Header="E_xport">
<!-- Remove height style property for menu item -->
<MenuItem.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="NaN"/>
</Style>
</MenuItem.Styles>
<MenuItem Name="exportLibraryToolStripMenuItem" Click="exportLibraryToolStripMenuItem_Click" Header="E_xport Library" />
</MenuItem>
<MenuItem Name="quickFiltersToolStripMenuItem" Header="Quick _Filters">
<!-- Remove height style property for menu item -->
<MenuItem.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="NaN"/>
</Style>
</MenuItem.Styles>
<MenuItem Name="firstFilterIsDefaultToolStripMenuItem" Click="firstFilterIsDefaultToolStripMenuItem_Click" Header="Start Libation with 1st filter _Default">
<MenuItem.Icon>
<CheckBox Name="firstFilterIsDefaultToolStripMenuItem_Checkbox" BorderThickness="0" IsHitTestVisible="False">Toggle _Me0</CheckBox>
@ -49,16 +79,28 @@
<Separator />
</MenuItem>
<controls:FormattableMenuItem Name="visibleBooksToolStripMenuItem" FormatText="_Visible Books: {0}" >
<!-- Remove height style property for menu item -->
<controls:FormattableMenuItem.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="NaN"/>
</Style>
</controls:FormattableMenuItem.Styles>
<controls:FormattableMenuItem Name="liberateVisibleToolStripMenuItem_VisibleBooksMenu" Click="liberateVisible" FormatText="_Liberate: {0}" />
<MenuItem Name="replaceTagsToolStripMenuItem" Click="replaceTagsToolStripMenuItem_Click" Header="Replace _Tags..." />
<MenuItem Click="replaceTagsToolStripMenuItem_Click" Header="Replace _Tags..." />
<MenuItem Name="setDownloadedToolStripMenuItem" Click="setDownloadedToolStripMenuItem_Click" Header="Set '_Downloaded' status..." />
<MenuItem Name="removeToolStripMenuItem" Click="removeToolStripMenuItem_Click" Header="_Remove from library..." />
</controls:FormattableMenuItem>
<MenuItem Name="settingsToolStripMenuItem" Header="_Settings">
<MenuItem Name="accountsToolStripMenuItem" Click="accountsToolStripMenuItem_Click" Header="_Accounts..." />
<MenuItem Name="basicSettingsToolStripMenuItem" Click="basicSettingsToolStripMenuItem_Click" Header="_Settings..." />
<MenuItem Header="_Settings">
<!-- Remove height style property for menu item -->
<MenuItem.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="NaN"/>
</Style>
</MenuItem.Styles>
<MenuItem Click="accountsToolStripMenuItem_Click" Header="_Accounts..." />
<MenuItem Click="basicSettingsToolStripMenuItem_Click" Header="_Settings..." />
<Separator />
<MenuItem Name="aboutToolStripMenuItem" Click="aboutToolStripMenuItem_Click" Header="A_bout..." />
<MenuItem Click="aboutToolStripMenuItem_Click" Header="A_bout..." />
</MenuItem>
</Menu>
<StackPanel Name="scanningToolStripMenuItem" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
@ -68,20 +110,34 @@
</Grid>
<!-- Buttons and Search Box -->
<Grid Grid.Row="1" ColumnDefinitions="30,170,1*,100,30">
<Button Name="filterHelpBtn" Click="filterHelpBtn_Click" Grid.Column="0" Height="30" Width="30" Content="?"/>
<Button Name="addQuickFilterBtn" Click="addQuickFilterBtn_Click" Grid.Column="1" Height="30" Width="150" Margin="10,0,10,0" Content="Add To Quick Filters"/>
<TextBox Name="filterSearchTb" KeyDown="filterSearchTb_KeyPress" Grid.Column="2" Height="30" />
<Button Name="filterBtn" Click="filterBtn_Click" Grid.Column="3" Height="30" Width="80" Margin="10,0,10,0" Content="Filter"/>
<Button Name="toggleQueueHideBtn" Click="ToggleQueueHideBtn_Click" Grid.Column="4" Height="30" Width="30" Content="❱❱❱"/>
<Grid Grid.Row="1" Margin="0,10,0,10" Height="30" ColumnDefinitions="Auto,*,Auto">
<StackPanel Grid.Column="2" Orientation="Horizontal">
<Grid.Styles>
<Style Selector="TextBox">
<Setter Property="MinHeight" Value="10" />
</Style>
</Grid.Styles>
<StackPanel Grid.Column="0" Orientation="Horizontal">
<Button Name="filterHelpBtn" Click="filterHelpBtn_Click" Height="30" Width="30" Content="?"/>
<Button Name="addQuickFilterBtn" Click="addQuickFilterBtn_Click" Height="30" Width="150" Margin="10,0,10,0" Content="Add To Quick Filters"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button Name="removeBooksBtn" Click="removeBooksBtn_Click" Height="30" Width="220" Content="Remove # Books from Libation"/>
<Button Name="doneRemovingBtn" Click="doneRemovingBtn_Click" Height="30" Width="160" Margin="10,0,0,0" Content="Done Removing Books"/>
</StackPanel>
</Grid>
<SplitView Name="splitContainer1" Grid.Row="2" IsPaneOpen="True" DisplayMode="Inline" OpenPaneLength="375" PanePlacement="Right">
<TextBox Grid.Column="1" Name="filterSearchTb" KeyDown="filterSearchTb_KeyPress" />
<StackPanel Grid.Column="2" Height="30" Orientation="Horizontal">
<Button Name="filterBtn" Click="filterBtn_Click" Height="30" Width="80" Margin="10,0,10,0" Content="Filter"/>
<Button Name="toggleQueueHideBtn" Click="ToggleQueueHideBtn_Click" Height="30" Width="30" Content="❱❱❱"/>
</StackPanel>
</Grid>
<Border Grid.Row="2" BorderThickness="1" BorderBrush="{DynamicResource DataGridGridLinesBrush}">
<SplitView Name="splitContainer1" IsPaneOpen="True" DisplayMode="Inline" OpenPaneLength="375" PanePlacement="Right">
<!-- Process Queue -->
<SplitView.Pane>
@ -96,13 +152,14 @@
VisibleCountChanged="productsDisplay_VisibleCountChanged"
Name="productsDisplay" />
</SplitView>
</Border>
<!-- Bottom Status Strip -->
<Grid Grid.Row="3" ColumnDefinitions="80,1*,100*">
<controls:FormattableTextBlock Name="visibleCountLbl" Grid.Column="0" FormatText="Visible {0}" VerticalAlignment="Center" />
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock Name="backupsCountsLbl" Text="[Calculating backed up book quantities]" VerticalAlignment="Center" />
<controls:FormattableTextBlock Name="pdfsCountsLbl" FormatText=" | PDFs: NOT d/l'ed: {0} Downloaded: {1}" VerticalAlignment="Center" />
<Grid Grid.Row="3" Margin="0,10,0,0" VerticalAlignment="Bottom" ColumnDefinitions="*,Auto">
<controls:FormattableTextBlock FontSize="14" Name="visibleCountLbl" Grid.Column="0" FormatText="Visible {0}" VerticalAlignment="Center" />
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock FontSize="14" Name="backupsCountsLbl" Text="[Calculating backed up book quantities]" VerticalAlignment="Center" />
<controls:FormattableTextBlock FontSize="14" Name="pdfsCountsLbl" FormatText=" | PDFs: NOT d/l'ed: {0} Downloaded: {1}" VerticalAlignment="Center" />
</StackPanel>
</Grid>
</Grid>

View File

@ -53,7 +53,6 @@ namespace LibationWinForms.AvaloniaUI.Views
private void FindAllControls()
{
importToolStripMenuItem = this.FindControl<MenuItem>(nameof(importToolStripMenuItem));
{
autoScanLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(autoScanLibraryToolStripMenuItem));
autoScanLibraryToolStripMenuItemCheckbox = this.FindControl<CheckBox>(nameof(autoScanLibraryToolStripMenuItemCheckbox));
@ -68,16 +67,12 @@ namespace LibationWinForms.AvaloniaUI.Views
}
}
liberateToolStripMenuItem = this.FindControl<MenuItem>(nameof(liberateToolStripMenuItem));
{
beginBookBackupsToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(beginBookBackupsToolStripMenuItem));
beginPdfBackupsToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(beginPdfBackupsToolStripMenuItem));
convertAllM4bToMp3ToolStripMenuItem = this.FindControl<MenuItem>(nameof(convertAllM4bToMp3ToolStripMenuItem));
liberateVisibleToolStripMenuItem_LiberateMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_LiberateMenu));
}
exportToolStripMenuItem = this.FindControl<MenuItem>(nameof(exportToolStripMenuItem));
{
exportLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(exportLibraryToolStripMenuItem));
}
@ -92,17 +87,10 @@ namespace LibationWinForms.AvaloniaUI.Views
visibleBooksToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(visibleBooksToolStripMenuItem));
{
liberateVisibleToolStripMenuItem_VisibleBooksMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_VisibleBooksMenu));
replaceTagsToolStripMenuItem = this.FindControl<MenuItem>(nameof(replaceTagsToolStripMenuItem));
setDownloadedToolStripMenuItem = this.FindControl<MenuItem>(nameof(setDownloadedToolStripMenuItem));
removeToolStripMenuItem = this.FindControl<MenuItem>(nameof(removeToolStripMenuItem));
}
settingsToolStripMenuItem = this.FindControl<MenuItem>(nameof(settingsToolStripMenuItem));
{
accountsToolStripMenuItem = this.FindControl<MenuItem>(nameof(accountsToolStripMenuItem));
basicSettingsToolStripMenuItem = this.FindControl<MenuItem>(nameof(basicSettingsToolStripMenuItem));
aboutToolStripMenuItem = this.FindControl<MenuItem>(nameof(aboutToolStripMenuItem));
}
scanningToolStripMenuItem = this.FindControl<StackPanel>(nameof(scanningToolStripMenuItem));
scanningToolStripMenuItem_Text = this.FindControl<TextBlock>(nameof(scanningToolStripMenuItem_Text));

View File

@ -5,12 +5,13 @@
mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="90" MaxHeight="90" MinHeight="90" MinWidth="300"
x:Class="LibationWinForms.AvaloniaUI.Views.ProcessBookControl2" Background="{Binding BackgroundColor}">
<Border BorderBrush="Gray" BorderThickness="2">
<Grid ColumnDefinitions="86,1*,58">
<Panel Grid.Column="0" Margin="3,0,0,0" Width="80" Height="80" HorizontalAlignment="Left">
<Border BorderBrush="{DynamicResource ProcessQueueBookBorderBrush}" BorderThickness="2">
<Grid ColumnDefinitions="Auto,*,Auto">
<Panel Grid.Column="0" Margin="3" Background="LightGray" Width="80" Height="80" HorizontalAlignment="Left">
<Image Width="80" Height="80" Source="{Binding Cover}" Stretch="Uniform" />
</Panel>
<Grid Margin="0,3,0,3" Grid.Column="1" ColumnDefinitions="1*" RowDefinitions="1*,14">
<Grid Margin="0,3,0,3" Grid.Column="1" ColumnDefinitions="1*" RowDefinitions="1*,16">
<StackPanel Grid.Column="0" Grid.Row="0" Orientation="Vertical">
<TextBlock ClipToBounds="True" TextWrapping="Wrap" FontSize="11" Text="{Binding Title}" />
<TextBlock FontSize="10" TextWrapping="NoWrap" Text="{Binding Author}" />
@ -26,8 +27,8 @@
<TextBlock IsVisible="{Binding !IsDownloading}" Text="{Binding StatusText}"/>
</Panel>
</Grid>
<Grid Margin="3" Grid.Column="2" ColumnDefinitions="30,26">
<StackPanel IsVisible="{Binding Queued }" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Vertical">
<Grid Margin="3" Grid.Column="2" HorizontalAlignment="Right" ColumnDefinitions="Auto,Auto">
<StackPanel IsVisible="{Binding Queued}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Vertical">
<Button Height="20" Width="30" Click="MoveFirst_Click">
<Image Height="20" Width="30" Source="/AvaloniaUI/Assets/first.png" Stretch="Uniform" VerticalAlignment="Bottom"/>
</Button>
@ -47,9 +48,10 @@
</Button>
</Panel>
</Grid>
<Panel Grid.Column="2" Margin="3">
<TextPresenter FontSize="9" VerticalAlignment="Bottom" HorizontalAlignment="Center" IsVisible="{Binding IsDownloading}" Text="{Binding ETA}" />
<Panel Margin="3" Width="50" Grid.Column="2">
<TextPresenter FontSize="9" VerticalAlignment="Bottom" HorizontalAlignment="Right" IsVisible="{Binding IsDownloading}" Text="{Binding ETA}" />
</Panel>
</Grid>
</Border>
</UserControl>

View File

@ -10,31 +10,30 @@
<UserControl.Resources>
<RecyclePool x:Key="RecyclePool" />
<DataTemplate x:Key="odd">
<DataTemplate x:Key="queuedBook">
<views:ProcessBookControl2 />
</DataTemplate>
<RecyclingElementFactory x:Key="elementFactory" RecyclePool="{StaticResource RecyclePool}">
<RecyclingElementFactory.Templates>
<StaticResource x:Key="odd" ResourceKey="odd" />
<StaticResource x:Key="queuedBook" ResourceKey="queuedBook" />
</RecyclingElementFactory.Templates>
</RecyclingElementFactory>
</UserControl.Resources>
<UserControl.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="20"/>
</Style>
</UserControl.Styles>
<Grid RowDefinitions="1*,30">
<Grid RowDefinitions="*,Auto">
<TabControl Grid.Row="0">
<TabControl.Styles>
<Style Selector="ItemsPresenter#PART_ItemsPresenter">
<Setter Property="Height" Value="33"/>
</Style>
</TabControl.Styles>
<!-- Queue Tab -->
<TabItem>
<TabItem.Header>
<TextBlock FontSize="14" VerticalAlignment="Center">Process Queue</TextBlock>
</TabItem.Header>
<Grid ColumnDefinitions="*" RowDefinitions="*,40">
<Border Grid.Column="0" Grid.Row="0" BorderThickness="1" BorderBrush="Black" Background="WhiteSmoke">
<Border Grid.Column="0" Grid.Row="0" BorderThickness="1" BorderBrush="{DynamicResource DataGridGridLinesBrush}" Background="WhiteSmoke">
<ScrollViewer
Name="scroller"
HorizontalScrollBarVisibility="Disabled"
@ -55,12 +54,13 @@
</Grid>
</Grid>
</TabItem>
<!-- Log Tab -->
<TabItem>
<TabItem.Header>
<TextBlock FontSize="14" VerticalAlignment="Center">Queue Log</TextBlock>
</TabItem.Header>
<Grid ColumnDefinitions="*" RowDefinitions="*,40">
<Border Grid.Column="0" Grid.Row="0" BorderThickness="1" BorderBrush="Black" Background="WhiteSmoke">
<Border Grid.Column="0" Grid.Row="0" BorderThickness="1" BorderBrush="{DynamicResource DataGridGridLinesBrush}" Background="WhiteSmoke">
<DataGrid AutoGenerateColumns="False" Items="{Binding LogEntries}">
<DataGrid.Columns>
<DataGridTextColumn SortMemberPath="LogDate" Header="Timestamp" CanUserSort="True" Binding="{Binding LogDateString}" Width="90"/>
@ -84,11 +84,11 @@
</TabItem>
</TabControl>
<!-- Queue Status -->
<Grid Grid.Row="1" Margin="5,0,0,0" ColumnDefinitions="120,1*,65">
<Grid Grid.Row="1" Margin="5,0,0,0" ColumnDefinitions="Auto,*,Auto">
<Panel Grid.Column="0">
<Panel.Styles>
<Style Selector="ProgressBar:horizontal">
<Setter Property="MinWidth" Value="20" />
<Setter Property="MinWidth" Value="100" />
</Style>
</Panel.Styles>
<ProgressBar Name="toolStripProgressBar1" ShowProgressText="True" />

View File

@ -11,7 +11,7 @@
<DataGrid Name="productsGrid" AutoGenerateColumns="False" Items="{Binding GridEntries}">
<DataGrid.Columns>
<controls:DataGridCheckBoxColumnExt IsVisible="True" Header="Remove" IsThreeState="True" IsReadOnly="False" CanUserSort="True" Binding="{Binding Remove, Mode=TwoWay}" Width="70" SortMemberPath="Remove"/>
<controls:DataGridCheckBoxColumnExt IsVisible="False" Header="Remove" IsThreeState="True" IsReadOnly="False" CanUserSort="True" Binding="{Binding Remove, Mode=TwoWay}" Width="70" SortMemberPath="Remove"/>
<DataGridTemplateColumn CanUserSort="True" Width="75" Header="Liberate" SortMemberPath="Liberate">
<DataGridTemplateColumn.CellTemplate>

View File

@ -38,6 +38,7 @@ namespace LibationWinForms.AvaloniaUI.Views
.Select(lbe => lbe.LibraryBook)
.ToList();
DataGridColumn removeGVColumn;
DataGridColumn liberateGVColumn;
DataGridColumn coverGVColumn;
@ -53,12 +54,28 @@ namespace LibationWinForms.AvaloniaUI.Views
DataGridColumn myRatingGVColumn;
DataGridColumn miscGVColumn;
DataGridColumn tagAndDetailsGVColumn;
#region Init
public ProductsDisplay2()
{
InitializeComponent();
if (Design.IsDesignMode)
{
using var context = DbContexts.GetContext();
var book = context.GetLibraryBook_Flat_NoTracking("B017V4IM1G");
productsGrid.DataContext = _viewModel = new ProductsDisplayViewModel(new List<LibraryBook> { book });
return;
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
productsGrid = this.FindControl<DataGrid>(nameof(productsGrid));
productsGrid.Sorting += Dg1_Sorting;
productsGrid.Sorting += ProductsGrid_Sorting;
productsGrid.CanUserSortColumns = true;
productsGrid.LoadingRow += ProductsGrid_LoadingRow;
@ -78,6 +95,42 @@ namespace LibationWinForms.AvaloniaUI.Views
miscGVColumn = productsGrid.Columns[13];
tagAndDetailsGVColumn = productsGrid.Columns[14];
RegisterCustomColumnComparers();
}
#endregion
#region Apply Background Brush Style to Series Books Rows
private static object tagObj = new();
private void ProductsGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
if (e.Row.Tag == tagObj)
return;
e.Row.Tag = tagObj;
static IBrush GetRowColor(DataGridRow row)
=> row.DataContext is GridEntry2 gEntry
&& gEntry is LibraryBookEntry2 lbEntry
&& lbEntry.Parent is not null
? App.SeriesEntryGridBackgroundBrush
: null;
e.Row.Background = GetRowColor(e.Row);
e.Row.DataContextChanged += (sender, e) =>
{
var row = sender as DataGridRow;
row.Background = GetRowColor(row);
};
}
#endregion
#region Sorting
private void RegisterCustomColumnComparers()
{
removeGVColumn.CustomSortComparer = new RowComparer(removeGVColumn);
liberateGVColumn.CustomSortComparer = new RowComparer(liberateGVColumn);
titleGVColumn.CustomSortComparer = new RowComparer(titleGVColumn);
@ -92,50 +145,27 @@ namespace LibationWinForms.AvaloniaUI.Views
myRatingGVColumn.CustomSortComparer = new RowComparer(myRatingGVColumn);
miscGVColumn.CustomSortComparer = new RowComparer(miscGVColumn);
tagAndDetailsGVColumn.CustomSortComparer = new RowComparer(tagAndDetailsGVColumn);
removeGVColumn.PropertyChanged += RemoveGVColumn_PropertyChanged;
if (Design.IsDesignMode)
{
using var context = DbContexts.GetContext();
var book = context.GetLibraryBook_Flat_NoTracking("B017V4IM1G");
productsGrid.DataContext = _viewModel = new ProductsDisplayViewModel(new List<LibraryBook> { book });
return;
}
}
private void RemoveGVColumn_PropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e)
private void ReSort()
{
if (CurrentSortColumn is null)
bindingList.InternalList.Sort((i1, i2) => i2.DateAdded.CompareTo(i1.DateAdded));
else
CurrentSortColumn.Sort(((RowComparer)CurrentSortColumn.CustomSortComparer).SortDirection ?? ListSortDirection.Ascending);
}
private static object tagObj = new();
private static readonly IBrush SeriesBgColor = Brush.Parse("#ffe6ffe6");
private void ProductsGrid_LoadingRow(object sender, DataGridRowEventArgs e)
private DataGridColumn CurrentSortColumn;
private void ProductsGrid_Sorting(object sender, DataGridColumnEventArgs e)
{
if (e.Row.Tag == tagObj)
return;
e.Row.Tag = tagObj;
static IBrush GetRowColor(DataGridRow row)
=> row.DataContext is GridEntry2 gEntry
&& gEntry is LibraryBookEntry2 lbEntry
&& lbEntry.Parent is not null
? SeriesBgColor
: null;
e.Row.Background = GetRowColor(e.Row);
e.Row.DataContextChanged += (sender, e) =>
{
var row = sender as DataGridRow;
row.Background = GetRowColor(row);
};
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
var comparer = e.Column.CustomSortComparer as RowComparer;
//Force the comparer to get the current sort order. We can't
//retrieve it from inside this event handler because Avalonia
//doesn't set the property until after this event.
comparer.SortDirection = null;
CurrentSortColumn = e.Column;
}
private class RowComparer : IComparer
@ -167,7 +197,7 @@ namespace LibationWinForms.AvaloniaUI.Views
var geA = (GridEntry2)x;
var geB = (GridEntry2)y;
SortDirection ??= GetSortOrder(Column);
SortDirection ??= GetSortOrder();
SeriesEntrys2 parentA = null;
SeriesEntrys2 parentB = null;
@ -209,8 +239,8 @@ namespace LibationWinForms.AvaloniaUI.Views
return Compare(parentA, parentB);
}
private static ListSortDirection? GetSortOrder(DataGridColumn column)
=> CurrentSortingStatePi.GetValue(HeaderCellPi.GetValue(column)) as ListSortDirection?;
private ListSortDirection? GetSortOrder()
=> CurrentSortingStatePi.GetValue(HeaderCellPi.GetValue(Column)) as ListSortDirection?;
private int Compare(GridEntry2 x, GridEntry2 y)
{
@ -221,17 +251,7 @@ namespace LibationWinForms.AvaloniaUI.Views
}
}
DataGridColumn CurrentSortColumn;
private void Dg1_Sorting(object sender, DataGridColumnEventArgs e)
{
var comparer = e.Column.CustomSortComparer as RowComparer;
//Force the comparer to get the current sort order. We can't
//retrieve it from inside this event handler because Avalonia
//doesn't set the property until after this event.
comparer.SortDirection = null;
CurrentSortColumn = e.Column;
}
#endregion
#region Button controls
@ -244,7 +264,10 @@ namespace LibationWinForms.AvaloniaUI.Views
if (sEntry.Liberate.Expanded)
bindingList.CollapseItem(sEntry);
else
{
bindingList.ExpandItem(sEntry);
ReSort();
}
VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count());
}
@ -565,14 +588,9 @@ namespace LibationWinForms.AvaloniaUI.Views
VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count());
//Re-sort after filtering
if (CurrentSortColumn is null)
bindingList.InternalList.Sort((i1, i2) => i2.DateAdded.CompareTo(i1.DateAdded));
else
{
CurrentSortColumn.Sort(((RowComparer)CurrentSortColumn.CustomSortComparer).SortDirection ?? ListSortDirection.Ascending);
}
bindingList.ResetCollection();
ReSort();
}
#endregion

View File

@ -48,6 +48,7 @@
<None Remove="AvaloniaUI\Assets\first.png" />
<None Remove="AvaloniaUI\Assets\import_16x16.png" />
<None Remove="AvaloniaUI\Assets\last.png" />
<None Remove="AvaloniaUI\Assets\LibationStyles.xaml" />
<None Remove="AvaloniaUI\Assets\queued.png" />
<None Remove="AvaloniaUI\Assets\up.png" />
</ItemGroup>
@ -81,6 +82,12 @@
</Compile>
</ItemGroup>
<ItemGroup>
<AvaloniaResource Update="AvaloniaUI\Assets\LibationStyles.xaml">
<Generator>MSBuild:Compile</Generator>
</AvaloniaResource>
</ItemGroup>
<ItemGroup>
<Compile Update="AvaloniaUI\Controls\FormattableTextBlock.axaml.cs">
<DependentUpon>FormattableTextBlock.axaml</DependentUpon>