c1_unity/Assets/Scripts/Component/UI/BFLayout/BFHorizontalOrVerticalLayout.cs
2023-04-03 11:04:31 +08:00

239 lines
7.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BF
{
[ExecuteInEditMode]
public class BFHorizontalOrVerticalLayout : BFLayoutBase
{
[SerializeField]
protected float spacing = 0;
public float Spaceing
{
get { return spacing; }
set { SetProperty(ref spacing, value); }
}
[SerializeField]
protected bool verticalOrHorizontal = true;
public bool VerticalOrHorizontal
{
get { return verticalOrHorizontal; }
set { SetProperty(ref verticalOrHorizontal, value); }
}
private float verticalSize = 0f;
private float horizontalSize = 0f;
public void Update()
{
if (!isDirty)
{
return;
}
RefreshLayout();
}
public void RefreshLayout()
{
CalculateLayoutInput();
if (verticalOrHorizontal)
{
CalChildPosVertical();
}
else
{
CalChildPosHorizontal();
}
isDirty = false;
}
protected void CalculateLayoutInput()
{
RectChildren.Clear();
var toIgnoreList = new List<Component>();
for (var i = 0; i < RectTransform.childCount; i++)
{
var rect = (RectTransform)RectTransform.GetChild(i);
if (rect != null && rect.gameObject.activeSelf)
{
RectChildren.Add(rect);
}
}
toIgnoreList = null;
}
protected void CalChildPosVertical()
{
verticalSize = 0f;
var rectSizeX = RectTransform.sizeDelta.x;
var rectSizeY = RectTransform.sizeDelta.y;
var tmpVec2 = Vector2.zero;
for (var i = 0; i < RectChildren.Count; ++i)
{
tmpVec2 = RectChildren[i].sizeDelta * RectChildren[i].localScale;
verticalSize += tmpVec2.y + Spaceing;
horizontalSize = Mathf.Max(horizontalSize, tmpVec2.x);
}
verticalSize -= Spaceing;
//align参数
var horizontalAlign = (int)ChildAlignment % 3;
var verticalAlign = (int)ChildAlignment / 3;
var horMiddlePos = 0f;
horMiddlePos += (rectSizeX - Right - Left) / 2 + Left;
//垂直开始位置
var verStartPos = 0f;
if (verticalAlign == 0) //upper
{
verStartPos += Top;
}
else if (verticalAlign == 1) //middle
{
if (verticalSize + Top + Bottom > rectSizeY)
{
verStartPos += Top;
}
else
{
verStartPos += (rectSizeY - verticalSize) / 2;
}
}
else if (verticalAlign == 2) //lower
{
if (verticalSize + Top + Bottom > rectSizeY)
{
verStartPos += Top;
}
else
{
verStartPos += rectSizeY - verticalSize - Bottom;
}
}
for (var i = 0; i < RectChildren.Count; ++i)
{
//设置水平位置
var rect = RectChildren[i];
if (horizontalAlign == 0) //left
{
SetChildAlongAxis(rect, 0, Left);
}
else if (horizontalAlign == 1) //center
{
SetChildAlongAxis(rect, 0, horMiddlePos - rect.sizeDelta.x * rect.localScale.x / 2);
}
else if (horizontalAlign == 2) //right
{
SetChildAlongAxis(rect, 0, rectSizeX - Right - rect.sizeDelta.x * rect.localScale.x);
}
//设置垂直位置
SetChildAlongAxis(rect, 1, verStartPos);
verStartPos += rect.sizeDelta.y * rect.localScale.y + spacing;
}
}
protected void CalChildPosHorizontal()
{
horizontalSize = 0f;
var rectSizeX = RectTransform.sizeDelta.x;
var rectSizeY = RectTransform.sizeDelta.y;
var tmpVec2 = Vector2.zero;
for (var i = 0; i < RectChildren.Count; ++i)
{
tmpVec2 = RectChildren[i].sizeDelta * RectChildren[i].localScale;
horizontalSize += tmpVec2.x + Spaceing;
verticalSize = Mathf.Max(verticalSize, tmpVec2.y);
}
horizontalSize -= Spaceing;
//align参数
var horizontalAlign = (int)ChildAlignment % 3;
var verticalAlign = (int)ChildAlignment / 3;
var verMiddlePos = 0f;
verMiddlePos += (rectSizeY - Top - Bottom) / 2 + Top;
//水平开始位置
var horStartPos = 0f;
if (horizontalAlign == 0) //left
{
horStartPos += Left;
}
else if (horizontalAlign == 1) //middle
{
if (horizontalSize + Left + Right > rectSizeX)
{
horStartPos += Left;
}
else
{
horStartPos += (rectSizeX - horizontalSize) / 2;
}
}
else if (horizontalAlign == 2) //right
{
if (horStartPos + Left + Right > rectSizeX)
{
horStartPos += Left;
}
else
{
horStartPos += rectSizeX - horizontalSize - Right;
}
}
for (var i = 0; i < RectChildren.Count; ++i)
{
//设置垂直位置
var rect = RectChildren[i];
if (verticalAlign == 0) //upper
{
SetChildAlongAxis(rect, 1, Top);
}
else if (verticalAlign == 1) //center
{
SetChildAlongAxis(rect, 1, verMiddlePos - rect.sizeDelta.y * rect.localScale.y / 2, rect.sizeDelta.y);
}
else if (verticalAlign == 2) //lower
{
SetChildAlongAxis(rect, 1, rectSizeY - Bottom - rect.sizeDelta.y * rect.localScale.y, rect.sizeDelta.y);
}
//设置水平位置
SetChildAlongAxis(rect, 0, horStartPos);
horStartPos += rect.sizeDelta.x * rect.localScale.x + spacing;
}
}
public float GetVerticalSize()
{
return verticalSize + Top + Bottom;
}
public float GetHorizontalSize()
{
return horizontalSize + Left + Right;
}
}
}