Using drag and drop


Starting a drag and drop operation

The do_drag_drop() function is used to start a drag and drop event in a Sculptor program. It is normally called when the program receives the left mouse button down event or equivalent, and returns after the mouse button has been released. The return value indicates the result of the drag and drop operation.


Target window

A window in which objects can be dropped must have the style flag WS_DROP_TARGET. An object can be dropped within its original window or in another window, but this style flag must always be applied if the window may be a drop target.

If drag and drop events are required, they must be enabled in the target window by means of the event_enable clause. Enabling EV_DRAG_DROP enables all drag and drop events. The following example enables drag and drop in addition to those events enabled for a window by default:

event_enable = EV_DEFAULT | EV_DRAG_DROP

Target window event function

When a dragged object is over a window that has the style flag WS_DROP_TARGET, the window’s event function is called as follows:

func_id(event_code, window_id, key_state, xpos, ypos, control_id, valid_effects)


event_code

The event code is one of the following:

EV_DRAG_ENTER

Indicates that an object being dragged has entered the window. The event function should return the drop effect codes that are valid for the window as a whole. See below. It may also change the shape of the cursor if desired (see the function setcursor()).

EV_DRAG_LEAVE

Indicates that an object being dragged has left the window. No action is necessary unless the cursor shape was altered when the object entered, in which case it should be reset.

EV_DRAG_OVER

Sent as the object is dragged across the window. If the object is currently over a control, the event function should return the drop effect codes that are valid for that control or, if not over a control, the codes that are valid for the window as a whole. The cursor shape can also be changed if desired.

EV_DROP

Indicates the position where the object has been dropped. The event function must process the dropped object and return the appropriate drop codes. If the cursor shape has been changed, it should be reset. See Returning drop codes from the event function below.

window_id

The window receiving the event. This is a required argument to the check_drag_drop() and get_drag_drop() functions.

key_state

The states of the mouse buttons and the shift and control keys. These should be tested using the & operator to determine which bits are set. Mouse and key states are defined in sculptor.h with the prefix MK_, and are as follows:

MK_LBUTTON

Left mouse button is down.

MK_RBUTTON

Right mouse button is down

MK_MBUTTON

Middle mouse button is down (3-button mouse)

MK_SHIFT

Shift key is down

MK_CONTROL

Control key is down

MK_ALT

ALT key is down

See Testing which keys have been pressed to determine drop effect.

xpos, ypos

The x and y co-ordinates of the mouse relative to the target window. The values are returned in pixels or characters, according to the grid type in use. Note, however, that in programs compiled with versions of scc earlier than 5.6.2 RC2, the values were always returned in characters. The command !compat dragchar can be used to retain the old behaviour if desired.

control_id

The identifier of the control within the window window_id that the mouse is over. If the mouse is over a blank area in the window this argument is NULL.

valid_effects

A bit mask indicating the drop effects that are valid for the object being dragged. It must be used to mask off the required drop effect bits when returning from the EV_DROP event. For example, to return DROPEFFECT_COPY:

return DROPEFFECT_COPY & valid_effects

See Returning drop codes from the event function below.


Returning drop codes from the event function

If the event code EV_DROP is received, the event function must process the dropped object and return the appropriate drop codes.

If the drop has been refused, the function should return DROPEFFECT_NONE.

Otherwise, it should return one or more of the following flags, combined using the | operator and masked with the value in valid_effects:

DROPEFFECT_COPY

The object has been copied.

DROPEFFECT_MOVE

The object has been moved. Normally used if the Shift key was down when the object was dropped and move is appropriate for the object type.

DROPEFFECT_LINK

The object has been linked. Normally used if the both the Shift and Control keys were down when the object was dropped and link is appropriate for the object type.

DROPEFFECT_SCROLL

Scrolling is about to start or is currently occurring in the target program. This bit can be set with other values above.


EXAMPLE

!function evWindow(EventCode, Window, Keys, X, Y, Ctrl, ValidEffect) {
     if ((EventCode & EV_DRAG_DROP) == 0) {       /* Not a drag and drop event */
          return
     }

     if ((EventCode == EV_DRAG_LEAVE) {           /* Object is leaving this window*/
          return DROPEFFECT_NONE
     }

     if ((EventCode == EV_DROP) {
          return DROPEFFECT_MOVE & ValidEffect
     }
}

Testing which keys have been pressed to determine drop effect

Testing whether the CTRL and SHIFT keys are pressed enables the correct DROPEFFECT value to be determined. This indicates the type of operation to be performed: a copy of, move of, or link to the object being dragged. The program is free to implement any meaning to these keys, but a typical application behaviour would be the following:

No key pressed

The default. The behaviour depends on the type of the target application. A typical interpretation is that if the drag is local (the drag source is the same program), a move operation is performed; if it is not, a copy is performed.

CTRL pressed

DROPEFFECT_COPY.

SHIFT pressed

DROPEFFECT_MOVE.

CTRL and SHIFT pressed

DROPEFFECT_LINK.

This example illustrates a function that tests for the CTRL and SHIFT keys, assigning DROPEFFECT_COPY as the default.


EXAMPLE

!function evWindow(EventCode, Window, Keys, X, Y, Ctrl, ValidEffect) {
!temp ResultEffect,,i2

     ...
     ResultEffect = fDropEffect(Keys)
     ...
}

!function fDropEffect(Keys) {
!temp ResultEffect,,i2

     if (Keys & MK_CONTROL) {
          if (Keys & MK_SHIFT) {    /* CTRL and SHIFT both pressed */
               ResultEffect = DROPEFFECT_LINK
          }
          else {                    /* CTRL only pressed */
              ResultEffect = DROPEFFECT_COPY
          }
     }
     else {
          if (Keys & MK_SHIFT) {    /* SHIFT only pressed */
               ResultEffect = DROPEFFECT_MOVE
          }
          else {                    /* Neither key pressed */
              ResultEffect = DROPEFFECT_COPY
         }
     }
     return ResultEffect
}

RELATED TOPICS

Drag and drop and the clipboard

Drag and drop and clipboard functions