using BeinLab.Util;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using XRTool.UI;
using XRTool.Util;
namespace XRTool.WorldUI
{
///
/// LayoutGroup
///
public enum LayoutType
{
None = -2,
UnKnow = -1,
GridLayoutGroup = 0,
VerticalLayoutGroup = 1,
HorizontalLayoutGroup = 2,
}
///
/// 目标:1实现基本列表功能,生成,销毁,刷新,点击事件的传递等,支持常规的Button,Toggle类型的组件支持
/// 2,实现滑动循环列表
/// 3,实现多项内容展示时的优化
/// 4,指定距离停顿
///
public class XRScrollRect : ScrollRect
{
public bool isLoop;
public LayoutType layoutType = LayoutType.UnKnow;
private int allCount;
private int showCount;
private Vector2 cellSize;
private Vector2 cellSpace;
//private bool isDraging = false;
private ItemCell superCell;
private LayoutGroup layoutGroup;
private List cellList;
private Bounds viewBounds;
//private float dragTime = 0.2f;
//private float lastDragTime;
protected override void Start()
{
base.Start();
viewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size);
}
public LayoutGroup LayoutGroup
{
get
{
if (!layoutGroup)
{
layoutGroup = content.GetComponent();
}
return layoutGroup;
}
}
public List CellList { get => cellList; set => cellList = value; }
protected override void LateUpdate()
{
if ( velocity.magnitude > 66 || !IsMoveCalculatePosition())
{
base.LateUpdate();
XRUpdateItemVisibility();
}
}
///
/// 更新显示Scroll
///
private void XRUpdateItemVisibility()
{
///存在子物体,同时显示数据小于总物体数字时
if (allCount > 0 && showCount < allCount && content.childCount > 0)
{
for (int i = 0; i < content.childCount; i++)
{
RectTransform child = content.GetChild(i) as RectTransform;
if (child.anchoredPosition.x < 0)
{
child.GetChild(0).gameObject.SetActive(false);
}
}
}
}
///
/// 计算最终落点
///
///
public bool IsMoveCalculatePosition()
{
return false;
}
///
/// 初始化数据
///
///
///
///
///
///
public void InitData(int count, int showCount, Vector2 cellSize, Vector3 cellSpace, ItemCell prefab)
{
this.allCount = count;
this.showCount = showCount;
this.cellSize = cellSize;
this.cellSpace = cellSpace;
this.superCell = prefab;
CreateScrollList();
}
public void ClearScrollList()
{
if (content)
{
for (int i = 0; i < content.childCount; i++)
{
Destroy(content.GetChild(i).gameObject);
}
}
CellList.Clear();
}
///
/// 创建列表
///
private void CreateScrollList(bool isClear = true)
{
if (CellList == null)
{
CellList = new List();
}
if (isClear)
{
ClearScrollList();
}
GameObject prefab = superCell.GetInstance();
///prefab.GetInstance()获取抽象类的实例,不确定这么做可以正常运行,测试中
if (prefab)
{
if (!isLoop)
{
int instanceCount = showCount;
if (showCount >= allCount)
{
instanceCount = allCount;
}
for (int i = 0; i < instanceCount; i++)
{
GameObject obj = Instantiate(prefab);
UnityUtil.SetParent(content, obj.transform);
CellList.Add(obj.GetComponent());
}
RectTransform body = GetComponent();
Vector2 size = body.sizeDelta;
if (horizontal && !vertical)
{
size.y = cellSize.y;
//size.x = instanceCount*cellSize.x +
}
else if (vertical && !horizontal)
{
size.x = cellSize.x;
}
}
}
if (LayoutGroup)
{
if (LayoutGroup is GridLayoutGroup)
{
var lay = (LayoutGroup as GridLayoutGroup);
lay.cellSize = this.cellSize;
lay.spacing = this.cellSpace;
}
else if (LayoutGroup is VerticalLayoutGroup)
{
var lay = (LayoutGroup as VerticalLayoutGroup);
lay.spacing = this.cellSpace.y;
}
else if (LayoutGroup is HorizontalLayoutGroup)
{
var lay = (LayoutGroup as HorizontalLayoutGroup);
lay.spacing = this.cellSpace.x;
}
}
}
//private void XRUpdateScrollbarVisibility()
//{
// if (horizontalScrollbar && !isShowHorizontal && horizontalScrollbar.isActiveAndEnabled)
// {
// horizontalScrollbar.gameObject.SetActive(false);
// }
// if (verticalScrollbar && !isShowVertical && verticalScrollbar.isActiveAndEnabled)
// {
// verticalScrollbar.gameObject.SetActive(false);
// }
//}
public override void OnDrag(PointerEventData eventData)
{
base.OnDrag(eventData);
}
protected override void SetContentAnchoredPosition(Vector2 position)
{
base.SetContentAnchoredPosition(position);
}
//public override void OnBeginDrag(PointerEventData eventData)
//{
// base.OnBeginDrag(eventData);
// //isDraging = true;
// //lastDragTime = Time.time;
//}
//public override void OnEndDrag(PointerEventData eventData)
//{
// base.OnEndDrag(eventData);
// //isDraging = false;
// //if (Time.time - lastDragTime < dragTime)
// //{
// // if (eventData.pointerEnter)
// // {
// // var tmpbutton = eventData.pointerEnter.GetComponentInParent();
// // if (tmpbutton != null)
// // {
// // tmpbutton.OnPointerClick(eventData);
// // }
// // }
// //}
//}
protected override void OnRectTransformDimensionsChange()
{
base.OnRectTransformDimensionsChange();
viewBounds = new Bounds(viewRect.rect.center, viewRect.rect.size);
}
private static float XRRubberDelta(float overStretching, float viewSize)
{
return (1 - (1 / ((Mathf.Abs(overStretching) * 0.55f / viewSize) + 1))) * viewSize * Mathf.Sign(overStretching);
}
private Vector2 XRCalculateOffset(Vector2 delta)
{
return XRInternalCalculateOffset(ref viewBounds, ref m_ContentBounds, horizontal, vertical, movementType, ref delta);
}
internal static Vector2 XRInternalCalculateOffset(ref Bounds viewBounds, ref Bounds contentBounds, bool horizontal, bool vertical, MovementType movementType, ref Vector2 delta)
{
Vector2 offset = Vector2.zero;
if (movementType == MovementType.Unrestricted)
return offset;
Vector2 min = contentBounds.min;
Vector2 max = contentBounds.max;
// min/max offset extracted to check if approximately 0 and avoid recalculating layout every frame (case 1010178)
if (horizontal)
{
min.x += delta.x;
max.x += delta.x;
float maxOffset = viewBounds.max.x - max.x;
float minOffset = viewBounds.min.x - min.x;
if (minOffset < -0.001f)
offset.x = minOffset;
else if (maxOffset > 0.001f)
offset.x = maxOffset;
}
if (vertical)
{
min.y += delta.y;
max.y += delta.y;
float maxOffset = viewBounds.max.y - max.y;
float minOffset = viewBounds.min.y - min.y;
if (maxOffset > 0.001f)
offset.y = maxOffset;
else if (minOffset < -0.001f)
offset.y = minOffset;
}
return offset;
}
}
}