diff options
Diffstat (limited to 'Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs')
-rw-r--r-- | Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs new file mode 100644 index 0000000..6a17e00 --- /dev/null +++ b/Assets/uGUI-2017.1/UnityEngine.UI/UI/Core/Layout/LayoutGroup.cs @@ -0,0 +1,237 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine.EventSystems; +using UnityEngine.Serialization; + +namespace UnityEngine.UI +{ + [DisallowMultipleComponent] + [ExecuteInEditMode] + [RequireComponent(typeof(RectTransform))] + public abstract class LayoutGroup : UIBehaviour, ILayoutElement, ILayoutGroup + { + [SerializeField] protected RectOffset m_Padding = new RectOffset(); + public RectOffset padding { get { return m_Padding; } set { SetProperty(ref m_Padding, value); } } + + [FormerlySerializedAs("m_Alignment")] + [SerializeField] protected TextAnchor m_ChildAlignment = TextAnchor.UpperLeft; + public TextAnchor childAlignment { get { return m_ChildAlignment; } set { SetProperty(ref m_ChildAlignment, value); } } + + [System.NonSerialized] private RectTransform m_Rect; + protected RectTransform rectTransform + { + get + { + if (m_Rect == null) + m_Rect = GetComponent<RectTransform>(); + return m_Rect; + } + } + + protected DrivenRectTransformTracker m_Tracker; + private Vector2 m_TotalMinSize = Vector2.zero; + private Vector2 m_TotalPreferredSize = Vector2.zero; + private Vector2 m_TotalFlexibleSize = Vector2.zero; + + [System.NonSerialized] private List<RectTransform> m_RectChildren = new List<RectTransform>(); + protected List<RectTransform> rectChildren { get { return m_RectChildren; } }
+
+
+ // ILayoutElement Interface
+ // 收集子节点中参与布局的节点
+ public virtual void CalculateLayoutInputHorizontal() + { + m_RectChildren.Clear(); + var toIgnoreList = ListPool<Component>.Get(); + for (int i = 0; i < rectTransform.childCount; i++) + { + var rect = rectTransform.GetChild(i) as RectTransform; + if (rect == null || !rect.gameObject.activeInHierarchy) + continue; + + rect.GetComponents(typeof(ILayoutIgnorer), toIgnoreList); + + if (toIgnoreList.Count == 0) + { + m_RectChildren.Add(rect); + continue; + } + + for (int j = 0; j < toIgnoreList.Count; j++) + { + var ignorer = (ILayoutIgnorer)toIgnoreList[j]; + if (!ignorer.ignoreLayout) + { + m_RectChildren.Add(rect); + break; + } + } + } + ListPool<Component>.Release(toIgnoreList); + m_Tracker.Clear(); + } + + // 这个方法不收集是因为在CalculateLayoutInputHorizontal收集了,在LayoutRebuilder的Rebuild()方法中有注释 + public abstract void CalculateLayoutInputVertical(); + public virtual float minWidth { get { return GetTotalMinSize(0); } } + public virtual float preferredWidth { get { return GetTotalPreferredSize(0); } } + public virtual float flexibleWidth { get { return GetTotalFlexibleSize(0); } } + public virtual float minHeight { get { return GetTotalMinSize(1); } } + public virtual float preferredHeight { get { return GetTotalPreferredSize(1); } } + public virtual float flexibleHeight { get { return GetTotalFlexibleSize(1); } } + public virtual int layoutPriority { get { return 0; } } + + // ILayoutController Interface + + public abstract void SetLayoutHorizontal(); + public abstract void SetLayoutVertical(); + + // Implementation + + protected LayoutGroup() + { + if (m_Padding == null) + m_Padding = new RectOffset(); + } + + protected override void OnEnable() + { + base.OnEnable(); + SetDirty(); + } + + protected override void OnDisable() + { + m_Tracker.Clear(); + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + base.OnDisable(); + } + + protected override void OnDidApplyAnimationProperties() + { + SetDirty(); + } + + protected float GetTotalMinSize(int axis) + { + return m_TotalMinSize[axis]; + } + + protected float GetTotalPreferredSize(int axis) + { + return m_TotalPreferredSize[axis]; + } + + protected float GetTotalFlexibleSize(int axis) + { + return m_TotalFlexibleSize[axis]; + } + + protected float GetStartOffset(int axis, float requiredSpaceWithoutPadding) + { + float requiredSpace = requiredSpaceWithoutPadding + (axis == 0 ? padding.horizontal : padding.vertical); // 算上padding后的大小 + float availableSpace = rectTransform.rect.size[axis]; // RectTransform大小 + float surplusSpace = availableSpace - requiredSpace; // 剩余空间 + float alignmentOnAxis = GetAlignmentOnAxis(axis); // 0\0.5\1 + return (axis == 0 ? padding.left : padding.top) + surplusSpace * alignmentOnAxis; + } + + protected float GetAlignmentOnAxis(int axis) + { + if (axis == 0) + return ((int)childAlignment % 3) * 0.5f; // 0, 0.5, 1 + else + return ((int)childAlignment / 3) * 0.5f; // 0, 0.5, 1 + } + + protected void SetLayoutInputForAxis(float totalMin, float totalPreferred, float totalFlexible, int axis) + { + m_TotalMinSize[axis] = totalMin; + m_TotalPreferredSize[axis] = totalPreferred; + m_TotalFlexibleSize[axis] = totalFlexible; + } + + protected void SetChildAlongAxis(RectTransform rect, int axis, float pos) + { + if (rect == null) + return; + + m_Tracker.Add(this, rect, + DrivenTransformProperties.Anchors | + (axis == 0 ? DrivenTransformProperties.AnchoredPositionX : DrivenTransformProperties.AnchoredPositionY)); + + rect.SetInsetAndSizeFromParentEdge(axis == 0 ? RectTransform.Edge.Left : RectTransform.Edge.Top, pos, rect.sizeDelta[axis]); + } + + protected void SetChildAlongAxis(RectTransform rect, int axis, float pos, float size) + { + if (rect == null) + return; + + m_Tracker.Add(this, rect, + DrivenTransformProperties.Anchors | + (axis == 0 ? + (DrivenTransformProperties.AnchoredPositionX | DrivenTransformProperties.SizeDeltaX) : + (DrivenTransformProperties.AnchoredPositionY | DrivenTransformProperties.SizeDeltaY) + )); + + rect.SetInsetAndSizeFromParentEdge(axis == 0 ? RectTransform.Edge.Left : RectTransform.Edge.Top, pos, size); + } + + private bool isRootLayoutGroup + { + get + { + Transform parent = transform.parent; + if (parent == null) + return true; + return transform.parent.GetComponent(typeof(ILayoutGroup)) == null; + } + } + + protected override void OnRectTransformDimensionsChange() + { + base.OnRectTransformDimensionsChange(); + if (isRootLayoutGroup) + SetDirty(); + } + + protected virtual void OnTransformChildrenChanged() + { + SetDirty(); + } + + protected void SetProperty<T>(ref T currentValue, T newValue) + { + if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue))) + return; + currentValue = newValue; + SetDirty(); + } + + protected void SetDirty() + { + if (!IsActive()) + return; + + if (!CanvasUpdateRegistry.IsRebuildingLayout()) + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + else + StartCoroutine(DelayedSetDirty(rectTransform)); + } + + IEnumerator DelayedSetDirty(RectTransform rectTransform) + { + yield return null; + LayoutRebuilder.MarkLayoutForRebuild(rectTransform); + } + + #if UNITY_EDITOR + protected override void OnValidate() + { + SetDirty(); + } + + #endif + } +} |