GEOS SDK TechDocs
|
|
4.4 Managing Input
|
5 Interaction Commands
Occasionally, you may need a response from the user before continuing with a thread of execution. In these cases, you should use a dialog box to prompt the user for the needed response. However, you also need a means to block the thread of execution until the user responds to this dialog box. The routines
UserDoDialog()
,
UserStandardDialog()
, and
UserStandardDialogOptr()
provide this functionality.
UserDoDialog(), UserCreateDialog(), UserDestroyDialog()
You may bring dialog boxes on-screen with several routines. The most common and easiest to use of these routines is
UserDoDialog()
.
UserDoDialog()
only operates on GIV_DIALOG Interactions set both GIA_MODAL and GIA_INITIATED_WITH_USER_DO_DIALOG.
This routine, when passed the optr of a dialog box, will bring the dialog Interaction on-screen. In addition to bringing up a dialog, however,
UserDoDialog()
will also block the calling thread until a response trigger in the dialog is activated by the user. When this happens,
UserDoDialog()
returns a value representing the response trigger selected. This return value is usually an
InteractionCommand
.
The dialog may contain any UI gadgetry but must have response triggers with valid
InteractionCommand
s to terminate the dialog box. These triggers should have a null output and message and have
ATTR_GEN_TRIGGER_INTERACTION_COMMAND
vardata set to the proper
InteractionCommand
s. (See the GenTrigger chapter.) This InteractionCommand
will be the response value returned by
UserDoDialog()
when that trigger is activated. This can be one of the predefined
InteractionCommand
s or an application-defined one with IC_CUSTOM_START.
The response triggers should also have the attribute GA_SIGNAL_INTERACTION_COMPLETE set to ensure that the dialog will be dismissed when they are activated. (This may be omitted to gain manual control over dismissal over the dialog, but you still must provide a way to dismiss the dialog.) Any response triggers in the dialog should have the hint
HINT_SEEK_REPLY_BAR
to place the triggers within the dialog's reply bar, but this is not necessary.
Because the calling thread is blocked by
UserDoDialog()
, views run by that thread will not be updated when exposed.
Code Display 7-18 Using UserDoDialog()
/* This dialog box asks for confirmation before beginning a delete file operation. * Therefore, it is advisable to block threads before beginning this operation. The * dialog using UserDoDialog() should be marked both GIA_MODAL and * GIA_INITIATED_VIA_USER_DO_DIALOG. */
@object GenInteractionClass ConfirmDeleteBox = {
GI_comp = @ConfirmDeleteText;
GII_type = GIT_AFFIRMATION;
GII_visibility = GIV_DIALOG;
GII_attrs = @default | GIA_INITIATED_VIA_USER_DO_DIALOG | GIA_MODAL;
}
@object GenTextClass ConfirmDeleteText = {
GTI_text = "Are you sure you want to delete this file?";
}
/* This dialog box is displayed through a normal routine call with * the optr of the dialog box as its one argument. */
/* Check for positive response. */
if (UserDoDialog(@ConfirmDeleteBox) == IC_YES) {
/* delete file. */
}
UserDoDialog()
may also return IC_NULL to indicate that the modal dialog has been dismissed by the system, so it is always a good idea to check for and act on positive responses even if only one response is possible (such as in a GIT_NOTIFICATION dialog box).
UserCreateDialog()
duplicates a dialog box to initiate later with
UserDoDialog()
. Typically, the dialog box duplicated is within a template object block; the dialog box must be both not GS_USABLE and not attached to the generic tree when created. The dialog box must also be marked GIA_INITIATED_VIA_USER_DO_DIALOG.
The template block that contains the dialog box and its children must be sharable and read-only.
UserCreateDialog()
duplicates a template dialog box, attaches the dialog box to the GenApplication object and sets it fully GS_USABLE; it may then be called with
UserDoDialog()
. When you no longer have a need for the dialog box, send it
UserDestroyDialog()
.
These routines are useful for conserving memory space; they only take up space when actually being used. In some cases, you may need to use these routines. For example, within libraries, dialog boxes must be duplicated before being used because multiple applications may require their own copy of the dialog box template.
Code Display 7-19 Using UserCreateDialog(), UserDestroyDialog()
/* * The template dialog box must not be GS_USABLE. The object must also be marked * GIA_INITIATED_VIA_USER_DO_DIALOG. The block must be sharable, read-only, and * the top GenInteraction must not be linked into the generic tree. */
@object GenInteractionClass MyDialogTemplate = {
GI_visMoniker = "Template";
GI_states = @default & ~GS_USABLE;
GII_visibility = GIV_DIALOG;
GII_attrs = @default | GIA_INITIATED_VIA_USER_DO_DIALOG |
GIA_NOT_USER_INITIATABLE | GIA_MODAL;
GII_type = GIT_NOTIFICATION;
GI_comp = @NotificationGlyph;
}
@method SomeProcessClass, MSG_BRING_UP_DUPLICATED_DIALOG
{
optr newDialog;
newDialog = UserCreateDialog(@MyDialogTemplate);
if (UserDoDialog(@newDialog) == IC_OK) {
/*** code ***/
}
UserDestroyDialog(@newDialog); }
UserStandardDialog(), UserStandardDialogOptr(), CustomDialogBoxFlags
UserStandardDialog()
displays standardized dialog boxes. The dialog is standardized in that it has a text area, an icon glyph representing the type of situation that caused the dialog to be displayed, and one or more response triggers. Like
UserDoDialog()
,
UserStandardDialog()
blocks the calling thread until the user activates one of the response triggers. Unlike
UserDoDialog()
, however,
UserStandardDialog()
does not need an application-defined dialog box.
UserStandardDialog()
builds a dialog box at run-time following the specifications passed.
UserStandardDialog()
passes a number of parameters:
CustomDialogBoxFlags
This bitfield stores the
CustomDialogType
(CDBF_DIALOG_TYPE) and the
GenInteractionType
(CDBF_INTERACTION_TYPE) to display the Interaction with, along with several miscellaneous flags
UserDoDialog()
should not only be application modal but also system modal.
CustomDialogType
) are:
GenInteractionType
enums. The available types are:
UserStandardDialog()
in
arg1
and
arg2
. They will replace all occurrences of \001 and \002 in the dialog string. This is useful for including filenames or other variable text in the dialog string.Code Display 7-20 Using UserStandardDialog()
/* * This simple example uses no help context, custom triggers, or string arguments. */
if ((UserStandardDialog( (char *)0,
(char *)0,
(char *)0,
(char *)0,
"Do you wish to continue?",
((CDT_QUESTION << CDBF_DIALOG_TYPE_OFFSET) |
(GIT_AFFIRMATION << CDBF_INTERACTION_TYPE_OFFSET))
) == IC_YES)) {
/* code to perform on a positive response. */
}
else {
/* code to perform on a negative response. */
}
You may also use
UserStandardDialogOptr()
for cases in which the strings are referenced through optrs rather than pointers.
Code Display 7-21 A ConfirmDeleteBox with explicit monikers
/* For this case, since we want to provide explicit monikers, we must use the * GIT_MULTIPLE_RESPONSE interaction type. Using this allows us to pass in the * monikers and response values for the response triggers for the dialog. This is * done by passing a pointer to a table consisting of the number of triggers in the * dialog and a StandardDialogResponseTriggerEntry for each trigger. Each entry * contains an optr of the moniker to use and the response value for the trigger. * The moniker may be simple text or a graphics string. The response value may be * one of the predefined InteractionCommands or an application-defined value based * on IC_CUSTOM_START. */
@visMoniker ConfirmYesMoniker = "Delete this file";
@visMoniker ConfirmNoMoniker = "Skip this file";
/* Create a table to hold the trigger data. */
static const StandardDialog2ResponseTriggerTable confirmResponseTable [] = {
2, /* SD2RTT_numTriggers */
/* WRT_trigger1 */
{ConfirmYesMoniker, /* SDRTE_moniker */
IC_YES}, /* SDRTE_responseValue */
/* WRT_trigger2 */
{ConfirmNoMoniker, /* SDRTE_moniker */
IC_NO} /* SDRTE_responseValue */
};
/* Display the dialog with UserStandardDialog(). */
if (UserStandardDialog( (char *)0,
(char *)&confirmResponseTable,
(char *)0,
(char *)0,
"Are you sure you want to delete this file?",
((CDT_QUESTION << CDBF_DIALOG_TYPE_OFFSET) |
/* interaction type - application supplied trigger */
(GIT_MULTIPLE_RESPONSE << CBDF_INTERACTION_TYPE_OFFSET)))
== IC_YES) {
/* delete file */
}
Code Display 7-22 A IC_CUSTOM_START Interaction
#define SAVE_CHANGES IC_CUSTOM_START+0 #define ABORT_CHANGES IC_CUSTOM_START+1 #define CANCEL_CLOSE IC_CUSTOM_START+2
@visMoniker CloseSaveMoniker = "Save Changes"; @visMoniker CloseAbortMoniker = "Abort Changes": @visMoniker CloseCancelMoniker = "Cancel Close";
static const StandardDialog3ResponseTriggerTable closeResponseTable [] = {
3, /* SD3RTT_numTriggers */
/* WRT_trigger1 */
{CloseSaveMoniker, /* SDRTE_moniker */
IC_YES}, /* SDRTE_responseValue */
/* WRT_trigger2 */
{CloseAbortMoniker, /* SDRTE_moniker */
IC_YES}, /* SDRTE_responseValue */
/* WRT_trigger3 */
{CloseCancelMoniker, /* SDRTE_moniker */
IC_NO} /* SDRTE_responseValue */
};
closeWithChangesResponse = (UserStandardDialog( (char *)0, (char *)&closeResponseTable, (char *)0, (char *)0, ((CDT_QUESTION << CDBF_DIALOG_TYPE_OFFSET) | /* interaction type - application supplied triggers */ (GIT_MULTIPLE_RESPONSE << CDBF_INTERACTION_TYPE_OFFSET)), (char *)0);
switch (closeWithChangesResponse) {
case SAVE_CHANGES:
/* save changes */
case ABORT_CHANGES:
/* abort changes */
case IC_CANCEL_CLOSE:
/* cancel close */
case IC_NULL:
/* IC_NULL is always a potential response */
}
GEOS SDK TechDocs
|
|
4.4 Managing Input
|
5 Interaction Commands