[NUI] All Layers have an Absolute layout (#313)
authordongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 27 Jun 2018 02:01:48 +0000 (11:01 +0900)
committerGitHub <noreply@github.com>
Wed, 27 Jun 2018 02:01:48 +0000 (11:01 +0900)
Change-Id: I08281a25b2b73822b45f5c6a567b574b5af74fb4

src/Tizen.NUI/src/public/Layer.cs
src/Tizen.NUI/src/public/Window.cs
test/NUITestSample/NUITestSample/examples/layouting/custom-layout-root-layer-test.cs [new file with mode: 0755]
test/NUITestSample/NUITestSample/examples/layouting/custom-layout-test-2.cs [new file with mode: 0755]
test/NUITestSample/NUITestSample/examples/layouting/custom-layout-test.cs
test/NUITestSample/NUITestSample/examples/layouting/flex-layout-test.cs
test/NUITestSample/NUITestSample/examples/layouting/linear-layout-test.cs
test/NUITestSample/NUITestSample/examples/layouting/root-problem-fix-adding-several-layers.cs [new file with mode: 0755]

index f3fe522..d366ea5 100755 (executable)
@@ -29,10 +29,19 @@ namespace Tizen.NUI
     public class Layer : Container
     {
         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
+        private global::System.IntPtr rootLayoutIntPtr;
+        private global::System.Runtime.InteropServices.HandleRef rootLayoutCPtr;
 
         internal Layer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicPINVOKE.Layer_SWIGUpcast(cPtr), cMemoryOwn)
         {
             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
+            // Create a root layout (AbsoluteLayout) that is invisible to the user but enables layouts added to this Layer.
+            // Enables layouts added to the Layer to have a parent layout.  As parent layout is needed to store measure spec properties.
+            rootLayoutIntPtr = NDalicManualPINVOKE.Window_NewRootLayout();
+            // Store HandleRef used by Add()
+            rootLayoutCPtr = new global::System.Runtime.InteropServices.HandleRef(this, rootLayoutIntPtr);
+            // Add the root layout created above to this layer.
+            NDalicPINVOKE.Actor_Add( swigCPtr, rootLayoutCPtr );
         }
 
         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Layer obj)
@@ -57,7 +66,7 @@ namespace Tizen.NUI
                 {
                     oldParent.Remove(child);
                 }
-                NDalicPINVOKE.Actor_Add(swigCPtr, View.getCPtr(child));
+                NDalicPINVOKE.Actor_Add( rootLayoutCPtr , View.getCPtr(child));
                 if (NDalicPINVOKE.SWIGPendingException.Pending)
                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
                 Children.Add(child);
@@ -73,7 +82,7 @@ namespace Tizen.NUI
         /// <since_tizen> 4 </since_tizen>
         public override void Remove(View child)
         {
-            NDalicPINVOKE.Actor_Remove(swigCPtr, View.getCPtr(child));
+            NDalicPINVOKE.Actor_Remove( rootLayoutCPtr, View.getCPtr(child));
             if (NDalicPINVOKE.SWIGPendingException.Pending)
                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
 
index a6c838e..3748667 100755 (executable)
@@ -676,7 +676,6 @@ namespace Tizen.NUI
             // Core has been initialized, not when Stage is ready.
             if (_rootLayer == null && Window.IsInstalled())
             {
-                // Get RootLayer so can add RootLayout to it.
                 _rootLayer = new Layer(NDalicPINVOKE.Stage_GetRootLayer(stageCPtr), true);
                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
                 LayersChildren.Add(_rootLayer);
diff --git a/test/NUITestSample/NUITestSample/examples/layouting/custom-layout-root-layer-test.cs b/test/NUITestSample/NUITestSample/examples/layouting/custom-layout-root-layer-test.cs
new file mode 100755 (executable)
index 0000000..e4fa4ec
--- /dev/null
@@ -0,0 +1,193 @@
+using System;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+
+namespace CustomLayoutWithoutAbsoluteLayout
+{
+    public class CustomLayout : LayoutGroup
+    {
+        protected override void OnMeasure(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
+        {
+            var accumulatedWidth = new LayoutLength(0);
+            var maxHeight = 0;
+            var measuredWidth = new LayoutLength(0);
+            LayoutLength measuredHeight = new LayoutLength(0);
+            LayoutMeasureSpec.ModeType widthMode = widthMeasureSpec.Mode;
+            LayoutMeasureSpec.ModeType heightMode = heightMeasureSpec.Mode;
+
+            bool isWidthExact = (widthMode == LayoutMeasureSpec.ModeType.EXACTLY);
+            bool isHeightExact = (heightMode == LayoutMeasureSpec.ModeType.EXACTLY);
+
+            // In this layout we will:
+            //  Measuring the layout with the children in a horizontal configuration, one after another
+            //  Set the required width to be the accumulated width of our children
+            //  Set the required height to be the maximum height of any of our children
+
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                var childLayout = GetChildAt(i);
+                if (childLayout)
+                {
+                    MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec);
+                    accumulatedWidth += childLayout.MeasuredWidth;
+                    maxHeight = System.Math.Max(childLayout.MeasuredHeight.Value, maxHeight);
+                }
+            }
+
+            measuredHeight.Value = maxHeight;
+            measuredWidth = accumulatedWidth;
+
+            if (isWidthExact)
+            {
+                measuredWidth = new LayoutLength(widthMeasureSpec.Size);
+            }
+
+            if (isHeightExact)
+            {
+                measuredHeight = new LayoutLength(heightMeasureSpec.Size);
+            }
+
+            // Finally, call this method to set the dimensions we would like
+            SetMeasuredDimensions(new MeasuredSize(measuredWidth), new MeasuredSize(measuredHeight));
+        }
+
+        protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
+        {
+            LayoutLength childTop = new LayoutLength(0);
+            LayoutLength childLeft = new LayoutLength(0);
+
+            // We want to vertically align the children to the middle
+            var height = bottom - top;
+            var middle = height / 2;
+
+            // Horizontally align the children to the middle of the space they are given too
+            var width = right - left;
+            uint count = ChildCount;
+            var childIncrement = 0;
+            if (count > 0)
+            {
+                childIncrement = width.Value / System.Convert.ToInt32(count);
+            }
+            var center = childIncrement / 2;
+
+            // Check layout direction
+            var view = GetOwner();
+            ViewLayoutDirectionType layoutDirection = view.LayoutDirection;
+
+            for (uint i = 0; i < count; i++)
+            {
+                uint itemIndex;
+                // If RTL, then layout the last item first
+                if (layoutDirection == ViewLayoutDirectionType.RTL)
+                {
+                    itemIndex = count - 1 - i;
+                }
+                else
+                {
+                    itemIndex = i;
+                }
+
+                LayoutItem childLayout = GetChildAt(itemIndex);
+                if (childLayout)
+                {
+                    var childWidth = childLayout.MeasuredWidth;
+                    var childHeight = childLayout.MeasuredHeight;
+
+                    childTop = middle - (childHeight / 2);
+
+                    var leftPosition = childLeft + center - childWidth / 2;
+
+                    childLayout.Layout(leftPosition, childTop, leftPosition + childWidth, childTop + childHeight);
+                    childLeft += childIncrement;
+                }
+            }
+        }
+    }
+}
+
+namespace CustomLayoutWithoutAbsoluteLayout
+{
+    static class TestImages
+    {
+        //private const string resources = "./res";
+        public static string resources = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+        /// Child image filenames
+        public static readonly string[] s_images = new string[]
+        {
+            resources + "/images/application-icon-101.png",
+            resources + "/images/application-icon-102.png",
+            resources + "/images/application-icon-103.png",
+            resources + "/images/application-icon-104.png"
+        };
+    }
+
+    class Example : NUIApplication
+    {
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            Initialize();
+        }
+
+        private void Initialize()
+        {
+            // Change the background color of Window to White
+            Window window = Window.Instance;
+            window.BackgroundColor = Color.White;
+
+            //Layer layer = new Layer();
+
+            //window.AddLayer(layer);
+
+            // Create a new view
+            View customLayoutView = new View();
+            customLayoutView.Name = "CustomLayoutView";
+            customLayoutView.ParentOrigin = ParentOrigin.Center;
+            customLayoutView.PivotPoint = PivotPoint.Center;
+            customLayoutView.PositionUsesPivotPoint = true;
+            // Set our Custom Layout on the view
+            var layout = new CustomLayout();
+            customLayoutView.Layout = layout;
+            customLayoutView.SetProperty(LayoutItemWrapper.ChildProperty.WIDTH_SPECIFICATION, new PropertyValue(-2));  // -2 WRAP_CONTENT
+            customLayoutView.SetProperty(LayoutItemWrapper.ChildProperty.HEIGHT_SPECIFICATION, new PropertyValue(350));
+            customLayoutView.BackgroundColor = Color.Blue;
+            window.Add(customLayoutView);
+
+            // Add child image-views to the created view
+            foreach (String image in TestImages.s_images)
+            {
+                customLayoutView.Add(CreateChildImageView(image, new Size2D(100, 100)));
+            }
+        }
+
+        /// <summary>
+        /// Helper function to create ImageViews with given filename and size..<br />
+        /// </summary>
+        /// <param name="filename"> The filename of the image to use.</param>
+        /// <param name="size"> The size that the image should be loaded at.</param>
+        /// <returns>The created ImageView.</returns>
+        ImageView CreateChildImageView(String url, Size2D size)
+        {
+            ImageView imageView = new ImageView();
+            ImageVisual imageVisual = new ImageVisual();
+
+            imageVisual.URL = url;
+            imageVisual.DesiredHeight = size.Height;
+            imageVisual.DesiredWidth = size.Width;
+            imageView.Image = imageVisual.OutputVisualMap;
+
+            imageView.Name = "ImageView";
+            imageView.HeightResizePolicy = ResizePolicyType.Fixed;
+            imageView.WidthResizePolicy = ResizePolicyType.Fixed;
+            return imageView;
+        }
+
+        static void _Main(string[] args)
+        {
+            Example simpleLayout = new Example();
+            simpleLayout.Run(args);
+        }
+    }
+}
+
+
diff --git a/test/NUITestSample/NUITestSample/examples/layouting/custom-layout-test-2.cs b/test/NUITestSample/NUITestSample/examples/layouting/custom-layout-test-2.cs
new file mode 100755 (executable)
index 0000000..2d4faa3
--- /dev/null
@@ -0,0 +1,325 @@
+using System;
+using System.Threading;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using System.Collections.Generic;
+
+namespace CustomLayoutTest2
+{
+    static class Images
+    {
+        public static string resources = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+        public static readonly string[] s_images = new string[]
+        {
+            resources + "images/gallery-1.jpg",
+            resources + "images/gallery-2.jpg",
+            resources + "images/gallery-3.jpg",
+            resources + "images/gallery-4.jpg",
+            resources + "images/image-1.jpg",
+            resources + "images/image-2.jpg",
+            resources + "images/image-3.jpg",
+        };
+    }
+
+    public class CustomLayoutHorizental : LayoutGroup
+    {
+        private static LayoutItem[] childLayouts = new LayoutItem[10];
+
+        public CustomLayoutHorizental()
+        {
+            Console.WriteLine($"CustomLayoutHorizental() constructor!");
+        }
+        protected override void OnMeasure(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
+        {
+            Console.WriteLine($"CustomLayoutHorizental OnMeasure() START");
+
+            var accumulatedWidth = new LayoutLength(0);
+            var maxHeight = new LayoutLength(0);
+
+            // this is needed, otherwise the child's LayoutItem is garbage collected!
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                childLayouts[i] = GetChildAt(i);
+            }
+
+            // In this layout we will:
+            //  Measuring the layout with the children in a horizontal configuration, one after another
+            //  Set the required width to be the accumulated width of our children
+            //  Set the required height to be the maximum height of any of our children
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                var childLayout = childLayouts[i];
+
+                Console.WriteLine($"child count={ChildCount}, i={i}");
+                if (childLayout)
+                {
+                    MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec);
+                    accumulatedWidth += childLayout.MeasuredWidth;
+                    maxHeight.Value = System.Math.Max(childLayout.MeasuredHeight.Value, maxHeight.Value);
+                    Console.WriteLine($"child layout is not NULL! accumulatedWidth={accumulatedWidth.Value}, i={i}");
+                }
+            }
+            // Finally, call this method to set the dimensions we would like
+            SetMeasuredDimensions(new MeasuredSize(accumulatedWidth), new MeasuredSize(maxHeight));
+            Console.WriteLine($"CustomLayoutHorizental OnMeasure() accumlated width={accumulatedWidth.Value}, maxHeight={maxHeight.Value} END");
+        }
+        protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
+        {
+            Console.WriteLine($"CustomLayoutHorizental OnLayout() START");
+
+            LayoutLength childTop = new LayoutLength(0);
+            LayoutLength childLeft = new LayoutLength(0);
+
+            // We want to vertically align the children to the middle
+            var height = bottom - top;
+            var middle = height / 2;
+
+            // Horizontally align the children to the middle of the space they are given too
+            var width = right - left;
+            uint count = ChildCount;
+            Console.WriteLine($"child count={count}");
+
+            var childIncrement = 0;
+            if (count > 0)
+            {
+                childIncrement = width.Value / System.Convert.ToInt32(count);
+            }
+            var center = childIncrement / 2;
+
+            // Check layout direction
+            var view = GetOwner();
+            ViewLayoutDirectionType layoutDirection = view.LayoutDirection;
+
+            // this is needed, otherwise the child's LayoutItem is garbage collected!
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                childLayouts[i] = GetChildAt(i);
+            }
+
+            for (uint i = 0; i < count; i++)
+            {
+                uint itemIndex;
+                // If RTL, then layout the last item first
+                if (layoutDirection == ViewLayoutDirectionType.RTL)
+                {
+                    itemIndex = count - 1 - i;
+                }
+                else
+                {
+                    itemIndex = i;
+                }
+
+                var childLayout = childLayouts[itemIndex];
+                if (childLayout)
+                {
+                    var childWidth = childLayout.MeasuredWidth;
+                    var childHeight = childLayout.MeasuredHeight;
+
+                    childTop = middle - (childHeight / 2);
+
+                    var leftPosition = childLeft + center - childWidth / 2;
+
+                    childLayout.Layout(leftPosition, childTop, leftPosition + childWidth, childTop + childHeight);
+                    childLeft += childIncrement;
+
+                    Console.WriteLine($"child layout is not NULL! childWidth={childWidth.Value}, i={i}");
+                }
+            }
+            Console.WriteLine($"CustomLayoutHorizental OnLayout() END");
+        }
+    }
+
+    public class CustomLayoutVertical : LayoutGroup
+    {
+        public CustomLayoutVertical()
+        {
+            this.LayoutAnimate = true;
+        }
+
+        private static LayoutItem[] childLayouts = new LayoutItem[10];
+
+        protected override void OnMeasure(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
+        {
+            var accumulatedHeight = new LayoutLength(0);
+            var maxWidth = new LayoutLength(0);
+
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                childLayouts[i] = GetChildAt(i);
+            }
+
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                var childLayout = childLayouts[i];
+                if (childLayout)
+                {
+                    MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec);
+                    accumulatedHeight += childLayout.MeasuredHeight;
+                    maxWidth.Value = System.Math.Max(childLayout.MeasuredWidth.Value, maxWidth.Value);
+                    Console.WriteLine($"CustomLayoutVertical child layout is not NULL! accumulatedHeight={accumulatedHeight.Value}, i={i}");
+                }
+            }
+            SetMeasuredDimensions(new MeasuredSize(maxWidth), new MeasuredSize(accumulatedHeight));
+            Console.WriteLine($"CustomLayoutVertical OnMeasure() max width={maxWidth.Value}, accumulated Height={accumulatedHeight.Value}");
+        }
+
+        protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
+        {
+            LayoutLength childTop = new LayoutLength(0);
+            LayoutLength childLeft = new LayoutLength(0);
+
+            var height = bottom - top;
+            var width = right - left;
+            var middle = width / 2;
+
+            uint count = ChildCount;
+            var childIncrement = 0;
+            if (count > 0)
+            {
+                childIncrement = height.Value / System.Convert.ToInt32(count);
+            }
+            var center = childIncrement / 2;
+
+            var view = GetOwner();
+            ViewLayoutDirectionType layoutDirection = view.LayoutDirection;
+
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                childLayouts[i] = GetChildAt(i);
+            }
+
+            for (uint i = 0; i < count; i++)
+            {
+                uint itemIndex;
+                if (layoutDirection == ViewLayoutDirectionType.RTL)
+                {
+                    itemIndex = count - 1 - i;
+                }
+                else
+                {
+                    itemIndex = i;
+                }
+
+                var childLayout = childLayouts[itemIndex];
+                if (childLayout)
+                {
+                    var childWidth = childLayout.MeasuredWidth;
+                    var childHeight = childLayout.MeasuredHeight;
+
+                    childLeft = middle - (childWidth / 2);
+
+                    var topPosition = childTop + center - childHeight / 2;
+
+                    childLayout.Layout(childLeft, topPosition, childLeft + childWidth, topPosition + childHeight);
+                    childTop += childIncrement;
+
+                    Console.WriteLine($"CustomLayoutVertical child layout is not NULL! childWidth={childWidth.Value}, i={i}");
+                }
+            }
+            Console.WriteLine($"CustomLayoutVertical OnLayout() END");
+        }
+    }
+    
+    class Example : NUIApplication
+    {
+        public Example() : base()
+        {
+            Console.WriteLine("Example()!");
+        }
+
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            Initialize();
+        }
+
+        static View linearContainer;
+        const int MAX_CHILDREN = 7;
+        static ImageView[] imageViews = new ImageView[MAX_CHILDREN];
+        static CustomLayoutHorizental horizontalLayout;
+        static CustomLayoutVertical verticalLayout;
+
+        private void Initialize()
+        {
+            Console.WriteLine("Initialize()!");
+            Window window = Window.Instance;
+            window.BackgroundColor = Color.Green;
+
+            linearContainer = new View();
+            linearContainer.PositionUsesPivotPoint = true;
+            linearContainer.PivotPoint = PivotPoint.Center;
+            linearContainer.ParentOrigin = ParentOrigin.Center;
+            linearContainer.KeyEvent += OnKeyEvent;
+            linearContainer.Focusable = true;
+
+            for (int index = 0; index < MAX_CHILDREN - 3; index++)
+            {
+                imageViews[index] = new ImageView(Images.s_images[index]);
+                imageViews[index].WidthSpecificationFixed = 150;
+                imageViews[index].HeightSpecificationFixed = 100;
+                linearContainer.Add(imageViews[index]);
+            }
+            for (int index = MAX_CHILDREN - 3; index < MAX_CHILDREN; index++)
+            {
+                imageViews[index] = new ImageView(Images.s_images[index]);
+                imageViews[index].WidthSpecificationFixed = 150;
+                imageViews[index].HeightSpecificationFixed = 100;
+                imageViews[index].Name = "t_image" + (index - 3);
+            }
+
+            horizontalLayout = new CustomLayoutHorizental();
+            verticalLayout = new CustomLayoutVertical();
+            horizontalLayout.LayoutAnimate = true;
+            linearContainer.Layout = horizontalLayout;
+
+            window.Add(linearContainer);
+            FocusManager.Instance.SetCurrentFocusView(linearContainer);
+            FocusManager.Instance.FocusIndicator = new View();
+        }
+
+        int cnt1 = 1;
+        private bool OnKeyEvent(object source, View.KeyEventArgs e)
+        {
+            if (e.Key.State == Key.StateType.Down)
+            {
+                Console.WriteLine($"key pressed name={e.Key.KeyPressedName}");
+                switch (e.Key.KeyPressedName)
+                {
+                    case "Right":
+                        if (cnt1 < 4 && cnt1 > 0)
+                        {
+                            linearContainer.Add(imageViews[cnt1 + 3]);
+                            cnt1++;
+                        }
+                        break;
+
+                    case "Left":
+                        if (cnt1 - 1 < 4 && cnt1 - 1 > 0)
+                        {
+                            View tmp = linearContainer.FindChildByName("t_image" + (cnt1 - 1));
+                            if (tmp != null)
+                            {
+                                linearContainer.Remove(tmp);
+                                cnt1--;
+                            }
+                        }
+                        break;
+
+                    case "Up":
+                        linearContainer.Layout = verticalLayout;
+                        break;
+
+                    case "Down":
+                        linearContainer.Layout = horizontalLayout;
+                        break;
+
+                    case "Return":
+                        if (linearContainer.LayoutDirection == ViewLayoutDirectionType.LTR) { linearContainer.LayoutDirection = ViewLayoutDirectionType.RTL; }
+                        else { linearContainer.LayoutDirection = ViewLayoutDirectionType.LTR; }
+                        break;
+                }
+            }
+            return true;
+        }
+    }
+}
index e2ae421..d92d463 100755 (executable)
@@ -4,7 +4,7 @@ using Tizen.NUI;
 using Tizen.NUI.BaseComponents;
 using System.Collections.Generic;
 
-namespace NUILayoutSample
+namespace CustomLayoutByAbsoluteLayout
 {
     static class Images
     {
@@ -219,9 +219,7 @@ namespace NUILayoutSample
             Console.WriteLine($"CustomLayoutVertical OnLayout() END");
         }
     }
-
-
-
+    
     class Example : NUIApplication
     {
         public Example() : base()
@@ -253,7 +251,6 @@ namespace NUILayoutSample
             rootLayoutView.HeightSpecificationFixed = 1000;
             rootLayoutView.Position = new Position(0, 0, 0);
             rootLayoutView.BackgroundColor = Color.Magenta;
-            window.Add(rootLayoutView);
 
             linearContainer = new View();
             linearContainer.PositionUsesPivotPoint = true;
@@ -263,12 +260,6 @@ namespace NUILayoutSample
             linearContainer.KeyEvent += OnKeyEvent;
             linearContainer.Focusable = true;
 
-
-            rootLayoutView.Add(linearContainer);
-            //window.Add(linearContainer);
-            FocusManager.Instance.SetCurrentFocusView(linearContainer);
-            FocusManager.Instance.FocusIndicator = new View();
-
             for (int index = 0; index < MAX_CHILDREN - 3; index++)
             {
                 imageViews[index] = new ImageView(Images.s_images[index]);
@@ -291,6 +282,11 @@ namespace NUILayoutSample
 
             rootLayout = new AbsoluteLayout();
             rootLayoutView.Layout = rootLayout;
+
+            rootLayoutView.Add(linearContainer);
+            window.Add(rootLayoutView);
+            FocusManager.Instance.SetCurrentFocusView(linearContainer);
+            FocusManager.Instance.FocusIndicator = new View();
         }
 
         int cnt1 = 1;
@@ -337,12 +333,5 @@ namespace NUILayoutSample
             }
             return true;
         }
-
-        [STAThread]
-        static void Main(string[] args)
-        {
-            Example layoutSample = new Example();
-            layoutSample.Run(args);
-        }
     }
 }
index 58d81c4..d09ab9a 100755 (executable)
@@ -74,12 +74,15 @@ namespace NUIFlexLayoutSample
             window.KeyEvent += OnKeyEvent;
         }
 
-        int cnt1 = 1;
+        int cnt1 = 1, cnt2;
         private void OnKeyEvent(object source, Window.KeyEventArgs e)
         {
             if (e.Key.State == Key.StateType.Down)
             {
                 Console.WriteLine($"key pressed name={e.Key.KeyPressedName}");
+                var tmpLayout = flexContainer.Layout as FlexLayout;
+                cnt2++;
+
                 switch (e.Key.KeyPressedName)
                 {
                     case "Right":
@@ -122,16 +125,31 @@ namespace NUIFlexLayoutSample
                         break;
 
                     case "1":
-                        var tmpLayout = flexContainer.Layout as FlexLayout;
-                        if (tmpLayout.WrapType == FlexLayout.FlexWrapType.NoWrap) { tmpLayout.WrapType = FlexLayout.FlexWrapType.Wrap; }
-                        else { tmpLayout.WrapType = FlexLayout.FlexWrapType.NoWrap; }
+                        var dir = cnt2 % 4;
+                        tmpLayout.Direction = (FlexLayout.FlexDirection)dir;
+                        break;
+
+                    case "2":
+                        var justi = cnt2 % 5;
+                        tmpLayout.Justification = (FlexLayout.FlexJustification)justi;
+                        break;
+
+                    case "3":
+                        var wrap = cnt2 % 2;
+                        tmpLayout.WrapType = (FlexLayout.FlexWrapType)wrap;
+                        break;
+
+                    case "4":
+                        var align = cnt2 % 5;
+                        tmpLayout.ItemsAlignment = (FlexLayout.AlignmentType)align;
                         break;
+
                 }
             }
         }
 
         [STAThread]
-        static void Main(string[] args)
+        static void _Main(string[] args)
         {
             Example layoutSample = new Example();
             layoutSample.Run(args);
index 9493a1c..7115f01 100755 (executable)
@@ -2,8 +2,10 @@
 using System.Threading;
 using Tizen.NUI;
 using Tizen.NUI.BaseComponents;
+using System.Runtime.InteropServices;
 
-namespace NUILayoutSample
+
+namespace NUILinearLayoutSample
 {
     static class Images
     {
@@ -36,6 +38,8 @@ namespace NUILayoutSample
         View rootLayoutView, linearContainer;
         const int MAX_CHILDREN = 7;
         ImageView[] imageViews = new ImageView[MAX_CHILDREN];
+        LinearLayout linearlayout;
+        LayoutSize layoutsize;
         private void Initialize()
         {
             Console.WriteLine("Initialize()!");
@@ -47,7 +51,7 @@ namespace NUILayoutSample
             rootLayoutView.HeightSpecificationFixed = 1000;
             rootLayoutView.Position = new Position(0, 0, 0);
             rootLayoutView.BackgroundColor = Color.Green;
-            window.Add(rootLayoutView);
+            //window.Add(rootLayoutView);
 
             linearContainer = new View();
             linearContainer.PositionUsesPivotPoint = true;
@@ -57,9 +61,6 @@ namespace NUILayoutSample
             linearContainer.KeyEvent += OnKeyEvent;
             linearContainer.Focusable = true;
 
-            rootLayoutView.Add(linearContainer);
-            FocusManager.Instance.SetCurrentFocusView(linearContainer);
-
             for (int index = 0; index < MAX_CHILDREN - 3; index++)
             {
                 imageViews[index] = new ImageView(Images.s_images[index]);
@@ -78,16 +79,36 @@ namespace NUILayoutSample
                 //imageViews[index].HeightSpecification = ChildLayoutData.MatchParent;
             }
 
-            var layout = new LinearLayout();
-            layout.LayoutAnimate = true;
-            layout.LinearOrientation = LinearLayout.Orientation.Vertical;
-            //layout.CellPadding = new LayoutSize(50, 50);
+            layoutsize = new LayoutSize(50, 50);
+            Console.WriteLine($"## layoutsize width={layoutsize.Width}, height={layoutsize.Height}");
+
+            linearlayout = new LinearLayout();
+            linearlayout.LayoutAnimate = true;
+            linearlayout.LinearOrientation = LinearLayout.Orientation.Vertical;
+
+            Console.WriteLine($"## TP1");
+            //Console.WriteLine($"linearlayout p=0x{LinearLayout.getCPtr(linearlayout).Handle.ToInt64():X},  layoutsize p=0x{LayoutSize.getCPtr(layoutsize).Handle.ToInt64():X}");
+
+            linearlayout.CellPadding = layoutsize;
+            Console.WriteLine($"## TP2");
             linearContainer.WidthSpecification = ChildLayoutData.WrapContent;
             linearContainer.HeightSpecification = ChildLayoutData.WrapContent;
-            linearContainer.Layout = layout;
+            Console.WriteLine($"## TP3");
+            linearContainer.Layout = linearlayout;
+            Console.WriteLine($"## TP4");
+
+            //var __layout = linearContainer.Layout as LinearLayout;
+            var __layout = linearlayout;
+            Console.WriteLine($"##  layout orientation={__layout.LinearOrientation}");
+            var __cellpadding = __layout.CellPadding;
+            Console.WriteLine($"##  layout cellpadding width={__cellpadding.Width}, height={ __cellpadding.Height}");
 
-            var rootLayout = new AbsoluteLayout();
-            rootLayoutView.Layout = rootLayout;
+            //var rootLayout = new AbsoluteLayout();
+            //rootLayoutView.Layout = rootLayout;
+            //rootLayoutView.Add(linearContainer);
+
+            window.Add(linearContainer);
+            FocusManager.Instance.SetCurrentFocusView(linearContainer);
         }
 
         int cnt1 = 1;
@@ -129,6 +150,7 @@ namespace NUILayoutSample
                         var horizon = new LinearLayout();
                         horizon.LayoutAnimate = true;
                         horizon.LinearOrientation = LinearLayout.Orientation.Horizontal;
+                        horizon.CellPadding = new LayoutSize(200, 200);
                         linearContainer.Layout = horizon;
                         break;
 
@@ -142,7 +164,7 @@ namespace NUILayoutSample
         }
 
         [STAThread]
-        static void Main(string[] args)
+        static void _Main(string[] args)
         {
             Example layoutSample = new Example();
             layoutSample.Run(args);
@@ -150,3 +172,7 @@ namespace NUILayoutSample
 
     }
 }
+
+
+
+
diff --git a/test/NUITestSample/NUITestSample/examples/layouting/root-problem-fix-adding-several-layers.cs b/test/NUITestSample/NUITestSample/examples/layouting/root-problem-fix-adding-several-layers.cs
new file mode 100755 (executable)
index 0000000..840ab1e
--- /dev/null
@@ -0,0 +1,244 @@
+using System;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.UIComponents;
+
+namespace RootProblemFixAddingSeveralLayers
+{
+    public class CustomLayout : LayoutGroup
+    {
+        protected override void OnMeasure(LayoutMeasureSpec widthMeasureSpec, LayoutMeasureSpec heightMeasureSpec)
+        {
+            var accumulatedWidth = new LayoutLength(0);
+            var maxHeight = 0;
+            var measuredWidth = new LayoutLength(0);
+            LayoutLength measuredHeight = new LayoutLength(0);
+            LayoutMeasureSpec.ModeType widthMode = widthMeasureSpec.Mode;
+            LayoutMeasureSpec.ModeType heightMode = heightMeasureSpec.Mode;
+
+            bool isWidthExact = (widthMode == LayoutMeasureSpec.ModeType.EXACTLY);
+            bool isHeightExact = (heightMode == LayoutMeasureSpec.ModeType.EXACTLY);
+
+            // In this layout we will:
+            //  Measuring the layout with the children in a horizontal configuration, one after another
+            //  Set the required width to be the accumulated width of our children
+            //  Set the required height to be the maximum height of any of our children
+
+            for (uint i = 0; i < ChildCount; ++i)
+            {
+                var childLayout = GetChildAt(i);
+                if (childLayout)
+                {
+                    MeasureChild(childLayout, widthMeasureSpec, heightMeasureSpec);
+                    accumulatedWidth += childLayout.MeasuredWidth;
+                    maxHeight = System.Math.Max(childLayout.MeasuredHeight.Value, maxHeight);
+                }
+            }
+
+            measuredHeight.Value = maxHeight;
+            measuredWidth = accumulatedWidth;
+
+            if (isWidthExact)
+            {
+                measuredWidth = new LayoutLength(widthMeasureSpec.Size);
+            }
+
+            if (isHeightExact)
+            {
+                measuredHeight = new LayoutLength(heightMeasureSpec.Size);
+            }
+
+            // Finally, call this method to set the dimensions we would like
+            SetMeasuredDimensions(new MeasuredSize(measuredWidth), new MeasuredSize(measuredHeight));
+        }
+
+        protected override void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
+        {
+            LayoutLength childTop = new LayoutLength(0);
+            LayoutLength childLeft = new LayoutLength(0);
+
+            // We want to vertically align the children to the middle
+            var height = bottom - top;
+            var middle = height / 2;
+
+            // Horizontally align the children to the middle of the space they are given too
+            var width = right - left;
+            uint count = ChildCount;
+            var childIncrement = 0;
+            if (count > 0)
+            {
+                childIncrement = width.Value / System.Convert.ToInt32(count);
+            }
+            var center = childIncrement / 2;
+
+            // Check layout direction
+            var view = GetOwner();
+            ViewLayoutDirectionType layoutDirection = view.LayoutDirection;
+
+            for (uint i = 0; i < count; i++)
+            {
+                uint itemIndex;
+                // If RTL, then layout the last item first
+                if (layoutDirection == ViewLayoutDirectionType.RTL)
+                {
+                    itemIndex = count - 1 - i;
+                }
+                else
+                {
+                    itemIndex = i;
+                }
+
+                LayoutItem childLayout = GetChildAt(itemIndex);
+                if (childLayout)
+                {
+                    var childWidth = childLayout.MeasuredWidth;
+                    var childHeight = childLayout.MeasuredHeight;
+
+                    childTop = middle - (childHeight / 2);
+
+                    var leftPosition = childLeft + center - childWidth / 2;
+
+                    childLayout.Layout(leftPosition, childTop, leftPosition + childWidth, childTop + childHeight);
+                    childLeft += childIncrement;
+                }
+            }
+        }
+    }
+
+    static class TestImages
+    {
+        public static string resources = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+        //private const string resources = "./res";
+        /// Child image filenames
+        public static readonly string[] s_images = new string[]
+        {
+            resources + "/images/application-icon-101.png",
+            resources + "/images/application-icon-102.png",
+            resources + "/images/application-icon-103.png",
+            resources + "/images/application-icon-104.png"
+        };
+    }
+
+    class Example : NUIApplication
+    {
+        private Layer _layer;
+        private Layer _layer2;
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            Initialize();
+        }
+        private void Initialize()
+        {
+            // Change the background color of Window to White
+            Window window = Window.Instance;
+            window.BackgroundColor = Color.White;
+            // Create first new view
+            View view = new View();
+            view.Name = "CustomLayoutView";
+            //view.ParentOrigin = ParentOrigin.Center;
+            //view.PivotPoint = PivotPoint.Center;
+            //view.PositionUsesPivotPoint = true;
+            // Set our Custom Layout on the first view
+            var layout = new CustomLayout();
+            view.Layout = layout;
+            view.WidthSpecification = ChildLayoutData.WrapContent;
+            view.HeightSpecificationFixed = 350;
+            view.BackgroundColor = Color.Blue;
+
+            // Create second View
+            View littleView = new View();
+            littleView.Name = "LittleView";
+            // Set our Custom Layout on the little view
+            var layout2 = new CustomLayout();
+            littleView.Layout = layout2;
+            littleView.SetProperty(LayoutItemWrapper.ChildProperty.WIDTH_SPECIFICATION, new PropertyValue(-2));
+            littleView.SetProperty(LayoutItemWrapper.ChildProperty.HEIGHT_SPECIFICATION, new PropertyValue(-2));
+            littleView.BackgroundColor = Color.Red;
+            littleView.Position2D = new Position2D(50, 50);
+            // Add second View to a Layer
+            _layer2 = new Layer();
+            window.AddLayer(_layer2);
+            _layer2.Add(littleView);
+
+            // Create single single ImageView in it's own Layer
+            _layer = new Layer();
+            window.AddLayer(_layer);
+            //_layer.Add(CreateChildImageView(TestImages.s_images[1], new Size2D(100, 100)));
+            _layer.Add(view);
+            // Initially single ImageView is not on top.
+            _layer2.Raise();
+            // Add an ImageView directly to window
+            window.Add(CreateChildImageView(TestImages.s_images[2], new Size2D(200, 200)));
+            // Add child image-views to the created view
+            foreach (String image in TestImages.s_images)
+            {
+                view.Add(CreateChildImageView(image, new Size2D(100, 100)));
+                littleView.Add(CreateChildImageView(image, new Size2D(50, 50)));
+            }
+            // Example info
+            TextLabel label = new TextLabel("Blue icon in a layer");
+            label.ParentOrigin = ParentOrigin.TopCenter;
+            label.Position2D = new Position2D(-50, 0);
+            window.Add(label);
+            // Add button to Raise or Lower the single ImageView
+            PushButton button = new PushButton();
+            button.LabelText = "Raise Layer";
+            button.ParentOrigin = ParentOrigin.BottomCenter;
+            button.PivotPoint = PivotPoint.BottomCenter;
+            button.PositionUsesPivotPoint = true;
+            window.Add(button);
+
+            button.Focusable = true;
+            button.KeyEvent += Button_KeyEvent;
+            FocusManager.Instance.SetCurrentFocusView(button);
+        }
+
+        private bool Button_KeyEvent(object source, View.KeyEventArgs e)
+        {
+            PushButton sender = source as PushButton;
+            if(e.Key.State == Key.StateType.Down)
+            {
+                if (sender.LabelText == "Raise Layer")
+                {
+                    _layer.RaiseToTop();
+                    sender.LabelText = "Lower Layer";
+                }
+                else
+                {
+                    sender.LabelText = "Raise Layer";
+                    _layer.LowerToBottom();
+                }
+            }
+            return true;
+        }
+
+        /// <summary>
+        /// Helper function to create ImageViews with given filename and size..<br />
+        /// </summary>
+        /// <param name="filename"> The filename of the image to use.</param>
+        /// <param name="size"> The size that the image should be loaded at.</param>
+        /// <returns>The created ImageView.</returns>
+        ImageView CreateChildImageView(String url, Size2D size)
+        {
+            ImageView imageView = new ImageView();
+            ImageVisual imageVisual = new ImageVisual();
+            imageVisual.URL = url;
+            imageVisual.DesiredHeight = size.Height;
+            imageVisual.DesiredWidth = size.Width;
+            imageView.Image = imageVisual.OutputVisualMap;
+            imageView.Name = "ImageView";
+            imageView.HeightResizePolicy = ResizePolicyType.Fixed;
+            imageView.WidthResizePolicy = ResizePolicyType.Fixed;
+            return imageView;
+        }
+
+        static void _Main(string[] args)
+        {
+            Example app = new Example();
+            app.Run(args);
+        }
+    }
+}
+
+