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/DefaultTheme.xaml"/>
<StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/> <StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
<StyleInclude Source="/AvaloniaUI/Assets/DataGridTheme.xaml"/> <StyleInclude Source="/AvaloniaUI/Assets/DataGridTheme.xaml"/>
<StyleInclude Source="/AvaloniaUI/Assets/LibationStyles.xaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

View File

@ -1,12 +1,20 @@
using Avalonia; using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Media;
using LibationWinForms.AvaloniaUI.Views; using LibationWinForms.AvaloniaUI.Views;
namespace LibationWinForms.AvaloniaUI namespace LibationWinForms.AvaloniaUI
{ {
public class App : Application 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() public override void Initialize()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
@ -14,6 +22,8 @@ namespace LibationWinForms.AvaloniaUI
public override void OnFrameworkInitializationCompleted() public override void OnFrameworkInitializationCompleted()
{ {
LoadStyles();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{ {
var mainWindow = new MainWindow(); var mainWindow = new MainWindow();
@ -23,5 +33,14 @@ namespace LibationWinForms.AvaloniaUI
base.OnFrameworkInitializationCompleted(); 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.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using ApplicationServices; using ApplicationServices;
using Avalonia.Media;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using DataLayer; using DataLayer;
using Dinah.Core; using Dinah.Core;
@ -63,12 +64,12 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
public bool IsDownloading => Status is ProcessBookStatus.Working; public bool IsDownloading => Status is ProcessBookStatus.Working;
public bool Queued => Status is ProcessBookStatus.Queued; public bool Queued => Status is ProcessBookStatus.Queued;
public string BackgroundColor => Status switch public IBrush BackgroundColor => Status switch
{ {
ProcessBookStatus.Cancelled => "Khaki", ProcessBookStatus.Cancelled => App.ProcessQueueBookCancelledBrush,
ProcessBookStatus.Completed => "PaleGreen", ProcessBookStatus.Completed => App.ProcessQueueBookCompletedBrush,
ProcessBookStatus.Failed => "LightCoral", ProcessBookStatus.Failed => App.ProcessQueueBookFailedBrush,
_ => "White", _ => App.ProcessQueueBookDefaultBrush,
}; };
public string StatusText => Result switch public string StatusText => Result switch
{ {
@ -83,6 +84,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
#endregion #endregion
private TimeSpan TimeRemaining { set { ETA = $"ETA: {value:mm\\:ss}"; } } private TimeSpan TimeRemaining { set { ETA = $"ETA: {value:mm\\:ss}"; } }
private Processable CurrentProcessable => _currentProcessable ??= Processes.Dequeue().Invoke(); private Processable CurrentProcessable => _currentProcessable ??= Processes.Dequeue().Invoke();
private Processable NextProcessable() => _currentProcessable = null; private Processable NextProcessable() => _currentProcessable = null;
@ -107,6 +109,7 @@ namespace LibationWinForms.AvaloniaUI.ViewModels
// Mutable property. Set the field so PropertyChanged isn't fired. // Mutable property. Set the field so PropertyChanged isn't fired.
using var ms = new System.IO.MemoryStream(picture); using var ms = new System.IO.MemoryStream(picture);
_cover = new Bitmap(ms); _cover = new Bitmap(ms);
} }
private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e) private void PictureStorage_PictureCached(object sender, PictureCachedEventArgs e)

View File

@ -9,13 +9,25 @@
mc:Ignorable="d" d:DesignWidth="2000" d:DesignHeight="700" mc:Ignorable="d" d:DesignWidth="2000" d:DesignHeight="700"
x:Class="LibationWinForms.AvaloniaUI.Views.MainWindow" Title="MainWindow"> x:Class="LibationWinForms.AvaloniaUI.Views.MainWindow" Title="MainWindow">
<Border BorderBrush="Gray" BorderThickness="2" Padding="15"> <Border BorderBrush="{DynamicResource DataGridGridLinesBrush}" BorderThickness="2" Padding="15">
<Grid RowDefinitions="30,40,1*,30"> <Grid RowDefinitions="Auto,Auto,*,Auto">
<Grid Grid.Row="0" ColumnDefinitions="1*, 200"> <Grid Grid.Row="0" ColumnDefinitions="1*, Auto">
<!-- Menu Strip --> <!-- Menu Strip -->
<Menu Grid.Column="0"> <Menu Grid.Column="0" VerticalAlignment="Top">
<MenuItem Name="importToolStripMenuItem" Header="_Import"> <!-- 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 Name="autoScanLibraryToolStripMenuItem" Click="autoScanLibraryToolStripMenuItem_Click" Header="A_uto Scan Library">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox Name="autoScanLibraryToolStripMenuItemCheckbox" BorderThickness="0" IsHitTestVisible="False">Toggle _Me0</CheckBox> <CheckBox Name="autoScanLibraryToolStripMenuItemCheckbox" BorderThickness="0" IsHitTestVisible="False">Toggle _Me0</CheckBox>
@ -30,16 +42,34 @@
<MenuItem Name="removeSomeAccountsToolStripMenuItem" Click="removeSomeAccountsToolStripMenuItem_Click" Header="Some Accounts" /> <MenuItem Name="removeSomeAccountsToolStripMenuItem" Click="removeSomeAccountsToolStripMenuItem_Click" Header="Some Accounts" />
</MenuItem> </MenuItem>
</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="beginBookBackupsToolStripMenuItem" Click="beginBookBackupsToolStripMenuItem_Click" FormatText="Begin _Book and PDF Backups: {0}" />
<controls:FormattableMenuItem Name="beginPdfBackupsToolStripMenuItem" Click="beginPdfBackupsToolStripMenuItem_Click" FormatText="Begin _PDF Only 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}" /> <controls:FormattableMenuItem Name="liberateVisibleToolStripMenuItem_LiberateMenu" Click="liberateVisible" FormatText="Liberate _Visible Books: {0}" />
</MenuItem> </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 Name="exportLibraryToolStripMenuItem" Click="exportLibraryToolStripMenuItem_Click" Header="E_xport Library" />
</MenuItem> </MenuItem>
<MenuItem Name="quickFiltersToolStripMenuItem" Header="Quick _Filters"> <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 Name="firstFilterIsDefaultToolStripMenuItem" Click="firstFilterIsDefaultToolStripMenuItem_Click" Header="Start Libation with 1st filter _Default">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox Name="firstFilterIsDefaultToolStripMenuItem_Checkbox" BorderThickness="0" IsHitTestVisible="False">Toggle _Me0</CheckBox> <CheckBox Name="firstFilterIsDefaultToolStripMenuItem_Checkbox" BorderThickness="0" IsHitTestVisible="False">Toggle _Me0</CheckBox>
@ -49,16 +79,28 @@
<Separator /> <Separator />
</MenuItem> </MenuItem>
<controls:FormattableMenuItem Name="visibleBooksToolStripMenuItem" FormatText="_Visible Books: {0}" > <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}" /> <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="setDownloadedToolStripMenuItem" Click="setDownloadedToolStripMenuItem_Click" Header="Set '_Downloaded' status..." />
<MenuItem Name="removeToolStripMenuItem" Click="removeToolStripMenuItem_Click" Header="_Remove from library..." /> <MenuItem Name="removeToolStripMenuItem" Click="removeToolStripMenuItem_Click" Header="_Remove from library..." />
</controls:FormattableMenuItem> </controls:FormattableMenuItem>
<MenuItem Name="settingsToolStripMenuItem" Header="_Settings"> <MenuItem Header="_Settings">
<MenuItem Name="accountsToolStripMenuItem" Click="accountsToolStripMenuItem_Click" Header="_Accounts..." /> <!-- Remove height style property for menu item -->
<MenuItem Name="basicSettingsToolStripMenuItem" Click="basicSettingsToolStripMenuItem_Click" Header="_Settings..." /> <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 /> <Separator />
<MenuItem Name="aboutToolStripMenuItem" Click="aboutToolStripMenuItem_Click" Header="A_bout..." /> <MenuItem Click="aboutToolStripMenuItem_Click" Header="A_bout..." />
</MenuItem> </MenuItem>
</Menu> </Menu>
<StackPanel Name="scanningToolStripMenuItem" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel Name="scanningToolStripMenuItem" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
@ -68,41 +110,56 @@
</Grid> </Grid>
<!-- Buttons and Search Box --> <!-- Buttons and Search Box -->
<Grid Grid.Row="1" ColumnDefinitions="30,170,1*,100,30"> <Grid Grid.Row="1" Margin="0,10,0,10" Height="30" ColumnDefinitions="Auto,*,Auto">
<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="❱❱❱"/>
<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="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"/> <Button Name="doneRemovingBtn" Click="doneRemovingBtn_Click" Height="30" Width="160" Margin="10,0,0,0" Content="Done Removing Books"/>
</StackPanel> </StackPanel>
<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> </Grid>
<Border Grid.Row="2" BorderThickness="1" BorderBrush="{DynamicResource DataGridGridLinesBrush}">
<SplitView Name="splitContainer1" IsPaneOpen="True" DisplayMode="Inline" OpenPaneLength="375" PanePlacement="Right">
<SplitView Name="splitContainer1" Grid.Row="2" IsPaneOpen="True" DisplayMode="Inline" OpenPaneLength="375" PanePlacement="Right"> <!-- Process Queue -->
<SplitView.Pane>
<views:ProcessQueueControl2 Name="processBookQueue1"/>
</SplitView.Pane>
<!-- Process Queue --> <!-- Product Display Grid -->
<SplitView.Pane> <views:ProductsDisplay2
<views:ProcessQueueControl2 Name="processBookQueue1"/> InitialLoaded="productsDisplay_Initialized"
</SplitView.Pane> LiberateClicked="ProductsDisplay_LiberateClicked"
RemovableCountChanged="productsDisplay_RemovableCountChanged"
<!-- Product Display Grid --> VisibleCountChanged="productsDisplay_VisibleCountChanged"
<views:ProductsDisplay2 Name="productsDisplay" />
InitialLoaded="productsDisplay_Initialized" </SplitView>
LiberateClicked="ProductsDisplay_LiberateClicked" </Border>
RemovableCountChanged="productsDisplay_RemovableCountChanged"
VisibleCountChanged="productsDisplay_VisibleCountChanged"
Name="productsDisplay" />
</SplitView>
<!-- Bottom Status Strip --> <!-- Bottom Status Strip -->
<Grid Grid.Row="3" ColumnDefinitions="80,1*,100*"> <Grid Grid.Row="3" Margin="0,10,0,0" VerticalAlignment="Bottom" ColumnDefinitions="*,Auto">
<controls:FormattableTextBlock Name="visibleCountLbl" Grid.Column="0" FormatText="Visible {0}" VerticalAlignment="Center" /> <controls:FormattableTextBlock FontSize="14" Name="visibleCountLbl" Grid.Column="0" FormatText="Visible {0}" VerticalAlignment="Center" />
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right"> <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
<TextBlock Name="backupsCountsLbl" Text="[Calculating backed up book quantities]" VerticalAlignment="Center" /> <TextBlock FontSize="14" 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" /> <controls:FormattableTextBlock FontSize="14" Name="pdfsCountsLbl" FormatText=" | PDFs: NOT d/l'ed: {0} Downloaded: {1}" VerticalAlignment="Center" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid> </Grid>

View File

@ -53,7 +53,6 @@ namespace LibationWinForms.AvaloniaUI.Views
private void FindAllControls() private void FindAllControls()
{ {
importToolStripMenuItem = this.FindControl<MenuItem>(nameof(importToolStripMenuItem));
{ {
autoScanLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(autoScanLibraryToolStripMenuItem)); autoScanLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(autoScanLibraryToolStripMenuItem));
autoScanLibraryToolStripMenuItemCheckbox = this.FindControl<CheckBox>(nameof(autoScanLibraryToolStripMenuItemCheckbox)); 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)); beginBookBackupsToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(beginBookBackupsToolStripMenuItem));
beginPdfBackupsToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(beginPdfBackupsToolStripMenuItem)); beginPdfBackupsToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(beginPdfBackupsToolStripMenuItem));
convertAllM4bToMp3ToolStripMenuItem = this.FindControl<MenuItem>(nameof(convertAllM4bToMp3ToolStripMenuItem));
liberateVisibleToolStripMenuItem_LiberateMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_LiberateMenu)); liberateVisibleToolStripMenuItem_LiberateMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_LiberateMenu));
} }
exportToolStripMenuItem = this.FindControl<MenuItem>(nameof(exportToolStripMenuItem));
{ {
exportLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(exportLibraryToolStripMenuItem)); exportLibraryToolStripMenuItem = this.FindControl<MenuItem>(nameof(exportLibraryToolStripMenuItem));
} }
@ -92,17 +87,10 @@ namespace LibationWinForms.AvaloniaUI.Views
visibleBooksToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(visibleBooksToolStripMenuItem)); visibleBooksToolStripMenuItem = this.FindControl<FormattableMenuItem>(nameof(visibleBooksToolStripMenuItem));
{ {
liberateVisibleToolStripMenuItem_VisibleBooksMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_VisibleBooksMenu)); liberateVisibleToolStripMenuItem_VisibleBooksMenu = this.FindControl<FormattableMenuItem>(nameof(liberateVisibleToolStripMenuItem_VisibleBooksMenu));
replaceTagsToolStripMenuItem = this.FindControl<MenuItem>(nameof(replaceTagsToolStripMenuItem));
setDownloadedToolStripMenuItem = this.FindControl<MenuItem>(nameof(setDownloadedToolStripMenuItem)); setDownloadedToolStripMenuItem = this.FindControl<MenuItem>(nameof(setDownloadedToolStripMenuItem));
removeToolStripMenuItem = this.FindControl<MenuItem>(nameof(removeToolStripMenuItem)); 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 = this.FindControl<StackPanel>(nameof(scanningToolStripMenuItem));
scanningToolStripMenuItem_Text = this.FindControl<TextBlock>(nameof(scanningToolStripMenuItem_Text)); 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" mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="90" MaxHeight="90" MinHeight="90" MinWidth="300"
x:Class="LibationWinForms.AvaloniaUI.Views.ProcessBookControl2" Background="{Binding BackgroundColor}"> x:Class="LibationWinForms.AvaloniaUI.Views.ProcessBookControl2" Background="{Binding BackgroundColor}">
<Border BorderBrush="Gray" BorderThickness="2"> <Border BorderBrush="{DynamicResource ProcessQueueBookBorderBrush}" BorderThickness="2">
<Grid ColumnDefinitions="86,1*,58"> <Grid ColumnDefinitions="Auto,*,Auto">
<Panel Grid.Column="0" Margin="3,0,0,0" Width="80" Height="80" HorizontalAlignment="Left">
<Panel Grid.Column="0" Margin="3" Background="LightGray" Width="80" Height="80" HorizontalAlignment="Left">
<Image Width="80" Height="80" Source="{Binding Cover}" Stretch="Uniform" /> <Image Width="80" Height="80" Source="{Binding Cover}" Stretch="Uniform" />
</Panel> </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"> <StackPanel Grid.Column="0" Grid.Row="0" Orientation="Vertical">
<TextBlock ClipToBounds="True" TextWrapping="Wrap" FontSize="11" Text="{Binding Title}" /> <TextBlock ClipToBounds="True" TextWrapping="Wrap" FontSize="11" Text="{Binding Title}" />
<TextBlock FontSize="10" TextWrapping="NoWrap" Text="{Binding Author}" /> <TextBlock FontSize="10" TextWrapping="NoWrap" Text="{Binding Author}" />
@ -26,8 +27,8 @@
<TextBlock IsVisible="{Binding !IsDownloading}" Text="{Binding StatusText}"/> <TextBlock IsVisible="{Binding !IsDownloading}" Text="{Binding StatusText}"/>
</Panel> </Panel>
</Grid> </Grid>
<Grid Margin="3" Grid.Column="2" ColumnDefinitions="30,26"> <Grid Margin="3" Grid.Column="2" HorizontalAlignment="Right" ColumnDefinitions="Auto,Auto">
<StackPanel IsVisible="{Binding Queued }" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Vertical"> <StackPanel IsVisible="{Binding Queued}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Vertical">
<Button Height="20" Width="30" Click="MoveFirst_Click"> <Button Height="20" Width="30" Click="MoveFirst_Click">
<Image Height="20" Width="30" Source="/AvaloniaUI/Assets/first.png" Stretch="Uniform" VerticalAlignment="Bottom"/> <Image Height="20" Width="30" Source="/AvaloniaUI/Assets/first.png" Stretch="Uniform" VerticalAlignment="Bottom"/>
</Button> </Button>
@ -47,9 +48,10 @@
</Button> </Button>
</Panel> </Panel>
</Grid> </Grid>
<Panel Grid.Column="2" Margin="3"> <Panel Margin="3" Width="50" Grid.Column="2">
<TextPresenter FontSize="9" VerticalAlignment="Bottom" HorizontalAlignment="Center" IsVisible="{Binding IsDownloading}" Text="{Binding ETA}" /> <TextPresenter FontSize="9" VerticalAlignment="Bottom" HorizontalAlignment="Right" IsVisible="{Binding IsDownloading}" Text="{Binding ETA}" />
</Panel> </Panel>
</Grid> </Grid>
</Border> </Border>
</UserControl> </UserControl>

View File

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

View File

@ -11,7 +11,7 @@
<DataGrid Name="productsGrid" AutoGenerateColumns="False" Items="{Binding GridEntries}"> <DataGrid Name="productsGrid" AutoGenerateColumns="False" Items="{Binding GridEntries}">
<DataGrid.Columns> <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 CanUserSort="True" Width="75" Header="Liberate" SortMemberPath="Liberate">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>

View File

@ -38,6 +38,7 @@ namespace LibationWinForms.AvaloniaUI.Views
.Select(lbe => lbe.LibraryBook) .Select(lbe => lbe.LibraryBook)
.ToList(); .ToList();
DataGridColumn removeGVColumn; DataGridColumn removeGVColumn;
DataGridColumn liberateGVColumn; DataGridColumn liberateGVColumn;
DataGridColumn coverGVColumn; DataGridColumn coverGVColumn;
@ -53,12 +54,28 @@ namespace LibationWinForms.AvaloniaUI.Views
DataGridColumn myRatingGVColumn; DataGridColumn myRatingGVColumn;
DataGridColumn miscGVColumn; DataGridColumn miscGVColumn;
DataGridColumn tagAndDetailsGVColumn; DataGridColumn tagAndDetailsGVColumn;
#region Init
public ProductsDisplay2() public ProductsDisplay2()
{ {
InitializeComponent(); 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 = this.FindControl<DataGrid>(nameof(productsGrid));
productsGrid.Sorting += Dg1_Sorting; productsGrid.Sorting += ProductsGrid_Sorting;
productsGrid.CanUserSortColumns = true; productsGrid.CanUserSortColumns = true;
productsGrid.LoadingRow += ProductsGrid_LoadingRow; productsGrid.LoadingRow += ProductsGrid_LoadingRow;
@ -78,6 +95,42 @@ namespace LibationWinForms.AvaloniaUI.Views
miscGVColumn = productsGrid.Columns[13]; miscGVColumn = productsGrid.Columns[13];
tagAndDetailsGVColumn = productsGrid.Columns[14]; 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); removeGVColumn.CustomSortComparer = new RowComparer(removeGVColumn);
liberateGVColumn.CustomSortComparer = new RowComparer(liberateGVColumn); liberateGVColumn.CustomSortComparer = new RowComparer(liberateGVColumn);
titleGVColumn.CustomSortComparer = new RowComparer(titleGVColumn); titleGVColumn.CustomSortComparer = new RowComparer(titleGVColumn);
@ -92,50 +145,27 @@ namespace LibationWinForms.AvaloniaUI.Views
myRatingGVColumn.CustomSortComparer = new RowComparer(myRatingGVColumn); myRatingGVColumn.CustomSortComparer = new RowComparer(myRatingGVColumn);
miscGVColumn.CustomSortComparer = new RowComparer(miscGVColumn); miscGVColumn.CustomSortComparer = new RowComparer(miscGVColumn);
tagAndDetailsGVColumn.CustomSortComparer = new RowComparer(tagAndDetailsGVColumn); 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) var comparer = e.Column.CustomSortComparer as RowComparer;
return; //Force the comparer to get the current sort order. We can't
e.Row.Tag = tagObj; //retrieve it from inside this event handler because Avalonia
//doesn't set the property until after this event.
static IBrush GetRowColor(DataGridRow row) comparer.SortDirection = null;
=> row.DataContext is GridEntry2 gEntry CurrentSortColumn = e.Column;
&& 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);
} }
private class RowComparer : IComparer private class RowComparer : IComparer
@ -167,7 +197,7 @@ namespace LibationWinForms.AvaloniaUI.Views
var geA = (GridEntry2)x; var geA = (GridEntry2)x;
var geB = (GridEntry2)y; var geB = (GridEntry2)y;
SortDirection ??= GetSortOrder(Column); SortDirection ??= GetSortOrder();
SeriesEntrys2 parentA = null; SeriesEntrys2 parentA = null;
SeriesEntrys2 parentB = null; SeriesEntrys2 parentB = null;
@ -209,8 +239,8 @@ namespace LibationWinForms.AvaloniaUI.Views
return Compare(parentA, parentB); return Compare(parentA, parentB);
} }
private static ListSortDirection? GetSortOrder(DataGridColumn column) private ListSortDirection? GetSortOrder()
=> CurrentSortingStatePi.GetValue(HeaderCellPi.GetValue(column)) as ListSortDirection?; => CurrentSortingStatePi.GetValue(HeaderCellPi.GetValue(Column)) as ListSortDirection?;
private int Compare(GridEntry2 x, GridEntry2 y) private int Compare(GridEntry2 x, GridEntry2 y)
{ {
@ -221,17 +251,7 @@ namespace LibationWinForms.AvaloniaUI.Views
} }
} }
DataGridColumn CurrentSortColumn; #endregion
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;
}
#region Button controls #region Button controls
@ -244,7 +264,10 @@ namespace LibationWinForms.AvaloniaUI.Views
if (sEntry.Liberate.Expanded) if (sEntry.Liberate.Expanded)
bindingList.CollapseItem(sEntry); bindingList.CollapseItem(sEntry);
else else
{
bindingList.ExpandItem(sEntry); bindingList.ExpandItem(sEntry);
ReSort();
}
VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count()); VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count());
} }
@ -565,14 +588,9 @@ namespace LibationWinForms.AvaloniaUI.Views
VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count()); VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count());
//Re-sort after filtering //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(); bindingList.ResetCollection();
ReSort();
} }
#endregion #endregion

View File

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