Programmer Reference : Common Widgets : Platform-integrated drag and drop : Drag source widgets and the CwDragContext object
Drag source widgets and the CwDragContext object
A drag source widget has a dragDetectCallback hooked that sends the dragStart:argBlock: method of CwWidget. To start a drag from a drag source widget, the user holds down a mouse button while over the widget and moves the mouse to a different location.
The mouse button that initiates a drag is platform dependent. On Windows platforms, the left mouse button triggers a dragDetectCallback. On OS/2, the right mouse button triggers it. And, on OSF/Motif platforms, the middle mouse button triggers it.
Some platforms allow dragging with a button other than those listed above. To implement this behavior, applications call dragStart:argBlock: from a button event handler.
The following example hooks a dragDetectCallback to a specified widget:
hookDragDetect: aCwWidget
"Hook a dragDetect callback to the specified widget."
addCallback: XmNdragDetectCallback
selector: #dragDetect:clientData:callData:
clientData: nil.
When a drag begins over the widget, dragDetect:clientData:callData: is sent to the receiver. The parameters to this callback are as follows:
The CwWidget to which the dragDetact callback hooks (aCwWidget)
The clientData specified when the dragDetect callback was hooked (nil)
An instance of CwDragDetectCallbackData.
The CwDragDetectCallbackData instance contains a ButtonPress event that can determine the mouse position and button when the button is pressed. The callData reason is either XmCRDRAG or XmCRDRAGSELECT.
On platforms that allow the left mouse button to initiate a drag, normal drag selection might cause the dragDetectCallback to be amibiguous in certain widgets, such as text and list widgets. In these cases, the callData reason will be XmCRDRAGSELECT and the application can decide whether to allow the drag selection to continue, or set the callData doit to false and start a drag.
OSF/Motif platforms provide default drag behavior in text, label, and button widgets. Common Widgets drag and drop turns off this behavior in a widget when a dragDetect callback is added.
Starting the drag--CwDragContext
An application starts a drag from a dragDetect callback handler by sending dragStart:argBlock: with a CwDragContext create argBlock to the widget that received the callback. Sending dragStart:argBlock: creates a CwDragContext which represents the drag source for the duration of the drag and drop operation. Only one instance of CwDragContext can exist at any time, and the instance ceases to exist when the drag and drop operation is complete.
The dragStart:argBlock: message must only be sent from a dragDetect callback handler or a button press event handler. The first parameter must be the button press event that initiated the drag.
The following drag context resources can be set in the create argBlock when the drag starts:
The CgIcon that replaces the mouse cursor during dragging.
The operations that the drag source supports.
The target types that the drag source supports, in order of source preference with the most complete and accurate representation of the data first.
A proc that is received one or more times after a valid drop, in which the source application must provide the dragged data in the format specified by the target type in the proc's callData. The convert proc will be called as many time as the destination requests, each time with a different target type. A source must be preparted to provide the data in the proper format for any of the export targets it supports. It passes the data to the destination by filling in the value field of the the proc's callData.
The following code shows a typical dragDetect callback handler. It starts a drag, specifying the operations and targets that the drag source supports and hooking a convertProc to handle the source side of the data transfer. Assume that self dragIcon answers a CgIcon.
dragDetectCallback: aCwWidget clientData: clientData callData: callData
"Handle the dragDetect callback for the receiver."
| startDrag |
(startDrag := callData reason = XmCRDRAG)
ifFalse: [
"The reason is XmCRDRAGSELECT.
Decide if the user is doing a drag or a select."
(self checkDragSourceCoordinates: callData event x @ callData event y)
ifTrue: [
"Interpret the mouse action as a drag operation
rather than a selection operation. Set the doit flag to false to
prevent the widget from doing normal selection processing."
callData doit: false.
startDrag := true]].
ifTrue: [
dragStart: callData event
argBlock: [:dragContext |
sourceCursorIcon: self dragIcon;
dragOperations: XmDROPMOVE | XmDROPCOPY;
exportTargets: #('STRING');
convertProc: (CwCallbackRec
receiver: self
selector: #convertProc:clientData:callData:
clientData: aCwWidget)]].
Last modified date: 01/29/2015