| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- using System;
- using System.Runtime.InteropServices;
- using System.Threading.Tasks;
- using Avalonia.Controls;
- using Avalonia.Input;
- using Avalonia.Input.Platform;
- using Avalonia.Interactivity;
- using Avalonia.Native.Interop;
- using Avalonia.VisualTree;
- namespace Avalonia.Native
- {
- class AvaloniaNativeDragSource : IPlatformDragSource
- {
- private readonly IAvaloniaNativeFactory _factory;
- public AvaloniaNativeDragSource(IAvaloniaNativeFactory factory)
- {
- _factory = factory;
- }
- private static TopLevel FindRoot(object? element)
- {
- while (element is Interactive interactive && element is not Visual)
- element = interactive.GetInteractiveParent();
- if (element == null)
- return null;
- var visual = (Visual)element;
- return visual.GetVisualRoot() as TopLevel;
- }
- class DndCallback : NativeCallbackBase, IAvnDndResultCallback
- {
- private TaskCompletionSource<DragDropEffects> _tcs;
- public DndCallback(TaskCompletionSource<DragDropEffects> tcs)
- {
- _tcs = tcs;
- }
- public void OnDragAndDropComplete(AvnDragDropEffects effect)
- {
- _tcs?.TrySetResult((DragDropEffects)effect);
- _tcs = null;
- }
- }
-
- public Task<DragDropEffects> DoDragDrop(PointerEventArgs triggerEvent, IDataObject data, DragDropEffects allowedEffects)
- {
- // Sanity check
- var tl = FindRoot(triggerEvent.Source);
- var view = tl?.PlatformImpl as WindowBaseImpl;
- if (view == null)
- throw new ArgumentException();
- triggerEvent.Pointer.Capture(null);
-
- var tcs = new TaskCompletionSource<DragDropEffects>();
-
- var clipboardImpl = _factory.CreateDndClipboard();
- using (var clipboard = new ClipboardImpl(clipboardImpl))
- using (var cb = new DndCallback(tcs))
- {
- if (data.Contains(DataFormats.Text))
- // API is synchronous, so it's OK
- clipboard.SetTextAsync(data.GetText()).Wait();
-
- view.BeginDraggingSession((AvnDragDropEffects)allowedEffects,
- triggerEvent.GetPosition(tl).ToAvnPoint(), clipboardImpl, cb,
- GCHandle.ToIntPtr(GCHandle.Alloc(data)));
- }
- return tcs.Task;
- }
- }
- }
|