Skip to content

Commit

Permalink
[Avalonia] Show side by side (work in progress) #89
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruben2776 committed Sep 6, 2024
1 parent 3bd64c4 commit 7a40129
Show file tree
Hide file tree
Showing 12 changed files with 1,072 additions and 768 deletions.
106 changes: 74 additions & 32 deletions src/PicView.Avalonia/CustomControls/PicBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using PicView.Avalonia.Navigation;
using PicView.Avalonia.UI;
using PicView.Avalonia.ViewModels;
using PicView.Core.Config;
using Vector = Avalonia.Vector;


Expand Down Expand Up @@ -61,6 +62,14 @@ public object? SecondarySource
get => GetValue(SecondarySourceProperty);
set => SetValue(SecondarySourceProperty, value);
}

public static readonly StyledProperty<double> SecondaryImageWidthProperty = AvaloniaProperty.Register<PicBox, double>(nameof(SecondaryImageWidth));

public double SecondaryImageWidth
{
get => GetValue(SecondaryImageWidthProperty);
set => SetValue(SecondaryImageWidthProperty, value);
}

/// <summary>
/// Defines the <see cref="ImageType"/> property.
Expand Down Expand Up @@ -216,15 +225,24 @@ private void RenderAnimatedImageIfRequired(DrawingContext context)

private void RenderBasedOnSettings(DrawingContext context, IImage source)
{
var is1To1 = false; // TODO: replace with settings value
var isSideBySide = SettingsHelper.Settings.ImageScaling.ShowImageSideBySide;
var secondarySource = SecondarySource as IImage;

var viewPort = DetermineViewPort();
Size sourceSize;
if (source is null)
{
return;
}
Size? secondarySourceSize = null;
try
{
sourceSize = source.Size;
if (isSideBySide)
{
secondarySourceSize = secondarySource.Size;
}
}
catch (Exception e)
{
Expand Down Expand Up @@ -267,29 +285,27 @@ private void RenderBasedOnSettings(DrawingContext context, IImage source)
}
else return;
}
if (isSideBySide)
{
var nextPreloadValue = vm.ImageIterator?.GetNextPreLoadValue();
if (nextPreloadValue?.ImageModel != null)
{
secondarySourceSize = new Size(nextPreloadValue.ImageModel.PixelWidth, nextPreloadValue.ImageModel.PixelHeight);
}
else
{
return;
}
}
}

var is1To1 = false; // TODO: replace with settings value
var isSideBySide = false; // TODO: replace with settings value

if (is1To1)
{
RenderImage1To1(context, source, viewPort, sourceSize);
}
else if (isSideBySide)
{
if (SecondarySource is IImage secondarySource)
{
RenderImageSideBySide(context, source, secondarySource, viewPort);
}
else
{
// Handle invalid secondary source
#if DEBUG
Console.WriteLine("Invalid secondary source type.");
TooltipHelper.ShowTooltipMessage("Invalid secondary source type.", true);
#endif
}
RenderImageSideBySide(context, source, secondarySource, viewPort, sourceSize, secondarySourceSize);
}
else
{
Expand Down Expand Up @@ -329,30 +345,56 @@ private void RenderImage(DrawingContext context, IImage source, Rect viewPort, S
}
}

private void RenderImageSideBySide(DrawingContext context, IImage source, IImage secondarySource, Rect viewPort)
private void RenderImageSideBySide(DrawingContext context, IImage source, IImage secondarySource, Rect viewPort, Size sourceSize, Size? secondarySourceSize)
{
// Get the aspect ratios of the images
var sourceAspectRatio = source.Size.Width / source.Size.Height;
var secondarySourceAspectRatio = secondarySource.Size.Width / secondarySource.Size.Height;
if (source == null || secondarySource == null || secondarySourceSize == null)
{
return;
}

// Calculate the width for each image
var halfViewportWidth = viewPort.Width / 2;
// Scale both images based on the height of the viewport
var scale = viewPort.Height / Math.Max(sourceSize.Height, secondarySourceSize.Value.Height);

// Calculate heights based on the aspect ratio
var sourceHeight = halfViewportWidth / sourceAspectRatio;
var secondarySourceHeight = halfViewportWidth / secondarySourceAspectRatio;
// Calculate the scaled size of the second image based on the specified width (SecondaryImageWidth)
var scaledSecondarySize = new Size(SecondaryImageWidth, secondarySourceSize.Value.Height * scale);

// Calculate the remaining width for the first image
var firstImageWidth = viewPort.Width - scaledSecondarySize.Width;

// Calculate the rectangles for each image
var sourceRect = new Rect(0, 0, halfViewportWidth, sourceHeight);
var secondarySourceRect = new Rect(halfViewportWidth, 0, halfViewportWidth, secondarySourceHeight);

if (firstImageWidth <= 0)
{
// If there's no space left for the first image, don't render anything
return;
}

// Scale the first image to fit within the remaining width while keeping the same height
var scaledSourceSize = new Size(firstImageWidth, sourceSize.Height * scale);

// Calculate the destination rectangles for both images
var sourceDestRect = new Rect(0, 0, firstImageWidth, viewPort.Height);
var secondaryDestRect = new Rect(firstImageWidth, 0, SecondaryImageWidth, viewPort.Height);

// Calculate the source rectangles (ensuring the aspect ratio is maintained)
var sourceRect = new Rect(sourceSize);
var secondarySourceRect = new Rect(secondarySourceSize.Value);

// Render the background before the images
RenderBackground(context);

// Draw the first image
context.DrawImage(source, new Rect(source.Size), sourceRect);
try
{
// Render the first image (filling the remaining space)
context.DrawImage(source, sourceRect, sourceDestRect);

// Draw the second image
context.DrawImage(secondarySource, new Rect(secondarySource.Size), secondarySourceRect);
// Render the second image (with the fixed SecondaryImageWidth)
context.DrawImage(secondarySource, secondarySourceRect, secondaryDestRect);
}
catch (Exception e)
{
#if DEBUG
Console.WriteLine(e);
#endif
}
}

private void RenderBackground(DrawingContext context)
Expand Down
Loading

0 comments on commit 7a40129

Please sign in to comment.