浏览代码

Avalonia updates

Ruben 1 年之前
父节点
当前提交
1002280b30

+ 26 - 13
src/PicView.Avalonia.MacOS/App.axaml.cs

@@ -1,22 +1,23 @@
 using Avalonia;
 using Avalonia;
+using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.ApplicationLifetimes;
+using PicView.Avalonia.Helpers;
 using PicView.Avalonia.MacOS.Views;
 using PicView.Avalonia.MacOS.Views;
+using PicView.Avalonia.Services;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
-using System.Runtime;
+using PicView.Core.Config;
+using PicView.Core.FileHandling;
+using PicView.Core.Localization;
 using System;
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
+using System.Runtime;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
-using PicView.Core.Config;
-using PicView.Core.Localization;
-using Avalonia.Controls;
-using PicView.Avalonia.Helpers;
-using PicView.Core.FileHandling;
-using ReactiveUI;
 
 
 namespace PicView.Avalonia.MacOS;
 namespace PicView.Avalonia.MacOS;
 
 
-public partial class App : Application
+public partial class App : Application, IPlatformSpecificService
 {
 {
     public override void Initialize()
     public override void Initialize()
     {
     {
@@ -42,11 +43,7 @@ public partial class App : Application
             return;
             return;
         }
         }
         var w = desktop.MainWindow = new MacMainWindow();
         var w = desktop.MainWindow = new MacMainWindow();
-        var vm = new MainViewModel();
-        vm.RetrieveFilesCommand = ReactiveCommand.Create(() =>
-        {
-            vm.Pics = FileListHelper.RetrieveFiles(vm.FileInfo).ToList();
-        });
+        var vm = new MainViewModel(this);
         w.DataContext = vm;
         w.DataContext = vm;
         if (SettingsHelper.Settings.WindowProperties.AutoFit)
         if (SettingsHelper.Settings.WindowProperties.AutoFit)
         {
         {
@@ -65,4 +62,20 @@ public partial class App : Application
         await vm.StartUpTask();
         await vm.StartUpTask();
         base.OnFrameworkInitializationCompleted();
         base.OnFrameworkInitializationCompleted();
     }
     }
+
+    public void SetCursorPos(int x, int y)
+    {
+        // TODO: Implement SetCursorPos
+    }
+
+    public List<string> GetFiles(FileInfo fileInfo)
+    {
+        var files = FileListHelper.RetrieveFiles(fileInfo);
+        return SortHelper.SortIEnumerable(files, this);
+    }
+
+    public int CompareStrings(string str1, string str2)
+    {
+        return string.CompareOrdinal(str1, str2);
+    }
 }
 }

+ 24 - 7
src/PicView.Avalonia.Win32/App.axaml.cs

@@ -3,18 +3,23 @@ using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Markup.Xaml;
 using Avalonia.Markup.Xaml;
 using PicView.Avalonia.Helpers;
 using PicView.Avalonia.Helpers;
+using PicView.Avalonia.Services;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Win32.Views;
 using PicView.Avalonia.Win32.Views;
 using PicView.Core.Config;
 using PicView.Core.Config;
+using PicView.Core.FileHandling;
 using PicView.Core.Localization;
 using PicView.Core.Localization;
-using ReactiveUI;
+using System.Runtime;
+using SortHelper = PicView.Avalonia.Helpers.SortHelper;
 
 
 namespace PicView.Avalonia.Win32;
 namespace PicView.Avalonia.Win32;
 
 
-public class App : Application
+public class App : Application, IPlatformSpecificService
 {
 {
     public override void Initialize()
     public override void Initialize()
     {
     {
+        ProfileOptimization.SetProfileRoot(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config/"));
+        ProfileOptimization.StartProfile("ProfileOptimization");
         AvaloniaXamlLoader.Load(this);
         AvaloniaXamlLoader.Load(this);
     }
     }
 
 
@@ -35,11 +40,7 @@ public class App : Application
             return;
             return;
         }
         }
         var w = desktop.MainWindow = new WinMainWindow();
         var w = desktop.MainWindow = new WinMainWindow();
-        var vm = new MainViewModel();
-        vm.RetrieveFilesCommand = ReactiveCommand.Create(() =>
-        {
-            vm.Pics = Windows.FileHandling.GetFileList.Get(vm.FileInfo);
-        });
+        var vm = new MainViewModel(this);
         w.DataContext = vm;
         w.DataContext = vm;
         if (SettingsHelper.Settings.WindowProperties.AutoFit)
         if (SettingsHelper.Settings.WindowProperties.AutoFit)
         {
         {
@@ -58,4 +59,20 @@ public class App : Application
         await vm.StartUpTask();
         await vm.StartUpTask();
         base.OnFrameworkInitializationCompleted();
         base.OnFrameworkInitializationCompleted();
     }
     }
+
+    public void SetCursorPos(int x, int y)
+    {
+        Windows.NativeMethods.SetCursorPos(x, y);
+    }
+
+    public List<string> GetFiles(FileInfo fileInfo)
+    {
+        var files = FileListHelper.RetrieveFiles(fileInfo);
+        return SortHelper.SortIEnumerable(files, this);
+    }
+
+    public int CompareStrings(string str1, string str2)
+    {
+        return Windows.NativeMethods.StrCmpLogicalW(str1, str2);
+    }
 }
 }

+ 7 - 10
src/PicView.Windows/FileHandling/GetFileList.cs → src/PicView.Avalonia/Helpers/SortHelper.cs

@@ -1,16 +1,13 @@
-using PicView.Core.Config;
+using PicView.Avalonia.Services;
+using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHandling;
 
 
-namespace PicView.Windows.FileHandling;
+namespace PicView.Avalonia.Helpers;
 
 
-public static class GetFileList
+public static class SortHelper
 {
 {
-    public static List<string> Get(FileInfo fileInfo)
+    public static List<string> SortIEnumerable(IEnumerable<string> files, IPlatformSpecificService platformService)
     {
     {
-        if (fileInfo == null)
-            return [];
-
-        var files = FileListHelper.RetrieveFiles(fileInfo);
         var sortFilesBy = FileListHelper.GetSortOrder();
         var sortFilesBy = FileListHelper.GetSortOrder();
 
 
         switch (sortFilesBy)
         switch (sortFilesBy)
@@ -20,11 +17,11 @@ public static class GetFileList
                 var list = files.ToList();
                 var list = files.ToList();
                 if (SettingsHelper.Settings.Sorting.Ascending)
                 if (SettingsHelper.Settings.Sorting.Ascending)
                 {
                 {
-                    list.Sort(NativeMethods.StrCmpLogicalW);
+                    list.Sort(platformService.CompareStrings);
                 }
                 }
                 else
                 else
                 {
                 {
-                    list.Sort((x, y) => NativeMethods.StrCmpLogicalW(y, x));
+                    list.Sort((x, y) => platformService.CompareStrings(y, x));
                 }
                 }
 
 
                 return list;
                 return list;

+ 44 - 47
src/PicView.Avalonia/Navigation/ImageIterator.cs

@@ -15,6 +15,8 @@ namespace PicView.Avalonia.Navigation
 
 
         public event FileSystemEventHandler? FileRenamed;
         public event FileSystemEventHandler? FileRenamed;
 
 
+        public List<string> Pics { get; set; }
+
         public int Index;
         public int Index;
         public FileInfo FileInfo;
         public FileInfo FileInfo;
         public bool Reverse;
         public bool Reverse;
@@ -22,37 +24,41 @@ namespace PicView.Avalonia.Navigation
 
 
         private static FileSystemWatcher? _watcher;
         private static FileSystemWatcher? _watcher;
         private static bool _running;
         private static bool _running;
+        private readonly IPlatformSpecificService _platformService;
 
 
-        public ImageIterator(FileInfo fileInfo, List<string> pics)
+        public ImageIterator(FileInfo fileInfo, IPlatformSpecificService platformService)
         {
         {
             ArgumentNullException.ThrowIfNull(fileInfo);
             ArgumentNullException.ThrowIfNull(fileInfo);
 
 
             FileInfo = fileInfo;
             FileInfo = fileInfo;
-            Index = pics.IndexOf(fileInfo.FullName);
-            _watcher ??= new FileSystemWatcher();
+
+            _platformService = platformService;
+            Pics = _platformService.GetFiles(fileInfo);
+            Index = Pics.IndexOf(fileInfo.FullName);
 #if DEBUG
 #if DEBUG
             Debug.Assert(fileInfo.DirectoryName != null, "fileInfo.DirectoryName != null");
             Debug.Assert(fileInfo.DirectoryName != null, "fileInfo.DirectoryName != null");
 #endif
 #endif
+            _watcher ??= new FileSystemWatcher();
             _watcher.Path = fileInfo.DirectoryName;
             _watcher.Path = fileInfo.DirectoryName;
             _watcher.EnableRaisingEvents = true;
             _watcher.EnableRaisingEvents = true;
             _watcher.Filter = "*.*";
             _watcher.Filter = "*.*";
             _watcher.IncludeSubdirectories = SettingsHelper.Settings.Sorting.IncludeSubDirectories;
             _watcher.IncludeSubdirectories = SettingsHelper.Settings.Sorting.IncludeSubDirectories;
-            _watcher.Created += async (_, e) => await OnFileAdded(e, pics).ConfigureAwait(false);
-            _watcher.Deleted += (_, e) => OnFileDeleted(e, pics);
-            _watcher.Renamed += (_, e) => OnFileRenamed(e, pics);
+            _watcher.Created += async (_, e) => await OnFileAdded(e).ConfigureAwait(false);
+            _watcher.Deleted += (_, e) => OnFileDeleted(e);
+            _watcher.Renamed += (_, e) => OnFileRenamed(e);
         }
         }
 
 
-        public async Task Preload(ImageService imageService, List<string> pics)
+        public async Task Preload(ImageService imageService)
         {
         {
-            await PreLoader.PreLoadAsync(Index, pics.Count, Reverse, imageService, pics).ConfigureAwait(false);
+            await PreLoader.PreLoadAsync(Index, Pics.Count, Reverse, imageService, Pics).ConfigureAwait(false);
         }
         }
 
 
-        public async Task AddAsync(int index, ImageService imageService, ImageModel imageModel, List<string> pics)
+        public async Task AddAsync(int index, ImageService imageService, ImageModel imageModel)
         {
         {
-            await PreLoader.AddAsync(index, imageService, pics, imageModel).ConfigureAwait(false);
+            await PreLoader.AddAsync(index, imageService, Pics, imageModel).ConfigureAwait(false);
         }
         }
 
 
-        public int GetIteration(int index, NavigateTo navigateTo, List<string> pics)
+        public int GetIteration(int index, NavigateTo navigateTo)
         {
         {
             int next;
             int next;
             switch (navigateTo)
             switch (navigateTo)
@@ -63,7 +69,7 @@ namespace PicView.Avalonia.Navigation
                     Reverse = navigateTo == NavigateTo.Previous;
                     Reverse = navigateTo == NavigateTo.Previous;
                     if (SettingsHelper.Settings.UIProperties.Looping)
                     if (SettingsHelper.Settings.UIProperties.Looping)
                     {
                     {
-                        next = (index + indexChange + pics.Count) % pics.Count;
+                        next = (index + indexChange + Pics.Count) % Pics.Count;
                     }
                     }
                     else
                     else
                     {
                     {
@@ -72,9 +78,9 @@ namespace PicView.Avalonia.Navigation
                         {
                         {
                             return 0;
                             return 0;
                         }
                         }
-                        if (newIndex >= pics.Count)
+                        if (newIndex >= Pics.Count)
                         {
                         {
-                            return pics.Count - 1;
+                            return Pics.Count - 1;
                         }
                         }
                         next = newIndex;
                         next = newIndex;
                     }
                     }
@@ -83,9 +89,9 @@ namespace PicView.Avalonia.Navigation
 
 
                 case NavigateTo.First:
                 case NavigateTo.First:
                 case NavigateTo.Last:
                 case NavigateTo.Last:
-                    if (pics.Count > PreLoader.MaxCount)
+                    if (Pics.Count > PreLoader.MaxCount)
                         PreLoader.Clear();
                         PreLoader.Clear();
-                    next = navigateTo == NavigateTo.First ? 0 : pics.Count - 1;
+                    next = navigateTo == NavigateTo.First ? 0 : Pics.Count - 1;
                     break;
                     break;
 
 
                 default: return -1;
                 default: return -1;
@@ -93,21 +99,21 @@ namespace PicView.Avalonia.Navigation
             return next;
             return next;
         }
         }
 
 
-        private void OnFileRenamed(RenamedEventArgs e, List<string> pics)
+        private void OnFileRenamed(RenamedEventArgs e)
         {
         {
             if (e.FullPath.IsSupported() == false)
             if (e.FullPath.IsSupported() == false)
             {
             {
-                if (pics.Contains(e.OldFullPath))
+                if (Pics.Contains(e.OldFullPath))
                 {
                 {
-                    pics.Remove(e.OldFullPath);
+                    Pics.Remove(e.OldFullPath);
                 }
                 }
                 return;
                 return;
             }
             }
             if (_running) { return; }
             if (_running) { return; }
             _running = true;
             _running = true;
 
 
-            var oldIndex = pics.IndexOf(e.OldFullPath);
-            var sameFile = Index == pics.IndexOf(e.OldFullPath);
+            var oldIndex = Pics.IndexOf(e.OldFullPath);
+            var sameFile = Index == Pics.IndexOf(e.OldFullPath);
 
 
             var fileInfo = new FileInfo(e.FullPath);
             var fileInfo = new FileInfo(e.FullPath);
             if (fileInfo.Exists == false) { return; }
             if (fileInfo.Exists == false) { return; }
@@ -117,9 +123,9 @@ namespace PicView.Avalonia.Navigation
 
 
             if (fileInfo.Exists == false) { return; }
             if (fileInfo.Exists == false) { return; }
 
 
-            pics = newList;
+            Pics = newList;
 
 
-            var index = pics.IndexOf(e.FullPath);
+            var index = Pics.IndexOf(e.FullPath);
             if (index < 0) { return; }
             if (index < 0) { return; }
 
 
             if (fileInfo.Exists == false)
             if (fileInfo.Exists == false)
@@ -127,7 +133,7 @@ namespace PicView.Avalonia.Navigation
                 return;
                 return;
             }
             }
 
 
-            PreLoader.Remove(index, pics);
+            PreLoader.Remove(index, Pics);
 
 
             _running = false;
             _running = false;
             //FileHistoryNavigation.Rename(e.OldFullPath, e.FullPath);
             //FileHistoryNavigation.Rename(e.OldFullPath, e.FullPath);
@@ -136,46 +142,37 @@ namespace PicView.Avalonia.Navigation
             FileRenamed?.Invoke(this, e);
             FileRenamed?.Invoke(this, e);
         }
         }
 
 
-        private void OnFileDeleted(FileSystemEventArgs e, List<string> pics)
+        private void OnFileDeleted(FileSystemEventArgs e)
         {
         {
             if (e.FullPath.IsSupported() == false)
             if (e.FullPath.IsSupported() == false)
             {
             {
                 return;
                 return;
             }
             }
 
 
-            if (pics.Contains(e.FullPath) == false)
+            if (Pics.Contains(e.FullPath) == false)
             {
             {
                 return;
                 return;
             }
             }
 
 
             if (_running) { return; }
             if (_running) { return; }
             _running = true;
             _running = true;
-            var sameFile = Index == pics.IndexOf(e.FullPath);
-            if (!pics.Remove(e.FullPath))
+            var sameFile = Index == Pics.IndexOf(e.FullPath);
+            if (!Pics.Remove(e.FullPath))
             {
             {
                 return;
                 return;
             }
             }
             Index--;
             Index--;
 
 
-            PreLoader.Remove(Index, pics);
-
-            if (sameFile)
-            {
-                //await Navigation.GoToNextImage(NavigateTo.Previous).ConfigureAwait(false);
-            }
-            else
-            {
-                //await UpdateTitle(Navigation.FolderIndex);
-            }
+            PreLoader.Remove(Index, Pics);
             _running = false;
             _running = false;
 
 
             //FileHistoryNavigation.Remove(e.FullPath);
             //FileHistoryNavigation.Remove(e.FullPath);
             FileDeleted?.Invoke(this, sameFile);
             FileDeleted?.Invoke(this, sameFile);
         }
         }
 
 
-        private async Task OnFileAdded(FileSystemEventArgs e, List<string> pics)
+        private async Task OnFileAdded(FileSystemEventArgs e)
         {
         {
-            if (pics.Contains(e.FullPath))
+            if (Pics.Contains(e.FullPath))
             {
             {
                 return;
                 return;
             }
             }
@@ -189,30 +186,30 @@ namespace PicView.Avalonia.Navigation
             if (_running) { return; }
             if (_running) { return; }
             _running = true;
             _running = true;
 
 
-            var newList = await Task.FromResult(FileListHelper.RetrieveFiles(fileInfo).ToList()); // TODO update to sync with platform
+            var newList = await Task.FromResult(_platformService.GetFiles(fileInfo));
             if (newList.Count == 0) { return; }
             if (newList.Count == 0) { return; }
-            if (newList.Count == pics.Count) { return; }
+            if (newList.Count == Pics.Count) { return; }
 
 
             if (fileInfo.Exists == false) { return; }
             if (fileInfo.Exists == false) { return; }
 
 
-            pics = newList;
+            Pics = newList;
 
 
             _running = false;
             _running = false;
 
 
-            var index = pics.IndexOf(e.FullPath);
+            var index = Pics.IndexOf(e.FullPath);
             if (index < 0) { return; }
             if (index < 0) { return; }
 
 
             var nextIndex = index + 1;
             var nextIndex = index + 1;
-            if (index >= pics.Count)
+            if (index >= Pics.Count)
             {
             {
                 nextIndex = 0;
                 nextIndex = 0;
             }
             }
             var prevIndex = index - 1;
             var prevIndex = index - 1;
             if (prevIndex < 0)
             if (prevIndex < 0)
             {
             {
-                prevIndex = pics.Count - 1;
+                prevIndex = Pics.Count - 1;
             }
             }
-            if (PreLoader.Contains(index, pics) || PreLoader.Contains(nextIndex, pics) || PreLoader.Contains(prevIndex, pics))
+            if (PreLoader.Contains(index, Pics) || PreLoader.Contains(nextIndex, Pics) || PreLoader.Contains(prevIndex, Pics))
             {
             {
                 PreLoader.Clear();
                 PreLoader.Clear();
             }
             }

+ 16 - 0
src/PicView.Avalonia/Services/IPlatformSpecificService.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PicView.Avalonia.Services;
+
+public interface IPlatformSpecificService
+{
+    void SetCursorPos(int x, int y);
+
+    List<string> GetFiles(FileInfo fileInfo);
+
+    int CompareStrings(string str1, string str2);
+}

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

@@ -35,12 +35,10 @@ namespace PicView.Avalonia.ViewModels
 
 
         public event EventHandler<ImageModel>? ImageChanged;
         public event EventHandler<ImageModel>? ImageChanged;
 
 
-        public List<string>? Pics { get; set; }
+        private readonly IPlatformSpecificService _platformService;
 
 
         #region Commands
         #region Commands
 
 
-        public ICommand? RetrieveFilesCommand;
-
         public ICommand? ExitCommand { get; }
         public ICommand? ExitCommand { get; }
         public ICommand? MinimizeCommand { get; }
         public ICommand? MinimizeCommand { get; }
         public ICommand? MaximizeCommand { get; }
         public ICommand? MaximizeCommand { get; }
@@ -796,7 +794,7 @@ namespace PicView.Avalonia.ViewModels
             {
             {
                 return;
                 return;
             }
             }
-            var preloadValue = ImageIterator?.PreLoader.Get(ImageIterator.Index, Pics);
+            var preloadValue = ImageIterator?.PreLoader.Get(ImageIterator.Index, ImageIterator.Pics);
             SetSize(preloadValue?.ImageModel?.PixelWidth ?? (int)ImageWidth, preloadValue?.ImageModel?.PixelHeight ?? (int)ImageHeight, RotationAngle);
             SetSize(preloadValue?.ImageModel?.PixelWidth ?? (int)ImageWidth, preloadValue?.ImageModel?.PixelHeight ?? (int)ImageHeight, RotationAngle);
         }
         }
 
 
@@ -1086,7 +1084,7 @@ namespace PicView.Avalonia.ViewModels
             }
             }
 
 
             var titleString = TitleHelper.GetTitle(imageModel.PixelWidth, imageModel.PixelHeight, imageIterator.Index,
             var titleString = TitleHelper.GetTitle(imageModel.PixelWidth, imageModel.PixelHeight, imageIterator.Index,
-                imageModel.FileInfo, ZoomValue, Pics);
+                imageModel.FileInfo, ZoomValue, imageIterator.Pics);
             WindowTitle = titleString[0];
             WindowTitle = titleString[0];
             Title = titleString[1];
             Title = titleString[1];
             TitleTooltip = titleString[2];
             TitleTooltip = titleString[2];
@@ -1112,7 +1110,7 @@ namespace PicView.Avalonia.ViewModels
             }
             }
 
 
             var titleString = TitleHelper.GetTitle((int)ImageWidth, (int)ImageHeight, ImageIterator.Index,
             var titleString = TitleHelper.GetTitle((int)ImageWidth, (int)ImageHeight, ImageIterator.Index,
-                    FileInfo, ZoomValue, Pics);
+                    FileInfo, ZoomValue, ImageIterator.Pics);
             WindowTitle = titleString[0];
             WindowTitle = titleString[0];
             Title = titleString[1];
             Title = titleString[1];
             TitleTooltip = titleString[2];
             TitleTooltip = titleString[2];
@@ -1136,7 +1134,7 @@ namespace PicView.Avalonia.ViewModels
             {
             {
                 return;
                 return;
             }
             }
-            var index = ImageIterator.GetIteration(ImageIterator.Index, navigateTo, Pics);
+            var index = ImageIterator.GetIteration(ImageIterator.Index, navigateTo);
             if (index < 0)
             if (index < 0)
             {
             {
                 return;
                 return;
@@ -1155,7 +1153,7 @@ namespace PicView.Avalonia.ViewModels
             {
             {
                 ImageIterator.Index = index;
                 ImageIterator.Index = index;
 
 
-                var preLoadValue = ImageIterator.PreLoader.Get(index, Pics);
+                var preLoadValue = ImageIterator.PreLoader.Get(index, ImageIterator.Pics);
                 var viewChanged = false;
                 var viewChanged = false;
                 var x = 0;
                 var x = 0;
                 if (preLoadValue is not null)
                 if (preLoadValue is not null)
@@ -1164,7 +1162,7 @@ namespace PicView.Avalonia.ViewModels
                     {
                     {
                         SetLoadingTitle();
                         SetLoadingTitle();
                         using var image = new MagickImage();
                         using var image = new MagickImage();
-                        image.Ping(Pics[index]);
+                        image.Ping(ImageIterator.Pics[index]);
                         var thumb = image.GetExifProfile()?.CreateThumbnail();
                         var thumb = image.GetExifProfile()?.CreateThumbnail();
                         if (thumb is not null)
                         if (thumb is not null)
                         {
                         {
@@ -1184,7 +1182,7 @@ namespace PicView.Avalonia.ViewModels
                         await Task.Delay(20);
                         await Task.Delay(20);
                         if (ImageIterator.Index != index)
                         if (ImageIterator.Index != index)
                         {
                         {
-                            await ImageIterator.Preload(ImageService, Pics);
+                            await ImageIterator.Preload(ImageService);
                             CurrentView = ImageViewer;
                             CurrentView = ImageViewer;
                             return;
                             return;
                         }
                         }
@@ -1210,7 +1208,7 @@ namespace PicView.Avalonia.ViewModels
 
 
                 if (ImageIterator.Index != index)
                 if (ImageIterator.Index != index)
                 {
                 {
-                    await ImageIterator.Preload(ImageService, Pics);
+                    await ImageIterator.Preload(ImageService);
                     return;
                     return;
                 }
                 }
 
 
@@ -1219,18 +1217,18 @@ namespace PicView.Avalonia.ViewModels
                 SetTitle(preLoadValue.ImageModel, ImageIterator);
                 SetTitle(preLoadValue.ImageModel, ImageIterator);
                 GetIndex = ImageIterator.Index + 1;
                 GetIndex = ImageIterator.Index + 1;
                 ImageChanged?.Invoke(this, preLoadValue.ImageModel);
                 ImageChanged?.Invoke(this, preLoadValue.ImageModel);
-                await ImageIterator.AddAsync(ImageIterator.Index, ImageService, preLoadValue?.ImageModel, Pics);
-                await ImageIterator.Preload(ImageService, Pics);
+                await ImageIterator.AddAsync(ImageIterator.Index, ImageService, preLoadValue?.ImageModel);
+                await ImageIterator.Preload(ImageService);
                 return;
                 return;
 
 
                 async Task GetPreload()
                 async Task GetPreload()
                 {
                 {
-                    await ImageIterator.PreLoader.AddAsync(index, ImageService, Pics)
+                    await ImageIterator.PreLoader.AddAsync(index, ImageService, ImageIterator.Pics)
                         .ConfigureAwait(false);
                         .ConfigureAwait(false);
-                    preLoadValue = ImageIterator.PreLoader.Get(index, Pics);
+                    preLoadValue = ImageIterator.PreLoader.Get(index, ImageIterator.Pics);
                     if (ImageIterator.Index != index)
                     if (ImageIterator.Index != index)
                     {
                     {
-                        await ImageIterator.Preload(ImageService, Pics);
+                        await ImageIterator.Preload(ImageService);
                         return;
                         return;
                     }
                     }
 
 
@@ -1274,12 +1272,8 @@ namespace PicView.Avalonia.ViewModels
                 await ImageService.LoadImageAsync(imageModel);
                 await ImageService.LoadImageAsync(imageModel);
                 SetImageModel(imageModel);
                 SetImageModel(imageModel);
                 SetSize(imageModel.PixelWidth, imageModel.PixelHeight, imageModel.Rotation);
                 SetSize(imageModel.PixelWidth, imageModel.PixelHeight, imageModel.Rotation);
-                RetrieveFilesCommand?.Execute(null);
-                ImageIterator = new ImageIterator(imageModel.FileInfo, Pics)
-                {
-                    Index = Pics.IndexOf(fileInfo.FullName),
-                };
-                await ImageIterator.AddAsync(ImageIterator.Index, ImageService, imageModel, Pics);
+                ImageIterator = new ImageIterator(imageModel.FileInfo, _platformService);
+                await ImageIterator.AddAsync(ImageIterator.Index, ImageService, imageModel);
                 await LoadPicAtIndex(ImageIterator.Index);
                 await LoadPicAtIndex(ImageIterator.Index);
                 ImageIterator.FileAdded += (_, e) => { SetTitle(); };
                 ImageIterator.FileAdded += (_, e) => { SetTitle(); };
                 ImageIterator.FileRenamed += (_, e) => { SetTitle(); };
                 ImageIterator.FileRenamed += (_, e) => { SetTitle(); };
@@ -1287,11 +1281,11 @@ namespace PicView.Avalonia.ViewModels
                 {
                 {
                     if (isSameFile) //change if deleting current file
                     if (isSameFile) //change if deleting current file
                     {
                     {
-                        if (ImageIterator?.Index < 0 || ImageIterator?.Index >= Pics.Count)
+                        if (ImageIterator?.Index < 0 || ImageIterator?.Index >= ImageIterator?.Pics.Count)
                         {
                         {
                             return;
                             return;
                         }
                         }
-                        await LoadPicFromString(Pics[ImageIterator.Index]);
+                        await LoadPicFromString(ImageIterator?.Pics[ImageIterator.Index]);
                     }
                     }
                     else
                     else
                     {
                     {
@@ -1333,7 +1327,7 @@ namespace PicView.Avalonia.ViewModels
 
 
         #endregion Methods
         #endregion Methods
 
 
-        public MainViewModel()
+        public MainViewModel(IPlatformSpecificService platformSpecificService)
         {
         {
             if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
             if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
             {
             {
@@ -1750,6 +1744,7 @@ namespace PicView.Avalonia.ViewModels
 
 
             #endregion EXIF commands
             #endregion EXIF commands
 
 
+            _platformService = platformSpecificService;
             Activator = new ViewModelActivator();
             Activator = new ViewModelActivator();
             this.WhenActivated(disposables =>
             this.WhenActivated(disposables =>
             {
             {

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

@@ -29,9 +29,9 @@ public partial class ImageMenu : UserControl
             {
             {
                 number = 0;
                 number = 0;
             }
             }
-            else if (number > vm.Pics.Count)
+            else if (number > vm.ImageIterator?.Pics?.Count)
             {
             {
-                number = vm.Pics.Count - 1;
+                number = vm.ImageIterator?.Pics?.Count - 1 ?? 0;
             }
             }
             else
             else
             {
             {

+ 56 - 1
src/PicView.WPF/FileHandling/FileLists.cs

@@ -2,6 +2,7 @@
 using PicView.Core.FileHandling;
 using PicView.Core.FileHandling;
 using PicView.WPF.ChangeImage;
 using PicView.WPF.ChangeImage;
 using System.IO;
 using System.IO;
+using PicView.Windows;
 using SearchOption = System.IO.SearchOption;
 using SearchOption = System.IO.SearchOption;
 
 
 namespace PicView.WPF.FileHandling;
 namespace PicView.WPF.FileHandling;
@@ -33,7 +34,61 @@ internal static class FileLists
 
 
         FileUpdateNavigation.Initiate(fileInfo.Attributes.HasFlag(FileAttributes.Directory) ? fileInfo.DirectoryName : Path.GetDirectoryName(fileInfo.FullName));
         FileUpdateNavigation.Initiate(fileInfo.Attributes.HasFlag(FileAttributes.Directory) ? fileInfo.DirectoryName : Path.GetDirectoryName(fileInfo.FullName));
         SettingsHelper.Settings.Sorting.SortPreference = (int)sortFilesBy;
         SettingsHelper.Settings.Sorting.SortPreference = (int)sortFilesBy;
-        return Windows.FileHandling.GetFileList.Get(fileInfo);
+        if (fileInfo == null)
+            return [];
+
+        var files = FileListHelper.RetrieveFiles(fileInfo);
+
+        switch (sortFilesBy)
+        {
+            default:
+            case FileListHelper.SortFilesBy.Name: // Alphanumeric sort
+                var list = files.ToList();
+                if (SettingsHelper.Settings.Sorting.Ascending)
+                {
+                    list.Sort(NativeMethods.StrCmpLogicalW);
+                }
+                else
+                {
+                    list.Sort((x, y) => NativeMethods.StrCmpLogicalW(y, x));
+                }
+
+                return list;
+
+            case FileListHelper.SortFilesBy.FileSize: // Sort by file size
+                var fileInfoList = files.Select(f => new FileInfo(f)).ToList();
+                var sortedBySize = SettingsHelper.Settings.Sorting.Ascending
+                    ? fileInfoList.OrderBy(f => f.Length)
+                    : fileInfoList.OrderByDescending(f => f.Length);
+                return sortedBySize.Select(f => f.FullName).ToList();
+
+            case FileListHelper.SortFilesBy.Extension: // Sort by file extension
+                var sortedByExtension = SettingsHelper.Settings.Sorting.Ascending
+                    ? files.OrderBy(Path.GetExtension)
+                    : files.OrderByDescending(Path.GetExtension);
+                return sortedByExtension.ToList();
+
+            case FileListHelper.SortFilesBy.CreationTime: // Sort by file creation time
+                var sortedByCreationTime = SettingsHelper.Settings.Sorting.Ascending
+                    ? files.OrderBy(f => new FileInfo(f).CreationTime)
+                    : files.OrderByDescending(f => new FileInfo(f).CreationTime);
+                return sortedByCreationTime.ToList();
+
+            case FileListHelper.SortFilesBy.LastAccessTime: // Sort by file last access time
+                var sortedByLastAccessTime = SettingsHelper.Settings.Sorting.Ascending
+                    ? files.OrderBy(f => new FileInfo(f).LastAccessTime)
+                    : files.OrderByDescending(f => new FileInfo(f).LastAccessTime);
+                return sortedByLastAccessTime.ToList();
+
+            case FileListHelper.SortFilesBy.LastWriteTime: // Sort by file last write time
+                var sortedByLastWriteTime = SettingsHelper.Settings.Sorting.Ascending
+                    ? files.OrderBy(f => new FileInfo(f).LastWriteTime)
+                    : files.OrderByDescending(f => new FileInfo(f).LastWriteTime);
+                return sortedByLastWriteTime.ToList();
+
+            case FileListHelper.SortFilesBy.Random: // Sort files randomly
+                return files.OrderBy(f => Guid.NewGuid()).ToList();
+        }
     }
     }
 
 
     /// <summary>
     /// <summary>