motifdeveloper.com
Sponsored by IST Limited
Formerly MW3: Motif on the World Wide Web [MW3 Logo]
Last Updated
November 18, 2002
 


X-Designer - The Leading X/Motif GUI Builder - Click to download a FREE evaluation
 

motifdeveloper.com
Home
About the site
Bulletin Board
News Archive
OpenGroup News
Events
Search
Frequently Asked Questions
The Motif FAQ
X/Motif FAQs
General FAQs
Ask Antony
Latest Q & A
All Q & As
Submit Question
Tips & Pointers
Code Examples
Software
OpenMotif
Widget Sets
GUI Toolkits & Libraries
Motif suppliers
Non-commercial S/W
Commercial Software
Multimedia
Miscellaneous
Organizations
Docs & Pubs
X/Motif Newsgroups
Security
Internationalization
Feedback
Feedback Form
Contributors
 

The Motif 2.1 ComboBox widget

Introduction

A ComboBox is a component which combines direct Textual user input with the convenience of List selection. Generally, the component presents itself to the user as a TextField of some description, with an ArrowButton to the side of the Text. The user can either type into the Text component, or press the ArrowButton, which results in the popping up of a List of available items from which the user can select using the mouse.

Figure 1 displays a typical ComboBox, configured to allow the user to select from the days of the week.

Figure 1 - An XmComboBox widget

When to use a ComboBox

ComboBoxes are components which are compact in terms of screen usage. Unlike a simple List, they occupy only sufficient space on the screen in order to display the current selection.

ComboBoxes are however associated with only a single selection at any given time. If multiple choices may be made from a set of items, the List remains the correct interface paradigm for the programmer to adopt.

Given the task of presenting a set of choices to the user, whilst at the same time minimizing the screen space required for the task, the ComboBox is the natural component. Where a ComboBox might not be preferred over other components depends on the nature of the data. If the set of choices is prohibitively expensive to calculate, or the set is fairly large, it might be better to simply present a TextField to the user; navigating through a particularly large set of items in a popup List is not a very pleasant user experience, and should generally be avoided.

A secondary consideration is whether the data to be presented forms a natural, closed and ordered set. If this is the case, a SpinBox component also comes into consideration; where the data is in any way unordered or arbitrary, the ComboBox is to be preferred. Where the data forms a small set, there is little to choose between the two components, ordered or otherwise.

Motif ComboBox Styles

In Motif, there are three logical kinds of ComboBox:

  • Drop-Down ComboBox

    The component displays a popup list of available choices on request. Figure 2 displays an Drop-Down ComboBox, after the user has pressed the Arrow, so that the popup List is visible.

    Figure 2 - A Drop-Down ComboBox

  • Drop-Down List

    This component also displays a popup list of available choices on request; the difference is that the TextField which displays the current choice is read-only. A Drop-Down List has identical appearance to a Drop-Down ComboBox.

  • ComboBox

    The component displays the set of available choices in a permanently visible list, placed underneath the TextField. Figure 3 is a sample ComboBox style.

    Figure 3 - The ComboBox style

The XmComboBox Header File

Programmers wishing to use the Motif ComboBox should include the file <Xm/ComboBox.h> in their sources. The header file declares the XmComboBoxWidget and XmComboBoxWidgetClass types, as well as providing functional prototypes for all the XmComboBox convenience routines, which are listed below. The class pointer is xmComboBoxWidgetClass.

The XmComboBox Class and Widget Hierarchy

The Motif XmComboBox widget class is a sub-class of the XmManager Widget Class; it inherits all of the resources of the class, although it overrides various default values of the super class, typically margins and shadow thicknesses. The full class inheritance is as follows:

Core -> Composite -> Constraint -> XmManager -> XmComboBox

Although the widget inherits via the Constraint class, XmComboBox does not define any new constraint resources.

The widget creates two internal components, a TextField, which is named "Text", and a Scrolled List, known as "List". The ScrolledList is either directly parented off the ComboBox, or from a special internal popup GrabShell, depending upon whether the ScrolledList is to be permanently visible. The GrabShell is of no real interest to this discussion: it is simply a popup shell which grabs the pointer until such time as the shell is popped down. The following code could be used to fetch the internal components of a ComboBox (although as will be seen below in the Resource tables, there are other means by which the abstract (built-in) components of the ComboBox can be fetched):

    extern Widget combo ;

    Widget text = XtNameToWidget(combo, "Text") ;
    Widget list = XtNameToWidget(combo, "*List") ;

Note that the wildcard specification (*) is required before the internal List name, because as already discussed, the ScrolledList may not be an immediate ComboBox child.

Whether fetching the internal components of the XmComboBox is really necessary from the general programming perspective is a moot point: the XmComboBox implements what is termed a mirror, whereby resources which normally would need to be applied to sub-components can be applied directly onto the XmComboBox itself.

Note that the ArrowButton which the XmComboBox component creates in order to facilitate popup of the List is a hand-drawn artifact, and not a real sub-component. So while it is possible to configure the built-in Text and List components of the ComboBox to whatever style the programmer requires, configuration of the ArrowButton is strictly limited by the interface which the XmComboBox directly presents to the programmer.

Creating an XmComboBox Widget

An XmComboBoxWidget can be created in a number of ways, either using generic Xt Intrinsics methods, or by utilizing a Motif convenience routine defined for the purpose.

The Motif Convenience Creators

Motif defines three convenience routines, one for each of the supported ComboBox styles of presentation:

    Widget XmCreateComboBox(Widget parent, char *name, ArgList argv, Cardinal argc)
    Widget XmCreateDropDownComboBox(Widget parent, char *name, ArgList argv,
								  Cardinal argc)
    Widget XmCreateDropDownList(Widget parent, char *name, ArgList argv,
								  Cardinal argc)

The methods simply instantiate an XmComboBox in each of the various supported styles. For example:

    #include <Xm/ComboBox.h>

    extern Widget parent ;

    Arg      argv[MAX_ARGS] ;
    Cardinal argc ;

    Widget combo ;
    Widget drop_down_combo ;
    Widget drop_down_list ;

    /*
    ** Specimen arguments for the widget. See Resource Table below.
    */
    argc = 0 ;
    XtSetArg(argv[argc], XmNvisibleItemCount, 12) ; argc++ ;
    combo = XmCreateComboBox(parent, "combo", argv, argc) ;

    ...
    drop_down_combo = XmCreateDropDownComboBox(parent, "drop_down_combo",
						      argv, argc) ;

    ...
    drop_down_list = XmCreateDropDownList(parent, "drop_down_list",
						      argv, argc) ;

Xt Intrinsics Creation

Ultimately, the Motif convenience creators are mapped down onto Xt Intrinsics methods in any case; these Xt methods can always be called directly as an alternative.

    Widget XtCreateWidget(char *name, WidgetClass class,
			   Widget parent, ArgList argv, Cardinal argc)
    Widget XtCreateManagedWidget(char *name, WidgetClass class,
			   Widget parent, ArgList argv, Cardinal argc)
    Widget XtVaCreateWidget(char *name, WidgetClass class,
			   Widget parent, ...) ;
    Widget XtVaCreateManagedWidget(char *name, WidgetClass class,
			   Widget parent, ...) ;

For example:

    #include <Xm/ComboBox.h>

    extern Widget parent ;

    Arg      argv[MAX_ARGS] ;
    Cardinal argc ;

    Widget combo ;
    Widget drop_down_combo ;
    Widget drop_down_list ;

    /*
    ** Specimen arguments for the widget. See Resource Table below.
    */
    argc = 0 ;
    XtSetArg(argv[argc], XmNcomboBoxType, XmCOMBO_BOX) ;
    argc++ ;
    combo = XtCreateWidget("combo", xmComboBoxWidgetClass,
					    parent, argv, argc) ;

    ...
    XtSetArg(argv[argc], XmNcomboBoxType, XmDROP_DOWN_COMBOBOX) ;
    argc++ ;
    drop_down_combo = XtCreateManagedWidget("combo",
		     xmComboBoxWidgetClass, parent, argv, argc) ;

    ...
    drop_down_list = XtVaCreateWidget("combo", xmComboBoxWidgetClass,
		 parent, XmNcomboBoxType, XmDROP_DOWN_COMBOBOX, NULL) ;

Note that if you use the generic Xt mechanisms, you must explicitly specify the type of ComboBox if you want a Drop-Down ComboBox or Drop-Down List style. This is implicitly set if you are using the Motif convenience routines, but must be explicitly stated here. More information on the various resources supported by the XmComboBox widget is given in the resource table below.

The geometry management associated with an XmComboBox is minimal: its layout of the constituent List and Text components is very basic, and so there is no reason why an XmComboBox cannot be instantiated in the managed state (XtCreateManagedWidget(), ...). As a general rule, geometry managers should be managed bottom-up after their children are all managed, in order to avoid explosive geometry management effects. Here, since the XmComboBox is not acting as a general purpose layout manager, the performance side effects are minimal.

XmComboBox Resources

The Following table lists all the resources associated with the XmNcomboBox widget, specifying for each the class, type, default value, and get/set access status.

How do you use the the XmComboBox Widget?

10-May-01 16:00 GMT
Name Class Type Default Access
XmNarrowSize XmCArrowSize Dimension dynamic CSG
XmNarrowSpacing XmCArrowSpacing Dimension dynamic CSG
XmNcolumns XmCColumns short dynamic CSG
XmNcomboBoxType XmCComboBoxType unsigned char dynamic CG
XmNfontList XmCFontList XmFontList NULL CSG
XmNhighlightThickness XmCHighlightThickness Dimension dynamic CSG
XmNitemCount XmCItemCount int dynamic CSG
XmNitems XmCItems XmStringTable dynamic CSG
XmNlist XmCList Widget dynamic G
XmNmarginHeight XmCMarginHeight Dimension 2 CSG
XmNmarginWidth XmCMarginWidth Dimension 2 CSG
XmNmatchBehavior XmCMatchBehavior unsigned char dynamic CSG
XmNpositionMode XmCPositionMode XtEnum XmZERO_BASED CSG
XmNrenderTable XmCRenderTable XmRenderTable dynamic CSG
XmNselectedItem XmCSelectedItem XmString NULL CSG
XmNselectedPosition XmCSelectedPosition int 0 CSG
XmNtextField XmCTextField Widget dynamic G
XmNvisibleItemCount XmCVisibleItemCount int 10 CSG

  • XmNarrowSize

    Specifies the size of the drawn ArrowButton which the user "presses" to display the popup List of items. The default value depends on the size of the TextField.

  • XmNarrowSpacing

    Specifies the horizontal distance, measured in Pixels, between the drawn ArrowButton and the built-in TextField.

  • XmNcolumns

    A "mirrored" resource, this specifies the number of columns to display in the built-in TextField.

  • XmNcomboBoxType

    Specifies the logical type or style of ComboBox. Possible values are:

    • XmCOMBO_BOX

      The List is permanently visible, and the TextField is editable.

    • XmDROP_DOWN_COMBO_BOX

      The List is hidden until required, and the TextField is editable.

    • XmDROP_DOWN_LIST

      The List is hidden until required, and the TextField is read-only.

  • XmNfontList

    Specifies the font used for the List items, and the TextField. The XmFontList type is considered deprecated from Motif 2.0 onwards; although maintained for backwards compatibility, the XmRenderTable is now the preferred way of specifying compound string appearance.

  • XmNhighlightThickness

    Specifies the thickness of the rectangle used for highlighting the XmComboBox widget. The default value depends upon the XmDisplay object XmNenableThinThickness resource. If this is True, the default is 1, otherwise 2.

  • XmNitemCount

    Specifies the number of items in the XmComboBox internal List. The resource must be used in conjunction with the XmNitems resource.

  • XmNitems

    Specifies the set of items in the XmComboBox internal List. This resource is represented by an array of compound strings (XmString).

  • XmNlist

    Specifies the widget ID of the internal List widget associated with the XmComboBox. This resource is read-only: applications cannot change the List component associated with the XmComboBox. The programmer can however fetch the value in order to perform direct operations on the internal List when required.

  • XmNmarginHeight

    Specifies the minimum vertical spacing between the XmComboBox top and bottom edges and the internal List and Text components.

  • XmNmarginWidth

    Specifies the minimum horizontal spacing between the XmComboBox left and right edges and the internal List and Text components.

  • XmNmatchBehavior

    Specifies whether keyboard input matching behavior is enabled for the internal List. If enabled, the user can type the first character of an item in order to select that item, when the internal List is visible. Possible values are:

    • XmNONE

      Match behavior is disabled.

    • XmQUICK_NAVIGATE

      Match behavior is enabled.

  • XmNpositionMode

    Configures the way in which the selected position is reported in XmComboBox callbacks. XmComboBox callbacks are considered in a section further down this document. Usually in Motif, List widgets assume that the first item in the List is at position 1, zero being reserved for the last position. However, under CDE, a set of desktop components were written which assumed that the first item is at position zero. For reasons of compatibility, this resource can be set so that callbacks report the position in a manner consistent with the DtComboBox component in particular. Possible values are:

    • XmZERO_BASED

      Selected positions are reported with the first List item at position zero.

    • XmONE_BASED

      Selected positions are reported with the first List item at position one.

    Note that this resource only affects callback reporting, and the interpretation of the XmNselectedPosition resource. Inserting or selecting items using the Motif convenience routines XmComboBoxAddItem(), XmComboBoxSelectItem(), and XmComboBoxSetItem() (see below) always assume that the List has the first item at position 1.

  • XmNrenderTable

    Specifies the render table used to render both the internal List and TextField components. If unspecified, this will be inherited from a BulletinBoard or VendorShell ancestor. Any render table specified will take precedence over any XmNfontList resource.

  • XmNselectedItem

    Specifies the currently selected item associated with the XmComboBox. It is represented by a compound string (XmString).

  • XmNselectedPosition

    Specifies the position of the currently selected item within the internal XmComboBox List. Interpretation depends upon the value of the XmNpositionMode resource.

  • XmNtextField

    Specifies the widget ID of the internal TextField component of the XmComboBox. This resource is read-only.

  • XmNvisibleItemCount

    Specifies the number of visible items in the XmComboBox internal List. Setting this resource may affect the height of the List widget, and hence the XmComboBox itself if the List is configured to be permanently visible.

XmComboBox Convenience Routines

The Motif toolkit defines the following convenience routines for the XmComboBox widget:

    void XmComboBoxAddItem(Widget   widget,
			   XmString item,
			   int      position,
			   Boolean  unique)

XmComboBoxAddItem() adds the specific item to the List component of the XmComboBox widget at the specified position. A position of 1 represents the first item of the List, 2 inserts at the second position, and so forth. A position of zero appends the item onto the end of the List. If unique is True, the item is only inserted if it does not already appear in the XmComboBox List.

The item parameter is a compound string (XmString): this should be constructed using a standard XmString routine such as XmStringCreateLocalized(), XmStringGenerate(), and so forth. The XmComboBox takes a copy of the supplied item (or rather, the built-in List component does, through the routine XmListAddItemUnselected()), and so the programmer should reclaim the utilized space associated with the item by calling XmStringFree() at an appropriate point.

    void XmComboBoxDeletePos(Widget widget,
			     int    position)

XmComboBoxDeletePos() removes the item at the specified position from the internal XmComboBox List. The first item in the List is at position 1, the second item is at position 2, and so forth. The last item in the List can be removed by specifying zero as the position parameter.

Note that if no item exists in the XmComboBox List at the specified position, the Motif toolkit automatically raises an error using the XmeWarning() routine, which maps onto XtAppWarningMsg(). By default, this will write a message to the standard error output, unless the programmer has installed a customized Xt warning handler using the routine XtAppSetWarningMsgHandler().

    void XmComboBoxSelectItem(Widget   widget,
			      XmString item)

XmComboBoxSelectItem() selects the first occurrence of the specified item in the XmComboBox internal List. If the specified item is found within the List, it also automatically replaces the value in the XmComboBox TextField.

Just as XmComboBoxDeletePos() raises an error if the parameters to the routine are invalid, so does XmComboBoxSelectItem() if the specified item is not found within the current internal List item array.

The item parameter is a compound string (XmString), which should be constructed through the standard XmString routines such as XmStringCreateLocalized() or XmStringGenerate(). It is the responsibility of the programmer to reclaim the utilized space associated with the item by calling XmStringFree() at an appropriate point after XmComboBoxSelectItem() has been called.

    void XmComboBoxSetItem(Widget   widget,
			   XmString item)

XmComboBoxSetItem() is almost identical in behavior to XmComboBoxSelectItem(); the difference is that XmComboBoxSetItem() also ensures that the given item is also visible in the internal List. If item is at a position greater than the XmNvisibleItemCount resource of the XmComboBox widget, the item becomes the first visible item in the List.

    void XmComboBoxUpdate(Widget widget)

XmComboBoxUpdate() updates the XmComboBox widget so thai it is synchronized with the state of the internal List component. This would be required where the programmer decides to manipulate the contents of the internal List directly, rather than using XmComboBox convenience functions and resources. In particular, the XmComboBox XmNselectedPosition, XmNitems, and XmNitemCount are recalculated from the internal List, and used to reset the XmComboBox selected item where appropriate.

Note that only the routine XmComboBoxUpdate() was defined for Motif 2.0: all the other convenience functions are Motif 2.1 specific.

XmComboBox Callbacks

The XmComboBox defines a single Callback resource, XmNselectionCallback. Each callback on this callback list is passed the following structure by the Motif toolkit:

    typedef struct
    {
	int      reason ;
	XEvent  *event ;
	XmString item_or_text ;
	int      item_position ;
    } XmComboBoxCallbackStruct ;
  • The reason field will always have the value XmCR_SELECT for an XmComboBox callback.

  • The event field is a standard X description of the event which triggered the callback.

  • The item_or_text field is a compound string (XmString) which represents the new selected item in the XmComboBox widget. This element of the structure is temporarily allocated by the Motif toolkit for the duration of the callback - if the programmer wants the value cached and utilized outside the scope of the callback, the application should copy the value using XmStringCopy().

  • The item_position element specifies the index of the selected item within the internal List. The interpretation of the value depends on the XmNpositionMode resource of the XmComboBox.

    If this is XmONE_BASED, the first item in the List is assumed to be at position one; it is possible for the toolkit to report an item_position of zero in these circumstances, and this situation corresponds to the case where the user directly typed a new value into the XmComboBox TextField rather than selecting from the List of choices.

    If this is XmZERO_BASED, the first item in the List is at position zero. If we follow on from the previous paragraph, it means that an item_position of zero is now ambiguous: it is not possible to distinguish between List selection and TextField direct entry in this mode, just by inspection of the callback data.

An XmComboBox Example

As an example, consider the simple task of presenting the user with a set of Month names from which to select.

The example consists of the following code:

  • MonthComboBox.c - the code which creates the widget hierarchy
  • MonthComboBox.h - widget declarations
  • MonthComboBox_stubs.c - selection callback code which prints out the current selection of the ComboBox as it is modified by the user.
  • Makefile - a general purpose Makefile for the application. This is configured for Solaris, although you will need to get hold of something later than Solaris 2.6 as this is a Motif 1.2 platform. At the top of the file are rules for various platforms: simply comment out the Solaris section, and uncomment your platform as required.
  • MonthComboBox.xd - the X-Designer design save file, created with version 6 of the product. Feel free to ignore this: the source codes can be read without the use of the GUI builder.

Alternatively download a tar archive, MonthCombopBox.tar, of all the above source files. If you are using Netscape Navigator you may have to hold down the Shift key when you click on the file name in order to ensure that you are prompted to save the file.

Quirks

The XmComboBox style, as indicated by the XmNcomboBoxType resource, is a create-only attribute. This means that the style of presentation is fixed once the component has been instantiated into the program. Unfortunately, the default value of XmNcomboBoxType is XmCOMBO_BOX, which is the permanently visible List arrangement.

This means that an XmComboBox, created using default values and standard Xt Intrinsics creation routines, differs from the normal understanding of how a ComboBox should look and feel. The default XmComboBox is not really a ComboBox at all; for proper ComboBox behavior, the correct convenience routine must be called, or the style explicitly coded.

This is probably a minor technical mistake; the default style can already be obtained out of standard components in any case.

Bibliography

The following materials are available for further reading. Firstly, for reference materials on the Motif 2.1 toolkit, may I be so bold as to suggest:

	Motif Reference Manual for Motif 2.1,
	Antony Fountain and Paula Fergusson,
	O'Reilly and Associates,
	ISBN: 1-56592-654-4
	Buy it from Amazon.com or Amazon.co.uk

A companion Motif 2.1 Programming Manual has been prepared for O'Reilly.

For a general Xt reference manual, the following is recommended:

	X Toolkit Intrinsics Reference Manual,
	Edited by David Flanagan,
	O'Reilly and Associates,
	ISBN: 1-56592-007-4
	Buy it from Amazon.com or Amazon.co.uk

A good one-stop general purpose Motif programming manual is:

	Advanced Motif Programming Techniques,
	Alistair George and Mark Riches,
	Prentice Hall,
	ISBN: 0-13-219965-3
	Unfortunately this book is out of print,
	but you may be able to buy it from Amazon.com

This last volume is Motif 1.2 specific, although the general techniques which are described remain invaluable, irrespective of the version of the toolkit you are using.




Sponsored by X-Designer - The Leading X/Motif GUI Builder - Click to download a FREE evaluation

 

Goto top of page

 

[IST Limited]
IST Limited is the
proud sponsor of motifdeveloper.com.
 

Thanks to all the contributors to these pages.

Privacy Policy

 
"Motif" is a registered trademark of The Open Group. All other trademarks are the property of their respective owners.

Some articles/papers here have their own copyright notice. All other information is copyright ©1999-2008 IST Limited

[CommerceOne] MW3 site originally by Ken Sall of Commerce One (formerly Century Computing).