Files
UltimateFishing/Assets/Scripts/Assembly-CSharp/UIWidgets/ListViewCustomHeight.cs
2026-02-21 16:45:37 +08:00

245 lines
6.2 KiB
C#

using System;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
namespace UIWidgets
{
public class ListViewCustomHeight<TComponent, TItem> : ListViewCustom<TComponent, TItem> where TComponent : ListViewItem where TItem : IItemHeight
{
[Tooltip("Calculate height automaticly without using IListViewItemHeight.Height.")]
[SerializeField]
private bool ForceAutoHeightCalculation = true;
private TComponent defaultItemCopy;
private RectTransform defaultItemCopyRect;
private bool IsCanCalculateHeight;
private LayoutGroup defaultItemlayoutGroup;
protected TComponent DefaultItemCopy
{
get
{
if (defaultItemCopy == null)
{
defaultItemCopy = UnityEngine.Object.Instantiate(DefaultItem);
defaultItemCopy.transform.SetParent(DefaultItem.transform.parent);
Utilites.FixInstantiated(DefaultItem, defaultItemCopy);
defaultItemCopy.gameObject.name = "DefaultItemCopy";
defaultItemCopy.gameObject.SetActive(false);
}
return defaultItemCopy;
}
}
protected RectTransform DefaultItemCopyRect
{
get
{
if (defaultItemCopyRect == null)
{
defaultItemCopyRect = defaultItemCopy.transform as RectTransform;
}
return defaultItemCopyRect;
}
}
public ListViewCustomHeight()
{
IsCanCalculateHeight = typeof(IListViewItemHeight).IsAssignableFrom(typeof(TComponent));
}
protected override void Awake()
{
Start();
}
protected override void CalculateMaxVisibleItems()
{
SetItemsHeight(base.DataSource);
float height = scrollHeight;
maxVisibleItems = base.DataSource.OrderBy(GetItemHeight).TakeWhile(delegate(TItem x)
{
height -= x.Height;
return height > 0f;
}).Count() + 2;
}
protected override void CalculateItemSize()
{
RectTransform rectTransform = DefaultItem.transform as RectTransform;
ILayoutElement[] source = rectTransform.GetComponents<ILayoutElement>();
if (itemHeight == 0f)
{
float num = source.Max((ILayoutElement x) => Mathf.Max(x.minHeight, x.preferredHeight));
itemHeight = ((!(num > 0f)) ? rectTransform.rect.height : num);
}
if (itemWidth == 0f)
{
float num2 = source.Max((ILayoutElement x) => Mathf.Max(x.minWidth, x.preferredWidth));
itemWidth = ((!(num2 > 0f)) ? rectTransform.rect.width : num2);
}
}
protected override void ScrollTo(int index)
{
if (CanOptimize())
{
float scrollValue = GetScrollValue();
float num = GetScrollValue() + scrollHeight;
float num2 = ItemStartAt(index);
float num3 = ItemEndAt(index) + LayoutBridge.GetMargin();
if (num2 < scrollValue)
{
SetScrollValue(num2);
}
else if (num3 > num)
{
SetScrollValue(num3 - GetScrollSize());
}
}
}
protected override float CalculateBottomFillerSize()
{
if (bottomHiddenItems == 0)
{
return 0f;
}
float num = base.DataSource.GetRange(topHiddenItems + visibleItems, bottomHiddenItems).SumFloat(GetItemHeight);
return Mathf.Max(0f, num + LayoutBridge.GetSpacing() * (float)(bottomHiddenItems - 1));
}
protected override float CalculateTopFillerSize()
{
if (topHiddenItems == 0)
{
return 0f;
}
float num = base.DataSource.GetRange(0, topHiddenItems).SumFloat(GetItemHeight);
return Mathf.Max(0f, num + LayoutBridge.GetSpacing() * (float)(topHiddenItems - 1));
}
private float GetItemHeight(TItem item)
{
return item.Height;
}
private float ItemStartAt(int index)
{
float num = base.DataSource.GetRange(0, index).SumFloat(GetItemHeight);
return num + LayoutBridge.GetSpacing() * (float)index;
}
private float ItemEndAt(int index)
{
float num = base.DataSource.GetRange(0, index + 1).SumFloat(GetItemHeight);
return num + LayoutBridge.GetSpacing() * (float)index;
}
public override int Add(TItem item)
{
if (item == null)
{
throw new ArgumentNullException("item", "Item is null.");
}
if (item.Height == 0f)
{
item.Height = CalculateItemHeight(item);
}
return base.Add(item);
}
private void SetItemsHeight(ObservableList<TItem> items, bool forceUpdate = true)
{
items.ForEach(delegate(TItem x)
{
if (x.Height == 0f || forceUpdate)
{
x.Height = CalculateItemHeight(x);
}
});
}
public override void Resize()
{
SetItemsHeight(base.DataSource);
base.Resize();
}
protected override void SetNewItems(ObservableList<TItem> newItems)
{
SetItemsHeight(newItems);
base.SetNewItems(newItems);
}
private int GetIndexByHeight(float height)
{
float spacing = LayoutBridge.GetSpacing();
return base.DataSource.TakeWhile(delegate(TItem item, int index)
{
height -= item.Height;
if (index > 0)
{
height -= spacing;
}
return height >= 0f;
}).Count();
}
protected override int GetLastVisibleIndex(bool strict = false)
{
int indexByHeight = GetIndexByHeight(GetScrollValue() + scrollHeight);
return (!strict) ? (indexByHeight + 2) : indexByHeight;
}
protected override int GetFirstVisibleIndex(bool strict = false)
{
int indexByHeight = GetIndexByHeight(GetScrollValue());
if (strict)
{
return indexByHeight;
}
return Mathf.Min(indexByHeight, Mathf.Max(0, base.DataSource.Count - visibleItems));
}
private float CalculateItemHeight(TItem item)
{
if (defaultItemlayoutGroup == null)
{
TComponent val = DefaultItemCopy;
defaultItemlayoutGroup = val.GetComponent<LayoutGroup>();
}
float num = 0f;
if ((!IsCanCalculateHeight || ForceAutoHeightCalculation) && defaultItemlayoutGroup != null)
{
TComponent val2 = DefaultItemCopy;
val2.gameObject.SetActive(true);
SetData(DefaultItemCopy, item);
defaultItemlayoutGroup.CalculateLayoutInputHorizontal();
defaultItemlayoutGroup.SetLayoutHorizontal();
defaultItemlayoutGroup.CalculateLayoutInputVertical();
defaultItemlayoutGroup.SetLayoutVertical();
num = LayoutUtility.GetPreferredHeight(DefaultItemCopyRect);
TComponent val3 = DefaultItemCopy;
val3.gameObject.SetActive(false);
}
else
{
SetData(DefaultItemCopy, item);
num = (DefaultItemCopy as IListViewItemHeight).Height;
}
return num;
}
public override void ForEachComponent(Action<ListViewItem> func)
{
base.ForEachComponent(func);
func(DefaultItemCopy);
}
}
}