Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Programmer's Guide to MacApp / Part 1 - MacApp Theory and Architecture
Chapter 9 - Drag and Drop


Performing a Drop Operation

This section describes how the objects in a MacApp application work together with the Macintosh Drag Manager to perform a drop operation. The discussion refers to the steps of a drop operation--those steps are shown in Figure 9-3.

Registering to Receive a Drop

Objects in the application register with other objects and with the Drag Manager to indicate that they can receive dropped data. A droppable view registers with its window object, and the window registers with the global drag session object. The drag session object installs any callback routines needed by the Drag Manager to let the application handle drag tracking and receive dropped data.

There is no need for a view to register the fact that it can initiate a drag.

The following routines perform drop registration and install Drag Manager callback routines:

Reacting to Drag Manager Callbacks

While a user continues a drag operation, the Drag Manager makes periodic calls to TDragDropSession::DragTrackingHandlerGlue, the application's callback routine for tracking a drag. The Drag Manager passes a message that indicates the state of the drag--that is, whether it's entering or leaving the drag handler or whether it's entering, leaving, or tracking in a drag window.

The DragTrackingHandlerGlue method passes the message on in a call to the TDragDropSession::DragTrackingHandler method, which calls an appropriate method of the drag session object, based on the message.

Determining the Target of a Drop

When a user drags over an application window, the Drag Manager calls on the application to determine whether the drag is above a droppable view. The Drag Manager passes the message for tracking in a window, causing the DragTrackingHandler method to call the drag session object's HandleTrackInWindow method. That method calls the window to supply from its list of droppable views a target view that can accept the current dragged data.

For each of its droppable views, the window's MouseToDropTarget method calls the WillAcceptDrop method, which iterates over the drag items in the current drag. A view normally accepts a drop only if it can accept at least one flavor for each drag item in the drag data. For efficiency, the window caches information about whether a specific view can accept the current drag, so it doesn't have to be recalculated if the user drags off a view and back over it again. For more information about accepting a drop, see "When a View Should Accept a Drop" and "CDragItemIterator" on page 266.

If the window contains a view that can accept the drop, the drag session's tracking handler calls methods of the view to provide visual feedback, as described in the next section.

Providing Visual Feedback for a Drop

Depending on the type of view, visual feedback may include highlighting a region of the view and indicating the current insertion point for the data to be dropped. Step 5 in Figure 9-3 (page 259) shows the highlighted drop-target view and the insertion point for a dragged text selection.

When the window returns a target view willing to accept the drag, the drag session object, in response to callbacks from the Drag Manager, calls the following TView methods to provide visual feedback and track the drag operation:

DoDragEnter
Notifies the view that it has been entered by a drag. The view can set up any internal data it uses to track a drag. This may involve initializing variables that track the drop insertion location.
DoMakeDropHiliteRegion
Creates and returns a highlight region to represent the target of the drag. Unlike other drag-and-drop methods that supply regions, DoMakeDropHiliteRegion returns the region in global screen coordinates. The TView method LocalToGlobalRegion is provided to convert a region from local to global coordinates.
DoDragWithin
Called repeatedly as the user drags within the view. Allows view to update any visual tracking indicators it provides. This may involve blinking and relocating an insertion point, highlighting a grid cell, or providing other feedback.
DoDragLeave
Called when the drag exits the view, it erases any visual tracking information that has been drawn and frees any memory allocated during tracking. If the user releases the mouse while over a view that is tracking, DoDragLeave is not called until after the view has been given a chance to extract data from the drag operation, as described in "Creating Drag-and-Drop Commands" below.

Performing a Drop

When the user releases the mouse while dragging over a view that has agreed to accept a drag, the Drag Manager calls the drag session object's DragReceiveHandlerGlue method, which in turns calls the DragReceiveHandler method. The DragReceiveHandler method determines whether the dragged data should be moved or copied. The logic used to determine whether to treat the drag as a move or copy is described in the section "Drag Copy Versus Drag Move" on page 268.

Once the DragReceiveHandler method has determined whether the drag is a copy or move, it calls the TView method DoMakeDragDropCommand, passing a command number of cDrag, cDrop, or cDragMove:

Creating Drag-and-Drop Commands

The previous section describes how a view's DoMakeDragDropCommand method is asked to create a drag-and-drop command based on the command number passed to it. When a view is asked to create a cDrag command, it creates and returns a command whose DoIt method removes the dragged data from the view. The command's UndoIt method reinserts the data, and its RedoIt method removes the data again.

When a view is asked to create a cDrop command, it creates and returns a command whose DoIt method inserts the dropped data into the view. The command's UndoIt method removes the inserted data, and its RedoIt method inserts the data again.

IMPORTANT
A view's DoMakeDragDropCommand method must pull all the necessary data out of the current drag before returning, because drag item data becomes invalid as soon as a drag operation is complete.
When a view is asked to create a cDragMove command, it creates and returns a command whose DoIt method moves the selected data from its current location in the view to the location specified by the drop. The UndoIt method reverses the move and the RedoIt method restores it.

Many current MacApp applications already implement commands that perform data insertion or removal. It should be possible to reuse these existing commands, with little modification, to perform the actual work of a drag, drop, or move operation.

Posting the Command

A view is not responsible for posting a command it creates. The DragReceiveHandler method posts commands as necessary.

Linked Commands

A drag move operation that causes data to be moved between views has the effect of causing both the source view and the destination view to create a command. The DragReceiveHandler method then links the two commands together. MacApp's TCommandHandler class automatically manages operations on linked commands. Doing, undoing, redoing, or committing either command causes the linked command to be done, undone, redone, or committed as well.

When MacApp performs a command, it checks the command's fValidationFailed field. If either command of a linked pair of commands fails to complete execution because of a validation error, MacApp ensures that both commands are left undone and that the Clipboard is also left in its
previous state.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
25 JUL 1996