Browse Source

update implementation of drag and drop for winit backend.

windowing-prototype-drag-and-drop
Dan Walmsley 8 years ago
parent
commit
19dd246703
  1. 92
      src/Avalonia.Windowing/DragSource.cs
  2. 9
      src/OSX/Avalonia.MonoMac/DragSource.cs

92
src/Avalonia.Windowing/DragSource.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Reactive.Subjects; using System.Reactive.Subjects;
@ -15,7 +16,51 @@ namespace Avalonia.Windowing
public class DragSource : IPlatformDragSource public class DragSource : IPlatformDragSource
{ {
[DllImport("winit_wrapper")] [DllImport("winit_wrapper")]
private static extern void winit_wrapper_begin_drag(IntPtr nsview, LogicalPosition position); private static extern unsafe void winit_wrapper_begin_drag(IntPtr nsview, IntPtr items, Int32 numItems, LogicalPosition position, IntPtr sourceHandle);
[DllImport("winit_wrapper")]
private static extern IntPtr winit_wrapper_create_dragging_source();
[DllImport("winit_wrapper")]
private static extern IntPtr winit_wrapper_initialise_drag_module();
[DllImport("winit_wrapper")]
private static extern IntPtr winit_wrapper_create_paste_board_item();
[DllImport("winit_wrapper")]
private static extern IntPtr winit_wrapper_nsdata_from_string(IntPtr dataString);
[DllImport("winit_wrapper")]
private static extern byte winit_wrapper_paste_board_item_set_data_for_type(IntPtr pasteBoardItem, IntPtr data, IntPtr typeString);
[DllImport("winit_wrapper")]
private static extern IntPtr winit_wrapper_create_ns_dragging_item(IntPtr pasteBoardItem);
private IntPtr NSDataFromString (string dataString)
{
var ansiString = Marshal.StringToHGlobalAnsi(dataString);
var result = winit_wrapper_nsdata_from_string(ansiString);
Marshal.FreeHGlobal(ansiString);
return result;
}
static DragSource()
{
winit_wrapper_initialise_drag_module();
}
private IntPtr _handle;
public DragSource()
{
_inputManager = AvaloniaLocator.Current.GetService<IInputManager>();
_handle = winit_wrapper_create_dragging_source();
}
private const string NSPasteboardTypeString = "public.utf8-plain-text"; private const string NSPasteboardTypeString = "public.utf8-plain-text";
private const string NSPasteboardTypeFileUrl = "public.file-url"; private const string NSPasteboardTypeFileUrl = "public.file-url";
@ -26,10 +71,6 @@ namespace Avalonia.Windowing
//public override bool IgnoreModifierKeysWhileDragging => false; //public override bool IgnoreModifierKeysWhileDragging => false;
public DragSource()
{
_inputManager = AvaloniaLocator.Current.GetService<IInputManager>();
}
private string DataFormatToUTI(string s) private string DataFormatToUTI(string s)
{ {
@ -40,20 +81,22 @@ namespace Avalonia.Windowing
return s; return s;
} }
/*private NSDraggingItem CreateDraggingItem(string format, object data) private IntPtr CreateDraggingItem(string format, object data)
{ {
var pasteboardItem = new NSPasteboardItem(); var pasteboardItem = winit_wrapper_create_paste_board_item();
NSData nsData;
IntPtr nsData = IntPtr.Zero;
if (data is string s) if (data is string s)
{ {
if (format == DataFormats.FileNames) if (format == DataFormats.FileNames)
s = new Uri(s).AbsoluteUri; // Ensure file uris... s = new Uri(s).AbsoluteUri; // Ensure file uris...
nsData = NSData.FromString(s); nsData = NSDataFromString(s);
//nsData = NSData.FromString(s);
} }
else if (data is Stream strm) /*else if (data is Stream strm)
nsData = NSData.FromStream(strm); nsData = NSData.FromStream(strm);
else if (data is byte[] bytes) else if (data is byte[] bytes)
nsData = NSData.FromArray(bytes); nsData = NSData.FromArray(bytes);e
else else
{ {
BinaryFormatter bf = new BinaryFormatter(); BinaryFormatter bf = new BinaryFormatter();
@ -63,15 +106,16 @@ namespace Avalonia.Windowing
ms.Position = 0; ms.Position = 0;
nsData = NSData.FromStream(ms); nsData = NSData.FromStream(ms);
} }
} }*/
pasteboardItem.SetDataForType(nsData, DataFormatToUTI(format));
NSPasteboardWriting writing = new NSPasteboardWriting(pasteboardItem.Handle); var typeStringPtr = Marshal.StringToHGlobalAnsi(DataFormatToUTI(format));
winit_wrapper_paste_board_item_set_data_for_type(pasteboardItem, nsData, typeStringPtr);
return new NSDraggingItem(writing); return winit_wrapper_create_ns_dragging_item(pasteboardItem);
} }
public IEnumerable<NSDraggingItem> CreateDraggingItems(string format, object data) public IEnumerable<IntPtr> CreateDraggingItems(string format, object data)
{ {
if (format == DataFormats.FileNames && data is IEnumerable<string> files) if (format == DataFormats.FileNames && data is IEnumerable<string> files)
{ {
@ -82,7 +126,7 @@ namespace Avalonia.Windowing
} }
yield return CreateDraggingItem(format, data); yield return CreateDraggingItem(format, data);
}*/ }
public async Task<DragDropEffects> DoDragDrop(IDataObject data, DragDropEffects allowedEffects) public async Task<DragDropEffects> DoDragDrop(IDataObject data, DragDropEffects allowedEffects)
@ -104,11 +148,21 @@ namespace Avalonia.Windowing
_allowedEffects = allowedEffects; _allowedEffects = allowedEffects;
// 3) create NSDraggingItem from the data. // 3) create NSDraggingItem from the data.
//var items = data.GetDataFormats().SelectMany(fmt => CreateDraggingItems(fmt, data.Get(fmt))).ToArray(); var items = data.GetDataFormats().SelectMany(fmt => CreateDraggingItems(fmt, data.Get(fmt))).ToArray();
// 4) Call BeginDraggingSession on the view. // 4) Call BeginDraggingSession on the view.
//view.BeginDraggingSession(items, ev, this); //view.BeginDraggingSession(items, ev, this);
winit_wrapper_begin_drag(view.WindowWrapper.NSView, pt);
var handle = GCHandle.Alloc(items, GCHandleType.Pinned);
try
{
IntPtr myPinnedPointer = handle.AddrOfPinnedObject();
winit_wrapper_begin_drag(view.WindowWrapper.NSView, myPinnedPointer, items.Length, pt, _handle);
}
finally
{
handle.Free();
}
return await _result; return await _result;
} }

9
src/OSX/Avalonia.MonoMac/DragSource.cs

@ -23,6 +23,11 @@ namespace Avalonia.MonoMac
{ {
public class DragSource : NSDraggingSource, IPlatformDragSource public class DragSource : NSDraggingSource, IPlatformDragSource
{ {
public override NSDragOperation DraggingSourceOperationMaskForLocal(bool flag)
{
return DraggingInfo.ConvertDragOperation(_allowedEffects);
}
private const string NSPasteboardTypeString = "public.utf8-plain-text"; private const string NSPasteboardTypeString = "public.utf8-plain-text";
private const string NSPasteboardTypeFileUrl = "public.file-url"; private const string NSPasteboardTypeFileUrl = "public.file-url";
@ -110,10 +115,10 @@ namespace Avalonia.MonoMac
return await _result; return await _result;
} }
public override NSDragOperation DraggingSourceOperationMaskForLocal(bool flag) /*public override NSDragOperation DraggingSourceOperationMaskForLocal(bool flag)
{ {
return DraggingInfo.ConvertDragOperation(_allowedEffects); return DraggingInfo.ConvertDragOperation(_allowedEffects);
} }*/
public override void DraggedImageEndedAtOperation(NSImage image, CGPoint screenPoint, NSDragOperation operation) public override void DraggedImageEndedAtOperation(NSImage image, CGPoint screenPoint, NSDragOperation operation)
{ {

Loading…
Cancel
Save