diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs b/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs index 1acf55699be..278ea1b2fed 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.DragAndDrop.cs @@ -33,11 +33,11 @@ internal enum DragType public static extern global::System.IntPtr New(); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_StartDragAndDrop")] - public static extern bool StartDragAndDrop(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef sourceView, global::System.Runtime.InteropServices.HandleRef shadow, string mimeType, string data, global::System.Runtime.InteropServices.HandleRef callback); + public static extern bool StartDragAndDrop(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef sourceView, global::System.Runtime.InteropServices.HandleRef shadow, string [] mimeTypes, int mimeTypsSize, string [] dataSet, int dataSetSize, global::System.Runtime.InteropServices.HandleRef callback); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_AddListener")] [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] - public static extern bool AddListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetView, global::System.Runtime.InteropServices.HandleRef callback); + public static extern bool AddListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetView, string mimeType, global::System.Runtime.InteropServices.HandleRef callback); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_RemoveListener")] [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] @@ -45,7 +45,7 @@ internal enum DragType [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_Window_AddListener")] [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] - public static extern bool WindowAddListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetWindow, global::System.Runtime.InteropServices.HandleRef callback); + public static extern bool WindowAddListener(global::System.Runtime.InteropServices.HandleRef dragAndDrop, global::System.Runtime.InteropServices.HandleRef targetWindow, string mimeType, global::System.Runtime.InteropServices.HandleRef callback); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragAndDrop_Window_RemoveListener")] [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)] @@ -57,8 +57,8 @@ internal enum DragType [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragEvent_GetPosition")] public static extern global::System.IntPtr GetPosition(global::System.IntPtr dragAndDrop); - [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragEvent_GetMimeType")] - public static extern string GetMimeType(global::System.IntPtr dragAndDrop); + [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragEvent_GetMimeTypes")] + public static extern bool GetMimeTypes(global::System.IntPtr dragAndDrop, out global::System.IntPtr mimeTypes, out int count); [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_DragEvent_GetData")] public static extern string GetData(global::System.IntPtr dragAndDrop); diff --git a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs index b37a11c2afc..c0d9120baaf 100755 --- a/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs +++ b/src/Tizen.NUI/src/public/DragAndDrop/DragAndDrop.cs @@ -18,6 +18,7 @@ using System.ComponentModel; using System.Runtime.InteropServices; using System.Collections.Generic; +using System.Linq; using System.Diagnostics.CodeAnalysis; using Tizen.NUI.BaseComponents; @@ -32,10 +33,10 @@ public class DragAndDrop : BaseHandle { public delegate void SourceEventHandler(DragSourceEventType sourceEventType); private delegate void InternalSourceEventHandler(int sourceEventType); - public delegate void DragAndDropEventHandler(View targetView, DragEvent dragEvent); + public delegate void DragAndDropEventHandler(View targetView, DragEvent navtiveDragEvent); [EditorBrowsable(EditorBrowsableState.Never)] - public delegate void DragAndDropWindowEventHandler(Window targetWindow, DragEvent dragEvent); - private delegate void InternalDragAndDropEventHandler(global::System.IntPtr dragEvent); + public delegate void DragAndDropWindowEventHandler(Window targetWindow, DragEvent navtiveDragEvent); + private delegate void InternalDragAndDropEventHandler(global::System.IntPtr navtiveDragEvent); private InternalSourceEventHandler sourceEventCb; private Dictionary targetEventDictionary = new Dictionary(); private Dictionary targetWindowEventDictionary = new Dictionary(); @@ -46,11 +47,107 @@ public class DragAndDrop : BaseHandle private int dragWindowOffsetX = 0; private int dragWindowOffsetY = 0; - private bool initDrag = false; - private const int MinDragWindowWidth = 100; private const int MinDragWindowHeight = 100; + private void ProcessDragEventTargetCallback(IntPtr navtiveDragEvent, View targetView, DragAndDropEventHandler callback) + { + DragType type = (DragType)Interop.DragAndDrop.GetAction(navtiveDragEvent); + DragEvent dragEvent = new DragEvent(); + global::System.IntPtr cPtr = Interop.DragAndDrop.GetPosition(navtiveDragEvent); + dragEvent.Position = (cPtr == global::System.IntPtr.Zero) ? null : new Position(cPtr, true); + + IntPtr nativeMimeTypes; + int count; + Interop.DragAndDrop.GetMimeTypes(navtiveDragEvent, out nativeMimeTypes, out count); + if (count > 0) + { + IntPtr [] nativeMimeTypesArrary = new IntPtr[count]; + Marshal.Copy(nativeMimeTypes, nativeMimeTypesArrary, 0, count); + + string [] managedMimeTypes = new string[count]; + + for (int iterator = 0; iterator < count; iterator++) + { + managedMimeTypes[iterator] = Marshal.PtrToStringAnsi(nativeMimeTypesArrary[iterator]); + } + + dragEvent.MimeType = managedMimeTypes[0]; + dragEvent.MimeTypes = managedMimeTypes; + } + + if (type == DragType.Enter) + { + dragEvent.DragType = type; + callback(targetView, dragEvent); + } + else if (type == DragType.Leave) + { + dragEvent.DragType = type; + callback(targetView, dragEvent); + } + else if (type == DragType.Move) + { + dragEvent.DragType = type; + callback(targetView, dragEvent); + } + else if (type == DragType.Drop) + { + dragEvent.DragType = type; + dragEvent.Data = Interop.DragAndDrop.GetData(navtiveDragEvent); + callback(targetView, dragEvent); + } + } + + private void ProcessDragEventWindowCallback(IntPtr navtiveDragEvent, Window targetWindow, DragAndDropWindowEventHandler callback) + { + DragType type = (DragType)Interop.DragAndDrop.GetAction(navtiveDragEvent); + DragEvent dragEvent = new DragEvent(); + global::System.IntPtr cPtr = Interop.DragAndDrop.GetPosition(navtiveDragEvent); + dragEvent.Position = (cPtr == global::System.IntPtr.Zero) ? null : new Position(cPtr, false); + + IntPtr nativeMimeTypes; + int count; + Interop.DragAndDrop.GetMimeTypes(navtiveDragEvent, out nativeMimeTypes, out count); + if (count > 0) + { + IntPtr [] nativeMimeTypesArrary = new IntPtr[count]; + Marshal.Copy(nativeMimeTypes, nativeMimeTypesArrary, 0, count); + + string [] managedMimeTypes = new string[count]; + + for (int iterator = 0; iterator < count; iterator++) + { + managedMimeTypes[iterator] = Marshal.PtrToStringAnsi(nativeMimeTypesArrary[iterator]); + } + + dragEvent.MimeType = managedMimeTypes[0]; + dragEvent.MimeTypes = managedMimeTypes; + } + + if (type == DragType.Enter) + { + dragEvent.DragType = type; + callback(targetWindow, dragEvent); + } + else if (type == DragType.Leave) + { + dragEvent.DragType = type; + callback(targetWindow, dragEvent); + } + else if (type == DragType.Move) + { + dragEvent.DragType = type; + callback(targetWindow, dragEvent); + } + else if (type == DragType.Drop) + { + dragEvent.DragType = type; + dragEvent.Data = Interop.DragAndDrop.GetData(navtiveDragEvent); + callback(targetWindow, dragEvent); + } + } + private DragAndDrop() : this(Interop.DragAndDrop.New(), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -92,14 +189,7 @@ private void ReleaseDragWindow() /// The source event callback /// 10 public void StartDragAndDrop(View sourceView, View shadowView, DragData dragData, SourceEventHandler callback) - { - if (initDrag) - { - Tizen.Log.Fatal("NUI", "Start Drag And Drop Initializing..."); - return; - } - initDrag = true; - + { if (Window.IsSupportedMultiWindow() == false) { throw new NotSupportedException("This device does not support surfaceless_context. So Window cannot be created."); @@ -155,7 +245,7 @@ public void StartDragAndDrop(View sourceView, View shadowView, DragData dragData { if ((DragSourceEventType)sourceEventType != DragSourceEventType.Start) { - Tizen.Log.Fatal("NUI", "DnD Source Event is Called"); + Tizen.Log.Fatal("NUI", "DnD Source Event is Called"); ReleaseDragWindow(); } @@ -165,15 +255,29 @@ public void StartDragAndDrop(View sourceView, View shadowView, DragData dragData //Show Drag Window before StartDragAndDrop mDragWindow.Show(); - if (!Interop.DragAndDrop.StartDragAndDrop(SwigCPtr, View.getCPtr(sourceView), Window.getCPtr(mDragWindow), dragData.MimeType, dragData.Data, + string [] mimeTypes; + string [] dataSet; + + if (string.IsNullOrEmpty(dragData.MimeType) && dragData.DataMap != null) + { + mimeTypes = dragData.DataMap.Keys.ToArray(); + dataSet = dragData.DataMap.Values.ToArray(); + } + else + { + mimeTypes = new string[1]; + mimeTypes[0] = dragData.MimeType; + + dataSet = new string[1]; + dataSet[0] = dragData.Data; + } + + if (!Interop.DragAndDrop.StartDragAndDrop(SwigCPtr, View.getCPtr(sourceView), Window.getCPtr(mDragWindow), mimeTypes, mimeTypes.Length, dataSet, dataSet.Length, new global::System.Runtime.InteropServices.HandleRef(this, Marshal.GetFunctionPointerForDelegate(sourceEventCb)))) { throw new InvalidOperationException("Fail to StartDragAndDrop"); } - - } - - initDrag = false; + } } /// @@ -184,42 +288,23 @@ public void StartDragAndDrop(View sourceView, View shadowView, DragData dragData /// 10 public void AddListener(View targetView, DragAndDropEventHandler callback) { - InternalDragAndDropEventHandler cb = (dragEvent) => - { - DragType type = (DragType)Interop.DragAndDrop.GetAction(dragEvent); - DragEvent ev = new DragEvent(); - global::System.IntPtr cPtr = Interop.DragAndDrop.GetPosition(dragEvent); - ev.Position = (cPtr == global::System.IntPtr.Zero) ? null : new Position(cPtr, true); + AddListener(targetView, "*/*", callback); + } - if (type == DragType.Enter) - { - ev.DragType = type; - ev.MimeType = Interop.DragAndDrop.GetMimeType(dragEvent); - callback(targetView, ev); - } - else if (type == DragType.Leave) - { - ev.DragType = type; - callback(targetView, ev); - } - else if (type == DragType.Move) - { - ev.DragType = type; - ev.MimeType = Interop.DragAndDrop.GetMimeType(dragEvent); - callback(targetView, ev); - } - else if (type == DragType.Drop) - { - ev.DragType = type; - ev.MimeType = Interop.DragAndDrop.GetMimeType(dragEvent); - ev.Data = Interop.DragAndDrop.GetData(dragEvent); - callback(targetView, ev); - } - }; + /// + /// Adds listener for drop targets + /// + /// The target view + /// The mime type for target view + /// The callback function to get drag event when the drag source enters, moves, leaves and drops on the drop target + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddListener(View targetView, string mimeType, DragAndDropEventHandler callback) + { + InternalDragAndDropEventHandler cb = (navtiveDragEvent) => ProcessDragEventTargetCallback(navtiveDragEvent, targetView, callback); targetEventDictionary.Add(targetView, cb); - if (!Interop.DragAndDrop.AddListener(SwigCPtr, View.getCPtr(targetView), + if (!Interop.DragAndDrop.AddListener(SwigCPtr, View.getCPtr(targetView), mimeType, new global::System.Runtime.InteropServices.HandleRef(this, Marshal.GetFunctionPointerForDelegate(cb)))) { throw new InvalidOperationException("Fail to AddListener for View"); @@ -256,40 +341,23 @@ public void RemoveListener(View targetView, DragAndDropEventHandler _) [EditorBrowsable(EditorBrowsableState.Never)] public void AddListener(Window targetWindow, DragAndDropWindowEventHandler callback) { - InternalDragAndDropEventHandler cb = (dragEvent) => - { - DragType type = (DragType)Interop.DragAndDrop.GetAction(dragEvent); - DragEvent ev = new DragEvent(); - global::System.IntPtr cPtr = Interop.DragAndDrop.GetPosition(dragEvent); - ev.Position = (cPtr == global::System.IntPtr.Zero) ? null : new Position(cPtr, false); + AddListener(targetWindow, "*/*", callback); + } - if (type == DragType.Enter) - { - ev.DragType = type; - callback(targetWindow, ev); - } - else if (type == DragType.Leave) - { - ev.DragType = type; - callback(targetWindow, ev); - } - else if (type == DragType.Move) - { - ev.DragType = type; - callback(targetWindow, ev); - } - else if (type == DragType.Drop) - { - ev.DragType = type; - ev.MimeType = Interop.DragAndDrop.GetMimeType(dragEvent); - ev.Data = Interop.DragAndDrop.GetData(dragEvent); - callback(targetWindow, ev); - } - }; + /// + /// Adds listener for drop targets + /// + /// The target Window + /// The mime type for target view + /// The callback function to get drag event when the drag source enters, moves, leaves and drops on the drop target + [EditorBrowsable(EditorBrowsableState.Never)] + public void AddListener(Window targetWindow, string mimeType, DragAndDropWindowEventHandler callback) + { + InternalDragAndDropEventHandler cb = (navtiveDragEvent) => ProcessDragEventWindowCallback(navtiveDragEvent, targetWindow, callback); targetWindowEventDictionary.Add(targetWindow, cb); - if (!Interop.DragAndDrop.WindowAddListener(SwigCPtr, Window.getCPtr(targetWindow), + if (!Interop.DragAndDrop.WindowAddListener(SwigCPtr, Window.getCPtr(targetWindow), mimeType, new global::System.Runtime.InteropServices.HandleRef(this, Marshal.GetFunctionPointerForDelegate(cb)))) { throw new InvalidOperationException("Fail to AddListener for Window"); diff --git a/src/Tizen.NUI/src/public/DragAndDrop/DragEvent.cs b/src/Tizen.NUI/src/public/DragAndDrop/DragEvent.cs index 6c705b90d3d..da4cc9ae183 100755 --- a/src/Tizen.NUI/src/public/DragAndDrop/DragEvent.cs +++ b/src/Tizen.NUI/src/public/DragAndDrop/DragEvent.cs @@ -16,6 +16,7 @@ */ using System; using System.ComponentModel; +using System.Collections.Generic; using Tizen.NUI.Binding; namespace Tizen.NUI @@ -60,6 +61,12 @@ public struct DragData /// The drag data to send /// public string Data { get; set; } + + /// + /// The mime types and drag data set + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public Dictionary DataMap; } /// @@ -106,6 +113,13 @@ public struct DragEvent /// The mime type of drag object /// public string MimeType { get; set; } + + /// + /// The mime types of drag object + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public string [] MimeTypes { get; set; } + /// /// The drag data to receive /// diff --git a/test/NUIDnDMultiWindow/NUIDnDMultiWindow.cs b/test/NUIDnDMultiWindow/NUIDnDMultiWindow.cs index 3d95b347b28..dec31805f78 100644 --- a/test/NUIDnDMultiWindow/NUIDnDMultiWindow.cs +++ b/test/NUIDnDMultiWindow/NUIDnDMultiWindow.cs @@ -89,7 +89,7 @@ void Initialize() Tizen.Log.Debug("NUIDnDMultiWindow", "StartDragAndDrop"); shadowView = new ImageView(Tizen.Applications.Application.Current.DirectoryInfo.SharedResource + "dragsource.png"); shadowView.Size = new Size(150, 150); - DragData dragData; + DragData dragData = new DragData(); dragData.MimeType = "text/uri-list"; dragData.Data = Tizen.Applications.Application.Current.DirectoryInfo.SharedResource + "dragsource.png"; dnd.StartDragAndDrop(sourceView, shadowView, dragData, OnSourceApp_SourceFunc); diff --git a/test/NUIDnDSource/NUIDnDSource.cs b/test/NUIDnDSource/NUIDnDSource.cs index 7bceebef55c..ae242037a8a 100644 --- a/test/NUIDnDSource/NUIDnDSource.cs +++ b/test/NUIDnDSource/NUIDnDSource.cs @@ -91,7 +91,7 @@ void Initialize() Tizen.Log.Debug("NUIDnDSource", "StartDragAndDrop"); shadowView = new ImageView(Tizen.Applications.Application.Current.DirectoryInfo.SharedResource + "dragsource.png"); shadowView.Size = new Size(150, 150); - DragData dragData; + DragData dragData = new DragData(); dragData.MimeType = "text/uri-list"; dragData.Data = Tizen.Applications.Application.Current.DirectoryInfo.SharedResource + "dragsource.png"; dnd.StartDragAndDrop(sourceView, shadowView, dragData, OnSourceEventFunc);