[NUI] Add DataSelected in Clipboard
authorBowon Ryu <bowon.ryu@samsung.com>
Fri, 1 Sep 2023 12:31:50 +0000 (21:31 +0900)
committerJoogabYun <40262755+JoogabYun@users.noreply.github.com>
Mon, 11 Sep 2023 07:30:31 +0000 (16:30 +0900)
Add DataSelected to catch the Copy event of another process.

The process using this event must be Secondary Selection.
General apps cannot use this event usefully.

Signed-off-by: Bowon Ryu <bowon.ryu@samsung.com>
src/Tizen.NUI/src/internal/Interop/Interop.Clipboard.cs
src/Tizen.NUI/src/public/Clipboard/Clipboard.cs
src/Tizen.NUI/src/public/Clipboard/ClipboardEvent.cs
test/NUIClipboard/Clipboard.cs
test/NUIClipboardDataSelected/ClipboardDataSelected.cs [new file with mode: 0644]
test/NUIClipboardDataSelected/NUIClipboardDataSelected.csproj [new file with mode: 0644]
test/NUIClipboardDataSelected/shared/res/NUIClipboardDataSelected.png [new file with mode: 0644]
test/NUIClipboardDataSelected/tizen-manifest.xml [new file with mode: 0644]

index 2e87e99..afcac17 100755 (executable)
@@ -37,6 +37,9 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Clipboard_DataReceivedSignal")]
             public static extern global::System.IntPtr ClipboardDataReceivedSignal(global::System.Runtime.InteropServices.HandleRef clipboard);
 
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Clipboard_DataSelectedSignal")]
+            public static extern global::System.IntPtr ClipboardDataSelectedSignal(global::System.Runtime.InteropServices.HandleRef clipboard);
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_ClipboardSignal_Empty")]
             [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
             public static extern bool ClipboardSignalEmpty(global::System.Runtime.InteropServices.HandleRef signal);
index b7aff8b..887ca9a 100755 (executable)
@@ -170,6 +170,11 @@ namespace Tizen.NUI
                 {
                     this.ClipboardDataReceivedSignal().Disconnect(clipboardDataReceivedCallback);
                 }
+
+                if (clipboardDataSelectedCallback != null)
+                {
+                    this.ClipboardDataSelectedSignal().Disconnect(clipboardDataSelectedCallback);
+                }
             }
 
             base.Dispose(type);
index 7c812d9..5ff6443 100755 (executable)
@@ -39,6 +39,19 @@ namespace Tizen.NUI
     }
 
     /// <summary>
+    /// ClipboardDataSelectedEventArgs is a class to record clipboard selected event arguments which will be sent to user.<br/>
+    /// This is to catch data selection event.
+    /// </summary>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class ClipboardDataSelectedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// The mime type of clipboard selected data.
+        /// </summary>
+        public string MimeType { get; set; }
+    }
+
+    /// <summary>
     /// ClipboardEventArgs is a class to record clipboard event arguments which will be sent to user.<br/>
     /// This is for internal use only.
     /// </summary>
@@ -68,9 +81,53 @@ namespace Tizen.NUI
         private EventHandler<ClipboardEventArgs> clipboardDataReceivedEventHandler;
         private ClipboardDataReceivedCallback clipboardDataReceivedCallback;
 
+        private EventHandler<ClipboardDataSelectedEventArgs> clipboardDataSelectedEventHandler;
+        private ClipboardDataSelectedCallback clipboardDataSelectedCallback;
+
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
         private delegate void ClipboardDataReceivedCallback(uint id, string mimeType, string data);
 
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        private delegate void ClipboardDataSelectedCallback(string mimeType);
+
+        /// <summary>
+        /// The DataSelected event is emitted when a copy event occurs somewhere.<br/>
+        /// In order for this event to operate normally,<br/>
+        /// the process using this event must be Secondary Selection.
+        /// </summary>
+        /// <example>
+        /// The following example demonstrates how to use the DataSelected.
+        /// <code>
+        /// kvmService.SetSecondarySelction(); // precondition
+        ///
+        /// Clipboard.Instance.DataSelected += (s, e) =>
+        /// {
+        ///     string selectedType = e.MimeType;
+        /// };
+        /// </code>
+        /// </example>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public event EventHandler<ClipboardDataSelectedEventArgs> DataSelected
+        {
+            add
+            {
+                if (clipboardDataSelectedEventHandler == null)
+                {
+                    clipboardDataSelectedCallback = (OnClipboardDataSelected);
+                    ClipboardDataSelectedSignal().Connect(clipboardDataSelectedCallback);
+                }
+                clipboardDataSelectedEventHandler += value;
+            }
+            remove
+            {
+                clipboardDataSelectedEventHandler -= value;
+                if (clipboardDataSelectedEventHandler == null && ClipboardDataSelectedSignal().Empty() == false)
+                {
+                    ClipboardDataSelectedSignal().Disconnect(clipboardDataSelectedCallback);
+                }
+            }
+        }
+
         private event EventHandler<ClipboardEventArgs> ClipboardDataReceived
         {
             add
@@ -92,6 +149,20 @@ namespace Tizen.NUI
             }
         }
 
+        internal ClipboardSignal ClipboardDataSelectedSignal()
+        {
+            var ret = new ClipboardSignal(Interop.Clipboard.ClipboardDataSelectedSignal(SwigCPtr), false);
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+            return ret;
+        }
+
+        private void OnClipboardDataSelected(string mimeType)
+        {
+            var e = new ClipboardDataSelectedEventArgs();
+            e.MimeType = mimeType;
+            clipboardDataSelectedEventHandler?.Invoke(this, e);
+        }
+
         internal ClipboardSignal ClipboardDataReceivedSignal()
         {
             var ret = new ClipboardSignal(Interop.Clipboard.ClipboardDataReceivedSignal(SwigCPtr), false);
index 34fce57..99b1425 100644 (file)
@@ -7,7 +7,7 @@ namespace NUIClipboard
 {
     class Program : NUIApplication
     {
-        const string TAG = "NUIClipboard";
+        const string TAG = "clipboard";
         const string MIME_TYPE_PLAIN_TEXT = "text/plain;charset=utf-8";
         const string MIME_TYPE_TEXT_URI = "text/uri-list";
         const string MIME_TYPE_HTML = "application/xhtml+xml";
@@ -28,6 +28,7 @@ namespace NUIClipboard
         {
             Window.Instance.WindowSize = new Size(900, 1080);
             Window.Instance.BackgroundColor = Color.White;
+
             View mainView = NewView(false);
             Window.Instance.GetDefaultLayer().Add(mainView);
 
@@ -58,7 +59,7 @@ namespace NUIClipboard
             {
                 string data = fieldCopy.Text;
                 Clipboard.Instance.SetData(MIME_TYPE_PLAIN_TEXT, data);
-                Tizen.Log.Debug(TAG, $"SetData type:{MIME_TYPE_PLAIN_TEXT}, data:{data}");
+                Tizen.Log.Info(TAG, $"SetData type:{MIME_TYPE_PLAIN_TEXT}, data:{data}\n");
             };
 
 
@@ -70,7 +71,7 @@ namespace NUIClipboard
             buttonPaste.Clicked += (s, e) =>
             {
                 Clipboard.Instance.GetData(MIME_TYPE_PLAIN_TEXT, OnClipboardDataReceived);
-                Tizen.Log.Debug(TAG, $"GetData request type:{MIME_TYPE_PLAIN_TEXT}");
+                Tizen.Log.Info(TAG, $"GetData request type:{MIME_TYPE_PLAIN_TEXT}\n");
             };
 
             Button buttonCopyClear = NewButton("Clear");
@@ -105,11 +106,11 @@ namespace NUIClipboard
         {
             if (!success)
             {
-                Tizen.Log.Debug(TAG, $"Data receive fail");
+                Tizen.Log.Error(TAG, $"Data receive fail");
                 return;
             }
 
-            Tizen.Log.Debug(TAG, $"OnClipboardDataReceived type:{clipEvent.MimeType}, data{clipEvent.Data}");
+            Tizen.Log.Info(TAG, $"OnClipboardDataReceived type:{clipEvent.MimeType}, data:{clipEvent.Data}\n");
 
             // info update
             labelType.Text = clipEvent.MimeType;
diff --git a/test/NUIClipboardDataSelected/ClipboardDataSelected.cs b/test/NUIClipboardDataSelected/ClipboardDataSelected.cs
new file mode 100644 (file)
index 0000000..f0dc005
--- /dev/null
@@ -0,0 +1,94 @@
+using System;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.WindowSystem;
+
+/*
+ * This app has no UI.
+ * After the app is launched, it is hidden and the focus is skipped.
+ * This is a sample app that becomes SecondarySelection and catches the Copy event of another process.
+ * If there is another SecondarySelection already running on the device, this sample will not work properly.
+ */
+
+namespace NUIClipboardDataSelected
+{
+    class Program : NUIApplication
+    {
+        const string TAG = "clipboard";
+
+        protected override void OnCreate()
+        {
+            base.OnCreate();
+            Initialize();
+        }
+
+        void Initialize()
+        {
+            Window.Instance.WindowSize = new Size(1, 1);
+            Window.Instance.BackgroundColor = Color.White;
+
+
+            Tizen.NUI.WindowSystem.Shell.TizenShell tzShell;
+            tzShell = new Tizen.NUI.WindowSystem.Shell.TizenShell();
+            Window.Instance.SetAcceptFocus(false);
+
+            Tizen.NUI.WindowSystem.Shell.KVMService kvmService;
+            // window that will act as KVM Service.
+            kvmService = new Tizen.NUI.WindowSystem.Shell.KVMService(tzShell, Window.Instance); 
+            kvmService.SetSecondarySelction();
+
+            // Add a dummy view for easy debugging.
+            View view = NewView();
+            Window.Instance.GetDefaultLayer().Add(view);
+
+            // Register event handler.
+            Clipboard.Instance.DataSelected += OnClipboardDataSelected;
+        }
+
+        // When copy occurs somewhere, this callback is invoked.
+        public void OnClipboardDataSelected(object sender, ClipboardDataSelectedEventArgs e)
+        {
+            // e.MimeType is the MIME type of the copy data that invoked this callback.
+            string selectedType = e.MimeType;
+            Tizen.Log.Info(TAG, $"OnClipboardDataSelected type:{selectedType}\n");
+
+            // Do something here.
+            // For example, MC app can call Clipboard's GetData() with the MIME type of the event argument.
+            Clipboard.Instance.GetData(selectedType, OnClipboardDataReceived);
+        }
+
+        // When call Clipboard's GetData(), the user callback is called.
+        public void OnClipboardDataReceived(bool success, ClipEvent clipEvent)
+        {
+            if (!success)
+            {
+                Tizen.Log.Error(TAG, $"Data receive fail");
+                return;
+            }
+
+            Tizen.Log.Info(TAG, $"OnClipboardDataReceived type:{clipEvent.MimeType}, data:{clipEvent.Data}\n");
+        }
+
+        public View NewView()
+        {
+            var view = new View()
+            {
+                Layout = new LinearLayout()
+                {
+                    LinearOrientation = LinearLayout.Orientation.Vertical,
+                    LinearAlignment = LinearLayout.Alignment.Begin,
+                },
+                WidthSpecification = LayoutParamPolicies.MatchParent,
+                HeightSpecification = LayoutParamPolicies.WrapContent,
+                BackgroundColor = Color.White,
+            };
+            return view;
+        }
+
+        static void Main(string[] args)
+        {
+            var app = new Program();
+            app.Run(args);
+        }
+    }
+}
diff --git a/test/NUIClipboardDataSelected/NUIClipboardDataSelected.csproj b/test/NUIClipboardDataSelected/NUIClipboardDataSelected.csproj
new file mode 100644 (file)
index 0000000..d6260df
--- /dev/null
@@ -0,0 +1,28 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <OutputType>Exe</OutputType>
+        <TargetFramework>net6.0</TargetFramework>
+    </PropertyGroup>
+
+    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+        <DebugType>portable</DebugType>
+    </PropertyGroup>
+    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+        <DebugType>None</DebugType>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="Tizen.NET.Sdk" Version="1.0.9" />
+        <ProjectReference Include="../../src/Tizen/Tizen.csproj" />
+        <ProjectReference Include="../../src/Tizen.NUI.Components/Tizen.NUI.Components.csproj" />
+        <ProjectReference Include="../../src/Tizen.NUI/Tizen.NUI.csproj" />
+        <ProjectReference Include="../../src/Tizen.NUI.WindowSystem/Tizen.NUI.WindowSystem.csproj" />
+    </ItemGroup>
+
+    <PropertyGroup>
+        <NeedInjection>True</NeedInjection>
+    </PropertyGroup>
+
+</Project>
+
diff --git a/test/NUIClipboardDataSelected/shared/res/NUIClipboardDataSelected.png b/test/NUIClipboardDataSelected/shared/res/NUIClipboardDataSelected.png
new file mode 100644 (file)
index 0000000..62d0dff
Binary files /dev/null and b/test/NUIClipboardDataSelected/shared/res/NUIClipboardDataSelected.png differ
diff --git a/test/NUIClipboardDataSelected/tizen-manifest.xml b/test/NUIClipboardDataSelected/tizen-manifest.xml
new file mode 100644 (file)
index 0000000..0feb628
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="6" package="org.tizen.example.NUIClipboardDataSelected" version="1.0.0">
+  <profile name="common" />
+  <ui-application appid="org.tizen.example.NUIClipboardDataSelected"
+                                       exec="NUIClipboardDataSelected.dll"
+                                       type="dotnet-nui"
+                                       multiple="false"
+                                       taskmanage="true"
+                                       nodisplay="false"
+                                       launch_mode="single"
+          >
+    <label>NUIClipboardDataSelected</label>
+    <icon>NUIClipboardDataSelected.png</icon>
+    <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+  </ui-application>
+</manifest>