Components that Can Take Children

If the component can take children, the following three functions might be required:

  • ChildParentFunction
  • ChildFunction
  • ConstraintFunction

The following sections describe these functions in detail.

Obtaining the Parent for Children (ChildParentFunction)

To identify the parent of a given widget, use the ChildParentFunction:

Widget GetWidgetParent(void* object);

This function retrieves the ID of the widget to use as the XtParent of any child widgets or components added to this component. If this routine is not provided, Builder Xcessory uses the base widget of the component.

extern "C" Widget
GetMyComponentWidgetParent(void* object)
{
MyComponent* obj = (MyComponent*)object;
return obj->getAddParent();
}

Adding A Child To The Component (ChildFunction)

If the component needs to do any internal record keeping after a new child has been added, you can specify a ChildFunction to be called:

void ModifyChildList(void* object, Widget child,
   Boolean add);

This routine is used to notify the component that a child has been added or is about to be removed, allowing the component to initialize or clean up any internal data relating to the child. An example of this is a component like a VkTabbedDeck, which may have an add method to register a widget or component as a tab panel after the child has been created:

extern "C" void
ModifyMyComponentChildList(void* object, Widget child, 
Boolean add)
{
MyComponent* obj = (MyComponent*)object;
if (add)
{
obj->addTabPanel(child);
}
else
{
obj->removeTabPanel(child);
}
}

Editing Child Constraint Resources (ConstraintFunction)

If the component has attributes that can be set for each child, you can provide a ConstraintFunction:

void EditComponentConstraint(void* object, Widget child,
Boolean set, ArgList args, Cardinal ac);

This routine provides for the case of a component applying constraint style attributes to its children, like the TabbedDeck attribute tabLabel. The WML definition for these resources occurs in the section for the component, but the resource definition is declared as Constraint rather than Argument.

A resource declared in this way appears in the Constraint Resources section of any children added to MyComponent. When those resources on the children are changed, it is this method, EditComponentConstraint(), that gets called to set the value. This function is nearly identical to the component Edit function, except that both the component pointer and the child widget are passed as parameters.

extern "C" void
EditMyComponentConstraint(void *object, Widget child,
Boolean set, ArgList args, Cardinal ac)
{
MyComponent *obj = (MyComponent *)object;
for (int i = 0; i < ac; i++)
{
// This is a constraint attribute
// defined by MyComponent.
if (!strcmp(args[i].name, "childLabel"))
{
if (set)
{
obj->setChildLabel(child,
(char *)args[i].value);
}
else
{
*((char **)(args[i].value)) =
obj->getChildLabel(child);
}
}
}
}

Documentation: