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
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; |
|
} |
|
} |
|
} |