Browse Source

[Avalonia] Window sizing updates

Ruben 1 year ago
parent
commit
ec041ab111

+ 21 - 0
src/PicView.Avalonia.Win32/Views/WinMainWindow.axaml.cs

@@ -5,6 +5,8 @@ using Avalonia.Input;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
+using PicView.Core.Config;
+using ReactiveUI;
 
 namespace PicView.Avalonia.Win32.Views;
 
@@ -25,6 +27,25 @@ public partial class WinMainWindow : Window
             {
                 WindowHelper.HandleWindowResize(this, size);
             });
+            
+            this.WhenAnyValue(x => x.WindowState).Subscribe(state =>
+            {
+                switch (state)
+                {
+                    case WindowState.Normal:
+                        SettingsHelper.Settings.WindowProperties.Maximized = false;
+                        SettingsHelper.Settings.WindowProperties.Fullscreen = false;
+                        break;
+                    case WindowState.Minimized:
+                        break;
+                    case WindowState.Maximized:
+                        WindowHelper.Maximize();
+                        break;
+                    case WindowState.FullScreen:
+                        WindowHelper.Fullscreen(DataContext as MainViewModel, Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime);
+                        break;
+                }
+            });
         };
         PointerPressed += (_, e) => MoveWindow(e);
         if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)

+ 1 - 1
src/PicView.Avalonia.Win32/Views/WinTitleBar.axaml

@@ -132,7 +132,7 @@
                 BorderBrush="{StaticResource MainBorderColor}"
                 BorderThickness="0,0,1,0"
                 Classes="hover"
-                Command="{CompiledBinding MaximizeCommand}"
+                Command="{CompiledBinding ToggleFullscreenCommand}"
                 DockPanel.Dock="Right"
                 Name="RestoreButton"
                 Width="35">

+ 1 - 1
src/PicView.Avalonia/Navigation/NavigationHelper.cs

@@ -403,7 +403,7 @@ public static class NavigationHelper
             // Set to closed to ensure next gallery mode changing is fired
             vm.GalleryMode = GalleryMode.Closed;
         }
-        WindowHelper.SetSize(width, height, vm);
+        WindowHelper.SetSize(width, height, 0, vm);
         if (vm.RotationAngle != 0)
         {
             vm.ImageViewer.Rotate(vm.RotationAngle);

+ 12 - 7
src/PicView.Avalonia/UI/StartUpHelper.cs

@@ -36,26 +36,31 @@ public static class StartUpHelper
             {
                 WindowHelper.Maximize();
             }
-            if (SettingsHelper.Settings.WindowProperties.AutoFit)
+            else if (SettingsHelper.Settings.WindowProperties.AutoFit)
             {
                 desktop.MainWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
                 vm.SizeToContent = SizeToContent.WidthAndHeight;
                 vm.CanResize = false;
                 vm.IsAutoFit = true;
+                if (SettingsHelper.Settings.UIProperties.ShowInterface)
+                {
+                    vm.IsTopToolbarShown = true;
+                    vm.IsBottomToolbarShown = SettingsHelper.Settings.UIProperties.ShowBottomNavBar;
+                }
             }
             else
             {
                 vm.CanResize = true;
                 vm.IsAutoFit = false;
                 WindowHelper.InitializeWindowSizeAndPosition(w);
+                if (SettingsHelper.Settings.UIProperties.ShowInterface)
+                {
+                    vm.IsTopToolbarShown = true;
+                    vm.IsBottomToolbarShown = SettingsHelper.Settings.UIProperties.ShowBottomNavBar;
+                }
             }
         }
-        
-        if (SettingsHelper.Settings.UIProperties.ShowInterface)
-        {
-            vm.IsTopToolbarShown = true;
-            vm.IsBottomToolbarShown = SettingsHelper.Settings.UIProperties.ShowBottomNavBar;
-        }
+
         w.Show();
         ScreenHelper.ScreenSize = ScreenHelper.GetScreenSize(w);
         UIHelper.SetControls(desktop);

+ 66 - 77
src/PicView.Avalonia/UI/WindowHelper.cs

@@ -1,4 +1,5 @@
 using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
@@ -241,12 +242,9 @@ public static class WindowHelper
             SettingsHelper.Settings.WindowProperties.Fullscreen = false;
             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             {
-                SetSize(vm);
-                vm.IsTopToolbarShown = SettingsHelper.Settings.UIProperties.ShowInterface;
-                vm.IsBottomToolbarShown = SettingsHelper.Settings.UIProperties.ShowBottomNavBar;
-                vm.IsGalleryShown = SettingsHelper.Settings.Gallery.IsBottomGalleryShown;
+                RestoreSize(desktop.MainWindow);
+                Restore(vm, desktop);
             }
-            
         }
         else
         {
@@ -264,23 +262,14 @@ public static class WindowHelper
             return;
         }
         var vm = desktop.MainWindow.DataContext as MainViewModel;
+        // Restore
         if (desktop.MainWindow.WindowState is WindowState.Maximized or WindowState.FullScreen)
         {
-            // Restore
-            if (SettingsHelper.Settings.WindowProperties.AutoFit)
-            {
-                vm.SizeToContent = SizeToContent.WidthAndHeight;
-                vm.CanResize = false;
-            }
-            await Dispatcher.UIThread.InvokeAsync(() => 
-                desktop.MainWindow.WindowState = WindowState.Normal);
-            SettingsHelper.Settings.WindowProperties.Maximized = false;
-            SetSize(vm);
-            InitializeWindowSizeAndPosition(desktop.MainWindow);
+            Restore(vm, desktop);
         }
+        // Maximize
         else
         {
-            // Maximize
             if (!SettingsHelper.Settings.WindowProperties.AutoFit)
             {
                 SaveSize(desktop.MainWindow);
@@ -291,6 +280,37 @@ public static class WindowHelper
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
 
+    public static void Restore(MainViewModel vm, IClassicDesktopStyleApplicationLifetime desktop)
+    {
+        if (SettingsHelper.Settings.WindowProperties.AutoFit)
+        {
+            vm.SizeToContent = SizeToContent.WidthAndHeight;
+            vm.CanResize = false;
+        }
+        else
+        {
+            vm.SizeToContent = SizeToContent.Manual;
+            vm.CanResize = true;
+        }
+        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+        {
+            vm.IsTopToolbarShown = true;
+            vm.TitlebarHeight = SizeDefaults.TitlebarHeight;
+            if (SettingsHelper.Settings.UIProperties.ShowBottomNavBar)
+            {
+                vm.IsBottomToolbarShown = true;
+                vm.BottombarHeight = SizeDefaults.BottombarHeight;
+            }
+            vm.IsInterfaceShown = true;
+        }
+        Dispatcher.UIThread.InvokeAsync(() => 
+            desktop.MainWindow.WindowState = WindowState.Normal);
+        SettingsHelper.Settings.WindowProperties.Maximized = false;
+        SettingsHelper.Settings.WindowProperties.Fullscreen = false;
+        SetSize(vm);
+        InitializeWindowSizeAndPosition(desktop.MainWindow);
+    }
+
     public static void Maximize()
     {
         if (Dispatcher.UIThread.CheckAccess())
@@ -341,6 +361,7 @@ public static class WindowHelper
         {
             vm.IsTopToolbarShown = false; // Hide interface in fullscreen. Remember to turn back when exiting fullscreen
             vm.IsBottomToolbarShown = false;
+            vm.IsInterfaceShown = false;
             vm.IsGalleryShown = SettingsHelper.Settings.Gallery.ShowBottomGalleryInHiddenUI;
             // TODO: Add Fullscreen mode for Windows (and maybe for Linux?)
             // macOS fullscreen version already works nicely
@@ -352,6 +373,8 @@ public static class WindowHelper
                 // TODO go to macOS fullscreen mode when auto fit is on
             }
         }
+        CenterWindowOnScreen();
+        vm.GalleryWidth = double.NaN;
     }
 
     public static async Task Minimize()
@@ -445,69 +468,41 @@ public static class WindowHelper
         vm.ImageHeight = size.Height;
         vm.GalleryMargin = new Thickness(0, 0, 0, size.Margin);
 
-        vm.GalleryWidth = SettingsHelper.Settings.WindowProperties.AutoFit ?
-            Math.Max(size.Width, desktopMinWidth) : double.NaN;;
+        if (SettingsHelper.Settings.WindowProperties.Fullscreen || SettingsHelper.Settings.WindowProperties.Maximized)
+        {
+            vm.GalleryWidth =  double.NaN;;
+        }
+        else
+        {
+            vm.GalleryWidth = SettingsHelper.Settings.WindowProperties.AutoFit ?
+                Math.Max(size.Width, desktopMinWidth) : double.NaN;;
+        }
     }
     
-    public static void SetSize(int width, int height, MainViewModel vm)
+    public static void SaveSize(Window window)
     {
-        if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
-        {
-            return;
-        }
-
-        var mainView = UIHelper.GetMainView;
-        var screenSize = ScreenHelper.ScreenSize;
-        double desktopMinWidth = 0, desktopMinHeight = 0, containerWidth = 0, containerHeight = 0;
         if (Dispatcher.UIThread.CheckAccess())
         {
-            desktopMinWidth = desktop.MainWindow.MinWidth;
-            desktopMinHeight = desktop.MainWindow.MinHeight;
-            containerWidth = mainView.Bounds.Width;
-            containerHeight = mainView.Bounds.Height;
+            Set();
         }
         else
         {
-            Dispatcher.UIThread.InvokeAsync(() =>
-            {
-                desktopMinWidth = desktop.MainWindow.MinWidth;
-                desktopMinHeight = desktop.MainWindow.MinHeight;
-                containerWidth = mainView.Bounds.Width;
-                containerHeight = mainView.Bounds.Height;
-            }, DispatcherPriority.Normal).Wait();
+            Dispatcher.UIThread.InvokeAsync(Set);
         }
 
-        if (double.IsNaN(containerWidth) || double.IsNaN(containerHeight) || double.IsNaN(width) || double.IsNaN(height))
+        return;
+        void Set()
         {
-            return;
+            var top = window.Position.Y;
+            var left = window.Position.X;
+            SettingsHelper.Settings.WindowProperties.Top = top;
+            SettingsHelper.Settings.WindowProperties.Left = left;
+            SettingsHelper.Settings.WindowProperties.Width = window.Width;
+            SettingsHelper.Settings.WindowProperties.Height = window.Height;
         }
-        var size = ImageSizeCalculationHelper.GetImageSize(
-            width,
-            height,
-            screenSize.WorkingAreaWidth,
-            screenSize.WorkingAreaHeight,
-            desktopMinWidth,
-            desktopMinHeight,
-            ImageSizeCalculationHelper.GetInterfaceSize(),
-            vm.RotationAngle,
-            0,
-            screenSize.Scaling,
-            vm.TitlebarHeight,
-            vm.BottombarHeight,
-            0,
-            containerWidth,
-            containerHeight);
-        
-        vm.TitleMaxWidth = size.TitleMaxWidth;
-        vm.ImageWidth = size.Width;
-        vm.ImageHeight = size.Height;
-        vm.GalleryMargin = new Thickness(0, 0, 0, 0);
-
-        vm.GalleryWidth = SettingsHelper.Settings.WindowProperties.AutoFit ?
-            Math.Max(size.Width, desktopMinWidth) : double.NaN;;
     }
     
-    public static void SaveSize(Window window)
+    public static void RestoreSize(Window window)
     {
         if (Dispatcher.UIThread.CheckAccess())
         {
@@ -521,17 +516,11 @@ public static class WindowHelper
         return;
         void Set()
         {
-            if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
-            {
-                return;
-            }
-            var monitor = ScreenHelper.GetScreen(desktop.MainWindow);
-            var top = window.Position.Y + (monitor.WorkingArea.Height - monitor.Bounds.Height);
-            var left = window.Position.X + (monitor.WorkingArea.Width - monitor.Bounds.Width);
-            SettingsHelper.Settings.WindowProperties.Top = top;
-            SettingsHelper.Settings.WindowProperties.Left = left;
-            SettingsHelper.Settings.WindowProperties.Width = window.Width;
-            SettingsHelper.Settings.WindowProperties.Height = window.Height;
+            var x = (int)SettingsHelper.Settings.WindowProperties.Left;
+            var y = (int)SettingsHelper.Settings.WindowProperties.Top;
+            window.Position = new PixelPoint(x, y);
+            window.Width = SettingsHelper.Settings.WindowProperties.Width;
+            window.Height = SettingsHelper.Settings.WindowProperties.Height;
         }
     }
 

+ 8 - 21
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -670,32 +670,19 @@ public class MainViewModel : ViewModelBase
         }
     }
     
-    private int _titlebarHeight;
-    public int TitlebarHeight
+    private double _titlebarHeight = SettingsHelper.Settings.WindowProperties.Fullscreen 
+                                     || !SettingsHelper.Settings.UIProperties.ShowInterface ? 0 : SizeDefaults.TitlebarHeight;
+    public double TitlebarHeight
     {
         set => this.RaiseAndSetIfChanged(ref _titlebarHeight, value);
-        get
-        {
-            if (IsFullscreen || !IsInterfaceShown || !IsTopToolbarShown)
-            {
-                return 0;
-            }
-
-            return SizeDefaults.TitlebarHeight;
-        }
+        get => _titlebarHeight;
     }
-    private int _bottombarHeight;
-    public int BottombarHeight         
+    private double _bottombarHeight = SettingsHelper.Settings.WindowProperties.Fullscreen 
+                                      || !SettingsHelper.Settings.UIProperties.ShowInterface ? 0 : SizeDefaults.BottombarHeight;
+    public double BottombarHeight         
     {
         set => this.RaiseAndSetIfChanged(ref _bottombarHeight, value);
-        get
-        {
-            if (IsFullscreen || !IsInterfaceShown || !IsBottomToolbarShown)
-            {
-                return 0;
-            }
-            return SizeDefaults.BottombarHeight;
-        }
+        get => _bottombarHeight;
     }
 
     private int _scaleX = 1;

+ 9 - 0
src/PicView.Avalonia/ViewModels/ViewModelBase.cs

@@ -218,6 +218,7 @@ public class ViewModelBase : ReactiveObject
         GallerySettings = TranslationHelper.Translation.GallerySettings;
         GalleryThumbnailStretch = TranslationHelper.Translation.GalleryThumbnailStretch;
         BottomGalleryThumbnailStretch = TranslationHelper.Translation.BottomGalleryThumbnailStretch;
+        RestoreDown = TranslationHelper.Translation.RestoreDown;
     }
 
     #region Strings
@@ -1397,6 +1398,14 @@ public class ViewModelBase : ReactiveObject
         set => this.RaiseAndSetIfChanged(ref _close, value);
     }
 
+    private string? _restoreDown;
+    
+    public string? RestoreDown
+    {
+        get => _restoreDown;
+        set => this.RaiseAndSetIfChanged(ref _restoreDown, value);
+    }
+
     private string? _open;
 
     public string? Open

+ 15 - 0
src/PicView.Avalonia/Views/MainView.axaml

@@ -507,6 +507,21 @@
             </MenuItem>
 
             <Separator />
+            <MenuItem
+                Command="{CompiledBinding ToggleFullscreenCommand}"
+                Header="{CompiledBinding RestoreDown,
+                                         Mode=OneWay}"
+                IsVisible="{CompiledBinding IsFullscreen,
+                                            Mode=OneWay}">
+                <MenuItem.Icon>
+                    <Path
+                        Data="{StaticResource FullscreenGeometry}"
+                        Fill="{StaticResource MainIconColor}"
+                        Height="12"
+                        Stretch="Fill"
+                        Width="12" />
+                </MenuItem.Icon>
+            </MenuItem>
             <MenuItem Command="{CompiledBinding ExitCommand}" Header="{CompiledBinding Close, Mode=OneWay}">
                 <MenuItem.Icon>
                     <Path

+ 3 - 0
src/PicView.Avalonia/Views/MainView.axaml.cs

@@ -1,10 +1,13 @@
 using System.Runtime.InteropServices;
+using Avalonia;
 using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Input;
 using Avalonia.Platform.Storage;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
+using ReactiveUI;
 
 namespace PicView.Avalonia.Views;
 

+ 4 - 2
src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs

@@ -46,10 +46,12 @@ public static class ImageSizeCalculationHelper
         double aspectRatio;
         double maxWidth, maxHeight;
         var margin = 0d;
+        
+        var fullscreen = SettingsHelper.Settings.WindowProperties.Fullscreen || SettingsHelper.Settings.WindowProperties.Maximized;
 
-        var borderSpaceHeight = SettingsHelper.Settings.WindowProperties.Fullscreen ?
+        var borderSpaceHeight = fullscreen ?
             0 : uiTopSize + uiBottomSize + galleryHeight;
-        var borderSpaceWidth = SettingsHelper.Settings.WindowProperties.Fullscreen ?
+        var borderSpaceWidth = fullscreen ?
             0 : padding;
 
         var workAreaWidth = monitorWidth * dpiScaling - borderSpaceWidth;