using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.EventSystems;
public class InfiniteScroll : MonoBehaviour
{
[SerializeField]
private RectTransform m_ItemBase;
[SerializeField, Range(0, 30)]
int m_instantateItemCount = 9;
[SerializeField]
float m_itemWidth = 1080;
[SerializeField]
float m_itemHeight = 200;
[SerializeField]
float gap = 10;
public Direction direction;
[System.NonSerialized]
public List<RectTransform> m_itemList = new List<RectTransform> ();
protected float m_diffPreFramePosition = 0;
protected int m_currentItemNo = 0;
public ScrollRect scrollRect;
public List<DataVO> listData;
public enum Direction
{
Vertical,
Horizontal,
}
//For Event
private const float inchToCm = 2.54f;
[SerializeField]
private EventSystem eventSystem = null;
[SerializeField]
private float dragThresholdCM = 0.5f;
//For drag Threshold
private void SetDragThreshold()
{
if (eventSystem != null)
{
eventSystem.pixelDragThreshold = (int)(dragThresholdCM * Screen.dpi / inchToCm);
}
}
// cache component
private RectTransform m_rectTransform;
protected RectTransform _RectTransform {
get {
if (m_rectTransform == null)
m_rectTransform = GetComponent<RectTransform> ();
return m_rectTransform;
}
}
private float AnchoredPosition
{
get{
return (direction == Direction.Vertical ) ?
-_RectTransform.anchoredPosition.y:
_RectTransform.anchoredPosition.x;
}
}
private float ItemScale{
get{
return (direction == Direction.Vertical) ?
m_itemHeight :
m_itemWidth;
}
}
void Awake()
{
SetDragThreshold();
}
public void ListStart ()
{
listData = ListModel.Instance.MusicList;
if(listData.Count<m_instantateItemCount){
m_instantateItemCount = listData.Count;
}else{
m_instantateItemCount = (direction == Direction.Vertical) ?
(int) System.Math.Truncate( Screen.height / ItemScale ) + 3 :
(int) System.Math.Truncate( Screen.width / ItemScale ) + 3;
}
// create items
scrollRect.horizontal = direction == Direction.Horizontal;
scrollRect.vertical = direction == Direction.Vertical;
scrollRect.content = _RectTransform;
if(direction == Direction.Vertical){
scrollRect.content.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, (ItemScale + gap) * (listData.Count-1) + gap );
scrollRect.content.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, m_itemWidth + gap*2);
}else{
scrollRect.content.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, (ItemScale + gap) * (listData.Count-1) + gap );
scrollRect.content.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, m_itemHeight + gap*2 );
}
scrollRect.onValueChanged.AddListener (valueChange);
Debug.Log( listData.Count );
m_ItemBase.gameObject.SetActive (false);
for (int i=0; i<m_instantateItemCount; i++) {
var item = GameObject.Instantiate (m_ItemBase) as RectTransform;
item.SetParent (transform, false);
item.name = i.ToString ();
if(direction == Direction.Vertical){
item.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, m_itemWidth - gap*2);
item.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, m_itemHeight);
}else{
item.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, m_itemWidth);
item.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, m_itemHeight);
}
item.anchoredPosition =
(direction == Direction.Vertical ) ?
new Vector2 (gap, - gap - (ItemScale + gap) * i) :
new Vector2 ((ItemScale + gap) * i + gap, -gap) ;
m_itemList.Add (item);
item.gameObject.SetActive (true);
item.GetComponent<Item>().UpdateItem(i);
}
}
private void valueChange(Vector2 _pos)
{
// scroll up, item attach bottom or right
while(AnchoredPosition - m_diffPreFramePosition < -(ItemScale + gap)*2 ){
m_diffPreFramePosition -= (ItemScale + gap);
var item = m_itemList [0];
m_itemList.RemoveAt (0);
m_itemList.Add (item);
var pos = (ItemScale + gap) * m_instantateItemCount + (ItemScale + gap) * m_currentItemNo ;
item.anchoredPosition = (direction == Direction.Vertical ) ? new Vector2 (gap, -pos - gap) : new Vector2 (pos + gap , -gap);
m_currentItemNo ++;
if(m_currentItemNo + m_instantateItemCount < listData.Count){
item.GetComponent<Item>().UpdateItem(m_currentItemNo + m_instantateItemCount);
}else{
item.GetComponent<Item>().UpdateItem(-100);
}
}
// scroll down, item attach top or left
while(AnchoredPosition - m_diffPreFramePosition > 0){
m_diffPreFramePosition += (ItemScale + gap);
var itemListLastCount = m_instantateItemCount - 1;
var item = m_itemList [itemListLastCount];
m_itemList.RemoveAt (itemListLastCount);
m_itemList.Insert (0, item);
m_currentItemNo --;
var pos = (ItemScale + gap) * m_currentItemNo + gap;
item.anchoredPosition = (direction == Direction.Vertical ) ? new Vector2 (gap, -pos ): new Vector2 (pos, -gap);
if(m_currentItemNo > -1){
item.GetComponent<Item>().UpdateItem(m_currentItemNo);
}else{
item.GetComponent<Item>().UpdateItem(-100);
}
}
}
}