Implement a more user-friendly selection tool

This commit is contained in:
wmayer
2013-04-26 17:13:20 +02:00
parent 11128a4ef8
commit db1edf0702
4 changed files with 291 additions and 0 deletions

View File

@@ -458,6 +458,193 @@ int PolyClipSelection::popupMenu()
// -----------------------------------------------------------------------------------
BrushSelection::BrushSelection()
: r(1.0f), g(0.0f), b(0.0f), a(0.0f), l(2.0f)
{
m_iNodes = 0;
m_bWorking = false;
}
void BrushSelection::initialize()
{
QPixmap p(cursor_cut_scissors);
QCursor cursor(p, 4, 4);
_pcView3D->getWidget()->setCursor(cursor);
}
void BrushSelection::terminate()
{
}
void BrushSelection::setColor(float r, float g, float b, float a)
{
this->r = r;
this->g = g;
this->b = b;
this->a = a;
}
void BrushSelection::setLineWidth(float l)
{
this->l = l;
}
void BrushSelection::draw ()
{
if (mustRedraw){
if (_cNodeVector.size() > 1) {
QPoint start = _cNodeVector.front();
for (std::vector<QPoint>::iterator it = _cNodeVector.begin()+1; it != _cNodeVector.end(); ++it) {
_pcView3D->drawLine(start.x(),start.y(),it->x(), it->y(),
this->l, this->r, this->g, this->b, this->a);
start = *it;
}
}
// recursive call, but no infinite loop
mustRedraw = false;
draw();
}
if (m_bWorking) {
_pcView3D->drawLine(m_iXnew, m_iYnew, m_iXold, m_iYold,
this->l, this->r, this->g, this->b, this->a);
}
}
BrushSelection::~BrushSelection()
{
}
int BrushSelection::popupMenu()
{
QMenu menu;
QAction* fi = menu.addAction(QObject::tr("Finish"));
menu.addAction(QObject::tr("Clear"));
QAction* ca = menu.addAction(QObject::tr("Cancel"));
if (getPositions().size() < 3)
fi->setEnabled(false);
QAction* id = menu.exec(QCursor::pos());
if (id == fi)
return Finish;
else if (id == ca)
return Cancel;
else
return Restart;
}
int BrushSelection::mouseButtonEvent(const SoMouseButtonEvent * const e, const QPoint& pos)
{
const int button = e->getButton();
const SbBool press = e->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
if (press) {
switch (button)
{
case SoMouseButtonEvent::BUTTON1:
{
// start working from now on
if (!m_bWorking) {
m_bWorking = true;
// clear the old polygon
_cNodeVector.clear();
_pcView3D->getGLWidget()->update();
_cNodeVector.push_back(pos);
m_iXnew = pos.x(); m_iYnew = pos.y();
m_iXold = pos.x(); m_iYold = pos.y();
}
} break;
case SoMouseButtonEvent::BUTTON2:
{
if (_cNodeVector.size() > 0) {
if (_cNodeVector.back() != pos)
_cNodeVector.push_back(pos);
m_iXnew = pos.x(); m_iYnew = pos.y();
m_iXold = pos.x(); m_iYold = pos.y();
}
} break;
default:
{
} break;
}
}
// release
else {
switch (button)
{
case SoMouseButtonEvent::BUTTON1:
return Finish;
case SoMouseButtonEvent::BUTTON2:
{
QCursor cur = _pcView3D->getWidget()->cursor();
_pcView3D->getWidget()->setCursor(m_cPrevCursor);
// The pop-up menu should be shown when releasing mouse button because
// otherwise the navigation style doesn't get the UP event and gets into
// an inconsistent state.
int id = popupMenu();
if (id == Finish || id == Cancel) {
releaseMouseModel();
}
else if (id == Restart) {
m_bWorking = false;
m_iNodes = 0;
_pcView3D->getWidget()->setCursor(cur);
}
return id;
} break;
default:
{
} break;
}
}
return Continue;
}
int BrushSelection::locationEvent(const SoLocation2Event * const e, const QPoint& pos)
{
// do all the drawing stuff for us
QPoint clPoint = pos;
if (m_bWorking) {
// check the position
QRect r = _pcView3D->getGLWidget()->rect();
if (!r.contains(clPoint)) {
if (clPoint.x() < r.left())
clPoint.setX( r.left());
if (clPoint.x() > r.right())
clPoint.setX(r.right());
if (clPoint.y() < r.top())
clPoint.setY(r.top());
if (clPoint.y() > r.bottom())
clPoint.setY(r.bottom());
}
SbVec2s last = _clPoly.back();
SbVec2s curr = e->getPosition();
if (abs(last[0]-curr[0]) > 20 || abs(last[1]-curr[1]) > 20)
_clPoly.push_back(curr);
_cNodeVector.push_back(clPoint);
}
m_iXnew = clPoint.x();
m_iYnew = clPoint.y();
draw();
m_iXold = clPoint.x();
m_iYold = clPoint.y();
return Continue;
}
int BrushSelection::keyboardEvent( const SoKeyboardEvent * const e )
{
return Continue;
}
// -----------------------------------------------------------------------------------
RectangleSelection::RectangleSelection()
{
m_bWorking = false;