-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVirtualHorizontalOrVerticalLayoutGroup.cs
216 lines (202 loc) · 8.62 KB
/
VirtualHorizontalOrVerticalLayoutGroup.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
using System;
using UnityEngine;
namespace InfinityScroll
{
public abstract class VirtualHorizontalOrVerticalLayoutGroup : VirtualLayoutGroup
{
[SerializeField] protected float m_Spacing = 0.0f;
[SerializeField] protected bool m_ChildForceExpandWidth = true;
[SerializeField] protected bool m_ChildForceExpandHeight = true;
[SerializeField] protected bool m_ChildControlWidth = true;
[SerializeField] protected bool m_ChildControlHeight = true;
/// <summary>
/// <para>The spacing to use between layout elements in the layout group.</para>
/// </summary>
public float spacing
{
get { return m_Spacing; }
set { SetProperty<float>(ref m_Spacing, value); }
}
/// <summary>
/// <para>Whether to force the children to expand to fill additional available horizontal space.</para>
/// </summary>
public bool childForceExpandWidth
{
get { return m_ChildForceExpandWidth; }
set { SetProperty<bool>(ref m_ChildForceExpandWidth, value); }
}
/// <summary>
/// <para>Whether to force the children to expand to fill additional available vertical space.</para>
/// </summary>
public bool childForceExpandHeight
{
get { return m_ChildForceExpandHeight; }
set { SetProperty<bool>(ref m_ChildForceExpandHeight, value); }
}
/// <summary>
/// <para>Returns true if the Layout Group controls the widths of its children. Returns false if children control their own widths.</para>
/// </summary>
public bool childControlWidth
{
get { return m_ChildControlWidth; }
set { SetProperty<bool>(ref m_ChildControlWidth, value); }
}
/// <summary>
/// <para>Returns true if the Layout Group controls the heights of its children. Returns false if children control their own heights.</para>
/// </summary>
public bool childControlHeight
{
get { return m_ChildControlHeight; }
set { SetProperty<bool>(ref m_ChildControlHeight, value); }
}
/// <summary>
/// <para>Calculate the layout element properties for this layout element along the given axis.</para>
/// </summary>
/// <param name="axis">The axis to calculate for. 0 is horizontal and 1 is vertical.</param>
/// <param name="isVertical">Is this group a vertical group?</param>
protected void CalcAlongAxis(int axis, bool isVertical)
{
float num1 = axis != 0 ? (float) padding.vertical : (float) padding.horizontal;
bool controlSize = axis != 0 ? m_ChildControlHeight : m_ChildControlWidth;
bool childForceExpand = axis != 0 ? childForceExpandHeight : childForceExpandWidth;
float num2 = num1;
float b = num1;
float num3 = 0.0f;
bool flag = isVertical ^ axis == 1;
for (int index = 0; index < childCount; ++index)
{
float min;
float preferred;
float flexible;
GetChildSizes(children[index], axis, controlSize, childForceExpand, out min, out preferred,
out flexible);
if (flag)
{
num2 = Mathf.Max(min + num1, num2);
b = Mathf.Max(preferred + num1, b);
num3 = Mathf.Max(flexible, num3);
}
else
{
num2 += min + spacing;
b += preferred + spacing;
num3 += flexible;
}
}
if (!flag && childCount > 0)
{
num2 -= spacing;
b -= spacing;
}
float totalPreferred = Mathf.Max(num2, b);
SetLayoutInputForAxis(num2, totalPreferred, num3, axis);
}
/// <summary>
/// <para>Set the positions and sizes of the child layout elements for the given axis.</para>
/// </summary>
/// <param name="axis">The axis to handle. 0 is horizontal and 1 is vertical.</param>
/// <param name="isVertical">Is this group a vertical group?</param>
protected void SetChildrenAlongAxis(int axis, bool isVertical)
{
float num1 = rectTransform.rect.size[axis];
bool controlSize = axis != 0 ? m_ChildControlHeight : m_ChildControlWidth;
bool childForceExpand = axis != 0 ? childForceExpandHeight : childForceExpandWidth;
float alignmentOnAxis = GetAlignmentOnAxis(axis);
if (isVertical ^ axis == 1)
{
float num2 = num1 - (axis != 0 ? (float) padding.vertical : (float) padding.horizontal);
for (int index = 0; index < childCount; ++index)
{
VirtualChild virtualChild = children[index];
float min;
float preferred;
float flexible;
GetChildSizes(virtualChild, axis, controlSize, childForceExpand, out min, out preferred,
out flexible);
float num3 = Mathf.Clamp(num2, min, flexible <= 0.0 ? preferred : num1);
float startOffset = GetStartOffset(axis, num3);
if (controlSize)
{
SetChildAlongAxis(virtualChild, axis, startOffset, num3);
}
else
{
float num4 = (num3 - virtualChild.sizeDelta[axis]) * alignmentOnAxis;
SetChildAlongAxis(virtualChild, axis, startOffset + num4);
}
}
}
else
{
float pos = axis != 0 ? padding.top : padding.left;
if (Math.Abs((double) GetTotalFlexibleSize(axis)) < 1e-4 &&
GetTotalPreferredSize(axis) < num1)
pos = GetStartOffset(axis,
GetTotalPreferredSize(axis) -
(axis != 0 ? padding.vertical : padding.horizontal));
float t = 0.0f;
if (Math.Abs((double) GetTotalMinSize(axis) - GetTotalPreferredSize(axis)) > 1e-4)
t = Mathf.Clamp01(((num1 - GetTotalMinSize(axis)) /
(GetTotalPreferredSize(axis) -
GetTotalMinSize(axis))));
float num2 = 0.0f;
if (num1 > GetTotalPreferredSize(axis) &&
GetTotalFlexibleSize(axis) > 0.0)
num2 = (num1 - GetTotalPreferredSize(axis)) / GetTotalFlexibleSize(axis);
for (int index = 0; index < childCount; ++index)
{
VirtualChild virtualChild = children[index];
float min;
float preferred;
float flexible;
GetChildSizes(virtualChild, axis, controlSize, childForceExpand, out min, out preferred,
out flexible);
float size = Mathf.Lerp(min, preferred, t) + flexible * num2;
if (controlSize)
{
SetChildAlongAxis(virtualChild, axis, pos, size);
}
else
{
float num3 = (size - virtualChild.sizeDelta[axis]) * alignmentOnAxis;
SetChildAlongAxis(virtualChild, axis, pos + num3);
}
pos += size + spacing;
}
}
}
private void GetChildSizes(
VirtualChild child,
int axis,
bool controlSize,
bool childForceExpand,
out float min,
out float preferred,
out float flexible)
{
if (!controlSize)
{
min = child.sizeDelta[axis];
preferred = min;
flexible = 0.0f;
}
else
{
min = child.GetMinSize(axis);
preferred = child.GetPreferredSize(axis);
flexible = child.GetFlexibleSize(axis);
}
if (!childForceExpand)
return;
flexible = Mathf.Max(flexible, 1f);
}
#if UNITY_EDITOR
protected override void Reset()
{
base.Reset();
m_ChildControlWidth = false;
m_ChildControlHeight = false;
}
#endif
}
}