The XmManager widget provides an XmManagerClassExtRec extension record. However, most standard Motif manager widgets do not define one. Nevertheless, the following is an example of one hypothetical manager widget that does:
static XmManagerClassExtRec MyWidgetMgrClassExtRec = { /* next_extension */ NULL, /* record_type */ NULLQUARK, /* version */ XmManagerClassExtVersion, /* record_size */ sizeof(XmManagerClassExtRec), /* traversal_children */ TraversalChildren, /* object_at_point */ XmInheritObjectAtPointProc };
The following subsections detail this extension record.
Your widget should always set the next_extension field to NULL.
Your widget should always set the record_type field to NULLQUARK.
Your widget must always set the version field to XmManagerClassExtVersion.
The record_size field holds the size of the manager class extension record. You should set it as follows:
/* record_size */ sizeof(XmManagerClassExtRec),
The traversal_children field holds the name of a method that defines the list of traversable children managed by your widget. Your widget must set the traversal_children field to one of the following:
Most standard Motif manager widgets set this field to NULL. If your widget does this, then your widget will obey the same traversal rules that most other Motif manager widgets enforce. That is, Motif will view all the children in your widget's composite.children list as potential candidates for traversal. However, some of these candidates may not actually be traversable. For example, a Motif traversal routine will mark a child as nontraversable if the child's XmNtraversalOn resource is set to False. (See the Motif Programmer's Guide for details on traversal.)
The only reason to write your own traversal_children method is that you do not want all of your widget's children to be potential candidates for traversal. A traversal_children method must have the following prototype:
Boolean TraversalChildren( Widget w, Widget **childList, Cardinal *numChildren)
Your traversal_children method must return a Boolean value. Returning False means that your widget did not allocate any dynamic memory to hold the childList. In this case, the callers (Motif traversal routines) assume that all the children in the widget's composite.children list are potential candidates for traversal. Returning True means that your widget did allocate dynamic memory to create childList. Therefore, the caller is responsible for deallocating (with XtFree) the returned childList.
In order to create childList, your traversal_children method will probably start with the default child list stored in composite.children. Your traversal_children method will then
For example, the XmRowColumn widget provides a traversal_children method. This method begins by gathering the default child list stored in composite.children. The code that does this looks something like this:
XmRowColumnWidget RCWid = (XmRowColumnWidget)w; *childList = (WidgetList) XtMalloc(sizeof(Widget) * (RCWid->composite.num_children+1));
The method then adds the visible tear-off control widget to the beginning of the child list. (If XmRowColumn did not provide a traversal_children method, the tear-off control widget would not be part of the traversable children list.) The modified childList is returned to the calling Motif traversal routine, which treats it as the list of potentially traversable children.
In the preceding code, the traversal_children method called XtMalloc to allocate enough dynamic memory to store the default child list.
The object_at_point field holds a method that returns the child most closely associated with a specified position within your manager widget. Motif calls the object_at_point method of your widget when an application specifies your widget as the first argument to the XmObjectAtPoint function. Your widget must set the object_at_point field to one of the following:
All standard Motif manager widgets except XmContainer inherit the object_at_point method of XmManager. The object_at_point method of XmManager uses the following rules to determine which child to return:
If you do write your own object_at_point method, it must have the same prototype as the XmObjectAtPoint routine, namely:
Widget ObjectAtPoint( Widget w, Position x, Position y)
An object_at_point method must return the child most closely associated with the specified x,y coordinate pair. Each object_at_point method is free to define "most closely associated" as it pleases. For example, your own object_at_point method might return the child closest to x,y, while another object_at_point method might return the child that is closest to just the x-coordinate.