using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Platform; using Dinah.Core; using LibationFileManager; using System; using System.Linq; #nullable enable namespace LibationAvalonia { public static class FormSaveExtension { static readonly WindowIcon? WindowIcon; static FormSaveExtension() { WindowIcon = Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop && desktop.MainWindow?.Icon is WindowIcon icon ? icon : null; } public static void SetLibationIcon(this Window form) { form.Icon = WindowIcon; } public static void RestoreSizeAndLocation(this Window form, Configuration config) { if (Design.IsDesignMode) return; try { var savedState = config.GetNonString(defaultValue: null, form.GetType().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; } if (form.Screens.Primary is Screen primaryScreen) { // Fit to the current screen size in case the screen resolution changed since the size was last persisted if (savedState.Width > primaryScreen.WorkingArea.Width) savedState.Width = primaryScreen.WorkingArea.Width; if (savedState.Height > primaryScreen.WorkingArea.Height) savedState.Height = primaryScreen.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; } catch (Exception ex) { Serilog.Log.Logger.Error(ex, "Failed to save {form} size and location", form.GetType().Name); } } public static void SaveSizeAndLocation(this Window form, Configuration config) { if (Design.IsDesignMode) return; try { 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.SetNonString(saveState, form.GetType().Name); } catch (Exception ex) { Serilog.Log.Logger.Error(ex, "Failed to save {form} size and location", form.GetType().Name); } } private record FormSizeAndPosition { public int X; public int Y; public int Height; public int Width; public bool IsMaximized; } public static void HideMinMaxBtns(this Window form) { if (Design.IsDesignMode || !Configuration.IsWindows || form.TryGetPlatformHandle() is not IPlatformHandle handle) return; var windowStyle = GetWindowStyle(handle.Handle) .Remove(WINDOW_STYLE.WS_MINIMIZEBOX) .Remove(WINDOW_STYLE.WS_MAXIMIZEBOX); SetWindowStyle(handle.Handle, windowStyle); } const int GWL_STYLE = -16; [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "GetWindowLong")] static extern long GetWindowLong(IntPtr hWnd, int nIndex); [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetWindowLong")] static extern int SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong); static WINDOW_STYLE GetWindowStyle(IntPtr hWnd) => (WINDOW_STYLE)GetWindowLong(hWnd, GWL_STYLE); static void SetWindowStyle(IntPtr hWnd, WINDOW_STYLE style) => SetWindowLong(hWnd, GWL_STYLE, (long)style); [Flags] enum WINDOW_STYLE : long { WS_OVERLAPPED = 0x0, WS_TILED = 0x0, WS_ACTIVECAPTION = 0x1, WS_MAXIMIZEBOX = 0x10000, WS_TABSTOP = 0x10000, WS_MINIMIZEBOX = 0x20000, WS_GROUP = 0x20000, WS_THICKFRAME = 0x40000, WS_SIZEBOX = 0x40000, WS_SYSMENU = 0x80000, WS_HSCROLL = 0x100000, WS_VSCROLL = 0x200000, WS_DLGFRAME = 0x400000, WS_BORDER = 0x800000, WS_CAPTION = 0xc00000, WS_OVERLAPPEDWINDOW = 0xcf0000, WS_TILEDWINDOW = 0xcf0000, WS_MAXIMIZE = 0x1000000, WS_CLIPCHILDREN = 0x2000000, WS_CLIPSIBLINGS = 0x4000000, WS_DISABLED = 0x8000000, WS_VISIBLE = 0x10000000, WS_ICONIC = 0x20000000, WS_MINIMIZE = 0x20000000, WS_CHILD = 0x40000000, WS_CHILDWINDOW = 0x40000000, WS_POPUP = 0x80000000, WS_POPUPWINDOW = 0x80880000 } } }