All Manuals > CAPI User Guide and Reference Manual > 17 Drag and Drop

17.2 Dragging

First you should decide which CAPI pane(s) and interfaces will support dragging, and which data formats they will support. Data formats are arbitrary keywords that must be interpreted by the pane where the user can drop.

17.2.1 Dragging values from a choice

To implement dragging in list-panel or tree-view supply the :drag-callback initarg. When the user drags, drag-callback receives a list of indices of the choice items being dragged.

The drag-callback should return a property list whose keys are the data formats (such as :string or :image) to be dragged, along with the values associated with each format.

17.2.1.1 Example: dragging from a tree

This example returns string data for a tree-view defined below:

(defun tree-drag-callback (pane indices)
  (list :string 
        (string (elt (capi:collection-items pane)
                     (first indices)))))
 
(defun fruits (x) 
  (case x 
    (:fruits (list :apple :orange))
    (:apple (list :cox :bramley))
    (:orange (list :blood-orange :seville))
    (t nil)))
 
(capi:contain
 (make-instance 'capi:tree-view
                :title "Fruit tree"
                :roots '(:fruits)
                :children-function 'fruits
                :drag-callback 'tree-drag-callback))

There is a further example showing dragging from list-panels in:

(example-edit-file "capi/choice/drag-and-drop")

17.2.2 Dragging within an output-pane

To implement dragging items around within a single output-pane, include suitable callbacks on these gestures in its input-model:

(:button-1 :press)
(:button-1 :motion)

In this case it is not necessary to call drag-pane-object and you can implement dropping in the same pane by a suitable callback for:

(:button-1 :release)

See this example:

(example-edit-file "capi/applications/balloons")

17.2.3 Dragging values from an output-pane

To implement dragging from an output-pane include an appropriate callback on the (:button-1 :press) gesture in the pane's input-model. This callback should call drag-pane-object with arguments which provide the data formats and values associated with each format. You will also specify drop-callback in the destination pane(s), as described in 17.3 Dropping.

See the example file in:

(example-edit-file "capi/output-panes/drag-and-drop")
17.2.3.1 Dragging editor-pane text

To implement dragging of text in an editor-pane, use EDITOR functions such as editor:points-to-string to obtain the value for the :string format.

17.2.4 Data formats

:string
Receives a string, potentially from another application. Is also understood by some other panes that expect text.
:image

Receives an image on Cocoa and GTK+. The value passed should be an image object. See 13.10 Working with images for more information about images.

When supplying an image for dragging (that is, including :image image in the plist argument of drag-pane-object or in the plist that is returned from the drop-callback), the dragging mechanism frees the image (as by free-image) when it finishes with it (which will be at some indeterminate time later). If you need to pass an image which you want to use later, you should make a copy of it by make-sub-image.

When receiving an image (by calling drop-object-get-object with :image), the received image should also be freed when you finish with it. However, it will be freed automatically when the pane supplied to drop-object-get-object is destroyed, so you do not need to free it explicitly if freeing can wait (which is probably true in most cases).

See this example:

(example-edit-file "capi/choice/list-panel-drag-images")
:filename-list

Receives a list of files. Is understood by other applications such as the macOS Finder and Windows Explorer.

You can also use private formats, named by arbitrary keywords, which will work only in the same Lisp image.

17.2.5 Dragging a Cocoa title bar image

On Cocoa, if there is a drag image in an interface title bar, then dragging this image will by default return a list containing the interface pathname as :filename-list data. You could override this by providing a drag-callback for the interface.


CAPI User Guide and Reference Manual (Macintosh version) - 01 Dec 2021 19:31:25