[NUI] Add InsetsChanged event to Window
authorJaehyun Cho <jae_hyun.cho@samsung.com>
Thu, 14 Jul 2022 10:13:28 +0000 (19:13 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 8 Aug 2023 03:02:35 +0000 (12:02 +0900)
Window insets are the inner size between window content and window edge.

Window insets are required when status bar, virtual keyboard, or
clipboard appears on window to avoid window content obscured by them.

To notify the window insets changes, InsetsChanged event is added to
Window.

src/Tizen.NUI/src/internal/Interop/Interop.WindowInsetsChangedSignal.cs [new file with mode: 0755]
src/Tizen.NUI/src/internal/Window/WindowInsetsChangedSignal.cs [new file with mode: 0755]
src/Tizen.NUI/src/public/Window/WindowEvent.cs

diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.WindowInsetsChangedSignal.cs b/src/Tizen.NUI/src/internal/Interop/Interop.WindowInsetsChangedSignal.cs
new file mode 100755 (executable)
index 0000000..73f0fd2
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright(c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+using System.Runtime.InteropServices;
+
+namespace Tizen.NUI
+{
+    internal static partial class Interop
+    {
+        internal static partial class WindowInsetsChangedSignal
+        {
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal")]
+            public static extern global::System.IntPtr GetSignal(HandleRef jarg1);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal_Empty")]
+            [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
+            public static extern bool Empty(HandleRef jarg1);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal_GetConnectionCount")]
+            public static extern uint GetConnectionCount(HandleRef jarg1);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal_Connect")]
+            public static extern void Connect(HandleRef jarg1, HandleRef jarg2);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal_Disconnect")]
+            public static extern void Disconnect(HandleRef jarg1, HandleRef jarg2);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal_Emit")]
+            [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
+            public static extern bool Emit(HandleRef jarg1);
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal_new")]
+            public static extern global::System.IntPtr NewSignal();
+
+            [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Window_InsetsChanged_Signal_delete")]
+            public static extern void DeleteSignal(HandleRef jarg1);
+        }
+    }
+}
diff --git a/src/Tizen.NUI/src/internal/Window/WindowInsetsChangedSignal.cs b/src/Tizen.NUI/src/internal/Window/WindowInsetsChangedSignal.cs
new file mode 100755 (executable)
index 0000000..318875f
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright(c) 2023 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+namespace Tizen.NUI
+{
+    internal class WindowInsetsChangedSignal : Disposable
+    {
+
+        internal WindowInsetsChangedSignal(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
+        {
+        }
+
+        protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
+        {
+            Interop.WindowInsetsChangedSignal.DeleteSignal(swigCPtr);
+        }
+
+        public bool Empty()
+        {
+            bool ret = Interop.WindowInsetsChangedSignal.Empty(SwigCPtr);
+
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return ret;
+        }
+
+        public uint GetConnectionCount()
+        {
+            uint ret = Interop.WindowInsetsChangedSignal.GetConnectionCount(SwigCPtr);
+
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return ret;
+        }
+
+        public void Connect(System.Delegate func)
+        {
+            System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(func);
+            {
+                Interop.WindowInsetsChangedSignal.Connect(SwigCPtr, new System.Runtime.InteropServices.HandleRef(this, ip));
+                if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            }
+        }
+
+        public void Disconnect(System.Delegate func)
+        {
+            System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(func);
+            {
+                Interop.WindowInsetsChangedSignal.Disconnect(SwigCPtr, new System.Runtime.InteropServices.HandleRef(this, ip));
+                if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            }
+        }
+
+        public bool Emit()
+        {
+            bool ret = Interop.WindowInsetsChangedSignal.Emit(SwigCPtr);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return ret;
+        }
+
+        public WindowInsetsChangedSignal(Window window) : this(Interop.WindowInsetsChangedSignal.GetSignal(Window.getCPtr(window)), false)
+        {
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+    }
+}
index 98b1c66..aebf931 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2023 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.
@@ -51,6 +51,7 @@ namespace Tizen.NUI
         private KeyboardRepeatSettingsChangedEventCallbackType keyboardRepeatSettingsChangedEventCallback;
         private AuxiliaryMessageEventCallbackType auxiliaryMessageEventCallback;
         private WindowMouseInOutEventCallbackType windowMouseInOutEventCallback;
+        private InsetsChangedEventCallbackType insetsChangedEventCallback;
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         private delegate void WindowFocusChangedEventCallbackType(IntPtr window, bool focusGained);
         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
@@ -75,6 +76,8 @@ namespace Tizen.NUI
         private delegate bool InterceptKeyEventDelegateType(IntPtr arg1);
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         private delegate void WindowMouseInOutEventCallbackType(IntPtr window, IntPtr mouseEvent);
+        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
+        private delegate void InsetsChangedEventCallbackType(int partType, int partState, IntPtr extents);
 
         /// <summary>
         /// FocusChanged event.
@@ -533,6 +536,7 @@ namespace Tizen.NUI
         private event EventHandler keyboardRepeatSettingsChangedHandler;
         private event EventHandler<AuxiliaryMessageEventArgs> auxiliaryMessageEventHandler;
         private event EventHandler<MouseInOutEventArgs> windowMouseInOutEventHandler;
+        private event EventHandler<InsetsChangedEventArgs> insetsChangedEventHandler;
 
         internal void SendViewAdded(View view)
         {
@@ -807,6 +811,12 @@ namespace Tizen.NUI
                 windowMouseInOutEventCallback = null;
             }
 
+            if (insetsChangedEventCallback != null)
+            {
+                using WindowInsetsChangedSignal signal = new WindowInsetsChangedSignal(Interop.WindowInsetsChangedSignal.GetSignal(GetBaseHandleCPtrHandleRef), false);
+                signal.Disconnect(insetsChangedEventCallback);
+                insetsChangedEventCallback = null;
+            }
         }
 
         private void OnWindowFocusedChanged(IntPtr window, bool focusGained)
@@ -1471,6 +1481,127 @@ namespace Tizen.NUI
         }
 
         /// <summary>
+        /// The type of insets part.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public enum InsetsPartType
+        {
+            StatusBar = 0,
+            Keyboard = 1,
+            Clipboard = 2
+        }
+
+        /// <summary>
+        /// The state of insets part.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public enum InsetsPartState
+        {
+            Invisible = 0,
+            Visible = 1
+        }
+
+        /// <summary>
+        /// InsetsChangedEventArgs
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public class InsetsChangedEventArgs : EventArgs
+        {
+            private InsetsPartType partType;
+            private InsetsPartState partState;
+            private Extents insets;
+
+            /// <summary>
+            /// The type of insets part.
+            /// e.g. StatusBar, Keyboard, or Clipboard
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public InsetsPartType PartType
+            {
+                get => partType;
+                internal set
+                {
+                    partType = value;
+                }
+            }
+
+            /// <summary>
+            /// The state of insets part.
+            /// e.g. Invisible or Visible
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public InsetsPartState PartState
+            {
+                get => partState;
+                internal set
+                {
+                    partState = value;
+                }
+            }
+
+            /// <summary>
+            /// The extents value of window insets
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public Extents Insets
+            {
+                get => insets;
+                internal set
+                {
+                    insets = value;
+                }
+            }
+        }
+
+        private void OnInsetsChanged(int partType, int partState, IntPtr extents)
+        {
+            if (insetsChangedEventHandler != null)
+            {
+                InsetsChangedEventArgs e = new InsetsChangedEventArgs();
+                e.PartType = (InsetsPartType)partType;
+                e.PartState = (InsetsPartState)partState;
+                e.Insets = new Extents(extents, false);
+
+                insetsChangedEventHandler.Invoke(this, e);
+            }
+        }
+
+        /// <summary>
+        /// Emits the event when the window insets changes by status bar, virtual keyboard, or clipboard appears and disappears.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<InsetsChangedEventArgs> InsetsChanged
+        {
+            add
+            {
+                if (insetsChangedEventHandler == null)
+                {
+                    insetsChangedEventCallback = OnInsetsChanged;
+                    using var signal = new WindowInsetsChangedSignal(this);
+                    signal.Connect(insetsChangedEventCallback);
+                }
+                insetsChangedEventHandler += value;
+            }
+            remove
+            {
+                insetsChangedEventHandler -= value;
+                if (insetsChangedEventHandler == null)
+                {
+                    if (insetsChangedEventCallback != null)
+                    {
+                        using var signal = new WindowInsetsChangedSignal(this);
+                        signal.Disconnect(insetsChangedEventCallback);
+
+                        if (signal.Empty())
+                        {
+                            insetsChangedEventCallback = null;
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
         /// AccessibilityHighlightArgs
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]