namespace UIWidgets { using System; using System.Collections.Generic; using UIWidgets.Styles; using UnityEngine; using UnityEngine.UI; /// /// Base generic class for the ScrollBlock. /// /// Type of the component. public class ScrollBlockCustom : ScrollBlockBase where TComponent : ScrollBlockItem { /// /// Item changed delegate. /// /// Index. /// Item instance. public delegate void ItemChanged(int index, TComponent item); /// /// Do nothing. /// static void DoNothing(int index, TComponent item) { } [SerializeField] TComponent defaultItem; /// /// DefaultItem. /// public TComponent DefaultItem { get { return defaultItem; } set { if (defaultItem != value) { defaultItem = value; ComponentsPool.Template = defaultItem; UpdateLayout(); Resize(); } } } /// /// Used instances of the DefaultItem. /// [SerializeField] [HideInInspector] protected List Components = new List(); /// /// Unused instances of the DefaultItem. /// [SerializeField] [HideInInspector] protected List ComponentsCache = new List(); ListComponentPool componentsPool; /// /// Components pool. /// protected ListComponentPool ComponentsPool { get { if (componentsPool == null) { componentsPool = new ListComponentPool(DefaultItem, Components, ComponentsCache, RectTransform); } return componentsPool; } } /// public override int Count { get { return ComponentsPool.Count; } } /// protected override int ComponentsMedian { get { return ComponentsPool.Count / 2; } } /// /// Item changed event. /// public event ItemChanged OnItemChanged = DoNothing; /// protected override void UpdateLayout() { var layout = GetComponent(); Layout = new EasyLayoutBridge(layout, DefaultItem.transform as RectTransform, false, false) { IsHorizontal = IsHorizontal, }; DefaultItemSize = Layout.GetItemSize(); DefaultItem.gameObject.SetActive(false); LayoutRebuilder.ForceRebuildLayoutImmediate(RectTransform.parent as RectTransform); } /// protected override void Resize() { var max = CalculateMax(); if (max == ComponentsPool.Count) { return; } ComponentsPool.Require(max); var median = ComponentsMedian; for (int i = 0; i < ComponentsPool.Count; i++) { ComponentsPool[i].Index = i - median; ComponentsPool[i].Owner = this; ComponentsPool[i].transform.SetAsLastSibling(); } UpdateView(); } /// /// Set text of the specified component. /// /// Component. protected virtual void SetComponentText(TComponent component) { component.Text.Value = Value(component.Index); component.DataChanged(); OnItemChanged(component.Index, component); } /// /// Set text. /// [Obsolete("Replaced with UpdateView().")] public void SetText() { UpdateView(); } /// public override void UpdateView() { Init(); foreach (var component in ComponentsPool) { SetComponentText(component); } } #region IStylable implementation /// public override bool SetStyle(Style style) { if (DefaultItem.Text != null) { style.ScrollBlock.Text.ApplyTo(DefaultItem.Text.GameObject); if (IsInited) { for (int i = 0; i < Components.Count; i++) { style.ScrollBlock.Text.ApplyTo(Components[i].Text.GameObject); } for (int i = 0; i < ComponentsCache.Count; i++) { style.ScrollBlock.Text.ApplyTo(ComponentsCache[i].Text.GameObject); } } } return true; } /// public override bool GetStyle(Style style) { if (DefaultItem.Text != null) { style.ScrollBlock.Text.GetFrom(DefaultItem.Text.GameObject); } return true; } #endregion } }