7 changed files with 145 additions and 7 deletions
@ -0,0 +1,90 @@ |
|||
using Avalonia.Input; |
|||
using Avalonia.Interactivity; |
|||
using Avalonia.VisualTree; |
|||
using System.Linq; |
|||
|
|||
namespace Avalonia.Controls.DragDrop |
|||
{ |
|||
class DefaultDragDispatcher : IDragDispatcher |
|||
{ |
|||
public static readonly DefaultDragDispatcher Instance = new DefaultDragDispatcher(); |
|||
|
|||
private Interactive _lastTarget = null; |
|||
|
|||
private DefaultDragDispatcher() |
|||
{ |
|||
} |
|||
|
|||
private Interactive GetTarget(IInputElement root, Point local) |
|||
{ |
|||
var target = root.InputHitTest(local)?.GetSelfAndVisualAncestors()?.OfType<Interactive>()?.FirstOrDefault(); |
|||
if (target != null && DragDrop.GetAcceptDrag(target)) |
|||
return target; |
|||
return null; |
|||
} |
|||
|
|||
private DragOperation RaiseDragEvent(Interactive target, RoutedEvent<DragEventArgs> routedEvent, DragOperation operation, IDragData data) |
|||
{ |
|||
if (target == null) |
|||
return DragOperation.None; |
|||
var args = new DragEventArgs(routedEvent, data) |
|||
{ |
|||
RoutedEvent = routedEvent, |
|||
DragOperation = operation |
|||
}; |
|||
target.RaiseEvent(args); |
|||
return args.DragOperation; |
|||
} |
|||
|
|||
public DragOperation DragEnter(IInputElement inputRoot, Point point, IDragData data, DragOperation operation) |
|||
{ |
|||
_lastTarget = GetTarget(inputRoot, point); |
|||
return RaiseDragEvent(_lastTarget, DragDrop.DragEnterEvent, operation, data); |
|||
} |
|||
|
|||
public DragOperation DragOver(IInputElement inputRoot, Point point, IDragData data, DragOperation operation) |
|||
{ |
|||
var target = GetTarget(inputRoot, point); |
|||
|
|||
if (target == _lastTarget) |
|||
return RaiseDragEvent(target, DragDrop.DragOverEvent, operation, data); |
|||
|
|||
try |
|||
{ |
|||
if (_lastTarget != null) |
|||
_lastTarget.RaiseEvent(new RoutedEventArgs(DragDrop.DragLeaveEvent)); |
|||
return RaiseDragEvent(target, DragDrop.DragEnterEvent, operation, data); |
|||
} |
|||
finally |
|||
{ |
|||
_lastTarget = target; |
|||
} |
|||
} |
|||
|
|||
public void DragLeave(IInputElement inputRoot) |
|||
{ |
|||
if (_lastTarget == null) |
|||
return; |
|||
try |
|||
{ |
|||
_lastTarget.RaiseEvent(new RoutedEventArgs(DragDrop.DragLeaveEvent)); |
|||
} |
|||
finally |
|||
{ |
|||
_lastTarget = null; |
|||
} |
|||
} |
|||
|
|||
public DragOperation Drop(IInputElement inputRoot, Point point, IDragData data, DragOperation operation) |
|||
{ |
|||
try |
|||
{ |
|||
return RaiseDragEvent(_lastTarget, DragDrop.DropEvent, operation, data); |
|||
} |
|||
finally |
|||
{ |
|||
_lastTarget = null; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using Avalonia.Interactivity; |
|||
|
|||
namespace Avalonia.Controls.DragDrop |
|||
{ |
|||
public sealed class DragDrop : AvaloniaObject |
|||
{ |
|||
public static RoutedEvent<DragEventArgs> DragEnterEvent = RoutedEvent.Register<DragEventArgs>("DragEnter", RoutingStrategies.Bubble, typeof(DragDrop)); |
|||
public static RoutedEvent<RoutedEventArgs> DragLeaveEvent = RoutedEvent.Register<RoutedEventArgs>("DragLeave", RoutingStrategies.Bubble, typeof(DragDrop)); |
|||
public static RoutedEvent<DragEventArgs> DragOverEvent = RoutedEvent.Register<DragEventArgs>("DragOver", RoutingStrategies.Bubble, typeof(DragDrop)); |
|||
public static RoutedEvent<DragEventArgs> DropEvent = RoutedEvent.Register<DragEventArgs>("Drop", RoutingStrategies.Bubble, typeof(DragDrop)); |
|||
|
|||
public static AvaloniaProperty<bool> AcceptDragProperty = AvaloniaProperty.RegisterAttached<Interactive, bool>("AcceptDrag", typeof(DragDrop), inherits: true); |
|||
|
|||
public static bool GetAcceptDrag(Interactive interactive) |
|||
{ |
|||
return interactive.GetValue(AcceptDragProperty); |
|||
} |
|||
|
|||
public static void SetAcceptDrag(Interactive interactive, bool value) |
|||
{ |
|||
interactive.SetValue(AcceptDragProperty, value); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using Avalonia.Interactivity; |
|||
|
|||
namespace Avalonia.Controls.DragDrop |
|||
{ |
|||
public class DragEventArgs : RoutedEventArgs |
|||
{ |
|||
public DragOperation DragOperation { get; set; } |
|||
|
|||
public IDragData Data { get; private set; } |
|||
|
|||
public DragEventArgs(RoutedEvent<DragEventArgs> routedEvent, IDragData data) |
|||
: base(routedEvent) |
|||
{ |
|||
this.Data = data; |
|||
} |
|||
|
|||
} |
|||
} |
|||
Loading…
Reference in new issue