154 lines
5.4 KiB
C#
154 lines
5.4 KiB
C#
//MIT License
|
|
//Copyright (c) 2020 Mohammed Iqubal Hussain
|
|
//Website : Polyandcode.com
|
|
|
|
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace PolyAndCode.UI
|
|
{
|
|
/// <summary>
|
|
/// Entry for the recycling system. Extends Unity's inbuilt ScrollRect.
|
|
/// </summary>
|
|
public class RecyclableScrollRect : ScrollRect
|
|
{
|
|
[HideInInspector]
|
|
public IRecyclableScrollRectDataSource DataSource;
|
|
|
|
public bool IsGrid;
|
|
//Prototype cell can either be a prefab or present as a child to the content(will automatically be disabled in runtime)
|
|
public RectTransform PrototypeCell;
|
|
//If true the intiziation happens at Start. Controller must assign the datasource in Awake.
|
|
//Set to false if self init is not required and use public init API.
|
|
public bool SelfInitialize = true;
|
|
|
|
public enum DirectionType
|
|
{
|
|
Vertical,
|
|
Horizontal
|
|
}
|
|
|
|
public DirectionType Direction;
|
|
|
|
//Segments : coloums for vertical and rows for horizontal.
|
|
public int Segments
|
|
{
|
|
set
|
|
{
|
|
_segments = Math.Max(value, 2);
|
|
}
|
|
get
|
|
{
|
|
return _segments;
|
|
}
|
|
}
|
|
[SerializeField]
|
|
private int _segments;
|
|
|
|
private RecyclingSystem _recyclingSystem;
|
|
private Vector2 _prevAnchoredPos;
|
|
|
|
protected override void Start()
|
|
{
|
|
//defafult(built-in) in scroll rect can have both directions enabled, Recyclable scroll rect can be scrolled in only one direction.
|
|
//setting default as vertical, Initialize() will set this again.
|
|
vertical = true;
|
|
horizontal = false;
|
|
|
|
if (!Application.isPlaying) return;
|
|
|
|
if (SelfInitialize) Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initialization when selfInitalize is true. Assumes that data source is set in controller's Awake.
|
|
/// </summary>
|
|
private void Initialize()
|
|
{
|
|
//Contruct the recycling system.
|
|
if (Direction == DirectionType.Vertical)
|
|
{
|
|
_recyclingSystem = new VerticalRecyclingSystem(PrototypeCell, viewport, content, DataSource, IsGrid, Segments);
|
|
}
|
|
else if (Direction == DirectionType.Horizontal)
|
|
{
|
|
_recyclingSystem = new HorizontalRecyclingSystem(PrototypeCell, viewport, content, DataSource, IsGrid, Segments);
|
|
}
|
|
vertical = Direction == DirectionType.Vertical;
|
|
horizontal = Direction == DirectionType.Horizontal;
|
|
|
|
_prevAnchoredPos = content.anchoredPosition;
|
|
onValueChanged.RemoveListener(OnValueChangedListener);
|
|
//Adding listener after pool creation to avoid any unwanted recycling behaviour.(rare scenerio)
|
|
StartCoroutine(_recyclingSystem.InitCoroutine(() =>
|
|
onValueChanged.AddListener(OnValueChangedListener)
|
|
));
|
|
}
|
|
|
|
/// <summary>
|
|
/// public API for Initializing when datasource is not set in controller's Awake. Make sure selfInitalize is set to false.
|
|
/// </summary>
|
|
public void Initialize(IRecyclableScrollRectDataSource dataSource)
|
|
{
|
|
DataSource = dataSource;
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Added as a listener to the OnValueChanged event of Scroll rect.
|
|
/// Recycling entry point for recyling systems.
|
|
/// </summary>
|
|
/// <param name="direction">scroll direction</param>
|
|
public void OnValueChangedListener(Vector2 normalizedPos)
|
|
{
|
|
Vector2 dir = content.anchoredPosition - _prevAnchoredPos;
|
|
m_ContentStartPosition += _recyclingSystem.OnValueChangedListener(dir);
|
|
_prevAnchoredPos = content.anchoredPosition;
|
|
}
|
|
|
|
/// <summary>
|
|
///Reloads the data. Call this if a new datasource is assigned.
|
|
/// </summary>
|
|
public void ReloadData()
|
|
{
|
|
ReloadData(DataSource);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overloaded ReloadData with dataSource param
|
|
///Reloads the data. Call this if a new datasource is assigned.
|
|
/// </summary>
|
|
public void ReloadData(IRecyclableScrollRectDataSource dataSource)
|
|
{
|
|
if (_recyclingSystem != null)
|
|
{
|
|
StopMovement();
|
|
onValueChanged.RemoveListener(OnValueChangedListener);
|
|
_recyclingSystem.DataSource = dataSource;
|
|
StartCoroutine(_recyclingSystem.InitCoroutine(() =>
|
|
onValueChanged.AddListener(OnValueChangedListener)
|
|
));
|
|
_prevAnchoredPos = content.anchoredPosition;
|
|
}
|
|
}
|
|
|
|
/*
|
|
#region Testing
|
|
private void OnDrawGizmos()
|
|
{
|
|
if (_recyclableScrollRect is VerticalRecyclingSystem)
|
|
{
|
|
((VerticalRecyclingSystem)_recyclableScrollRect).OnDrawGizmos();
|
|
}
|
|
|
|
if (_recyclableScrollRect is HorizontalRecyclingSystem)
|
|
{
|
|
((HorizontalRecyclingSystem)_recyclableScrollRect).OnDrawGizmos();
|
|
}
|
|
|
|
}
|
|
#endregion
|
|
*/
|
|
}
|
|
} |