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


Notebook is a manager that treats all children as either a page, a component to access a page, or a component that describes a page.

Setting the XmNnotebookChildType constraint resource to XmPAGE when creating a child of Notebook indicates that it is to be treated as a page. Notebook will only display one page at any one time (determined by the XmNcurrentPageNumber resource) even though the Notebook may have several page-type widgets, all of which are managed and realized. This makes the Notebook a useful component for applications that maintain a large amount of information but only wish to allow the user to see and/or manipulate a small portion of the information at one time. An application that maintains a large set of images may wish to use Notebook to keep track of them and to allow only one at a time to be seen so that screen real estate and color resources are conserved. An application that maintains user-configurable data (such as name and address entries, Xserver options, book catalog information) can segment that data into pages for the Notebook. Each page-type widget has a XmNpageNumber constraint resource (Notebook will assign it a default one if one isn't given). When that XmNpageNumber constraint resource matches Notebook's XmNcurrentPageNumber resource, the page-type widget will be shown. Since the XmNpageNumber constraint resource can be changed by the application, a single widget can represent many "virtual" pages. For example, an application displaying help text can place all the text in a single ScrolledText widget and, by changing the XmNpageNumber constraint resource and changing the scroll position, allow a user to access the textual information by page instead of scrolling to find it.

An application can cause pages in Notebook to be displayed by changing the value of the XmNcurrentPageNumber resource. However, an application can also provide other child widgets to Notebook that will enable the user to access pages. By setting the constraint resource XmNnotebookChildType to XmMAJOR_TAB, XmMINOR_TAB, or XmPAGE_SCROLLER when creating a child of the Notebook, that child widget will be used by the Notebook to access pages. Each of these child widgets will access the page that corresponds to their XmNpageNumber constraint resource.

Notebook always contains one page-scroller. If one is not supplied, then Notebook will create it by default. If more than one is supplied, then Notebook will only display one of them. The page-scroller (XmPAGE_SCROLLER) is, by default, a SpinBox component and allows a user to access pages by changing the XmNcurrentPageNumber resource one increment at a time.

Applications can use major-tabs (XmMAJOR_TAB) and minor-tabs (XmMINOR_TAB) to allow users to access pages individually or within groups of pages. For example, an online photo album with one picture per page could add a major tab for every page; each major-tab could be a PushButton with a description of the corresponding picture in its label. The user can then access a particular photo by pressing the tab with the photo description instead of using the page-scroller to access each page one at a time. If the same photo album were, in fact, a class yearbook, there might be many of these labels. So, instead of major-tabs, PushButtons with descriptive labels (the person's name) could be attached to each page as minor-tabs. Then a major-tab could be added to the first person's photo in each class; the major-tab PushButton would have a label describing the class as a whole. In this application, the user would be able to use the major-tab components to quickly skip to the class of interest, and then use the minor-tabs to find the picture of interest. There might still be a large number of minor tabs; if Notebook does not have enough space to display all the major-tabs and/or minor-tabs that are to be shown, then Notebook will provide tab-scrollers (arrow buttons) so the user can scroll to the major-tab and/or minor-tab of interest.

Some applications might require all three of the component types that are used to access pages. A calendar application might have a page for each day. Major-tabs that display a particular year could be added to the first page (day) of each year. Minor-tabs that display the name of a month could be added to the first page (day) of each month. Users could quickly access the year and month of interest by activating the corresponding major-tab and minor-tab and then access the day of interest by using the page-scroller.

Setting the XmNnotebookChildType constraint resource to XmSTATUS_AREA when creating a child of Notebook indicates that it is used to describe a page. As with a page-type widget, Notebook will only display a status-area when its XmNpageNumber constraint resource is equal to Notebook's XmNcurrentPageNumber resource. Status-areas can be used by applications to describe pages. In the previously mentioned photo album example, a status-area widget could contain information about the photo that is not contained in the photo (page) itself or in the major-tab or minor-tab descriptive labels. It could describe the date the photo was taken, the shutter speed used, the type of film used, and so on.

Notebook invokes callbacks associated with the XmNpageChangedCallback resource whenever the value of the XmNcurrentPageNumber resource is changed. After invoking the callbacks, Notebook displays the children that have an XmNpageNumber constraint resource equal to Notebook's XmNcurrentPageNumber resource. However, if there are multiple children of the same type that share the same XmNpageNumber, then Notebook displays only one of that type. For example, if the application defines two minor tabs that both have an XmNpageNumber constraint resource equal to XmNcurrentPageNumber, then Notebook displays only one of the minor tabs. The callback information contains the page number that is about to be displayed. Since the callback is done first, applications don't have to maintain a separate child widget for each page number and, in fact, do not have to create a page widget or access the information needed for a particular page until that page is actually requested by the user. An application can use XmNpageChangedCallback to always update a single page and/or status-area widget to always have the current page number in its XmNpageNumber constraint resource; the information content rather than the widget itself can be changed. In the previous photo album example, the image data required to display a photo needn't be loaded into memory until the XmNpageChangedCallback indicates that the user wishes to see that photo.

Following are the relevant portions of a simple example program that creates a Notebook with 7 pages, numbered 1 through 7, all Label components. Each Label displays a simple string. The 7 pages are divided into two major tab categories, fruits and vegetables. The vegetables category is subdivided into two minor tab categories, green and orange. A status area appears in the Notebook when the current page number is 2. No page-scroller is created by the application, so the Notebook widget will create a default page-scroller.

In this example, all pages can be accessed by the page-scroller; pages 1 and 4 can be accessed by major-tab buttons; and pages 4 and 6 can be accessed by minor-tab buttons.

CreateNotebook(Widget parent_of_notebook)
 Widget notebook, frame;
 char buff[80];
 int i;
 static char *info[PAGES_IN_NOTEBOOK+1] = {
                                  "apples are high in fiber",
                                  "bananas are high in Potassium",
                                  "oranges are high in Vitamin C",
                                  "sweet potato",
   notebook = XtVaCreateWidget("notebook", xmNotebookWidgetClass,
                               parent_of_notebook, NULL);
 /* Create the pages of the Notebook. */
   for (i=1; i<=PAGES_IN_NOTEBOOK; i++) {
      /* Create a frame on every page. */
        frame = XtVaCreateManagedWidget("frame",
                     xmFrameWidgetClass, notebook,
                     XmNnotebookChildType, XmPAGE,
      /* Place the page contents (a string) on each page. */
                     xmLabelWidgetClass, frame,
   XtVaCreateManagedWidget("tropical only",
                     xmLabelWidgetClass, notebook,
                     XmNnotebookChildType, XmSTATUS_AREA,
                     XmNpageNumber, 2,
 /* Create major tabs to divide the pages into categories. */
                xmPushButtonWidgetClass, notebook,
                XmNnotebookChildType, XmMAJOR_TAB,
                XmNpageNumber, 1,
                xmPushButtonWidgetClass, notebook,
                XmNnotebookChildType, XmMAJOR_TAB,
                XmNpageNumber, 4,
 /* Create some minor tabs to divide the categories into
    subcategories. */
                xmPushButtonWidgetClass, notebook,
                XmNnotebookChildType, XmMINOR_TAB,
                XmNpageNumber, 4,
                xmPushButtonWidgetClass, notebook,
                XmNnotebookChildType, XmMINOR_TAB,
                XmNpageNumber, 6,

The preceding example appears online in directory demos/doc/programGuide/ch08/Notebook.

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