[ Previous | Next | Contents | Glossary | Home | Search ]
Motif 2.1 Programmer's Guide



Drop Receiver Responsibilities for Dropping

The drop receiver's responsibilities for dropping are the same as any widget's responsibilities as the destination widget in a UTM transfer. See Chapter 16 for more details.

This chapter explains how a drop receiver can provide help to the user.

Providing Help

It might not always be obvious to the user what the result of dropping a particular source on a drop site might be. The user can request more information about the drop site by pressing osfHelp while the drag icon is over the drop site.

When the user presses osfHelp, UTM starts a drop by doing the following:

  1. Sets the dropAction member of the XmDropProcCallbackStruct to XmDROP_HELP.

  2. Sets the operation member of the XmDestinationCallbackStruct to XmOTHER.

    When the user presses osfHelp, your XmNdestinationCallback procedure must realize a DialogBox. This DialogBox must provide help about the drop site, and must give users the choice of either continuing or cancelling the drop. While the DialogBox is realized, your XmNdestinationCallback procedure must neither perform any transfers nor call XmTransferDone. Your XmNdestinationCallback procedure must save the transfer_id member for any later XmTransferValue calls to be made.

    After the user accepts or rejects the transfer, the processing continues from the callbacks on the dialog buttons. In the case of accepting the transfer, the transfer may be continued by using the transfer_id in calls to all the normal transfer calls in UTM. In the case of rejecting the transfer, the programmer must call XmTransferDone with a status of XmTRANSFER_DONE_FAIL. This will clean up the internal state of UTM and provide drag and drop zap effects to indicate the failure to the user.

    The following example taken from DNDDemo.c shows how the help dialog shown in the illustration was created.

    Figure 26. Help Dialog.

    View figure.

    The handleDestination routine examines the operation member of the XmDestinationCallbackStruct. If operation holds XmOTHER, then the HandleHelp routine is called:

    void
    handleDestination(Widget w, XtPointer client, XtPointer call)
    {
      XmDestinationCallbackStruct *cs = (XmDestinationCallbackStruct *)
    call;
     
      if (appInfo->highlightRect != NULL)
        RectUnhighlight(w);
     
      if (cs->operation != XmOTHER)
        HandleDrop(w, call, NULL);
      else
        HandleHelp(w, call, NULL);
    }

    The HandleHelp routine displays the help dialog. The text presented in the dialog depends on the drop site and on the requested operation. Callback routines are registered to be performed when either of the dialog pushbuttons is pressed.

    static void
    HandleHelp(Widget w, XtPointer call, XtPointer ignore)
    {
      XmDestinationCallbackStruct *cs = (XmDestinationCallbackStruct *)
    call;
      XmDropProcCallbackStruct *ds =  
      	(XmDropProcCallbackStruct *) cs -> destination_data;
      Boolean                         rectFound, bgFound, pixFound;
      XmString                        helpStr;
      RectPtr                         rect;
      Arg                             args[5];
      XmString                        tempStr, buttonArray[2];
      int                             n = 0;
     
      savedCB = cs;
     
      /* if we haven't created a help dialog, create one now */
      if (helpDialog == NULL) {
        XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
        XtSetArg(args[n], XmNtitle, "Drop Help"); n++;
        helpDialog = XmCreateMessageDialog(topLevel, "Help", args, n);
     
        n = 0;
        buttonArray[0] = XmStringCreateSimple("Move");
        buttonArray[1] = XmStringCreateSimple("Copy");
        XtSetArg(args[n], XmNbuttons, buttonArray); n++;
        XtSetArg(args[n], XmNbuttonCount, 2); n++;
        XtSetArg(args[n], XmNbuttonSet, 0); n++;
        XtSetArg(args[n], XmNsimpleCallback, ChangeOperation); n++;
        tempStr = XmStringCreateSimple("Operations:");
        XtSetArg(args[n], XmNoptionLabel, tempStr); n++;
        helpMenu = XmCreateSimpleOptionMenu(helpDialog, "helpMenu", args, n);
        XmStringFree(tempStr);
        XmStringFree(buttonArray[0]);
        XmStringFree(buttonArray[1]);
     
        XtAddCallback(helpDialog, XmNokCallback,
                      (XtCallbackProc) HandleDrop, NULL);
        XtAddCallback(helpDialog, XmNcancelCallback,
                      (XtCallbackProc) CancelDrop, NULL);
        XtUnmanageChild(XmMessageBoxGetChild(helpDialog, XmDIALOG_HELP_BUTTON));
        XtRealizeWidget(helpDialog);
      }
     
      /* find the valid targets */
      CheckTargets(ds->dragContext, XtDisplay(w), &rectFound,
                   &bgFound, &pixFound);
     
      /* determine the appropriate help message */
      if (rectFound) {
        if (ds->operations == XmDROP_MOVE | XmDROP_COPY) {
          XtManageChild(helpMenu);
          helpStr = XmStringCreateLtoR(HELP_MSG4, XmFONTLIST_DEFAULT_TAG);
          XtManageChild(XmMessageBoxGetChild(helpDialog, XmDIALOG_OK_BUTTON));
        } else if (ds->operation == XmDROP_MOVE) {
          XtUnmanageChild(helpMenu);
          helpStr = XmStringCreateLtoR(HELP_MSG2, XmFONTLIST_DEFAULT_TAG);
          XtManageChild(XmMessageBoxGetChild(helpDialog, XmDIALOG_OK_BUTTON));
        } else if (ds->operation == XmDROP_COPY) {
          XtUnmanageChild(helpMenu);
          helpStr = XmStringCreateLtoR(HELP_MSG3, XmFONTLIST_DEFAULT_TAG);
          XtManageChild(XmMessageBoxGetChild(helpDialog, XmDIALOG_OK_BUTTON));
        }
      } else if (bgFound || pixFound && ds->operation == XmDROP_COPY) {
        XtUnmanageChild(helpMenu);
        rect = RectFind(ds->x, ds->y);
        if (rect) {
          helpStr = XmStringCreateLtoR(HELP_MSG1, XmFONTLIST_DEFAULT_TAG);
          XtManageChild(XmMessageBoxGetChild(helpDialog, XmDIALOG_OK_BUTTON));
        } else {
          helpStr = XmStringCreateLtoR(HELP_MSG5, XmFONTLIST_DEFAULT_TAG);
          XtUnmanageChild(XmMessageBoxGetChild(helpDialog,
                                               XmDIALOG_OK_BUTTON));
        }
      } else {
        XtUnmanageChild(helpMenu);
        helpStr = XmStringCreateLtoR(HELP_MSG5, XmFONTLIST_DEFAULT_TAG);
        XtUnmanageChild(XmMessageBoxGetChild(helpDialog, XmDIALOG_OK_BUTTON));
      }
     
      /* set the help message into the dialog */
      XtSetArg(args[0], XmNmessageString, helpStr);
      XtSetValues(helpDialog, args, 1);
     
      /* Free the XmString */
      XmStringFree(helpStr);
     
      /* map the help dialog */
      XtManageChild(helpDialog);
    }

    If the user selects the OK button to continue the drop, the program calls HandleDrop again. If the user selects the Cancel button, the program calls the CancelDrop routine. This routine calls XmTransferDone as follows to cancel the drop:

    static void
    CancelDrop(Widget w, XtPointer call, XtPointer ignore)
    {
      XmDestinationCallbackStruct *cs;
     
      /* For drop help we save the XmDestinationCallbackStruct in a global
         variable named savedCB. */
      cs = savedCB;
     
      XmTransferDone(cs -> transfer_id, XmTRANSFER_DONE_FAIL);
    }

  3. [ Previous | Next | Contents | Glossary | Home | Search ]