Browse Source

[Avalonia] Window improvements, mouse wheel events, startup, refactor

Ruben 1 year ago
parent
commit
60c6b3dabb

+ 0 - 1
src/PicView.Avalonia/CustomControls/EditableTitlebar.cs

@@ -11,7 +11,6 @@ using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.FileHandling;
 using PicView.Core.ImageDecoding;
-using PicView.Core.Localization;
 
 namespace PicView.Avalonia.CustomControls;
 

+ 0 - 1
src/PicView.Avalonia/CustomControls/GalleryAnimationControl.cs

@@ -1,5 +1,4 @@
 using System.Reactive.Linq;
-using System.Reflection.Metadata.Ecma335;
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Input;

+ 7 - 5
src/PicView.Avalonia/ImageHandling/ImageHelper.cs

@@ -1,15 +1,10 @@
 using Avalonia.Controls;
 using Avalonia.Media.Imaging;
 using Avalonia.Svg.Skia;
-using Avalonia.Threading;
 using ImageMagick;
-using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Navigation;
-using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
-using PicView.Core.Gallery;
 using PicView.Core.ImageDecoding;
-using PicView.Core.Navigation;
 
 namespace PicView.Avalonia.ImageHandling;
 
@@ -216,4 +211,11 @@ public static class ImageHelper
             _ => imageControl.Source
         };
     }
+
+    public static EXIFHelper.EXIFOrientation GetExifOrientation(MainViewModel vm)
+    {
+        var magickImage = new MagickImage();
+        magickImage.Ping(vm.FileInfo);
+        return EXIFHelper.GetImageOrientation(magickImage);
+    }
 }

+ 30 - 20
src/PicView.Avalonia/Navigation/ExifHandling.cs

@@ -20,6 +20,12 @@ public static class ExifHandling
             switch (imageModel.EXIFOrientation.Value)
             {
                 default:
+                    vm.ScaleX = 1;
+                    vm.RotationAngle = 0;
+                    vm.GetOrientation =  string.Empty;
+                    break;
+                
+                case EXIFHelper.EXIFOrientation.Normal:
                     vm.ScaleX = 1;
                     vm.RotationAngle = 0;
                     vm.GetOrientation = TranslationHelper.Translation.Normal;
@@ -125,29 +131,33 @@ public static class ExifHandling
                 vm.GetBitDepth = (magick.Depth * 3).ToString();
             }
 
-            if (vm.DpiX == 0)
-            {
-                vm.GetPrintSizeCm = vm.GetPrintSizeInch = vm.GetSizeMp = vm.GetResolution = string.Empty;
-            }
-            else
+            if (vm is { PixelWidth: > 0, PixelHeight: > 0 })
             {
-                var inchesWidth = vm.PixelWidth / vm.DpiX;
-                var inchesHeight = vm.PixelHeight / vm.DpiY;
-                vm.GetPrintSizeInch =
-                    $"{inchesWidth.ToString("0.##", CultureInfo.CurrentCulture)} x {inchesHeight.ToString("0.##", CultureInfo.CurrentCulture)} {TranslationHelper.GetTranslation("Inches")}";
-
-                var cmWidth = vm.PixelWidth / vm.DpiX * 2.54;
-                var cmHeight = vm.PixelHeight / vm.DpiY * 2.54;
-                vm.GetPrintSizeCm =
-                    $"{cmWidth.ToString("0.##", CultureInfo.CurrentCulture)} x {cmHeight.ToString("0.##", CultureInfo.CurrentCulture)} {TranslationHelper.GetTranslation("Centimeters")}";
-                vm.GetSizeMp =
-                    $"{((float)vm.PixelHeight * vm.PixelWidth / 1000000).ToString("0.##", CultureInfo.CurrentCulture)} {TranslationHelper.Translation.MegaPixels}";
-
-                vm.GetResolution = $"{vm.DpiX} x {vm.DpiY} {TranslationHelper.GetTranslation("Dpi")}";
+                if (vm.DpiX == 0)
+                {
+                    vm.GetPrintSizeCm = vm.GetPrintSizeInch = vm.GetSizeMp = vm.GetResolution = string.Empty;
+                }
+                else
+                {
+                    var inchesWidth = vm.PixelWidth / vm.DpiX;
+                    var inchesHeight = vm.PixelHeight / vm.DpiY;
+                    vm.GetPrintSizeInch =
+                        $"{inchesWidth.ToString("0.##", CultureInfo.CurrentCulture)} x {inchesHeight.ToString("0.##", CultureInfo.CurrentCulture)} {TranslationHelper.GetTranslation("Inches")}";
+
+                    var cmWidth = vm.PixelWidth / vm.DpiX * 2.54;
+                    var cmHeight = vm.PixelHeight / vm.DpiY * 2.54;
+                    vm.GetPrintSizeCm =
+                        $"{cmWidth.ToString("0.##", CultureInfo.CurrentCulture)} x {cmHeight.ToString("0.##", CultureInfo.CurrentCulture)} {TranslationHelper.GetTranslation("Centimeters")}";
+                    vm.GetSizeMp =
+                        $"{((float)vm.PixelHeight * vm.PixelWidth / 1000000).ToString("0.##", CultureInfo.CurrentCulture)} {TranslationHelper.Translation.MegaPixels}";
+
+                    vm.GetResolution = $"{vm.DpiX} x {vm.DpiY} {TranslationHelper.GetTranslation("Dpi")}";
+                }
             }
 
-            var firstRatio = vm.PixelWidth / TitleHelper.GCD(vm.PixelWidth, vm.PixelHeight);
-            var secondRatio = vm.PixelHeight / TitleHelper.GCD(vm.PixelWidth, vm.PixelHeight);
+            var gcd = TitleHelper.GCD(vm.PixelWidth, vm.PixelHeight);
+            var firstRatio = vm.PixelWidth / gcd;
+            var secondRatio = vm.PixelHeight / gcd;
 
             if (firstRatio == secondRatio)
             {

+ 35 - 7
src/PicView.Avalonia/Navigation/QuickLoad.cs

@@ -1,10 +1,10 @@
-using PicView.Avalonia.Gallery;
+using Avalonia.Threading;
+using PicView.Avalonia.Gallery;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.Config;
 using PicView.Core.FileHandling;
-using PicView.Core.ImageDecoding;
 
 namespace PicView.Avalonia.Navigation;
 
@@ -44,19 +44,47 @@ public static class QuickLoad
             }
             else
             {
+                vm.FileInfo ??= fileInfo;
                 var imageModel = await ImageHelper.GetImageModelAsync(fileInfo).ConfigureAwait(false);
                 vm.ImageSource = imageModel.Image;
                 vm.ImageType = imageModel.ImageType;
                 WindowHelper.SetSize(imageModel.PixelWidth, imageModel.PixelHeight, imageModel.Rotation, vm);
+                vm.IsLoading = false;
+                imageModel.EXIFOrientation = ImageHelper.GetExifOrientation(vm);
+                ExifHandling.SetImageModel(imageModel, vm);
+                var changed = false; // Need to recalculate size if changed
+                if (vm.ScaleX != 1)
+                {
+                    await Dispatcher.UIThread.InvokeAsync(() =>
+                    {
+                        vm.ImageViewer.SetScaleX();
+                    });
+                    changed = true;
+                }
                 if (vm.RotationAngle != 0)
                 {
-                    vm.ImageViewer.Rotate(vm.RotationAngle);
+                    await Dispatcher.UIThread.InvokeAsync(() =>
+                    {
+                        vm.ImageViewer.Rotate(vm.RotationAngle);
+                    });
+                    changed = true;
                 }
-                vm.IsLoading = false;
+                if (changed)
+                {
+                    WindowHelper.SetSize(imageModel.PixelWidth, imageModel.PixelHeight, imageModel.Rotation, vm);
+                }
+                
+                ExifHandling.UpdateExifValues(imageModel, vm);
                 vm.ImageIterator = new ImageIterator(fileInfo, vm);
-                await vm.ImageIterator.AddAsync(vm.ImageIterator.Index, imageModel).ConfigureAwait(false);
-                var preloadValue = vm.ImageIterator.PreLoader.Get(vm.ImageIterator.Index, vm.ImageIterator.Pics);
-                vm.ImageIterator.UpdateSource(preloadValue);
+                
+                SetTitleHelper.SetTitle(vm, imageModel);
+                vm.GetIndex = vm.ImageIterator.Index + 1;
+                if (SettingsHelper.Settings.WindowProperties.KeepCentered)
+                {
+                    WindowHelper.CenterWindowOnScreen(false);
+                }
+                
+                _ = vm.ImageIterator.AddAsync(vm.ImageIterator.Index, imageModel);
                 _ = vm.ImageIterator.Preload();
             }
 

+ 18 - 9
src/PicView.Avalonia/UI/WindowHelper.cs

@@ -266,8 +266,12 @@ public static class WindowHelper
         var vm = desktop.MainWindow.DataContext as MainViewModel;
         if (desktop.MainWindow.WindowState is WindowState.Maximized or WindowState.FullScreen)
         {
-            vm.SizeToContent = SettingsHelper.Settings.WindowProperties.AutoFit ?
-                SizeToContent.WidthAndHeight : SizeToContent.Manual;
+            // 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;
@@ -276,12 +280,11 @@ public static class WindowHelper
         }
         else
         {
-            if (SettingsHelper.Settings.WindowProperties.AutoFit)
+            // Maximize
+            if (!SettingsHelper.Settings.WindowProperties.AutoFit)
             {
-                Fullscreen(vm, desktop);
-                return;
+                SaveSize(desktop.MainWindow);
             }
-            SaveSize(desktop.MainWindow);
             Maximize();
         }
         
@@ -306,8 +309,14 @@ public static class WindowHelper
             {
                 return;
             }
+            var vm = desktop.MainWindow.DataContext as MainViewModel;
+            if (SettingsHelper.Settings.WindowProperties.AutoFit)
+            {
+                vm.SizeToContent = SizeToContent.Manual;
+                vm.CanResize = true;
+            }
 
-            desktop.MainWindow.WindowState = WindowState.FullScreen;
+            desktop.MainWindow.WindowState = WindowState.Maximized;
             SetSize(desktop.MainWindow.DataContext as MainViewModel);
             SettingsHelper.Settings.WindowProperties.Maximized = true;
         }
@@ -376,7 +385,7 @@ public static class WindowHelper
             return;
         }
         var preloadValue = vm.ImageIterator?.PreLoader.Get(vm.ImageIterator.Index, vm.ImageIterator.Pics);
-        SetSize(preloadValue?.ImageModel?.PixelWidth ?? (int)vm.ImageWidth, preloadValue?.ImageModel?.PixelHeight ?? (int)vm.ImageHeight, vm.RotationAngle, vm);
+        SetSize(preloadValue?.ImageModel?.PixelWidth ?? vm.ImageWidth, preloadValue?.ImageModel?.PixelHeight ?? vm.ImageHeight, vm.RotationAngle, vm);
     }
 
     public static void SetSize(double width, double height, double rotation, MainViewModel vm)
@@ -422,7 +431,7 @@ public static class WindowHelper
             desktopMinHeight,
             ImageSizeCalculationHelper.GetInterfaceSize(),
             rotation,
-            0,
+            padding: SettingsHelper.Settings.ImageScaling.StretchImage ? 2 : 45,
             screenSize.Scaling,
             vm.TitlebarHeight,
             vm.BottombarHeight,

+ 14 - 2
src/PicView.Avalonia/Views/ImageViewer.axaml.cs

@@ -61,7 +61,7 @@ public partial class ImageViewer : UserControl
         ZoomTo(e.GetPosition(this), e.Delta.X > 0);
     }
 
-    private async Task PreviewOnPointerWheelChanged(object? sender, PointerWheelEventArgs e)
+    public async Task PreviewOnPointerWheelChanged(object? sender, PointerWheelEventArgs e)
     {
         e.Handled = true;
         await Main_OnPointerWheelChanged(e);
@@ -472,7 +472,7 @@ public partial class ImageViewer : UserControl
         }
 
         WindowHelper.SetSize(vm);
-        MainImage.InvalidateVisual();
+        //MainImage.InvalidateVisual();
     }
     
     public void Rotate(double angle)
@@ -526,6 +526,18 @@ public partial class ImageViewer : UserControl
         }
         MainImage.InvalidateVisual();
     }
+    
+    public void SetScaleX()
+    {
+        if (DataContext is not MainViewModel vm)
+            return;
+        if (MainImage.Source is null)
+        {
+            return;
+        }
+        var flipTransform = new ScaleTransform(vm.ScaleX, 1);
+        MainImage.RenderTransform = flipTransform;
+    }
 
     #endregion Rotation and Flip
 

+ 5 - 0
src/PicView.Avalonia/Views/UC/Buttons/AltClose.axaml.cs

@@ -10,7 +10,12 @@ public partial class AltClose : UserControl
         InitializeComponent();
         Loaded += delegate
         {
+            if (DataContext is not MainViewModel vm)
+            {
+                return;
+            }            
             HideInterfaceLogic.AddHoverButtonEvents(this, XButton, DataContext as MainViewModel);
+            PointerWheelChanged += async (_, e) => await vm.ImageViewer.PreviewOnPointerWheelChanged(this, e);
         };
     }
 }

+ 6 - 1
src/PicView.Avalonia/Views/UC/Buttons/ClickArrowLeft.axaml.cs

@@ -10,7 +10,12 @@ public partial class ClickArrowLeft : UserControl
         InitializeComponent();
         Loaded += delegate
         {
-            HideInterfaceLogic.AddHoverButtonEvents(this, PolyButton, DataContext as MainViewModel);
+            if (DataContext is not MainViewModel vm)
+            {
+                return;
+            }
+            HideInterfaceLogic.AddHoverButtonEvents(this, PolyButton, vm);
+            PointerWheelChanged += async (_, e) => await vm.ImageViewer.PreviewOnPointerWheelChanged(this, e);
         };
     }
 }

+ 6 - 1
src/PicView.Avalonia/Views/UC/Buttons/ClickArrowRight.axaml.cs

@@ -10,7 +10,12 @@ public partial class ClickArrowRight : UserControl
         InitializeComponent();
         Loaded += delegate
         {
-            HideInterfaceLogic.AddHoverButtonEvents(this, PolyButton, DataContext as MainViewModel);
+            if (DataContext is not MainViewModel vm)
+            {
+                return;
+            }
+            HideInterfaceLogic.AddHoverButtonEvents(this, PolyButton, vm);
+            PointerWheelChanged += async (_, e) => await vm.ImageViewer.PreviewOnPointerWheelChanged(this, e);
         };
     }
 }

+ 5 - 0
src/PicView.Avalonia/Views/UC/Buttons/GalleryShortcut.axaml.cs

@@ -11,7 +11,12 @@ public partial class GalleryShortcut : UserControl
         InitializeComponent();
         Loaded += delegate
         {
+            if (DataContext is not MainViewModel vm)
+            {
+                return;
+            }
             HideInterfaceLogic.AddHoverButtonEvents(this, InnerButton, DataContext as MainViewModel);
+            PointerWheelChanged += async (_, e) => await vm.ImageViewer.PreviewOnPointerWheelChanged(this, e);
         };
     }
 }