Added DescriptionDisplayDialog and ImageDisplayDialog

This commit is contained in:
Michael Bucari-Tovo 2022-07-16 23:27:56 -06:00
parent 1578be2520
commit ad6b86fcb4
6 changed files with 211 additions and 18 deletions

View File

@ -0,0 +1,19 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="540" d:DesignHeight="140"
x:Class="LibationWinForms.AvaloniaUI.Views.Dialogs.DescriptionDisplayDialog"
SystemDecorations="None"
Title="DescriptionDisplay">
<TextBox
Text="{Binding DescriptionText}"
IsReadOnly="True"
MinWidth="540"
TextWrapping="Wrap"
Name="DescriptionTextBox"
CaretBrush="{StaticResource SystemControlTransparentBrush}"
LostFocus="DescriptionTextBox_LostFocus" />
</Window>

View File

@ -0,0 +1,62 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using System;
namespace LibationWinForms.AvaloniaUI.Views.Dialogs
{
public partial class DescriptionDisplayDialog : Window
{
public Point SpawnLocation { get; set; }
public string DescriptionText { get; init; }
public DescriptionDisplayDialog()
{
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
DescriptionTextBox = this.FindControl<TextBox>(nameof(DescriptionTextBox));
this.Activated += DescriptionDisplay_Activated;
Opened += DescriptionDisplay_Opened;
}
private void DescriptionDisplay_Opened(object sender, EventArgs e)
{
DescriptionTextBox.Focus();
}
private void DescriptionDisplay_Activated(object sender, EventArgs e)
{
DataContext = this;
var workingHeight = this.Screens.Primary.WorkingArea.Height;
DescriptionTextBox.Measure(new Size(DescriptionTextBox.MinWidth, workingHeight * 0.8));
this.Width = DescriptionTextBox.DesiredSize.Width;
this.Height = DescriptionTextBox.DesiredSize.Height;
this.MinWidth = this.Width;
this.MaxWidth = this.Width;
this.MinHeight = this.Height;
this.MaxHeight = this.Height;
DescriptionTextBox.Width = this.Width;
DescriptionTextBox.Height = this.Height;
DescriptionTextBox.MinWidth = this.Width;
DescriptionTextBox.MaxWidth = this.Width;
DescriptionTextBox.MinHeight = this.Height;
DescriptionTextBox.MaxHeight = this.Height;
this.Position = new PixelPoint((int)SpawnLocation.X, (int)Math.Min(SpawnLocation.Y, (double)workingHeight - DescriptionTextBox.DesiredSize.Height));
}
private void DescriptionTextBox_LostFocus(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
Close();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

View File

@ -0,0 +1,21 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="500"
x:Class="LibationWinForms.AvaloniaUI.Views.Dialogs.ImageDisplayDialog"
MinWidth="500" MinHeight="500"
Title="Cover"
WindowStartupLocation="CenterOwner"
Icon="/AvaloniaUI/Assets/libation.ico">
<Image Stretch="Uniform" Source="{Binding CoverImage}">
<Image.ContextMenu>
<ContextMenu>
<MenuItem
Click="SaveImage_Clicked"
Header="Save Picture to File"/>
</ContextMenu>
</Image.ContextMenu>
</Image>
</Window>

View File

@ -0,0 +1,84 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
using System;
using System.ComponentModel;
using System.IO;
using ReactiveUI;
namespace LibationWinForms.AvaloniaUI.Views.Dialogs
{
public partial class ImageDisplayDialog : DialogWindow, INotifyPropertyChanged
{
public string PictureFileName { get; set; }
public string BookSaveDirectory { get; set; }
private byte[] _coverBytes;
public byte[] CoverBytes
{
get => _coverBytes;
set
{
_coverBytes = value;
var ms = new MemoryStream(_coverBytes);
ms.Position = 0;
_bitmapHolder.CoverImage = new Bitmap(ms);
}
}
private readonly BitmapHolder _bitmapHolder = new BitmapHolder();
public ImageDisplayDialog()
{
InitializeComponent();
DataContext = _bitmapHolder;
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
public async void SaveImage_Clicked(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
SaveFileDialog saveFileDialog = new();
saveFileDialog.Filters.Add(new FileDialogFilter { Name = "Jpeg", Extensions = new System.Collections.Generic.List<string>() { "jpg" } });
saveFileDialog.Directory = Directory.Exists(BookSaveDirectory) ? BookSaveDirectory : Path.GetDirectoryName(BookSaveDirectory);
saveFileDialog.InitialFileName = PictureFileName;
var fileName = await saveFileDialog.ShowAsync(this);
if (fileName is null)
return;
try
{
File.WriteAllBytes(fileName, CoverBytes);
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, $"Failed to save picture to {fileName}");
await MessageBox.Show(this, $"An error was encountered while trying to save the picture\r\n\r\n{ex.Message}", "Failed to save picture", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
}
}
public class BitmapHolder : ViewModels.ViewModelBase
{
private Bitmap _coverImage;
public Bitmap CoverImage
{
get => _coverImage;
set
{
this.RaiseAndSetIfChanged(ref _coverImage, value);
}
}
}
}
}

View File

@ -18,7 +18,7 @@ namespace LibationWinForms.AvaloniaUI.Views
public event EventHandler<LibraryBook> LiberateClicked;
private ProductsDisplayViewModel _viewModel => DataContext as ProductsDisplayViewModel;
private GridView.ImageDisplay imageDisplay;
ImageDisplayDialog imageDisplayDialog;
public ProductsDisplay2()
{
@ -211,12 +211,18 @@ namespace LibationWinForms.AvaloniaUI.Views
if (sender is not Image tblock || tblock.DataContext is not GridEntry2 gEntry)
return;
if (imageDisplayDialog is null || !imageDisplayDialog.IsVisible)
{
imageDisplayDialog = new ImageDisplayDialog();
}
var picDef = new PictureDefinition(gEntry.LibraryBook.Book.PictureLarge ?? gEntry.LibraryBook.Book.PictureId, PictureSize.Native);
void PictureCached(object sender, PictureCachedEventArgs e)
{
if (e.Definition.PictureId == picDef.PictureId)
imageDisplay.CoverPicture = e.Picture;
imageDisplayDialog.CoverBytes = e.Picture;
PictureStorage.PictureCached -= PictureCached;
}
@ -224,24 +230,20 @@ namespace LibationWinForms.AvaloniaUI.Views
PictureStorage.PictureCached += PictureCached;
(bool isDefault, byte[] initialImageBts) = PictureStorage.GetPicture(picDef);
var windowTitle = $"{gEntry.Title} - Cover";
if (imageDisplay is null || imageDisplay.IsDisposed || !imageDisplay.Visible)
{
imageDisplay = new GridView.ImageDisplay();
imageDisplay.RestoreSizeAndLocation(Configuration.Instance);
imageDisplay.FormClosed += (_, _) => imageDisplay.SaveSizeAndLocation(Configuration.Instance);
}
imageDisplay.BookSaveDirectory = AudibleFileStorage.Audio.GetDestinationDirectory(gEntry.LibraryBook);
imageDisplay.PictureFileName = System.IO.Path.GetFileName(AudibleFileStorage.Audio.GetBooksDirectoryFilename(gEntry.LibraryBook, ".jpg"));
imageDisplay.Text = windowTitle;
imageDisplay.CoverPicture = initialImageBts;
imageDisplayDialog.BookSaveDirectory = AudibleFileStorage.Audio.GetDestinationDirectory(gEntry.LibraryBook);
imageDisplayDialog.PictureFileName = System.IO.Path.GetFileName(AudibleFileStorage.Audio.GetBooksDirectoryFilename(gEntry.LibraryBook, ".jpg"));
imageDisplayDialog.Title = windowTitle;
imageDisplayDialog.CoverBytes = initialImageBts;
if (!isDefault)
PictureStorage.PictureCached -= PictureCached;
if (!imageDisplay.Visible)
imageDisplay.Show(null);
if (!imageDisplayDialog.IsVisible)
imageDisplayDialog.Show();
}
public void Description_Click(object sender, Avalonia.Interactivity.RoutedEventArgs args)
@ -249,11 +251,10 @@ namespace LibationWinForms.AvaloniaUI.Views
if (sender is TextBlock tblock && tblock.DataContext is GridEntry2 gEntry)
{
var pt = tblock.Parent.PointToScreen(tblock.Parent.Bounds.TopRight);
var displayWindow = new GridView.DescriptionDisplay
var displayWindow = new DescriptionDisplayDialog
{
SpawnLocation = new System.Drawing.Point(pt.X, pt.Y),
SpawnLocation = new Point(pt.X, pt.Y),
DescriptionText = gEntry.LongDescription,
BorderThickness = 2,
};
void CloseWindow(object o, DataGridRowEventArgs e)
@ -261,7 +262,7 @@ namespace LibationWinForms.AvaloniaUI.Views
displayWindow.Close();
}
productsGrid.LoadingRow += CloseWindow;
displayWindow.FormClosed += (_, _) =>
displayWindow.Closing += (_, _) =>
{
productsGrid.LoadingRow -= CloseWindow;
};

View File

@ -109,6 +109,9 @@
</ItemGroup>
<ItemGroup>
<Compile Update="AvaloniaUI\Views\Dialogs\DescriptionDisplayDialog.axaml.cs">
<DependentUpon>DescriptionDisplayDialog.axaml</DependentUpon>
</Compile>
<Compile Update="AvaloniaUI\Views\Dialogs\EditQuickFilters.axaml.cs">
<DependentUpon>EditQuickFilters.axaml</DependentUpon>
</Compile>
@ -118,6 +121,9 @@
<Compile Update="AvaloniaUI\Views\Dialogs\SearchSyntaxDialog.axaml.cs">
<DependentUpon>SearchSyntaxDialog.axaml</DependentUpon>
</Compile>
<Compile Update="AvaloniaUI\Views\Dialogs\ImageDisplayDialog.axaml.cs">
<DependentUpon>ImageDisplayDialog.axaml</DependentUpon>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>