Skip to content

Commit

Permalink
Tiff navigation updates #190
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruben2776 committed Feb 9, 2025
1 parent 49bf8d2 commit f2ec44d
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 15 deletions.
7 changes: 4 additions & 3 deletions src/PicView.Avalonia/Navigation/NavigationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static class NavigationHelper
{
private static CancellationTokenSource? _cancellationTokenSource;

public static TiffManager.TiffNavigationInfo? TiffNavigationInfo { get; private set; }
public static TiffManager.TiffNavigationInfo? TiffNavigationInfo { get; set; }

#region Navigation

Expand Down Expand Up @@ -102,7 +102,8 @@ private static async Task TiffNavigation(MainViewModel vm, string currentFileNam
{
if (TiffNavigationInfo.CurrentPage - 1 <= 0)
{
await CheckCancellationAndStartIterateToIndex(vm.ImageIterator.CurrentIndex, vm).ConfigureAwait(false);
var index = TiffManager.IsTiff(currentFileName) ? vm.ImageIterator.NextIndex : vm.ImageIterator.CurrentIndex;
await CheckCancellationAndStartIterateToIndex(index, vm).ConfigureAwait(false);
TiffNavigationInfo.Dispose();
TiffNavigationInfo = null;
return;
Expand All @@ -123,7 +124,7 @@ private static async Task TiffNavigation(MainViewModel vm, string currentFileNam
}
else
{
UpdateImage.SetTiffImage(TiffNavigationInfo, Path.GetFileName(currentFileName), vm);
UpdateImage.SetTiffImage(TiffNavigationInfo, nextIteration, vm.FileInfo, vm);
}
}
}
Expand Down
28 changes: 17 additions & 11 deletions src/PicView.Avalonia/Navigation/UpdateImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,21 @@ await Dispatcher.UIThread.InvokeAsync(() =>
}
else
{
SetTitleHelper.SetTitle(vm, preLoadValue.ImageModel);
if (TiffManager.IsTiff(preLoadValue.ImageModel.FileInfo.FullName))
{
if (TiffManager.IsTiff(preLoadValue.ImageModel.FileInfo.FullName))
{
SetTitleHelper.TrySetTiffTitle(preLoadValue.ImageModel.PixelWidth, preLoadValue.ImageModel.PixelHeight, vm.ImageIterator.CurrentIndex, preLoadValue.ImageModel.FileInfo, vm);
}
else
{
SetTitleHelper.SetTitle(vm, preLoadValue.ImageModel);
}
}
else
{
SetTitleHelper.SetTitle(vm, preLoadValue.ImageModel);
}
}

if (Settings.WindowProperties.KeepCentered)
Expand Down Expand Up @@ -191,16 +205,14 @@ public static void SetSingleImage(object source, ImageType imageType, string nam
vm.PixelHeight = height;
}

public static void SetTiffImage(TiffManager.TiffNavigationInfo tiffNavigationInfo, string name, MainViewModel vm)
public static void SetTiffImage(TiffManager.TiffNavigationInfo tiffNavigationInfo, int index, FileInfo fileInfo, MainViewModel vm)
{
var source = tiffNavigationInfo.Pages[tiffNavigationInfo.CurrentPage].ToWriteableBitmap();
vm.ImageSource = source;
vm.SecondaryImageSource = null;
vm.ImageType = ImageType.Bitmap;
var width = source?.PixelSize.Width ?? 0;
var height = source?.PixelSize.Height ?? 0;

name = name.Insert(name.LastIndexOf('.'), $" [{tiffNavigationInfo.CurrentPage + 1}/{tiffNavigationInfo.PageCount}]");

Dispatcher.UIThread.Invoke(() =>
{
Expand All @@ -212,13 +224,7 @@ public static void SetTiffImage(TiffManager.TiffNavigationInfo tiffNavigationInf
vm.ImageViewer.Rotate(vm.RotationAngle);
}

var singeImageWindowTitles = ImageTitleFormatter.GenerateTitleForSingleImage(width, height, name, 1);
vm.WindowTitle = singeImageWindowTitles.TitleWithAppName;
vm.Title = singeImageWindowTitles.BaseTitle;
vm.TitleTooltip = singeImageWindowTitles.BaseTitle;
vm.GalleryMargin = new Thickness(0, 0, 0, 0);

vm.PlatformService.StopTaskbarProgress();
SetTitleHelper.SetTiffTitle(tiffNavigationInfo, width, height, index, fileInfo, vm);

vm.PixelWidth = width;
vm.PixelHeight = height;
Expand Down
10 changes: 9 additions & 1 deletion src/PicView.Avalonia/StartUp/QuickLoad.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using PicView.Avalonia.WindowBehavior;
using PicView.Core.FileHandling;
using PicView.Core.Gallery;
using PicView.Core.ImageDecoding;

namespace PicView.Avalonia.StartUp;

Expand Down Expand Up @@ -76,7 +77,14 @@ await Dispatcher.UIThread.InvokeAsync(() =>
}
else
{
SetTitleHelper.SetTitle(vm, imageModel);
if (TiffManager.IsTiff(imageModel.FileInfo.FullName))
{
SetTitleHelper.TrySetTiffTitle(imageModel.PixelWidth, imageModel.PixelHeight, vm.ImageIterator.CurrentIndex, fileInfo, vm);
}
else
{
SetTitleHelper.SetTitle(vm, imageModel);
}
}

vm.ExifOrientation = imageModel.EXIFOrientation;
Expand Down
29 changes: 29 additions & 0 deletions src/PicView.Avalonia/UI/SetTitleHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using PicView.Avalonia.ImageHandling;
using PicView.Avalonia.ViewModels;
using PicView.Core.FileHandling;
using PicView.Core.ImageDecoding;
using PicView.Core.Localization;
using PicView.Core.Navigation;

Expand Down Expand Up @@ -89,6 +90,34 @@ void ReturnError()
}
}

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 singeImageWindowTitles = ImageTitleFormatter.GenerateTiffTitleStrings(width, height, index, fileInfo, tiffNavigationInfo, 1, vm.ImageIterator.ImagePaths);
vm.WindowTitle = singeImageWindowTitles.TitleWithAppName;
vm.Title = singeImageWindowTitles.BaseTitle;
vm.TitleTooltip = singeImageWindowTitles.BaseTitle;
}

public static void TrySetTiffTitle(int width, int height, int index, FileInfo fileInfo, MainViewModel vm)
{
if (TiffManager.GetTiffPageCount(fileInfo.FullName) is { } pageCount and > 1)
{
var tiffNavigationInfo = new TiffManager.TiffNavigationInfo
{
CurrentPage = 0,
PageCount = pageCount,
Pages = TiffManager.LoadTiffPages(fileInfo.FullName)
};
SetTiffTitle(tiffNavigationInfo, width, height,
vm.ImageIterator.CurrentIndex, fileInfo, vm);
}
else
{
SetTitle(vm);
}
}

public static void SetSideBySideTitle(MainViewModel vm, ImageModel? imageModel1, ImageModel? imageModel2)
{
if (imageModel1 is null || imageModel2 is null)
Expand Down
12 changes: 12 additions & 0 deletions src/PicView.Core/ImageDecoding/TiffManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ public static bool IsTiff(string path)

return pageCollection;
}

public static int? GetTiffPageCount(string path)
{
using var image = new MagickImage();
image.Ping(path);
var settings = new MagickReadSettings
{
// Specify that we want to read a TIFF format image
Format = MagickFormat.Tiff
};
return new MagickImageCollection(path, settings).Count;
}

public class TiffNavigationInfo : IDisposable
{
Expand Down
76 changes: 76 additions & 0 deletions src/PicView.Core/Navigation/ImageTitleFormatter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Diagnostics;
using Cysharp.Text;
using PicView.Core.Extensions;
using PicView.Core.ImageDecoding;
using PicView.Core.Localization;

namespace PicView.Core.Navigation;
Expand Down Expand Up @@ -116,6 +117,81 @@ public static WindowTitles GenerateTitleStrings(int width, int height, int index
FilePathTitle = filePathTitle
};
}

public static WindowTitles GenerateTiffTitleStrings(int width, int height, int index, FileInfo fileInfo, TiffManager.TiffNavigationInfo tiffNavigationInfo, double zoomValue,
List<string> filesList)
{
if (index < 0 || index >= filesList.Count)
{
return GenerateErrorTitle($"{nameof(ImageTitleFormatter)}:{nameof(GenerateTitleStrings)} - index invalid");
}

if (tiffNavigationInfo == null)
{
return GenerateErrorTitle(
$"{nameof(ImageTitleFormatter)}:{nameof(GenerateTitleStrings)} - TiffNavigationInfo is null");
}

if (fileInfo == null)
{
try
{
fileInfo = new FileInfo(filesList[index]);
}
catch (Exception e)
{
return GenerateErrorTitle(
$"{nameof(ImageTitleFormatter)}:{nameof(GenerateTitleStrings)} - FileInfo exception \n{e.Message}");
}
}

if (!fileInfo.Exists)
{
return GenerateErrorTitle(
$"{nameof(ImageTitleFormatter)}:{nameof(GenerateTitleStrings)} - FileInfo does not exist");
}

using var sb = ZString.CreateStringBuilder(true);


// Build the base title (common parts)
sb.Append(fileInfo.Name + $" [{tiffNavigationInfo.CurrentPage + 1}/{tiffNavigationInfo.PageCount}]");
sb.Append(' ');
sb.Append(index + 1);
sb.Append('/');
sb.Append(filesList.Count);
sb.Append(' ');
sb.Append(filesList.Count == 1 ? TranslationHelper.Translation.File : TranslationHelper.Translation.Files);
sb.Append(" (");
sb.Append(width);
sb.Append(" x ");
sb.Append(height);
sb.Append(FormatAspectRatio(width, height));
sb.Append(fileInfo.Length.GetReadableFileSize());

// Add zoom information if applicable
var zoomString = FormatZoomPercentage(zoomValue);
if (zoomString is not null)
{
sb.Append(", ");
sb.Append(zoomString);
}

var baseTitle = sb.ToString();

// Full title with AppName
var fullTitle = $"{baseTitle} - {AppName}";

// Title with file path instead of file name
var filePathTitle = baseTitle.Replace(fileInfo.Name, fileInfo.FullName);

return new WindowTitles
{
BaseTitle = baseTitle,
TitleWithAppName = fullTitle,
FilePathTitle = filePathTitle
};
}


/// <inheritdoc cref="GenerateTitleStrings(int, int, int, FileInfo, double, List{string})" />
Expand Down

0 comments on commit f2ec44d

Please sign in to comment.