Cancel vs Dismiss DA2


 
There are two functions that are needed to dismiss either Open C dialogs or UIStyler dialogs. These functions are UF_UI_cancel_uf_dialog and UF_UI_dismiss_dialog_area_2. This section discusses how and when to use these functions.
 
When done using an Open C dialog it is required to send a message informing NX that this dialog is no longer in use and that it can dismiss it. To do this you use the Open C API UF_UI_dismiss_dialog_area_2. It may seem a little strange that this dialog is not automatically dismissed, but this lies in the current NX design assumption. This assumption is that even though a dialog has been dismissed, it may really be coming right back depending on the actions the user has taken. Therefore, in order to avoid dialog flickering we leave the dialog up unless a message is sent saying, "No, I really want this dialog to be dismissed." Because the Open C dialogs are dialogs that are used in NX this theory flows down to the Open C dialogs.
 
If you have wrappered your Open C dialog call with UF_UI_lock_ug_access and UF_UI_unlock_ug_access then you do not need to call UF_UI_dismiss_dialog_area_2. Note that your Open C dialog call must be immediately followed with UF_UI_unlock_ug_access or else the dialog remains up until this is called. Also, if you call two Open C dialogs in a row, in other words a callback that calls two Open C dialogs, then you do not need to call UF_UI_dismiss_dialog_area_2 in between the two Open C calls. Calling the second Open C dialog automatically dismisses the first Open C dialog for you.
 
Calling UF_UI_dismiss_dialog_area_2 when it is not necessary does not cause any problems. So if in doubt call UF_UI_dismiss_dialog_area_2. However, UF_UI_dismiss_dialog_area_2 is NOT needed with UIStyler dialogs.
 
As mentioned earlier if you desire your custom applications to call interactive Open C APIs which can override other interactive Open C APIs, you must use the cancel protocol - UF_UI_cancel_uf_dialog. By following this protocol, your customized menu and persistent dialogs can keep specific push buttons and toggle buttons available while other custom applications are active. This means that push buttons on your persistent dialogs which use this protocol do not have to be greyed or ungreyed in a corresponding state change callback.
 
A custom dialog can only bring up a new Open C dialog when UF_UI_cancel_uf_dialog returns a UF_UI_SUCCESS. The new interactive Open C dialog MUST be brought up with a call to XtAppAddTimeOut. Failure to do this can give unpredictable results. Below is a small code sample showing this protocol. A more complete example is shown under the UF_UI_cancel_uf_dialog reference page.
 
Example:
This is an excerpt of an example which uses UF_UI_cancel_uf_dialog with the XtAppAddTimeOut call. The complete example is located in the reference page to UF_UI_cancel_uf_dialog. The function launch_pt_sub_cb in the below excerpt is the callback from a push button on a custom dialog. This push button is never greyed out, so the user can call it at any time. Because of this it is necessary to check and see if NX is locked. If it is then a call to UF_UI_cancel_uf_dialog must be made prior to the call to Point Subfunction in order to ensure that the currently displayed Open C dialog or UIStyler dialog is canceled properly. XtAppAddTimeOut has a callback proc that calls a wrapper function that calls the actual program that launches the point subfunction dialog.
static void
launch_pt_sub_cb( Widget w, XtPointer button_state, 
                  XtPointer client_data)
{
    int rcode;

    if (initialize_uf( ) == UFUN_NOT_INITIALIZED)
        return;

    /*  Check to see if a lock is set if so then follow the */
    /*  cancel protocol                                     */

    if (UF_UI_ask_lock_status() == UF_UI_LOCK)
    {
    /*  Cancel the user function dialog. If the currently   */
    /*  displayed DA2 was not brought up by either the       */
    /*  UIStyler or Open C then you are not allowed to */
    /*  cancel this DA2 and will receive a UF_UI_FAILURE     */
    /*  from the call to UF_UI_cancel_uf_dialog              */

        rcode = UF_UI_cancel_uf_dialog(UF_UI_FROM_CUSTOM);

        if (rcode == UF_UI_SUCCESS)
    /*  It is imperative that you call XtAppAddTimeOut prior */
    /*  to launching a another Open C dialog                */
            
XtAppAddTimeOut(XtWidgetToApplicationContext(custom_dialog),
                10,
                XtTimerCallbackProc) call_uc1616_xt,
                (XtPointer) NULL);

 
NOTE:
The function call_uc1616_xt() must be defined as type XtTimerCallbackProc rather than XtCallbackProc:
        else
            UF_UI_set_status("Can not launch an Open C dialog in 
this state");
    }
    else
        call_uc1616();

    UF_terminate();
}

/*  This is called with the XtAppAddTimeOut function. It is just */
/*  a wrapper to the real function that does the actual work.   */
/*  This way it can be called outside of the XtAppAddTimeOut     */
/*  function.                                                   */

static void call_uc1616_xt ( XtPointer call_data, 
                             XtIntervalId *id )
{
    call_uc1616();
}

/**************************************************************
 *  Function:     call_uc1616
 *  Description:  This launches the Open C dialog Point
 *                Subfunction.
 **************************************************************/

static void call_uc1616 ( void )
{
    int    def[2];
    double point1[3];

    int rcode;

    /*  Call a local function to init ufun */
    if ( initialize_uf( ) == UFUN_NOT_INITIALIZED)
        return;

    /*  You must wrapper the call to uc1616 with         */
    /*  UF_UI_lock_ug_access and UF_UI_unlock_ug_access. */
    /*  This handles the necessary handshaking which     */
    /*  informs NX that an Open C dialog is coming up    */
    /*  from a custom dialog. Also, because of the use   */
    /*  of these wrappers, it is not necessary to use    */
    /*  UF_UI_dismiss_dialog_area_2 when done with uc1616*/

    rcode = UF_UI_lock_ug_access(UF_UI_FROM_CUSTOM);

    if (rcode == UF_UI_LOCK_SET)
    {
        rcode = uc1616("Create Point", def, 0, point1);
        if (rcode == 8)
           UF_UI_set_status("Not allowed to bring up an Open C 
dialog in this state");

        rcode = UF_UI_unlock_ug_access(UF_UI_FROM_CUSTOM);
    }
    else
        UF_UI_set_status("Could not lock NX");

    UF_terminate();
  
}

 
Another location for the UF_UI_cancel_uf_dialog is to place it at any custom dialog navigation button that causes the custom dialog to be dismissed, such as OK, Back, and Cancel. This way if the user has brought up an Open C dialog and then decides to Cancel the custom dialog the Open C dialog is cancelled. If UF_UI_cancel_uf_dialog is not used then some unpredictable behavior may occur. It is recommended to check and see if the lock has been set when cancelling the custom dialog via a navigation button. This can be done using UF_UI_ask_lock_status. If the lock is currently set then first call UF_UI_cancel_uf_dialog. In this particular scenario, nothing should follow the call to UF_UI_cancel_uf_dialog. The unlocking of the Open C dialog is handled in the original callback that called UF_UI_lock_ug_access. An example of this is in the reference section of UF_UI_cancel_uf_dialog.
 
NOTE: You can not cancel a dialog unless the lock protocol has been used.
 
In Figure 1-4 the Point, Select, and CSYS buttons use the Cancel Custom DA2 protocol. When the CSYS dialog displays, pressing the Select button causes the CSYS dialog to be replaced by the Class Selection dialog. The Point button can be pressed to replace the Class Selection dialog with the Point Subfunction dialog. This protocol only replaces dialogs which are created from custom applications.
 
Refer to the description of UF_UI_cancel_uf_dialog() for an example of the this API.
 
 

 
Figure 1-4 Cancel Custom DA2. This is from the mult_ufsta.c example provided in the ugsamples kit.
 
Cancel vs Dismiss Summary