[NUI] Optimizing item positioning on MeasureFirst (#2895)
authorSangHyeon Jade Lee <sh10233.lee@samsung.com>
Tue, 13 Apr 2021 10:59:31 +0000 (19:59 +0900)
committerhuiyueun <35286162+huiyueun@users.noreply.github.com>
Tue, 20 Apr 2021 06:13:00 +0000 (15:13 +0900)
* [NUI] Optimizing item positioning on MeasureFirst

using List<T> Data Structure is redundant in MeasureFirst case,
and it makes worse sometimes for searching indexed item's position.
In MeasureFirst, every item has same size,
thus we can calculate it's position in linear or grouped cases.

src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/LinearLayouter.cs

index 1f0196f..cf651a2 100755 (executable)
@@ -293,7 +293,8 @@ namespace Tizen.NUI.Components
                                 GroupSize = groupHeaderSize,
                                 GroupPosition = Current
                             };
-                            currentGroup.ItemPosition.Add(0);
+                            if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                                currentGroup.ItemPosition.Add(0);
                             groups.Add(currentGroup);
                             Current += groupHeaderSize;
                         }
@@ -303,21 +304,24 @@ namespace Tizen.NUI.Components
                             //currentGroup.hasFooter = true;
                             currentGroup.Count++;
                             currentGroup.GroupSize += groupFooterSize;
-                            currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
+                            if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                                currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
                             Current += groupFooterSize;
                         }
                         else
                         {
                             currentGroup.Count++;
                             currentGroup.GroupSize += StepCandidate;
-                            currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
+                            if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                                currentGroup.ItemPosition.Add(Current - currentGroup.GroupPosition);
                             Current += StepCandidate;
                         }
                     }
                 }
                 else
                 {
-                    ItemPosition.Add(Current);
+                    if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                        ItemPosition.Add(Current);
 
                     if (i == 0 && hasHeader) Current += headerSize;
                     else if (i == count - 1 && hasFooter) Current += footerSize;
@@ -329,7 +333,6 @@ namespace Tizen.NUI.Components
             if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
             else colView.ContentContainer.SizeHeight = ScrollContentSize;
 
-
             base.Initialize(view);
             //Console.WriteLine("[NUI] Init Done, StepCnadidate{0}, Scroll{1}", StepCandidate, ScrollContentSize);
         }
@@ -353,7 +356,8 @@ namespace Tizen.NUI.Components
             {
                 for (int i = ItemSizeChanged; i <= LastIndex; i++)
                     UpdatePosition(i);
-                ScrollContentSize = ItemPosition[LastIndex - 1] + GetItemStepSize(LastIndex) + (IsHorizontal? Padding.End : Padding.Bottom);
+                (float updateX, float updateY) = GetItemPosition(LastIndex);
+                ScrollContentSize = GetItemStepSize(LastIndex) + (IsHorizontal? updateX + Padding.End : updateY + Padding.Bottom);
             }
 
             int prevFirstVisible = FirstVisible;
@@ -395,40 +399,7 @@ namespace Tizen.NUI.Components
                 VisibleItems.Add(item);
 
                 // 5. Placing item.
-                float posX = 0F, posY = 0F;
-                int spaceStartX = Padding.Start + item.Margin.Start;
-                int spaceStartY = Padding.Top + item.Margin.Top;
-
-                if (isGrouped)
-                {
-                    //isHeader?
-                    if (colView.Header == item)
-                    {
-                        posX = spaceStartX;
-                        posY = spaceStartY;
-                    }
-                    else if (colView.Footer == item)
-                    {
-                        posX = (IsHorizontal? ScrollContentSize - footerSize - Padding.End + footerMargin.Start : spaceStartX);
-                        posY = (IsHorizontal? spaceStartY : ScrollContentSize - footerSize - Padding.Bottom - footerMargin.Top);
-                    }
-                    else
-                    {
-                        GroupInfo gInfo = GetGroupInfo(i);
-                        posX = (IsHorizontal?
-                                item.Margin.Start + gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex]:
-                                spaceStartX);
-                        posY = (IsHorizontal?
-                                spaceStartY:
-                                item.Margin.Top + gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex]);
-                    }
-                }
-                else
-                {
-                    posX = (IsHorizontal? ItemPosition[i] + item.Margin.Start : spaceStartX);
-                    posY = (IsHorizontal? spaceStartY : ItemPosition[i] + item.Margin.Top);
-                }
-
+                (float posX, float posY) = GetItemPosition(i);
                 item.Position = new Position(posX, posY);
             
                 if (IsHorizontal && item.HeightSpecification == LayoutParamPolicies.MatchParent)
@@ -579,8 +550,8 @@ namespace Tizen.NUI.Components
                                     break;
 
                                 }
-                                else if (gInfo.ItemPosition[i] <= visibleArea.X - gInfo.GroupPosition &&
-                                        gInfo.ItemPosition[i + 1] >= visibleArea.X - gInfo.GroupPosition)
+                                else if (GetGroupPosition(gInfo, gInfo.StartIndex + i) <= visibleArea.X &&
+                                        GetGroupPosition(gInfo, gInfo.StartIndex + i + 1) >= visibleArea.X)
                                 {
                                     found.start = gInfo.StartIndex + i - adds;
                                     failed = false;
@@ -631,8 +602,8 @@ namespace Tizen.NUI.Components
                                     break;
 
                                 }
-                                else if (gInfo.ItemPosition[i] <= visibleArea.Y - gInfo.GroupPosition &&
-                                        gInfo.ItemPosition[i + 1] >= visibleArea.Y - gInfo.GroupPosition)
+                                else if (GetGroupPosition(gInfo, gInfo.StartIndex + i) <= visibleArea.Y &&
+                                        GetGroupPosition(gInfo, gInfo.StartIndex + i + 1) >= visibleArea.Y)
                                 {
                                     found.end = gInfo.StartIndex + i + adds;
                                     failed = false;
@@ -671,18 +642,38 @@ namespace Tizen.NUI.Components
             else if (isGrouped)
             {
                 GroupInfo gInfo = GetGroupInfo(index);
+                float current = GetGroupPosition(gInfo, index);
+                Extents itemMargin = CandidateMargin;
+
+                if (colView.InternalItemSource.IsGroupHeader(index))
+                {
+                    itemMargin = groupHeaderMargin;
+                }
+                else if (colView.InternalItemSource.IsGroupFooter(index))
+                {
+                    itemMargin = groupFooterMargin;
+                }
                 return ((IsHorizontal?
-                            CandidateMargin.Start + gInfo.GroupPosition + gInfo.ItemPosition[index - gInfo.StartIndex]:
-                            spaceStartX),
+                        itemMargin.Start + GetGroupPosition(gInfo, index):
+                        spaceStartX + itemMargin.Start),
                         (IsHorizontal?
-                            spaceStartY:
-                            CandidateMargin.Top + gInfo.GroupPosition + gInfo.ItemPosition[index - gInfo.StartIndex]));
+                        spaceStartY + itemMargin.Top:
+                        itemMargin.Top + GetGroupPosition(gInfo, index)));
             }
-            else
+            else if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
             {
+                //FIXME : CandidateMargin need to be actual itemMargin
                 return ((IsHorizontal? ItemPosition[index] + CandidateMargin.Start : spaceStartX + CandidateMargin.Start),
                         (IsHorizontal? spaceStartY + CandidateMargin.Top : ItemPosition[index] + CandidateMargin.Top));
             }
+            else
+            {
+                int adjustIndex = index - (hasHeader ? 1 : 0);
+                float current = (hasHeader? headerSize : 0) + adjustIndex * StepCandidate;
+                //FIXME : CandidateMargin need to be actual itemMargin
+                return ((IsHorizontal? current + CandidateMargin.Start : spaceStartX + CandidateMargin.Start),
+                        (IsHorizontal? spaceStartY + CandidateMargin.Top : current + CandidateMargin.Top));
+            }
         }
 
         // Item size excluding margins. this size is approximated size.
@@ -759,8 +750,8 @@ namespace Tizen.NUI.Components
                     //IsGroupFooter = (colView.InternalItemSource as IGroupableItemSource).IsGroupFooter(index);
                     //Do Something
                 }
-
-            ItemPosition[index] = ItemPosition[index - 1] + GetItemStepSize(index - 1);
+            if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                ItemPosition[index] = ItemPosition[index - 1] + GetItemStepSize(index - 1);
         }
 
         private RecyclerViewItem GetVisibleItem(int index)
@@ -791,6 +782,21 @@ namespace Tizen.NUI.Components
             Visited = null;
             return null;
         }
+
+        private float GetGroupPosition(GroupInfo groupInfo, int index)
+        {
+            if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
+                return groupInfo.GroupPosition + groupInfo.ItemPosition[index - groupInfo.StartIndex];
+            else
+            {
+                float pos = groupInfo.GroupPosition;
+                if (groupInfo.StartIndex == index) return pos;
+
+                pos = pos + groupHeaderSize + StepCandidate * (index - groupInfo.StartIndex - 1);
+
+                return pos;
+            }
+        }
         /*
                 private object GetGroupParent(int index)
                 {
@@ -819,7 +825,7 @@ namespace Tizen.NUI.Components
             public int Count;
             public float GroupSize;
             public float GroupPosition;
-            //Items relative position from the GroupPosition
+            //Items relative position from the GroupPosition. Only use for MeasureAll.
             public List<float> ItemPosition = new List<float>();
         }
     }