[NUI] Change all CallingConvention to `Cdecl`
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Common / Layer.cs
index 9abbe28..828ba47 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
 using System;
 using Tizen.NUI.BaseComponents;
 using System.ComponentModel;
-using Tizen.NUI.Binding;
+using System.Runtime.InteropServices;
 
 namespace Tizen.NUI
 {
@@ -28,6 +28,11 @@ namespace Tizen.NUI
     public class Layer : Container
     {
         private Window window;
+        private int layoutCount = 0;
+        private EventHandler<VisibilityChangedEventArgs> visibilityChangedEventHandler;
+        private VisibilityChangedEventCallbackType visibilityChangedEventCallback;
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        private delegate void VisibilityChangedEventCallbackType(IntPtr data, bool visibility, VisibilityChangeType type);
 
         /// <summary>
         /// Creates a Layer object.
@@ -45,6 +50,31 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// Dispose Explicit or Implicit
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (Disposed)
+            {
+                return;
+            }
+
+            if (visibilityChangedEventCallback != null)
+            {
+                NUILog.Debug($"[Dispose] visibilityChangedEventCallback");
+
+                Interop.ActorSignal.VisibilityChangedDisconnect(GetBaseHandleCPtrHandleRef, visibilityChangedEventCallback.ToHandleRef(this));
+                NDalicPINVOKE.ThrowExceptionIfExistsDebug();
+                visibilityChangedEventCallback = null;
+            }
+
+            LayoutCount = 0;
+
+            base.Dispose(type);
+        }
+
+        /// <summary>
         /// Enumeration for the behavior of the layer.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
@@ -64,14 +94,6 @@ namespace Tizen.NUI
             LayerUI,
 
             /// <summary>
-            /// Deprecated in API6; Will be removed in API9. Please use LayerUI instead.
-            /// </summary>
-            /// <since_tizen> 3 </since_tizen>
-            [Obsolete("Deprecated in API6; Will be removed in API9. Please use LayerUI instead.")]
-            [EditorBrowsable(EditorBrowsableState.Never)]
-            Layer2D = LayerUI,
-
-            /// <summary>
             /// Layer will use depth test.
             /// This mode is designed for a 3 dimensional scene where actors in front
             /// of other actors will obscure them, i.e. the actors are sorted by the
@@ -250,20 +272,21 @@ namespace Tizen.NUI
             }
         }
 
-        /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
+        /// <summary>
+        /// Gets the Layer's ID
+        /// Readonly
+        /// </summary>
+        /// <remarks>Hidden-API</remarks>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public ResourceDictionary XamlResources
+        public uint ID
         {
             get
             {
-                return Application.Current.XamlResources;
-            }
-            set
-            {
-                Application.Current.XamlResources = value;
+                return GetId();
             }
         }
 
+
         /// From the Container base class.
 
         /// <summary>
@@ -292,11 +315,14 @@ namespace Tizen.NUI
                 {
                     child.InternalParent = this;
                 }
-                Interop.Actor.Add( SwigCPtr , View.getCPtr(child));
+
+                LayoutCount += child.LayoutCount;
+
+                Interop.Actor.Add(SwigCPtr, View.getCPtr(child));
                 if (NDalicPINVOKE.SWIGPendingException.Pending)
                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
                 Children.Add(child);
-                BindableObject.SetInheritedBindingContext(child, this?.BindingContext);
+                OnChildAdded(child);
             }
         }
 
@@ -313,12 +339,29 @@ namespace Tizen.NUI
             {
                 throw new ArgumentNullException(nameof(child));
             }
-            Interop.Actor.Remove( SwigCPtr, View.getCPtr(child));
+            if (child.GetParent() == null) // Early out if child parent is null.
+                return;
+
+            if (child.GetParent() != this)
+            {
+                //throw new System.InvalidOperationException("You have deleted a view that is not a child of this layer.");
+                Tizen.Log.Error("NUI", "You have deleted a view that is not a child of this layer.");
+                return;
+            }
+            // If the view had focus, it clears focus.
+            if (child == FocusManager.Instance.GetCurrentFocusView())
+            {
+                FocusManager.Instance.ClearFocus();
+            }
+
+            Interop.Actor.Remove(SwigCPtr, View.getCPtr(child));
             if (NDalicPINVOKE.SWIGPendingException.Pending)
                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
 
             Children.Remove(child);
             child.InternalParent = null;
+            OnChildRemoved(child);
+            LayoutCount -= child.LayoutCount;
         }
 
         /// <summary>
@@ -355,7 +398,7 @@ namespace Tizen.NUI
         /// </summary>
         /// <returns>The child count of the layer.</returns>
         /// <since_tizen> 4 </since_tizen>
-        [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
+        [Obsolete("This has been deprecated in API9 and will be removed in API11. Use ChildCount property instead")]
         public override uint GetChildCount()
         {
             return Convert.ToUInt32(Children.Count);
@@ -366,9 +409,8 @@ namespace Tizen.NUI
         /// </summary>
         /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
         /// <since_tizen> 3 </since_tizen>
-        /// Please do not use! this will be deprecated!
-        /// Instead please use as keyword.
-        [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead!")]
+        /// Do not use this, that will be deprecated. Use as keyword instead.
+        [Obsolete("Do not use this, that will be deprecated. Use as keyword instead.")]
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static Layer DownCast(BaseHandle handle)
         {
@@ -443,8 +485,9 @@ namespace Tizen.NUI
             if (parentChildren != null)
             {
                 int currentIdx = parentChildren.IndexOf(this);
+                int idx = window.IsBorderEnabled ? 1 : 0;
 
-                if (currentIdx > 0 && currentIdx < parentChildren.Count)
+                if (currentIdx > idx && currentIdx < parentChildren.Count)
                 {
                     var low = parentChildren[currentIdx - 1];
                     LowerBelow(low);
@@ -484,6 +527,14 @@ namespace Tizen.NUI
                 parentChildren.Insert(0, this);
 
                 Interop.Layer.LowerToBottom(SwigCPtr);
+
+                if (window.IsBorderEnabled)
+                {
+                    Layer bottomLayer = window.GetBorderWindowBottomLayer();
+                    parentChildren.Remove(bottomLayer);
+                    parentChildren.Insert(0, bottomLayer);
+                    Interop.Layer.LowerToBottom(Layer.getCPtr(bottomLayer));
+                }
                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
             }
         }
@@ -496,8 +547,7 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public void MoveAbove(Layer target)
         {
-            Interop.Layer.MoveAbove(SwigCPtr, Layer.getCPtr(target));
-            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            RaiseAbove(target);
         }
 
         /// <summary>
@@ -508,13 +558,7 @@ namespace Tizen.NUI
         /// <since_tizen> 3 </since_tizen>
         public void MoveBelow(Layer target)
         {
-            Interop.Layer.MoveBelow(SwigCPtr, Layer.getCPtr(target));
-            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
-        }
-
-        internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Layer obj)
-        {
-            return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
+            LowerBelow(target);
         }
 
         /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API.
@@ -579,6 +623,78 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
+        /// <summary>
+        /// An event for visibility change which can be used to subscribe or unsubscribe the event handler.<br />
+        /// This signal is emitted when the visible property of this or a parent view is changed.<br />
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<VisibilityChangedEventArgs> VisibilityChanged
+        {
+            add
+            {
+                if (visibilityChangedEventHandler == null)
+                {
+                    visibilityChangedEventCallback = OnVisibilityChanged;
+                    Interop.ActorSignal.VisibilityChangedConnect(SwigCPtr, visibilityChangedEventCallback.ToHandleRef(this));
+                    NDalicPINVOKE.ThrowExceptionIfExists();
+                }
+                visibilityChangedEventHandler += value;
+            }
+
+            remove
+            {
+                visibilityChangedEventHandler -= value;
+                if (visibilityChangedEventHandler == null && visibilityChangedEventCallback != null)
+                {
+                    Interop.ActorSignal.VisibilityChangedDisconnect(SwigCPtr, visibilityChangedEventCallback.ToHandleRef(this));
+                    NDalicPINVOKE.ThrowExceptionIfExists();
+                    visibilityChangedEventCallback = null;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Event arguments of visibility changed.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public class VisibilityChangedEventArgs : EventArgs
+        {
+            private Layer layer;
+            private bool visibility;
+
+            /// <summary>
+            /// The layer whose visibility has changed.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public Layer Layer
+            {
+                get
+                {
+                    return layer;
+                }
+                set
+                {
+                    layer = value;
+                }
+            }
+
+            /// <summary>
+            /// Whether the layer is now visible or not.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public bool Visibility
+            {
+                get
+                {
+                    return visibility;
+                }
+                set
+                {
+                    visibility = value;
+                }
+            }
+        }
+
         internal uint GetDepth()
         {
             var parentChildren = window?.LayersChildren;
@@ -694,7 +810,53 @@ 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()
+        {
+            uint ret = Interop.Actor.GetId(SwigCPtr);
+            if (NDalicPINVOKE.SWIGPendingException.Pending)
+                throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            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");
+
+                if (window != null)
+                {
+                    int diff = value - layoutCount;
+                    window.LayoutController.LayoutCount += diff;
+                }
+                layoutCount = value;
+            }
         }
 
         /// This will not be public opened.
@@ -721,5 +883,22 @@ namespace Tizen.NUI
         {
             internal static readonly int BEHAVIOR = Interop.Layer.BehaviorGet();
         }
+
+        // Callback for View visibility change signal
+        // type is not used because layer does not have parent so layer's visibility cannot be changed by its parent.
+        private void OnVisibilityChanged(IntPtr data, bool visibility, VisibilityChangeType type)
+        {
+            VisibilityChangedEventArgs e = new VisibilityChangedEventArgs();
+            if (data != IntPtr.Zero)
+            {
+                e.Layer = Registry.GetManagedBaseHandleFromNativePtr(data) as Layer;
+            }
+            e.Visibility = visibility;
+
+            if (visibilityChangedEventHandler != null)
+            {
+                visibilityChangedEventHandler(this, e);
+            }
+        }
     }
 }