Skip to content

Instantly share code, notes, and snippets.

@SuperJMN
Last active October 1, 2018 08:26
Show Gist options
  • Save SuperJMN/703721f919cdab29094499c579c7c52d to your computer and use it in GitHub Desktop.
Save SuperJMN/703721f919cdab29094499c579c7c52d to your computer and use it in GitHub Desktop.
AvaloniaUI's Viewbox
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using static System.Math;
public class Viewbox : Decorator
{
private IControl Root => Child;
protected override Size MeasureOverride(Size constraint)
{
if (Root == null)
{
return constraint;
}
var availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
Root.Measure(availableSize);
var desiredSize = Root.DesiredSize;
var factor = GetFactorToFillUniformly(constraint, desiredSize);
return new Size(factor.Width * desiredSize.Width, factor.Height * desiredSize.Height);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
if (Root == null)
{
return arrangeSize;
}
var desiredSize = Root.DesiredSize;
var factor = GetFactorToFillUniformly(arrangeSize, desiredSize);
Root.RenderTransform = new ScaleTransform(factor.Width, factor.Height);
Root.Arrange(new Rect(new Point(0, 0), desiredSize));
return new Size(factor.Width * desiredSize.Width, factor.Height * desiredSize.Height);
}
private static Size GetFactorToFillUniformly(Size availableSize, Size contentSize)
{
var width = DoubleUtil.IsZero(contentSize.Width) ? 0.0 : availableSize.Width / contentSize.Width;
var height = DoubleUtil.IsZero(contentSize.Height) ? 0.0 : availableSize.Height / contentSize.Height;
var min = Min(width, height);
return new Size(min, min);
}
}
internal class DoubleUtil
{
const double Tolerance = 0.1D;
public static bool IsZero(double contentSizeWidth)
{
return Abs(contentSizeWidth) < Tolerance;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment