浏览代码

Move access to ImageIterator to NavigationManager. Refactor, rename, misc.

Ruben 8 月之前
父节点
当前提交
e76f266182

+ 0 - 1
src/PicView.Avalonia/Clipboard/ClipboardHelper.cs

@@ -65,7 +65,6 @@ public static class ClipboardHelper
         {
         {
             return;
             return;
         }
         }
-        await vm.ImageIterator.ClearAsync();
         await NavigationManager.LoadPicFromFile(duplicatedPath, vm);
         await NavigationManager.LoadPicFromFile(duplicatedPath, vm);
     }
     }
     
     

+ 6 - 7
src/PicView.Avalonia/CustomControls/PicBox.cs

@@ -12,9 +12,9 @@ using Avalonia.Svg.Skia;
 using ImageMagick;
 using ImageMagick;
 using PicView.Avalonia.AnimatedImage;
 using PicView.Avalonia.AnimatedImage;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.ImageHandling;
+using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
-using PicView.Core.Navigation;
 using ReactiveUI;
 using ReactiveUI;
 using Vector = Avalonia.Vector;
 using Vector = Avalonia.Vector;
 
 
@@ -234,7 +234,7 @@ public class PicBox : Control
                 return;
                 return;
             }
             }
 
 
-            var preloadValue = vm.ImageIterator?.GetCurrentPreLoadValue();
+            var preloadValue = NavigationManager.GetCurrentPreLoadValue();
             if (preloadValue?.ImageModel != null)
             if (preloadValue?.ImageModel != null)
             {
             {
                 sourceSize = new Size(preloadValue.ImageModel.PixelWidth, preloadValue.ImageModel.PixelHeight);
                 sourceSize = new Size(preloadValue.ImageModel.PixelWidth, preloadValue.ImageModel.PixelHeight);
@@ -265,18 +265,17 @@ public class PicBox : Control
             }
             }
             if (isSideBySide)
             if (isSideBySide)
             {
             {
-                var nextPreloadValue = vm.ImageIterator?.GetNextPreLoadValue();
+                var nextPreloadValue = NavigationManager.GetNextPreLoadValue();
                 if (nextPreloadValue?.ImageModel != null)
                 if (nextPreloadValue?.ImageModel != null)
                 {
                 {
                     secondarySourceSize = new Size(nextPreloadValue.ImageModel.PixelWidth, nextPreloadValue.ImageModel.PixelHeight);
                     secondarySourceSize = new Size(nextPreloadValue.ImageModel.PixelWidth, nextPreloadValue.ImageModel.PixelHeight);
                 }
                 }
                 else
                 else
                 {
                 {
-                    if (vm.ImageIterator is not null)
+                    if (NavigationManager.CanNavigate(vm))
                     {
                     {
-                        var nextIndex = vm.ImageIterator.GetIteration(vm.ImageIterator.CurrentIndex, vm.ImageIterator.IsReversed ? NavigateTo.Previous : NavigateTo.Next);
                         var magickImage = new MagickImage();
                         var magickImage = new MagickImage();
-                        magickImage.Ping(vm.ImageIterator.ImagePaths[nextIndex]);
+                        magickImage.Ping(NavigationManager.GetNextFileName);
                         secondarySourceSize = new Size(magickImage.Width, magickImage.Height);
                         secondarySourceSize = new Size(magickImage.Width, magickImage.Height);
                     }
                     }
                     else return;
                     else return;
@@ -397,7 +396,7 @@ public class PicBox : Control
                 return new Size();
                 return new Size();
             }
             }
 
 
-            var preloadValue = vm.ImageIterator?.GetCurrentPreLoadValue();
+            var preloadValue = NavigationManager.GetCurrentPreLoadValue();
             if (preloadValue is not null)
             if (preloadValue is not null)
             {
             {
                 return new Size(preloadValue.ImageModel.PixelWidth, preloadValue.ImageModel.PixelHeight);
                 return new Size(preloadValue.ImageModel.PixelWidth, preloadValue.ImageModel.PixelHeight);

+ 5 - 5
src/PicView.Avalonia/Gallery/GalleryFunctions.cs

@@ -46,7 +46,7 @@ public static class GalleryFunctions
 
 
         if (vm != null)
         if (vm != null)
         {
         {
-            vm.SelectedGalleryItemIndex = vm.ImageIterator.CurrentIndex;
+            vm.SelectedGalleryItemIndex = NavigationManager.GetCurrentIndex;
         }
         }
 
 
         return true;
         return true;
@@ -86,7 +86,7 @@ public static class GalleryFunctions
 
 
         if (vm != null)
         if (vm != null)
         {
         {
-            vm.SelectedGalleryItemIndex = vm.ImageIterator.CurrentIndex;
+            vm.SelectedGalleryItemIndex = NavigationManager.GetCurrentIndex;
         }
         }
 
 
         return true;
         return true;
@@ -152,7 +152,7 @@ public static class GalleryFunctions
                         ToggleGallery(vm);
                         ToggleGallery(vm);
                     }
                     }
 
 
-                    await NavigationManager.Navigate(vm.ImageIterator.ImagePaths.IndexOf(fileInfo.FullName), vm).ConfigureAwait(false);
+                    await NavigationManager.Navigate(fileInfo.FullName, vm).ConfigureAwait(false);
                 };
                 };
                 if (galleryListBox.Items.Count > index)
                 if (galleryListBox.Items.Count > index)
                 {
                 {
@@ -321,7 +321,7 @@ public static class GalleryFunctions
         }
         }
 
 
         
         
-        _ = Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.ImagePaths[0])));
+        _ = Task.Run(() => GalleryLoad.LoadGallery(vm, NavigationManager.GetInitialFileInfo?.DirectoryName));
     }
     }
 
 
     public static void OpenCloseBottomGallery(MainViewModel vm)
     public static void OpenCloseBottomGallery(MainViewModel vm)
@@ -357,7 +357,7 @@ public static class GalleryFunctions
             return;
             return;
         }
         }
 
 
-        Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.ImagePaths[0])));
+        Task.Run(() => GalleryLoad.LoadGallery(vm, NavigationManager.GetInitialFileInfo?.DirectoryName));
     }
     }
 
 
     public static void OpenBottomGallery(MainViewModel vm)
     public static void OpenBottomGallery(MainViewModel vm)

+ 11 - 26
src/PicView.Avalonia/Gallery/GalleryLoad.cs

@@ -20,7 +20,7 @@ public static class GalleryLoad
         // TODO: When list larger than 500, lazy load this when scrolling instead.
         // TODO: When list larger than 500, lazy load this when scrolling instead.
         // Figure out how to support virtualization. 
         // Figure out how to support virtualization. 
 
 
-        if (vm.ImageIterator?.ImagePaths.Count == 0 || IsLoading || vm.ImageIterator is null)
+        if (IsLoading || !NavigationManager.CanNavigate(vm) || string.IsNullOrEmpty(currentDirectory))
         {
         {
             return;
             return;
         }
         }
@@ -69,10 +69,10 @@ public static class GalleryLoad
         _cancellationTokenSource = new CancellationTokenSource();
         _cancellationTokenSource = new CancellationTokenSource();
         _currentDirectory = currentDirectory;
         _currentDirectory = currentDirectory;
         IsLoading = true;
         IsLoading = true;
-        var index = vm.ImageIterator.CurrentIndex;
+        var index = NavigationManager.GetCurrentIndex;
         var galleryItemSize = Math.Max(vm.GetBottomGalleryItemHeight, vm.GetFullGalleryItemHeight);
         var galleryItemSize = Math.Max(vm.GetBottomGalleryItemHeight, vm.GetFullGalleryItemHeight);
 
 
-        var endIndex = vm.ImageIterator.ImagePaths.Count;
+        var endIndex = NavigationManager.GetCount;
         // Set priority low when loading excess images to ensure app responsiveness
         // Set priority low when loading excess images to ensure app responsiveness
         var priority = endIndex switch
         var priority = endIndex switch
         {
         {
@@ -88,14 +88,13 @@ public static class GalleryLoad
         {
         {
             for (var i = 0; i < endIndex; i++)
             for (var i = 0; i < endIndex; i++)
             {
             {
-                if (currentDirectory != _currentDirectory || _cancellationTokenSource.IsCancellationRequested ||
-                    vm.ImageIterator is null)
+                if (NavigationManager.GetInitialFileInfo?.DirectoryName != _currentDirectory || _cancellationTokenSource.IsCancellationRequested)
                 {
                 {
                     await _cancellationTokenSource.CancelAsync();
                     await _cancellationTokenSource.CancelAsync();
                     return;
                     return;
                 }
                 }
 
 
-                fileInfos[i] = new FileInfo(vm.ImageIterator.ImagePaths[i]);
+                fileInfos[i] = new FileInfo(NavigationManager.GetFileNameAt(i));
                 var thumbData = GalleryThumbInfo.GalleryThumbHolder.GetThumbData(fileInfos[i]);
                 var thumbData = GalleryThumbInfo.GalleryThumbHolder.GetThumbData(fileInfos[i]);
                 await Dispatcher.UIThread.InvokeAsync(() =>
                 await Dispatcher.UIThread.InvokeAsync(() =>
                 {
                 {
@@ -115,11 +114,10 @@ public static class GalleryLoad
                             GalleryFunctions.ToggleGallery(vm);
                             GalleryFunctions.ToggleGallery(vm);
                         }
                         }
 
 
-                        await NavigationManager.Navigate(vm.ImageIterator.ImagePaths.IndexOf(fileInfos[i1].FullName), vm)
-                            .ConfigureAwait(false);
+                        await NavigationManager.Navigate(fileInfos[i1].FullName, vm).ConfigureAwait(false);
                     };
                     };
                     galleryListBox.Items.Add(galleryItem);
                     galleryListBox.Items.Add(galleryItem);
-                    if (i != vm.ImageIterator?.CurrentIndex)
+                    if (i != NavigationManager.GetCurrentIndex)
                     {
                     {
                         return;
                         return;
                     }
                     }
@@ -142,7 +140,7 @@ public static class GalleryLoad
                 }
                 }
 
 
                 var horizontalItems = (int)Math.Floor(galleryListBox.Bounds.Width / galleryItem.ImageBorder.MinWidth);
                 var horizontalItems = (int)Math.Floor(galleryListBox.Bounds.Width / galleryItem.ImageBorder.MinWidth);
-                index = (vm.ImageIterator.CurrentIndex - horizontalItems) % vm.ImageIterator.ImagePaths.Count;
+                index = (NavigationManager.GetCurrentIndex - horizontalItems) % NavigationManager.GetCount;
             });
             });
 
 
             index = index < 0 ? 0 : index;
             index = index < 0 ? 0 : index;
@@ -183,8 +181,7 @@ public static class GalleryLoad
         {
         {
             await Parallel.ForAsync(0, endPosition, options, async (i, _) =>
             await Parallel.ForAsync(0, endPosition, options, async (i, _) =>
             {
             {
-                if (currentDirectory != _currentDirectory || _cancellationTokenSource.IsCancellationRequested ||
-                    vm.ImageIterator is null)
+                if (NavigationManager.GetInitialFileInfo?.DirectoryName != _currentDirectory || _cancellationTokenSource.IsCancellationRequested)
                 {
                 {
                     await _cancellationTokenSource.CancelAsync();
                     await _cancellationTokenSource.CancelAsync();
                     return;
                     return;
@@ -192,7 +189,7 @@ public static class GalleryLoad
 
 
                 ct.ThrowIfCancellationRequested();
                 ct.ThrowIfCancellationRequested();
 
 
-                if (i < 0 || i >= vm.ImageIterator.ImagePaths.Count)
+                if (i < 0 || i >= NavigationManager.GetCount)
                 {
                 {
                     return;
                     return;
                 }
                 }
@@ -229,19 +226,7 @@ public static class GalleryLoad
                         galleryItem.GalleryImage.Source = thumb;
                         galleryItem.GalleryImage.Source = thumb;
                     }
                     }
 
 
-                    if (vm.ImageIterator is null)
-                    {
-                        ct.ThrowIfCancellationRequested();
-                        GalleryFunctions.Clear();
-                        if (GalleryFunctions.IsBottomGalleryOpen)
-                        {
-                            mainView.GalleryView.GalleryMode = GalleryMode.BottomToClosed;
-                        }
-
-                        return;
-                    }
-
-                    if (nextIndex == vm.ImageIterator.CurrentIndex)
+                    if (nextIndex == NavigationManager.GetCurrentIndex)
                     {
                     {
                         galleryListBox.ScrollToCenterOfItem(galleryItem);
                         galleryListBox.ScrollToCenterOfItem(galleryItem);
                     }
                     }

+ 1 - 1
src/PicView.Avalonia/Gallery/GalleryNavigation.cs

@@ -176,7 +176,7 @@ public static class GalleryNavigation
             return;
             return;
         }
         }
         GalleryFunctions.ToggleGallery(vm);
         GalleryFunctions.ToggleGallery(vm);
-        if (vm.SelectedGalleryItemIndex != vm.ImageIterator.CurrentIndex) 
+        if (vm.SelectedGalleryItemIndex != NavigationManager.GetCurrentIndex) 
         {
         {
             await NavigationManager.Navigate(vm.SelectedGalleryItemIndex, vm).ConfigureAwait(false);
             await NavigationManager.Navigate(vm.SelectedGalleryItemIndex, vm).ConfigureAwait(false);
         }
         }

+ 1 - 2
src/PicView.Avalonia/ImageHandling/ImageHelper.cs

@@ -50,8 +50,7 @@ public static class ImageHelper
             }
             }
             else
             else
             {
             {
-                var preloadValue = await vm.ImageIterator.GetPreLoadValueAsync(vm.ImageIterator.ImagePaths.IndexOf(path))
-                    .ConfigureAwait(false);
+                var preloadValue = await NavigationManager.GetPreLoadValueAsync(path).ConfigureAwait(false);
                 if (preloadValue?.ImageModel.Image is Bitmap bitmap)
                 if (preloadValue?.ImageModel.Image is Bitmap bitmap)
                 {
                 {
                     source = bitmap;
                     source = bitmap;

+ 5 - 40
src/PicView.Avalonia/Navigation/ErrorHandling.cs

@@ -1,12 +1,9 @@
 using Avalonia;
 using Avalonia;
-using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Threading;
 using Avalonia.Threading;
-using PicView.Avalonia.Clipboard;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.Calculations;
 using PicView.Core.Calculations;
-using PicView.Core.FileHandling;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
 using StartUpMenu = PicView.Avalonia.Views.StartUpMenu;
 using StartUpMenu = PicView.Avalonia.Views.StartUpMenu;
 
 
@@ -55,12 +52,12 @@ public static class ErrorHandling
             vm.GalleryMode = GalleryMode.Closed;
             vm.GalleryMode = GalleryMode.Closed;
             GalleryFunctions.Clear();
             GalleryFunctions.Clear();
             UIHelper.CloseMenus(vm);
             UIHelper.CloseMenus(vm);
-            vm.ImageIterator?.Dispose();
-            vm.ImageIterator = null;
             vm.GalleryMargin = new Thickness(0, 0, 0, 0);
             vm.GalleryMargin = new Thickness(0, 0, 0, 0);
             vm.GetIndex = 0;
             vm.GetIndex = 0;
             vm.PlatformService.StopTaskbarProgress();
             vm.PlatformService.StopTaskbarProgress();
             vm.IsLoading = false;
             vm.IsLoading = false;
+
+            _ = NavigationManager.DisposeImageIteratorAsync();
         }
         }
     }
     }
 
 
@@ -83,7 +80,7 @@ public static class ErrorHandling
             return;
             return;
         }
         }
         
         
-        if (vm.ImageIterator is null)
+        if (vm.ImageSource is null || !NavigationManager.CanNavigate(vm))
         {
         {
             await Dispatcher.UIThread.InvokeAsync(() =>
             await Dispatcher.UIThread.InvokeAsync(() =>
             {
             {
@@ -94,10 +91,7 @@ public static class ErrorHandling
 
 
         try
         try
         {
         {
-            var index = vm.ImageIterator.CurrentIndex;
-            await vm.ImageIterator.DisposeAsync().ConfigureAwait(false);
-            vm.ImageIterator = new ImageIterator(vm.FileInfo, vm.ImageIterator.ImagePaths, index, vm);
-            await NavigationManager.Navigate(index, vm).ConfigureAwait(false);
+            await NavigationManager.FullReload(vm);
         }
         }
         catch (Exception e)
         catch (Exception e)
         {
         {
@@ -114,35 +108,6 @@ public static class ErrorHandling
     
     
     public static async Task ReloadImageAsync(MainViewModel vm)
     public static async Task ReloadImageAsync(MainViewModel vm)
     {
     {
-        if (vm.ImageSource is null)
-        {
-            return;
-        }
-
-        if (NavigationManager.CanNavigate(vm))
-        {
-            var preloadValue = await vm.ImageIterator.GetPreLoadValueAsync(vm.ImageIterator.CurrentIndex).ConfigureAwait(false);
-            if (preloadValue?.ImageModel.Image is not null)
-            {
-                vm.ImageSource = preloadValue.ImageModel.Image;
-            }
-        }
-        else
-        {
-            var url = vm.Title.GetURL();
-            if (!string.IsNullOrEmpty(url))
-            {
-                await NavigationManager.LoadPicFromUrlAsync(url, vm).ConfigureAwait(false);
-            }
-            else 
-            {
-                if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
-                {
-                    return;
-                }
-                var clipboard = desktop.MainWindow.Clipboard;
-                await ClipboardHelper.PasteClipboardImage(vm, clipboard);
-            }
-        }
+        await NavigationManager.FullReload(vm);
     }
     }
 }
 }

+ 7 - 22
src/PicView.Avalonia/Navigation/FileHistoryNavigation.cs

@@ -83,25 +83,11 @@ public static class FileHistoryNavigation
         }
         }
     }
     }
 
 
-    public static async Task NextAsync(MainViewModel vm)
-    {
-        if (!NavigationManager.CanNavigate(vm))
-        {
-            await OpenLastFileAsync(vm).ConfigureAwait(false);
-            return;
-        }
+    public static async Task NextAsync(MainViewModel vm) => await NextAsyncInternal(vm, true).ConfigureAwait(false);
 
 
-        if (vm.ImageIterator is null)
-        {
-            await OpenLastFileAsync(vm).ConfigureAwait(false);
-            return;
-        }
-
-        var index = vm.ImageIterator.CurrentIndex;
-        await LoadEntryAsync(vm, index, true).ConfigureAwait(false);
-    }
-
-    public static async Task PrevAsync(MainViewModel vm)
+    public static async Task PrevAsync(MainViewModel vm) => await NextAsyncInternal(vm, false).ConfigureAwait(false);
+    
+    private static async Task NextAsyncInternal(MainViewModel vm, bool next)
     {
     {
         if (!NavigationManager.CanNavigate(vm))
         if (!NavigationManager.CanNavigate(vm))
         {
         {
@@ -109,19 +95,18 @@ public static class FileHistoryNavigation
             return;
             return;
         }
         }
         
         
-        if (vm.ImageIterator is null)
+        if (!NavigationManager.CanNavigate(vm))
         {
         {
             await OpenLastFileAsync(vm).ConfigureAwait(false);
             await OpenLastFileAsync(vm).ConfigureAwait(false);
             return;
             return;
         }
         }
 
 
-        var index = vm.ImageIterator.CurrentIndex;
-        await LoadEntryAsync(vm, index, false).ConfigureAwait(false);
+        await LoadEntryAsync(vm, NavigationManager.GetCurrentIndex, next).ConfigureAwait(false);
     }
     }
 
 
     public static async Task LoadEntryAsync(MainViewModel vm, int index, bool next)
     public static async Task LoadEntryAsync(MainViewModel vm, int index, bool next)
     {
     {
-        var imagePaths = vm.ImageIterator.ImagePaths;
+        var imagePaths = NavigationManager.GetCollection;
 
 
         _fileHistory ??= new FileHistory();
         _fileHistory ??= new FileHistory();
         string? nextEntry;
         string? nextEntry;

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

@@ -107,7 +107,7 @@ public static class FileListManager
                     return false;
                     return false;
                 }
                 }
 
 
-                vm.ImageIterator.UpdateFileListAndIndex(files, files.IndexOf(vm.FileInfo.FullName));
+                NavigationManager.UpdateFileListAndIndex(files, files.IndexOf(vm.FileInfo.FullName));
                 SetTitleHelper.SetTitle(vm);
                 SetTitleHelper.SetTitle(vm);
                 return true;
                 return true;
             }
             }

+ 6 - 2
src/PicView.Avalonia/Navigation/ImageIterator.cs

@@ -22,8 +22,12 @@ public class ImageIterator : IAsyncDisposable
     public List<string> ImagePaths { get; private set; }
     public List<string> ImagePaths { get; private set; }
 
 
     public int CurrentIndex { get; private set; }
     public int CurrentIndex { get; private set; }
+    
+    public int GetNonZeroIndex => CurrentIndex + 1 > GetCount ? 1 : CurrentIndex + 1;
 
 
     public int NextIndex => GetIteration(CurrentIndex, NavigateTo.Next);
     public int NextIndex => GetIteration(CurrentIndex, NavigateTo.Next);
+    
+    public int GetCount => ImagePaths.Count;
 
 
     public FileInfo InitialFileInfo { get; private set; } = null!;
     public FileInfo InitialFileInfo { get; private set; } = null!;
     public bool IsReversed { get; private set; }
     public bool IsReversed { get; private set; }
@@ -321,7 +325,7 @@ public class ImageIterator : IAsyncDisposable
         await PreLoader.ClearAsync().ConfigureAwait(false);
         await PreLoader.ClearAsync().ConfigureAwait(false);
     }
     }
 
 
-    public async Task Preload()
+    public async Task PreloadAsync()
     {
     {
         await PreLoader.PreLoadAsync(CurrentIndex, IsReversed, ImagePaths).ConfigureAwait(false);
         await PreLoader.PreLoadAsync(CurrentIndex, IsReversed, ImagePaths).ConfigureAwait(false);
     }
     }
@@ -370,7 +374,7 @@ public class ImageIterator : IAsyncDisposable
 
 
     #region Navigation
     #region Navigation
 
 
-    public async Task ReloadFileList()
+    public async Task ReloadFileListAsync()
     {
     {
         ImagePaths = await Task.FromResult(_vm.PlatformService.GetFiles(InitialFileInfo)).ConfigureAwait(false);
         ImagePaths = await Task.FromResult(_vm.PlatformService.GetFiles(InitialFileInfo)).ConfigureAwait(false);
         CurrentIndex = ImagePaths.IndexOf(_vm.FileInfo.FullName);
         CurrentIndex = ImagePaths.IndexOf(_vm.FileInfo.FullName);

+ 183 - 38
src/PicView.Avalonia/Navigation/NavigationManager.cs

@@ -1,16 +1,20 @@
 using Avalonia;
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Media.Imaging;
 using Avalonia.Media.Imaging;
 using Avalonia.Threading;
 using Avalonia.Threading;
 using ImageMagick;
 using ImageMagick;
+using PicView.Avalonia.Clipboard;
 using PicView.Avalonia.Crop;
 using PicView.Avalonia.Crop;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.Input;
 using PicView.Avalonia.Input;
+using PicView.Avalonia.Preloading;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.WindowBehavior;
 using PicView.Avalonia.WindowBehavior;
 using PicView.Core.ArchiveHandling;
 using PicView.Core.ArchiveHandling;
+using PicView.Core.FileHandling;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
 using PicView.Core.ImageDecoding;
 using PicView.Core.ImageDecoding;
 using PicView.Core.Localization;
 using PicView.Core.Localization;
@@ -19,7 +23,7 @@ using PicView.Core.Navigation;
 namespace PicView.Avalonia.Navigation;
 namespace PicView.Avalonia.Navigation;
 
 
 /// <summary>
 /// <summary>
-///     Helper class for navigation and image loading functionalities in the application.
+///     Manages image navigation within the application.
 /// </summary>
 /// </summary>
 public static class NavigationManager
 public static class NavigationManager
 {
 {
@@ -27,6 +31,9 @@ public static class NavigationManager
 
 
     private static TiffManager.TiffNavigationInfo? _tiffNavigationInfo;
     private static TiffManager.TiffNavigationInfo? _tiffNavigationInfo;
 
 
+    // Should be updated to handle multiple iterators, in the future when adding tab support
+    private static ImageIterator? _imageIterator;
+
     #region Navigation
     #region Navigation
 
 
     /// <summary>
     /// <summary>
@@ -36,8 +43,8 @@ public static class NavigationManager
     /// <returns>True if navigation is possible, otherwise false.</returns>
     /// <returns>True if navigation is possible, otherwise false.</returns>
     public static bool CanNavigate(MainViewModel vm)
     public static bool CanNavigate(MainViewModel vm)
     {
     {
-        return vm?.ImageIterator?.ImagePaths is not null &&
-               vm.ImageIterator.ImagePaths.Count > 0 && !CropFunctions.IsCropping &&
+        return _imageIterator?.ImagePaths is not null &&
+               _imageIterator.ImagePaths.Count > 0 && !CropFunctions.IsCropping &&
                !UIHelper.IsDialogOpen && !vm.IsEditableTitlebarOpen;
                !UIHelper.IsDialogOpen && !vm.IsEditableTitlebarOpen;
         // TODO: should probably turn this into CanExecute observable for ReactiveUI
         // TODO: should probably turn this into CanExecute observable for ReactiveUI
     }
     }
@@ -62,26 +69,26 @@ public static class NavigationManager
         }
         }
 
 
         var navigateTo = next ? NavigateTo.Next : NavigateTo.Previous;
         var navigateTo = next ? NavigateTo.Next : NavigateTo.Previous;
-        var nextIteration = vm.ImageIterator.GetIteration(vm.ImageIterator.CurrentIndex, navigateTo);
-        var currentFileName = vm.ImageIterator.ImagePaths[vm.ImageIterator.CurrentIndex];
+        var nextIteration = _imageIterator.GetIteration(_imageIterator.CurrentIndex, navigateTo);
+        var currentFileName = _imageIterator.ImagePaths[_imageIterator.CurrentIndex];
         if (TiffManager.IsTiff(currentFileName))
         if (TiffManager.IsTiff(currentFileName))
         {
         {
             await TiffNavigation(vm, currentFileName, nextIteration).ConfigureAwait(false);
             await TiffNavigation(vm, currentFileName, nextIteration).ConfigureAwait(false);
         }
         }
         else
         else
         {
         {
-            await CheckCancellationAndStartIterateToIndex(nextIteration, vm).ConfigureAwait(false);
+            await CheckCancellationAndStartIterateToIndex(nextIteration).ConfigureAwait(false);
         }
         }
     }
     }
 
 
     private static async Task TiffNavigation(MainViewModel vm, string currentFileName, int nextIteration)
     private static async Task TiffNavigation(MainViewModel vm, string currentFileName, int nextIteration)
     {
     {
-        if (_tiffNavigationInfo is null && !vm.ImageIterator.IsReversed)
+        if (_tiffNavigationInfo is null && !_imageIterator.IsReversed)
         {
         {
             var tiffPages = await Task.FromResult(TiffManager.LoadTiffPages(currentFileName)).ConfigureAwait(false);
             var tiffPages = await Task.FromResult(TiffManager.LoadTiffPages(currentFileName)).ConfigureAwait(false);
             if (tiffPages.Count < 1)
             if (tiffPages.Count < 1)
             {
             {
-                await CheckCancellationAndStartIterateToIndex(nextIteration, vm).ConfigureAwait(false);
+                await CheckCancellationAndStartIterateToIndex(nextIteration).ConfigureAwait(false);
                 return;
                 return;
             }
             }
 
 
@@ -95,11 +102,11 @@ public static class NavigationManager
 
 
         if (_tiffNavigationInfo is null)
         if (_tiffNavigationInfo is null)
         {
         {
-            await CheckCancellationAndStartIterateToIndex(nextIteration, vm).ConfigureAwait(false);
+            await CheckCancellationAndStartIterateToIndex(nextIteration).ConfigureAwait(false);
         }
         }
         else
         else
         {
         {
-            if (vm.ImageIterator.IsReversed)
+            if (_imageIterator.IsReversed)
             {
             {
                 if (_tiffNavigationInfo.CurrentPage - 1 < 0)
                 if (_tiffNavigationInfo.CurrentPage - 1 < 0)
                 {
                 {
@@ -120,14 +127,14 @@ public static class NavigationManager
             }
             }
             else
             else
             {
             {
-                await UpdateImage.SetTiffImageAsync(_tiffNavigationInfo, vm.ImageIterator.CurrentIndex, vm.FileInfo, vm);
+                await UpdateImage.SetTiffImageAsync(_tiffNavigationInfo, _imageIterator.CurrentIndex, vm.FileInfo, vm);
             }
             }
         }
         }
         return;
         return;
         
         
         async Task ExitTiffNavigationAndNavigate()
         async Task ExitTiffNavigationAndNavigate()
         {
         {
-            await CheckCancellationAndStartIterateToIndex(nextIteration, vm).ConfigureAwait(false);
+            await CheckCancellationAndStartIterateToIndex(nextIteration).ConfigureAwait(false);
             _tiffNavigationInfo?.Dispose();
             _tiffNavigationInfo?.Dispose();
             _tiffNavigationInfo = null;
             _tiffNavigationInfo = null;
         }
         }
@@ -163,7 +170,19 @@ public static class NavigationManager
             return;
             return;
         }
         }
 
 
-        await CheckCancellationAndStartIterateToIndex(index, vm).ConfigureAwait(false);
+        await CheckCancellationAndStartIterateToIndex(index).ConfigureAwait(false);
+    }
+    
+    public static async Task Navigate(string fileName, MainViewModel vm)
+    {
+        if (!CanNavigate(vm))
+        {
+            return;
+        }
+        
+        var index = _imageIterator.ImagePaths.IndexOf(fileName);
+
+        await CheckCancellationAndStartIterateToIndex(index).ConfigureAwait(false);
     }
     }
 
 
     private static async Task NavigateIncrements(MainViewModel vm, bool next, bool is10, bool is100)
     private static async Task NavigateIncrements(MainViewModel vm, bool next, bool is10, bool is100)
@@ -173,11 +192,11 @@ public static class NavigationManager
             return;
             return;
         }
         }
 
 
-        var currentIndex = vm.ImageIterator.CurrentIndex;
+        var currentIndex = _imageIterator.CurrentIndex;
         var direction = next ? NavigateTo.Next : NavigateTo.Previous;
         var direction = next ? NavigateTo.Next : NavigateTo.Previous;
-        var index = vm.ImageIterator.GetIteration(currentIndex, direction, false, is10, is100);
+        var index = _imageIterator.GetIteration(currentIndex, direction, false, is10, is100);
 
 
-        await CheckCancellationAndStartIterateToIndex(index, vm).ConfigureAwait(false);
+        await CheckCancellationAndStartIterateToIndex(index).ConfigureAwait(false);
     }
     }
 
 
     public static Task Next10(MainViewModel vm) => NavigateIncrements(vm, true, true, false);
     public static Task Next10(MainViewModel vm) => NavigateIncrements(vm, true, true, false);
@@ -210,7 +229,7 @@ public static class NavigationManager
             }
             }
 
 
             _cancellationTokenSource = new CancellationTokenSource();
             _cancellationTokenSource = new CancellationTokenSource();
-            await vm.ImageIterator.NextIteration(last ? NavigateTo.Last : NavigateTo.First, _cancellationTokenSource)
+            await _imageIterator.NextIteration(last ? NavigateTo.Last : NavigateTo.First, _cancellationTokenSource)
                 .ConfigureAwait(false);
                 .ConfigureAwait(false);
             await ScrollToEndIfNecessary(last);
             await ScrollToEndIfNecessary(last);
         }
         }
@@ -340,11 +359,11 @@ public static class NavigationManager
             {
             {
                 case ErrorHelper.LoadAbleFileType.File:
                 case ErrorHelper.LoadAbleFileType.File:
                     // Navigate to the image if it exists in the image iterator
                     // Navigate to the image if it exists in the image iterator
-                    if (vm.ImageIterator is not null)
+                    if (_imageIterator is not null)
                     {
                     {
-                        if (vm.ImageIterator.ImagePaths.Contains(check.Value.Data))
+                        if (_imageIterator.ImagePaths.Contains(check.Value.Data))
                         {
                         {
-                            await vm.ImageIterator.IterateToIndex(vm.ImageIterator.ImagePaths.IndexOf(check.Value.Data),
+                            await _imageIterator.IterateToIndex(_imageIterator.ImagePaths.IndexOf(check.Value.Data),
                                     _cancellationTokenSource)
                                     _cancellationTokenSource)
                                 .ConfigureAwait(false);
                                 .ConfigureAwait(false);
                             return;
                             return;
@@ -415,14 +434,14 @@ public static class NavigationManager
 
 
         _cancellationTokenSource = new CancellationTokenSource();
         _cancellationTokenSource = new CancellationTokenSource();
 
 
-        if (vm.ImageIterator is not null)
+        if (_imageIterator is not null)
         {
         {
-            if (fileInfo.DirectoryName == vm.ImageIterator.InitialFileInfo.DirectoryName)
+            if (fileInfo.DirectoryName == _imageIterator.InitialFileInfo.DirectoryName)
             {
             {
-                var index = vm.ImageIterator.ImagePaths.IndexOf(fileInfo.FullName);
+                var index = _imageIterator.ImagePaths.IndexOf(fileInfo.FullName);
                 if (index != -1)
                 if (index != -1)
                 {
                 {
-                    await vm.ImageIterator.IterateToIndex(index, _cancellationTokenSource).ConfigureAwait(false);
+                    await _imageIterator.IterateToIndex(index, _cancellationTokenSource).ConfigureAwait(false);
                     await CheckTiffUpdate(vm, fileInfo.FullName, index);
                     await CheckTiffUpdate(vm, fileInfo.FullName, index);
                 }
                 }
                 else
                 else
@@ -571,7 +590,7 @@ public static class NavigationManager
     /// <returns>A task representing the asynchronous operation.</returns>
     /// <returns>A task representing the asynchronous operation.</returns>
     public static async Task LoadPicFromBase64Async(string base64, MainViewModel vm)
     public static async Task LoadPicFromBase64Async(string base64, MainViewModel vm)
     {
     {
-        vm.ImageIterator = null;
+        _imageIterator = null;
         vm.ImageSource = null;
         vm.ImageSource = null;
         vm.IsLoading = true;
         vm.IsLoading = true;
         SetTitleHelper.SetLoadingTitle(vm);
         SetTitleHelper.SetLoadingTitle(vm);
@@ -678,15 +697,144 @@ public static class NavigationManager
 
 
     #endregion
     #endregion
 
 
-    #region Private helpers
+    #region Helpers
+
+    #region ImageIterator
+
+    public static void InitializeImageIterator(MainViewModel vm)
+    {
+        _imageIterator ??= new ImageIterator(vm.FileInfo, vm);
+    }
+    
+    public static async Task DisposeImageIteratorAsync()
+    {
+        if (_imageIterator is null)
+        {
+            return;
+        }
+        await _imageIterator.DisposeAsync();
+    }
+    
+    public static bool IsCollectionEmpty => _imageIterator.ImagePaths is null || _imageIterator.ImagePaths.Count < 0;
+    public static List<string> GetCollection => _imageIterator.ImagePaths;
+    
+    public static void UpdateFileListAndIndex(List<string> fileList, int index) => _imageIterator?.UpdateFileListAndIndex(fileList, index);
+    
+    public static int? GetFileNameIndex(string fileName) =>
+        IsCollectionEmpty ? null : _imageIterator.ImagePaths.IndexOf(fileName);
+
+    /// <summary>
+    ///     Returns the file name at a given index in the image collection.
+    /// </summary>
+    /// <param name="index">The index of the file to retrieve.</param>
+    /// <returns>The file name at the given index.</returns>
+    public static string? GetFileNameAt(int index)
+    {
+        if (IsCollectionEmpty)
+        {
+            return null;
+        }
+
+        if (index < 0 || index >= _imageIterator.ImagePaths.Count)
+        {
+            return null;
+        }
+
+        return _imageIterator.ImagePaths[index];
+    }
+    
+    /// <summary>
+    ///     Gets the current file name.
+    /// </summary>
+    public static string? GetCurrentFileName => GetFileNameAt(_imageIterator?.CurrentIndex ?? -1);
+    
+    /// <summary>
+    ///     Gets the next file name.
+    /// </summary>
+    public static string? GetNextFileName => GetFileNameAt(_imageIterator?.NextIndex ?? -1);
+
+    public static int GetCurrentIndex => _imageIterator?.CurrentIndex ?? -1;
+    
+    public static int GetNextIndex => _imageIterator?.NextIndex ?? -1;
+    
+    public static int GetNonZeroIndex => _imageIterator?.GetNonZeroIndex ?? -1;
+    
+    public static int GetCount => _imageIterator?.GetCount ?? -1;
+    
+    public static FileInfo? GetInitialFileInfo => _imageIterator?.InitialFileInfo;
+    
+    public static PreLoadValue? GetPreLoadValue(int index) => _imageIterator?.GetPreLoadValue(index) ?? null;
+    public static async Task<PreLoadValue?> GetPreLoadValueAsync(int index) => await _imageIterator?.GetPreLoadValueAsync(index) ?? null;
+    public static async Task<PreLoadValue?> GetPreLoadValueAsync(string fileName) => await _imageIterator?.GetPreLoadValueAsync(GetFileNameIndex(fileName) ?? GetCurrentIndex) ?? null;
+    public static PreLoadValue? GetCurrentPreLoadValue() => _imageIterator?.GetCurrentPreLoadValue() ?? null;
+    public static async Task<PreLoadValue?> GetCurrentPreLoadValueAsync() => await _imageIterator?.GetCurrentPreLoadValueAsync() ?? null;
+    public static PreLoadValue? GetNextPreLoadValue() => _imageIterator?.GetNextPreLoadValue() ?? null;
+    public static async Task<PreLoadValue?> GetNextPreLoadValueAsync() => await _imageIterator?.GetNextPreLoadValueAsync() ?? null;
+    
+    public static async Task ReloadFileListAsync() => await _imageIterator?.ReloadFileListAsync();
+    
+    public static void AddToPreloader(int index, ImageModel imageModel) => _imageIterator?.Add(index, imageModel);
+    public static async Task PreloadAsync() => await _imageIterator?.PreloadAsync();
+    
+    public static void RemoveCurrentItemFromPreLoader() => _imageIterator?.RemoveItemFromPreLoader(_imageIterator.CurrentIndex);
+    public static void RemoveItemFromPreLoader(string fileName) => _imageIterator?.RemoveItemFromPreLoader(fileName);
+
+    #endregion
+
+
+    #region Reload
+
+    public static async Task QuickReload()
+    {
+        if (_imageIterator is null)
+        {
+            return;
+        }
+        await _imageIterator.QuickReload();
+    }
+    
+    public static async Task FullReload(MainViewModel vm)
+    {
+        if (vm.ImageSource is null)
+        {
+            return;
+        }
+        
+        if (_imageIterator is null)
+        {
+            var url = vm.Title.GetURL();
+            if (!string.IsNullOrEmpty(url))
+            {
+                await LoadPicFromUrlAsync(url, vm).ConfigureAwait(false);
+            }
+            else 
+            {
+                if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
+                {
+                    return;
+                }
+                var clipboard = desktop.MainWindow.Clipboard;
+                await ClipboardHelper.PasteClipboardImage(vm, clipboard);
+            }
+            return;
+        }
+
+        var index = _imageIterator.CurrentIndex;
+        await _imageIterator.DisposeAsync().ConfigureAwait(false);
+        _imageIterator = new ImageIterator(vm.FileInfo, vm);
+        await Navigate(index, vm).ConfigureAwait(false);
+    }
+
+    #endregion
+    
+
 
 
     /// <summary>
     /// <summary>
     ///     Checks if the previous iteration has been cancelled and starts the iteration at the given index in a new task.
     ///     Checks if the previous iteration has been cancelled and starts the iteration at the given index in a new task.
     /// </summary>
     /// </summary>
     /// <param name="index">The index to iterate to.</param>
     /// <param name="index">The index to iterate to.</param>
-    /// <param name="vm">The main view model instance.</param>
     /// <returns>A task representing the asynchronous operation.</returns>
     /// <returns>A task representing the asynchronous operation.</returns>
-    private static async Task CheckCancellationAndStartIterateToIndex(int index, MainViewModel vm)
+    private static async Task CheckCancellationAndStartIterateToIndex(int index)
     {
     {
         await Task.Run(() =>
         await Task.Run(() =>
         {
         {
@@ -696,7 +844,7 @@ public static class NavigationManager
             }
             }
 
 
             _cancellationTokenSource = new CancellationTokenSource();
             _cancellationTokenSource = new CancellationTokenSource();
-            _ = vm.ImageIterator.NextIteration(index, _cancellationTokenSource).ConfigureAwait(false);
+            _ = _imageIterator.NextIteration(index, _cancellationTokenSource).ConfigureAwait(false);
             _cancellationTokenSource.CancelAfter(TimeSpan.FromMinutes(5));
             _cancellationTokenSource.CancelAfter(TimeSpan.FromMinutes(5));
         }).ConfigureAwait(false);
         }).ConfigureAwait(false);
     }
     }
@@ -712,7 +860,7 @@ public static class NavigationManager
         return await Task.Run(() =>
         return await Task.Run(() =>
         {
         {
             var indexChange = next ? 1 : -1;
             var indexChange = next ? 1 : -1;
-            var currentFolder = Path.GetDirectoryName(vm.ImageIterator?.ImagePaths[vm.ImageIterator.CurrentIndex]);
+            var currentFolder = Path.GetDirectoryName(_imageIterator?.ImagePaths[_imageIterator.CurrentIndex]);
             var parentFolder = Path.GetDirectoryName(currentFolder);
             var parentFolder = Path.GetDirectoryName(currentFolder);
             var directories = Directory.GetDirectories(parentFolder, "*", SearchOption.TopDirectoryOnly);
             var directories = Directory.GetDirectories(parentFolder, "*", SearchOption.TopDirectoryOnly);
             var directoryIndex = Array.IndexOf(directories, currentFolder);
             var directoryIndex = Array.IndexOf(directories, currentFolder);
@@ -765,7 +913,7 @@ public static class NavigationManager
         vm.ImageType = imageModel.ImageType;
         vm.ImageType = imageModel.ImageType;
         if (Settings.ImageScaling.ShowImageSideBySide)
         if (Settings.ImageScaling.ShowImageSideBySide)
         {
         {
-            nextImageModel = (await vm.ImageIterator.GetNextPreLoadValueAsync()).ImageModel;
+            nextImageModel = (await _imageIterator.GetNextPreLoadValueAsync()).ImageModel;
             vm.SecondaryImageSource = nextImageModel.Image;
             vm.SecondaryImageSource = nextImageModel.Image;
             await Dispatcher.UIThread.InvokeAsync(() =>
             await Dispatcher.UIThread.InvokeAsync(() =>
             {
             {
@@ -789,19 +937,16 @@ public static class NavigationManager
             Dispatcher.UIThread.Post(() => { vm.ImageViewer?.MainImage?.InvalidateVisual(); });
             Dispatcher.UIThread.Post(() => { vm.ImageViewer?.MainImage?.InvalidateVisual(); });
         }
         }
 
 
-        if (vm.ImageIterator is not null)
-        {
-            await vm.ImageIterator.DisposeAsync();
-        }
+        await DisposeImageIteratorAsync();
         
         
         if (files is null)
         if (files is null)
         {
         {
-            vm.ImageIterator = new ImageIterator(fileInfo, vm);
-            index = vm.ImageIterator.CurrentIndex;
+            _imageIterator = new ImageIterator(fileInfo, vm);
+            index = _imageIterator.CurrentIndex;
         }
         }
         else
         else
         {
         {
-            vm.ImageIterator = new ImageIterator(fileInfo, files, index, vm);
+            _imageIterator = new ImageIterator(fileInfo, files, index, vm);
         }
         }
         
         
         var isTiffUpdated = await CheckTiffUpdate(vm, fileInfo.FullName, index); 
         var isTiffUpdated = await CheckTiffUpdate(vm, fileInfo.FullName, index); 

+ 17 - 14
src/PicView.Avalonia/Navigation/UpdateImage.cs

@@ -32,8 +32,13 @@ public static class UpdateImage
         PreLoadValue? preLoadValue,
         PreLoadValue? preLoadValue,
         PreLoadValue? nextPreloadValue = null)
         PreLoadValue? nextPreloadValue = null)
     {
     {
-        preLoadValue ??= await vm.ImageIterator.GetPreLoadValueAsync(index).ConfigureAwait(false);
-        if (preLoadValue.ImageModel?.Image is null && index == vm.ImageIterator.CurrentIndex)
+        preLoadValue ??= await NavigationManager.GetPreLoadValueAsync(index).ConfigureAwait(false);
+        if (preLoadValue is null)
+        {
+            await ErrorHandling.ReloadAsync(vm).ConfigureAwait(false);
+            return;
+        }
+        if (preLoadValue.ImageModel?.Image is null && index == NavigationManager.GetCurrentIndex)
         {
         {
             var fileInfo = preLoadValue.ImageModel?.FileInfo ?? new FileInfo(imagePaths[index]);
             var fileInfo = preLoadValue.ImageModel?.FileInfo ?? new FileInfo(imagePaths[index]);
             preLoadValue.ImageModel = await GetImageModel.GetImageModelAsync(fileInfo).ConfigureAwait(false);
             preLoadValue.ImageModel = await GetImageModel.GetImageModelAsync(fileInfo).ConfigureAwait(false);
@@ -41,25 +46,22 @@ public static class UpdateImage
 
 
         if (Settings.ImageScaling.ShowImageSideBySide)
         if (Settings.ImageScaling.ShowImageSideBySide)
         {
         {
-            nextPreloadValue ??= await vm.ImageIterator.GetNextPreLoadValueAsync().ConfigureAwait(false);
-            if (nextPreloadValue.ImageModel?.Image is null && index == vm.ImageIterator.CurrentIndex)
+            nextPreloadValue ??= await NavigationManager.GetNextPreLoadValueAsync().ConfigureAwait(false);
+            if (nextPreloadValue.ImageModel?.Image is null && index == NavigationManager.GetCurrentIndex)
             {
             {
-                var fileInfo = nextPreloadValue.ImageModel?.FileInfo ?? new FileInfo(
-                    imagePaths[
-                        vm.ImageIterator.GetIteration(index, isReversed ? NavigateTo.Previous : NavigateTo.Next,
-                            true)]);
+                var fileInfo = nextPreloadValue.ImageModel?.FileInfo ?? new FileInfo(NavigationManager.GetNextFileName);
                 nextPreloadValue.ImageModel = await GetImageModel.GetImageModelAsync(fileInfo).ConfigureAwait(false);
                 nextPreloadValue.ImageModel = await GetImageModel.GetImageModelAsync(fileInfo).ConfigureAwait(false);
             }
             }
         }
         }
 
 
-        if (index != vm.ImageIterator.CurrentIndex)
+        if (index != NavigationManager.GetCurrentIndex)
         {
         {
             return;
             return;
         }
         }
 
 
         await Dispatcher.UIThread.InvokeAsync(() =>
         await Dispatcher.UIThread.InvokeAsync(() =>
         {
         {
-            if (index != vm.ImageIterator.CurrentIndex)
+            if (index != NavigationManager.GetCurrentIndex)
             {
             {
                 return;
                 return;
             }
             }
@@ -98,7 +100,7 @@ public static class UpdateImage
                 if (TiffManager.IsTiff(preLoadValue.ImageModel.FileInfo.FullName))
                 if (TiffManager.IsTiff(preLoadValue.ImageModel.FileInfo.FullName))
                 {
                 {
                     SetTitleHelper.TrySetTiffTitle(preLoadValue.ImageModel.PixelWidth,
                     SetTitleHelper.TrySetTiffTitle(preLoadValue.ImageModel.PixelWidth,
-                        preLoadValue.ImageModel.PixelHeight, vm.ImageIterator.CurrentIndex,
+                        preLoadValue.ImageModel.PixelHeight, NavigationManager.GetCurrentIndex,
                         preLoadValue.ImageModel.FileInfo, vm);
                         preLoadValue.ImageModel.FileInfo, vm);
                 }
                 }
                 else
                 else
@@ -254,7 +256,7 @@ public static class UpdateImage
             }
             }
         }, DispatcherPriority.Render);
         }, DispatcherPriority.Render);
 
 
-        vm.ImageIterator = null;
+        
         int width, height;
         int width, height;
         if (imageType is ImageType.Svg)
         if (imageType is ImageType.Svg)
         {
         {
@@ -295,6 +297,7 @@ public static class UpdateImage
         vm.PixelHeight = height;
         vm.PixelHeight = height;
 
 
         await dispatchAction(() => { UIHelper.GetGalleryView.IsVisible = false; }, DispatcherPriority.Render);
         await dispatchAction(() => { UIHelper.GetGalleryView.IsVisible = false; }, DispatcherPriority.Render);
+        await NavigationManager.DisposeImageIteratorAsync();
     }
     }
 
 
     #endregion
     #endregion
@@ -337,11 +340,11 @@ public static class UpdateImage
             GalleryNavigation.CenterScrollToSelectedItem(vm);
             GalleryNavigation.CenterScrollToSelectedItem(vm);
         }
         }
 
 
-        vm.ImageSource = GetThumbnails.GetExifThumb(vm.ImageIterator.ImagePaths[index]);
+        vm.ImageSource = GetThumbnails.GetExifThumb(NavigationManager.GetFileNameAt(index));
         if (Settings.ImageScaling.ShowImageSideBySide)
         if (Settings.ImageScaling.ShowImageSideBySide)
         {
         {
             vm.SecondaryImageSource =
             vm.SecondaryImageSource =
-                GetThumbnails.GetExifThumb(vm.ImageIterator.ImagePaths[vm.ImageIterator.NextIndex]);
+                GetThumbnails.GetExifThumb(NavigationManager.GetNextFileName);
         }
         }
         else
         else
         {
         {

+ 15 - 8
src/PicView.Avalonia/SettingsManagement/SettingsUpdater.cs

@@ -59,8 +59,8 @@ public static class SettingsUpdater
                 vm.PlatformService.StopTaskbarProgress();
                 vm.PlatformService.StopTaskbarProgress();
                 if (NavigationManager.CanNavigate(vm))
                 if (NavigationManager.CanNavigate(vm))
                 {
                 {
-                    vm.PlatformService.SetTaskbarProgress((ulong)vm.ImageIterator?.CurrentIndex!,
-                        (ulong)vm.ImageIterator?.ImagePaths?.Count!);
+                    vm.PlatformService.SetTaskbarProgress((ulong)NavigationManager.GetCurrentIndex,
+                        (ulong)NavigationManager.GetCount);
                 }
                 }
                 WindowResizing.SetSize(vm);
                 WindowResizing.SetSize(vm);
             });
             });
@@ -120,7 +120,7 @@ public static class SettingsUpdater
         vm.IsIncludingSubdirectories = false;
         vm.IsIncludingSubdirectories = false;
         Settings.Sorting.IncludeSubDirectories = false;
         Settings.Sorting.IncludeSubDirectories = false;
         
         
-        await vm.ImageIterator.ReloadFileList().ConfigureAwait(false);
+        await NavigationManager.ReloadFileListAsync().ConfigureAwait(false);
         SetTitleHelper.SetTitle(vm);
         SetTitleHelper.SetTitle(vm);
     }
     }
     
     
@@ -129,7 +129,7 @@ public static class SettingsUpdater
         vm.IsIncludingSubdirectories = true;
         vm.IsIncludingSubdirectories = true;
         Settings.Sorting.IncludeSubDirectories = true;
         Settings.Sorting.IncludeSubDirectories = true;
         
         
-        await vm.ImageIterator.ReloadFileList();
+        await NavigationManager.ReloadFileListAsync().ConfigureAwait(false);
         SetTitleHelper.SetTitle(vm);
         SetTitleHelper.SetTitle(vm);
     }
     }
     
     
@@ -150,8 +150,8 @@ public static class SettingsUpdater
             {
             {
                 await Dispatcher.UIThread.InvokeAsync(() =>
                 await Dispatcher.UIThread.InvokeAsync(() =>
                 {
                 {
-                    vm.PlatformService.SetTaskbarProgress((ulong)vm.ImageIterator?.CurrentIndex!,
-                        (ulong)vm.ImageIterator?.ImagePaths?.Count!);
+                    vm.PlatformService.SetTaskbarProgress((ulong)NavigationManager.GetCurrentIndex,
+                        (ulong)NavigationManager.GetCount);
                 });
                 });
             }
             }
         }
         }
@@ -194,8 +194,15 @@ public static class SettingsUpdater
         vm.IsShowingSideBySide = true;
         vm.IsShowingSideBySide = true;
         if (NavigationManager.CanNavigate(vm))
         if (NavigationManager.CanNavigate(vm))
         {
         {
-            var preloadValue = await vm.ImageIterator?.GetNextPreLoadValueAsync();
-            vm.SecondaryImageSource = preloadValue?.ImageModel.Image;
+            var preloadValue = await NavigationManager.GetNextPreLoadValueAsync();
+            if (preloadValue is null)
+            {
+#if DEBUG
+                Console.WriteLine($"{nameof(TurnOnSideBySide)} {nameof(preloadValue)} is null");       
+#endif
+                return;
+            }
+            vm.SecondaryImageSource = preloadValue.ImageModel.Image;
             await Dispatcher.UIThread.InvokeAsync(() =>
             await Dispatcher.UIThread.InvokeAsync(() =>
             {
             {
                 WindowResizing.SetSize(vm.ImageWidth, vm.ImageHeight, preloadValue.ImageModel.PixelWidth,
                 WindowResizing.SetSize(vm.ImageWidth, vm.ImageHeight, preloadValue.ImageModel.PixelWidth,

+ 10 - 13
src/PicView.Avalonia/StartUp/QuickLoad.cs

@@ -44,8 +44,8 @@ public static class QuickLoad
         PreLoadValue? secondaryPreloadValue = null;
         PreLoadValue? secondaryPreloadValue = null;
         if (Settings.ImageScaling.ShowImageSideBySide)
         if (Settings.ImageScaling.ShowImageSideBySide)
         {
         {
-            vm.ImageIterator = new ImageIterator(fileInfo, vm);
-            secondaryPreloadValue = await vm.ImageIterator.GetNextPreLoadValueAsync();
+            NavigationManager.InitializeImageIterator(vm);
+            secondaryPreloadValue = await NavigationManager.GetNextPreLoadValueAsync();
             vm.SecondaryImageSource = secondaryPreloadValue?.ImageModel?.Image;
             vm.SecondaryImageSource = secondaryPreloadValue?.ImageModel?.Image;
         }
         }
         await Dispatcher.UIThread.InvokeAsync(() =>
         await Dispatcher.UIThread.InvokeAsync(() =>
@@ -64,8 +64,8 @@ public static class QuickLoad
 
 
         vm.IsLoading = false;
         vm.IsLoading = false;
         
         
-        vm.ImageIterator ??= new ImageIterator(fileInfo, vm);
-        vm.GetIndex = vm.ImageIterator.CurrentIndex + 1;
+        NavigationManager.InitializeImageIterator(vm);
+        vm.GetIndex = NavigationManager.GetNonZeroIndex;
 
 
         if (Settings.ImageScaling.ShowImageSideBySide)
         if (Settings.ImageScaling.ShowImageSideBySide)
         {
         {
@@ -82,7 +82,7 @@ public static class QuickLoad
         {
         {
             if (TiffManager.IsTiff(imageModel.FileInfo.FullName))
             if (TiffManager.IsTiff(imageModel.FileInfo.FullName))
             {
             {
-                SetTitleHelper.TrySetTiffTitle(imageModel.PixelWidth, imageModel.PixelHeight, vm.ImageIterator.CurrentIndex, fileInfo, vm);
+                SetTitleHelper.TrySetTiffTitle(imageModel.PixelWidth, imageModel.PixelHeight, NavigationManager.GetCurrentIndex, fileInfo, vm);
             }
             }
             else
             else
             {
             {
@@ -114,24 +114,21 @@ public static class QuickLoad
             FileHistoryNavigation.Add(fileInfo.FullName);
             FileHistoryNavigation.Add(fileInfo.FullName);
         }
         }
 
 
-        vm.ImageIterator.Add(vm.ImageIterator.CurrentIndex, imageModel);
+        NavigationManager.AddToPreloader(NavigationManager.GetCurrentIndex, imageModel);
         
         
-        var tasks = new List<Task>
-        {
-            vm.ImageIterator.AddAsync(vm.ImageIterator.CurrentIndex)
-        };
+        var tasks = new List<Task>();
         
         
-        if (vm.ImageIterator.ImagePaths.Count > 1)
+        if (NavigationManager.GetCount > 1)
         {
         {
             if (Settings.UIProperties.IsTaskbarProgressEnabled)
             if (Settings.UIProperties.IsTaskbarProgressEnabled)
             {
             {
                 await Dispatcher.UIThread.InvokeAsync(() =>
                 await Dispatcher.UIThread.InvokeAsync(() =>
                 {
                 {
-                    vm.PlatformService.SetTaskbarProgress((ulong)vm.ImageIterator.CurrentIndex, (ulong)vm.ImageIterator.ImagePaths.Count);
+                    vm.PlatformService.SetTaskbarProgress((ulong)NavigationManager.GetCurrentIndex, (ulong)NavigationManager.GetCount);
                 });
                 });
             }
             }
 
 
-            tasks.Add(vm.ImageIterator.Preload());
+            tasks.Add(NavigationManager.PreloadAsync());
         }
         }
 
 
         if (Settings.Gallery.IsBottomGalleryShown)
         if (Settings.Gallery.IsBottomGalleryShown)

+ 4 - 4
src/PicView.Avalonia/UI/HideInterfaceLogic.cs

@@ -142,7 +142,7 @@ public static class HideInterfaceLogic
                 return;
                 return;
             }
             }
             
             
-            if (vm.ImageIterator is null)
+            if (!NavigationManager.CanNavigate(vm))
             {
             {
                 Dispatcher.UIThread.Invoke(() =>
                 Dispatcher.UIThread.Invoke(() =>
                 {
                 {
@@ -152,7 +152,7 @@ public static class HideInterfaceLogic
                 return;
                 return;
             }
             }
 
 
-            if (vm.ImageIterator.ImagePaths?.Count <= 1)
+            if (NavigationManager.GetCount <= 1)
             {
             {
                 Dispatcher.UIThread.Invoke(() =>
                 Dispatcher.UIThread.Invoke(() =>
                 {
                 {
@@ -236,14 +236,14 @@ public static class HideInterfaceLogic
             return;
             return;
         }
         }
 
 
-        if (vm.ImageIterator is null)
+        if (!NavigationManager.CanNavigate(vm))
         {
         {
             parent.Opacity = 0;
             parent.Opacity = 0;
             childControl.Opacity = 0;
             childControl.Opacity = 0;
             return;
             return;
         }
         }
 
 
-        if (vm.ImageIterator.ImagePaths?.Count <= 1)
+        if (NavigationManager.GetCount <= 1)
         {
         {
             parent.Opacity = 0;
             parent.Opacity = 0;
             childControl.Opacity = 0;
             childControl.Opacity = 0;

+ 12 - 11
src/PicView.Avalonia/UI/SetTitleHelper.cs

@@ -1,4 +1,5 @@
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.ImageHandling;
+using PicView.Avalonia.Navigation;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHandling;
 using PicView.Core.ImageDecoding;
 using PicView.Core.ImageDecoding;
@@ -11,7 +12,7 @@ public static class SetTitleHelper
 {
 {
     public static void SetTitle(MainViewModel vm)
     public static void SetTitle(MainViewModel vm)
     {
     {
-        if (vm.ImageIterator is null || vm.FileInfo is null)
+        if (!NavigationManager.CanNavigate(vm))
         {
         {
             string title;
             string title;
             var s = vm.Title;
             var s = vm.Title;
@@ -35,8 +36,8 @@ public static class SetTitleHelper
             return;
             return;
         }
         }
 
 
-        var windowTitles = ImageTitleFormatter.GenerateTitleStrings(vm.PixelWidth, vm.PixelHeight, vm.ImageIterator.CurrentIndex,
-            vm.FileInfo, vm.ZoomValue, vm.ImageIterator.ImagePaths);
+        var windowTitles = ImageTitleFormatter.GenerateTitleStrings(vm.PixelWidth, vm.PixelHeight, NavigationManager.GetCurrentIndex,
+            vm.FileInfo, vm.ZoomValue, NavigationManager.GetCollection);
         vm.WindowTitle = windowTitles.TitleWithAppName;
         vm.WindowTitle = windowTitles.TitleWithAppName;
         vm.Title = windowTitles.BaseTitle;
         vm.Title = windowTitles.BaseTitle;
         vm.TitleTooltip = windowTitles.FilePathTitle;
         vm.TitleTooltip = windowTitles.FilePathTitle;
@@ -74,8 +75,8 @@ public static class SetTitleHelper
             return;
             return;
         }
         }
 
 
-        var windowTitles = ImageTitleFormatter.GenerateTitleStrings(imageModel.PixelWidth, imageModel.PixelHeight,  vm.ImageIterator.CurrentIndex,
-            imageModel.FileInfo,  vm.ZoomValue,  vm.ImageIterator.ImagePaths);
+        var windowTitles = ImageTitleFormatter.GenerateTitleStrings(imageModel.PixelWidth, imageModel.PixelHeight,  NavigationManager.GetCurrentIndex,
+            imageModel.FileInfo,  vm.ZoomValue,  NavigationManager.GetCollection);
         vm.WindowTitle = windowTitles.TitleWithAppName;
         vm.WindowTitle = windowTitles.TitleWithAppName;
         vm.Title = windowTitles.BaseTitle;
         vm.Title = windowTitles.BaseTitle;
         vm.TitleTooltip = windowTitles.FilePathTitle;
         vm.TitleTooltip = windowTitles.FilePathTitle;
@@ -93,7 +94,7 @@ public static class SetTitleHelper
     public static void SetTiffTitle(TiffManager.TiffNavigationInfo tiffNavigationInfo, int width, int height, int index, FileInfo fileInfo, MainViewModel vm)
     public static void SetTiffTitle(TiffManager.TiffNavigationInfo tiffNavigationInfo, int width, int height, int index, FileInfo fileInfo, MainViewModel vm)
     {
     {
         var name = tiffNavigationInfo.Pages[tiffNavigationInfo.CurrentPage].FileName + $" [{tiffNavigationInfo.CurrentPage + 1}/{tiffNavigationInfo.PageCount}]";
         var name = tiffNavigationInfo.Pages[tiffNavigationInfo.CurrentPage].FileName + $" [{tiffNavigationInfo.CurrentPage + 1}/{tiffNavigationInfo.PageCount}]";
-        var singeImageWindowTitles = ImageTitleFormatter.GenerateTiffTitleStrings(width, height, index, fileInfo, tiffNavigationInfo, 1, vm.ImageIterator.ImagePaths);
+        var singeImageWindowTitles = ImageTitleFormatter.GenerateTiffTitleStrings(width, height, index, fileInfo, tiffNavigationInfo, 1, NavigationManager.GetCollection);
         vm.WindowTitle = singeImageWindowTitles.TitleWithAppName;
         vm.WindowTitle = singeImageWindowTitles.TitleWithAppName;
         vm.Title = singeImageWindowTitles.BaseTitle; 
         vm.Title = singeImageWindowTitles.BaseTitle; 
         vm.TitleTooltip = singeImageWindowTitles.BaseTitle;
         vm.TitleTooltip = singeImageWindowTitles.BaseTitle;
@@ -110,7 +111,7 @@ public static class SetTitleHelper
                 Pages = TiffManager.LoadTiffPages(fileInfo.FullName)
                 Pages = TiffManager.LoadTiffPages(fileInfo.FullName)
             };
             };
             SetTiffTitle(tiffNavigationInfo, width, height,
             SetTiffTitle(tiffNavigationInfo, width, height,
-                vm.ImageIterator.CurrentIndex, fileInfo, vm);
+                NavigationManager.GetCurrentIndex, fileInfo, vm);
         }
         }
         else
         else
         {
         {
@@ -132,10 +133,10 @@ public static class SetTitleHelper
             return;
             return;
         }
         }
 
 
-        var firstWindowTitles = ImageTitleFormatter.GenerateTitleStrings(imageModel1.PixelWidth, imageModel1.PixelHeight,  vm.ImageIterator.CurrentIndex,
-            imageModel1.FileInfo,  vm.ZoomValue,  vm.ImageIterator.ImagePaths);
-        var secondWindowTitles = ImageTitleFormatter.GenerateTitleStrings(imageModel2.PixelWidth, imageModel2.PixelHeight,  vm.ImageIterator.NextIndex,
-            imageModel2.FileInfo,  vm.ZoomValue,  vm.ImageIterator.ImagePaths);
+        var firstWindowTitles = ImageTitleFormatter.GenerateTitleStrings(imageModel1.PixelWidth, imageModel1.PixelHeight,  NavigationManager.GetCurrentIndex,
+            imageModel1.FileInfo,  vm.ZoomValue,  NavigationManager.GetCollection);
+        var secondWindowTitles = ImageTitleFormatter.GenerateTitleStrings(imageModel2.PixelWidth, imageModel2.PixelHeight,  NavigationManager.GetNextIndex,
+            imageModel2.FileInfo,  vm.ZoomValue,  NavigationManager.GetCollection);
         var windowTitle = $"{firstWindowTitles.BaseTitle} \u21dc || \u21dd {secondWindowTitles.BaseTitle} - PicView";
         var windowTitle = $"{firstWindowTitles.BaseTitle} \u21dc || \u21dd {secondWindowTitles.BaseTitle} - PicView";
         var title = $"{firstWindowTitles.BaseTitle} \u21dc || \u21dd  {secondWindowTitles.BaseTitle}";
         var title = $"{firstWindowTitles.BaseTitle} \u21dc || \u21dd  {secondWindowTitles.BaseTitle}";
         var titleTooltip = $"{firstWindowTitles.FilePathTitle} \u21dc || \u21dd  {secondWindowTitles.FilePathTitle}";
         var titleTooltip = $"{firstWindowTitles.FilePathTitle} \u21dc || \u21dd  {secondWindowTitles.FilePathTitle}";

+ 1 - 8
src/PicView.Avalonia/ViewModels/ImageCropperViewModel.cs

@@ -163,14 +163,7 @@ public class ImageCropperViewModel : ViewModelBase
     }
     }
 
 
     private (string fileName, FileInfo fileInfo, Bitmap? bitmap) PrepareCropData(MainViewModel vm)
     private (string fileName, FileInfo fileInfo, Bitmap? bitmap) PrepareCropData(MainViewModel vm)
-    {
-        if (vm.ImageIterator?.ImagePaths is null || vm.ImageIterator.ImagePaths.Count < 0)
-        {
-            return CreateNewCroppedImage();
-        }
-        
-        return (vm.FileInfo.FullName, vm.FileInfo, null);
-    }
+      => NavigationManager.IsCollectionEmpty ? CreateNewCroppedImage() : (vm.FileInfo.FullName, vm.FileInfo, null);
 
 
     private (string fileName, FileInfo fileInfo, Bitmap bitmap) CreateNewCroppedImage()
     private (string fileName, FileInfo fileInfo, Bitmap bitmap) CreateNewCroppedImage()
     {
     {

+ 1 - 20
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -1186,12 +1186,6 @@ public class MainViewModel : ViewModelBase
 
 
     #endregion Fields
     #endregion Fields
 
 
-    #region Services
-
-    public ImageIterator? ImageIterator;
-
-    #endregion Services
-
     #region Methods
     #region Methods
 
 
     #region Sorting Order
     #region Sorting Order
@@ -1216,10 +1210,7 @@ public class MainViewModel : ViewModelBase
         var success = await ConversionHelper.ResizeImageByPercentage(FileInfo, percentage);
         var success = await ConversionHelper.ResizeImageByPercentage(FileInfo, percentage);
         if (success)
         if (success)
         {
         {
-            if (ImageIterator is not null)
-            {
-                await ImageIterator.QuickReload().ConfigureAwait(false);
-            }
+            await NavigationManager.QuickReload();
         }
         }
         else
         else
         {
         {
@@ -1299,21 +1290,11 @@ public class MainViewModel : ViewModelBase
         {
         {
             try
             try
             {
             {
-                var index = ImageIterator?.ImagePaths.IndexOf(path);
-                if (!index.HasValue)
-                {
-                    return;
-                }
-
                 var errorMsg = FileDeletionHelper.DeleteFileWithErrorMsg(path, recycle: false);
                 var errorMsg = FileDeletionHelper.DeleteFileWithErrorMsg(path, recycle: false);
                 if (!string.IsNullOrWhiteSpace(errorMsg))
                 if (!string.IsNullOrWhiteSpace(errorMsg))
                 {
                 {
                     _ = TooltipHelper.ShowTooltipMessageAsync(errorMsg);
                     _ = TooltipHelper.ShowTooltipMessageAsync(errorMsg);
                 }
                 }
-                else
-                {
-                    ImageIterator?.RemoveItemFromPreLoader(index.Value);
-                }
             }
             }
             catch (Exception e)
             catch (Exception e)
             {
             {

+ 2 - 6
src/PicView.Avalonia/Views/ExifView.axaml.cs

@@ -160,10 +160,7 @@ public partial class ExifView : UserControl
                 var success = await ConversionHelper.ResizeByWidth(vm.FileInfo, widthValue).ConfigureAwait(false);
                 var success = await ConversionHelper.ResizeByWidth(vm.FileInfo, widthValue).ConfigureAwait(false);
                 if (success)
                 if (success)
                 {
                 {
-                    if (vm.ImageIterator is not null)
-                    {
-                        await vm.ImageIterator.QuickReload().ConfigureAwait(false);
-                    }
+                    await NavigationManager.QuickReload().ConfigureAwait(false);
                 }
                 }
             }
             }
         }
         }
@@ -178,8 +175,7 @@ public partial class ExifView : UserControl
                 var success = await ConversionHelper.ResizeByHeight(vm.FileInfo, heightValue).ConfigureAwait(false);
                 var success = await ConversionHelper.ResizeByHeight(vm.FileInfo, heightValue).ConfigureAwait(false);
                 if (success)
                 if (success)
                 {
                 {
-                    vm.ImageIterator?.RemoveCurrentItemFromPreLoader();
-                    await NavigationManager.Navigate(vm.ImageIterator.CurrentIndex, vm).ConfigureAwait(false);
+                    await NavigationManager.QuickReload().ConfigureAwait(false);
                 }
                 }
             }
             }
         }
         }

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

@@ -139,7 +139,7 @@ public partial class MainView : UserControl
 #endif
 #endif
             var secondaryAccentBrush = (SolidColorBrush)secondaryAccentColor;
             var secondaryAccentBrush = (SolidColorBrush)secondaryAccentColor;
             var fileLocation = FileHistoryNavigation.GetFileLocation(index);
             var fileLocation = FileHistoryNavigation.GetFileLocation(index);
-            var selected = vm.ImageIterator?.CurrentIndex == vm.ImageIterator?.ImagePaths.IndexOf(fileLocation);
+            var selected = NavigationManager.GetCurrentIndex == NavigationManager.GetCollection.IndexOf(fileLocation);
             var header = Path.GetFileNameWithoutExtension(fileLocation);
             var header = Path.GetFileNameWithoutExtension(fileLocation);
             header = header.Length > 60 ? header.Shorten(60) : header;
             header = header.Length > 60 ? header.Shorten(60) : header;
         
         

+ 1 - 4
src/PicView.Avalonia/Views/SingleImageResizeView.axaml.cs

@@ -239,10 +239,7 @@ public partial class SingleImageResizeView : UserControl
     {
     {
         if (destination == file)
         if (destination == file)
         {
         {
-            if (NavigationManager.CanNavigate(vm) && vm.ImageIterator is not null)
-            {
-                await vm.ImageIterator.QuickReload().ConfigureAwait(false);
-            }
+            await NavigationManager.QuickReload().ConfigureAwait(false);
         }
         }
         else if (Path.GetDirectoryName(file) == Path.GetDirectoryName(destination))
         else if (Path.GetDirectoryName(file) == Path.GetDirectoryName(destination))
         {
         {

+ 10 - 13
src/PicView.Avalonia/Views/UC/EditableTitlebar.axaml.cs

@@ -143,7 +143,14 @@ public partial class EditableTitlebar : UserControl
         // Check if the file is being moved to a different directory
         // Check if the file is being moved to a different directory
         if (Path.GetDirectoryName(oldPath) != Path.GetDirectoryName(newPath))
         if (Path.GetDirectoryName(oldPath) != Path.GetDirectoryName(newPath))
         {
         {
-            vm.ImageIterator?.RemoveCurrentItemFromPreLoader();
+            await Dispatcher.UIThread.InvokeAsync(() =>
+            {
+                TextBox.ClearSelection();
+                Cursor = new Cursor(StandardCursorType.Arrow);
+                MainKeyboardShortcuts.IsKeysEnabled = true;
+                UIHelper.GetMainView.Focus();
+            });
+            NavigationManager.RemoveCurrentItemFromPreLoader();
             await NavigationManager.Navigate(true, vm);
             await NavigationManager.Navigate(true, vm);
             FileHelper.RenameFile(oldPath, newPath);
             FileHelper.RenameFile(oldPath, newPath);
             return;
             return;
@@ -161,7 +168,7 @@ public partial class EditableTitlebar : UserControl
             if (saved)
             if (saved)
             {
             {
                 // Delete old file
                 // Delete old file
-                vm.ImageIterator?.RemoveItemFromPreLoader(oldPath);
+                NavigationManager.RemoveItemFromPreLoader(oldPath);
                 
                 
                 var deleteMsg = FileDeletionHelper.DeleteFileWithErrorMsg(oldPath, false);
                 var deleteMsg = FileDeletionHelper.DeleteFileWithErrorMsg(oldPath, false);
                 if (!string.IsNullOrWhiteSpace(deleteMsg))
                 if (!string.IsNullOrWhiteSpace(deleteMsg))
@@ -199,17 +206,7 @@ public partial class EditableTitlebar : UserControl
                 UIHelper.GetMainView.Focus();
                 UIHelper.GetMainView.Focus();
             });
             });
             vm.IsEditableTitlebarOpen = false;
             vm.IsEditableTitlebarOpen = false;
-            await vm.ImageIterator?.ResynchronizeAsync();
-            vm.FileInfo = new FileInfo(newPath);
-            SetTitleHelper.RefreshTitle(vm);
-            if (vm.Title == TranslationHelper.Translation.UnexpectedError)
-            {
-                var preloadValue = await vm.ImageIterator?.GetCurrentPreLoadValueAsync();
-                if (preloadValue?.ImageModel is not null)
-                {
-                    SetTitleHelper.SetTitle(vm, preloadValue.ImageModel);
-                }
-            }
+            await NavigationManager.LoadPicFromFile(newPath, vm);
         }
         }
     }
     }
     
     

+ 2 - 2
src/PicView.Avalonia/Views/UC/Menus/ImageMenu.axaml.cs

@@ -66,9 +66,9 @@ public partial class ImageMenu  : AnimatedMenu
             {
             {
                 number = 0;
                 number = 0;
             }
             }
-            else if (number > vm.ImageIterator?.ImagePaths?.Count)
+            else if (number > NavigationManager.GetCount)
             {
             {
-                number = vm.ImageIterator?.ImagePaths?.Count - 1 ?? 0;
+                number = NavigationManager.GetCount - 1;
             }
             }
             else
             else
             {
             {

+ 6 - 7
src/PicView.Avalonia/WindowBehavior/WindowResizing.cs

@@ -4,10 +4,10 @@ using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Media.Imaging;
 using Avalonia.Media.Imaging;
 using Avalonia.Threading;
 using Avalonia.Threading;
 using ImageMagick;
 using ImageMagick;
+using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.Calculations;
 using PicView.Core.Calculations;
-using PicView.Core.Navigation;
 
 
 namespace PicView.Avalonia.WindowBehavior;
 namespace PicView.Avalonia.WindowBehavior;
 
 
@@ -51,7 +51,7 @@ public static class WindowResizing
     public static void SetSize(MainViewModel vm)
     public static void SetSize(MainViewModel vm)
     {
     {
         double firstWidth, firstHeight;
         double firstWidth, firstHeight;
-        var preloadValue = vm.ImageIterator?.GetCurrentPreLoadValue();
+        var preloadValue = NavigationManager.GetCurrentPreLoadValue();
         if (preloadValue == null)
         if (preloadValue == null)
         {
         {
             if (vm.FileInfo is null)
             if (vm.FileInfo is null)
@@ -86,19 +86,18 @@ public static class WindowResizing
 
 
         if (Settings.ImageScaling.ShowImageSideBySide)
         if (Settings.ImageScaling.ShowImageSideBySide)
         {
         {
-            var secondaryPreloadValue = vm.ImageIterator?.GetNextPreLoadValue();
+            var secondaryPreloadValue = NavigationManager.GetNextPreLoadValue();
             double secondWidth, secondHeight;
             double secondWidth, secondHeight;
             if (secondaryPreloadValue != null)
             if (secondaryPreloadValue != null)
             {
             {
                 secondWidth = GetWidth();
                 secondWidth = GetWidth();
                 secondHeight = GetHeight();
                 secondHeight = GetHeight();
             }
             }
-            else if (vm.ImageIterator is not null)
+            else if (NavigationManager.CanNavigate(vm))
             {
             {
-                var nextIndex = vm.ImageIterator.GetIteration(vm.ImageIterator.CurrentIndex,
-                    vm.ImageIterator.IsReversed ? NavigateTo.Previous : NavigateTo.Next);
+                var nextFileName = NavigationManager.GetNextFileName;
                 var magickImage = new MagickImage();
                 var magickImage = new MagickImage();
-                magickImage.Ping(vm.ImageIterator.ImagePaths[nextIndex]);
+                magickImage.Ping(nextFileName);
                 secondWidth = magickImage.Width;
                 secondWidth = magickImage.Width;
                 secondHeight = magickImage.Height;
                 secondHeight = magickImage.Height;
             }
             }