Files
JJBB/Assets/Project/Script/GUI/Base/UIContainerBase.cs

475 lines
14 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System;
using XLua;
public class UIContainerBase : UIBase
{
// 容器每个Item的内容和位置
public class ContentPos
{
public Vector2 Pos; // 位置
public object Obj; // 显示信息
public UIItemBase ShowItem; // 显示脚本 - 内包含和 Obj 一样的显示信息
}
void OnDisable()
{
_ContainerObj.anchoredPosition = Vector2.zero;
}
void OnEnable()
{
// 仅当Conten内容被重新设置过才执行初始化。
if (!_HasInit)
{
StartInitContainer();
}
}
#region calculate rect
protected float _ViewPortWidth = 0;
protected float _ViewPortHeight = 0;
protected float _ContentCanvasWidth = 0;
protected float _ContentCanvasHeight = 0;
protected int _ContentRow = 0;
protected int _ContentColumn = 0;
protected int _ShowRowCount = 0;
protected int _ShowColumnCount = 0;
public int _InitItemCount = 0;
private int _InitItemCountPrivate = 0;
private void CalculateRect(ICollection items)
{
int itemCount = items.Count;
_ViewPortWidth = _ScrollTransform.sizeDelta.x;
_ViewPortHeight = _ScrollTransform.sizeDelta.y;
_ContentColumn = 1;
_ContentRow = 1;
if (_LayoutGroup.constraint == GridLayoutGroup.Constraint.FixedRowCount)
{
_ContentColumn = _LayoutGroup.constraintCount;
_ContentRow = itemCount / _ContentColumn;
if (itemCount % _ContentColumn > 0)
{
++_ContentRow;
}
}
else if (_LayoutGroup.constraint == GridLayoutGroup.Constraint.FixedColumnCount)
{
_ContentRow = _LayoutGroup.constraintCount;
_ContentColumn = itemCount / _ContentRow;
if (itemCount % _ContentRow > 0)
{
++_ContentColumn;
}
}
_ValueList.Clear();
int i = 0;
var enumerator = items.GetEnumerator();
enumerator.Reset();
while (enumerator.MoveNext())
//for (int i = 0; i < itemCount; ++i)
{
int column = i / _ContentRow;
int row = i % _ContentRow;
var contentPos = new ContentPos();
contentPos.Pos = new Vector2(
row * (_LayoutGroup.cellSize.x + _LayoutGroup.spacing.x) + _LayoutGroup.cellSize.x * 0.5f,
-column * (_LayoutGroup.cellSize.y + _LayoutGroup.spacing.y) - _LayoutGroup.cellSize.y * 0.5f);
contentPos.Obj = enumerator.Current;
_ValueList.Add(contentPos);
++i;
}
_ContentCanvasWidth = _LayoutGroup.cellSize.x * _ContentRow + _LayoutGroup.spacing.x * (_ContentRow - 1);
_ContentCanvasHeight = _LayoutGroup.cellSize.y * _ContentColumn + _LayoutGroup.spacing.y * (_ContentColumn - 1);
if (_BG != null)
{
_BG.rectTransform.sizeDelta = new Vector2(_ContentCanvasWidth + 20, _ContentCanvasHeight + 20);
}
if (_ContainerBaseLarge)
{
_ContentCanvasWidth = Math.Max(_ScrollTransform.sizeDelta.x, _ContentCanvasWidth);
_ContentCanvasHeight = Math.Max(_ScrollTransform.sizeDelta.y, _ContentCanvasHeight);
}
_ShowRowCount = (int)Math.Ceiling((_ViewPortWidth + _LayoutGroup.spacing.x) / (_LayoutGroup.cellSize.x + _LayoutGroup.spacing.x));
_ShowColumnCount = (int)Math.Ceiling((_ViewPortHeight + _LayoutGroup.spacing.y) / (_LayoutGroup.cellSize.y + _LayoutGroup.spacing.y));
//_InitItemCount = _ShowColumnCount * _ShowRowCount;
//_InitItemCount = Math.Min(_InitItemCount, itemCount);
_ContainerObj.sizeDelta = new Vector2(_ContentCanvasWidth, _ContentCanvasHeight);
float containerPosX = 0;
float containerPosY = 0;
if (_ContainerObj.sizeDelta.x < _ScrollTransform.sizeDelta.x)
{
containerPosX = (_ScrollTransform.sizeDelta.x - _ContainerObj.sizeDelta.x) * 0.5f;
}
if (_ContainerObj.sizeDelta.y < _ScrollTransform.sizeDelta.y)
{
containerPosY = (_ContainerObj.sizeDelta.y - _ScrollTransform.sizeDelta.y) * 0.5f;
}
_ContainerObj.transform.localPosition = new Vector3(containerPosX, containerPosY, 0);
//LogModule.DebugLog("CalculateRect viewPortWidth:" + _ShowRowCount + "," + _ShowColumnCount + "," + _ContentCanvasWidth + "," + _ContentCanvasHeight);
}
#endregion
#region
public Vector3 GetItemPosition(object item)
{
foreach (UIItemBase uiItem in _ItemPrefabList)
{
if (uiItem._InitInfo == item)
{
return uiItem.transform.position;
}
}
return Vector3.zero;
}
public Vector3 GetItemLocalPosition(UIItemBase item)
{
foreach (UIItemBase uiItem in _ItemPrefabList)
{
if (uiItem._InitInfo.Equals(item._InitInfo))
{
return uiItem.transform.localPosition;
}
}
return Vector3.zero;
}
#endregion
public ScrollRect _ScrollRect; // 滑动框组件
public RectTransform _ScrollTransform; // 滑动框组件Rt
public GridLayoutGroup _LayoutGroup; // 自动布局组件
public GameObject _ContainItemPre; // Item预设体
public RectTransform _ContainerObj; // 自身容器Rt
public Image _BG;
public bool _ContainerBaseLarge = false;
protected List<UIItemBase> _ItemPrefabList = new List<UIItemBase>();
protected List<ContentPos> _ValueList = new List<ContentPos>(); // 内容的数组
protected UIItemBase.ItemClick _OnClickItem; // 单个内容Item点击回调
protected UIItemBase.PanelClick _OnClickPanel; // ...
public int GetValueCnt()
{
return _ValueList.Count;
}
public void SetValueObjByIndex(int index, object initInfo)
{
if(index < _ValueList.Count)
{
_ValueList[index].Obj = initInfo;
_ItemPrefabList[index]._InitInfo = initInfo;
Hashtable param = new Hashtable();
param.Add("InitObj", initInfo);
_ValueList[index].ShowItem.Show(param);
}
}
public delegate void ShowItemFinish();
protected ShowItemFinish m_ShowItemFinish = null;
public void SetShowItemFinishCallFun(ShowItemFinish fun)
{
m_ShowItemFinish = fun;
}
public void SetLayoutPosotion(int index)
{
if(_LayoutGroup!=null)
{
_LayoutGroup.transform.localPosition = new Vector3(_LayoutGroup.transform.position.x, _LayoutGroup.cellSize.y * index, _LayoutGroup.transform.position.z);
}
}
public int GetItemCount()
{
return _ValueList.Count;
}
protected Hashtable _ExHash;
private bool _HasInit = false;
//[CSharpCallLua]
public virtual void InitContentItem(IEnumerable valueList, UIItemBase.ItemClick onClick = null, Hashtable exhash = null, UIItemBase.PanelClick onPanelClick = null)
{
_InitItemCountPrivate = _InitItemCount;
//CalculateRect(valueList);
_ValueList.Clear();
//ClearPrefab();
int i = 0;
if (valueList == null)
{
ClearPrefab();
return;
}
var enumerator = valueList.GetEnumerator();
enumerator.Reset();
while (enumerator.MoveNext())
{
var contentPos = new ContentPos();
contentPos.Obj = enumerator.Current;
_ValueList.Add(contentPos);
++i;
}
if (_InitItemCountPrivate <= 0)
{
_InitItemCountPrivate = 30;
}
_InitItemCountPrivate = Math.Min(_InitItemCountPrivate, _ValueList.Count);
_HasInit = false;
_OnClickItem = onClick;
_OnClickPanel = onPanelClick;
_ExHash = exhash;
if (isActiveAndEnabled)
{
StartInitContainer();
}
//_LayoutGroup.enabled = false;
}
// For lua
public void InitContentItemL2L(List<System.Object> valueList, UIItemBase.ItemClick onClick = null, Hashtable exhash = null, UIItemBase.PanelClick onPanelClick = null)
{
InitContentItem(valueList, onClick, exhash, onPanelClick);
}
public void StartInitContainer()
{
_HasInit = true;
if (_ValueList.Count > 0)
{
StartCoroutine(InitItems(_ExHash));
}
else
{
ClearPrefab();
}
}
public virtual void ShowItems()
{
}
public virtual void ShowItemsFinish()
{
if (m_ShowItemFinish != null)
m_ShowItemFinish.Invoke();
WindowSign wnd = gameObject.GetComponentInParent<WindowSign>();
if (wnd != null)
wnd.SetWndDirty();
}
private bool IsPosInView(ContentPos pos)
{
return (_ContainerObj.localPosition.x + pos.Pos.x >= -_LayoutGroup.cellSize.x * 0.5f
&& _ContainerObj.localPosition.x + pos.Pos.x <= _ViewPortWidth + _LayoutGroup.cellSize.x * 0.5f
&& -_ContainerObj.localPosition.y - pos.Pos.y >= -_LayoutGroup.cellSize.y * 0.5f
&& -_ContainerObj.localPosition.y - pos.Pos.y <= _ViewPortHeight + _LayoutGroup.cellSize.y * 0.5f);
}
private void InitItem(ContentPos contentItem, UIItemBase preItem, Hashtable exhash)
{
preItem.gameObject.SetActive(true);
//preItem.transform.localPosition = new Vector3(contentItem.Pos.x, contentItem.Pos.y, 0);
//if (preItem._InitInfo != contentItem.Obj)
{
Hashtable hash;
if (exhash == null)
{
hash = new Hashtable();
}
else
{
hash = new Hashtable(exhash);
}
hash.Add("InitObj", contentItem.Obj);
preItem.Show(hash);
preItem._InitInfo = contentItem.Obj;
preItem._ClickEvent = _OnClickItem;
preItem._PanelClickEvent = _OnClickPanel;
contentItem.ShowItem = preItem;
}
}
public virtual void RefreshItems()
{
foreach (var item in _ItemPrefabList)
{
item.Refresh();
}
}
public virtual void RefreshItems(Hashtable hash)
{
foreach (var item in _ItemPrefabList)
{
item.Refresh(hash);
}
}
public void PreLoadItem(int preLoadCount)
{
InitItems(null);
}
private void ClearPrefab()
{
foreach (var prefab in _ItemPrefabList)
{
//prefab.transform.localPosition = new Vector3(1000, 1000, 1);
prefab.Hide();
prefab._InitInfo = null;
}
}
private IEnumerator InitItems(Hashtable exhash)
{
//先初始化可见
//var itemPrefabList = _ContainerObj.GetComponentsInChildren<CommonItemBackPackItem>();
//_ItemPrefabList = new List<UIItemBase>(itemPrefabList);
//ClearPrefab();
if (_InitItemCountPrivate > _ItemPrefabList.Count)
{
for (int i = _ItemPrefabList.Count; i < _InitItemCountPrivate; ++i)
{
GameObject obj = GameObject.Instantiate<GameObject>(_ContainItemPre);
obj.transform.SetParent(_ContainerObj.transform);
obj.transform.localScale = Vector3.one;
obj.transform.localPosition = Vector3.zero;
obj.name = _ContainItemPre.name + _ItemPrefabList.Count;
var itemScript = obj.GetComponent<UIItemBase>();
//itemScript.Hide();
_ItemPrefabList.Add(itemScript);
//_EmpeyItemPrefab.Enqueue(itemScript);
}
}
for (int i = 0; i < _InitItemCountPrivate; ++i)
{
InitItem(_ValueList[i], _ItemPrefabList[i], exhash);
}
if (_ItemPrefabList.Count > _ValueList.Count)
{
for (int i = _ValueList.Count; i < _ItemPrefabList.Count; ++i)
{
_ItemPrefabList[i].Hide();
}
}
if (_InitItemCountPrivate >= _ValueList.Count)
{
ShowItemsFinish();
yield break;
}
yield return new WaitForFixedUpdate();
int nextNeedCount = _ValueList.Count - _InitItemCountPrivate;
if (nextNeedCount > 0)
{
int needCreateCount = nextNeedCount - (_ItemPrefabList.Count - _InitItemCountPrivate);
for (int i = 0; i < needCreateCount; ++i)
{
GameObject obj = GameObject.Instantiate<GameObject>(_ContainItemPre);
obj.transform.SetParent(_ContainerObj.transform);
obj.transform.localScale = Vector3.one;
obj.transform.localPosition = Vector3.zero;
var itemScript = obj.GetComponent<UIItemBase>();
//itemScript.Hide();
_ItemPrefabList.Add(itemScript);
//_EmpeyItemPrefab.Enqueue(itemScript);
}
for (int i = _InitItemCountPrivate; i < _ValueList.Count; ++i)
{
InitItem(_ValueList[i], _ItemPrefabList[i], exhash);
}
}
if (_ItemPrefabList.Count > _ValueList.Count)
{
for (int i = _ValueList.Count; i < _ItemPrefabList.Count; ++i)
{
_ItemPrefabList[i].Hide();
}
}
ShowItemsFinish();
}
public T GetContainItem<T>(int idx)
{
return _ItemPrefabList[idx].GetComponent<T>();
}
public void ForeachActiveItem<T>(Action<T> action)
{
for (int i = 0; i < _ItemPrefabList.Count; ++i)
{
if (_ItemPrefabList[i].gameObject.activeSelf)
{
var component = _ItemPrefabList[i].gameObject.GetComponent<T>();
if (component == null)
continue;
action(component);
}
}
}
public virtual void ForeachActiveBaseItemL2L(Action<LuaUIItemBase> action)
{
ForeachActiveItem<LuaUIItemBase>(action);
}
public Vector3 GetObjItemPos(object obj)
{
foreach (var item in _ItemPrefabList)
{
if (item._InitInfo == obj)
{
return item.transform.position;
}
}
return Vector3.zero;
}
}