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 } }