XPCE's drag-and-drop interface allows the user to drag-and-drop graphical objects and dict_item objects. Drag-and-drop is a common GUI technique to specify operations that require two objects in a specific order. Moving files to another directory by dragging them to the icon of the target directory is a common example.
It may also be used to specify operations on a single object, where the operation is represented by an icon. Dragging files to a trash-bin is the most commonly found example.
For the drag-and-drop interface to work, the programmer must connect 
a drag_and_drop_gesture to the object to be dragged.12Attach 
a drag_and_drop_dict_item_gesture to a list_browser 
to enable dragging the items in the dictionary. A Drop-zone 
defines the method ->drop and (not strictly 
obligatory) ->preview_drop. ->drop 
is called to actually perform the associated operation, while ->preview_drop 
may be used to indicate what will happen if the object is dropped now.
Below is a complete example that allows the user to drag objects for moving and copying on another window.
Class drop_picture defines a graphical window that imports graphical 
objects when they are dropped onto it. The feedback is a dotted 
rectangle indicating the area of the graphical to be imported. See
`graphical ->preview_drop' 
for a description of the arguments.
:- pce_begin_class(drop_picture, picture).
preview_drop(P, Gr:graphical*, Pos:[point]) :->
        (   Gr == @nil                  % pointer leaves area
        ->  (   get(P, attribute, drop_outline, OL)
            ->  send(OL, free),
                send(P, delete_attribute, drop_outline)
            ;   true
            )
        ;   (   get(P, attribute, drop_outline, OL)
            ->  send(OL, position, Pos)
            ;   get(Gr?area, size, size(W, H)),
                new(OL, box(W, H)),
                send(OL, texture, dotted),
                send(P, display, OL, Pos),
                send(P, attribute, drop_outline, OL)
            )
        ).
The method ->drop. If the graphical originates 
from the same picture just move it. Otherwise <-clone 
the graphical and display the clone.
drop(P, Gr:graphical, Pos:point) :->
        (   get(Gr, device, P)
        ->  send(Gr, position, Pos)
        ;   get(Gr, clone, Gr2),
            send(P, display, Gr2, Pos)
        ).
:- pce_end_class.
Class dragbox defines a simple subclass of class box that can be resized and dragged.
:- pce_begin_class(dragbox, box).
:- pce_autoload(drag_and_drop_gesture, library(dragdrop)).
:- pce_global(@dragbox_recogniser, make_dragbox_recogniser).
make_dragbox_recogniser(G) :-
        new(G, handler_group(resize_gesture(left),
                             drag_and_drop_gesture(left))).
event(B, Ev:event) :->
        (   send(B, send_super, event, Ev)
        ;   send(@dragbox_recogniser, event, Ev)
        ).
:- pce_end_class.
The toplevel predicate creates two drop_pictures in one frame (note that drag-and-drop-gestures work accross frames, but not accross multiple XPCE processes at the moment). It displays one dragbox in one of the windows. Dragging it inside a picture moves the box, dragging it to the other windows makes a copy of the box.
dragdropdemo :-
        new(F, frame('Drag and Drop Demo')),
        send(F, append, new(P1, drop_picture)),
        send(new(drop_picture), right, P1),
        send(P1, display, dragbox(100, 50), point(20,20)),
        send(F, open).
->drop and ->preview_drop 
methods than to pass the icon representing it. GetSource is a 
function that is evaluated with @arg1 
bound to the graphical when the gesture is activated. An example could 
be:
drag_and_drop_gesture(left,
                      get_source :=
                             @arg1?db_record)
If the method accepts a point for the second argument, a point will be passed that represents the location of the pointer in the coordinate system of the drop-zone, subtracted by the distance between the top-left corner of the dragged graphical to the pointer at the moment the button was depressed. To get the position of the pointer itself, just ask for the position of @event relative to the drop-zone.
->drop, 
but the first argument can be @nil, 
indicating that the mouse has left the drop-zone. Under this condition, 
the position argument is @default.
If a position argument is available, the drag_and_drop_gesture will be activated on each drag event. Otherwise it is only activated if the pointer enters the area of the drop-zone.