[NUI] Fix osv issue (#1919)
authorAdunFang <30402408+AdunFang@users.noreply.github.com>
Wed, 19 Aug 2020 07:45:21 +0000 (15:45 +0800)
committerGitHub <noreply@github.com>
Wed, 19 Aug 2020 07:45:21 +0000 (16:45 +0900)
* [NUI] Fix OSV issue

* [NUI] Fix OSV issue of NUI

Co-authored-by: Fang Xiaohui <xiaohui fang>
src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleView.cs
src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleViewLayoutManager.cs
src/Tizen.NUI.Components/Controls/FlexibleView/LinearLayoutManager.Internal.cs
src/Tizen.NUI/src/public/Layouting/LayoutGroup.cs

index 5f2df59..139ddeb 100755 (executable)
@@ -250,7 +250,7 @@ namespace Tizen.NUI.Components
                 }
                 else
                 {
-                    mLayout.RequestChildRectangleOnScreen(this, nextFocusView, mRecycler, true);
+                    mLayout.GetRectOfVisibleChild(this, nextFocusView, mRecycler, true);
                     DispatchFocusChanged(value);
                 }
             }
index c6bf781..a7b3a01 100755 (executable)
@@ -209,31 +209,17 @@ namespace Tizen.NUI.Components
 
             if (nextFocusChild != null)
             {
-                RequestChildRectangleOnScreen(mFlexibleView, nextFocusChild, recycler, false);
+                GetRectOfVisibleChild(mFlexibleView, nextFocusChild, recycler, false);
 
                 ChangeFocus(nextFocusPosition);
             }
         }
 
-        /**
-         * Requests that the given child of the FlexibleViewRecyclerView be positioned onto the screen. This
-         * method can be called for both unfocusable and focusable child views. For unfocusable
-         * child views, focusedChildVisible is typically true in which case, layout manager
-         * makes the child view visible only if the currently focused child stays in-bounds of RV.
-         * @param parent The parent FlexibleViewRecyclerView.
-         * @param child The direct child making the request.
-         * @param rect The rectangle in the child's coordinates the child
-         *              wishes to be on the screen.
-         * @param immediate True to forbid animated or delayed scrolling,
-         *                  false otherwise
-         * @param focusedChildVisible Whether the currently focused view must stay visible.
-         * @return Whether the group scrolled to handle the operation
-         */
-        internal bool RequestChildRectangleOnScreen(FlexibleView parent, FlexibleViewViewHolder child, FlexibleViewRecycler recycler, bool immediate)
+        internal bool GetRectOfVisibleChild(FlexibleView parent, FlexibleViewViewHolder child, FlexibleViewRecycler recycler, bool immediate)
         {
-            Vector2 scrollAmount = GetChildRectangleOnScreenScrollAmount(parent, child);
-            float dx = scrollAmount[0];
-            float dy = scrollAmount[1];
+            Vector2 amounts = GetRectOfVisibleChildScrollAmount(parent, child);
+            float dx = amounts[0];
+            float dy = amounts[1];
             if (dx != 0 || dy != 0)
             {
                 if (dx != 0 && CanScrollHorizontally())
@@ -771,7 +757,7 @@ namespace Tizen.NUI.Components
          * @return The array containing the scroll amount in x and y directions that brings the
          * given rect into RV's padded area.
          */
-        private Vector2 GetChildRectangleOnScreenScrollAmount(FlexibleView parent, FlexibleViewViewHolder child)
+        private Vector2 GetRectOfVisibleChildScrollAmount(FlexibleView parent, FlexibleViewViewHolder child)
         {
             Vector2 ret = new Vector2(0, 0);
             int parentLeft = PaddingLeft;
@@ -783,21 +769,14 @@ namespace Tizen.NUI.Components
             int childRight = (int)child.Right;
             int childBottom = (int)child.Bottom;
 
-            int offScreenLeft = Math.Min(0, childLeft - parentLeft);
-            int offScreenTop = Math.Min(0, childTop - parentTop);
-            int offScreenRight = Math.Max(0, childRight - parentRight);
-            int offScreenBottom = Math.Max(0, childBottom - parentBottom);
-
-            // Favor the "start" layout direction over the end when bringing one side or the other
-            // of a large rect into view. If we decide to bring in end because start is already
-            // visible, limit the scroll such that start won't go out of bounds.
-            int dx = offScreenLeft != 0 ? offScreenLeft
-                        : Math.Min(childLeft - parentLeft, offScreenRight);
-
-            // Favor bringing the top into view over the bottom. If top is already visible and
-            // we should scroll to make bottom visible, make sure top does not go out of bounds.
-            int dy = offScreenTop != 0 ? offScreenTop
-                    : Math.Min(childTop - parentTop, offScreenBottom);
+            Extents offset = new Extents((ushort)Math.Min(0, childLeft - parentLeft),
+                                         (ushort)Math.Max(0, childRight - parentRight),
+                                         (ushort)Math.Min(0, childTop - parentTop),
+                                         (ushort)Math.Max(0, childBottom - parentBottom));
+
+            int dx = offset.Start != 0 ? offset.Start : Math.Min(childLeft - parentLeft, offset.End);
+
+            int dy = offset.Top != 0 ? offset.Top : Math.Min(childTop - parentTop, offset.Bottom);
 
             ret.X = -dx;
             ret.Y = -dy;
index 88375d2..8dfaa1e 100755 (executable)
@@ -72,7 +72,7 @@ namespace Tizen.NUI.Components
                 return null;
             }
             int maxScroll = (int)(MAX_SCROLL_FACTOR * mOrientationHelper.GetTotalSpace());
-            UpdateLayoutState(layoutDir, maxScroll, false);
+            UpdateLayout(layoutDir, maxScroll, false);
             mLayoutState.ScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN;
             mLayoutState.Recycle = false;
             Fill(recycler, mLayoutState, true, true);
@@ -396,7 +396,7 @@ namespace Tizen.NUI.Components
             int layoutDirection = dy < 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START;
             float absDy = Math.Abs(dy);
 
-            UpdateLayoutState(layoutDirection, absDy, true);
+            UpdateLayout(layoutDirection, absDy, true);
 
             float consumed = mLayoutState.ScrollingOffset
                 + Fill(recycler, mLayoutState, false, immediate);
@@ -414,49 +414,9 @@ namespace Tizen.NUI.Components
             return scrolled;
         }
 
-        private void UpdateLayoutState(int layoutDirection, float requiredSpace, bool canUseExistingSpace)
+        private void UpdateLayout(int direction, float space, bool canUseExistingSpace)
         {
-            mLayoutState.Extra = 0;
-            mLayoutState.LayoutDirection = layoutDirection;
-            float scrollingOffset = 0.0f;
-            if (layoutDirection == LayoutState.LAYOUT_END)
-            {
-                mLayoutState.Extra += mOrientationHelper.GetEndPadding();
-                // get the first child in the direction we are going
-                FlexibleViewViewHolder child = GetChildClosestToEnd();
-                if (child != null)
-                {
-                    // the direction in which we are traversing children
-                    mLayoutState.ItemDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_HEAD
-                            : LayoutState.ITEM_DIRECTION_TAIL;
-                    mLayoutState.CurrentPosition = child.LayoutPosition + mLayoutState.ItemDirection;
-                    mLayoutState.Offset = mOrientationHelper.GetViewHolderEnd(child);
-                    // calculate how much we can scroll without adding new children (independent of layout)
-                    scrollingOffset = mOrientationHelper.GetViewHolderEnd(child)
-                            - mOrientationHelper.GetEndAfterPadding();
-                }
-
-            }
-            else
-            {
-                mLayoutState.Extra += mOrientationHelper.GetStartAfterPadding();
-                FlexibleViewViewHolder child = GetChildClosestToStart();
-                if (child != null)
-                {
-                    mLayoutState.ItemDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_TAIL
-                            : LayoutState.ITEM_DIRECTION_HEAD;
-                    mLayoutState.CurrentPosition = child.LayoutPosition + mLayoutState.ItemDirection;
-                    mLayoutState.Offset = mOrientationHelper.GetViewHolderStart(child);
-                    scrollingOffset = -mOrientationHelper.GetViewHolderStart(child)
-                            + mOrientationHelper.GetStartAfterPadding();
-                }
-            }
-            mLayoutState.Available = requiredSpace;
-            if (canUseExistingSpace)
-            {
-                mLayoutState.Available -= scrollingOffset;
-            }
-            mLayoutState.ScrollingOffset = scrollingOffset;
+            mLayoutState.ResetLayout(direction, canUseExistingSpace, space, mOrientationHelper, this);
         }
 
         // Convenience method to find the child closes to start. Caller should check it has enough
@@ -622,6 +582,50 @@ namespace Tizen.NUI.Components
 
                 return itemView;
             }
+
+            public void ResetLayout(int direction, bool canUseExistingSpace, float space, OrientationHelper orientationHelper, LinearLayoutManager linearLayoutManager)
+            {
+                this.Extra = 0;
+                this.LayoutDirection = direction;
+
+                float scrollingOffset = 0.0f;
+                if (direction == LayoutState.LAYOUT_END)
+                {
+                    this.Extra += orientationHelper.GetEndPadding();
+                    FlexibleViewViewHolder endChild = linearLayoutManager.GetChildClosestToEnd();
+                    if (endChild != null)
+                    {
+                        // the direction in which we are traversing children
+                        this.ItemDirection = linearLayoutManager.mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_HEAD
+                                : LayoutState.ITEM_DIRECTION_TAIL;
+                        this.CurrentPosition = endChild.LayoutPosition + linearLayoutManager.mLayoutState.ItemDirection;
+                        this.Offset = orientationHelper.GetViewHolderEnd(endChild);
+                        scrollingOffset = orientationHelper.GetViewHolderEnd(endChild) - orientationHelper.GetEndAfterPadding();
+                    }
+
+                }
+                else
+                {
+                    this.Extra += orientationHelper.GetStartAfterPadding();
+                    FlexibleViewViewHolder startChild = linearLayoutManager.GetChildClosestToStart();
+                    if (startChild != null)
+                    {
+                        this.ItemDirection = linearLayoutManager.mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_TAIL
+                                : LayoutState.ITEM_DIRECTION_HEAD;
+                        this.CurrentPosition = startChild.LayoutPosition + linearLayoutManager.mLayoutState.ItemDirection;
+                        this.Offset = orientationHelper.GetViewHolderStart(startChild);
+                        scrollingOffset = -orientationHelper.GetViewHolderStart(startChild) + orientationHelper.GetStartAfterPadding();
+                    }
+                }
+
+                this.Available = space;
+
+                if (canUseExistingSpace)
+                {
+                    this.Available -= scrollingOffset;
+                }
+                this.ScrollingOffset = scrollingOffset;
+            }
         }
 
         internal class LayoutChunkResult
index a07d29b..901b1eb 100755 (executable)
@@ -278,19 +278,14 @@ namespace Tizen.NUI
                 {
                     if ((int)childDimension.AsRoundedValue() == LayoutParamPolicies.MatchParent)
                     {
-                        // Child wants to be our size. So be it.
                         resultMode = MeasureSpecification.ModeType.Exactly;
                     }
                     else if ((int)childDimension.AsRoundedValue() == LayoutParamPolicies.WrapContent)
                     {
-                        // Child wants to determine its own size. It can't be
-                        // bigger than us.
-                        // Don't need parent's size. Size of this child will be determined by its children.
                         resultMode = MeasureSpecification.ModeType.AtMost;
                     }
                     else
                     {
-                        // Child has its own size.
                         resultSize = childDimension;
                         resultMode = MeasureSpecification.ModeType.Exactly;
                     }