95 lines
3.7 KiB
C#
95 lines
3.7 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Cryville.Common.Unity.UI {
|
|
[AddComponentMenu("Layout/Single Layout Group")]
|
|
[ExecuteAlways]
|
|
public class SingleLayoutGroup : LayoutGroup {
|
|
[SerializeField]
|
|
protected bool m_ChildForceExpandWidth = true;
|
|
|
|
[SerializeField]
|
|
protected bool m_ChildForceExpandHeight = true;
|
|
|
|
[SerializeField]
|
|
protected bool m_ChildControlWidth = true;
|
|
|
|
[SerializeField]
|
|
protected bool m_ChildControlHeight = true;
|
|
|
|
[SerializeField]
|
|
protected bool m_ChildScaleWidth;
|
|
|
|
[SerializeField]
|
|
protected bool m_ChildScaleHeight;
|
|
|
|
public override void CalculateLayoutInputHorizontal() {
|
|
base.CalculateLayoutInputHorizontal();
|
|
CalcAlongAxis(0);
|
|
}
|
|
public override void CalculateLayoutInputVertical() { CalcAlongAxis(1); }
|
|
public override void SetLayoutHorizontal() { SetChildrenAlongAxis(0); }
|
|
public override void SetLayoutVertical() { SetChildrenAlongAxis(1); }
|
|
|
|
protected void CalcAlongAxis(int axis) {
|
|
float combinedPadding = (axis == 0) ? padding.horizontal : padding.vertical;
|
|
bool controlSize = (axis == 0) ? m_ChildControlWidth : m_ChildControlHeight;
|
|
bool useScale = (axis == 0) ? m_ChildScaleWidth : m_ChildScaleHeight;
|
|
bool childForceExpandSize = (axis == 0) ? m_ChildForceExpandWidth : m_ChildForceExpandHeight;
|
|
float totalMin = combinedPadding;
|
|
float totalPreferred = combinedPadding;
|
|
float totalFlexible = 0f;
|
|
RectTransform child = rectChildren[0];
|
|
GetChildSizes(child, axis, controlSize, childForceExpandSize, out var min, out var preferred, out var flexible);
|
|
if (useScale) {
|
|
float scaleFactor = child.localScale[axis];
|
|
min *= scaleFactor;
|
|
preferred *= scaleFactor;
|
|
flexible *= scaleFactor;
|
|
}
|
|
totalMin = Mathf.Max(min + combinedPadding, totalMin);
|
|
totalPreferred = Mathf.Max(preferred + combinedPadding, totalPreferred);
|
|
totalFlexible = Mathf.Max(flexible, totalFlexible);
|
|
totalPreferred = Mathf.Max(totalMin, totalPreferred);
|
|
SetLayoutInputForAxis(totalMin, totalPreferred, totalFlexible, axis);
|
|
}
|
|
|
|
protected void SetChildrenAlongAxis(int axis) {
|
|
float size = rectTransform.rect.size[axis];
|
|
bool controlSize = (axis == 0) ? m_ChildControlWidth : m_ChildControlHeight;
|
|
bool useScale = (axis == 0) ? m_ChildScaleWidth : m_ChildScaleHeight;
|
|
bool childForceExpandSize = (axis == 0) ? m_ChildForceExpandWidth : m_ChildForceExpandHeight;
|
|
float alignmentOnAxis = GetAlignmentOnAxis(axis);
|
|
float innerSize = size - ((axis == 0) ? padding.horizontal : padding.vertical);
|
|
RectTransform child = rectChildren[0];
|
|
GetChildSizes(child, axis, controlSize, childForceExpandSize, out var min2, out var preferred2, out var flexible2);
|
|
float scaleFactor2 = useScale ? child.localScale[axis] : 1f;
|
|
float requiredSpace = Mathf.Clamp(innerSize, min2, (flexible2 > 0f) ? size : preferred2);
|
|
float startOffset = GetStartOffset(axis, requiredSpace * scaleFactor2);
|
|
if (controlSize) {
|
|
SetChildAlongAxisWithScale(child, axis, startOffset, requiredSpace, scaleFactor2);
|
|
}
|
|
else {
|
|
float offsetInCell2 = (requiredSpace - child.sizeDelta[axis]) * alignmentOnAxis;
|
|
SetChildAlongAxisWithScale(child, axis, startOffset + offsetInCell2, scaleFactor2);
|
|
}
|
|
}
|
|
|
|
void GetChildSizes(RectTransform 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 = 0f;
|
|
}
|
|
else {
|
|
min = LayoutUtility.GetMinSize(child, axis);
|
|
preferred = LayoutUtility.GetPreferredSize(child, axis);
|
|
flexible = LayoutUtility.GetFlexibleSize(child, axis);
|
|
}
|
|
if (childForceExpand) {
|
|
flexible = Mathf.Max(flexible, 1f);
|
|
}
|
|
}
|
|
}
|
|
}
|