Drag and Drop Handling


Simple Feedback

Here is a very simple example for handling feedback:

 onDragEnter
   "An object is being dragged over me"
   <on: dragEnter>
   self color := Color green. "show feedback"
 onDragLeave
   "An object is being dragged out of me"
   <on: dragLeave>
   self color := Color white. "reset feedback"

Conditional feedback

It is often useful to determine whether an object can accept the drop and give proper feedback. This can be done for example by:

 onDragEnter
   "An object is being dragged over me"
   <on: dragEnter>
   (self canAcceptDrop: hand dragContents)
      ifTrue:[self color := Color green] "accept"
      ifFalse:[self color := Color red]. "reject"

The method "canAcceptDrop:" needs to be written by the user - see below for examples.


Handling the drop itself

When an object is being dropped, we need to make sure we accept or reject the drop properly. Here is how:

 onDragDrop: aPlayer
   <on: dragDrop>
   (self canAcceptDrop: aPlayer)
     ifTrue:[aPlayer signal: #dropAccept with: self]
     ifFalse:[aPlayer signal: #dropReject].

The #dropReject event is used to inform the player that we did NOT accept that drop but rather actively rejected it. The #dropAccept event informs the player that the drag and drop operation was successfully completed.


Figuring out what to accept

Unless you plan to accept arbitrary players you may need to figure out which players to accept. Here are some choices:

 canAcceptDrop: aPlayer
   "Answer whether I can accept this player"
   ^aPlayer isKindOf: SomePlayerClass
 canAcceptDrop: aPlayer
   "Answer whether I can accept this player"
   ^aPlayer isTilePlayer
 canAcceptDrop: aPlayer
   "Answer whether I can accept this player"
   ^(aPlayer userDataAt: #dropStuff) notNil

The last version requires that the player in question has been set up properly to carry the appropriate "drop stuff" by, e.g.,

 aPlayer userDataAt: #dropStuff put: <something>