MPxManipContainer is the parent class of user-defined container manipulators. User-defined container manipulators are comprised of one or more base manipulators. There are a number of methods on MPxManipContainer that allow you to add a variety of base manipulators to the container. There are also a number of methods you need to implement on your user-defined manipulator derived from MPxManipContainer.
You can also override the draw method to customize the way your container manipulator is drawn.
The creator method needs to return a new instance of the manipulator, and it is registered in the initializePlugin function with a call to the MFnPlugin::registerNode method.
The initialize method performs any necessary initializations for the manipulator as well as calling the method in the parent class MPxManipContainer::initialize. Like the creator method, the initialize method is static and registered rather than derived.
The createChildren method is where calls to add base manipulators should be called.
For example, in the moveManip::createChildren method:
MStatus moveManip::createChildren()
{
...
fDistanceManip = addDistanceManip(manipName,
distanceName);
fFreePointManip = addFreePointTriadManip(pointManipName,
pointName);
...
}
The connectToDependNode method is where the association is made between the manipulator and the plug(s) with which it will communicate. This method requires two additional methods to be called after the calls to associate manipulators with plugs have been made. The methods are MPxManipContainer::finishAddingManips and MPxManipContainer::connectToDependNode and must be called in that order. It is important to note that MPxManipContainer::finishAddingManips must be called after all calls to connect to plugs have been made. Furthermore, finishAddingManips must be called only once.
For example, in the moveManip::connectToDependNode method:
MStatus moveManip::connectToDependNode(const MObject &node)
{
...
distanceManipFn.connectToDistancePlug(syPlug);
...
freePointTriadManipFn.connectToPointPlug(tPlug);
...
finishAddingManips();
...
MPxManipContainer::connectToDependNode(node);
...
}
The draw method is an optional method which can be used to customize the drawing of a container manipulator. If you are overriding the draw method, you should first call MPxManipContainer::draw to draw all the children.
For example, the moveManip::draw method draws a label in addition to the base manipulators.
void moveManip::draw(M3dView &view,
const MDagPath &path,
M3dView::DisplayStyle style,
M3dView::DispalyStatus status)
{
MPxManipContainer::draw(view, path, style, status);
view.beginGL();
MPoint textPos(0, 0, 0);
char str[100];
sprintf(str, "Stretch Me!");
MString distanceText(str);
view.drawText(distanceText, textPos, M3dView::kLeft);
view.endGL();
}
Because manipulator containers are derived from nodes, user-defined manipulators can be registered and deregistered like any other node, with the exception that the MPxNode::Type argument in MFnPlugin::registerNode is set to MPxNode::kManipContainer instead of the default MPxNode::kDependNode.
For example, in moveToolManip.cpp:
MStatus initializePlugin(MObject obj)
{
...
plugin.registerNode("moveManip",
moveManip::id,
&moveManip::creator,
&moveManip::initialize,
MPxNode::kManipContainer);
...
}
MStatus uninitializePlugin(MObject obj)
{
...
plugin.deregisterNode(moveManip::id);
...
}