From 2b6d1201b6deea9084a7ae48424170d4d69451f3 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Thu, 14 Jul 2022 15:41:30 -0600 Subject: [PATCH] Add save and restore form size --- .../LibationWinForms/AvaloniaUI/App.axaml.cs | 2 + .../AvaloniaUI/FormSaveExtension2.cs | 94 +++++++++++++++++++ .../Views/MainWindow/MainWindow.axaml | 3 +- .../Views/MainWindow/MainWindow.axaml.cs | 4 +- 4 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 Source/LibationWinForms/AvaloniaUI/FormSaveExtension2.cs diff --git a/Source/LibationWinForms/AvaloniaUI/App.axaml.cs b/Source/LibationWinForms/AvaloniaUI/App.axaml.cs index dadd659c..1f0642bc 100644 --- a/Source/LibationWinForms/AvaloniaUI/App.axaml.cs +++ b/Source/LibationWinForms/AvaloniaUI/App.axaml.cs @@ -2,6 +2,7 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Media; +using LibationFileManager; using LibationWinForms.AvaloniaUI.Views; namespace LibationWinForms.AvaloniaUI @@ -27,6 +28,7 @@ namespace LibationWinForms.AvaloniaUI { var mainWindow = new MainWindow(); desktop.MainWindow = mainWindow; + mainWindow.RestoreSizeAndLocation(Configuration.Instance); mainWindow.OnLoad(); } diff --git a/Source/LibationWinForms/AvaloniaUI/FormSaveExtension2.cs b/Source/LibationWinForms/AvaloniaUI/FormSaveExtension2.cs new file mode 100644 index 00000000..0f3bfd8d --- /dev/null +++ b/Source/LibationWinForms/AvaloniaUI/FormSaveExtension2.cs @@ -0,0 +1,94 @@ +using System.Linq; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; +using LibationFileManager; + +namespace LibationWinForms.AvaloniaUI +{ + public static class FormSaveExtension2 + { + static readonly WindowIcon WindowIcon; + static FormSaveExtension2() + { + if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + WindowIcon = desktop.MainWindow.Icon; + else + WindowIcon = null; + } + + public static void SetLibationIcon(this Window form) + { + form.Icon = WindowIcon; + } + + public static void RestoreSizeAndLocation(this Window form, Configuration config) + { + FormSizeAndPosition savedState = config.GetNonString(form.Name); + + if (savedState is null) + return; + + // too small -- something must have gone wrong. use defaults + if (savedState.Width < form.MinWidth || savedState.Height < form.MinHeight) + { + savedState.Width = (int)form.Width; + savedState.Height = (int)form.Height; + } + + // Fit to the current screen size in case the screen resolution changed since the size was last persisted + if (savedState.Width > form.Screens.Primary.WorkingArea.Width) + savedState.Width = form.Screens.Primary.WorkingArea.Width; + if (savedState.Height > form.Screens.Primary.WorkingArea.Height) + savedState.Height = form.Screens.Primary.WorkingArea.Height; + + var rect = new PixelRect(savedState.X, savedState.Y, savedState.Width, savedState.Height); + + form.Width = savedState.Width; + form.Height = savedState.Height; + + // is proposed rect on a screen? + if (form.Screens.All.Any(screen => screen.WorkingArea.Contains(rect))) + { + form.WindowStartupLocation = WindowStartupLocation.Manual; + form.Position = new PixelPoint(savedState.X, savedState.Y); + } + else + { + form.WindowStartupLocation = WindowStartupLocation.CenterScreen; + } + + // FINAL: for Maximized: start normal state, set size and location, THEN set max state + form.WindowState = savedState.IsMaximized ? WindowState.Maximized : WindowState.Normal; + } + public static void SaveSizeAndLocation(this Window form, Configuration config) + { + var saveState = new FormSizeAndPosition(); + + saveState.IsMaximized = form.WindowState == WindowState.Maximized; + + // restore normal state to get real window size. + if (form.WindowState != WindowState.Normal) + { + form.WindowState = WindowState.Normal; + } + + saveState.X = form.Position.X; + saveState.Y = form.Position.Y; + + saveState.Width = (int)form.Bounds.Size.Width; + saveState.Height = (int)form.Bounds.Size.Height; + + config.SetObject(form.Name, saveState); + } + + class FormSizeAndPosition + { + public int X; + public int Y; + public int Height; + public int Width; + public bool IsMaximized; + } + } +} diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml index 5964e3cc..864fc60f 100644 --- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml +++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml @@ -7,9 +7,10 @@ xmlns:views="clr-namespace:LibationWinForms.AvaloniaUI.Views" xmlns:prgid="clr-namespace:LibationWinForms.AvaloniaUI.Views.ProductsGrid" xmlns:controls="clr-namespace:LibationWinForms.AvaloniaUI.Controls" - mc:Ignorable="d" d:DesignWidth="2000" d:DesignHeight="700" + mc:Ignorable="d" d:DesignWidth="1850" d:DesignHeight="700" x:Class="LibationWinForms.AvaloniaUI.Views.MainWindow" Title="MainWindow" + Name="Form1" Icon="/AvaloniaUI/Assets/glass-with-glow_16.png"> diff --git a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs index 2ae8ca96..af644b21 100644 --- a/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs +++ b/Source/LibationWinForms/AvaloniaUI/Views/MainWindow/MainWindow.axaml.cs @@ -4,11 +4,10 @@ using Avalonia.Controls; using Avalonia.Markup.Xaml; using LibationWinForms.AvaloniaUI.Controls; using System; -using Avalonia.Threading; using LibationWinForms.AvaloniaUI.Views.ProductsGrid; using Avalonia.ReactiveUI; using LibationWinForms.AvaloniaUI.ViewModels; -using System.Threading.Tasks; +using LibationFileManager; namespace LibationWinForms.AvaloniaUI.Views { @@ -45,6 +44,7 @@ namespace LibationWinForms.AvaloniaUI.Views { this.Load += DoDisplay; LibraryCommands.LibrarySizeChanged += DoDisplay; + this.Closing += (_,_) => this.SaveSizeAndLocation(Configuration.Instance); } }