Generic Function | Package: cg | ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 10.1 Unrevised from 10.0 to 10.1. 10.0 version

## drag-and-drop

Arguments: widget

Initiates a dragging operation from widget. The user may "drop" onto another control by clicking the mouse to associate the two controls together in some way.

The drag continues until the user "drops" by either pressing a mouse button (if no mouse buttons were down when drag-and-drop was called), releasing a mouse button (if a mouse button was down when drag-and-drop was called), or pressing ESCAPE to cancel the drag.

During this time, the mouse cursor changes to indicate whether a drop is allowed at the current mouse cursor location. A drop is allowed whenever the mouse cursor is over a control where droppable-p returns true when called on the dragged control and that dropped-onto control. When the drop is done on the dragged widget, then both droppable-p and droppable-onto-self must return true to allow the drop.

The default droppable-p and droppable-onto-self methods return `nil`, so an application must supply methods in order to allow any drag-and-drop behavior.

By convention, drag-and-drop should not be called for a particular control if

    (draggable-p control)

returns `nil`. The default draggable-p method returns true for any control.

If the user drops where a drop is allowed, then good-drop is called; if the user drops elsewhere, then bad-drop is called; if the user cancels by pressing ESCAPE, then neither function is called.

An application will typically add draggable-p methods to determine which controls may be dragged from, droppable-p methods to determine which controls may be dropped onto which, and good-drop methods to process successful drops. drag-and-drop-mouse-moved methods could be added to trigger side effects as the user drags the mouse cursor.

drag-and-drop returns the control that was dropped onto if any, or `nil` otherwise. There is no dropped-onto control if the user either cancels the drag by pressing ESCAPE or drops at a location that is not over any control.

By default, the only visual indication that a drag is taking place is the changing mouse cursor. This is the standard drag-and-drop approach in Windows. But if

    (drag-images (configuration *system*))

is set to true, then an attempt is made to drag an image of some part of the dragged-from control. (See configuration, `*system*`, and drag-images.)

This image is obtained by calling box-to-drag on the dragged-from control and copying pixels from the screen for that section of the control. box-to-drag methods are supplied for most of the controls to specify the area occupied by the currently selected value of the control. Note that this approach will not work well if the current value of the control is ever scrolled out of view. Depending on which types of controls are being dragged from, these images may or may not be considered sufficiently aesthetic for an application's interface, and so this dragging option should not be used if the result is unsatisfactory.

When the IDE is running, a general mouse-left-down method (shown below) causes drag-and-drop to be called if the ALT key is held down and a left click and drag is done on a control. A droppable-p method for the inspector allows dropping arbitrary values from arbitrary controls into inspector slots, and a droppable-p method specializing on both the main IDE toolbar and the extended IDE toolbar allows dragging commands between or within these toolbars. Other than these cases, the IDE does not make use of drag-and-drop, and the methods described in this paragraph exist in the IDE only. Applications must define their own gestures to call drag-and-drop, as well as their own droppable-p methods to define where drops are allowed.

The following code implements the IDE's mouse-left-down method for initiating drags. It checks to see if the alt-key is down (but not the control-key or shift-key) and if the mouse cursor was in the interior area of the widget that was clicked. If so, it then initiates a drag, and otherwise it calls the next method.

    (defmethod mouse-left-down ((widget dialog-item)
                                buttons cursor-position)
      ;; This method exists in the IDE to allow initiating drags
      ;; by alt-clicking any widget.
      (with-boxes (box1)
        (case (logand buttons #.(logior control-key shift-key alt-key))
          (#.alt-key
           (when (and (draggable-p widget)
                      (inside-box-p cursor-position
                                    (nvisible-box (window widget) box1)))
             (drag-and-drop widget)))
          (t (call-next-method)))))

Applications can add similar methods to initiate drags. Note that while a simple left click could alternately be used to initiate a drag, this should not be done for certain widgets where a mouse-left-down always waits for a mouse-left-up to complete a value selection gesture, since the mouse will not be in a meaningful position for this when the user finally releases the mouse button after dragging; this constraint appears to be limited to the `single-item-list` and `multi-item-list` widgets. See also wait-for-drag for another way to decide whether to initiate a drag.

### GTK Note

drag-and-drop is not yet supported on the GTK platform due to an unsolved problem with not being able to change the mouse cursor while the mouse button is down. If you call the function on GTK, it will otherwise work, but it is not really useful without being able to change the mouse cursor image to show the user where a drop is allowed.

Copyright (c) 1998-2022, Franz Inc. Lafayette, CA., USA. All rights reserved.
This page was not revised from the 10.0 page.
Created 2019.8.20.

|  | ToC | DocOverview | CGDoc | RelNotes | FAQ | Index | PermutedIndex
| Allegro CL version 10.1 Unrevised from 10.0 to 10.1. 10.0 version