Advertisement
Guest User

Untitled

a guest
Jun 8th, 2018
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.92 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.UI;
  4. using System;
  5. using System.Collections.Generic;
  6. using frame8.Logic.Misc.Visual.UI.ScrollRectItemsAdapter;
  7. using frame8.Logic.Misc.Other.Extensions;
  8. using frame8.ScrollRectItemsAdapter.Util;
  9. using frame8.ScrollRectItemsAdapter.Util.Drawer;
  10. using frame8.Logic.Misc.Visual.UI.MonoBehaviours;
  11. using UnityEngine.EventSystems;
  12. using frame8.Logic.Misc.Visual.UI;
  13. using UnityEngine.Events;
  14.  
  15. namespace frame8.ScrollRectItemsAdapter.ContentSizeFitterExample
  16. {
  17.     /// <summary>
  18.     /// <para>The prefabhas a disabled ContentSizeFitter added, which will be enabled in <see cref="UpdateViewsHolder(MyItemViewsHolder)"/> </para>
  19.     /// <para>if the size was not already calculated (in a previous call), then <see cref="SRIA{TParams, TItemViewsHolder}.ScheduleComputeVisibilityTwinPass(bool)"/> should be called. </para>
  20.     /// <para>After that, as soon as <see cref="UpdateViewsHolder(MyItemViewsHolder)"/> was called for all visible items, you'll receive a callback to <see cref="SRIA{TParams, TItemViewsHolder}.OnItemHeightChangedPreTwinPass(TItemViewsHolder)"/> </para>
  21.     /// <para>(or <see cref="SRIA{TParams, TItemViewsHolder}.OnItemWidthChangedPreTwinPass(TItemViewsHolder)"/> for horizontal ScrollRects) for each of them,</para>
  22.     /// <para>where you can disable the content size fitter.</para>
  23.     /// <para>A "Twin" <see cref="SRIA{TParams, TItemViewsHolder}.ComputeVisibility(double)"/> pass is executed after the current one has finished (meaning <see cref="UpdateViewsHolder(MyItemViewsHolder)"/> was called for all visible items).</para>
  24.     /// </summary>
  25.     public class ContentSizeFitterExample : SRIA<MyParams, MyItemViewsHolder>
  26.     {
  27.         public RectTransformEdgeDragger edgeDragger;
  28.  
  29.         const string LOREM_IPSUM = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";
  30.  
  31.  
  32.         #region SRIA implementation
  33.         /// <inheritdoc/>
  34.         protected override void Start()
  35.         {
  36.             _Params.NewModelCreator = index => CreateNewModel(index);
  37.             base.Start();
  38.  
  39.             DrawerCommandPanel.Instance.Init(this, true, false, true, false, true);
  40.             DrawerCommandPanel.Instance.galleryEffectSetting.slider.value = 0f;
  41.             DrawerCommandPanel.Instance.ItemCountChangeRequested += OnItemCountChangeRequested;
  42.             DrawerCommandPanel.Instance.AddItemRequested += OnAddItemRequested;
  43.             DrawerCommandPanel.Instance.RemoveItemRequested += OnRemoveItemRequested;
  44.  
  45.             //while (EventSystem.current.currentInputModule == null) { Debug.Log("waiting"); yield return null; };
  46.  
  47.             // Initially set the number of items to the number in the input field
  48.             DrawerCommandPanel.Instance.RequestChangeItemCountToSpecified();
  49.         }
  50.  
  51.         /// <inheritdoc/>
  52.         protected override MyItemViewsHolder CreateViewsHolder(int itemIndex)
  53.         {
  54.             var instance = new MyItemViewsHolder();
  55.             instance.Init(_Params.itemPrefab, itemIndex);
  56.             instance.onButtonClick.AddListener(() => { RebuildLayoutDueToScrollViewSizeChange(); });
  57.  
  58.             return instance;
  59.         }
  60.  
  61.         /// <inheritdoc/>
  62.         protected override void OnItemHeightChangedPreTwinPass(MyItemViewsHolder vh)
  63.         {          
  64.             base.OnItemHeightChangedPreTwinPass(vh);
  65.  
  66.             _Params.Data[vh.ItemIndex].HasPendingSizeChange = false;
  67.             vh.contentSizeFitter.enabled = false;
  68.         }
  69.  
  70.         /// <inheritdoc/>
  71.         protected override void UpdateViewsHolder(MyItemViewsHolder newOrRecycled)
  72.         {
  73.             // Initialize the views from the associated model
  74.             ExampleItemModel model = _Params.Data[newOrRecycled.ItemIndex];
  75.  
  76.             newOrRecycled.UpdateFromModel(model, _Params.availableIcons);
  77.  
  78.             if (newOrRecycled.contentSizeFitter.enabled)
  79.                 newOrRecycled.contentSizeFitter.enabled = false;
  80.  
  81.             if (model.HasPendingSizeChange)
  82.             {
  83.                 // Height will be available before the next 'twin' pass, inside OnItemHeightChangedPreTwinPass() callback (see above)
  84.                 newOrRecycled.MarkForRebuild(); // will enable the content size fitter
  85.                 ScheduleComputeVisibilityTwinPass();
  86.             }
  87.         }
  88.  
  89.         /// <inheritdoc/>
  90.         protected override void RebuildLayoutDueToScrollViewSizeChange()
  91.         {
  92.             // Invalidate the last sizes so that they'll be re-calculated
  93.             foreach (var model in _Params.Data.AsEnumerableForExistingItems)
  94.                 model.HasPendingSizeChange = true;
  95.  
  96.             base.RebuildLayoutDueToScrollViewSizeChange();
  97.         }
  98.         #endregion
  99.  
  100.         #region events from DrawerCommandPanel
  101.         void OnAddItemRequested(bool atEnd)
  102.         {
  103.             int index = atEnd ? _Params.Data.Count : 0;
  104.             _Params.Data.Insert(index, 1);
  105.             //_Params.Data.Insert(index, CreateNewModel(index));
  106.             InsertItems(index, 1, DrawerCommandPanel.Instance.freezeContentEndEdgeToggle.isOn);
  107.         }
  108.         void OnRemoveItemRequested(bool fromEnd)
  109.         {
  110.             if (_Params.Data.Count == 0)
  111.                 return;
  112.  
  113.             int index = fromEnd ? _Params.Data.Count - 1 : 0;
  114.             _Params.Data.RemoveAt(index);
  115.             RemoveItems(index, 1, DrawerCommandPanel.Instance.freezeContentEndEdgeToggle.isOn);
  116.         }
  117.         void OnItemCountChangeRequested(int newCount)
  118.         {
  119.             //// Generating some random models
  120.             //var newModels = new ExampleItemModel[newCount];
  121.             //for (int i = 0; i < newCount; ++i)
  122.             //  newModels[i] = CreateNewModel(i);
  123.  
  124.             //_Params.Data.Clear();
  125.             //_Params.Data.AddRange(newModels);
  126.             _Params.Data.InitWithNewCount(newCount);
  127.             ResetItems(_Params.Data.Count, DrawerCommandPanel.Instance.freezeContentEndEdgeToggle.isOn);
  128.         }
  129.         #endregion
  130.  
  131.         public ExampleItemModel CreateNewModel(int itemIdex)
  132.         {
  133.             return new ExampleItemModel()
  134.             {
  135.                 //Title = LOREM_IPSUM.Substring(400),
  136.                 Title = LOREM_IPSUM.Substring(0, UnityEngine.Random.Range(LOREM_IPSUM.Length / 50 + 1, LOREM_IPSUM.Length / 2)),
  137.                 IconIndex = UnityEngine.Random.Range(0, _Params.availableIcons.Length)
  138.             };
  139.         }
  140.     }
  141.  
  142.  
  143.     public class ExampleItemModel
  144.     {
  145.         /// <summary><see cref="HasPendingSizeChange"/> is set to true each time this property changes</summary>
  146.         public string Title
  147.         {
  148.             get { return _Title; }
  149.             set
  150.             {
  151.                 if (_Title != value)
  152.                 {
  153.                     _Title = value;
  154.                     HasPendingSizeChange = true;
  155.                 }
  156.             }
  157.         }
  158.  
  159.         public int IconIndex { get; set; }
  160.  
  161.         /// <summary>This will be true when the item size may have changed and the ContentSizeFitter component needs to be updated</summary>
  162.         public bool HasPendingSizeChange;
  163.  
  164.         string _Title;
  165.         public bool expanded = false;
  166.  
  167.         public ExampleItemModel()
  168.         {
  169.             // By default, the model's size is unknown, so mark it for size re-calculation
  170.             HasPendingSizeChange = true;
  171.         }
  172.     }
  173.  
  174.  
  175.     // This in almost all cases will contain the prefab and the list of models
  176.     [Serializable] // serializable, so it can be shown in inspector
  177.     public class MyParams : BaseParamsWithPrefabAndLazyData<ExampleItemModel>
  178.     {
  179.         public Texture2D[] availableIcons; // used to randomly generate models;
  180.     }
  181.  
  182.  
  183.     /// <summary>The ContentSizeFitter should be attached to the item itself</summary>
  184.     public class MyItemViewsHolder : BaseItemViewsHolder
  185.     {
  186.         public Text titleText;
  187.         public RawImage icon1Image;
  188.         public Button showButton;
  189.         public ExampleItemModel _Model;
  190.         public UnityEvent onButtonClick = new UnityEvent();
  191.  
  192.         public ContentSizeFitter contentSizeFitter { get; private set; }
  193.  
  194.  
  195.         public override void CollectViews()
  196.         {
  197.             base.CollectViews();
  198.  
  199.             contentSizeFitter = root.GetComponent<ContentSizeFitter>();
  200.             contentSizeFitter.enabled = false; // the content size fitter should not be enabled during normal lifecycle, only in the "Twin" pass frame
  201.             root.GetComponentAtPath("TitlePanel/TitleText", out titleText);
  202.             root.GetComponentAtPath("Icon1Image", out icon1Image);
  203.             root.GetComponentAtPath("Icon1Image", out showButton);
  204.             showButton.onClick.AddListener(OnClick);
  205.         }
  206.  
  207.         private void OnClick()
  208.         {
  209.             if (_Model == null)
  210.                 return;
  211.  
  212.             _Model.expanded = !_Model.expanded;
  213.             /*_Model.HasPendingSizeChange = true;
  214.             contentSizeFitter.enabled = true;*/
  215.             onButtonClick.Invoke();
  216.             titleText.gameObject.SetActive(_Model.expanded);
  217.         }
  218.  
  219.         public override void MarkForRebuild()
  220.         {
  221.             base.MarkForRebuild();
  222.             if (contentSizeFitter)
  223.                 contentSizeFitter.enabled = true;
  224.         }
  225.  
  226.         /// <summary>Utility getting rid of the need of manually writing assignments</summary>
  227.         public void UpdateFromModel(ExampleItemModel model, Texture2D[] availableIcons)
  228.         {
  229.             _Model = model;
  230.            
  231.             string title = "[#" + ItemIndex + "] " + model.Title;
  232.             if (titleText.text != title)
  233.                 titleText.text = title;
  234.             var tex = availableIcons[model.IconIndex];
  235.             if (icon1Image.texture != tex)
  236.                 icon1Image.texture = tex;
  237.  
  238.             titleText.gameObject.SetActive(model.expanded);
  239.         }
  240.     }
  241. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement