API Guide > Manipulators >

# Manipulator containers

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.

The necessary methods are:

- creator method
- initialize method
- createChildren method
- connectToDependNode method.

You can also override the draw method to customize the way your container manipulator is drawn.

creator method

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.

Note

Since this method is static and registered and not derived, the name of the method does not need to be "creator" although by convention the name "creator" is typically used.

initialize 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.

createChildren method

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);
        ...
    }

connectToDependNode method

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);
        ...
    }

Note

Although connectToDependNode is a virtual method, you will usually be responsible for calling this method yourself when you are using the manipulator within a custom context. For more information, see Connect manipulators to the Show Manipulator Tool.

draw method

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();
    }

Registration/Deregistration

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);
        ...
    }