245 lines
6.2 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|