Editing Resources on Subclass Components

The superclass integration files already deal with all the resources for the superclass and its base widget, so we can leverage that code. The EditComponent function for the subclass should deal only with its own resources, then pass any remaining resources up to the superclass's EditComponent integration method. This is simple for the set version of the function. The get version requires work similar to dealing with the base widget of a class in "Editing component resources" .

Set Mode

For the subclass, we must check for resources specific to this class, but not already dealt with by the superclass, or any of its superclasses. These resources should be removed from the ArgList and the remaining ArgList passed up to the superclasses EditComponent.

Example

The following code sample below shows only the set portion of the code required for MySubComponent integration:

extern "C" void
EditMySubComponent(void *object, Boolean set,
ArgList p_args, Cardinal p_ac)
{
MySubComponent *obj = (MySubComponent *)object;
// A loop index variable.
int i;
if (set)
{
// Allocate an argument list for superclass attributes
ArgList s_args ArgList)XtMalloc(p_ac * sizeof(Arg));
Cardinal s_ac = 0;
for (i = 0; i < p_ac; i++)
{
if (!strcmp("MySubAttribute", p_args[i].name))
{
// This is a subclass attribute, so set it.
MySubAttributeType *val =
(MySubAttributeType *)p_args[i].value;
obj->setMySubAttribute(val);
}
.
.
.
else
{
// No subclass attribute applied to this, so
// save it for passing to the superclass.
XtSetArg(s_args[s_ac],
p_args[i].name, p_args[i].value);
s_ac++;
}
}
// Now call the superclass's Edit function.
EditMyComponent(object, set, s_args, s_ac);
// Free the allocated memory.
XtFree((char *)s_args);
}
}

Get Mode

This adds the complication that it is necessary to find the subclass's values and pass any others to the superclass. Once the superclass returns its values, they must be merged with the subclass's before they can be returned.

Code

The following code example merges the get code into the previous example:

extern "C" void
EditMySubComponent(void *object, Boolean set,
ArgList p_args, Cardinal p_ac)
{
MySubComponent *obj = (MySubComponent *)object;
// A loop index variable.
int i;
// Allocate an argument list for superclass attributes
ArgList s_args=(ArgList)XtMalloc(p_ac * sizeof(Arg));
Cardinal s_ac = 0;
// Allocate an argument list for values retrieved via
// methods of this component.
ArgList c_args=ArgList)XtMalloc(p_ac * sizeof(Arg));
Cardinal c_ac = 0;
for (i = 0; i < p_ac; i++)
{
if (!strcmp("MySubAttribute", p_args[i].name))
{
if (set)
{
MySubAttributeType *val =
(MySubAttributeType *)p_args[i].value;
obj->setMySubAttribute(val);
}
else
{
XtSetArg(c_args[c_ac], p_args[i].name,
obj->getMySubAttribute());
c_ac++;
}
}
.
.
.
else
{
// No subclass attribute corresponds to this
// attribute name, so pass it up to the superclass.
XtSetArg(s_args[s_ac], p_args[i].name,
p_args[i].value);
s_ac++;
}
}
// Now call the superclass's Edit function.
EditMyComponent(object, set, s_args, s_ac);
// Merge the retrieved values back into p_args
if (!set)
{
// First merge in the values retrieved
// from the superclass.
for (i = 0; i < s_ac; i++)
{
XtSetArg(p_args[i],
s_args[i].name, s_args[i].value);
}
// Then merge in the values retrieved
// from component methods.
for (i = 0; i < c_ac; i++)
{
XtSetArg(p_args[s_ac + i], c_args[i].name,
c_args[i].value);
}
}
// Free the allocated memory.
XtFree((char *)s_args);
XtFree((char *)c_args);
}

Documentation: