فهرست منبع

[Avalonia] Set defaults, drag and drop updates, image iteration updates

Ruben 1 سال پیش
والد
کامیت
c5d325d5a3

+ 19 - 6
src/PicView.Avalonia/Helpers/StartUpHelper.cs

@@ -1,7 +1,6 @@
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.Primitives;
-using Avalonia.Media;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.Navigation;
@@ -21,6 +20,10 @@ public static class StartUpHelper
         
         if (!settingsExists)
         {
+            // Fixes incorrect window
+            w.Height = w.MinHeight;
+            w.Width = w.MinWidth;
+            
             WindowHelper.CenterWindowOnScreen();
             vm.CanResize = true;
             vm.IsAutoFit = false;
@@ -42,9 +45,9 @@ public static class StartUpHelper
             }
         }
         w.Show();
-        _ = Task.Run(vm.UpdateLanguage);
-
         vm.SetLoadingTitle();
+        vm.IsLoading = true;
+        _ = Task.Run(vm.UpdateLanguage);
 
         vm.GetFlipped = vm.Flip;
 
@@ -83,16 +86,26 @@ public static class StartUpHelper
         else
         {
             vm.CurrentView = new StartUpMenu();
+            vm.IsLoading = false;
+        }
+
+        const int defaultBottomGalleryHeight = 53;
+        const int defaultFullGalleryHeight = 73;
+
+        if (!settingsExists)
+        {
+            vm.GetBottomGalleryItemHeight = defaultBottomGalleryHeight;
+            vm.GetExpandedGalleryItemHeight = defaultFullGalleryHeight;
         }
         
         // Set default gallery sizes if they are out of range or upgrading from an old version
         if (vm.GetBottomGalleryItemHeight is < 36 or > 110)
         {
-            vm.GetBottomGalleryItemHeight = 47;
+            vm.GetBottomGalleryItemHeight = defaultBottomGalleryHeight;
         }
-        if (vm.GetExpandedGalleryItemHeight is  < 25 or 110)
+        if (vm.GetExpandedGalleryItemHeight is < 25 or 110)
         {
-            vm.GetExpandedGalleryItemHeight = 47;
+            vm.GetExpandedGalleryItemHeight = defaultFullGalleryHeight;
         }
 
         if (!settingsExists)

+ 27 - 12
src/PicView.Avalonia/Navigation/ImageIterator.cs

@@ -6,6 +6,8 @@ using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.Navigation;
 using System.Diagnostics;
+using Avalonia.Media.Imaging;
+using ImageMagick;
 using PicView.Avalonia.Gallery;
 using Timer = System.Timers.Timer;
 
@@ -309,22 +311,25 @@ public class ImageIterator
                     if (preLoadValue.IsLoading)
                     {
                         vm.SetLoadingTitle();
+                        vm.IsLoading = true;
                         await NavigationHelper.LoadingPreview(index, vm);
                         if (Index != index)
                         {
+                            vm.IsLoading = false;
                             await Preload();
                             return;
                         }
-                        vm.IsLoading = true;
-                        while (preLoadValue.IsLoading)
+                        
+                        preLoadValue.ImageLoaded += async (_, p) =>
                         {
-                            await Task.Delay(10);
-                            if (Index != index)
+                            if (p.Index != index)
                             {
                                 return;
                             }
-                        }
-                        await UpdateSourceTask(vm, preLoadValue);
+
+                            preLoadValue = p.PreLoadValue;
+                            await UpdateSourceTask(vm, preLoadValue);
+                        };
                         return;
                     }
                 }
@@ -408,7 +413,15 @@ public class ImageIterator
     public async Task LoadPicFromFile(FileInfo fileInfo, MainViewModel vm)
     {
         vm.SetLoadingTitle();
-
+        using var image = new MagickImage();
+        image.Ping(fileInfo);
+        var thumb = image.GetExifProfile()?.CreateThumbnail();
+        if (thumb is not null)
+        {
+            var byteArray = await Task.FromResult(thumb.ToByteArray());
+            var stream = new MemoryStream(byteArray);
+            vm.ImageViewer.SetImage(WriteableBitmap.Decode(stream), ImageType.Bitmap);
+        }
         var imageModel = await ImageHelper.GetImageModelAsync(fileInfo).ConfigureAwait(false);
         WindowHelper.SetSize(imageModel.PixelWidth, imageModel.PixelHeight, imageModel.Rotation, vm);
         vm.ImageViewer.SetImage(imageModel.Image, imageModel.ImageType);
@@ -470,15 +483,17 @@ public class ImageIterator
                 vm.SetLoadingTitle();
                 vm.IsLoading = true;
                 await NavigationHelper.LoadingPreview(index, vm);
-                while (preLoadValue.IsLoading)
+                preLoadValue.ImageLoaded += async (_, p) =>
                 {
-                    await Task.Delay(10);
-                    if (Index != index)
+                    if (p.Index != index)
                     {
                         return;
                     }
-                }
-                await UpdateSourceTask(vm, preLoadValue);
+
+                    preLoadValue = p.PreLoadValue;
+                    await UpdateSourceTask(vm, preLoadValue);
+                };
+                return;
             }
         }
         else

+ 19 - 0
src/PicView.Avalonia/Navigation/PreloaderService.cs

@@ -17,6 +17,24 @@ public class PreLoader
         public ImageModel? ImageModel { get; set; } = imageModel;
 
         public bool IsLoading = true;
+        
+        #region Event
+
+        public event ImageLoadedEventHandler? ImageLoaded;
+        public delegate void ImageLoadedEventHandler(object sender, ImageLoadedEventArgs e);
+
+        internal void OnImageLoaded(int index, PreLoadValue preLoadValue)
+        {
+            ImageLoaded?.Invoke(this, new ImageLoadedEventArgs(index, preLoadValue));
+        }
+
+        public class ImageLoadedEventArgs(int index, PreLoadValue preLoadValue) : EventArgs
+        {
+            public int Index { get; } = index;
+            public PreLoadValue PreLoadValue { get; } = preLoadValue;
+        }
+
+        #endregion
     }
 
     private readonly ConcurrentDictionary<int, PreLoadValue> _preLoadList = new();
@@ -78,6 +96,7 @@ public class PreLoader
                 if (ShowAddRemove)
                     Trace.WriteLine($"{imageModel?.FileInfo?.Name} added at {index}");
 #endif
+                preLoadValue.OnImageLoaded(index, preLoadValue); 
                 return true;
             }
         }

+ 0 - 6
src/PicView.Avalonia/Views/ImageViewer.axaml

@@ -1,5 +1,4 @@
 <UserControl
-    DragDrop.AllowDrop="True"
     PointerPressed="InputElement_OnPointerPressed"
     mc:Ignorable="d"
     x:Class="PicView.Avalonia.Views.ImageViewer"
@@ -8,7 +7,6 @@
     xmlns:customControls="clr-namespace:PicView.Avalonia.CustomControls"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    xmlns:uc="clr-namespace:PicView.Avalonia.Views.UC"
     xmlns:vm="clr-namespace:PicView.Avalonia.ViewModels"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
     <Design.DataContext>
@@ -36,9 +34,5 @@
                 </Border>
             </customControls:AutoScrollViewer>
         </LayoutTransformControl>
-        <uc:SpinWaiter
-            HorizontalAlignment="Center"
-            IsVisible="{CompiledBinding IsLoading}"
-            VerticalAlignment="Center" />
     </Panel>
 </UserControl>

+ 1 - 26
src/PicView.Avalonia/Views/ImageViewer.axaml.cs

@@ -37,9 +37,6 @@ public partial class ImageViewer : UserControl
     {
         InitializeComponent();
         AddHandler(PointerWheelChangedEvent, PreviewOnPointerWheelChanged, RoutingStrategies.Tunnel);
-        // TODO add visual feedback for drag and drop
-        //AddHandler(DragDrop.DragOverEvent, DragOver);
-        AddHandler(DragDrop.DropEvent, Drop);
         AddHandler(Gestures.PointerTouchPadGestureMagnifyEvent, TouchMagnifyEvent, RoutingStrategies.Bubble);
 
         Loaded += delegate
@@ -110,29 +107,7 @@ public partial class ImageViewer : UserControl
         e.Handled = true;
         await Main_OnPointerWheelChanged(e);
     }
-
-    private async Task Drop(object? sender, DragEventArgs e)
-    {
-        if (DataContext is not MainViewModel vm)
-            return;
-
-        var data = e.Data.GetFiles();
-        if (data == null)
-        {
-            // TODO Handle URL and folder drops
-            return;
-        }
-
-        var storageItems = data as IStorageItem[] ?? data.ToArray();
-        var firstFile = storageItems.FirstOrDefault();
-        var path = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? firstFile.Path.AbsolutePath : firstFile.Path.LocalPath;
-        await NavigationHelper.LoadPicFromString(path, vm).ConfigureAwait(false);
-        foreach (var file in storageItems.Skip(1))
-        {
-            // TODO Open each file in a new window if the setting to open in the same window is false
-        }
-    }
-
+    
     private async Task Main_OnPointerWheelChanged(PointerWheelEventArgs e)
     {
         if (DataContext is not MainViewModel mainViewModel)

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

@@ -1,4 +1,5 @@
 <UserControl
+    DragDrop.AllowDrop="True"
     Focusable="True"
     d:DesignHeight="450"
     d:DesignWidth="800"
@@ -9,6 +10,7 @@
     xmlns:converters="clr-namespace:PicView.Avalonia.Converters"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:uc="clr-namespace:PicView.Avalonia.Views.UC"
     xmlns:views="clr-namespace:PicView.Avalonia.Views"
     xmlns:vm="clr-namespace:PicView.Avalonia.ViewModels"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
@@ -464,6 +466,11 @@
         </ContextMenu>
     </UserControl.ContextMenu>
     <Panel x:Name="MainGrid">
+        <uc:SpinWaiter
+            HorizontalAlignment="Center"
+            IsVisible="{CompiledBinding IsLoading}"
+            VerticalAlignment="Center"
+            ZIndex="3" />
         <ContentControl Content="{CompiledBinding CurrentView}" Margin="{CompiledBinding ImageMargin}" />
         <views:GalleryAnimationControlView
             GalleryMode="{CompiledBinding GalleryMode}"

+ 31 - 1
src/PicView.Avalonia/Views/MainView.axaml.cs

@@ -1,4 +1,9 @@
-using Avalonia.Controls;
+using System.Runtime.InteropServices;
+using Avalonia.Controls;
+using Avalonia.Input;
+using Avalonia.Platform.Storage;
+using PicView.Avalonia.Navigation;
+using PicView.Avalonia.ViewModels;
 
 namespace PicView.Avalonia.Views;
 
@@ -7,5 +12,30 @@ public partial class MainView : UserControl
     public MainView()
     {
         InitializeComponent();
+        // TODO add visual feedback for drag and drop
+        //AddHandler(DragDrop.DragOverEvent, DragOver);
+        AddHandler(DragDrop.DropEvent, Drop);
+    }
+    
+    private async Task Drop(object? sender, DragEventArgs e)
+    {
+        if (DataContext is not MainViewModel vm)
+            return;
+
+        var data = e.Data.GetFiles();
+        if (data == null)
+        {
+            // TODO Handle URL and folder drops
+            return;
+        }
+
+        var storageItems = data as IStorageItem[] ?? data.ToArray();
+        var firstFile = storageItems.FirstOrDefault();
+        var path = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? firstFile.Path.AbsolutePath : firstFile.Path.LocalPath;
+        await NavigationHelper.LoadPicFromString(path, vm).ConfigureAwait(false);
+        foreach (var file in storageItems.Skip(1))
+        {
+            // TODO Open each file in a new window if the setting to open in the same window is false
+        }
     }
 }