From f0c617e3efbdcf097e8204d66fa39188db561538 Mon Sep 17 00:00:00 2001 From: AdunFang <30402408+AdunFang@users.noreply.github.com> Date: Wed, 19 Aug 2020 15:45:21 +0800 Subject: [PATCH] [NUI] Fix osv issue (#1919) * [NUI] Fix OSV issue * [NUI] Fix OSV issue of NUI Co-authored-by: Fang Xiaohui --- .../Controls/FlexibleView/FlexibleView.cs | 2 +- .../FlexibleView/FlexibleViewLayoutManager.cs | 49 ++++-------- .../FlexibleView/LinearLayoutManager.Internal.cs | 92 +++++++++++----------- src/Tizen.NUI/src/public/Layouting/LayoutGroup.cs | 5 -- 4 files changed, 63 insertions(+), 85 deletions(-) diff --git a/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleView.cs b/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleView.cs index 5f2df59..139ddeb 100755 --- a/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleView.cs +++ b/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleView.cs @@ -250,7 +250,7 @@ namespace Tizen.NUI.Components } else { - mLayout.RequestChildRectangleOnScreen(this, nextFocusView, mRecycler, true); + mLayout.GetRectOfVisibleChild(this, nextFocusView, mRecycler, true); DispatchFocusChanged(value); } } diff --git a/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleViewLayoutManager.cs b/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleViewLayoutManager.cs index c6bf781..a7b3a01 100755 --- a/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleViewLayoutManager.cs +++ b/src/Tizen.NUI.Components/Controls/FlexibleView/FlexibleViewLayoutManager.cs @@ -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; diff --git a/src/Tizen.NUI.Components/Controls/FlexibleView/LinearLayoutManager.Internal.cs b/src/Tizen.NUI.Components/Controls/FlexibleView/LinearLayoutManager.Internal.cs index 88375d2..8dfaa1e 100755 --- a/src/Tizen.NUI.Components/Controls/FlexibleView/LinearLayoutManager.Internal.cs +++ b/src/Tizen.NUI.Components/Controls/FlexibleView/LinearLayoutManager.Internal.cs @@ -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 diff --git a/src/Tizen.NUI/src/public/Layouting/LayoutGroup.cs b/src/Tizen.NUI/src/public/Layouting/LayoutGroup.cs index a07d29b..901b1eb 100755 --- a/src/Tizen.NUI/src/public/Layouting/LayoutGroup.cs +++ b/src/Tizen.NUI/src/public/Layouting/LayoutGroup.cs @@ -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; } -- 2.7.4