1 using Microsoft.Xna.Framework;
9 private bool isHorizontal;
12 get {
return isHorizontal; }
16 needsToRecalculate =
true;
26 get {
return stretch; }
30 needsToRecalculate =
true;
34 private int absoluteSpacing;
37 get {
return absoluteSpacing; }
40 absoluteSpacing = MathHelper.Clamp(value, 0,
int.MaxValue);
41 needsToRecalculate =
true;
45 private float relativeSpacing;
48 get {
return relativeSpacing; }
51 relativeSpacing = MathHelper.Clamp(value, -1, 1);
52 needsToRecalculate =
true;
56 private Anchor childAnchor;
59 get {
return childAnchor; }
63 needsToRecalculate =
true;
67 private bool needsToRecalculate;
70 get {
return needsToRecalculate; }
73 if (value) { needsToRecalculate =
true; }
80 this.isHorizontal = isHorizontal;
81 this.childAnchor = childAnchor;
84 rectT.
SizeChanged += () => needsToRecalculate =
true;
89 float stretchFactor = 1.0f;
112 .Where(c => !c.GUIComponent.IgnoreLayoutGroups)
113 .Sum(c => isHorizontal ? (c.IsFixedSize ? c.NonScaledSize.X : c.MinSize.X) : (c.IsFixedSize ? c.NonScaledSize.Y : c.MinSize.Y));
116 .Where(c => !c.GUIComponent.IgnoreLayoutGroups)
117 .Sum(c => isHorizontal ?
118 (c.IsFixedSize ? c.Rect.Width : MathHelper.Clamp(c.Rect.Width, c.MinSize.X, c.MaxSize.X)) :
119 (c.IsFixedSize ? c.Rect.Height : MathHelper.Clamp(c.Rect.Height, c.MinSize.Y, c.MaxSize.Y)));
121 float thisSize = (isHorizontal ?
Rect.Width :
Rect.Height);
125 (absoluteSpacing + relativeSpacing * thisSize);
127 stretchFactor = totalSize <= 0.0f || minSize >= thisSize || totalSize == minSize ?
129 (thisSize - minSize) / (totalSize - minSize);
136 if (child.GUIComponent.IgnoreLayoutGroups) {
continue; }
138 float currentStretchFactor = child.ScaleBasis ==
ScaleBasis.Normal ? stretchFactor : 1.0f;
139 child.SetPosition(childAnchor);
141 void advancePositionsAndCalculateChildSizes(
142 ref
int childNonScaledSize,
143 ref
float childRelativeSize,
149 if (child.IsFixedSize)
151 absPos += childNonScaledSize + absoluteSpacing;
155 absPos += (int)Math.Round(MathHelper.Clamp(childRectSize * currentStretchFactor, childMinSize, childMaxSize) + (absoluteSpacing * currentStretchFactor));
159 MathF.Round(childRelativeSize * currentStretchFactor * selfRectSize) / selfRectSize;
160 childRelativeSize = relativeSize;
165 Point childNonScaledSize = child.NonScaledSize;
166 Vector2 childRelativeSize = child.RelativeSize;
169 child.RelativeOffset =
new Vector2(relPos, child.RelativeOffset.Y);
170 child.AbsoluteOffset =
new Point(absPos, child.AbsoluteOffset.Y);
171 advancePositionsAndCalculateChildSizes(
172 ref childNonScaledSize.X,
173 ref childRelativeSize.X,
181 child.RelativeOffset =
new Vector2(child.RelativeOffset.X, relPos);
182 child.AbsoluteOffset =
new Point(child.AbsoluteOffset.X, absPos);
183 advancePositionsAndCalculateChildSizes(
184 ref childNonScaledSize.Y,
185 ref childRelativeSize.Y,
191 child.NonScaledSize = childNonScaledSize;
192 child.RelativeSize = childRelativeSize;
193 relPos += relativeSpacing * stretchFactor;
194 if (isHorizontal) { relPos = MathF.Round(relPos *
Rect.Width) /
Rect.Width; }
195 else { relPos = MathF.Round(relPos *
Rect.Height) /
Rect.Height; }
197 needsToRecalculate =
false;
200 protected override void Update(
float deltaTime)
202 base.Update(deltaTime);
203 if (needsToRecalculate)
212 base.ForceLayoutRecalculation();
bool Stretch
Note that stretching cannot be undone, because the previous child sizes are not stored.
override void Update(float deltaTime)
GUILayoutGroup(RectTransform rectT, bool isHorizontal=false, Anchor childAnchor=Anchor.TopLeft)
override void ForceLayoutRecalculation()