[NUI] Sync dalihub/TizenFX and Samsung/TizenFX[NUI (#548)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Layouting / LayoutItem.cs
1 /*
2  * Copyright (c) 2018 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
18 using System.ComponentModel;
19 using Tizen.NUI.BaseComponents;
20
21 namespace Tizen.NUI
22 {
23     /// <summary>
24     /// [Draft] Base class for layouts. It is used to layout a control (or visual).
25     /// It can be laid out by a LayoutGroup.
26     /// </summary>
27     internal class LayoutItem : LayoutItemWrapper
28     {
29         //It is called by LayoutGroupWrapper constructor.
30         internal LayoutItem(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
31         {
32             System.IntPtr wrapperImpe_CPtr = LayoutPINVOKE.LayoutItemWrapper_GetImplementation(cPtr);
33             layoutItemWrapperImpl = new LayoutItemWrapperImpl(wrapperImpe_CPtr, true);
34             LayoutItemInitialize(layoutItemWrapperImpl);
35         }
36
37         public LayoutItem() : base(new LayoutItemWrapperImpl())
38         {
39             LayoutItemInitialize(layoutItemWrapperImpl);
40         }
41
42         // This should be protected though but made internal because LayoutItemWrapperImpl is internal.
43         internal void LayoutItemInitialize(LayoutItemWrapperImpl implementation)
44         {
45             layoutItemWrapperImpl = implementation;
46             layoutItemWrapperImpl.OnMeasure = new LayoutItemWrapperImpl.OnMeasureDelegate(OnMeasure);
47             layoutItemWrapperImpl.OnLayout = new LayoutItemWrapperImpl.OnLayoutDelegate(OnLayout);
48             layoutItemWrapperImpl.OnSizeChanged = new LayoutItemWrapperImpl.OnSizeChangedDelegate(OnSizeChanged);
49         }
50
51         /// <summary>
52         /// Unparent this layout from it's owner, and remove any layout children in derived types. <br />
53         /// </summary>
54         public void Unparent()
55         {
56             layoutItemWrapperImpl.Unparent();
57         }
58
59         protected void SetMeasuredDimensions(MeasuredSize measuredWidth, MeasuredSize measuredHeight)
60         {
61             layoutItemWrapperImpl.SetMeasuredDimensions(measuredWidth, measuredHeight);
62         }
63
64         /// <summary>
65         /// This is called to find out how big a layout should be. <br />
66         /// The parent supplies constraint information in the width and height parameters. <br />
67         /// The actual measurement work of a layout is performed in OnMeasure called by this
68         /// method. Therefore, only OnMeasure can and must be overridden by subclasses. <br />
69         /// </summary>
70         /// <param name="widthMeasureSpec"> Horizontal space requirements as imposed by the parent.</param>
71         /// <param name="heightMeasureSpec">Vertical space requirements as imposed by the parent.</param>
72         internal void Measure(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
73         {
74             layoutItemWrapperImpl.Measure(widthMeasureSpec, heightMeasureSpec);
75         }
76
77         /// <summary>
78         /// Assign a size and position to a layout and all of its descendants. <br />
79         /// This is the second phase of the layout mechanism.  (The first is measuring). In this phase, each parent
80         /// calls layout on all of its children to position them.  This is typically done using the child<br />
81         /// measurements that were stored in the measure pass.<br />
82         /// </summary>
83         /// <param name="left">Left position, relative to parent.</param>
84         /// <param name="top">Top position, relative to parent.</param>
85         /// <param name="right">Right position, relative to parent.</param>
86         /// <param name="bottom">Bottom position, relative to parent.</param>
87         public void Layout(LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
88         {
89             Log.Info("NUI", "LayoutItem Layout\n");
90             layoutItemWrapperImpl.Layout(left, top, right, bottom);
91         }
92
93         /// <summary>
94         /// Utility to return a default size.<br />
95         /// Uses the supplied size if the MeasureSpec imposed no constraints. Will get larger if allowed by the
96         /// MeasureSpec.<br />
97         /// </summary>
98         /// <param name="size"> Default size for this layout.</param>
99         /// <param name="measureSpec"> Constraints imposed by the parent.</param>
100         /// <returns>The size this layout should be.</returns>
101         public static LayoutLength GetDefaultSize(LayoutLength size, LayoutMeasureSpec measureSpec)
102         {
103             return LayoutItemWrapperImpl.GetDefaultSize(size, measureSpec);
104         }
105
106         public ILayoutParent GetParent
107         {
108             get
109             {
110                 return layoutItemWrapperImpl.GetParent();
111             }
112         }
113
114         /// <summary>
115         /// Request that this layout is re-laid out.<br />
116         /// This will make this layout and all it's parent layouts dirty.<br />
117         /// </summary>
118         public void RequestLayout()
119         {
120             layoutItemWrapperImpl.RequestLayout();
121         }
122
123         /// <summary>
124         /// Predicate to determine if this layout has been requested to re-layout.<br />
125         /// </summary>
126         public bool LayoutRequested
127         {
128             get
129             {
130                 return IsLayoutRequested();
131             }
132         }
133
134         /// <summary>
135         /// Predicate to determine if this layout has been requested to re-layout.<br />
136         /// </summary>
137         /// <returns>True if a layout request has occured on this layout.</returns>
138         private bool IsLayoutRequested()
139         {
140             return layoutItemWrapperImpl.IsLayoutRequested();
141         }
142
143         /// <summary>
144         /// Get the measured width (without any measurement flags).<br />
145         /// This method should be used only during measurement and layout calculations.<br />
146         /// </summary>
147         public LayoutLength MeasuredWidth
148         {
149             get
150             {
151                 return GetMeasuredWidth();
152             }
153         }
154
155         /// <summary>
156         /// Get the measured width (without any measurement flags).<br />
157         /// This method should be used only during measurement and layout calculations.<br />
158         /// </summary>
159         private LayoutLength GetMeasuredWidth()
160         {
161             return layoutItemWrapperImpl.GetMeasuredWidth();
162         }
163
164         /// <summary>
165         /// Get the measured height (without any measurement flags).<br />
166         /// This method should be used only during measurement and layout calculations.<br />
167         /// </summary>
168         public LayoutLength MeasuredHeight
169         {
170             get
171             {
172                 return GetMeasuredHeight();
173             }
174         }
175
176         /// <summary>
177         /// Get the measured height (without any measurement flags).<br />
178         /// This method should be used only during measurement and layout calculations.<br />
179         /// </summary>
180         private LayoutLength GetMeasuredHeight()
181         {
182             return layoutItemWrapperImpl.GetMeasuredHeight();
183         }
184
185         /// <summary>
186         /// Get the measured width and state.<br />
187         /// This method should be used only during measurement and layout calculations.<br />
188         /// </summary>
189         public MeasuredSize MeasuredWidthAndState
190         {
191             get
192             {
193                 return GetMeasuredWidthAndState();
194             }
195         }
196
197         /// <summary>
198         /// Get the measured width and state.<br />
199         /// This method should be used only during measurement and layout calculations.<br />
200         /// </summary>
201         private MeasuredSize GetMeasuredWidthAndState()
202         {
203             return layoutItemWrapperImpl.GetMeasuredWidthAndState();
204         }
205
206         /// <summary>
207         /// Get the measured height and state.<br />
208         /// This method should be used only during measurement and layout calculations.<br />
209         /// </summary>
210         public MeasuredSize MeasuredHeightAndState
211         {
212             get
213             {
214                 return GetMeasuredHeightAndState();
215             }
216         }
217
218         /// <summary>
219         /// Get the measured height and state.<br />
220         /// This method should be used only during measurement and layout calculations.<br />
221         /// </summary>
222         private MeasuredSize GetMeasuredHeightAndState()
223         {
224             return layoutItemWrapperImpl.GetMeasuredHeightAndState();
225         }
226
227         /// <summary>
228         /// Returns the suggested minimum width that the layout should use.<br />
229         /// This returns the maximum of the layout's minimum width and the owner's natural width.<br />
230         /// </summary>
231         public LayoutLength SuggestedMinimumWidth
232         {
233             get
234             {
235                 return GetSuggestedMinimumWidth();
236             }
237         }
238
239         /// <summary>
240         /// Returns the suggested minimum width that the layout should use.<br />
241         /// This returns the maximum of the layout's minimum width and the owner's natural width.<br />
242         /// </summary>
243         /// <returns>The suggested minimum width of the layout.</returns>
244         private LayoutLength GetSuggestedMinimumWidth()
245         {
246             return layoutItemWrapperImpl.GetSuggestedMinimumWidth();
247         }
248
249         /// <summary>
250         /// Returns the suggested minimum height that the layout should use.<br />
251         /// This returns the maximum of the layout's minimum height and the owner's natural height.<br />
252         /// </summary>
253         public LayoutLength SuggestedMinimumHeight
254         {
255             get
256             {
257                 return GetSuggestedMinimumHeight();
258             }
259         }
260
261         /// <summary>
262         /// Returns the suggested minimum height that the layout should use.<br />
263         /// This returns the maximum of the layout's minimum height and the owner's natural height.<br />
264         /// </summary>
265         /// <returns>The suggested minimum height of the layout.</returns>
266         private LayoutLength GetSuggestedMinimumHeight()
267         {
268             return layoutItemWrapperImpl.GetSuggestedMinimumHeight();
269         }
270
271         /// <summary>
272         /// Sets the minimum width of the layout.<br />
273         /// It is not guaranteed the layout will be able to achieve this minimum width (for example, if its parent
274         /// layout constrains it with less available width).<br />
275         /// 1. if the owner's View.LayoutWidthSpecification has exact value, then that value overrides the minimum size.<br />
276         /// 2. If the owner's View.LayoutWidthSpecification is set to View.ChildLayoutData.WrapContent, then the view's width is set based on the suggested minimum width. (@see GetSuggestedMinimumWidth()).<br />
277         /// 3. If the owner's View.LayoutWidthSpecification is set to View.ChildLayoutData.MatchParent, then the parent width takes precedence over the minimum width.<br />
278         /// </summary>
279         public LayoutLength MinimumWidth
280         {
281             get
282             {
283                 return GetMinimumWidth();
284             }
285             set
286             {
287                 SetMinimumWidth(value);
288             }
289         }
290
291         /// <summary>
292         /// Sets the minimum width of the layout.<br />
293         /// It is not guaranteed the layout will be able to achieve this minimum width (for example, if its parent
294         /// layout constrains it with less available width).<br />
295         /// </summary>
296         /// <param name="minWidth">The minimum width the layout will try to be, in pixels.</param>
297         private void SetMinimumWidth(LayoutLength minWidth)
298         {
299             layoutItemWrapperImpl.SetMinimumWidth(minWidth);
300         }
301
302         /// <summary>
303         /// Sets the minimum height of the layout.<br />
304         /// It is not guaranteed the layout will be able to achieve this minimum height (for example, if its parent
305         /// layout constrains it with less available height).<br />
306         /// 1. if the owner's View.LayoutHeightSpecification has exact value, then that value overrides the minimum size.<br />
307         /// 2. If the owner's View.LayoutHeightSpecification is set to View.ChildLayoutData.WrapContent, then the view's height is set based on the suggested minimum height. (@see GetSuggestedMinimumHeight()).<br />
308         /// 3. If the owner's View.LayoutHeightSpecification is set to View.ChildLayoutData.MatchParent, then the parent height takes precedence over the minimum height.<br />
309         /// </summary>
310         public LayoutLength MinimumHeight
311         {
312             get
313             {
314                 return GetMinimumHeight();
315             }
316             set
317             {
318                 SetMinimumHeight(value);
319             }
320         }
321
322         /// <summary>
323         /// Sets the minimum height of the layout.<br />
324         /// It is not guaranteed the layout will be able to achieve this minimum height (for example, if its parent
325         /// layout constrains it with less available height).<br />
326         /// </summary>
327         /// <param name="minHeight">The minimum height the layout will try to be, in pixels.</param>
328         private void SetMinimumHeight(LayoutLength minHeight)
329         {
330             layoutItemWrapperImpl.SetMinimumHeight(minHeight);
331         }
332
333         /// <summary>
334         /// Returns the minimum width of the layout.<br />
335         /// </summary>
336         /// <returns>the minimum width the layout will try to be, in pixels.</returns>
337         private LayoutLength GetMinimumWidth()
338         {
339             return layoutItemWrapperImpl.GetMinimumWidth();
340         }
341
342         /// <summary>
343         /// Returns the minimum height of the layout.<br />
344         /// </summary>
345         /// <returns>the minimum height the layout will try to be, in pixels.</returns>
346         private LayoutLength GetMinimumHeight()
347         {
348             return layoutItemWrapperImpl.GetMinimumHeight();
349         }
350
351         /// <summary>
352         /// Measure the layout and its content to determine the measured width and the
353         /// measured height.<br />
354         /// The base class implementation of measure defaults to the background size,
355         /// unless a larger size is allowed by the MeasureSpec. Subclasses should
356         /// override to provide better measurements of their content.<br />
357         /// If this method is overridden, it is the subclass's responsibility to make sure the
358         /// measured height and width are at least the layout's minimum height and width.<br />
359         /// </summary>
360         /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param>
361         /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param>
362         protected virtual void OnMeasure(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
363         {
364             layoutItemWrapperImpl.OnMeasureNative(widthMeasureSpec, heightMeasureSpec);
365         }
366
367         /// <summary>
368         /// Called from Layout() when this layout should assign a size and position to each of its children. <br />
369         /// Derived classes with children should override this method and call Layout() on each of their children. <br />
370         /// </summary>
371         /// <param name="changed">This is a new size or position for this layout.</param>
372         /// <param name="left">Left position, relative to parent.</param>
373         /// <param name="top">Top position, relative to parent.</param>
374         /// <param name="right">Right position, relative to parent.</param>
375         /// <param name="bottom">Bottom position, relative to parent.</param>
376         protected virtual void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
377         {
378         }
379
380         /// <summary>
381         /// Virtual method to inform derived classes when the layout size changed. <br />
382         /// </summary>
383         /// <param name="newSize">The new size of the layout.</param>
384         /// <param name="oldSize">The old size of the layout.</param>
385         protected virtual void OnSizeChanged(LayoutSize newSize, LayoutSize oldSize)
386         {
387         }
388     }
389 }