Browse Source

OSX drag cleanup

pull/1417/head
boombuler 9 years ago
parent
commit
1afb52b27d
  1. 96
      src/OSX/Avalonia.MonoMac/DragSource.cs

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

@ -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();
}
}
}
Loading…
Cancel
Save