The second part of the class record is the CompositeClassPart structure. For example, following is the CompositeClassPart structure of the ExmGrid widget:
{ /* composite_class */ /* geometry_manager */ GeometryManager, /* change_managed */ ChangeManaged, /* insert_child */ XtInheritInsertChild, /* delete_child */ XtInheritDeleteChild, /* extension */ NULL, },
The following subsections detail each field from a Motif widget writer's perspective.
The geometry_manager method handles geometry requests from children of your manager widget. Your widget must specify one of the following for the geometry_manager field:
Most standard Motif manager widgets provide their own geometry_manager method. Motif makes no requirements of the geometry_manager method beyond those required by the Intrinsics.
The ExmGrid demonstration widget illustrates how to write one kind of geometry_manager method. You can find the source code for ExmGrid in demos/widgets/Exm/lib/Grid.c. (See Chapter 12 for an overview of geometry management in Motif.)
The Intrinsics call the change_managed method whenever:
Your widget must specify one of the following for the change_managed field:
Motif requires that your change_managed method call the XmeNavigChangeManaged function. If your change_managed method does not, Motif's keyboard traversal will not work correctly.
The ExmGrid demonstration widget illustrates how to write one kind of change_managed method. You can find the source code for ExmGrid in demos/widgets/Exm/lib/Grid.c. (See Chapter 12 for an overview of geometry management in Motif.)
The Intrinsics call the insert_child method to report the creation of a new child under control of the manager widget.
You must set the insert_child method to one of the following:
The insert_child method of XmManager simply calls the insert_child method of Composite. (See documentation on the Intrinsics for more information on Composite.)
If you do write your own insert_child method, Motif recommends that it call the insert_child method of XmManager. For example, suppose you are writing a manager widget that can only support one child. The following insert_child method rejects any attempt to add a second child. If the added child is the first child, then MyManagerInsertChild calls the insert_child method of XmManager.
MyManagerInsertChild(Widget child) { ExmMyManagerWidget cb = (ExmMyManagerWidget) XtParent(child); if (cb->composite.num_children > 1) XmeWarning((Widget)cb, "MyManager cannot manage more than one child"); else /* Call the insert_child method of XmManager to update child info. */ (*((XmManagerWidgetClass) xmManagerWidgetClass) ->composite_class.insert_child) (child); }
The Intrinsics call the delete_child method to report the destruction of a child under control of the manager widget. The widget ID of the deleted child is the sole argument passed to the delete_child method.
You must set the delete_child method to one of the following:
The delete_child method of XmManager does the following:
The Composite class supports an extension record. The only nontrivial field in this extension record is called accepts_objects. If you specify the extension field as NULL, an extension record is automatically installed and accepts_objects is set to True. All but one of the standard Motif manager widgets (XmRowColumn) set the extension field to NULL.
If your manager widget requires that accepts_objects be False, then you must create an extension record with the accepts_objects field set to False. Furthermore, you must set the extension field to the name of your own composite class extension record.