#include <maya/MIOStream.h>
#include <math.h>
#include <stdlib.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MGlobal.h>
#include <maya/M3dView.h>
#include <maya/MDagPath.h>
#include <maya/MItSelectionList.h>
#include <maya/MSelectionList.h>
#include <maya/MPxContextCommand.h>
#include <maya/MPxContext.h>
#include <maya/MEvent.h>
#if defined(OSMac_MachO_)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
const char helpString[] =
"Click with left button or drag with middle button to select";
class marqueeContext : public MPxContext
{
public:
marqueeContext();
virtual void toolOnSetup( MEvent & event );
virtual MStatus doPress( MEvent & event );
virtual MStatus doDrag( MEvent & event );
virtual MStatus doRelease( MEvent & event );
virtual MStatus doEnterRegion( MEvent & event );
private:
short start_x, start_y;
short last_x, last_y;
short p_last_x, p_last_y;
bool fsDrawn;
MGlobal::ListAdjustment listAdjustment;
M3dView view;
};
marqueeContext::marqueeContext()
{
setTitleString ( "Marquee Tool" );
setImage("marqueeTool.xpm", MPxContext::kImage1 );
}
void marqueeContext::toolOnSetup ( MEvent & )
{
setHelpString( helpString );
}
MStatus marqueeContext::doPress( MEvent & event )
{
if (event.isModifierShift() || event.isModifierControl() ) {
if ( event.isModifierShift() ) {
if ( event.isModifierControl() ) {
listAdjustment = MGlobal::kAddToList;
} else {
listAdjustment = MGlobal::kXORWithList;
}
} else if ( event.isModifierControl() ) {
listAdjustment = MGlobal::kRemoveFromList;
}
} else {
listAdjustment = MGlobal::kReplaceList;
}
event.getPosition( start_x, start_y );
view = M3dView::active3dView();
p_last_x = start_x;
p_last_y = start_y;
fsDrawn = false;
return MS::kSuccess;
}
class xorDraw
{
public:
xorDraw(M3dView *view) { fView = view; };
~xorDraw() {};
void beginXorDrawing();
void endXorDrawing();
protected:
xorDraw() { fView = NULL; }
GLboolean depthTest[1];
GLboolean colorLogicOp[1];
GLboolean lineStipple[1];
M3dView *fView;
};
void xorDraw::beginXorDrawing()
{
glGetBooleanv (GL_DEPTH_TEST, depthTest);
glGetBooleanv (GL_COLOR_LOGIC_OP, colorLogicOp);
glGetBooleanv (GL_LINE_STIPPLE, lineStipple);
glDrawBuffer( GL_FRONT );
glLineStipple( 1, 0x5555 );
glLineWidth( 1.0 );
glEnable( GL_LINE_STIPPLE );
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluOrtho2D(
0.0, (GLdouble) fView->portWidth(),
0.0, (GLdouble) fView->portHeight()
);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef(0.375, 0.375, 0.0);
glColor3f(1.0f, 1.0f, 1.0f);
glDisable (GL_DEPTH_TEST);
glEnable(GL_COLOR_LOGIC_OP);
glLogicOp (GL_XOR);
}
void xorDraw::endXorDrawing()
{
glFlush();
glDrawBuffer( GL_BACK );
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
if (colorLogicOp[0])
glEnable (GL_COLOR_LOGIC_OP);
else
glDisable (GL_COLOR_LOGIC_OP);
if (depthTest[0])
glEnable (GL_DEPTH_TEST);
else
glDisable (GL_DEPTH_TEST);
if (lineStipple[0])
glEnable( GL_LINE_STIPPLE );
else
glDisable( GL_LINE_STIPPLE );
}
MStatus marqueeContext::doDrag( MEvent & event )
{
event.getPosition( last_x, last_y );
view.beginXorDrawing();
if (fsDrawn)
{
glBegin( GL_LINE_LOOP );
glVertex2i( start_x, start_y );
glVertex2i( p_last_x, start_y );
glVertex2i( p_last_x, p_last_y );
glVertex2i( start_x, p_last_y );
glEnd();
}
fsDrawn = true;
glBegin( GL_LINE_LOOP );
glVertex2i( start_x, start_y );
glVertex2i( last_x, start_y );
glVertex2i( last_x, last_y );
glVertex2i( start_x, last_y );
glEnd();
view.endXorDrawing();
p_last_x = last_x;
p_last_y = last_y;
return MS::kSuccess;
}
MStatus marqueeContext::doRelease( MEvent & event )
{
MSelectionList incomingList, marqueeList;
event.getPosition( last_x, last_y );
view.beginXorDrawing();
glBegin( GL_LINE_LOOP );
glVertex2i( start_x, start_y );
glVertex2i( p_last_x, start_y );
glVertex2i( p_last_x, p_last_y );
glVertex2i( start_x, p_last_y );
glEnd();
view.endXorDrawing();
event.getPosition( last_x, last_y );
MGlobal::getActiveSelectionList(incomingList);
if ( abs(start_x - last_x) < 2 && abs(start_y - last_y) < 2 ) {
MGlobal::SelectionMethod selectionMethod = MGlobal::selectionMethod();
MGlobal::selectFromScreen( start_x, start_y, MGlobal::kReplaceList, selectionMethod );
} else {
MGlobal::selectFromScreen( start_x, start_y, last_x, last_y,
MGlobal::kReplaceList,
MGlobal::kWireframeSelectMethod );
}
MGlobal::getActiveSelectionList(marqueeList);
MGlobal::setActiveSelectionList(incomingList, MGlobal::kReplaceList);
MGlobal::selectCommand(marqueeList, listAdjustment);
return MS::kSuccess;
}
MStatus marqueeContext::doEnterRegion( MEvent & )
{
return setHelpString( helpString );
}
class marqueeContextCmd : public MPxContextCommand
{
public:
marqueeContextCmd();
virtual MPxContext* makeObj();
static void* creator();
};
marqueeContextCmd::marqueeContextCmd() {}
MPxContext* marqueeContextCmd::makeObj()
{
return new marqueeContext();
}
void* marqueeContextCmd::creator()
{
return new marqueeContextCmd;
}
MStatus initializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5", "Any");
status = plugin.registerContextCommand( "marqueeToolContext",
marqueeContextCmd::creator );
return status;
}
MStatus uninitializePlugin( MObject obj )
{
MStatus status;
MFnPlugin plugin( obj );
status = plugin.deregisterContextCommand( "marqueeToolContext" );
return status;
}