diff --git a/src/PicView.Avalonia.MacOS/Views/MacMainWindow.axaml b/src/PicView.Avalonia.MacOS/Views/MacMainWindow.axaml index 3ff84802d..abd3622dd 100644 --- a/src/PicView.Avalonia.MacOS/Views/MacMainWindow.axaml +++ b/src/PicView.Avalonia.MacOS/Views/MacMainWindow.axaml @@ -78,6 +78,7 @@ diff --git a/src/PicView.Avalonia/Gallery/GalleryFunctions.cs b/src/PicView.Avalonia/Gallery/GalleryFunctions.cs new file mode 100644 index 000000000..72ae439c2 --- /dev/null +++ b/src/PicView.Avalonia/Gallery/GalleryFunctions.cs @@ -0,0 +1,83 @@ +using System.Diagnostics; +using Avalonia.Controls; +using PicView.Avalonia.Navigation; +using PicView.Avalonia.ViewModels; +using PicView.Core.Config; +using PicView.Core.FileHandling; +using PicView.Core.Gallery; + +namespace PicView.Avalonia.Gallery +{ + public static class GalleryFunctions + { + public static void RecycleItem(object sender, MainViewModel vm) + { +#if DEBUG + Debug.Assert(sender != null, nameof(sender) + " != null"); +#endif + var menuItem = (MenuItem)sender; + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract + if (menuItem is null) { return; } +#if DEBUG + Debug.Assert(menuItem != null, nameof(menuItem) + " != null"); + Debug.Assert(menuItem.DataContext != null, "menuItem.DataContext != null"); +#endif + var galleryItem = (GalleryThumbInfo.GalleryThumbHolder)menuItem.DataContext; + FileDeletionHelper.DeleteFileWithErrorMsg(galleryItem.FileLocation, recycle: true); + + vm.GalleryItems.Remove(galleryItem); // TODO: rewrite file system watcher to delete gallery items + } + + public static async Task ToggleGallery(MainViewModel vm) + { + if (vm is null) + { + return; + } + vm.IsGalleryOpen = !vm.IsGalleryOpen; + SettingsHelper.Settings.Gallery.IsBottomGalleryShown = false; + if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown) + { + // TODO: Change to bottom gallery view + } + + vm.CloseMenuCommand.Execute(null); + if (vm.IsGalleryOpen) + { + if (!NavigationHelper.CanNavigate(vm)) + { + return; + } + _ = Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.Pics[0]))); + } + //WindowHelper.SetSize(this); + await SettingsHelper.SaveSettingsAsync(); + } + + public static async Task ToggleBottomGallery(MainViewModel vm) + { + if (vm is null) + { + return; + } + if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown) + { + vm.IsGalleryOpen = false; + SettingsHelper.Settings.Gallery.IsBottomGalleryShown = false; + } + else + { + vm.IsGalleryOpen = true; + SettingsHelper.Settings.Gallery.IsBottomGalleryShown = true; + if (!NavigationHelper.CanNavigate(vm)) + { + return; + } + _ = Task.Run(() => GalleryLoad.LoadGallery(vm, Path.GetDirectoryName(vm.ImageIterator.Pics[0]))); + } + vm.CloseMenuCommand.Execute(null); + //WindowHelper.SetSize(this); + await SettingsHelper.SaveSettingsAsync(); + } + } +} \ No newline at end of file diff --git a/src/PicView.Avalonia/Gallery/GalleryLoad.cs b/src/PicView.Avalonia/Gallery/GalleryLoad.cs index a16a669ad..bede440c8 100644 --- a/src/PicView.Avalonia/Gallery/GalleryLoad.cs +++ b/src/PicView.Avalonia/Gallery/GalleryLoad.cs @@ -18,6 +18,7 @@ public static async Task LoadGallery(MainViewModel viewModel, string currentDire return; } + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract if (viewModel.GalleryItems is null) { viewModel.GalleryItems = []; @@ -39,8 +40,9 @@ public static async Task LoadGallery(MainViewModel viewModel, string currentDire _isLoading = true; var count = viewModel.ImageIterator.Pics.Count; - foreach (var item in viewModel.ImageIterator.Pics) + for (var i = 0; i < viewModel.ImageIterator.Pics.Count; i++) { + var item = viewModel.ImageIterator.Pics[i]; object? avaloniaImage = null; FileInfo? fileInfo = null; try @@ -60,7 +62,7 @@ public static async Task LoadGallery(MainViewModel viewModel, string currentDire await magick.ReadAsync(item); } - var geometry = new MagickGeometry(100, 100); + var geometry = new MagickGeometry(0, (int)viewModel.GalleryItemSize); magick?.Thumbnail(geometry); magick.Format = MagickFormat.Png; await using var memoryStream = new MemoryStream(); @@ -79,61 +81,13 @@ public static async Task LoadGallery(MainViewModel viewModel, string currentDire // } var thumbData = GalleryThumbInfo.GalleryThumbHolder.GetThumbData(0, avaloniaImage as GalleryThumbInfo.IImageSource, fileInfo); + thumbData.ThumbNailSize = viewModel.GalleryItemSize; viewModel.GalleryItems.Add(thumbData); + if (i == viewModel.ImageIterator.Index) + { + viewModel.SelectedGalleryItem = thumbData; + } } - - //ParallelOptions options = new() - //{ - // // Don't slow the system down too much - // MaxDegreeOfParallelism = Math.Max(Environment.ProcessorCount - 2, 4) - //}; - //await Parallel.ForAsync(0, count, options, async (i, cancellationToken) => - //{ - // try - // { - // var item = viewModel.ImageIterator.Pics[i]; - // object? avaloniaImage = null; - // FileInfo? fileInfo = null; - - // var magick = new MagickImage(); - // fileInfo = new FileInfo(item); - // if (fileInfo.Length >= 2147483648) - // { - // await using var fileStream = new FileStream(item, FileMode.Open, FileAccess.Read, - // FileShare.ReadWrite, 4096, true); - // Fixes "The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size." - // ReSharper disable once MethodHasAsyncOverload - // magick?.Read(fileStream); - // } - // else - // { - // await magick.ReadAsync(item, cancellationToken); - // } - - // var geometry = new MagickGeometry(100, 100); - // magick?.Thumbnail(geometry); - // magick.Format = MagickFormat.Png; - // await using var memoryStream = new MemoryStream(); - // await magick.WriteAsync(memoryStream, cancellationToken); - // memoryStream.Position = 0; - // var bmp = new Bitmap(memoryStream); - // avaloniaImage = new ImageService.AvaloniaImageSource(bmp); - - // if (currentDirectory != _currentDirectory || count != viewModel.ImageIterator.Pics.Count) - // { - // cancellationToken.ThrowIfCancellationRequested(); - // return; - // } - - // var thumbData = GalleryThumbInfo.GalleryThumbHolder.GetThumbData(0, - // avaloniaImage as GalleryThumbInfo.IImageSource, fileInfo); - // viewModel.GalleryItems.Add(thumbData); - // } - // catch (Exception) - // { - // } - //}); - _isLoading = false; } } \ No newline at end of file diff --git a/src/PicView.Avalonia/Helpers/FunctionsHelper.cs b/src/PicView.Avalonia/Helpers/FunctionsHelper.cs index 29b13b2b2..a5dcad384 100644 --- a/src/PicView.Avalonia/Helpers/FunctionsHelper.cs +++ b/src/PicView.Avalonia/Helpers/FunctionsHelper.cs @@ -303,54 +303,12 @@ public static Task ToggleLooping() public static async Task ToggleGallery() { - if (Vm is null) - { - return; - } - Vm.IsGalleryOpen = !Vm.IsGalleryOpen; - SettingsHelper.Settings.Gallery.IsBottomGalleryShown = false; - if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown) - { - // TODO: Change to bottom gallery view - } - - Vm.CloseMenuCommand.Execute(null); - if (Vm.IsGalleryOpen) - { - if (!NavigationHelper.CanNavigate(Vm)) - { - return; - } - _ = Task.Run(() => GalleryLoad.LoadGallery(Vm, Path.GetDirectoryName(Vm.ImageIterator.Pics[0]))); - } - //WindowHelper.SetSize(this); - await SettingsHelper.SaveSettingsAsync(); + await GalleryFunctions.ToggleGallery(Vm).ConfigureAwait(false); } public static async Task ToggleBottomGallery() { - if (Vm is null) - { - return; - } - if (SettingsHelper.Settings.Gallery.IsBottomGalleryShown) - { - Vm.IsGalleryOpen = false; - SettingsHelper.Settings.Gallery.IsBottomGalleryShown = false; - } - else - { - Vm.IsGalleryOpen = true; - SettingsHelper.Settings.Gallery.IsBottomGalleryShown = true; - if (!NavigationHelper.CanNavigate(Vm)) - { - return; - } - _ = Task.Run(() => GalleryLoad.LoadGallery(Vm, Path.GetDirectoryName(Vm.ImageIterator.Pics[0]))); - } - Vm.CloseMenuCommand.Execute(null); - //WindowHelper.SetSize(this); - await SettingsHelper.SaveSettingsAsync(); + await GalleryFunctions.ToggleBottomGallery(Vm).ConfigureAwait(false); } public static Task AutoFitWindow() diff --git a/src/PicView.Avalonia/Helpers/StartUpHelper.cs b/src/PicView.Avalonia/Helpers/StartUpHelper.cs index 536044753..21e655e1c 100644 --- a/src/PicView.Avalonia/Helpers/StartUpHelper.cs +++ b/src/PicView.Avalonia/Helpers/StartUpHelper.cs @@ -79,6 +79,13 @@ public static async Task Start(MainViewModel vm, bool settingsExists, IClassicDe vm.CurrentView = new StartUpMenu(); } + if (vm.GalleryItemSize <= 0) + { + var screen = ScreenHelper.GetScreen(desktop.MainWindow); + // ReSharper disable once PossibleLossOfFraction + vm.GalleryItemSize = screen.WorkingArea.Height / 10; + } + vm.IsLoading = false; await KeybindingsHelper.LoadKeybindings(vm).ConfigureAwait(false); diff --git a/src/PicView.Avalonia/Keybindings/KeybindingsHelper.cs b/src/PicView.Avalonia/Keybindings/KeybindingsHelper.cs index 1c80df088..0d76facb9 100644 --- a/src/PicView.Avalonia/Keybindings/KeybindingsHelper.cs +++ b/src/PicView.Avalonia/Keybindings/KeybindingsHelper.cs @@ -18,7 +18,10 @@ public static class KeybindingsHelper { "D": "Next", "Right": "Next", + "Ctrl+Right": "Last", "Ctrl+D": "Last", + "Ctrl+Left": "First", + "Ctrl+A": "First", "A": "Prev", "Left": "Prev", "W": "Up", @@ -81,20 +84,6 @@ public static async Task LoadKeybindings(MainViewModel vm) } } - public static async Task UpdateKeybindings() - { - var json = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config/keybindings.json"); - if (!File.Exists(json)) - { -#if DEBUG - Trace.WriteLine($"{nameof(UpdateKeybindings)} no json found"); -#endif - return; - } - - await UpdateKeybindings(json); - } - public static async Task UpdateKeybindings(string json) { // Deserialize JSON into a dictionary of string keys and string values diff --git a/src/PicView.Avalonia/ViewModels/MainViewModel.cs b/src/PicView.Avalonia/ViewModels/MainViewModel.cs index 44ddd9c4c..a03b5f87d 100644 --- a/src/PicView.Avalonia/ViewModels/MainViewModel.cs +++ b/src/PicView.Avalonia/ViewModels/MainViewModel.cs @@ -134,6 +134,10 @@ public GalleryThumbHolder? SelectedGalleryItem public ICommand? ToggleScrollCommand { get; } public ICommand? ToggleSubdirectoriesCommand { get; } + + public ICommand? SetGalleryItemSizeCommand { get; } + + public ICommand? SetBottomGalleryItemSizeCommand { get; } #endregion Commands @@ -433,6 +437,20 @@ public double GetZoomSpeed } } + private double _galleryItemSize; + public double GalleryItemSize + { + get => _galleryItemSize; + set => this.RaiseAndSetIfChanged(ref _galleryItemSize, value); + } + + private double _bottomGalleryItemSize; + public double BottomGalleryItemSize + { + get => _bottomGalleryItemSize; + set => this.RaiseAndSetIfChanged(ref _bottomGalleryItemSize, value); + } + #region strings private string? _getFlipped; diff --git a/src/PicView.Avalonia/Views/GalleryView.axaml b/src/PicView.Avalonia/Views/GalleryView.axaml index e2e1d6ff3..eec9e1770 100644 --- a/src/PicView.Avalonia/Views/GalleryView.axaml +++ b/src/PicView.Avalonia/Views/GalleryView.axaml @@ -1,12 +1,12 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> @@ -20,37 +20,37 @@ + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + SelectedItem="{CompiledBinding SelectedGalleryItem}" + x:Name="GalleryListBox"> @@ -59,30 +59,30 @@ - + @@ -92,104 +92,104 @@ + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> + Height="12" + Stretch="Fill" + Width="12" /> @@ -199,23 +199,23 @@ diff --git a/src/PicView.Avalonia/Views/GalleryView.axaml.cs b/src/PicView.Avalonia/Views/GalleryView.axaml.cs index f36e3e36f..92f122770 100644 --- a/src/PicView.Avalonia/Views/GalleryView.axaml.cs +++ b/src/PicView.Avalonia/Views/GalleryView.axaml.cs @@ -9,6 +9,7 @@ using PicView.Core.Config; using System.Runtime.InteropServices; using DynamicData; +using PicView.Avalonia.Gallery; using PicView.Core.FileHandling; using static PicView.Core.Gallery.GalleryThumbInfo; @@ -96,6 +97,7 @@ private async void InputElement_OnPointerPressed(object? sender, PointerPressedE Debug.Assert(sender != null, nameof(sender) + " != null"); #endif var border = (Border)sender; + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract if (border is null) { return; } #if DEBUG Debug.Assert(border != null, nameof(border) + " != null"); @@ -114,18 +116,6 @@ private void RecycleItem(object? sender, RoutedEventArgs e) { return; } -#if DEBUG - Debug.Assert(sender != null, nameof(sender) + " != null"); -#endif - var menuItem = (MenuItem)sender; - if (menuItem is null) { return; } -#if DEBUG - Debug.Assert(menuItem != null, nameof(menuItem) + " != null"); - Debug.Assert(menuItem.DataContext != null, "menuItem.DataContext != null"); -#endif - var galleryItem = (GalleryThumbHolder)menuItem.DataContext; - FileDeletionHelper.DeleteFileWithErrorMsg(galleryItem.FileLocation, recycle: true); - - vm.GalleryItems.Remove(galleryItem); // TODO: rewrite file system watcher to delete gallery items + GalleryFunctions.RecycleItem(sender, vm); } } \ No newline at end of file diff --git a/src/PicView.Core/Gallery/GalleryThumbInfo.cs b/src/PicView.Core/Gallery/GalleryThumbInfo.cs index bb5a773b8..c6edd253a 100644 --- a/src/PicView.Core/Gallery/GalleryThumbInfo.cs +++ b/src/PicView.Core/Gallery/GalleryThumbInfo.cs @@ -76,6 +76,8 @@ public object? GetSource } } } + + public double ThumbNailSize { get; set; } /// /// Initializes a new instance of the class.