| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- using System;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- using UnityEngine.EventSystems;
- namespace SuperScrollView
- {
- public class ItemSizeGroup
- {
- public float[] mItemSizeArray = null;
- public float[] mItemStartPosArray = null;
- public int mItemCount = 0;
- int mDirtyBeginIndex = ItemPosMgr.mItemMaxCountPerGroup;
- public float mGroupSize = 0;
- public float mGroupStartPos = 0;
- public float mGroupEndPos = 0;
- public int mGroupIndex = 0;
- float mItemDefaultSize = 0;
- int mMaxNoZeroIndex = 0;
- public ItemSizeGroup(int index,float itemDefaultSize)
- {
- mGroupIndex = index;
- mItemDefaultSize = itemDefaultSize;
- Init();
- }
- public void Init()
- {
- mItemSizeArray = new float[ItemPosMgr.mItemMaxCountPerGroup];
- if (mItemDefaultSize != 0)
- {
- for (int i = 0; i < mItemSizeArray.Length; ++i)
- {
- mItemSizeArray[i] = mItemDefaultSize;
- }
- }
- mItemStartPosArray = new float[ItemPosMgr.mItemMaxCountPerGroup];
- mItemStartPosArray[0] = 0;
- mItemCount = ItemPosMgr.mItemMaxCountPerGroup;
- mGroupSize = mItemDefaultSize * mItemSizeArray.Length;
- if (mItemDefaultSize != 0)
- {
- mDirtyBeginIndex = 0;
- }
- else
- {
- mDirtyBeginIndex = ItemPosMgr.mItemMaxCountPerGroup;
- }
- }
- public float GetItemStartPos(int index)
- {
- return mGroupStartPos + mItemStartPosArray[index];
- }
- public bool IsDirty
- {
- get
- {
- return (mDirtyBeginIndex < mItemCount);
- }
- }
- public float SetItemSize(int index, float size)
- {
- if(index > mMaxNoZeroIndex && size > 0)
- {
- mMaxNoZeroIndex = index;
- }
- float old = mItemSizeArray[index];
- if (old == size)
- {
- return 0;
- }
- mItemSizeArray[index] = size;
- if (index < mDirtyBeginIndex)
- {
- mDirtyBeginIndex = index;
- }
- float ds = size - old;
- mGroupSize = mGroupSize + ds;
- return ds;
- }
- public void SetItemCount(int count)
- {
- if(count < mMaxNoZeroIndex)
- {
- mMaxNoZeroIndex = count;
- }
- if (mItemCount == count)
- {
- return;
- }
- mItemCount = count;
- RecalcGroupSize();
- }
- public void RecalcGroupSize()
- {
- mGroupSize = 0;
- for (int i = 0; i < mItemCount; ++i)
- {
- mGroupSize += mItemSizeArray[i];
- }
- }
- public int GetItemIndexByPos(float pos)
- {
- if (mItemCount == 0)
- {
- return -1;
- }
-
- int low = 0;
- int high = mItemCount - 1;
- if (mItemDefaultSize == 0f)
- {
- if(mMaxNoZeroIndex < 0)
- {
- mMaxNoZeroIndex = 0;
- }
- high = mMaxNoZeroIndex;
- }
- while (low <= high)
- {
- int mid = (low + high) / 2;
- float startPos = mItemStartPosArray[mid];
- float endPos = startPos + mItemSizeArray[mid];
- if (startPos <= pos && endPos >= pos)
- {
- return mid;
- }
- else if (pos > endPos)
- {
- low = mid + 1;
- }
- else
- {
- high = mid - 1;
- }
- }
- return -1;
- }
- public void UpdateAllItemStartPos()
- {
- if (mDirtyBeginIndex >= mItemCount)
- {
- return;
- }
- int startIndex = (mDirtyBeginIndex < 1) ? 1 : mDirtyBeginIndex;
- for (int i = startIndex; i < mItemCount; ++i)
- {
- mItemStartPosArray[i] = mItemStartPosArray[i - 1] + mItemSizeArray[i - 1];
- }
- mDirtyBeginIndex = mItemCount;
- }
- public void ClearOldData()
- {
- for (int i = mItemCount; i < ItemPosMgr.mItemMaxCountPerGroup; ++i)
- {
- mItemSizeArray[i] = 0;
- }
- }
- }
- public class ItemPosMgr
- {
- public const int mItemMaxCountPerGroup = 100;
- List<ItemSizeGroup> mItemSizeGroupList = new List<ItemSizeGroup>();
- int mDirtyBeginIndex = int.MaxValue;
- public float mTotalSize = 0;
- public float mItemDefaultSize = 20;
- int mMaxNotEmptyGroupIndex = 0;
- public ItemPosMgr(float itemDefaultSize)
- {
- mItemDefaultSize = itemDefaultSize;
- }
- public void SetItemMaxCount(int maxCount)
- {
- mDirtyBeginIndex = 0;
- mTotalSize = 0;
- int st = maxCount % mItemMaxCountPerGroup;
- int lastGroupItemCount = st;
- int needMaxGroupCount = maxCount / mItemMaxCountPerGroup;
- if (st > 0)
- {
- needMaxGroupCount++;
- }
- else
- {
- lastGroupItemCount = mItemMaxCountPerGroup;
- }
- int count = mItemSizeGroupList.Count;
- if (count > needMaxGroupCount)
- {
- int d = count - needMaxGroupCount;
- mItemSizeGroupList.RemoveRange(needMaxGroupCount, d);
- }
- else if (count < needMaxGroupCount)
- {
- if(count > 0)
- {
- mItemSizeGroupList[count - 1].ClearOldData();
- }
- int d = needMaxGroupCount - count;
- for (int i = 0; i < d; ++i)
- {
- ItemSizeGroup tGroup = new ItemSizeGroup(count + i, mItemDefaultSize);
- mItemSizeGroupList.Add(tGroup);
- }
- }
- else
- {
- if (count > 0)
- {
- mItemSizeGroupList[count - 1].ClearOldData();
- }
- }
- count = mItemSizeGroupList.Count;
- if((count-1) < mMaxNotEmptyGroupIndex)
- {
- mMaxNotEmptyGroupIndex = count - 1;
- }
- if(mMaxNotEmptyGroupIndex < 0)
- {
- mMaxNotEmptyGroupIndex = 0;
- }
- if (count == 0)
- {
- return;
- }
- for (int i = 0; i < count - 1; ++i)
- {
- mItemSizeGroupList[i].SetItemCount(mItemMaxCountPerGroup);
- }
- mItemSizeGroupList[count - 1].SetItemCount(lastGroupItemCount);
- for (int i = 0; i < count; ++i)
- {
- mTotalSize = mTotalSize + mItemSizeGroupList[i].mGroupSize;
- }
- }
- public void SetItemSize(int itemIndex, float size)
- {
- int groupIndex = itemIndex / mItemMaxCountPerGroup;
- int indexInGroup = itemIndex % mItemMaxCountPerGroup;
- ItemSizeGroup tGroup = mItemSizeGroupList[groupIndex];
- float changedSize = tGroup.SetItemSize(indexInGroup, size);
- if (changedSize != 0f)
- {
- if (groupIndex < mDirtyBeginIndex)
- {
- mDirtyBeginIndex = groupIndex;
- }
- }
- mTotalSize += changedSize;
- if(groupIndex > mMaxNotEmptyGroupIndex && size > 0)
- {
- mMaxNotEmptyGroupIndex = groupIndex;
- }
- }
- public float GetItemPos(int itemIndex)
- {
- Update(true);
- int groupIndex = itemIndex / mItemMaxCountPerGroup;
- int indexInGroup = itemIndex % mItemMaxCountPerGroup;
- return mItemSizeGroupList[groupIndex].GetItemStartPos(indexInGroup);
- }
- public bool GetItemIndexAndPosAtGivenPos(float pos, ref int index, ref float itemPos)
- {
- Update(true);
- index = 0;
- itemPos = 0f;
- int count = mItemSizeGroupList.Count;
- if (count == 0)
- {
- return true;
- }
- ItemSizeGroup hitGroup = null;
- int low = 0;
- int high = count - 1;
- if (mItemDefaultSize == 0f)
- {
- if(mMaxNotEmptyGroupIndex < 0)
- {
- mMaxNotEmptyGroupIndex = 0;
- }
- high = mMaxNotEmptyGroupIndex;
- }
- while (low <= high)
- {
- int mid = (low + high) / 2;
- ItemSizeGroup tGroup = mItemSizeGroupList[mid];
- if (tGroup.mGroupStartPos <= pos && tGroup.mGroupEndPos >= pos)
- {
- hitGroup = tGroup;
- break;
- }
- else if (pos > tGroup.mGroupEndPos)
- {
- low = mid + 1;
- }
- else
- {
- high = mid - 1;
- }
- }
- int hitIndex = -1;
- if (hitGroup != null)
- {
- hitIndex = hitGroup.GetItemIndexByPos(pos - hitGroup.mGroupStartPos);
- }
- else
- {
- return false;
- }
- if (hitIndex < 0)
- {
- return false;
- }
- index = hitIndex + hitGroup.mGroupIndex * mItemMaxCountPerGroup;
- itemPos = hitGroup.GetItemStartPos(hitIndex);
- return true;
- }
- public void Update(bool updateAll)
- {
- int count = mItemSizeGroupList.Count;
- if (count == 0)
- {
- return;
- }
- if (mDirtyBeginIndex >= count)
- {
- return;
- }
- int loopCount = 0;
- for (int i = mDirtyBeginIndex; i < count; ++i)
- {
- loopCount++;
- ItemSizeGroup tGroup = mItemSizeGroupList[i];
- mDirtyBeginIndex++;
- tGroup.UpdateAllItemStartPos();
- if (i == 0)
- {
- tGroup.mGroupStartPos = 0;
- tGroup.mGroupEndPos = tGroup.mGroupSize;
- }
- else
- {
- tGroup.mGroupStartPos = mItemSizeGroupList[i - 1].mGroupEndPos;
- tGroup.mGroupEndPos = tGroup.mGroupStartPos + tGroup.mGroupSize;
- }
- if (!updateAll && loopCount > 1)
- {
- return;
- }
- }
- }
- }
- }
|