201 lines
5.5 KiB
C#
201 lines
5.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using EasyLayout;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.UI;
|
|
|
|
namespace UIWidgets
|
|
{
|
|
public class TileView<TComponent, TItem> : ListViewCustom<TComponent, TItem> where TComponent : ListViewItem
|
|
{
|
|
private int itemsPerRow;
|
|
|
|
private int itemsPerColumn;
|
|
|
|
protected override bool CanOptimize()
|
|
{
|
|
bool flag = scrollRect != null;
|
|
LayoutGroup layoutGroup = ((!(Container != null)) ? null : (layout ?? Container.GetComponent<LayoutGroup>()));
|
|
bool flag2 = layoutGroup is global::EasyLayout.EasyLayout;
|
|
return flag && flag2;
|
|
}
|
|
|
|
protected override void ScrollTo(int index)
|
|
{
|
|
if (CanOptimize())
|
|
{
|
|
int firstVisibleIndex = GetFirstVisibleIndex(true);
|
|
int lastVisibleIndex = GetLastVisibleIndex(true);
|
|
int num = Mathf.FloorToInt((float)index / (float)ItemsPerBlock());
|
|
if (firstVisibleIndex > num)
|
|
{
|
|
SetScrollValue(GetItemPosition(index));
|
|
}
|
|
else if (lastVisibleIndex < num)
|
|
{
|
|
SetScrollValue(GetItemPositionBottom(index));
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override float GetItemPosition(int index)
|
|
{
|
|
int num = Mathf.FloorToInt((float)index / (float)ItemsPerBlock());
|
|
return (float)num * GetItemSize();
|
|
}
|
|
|
|
protected override void CalculateMaxVisibleItems()
|
|
{
|
|
float spacing = LayoutBridge.GetSpacing();
|
|
if (IsHorizontal())
|
|
{
|
|
float num = scrollHeight + spacing - LayoutBridge.GetFullMargin();
|
|
itemsPerRow = Mathf.CeilToInt(scrollWidth / itemWidth) + 1;
|
|
itemsPerRow = Mathf.Max(2, itemsPerRow);
|
|
itemsPerColumn = Mathf.FloorToInt(num / (itemHeight + spacing));
|
|
itemsPerColumn = Mathf.Max(1, itemsPerColumn);
|
|
}
|
|
else
|
|
{
|
|
float num2 = scrollWidth + spacing - LayoutBridge.GetFullMargin();
|
|
itemsPerRow = Mathf.FloorToInt(num2 / (itemWidth + spacing));
|
|
itemsPerRow = Mathf.Max(1, itemsPerRow);
|
|
itemsPerColumn = Mathf.CeilToInt(scrollHeight / itemHeight) + 1;
|
|
itemsPerColumn = Mathf.Max(2, itemsPerColumn);
|
|
}
|
|
maxVisibleItems = itemsPerRow * itemsPerColumn;
|
|
}
|
|
|
|
protected override int GetFirstVisibleIndex(bool strict = false)
|
|
{
|
|
return Mathf.Max(0, base.GetFirstVisibleIndex(strict) * ItemsPerBlock());
|
|
}
|
|
|
|
protected override int GetLastVisibleIndex(bool strict = false)
|
|
{
|
|
return (base.GetLastVisibleIndex(strict) + 1) * ItemsPerBlock() - 1;
|
|
}
|
|
|
|
protected override void ScrollUpdate()
|
|
{
|
|
int num = topHiddenItems;
|
|
topHiddenItems = GetFirstVisibleIndex();
|
|
if (topHiddenItems > base.DataSource.Count - 1)
|
|
{
|
|
topHiddenItems = Mathf.Max(0, base.DataSource.Count - 2);
|
|
}
|
|
if (num == topHiddenItems)
|
|
{
|
|
return;
|
|
}
|
|
if (CanOptimize() && base.DataSource.Count > 0)
|
|
{
|
|
visibleItems = ((maxVisibleItems >= base.DataSource.Count) ? base.DataSource.Count : maxVisibleItems);
|
|
}
|
|
else
|
|
{
|
|
visibleItems = base.DataSource.Count;
|
|
}
|
|
if (topHiddenItems + visibleItems > base.DataSource.Count)
|
|
{
|
|
visibleItems = base.DataSource.Count - topHiddenItems;
|
|
if (visibleItems < ItemsPerBlock())
|
|
{
|
|
visibleItems = Mathf.Min(base.DataSource.Count, visibleItems + ItemsPerBlock());
|
|
topHiddenItems = base.DataSource.Count - visibleItems;
|
|
}
|
|
}
|
|
RemoveCallbacks();
|
|
UpdateComponentsCount();
|
|
bottomHiddenItems = Mathf.Max(0, base.DataSource.Count - visibleItems - topHiddenItems);
|
|
List<int> new_visible_range = Enumerable.Range(topHiddenItems, visibleItems).ToList();
|
|
List<int> second = components.Convert(base.GetComponentIndex);
|
|
List<int> list = new_visible_range.Except(second).ToList();
|
|
Stack<TComponent> components_to_change = new Stack<TComponent>(components.Where((TComponent x) => !new_visible_range.Contains(x.Index)));
|
|
list.ForEach(delegate(int index)
|
|
{
|
|
TComponent val = components_to_change.Pop();
|
|
val.Index = index;
|
|
SetData(val, base.DataSource[index]);
|
|
Coloring(val);
|
|
});
|
|
components.Sort(base.ComponentsComparer);
|
|
components.ForEach(base.SetComponentAsLastSibling);
|
|
AddCallbacks();
|
|
if (LayoutBridge != null)
|
|
{
|
|
LayoutBridge.SetFiller(CalculateTopFillerSize(), CalculateBottomFillerSize());
|
|
LayoutBridge.UpdateLayout();
|
|
}
|
|
}
|
|
|
|
protected override void OnItemMove(AxisEventData eventData, ListViewItem item)
|
|
{
|
|
int num = item.Index % ItemsPerBlock();
|
|
switch (eventData.moveDir)
|
|
{
|
|
case MoveDirection.Left:
|
|
if (num > 0)
|
|
{
|
|
SelectComponentByIndex(item.Index - 1);
|
|
}
|
|
break;
|
|
case MoveDirection.Right:
|
|
if (num < ItemsPerBlock() - 1)
|
|
{
|
|
SelectComponentByIndex(item.Index + 1);
|
|
}
|
|
break;
|
|
case MoveDirection.Up:
|
|
{
|
|
int index2 = item.Index - ItemsPerBlock();
|
|
if (IsValid(index2))
|
|
{
|
|
SelectComponentByIndex(index2);
|
|
}
|
|
break;
|
|
}
|
|
case MoveDirection.Down:
|
|
{
|
|
int index = item.Index + ItemsPerBlock();
|
|
if (IsValid(index))
|
|
{
|
|
SelectComponentByIndex(index);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private int ItemsPerBlock()
|
|
{
|
|
return (!IsHorizontal()) ? itemsPerRow : itemsPerColumn;
|
|
}
|
|
|
|
private int GetBlocksCount(int items)
|
|
{
|
|
return Mathf.CeilToInt((float)items / (float)ItemsPerBlock());
|
|
}
|
|
|
|
protected override float CalculateBottomFillerSize()
|
|
{
|
|
int blocksCount = GetBlocksCount(bottomHiddenItems);
|
|
if (blocksCount == 0)
|
|
{
|
|
return 0f;
|
|
}
|
|
return Mathf.Max(0f, (float)blocksCount * GetItemSize() - LayoutBridge.GetSpacing());
|
|
}
|
|
|
|
protected override float CalculateTopFillerSize()
|
|
{
|
|
if (GetBlocksCount(topHiddenItems) == 0)
|
|
{
|
|
return 0f;
|
|
}
|
|
return Mathf.Max(0f, (float)GetBlocksCount(topHiddenItems) * GetItemSize() - LayoutBridge.GetSpacing());
|
|
}
|
|
}
|
|
}
|