diff --git a/Source/LibationWinForms/AvaloniaUI/App.axaml.cs b/Source/LibationWinForms/AvaloniaUI/App.axaml.cs index 0c1f1c19..dadd659c 100644 --- a/Source/LibationWinForms/AvaloniaUI/App.axaml.cs +++ b/Source/LibationWinForms/AvaloniaUI/App.axaml.cs @@ -6,40 +6,40 @@ 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 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); - } + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } - public override void OnFrameworkInitializationCompleted() - { - LoadStyles(); + public override void OnFrameworkInitializationCompleted() + { + LoadStyles(); - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - var mainWindow = new MainWindow(); - desktop.MainWindow = mainWindow; - mainWindow.OnLoad(); - } + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + var mainWindow = new MainWindow(); + desktop.MainWindow = mainWindow; + mainWindow.OnLoad(); + } - 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"); - } - } + private void LoadStyles() + { + ProcessQueueBookFailedBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookFailedBrush"); + ProcessQueueBookCompletedBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookCompletedBrush"); + ProcessQueueBookCancelledBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookCancelledBrush"); + ProcessQueueBookDefaultBrush = AvaloniaUtils.GetBrushFromResources("ProcessQueueBookDefaultBrush"); + SeriesEntryGridBackgroundBrush = AvaloniaUtils.GetBrushFromResources("SeriesEntryGridBackgroundBrush"); + } + } } \ No newline at end of file diff --git a/Source/LibationWinForms/AvaloniaUI/Assets/1x1.png b/Source/LibationWinForms/AvaloniaUI/Assets/1x1.png new file mode 100644 index 00000000..1914264c Binary files /dev/null and b/Source/LibationWinForms/AvaloniaUI/Assets/1x1.png differ diff --git a/Source/LibationWinForms/AvaloniaUI/MessageBox.cs b/Source/LibationWinForms/AvaloniaUI/MessageBox.cs index b1619da8..810999d3 100644 --- a/Source/LibationWinForms/AvaloniaUI/MessageBox.cs +++ b/Source/LibationWinForms/AvaloniaUI/MessageBox.cs @@ -214,42 +214,28 @@ namespace LibationWinForms.AvaloniaUI var vm = new MessageBoxViewModel(message, caption, buttons, icon, defaultButton); dialog.DataContext = vm; dialog.CanResize = false; - - var thisScreen = (owner ?? dialog).Screens.ScreenFromVisual(owner ?? dialog); var tbx = dialog.FindControl("messageTextBlock"); + + tbx.MinWidth = vm.TextBlockMinWidth; tbx.Text = message; - var maxSize = new Size(0.6 * thisScreen.Bounds.Width - 72, 0.9 * thisScreen.Bounds.Height); + var thisScreen = (owner ?? dialog).Screens.ScreenFromVisual(owner ?? dialog); - var desiredMax = maxSize; + var maxSize = new Size(0.20 * thisScreen.Bounds.Width, 0.9 * thisScreen.Bounds.Height - 55); - //Try to minimize the TextBlock area. - List<(double, Size)> areas = new(); - for (int i = 0; i < 20; i++) - { - tbx.Measure(desiredMax); + var desiredMax = new Size(maxSize.Width, maxSize.Height); - var area = tbx.DesiredSize.Width * tbx.DesiredSize.Height; - areas.Add((area, new Size(tbx.DesiredSize.Width, tbx.DesiredSize.Height))); + tbx.Measure(desiredMax); - if (tbx.DesiredSize.Height < maxSize.Height - 20) - { - if (desiredMax.Width / 2 < tbx.MinWidth) - desiredMax = new Size(desiredMax.Width * 1.5 + 1, desiredMax.Height); - else - desiredMax = new Size(desiredMax.Width / 2, desiredMax.Height); - } - } + tbx.Height = tbx.DesiredSize.Height; + tbx.Width = tbx.DesiredSize.Width; + dialog.MinHeight = vm.FormHeightFromTboxHeight((int)tbx.DesiredSize.Height); + dialog.MinWidth = vm.FormWidthFromTboxWidth((int)tbx.DesiredSize.Width); + dialog.MaxHeight = dialog.MinHeight; + dialog.MaxWidth = dialog.MinWidth; + dialog.Height = dialog.MinHeight; + dialog.Width = dialog.MinWidth; - var min = areas.Min(a => a.Item1); - var mindim = areas.First(a => a.Item1 == min); - - var desiredSize = new Size(dialog.MinWidth - tbx.MinWidth + mindim.Item2.Width, dialog.MinHeight - tbx.MinHeight + mindim.Item2.Height); - - dialog.Width = desiredSize.Width; - dialog.Height = desiredSize.Height; - tbx.Width = mindim.Item2.Width; - tbx.Height = mindim.Item2.Height; if (owner is null) { diff --git a/Source/LibationWinForms/AvaloniaUI/ViewModels/Dialogs/MessageBoxViewModel.cs b/Source/LibationWinForms/AvaloniaUI/ViewModels/Dialogs/MessageBoxViewModel.cs index 51e0fab2..6c87d164 100644 --- a/Source/LibationWinForms/AvaloniaUI/ViewModels/Dialogs/MessageBoxViewModel.cs +++ b/Source/LibationWinForms/AvaloniaUI/ViewModels/Dialogs/MessageBoxViewModel.cs @@ -63,6 +63,15 @@ namespace LibationWinForms.AvaloniaUI.ViewModels.Dialogs _ => string.Empty, }; + public int TextBlockMinWidth { get; } + + public double FormHeightFromTboxHeight(double tboxHeight) => tboxHeight + 65; + public double FormWidthFromTboxWidth(double tboxWidth) + { + int iconWidth = _icon is MessageBoxIcon.None ? 0 : 42; + return tboxWidth + 20 + iconWidth; + } + public MessageBoxViewModel() { } public MessageBoxViewModel(string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultBtn) { @@ -72,6 +81,11 @@ namespace LibationWinForms.AvaloniaUI.ViewModels.Dialogs _button = buttons; _icon = icon; _defaultButton = defaultBtn; + + int numBtns = HasButton3 ? 3 : HasButton2 ? 2 : 1; + int iconWidth = icon is MessageBoxIcon.None ? 0 : 42; + int formMinWidth = Math.Max(85 * numBtns + 10, 71 + iconWidth + 20); + TextBlockMinWidth = formMinWidth - 20 - iconWidth; } } } diff --git a/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/MessageBoxWindow.axaml b/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/MessageBoxWindow.axaml index 1e88cbc8..9a05521f 100644 --- a/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/MessageBoxWindow.axaml +++ b/Source/LibationWinForms/AvaloniaUI/Views/Dialogs/MessageBoxWindow.axaml @@ -3,39 +3,41 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:LibationWinForms.AvaloniaUI.ViewModels" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" - mc:Ignorable="d" d:DesignWidth="375" d:DesignHeight="130" MinWidth="385" MinHeight="150" + mc:Ignorable="d" d:DesignWidth="265" d:DesignHeight="110" + MinWidth="265" MinHeight="110" x:Class="LibationWinForms.AvaloniaUI.Views.Dialogs.MessageBoxWindow" - Title="{Binding Caption}" HasSystemDecorations="True" ShowInTaskbar="True"> + Title="{Binding Caption}" HasSystemDecorations="True" ShowInTaskbar="True" + Icon="/AvaloniaUI/Assets/1x1.png"> - - + + + - - - - - - - + + + + + + - + - + + - - - - - + + + + + + + diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs index 4d5a3c90..2ae8ca96 100644 --- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs +++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs @@ -8,6 +8,7 @@ using Avalonia.Threading; using LibationWinForms.AvaloniaUI.Views.ProductsGrid; using Avalonia.ReactiveUI; using LibationWinForms.AvaloniaUI.ViewModels; +using System.Threading.Tasks; namespace LibationWinForms.AvaloniaUI.Views { @@ -21,7 +22,6 @@ namespace LibationWinForms.AvaloniaUI.Views #endif this.FindAllControls(); - // eg: if one of these init'd productsGrid, then another can't reliably subscribe to it Configure_BackupCounts(); Configure_ScanAuto(); @@ -38,11 +38,21 @@ namespace LibationWinForms.AvaloniaUI.Views // misc which belongs in winforms app but doesn't have a UI element Configure_NonUI(); + async void DoDisplay(object _, EventArgs __) { - this.Load += (_, _) => productsDisplay.Display(); - LibraryCommands.LibrarySizeChanged += (_, __) => Dispatcher.UIThread.Post(() => productsDisplay.Display()); + await productsDisplay.Display(); + } + { + this.Load += DoDisplay; + LibraryCommands.LibrarySizeChanged += DoDisplay; } } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + } + public event EventHandler Load; public void OnLoad() => Load?.Invoke(this, EventArgs.Empty); @@ -114,10 +124,5 @@ namespace LibationWinForms.AvaloniaUI.Views { base.OnDataContextChanged(e); } - - private void InitializeComponent() - { - AvaloniaXamlLoader.Load(this); - } } } diff --git a/Source/LibationWinForms/AvaloniaUI/Views/ProductsGrid/ProductsDisplay2.Display.xaml.cs b/Source/LibationWinForms/AvaloniaUI/Views/ProductsGrid/ProductsDisplay2.Display.xaml.cs index b255567b..824f26b6 100644 --- a/Source/LibationWinForms/AvaloniaUI/Views/ProductsGrid/ProductsDisplay2.Display.xaml.cs +++ b/Source/LibationWinForms/AvaloniaUI/Views/ProductsGrid/ProductsDisplay2.Display.xaml.cs @@ -5,6 +5,8 @@ using System; using System.Collections; using System.Linq; using System.Reflection; +using Avalonia.Threading; +using System.Threading.Tasks; namespace LibationWinForms.AvaloniaUI.Views.ProductsGrid { @@ -12,7 +14,7 @@ namespace LibationWinForms.AvaloniaUI.Views.ProductsGrid { private void Configure_Display() { } - public void Display() + public async Task Display() { try { @@ -21,8 +23,10 @@ namespace LibationWinForms.AvaloniaUI.Views.ProductsGrid if (_viewModel is null) { _viewModel = new ProductsDisplayViewModel(dbBooks); - InitialLoaded?.Invoke(this, EventArgs.Empty); - VisibleCountChanged?.Invoke(this, bindingList.BookEntries().Count()); + await Dispatcher.UIThread.InvokeAsync(() => InitialLoaded?.Invoke(this, EventArgs.Empty)); + + int bookEntryCount = bindingList.BookEntries().Count(); + await Dispatcher.UIThread.InvokeAsync(() => VisibleCountChanged?.Invoke(this, bookEntryCount)); //Avalonia displays items in the DataConncetion from an internal copy of //the bound list, not the actual bound list. So we need to reflect to get @@ -48,9 +52,13 @@ namespace LibationWinForms.AvaloniaUI.Views.ProductsGrid { //List is already displayed. Replace all items with new ones, refilter, and re-sort string existingFilter = _viewModel?.GridEntries?.Filter; - bindingList.ReplaceList(ProductsDisplayViewModel.CreateGridEntries(dbBooks)); - bindingList.Filter = existingFilter; - ReSort(); + var newEntries = ProductsDisplayViewModel.CreateGridEntries(dbBooks); + await Dispatcher.UIThread.InvokeAsync(() => + { + bindingList.ReplaceList(newEntries); + bindingList.Filter = existingFilter; + ReSort(); + }); } } catch (Exception ex) diff --git a/Source/LibationWinForms/Form1.cs b/Source/LibationWinForms/Form1.cs index ae4628a4..209f2c48 100644 --- a/Source/LibationWinForms/Form1.cs +++ b/Source/LibationWinForms/Form1.cs @@ -65,6 +65,27 @@ namespace LibationWinForms if (this.DesignMode) return; + string message = +@"What’s funny is how the alt-right completely misses the point with Rome. + +What’s funny though is that Rome was actually quite diverse. Sure the power came from Italy but without Egypt, Spain, North Africa, and Gaul it's unlikely Rome would have been the power they are. + +Rome’s great strength was its diversity. The fact they could work with countless cultures without prejudice allowed them to maintain such a massive Empire in the first place. They would adopt foreign gods and foreign cultures with ease and it allowed them to distill the best pieces of the Mediterranean world for themselves. + +In the final years of the Western Roman Empire, there was this sudden focus on ethnic make up. Where Rome had once accepted all cultures and assimilated them they refused to do so with the new Germanic migrants like the Goths, Vandals, Burgundians, and Franks. + +The Goths in particular just wanted a seat at the table. They were willing to fight for Rome and defend the borders. The 2 greatest generals of the final decades- Stilicho and Aetius- were both half barbarian themselves. + +In previous periods of collapse, Rome would find ethnically new emperors to help turn the tide. In the third century crisis, the Illyrian Empires (Aurelian, Probus, Diocletian) rose to the challenge and restored the Empire fully. In the tumultuous collapse of the Flavian dynasty, the Spanish Emporers (Trajan, Hadrian) would lead Rome to its peak of power. + +Had Rome accepted the Goths, assimilated them and treated them fairly, and brought them into the Empire they may have survived. Great men like Stilicho would have become Emperor and maybe they could have restored the Empire. + +Instead, Rome chose to keep them at arm's length and forced them into desperation within turn led to the Goths sacking Rome. + +Put simply the Rome that accepted all peoples regardless of race was the Rome of Trajan and glory- the Rome that demanded ethnic purity was the Rome of Honorius and collapse."; + + System.Windows.Forms.MessageBox.Show("funny", "Caption", MessageBoxButtons.CancelTryContinue, MessageBoxIcon.Warning); + // I'm leaving this empty call here as a reminder that if we use this, it should probably be after DesignMode check } } diff --git a/Source/LibationWinForms/GridView/ProductsGrid.cs b/Source/LibationWinForms/GridView/ProductsGrid.cs index df6a5ec0..f7905a4e 100644 --- a/Source/LibationWinForms/GridView/ProductsGrid.cs +++ b/Source/LibationWinForms/GridView/ProductsGrid.cs @@ -357,7 +357,9 @@ namespace LibationWinForms.GridView { var column = gridEntryDataGridView.Columns .Cast() - .Single(c => c.DataPropertyName == itemName); + .SingleOrDefault(c => c.DataPropertyName == itemName); + + if (column is null) continue; column.DisplayIndex = displayIndices.GetValueOrDefault(itemName, column.Index); } diff --git a/Source/LibationWinForms/Program.cs b/Source/LibationWinForms/Program.cs index 0555bd5c..42441865 100644 --- a/Source/LibationWinForms/Program.cs +++ b/Source/LibationWinForms/Program.cs @@ -41,7 +41,7 @@ namespace LibationWinForms //Otherwise we just ignore all the Avalonia app build stuff and continue with winforms. //For debug purposes, always run AvaloniaUI. - if (true)// (startupTask.Result.useBeta) + if (true) //(startupTask.Result.useBeta) { await Task.WhenAll(appBuilderTask, classicLifetimeTask, startupTask);