[NUI] add attached property for FlexLayout (#1803)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Layouting / FlexLayout.cs
1 /* Copyright (c) 2019 Samsung Electronics Co., Ltd.
2  *
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
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
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.
14  *
15  */
16
17 using System;
18 using System.ComponentModel;
19 using Tizen.NUI.BaseComponents;
20 using System.Runtime.InteropServices;
21 using System.Diagnostics;
22 using Tizen.NUI.Binding;
23
24 namespace Tizen.NUI
25 {
26     /// <summary>
27     /// [Draft] This class implements a flex layout.
28     /// The flex layout implementation is based on open source Facebook Yoga layout engine.
29     /// For more information about the flex layout API and how to use it please refer to https://yogalayout.com/docs/
30     /// We implement the subset of the API in the class below.
31     /// </summary>
32     public class FlexLayout : LayoutGroup,  global::System.IDisposable
33     {
34         /// <summary>
35         /// FlexItemProperty
36         /// </summary>
37         [EditorBrowsable(EditorBrowsableState.Never)]
38         internal static readonly BindableProperty FlexItemProperty = BindableProperty.CreateAttached("FlexItem", typeof(HandleRef), typeof(FlexLayout), default(HandleRef));
39
40         /// <summary>
41         /// FlexAlignmentSelfProperty
42         /// </summary>
43         [EditorBrowsable(EditorBrowsableState.Never)]
44         public static readonly BindableProperty FlexAlignmentSelfProperty = BindableProperty.CreateAttached("FlexAlignmentSelf", typeof(AlignmentType), typeof(FlexLayout), AlignmentType.Auto, propertyChanged: OnChildPropertyChanged);
45
46         /// <summary>
47         /// FlexPositionTypeProperty
48         /// </summary>
49         [EditorBrowsable(EditorBrowsableState.Never)]
50         public static readonly BindableProperty FlexPositionTypeProperty = BindableProperty.CreateAttached("FlexPositionType", typeof(PositionType), typeof(FlexLayout), PositionType.Relative, propertyChanged: OnChildPropertyChanged);
51
52         /// <summary>
53         /// AspectRatioProperty
54         /// </summary>
55         [EditorBrowsable(EditorBrowsableState.Never)]
56         public static readonly BindableProperty FlexAspectRatioProperty = BindableProperty.CreateAttached("FlexAspectRatio", typeof(float), typeof(FlexLayout), FlexUndefined, validateValue: (bindable, value) => (float)value > 0, propertyChanged: OnChildPropertyChanged);
57
58         /// <summary>
59         /// FlexBasisProperty
60         /// </summary>
61         [EditorBrowsable(EditorBrowsableState.Never)]
62         public static readonly BindableProperty FlexBasisProperty = BindableProperty.CreateAttached("FlexBasis", typeof(float), typeof(FlexLayout), FlexUndefined, validateValue: (bindable, value) => (float)value >= 0, propertyChanged: OnChildPropertyChanged);
63
64         /// <summary>
65         /// FlexShrinkProperty
66         /// </summary>
67         [EditorBrowsable(EditorBrowsableState.Never)]
68         public static readonly BindableProperty FlexShrinkProperty = BindableProperty.CreateAttached("FlexShrink", typeof(float), typeof(FlexLayout), 1.0f, validateValue: (bindable, value) => (float)value >= 0, propertyChanged: OnChildPropertyChanged);
69
70         /// <summary>
71         /// FlexGrowProperty
72         /// </summary>
73         [EditorBrowsable(EditorBrowsableState.Never)]
74         public static readonly BindableProperty FlexGrowProperty = BindableProperty.CreateAttached("FlexGrow", typeof(float), typeof(FlexLayout), FlexUndefined, validateValue: (bindable, value) => (float)value >= 0, propertyChanged: OnChildPropertyChanged);
75
76         private static bool LayoutDebugFlex = false; // Debug flag
77
78         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
79         private bool swigCMemOwn;
80         private bool disposed;
81         private bool isDisposeQueued = false;
82
83         private MeasureSpecification parentMeasureSpecificationWidth;
84         private MeasureSpecification parentMeasureSpecificationHeight;
85
86         private IntPtr _rootFlex;  // Pointer to the unmanged flex layout class.
87
88         internal const float FlexUndefined = 10E20F; // Auto setting which is equivalent to WrapContent.
89
90         internal struct MeasuredSize
91         {
92           public MeasuredSize(float x, float y)
93           {
94             width = x;
95             height = y;
96           }
97           float width;
98           float height;
99         };
100
101         /// <summary>
102         /// Get the alignment self of the layout items.
103         /// </summary>
104         [EditorBrowsable(EditorBrowsableState.Never)]
105         public static AlignmentType GetFlexAlignmentSelf(View view)
106         {
107             return (AlignmentType)view.GetValue(FlexAlignmentSelfProperty);
108         }
109
110         /// <summary>
111         /// Get the position type of the layout items.
112         /// </summary>
113         [EditorBrowsable(EditorBrowsableState.Never)]
114         public static PositionType GetFlexPositionType(View view)
115         {
116             return (PositionType)view.GetValue(FlexPositionTypeProperty);
117         }
118
119         /// <summary>
120         /// Get the aspect ratio of the layout items.
121         /// </summary>
122         [EditorBrowsable(EditorBrowsableState.Never)]
123         public static float GetFlexAspectRatio(View view)
124         {
125             return (float)view.GetValue(FlexAspectRatioProperty);
126         }
127
128         /// <summary>
129         /// Get the basis of the layout items.
130         /// </summary>
131         [EditorBrowsable(EditorBrowsableState.Never)]
132         public static float GetFlexBasis(View view)
133         {
134             return (float)view.GetValue(FlexBasisProperty);
135         }
136
137         /// <summary>
138         /// Get the shrink of the layout items.
139         /// </summary>
140         [EditorBrowsable(EditorBrowsableState.Never)]
141         public static float GetFlexShrink(View view)
142         {
143             return (float)view.GetValue(FlexShrinkProperty);
144         }
145
146         /// <summary>
147         /// Get the grow of the layout items.
148         /// </summary>
149         [EditorBrowsable(EditorBrowsableState.Never)]
150         public static float GetFlexGrow(View view)
151         {
152             return (float)view.GetValue(FlexGrowProperty);
153         }
154
155         /// <summary>
156         /// Set the alignment self of the layout items.
157         /// </summary>
158         [EditorBrowsable(EditorBrowsableState.Never)]
159         public static void SetFlexAlignmentSelf(View view, AlignmentType value)
160         {
161             SetChildValue(view, FlexAlignmentSelfProperty, value);
162         }
163
164         /// <summary>
165         /// Set the position type of the layout items.
166         /// </summary>
167         [EditorBrowsable(EditorBrowsableState.Never)]
168         public static void SetFlexPositionType(View view, PositionType value)
169         {
170             SetChildValue(view, FlexPositionTypeProperty, value);
171         }
172
173         /// <summary>
174         /// Set the aspect ratio of the layout items.
175         /// </summary>
176         [EditorBrowsable(EditorBrowsableState.Never)]
177         public static void SetFlexAspectRatio(View view, float value)
178         {
179             SetChildValue(view, FlexAspectRatioProperty, value);
180         }
181
182         /// <summary>
183         /// Set the basis of the layout items.
184         /// </summary>
185         [EditorBrowsable(EditorBrowsableState.Never)]
186         public static void SetFlexBasis(View view, float value)
187         {
188             SetChildValue(view, FlexBasisProperty, value);
189         }
190
191         /// <summary>
192         /// Set the shrink of the layout items.
193         /// </summary>
194         [EditorBrowsable(EditorBrowsableState.Never)]
195         public static void SetFlexShrink(View view, float value)
196         {
197             SetChildValue(view, FlexShrinkProperty, value);
198         }
199
200         /// <summary>
201         /// Set the grow of the layout items.
202         /// </summary>
203         [EditorBrowsable(EditorBrowsableState.Never)]
204         public static void SetFlexGrow(View view, float value)
205         {
206             SetChildValue(view, FlexGrowProperty, value);
207         }
208
209         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
210         internal delegate MeasuredSize ChildMeasureCallback( global::System.IntPtr child, float width, int measureModeWidth, float height, int measureModeHeight );
211
212         event ChildMeasureCallback measureChildDelegate; // Stores a delegate to the child measure callback. Used for all children of this FlexLayout.
213
214         internal FlexLayout(global::System.IntPtr cPtr, bool cMemoryOwn)
215         {
216             swigCMemOwn = cMemoryOwn;
217             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
218             _rootFlex = Interop.FlexLayout.FlexLayout_New();
219             measureChildDelegate = new ChildMeasureCallback(measureChild);
220         }
221
222         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FlexLayout obj)
223         {
224             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
225         }
226
227         /// <summary>
228         /// Dispose.
229         /// </summary>
230         /// <since_tizen> 6 </since_tizen>
231         public void Dispose()
232         {
233             // Throw exception if Dispose() is called in separate thread.
234             if (!Window.IsInstalled())
235             {
236                 throw new System.InvalidOperationException("This API called from separate thread. This API must be called from MainThread.");
237             }
238
239             if (isDisposeQueued)
240             {
241                 Dispose(DisposeTypes.Implicit);
242             }
243             else
244             {
245                 Dispose(DisposeTypes.Explicit);
246                 System.GC.SuppressFinalize(this);
247             }
248         }
249
250         /// <summary>
251         /// Dispose.
252         /// </summary>
253         /// <since_tizen> 6 </since_tizen>
254         protected virtual void Dispose(DisposeTypes type)
255         {
256             if (disposed)
257             {
258                 return;
259             }
260
261             if (type == DisposeTypes.Explicit)
262             {
263                 // Called by User
264                 // Release your own managed resources here.
265                 // You should release all of your own disposable objects here.
266
267             }
268
269             // Release your own unmanaged resources here.
270             // You should not access any managed member here except static instance.
271             // because the execution order of Finalizes is non-deterministic.
272             if (swigCPtr.Handle != global::System.IntPtr.Zero)
273             {
274                 if (swigCMemOwn)
275                 {
276                     swigCMemOwn = false;
277                     Interop.FlexLayout.delete_FlexLayout(swigCPtr);
278                 }
279                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
280             }
281             disposed = true;
282         }
283
284         /// <summary>
285         /// [Draft] Creates a FlexLayout object.
286         /// </summary>
287         /// <since_tizen> 6 </since_tizen>
288         public FlexLayout() : this(Interop.FlexLayout.FlexLayout_New(), true)
289         {
290             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
291         }
292
293         internal static FlexLayout DownCast(BaseHandle handle)
294         {
295             FlexLayout ret = new FlexLayout(Interop.FlexLayout.FlexLayout_DownCast(BaseHandle.getCPtr(handle)), true);
296             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
297             return ret;
298         }
299
300         internal FlexLayout(FlexLayout other) : this(Interop.FlexLayout.new_FlexLayout__SWIG_1(FlexLayout.getCPtr(other)), true)
301         {
302             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
303         }
304
305         internal FlexLayout Assign(FlexLayout other)
306         {
307             FlexLayout ret = new FlexLayout(Interop.FlexLayout.FlexLayout_Assign(swigCPtr, FlexLayout.getCPtr(other)), false);
308             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
309             return ret;
310         }
311
312         internal void SetFlexDirection(FlexLayout.FlexDirection flexDirection)
313         {
314             Interop.FlexLayout.FlexLayout_SetFlexDirection(swigCPtr, (int)flexDirection);
315             RequestLayout();
316         }
317
318         internal FlexLayout.FlexDirection GetFlexDirection()
319         {
320             FlexLayout.FlexDirection ret = (FlexLayout.FlexDirection)Interop.FlexLayout.FlexLayout_GetFlexDirection(swigCPtr);
321             return ret;
322
323         }
324
325         internal void SetFlexJustification(FlexLayout.FlexJustification flexJustification)
326         {
327             Interop.FlexLayout.FlexLayout_SetFlexJustification(swigCPtr, (int)flexJustification);
328             RequestLayout();
329         }
330
331         internal FlexLayout.FlexJustification GetFlexJustification()
332         {
333             FlexLayout.FlexJustification ret = (FlexLayout.FlexJustification)Interop.FlexLayout.FlexLayout_GetFlexJustification(swigCPtr);
334             return ret;
335         }
336
337         internal void SetFlexWrap(FlexLayout.FlexWrapType flexWrap)
338         {
339             Interop.FlexLayout.FlexLayout_SetFlexWrap(swigCPtr, (int)flexWrap);
340             RequestLayout();
341         }
342
343         internal FlexLayout.FlexWrapType GetFlexWrap()
344         {
345             FlexLayout.FlexWrapType ret = (FlexLayout.FlexWrapType)Interop.FlexLayout.FlexLayout_GetFlexWrap(swigCPtr);
346             return ret;
347         }
348
349         internal void SetFlexAlignment(FlexLayout.AlignmentType flexAlignment)
350         {
351             Interop.FlexLayout.FlexLayout_SetFlexAlignment(swigCPtr, (int)flexAlignment);
352             RequestLayout();
353         }
354
355         internal FlexLayout.AlignmentType GetFlexAlignment()
356         {
357             FlexLayout.AlignmentType ret = (FlexLayout.AlignmentType)Interop.FlexLayout.FlexLayout_GetFlexAlignment(swigCPtr);
358             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
359             return ret;
360         }
361
362         internal void SetFlexItemsAlignment(FlexLayout.AlignmentType flexAlignment)
363         {
364             Interop.FlexLayout.FlexLayout_SetFlexItemsAlignment(swigCPtr, (int)flexAlignment);
365             RequestLayout();
366         }
367
368         internal FlexLayout.AlignmentType GetFlexItemsAlignment()
369         {
370             FlexLayout.AlignmentType ret = (FlexLayout.AlignmentType)Interop.FlexLayout.FlexLayout_GetFlexItemsAlignment(swigCPtr);
371             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
372             return ret;
373         }
374
375         /// <summary>
376         /// [Draft] Get/Set the flex direction in the layout.
377         /// The direction of the main-axis which determines the direction that flex items are laid out.
378         /// </summary>
379         /// <since_tizen> 6 </since_tizen>
380         public FlexDirection Direction
381         {
382             get
383             {
384                 return GetFlexDirection();
385             }
386             set
387             {
388                 SetFlexDirection(value);
389             }
390         }
391
392         /// <summary>
393         /// [Draft] Get/Set the justification in the layout.
394         /// </summary>
395         /// <since_tizen> 6 </since_tizen>
396         public FlexJustification Justification
397         {
398             get
399             {
400                 return GetFlexJustification();
401             }
402             set
403             {
404                 SetFlexJustification(value);
405             }
406         }
407
408         /// <summary>
409         /// [Draft] Get/Set the wrap in the layout.
410         /// </summary>
411         /// <since_tizen> 6 </since_tizen>
412         public FlexWrapType WrapType
413         {
414             get
415             {
416                 return GetFlexWrap();
417             }
418             set
419             {
420                 SetFlexWrap(value);
421             }
422         }
423
424         /// <summary>
425         /// [Draft] Get/Set the alignment of the layout content.
426         /// </summary>
427         /// <since_tizen> 6 </since_tizen>
428         public AlignmentType Alignment
429         {
430             get
431             {
432                 return GetFlexAlignment();
433             }
434             set
435             {
436                 SetFlexAlignment(value);
437             }
438         }
439
440         /// <summary>
441         /// [Draft] Get/Set the alignment of the layout items.
442         /// </summary>
443         /// <since_tizen> 6 </since_tizen>
444         public AlignmentType ItemsAlignment
445         {
446             get
447             {
448                 return GetFlexItemsAlignment();
449             }
450             set
451             {
452                 SetFlexItemsAlignment(value);
453             }
454         }
455
456         /// <summary>
457         /// [Draft] Enumeration for the direction of the main axis in the flex container.
458         /// This determines the direction that flex items are laid out in the flex container.
459         /// </summary>
460         /// <since_tizen> 6 </since_tizen>
461         public enum FlexDirection
462         {
463             /// <summary>
464             /// The flexible items are displayed vertically as a column
465             /// </summary>
466             Column,
467             /// <summary>
468             /// The flexible items are displayed vertically as a column, but in reverse order
469             /// </summary>
470             ColumnReverse,
471             /// <summary>
472             /// The flexible items are displayed horizontally as a row
473             /// </summary>
474             Row,
475             /// <summary>
476             /// The flexible items are displayed horizontally as a row, but in reverse order
477             /// </summary>
478             RowReverse
479         }
480
481         /// <summary>
482         /// [Draft] Enumeration for the alignment of the flex items when the items do not use all available space on the main-axis.
483         /// </summary>
484         /// <since_tizen> 6 </since_tizen>
485         public enum FlexJustification
486         {
487             /// <summary>
488             /// Items are positioned at the beginning of the container
489             /// </summary>
490             FlexStart,
491             /// <summary>
492             /// Items are positioned at the center of the container
493             /// </summary>
494             Center,
495             /// <summary>
496             /// Items are positioned at the end of the container
497             /// </summary>
498             FlexEnd,
499             /// <summary>
500             /// Items are positioned with equal space between the lines
501             /// </summary>
502             SpaceBetween,
503             /// <summary>
504             /// Items are positioned with equal space before, between, and after the lines
505             /// </summary>
506             SpaceAround
507         }
508
509         /// <summary>
510         /// [Draft] Enumeration for the wrap type of the flex container when there is no enough room for all the items on one flex line.
511         /// </summary>
512         /// <since_tizen> 6 </since_tizen>
513         public enum FlexWrapType
514         {
515             /// <summary>
516             /// Flex items laid out in single line (shrunk to fit the flex container along the main axis)
517             /// </summary>
518             NoWrap,
519             /// <summary>
520             /// Flex items laid out in multiple lines if needed
521             /// </summary>
522             Wrap
523         }
524
525         /// <summary>
526         /// [Draft] Enumeration for the alignment of the flex items or lines when the items or lines do not use all the available space on the cross-axis.
527         /// </summary>
528         /// <since_tizen> 6 </since_tizen>
529         public enum AlignmentType
530         {
531             /// <summary>
532             /// Inherits the same alignment from the parent
533             /// </summary>
534             Auto,
535             /// <summary>
536             /// At the beginning of the container
537             /// </summary>
538             FlexStart,
539             /// <summary>
540             /// At the center of the container
541             /// </summary>
542             Center,
543             /// <summary>
544             /// At the end of the container
545             /// </summary>
546             FlexEnd,
547             /// <summary>
548             /// Stretch to fit the container
549             /// </summary>
550             Stretch
551         }
552         /// <summary>
553         /// Enumeration for the position type of the flex item how it is positioned within its parent.
554         /// </summary>
555         [EditorBrowsable(EditorBrowsableState.Never)]
556         public enum PositionType
557         {
558             /// <summary>
559             /// Flex items laid out relatively.
560             /// </summary>
561             [EditorBrowsable(EditorBrowsableState.Never)]
562             Relative,
563             /// <summary>
564             /// Flex items laid out absolutely.
565             /// </summary>
566             [EditorBrowsable(EditorBrowsableState.Never)]
567             Absolute
568         }
569
570         private MeasuredSize measureChild(global::System.IntPtr childPtr, float width, int measureModeWidth, float height, int measureModeHeight)
571         {
572             // We need to measure child layout
573             View child = Registry.GetManagedBaseHandleFromNativePtr(childPtr) as View;
574
575             LayoutItem childLayout = child.Layout;
576
577             MeasureSpecification childWidthMeasureSpec = GetChildMeasureSpecification(
578                                     new MeasureSpecification(
579                                         new LayoutLength(parentMeasureSpecificationWidth.Size - (child.Margin.Start + child.Margin.End)),
580                                         parentMeasureSpecificationWidth.Mode),
581                                     new LayoutLength(Padding.Start + Padding.End),
582                                     new LayoutLength(child.WidthSpecification));
583
584             MeasureSpecification childHeightMeasureSpec = GetChildMeasureSpecification(
585                                     new MeasureSpecification(
586                                         new LayoutLength(parentMeasureSpecificationHeight.Size - (child.Margin.Top + child.Margin.Bottom)),
587                                         parentMeasureSpecificationHeight.Mode),
588                                     new LayoutLength(Padding.Top + Padding.Bottom),
589                                     new LayoutLength(child.HeightSpecification));
590
591             childLayout.Measure( childWidthMeasureSpec, childHeightMeasureSpec);
592
593             return new MeasuredSize(childLayout.MeasuredWidth.Size.AsRoundedValue(),childLayout.MeasuredHeight.Size.AsRoundedValue());
594         }
595
596         void InsertChild( LayoutItem child )
597         {
598             // Store created node for child
599             IntPtr childPtr = Interop.FlexLayout.FlexLayout_AddChildWithMargin(swigCPtr, View.getCPtr(child.Owner), Extents.getCPtr(child.Owner.Margin), measureChildDelegate, LayoutChildren.Count-1);
600             HandleRef childHandleRef = new HandleRef(child.Owner, childPtr);
601             SetChildValue(child.Owner, FlexItemProperty, childHandleRef);
602         }
603
604         /// <summary>
605         /// Callback when child is added to container.<br />
606         /// Derived classes can use this to set their own child properties on the child layout's owner.<br />
607         /// </summary>
608         /// <param name="child">The Layout child.</param>
609         /// <since_tizen> 6 </since_tizen>
610         protected override void OnChildAdd(LayoutItem child)
611         {
612             InsertChild(child);
613         }
614
615         /// <summary>
616         /// Callback when child is removed from container.<br />
617         /// </summary>
618         /// <param name="child">The Layout child.</param>
619         /// <since_tizen> 6 </since_tizen>
620         protected override void OnChildRemove(LayoutItem child)
621         {
622             // When child View is removed from it's parent View (that is a Layout) then remove it from the layout too.
623             // FlexLayout refers to the child as a View not LayoutItem.
624             Interop.FlexLayout.FlexLayout_RemoveChild(swigCPtr, child);
625         }
626
627         /// <summary>
628         /// Measure the layout and its content to determine the measured width and the measured height.<br />
629         /// </summary>
630         /// <param name="widthMeasureSpec">horizontal space requirements as imposed by the parent.</param>
631         /// <param name="heightMeasureSpec">vertical space requirements as imposed by the parent.</param>
632         /// <since_tizen> 6 </since_tizen>
633         protected override void OnMeasure( MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec )
634         {
635             bool isLayoutRtl = Owner.LayoutDirection == ViewLayoutDirectionType.RTL;
636             Extents padding = Owner.Padding;
637             Extents margin = Owner.Margin;
638
639             Interop.FlexLayout.FlexLayout_SetMargin(swigCPtr, Extents.getCPtr(margin));
640             Interop.FlexLayout.FlexLayout_SetPadding(swigCPtr, Extents.getCPtr(padding));
641
642             float width = FlexUndefined; // Behaves as WrapContent (Flex Auto)
643             float height = FlexUndefined; // Behaves as WrapContent (Flex Auto)
644
645             if( widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly ||  widthMeasureSpec.Mode == MeasureSpecification.ModeType.AtMost )
646             {
647                 width = widthMeasureSpec.Size.AsDecimal();
648             }
649
650             if ( heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly || heightMeasureSpec.Mode == MeasureSpecification.ModeType.AtMost )
651             {
652                 height = heightMeasureSpec.Size.AsDecimal();
653             }
654
655             // Save measureSpec to measure children.
656             // In other Layout, we can pass it as parameter to measuring child but in FlexLayout we can't
657             // because measurChild function is called by native callback.
658             parentMeasureSpecificationWidth = widthMeasureSpec;
659             parentMeasureSpecificationHeight = heightMeasureSpec;
660
661             // Assign child properties
662             for (int i = 0; i < LayoutChildren.Count; i++)
663             {
664                 LayoutItem layoutItem = LayoutChildren[i];
665                 View Child = layoutItem?.Owner;
666                 HandleRef childHandleRef = (HandleRef)Child.GetValue(FlexItemProperty);
667                 if (childHandleRef.Handle == IntPtr.Zero || Child == null)
668                     continue;
669
670                 AlignmentType flexAlignemnt = GetFlexAlignmentSelf(Child);
671                 PositionType flexPosition = GetFlexPositionType(Child);
672                 float flexAspectRatio = GetFlexAspectRatio(Child);
673                 float flexBasis = GetFlexBasis(Child);
674                 float flexShrink = GetFlexShrink(Child);
675                 float flexGrow = GetFlexGrow(Child);
676
677                 Interop.FlexLayout.FlexLayout_SetFlexAlignmentSelf(childHandleRef, (int)flexAlignemnt);
678                 Interop.FlexLayout.FlexLayout_SetFlexPositionType(childHandleRef, (int)flexPosition);
679                 Interop.FlexLayout.FlexLayout_SetFlexAspectRatio(childHandleRef, flexAspectRatio);
680                 Interop.FlexLayout.FlexLayout_SetFlexBasis(childHandleRef, flexBasis);
681                 Interop.FlexLayout.FlexLayout_SetFlexShrink(childHandleRef, flexShrink);
682                 Interop.FlexLayout.FlexLayout_SetFlexGrow(childHandleRef, flexGrow);
683             }
684
685             Interop.FlexLayout.FlexLayout_CalculateLayout( swigCPtr, width, height, isLayoutRtl );
686
687             LayoutLength flexLayoutWidth =  new LayoutLength( Interop.FlexLayout.FlexLayout_GetWidth(swigCPtr) );
688             LayoutLength flexLayoutHeight = new LayoutLength( Interop.FlexLayout.FlexLayout_GetHeight(swigCPtr) );
689
690             Debug.WriteLineIf( LayoutDebugFlex, "FlexLayout OnMeasure width:" + flexLayoutWidth.AsRoundedValue()
691                                                 + " height:" + flexLayoutHeight.AsRoundedValue() );
692
693             SetMeasuredDimensions( GetDefaultSize(flexLayoutWidth, widthMeasureSpec ),
694                                    GetDefaultSize(flexLayoutHeight, heightMeasureSpec ) );
695         }
696
697         /// <summary>
698         /// Assign a size and position to each of its children.<br />
699         /// </summary>
700         /// <param name="changed">This is a new size or position for this layout.</param>
701         /// <param name="left">Left position, relative to parent.</param>
702         /// <param name="top"> Top position, relative to parent.</param>
703         /// <param name="right">Right position, relative to parent.</param>
704         /// <param name="bottom">Bottom position, relative to parent.</param>
705         /// <since_tizen> 6 </since_tizen>
706         protected override void OnLayout( bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom )
707         {
708
709             bool isLayoutRtl = Owner.LayoutDirection == ViewLayoutDirectionType.RTL;
710             LayoutLength width = right - left;
711             LayoutLength height = bottom - top;
712
713             // Call to FlexLayout implementation to calculate layout values for later retrieval.
714             Interop.FlexLayout.FlexLayout_CalculateLayout( swigCPtr, width.AsDecimal(), height.AsDecimal(), isLayoutRtl );
715
716             int count = LayoutChildren.Count;
717             for( int childIndex = 0; childIndex < count; childIndex++)
718             {
719                 LayoutItem childLayout = LayoutChildren[childIndex];
720                 if( childLayout != null )
721                 {
722                     // Get the frame for the child, start, top, end, bottom.
723                     Vector4 frame = new Vector4(Interop.FlexLayout.FlexLayout_GetNodeFrame(swigCPtr, childIndex ), true);
724                     childLayout.Layout( new LayoutLength(frame.X), new LayoutLength(frame.Y), new LayoutLength(frame.Z), new LayoutLength(frame.W) );
725                 }
726             }
727         }
728
729     } // FLexlayout
730 } // namesspace Tizen.NUI