1 /* Copyright (c) 2020 Samsung Electronics Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
17 using Tizen.NUI.BaseComponents;
18 using System.Collections.Generic;
19 using System.ComponentModel;
21 namespace Tizen.NUI.Components
24 /// [Draft] This class implements a grid box layout.
26 /// <since_tizen> 8 </since_tizen>
27 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
28 [EditorBrowsable(EditorBrowsableState.Never)]
29 public class GridRecycleLayoutManager : RecycleLayoutManager
34 /// [draft ]Get/Set the number of rows in the grid
36 /// <since_tizen> 8 </since_tizen>
37 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
38 [EditorBrowsable(EditorBrowsableState.Never)]
49 if (Container != null)
51 Layout(PrevScrollPosition);
56 private int columns = 1;
60 /// [Draft] Get/Set the number of columns in the grid
62 /// <since_tizen> 8 </since_tizen>
63 // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
64 [EditorBrowsable(EditorBrowsableState.Never)]
75 if (Container != null)
77 Layout(PrevScrollPosition);
82 private int firstVisibleItemIndex = -1;
83 private int lastVisibleItemIndex = -1;
85 private bool IsItemVisible(float scrollPosition, RecycleItem item)
88 View list = Container.GetParent() as View;
90 Vector2 visibleArea = new Vector2(Math.Abs(scrollPosition),
91 Math.Abs(scrollPosition) + (LayoutOrientation == Orientation.Horizontal ?
92 list.Size.Width : list.Size.Height)
95 float firstCheckPoint = LayoutOrientation == Orientation.Horizontal ? item.Position.X : item.Position.Y;
96 float secondCheckPoint = LayoutOrientation == Orientation.Horizontal ?
97 firstCheckPoint + item.Size.Width :
98 firstCheckPoint + item.Size.Height;
100 result = (firstCheckPoint >= visibleArea.X && firstCheckPoint <= visibleArea.Y) || (secondCheckPoint >= visibleArea.X && secondCheckPoint <= visibleArea.Y);
106 /// This is called to find out how much container size can be.
108 /// <since_tizen> 8 </since_tizen>
109 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
110 [EditorBrowsable(EditorBrowsableState.Never)]
111 public override float CalculateLayoutOrientationSize()
113 float orientationFactor = LayoutOrientation == Orientation.Horizontal ? Rows : Columns;
114 return StepSize * (int)Math.Ceiling((double)DataCount / (double)orientationFactor);
119 /// This is called to find out where items are lain out according to current scroll position.
121 /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
122 /// <since_tizen> 8 </since_tizen>
123 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
124 public override void Layout(float scrollPosition)
126 int itemInGroup = LayoutOrientation == Orientation.Horizontal ? Rows : Columns;
127 firstVisibleItemIndex = -1;
128 lastVisibleItemIndex = -1;
130 RecycleItem previousItem = null;
132 for (int i = 0; i < Container.Children.Count; i++)
134 RecycleItem item = Container.Children[i] as RecycleItem;
136 if (previousItem != null)
138 item.Position = LayoutOrientation == Orientation.Horizontal ?
140 (i % itemInGroup == 0 ?
141 previousItem.Position.X + (previousItem.CurrentSize.Width != 0 ?
142 previousItem.CurrentSize.Width :
143 previousItem.Size.Width) :
144 previousItem.Position.X),
145 (i % itemInGroup == 0 ?
147 previousItem.PositionY + (previousItem.CurrentSize.Height != 0 ?
148 previousItem.CurrentSize.Height :
149 previousItem.Size.Height))
152 (i % itemInGroup == 0 ?
154 previousItem.PositionX + (previousItem.CurrentSize.Width != 0 ?
155 previousItem.CurrentSize.Width :
156 previousItem.Size.Width)),
157 (i % itemInGroup == 0 ?
158 previousItem.Position.Y + (previousItem.CurrentSize.Height != 0 ?
159 previousItem.CurrentSize.Height :
160 previousItem.Size.Height) :
161 previousItem.Position.Y)
165 bool isVisible = IsItemVisible(scrollPosition, item);
169 firstVisibleItemIndex = firstVisibleItemIndex == -1 ? i : firstVisibleItemIndex;
170 lastVisibleItemIndex = i;
178 StepSize = LayoutOrientation == Orientation.Horizontal ? ItemSize.Width : ItemSize.Height;
184 /// This is called to find out which items should be recycled according to current scroll position.
186 /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
187 /// <returns>List of RecycleItems which should be recycled.</returns>
188 /// <since_tizen> 8 </since_tizen>
189 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
190 public override List<RecycleItem> Recycle(float scrollPosition)
192 List<RecycleItem> result = new List<RecycleItem>();
193 bool checkFront = (PrevScrollPosition - scrollPosition) > 0;
195 int itemInGroup = LayoutOrientation == Orientation.Horizontal ? Rows : Columns;
199 int currentGroupNum = (int)(firstVisibleItemIndex / itemInGroup) + 1;
201 if (currentGroupNum > 2)
203 // Too many item is in front!!! move first item to back!!!!
204 for (int i = 0; i < itemInGroup; i++)
206 RecycleItem target = Container.Children[0] as RecycleItem;
207 target.DataIndex = target.DataIndex + Container.Children.Count;
208 target.SiblingOrder = Container.Children.Count - 1;
216 int currentGroupNum = (int)(lastVisibleItemIndex / itemInGroup) + 1;
218 if (currentGroupNum < (int)(Container.Children.Count / itemInGroup) - 3)
220 for (int i = 0; i < itemInGroup; i++)
222 RecycleItem prevFirstItem = Container.Children[itemInGroup] as RecycleItem;
224 RecycleItem target = Container.Children[Container.Children.Count - 1] as RecycleItem;
225 target.Position = new Position(
226 LayoutOrientation == Orientation.Horizontal ? (prevFirstItem.Position.X - target.Size.Width) : prevFirstItem.Position.X,
227 LayoutOrientation == Orientation.Horizontal ? prevFirstItem.Position.Y : (prevFirstItem.Position.Y - target.Size.Height)
229 target.DataIndex = target.DataIndex - Container.Children.Count;
230 target.SiblingOrder = 0;
238 PrevScrollPosition = scrollPosition;
244 /// Adjust scrolling position by own scrolling rules.
246 /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
247 /// <since_tizen> 8 </since_tizen>
248 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
249 public override float CalculateCandidateScrollPosition(float scrollPosition)
251 return scrollPosition;