|
|
@@ -1,13 +1,19 @@
|
|
|
-using System.Data;
|
|
|
+using System;
|
|
|
+using System.Data;
|
|
|
+using System.IO;
|
|
|
+using System.Linq;
|
|
|
using System.Linq.Expressions;
|
|
|
using System.Reactive.Linq;
|
|
|
using System.Reactive.Subjects;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+using System.Runtime.Serialization.Formatters.Binary;
|
|
|
using System.Threading.Tasks;
|
|
|
using Avalonia.Controls;
|
|
|
using Avalonia.Controls.DragDrop;
|
|
|
using Avalonia.Controls.Platform;
|
|
|
using Avalonia.Input;
|
|
|
using Avalonia.Input.Raw;
|
|
|
+using MonoMac;
|
|
|
using MonoMac.AppKit;
|
|
|
using MonoMac.CoreGraphics;
|
|
|
using MonoMac.Foundation;
|
|
|
@@ -17,46 +23,54 @@ namespace Avalonia.MonoMac
|
|
|
{
|
|
|
public class DragSource : NSDraggingSource, IPlatformDragSource
|
|
|
{
|
|
|
- class DS : NSDraggingSource
|
|
|
- {
|
|
|
- private readonly DragDropEffects _allowedEffects;
|
|
|
- public ReplaySubject<DragDropEffects> Result { get; } = new ReplaySubject<DragDropEffects>();
|
|
|
-
|
|
|
- public DS(DragDropEffects allowedEffects)
|
|
|
- {
|
|
|
- _allowedEffects = allowedEffects;
|
|
|
- }
|
|
|
-
|
|
|
- public override bool IgnoreModifierKeysWhileDragging => false;
|
|
|
-
|
|
|
- public override NSDragOperation DraggingSourceOperationMaskForLocal(bool flag)
|
|
|
- {
|
|
|
- return DraggingInfo.ConvertDragOperation(_allowedEffects);
|
|
|
- }
|
|
|
-
|
|
|
- public override void DraggedImageEndedAtOperation(NSImage image, CGPoint screenPoint, NSDragOperation operation)
|
|
|
- {
|
|
|
- Result.OnNext(DraggingInfo.ConvertDragOperation(operation));
|
|
|
- Result.OnCompleted();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+ private const string NSPasteboardTypeString = "public.utf8-plain-text";
|
|
|
|
|
|
+ private readonly Subject<DragDropEffects> _result = new Subject<DragDropEffects>();
|
|
|
private readonly IInputManager _inputManager;
|
|
|
+ private DragDropEffects _allowedEffects;
|
|
|
|
|
|
-
|
|
|
+ public override bool IgnoreModifierKeysWhileDragging => false;
|
|
|
+
|
|
|
public DragSource()
|
|
|
{
|
|
|
_inputManager = AvaloniaLocator.Current.GetService<IInputManager>();
|
|
|
}
|
|
|
|
|
|
- private NSDraggingItem[] ConvertDraggedItems(IDataObject data)
|
|
|
+ private string DataFormatToUTI(string s)
|
|
|
+ {
|
|
|
+ if (s == DataFormats.FileNames)
|
|
|
+ throw new NotImplementedException();
|
|
|
+ if (s == DataFormats.Text)
|
|
|
+ return NSPasteboardTypeString;
|
|
|
+ return s;
|
|
|
+ }
|
|
|
+
|
|
|
+ private NSDraggingItem CreateDraggingItem(string format, object data)
|
|
|
{
|
|
|
- NSString s = new NSString("FOOBAR");
|
|
|
- NSPasteboardWriting w = new NSPasteboardWriting(s.Handle);
|
|
|
- var text = new NSDraggingItem(w);
|
|
|
- return new[] {text};
|
|
|
+
|
|
|
+ var pasteboardItem = new NSPasteboardItem();
|
|
|
+ NSData nsData;
|
|
|
+ if(data is string s)
|
|
|
+ nsData = NSData.FromString(s);
|
|
|
+ else if (data is Stream strm)
|
|
|
+ nsData = NSData.FromStream(strm);
|
|
|
+ else if (data is byte[] bytes)
|
|
|
+ nsData = NSData.FromArray(bytes);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ BinaryFormatter bf = new BinaryFormatter();
|
|
|
+ using (var ms = new MemoryStream())
|
|
|
+ {
|
|
|
+ bf.Serialize(ms, data);
|
|
|
+ ms.Position = 0;
|
|
|
+ nsData = NSData.FromStream(ms);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pasteboardItem.SetDataForType(nsData, DataFormatToUTI(format));
|
|
|
+
|
|
|
+ NSPasteboardWriting writing = new NSPasteboardWriting(pasteboardItem.Handle);
|
|
|
+
|
|
|
+ return new NSDraggingItem(writing);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -72,10 +86,22 @@ namespace Avalonia.MonoMac
|
|
|
var pt = view.TranslateLocalPoint(mouseEv.Position).ToMonoMacPoint();
|
|
|
var ev = NSEvent.MouseEvent(NSEventType.LeftMouseDown, pt, 0, 0, 0, null, 0, 0, 0);
|
|
|
|
|
|
- var ds = new DS(allowedEffects);
|
|
|
- view.BeginDraggingSession(ConvertDraggedItems(data) ,ev, ds);
|
|
|
+ _allowedEffects = allowedEffects;
|
|
|
+ var items = data.GetDataFormats().Select(fmt => CreateDraggingItem(fmt, data.Get(fmt))).ToArray();
|
|
|
+ view.BeginDraggingSession(items ,ev, this);
|
|
|
|
|
|
- return await ds.Result;
|
|
|
+ return await _result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override NSDragOperation DraggingSourceOperationMaskForLocal(bool flag)
|
|
|
+ {
|
|
|
+ return DraggingInfo.ConvertDragOperation(_allowedEffects);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override void DraggedImageEndedAtOperation(NSImage image, CGPoint screenPoint, NSDragOperation operation)
|
|
|
+ {
|
|
|
+ _result.OnNext(DraggingInfo.ConvertDragOperation(operation));
|
|
|
+ _result.OnCompleted();
|
|
|
}
|
|
|
}
|
|
|
}
|