Chapter 5. Basic Controls

Controls are widgets and gadgets with which the user interacts directly. They form the leaves of the widget tree whose root is the application's top-level shell. In most cases, controls are subclasses of XmPrimitive or XmGadget, and their parents are subclasses of XmManager. (XmScale is a manager, but in many ways the application treats it as a primitive.) Motif provides the following basic controls:

Core, RectObj, XmPrimitive, and XmGadget Classes

Nearly all the basic controls are subclasses of XmPrimitive or XmGadget. XmPrimitive, in turn, is a subclass of the Intrinsics Core class, and XmGadget is a subclass of the Intrinsics RectObj class.

Core

The Core class provides basic attributes of all widgets that have associated windows. It has the following groups of resources:

  • Specifications of the widget's x and y coordinates, width and height, and border width

  • A resource specifying whether or not the widget is sensitive or able to receive input events from the Intrinsics event manager

  • Characteristics of the window, including background and border color or pixmap, colormap, depth, and screen

  • A resource controlling whether or not the Intrinsics map the window when the widget is managed

  • A table associating translations with actions

  • A set of accelerators, which is a translation table bound in the context of a particular widget

RectObj

RectObj is the foundation for gadget classes; it is essentially Core without the attributes related to having a window. RectObj resources control the position and dimensions of the gadget's rectangular area within its parent widget. A RectObj resource also determines whether or not the gadget is sensitive.

XmPrimitive

XmPrimitive is the fundamental Motif class for all basic control widgets—widgets that do not have children. It includes the following resources and behavior:

  • Foreground color, top and bottom shadow colors or pixmaps, and shadow thickness

  • Thickness and color or pixmap for the highlighting rectangle, which is displayed when the widget has keyboard focus

  • Resources to determine whether the user can traverse to the widget and whether or not it is a tab group

  • A resource to determine what unit of measurement the widget uses for size and position resources

  • Callbacks for the widget to invoke when the user presses KHelp

  • A resource for the application to use in associating arbitrary data with the widget

  • Translations and actions for keyboard traversal to another widget

XmGadget

XmGadget is the fundamental Motif class for all basic control gadgets. It is equivalent to XmPrimitive, with two major exceptions:

  • It has no resources for colors or pixmaps. A gadget inherits these from its parent; therefore, all gadgets within a Manager have the same colors or pixmaps.

  • It has no translations or actions. The Manager parent controls traversal between its gadget children, keeps track of gadgets that have input focus, and dispatches events to them.

Labels, Buttons, and Separators

Labels, buttons, and separators are simple widgets built on XmPrimitive.

Labels

Labels provide the ability to display static (uneditable) text or a pixmap. A Label or LabelGadget itself is useful for displaying a message, title, or description. Label and LabelGadget are also superclasses for buttons used as menu items, toggles, or controls.

The application can specify the following characteristics of Labels, LabelGadgets, and their subclasses:

  • A compound string or pixmap to be displayed. When using a pixmap, the application can supply a separate pixmap to be displayed when the widget is insensitive.

  • A font list for displaying the compound string.

  • Resources to determine the positioning of the text or pixmap within the widget. One sets of resources determines the space allocated for the margins; another determines the distance between the margins and the text or pixmap inside. The XmNalignment and XmNstringDirection resources together determine whether the text or pixmap is centered or is left or right justified within the widget.

  • A resource, XmNrecomputeSize, that determines whether the widget attempts to remain large enough to contain the text or pixmap. When this resource is True and a resource that affects the size of the text or pixmap, the margins, or the widget itself is changed, the widget tries to resize itself to be just large enough to contain the text or pixmap.

In addition, Label and LabelGadget provide the following facilities for button subclasses in menus:

  • A keysym used as a mnemonic to select the button. The user can activate the button by pressing the mnemonic key when the button is visible.

  • An accelerator, a KeyPress event by which the user can activate the button whether or not it is visible. Accelerators are supported only for PushButtons and ToggleButtons in PulldownMenus and PopupMenus.

  • Translations and actions for keyboard traversal within the menu or menu system.

Buttons

A button is a basic control that performs some action when the user activates it. Buttons commonly appear in menus, RadioBoxes, CheckBoxes, SelectionBoxes, and MessageBoxes. This section describes some of the functions of each subclass.

CascadeButtons

A CascadeButton or CascadeButtonGadget is used inside a menu and, when activated, usually causes a PulldownMenu to appear. CascadeButtons have the following resources and behavior:

  • A pixmap displayed at one end of the widget in a PopupMenu or PulldownMenu to indicate that activating the CascadeButton posts another menu.

  • A resource, XmNsubMenuId, that holds the widget ID of the PulldownMenu posted when the user activates the button.

  • XmNactivateCallback callbacks, which the widget invokes when the user activates it, and XmNcascadingCallback callbacks, which the widget invokes just before posting a PulldownMenu.

  • A resource to provide a delay between the time the mouse enters the widget and the time it posts a menu.

  • Translations and actions to activate the widget and to post and unpost PulldownMenus. In general, pressing BSelect or dragging BSelect into the widget posts the PulldownMenu. Releasing BSelect in the widget causes the PulldownMenu to remain posted and enables keyboard traversal. When keyboard traversal is enabled, pressing KActivate or KSelect in the widget posts the PulldownMenu and enables keyboard traversal in that menu.

PushButtons

A PushButton or PushButtonGadget can appear either inside or outside a menu. It performs some action determined by the application. When a PushButton is armed, or ready to be activated, it changes its appearance so that it looks as if the user has pressed it in. When it is disarmed it reverts to the appearance of extending out. PushButtons provide the following behavior:

  • Callbacks that the widget invokes when it is armed, disarmed, and activated. The application usually provides only an XmNactivateCallback procedure to perform the action associated with the button.

  • Resources to provide a color or pixmap to be displayed when the button is armed and not inside a menu. When a button in a menu is armed, the top and bottom shadows switch colors.

  • A resource to determine whether or not the widget considers multiple mouse clicks distinct from single mouse clicks.

  • A resource to determine whether or not the button is marked as the default button when outside a menu. In a BulletinBoard, the default button is the one activated when the user presses KActivate and no other button has keyboard focus. The default button has a distinctive shadow whose thickness is controlled by the XmNdefaultButtonShadowThickness resource.

  • Translations to arm, disarm, and activate the button. In general, pressing BSelect on a button or, in a menu, dragging BSelect or traversing to a button arms it. Releasing BSelect or pressing KActivate (in a menu) or KSelect in the widget activates and disarms it.

ToggleButtons

ToggleButtons and ToggleButtonGadgets have one of two states: like toggle switches, they are either "on" or "off". They can appear in menus or in nonmenu RowColumn WorkAreas, including RadioBoxes and CheckBoxes. In a RadioBox only one ToggleButton at a time can be on; in a CheckBox more than one ToggleButton can be on. ToggleButtons can have indicators with distinctive shapes to distinguish whether or not more than one button at a time can be set. However, it is the RowColumn parent, not the ToggleButton, that controls this behavior.

ToggleButtons have the following characteristics:

  • Callbacks that the widget invokes when it is armed or disarmed and when it changes state. The widget invokes the XmNvalueChangedCallback callbacks when the button's state changes from on to off or from off to on.

  • Resources to control the appearance of the indicator. If XmNindicatorOn is False or if XmNvisibleWhenOff is False and the button is in the off state, no indicator is displayed. Otherwise, XmNindicatorType determines whether the indicator shows that only one or more than one button at a time can be on.

  • A color or pixmap to be displayed when the button is armed and XmNfillOnSelect is True.

  • Pixmaps to be displayed when the button is selected and the Label or LabelGadget superclass's XmNlabelType is XmPIXMAP.

  • Translations to arm and disarm the button and to change its state. In general, pressing BSelect on a button or, in a menu, dragging BSelect or traversing to a button arms it. Releasing BSelect or pressing KActivate (in a menu) or KSelect in the widget changes its state and disarms it.

DrawnButtons

A DrawnButton is an empty button surrounded by a shadow border. It is intended to be used as a PushButton but with graphics drawn by the application. Like a PushButton, it has translations and actions to arm, disarm, and activate the button and invoke the corresponding callbacks. If XmNpushButtonEnabled is True, it draws the shadow so that the button appears pressed in when armed and popped out when disarmed.

Other than this, the application must manage the button's visual appearance. It has XmNexposeCallback and XmNresizeCallback callbacks to notify the application that the button has been exposed or resized and therefore needs to be redrawn. The application must be careful not to draw within the button's shadows or highlight areas. The application can use a clipping rectangle in the widget's graphics context that takes account of the button's XmNhighlightThickness and XmNshadowThickness.

ArrowButtons

An ArrowButton or ArrowButtonGadget is a button with an arrow graphic and a shadow. A resource controls the direction of the arrow. Unlike other buttons, it is not a subclass of XmLabel or XmLabelGadget, but is has some of the same behavior as other buttons. It has callbacks that the widget invokes when armed, disarmed, or activated. It has translations and actions similar to those of other buttons to arm, disarm, or activate the button.

Separators

A Separator or SeparatorGadget separates controls or groups of controls. It usually appears as a horizontal or vertical line and supports several styles of line drawing. Resources control its orientation and the type of line it draws. One line style consists of no line at all. This allows the application to control the appearance of the separator by setting its XmNbackgroundColor or XmNbackgroundPixmap.

ScrollBar

A widget can act as a viewport onto a virtual scroll. The ScrollBar is the control that moves the viewport horizontally or vertically relative to the underlying scroll. A ScrollBar consists of a rectangle, called the scroll region, representing the full size of the scroll. It has a smaller rectangle, called the slider, within the scroll region, representing the position and size of the viewport relative to the full scroll. The ScrollBar usually has arrow graphics at both ends of the larger rectangle.

A ScrollBar has translations and actions that allow the user to move the slider. By clicking on an arrow, the user moves the slider one small increment in the direction of the arrow. By clicking in the scroll region between an arrow and the slider, the user moves the slider a larger increment (the page increment) in the direction of the arrow. When the ScrollBar has keyboard focus the user can use the keyboard to move the slider in this way. The user can also drag the slider using the mouse.

By itself, the ScrollBar does not have an association with a widget acting as a viewport onto a scroll. Most applications use a ScrolledWindow, a Manager widget with a child to be scrolled and possibly with one or two ScrollBars to control the scrolling. ScrolledWindow can automatically control the interaction between the scrolled child and the ScrollBars, or it can allow the application to control the interaction. For more information see Chapter 9, "Scrolling, Panes, and Frames."

ScrollBar has a number of resources that allow the application to use it to control scrolling:

  • A minimum value (XmNminimum), representing the position of the slider at one end of the scroll region, and a maximum value (XmNmaximum), representing the position of the slider at the other end of the scroll region. These values can be in any integral units the application chooses so long as the maximum is greater than the minimum.

  • The length of the slider (XmNsliderSize) between 1 and (XmNmaximum - XmNminimum).

  • A value (XmNvalue), ranging between XmNminimum and (XmNmaximum - XmNsliderSize), representing the current position of the slider between the maximum and minimum values.

  • Values for the increment (XmNincrement) and page increment (XmNpageIncrement) by which the user can move the slider.

  • A resource (XmNprocessingDirection) that determines whether the minimum value is on the left or right for horizontal ScrollBars or is on the bottom or top for vertical ScrollBars.

  • Distinct callbacks that the widget invokes when the user moves the slider by one increment in either direction, by one page increment in either direction, or all the way to either end of the scroll region. The widget invokes other callbacks as the user drags the slider and when the user stops dragging the slider. The application does not have to provide routines for all these callback lists; if it provides only an XmNvalueChangedCallback procedure, the widget invokes that procedure whenever the ScrollBar value changes (except during interactive dragging of the slider).

  • Resources to control the color of the scroll region, whether the ScrollBar is horizontal or vertical, and whether or not the ScrollBar has arrows.

  • Resources to control the delays before the widget moves the slider continuously as the user presses and holds BSelect on an arrow or the scroll region.

Two convenience routines, XmScrollBarGetValues and XmScrollBarSetValues, allow the application to get and set the value, slider size, increment, and page increment in one call.

Scale

A Scale displays a value within a range and optionally allows the user to supply a new value. Its appearance and behavior are much like those of a ScrollBar without arrows. It also has a title and can display the current value next to the slider.

Like a ScrollBar, a Scale has minimum, maximum, and current integral values. The application has no access to the slider size, and the current value ranges between the minimum and maximum. The increment by which the arrow keys move the slider is always 1, but the application can supply a multiple increment (XmNscaleMultiple) analogous to ScrollBar's XmNpageIncrement. Scale has two callback lists: XmNvalueChangedCallback is invoked when the user changes the value but is not in the process of dragging the slider, and XmNdragCallback is invoked when the user changes the value while dragging the slider.

Scale also has resources controlling whether the orientation is vertical or horizontal and which end of the Scale represents the minimum value. Other resources control aspects of the Scale's appearance, including the width and height, the title string, whether or not the Scale displays the current value next to the slider, the number of decimal places in the displayed value, and a font list for the title and value.

Two convenience routines, XmScaleGetValue and XmScaleSetValue, allow the application to get and set the value.

By default, a Scale has no labels or tic marks along the rectangle in which the slider moves. The application can add these by creating a series of widgets—such as LabelGadgets or SeparatorGadgets—as children of the Scale. For example, LabelGadgets could display values at intervals between the minimum and maximum, or SeparatorGadgets could display short lines as tic marks. The Scale positions any children, in order of creation, along the rectangle containing the slider, as follows:

  • A single child appears in the middle of the rectangle

  • If there are two children, the first appears at the top (for a vertical Scale) or left (for a horizontal scale) of the rectangle, and the other child appears at the bottom or right of the rectangle

  • If there are more than three children, they appear at equal intervals along the rectangle ranging from top to bottom or from left to right

The following example creates a Scale with five tic marks:

#define NUM_TICS 5
Widget          parent, scale, tics[NUM_TICS];
Arg             args[10];
Cardinal        i, n;
unsigned char   scale_orientation, tic_orientation;
Dimension       tic_long_dim = 10, tic_short_dim = 5;
Dimension       tic_width, tic_height;
char            tic_name[10];
...
scale = XmCreateScale(parent, "scale", args, n);
XtManageChild(scale);
...
n = 0;
XtSetArg(args[n], XmNorientation, &scale_orientation);   n++;
XtGetValues(scale, args, n);
if (scale_orientation == XmHORIZONTAL) {
    tic_orientation = XmVERTICAL;
    tic_width = tic_short_dim;
    tic_height = tic_long_dim;
} else {
    tic_orientation = XmHORIZONTAL;
    tic_width = tic_long_dim;
    tic_height = tic_short_dim;
}
for (i = 0; i < NUM_TICS; i++) {
    sprintf(tic_name, "tic_%d", i);
    n = 0;
    XtSetArg(args[n], XmNseparatorType, XmSINGLE_LINE);  n++;
    XtSetArg(args[n], XmNorientation, tic_orientation);  n++;
    XtSetArg(args[n], XmNwidth, tic_width);              n++;
    XtSetArg(args[n], XmNheight, tic_height);            n++;
    tics[i] = XmCreateSeparatorGadget(scale, tic_name,
                                        args, n);
}
XtManageChildren(tics, NUM_TICS);
...

List

A List is an array of textual items from which the user selects one or more entries. Each item is a compound string. List has four modes, controlled by the XmNselectionPolicy resource, for selecting items:

Single Select 


At most one item is selected. Performing the selection action on an item toggles the selection state of the item and deselects any other selected item.

Browse Select 


At most one item is selected. Performing the selection action on an item selects the item and deselects any other selected item. Dragging BSelect through the list moves the selection along with the cursor.

Multiple Select 


Any number of items can be selected. Performing the selection action on an item toggles the selection state of the item but does not deselect any other selected item.

Extended Select 


Any number of items can be selected. The user can select either continuous or discontinuous ranges of items, depending on the mouse buttons used or, when using the keyboard, on whether the List is in Normal Mode or Add Mode:

  • Pressing BSelect or, in Normal Mode, KSelect on an item selects the item and deselects any other selected item. Dragging BSelect or pressing or dragging BExtend following a BSelect action selects all items between the item under the pointer and the item on which BSelect was pressed. In Normal Mode, KExtend and shifted navigation have the same effect as pressing BExtend following a BSelect action.

  • Pressing BToggle or, in Add Mode, KSelect on an item toggles the selection state of the item but does not deselect any selected item. Dragging BToggle or pressing or dragging BExtend following a BToggle action sets the selection state of all items between the item under the pointer and the item on which BToggle was pressed to the state of the item on which BToggle was pressed. In Add Mode, KExtend and shifted navigation have the same effect as pressing BExtend following a BToggle action.

When the user makes a selection, the List invokes one of four callback lists, depending on the selection policy:

Selection Policy

Callback List

Single Select

XmNsingleSelectionCallback

Browse Select

XmNbrowseSelectionCallback

Multiple Select

XmNmultipleSelectionCallback

Extended Select

XmNextendedSelectionCallback

By default, the List does not invoke a callback list when the List is in Single Select or Extended Select mode and the user drags the mouse cursor over a new item. It does invoke the callbacks when the user releases the mouse button. If XmNautomaticSelection is True, the List invokes the callbacks while the user is dragging the mouse.

The widget data passed to selection callback routines contains both the selected items—the compound strings—and integers representing the positions within the list of the selected items. The first item in the list is at position 1, the second item at position 2, and so on.

List has another callback list, XmNdefaultActionCallback, which it invokes when the user double clicks or presses KActivate on an item. The widget data passed to these callback routines contains only the item at the location cursor and its position, not the selected items. When the user performs the default action via a double click, the List calls the appropriate selection callbacks on the first click and the XmNdefaultActionCallback callbacks on the second click.

List includes several other sets of resources:

  • Arrays and counts of the List items and selected items

  • The number of items, XmNvisibleItemCount, that the list can display at one time, and the position in the List of the first visible item

  • Several resources that affect the appearance of the list items: font list, justification (XmNstringDirection), spacing between items, and margins between the items and the List border

  • The maximum time interval between clicks for a double click

  • A resource (XmNlistSizePolicy) that determines what the List does when an item is too wide to fit into the List: it can keep its size and, if it is a ScrolledList, add a horizontal ScrollBar; grow to accommodate the item; or try to grow and, if it fails to accommodate the item but is a ScrolledList, add a ScrollBar

  • A resource that determines whether the ScrollBars in a ScrolledList are displayed at all times or only when needed.

A ScrolledList is a List inside a ScrolledWindow. The application can use XmCreateScrolledList to create one.

In addition to its resources, List has a variety of convenience routines that allow the application to add, remove, select, and deselect items; specify the first or last visible item; find the position of an item or the positions of the selected items; set Add Mode; and scroll the List horizontally.

Text and TextField

Text is a widget for displaying and, optionally, editing text. When the Text is editable and the user presses a key that represents a text character, that character is inserted into the text. Other translations and actions allow the user to navigate or to select, cut, copy, paste, or scroll the text.

For more information on Text and TextField, see Chapter 8, "Text."