-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAspectRatioLayoutDecorator.cs
108 lines (90 loc) · 3.12 KB
/
AspectRatioLayoutDecorator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System;
namespace MashBattle {
public class AspectRatioLayoutDecorator : Decorator
{
public static readonly DependencyProperty AspectRatioProperty =
DependencyProperty.Register(
"AspectRatio",
typeof(double),
typeof(AspectRatioLayoutDecorator),
new FrameworkPropertyMetadata
(
1d,
FrameworkPropertyMetadataOptions.AffectsMeasure
),
ValidateAspectRatio);
private static bool ValidateAspectRatio(object value)
{
if (!(value is double))
{
return false;
}
var aspectRatio = (double)value;
return aspectRatio > 0
&& !double.IsInfinity(aspectRatio)
&& !double.IsNaN(aspectRatio);
}
public double AspectRatio
{
get { return (double)GetValue(AspectRatioProperty); }
set { SetValue(AspectRatioProperty, value); }
}
protected override Size MeasureOverride(Size constraint)
{
if (Child != null)
{
constraint = SizeToRatio(constraint, false);
Child.Measure(constraint);
if (double.IsInfinity(constraint.Width)
|| double.IsInfinity(constraint.Height))
{
return SizeToRatio(Child.DesiredSize, true);
}
return constraint;
}
// we don't have a child, so we don't need any space
return new Size(0, 0);
}
public Size SizeToRatio(Size size, bool expand)
{
double ratio = AspectRatio;
double height = size.Width / ratio;
double width = size.Height * ratio;
if (expand)
{
width = Math.Max(width, size.Width);
height = Math.Max(height, size.Height);
}
else
{
width = Math.Min(width, size.Width);
height = Math.Min(height, size.Height);
}
return new Size(width, height);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
if (Child != null)
{
var newSize = SizeToRatio(arrangeSize, false);
double widthDelta = arrangeSize.Width - newSize.Width;
double heightDelta = arrangeSize.Height - newSize.Height;
double top = 0;
double left = 0;
if (!double.IsNaN(widthDelta)
&& !double.IsInfinity(widthDelta))
{
left = widthDelta / 2;
}
if (!double.IsNaN(heightDelta)
&& !double.IsInfinity(heightDelta))
{
top = heightDelta / 2;
}
var finalRect = new Rect(new Point(left, top), newSize);
Child.Arrange(finalRect);
}
return arrangeSize;
}
}
}