 |
DECwindows Motif Guide to Application
Programming
- When the user clicks on the On Context push
button, the activate callback calls a routine to enter
context-sensitive help mode. The On Context push button also has a
context-sensitive help callback.
5.5.2 Entering Context-Sensitive Help Mode
The activate callback for the On Context push button calls a routine to
enter context-sensitive help mode, as shown in Example 5-3. Note that
all of the push buttons in the OpenVMS DECburger demo application call
back to the activate_proc routine. However, your application can
directly invoke the context-sensitive help callback from the On Context
push button.
Example 5-3 Calling the DXmHelpOnContext
Routine |
.
.
.
static void activate_proc(w, tag, reason)
Widget w;
int *tag;
XmAnyCallbackStruct *reason;
{
int widget_num = *tag; /* Convert tag to widget number. */
int i, value;
XmString topic;
switch (widget_num) {
.
.
.
(1)case k_help_sensitive:
tracking_help();
break;
.
.
.
static void tracking_help()
{
(2)DXmHelpOnContext(toplevel_widget, FALSE);
}
.
.
.
|
- When the activate_proc routine is called
with a tag that identifies the On Context push button, a
context-sensitive help routine (tracking_help) is called.
- DXmHelpOnContext changes the pointer cursor
to the help cursor and grabs it. (The application is in
context-sensitive help mode.) The user then moves the pointer cursor to
the object for which context-sensitive help is required and clicks MB1.
If the selected widget has a help callback, that help callback is
invoked. If the selected widget does not have a help callback, the
widget's ancestors are tested until a help callback is found or the top
of the widget hierarchy is reached. The DXmHelpOnContext routine
is called with the name of the application's top-level widget and a
Boolean value that indicates whether you want the locating activity
confined to that widget. If you confine the help pointer cursor to
the application's top-level widget (a Boolean value of TRUE), the user
will not be able to move the help pointer cursor outside the boundaries
of the main window. This means that the user could not get
context-sensitive help on pop-up widgets that extend beyond the
boundaries of the top-level widget. If you do not confine the help
pointer cursor to the application's top-level widget (a Boolean value
of FALSE), the user can potentially get context-sensitive help on any
of the application's widgets. The example does not confine the
help pointer cursor.
5.5.3 Specifying a Help Callback
Your application uses the XmNhelpCallback resource to
associate a context-sensitive help callback routine with the widgets
for which you want to provide help.
Your application can use the callback's tag argument
to supply help-topic-specific data. The help system
DXmHelpSystemDisplay routine uses a string value to specify the help
topic to display. Therefore, your application must supply the help
callback routine with a string value that specifies the help topic, as
shown in Example 5-4.
Example 5-4 Specifying a Help Callback---UIL
Module |
.
.
.
!String value to use for the help system callback
value
helpsys_order_help : 'order';
.
.
.
object ! The control panel. All order entry
! is done through this dialog box.
control_box : XmFormDialog {
arguments {
XmNdialogTitle = k_decburger_title;
XmNdialogStyle = XmDIALOG_MODELESS;
XmNnoResize = true;
XmNdefaultPosition = false;
XmNx = 525;
XmNy = 100;
XmNautoUnmanage = false;
XmNallowOverlap = false;
XmNdefaultButton = XmPushButton ok_button;
XmNcancelButton = XmPushButton cancel_button;
XmNhorizontalSpacing = 10;
XmNverticalSpacing = 10;
XmNnavigationType = XmEXCLUSIVE_TAB_GROUP;
};
controls {
XmForm burger_form;
XmForm fries_form;
XmForm drinks_form;
XmSeparator button_separator;
XmPushButton ok_button;
XmPushButton apply_button;
XmPushButton reset_button;
XmPushButton cancel_button;
XmSeparator button_separator;
};
callbacks {
MrmNcreateCallback = procedure create_proc (k_order_box);
(1)XmNhelpCallback = procedure help_system_proc (helpsys_order_help);
};
};
.
.
.
|
- The help callback routine uses this string
to set the DXmHelpSystemDisplay name argument, as
shown in Example 5-5.
Example 5-5 Specifying a Help Callback---C
Module |
.
.
.
/* Creates a help system session */
static void help_system_proc(w, tag, reason)
Widget w;
char *tag;
XmAnyCallbackStruct *reason;
{
DXmHelpSystemDisplay(help_context, decburger_help, "topic", tag,
help_error, "Help System Error");
}
.
.
.
|
If "dir" is used for the keyword argument, the
name argument must specify the character string
identifying the Bookreader directory to open. You could use this
feature to present the user directly with a list of examples, open the
help file at the index, and so forth. The Bookreader directory can be
"Contents", "Index", "Examples", "Figures", or "Tables", as shown in
the following example.
DXmHelpSystemDisplay(help_context, decburger_help, "dir", "Contents",
help_error, "Help System Error");
|
5.6 Implementing the Help System
Example 5-6 shows a sample implementation of the help system for
OpenVMS DECburger. Note that, unlike the actual DECburger code, this
code implements only the help system and not the help widget.
Example 5-6 UIL Help System
Implementation |
.
.
.
!module DECburger_demo
module decburger
version = 'v1.1.1'
names = case_sensitive
objects = {
XmSeparator = gadget ;
XmLabel = gadget ;
XmPushButton = gadget ;
XmToggleButton = gadget ;
}
procedure
toggle_proc (integer);
activate_proc (integer);
create_proc (integer);
scale_proc (integer);
list_proc (integer);
exit_proc (string);
show_hide_proc (integer);
pull_proc (integer);
(1) help_system_proc (string);
ok_color_proc ();
apply_color_proc ();
cancel_color_proc ();
value
k_create_order : 1;
k_order_pdme : 2;
k_file_pdme : 3;
k_edit_pdme : 4;
k_nyi : 5;
k_ok : 6; ! NOTE: ok, apply, reset, cancel
k_apply : 7; ! must be sequential
k_reset : 8;
k_cancel : 9;
k_cancel_order : 10;
k_submit_order : 11;
k_order_box : 12;
k_burger_min : 13;
k_burger_rare : 13;
k_burger_medium : 14;
k_burger_well : 15;
k_burger_ketchup : 16;
k_burger_mustard : 17;
k_burger_onion : 18;
k_burger_mayo : 19;
k_burger_pickle : 20;
k_burger_max : 20;
k_burger_quantity : 21;
k_fries_tiny : 22;
k_fries_small : 23;
k_fries_medium : 24;
k_fries_large : 25;
k_fries_huge : 26;
k_fries_quantity : 27;
k_drink_list : 28;
k_drink_add : 29;
k_drink_sub : 30;
k_drink_quantity : 31;
k_total_order : 32;
k_burger_label : 33;
k_fries_label : 34;
k_drink_label : 35;
k_menu_bar : 36;
k_file_menu : 37;
k_edit_menu : 38;
k_order_menu : 39;
k_help_pdme : 40;
k_help_menu : 41;
k_help_overview : 42;
k_help_about : 43;
k_help_onhelp : 44;
k_help_sensitive : 45;
k_print : 46;
k_options_pdme : 47;
k_options_menu : 48;
k_create_options : 49;
k_fries_optionmenu : 50;
value
k_decburger_title : 'DECburger: Order Entry Box';
k_nyi_label_text : 'This feature is not yet implemented.';
k_file_label_text : 'File';
k_print_label_text : 'Print Order..';
k_exit_label_text : 'Exit';
k_edit_label_text : 'Edit';
k_cut_dot_label_text : 'Cut';
k_copy_dot_label_text : 'Copy';
k_paste_dot_label_text : 'Paste';
k_clear_dot_label_text : 'Clear';
k_select_all_label_text : 'Select All';
k_order_label_text : 'Order';
k_cancel_order_label_text : 'Cancel Order';
k_submit_order_label_text : 'Submit Order';
k_options_label_text : 'Options';
k_options_color_label_text : 'Background Color...';
(2) k_help_label_text : 'Help';
k_sensitive_label_text : 'On Context';
k_overview_label_text : 'On Window';
k_about_label_text : 'On Version';
k_onhelp_label_text : 'On Help';
k_hamburgers_label_text : 'Hamburgers';
k_rare_label_text : 'Rare';
k_medium_label_text : 'Medium';
k_well_done_label_text : 'Well Done';
k_ketchup_label_text : 'Ketchup';
k_mustard_label_text : 'Mustard';
k_onion_label_text : 'Onion';
k_mayonnaise_label_text : 'Mayonnaise';
k_pickle_label_text : 'Pickle';
k_quantity_label_text : 'Quantity';
k_fries_label_text : 'Fries';
k_size_label_text : 'Size';
k_tiny_label_text : 'Tiny';
k_small_label_text : 'Small';
k_large_label_text : 'Large';
k_huge_label_text : 'Huge';
k_drinks_label_text : 'Drinks';
k_0_label_text : ' 0';
k_drink_list_text :
string_table ( 'Apple Juice',
'Orange Juice',
'Grape Juice',
'Cola',
'Punch',
'Root beer',
'Water',
'Ginger Ale',
'Milk',
'Coffee',
'Tea');
k_drink_list_select : string_table('Apple Juice');
k_ok_label_text : 'OK';
k_apply_label_text : 'Apply';
k_reset_label_text : 'Reset';
k_cancel_label_text : 'Cancel';
.
.
.
!String value to use for the Help System callbacks
(3) value
k_order_help : 'order';
k_print_help : 'print';
k_options_help : 'options';
k_menu_bar_help : 'menu_bar';
k_file_help : 'file_menu';
k_edit_help : 'edit_menu';
k_order_menu_help : 'order_menu';
k_help_help : 'help';
k_sensitive_help : 'sensitive';
k_onhelp_help : 'onhelp';
k_about_help : 'about';
k_overview_help : 'overview';
k_nyi_help : 'not_implemented';
.
.
.
object
s_menu_bar : XmMenuBar {
arguments {
XmNorientation = XmHORIZONTAL;
(4) XmNmenuHelpWidget = XmCascadeButton help_menu_entry;
};
controls {
XmCascadeButton file_menu_entry;
XmCascadeButton edit_menu_entry;
XmCascadeButton order_menu_entry;
XmCascadeButton options_menu_entry;
(5) XmCascadeButton help_menu_entry;
};
callbacks {
MrmNcreateCallback = procedure create_proc (k_menu_bar);
XmNhelpCallback = procedure help_system_proc(k_menu_bar_help);
};
};
.
.
.
(6) object help_menu_entry : XmCascadeButton {
arguments {
XmNlabelString = k_help_label_text;
XmNmnemonic = keysym("H");
};
controls {
XmPulldownMenu help_menu;
};
callbacks
{
XmNhelpCallback = procedure help_system_proc(k_help_help);
};
};
(7) object help_menu : XmPulldownMenu
{
controls
{
XmPushButton help_sensitive;
XmPushButton help_window;
XmPushButton help_version;
XmPushButton help_onhelp;
};
callbacks
{
XmNhelpCallback = procedure help_system_proc(k_help_help);
};
};
object help_sensitive : XmPushButton
{
arguments
{
XmNlabelString = k_sensitive_label_text;
XmNmnemonic = keysym("C");
};
callbacks
{
XmNactivateCallback = procedure activate_proc (k_help_sensitive);
XmNhelpCallback = procedure help_system_proc(k_sensitive_help);
};
};
object help_onhelp : XmPushButton
{
arguments
{
XmNlabelString = k_onhelp_label_text;
XmNmnemonic = keysym("H");
};
callbacks
{
XmNactivateCallback = procedure activate_proc (k_help_onhelp);
XmNhelpCallback = procedure help_system_proc(k_onhelp_help);
};
};
object help_version : XmPushButton
{
arguments
{
XmNlabelString = k_about_label_text;
XmNmnemonic = keysym("V");
};
callbacks
{
XmNactivateCallback = procedure activate_proc (k_help_about);
XmNhelpCallback = procedure help_system_proc(k_about_help);
};
};
object help_window : XmPushButton
{
arguments
{
XmNlabelString = k_overview_label_text;
XmNmnemonic = keysym("W");
};
callbacks
{
(8) XmNactivateCallback = procedure activate_proc (k_help_overview);
XmNhelpCallback = procedure help_system_proc(k_overview_help);
};
};
object ! The control panel. All order entry
! is done through this dialog box.
control_box : XmFormDialog {
arguments {
XmNdialogTitle = k_decburger_title;
XmNdialogStyle = XmDIALOG_MODELESS;
XmNnoResize = true;
XmNdefaultPosition = false;
XmNx = 375;
XmNy = 100;
XmNautoUnmanage = false;
XmNallowOverlap = false;
XmNdefaultButton = XmPushButton ok_button;
XmNcancelButton = XmPushButton cancel_button;
XmNhorizontalSpacing = 10;
XmNverticalSpacing = 10;
XmNnavigationType = XmEXCLUSIVE_TAB_GROUP;
};
controls {
XmForm burger_form;
XmForm fries_form;
XmForm drinks_form;
XmSeparator button_separator;
XmPushButton ok_button;
XmPushButton apply_button;
XmPushButton reset_button;
XmPushButton cancel_button;
XmSeparator button_separator;
};
callbacks {
MrmNcreateCallback = procedure create_proc (k_order_box);
(9) XmNhelpCallback = procedure help_system_proc (k_order_help);
};
};
.
.
.
|
- The help_system_proc routine is used to
implement context-sensitive help.
- Compound string value declarations for the
help push-button labels. Using values for widget labels makes it easier
to modify the interface. Putting all of the label definitions at the
beginning of the module makes it easier to find a label if you want to
change it later.
- String value declarations for the help
callbacks. Putting the definitions at the beginning of the module makes
it easier to find a string if you want to change it later.
- To conform with the guidelines of the
OSF/Motif Style Guide, use the XmNmenuHelpWidget resource to position the Help
menu item at the far right of the menu bar. If the menu bar widget
wraps onto additional lines, the menu bar widget positions the Help
menu item at the bottom right of the menu bar.
- The menu bar controls a cascade button for
the Help menu entry.
- The Help menu entry is a cascade button that
controls a Help pull-down menu.
- The Help pull-down menu includes push-button
gadgets for context-sensitive help, overview, version, and on-help menu
entries. An application that does not support a specific help menu item
should not include that item in its Help pull-down menu.
- When activated, the help push-button gadgets
call the activate_proc callback routine with an identifying integer
value. The activate_proc callback uses this integer value, which is the
tag argument for the callback, to determine which
widget called it.
- The help callback routine uses this string
to set the DXmHelpSystemDisplay name argument, as
shown in Example 5-5.
5.7 Help System Implementation---C Language Module
Example 5-7 shows the C language code that implements the help system
created in Example 5-6. The complete C source code for the OpenVMS
DECburger application is included in in DECW$EXAMPLES on OpenVMS
systems.
Example 5-7 Help System Implementation---C
Language Module |
.
.
.
#include <stdio.h> /* For printf and so on. */
#include <Xm/Text.h>
#include <Mrm/MrmAppl.h>
#include <DXm/DXmHelpB.h>
#include <DXm/DXmPrint.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <DXm/DXmColor.h>
#include <DXm/DECspecific.h>
#ifdef VMS
/* For OpenVMS systems, use the following include file: */
#include <sys$library/DECw$Cursor.h>
#else
/* For UNIX systems, use the following include file: */
#include <X11/decwcursor.h>
#endif
.
.
.
/*
* Global data
*/
/* Book file for help system */
(1)
/* Use the following define command on OpenVMS systems: */
#define decburger_help "decw$examples:decburger_help.decw$book"
/* Global help system context */
(2)Opaque help_context;
.
.
.
/*
* Forward declarations
*/
static void s_error();
static void help_error();
static void get_something();
static void set_something();
static void activate_proc();
static void create_proc();
static void list_proc();
static void exit_proc();
static void pull_proc();
static void scale_proc();
static void show_hide_proc();
static void show_label_proc();
static void toggle_proc();
static void tracking_help();
(3)static void help_system_proc();
static void create_print();
static void activate_print();
static void create_color();
static void ok_color_proc();
static void apply_color_proc();
static void cancel_color_proc();
static void xmstring_append();
static void start_watch();
static void stop_watch();
/* The names and addresses of things that Mrm has to bind. The names do
* not have to be in alphabetical order. */
static MrmRegisterArg reglist[] = {
{"activate_proc", (caddr_t) activate_proc},
{"create_proc", (caddr_t) create_proc},
{"list_proc", (caddr_t) list_proc},
{"pull_proc", (caddr_t) pull_proc},
{"exit_proc", (caddr_t) exit_proc},
{"scale_proc", (caddr_t) scale_proc},
{"show_hide_proc", (caddr_t) show_hide_proc},
{"show_label_proc", (caddr_t) show_label_proc},
{"toggle_proc", (caddr_t) toggle_proc},
(4){"help_system_proc", (caddr_t) help_system_proc},
{"cancel_color_proc", (caddr_t) cancel_color_proc},
{"apply_color_proc", (caddr_t) apply_color_proc},
{"ok_color_proc", (caddr_t) ok_color_proc}
};
static int reglist_num = (sizeof reglist / sizeof reglist [0]);
static font_unit = 400;
/*
* OS transfer point. The main routine does all the one-time setup and
* then calls XtMainLoop.
*/
static String fallback =
"DECburger.title: DECburger\nDECburger.x: 100\nDECburger.y: 100";
unsigned int main(argc, argv)
unsigned int argc; /* Command line argument count. */
char *argv[]; /* Pointers to command line args. */
{
XtAppContext app_context;
MrmInitialize(); /* Initialize MRM before initializing
/* the X Toolkit. */
(5)DXmInitialize(); /* Initialize DXm widgets */
/* If we had user-defined widgets, we would register them with Mrm here. */
/* Initialize the X Toolkit. We get back a top level shell widget. */
toplevel_widget = XtAppInitialize(
&app_context, /* App. context is returned */
"DECburger", /* Root class name. */
NULL, /* No option list. */
0, /* Number of options. */
&argc, /* Address of argc */
argv, /* argv */
&fallback, /* Fallback resources */
NULL, /* No override resources */
0); /* No override resources */
/* Open the UID files (the output of the UIL compiler) in the hierarchy*/
if (MrmOpenHierarchy(
db_filename_num, /* Number of files. */
db_filename_vec, /* Array of file names. */
NULL, /* Default OS extension. */
&s_MrmHierarchy) /* Pointer to returned MRM ID */
!=MrmSUCCESS)
s_error("can't open hierarchy");
init_application();
/* Register the items MRM needs to bind for us. */
MrmRegisterNames(reglist, reglist_num);
/* Go get the main part of the application. */
if (MrmFetchWidget(s_MrmHierarchy, "S_MAIN_WINDOW", toplevel_widget,
&main_window_widget, &dummy_class) != MrmSUCCESS)
s_error("can't fetch main window");
/* Save some frequently used values */
the_screen = XtScreen(toplevel_widget);
the_display = XtDisplay(toplevel_widget);
/* If it's a color display, map customize color menu entry */
if ((XDefaultVisualOfScreen(the_screen))->class == TrueColor
|| (XDefaultVisualOfScreen(the_screen))->class == PseudoColor
|| (XDefaultVisualOfScreen(the_screen))->class == DirectColor
|| (XDefaultVisualOfScreen(the_screen))->class == StaticColor)
XtSetMappedWhenManaged(widget_array[k_custom_pdme], TRUE);
/* Manage the main part and realize everything. The interface comes up
* on the display now. */
XtManageChild(main_window_widget);
XtRealizeWidget(toplevel_widget);
/* Set up Help System environment */
(6)DXmHelpSystemOpen(&help_context, toplevel_widget, decburger_help,
help_error, "Help System Error");
/* Sit around forever waiting to process X-events. We never leave
* XtAppMainLoop. From here on, we only execute our callback routines. */
XtAppMainLoop(app_context);
}
.
.
.
/*
* Help System errors are also fatal.
*/
(7)static void help_error(problem_string, status)
char *problem_string;
int status;
{
printf("%s, %x\n", problem_string, status);
exit(0);
}
.
.
.
/*
* All push buttons in this application call back to this routine. We
* use the tag to tell us what widget it is, then react accordingly.
*/
static void activate_proc(w, tag, reason)
Widget w;
int *tag;
XmAnyCallbackStruct *reason;
{
int widget_num = *tag; /* Convert tag to widget number. */
int i, value;
XmString topic;
switch (widget_num) {
case k_nyi:
/* The user activated a 'not yet implemented' push button. Send
* the user a message. */
if (widget_array[k_nyi] == NULL) {
/* The first time, fetch from the data base. */
if (MrmFetchWidget(s_MrmHierarchy, "nyi", toplevel_widget,
&widget_array[k_nyi], &dummy_class) != MrmSUCCESS) {
s_error("can't fetch nyi widget");
}
}
/* Put up the message box saying 'not yet implemented'. */
XtManageChild(widget_array[k_nyi]);
break;
.
.
.
(8)case k_help_overview:
DXmHelpSystemDisplay(help_context, decburger_help, "topic",
"overview", help_error, "Help System Error");
break;
case k_help_about:
DXmHelpSystemDisplay(help_context, decburger_help, "topic",
"about", help_error, "Help System Error");
break;
case k_help_onhelp:
DXmHelpSystemDisplay(help_context, decburger_help, "topic",
"onhelp", help_error, "Help System Error");
break;
case k_help_sensitive:
tracking_help();
break;
.
.
.
/* Switches DECburger into context-sensitive mode and calls the selected
** widget's context-sensitive help callback
*/
static void tracking_help()
{
DXmHelpOnContext(toplevel_widget, FALSE);
}
/* Help system callback. Creates a help system session */
(9)static void help_system_proc(w, tag, reason)
Widget w;
int *tag;
XmAnyCallbackStruct *reason;
{
DXmHelpSystemDisplay(help_context, decburger_help, "topic", tag,
help_error, "Help System Error");
}
.
.
.
/*
* The user pushed the exit button, so the application exits.
*/
(10)static void exit_proc(w, tag, reason)
Widget w;
char *tag;
XmAnyCallbackStruct *reason;
{
if (tag != NULL)
printf("Exit - %s\n", tag);
DXmHelpSystemClose(help_context, help_error, "Help System Error");
exit(1);
}
|
|