Drag and Drop
Drag and drop is quite simple, really. You have a few events to work with, if you’re working directly with a Panel and not a PanelComponent:
// called when you start dragging
// i like to create a "ghost" element here to represent the thing i'm dragging
protected override void OnDragStart( DragEvent dragEvent )
{
}
// called when you stop dragging
// you can clean up your "ghost" element here
// this is also where you'd handle dropping the item
protected override void OnDragEnd( DragEvent dragEvent )
{
}
// called while you're dragging, on every movement
// you can update the position of your "ghost" element here
protected override void OnDrag( DragEvent dragEvent )
{
}
To allow dragging in the first place, you need to override WantsDrag:
public override bool WantsDrag => true;
If you spawn a “ghost” element to represent the thing you’re dragging, you can position it inside the OnDrag method with this calculation:
_ghost.Style.Top = (dragEvent.ScreenPosition.y - dragEvent.LocalGrabPosition.y) * ScaleFromScreen;
_ghost.Style.Left = (dragEvent.ScreenPosition.x - dragEvent.LocalGrabPosition.x) * ScaleFromScreen;
To handle dropping the item onto another panel, there are a couple of ways to do it. This is the way I do it, but I think there is a built in method to handle this now that I haven’t tried yet.
In the OnDragEnd method, you can query all the panels under the mouse position like this:
var characterPreview = FindRootPanel()
.Descendants
.OfType<CharacterPreview>()
.FirstOrDefault( x => x.IsInside( dragEvent.ScreenPosition ) );
if ( characterPreview.IsValid() )
{
// dropped on a valid CharacterPreview panel
}
If you know where that official method was, please let me know!