Drag and Drop

Like the clipboard, drag and drop is a common metaphor for data transfer. By clicking and dragging with the mouse, the user can move, copy, or link data within or between applications. It is signed to allow drag/drop integration with other applications; as with the clipboard, untrusted applications can only perform local drag and drop operations.

The following application demonstrates Pivot's support for drag and drop. Users can drag the sample images from this page into the applet (the area within the border), or drag the image out of the applet into any other application that supports images:

The BXML source for this example is as follows. It creates an ImageView and attaches a drag source and drop target to it via the dragSource and dropTarget attributes, respectively. The code for these handlers is defined in "dragdrop.js", discussed next:

            
            <Window title="Drag and Drop" maximized="true"
                xmlns:bxml="http://pivot.apache.org/bxml"
                xmlns="org.apache.pivot.wtk">
                <bxml:script src="dragdrop.js"/>
                <Border styles="{padding:2}">
                    <ImageView bxml:id="imageView" image="/org/apache/pivot/tutorials/IMG_0767_2.jpg"
                        dragSource="$dragSoure" dropTarget="$dropTarget"/>
                </Border>
            </Window>
            
        

The contents of "dragdrop.js" are as follows:

            
            importPackage(org.apache.pivot.wtk);

            var dragSoure = new DragSource() {
                beginDrag: function(component, x, y) {
                    return true;
                },

                endDrag: function(component, dropAction) {
                    // No-op
                },

                getContent: function() {
                    var content = new LocalManifest();
                    content.putImage(imageView.getImage());

                    return content;
                },

                getOffset: function() {
                    // No-op; not used for native drags
                    return null;
                },

                getRepresentation: function() {
                    // No-op; not used for native drags
                    return null;
                },

                getSupportedDropActions: function() {
                    return DropAction.COPY.getMask();
                },

                isNative: function() {
                    return true;
                }
            };

            var dropTarget = new DropTarget() {
                dragEnter: function(component, dragContent, supportedDropActions, userDropAction) {
                    return (dragContent.containsImage()) ? DropAction.COPY : null;
                },

                dragExit: function(component) {
                    // No-op
                },

                dragMove: function(component, dragContent, supportedDropActions, x, y, userDropAction) {
                    return (dragContent.containsImage()) ? DropAction.COPY : null;
                },

                userDropActionChange: function(component, dragContent, supportedDropActions,
                    x, y, userDropAction) {
                    return (dragContent.containsImage()) ? DropAction.COPY : null;
                },

                drop: function(component, dragContent, supportedDropActions, x, y, userDropAction) {
                    var dropAction = null;

                    if (dragContent.containsImage()) {
                        imageView.setImage(dragContent.getImage());
                        dropAction = DropAction.COPY;
                    }

                    return dropAction;
                }
            };
            
        

When the user initiates a drag operation, the Pivot platform detects the gesture and walks the component hierarchy looking for a drag source. When it finds one, it calls beginDrag(). If this method returns true, the platform calls getContent() and begins the drag. Like the clipboard, drag/drop content is also stored in a Manifest. In the case of a drag source, a LocalManifest is used. The drag source in this example simply places the image that is currently displayed by the image view in the manifest. It also reports that the only supported action for this drag operation is COPY, by returning the bitmask value of DropAction.COPY from getSupportedDropActions().

When the user drags an image over the image view, the platform walks the component hierarchy looking for a drop target. When it finds one, it calls dragEnter(). If the drop target is capable of accepting the drop, it returns its preferred drop action (the action that would result if the user dropped the drag content at that point). The platform repeatedly calls dragMove() while the mouse remains over the drop target, giving the application the opportunity to report a different drop action depending on the current mouse location.

Finally, when the user releases the mouse button, the drop() method is called. This method actually performs the drop, and returns the actual drop action that was performed (or null if nothing was dropped).

Next: Effects