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



The Manager Class Extension Record

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.

The next_extension Field

Your widget should always set the next_extension field to NULL.

The record_type Field

Your widget should always set the record_type field to NULLQUARK.

The version Field

Your widget must always set the version field to XmManagerClassExtVersion.

The record_size Field

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

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:

  1. The name of your widget's traversal_children method.

  2. XmInheritTraversalChildrenProc, to indicate that you are inheriting the traversal_children method of your superclass. The XmManager widget does not provide a traversal_children method, so you cannot inherit from it.

  3. NULL, to indicate the absence of a traversal_children method.

    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)

    w
    Specifies the widget ID of your widget.

    childList
    Returns a pointer to the list of potentially traversable children. The traversal_children method must dynamically allocate this list. The caller is responsible for deallocating it.

    numChildren
    Returns a pointer to the number of potentially traversable children returned into childList.

    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

    1. Remove some of the children from this list

    2. Add some children to this list

    3. Keep the contents of the list the same, but rearrange their order

      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.

    4. The object_at_point Field

      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:

      1. XmInheritObjectAtPointProc, to indicate that you are inheriting the object_at_point method of your superclass. The XmManager widget provides an object_at_point method, and your manager widget can inherit this method.

      2. The name of your object_at_point method.

        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:

        1. If one child intersects the specified coordinate pair, that child's widget ID is returned.

        2. If more than one child intersects the specified coordinate pair, the visible child's widget ID is returned.

        3. If no child intersects the specified coordinate pair, NULL is returned.

          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)

          widget
          Specifies your manager widget.

          x
          Specifies the x-coordinate about which the caller is seeking child information. The x-coordinate is specified in pixels, relative to the left side of your manager.

          y
          Specifies the y-coordinate about which the caller is seeking child information. The y-coordinate is specified in pixels, relative to the top side of manager.

          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.


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