1026 lines
23 KiB
C#
1026 lines
23 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using EasyLayout;
|
|
using UnityEngine;
|
|
using UnityEngine.EventSystems;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.Serialization;
|
|
using UnityEngine.UI;
|
|
|
|
namespace UIWidgets
|
|
{
|
|
[AddComponentMenu("UI/ListView", 250)]
|
|
public class ListView : ListViewBase
|
|
{
|
|
[SerializeField]
|
|
[Obsolete("Use DataSource instead.")]
|
|
private List<string> strings = new List<string>();
|
|
|
|
private ObservableList<string> dataSource;
|
|
|
|
[SerializeField]
|
|
private TextAsset file;
|
|
|
|
[SerializeField]
|
|
public List<string> CommentsStartWith = new List<string> { "#", "//" };
|
|
|
|
[SerializeField]
|
|
public ListViewSources Source;
|
|
|
|
[SerializeField]
|
|
public bool Unique = true;
|
|
|
|
[SerializeField]
|
|
public bool AllowEmptyItems;
|
|
|
|
[SerializeField]
|
|
private Color backgroundColor = Color.white;
|
|
|
|
[SerializeField]
|
|
private Color textColor = Color.black;
|
|
|
|
[SerializeField]
|
|
public Color HighlightedBackgroundColor = new Color(203f, 230f, 244f, 255f);
|
|
|
|
[SerializeField]
|
|
public Color HighlightedTextColor = Color.black;
|
|
|
|
[SerializeField]
|
|
private Color selectedBackgroundColor = new Color(53f, 83f, 227f, 255f);
|
|
|
|
[SerializeField]
|
|
private Color selectedTextColor = Color.black;
|
|
|
|
[SerializeField]
|
|
public ImageAdvanced DefaultItem;
|
|
|
|
private List<ListViewStringComponent> components = new List<ListViewStringComponent>();
|
|
|
|
private List<UnityAction<PointerEventData>> callbacksEnter = new List<UnityAction<PointerEventData>>();
|
|
|
|
private List<UnityAction<PointerEventData>> callbacksExit = new List<UnityAction<PointerEventData>>();
|
|
|
|
[FormerlySerializedAs("Sort")]
|
|
[SerializeField]
|
|
private bool sort = true;
|
|
|
|
private Func<IEnumerable<string>, IEnumerable<string>> sortFunc = (IEnumerable<string> items) => items.OrderBy((string x) => x);
|
|
|
|
public ListViewEvent OnSelectString = new ListViewEvent();
|
|
|
|
public ListViewEvent OnDeselectString = new ListViewEvent();
|
|
|
|
[SerializeField]
|
|
private ScrollRect scrollRect;
|
|
|
|
private float itemHeight;
|
|
|
|
private float itemWidth;
|
|
|
|
private float scrollHeight;
|
|
|
|
private float scrollWidth;
|
|
|
|
private int maxVisibleItems;
|
|
|
|
private int visibleItems;
|
|
|
|
private int topHiddenItems;
|
|
|
|
private int bottomHiddenItems;
|
|
|
|
[SerializeField]
|
|
private ListViewDirection direction = ListViewDirection.Vertical;
|
|
|
|
[NonSerialized]
|
|
private bool isStartedListView;
|
|
|
|
private LayoutGroup layout;
|
|
|
|
protected ILayoutBridge LayoutBridge;
|
|
|
|
private List<string> SelectedItemsCache;
|
|
|
|
private List<ListViewStringComponent> componentsCache = new List<ListViewStringComponent>();
|
|
|
|
private bool needResize;
|
|
|
|
public ObservableList<string> DataSource
|
|
{
|
|
get
|
|
{
|
|
if (dataSource == null)
|
|
{
|
|
dataSource = new ObservableList<string>(strings);
|
|
dataSource.OnChange += UpdateItems;
|
|
strings = null;
|
|
}
|
|
return dataSource;
|
|
}
|
|
set
|
|
{
|
|
SetNewItems(value);
|
|
SetScrollValue(0f);
|
|
}
|
|
}
|
|
|
|
[Obsolete("Use DataSource instead.")]
|
|
public List<string> Strings
|
|
{
|
|
get
|
|
{
|
|
return new List<string>(DataSource);
|
|
}
|
|
set
|
|
{
|
|
SetNewItems(new ObservableList<string>(value));
|
|
SetScrollValue(0f);
|
|
}
|
|
}
|
|
|
|
[Obsolete("Use DataSource instead.")]
|
|
public new List<string> Items
|
|
{
|
|
get
|
|
{
|
|
return new List<string>(DataSource);
|
|
}
|
|
set
|
|
{
|
|
SetNewItems(new ObservableList<string>(value));
|
|
SetScrollValue(0f);
|
|
}
|
|
}
|
|
|
|
public TextAsset File
|
|
{
|
|
get
|
|
{
|
|
return file;
|
|
}
|
|
set
|
|
{
|
|
file = value;
|
|
if (file != null)
|
|
{
|
|
GetItemsFromFile(file);
|
|
SetScrollValue(0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Color BackgroundColor
|
|
{
|
|
get
|
|
{
|
|
return backgroundColor;
|
|
}
|
|
set
|
|
{
|
|
backgroundColor = value;
|
|
UpdateColors();
|
|
}
|
|
}
|
|
|
|
public Color TextColor
|
|
{
|
|
get
|
|
{
|
|
return textColor;
|
|
}
|
|
set
|
|
{
|
|
textColor = value;
|
|
UpdateColors();
|
|
}
|
|
}
|
|
|
|
public Color SelectedBackgroundColor
|
|
{
|
|
get
|
|
{
|
|
return selectedBackgroundColor;
|
|
}
|
|
set
|
|
{
|
|
selectedBackgroundColor = value;
|
|
UpdateColors();
|
|
}
|
|
}
|
|
|
|
public Color SelectedTextColor
|
|
{
|
|
get
|
|
{
|
|
return selectedTextColor;
|
|
}
|
|
set
|
|
{
|
|
selectedTextColor = value;
|
|
UpdateColors();
|
|
}
|
|
}
|
|
|
|
public bool Sort
|
|
{
|
|
get
|
|
{
|
|
return sort;
|
|
}
|
|
set
|
|
{
|
|
sort = value;
|
|
if (Sort && isStartedListView && sortFunc != null)
|
|
{
|
|
UpdateItems();
|
|
}
|
|
}
|
|
}
|
|
|
|
public Func<IEnumerable<string>, IEnumerable<string>> SortFunc
|
|
{
|
|
get
|
|
{
|
|
return sortFunc;
|
|
}
|
|
set
|
|
{
|
|
sortFunc = value;
|
|
if (Sort && isStartedListView && sortFunc != null)
|
|
{
|
|
UpdateItems();
|
|
}
|
|
}
|
|
}
|
|
|
|
public ScrollRect ScrollRect
|
|
{
|
|
get
|
|
{
|
|
return scrollRect;
|
|
}
|
|
set
|
|
{
|
|
if (scrollRect != null)
|
|
{
|
|
ResizeListener component = scrollRect.GetComponent<ResizeListener>();
|
|
if (component != null)
|
|
{
|
|
component.OnResize.RemoveListener(SetNeedResize);
|
|
}
|
|
scrollRect.onValueChanged.RemoveListener(OnScrollUpdate);
|
|
}
|
|
scrollRect = value;
|
|
if (scrollRect != null)
|
|
{
|
|
ResizeListener resizeListener = scrollRect.GetComponent<ResizeListener>() ?? scrollRect.gameObject.AddComponent<ResizeListener>();
|
|
resizeListener.OnResize.AddListener(SetNeedResize);
|
|
scrollRect.onValueChanged.AddListener(OnScrollUpdate);
|
|
}
|
|
}
|
|
}
|
|
|
|
public ListViewDirection Direction
|
|
{
|
|
get
|
|
{
|
|
return direction;
|
|
}
|
|
set
|
|
{
|
|
direction = value;
|
|
if ((bool)scrollRect)
|
|
{
|
|
scrollRect.horizontal = IsHorizontal();
|
|
scrollRect.vertical = !IsHorizontal();
|
|
}
|
|
if (CanOptimize() && layout is global::EasyLayout.EasyLayout)
|
|
{
|
|
LayoutBridge.IsHorizontal = IsHorizontal();
|
|
CalculateMaxVisibleItems();
|
|
}
|
|
UpdateView();
|
|
}
|
|
}
|
|
|
|
public global::EasyLayout.EasyLayout Layout
|
|
{
|
|
get
|
|
{
|
|
return layout as global::EasyLayout.EasyLayout;
|
|
}
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
Start();
|
|
}
|
|
|
|
public override void Start()
|
|
{
|
|
if (isStartedListView)
|
|
{
|
|
return;
|
|
}
|
|
isStartedListView = true;
|
|
base.Start();
|
|
base.Items = new List<ListViewItem>();
|
|
SelectedItemsCache = base.SelectedIndicies.Convert(GetDataItem);
|
|
DestroyGameObjects = false;
|
|
if (DefaultItem == null)
|
|
{
|
|
throw new NullReferenceException("DefaultItem is null. Set component of type ImageAdvanced to DefaultItem.");
|
|
}
|
|
DefaultItem.gameObject.SetActive(true);
|
|
if (DefaultItem.GetComponentInChildren<Text>() == null)
|
|
{
|
|
throw new MissingComponentException("DefaultItem don't have child with 'Text' component. Add child with 'Text' component to DefaultItem.");
|
|
}
|
|
if (CanOptimize())
|
|
{
|
|
ScrollRect = scrollRect;
|
|
RectTransform rectTransform = scrollRect.transform as RectTransform;
|
|
scrollHeight = rectTransform.rect.height;
|
|
scrollWidth = rectTransform.rect.width;
|
|
layout = Container.GetComponent<LayoutGroup>();
|
|
if (layout is global::EasyLayout.EasyLayout)
|
|
{
|
|
LayoutBridge = new EasyLayoutBridge(layout as global::EasyLayout.EasyLayout, DefaultItem.transform as RectTransform);
|
|
LayoutBridge.IsHorizontal = IsHorizontal();
|
|
}
|
|
else if (layout is HorizontalOrVerticalLayoutGroup)
|
|
{
|
|
LayoutBridge = new StandardLayoutBridge(layout as HorizontalOrVerticalLayoutGroup, DefaultItem.transform as RectTransform);
|
|
}
|
|
CalculateItemSize();
|
|
CalculateMaxVisibleItems();
|
|
}
|
|
DefaultItem.gameObject.SetActive(false);
|
|
UpdateItems();
|
|
OnSelect.AddListener(OnSelectCallback);
|
|
OnDeselect.AddListener(OnDeselectCallback);
|
|
}
|
|
|
|
protected virtual void CalculateItemSize()
|
|
{
|
|
if (LayoutBridge != null)
|
|
{
|
|
Vector2 itemSize = LayoutBridge.GetItemSize();
|
|
itemHeight = itemSize.y;
|
|
itemWidth = itemSize.x;
|
|
}
|
|
}
|
|
|
|
protected string GetDataItem(int index)
|
|
{
|
|
return DataSource[index];
|
|
}
|
|
|
|
protected bool IsHorizontal()
|
|
{
|
|
return direction == ListViewDirection.Horizontal;
|
|
}
|
|
|
|
private void CalculateMaxVisibleItems()
|
|
{
|
|
if (IsHorizontal())
|
|
{
|
|
maxVisibleItems = Mathf.CeilToInt(scrollWidth / itemWidth) + 1;
|
|
}
|
|
else
|
|
{
|
|
maxVisibleItems = Mathf.CeilToInt(scrollHeight / itemHeight) + 1;
|
|
}
|
|
}
|
|
|
|
private void Resize()
|
|
{
|
|
needResize = false;
|
|
RectTransform rectTransform = scrollRect.transform as RectTransform;
|
|
scrollHeight = rectTransform.rect.height;
|
|
scrollWidth = rectTransform.rect.width;
|
|
CalculateMaxVisibleItems();
|
|
UpdateView();
|
|
}
|
|
|
|
private bool CanOptimize()
|
|
{
|
|
return scrollRect != null && (layout != null || Container.GetComponent<global::EasyLayout.EasyLayout>() != null);
|
|
}
|
|
|
|
private void OnSelectCallback(int index, ListViewItem item)
|
|
{
|
|
if (SelectedItemsCache != null)
|
|
{
|
|
SelectedItemsCache.Add(DataSource[index]);
|
|
}
|
|
OnSelectString.Invoke(index, DataSource[index]);
|
|
if (item != null)
|
|
{
|
|
SelectColoring(item as ListViewStringComponent);
|
|
}
|
|
}
|
|
|
|
private void OnDeselectCallback(int index, ListViewItem item)
|
|
{
|
|
if (SelectedItemsCache != null)
|
|
{
|
|
SelectedItemsCache.Remove(DataSource[index]);
|
|
}
|
|
OnDeselectString.Invoke(index, DataSource[index]);
|
|
if (item != null)
|
|
{
|
|
DefaultColoring(item as ListViewStringComponent);
|
|
}
|
|
}
|
|
|
|
public override void UpdateItems()
|
|
{
|
|
if (Source == ListViewSources.List)
|
|
{
|
|
SetNewItems(DataSource);
|
|
return;
|
|
}
|
|
Source = ListViewSources.List;
|
|
GetItemsFromFile(File);
|
|
}
|
|
|
|
public override void Clear()
|
|
{
|
|
DataSource.Clear();
|
|
}
|
|
|
|
public void GetItemsFromFile()
|
|
{
|
|
GetItemsFromFile(File);
|
|
}
|
|
|
|
private string StringTrimEnd(string str)
|
|
{
|
|
return str.TrimEnd();
|
|
}
|
|
|
|
private bool IsStringNotEmpty(string str)
|
|
{
|
|
return str != string.Empty;
|
|
}
|
|
|
|
private bool NotComment(string str)
|
|
{
|
|
return !CommentsStartWith.Any((string comment) => str.StartsWith(comment));
|
|
}
|
|
|
|
public void GetItemsFromFile(TextAsset sourceFile)
|
|
{
|
|
if (!(file == null))
|
|
{
|
|
IEnumerable<string> enumerable = sourceFile.text.Split(new string[3] { "\r\n", "\r", "\n" }, StringSplitOptions.None).Select(StringTrimEnd);
|
|
if (Unique)
|
|
{
|
|
enumerable = enumerable.Distinct();
|
|
}
|
|
if (!AllowEmptyItems)
|
|
{
|
|
enumerable = enumerable.Where(IsStringNotEmpty);
|
|
}
|
|
if (CommentsStartWith.Count > 0)
|
|
{
|
|
enumerable = enumerable.Where(NotComment);
|
|
}
|
|
SetNewItems(enumerable.ToObservableList());
|
|
}
|
|
}
|
|
|
|
public virtual List<int> FindIndicies(string item)
|
|
{
|
|
return (from i in Enumerable.Range(0, DataSource.Count)
|
|
where DataSource[i] == item
|
|
select i).ToList();
|
|
}
|
|
|
|
public virtual int FindIndex(string item)
|
|
{
|
|
return DataSource.IndexOf(item);
|
|
}
|
|
|
|
public virtual int Add(string item)
|
|
{
|
|
List<int> second = ((!Sort || SortFunc == null) ? null : FindIndicies(item));
|
|
DataSource.Add(item);
|
|
if (Sort && SortFunc != null)
|
|
{
|
|
List<int> list = FindIndicies(item);
|
|
int[] array = list.Except(second).ToArray();
|
|
if (array.Length > 0)
|
|
{
|
|
return array[0];
|
|
}
|
|
if (list.Count > 0)
|
|
{
|
|
return list[0];
|
|
}
|
|
return -1;
|
|
}
|
|
return DataSource.Count - 1;
|
|
}
|
|
|
|
public virtual int Remove(string item)
|
|
{
|
|
int num = FindIndex(item);
|
|
if (num == -1)
|
|
{
|
|
return num;
|
|
}
|
|
DataSource.Remove(item);
|
|
return num;
|
|
}
|
|
|
|
private void RemoveCallback(ListViewStringComponent component, int index)
|
|
{
|
|
if (!(component == null))
|
|
{
|
|
if (index < callbacksEnter.Count)
|
|
{
|
|
component.onPointerEnter.RemoveListener(callbacksEnter[index]);
|
|
}
|
|
if (index < callbacksExit.Count)
|
|
{
|
|
component.onPointerExit.RemoveListener(callbacksExit[index]);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void RemoveCallbacks()
|
|
{
|
|
components.ForEach(RemoveCallback);
|
|
callbacksEnter.Clear();
|
|
callbacksExit.Clear();
|
|
}
|
|
|
|
private void AddCallbacks()
|
|
{
|
|
components.ForEach(AddCallback);
|
|
}
|
|
|
|
private void AddCallback(ListViewStringComponent component, int index)
|
|
{
|
|
callbacksEnter.Add(delegate
|
|
{
|
|
OnPointerEnterCallback(component);
|
|
});
|
|
callbacksExit.Add(delegate
|
|
{
|
|
OnPointerExitCallback(component);
|
|
});
|
|
component.onPointerEnter.AddListener(callbacksEnter[index]);
|
|
component.onPointerExit.AddListener(callbacksExit[index]);
|
|
}
|
|
|
|
public override bool IsValid(int index)
|
|
{
|
|
return index >= 0 && index < DataSource.Count;
|
|
}
|
|
|
|
private void OnPointerEnterCallback(ListViewStringComponent component)
|
|
{
|
|
if (!IsValid(component.Index))
|
|
{
|
|
string message = string.Format("Index must be between 0 and Items.Count ({0})", DataSource.Count);
|
|
throw new IndexOutOfRangeException(message);
|
|
}
|
|
if (!IsSelected(component.Index))
|
|
{
|
|
HighlightColoring(component);
|
|
}
|
|
}
|
|
|
|
private void OnPointerExitCallback(ListViewStringComponent component)
|
|
{
|
|
if (!IsValid(component.Index))
|
|
{
|
|
string message = string.Format("Index must be between 0 and Items.Count ({0})", DataSource.Count);
|
|
throw new IndexOutOfRangeException(message);
|
|
}
|
|
if (!IsSelected(component.Index))
|
|
{
|
|
DefaultColoring(component);
|
|
}
|
|
}
|
|
|
|
protected void SetScrollValue(float value)
|
|
{
|
|
Vector2 anchoredPosition = scrollRect.content.anchoredPosition;
|
|
Vector2 vector = new Vector2(anchoredPosition.x, value);
|
|
if (vector != anchoredPosition)
|
|
{
|
|
scrollRect.content.anchoredPosition = vector;
|
|
ScrollUpdate();
|
|
}
|
|
}
|
|
|
|
protected float GetScrollValue()
|
|
{
|
|
Vector2 anchoredPosition = scrollRect.content.anchoredPosition;
|
|
return Mathf.Max(0f, (!IsHorizontal()) ? anchoredPosition.y : (0f - anchoredPosition.x));
|
|
}
|
|
|
|
protected float GetItemSize()
|
|
{
|
|
return (!IsHorizontal()) ? (itemHeight + LayoutBridge.GetSpacing()) : (itemWidth + LayoutBridge.GetSpacing());
|
|
}
|
|
|
|
protected float GetScrollSize()
|
|
{
|
|
return (!IsHorizontal()) ? scrollHeight : scrollWidth;
|
|
}
|
|
|
|
protected override void ScrollTo(int index)
|
|
{
|
|
if (CanOptimize())
|
|
{
|
|
int firstVisibleIndex = GetFirstVisibleIndex(true);
|
|
int lastVisibleIndex = GetLastVisibleIndex(true);
|
|
if (firstVisibleIndex > index)
|
|
{
|
|
float scrollValue = (float)index * GetItemSize();
|
|
SetScrollValue(scrollValue);
|
|
}
|
|
else if (lastVisibleIndex < index)
|
|
{
|
|
float scrollValue2 = (float)(index + 1) * GetItemSize() - LayoutBridge.GetSpacing() + LayoutBridge.GetMargin() - GetScrollSize();
|
|
SetScrollValue(scrollValue2);
|
|
}
|
|
}
|
|
}
|
|
|
|
private int GetLastVisibleIndex(bool strict = false)
|
|
{
|
|
float num = GetScrollValue() + GetScrollSize();
|
|
int num2 = ((!strict) ? Mathf.CeilToInt(num / GetItemSize()) : Mathf.FloorToInt(num / GetItemSize()));
|
|
return num2 - 1;
|
|
}
|
|
|
|
private int GetFirstVisibleIndex(bool strict = false)
|
|
{
|
|
int num = ((!strict) ? Mathf.FloorToInt(GetScrollValue() / GetItemSize()) : Mathf.CeilToInt(GetScrollValue() / GetItemSize()));
|
|
if (strict)
|
|
{
|
|
return num;
|
|
}
|
|
return Mathf.Min(num, Mathf.Max(0, DataSource.Count - visibleItems));
|
|
}
|
|
|
|
private ListViewStringComponent ComponentTopToBottom()
|
|
{
|
|
int index = components.Count - 1;
|
|
ListViewStringComponent listViewStringComponent = components[index];
|
|
components.RemoveAt(index);
|
|
components.Insert(0, listViewStringComponent);
|
|
listViewStringComponent.transform.SetAsFirstSibling();
|
|
return listViewStringComponent;
|
|
}
|
|
|
|
private ListViewStringComponent ComponentBottomToTop()
|
|
{
|
|
ListViewStringComponent listViewStringComponent = components[0];
|
|
components.RemoveAt(0);
|
|
components.Add(listViewStringComponent);
|
|
listViewStringComponent.transform.SetAsLastSibling();
|
|
return listViewStringComponent;
|
|
}
|
|
|
|
private void OnScrollUpdate(Vector2 position)
|
|
{
|
|
ScrollUpdate();
|
|
}
|
|
|
|
private void OnScroll(float value)
|
|
{
|
|
ScrollUpdate();
|
|
}
|
|
|
|
private void ScrollUpdate()
|
|
{
|
|
int num = topHiddenItems;
|
|
topHiddenItems = GetFirstVisibleIndex();
|
|
bottomHiddenItems = Mathf.Max(0, DataSource.Count - visibleItems - topHiddenItems);
|
|
if (num != topHiddenItems)
|
|
{
|
|
if (num == topHiddenItems + 1)
|
|
{
|
|
ListViewStringComponent listViewStringComponent = ComponentTopToBottom();
|
|
listViewStringComponent.Index = topHiddenItems;
|
|
listViewStringComponent.Text.text = DataSource[topHiddenItems];
|
|
Coloring(listViewStringComponent);
|
|
}
|
|
else if (num == topHiddenItems - 1)
|
|
{
|
|
ListViewStringComponent listViewStringComponent2 = ComponentBottomToTop();
|
|
int index = (listViewStringComponent2.Index = topHiddenItems + visibleItems - 1);
|
|
listViewStringComponent2.Text.text = DataSource[index];
|
|
Coloring(listViewStringComponent2);
|
|
}
|
|
else
|
|
{
|
|
int[] new_indicies = Enumerable.Range(topHiddenItems, visibleItems).ToArray();
|
|
components.ForEach(delegate(ListViewStringComponent x, int i)
|
|
{
|
|
x.Index = new_indicies[i];
|
|
x.Text.text = DataSource[new_indicies[i]];
|
|
Coloring(x);
|
|
});
|
|
}
|
|
}
|
|
if (LayoutBridge != null)
|
|
{
|
|
LayoutBridge.SetFiller(CalculateTopFillerSize(), CalculateBottomFillerSize());
|
|
LayoutBridge.UpdateLayout();
|
|
}
|
|
}
|
|
|
|
private bool IsNullComponent(ListViewStringComponent component)
|
|
{
|
|
return component == null;
|
|
}
|
|
|
|
private List<ListViewStringComponent> GetNewComponents()
|
|
{
|
|
componentsCache.RemoveAll(IsNullComponent);
|
|
List<ListViewStringComponent> new_components = new List<ListViewStringComponent>();
|
|
DataSource.ForEach(delegate(string x, int i)
|
|
{
|
|
if (i < visibleItems)
|
|
{
|
|
if (components.Count > 0)
|
|
{
|
|
new_components.Add(components[0]);
|
|
components.RemoveAt(0);
|
|
}
|
|
else if (componentsCache.Count > 0)
|
|
{
|
|
componentsCache[0].gameObject.SetActive(true);
|
|
new_components.Add(componentsCache[0]);
|
|
componentsCache.RemoveAt(0);
|
|
}
|
|
else
|
|
{
|
|
ImageAdvanced imageAdvanced = UnityEngine.Object.Instantiate(DefaultItem);
|
|
imageAdvanced.gameObject.SetActive(true);
|
|
ListViewStringComponent listViewStringComponent = imageAdvanced.GetComponent<ListViewStringComponent>();
|
|
if (listViewStringComponent == null)
|
|
{
|
|
listViewStringComponent = imageAdvanced.gameObject.AddComponent<ListViewStringComponent>();
|
|
listViewStringComponent.Background = imageAdvanced;
|
|
listViewStringComponent.Text = imageAdvanced.GetComponentInChildren<Text>();
|
|
}
|
|
Utilites.FixInstantiated(DefaultItem, imageAdvanced);
|
|
listViewStringComponent.gameObject.SetActive(true);
|
|
new_components.Add(listViewStringComponent);
|
|
}
|
|
}
|
|
});
|
|
components.ForEach(delegate(ListViewStringComponent x)
|
|
{
|
|
x.MovedToCache();
|
|
x.Index = -1;
|
|
x.gameObject.SetActive(false);
|
|
});
|
|
componentsCache.AddRange(components);
|
|
components.Clear();
|
|
return new_components;
|
|
}
|
|
|
|
private void UpdateView()
|
|
{
|
|
RemoveCallbacks();
|
|
if (CanOptimize() && DataSource.Count > 0)
|
|
{
|
|
visibleItems = ((maxVisibleItems >= DataSource.Count) ? DataSource.Count : maxVisibleItems);
|
|
}
|
|
else
|
|
{
|
|
visibleItems = DataSource.Count;
|
|
}
|
|
components = GetNewComponents();
|
|
base.Items = components.Convert((Converter<ListViewStringComponent, ListViewItem>)((ListViewStringComponent x) => x));
|
|
components.ForEach(SetComponentData);
|
|
AddCallbacks();
|
|
topHiddenItems = 0;
|
|
bottomHiddenItems = DataSource.Count() - visibleItems;
|
|
if (LayoutBridge != null)
|
|
{
|
|
LayoutBridge.SetFiller(CalculateTopFillerSize(), CalculateBottomFillerSize());
|
|
LayoutBridge.UpdateLayout();
|
|
}
|
|
if (scrollRect != null)
|
|
{
|
|
RectTransform rectTransform = scrollRect.transform as RectTransform;
|
|
rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, rectTransform.rect.width);
|
|
}
|
|
}
|
|
|
|
private void SetComponentData(ListViewStringComponent component, int index)
|
|
{
|
|
component.Index = index;
|
|
component.Text.text = DataSource[index];
|
|
Coloring(component);
|
|
}
|
|
|
|
private bool IndexNotFound(int index)
|
|
{
|
|
return index == -1;
|
|
}
|
|
|
|
private void SetNewItems(ObservableList<string> newItems)
|
|
{
|
|
DataSource.OnChange -= UpdateItems;
|
|
if (Sort && SortFunc != null)
|
|
{
|
|
newItems.BeginUpdate();
|
|
string[] array = SortFunc(newItems).ToArray();
|
|
newItems.Clear();
|
|
newItems.AddRange(array);
|
|
newItems.EndUpdate();
|
|
}
|
|
SilentDeselect(base.SelectedIndicies);
|
|
List<int> list = SelectedItemsCache.Convert(newItems.IndexOf);
|
|
list.RemoveAll(IndexNotFound);
|
|
dataSource = newItems;
|
|
SilentSelect(list);
|
|
SelectedItemsCache = base.SelectedIndicies.Convert(GetDataItem);
|
|
UpdateView();
|
|
DataSource.OnChange += UpdateItems;
|
|
}
|
|
|
|
private float CalculateBottomFillerSize()
|
|
{
|
|
return (bottomHiddenItems != 0) ? ((float)bottomHiddenItems * GetItemSize() - LayoutBridge.GetSpacing()) : 0f;
|
|
}
|
|
|
|
private float CalculateTopFillerSize()
|
|
{
|
|
return (topHiddenItems != 0) ? ((float)topHiddenItems * GetItemSize() - LayoutBridge.GetSpacing()) : 0f;
|
|
}
|
|
|
|
private List<int> NewSelectedIndicies(ObservableList<string> newItems)
|
|
{
|
|
List<int> selected_indicies = new List<int>();
|
|
if (newItems.Count == 0)
|
|
{
|
|
return selected_indicies;
|
|
}
|
|
List<string> new_items_copy = new List<string>(newItems);
|
|
List<string> selected_items = base.SelectedIndicies.Convert(GetDataItem);
|
|
selected_items = selected_items.Where(delegate(string x)
|
|
{
|
|
bool flag = newItems.Contains(x);
|
|
if (flag)
|
|
{
|
|
new_items_copy.Remove(x);
|
|
}
|
|
return flag;
|
|
}).ToList();
|
|
newItems.ForEach(delegate(string item, int index)
|
|
{
|
|
if (selected_items.Contains(item))
|
|
{
|
|
selected_items.Remove(item);
|
|
selected_indicies.Add(index);
|
|
}
|
|
});
|
|
return selected_indicies;
|
|
}
|
|
|
|
protected override void Coloring(ListViewItem component)
|
|
{
|
|
if (!(component == null))
|
|
{
|
|
if (base.SelectedIndicies.Contains(component.Index))
|
|
{
|
|
SelectColoring(component);
|
|
}
|
|
else
|
|
{
|
|
DefaultColoring(component);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateColors()
|
|
{
|
|
components.ForEach(Coloring);
|
|
}
|
|
|
|
private ListViewStringComponent GetComponent(int index)
|
|
{
|
|
return components.Find((ListViewStringComponent x) => x.Index == index);
|
|
}
|
|
|
|
public int Set(string item, bool allowDuplicate = true)
|
|
{
|
|
int num;
|
|
if (!allowDuplicate)
|
|
{
|
|
num = DataSource.IndexOf(item);
|
|
if (num == -1)
|
|
{
|
|
num = Add(item);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
num = Add(item);
|
|
}
|
|
Select(num);
|
|
return num;
|
|
}
|
|
|
|
protected override void SelectItem(int index)
|
|
{
|
|
SelectColoring(GetComponent(index));
|
|
}
|
|
|
|
protected override void DeselectItem(int index)
|
|
{
|
|
DefaultColoring(GetComponent(index));
|
|
}
|
|
|
|
protected override void HighlightColoring(ListViewItem component)
|
|
{
|
|
if (!IsSelected(component.Index))
|
|
{
|
|
HighlightColoring(component as ListViewStringComponent);
|
|
}
|
|
}
|
|
|
|
protected virtual void HighlightColoring(ListViewStringComponent component)
|
|
{
|
|
if (!(component == null))
|
|
{
|
|
component.Background.color = HighlightedBackgroundColor;
|
|
component.Text.color = HighlightedTextColor;
|
|
}
|
|
}
|
|
|
|
protected virtual void SelectColoring(ListViewItem component)
|
|
{
|
|
if (!(component == null))
|
|
{
|
|
SelectColoring(component as ListViewStringComponent);
|
|
}
|
|
}
|
|
|
|
protected virtual void SelectColoring(ListViewStringComponent component)
|
|
{
|
|
if (!(component == null))
|
|
{
|
|
component.Background.color = selectedBackgroundColor;
|
|
component.Text.color = selectedTextColor;
|
|
}
|
|
}
|
|
|
|
protected virtual void DefaultColoring(ListViewItem component)
|
|
{
|
|
if (!(component == null))
|
|
{
|
|
DefaultColoring(component as ListViewStringComponent);
|
|
}
|
|
}
|
|
|
|
protected virtual void DefaultColoring(ListViewStringComponent component)
|
|
{
|
|
if (!(component == null))
|
|
{
|
|
component.Background.color = backgroundColor;
|
|
component.Text.color = textColor;
|
|
}
|
|
}
|
|
|
|
protected override void OnDestroy()
|
|
{
|
|
OnSelect.RemoveListener(OnSelectCallback);
|
|
OnDeselect.RemoveListener(OnDeselectCallback);
|
|
ScrollRect = null;
|
|
RemoveCallbacks();
|
|
base.OnDestroy();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (needResize)
|
|
{
|
|
Resize();
|
|
}
|
|
}
|
|
|
|
private void SetNeedResize()
|
|
{
|
|
if (CanOptimize())
|
|
{
|
|
needResize = true;
|
|
}
|
|
}
|
|
}
|
|
}
|