[NUI] Support Layout for Multi-Window
authorJaehyun Cho <jae_hyun.cho@samsung.com>
Mon, 10 Jan 2022 11:33:36 +0000 (20:33 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 19 Jan 2022 05:29:33 +0000 (14:29 +0900)
Previously, Layouts in the default Window were supported.

Now, Layouts in all Windows are supported.

To enable Multi-Window, Window.IsSupportedMultiWindow() should be true
and the following code should not be executed.

Information.TryGetValue("http://tizen.org/feature/opengles.surfaceless_context", out isSupported);

src/Tizen.NUI/src/internal/Layouting/LayoutController.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs
src/Tizen.NUI/src/public/BaseComponents/ViewPublicMethods.cs
src/Tizen.NUI/src/public/Common/Layer.cs
src/Tizen.NUI/src/public/Window/Window.cs
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/MultiWindowLayoutSample.cs [new file with mode: 0644]

index adb9e41..4373ee1 100755 (executable)
@@ -35,7 +35,7 @@ namespace Tizen.NUI
         private float windowHeight;
         private LayoutTransitionManager transitionManager;
 
-        private bool subscribed;
+        private int layoutCount = 0;
 
         /// <summary>
         /// Constructs a LayoutController which controls the measuring and layouting.<br />
@@ -59,11 +59,7 @@ namespace Tizen.NUI
                 return;
             }
 
-            if (subscribed)
-            {
-                ProcessorController.Instance.LayoutProcessorEvent -= Process;
-                subscribed = false;
-            }
+            LayoutCount = 0;
 
             //Release your own unmanaged resources here.
             //You should not access any managed member here except static instance.
@@ -154,18 +150,6 @@ namespace Tizen.NUI
         }
 
         /// <summary>
-        /// Create and set process callback
-        /// </summary>
-        internal void CreateProcessCallback()
-        {
-            if (!subscribed)
-            {
-                ProcessorController.Instance.LayoutProcessorEvent += Process;
-                subscribed = true;
-            }
-        }
-
-        /// <summary>
         /// Add transition data for a LayoutItem to the transition stack.
         /// </summary>
         /// <param name="transitionDataEntry">Transition data for a LayoutItem.</param>
@@ -183,6 +167,36 @@ namespace Tizen.NUI
             transitionManager.AddToRemovalStack(itemToRemove);
         }
 
+        /// <summary>
+        /// The number of layouts.
+        /// This can be used to set/unset Process callback to calculate Layout.
+        /// </summary>
+        internal int LayoutCount
+        {
+            get
+            {
+                return layoutCount;
+            }
+
+            set
+            {
+                if (layoutCount == value) return;
+
+                if (value < 0) throw new global::System.ArgumentOutOfRangeException(nameof(LayoutCount), "LayoutCount(" + LayoutCount + ") should not be less than zero");
+
+                if (layoutCount == 0)
+                {
+                    ProcessorController.Instance.LayoutProcessorEvent += Process;
+                }
+                else if (value == 0)
+                {
+                    ProcessorController.Instance.LayoutProcessorEvent -= Process;
+                }
+
+                layoutCount = value;
+            }
+        }
+
         // Traverse the tree looking for a root node that is a layout.
         // Once found, it's children can be assigned Layouts and the Measure process started.
         private void FindRootLayouts(View rootNode, float parentWidth, float parentHeight)
index d62c459..ae02bde 100755 (executable)
@@ -66,6 +66,7 @@ namespace Tizen.NUI.BaseComponents
         private Vector3 internalScale = null;
         private Size internalSize = null;
         private Size2D internalSize2D = null;
+        private int layoutCount = 0;
 
         static View()
         {
index d154a4b..f9b752e 100755 (executable)
@@ -189,7 +189,8 @@ namespace Tizen.NUI.BaseComponents
 
         internal void SetLayout(LayoutItem layout)
         {
-            Window.Instance.LayoutController.CreateProcessCallback();
+            LayoutCount++;
+
             this.layout = layout;
             this.layout?.AttachToOwner(this);
             this.layout?.RequestLayout();
@@ -330,6 +331,45 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
+        /// The number of layouts including view's layout and children's layouts.
+        /// This can be used to set/unset Process callback to calculate Layout.
+        /// </summary>
+        internal int LayoutCount
+        {
+            get
+            {
+                return layoutCount;
+            }
+
+            set
+            {
+                if (layoutCount == value) return;
+
+                if (value < 0) throw new global::System.ArgumentOutOfRangeException(nameof(LayoutCount), "LayoutCount(" + LayoutCount + ") should not be less than zero");
+
+                int diff = value - layoutCount;
+                layoutCount = value;
+
+                if (InternalParent != null)
+                {
+                    var parentView = InternalParent as View;
+                    if (parentView != null)
+                    {
+                        parentView.LayoutCount += diff;
+                    }
+                    else
+                    {
+                        var parentLayer = InternalParent as Layer;
+                        if (parentLayer != null)
+                        {
+                            parentLayer.LayoutCount += diff;
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
         /// Indicates that this View should listen Touch event to handle its ControlState.
         /// </summary>
         private bool enableControlState = false;
@@ -992,6 +1032,7 @@ namespace Tizen.NUI.BaseComponents
 
             Children.Remove(child);
             child.InternalParent = null;
+            LayoutCount -= child.LayoutCount;
 
             RemoveChildBindableObject(child);
 
@@ -1010,6 +1051,8 @@ namespace Tizen.NUI.BaseComponents
         /// </summary>
         internal void ResetLayout()
         {
+            LayoutCount--;
+
             layout = null;
         }
 
@@ -1188,6 +1231,8 @@ namespace Tizen.NUI.BaseComponents
                 view.InternalParent = null;
             }
 
+            LayoutCount = 0;
+
             NUILog.Debug($"[Dispose] View.Dispose({type}) END");
             NUILog.Debug($"=============================");
 
index 9e31264..60f2974 100755 (executable)
@@ -151,6 +151,7 @@ namespace Tizen.NUI.BaseComponents
                     oldParent.Remove(child);
                 }
                 child.InternalParent = this;
+                LayoutCount += child.LayoutCount;
 
                 Interop.Actor.Add(SwigCPtr, View.getCPtr(child));
 
index 494286b..2b54150 100755 (executable)
@@ -29,6 +29,8 @@ namespace Tizen.NUI
     {
         private Window window;
 
+        private int layoutCount = 0;
+
         /// <summary>
         /// Creates a Layer object.
         /// </summary>
@@ -45,6 +47,22 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// Dispose Explicit or Implicit
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (Disposed)
+            {
+                return;
+            }
+
+            LayoutCount = 0;
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
         /// Enumeration for the behavior of the layer.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
@@ -299,6 +317,9 @@ namespace Tizen.NUI
                 {
                     child.InternalParent = this;
                 }
+
+                LayoutCount += child.LayoutCount;
+
                 Interop.Actor.Add(SwigCPtr, View.getCPtr(child));
                 if (NDalicPINVOKE.SWIGPendingException.Pending)
                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
@@ -326,6 +347,8 @@ namespace Tizen.NUI
 
             Children.Remove(child);
             child.InternalParent = null;
+
+            LayoutCount -= child.LayoutCount;
         }
 
         /// <summary>
@@ -696,7 +719,19 @@ namespace Tizen.NUI
 
         internal void SetWindow(Window win)
         {
+            if (window == win) return;
+
+            if (window != null)
+            {
+                window.LayoutController.LayoutCount -= LayoutCount;
+            }
+
             window = win;
+
+            if (window != null)
+            {
+                window.LayoutController.LayoutCount += LayoutCount;
+            }
         }
 
         internal uint GetId()
@@ -707,6 +742,33 @@ namespace Tizen.NUI
             return ret;
         }
 
+        /// <summary>
+        /// The number of layouts of children views.
+        /// This can be used to set/unset Process callback to calculate Layout.
+        /// </summary>
+        internal int LayoutCount
+        {
+            get
+            {
+                return layoutCount;
+            }
+
+            set
+            {
+                if (layoutCount == value) return;
+
+                if (value < 0) throw new global::System.ArgumentOutOfRangeException(nameof(LayoutCount), "LayoutCount(" + LayoutCount + ") should not be less than zero");
+
+                int diff = value - layoutCount;
+                layoutCount = value;
+
+                if (window != null)
+                {
+                    window.LayoutController.LayoutCount += diff;
+                }
+            }
+        }
+
         /// This will not be public opened.
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
index 6d28eb1..18ad468 100644 (file)
@@ -901,6 +901,8 @@ namespace Tizen.NUI
             if (null != view)
             {
                 view.InternalParent = this.GetRootLayer();
+
+                this.GetRootLayer().LayoutCount += view.LayoutCount;
             }
         }
 
@@ -916,6 +918,8 @@ namespace Tizen.NUI
             if (null != view)
             {
                 view.InternalParent = null;
+
+                this.GetRootLayer().LayoutCount -= view.LayoutCount;
             }
         }
 
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/MultiWindowLayoutSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/MultiWindowLayoutSample.cs
new file mode 100644 (file)
index 0000000..aee747a
--- /dev/null
@@ -0,0 +1,98 @@
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace Tizen.NUI.Samples
+{
+    public class MultiWindowLayoutSample : IExample
+    {
+        private Window mainWindow = null;
+        private Window subWindow = null;
+        private View mainView = null;
+        private View subView = null;
+
+        public void Activate()
+        {
+            mainWindow = NUIApplication.GetDefaultWindow();
+
+            mainView = new View()
+            {
+                Layout = new LinearLayout(),
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                BackgroundColor = Color.White
+            };
+            mainWindow.Add(mainView);
+
+            var mainChild = new View()
+            {
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                BackgroundColor = Color.Red
+            };
+            mainView.Add(mainChild);
+
+            var mainChild2 = new View()
+            {
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                BackgroundColor = Color.Yellow
+            };
+            mainView.Add(mainChild2);
+
+            subWindow = new Window();
+
+            subView = new View()
+            {
+                Layout = new LinearLayout(),
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                BackgroundColor = Color.White
+            };
+            subWindow.Add(subView);
+
+            var subChild = new View()
+            {
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                BackgroundColor = Color.Green
+            };
+            subView.Add(subChild);
+
+            var subChild2 = new View()
+            {
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.MatchParent,
+                BackgroundColor = Color.Blue
+            };
+            subView.Add(subChild2);
+        }
+
+        public void Deactivate()
+        {
+            if (subWindow != null)
+            {
+                if (subView != null)
+                {
+                    subWindow.Remove(subView);
+                    subView.Dispose();
+                    subView = null;
+                }
+
+                subWindow.Dispose();
+                subWindow = null;
+            }
+
+            if (mainWindow != null)
+            {
+                if (mainView != null)
+                {
+                    mainWindow.Remove(mainView);
+                    mainView.Dispose();
+                    mainView = null;
+                }
+
+                mainWindow = null;
+            }
+        }
+    }
+}