You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

174 lines
6.8 KiB

using UnityEngine;
using System.Collections;
namespace UnityEngine.UI
{
[AddComponentMenu("UI/Loop Horizontal Scroll Rect(MultiPrefab)", 52)]
[DisallowMultipleComponent]
public class LoopHorizontalScrollRectMulti : LoopScrollRectMulti
{
protected override float GetSize(RectTransform item, bool includeSpacing)
{
float size = includeSpacing ? contentSpacing : 0;
if (m_GridLayout != null)
{
size += m_GridLayout.cellSize.x;
}
else
{
size += LayoutUtility.GetPreferredWidth(item);
}
size *= m_Content.localScale.x;
return size;
}
protected override float GetDimension(Vector2 vector)
{
return -vector.x;
}
protected override float GetAbsDimension(Vector2 vector)
{
return vector.x;
}
protected override Vector2 GetVector(float value)
{
return new Vector2(-value, 0);
}
protected override void Awake()
{
direction = LoopScrollRectDirection.Horizontal;
base.Awake();
GridLayoutGroup layout = content.GetComponent<GridLayoutGroup>();
if (layout != null && layout.constraint != GridLayoutGroup.Constraint.FixedRowCount)
{
Debug.LogError("[LoopHorizontalScrollRect] unsupported GridLayoutGroup constraint");
}
}
protected override bool UpdateItems(Bounds viewBounds, Bounds contentBounds)
{
bool changed = false;
// special case: handling move several page in one frame
if (viewBounds.max.x < contentBounds.min.x && itemTypeEnd > itemTypeStart)
{
float currentSize = contentBounds.size.x;
float elementSize = (currentSize - contentSpacing * (CurrentLines - 1)) / CurrentLines;
ReturnToTempPool(false, itemTypeEnd - itemTypeStart);
itemTypeEnd = itemTypeStart;
int offsetCount = Mathf.FloorToInt((contentBounds.min.x - viewBounds.max.x) / (elementSize + contentSpacing));
if (totalCount >= 0 && itemTypeStart - offsetCount * contentConstraintCount < 0)
{
offsetCount = Mathf.FloorToInt((float)(itemTypeStart) / contentConstraintCount);
}
itemTypeStart -= offsetCount * contentConstraintCount;
if (totalCount >= 0)
{
itemTypeStart = Mathf.Max(itemTypeStart, 0);
}
itemTypeEnd = itemTypeStart;
float offset = offsetCount * (elementSize + contentSpacing);
content.anchoredPosition -= new Vector2(offset + (reverseDirection ? currentSize : 0), 0);
contentBounds.center -= new Vector3(offset + currentSize / 2, 0, 0);
contentBounds.size = Vector3.zero;
changed = true;
}
if (viewBounds.min.x > contentBounds.max.x && itemTypeEnd > itemTypeStart)
{
int maxItemTypeStart = -1;
if (totalCount >= 0)
{
maxItemTypeStart = Mathf.Max(0, totalCount - (itemTypeEnd - itemTypeStart));
maxItemTypeStart = (maxItemTypeStart / contentConstraintCount) * contentConstraintCount;
}
float currentSize = contentBounds.size.x;
float elementSize = (currentSize - contentSpacing * (CurrentLines - 1)) / CurrentLines;
ReturnToTempPool(true, itemTypeEnd - itemTypeStart);
// TODO: fix with contentConstraint?
itemTypeStart = itemTypeEnd;
int offsetCount = Mathf.FloorToInt((viewBounds.min.x - contentBounds.max.x) / (elementSize + contentSpacing));
if (maxItemTypeStart >= 0 && itemTypeStart + offsetCount * contentConstraintCount > maxItemTypeStart)
{
offsetCount = Mathf.FloorToInt((float)(maxItemTypeStart - itemTypeStart) / contentConstraintCount);
}
itemTypeStart += offsetCount * contentConstraintCount;
if (totalCount >= 0)
{
itemTypeStart = Mathf.Max(itemTypeStart, 0);
}
itemTypeEnd = itemTypeStart;
float offset = offsetCount * (elementSize + contentSpacing);
content.anchoredPosition += new Vector2(offset + (reverseDirection ? 0 : currentSize), 0);
contentBounds.center += new Vector3(offset + currentSize / 2, 0, 0);
contentBounds.size = Vector3.zero;
changed = true;
}
if (viewBounds.max.x < contentBounds.max.x - threshold - m_ContentRightPadding)
{
float size = DeleteItemAtEnd(), totalSize = size;
while (size > 0 && viewBounds.max.x < contentBounds.max.x - threshold - m_ContentRightPadding - totalSize)
{
size = DeleteItemAtEnd();
totalSize += size;
}
if (totalSize > 0)
changed = true;
}
if (viewBounds.min.x > contentBounds.min.x + threshold + m_ContentLeftPadding)
{
float size = DeleteItemAtStart(), totalSize = size;
while (size > 0 && viewBounds.min.x > contentBounds.min.x + threshold + m_ContentLeftPadding + totalSize)
{
size = DeleteItemAtStart();
totalSize += size;
}
if (totalSize > 0)
changed = true;
}
if (viewBounds.max.x > contentBounds.max.x - m_ContentRightPadding)
{
float size = NewItemAtEnd(), totalSize = size;
while (size > 0 && viewBounds.max.x > contentBounds.max.x - m_ContentRightPadding + totalSize)
{
size = NewItemAtEnd();
totalSize += size;
}
if (totalSize > 0)
changed = true;
}
if (viewBounds.min.x < contentBounds.min.x + m_ContentLeftPadding)
{
float size = NewItemAtStart(), totalSize = size;
while (size > 0 && viewBounds.min.x < contentBounds.min.x + m_ContentLeftPadding - totalSize)
{
size = NewItemAtStart();
totalSize += size;
}
if (totalSize > 0)
changed = true;
}
if (changed)
{
ClearTempPool();
}
return changed;
}
}
}