[NUI] Sync with dalihub (#969)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.CommonUI / Controls / FlexibleView / OrientationHelper.cs
1 /*
2  * Copyright(c) 2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 using System;
18
19 namespace Tizen.NUI.CommonUI
20 {
21     /**
22     * Helper class for LayoutManagers to abstract measurements depending on the View's orientation.
23     * It is developed to easily support vertical and horizontal orientations in a LayoutManager but
24     * can also be used to abstract calls around view bounds and child measurements with margins and
25     * decorations.
26     *
27     * @see #createHorizontalHelper(RecyclerView.LayoutManager)
28     * @see #createVerticalHelper(RecyclerView.LayoutManager)
29     */
30     internal abstract class OrientationHelper
31     {
32         public static readonly int HORIZONTAL = 0;
33         public static readonly int VERTICAL = 1;
34
35         private static readonly int INVALID_SIZE = -1;
36
37         protected FlexibleView.LayoutManager mLayoutManager;
38
39         private float mLastTotalSpace = INVALID_SIZE;
40
41         public OrientationHelper(FlexibleView.LayoutManager layoutManager)
42         {
43             mLayoutManager = layoutManager;
44         }
45
46         /**
47          * Call this method after onLayout method is complete if state is NOT pre-layout.
48          * This method records information like layout bounds that might be useful in the next layout
49          * calculations.
50          */
51         public void OnLayoutComplete()
52         {
53             mLastTotalSpace = GetTotalSpace();
54         }
55
56         /**
57          * Returns the layout space change between the previous layout pass and current layout pass.
58          * Make sure you call {@link #onLayoutComplete()} at the end of your LayoutManager's
59          * {@link RecyclerView.LayoutManager#onLayoutChildren(RecyclerView.Recycler,
60          * RecyclerView.State)} method.
61          *
62          * @return The difference between the current total space and previous layout's total space.
63          * @see #onLayoutComplete()
64          */
65         public float GetTotalSpaceChange()
66         {
67             return INVALID_SIZE == mLastTotalSpace ? 0 : GetTotalSpace() - mLastTotalSpace;
68         }
69
70         /**
71          * Returns the start of the view including its decoration and margin.
72          * For example, for the horizontal helper, if a View's left is at pixel 20, has 2px left
73          * decoration and 3px left margin, returned value will be 15px.
74          *
75          * @param view The view element to check
76          * @return The first pixel of the element
77          * @see #getDecoratedEnd(android.view.View)
78          */
79         public abstract float GetViewHolderStart(FlexibleView.ViewHolder holder);
80
81         /**
82          * Returns the end of the view including its decoration and margin.
83          * For example, for the horizontal helper, if a View's right is at pixel 200, has 2px right
84          * decoration and 3px right margin, returned value will be 205.
85          *
86          * @param view The view element to check
87          * @return The last pixel of the element
88          * @see #getDecoratedStart(android.view.View)
89          */
90         public abstract float GetViewHolderEnd(FlexibleView.ViewHolder holder);
91
92         /**
93          * Returns the space occupied by this View in the current orientation including decorations and
94          * margins.
95          *
96          * @param view The view element to check
97          * @return Total space occupied by this view
98          * @see #getDecoratedMeasurementInOther(View)
99          */
100         public abstract float GetViewHolderMeasurement(FlexibleView.ViewHolder holder);
101
102         /**
103          * Returns the space occupied by this View in the perpendicular orientation including
104          * decorations and margins.
105          *
106          * @param view The view element to check
107          * @return Total space occupied by this view in the perpendicular orientation to current one
108          * @see #getDecoratedMeasurement(View)
109          */
110         public abstract float GetViewHolderMeasurementInOther(FlexibleView.ViewHolder holder);
111
112         /**
113          * Returns the start position of the layout after the start padding is added.
114          *
115          * @return The very first pixel we can draw.
116          */
117         public abstract float GetStartAfterPadding();
118
119         /**
120          * Returns the end position of the layout after the end padding is removed.
121          *
122          * @return The end boundary for this layout.
123          */
124         public abstract float GetEndAfterPadding();
125
126         /**
127          * Returns the end position of the layout without taking padding into account.
128          *
129          * @return The end boundary for this layout without considering padding.
130          */
131         public abstract float GetEnd();
132
133         /**
134          * Offsets all children's positions by the given amount.
135          *
136          * @param amount Value to add to each child's layout parameters
137          */
138         public abstract void OffsetChildren(float amount, bool immediate);
139
140         /**
141          * Returns the total space to layout. This number is the difference between
142          * {@link #getEndAfterPadding()} and {@link #getStartAfterPadding()}.
143          *
144          * @return Total space to layout children
145          */
146         public abstract float GetTotalSpace();
147
148         /**
149          * Offsets the child in this orientation.
150          *
151          * @param view   View to offset
152          * @param offset offset amount
153          */
154         internal abstract void OffsetChild(FlexibleView.ViewHolder holder, int offset);
155
156         /**
157          * Returns the padding at the end of the layout. For horizontal helper, this is the right
158          * padding and for vertical helper, this is the bottom padding. This method does not check
159          * whether the layout is RTL or not.
160          *
161          * @return The padding at the end of the layout.
162          */
163         public abstract float GetEndPadding();
164
165         /**
166          * Creates an OrientationHelper for the given LayoutManager and orientation.
167          *
168          * @param layoutManager LayoutManager to attach to
169          * @param orientation   Desired orientation. Should be {@link #HORIZONTAL} or {@link #VERTICAL}
170          * @return A new OrientationHelper
171          */
172         public static OrientationHelper CreateOrientationHelper(
173                 FlexibleView.LayoutManager layoutManager, int orientation)
174         {
175             if (orientation == HORIZONTAL)
176             {
177                 return CreateHorizontalHelper(layoutManager);
178             }
179             else if (orientation == VERTICAL)
180             {
181                 return CreateVerticalHelper(layoutManager);
182             }
183             
184             throw new ArgumentException("invalid orientation");
185         }
186
187
188         /**
189          * Creates a horizontal OrientationHelper for the given LayoutManager.
190          *
191          * @param layoutManager The LayoutManager to attach to.
192          * @return A new OrientationHelper
193          */
194         public static OrientationHelper CreateHorizontalHelper(FlexibleView.LayoutManager layoutManager)
195         {
196             return new HorizontalHelper(layoutManager);
197
198         }
199         /**
200         * Creates a vertical OrientationHelper for the given LayoutManager.
201         *
202         * @param layoutManager The LayoutManager to attach to.
203         * @return A new OrientationHelper
204         */
205         public static OrientationHelper CreateVerticalHelper(FlexibleView.LayoutManager layoutManager)
206         {
207             return new VerticalHelper(layoutManager);
208         }
209     }
210
211     internal class HorizontalHelper : OrientationHelper
212     {
213         public HorizontalHelper(FlexibleView.LayoutManager layoutManager): base(layoutManager)
214         {
215
216         }
217
218         public override float GetEndAfterPadding()
219         {
220             return mLayoutManager.GetWidth() - mLayoutManager.GetPaddingRight();
221         }
222
223         public override float GetEnd()
224         {
225             return mLayoutManager.GetWidth();
226         }
227
228         public override void OffsetChildren(float amount, bool immediate)
229         {
230             mLayoutManager.OffsetChildrenHorizontal(amount, immediate);
231         }
232
233
234         public override float GetStartAfterPadding()
235         {
236             return mLayoutManager.GetPaddingLeft();
237         }
238
239         public override float GetViewHolderMeasurement(FlexibleView.ViewHolder holder)
240         {
241             return holder.Right - holder.Left;
242         }
243
244         public override float GetViewHolderMeasurementInOther(FlexibleView.ViewHolder holder)
245         {
246             return holder.Bottom - holder.Top;
247         }
248
249         public override float GetViewHolderEnd(FlexibleView.ViewHolder holder)
250         {
251             return holder.Right;
252         }
253
254         public override float GetViewHolderStart(FlexibleView.ViewHolder holder)
255         {
256             return holder.Left;
257         }
258
259         public override float GetTotalSpace()
260         {
261             return mLayoutManager.GetWidth() - mLayoutManager.GetPaddingLeft()
262                     - mLayoutManager.GetPaddingRight();
263         }
264
265         internal override void OffsetChild(FlexibleView.ViewHolder holder, int offset)
266         {
267             //holder.offsetLeftAndRight(offset);
268         }
269
270         public override float GetEndPadding()
271         {
272             return mLayoutManager.GetPaddingRight();
273         }
274
275     }
276
277     internal class VerticalHelper : OrientationHelper
278     {
279         public VerticalHelper(FlexibleView.LayoutManager layoutManager) : base(layoutManager)
280         {
281
282         }
283
284         public override float GetEndAfterPadding()
285         {
286             return mLayoutManager.GetHeight() - mLayoutManager.GetPaddingBottom();
287         }
288
289         public override float GetEnd()
290         {
291             return mLayoutManager.GetHeight();
292         }
293
294         public override void OffsetChildren(float amount, bool immediate)
295         {
296             mLayoutManager.OffsetChildrenVertical(amount, immediate);
297         }
298
299         public override float GetStartAfterPadding()
300         {
301             return mLayoutManager.GetPaddingTop();
302         }
303
304         public override float GetViewHolderMeasurement(FlexibleView.ViewHolder holder)
305         {
306             return holder.Bottom - holder.Top;
307         }
308
309         public override float GetViewHolderMeasurementInOther(FlexibleView.ViewHolder holder)
310         {
311             return holder.Right - holder.Left;
312         }
313
314         public override float GetViewHolderEnd(FlexibleView.ViewHolder holder)
315         {
316             return holder.Bottom;
317         }
318
319         public override float GetViewHolderStart(FlexibleView.ViewHolder holder)
320         {
321             return holder.Top;
322         }
323
324         public override float GetTotalSpace()
325         {
326             return mLayoutManager.GetHeight() - mLayoutManager.GetPaddingTop()
327                     - mLayoutManager.GetPaddingBottom();
328         }
329
330         internal override void OffsetChild(FlexibleView.ViewHolder holder, int offset)
331         {
332             //holder.offsetTopAndBottom(offset);
333         }
334
335         public override float GetEndPadding()
336         {
337             return mLayoutManager.GetPaddingBottom();
338         }
339
340     }
341
342 }