summaryrefslogtreecommitdiff
path: root/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs')
-rw-r--r--Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs207
1 files changed, 207 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs
new file mode 100644
index 0000000..170e410
--- /dev/null
+++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/GridLayoutGroup.cs
@@ -0,0 +1,207 @@
+using UnityEngine;
+using System.Collections.Generic;
+
+namespace UnityEngine.UI
+{
+ [AddComponentMenu("Layout/Grid Layout Group", 152)]
+ public class GridLayoutGroup : LayoutGroup
+ {
+ public enum Corner { UpperLeft = 0, UpperRight = 1, LowerLeft = 2, LowerRight = 3 }
+ public enum Axis { Horizontal = 0, Vertical = 1 }
+ public enum Constraint { Flexible = 0, FixedColumnCount = 1, FixedRowCount = 2 }
+
+ [SerializeField] protected Corner m_StartCorner = Corner.UpperLeft;
+ public Corner startCorner { get { return m_StartCorner; } set { SetProperty(ref m_StartCorner, value); } }
+
+ [SerializeField] protected Axis m_StartAxis = Axis.Horizontal;
+ public Axis startAxis { get { return m_StartAxis; } set { SetProperty(ref m_StartAxis, value); } }
+
+ [SerializeField] protected Vector2 m_CellSize = new Vector2(100, 100);
+ public Vector2 cellSize { get { return m_CellSize; } set { SetProperty(ref m_CellSize, value); } }
+
+ [SerializeField] protected Vector2 m_Spacing = Vector2.zero;
+ public Vector2 spacing { get { return m_Spacing; } set { SetProperty(ref m_Spacing, value); } }
+
+ [SerializeField] protected Constraint m_Constraint = Constraint.Flexible;
+ public Constraint constraint { get { return m_Constraint; } set { SetProperty(ref m_Constraint, value); } }
+
+ [SerializeField] protected int m_ConstraintCount = 2;
+ public int constraintCount { get { return m_ConstraintCount; } set { SetProperty(ref m_ConstraintCount, Mathf.Max(1, value)); } }
+
+ protected GridLayoutGroup()
+ {}
+
+ #if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ base.OnValidate();
+ constraintCount = constraintCount;
+ }
+
+ #endif
+
+ public override void CalculateLayoutInputHorizontal()
+ {
+ base.CalculateLayoutInputHorizontal();
+
+ int minColumns = 0;
+ int preferredColumns = 0;
+ if (m_Constraint == Constraint.FixedColumnCount)
+ {
+ minColumns = preferredColumns = m_ConstraintCount;
+ }
+ else if (m_Constraint == Constraint.FixedRowCount)
+ {
+ minColumns = preferredColumns = Mathf.CeilToInt(rectChildren.Count / (float)m_ConstraintCount - 0.001f);
+ }
+ else
+ {
+ minColumns = 1;
+ preferredColumns = Mathf.CeilToInt(Mathf.Sqrt(rectChildren.Count));
+ }
+
+ SetLayoutInputForAxis(
+ padding.horizontal + (cellSize.x + spacing.x) * minColumns - spacing.x,
+ padding.horizontal + (cellSize.x + spacing.x) * preferredColumns - spacing.x,
+ -1, 0);
+ }
+
+ public override void CalculateLayoutInputVertical()
+ {
+ int minRows = 0;
+ if (m_Constraint == Constraint.FixedColumnCount)
+ {
+ minRows = Mathf.CeilToInt(rectChildren.Count / (float)m_ConstraintCount - 0.001f);
+ }
+ else if (m_Constraint == Constraint.FixedRowCount)
+ {
+ minRows = m_ConstraintCount;
+ }
+ else
+ {
+ float width = rectTransform.rect.size.x;
+ int cellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));
+ minRows = Mathf.CeilToInt(rectChildren.Count / (float)cellCountX);
+ }
+
+ float minSpace = padding.vertical + (cellSize.y + spacing.y) * minRows - spacing.y;
+ SetLayoutInputForAxis(minSpace, minSpace, -1, 1);
+ }
+
+ public override void SetLayoutHorizontal()
+ {
+ SetCellsAlongAxis(0);
+ }
+
+ public override void SetLayoutVertical()
+ {
+ SetCellsAlongAxis(1);
+ }
+
+ private void SetCellsAlongAxis(int axis)
+ {
+ // Normally a Layout Controller should only set horizontal values when invoked for the horizontal axis
+ // and only vertical values when invoked for the vertical axis.
+ // However, in this case we set both the horizontal and vertical position when invoked for the vertical axis.
+ // Since we only set the horizontal position and not the size, it shouldn't affect children's layout,
+ // and thus shouldn't break the rule that all horizontal layout must be calculated before all vertical layout.
+
+ if (axis == 0)
+ {
+ // Only set the sizes when invoked for horizontal axis, not the positions.
+ for (int i = 0; i < rectChildren.Count; i++)
+ {
+ RectTransform rect = rectChildren[i];
+
+ m_Tracker.Add(this, rect,
+ DrivenTransformProperties.Anchors |
+ DrivenTransformProperties.AnchoredPosition |
+ DrivenTransformProperties.SizeDelta);
+
+ rect.anchorMin = Vector2.up;
+ rect.anchorMax = Vector2.up;
+ rect.sizeDelta = cellSize;
+ }
+ return;
+ }
+
+ float width = rectTransform.rect.size.x;
+ float height = rectTransform.rect.size.y;
+
+ int cellCountX = 1;
+ int cellCountY = 1;
+ if (m_Constraint == Constraint.FixedColumnCount)
+ {
+ cellCountX = m_ConstraintCount;
+ cellCountY = Mathf.CeilToInt(rectChildren.Count / (float)cellCountX - 0.001f);
+ }
+ else if (m_Constraint == Constraint.FixedRowCount)
+ {
+ cellCountY = m_ConstraintCount;
+ cellCountX = Mathf.CeilToInt(rectChildren.Count / (float)cellCountY - 0.001f);
+ }
+ else
+ {
+ if (cellSize.x + spacing.x <= 0)
+ cellCountX = int.MaxValue;
+ else
+ cellCountX = Mathf.Max(1, Mathf.FloorToInt((width - padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));
+
+ if (cellSize.y + spacing.y <= 0)
+ cellCountY = int.MaxValue;
+ else
+ cellCountY = Mathf.Max(1, Mathf.FloorToInt((height - padding.vertical + spacing.y + 0.001f) / (cellSize.y + spacing.y)));
+ }
+
+ int cornerX = (int)startCorner % 2;
+ int cornerY = (int)startCorner / 2;
+
+ int cellsPerMainAxis, actualCellCountX, actualCellCountY;
+ if (startAxis == Axis.Horizontal)
+ {
+ cellsPerMainAxis = cellCountX;
+ actualCellCountX = Mathf.Clamp(cellCountX, 1, rectChildren.Count);
+ actualCellCountY = Mathf.Clamp(cellCountY, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));
+ }
+ else
+ {
+ cellsPerMainAxis = cellCountY;
+ actualCellCountY = Mathf.Clamp(cellCountY, 1, rectChildren.Count);
+ actualCellCountX = Mathf.Clamp(cellCountX, 1, Mathf.CeilToInt(rectChildren.Count / (float)cellsPerMainAxis));
+ }
+
+ Vector2 requiredSpace = new Vector2(
+ actualCellCountX * cellSize.x + (actualCellCountX - 1) * spacing.x,
+ actualCellCountY * cellSize.y + (actualCellCountY - 1) * spacing.y
+ );
+ Vector2 startOffset = new Vector2(
+ GetStartOffset(0, requiredSpace.x),
+ GetStartOffset(1, requiredSpace.y)
+ );
+
+ for (int i = 0; i < rectChildren.Count; i++)
+ {
+ int positionX;
+ int positionY;
+ if (startAxis == Axis.Horizontal)
+ {
+ positionX = i % cellsPerMainAxis;
+ positionY = i / cellsPerMainAxis;
+ }
+ else
+ {
+ positionX = i / cellsPerMainAxis;
+ positionY = i % cellsPerMainAxis;
+ }
+
+ if (cornerX == 1)
+ positionX = actualCellCountX - 1 - positionX;
+ if (cornerY == 1)
+ positionY = actualCellCountY - 1 - positionY;
+
+ SetChildAlongAxis(rectChildren[i], 0, startOffset.x + (cellSize[0] + spacing[0]) * positionX, cellSize[0]);
+ SetChildAlongAxis(rectChildren[i], 1, startOffset.y + (cellSize[1] + spacing[1]) * positionY, cellSize[1]);
+ }
+ }
+ }
+}