-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCAbsoluteLayout.cs
137 lines (101 loc) · 5.8 KB
/
CAbsoluteLayout.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
using Microsoft.Maui.Layouts;
using System.Diagnostics;
namespace iOSTranslationArrangeBug {
public class CAbsoluteLayout : AbsoluteLayout {
protected override ILayoutManager CreateLayoutManager() {
return new CustomAbsoluteLayoutManager(this);
}
}
//======================
//LAYOUT MANAGER
//======================
//https://github.com/dotnet/maui/blob/main/src/Core/src/Layouts/AbsoluteLayoutManager.cs#L8
public class CustomAbsoluteLayoutManager : LayoutManager {
public CustomAbsoluteLayoutManager(IAbsoluteLayout layout) : base(layout) {
customAbsoluteLayout = layout;
}
public IAbsoluteLayout customAbsoluteLayout { get; }
const double AutoSize = -1;
public override Size Measure(double widthConstraint, double heightConstraint) {
Debug.WriteLine("MEASURE CHILDREN OF: " + (customAbsoluteLayout as CAbsoluteLayout).StyleId + " NUM CHILDREN " + customAbsoluteLayout.Count);
var availableWidth = widthConstraint;// - padding.HorizontalThickness;
var availableHeight = heightConstraint;// - padding.VerticalThickness;
double measuredHeight = 0;
double measuredWidth = 0;
for (int n = 0; n < customAbsoluteLayout.Count; n++) {
var child = customAbsoluteLayout[n];
if (child.Visibility == Visibility.Collapsed) {
continue;
}
var bounds = customAbsoluteLayout.GetLayoutBounds(child);
bool isWidthProportional = false;
bool isHeightProportional = false;
var measureWidth = ResolveChildMeasureConstraint(bounds.Width, isWidthProportional, widthConstraint);
var measureHeight = ResolveChildMeasureConstraint(bounds.Height, isHeightProportional, heightConstraint);
var measure = child.Measure(measureWidth, measureHeight);
var width = ResolveDimension(isWidthProportional, bounds.Width, availableWidth, measure.Width);
var height = ResolveDimension(isHeightProportional, bounds.Height, availableHeight, measure.Height);
measuredHeight = Math.Max(measuredHeight, bounds.Top + height);
measuredWidth = Math.Max(measuredWidth, bounds.Left + width);
}
var finalHeight = ResolveConstraints(heightConstraint, customAbsoluteLayout.Height, measuredHeight, customAbsoluteLayout.MinimumHeight, customAbsoluteLayout.MaximumHeight);
var finalWidth = ResolveConstraints(widthConstraint, customAbsoluteLayout.Width, measuredWidth, customAbsoluteLayout.MinimumWidth, customAbsoluteLayout.MaximumWidth);
return new Size(finalWidth, finalHeight);
}
public override Size ArrangeChildren(Rect bounds) {
Debug.WriteLine("ARRANGE CHILDREN OF: " + (customAbsoluteLayout as CAbsoluteLayout).StyleId + " NUM CHILDREN " + customAbsoluteLayout.Count);
var padding = customAbsoluteLayout.Padding;
double top = padding.Top + bounds.Top;
double left = padding.Left + bounds.Left;
double availableWidth = bounds.Width - padding.HorizontalThickness;
double availableHeight = bounds.Height - padding.VerticalThickness;
for (int n = 0; n < customAbsoluteLayout.Count; n++) {
IView child = customAbsoluteLayout[n];
if (child.Visibility == Visibility.Collapsed) {
string invisibleID = "";
if (child as VisualElement != null) {
invisibleID = (child as VisualElement).StyleId;
}
continue;
}
var destination = customAbsoluteLayout.GetLayoutBounds(child);
bool isWidthProportional = false;
bool isHeightProportional = false;
destination.Width = ResolveDimension(isWidthProportional, destination.Width, availableWidth, child.DesiredSize.Width);
destination.Height = ResolveDimension(isHeightProportional, destination.Height, availableHeight, child.DesiredSize.Height);
destination.X += left;
destination.Y += top;
child.Arrange(destination);
}
return new Size(availableWidth, availableHeight);
}
static bool HasFlag(AbsoluteLayoutFlags a, AbsoluteLayoutFlags b) {
// Avoiding Enum.HasFlag here for performance reasons; we don't need the type check
return (a & b) == b;
}
static double ResolveDimension(bool isProportional, double fromBounds, double available, double measured) {
// By default, we use the absolute value from LayoutBounds
var value = fromBounds;
if (isProportional && !double.IsInfinity(available)) {
// If this dimension is marked proportional, then the value is a percentage of the available space
// Multiple it by the available space to figure out the final value
value *= available;
}
else if (value == AutoSize) {
// No absolute or proportional value specified, so we use the measured value
value = measured;
}
return value;
}
static double ResolveChildMeasureConstraint(double boundsValue, bool proportional, double constraint) {
if (boundsValue < 0) {
// If the child view doesn't have bounds set by the AbsoluteLayout, then we'll let it auto-size
return double.PositiveInfinity;
}
if (proportional) {
return boundsValue * constraint;
}
return boundsValue;
}
}
}