namespace UIWidgets
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UIWidgets.Styles;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
using UnityEngine.UI;
///
/// Table Header.
/// How to change DefaultItem:
/// var order = tableHeader.GetColumnsOrder();
/// tableHeader.RestoreColumnsOrder();
/// listView.DefaultItem = newDefaultItem;
/// tableHeader.SetColumnsOrder(order);
///
[RequireComponent(typeof(LayoutGroup))]
[AddComponentMenu("UI/New UI Widgets/Collections/Table Header")]
[DisallowMultipleComponent]
public class TableHeader : UIBehaviour, IDropSupport, IPointerEnterHandler, IPointerExitHandler, IStylable, ILateUpdatable
{
#region Interactable
[SerializeField]
bool interactable = true;
///
/// Is widget interactable.
///
/// true if interactable; otherwise, false.
public bool Interactable
{
get
{
return interactable;
}
set
{
if (interactable != value)
{
interactable = value;
InteractableChanged();
}
}
}
///
/// If the canvas groups allow interaction.
///
protected bool GroupsAllowInteraction = true;
///
/// The CanvasGroup cache.
///
protected List CanvasGroupCache = new List();
///
/// Process the CanvasGroupChanged event.
///
protected override void OnCanvasGroupChanged()
{
var groupAllowInteraction = true;
var t = transform;
while (t != null)
{
t.GetComponents(CanvasGroupCache);
var shouldBreak = false;
foreach (var canvas_group in CanvasGroupCache)
{
if (!canvas_group.interactable)
{
groupAllowInteraction = false;
shouldBreak = true;
}
shouldBreak |= canvas_group.ignoreParentGroups;
}
if (shouldBreak)
{
break;
}
t = t.parent;
}
if (groupAllowInteraction != GroupsAllowInteraction)
{
GroupsAllowInteraction = groupAllowInteraction;
InteractableChanged();
}
}
///
/// Returns true if the GameObject and the Component are active.
///
/// true if the GameObject and the Component are active; otherwise false.
public override bool IsActive()
{
return base.IsActive() && GroupsAllowInteraction && Interactable;
}
///
/// Is instance interactable?
///
/// true if instance interactable; otherwise false
public bool IsInteractable()
{
return GroupsAllowInteraction && Interactable;
}
///
/// Process interactable change.
///
protected virtual void InteractableChanged()
{
if (!base.IsActive())
{
return;
}
OnInteractableChange(GroupsAllowInteraction && Interactable);
}
///
/// Process interactable change.
///
/// Current interactable state.
protected virtual void OnInteractableChange(bool interactableState)
{
if (!interactableState)
{
if (IsCursorOver)
{
IsCursorOver = false;
ResetCursor();
}
}
}
#endregion
///
/// ListView instance.
///
[SerializeField]
public ListViewBase List;
///
/// Allow resize.
///
[SerializeField]
public bool AllowResize = true;
///
/// Allow reorder.
///
[SerializeField]
public bool AllowReorder = true;
///
/// Is now processed cell reorder?
///
[NonSerialized]
[HideInInspector]
public bool ProcessCellReorder = false;
///
/// Update ListView columns width on drag.
///
[SerializeField]
public bool OnDragUpdate = true;
///
/// The active region in points from left or right border where resize allowed.
///
[SerializeField]
public float ActiveRegion = 5;
///
/// The current camera. For Screen Space - Overlay let it empty.
///
[NonSerialized]
protected Camera CurrentCamera;
///
/// Cursors.
///
[SerializeField]
public Cursors Cursors;
///
/// The cursor texture.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Texture2D CursorTexture;
///
/// The cursor hot spot.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Vector2 CursorHotSpot = new Vector2(16, 16);
///
/// The cursor texture.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Texture2D AllowDropCursor;
///
/// The cursor hot spot.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Vector2 AllowDropCursorHotSpot = new Vector2(4, 2);
///
/// The cursor texture.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Texture2D DeniedDropCursor;
///
/// The cursor hot spot.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Vector2 DeniedDropCursorHotSpot = new Vector2(4, 2);
///
/// The default cursor texture.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Texture2D DefaultCursorTexture;
///
/// The default cursor hot spot.
///
[SerializeField]
[Obsolete("Replaced with Cursors and UICursor.Cursors.")]
public Vector2 DefaultCursorHotSpot;
///
/// The drop indicator.
///
[SerializeField]
public LayoutDropIndicator DropIndicator;
RectTransform rectTransform;
///
/// Gets the RectTransform.
///
/// The RectTransform.
public RectTransform RectTransform
{
get
{
if (rectTransform == null)
{
rectTransform = transform as RectTransform;
}
return rectTransform;
}
}
///
/// The cells info.
///
protected List CellsInfo = new List();
///
/// Header cells.
///
/// The cells.
public RectTransform[] Cells
{
get
{
var result = new RectTransform[CellsInfo.Count];
for (int i = 0; i < CellsInfo.Count; i++)
{
result[i] = CellsInfo[i].Rect;
}
return result;
}
}
///
/// Gets a value indicating whether mouse position in active region.
///
/// true if in active region; otherwise, false.
public bool InActiveRegion
{
get
{
return CheckInActiveRegion(CompatibilityInput.MousePosition, CurrentCamera);
}
}
///
/// Can change cursor?
///
protected bool CanChangeCursor
{
get
{
return UICursor.CanSet(this) && CompatibilityInput.MousePresent && IsCursorOver;
}
}
///
/// Is cursor over gameobject?
///
protected bool IsCursorOver;
LayoutElement leftTarget;
LayoutElement rightTarget;
bool processDrag;
LayoutGroup layout;
bool isInited;
///
/// Start this instance.
///
protected override void Start()
{
base.Start();
Init();
Refresh();
}
///
/// Init this instance.
///
public virtual void Init()
{
if (isInited)
{
return;
}
isInited = true;
#pragma warning disable 0618
if (DefaultCursorTexture != null)
{
UICursor.ObsoleteWarning();
}
#pragma warning restore 0618
}
///
/// Process the initialize potential drag event.
///
/// Event data.
public virtual void OnInitializePotentialDrag(PointerEventData eventData)
{
// do nothing, left for compatibility reason
}
///
/// Shows the drop indicator.
///
/// Index.
protected virtual void ShowDropIndicator(int index)
{
if (DropIndicator != null)
{
DropIndicator.Show(index, RectTransform);
}
}
///
/// Hides the drop indicator.
///
protected virtual void HideDropIndicator()
{
if (DropIndicator != null)
{
DropIndicator.Hide();
}
}
///
/// Restore initial cells order.
///
[Obsolete("Renamed to RestoreColumnOrder().")]
public void RestoreOrder()
{
RestoreColumnsOrder();
}
///
/// Get the columns order.
///
/// Columns order.
public List GetColumnsOrder()
{
var result = new List(CellsInfo.Count);
GetColumnsOrder(result);
return result;
}
///
/// Get the columns order.
///
/// Columns order.
public void GetColumnsOrder(List order)
{
order.Clear();
foreach (var cell in CellsInfo)
{
order.Add(cell.Position);
}
}
List tempList = new List();
List tempReverseOrder = new List();
///
/// Set the columns order.
///
/// New columns order.
public void SetColumnsOrder(List order)
{
// restore original order
RestoreColumnsOrder();
// convert list of the new positions to list of the old positions
for (int i = 0; i < order.Count; i++)
{
tempReverseOrder.Add(order.IndexOf(i));
}
// restore list components cells order
List.Init();
List.ForEachComponent(SetItemColumnOrder);
for (int new_position = 0; new_position < tempReverseOrder.Count; new_position++)
{
var old_position = tempReverseOrder[new_position];
CellsInfo[old_position].Position = new_position;
CellsInfo[old_position].Rect.SetAsLastSibling();
}
tempReverseOrder.Clear();
}
void SetItemColumnOrder(ListViewItem component)
{
tempList.Clear();
var t = component.transform;
for (int i = 0; i < t.childCount; i++)
{
tempList.Add(t.GetChild(i));
}
for (int i = 0; i < tempReverseOrder.Count; i++)
{
tempList[i].SetAsLastSibling();
}
}
///
/// Restore column order for the specified component.
///
/// Component.
protected void RestoreColumnsOrder(ListViewItem component)
{
tempList.Clear();
var t = component.RectTransform;
for (int i = 0; i < t.childCount; i++)
{
tempList.Add(t.GetChild(i));
}
foreach (var cell in CellsInfo)
{
tempList[cell.Position].SetAsLastSibling();
}
}
///
/// Restore initial cells order.
///
public void RestoreColumnsOrder()
{
// restore order
if ((List != null) && (CellsInfo != null) && (CellsInfo.Count > 1))
{
// restore list components cells order
List.Init();
List.ForEachComponent(RestoreColumnsOrder);
// restore header cells order
for (int i = 0; i < CellsInfo.Count; i++)
{
CellsInfo[i].Position = i;
CellsInfo[i].Rect.SetSiblingIndex(i);
}
}
}
///
/// Re-init this instance in case if you remove or add cells manually.
///
public void Reinit()
{
RestoreColumnsOrder();
// clear cells list
CellsInfo.Clear();
// clear cell settings and events
for (int i = 0; i < RectTransform.childCount; i++)
{
var child = RectTransform.GetChild(i);
child.gameObject.SetActive(true);
var cell = Utilities.GetOrAddComponent(child);
cell.Position = -1;
var events = Utilities.GetOrAddComponent(child);
events.OnInitializePotentialDragEvent.RemoveListener(OnInitializePotentialDrag);
events.OnBeginDragEvent.RemoveListener(OnBeginDrag);
events.OnDragEvent.RemoveListener(OnDrag);
events.OnEndDragEvent.RemoveListener(OnEndDrag);
}
Refresh();
}
///
/// Init cells.
///
protected void InitCells()
{
for (int i = 0; i < RectTransform.childCount; i++)
{
var child = RectTransform.GetChild(i);
var cell = Utilities.GetOrAddComponent(child);
if (cell.Position == -1)
{
cell.Position = CellsInfo.Count;
cell.TableHeader = this;
cell.Cursors = Cursors;
#pragma warning disable 0618
cell.AllowDropCursor = AllowDropCursor;
cell.AllowDropCursorHotSpot = AllowDropCursorHotSpot;
cell.DeniedDropCursor = DeniedDropCursor;
cell.DeniedDropCursorHotSpot = DeniedDropCursorHotSpot;
#pragma warning restore 0618
var events = Utilities.GetOrAddComponent(child);
events.OnInitializePotentialDragEvent.AddListener(OnInitializePotentialDrag);
events.OnBeginDragEvent.AddListener(OnBeginDrag);
events.OnDragEvent.AddListener(OnDrag);
events.OnEndDragEvent.AddListener(OnEndDrag);
CellsInfo.Add(new TableHeaderCellInfo()
{
Rect = child as RectTransform,
LayoutElement = Utilities.GetOrAddComponent(child),
Position = CellsInfo.Count,
});
}
}
}
///
/// Called by a BaseInputModule when an OnPointerEnter event occurs.
///
/// Event data.
public void OnPointerEnter(PointerEventData eventData)
{
if (!IsActive())
{
return;
}
IsCursorOver = true;
CurrentCamera = eventData.pressEventCamera;
}
///
/// Called by a BaseInputModule when an OnPointerExit event occurs.
///
/// Event data.
public void OnPointerExit(PointerEventData eventData)
{
IsCursorOver = false;
ResetCursor();
}
///
/// Process application focus event.
///
/// Application has focus?
protected virtual void OnApplicationFocus(bool hasFocus)
{
if (!hasFocus)
{
IsCursorOver = false;
}
}
///
/// Reset cursor.
///
protected void ResetCursor()
{
cursorChanged = false;
UICursor.Reset(this);
}
///
/// Is cursor changed?
///
protected bool cursorChanged;
///
/// Process the enable event.
///
protected override void OnEnable()
{
base.OnEnable();
Updater.AddLateUpdate(this);
}
///
/// Process the disable event.
///
protected override void OnDisable()
{
base.OnDisable();
Updater.RemoveLateUpdate(this);
}
///
/// Update cursors.
///
public virtual void RunLateUpdate()
{
if (!IsActive())
{
return;
}
if (!AllowResize)
{
return;
}
if (!CanChangeCursor)
{
return;
}
if (processDrag || ProcessCellReorder)
{
return;
}
if (InActiveRegion)
{
UICursor.Set(this, GetCursor());
cursorChanged = true;
}
else if (cursorChanged)
{
ResetCursor();
}
}
///
/// Get cursor.
///
/// Cursor.
protected virtual Cursors.Cursor GetCursor()
{
if (Cursors != null)
{
return Cursors.EastWestArrow;
}
if (UICursor.Cursors != null)
{
return UICursor.Cursors.EastWestArrow;
}
return default(Cursors.Cursor);
}
///
/// Check if event happened in active region.
///
/// Event data
/// True if event happened in active region; otherwise false.
public virtual bool CheckInActiveRegion(PointerEventData eventData)
{
return CheckInActiveRegion(eventData.pressPosition, eventData.pressEventCamera);
}
readonly List cellsInfoOrdered = new List();
///
/// CellInfo sorted by position.
///
protected List CellsInfoOrdered
{
get
{
cellsInfoOrdered.Clear();
cellsInfoOrdered.AddRange(CellsInfo);
cellsInfoOrdered.Sort(CellComparison);
return cellsInfoOrdered;
}
}
///
/// Cell comparison.
///
/// First cell.
/// Second cell.
/// Comparison result.
protected static int CellComparison(TableHeaderCellInfo x, TableHeaderCellInfo y)
{
return x.Position.CompareTo(y.Position);
}
///
/// Check if cursor in active region to resize.
///
/// Cursor position.
/// Camera.
/// true if cursor in active region to resize; otherwise, false.
protected virtual bool CheckInActiveRegion(Vector2 position, Camera camera)
{
Vector2 point;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, position, camera, out point))
{
return false;
}
var rect = RectTransform.rect;
if (!rect.Contains(point))
{
return false;
}
point += new Vector2(rect.width * RectTransform.pivot.x, 0);
int i = 0;
foreach (var cell in CellsInfoOrdered)
{
if (!cell.ActiveSelf)
{
i++;
continue;
}
if (GetTargetIndex(i, -1) != -1)
{
if (CheckLeft(cell.Rect, point))
{
return true;
}
}
if (GetTargetIndex(i, +1) != -1)
{
if (CheckRight(cell.Rect, point))
{
return true;
}
}
i++;
}
return false;
}
float widthLimit;
float leftTargetWidth;
float rightTargetWidth;
///
/// Process the begin drag event.
///
/// Event data.
public virtual void OnBeginDrag(PointerEventData eventData)
{
if (!IsActive())
{
return;
}
if (!AllowResize)
{
return;
}
if (ProcessCellReorder)
{
return;
}
Vector2 point;
processDrag = false;
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.pressPosition, eventData.pressEventCamera, out point))
{
return;
}
var r = RectTransform.rect;
point += new Vector2(r.width * RectTransform.pivot.x, 0);
foreach (var cell in CellsInfoOrdered)
{
var i = cell.Position;
if (!cell.ActiveSelf)
{
continue;
}
if (CheckLeft(cell.Rect, point))
{
var left = GetTargetIndex(i, -1);
if (left != -1)
{
processDrag = true;
var left_cell = GetCellInfo(left);
leftTarget = left_cell.LayoutElement;
rightTarget = cell.LayoutElement;
leftTargetWidth = left_cell.Width;
rightTargetWidth = cell.Width;
widthLimit = leftTargetWidth + rightTargetWidth;
return;
}
}
if (CheckRight(cell.Rect, point))
{
var right = GetTargetIndex(i, +1);
if (right != -1)
{
processDrag = true;
var right_cell = GetCellInfo(right);
leftTarget = cell.LayoutElement;
rightTarget = right_cell.LayoutElement;
leftTargetWidth = cell.Width;
rightTargetWidth = right_cell.Width;
widthLimit = leftTargetWidth + rightTargetWidth;
return;
}
}
}
}
TableHeaderCellInfo GetCellInfo(int position)
{
foreach (var cell in CellsInfo)
{
if (cell.Position == position)
{
return cell;
}
}
return null;
}
int GetTargetIndex(int index, int direction)
{
if ((index + direction) == -1)
{
return -1;
}
if ((index + direction) == CellsInfo.Count)
{
return -1;
}
var is_active = GetCellInfo(index + direction).ActiveSelf;
var result = is_active
? index + direction
: GetTargetIndex(index + direction, direction);
return result;
}
///
/// Checks if point in the left region.
///
/// true, if point in the left region, false otherwise.
/// RectTransform.
/// Point.
bool CheckLeft(RectTransform childRectTransform, Vector2 point)
{
var r = childRectTransform.rect;
r.position += new Vector2(childRectTransform.anchoredPosition.x, 0);
r.width = ActiveRegion;
return r.Contains(point);
}
///
/// Checks if point in the right region.
///
/// true, if right was checked, false otherwise.
/// Child RectTransform.
/// Point.
bool CheckRight(RectTransform childRectTransform, Vector2 point)
{
var r = childRectTransform.rect;
r.position += new Vector2(childRectTransform.anchoredPosition.x, 0);
r.position = new Vector2(r.position.x + r.width - ActiveRegion - 1, r.position.y);
r.width = ActiveRegion + 1;
return r.Contains(point);
}
///
/// Process the end drag event.
///
/// Event data.
public void OnEndDrag(PointerEventData eventData)
{
if (!processDrag)
{
return;
}
ResetCursor();
ResetChildren();
if (!OnDragUpdate)
{
Resize();
}
processDrag = false;
}
///
/// Process the drag event.
///
/// Event data.
public void OnDrag(PointerEventData eventData)
{
if (!processDrag)
{
return;
}
cursorChanged = true;
UICursor.Set(this, GetCursor());
Vector2 current_point;
Vector2 original_point;
RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.position, eventData.pressEventCamera, out current_point);
RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform, eventData.pressPosition, eventData.pressEventCamera, out original_point);
var delta = current_point - original_point;
if (delta.x > 0)
{
leftTarget.preferredWidth = Mathf.Min(leftTargetWidth + delta.x, widthLimit - rightTarget.minWidth);
rightTarget.preferredWidth = widthLimit - leftTarget.preferredWidth;
}
else
{
rightTarget.preferredWidth = Mathf.Min(rightTargetWidth - delta.x, widthLimit - leftTarget.minWidth);
leftTarget.preferredWidth = widthLimit - rightTarget.preferredWidth;
}
LayoutUtilities.UpdateLayout(layout);
if (OnDragUpdate)
{
Resize();
}
}
///
/// Resets the children widths.
///
void ResetChildren()
{
foreach (var cell in CellsInfo)
{
ResetChildrenWidth(cell);
}
}
void ResetChildrenWidth(TableHeaderCellInfo cell)
{
cell.LayoutElement.preferredWidth = cell.Rect.rect.width;
}
///
/// Resize items in ListView.
///
public void Resize()
{
if (List == null)
{
return;
}
if (CellsInfo.Count < 2)
{
return;
}
List.Init();
List.ForEachComponent(ResizeComponent);
}
///
/// Resizes the game object.
///
/// Game object.
/// The index.
void ResizeGameObject(GameObject go, int index)
{
var cell = GetCellInfo(index);
(go.transform as RectTransform).SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, cell.Width);
var layoutElement = go.GetComponent();
if (layoutElement)
{
layoutElement.minWidth = cell.LayoutElement.minWidth;
layoutElement.flexibleWidth = cell.LayoutElement.flexibleWidth;
layoutElement.preferredWidth = cell.Width;
}
}
///
/// Resizes the component.
///
/// Component.
void ResizeComponent(ListViewItem component)
{
for (int i = 0; i < component.transform.childCount; i++)
{
ResizeGameObject(component.transform.GetChild(i).gameObject, i);
}
}
static void ReorderComponent(ListViewItem component, int prevPosition, int newPosition)
{
var target = component.transform.GetChild(prevPosition);
target.SetSiblingIndex(newPosition);
}
///
/// Move column from oldColumnPosition to newColumnPosition.
///
/// Old column position.
/// New column position.
public void Reorder(int oldColumnPosition, int newColumnPosition)
{
if (CellsInfo.Count < 2)
{
return;
}
if (List != null)
{
List.Init();
#if CSHARP_7_3_OR_NEWER
void Action(ListViewItem component)
#else
Action Action = component =>
#endif
{
ReorderComponent(component, CellsInfo[oldColumnPosition].Position, CellsInfo[newColumnPosition].Position);
}
#if !CSHARP_7_3_OR_NEWER
;
#endif
List.ForEachComponent(Action);
}
var target = CellsInfo[oldColumnPosition].Rect;
target.SetSiblingIndex(CellsInfo[newColumnPosition].Position);
for (int i = 0; i < CellsInfo.Count; i++)
{
CellsInfo[i].Position = CellsInfo[i].Rect.GetSiblingIndex();
}
}
#region IDropSupport
///
/// Determines whether this instance can receive drop with the specified data and eventData.
///
/// true if this instance can receive drop with the specified data and eventData; otherwise, false.
/// Cell.
/// Event data.
public bool CanReceiveDrop(TableHeaderDragCell data, PointerEventData eventData)
{
if (!IsActive())
{
return false;
}
if (!AllowReorder)
{
return false;
}
var target = FindTarget(eventData);
if ((target == null) || (target.GetInstanceID() == data.GetInstanceID()))
{
return false;
}
ShowDropIndicator(CellsInfo[target.Position].Position);
return true;
}
///
/// Handle dropped data.
///
/// Cell.
/// Event data.
public void Drop(TableHeaderDragCell data, PointerEventData eventData)
{
HideDropIndicator();
var target = FindTarget(eventData);
Reorder(data.Position, target.Position);
}
///
/// Handle canceled drop.
///
/// Cell.
/// Event data.
public void DropCanceled(TableHeaderDragCell data, PointerEventData eventData)
{
HideDropIndicator();
}
///
/// Change value position in specified list.
///
/// Type.
/// List.
/// Old position.
/// New position.
protected static void ChangePosition(List list, int oldPosition, int newPosition)
{
var item = list[oldPosition];
list.RemoveAt(oldPosition);
list.Insert(newPosition, item);
}
readonly List raycastResults = new List();
///
/// Get TableHeaderDragCell in position specified with event data.
///
/// Event data.
/// TableHeaderDragCell if found; otherwise null.
protected TableHeaderDragCell FindTarget(PointerEventData eventData)
{
raycastResults.Clear();
EventSystem.current.RaycastAll(eventData, raycastResults);
foreach (var raycastResult in raycastResults)
{
if (!raycastResult.isValid)
{
continue;
}
var target = raycastResult.gameObject.GetComponent();
if ((target != null) && target.transform.IsChildOf(transform))
{
return target;
}
}
return null;
}
#endregion
///
/// Remove listeners.
///
protected override void OnDestroy()
{
base.OnDestroy();
CellsInfo.Clear();
for (int i = 0; i < RectTransform.childCount; i++)
{
var child = RectTransform.GetChild(i);
var events = child.GetComponent();
if (events == null)
{
continue;
}
events.OnInitializePotentialDragEvent.RemoveListener(OnInitializePotentialDrag);
events.OnBeginDragEvent.RemoveListener(OnBeginDrag);
events.OnDragEvent.RemoveListener(OnDrag);
events.OnEndDragEvent.RemoveListener(OnEndDrag);
}
}
///
/// Refresh header.
///
public void Refresh()
{
if (layout == null)
{
layout = GetComponent();
}
if (layout != null)
{
LayoutUtilities.UpdateLayout(layout);
}
InitCells();
ResetChildren();
Resize();
}
///
/// Change column state.
///
/// Index.
/// If set state to active.
public void ColumnToggle(int index, bool active)
{
var target = CellsInfo[index];
target.Rect.gameObject.SetActive(active);
#if CSHARP_7_3_OR_NEWER
void Action(ListViewItem component)
#else
Action Action = component =>
#endif
{
var child = component.transform.GetChild(target.Position);
child.gameObject.SetActive(active);
}
#if !CSHARP_7_3_OR_NEWER
;
#endif
List.ForEachComponent(Action);
List.ComponentsColoring();
Refresh();
}
///
/// Disable column.
///
/// Index.
public void ColumnDisable(int index)
{
ColumnToggle(index, false);
}
///
/// Enable column.
///
/// Index.
public void ColumnEnable(int index)
{
ColumnToggle(index, true);
}
///
/// Add header cell.
///
/// Cell.
public void AddCell(GameObject cell)
{
cell.transform.SetParent(transform, false);
cell.SetActive(true);
Refresh();
}
///
/// Get cell index for the specified gameobject.
///
/// Gameobject.
/// Index of the cell.
protected int GetCellIndex(GameObject go)
{
for (int i = 0; i < CellsInfo.Count; i++)
{
if (CellsInfo[i].Rect.gameObject == go)
{
return i;
}
}
return -1;
}
///
/// Remove header cell.
///
/// Cell.
/// Parent.
public void RemoveCell(GameObject cell, RectTransform parent = null)
{
var index = GetCellIndex(cell);
if (index == -1)
{
Debug.LogWarning("Cell not in header", cell);
return;
}
cell.SetActive(false);
cell.transform.SetParent(parent, false);
if (parent == null)
{
Destroy(cell);
}
// remove from cells
CellsInfo.RemoveAt(index);
// remove events
var events = Utilities.GetOrAddComponent(cell);
events.OnInitializePotentialDragEvent.RemoveListener(OnInitializePotentialDrag);
events.OnBeginDragEvent.RemoveListener(OnBeginDrag);
events.OnDragEvent.RemoveListener(OnDrag);
events.OnEndDragEvent.RemoveListener(OnEndDrag);
// decrease position for cells where >cell_position
var cell_info = CellsInfo[index];
for (int i = 0; i < CellsInfo.Count; i++)
{
if (CellsInfo[i].Position > cell_info.Position)
{
CellsInfo[i].Position -= 1;
}
}
// update list widths
LayoutUtilities.UpdateLayout(layout);
Resize();
}
#if UNITY_EDITOR
///
/// Reset this instance.
///
protected override void Reset()
{
CursorsDPISelector.Require(this);
base.Reset();
}
#endif
#region IStylable implementation
///
public virtual bool SetStyle(Style style)
{
// apply style for header
style.Table.Border.ApplyTo(gameObject);
for (int i = 0; i < RectTransform.childCount; i++)
{
var cell = RectTransform.GetChild(i);
var style_support = cell.GetComponent();
if (style_support != null)
{
style_support.SetStyle(style);
}
else
{
style.Table.Background.ApplyTo(cell);
style.Table.HeaderText.ApplyTo(cell.Find("Text"));
}
}
// apply style to list
style.Table.Border.ApplyTo(List.Container);
#if CSHARP_7_3_OR_NEWER
void Action(ListViewItem component)
#else
Action Action = component =>
#endif
{
style.Table.Border.ApplyTo(component);
for (int i = 0; i < component.RectTransform.childCount; i++)
{
var child = component.RectTransform.GetChild(i);
style.Table.Background.ApplyTo(child.gameObject);
}
}
#if !CSHARP_7_3_OR_NEWER
;
#endif
List.ForEachComponent(Action);
return true;
}
///
public virtual bool GetStyle(Style style)
{
// got style from header
style.Table.Border.GetFrom(gameObject);
for (int i = 0; i < RectTransform.childCount; i++)
{
var cell = RectTransform.GetChild(i);
var style_support = cell.GetComponent();
if (style_support != null)
{
style_support.GetStyle(style);
}
else
{
style.Table.Background.GetFrom(cell);
style.Table.HeaderText.GetFrom(cell.Find("Text"));
}
}
// got style from list
style.Table.Border.GetFrom(List.Container);
return true;
}
#endregion
}
}