691 lines
27 KiB
C#
691 lines
27 KiB
C#
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace BF
|
||
{
|
||
public class BFScrollRectCommon : BFScrollRectBase
|
||
{
|
||
public BFCell bfCell;
|
||
// public float spacing;
|
||
public int topRecoveryOffset;
|
||
public int downRecoveryOffset;
|
||
public BFUIDirection direction;
|
||
public bool reverse = false;
|
||
public bool centerWhenNotFull = false; // 新增参数,控制是否在不满一行时居中
|
||
|
||
Stack<BFCell> cellPool = new Stack<BFCell>();
|
||
List<BFCell> activeCells = new List<BFCell>();
|
||
|
||
float cellSize;
|
||
int instantiateCount = 0;
|
||
int totalCount = 0;
|
||
int tmpTotalCount = 0;
|
||
public float cellWidth = 0.0f;
|
||
public float CellWidth
|
||
{
|
||
get { return cellWidth;}
|
||
set {
|
||
cellWidth = value;
|
||
UpdateAllCellPosition();
|
||
}
|
||
}
|
||
public float cellHeight = 0.0f;
|
||
public float CellHeight
|
||
{
|
||
get { return cellHeight;}
|
||
set {
|
||
cellHeight = value;
|
||
UpdateAllCellPosition();
|
||
}
|
||
}
|
||
private int minIdx = 0;
|
||
private int maxIdx = 0;
|
||
private int tmpMinIdx = 0;
|
||
private int tmpMaxIdx = 0;
|
||
private int maxLine = 0;
|
||
private Vector2 curAnchoredPosition = new Vector2(0.0f, 0.0f);
|
||
public int perLineNum = 1;
|
||
void Awake()
|
||
{
|
||
if (bfCell.gameObject.activeSelf)
|
||
{
|
||
bfCell.gameObject.SetActive(false);
|
||
}
|
||
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
if (reverse)
|
||
{
|
||
ContentTrans.anchorMax = new Vector2(0.0f, 0.0f);
|
||
ContentTrans.anchorMin = new Vector2(0.0f, 0.0f);
|
||
ContentTrans.pivot = new Vector2(0.0f, 0.0f);
|
||
ContentTrans.anchoredPosition = Vector2.zero;
|
||
}
|
||
else
|
||
{
|
||
ContentTrans.anchorMax = new Vector2(0.0f, 1.0f);
|
||
ContentTrans.anchorMin = new Vector2(0.0f, 1.0f);
|
||
ContentTrans.pivot = new Vector2(0.0f, 1.0f);
|
||
ContentTrans.anchoredPosition = Vector2.zero;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (reverse)
|
||
{
|
||
ContentTrans.anchorMax = new Vector2(1.0f, 1.0f);
|
||
ContentTrans.anchorMin = new Vector2(1.0f, 1.0f);
|
||
ContentTrans.pivot = new Vector2(1.0f, 1.0f);
|
||
ContentTrans.anchoredPosition = new Vector2(1.0f, 1.0f);
|
||
}
|
||
else
|
||
{
|
||
ContentTrans.anchorMax = new Vector2(0.0f, 0.0f);
|
||
ContentTrans.anchorMin = new Vector2(0.0f, 0.0f);
|
||
ContentTrans.pivot = new Vector2(0.0f, 0.0f);
|
||
ContentTrans.anchoredPosition = Vector2.zero;
|
||
}
|
||
}
|
||
}
|
||
|
||
public override void RefillCells(int totalCount, int targetIndex)
|
||
{
|
||
SetTotalCount(totalCount);
|
||
if (activeCells.Count != 0)
|
||
{
|
||
while (activeCells.Count != 0)
|
||
{
|
||
Pool(activeCells[activeCells.Count - 1]);
|
||
}
|
||
UnityScrollRect.StopMovement();
|
||
}
|
||
minIdx = 0;
|
||
maxIdx = 0;
|
||
|
||
if (targetIndex > 0)
|
||
{
|
||
MoveToIndex(targetIndex);
|
||
}
|
||
|
||
TryFullFill();
|
||
AnchoredPositionChange();
|
||
}
|
||
|
||
public override void SetTotalCount(int totalCount)
|
||
{
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "totalCount = " + totalCount.ToString());
|
||
this.totalCount = totalCount;
|
||
if (totalCount < activeCells.Count)
|
||
{
|
||
for (int i = activeCells.Count - 1; i > totalCount - 1; i--)
|
||
{
|
||
Pool(activeCells[i]);
|
||
}
|
||
}
|
||
|
||
maxLine = Mathf.CeilToInt(totalCount*1.0f/perLineNum);
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
float maxHeight = Mathf.Max(UnityScrollRect.viewport.rect.height, maxLine*cellHeight + topRecoveryOffset + downRecoveryOffset);
|
||
ContentTrans.sizeDelta = new Vector2(ContentTrans.sizeDelta.x, maxHeight);
|
||
// cellWidth = (int)UnityScrollRect.viewport.rect.width;
|
||
if (reverse)
|
||
{
|
||
float posY = UnityScrollRect.content.anchoredPosition.y;
|
||
float minPosY = Mathf.Floor(UnityScrollRect.viewport.rect.height) - maxHeight;
|
||
if (posY < minPosY)
|
||
{
|
||
UnityScrollRect.content.anchoredPosition = new Vector2(UnityScrollRect.content.anchoredPosition.x, minPosY);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
float posY = UnityScrollRect.content.anchoredPosition.y;
|
||
float maxPosY = maxHeight - Mathf.Floor(UnityScrollRect.viewport.rect.height);
|
||
if (posY > maxPosY)
|
||
{
|
||
UnityScrollRect.content.anchoredPosition = new Vector2(UnityScrollRect.content.anchoredPosition.x, maxPosY);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
float maxWidth = Mathf.Max(UnityScrollRect.viewport.rect.width, maxLine*cellWidth + topRecoveryOffset + downRecoveryOffset);
|
||
ContentTrans.sizeDelta = new Vector2(maxWidth, ContentTrans.sizeDelta.y);
|
||
// cellHeight = (int)UnityScrollRect.viewport.rect.height;
|
||
|
||
if (reverse)
|
||
{
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "UnityScrollRect.content.anchoredPosition.x = " + UnityScrollRect.content.anchoredPosition.x);
|
||
float posX = UnityScrollRect.content.anchoredPosition.x;
|
||
float maxPosX = maxWidth - Mathf.Floor(UnityScrollRect.viewport.rect.width);
|
||
if (posX > maxPosX)
|
||
{
|
||
UnityScrollRect.content.anchoredPosition = new Vector2(maxPosX, UnityScrollRect.content.anchoredPosition.y);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
float posX = UnityScrollRect.content.anchoredPosition.x;
|
||
float minPosX = Mathf.Floor(UnityScrollRect.viewport.rect.width) - maxWidth;
|
||
if (posX < minPosX)
|
||
{
|
||
UnityScrollRect.content.anchoredPosition = new Vector2(minPosX, UnityScrollRect.content.anchoredPosition.y);
|
||
}
|
||
}
|
||
}
|
||
// minIdx = Mathf.Max(1, minIdx);
|
||
// maxIdx = Mathf.Min(this.totalCount, maxIdx);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", " ContentTrans.sizeDelta.x = " + ContentTrans.sizeDelta.x);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", " ContentTrans.sizeDelta.y = " + ContentTrans.sizeDelta.y);
|
||
UpdateAllCellPosition();
|
||
}
|
||
|
||
public override void RefreshAll()
|
||
{
|
||
int count = activeCells.Count;
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
var cell = activeCells[i];
|
||
RefreshAction?.Invoke(cell.dataIndex, cell.objIndex);
|
||
}
|
||
}
|
||
|
||
public override void SetSelected(int index)
|
||
{
|
||
selectedIndex = index;
|
||
int count = activeCells.Count;
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
var cell = activeCells[i];
|
||
Selected?.Invoke(cell.dataIndex == index, cell.objIndex);
|
||
}
|
||
}
|
||
|
||
public override void ClearCells()
|
||
{
|
||
while (activeCells.Count != 0)
|
||
{
|
||
Pool(activeCells[activeCells.Count - 1]);
|
||
}
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
ContentTrans.anchoredPosition = Vector2.zero;
|
||
}
|
||
else
|
||
{
|
||
if (reverse)
|
||
{
|
||
ContentTrans.anchoredPosition = new Vector2(1.0f, 1.0f);
|
||
}
|
||
else
|
||
{
|
||
ContentTrans.anchoredPosition = Vector2.zero;
|
||
}
|
||
}
|
||
minIdx = 0;
|
||
maxIdx = 0;
|
||
}
|
||
|
||
public override void AnchoredPositionChange()
|
||
{
|
||
if (Mathf.Abs(curAnchoredPosition.x - UnityScrollRect.content.anchoredPosition.x) >= 1 || Mathf.Abs(curAnchoredPosition.y - UnityScrollRect.content.anchoredPosition.y) >= 1)
|
||
{
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "diffX = " + (curAnchoredPosition.x - UnityScrollRect.content.anchoredPosition.x));
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "diffY = " + (curAnchoredPosition.y - UnityScrollRect.content.anchoredPosition.y));
|
||
curAnchoredPosition.x = UnityScrollRect.content.anchoredPosition.x;
|
||
curAnchoredPosition.y = UnityScrollRect.content.anchoredPosition.y;
|
||
OnAnchoredPositionAction?.Invoke(UnityScrollRect.content.anchoredPosition.x, UnityScrollRect.content.anchoredPosition.y);
|
||
}
|
||
}
|
||
|
||
protected override void TryFullFill()
|
||
{
|
||
CheckBorder();
|
||
}
|
||
|
||
void calculateIndex()
|
||
{
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
float posY = UnityScrollRect.content.anchoredPosition.y;
|
||
if (reverse)
|
||
{
|
||
// float posX = totalMaxWidth - (Mathf.Floor(UnityScrollRect.viewport.rect.width) - UnityScrollRect.content.anchoredPosition.x);
|
||
tmpMinIdx = Mathf.CeilToInt(-(posY + topRecoveryOffset)/cellHeight);
|
||
tmpMaxIdx = Mathf.CeilToInt((Mathf.Floor(UnityScrollRect.viewport.rect.height) - (posY + topRecoveryOffset))/cellHeight);
|
||
}
|
||
else
|
||
{
|
||
tmpMinIdx = Mathf.CeilToInt((posY - topRecoveryOffset)/cellHeight);
|
||
tmpMaxIdx = Mathf.CeilToInt((posY - topRecoveryOffset + Mathf.Floor(UnityScrollRect.viewport.rect.height))/cellHeight);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "posY = " + posY);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
float posX = UnityScrollRect.content.anchoredPosition.x;
|
||
if (reverse)
|
||
{
|
||
// float posX = totalMaxWidth - (Mathf.Floor(UnityScrollRect.viewport.rect.width) - UnityScrollRect.content.anchoredPosition.x);
|
||
tmpMinIdx = Mathf.CeilToInt((posX - topRecoveryOffset)/cellWidth);
|
||
tmpMaxIdx = Mathf.CeilToInt((Mathf.Floor(UnityScrollRect.viewport.rect.width) + (posX - topRecoveryOffset))/cellWidth);
|
||
}
|
||
else
|
||
{
|
||
tmpMinIdx = Mathf.CeilToInt(-(posX + topRecoveryOffset)/cellWidth);
|
||
tmpMaxIdx = Mathf.CeilToInt((Mathf.Floor(UnityScrollRect.viewport.rect.width) - (posX + topRecoveryOffset))/cellWidth);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "posX = " + posX);
|
||
}
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "posX = " + posX);
|
||
}
|
||
tmpMinIdx = Mathf.Max(1, tmpMinIdx);
|
||
tmpMaxIdx = Mathf.Min(maxLine, tmpMaxIdx);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "tmpMinIdx = " + tmpMinIdx + " tmpMaxIdx = " + tmpMaxIdx);
|
||
}
|
||
|
||
bool CheckBorder()
|
||
{
|
||
calculateIndex();
|
||
|
||
if (minIdx == 0)
|
||
{
|
||
minIdx = tmpMinIdx;
|
||
maxIdx = tmpMaxIdx;
|
||
tmpTotalCount = totalCount;
|
||
int minIdxMult = (minIdx - 1)*perLineNum + 1;
|
||
int maxIdxMult = maxIdx*perLineNum;
|
||
maxIdxMult = Mathf.Min(maxIdxMult, totalCount);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "===== 1 minIdxMult = " + minIdxMult + " maxIdxMult = " + maxIdxMult);
|
||
for (int i = minIdxMult; i <= maxIdxMult; i++)
|
||
{
|
||
TryStartAdd(i, false);
|
||
}
|
||
AnchoredPositionChange();
|
||
return false;
|
||
}
|
||
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "===== 1 tmpMinIdx = " + tmpMinIdx + " tmpMaxIdx = " + tmpMaxIdx);
|
||
if (tmpMinIdx == minIdx && tmpMaxIdx == maxIdx && tmpTotalCount == totalCount)
|
||
{
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "===== 3 minIdx = " + minIdx + " maxIdx = " + maxIdx);
|
||
AnchoredPositionChange();
|
||
return false;
|
||
}
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "===== 2 tmpMinIdx = " + tmpMinIdx + " tmpMaxIdx = " + tmpMaxIdx);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "minIdx = " + minIdx + " maxIdx = " + maxIdx);
|
||
int minIdxMult2 = (tmpMinIdx - 1)*perLineNum + 1;
|
||
int maxIdxMult2 = tmpMaxIdx*perLineNum;
|
||
maxIdxMult2 = Mathf.Min(maxIdxMult2, totalCount);
|
||
for (int ii = activeCells.Count - 1; ii >= 0; ii--)
|
||
{
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "================================1 minIdx = " + i);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", activeCells[ii].dataIndex.ToString());
|
||
if (activeCells[ii] && (activeCells[ii].dataIndex < minIdxMult2 || activeCells[ii].dataIndex > maxIdxMult2))
|
||
{
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "activeCells[ii].dataIndex = " + activeCells[ii].dataIndex);
|
||
Pool(activeCells[ii]);
|
||
}
|
||
}
|
||
int minIdxMult1 = (tmpMinIdx - 1)*perLineNum + 1;
|
||
int maxIdxMult1 = tmpMaxIdx*perLineNum;
|
||
maxIdxMult1 = Mathf.Min(maxIdxMult1, totalCount);
|
||
for (int i = minIdxMult1; i <= maxIdxMult1; i++)
|
||
{
|
||
bool notFind = true;
|
||
for (int ii = 0; ii < activeCells.Count; ii++)
|
||
{
|
||
if (activeCells[ii] && activeCells[ii].dataIndex == i)
|
||
{
|
||
notFind = false;
|
||
break;
|
||
}
|
||
}
|
||
if(notFind)
|
||
{
|
||
if (minIdx > tmpMinIdx)
|
||
{
|
||
TryStartAdd(i, true);
|
||
}
|
||
else
|
||
{
|
||
TryStartAdd(i, false);
|
||
}
|
||
}
|
||
}
|
||
// if (minIdx > tmpMinIdx)
|
||
// {
|
||
// float minIdxMult1 = (tmpMinIdx - 1)*perLineNum + 1;
|
||
// float minIdxMult2 = (minIdx - 1)*perLineNum;
|
||
// for (float i = minIdxMult1; i <= minIdxMult2; i++)
|
||
// {
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "minIdx i = " + i);
|
||
// TryStartAdd(i, true);
|
||
// }
|
||
// }
|
||
// if (tmpMaxIdx > maxIdx || tmpTotalCount != totalCount)
|
||
// {
|
||
// float maxIdxMult1 = maxIdx*perLineNum + 1;
|
||
// float maxIdxMult2 = tmpMaxIdx*perLineNum;
|
||
// maxIdxMult2 = Mathf.Min(maxIdxMult2, totalCount);
|
||
// // BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "maxIdxMult2 = " + maxIdxMult2);
|
||
// for (float i = maxIdxMult1; i <= maxIdxMult2; i++)
|
||
// {
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "maxIdx i = " + i);
|
||
// TryStartAdd(i, false);
|
||
// }
|
||
// }
|
||
minIdx = tmpMinIdx;
|
||
maxIdx = tmpMaxIdx;
|
||
tmpTotalCount = totalCount;
|
||
AnchoredPositionChange();
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "minIdx = " + minIdx + " maxIdx = " + maxIdx + " maxCellNum = " + (int)Mathf.Ceil(UnityScrollRect.viewport.rect.width/cellWidth));
|
||
|
||
return false;
|
||
}
|
||
|
||
private float GetPositionXByIndex(int index)
|
||
{
|
||
float posX = 0.0f;
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
if (centerWhenNotFull && totalCount < perLineNum)
|
||
{
|
||
float totalWidth = totalCount * cellWidth;
|
||
float startPos = (UnityScrollRect.viewport.rect.width - totalWidth) / 2;
|
||
float idx = (index - 1.0f) % perLineNum + 1.0f;
|
||
posX = startPos + (idx - 0.5f) * cellWidth;
|
||
}
|
||
else
|
||
{
|
||
if (reverse)
|
||
{
|
||
float cellWidth1 = UnityScrollRect.viewport.rect.width / perLineNum;
|
||
float idx = (index - 1.0f) % perLineNum + 1.0f;
|
||
posX = (idx - 0.5f) * cellWidth1;
|
||
}
|
||
else
|
||
{
|
||
float cellWidth1 = UnityScrollRect.viewport.rect.width / perLineNum;
|
||
float idx = (index - 1.0f) % perLineNum + 1.0f;
|
||
posX = (idx - 0.5f) * cellWidth1;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (reverse)
|
||
{
|
||
float idxX = Mathf.Ceil(index*1.0f/perLineNum);
|
||
posX = -(idxX - 0.5f)*cellWidth - topRecoveryOffset;
|
||
}
|
||
else
|
||
{
|
||
float idxX = Mathf.Ceil(index*1.0f/perLineNum);
|
||
posX = (idxX - 0.5f)*cellWidth + topRecoveryOffset;
|
||
}
|
||
}
|
||
return posX;
|
||
}
|
||
private float GetPositionYByIndex(int index)
|
||
{
|
||
float posY = 0.0f;
|
||
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
if (reverse)
|
||
{
|
||
float idxY = Mathf.Ceil(index*1.0f/perLineNum);
|
||
posY = (idxY - 0.5f)*cellHeight + topRecoveryOffset;
|
||
}
|
||
else
|
||
{
|
||
float idxY = Mathf.Ceil(index*1.0f/perLineNum);
|
||
posY = -(idxY - 0.5f)*cellHeight - topRecoveryOffset;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (centerWhenNotFull && totalCount < perLineNum)
|
||
{
|
||
// 在ContentTrans高度范围内居中
|
||
float totalHeight = totalCount * cellHeight;
|
||
float contentOffset = (ContentTrans.rect.height - totalHeight) / 2;
|
||
|
||
// 元素在ContentTrans内垂直居中
|
||
float idx = (index - 1.0f) % perLineNum + 1.0f;
|
||
if (reverse)
|
||
{
|
||
posY = -(contentOffset + (idx - 0.5f) * cellHeight);
|
||
}
|
||
else
|
||
{
|
||
posY = contentOffset + (idx - 0.5f) * cellHeight;
|
||
}
|
||
|
||
// 如果ContentTrans比viewport矮,调整全局居中
|
||
if (ContentTrans.rect.height < UnityScrollRect.viewport.rect.height)
|
||
{
|
||
float viewportOffset = (UnityScrollRect.viewport.rect.height - ContentTrans.rect.height) / 2;
|
||
if (reverse)
|
||
{
|
||
posY -= viewportOffset; // 抵消视口偏移
|
||
}
|
||
else
|
||
{
|
||
posY += viewportOffset; // 抵消视口偏移
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (reverse)
|
||
{
|
||
float cellHeight1 = UnityScrollRect.viewport.rect.height / perLineNum;
|
||
float offset = UnityScrollRect.viewport.rect.height / perLineNum / 2.0f;
|
||
float idx = (index - 1.0f) % perLineNum + 1.0f;
|
||
posY = -(offset + (idx - 1.0f) * cellHeight1);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "index = " + index + " posY = " + posY + " offset = " + offset);
|
||
}
|
||
else
|
||
{
|
||
float cellHeight1 = UnityScrollRect.viewport.rect.height / perLineNum;
|
||
float offset = UnityScrollRect.viewport.rect.height - UnityScrollRect.viewport.rect.height / perLineNum / 2.0f;
|
||
float idx = (index - 1.0f) % perLineNum + 1.0f;
|
||
posY = offset - (idx - 1.0f) * cellHeight1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return posY;
|
||
}
|
||
void TryStartAdd(int index, bool addMin)
|
||
{
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "index = " + index);
|
||
if (totalCount == 0)
|
||
{
|
||
return;
|
||
}
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "cellWidth = " + cellWidth + " index - 0.5 = " + (index - 0.5));
|
||
float posX = GetPositionXByIndex(index);
|
||
float posY = GetPositionYByIndex(index);
|
||
// BFLog.LogDebug(BFLog.DEBUG_GAME_LAUNCH, "red", "posX = " + posX + " posY = " + posY + " index = " + index);
|
||
var cell = GetCell();
|
||
cell.name = StringConst.GetScrollRectCellName(index - 1);
|
||
cell.dataIndex = index;
|
||
if (reverse)
|
||
{
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
cell.CachedRectTransform.anchorMin = new Vector2(0.0f, 0.0f);
|
||
cell.CachedRectTransform.anchorMax = new Vector2(0.0f, 0.0f);
|
||
}
|
||
else
|
||
{
|
||
cell.CachedRectTransform.anchorMin = new Vector2(1.0f, 1.0f);
|
||
cell.CachedRectTransform.anchorMax = new Vector2(1.0f, 1.0f);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
cell.CachedRectTransform.anchorMin = new Vector2(0.0f, 1.0f);
|
||
cell.CachedRectTransform.anchorMax = new Vector2(0.0f, 1.0f);
|
||
}
|
||
else
|
||
{
|
||
cell.CachedRectTransform.anchorMin = new Vector2(0.0f, 0.0f);
|
||
cell.CachedRectTransform.anchorMax = new Vector2(0.0f, 0.0f);
|
||
}
|
||
}
|
||
|
||
cell.CachedRectTransform.pivot = new Vector2(0.5f, 0.5f);
|
||
|
||
cell.CachedRectTransform.anchoredPosition = new Vector2(posX, posY);
|
||
if (addMin)
|
||
{
|
||
activeCells.Insert(0, cell);
|
||
}
|
||
else
|
||
{
|
||
activeCells.Add(cell);
|
||
}
|
||
cell.gameObject.SetActive(true);
|
||
RefreshAction?.Invoke(cell.dataIndex, cell.objIndex);
|
||
}
|
||
|
||
BFCell GetCell()
|
||
{
|
||
if (cellPool.Count > 0)
|
||
{
|
||
return cellPool.Pop();
|
||
}
|
||
else
|
||
{
|
||
var t = Instantiate(bfCell.CachedRectTransform);
|
||
t.SetParent(ContentTrans);
|
||
t.localScale = bfCell.CachedRectTransform.localScale;
|
||
t.anchoredPosition3D = Vector3.zero;
|
||
instantiateCount++;
|
||
var newCell = t.GetComponent<BFCell>();
|
||
newCell.objIndex = instantiateCount;
|
||
OnInstantiateCell?.Invoke(newCell.gameObject);
|
||
return newCell;
|
||
}
|
||
}
|
||
|
||
void Pool(BFCell cell)
|
||
{
|
||
activeCells.Remove(cell);
|
||
cell.gameObject.SetActive(false);
|
||
cellPool.Push(cell);
|
||
}
|
||
public override void MoveToIndex(int index)
|
||
{
|
||
if (index > totalCount)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (direction == BFUIDirection.Vertical)
|
||
{
|
||
float moveDistance = cellHeight * Mathf.Floor((index - 1)*1.0f/perLineNum);
|
||
float moveHeight = Mathf.Min(moveDistance, ContentTrans.rect.size.y - ViewPortTrans.rect.size.y);
|
||
if(this.reverse)
|
||
{
|
||
ContentTrans.anchoredPosition = new Vector2(ContentTrans.anchoredPosition.x, -moveHeight);
|
||
}
|
||
else
|
||
{
|
||
ContentTrans.anchoredPosition = new Vector2(ContentTrans.anchoredPosition.x, moveHeight);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
float moveDistance = cellWidth * Mathf.Floor((index - 1)*1.0f/perLineNum);
|
||
float moveWidth = Mathf.Min(moveDistance, ContentTrans.rect.size.x - ViewPortTrans.rect.size.x);
|
||
if(this.reverse)
|
||
{
|
||
ContentTrans.anchoredPosition = new Vector2(moveWidth, ContentTrans.anchoredPosition.y);
|
||
}
|
||
else
|
||
{
|
||
ContentTrans.anchoredPosition = new Vector2(-moveWidth, ContentTrans.anchoredPosition.y);
|
||
}
|
||
}
|
||
}
|
||
|
||
public override void RemoveCell(int index)
|
||
{
|
||
if (totalCount <= 0)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var activeCount = activeCells.Count;
|
||
if (activeCells[activeCount - 1].dataIndex == totalCount && activeCells[0].dataIndex > index)
|
||
{
|
||
foreach (var cell in activeCells)
|
||
{
|
||
cell.dataIndex -= 1;
|
||
}
|
||
}
|
||
|
||
SetTotalCount(totalCount - 1);
|
||
TryFullFill();
|
||
RefreshAll();
|
||
}
|
||
|
||
|
||
public void StopMovement()
|
||
{
|
||
UnityScrollRect.StopMovement();
|
||
}
|
||
[ContextMenu("UpdateAllCellPosition")]
|
||
public void UpdateAllCellPosition()
|
||
{
|
||
for (int i = 0; i < activeCells.Count; i++)
|
||
{
|
||
float posX = GetPositionXByIndex(activeCells[i].dataIndex);
|
||
float posY = GetPositionYByIndex(activeCells[i].dataIndex);
|
||
activeCells[i].CachedRectTransform.anchoredPosition = new Vector2(posX, posY);
|
||
}
|
||
}
|
||
public void SetCellWidth(float width)
|
||
{
|
||
cellWidth = width;
|
||
UpdateAllCellPosition();
|
||
}
|
||
|
||
public void SetCellHeight(float height)
|
||
{
|
||
cellHeight = height;
|
||
UpdateAllCellPosition();
|
||
}
|
||
public void SetPerLineNum(int num)
|
||
{
|
||
perLineNum = num;
|
||
UpdateAllCellPosition();
|
||
}
|
||
public void SetTopRecoveryOffset(int num)
|
||
{
|
||
topRecoveryOffset = num;
|
||
UpdateAllCellPosition();
|
||
}
|
||
public void SetDownRecoveryOffset(int num)
|
||
{
|
||
downRecoveryOffset = num;
|
||
UpdateAllCellPosition();
|
||
}
|
||
public int GetTopRecoveryOffset()
|
||
{
|
||
return topRecoveryOffset;
|
||
}
|
||
public int GetDownRecoveryOffset()
|
||
{
|
||
return downRecoveryOffset;
|
||
}
|
||
}
|
||
} |