Browse Source

first bits of drag+drop support for osx

pull/1417/head
Florian Sundermann 9 years ago
parent
commit
edf6b12c4d
  1. 15
      src/Avalonia.Controls/DragDrop/DataFormats.cs
  2. 13
      src/Avalonia.Controls/DragDrop/DragOperation.cs
  3. 15
      src/Avalonia.Controls/DragDrop/IDragData.cs
  4. 12
      src/Avalonia.Controls/DragDrop/IDragDispatcher.cs
  5. 4
      src/OSX/Avalonia.MonoMac/Avalonia.MonoMac.csproj
  6. 63
      src/OSX/Avalonia.MonoMac/DraggingInfo.cs
  7. 76
      src/OSX/Avalonia.MonoMac/TopLevelImpl.cs

15
src/Avalonia.Controls/DragDrop/DataFormats.cs

@ -0,0 +1,15 @@
namespace Avalonia.Controls.DragDrop
{
public static class DataFormats
{
/// <summary>
/// Dataformat for plaintext
/// </summary>
public static string Text = nameof(Text);
/// <summary>
/// Dataformat for one or more filenames
/// </summary>
public static string FileNames = nameof(FileNames);
}
}

13
src/Avalonia.Controls/DragDrop/DragOperation.cs

@ -0,0 +1,13 @@
using System;
namespace Avalonia.Controls.DragDrop
{
[Flags]
public enum DragOperation
{
None = 0,
Copy = 1,
Move = 2,
Link = 4,
}
}

15
src/Avalonia.Controls/DragDrop/IDragData.cs

@ -0,0 +1,15 @@
using System.Collections.Generic;
namespace Avalonia.Controls.DragDrop
{
public interface IDragData
{
IEnumerable<string> GetDataFormats();
bool Contains(string dataFormat);
string GetText();
IEnumerable<string> GetFileNames();
}
}

12
src/Avalonia.Controls/DragDrop/IDragDispatcher.cs

@ -0,0 +1,12 @@
using Avalonia.Input;
namespace Avalonia.Controls.DragDrop
{
public interface IDragDispatcher
{
DragOperation DragEnter(IInputRoot inputRoot, Point point, IDragData data, DragOperation operation);
DragOperation DragOver(IInputRoot inputRoot, Point point, IDragData data, DragOperation operation);
void DragLeave(IInputRoot inputRoot);
DragOperation Drop(IInputRoot inputRoot, Point point, IDragData data, DragOperation operation);
}
}

4
src/OSX/Avalonia.MonoMac/Avalonia.MonoMac.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
@ -19,4 +19,4 @@
<ProjectReference Include="..\..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
</ItemGroup>
<Import Project="..\..\..\build\MonoMac.props" />
</Project>
</Project>

63
src/OSX/Avalonia.MonoMac/DraggingInfo.cs

@ -0,0 +1,63 @@
using System.Collections.Generic;
using Avalonia.Controls.DragDrop;
using MonoMac.AppKit;
namespace Avalonia.MonoMac
{
class DraggingInfo : IDragData
{
private readonly NSDraggingInfo _info;
public DraggingInfo(NSDraggingInfo info)
{
_info = info;
}
internal static NSDragOperation ConvertDragOperation(DragOperation d)
{
NSDragOperation result = NSDragOperation.None;
if (d.HasFlag(DragOperation.Copy))
result |= NSDragOperation.Copy;
if (d.HasFlag(DragOperation.Link))
result |= NSDragOperation.Link;
if (d.HasFlag(DragOperation.Move))
result |= NSDragOperation.Move;
return result;
}
internal static DragOperation ConvertDragOperation(NSDragOperation d)
{
DragOperation result = DragOperation.None;
if (d.HasFlag(NSDragOperation.Copy))
result |= DragOperation.Copy;
if (d.HasFlag(NSDragOperation.Link))
result |= DragOperation.Link;
if (d.HasFlag(NSDragOperation.Move))
result |= DragOperation.Move;
return result;
}
public Point Location => new Point(_info.DraggingLocation.X, _info.DraggingLocation.Y);
public IEnumerable<string> GetDataFormats()
{
yield break;
}
public string GetText()
{
return null;
}
public IEnumerable<string> GetFileNames()
{
yield break;
}
public bool Contains(string dataFormat)
{
return false;
}
}
}

76
src/OSX/Avalonia.MonoMac/TopLevelImpl.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Avalonia.Controls.DragDrop;
using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Platform;
@ -36,6 +37,7 @@ namespace Avalonia.MonoMac
bool _isLeftPressed, _isRightPressed, _isMiddlePressed;
private readonly IMouseDevice _mouse;
private readonly IKeyboardDevice _keyboard;
private readonly IDragDispatcher _dragDispatcher;
private NSTrackingArea _area;
private NSCursor _cursor;
private bool _nonUiRedrawQueued;
@ -52,6 +54,11 @@ namespace Avalonia.MonoMac
_tl = tl;
_mouse = AvaloniaLocator.Current.GetService<IMouseDevice>();
_keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
_dragDispatcher = AvaloniaLocator.Current.GetService<IDragDispatcher>();
RegisterForDraggedTypes(new string[] {
"public.data" // register for any kind of data.
});
}
protected override void Dispose(bool disposing)
@ -144,6 +151,75 @@ namespace Avalonia.MonoMac
UpdateCursor();
}
public override NSDragOperation DraggingEntered(NSDraggingInfo sender)
{
IInputRoot root = _tl?.InputRoot;
if (root == null || _dragDispatcher == null)
return NSDragOperation.None;
var dragOp = DraggingInfo.ConvertDragOperation(sender.DraggingSourceOperationMask);
DraggingInfo info = new DraggingInfo(sender);
var pt = TranslateLocalPoint(info.Location);
dragOp = _dragDispatcher.DragEnter(root, pt, info, dragOp);
return DraggingInfo.ConvertDragOperation(dragOp);
}
public override NSDragOperation DraggingUpdated(NSDraggingInfo sender)
{
IInputRoot root = _tl?.InputRoot;
if (root == null || _dragDispatcher == null)
return NSDragOperation.None;
var dragOp = DraggingInfo.ConvertDragOperation(sender.DraggingSourceOperationMask);
DraggingInfo info = new DraggingInfo(sender);
var pt = TranslateLocalPoint(info.Location);
dragOp = _dragDispatcher.DragOver(root, pt, info, dragOp);
return DraggingInfo.ConvertDragOperation(dragOp);
}
public override void DraggingExited(NSDraggingInfo sender)
{
IInputRoot root = _tl?.InputRoot;
if (root == null || _dragDispatcher == null)
return;
_dragDispatcher.DragLeave(root);
}
public override bool PrepareForDragOperation(NSDraggingInfo sender)
{
IInputRoot root = _tl?.InputRoot;
if (root == null || _dragDispatcher == null)
return false;
var dragOp = DraggingInfo.ConvertDragOperation(sender.DraggingSourceOperationMask);
DraggingInfo info = new DraggingInfo(sender);
var pt = TranslateLocalPoint(info.Location);
dragOp = _dragDispatcher.DragOver(root, pt, info, dragOp);
return DraggingInfo.ConvertDragOperation(dragOp) != DragOperation.None;
}
public override bool PerformDragOperation(NSDraggingInfo sender)
{
IInputRoot root = _tl?.InputRoot;
if (root == null || _dragDispatcher == null)
return false;
var dragOp = DraggingInfo.ConvertDragOperation(sender.DraggingSourceOperationMask);
DraggingInfo info = new DraggingInfo(sender);
var pt = TranslateLocalPoint(info.Location);
dragOp = _dragDispatcher.Drop(root, pt, info, dragOp);
return DraggingInfo.ConvertDragOperation(dragOp) != DragOperation.None;
}
public override void SetFrameSize(CGSize newSize)
{
lock (SyncRoot)

Loading…
Cancel
Save