From cccfe3d554a1f3a7d7bf30079a3fd053b884bb18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Wed, 6 Aug 2014 17:17:27 +0200 Subject: [PATCH] Adopt mouse selection to quarter widget Quarter Widget soes not allow to switch of multisampling on the fly, therefore we need to use glgraphicsitem instead of direct opengl xor rendering for mouse selection --- src/Gui/GLPainter.cpp | 139 +++++- src/Gui/GLPainter.h | 31 +- src/Gui/MouseSelection.cpp | 857 ++++++++++++------------------------ src/Gui/MouseSelection.h | 143 +++--- src/Gui/NavigationStyle.cpp | 6 +- 5 files changed, 509 insertions(+), 667 deletions(-) diff --git a/src/Gui/GLPainter.cpp b/src/Gui/GLPainter.cpp index 392e23f914..68758dd99e 100644 --- a/src/Gui/GLPainter.cpp +++ b/src/Gui/GLPainter.cpp @@ -204,12 +204,14 @@ Rubberband::Rubberband(Gui::View3DInventorViewer* v) : viewer(v) { x_old = y_old = x_new = y_new = 0; working = false; + stipple = true; } Rubberband::Rubberband() { x_old = y_old = x_new = y_new = 0; working = false; + stipple = true; } Rubberband::~Rubberband() @@ -234,6 +236,20 @@ void Rubberband::setCoords(int x1, int y1, int x2, int y2) y_new = y2; } +void Rubberband::setLineStipple(bool on) +{ + stipple = on; +} + + +void Rubberband::setColor(float r, float g, float b, float a) +{ + rgb_a = a; + rgb_b = b; + rgb_g = g; + rgb_r = r; +} + void Rubberband::paintGL() { if(!working) @@ -242,7 +258,7 @@ void Rubberband::paintGL() const SbViewportRegion vp = viewer->getSoRenderManager()->getViewportRegion(); SbVec2s size = vp.getViewportSizePixels(); - + glMatrixMode(GL_PROJECTION); glOrtho(0, size[0], size[1], 0, 0, 100); @@ -253,14 +269,13 @@ void Rubberband::paintGL() glLineWidth(4.0); glColor4f(1.0f, 1.0f, 1.0f, 0.5f); glRecti(x_old, y_old, x_new, y_new); - glColor4f(0.0, 0.0, 1.0, 1.0); - glLineStipple(3, 0xAAAA); - glEnable(GL_LINE_STIPPLE); glLineWidth(4.0); - glColor4f(0.0, 0.0, 1.0, 1.0); - glLineStipple(3, 0xAAAA); - glEnable(GL_LINE_STIPPLE); + glColor4f(rgb_r, rgb_g, rgb_b, rgb_a); + if(stipple) { + glLineStipple(3, 0xAAAA); + glEnable(GL_LINE_STIPPLE); + } glBegin(GL_LINE_LOOP); glVertex2i(x_old, y_old); glVertex2i(x_old, y_new); @@ -269,7 +284,115 @@ void Rubberband::paintGL() glEnd(); glLineWidth(1.0); - glDisable(GL_LINE_STIPPLE); + + if(stipple) + glDisable(GL_LINE_STIPPLE); + + glDisable(GL_BLEND); +} + +Polyline::Polyline(Gui::View3DInventorViewer* v) : viewer(v) +{ + x_new = y_new = 0; + working = false; + closed = true; + line = 2.0; +} + +Polyline::Polyline() +{ + x_new = y_new = 0; + working = false; + closed = true; + line = 2.0; +} + +Polyline::~Polyline() +{ +} + +void Polyline::setWorking(bool on) +{ + working = on; +} + +bool Polyline::isWorking() +{ + return working; +}; + +void Polyline::setViewer(View3DInventorViewer* v) +{ + viewer = v; +} + + +void Polyline::setCoords(int x, int y) +{ + x_new = x; + y_new = y; +} + +void Polyline::setColor(int r, int g, int b, int a) +{ + rgb_a = a; + rgb_b = b; + rgb_g = g; + rgb_r = r; +} + +void Polyline::setClosed(bool c) +{ + closed = c; +} + +void Polyline::setLineWidth(float l) +{ + line = l; +} + + +void Polyline::addNode(QPoint p) +{ + _cNodeVector.push_back(p); +} +void Polyline::clear() +{ + _cNodeVector.clear(); +} +void Polyline::paintGL() +{ + if(!working) + return; + + if(_cNodeVector.empty()) + return; + + const SbViewportRegion vp = viewer->getSoRenderManager()->getViewportRegion(); + SbVec2s size = vp.getViewportSizePixels(); + + + glMatrixMode(GL_PROJECTION); + + glOrtho(0, size[0], size[1], 0, 0, 100); + glMatrixMode(GL_MODELVIEW); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glLineWidth(line); + glColor4f(rgb_r, rgb_g, rgb_b, rgb_a); + glBegin(GL_LINE_LOOP); + + QPoint start = _cNodeVector.front(); + + for(std::vector::iterator it = _cNodeVector.begin(); it != _cNodeVector.end(); ++it) { + glVertex2i(it->x(), it->y()); + } + + if(_cNodeVector.size() > 0) + glVertex2i(x_new, y_new); + + glEnd(); glDisable(GL_BLEND); } diff --git a/src/Gui/GLPainter.h b/src/Gui/GLPainter.h index e8e78f885f..52158e808b 100644 --- a/src/Gui/GLPainter.h +++ b/src/Gui/GLPainter.h @@ -34,6 +34,7 @@ #endif #include +#include namespace Gui { class View3DInventorViewer; @@ -93,17 +94,45 @@ class GuiExport Rubberband : public Gui::GLGraphicsItem { Gui::View3DInventorViewer* viewer; int x_old, y_old, x_new, y_new; - bool working; + float rgb_r, rgb_g, rgb_b, rgb_a; + bool working, stipple; public: Rubberband(Gui::View3DInventorViewer* v); Rubberband(); ~Rubberband(); void setWorking(bool on); + void setLineStipple(bool on); + bool isWorking(); void setViewer(Gui::View3DInventorViewer* v); void setCoords(int x1, int y1, int x2, int y2); + void setColor(float r, float g, float b, float a); void paintGL(); }; +class Polyline : public Gui::GLGraphicsItem +{ + Gui::View3DInventorViewer* viewer; + std::vector _cNodeVector; + int x_new, y_new; + float rgb_r, rgb_g, rgb_b, rgb_a, line; + bool working, closed; + GLPainter p; + +public: + Polyline(Gui::View3DInventorViewer* v); + Polyline(); + ~Polyline(); + void setWorking(bool on); + bool isWorking(); + void setViewer(Gui::View3DInventorViewer* v); + void setCoords(int x, int y); + void setColor(int r, int g, int b, int a=0); + void setLineWidth(float l); + void setClosed(bool c); + void addNode(QPoint p); + void clear(); + void paintGL(); +}; } // namespace Gui diff --git a/src/Gui/MouseSelection.cpp b/src/Gui/MouseSelection.cpp index e21fb022dc..da0a9a6e09 100644 --- a/src/Gui/MouseSelection.cpp +++ b/src/Gui/MouseSelection.cpp @@ -42,9 +42,8 @@ #include "MouseSelection.h" #include "View3DInventor.h" #include "View3DInventorViewer.h" -#include "GLPainter.h" -using namespace Gui; +using namespace Gui; AbstractMouseSelection::AbstractMouseSelection() : _pcView3D(0) { @@ -52,7 +51,7 @@ AbstractMouseSelection::AbstractMouseSelection() : _pcView3D(0) mustRedraw = false; } -void AbstractMouseSelection::grabMouseModel( Gui::View3DInventorViewer* viewer ) +void AbstractMouseSelection::grabMouseModel(Gui::View3DInventorViewer* viewer) { _pcView3D = viewer; m_cPrevCursor = _pcView3D->getWidget()->cursor(); @@ -65,7 +64,7 @@ void AbstractMouseSelection::grabMouseModel( Gui::View3DInventorViewer* viewer ) void AbstractMouseSelection::releaseMouseModel() { - if (_pcView3D) { + if(_pcView3D) { // do termination of your mousemodel terminate(); @@ -83,22 +82,24 @@ void AbstractMouseSelection::redraw() mustRedraw = true; } -int AbstractMouseSelection::handleEvent(const SoEvent * const ev, const SbViewportRegion& vp) +int AbstractMouseSelection::handleEvent(const SoEvent* const ev, const SbViewportRegion& vp) { int ret=Continue; - const SbVec2s& sz = vp.getWindowSize(); - short w,h; sz.getValue(w,h); + const SbVec2s& sz = vp.getWindowSize(); + short w,h; + sz.getValue(w,h); SbVec2s loc = ev->getPosition(); - short x,y; loc.getValue(x,y); + short x,y; + loc.getValue(x,y); y = h-y; // the origin is at the left bottom corner (instead of left top corner) - if (ev->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) { - const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev; + if(ev->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) { + const SoMouseButtonEvent* const event = (const SoMouseButtonEvent*) ev; const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE; - if (press) { + if(press) { _clPoly.push_back(ev->getPosition()); ret = mouseButtonEvent(static_cast(ev), QPoint(x,y)); } @@ -106,14 +107,14 @@ int AbstractMouseSelection::handleEvent(const SoEvent * const ev, const SbViewpo ret = mouseButtonEvent(static_cast(ev), QPoint(x,y)); } } - else if (ev->getTypeId().isDerivedFrom(SoLocation2Event::getClassTypeId())) { + else if(ev->getTypeId().isDerivedFrom(SoLocation2Event::getClassTypeId())) { ret = locationEvent(static_cast(ev), QPoint(x,y)); } - else if (ev->getTypeId().isDerivedFrom(SoKeyboardEvent::getClassTypeId())) { + else if(ev->getTypeId().isDerivedFrom(SoKeyboardEvent::getClassTypeId())) { ret = keyboardEvent(static_cast(ev)); } - if (ret == Restart) + if(ret == Restart) _clPoly.clear(); return ret; @@ -122,135 +123,135 @@ int AbstractMouseSelection::handleEvent(const SoEvent * const ev, const SbViewpo // ----------------------------------------------------------------------------------- BaseMouseSelection::BaseMouseSelection() - : AbstractMouseSelection() + : AbstractMouseSelection() { } // ----------------------------------------------------------------------------------- #if 0 /* XPM */ -static const char *cursor_polypick[]={ -"32 32 2 1", -"# c #646464", -". c None", -"................................", -"................................", -".......#........................", -".......#........................", -".......#........................", -"................................", -".......#........................", -"..###.###.###...................", -".......#...............#........", -"......................##........", -".......#..............#.#.......", -".......#.............#..#.......", -".......#............#...#.......", -"....................#....#......", -"...................#.....#......", -"..................#......#......", -"............#.....#.......#.....", -"...........#.##..#........#.....", -"..........#....##.........#.....", -".........#...............#......", -"........#................#......", -".......#................#.......", -"......#.................#.......", -".....#.................#........", -"....#####..............#........", -".........#########....#.........", -"..................#####.........", -"................................", -"................................", -"................................", -"................................", -"................................"}; +static const char* cursor_polypick[]= { + "32 32 2 1", + "# c #646464", + ". c None", + "................................", + "................................", + ".......#........................", + ".......#........................", + ".......#........................", + "................................", + ".......#........................", + "..###.###.###...................", + ".......#...............#........", + "......................##........", + ".......#..............#.#.......", + ".......#.............#..#.......", + ".......#............#...#.......", + "....................#....#......", + "...................#.....#......", + "..................#......#......", + "............#.....#.......#.....", + "...........#.##..#........#.....", + "..........#....##.........#.....", + ".........#...............#......", + "........#................#......", + ".......#................#.......", + "......#.................#.......", + ".....#.................#........", + "....#####..............#........", + ".........#########....#.........", + "..................#####.........", + "................................", + "................................", + "................................", + "................................", + "................................" +}; /* XPM */ -static const char *cursor_scissors[]={ -"32 32 3 1", -"# c #000000", -"+ c #ffffff", -". c None", -"....+...........................", -"....+...........................", -"....+...........................", -"................................", -"+++.+.+++.......................", -"................................", -"....+...........................", -"....+...................#####...", -"....+.................########..", -".....................#########..", -".....###............##########..", -"....##++##.........#####...###..", -"...#++++++##.......####...####..", -"...##+++++++#......####.######..", -".....#+++++++##....##########...", -"......##+++++++##.##########....", -"........##+++++++#########......", -"..........#+++++++#####.........", -"...........##+++++####..........", -"...........##+++++###...........", -".........##+++++++########......", -"........##+++++++###########....", -"......##+++++++##.###########...", -"....##+++++++##....##########...", -"...#+++++++##......####..#####..", -"...#++++++#........#####..####..", -"....##++##..........#####..###..", -"......#.............##########..", -".....................#########..", -".......................######...", -"................................", -"................................"}; +static const char* cursor_scissors[]= { + "32 32 3 1", + "# c #000000", + "+ c #ffffff", + ". c None", + "....+...........................", + "....+...........................", + "....+...........................", + "................................", + "+++.+.+++.......................", + "................................", + "....+...........................", + "....+...................#####...", + "....+.................########..", + ".....................#########..", + ".....###............##########..", + "....##++##.........#####...###..", + "...#++++++##.......####...####..", + "...##+++++++#......####.######..", + ".....#+++++++##....##########...", + "......##+++++++##.##########....", + "........##+++++++#########......", + "..........#+++++++#####.........", + "...........##+++++####..........", + "...........##+++++###...........", + ".........##+++++++########......", + "........##+++++++###########....", + "......##+++++++##.###########...", + "....##+++++++##....##########...", + "...#+++++++##......####..#####..", + "...#++++++#........#####..####..", + "....##++##..........#####..###..", + "......#.............##########..", + ".....................#########..", + ".......................######...", + "................................", + "................................" +}; #endif -static const char *cursor_cut_scissors[]={ -"32 32 6 1", -"a c #800000", -"c c #808080", -"+ c #c0c0c0", -"b c #ff0000", -"# c #ffffff", -". c None", -"....#...........................", -"....#...........................", -"....#...........................", -"................................", -"###.#.###.......................", -"................................", -"....#...........................", -"....#...................aaaaa...", -"....#.................aabbbbba..", -".....................abbbbbbba..", -".....ccc............abbaaaaabb..", -"....cc++cc.........babaa...aba..", -"...c+#++++cc.......abba...abba..", -"...cc+#+++++c......abba.aabbaa..", -".....c+++++#+cc....abbaaabbaa...", -"......cc+#+++#+cc.aabbbbbbaa....", -"........cc+#+++#+cabbbaaaa......", -"..........c+++++++abbaa.........", -"...........cc+++#+aaaa..........", -"...........cc+#+++caa...........", -".........cc+++++#+cbbaaaaa......", -"........cc+#+++#+cabbabbbaaa....", -"......cc+#+++#+cc.aaabbbbbbaa...", -"....cc+#+++#+cc....abbaaaabba...", -"...c++#++#+cc......abba..aabba..", -"...c+###++c........aabaa..aaba..", -"....cc++cc..........abbaa..aba..", -"......c.............aabbaaaaba..", -".....................baabbbbba..", -".......................aaaaaa...", -"................................", -"................................"}; +static const char* cursor_cut_scissors[]= { + "32 32 6 1", + "a c #800000", + "c c #808080", + "+ c #c0c0c0", + "b c #ff0000", + "# c #ffffff", + ". c None", + "....#...........................", + "....#...........................", + "....#...........................", + "................................", + "###.#.###.......................", + "................................", + "....#...........................", + "....#...................aaaaa...", + "....#.................aabbbbba..", + ".....................abbbbbbba..", + ".....ccc............abbaaaaabb..", + "....cc++cc.........babaa...aba..", + "...c+#++++cc.......abba...abba..", + "...cc+#+++++c......abba.aabbaa..", + ".....c+++++#+cc....abbaaabbaa...", + "......cc+#+++#+cc.aabbbbbbaa....", + "........cc+#+++#+cabbbaaaa......", + "..........c+++++++abbaa.........", + "...........cc+++#+aaaa..........", + "...........cc+#+++caa...........", + ".........cc+++++#+cbbaaaaa......", + "........cc+#+++#+cabbabbbaaa....", + "......cc+#+++#+cc.aaabbbbbbaa...", + "....cc+#+++#+cc....abbaaaabba...", + "...c++#++#+cc......abba..aabba..", + "...c+###++c........aabaa..aaba..", + "....cc++cc..........abbaa..aba..", + "......c.............aabbaaaaba..", + ".....................baabbbbba..", + ".......................aaaaaa...", + "................................", + "................................" +}; -PolyPickerSelection::PolyPickerSelection() +PolyPickerSelection::PolyPickerSelection() { - m_iRadius = 2; - m_iNodes = 0; - m_bWorking = false; } void PolyPickerSelection::initialize() @@ -258,60 +259,25 @@ void PolyPickerSelection::initialize() QPixmap p(cursor_cut_scissors); QCursor cursor(p, 4, 4); _pcView3D->getWidget()->setCursor(cursor); + + polyline.setViewer(_pcView3D); + polyline.setColor(0.0,0.0,1.0,1.0); + + _pcView3D->addGraphicsItem(&polyline); + _pcView3D->setRenderFramebuffer(true); + _pcView3D->redraw(); } void PolyPickerSelection::terminate() { -// _pcView3D->getGLWidget()->releaseMouse(); + _pcView3D->removeGraphicsItem(&polyline); + _pcView3D->setRenderFramebuffer(false); + _pcView3D->redraw(); } -void PolyPickerSelection::draw () +void PolyPickerSelection::draw() { - if (mustRedraw){ - if (_cNodeVector.size() > 1) { - QPoint start = _cNodeVector.front(); - GLPainter p; - p.begin(_pcView3D); - p.setColor(1.0f,1.0f,1.0f); - p.setLogicOp(GL_XOR); - for (std::vector::iterator it = _cNodeVector.begin()+1; it != _cNodeVector.end(); ++it) { - p.drawLine(start.x(),start.y(),it->x(), it->y()); - start = *it; - } - p.end(); - } - - // recursive call, but no infinite loop - mustRedraw = false; - draw(); - } - if (m_bWorking) { - if (m_iNodes < int(_cNodeVector.size())) { - m_iNodes = int(_cNodeVector.size()); - - if (_cNodeVector.size() > 2) { - QPoint start = _cNodeVector.front(); - GLPainter p; - p.begin(_pcView3D); - p.setColor(1.0f,1.0f,1.0f); - p.setLogicOp(GL_XOR); - p.drawLine(m_iXnew,m_iYnew,start.x(), start.y()); - p.end(); - } - } - else { - GLPainter p; - p.begin(_pcView3D); - p.setColor(1.0f,1.0f,1.0f); - p.setLogicOp(GL_XOR); - p.drawLine(m_iXnew,m_iYnew,m_iXold,m_iYold); - if (_cNodeVector.size() > 1) { - QPoint start = _cNodeVector.front(); - p.drawLine(m_iXnew,m_iYnew,start.x(), start.y()); - } - p.end(); - } - } + _pcView3D->redraw(); } PolyPickerSelection::~PolyPickerSelection() @@ -324,103 +290,109 @@ int PolyPickerSelection::popupMenu() QAction* fi = menu.addAction(QObject::tr("Finish")); menu.addAction(QObject::tr("Clear")); QAction* ca = menu.addAction(QObject::tr("Cancel")); - if (getPositions().size() < 3) + + if(getPositions().size() < 3) fi->setEnabled(false); + QAction* id = menu.exec(QCursor::pos()); - if (id == fi) + + if(id == fi) return Finish; - else if (id == ca) + else if(id == ca) return Cancel; else return Restart; } -int PolyPickerSelection::mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ) +int PolyPickerSelection::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) + 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(); -// _pcView3D->getGLWidget()->grabMouse(); - } + { + if(!polyline.isWorking()) { + polyline.setWorking(true); + polyline.clear(); + }; + polyline.addNode(pos); + polyline.setCoords(pos.x(), pos.y()); + m_iXnew = pos.x(); m_iYnew = pos.y(); + m_iXold = pos.x(); m_iYold = pos.y(); + } + break; - _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; + { + polyline.addNode(pos); + m_iXnew = pos.x(); m_iYnew = pos.y(); + m_iXold = pos.x(); m_iYold = pos.y(); + } + break; + default: - { - } break; + { + } break; } } // release else { - switch (button) + switch(button) { case SoMouseButtonEvent::BUTTON2: - { - QCursor cur = _pcView3D->getWidget()->cursor(); - _pcView3D->getWidget()->setCursor(m_cPrevCursor); + { + 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) { + _pcView3D->getWidget()->setCursor(cur); + } + + polyline.setWorking(false); + return id; + } + break; - // 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; + { + } break; } } return Continue; } -int PolyPickerSelection::locationEvent( const SoLocation2Event * const e, const QPoint& pos ) +int PolyPickerSelection::locationEvent(const SoLocation2Event* const e, const QPoint& pos) { // do all the drawing stuff for us QPoint clPoint = pos; - if (m_bWorking) { + if(polyline.isWorking()) { // 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()) + + 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()) + + if(clPoint.y() < r.top()) clPoint.setY(r.top()); - if (clPoint.y() > r.bottom()) + + if(clPoint.y() > r.bottom()) clPoint.setY(r.bottom()); #ifdef FC_OS_WINDOWS @@ -428,24 +400,24 @@ int PolyPickerSelection::locationEvent( const SoLocation2Event * const e, const QCursor::setPos(newPos); #endif } + polyline.setCoords(clPoint.x(), clPoint.y()); } - + draw(); m_iXnew = clPoint.x(); m_iYnew = clPoint.y(); - draw(); return Continue; } -int PolyPickerSelection::keyboardEvent( const SoKeyboardEvent * const e ) +int PolyPickerSelection::keyboardEvent(const SoKeyboardEvent* const e) { return Continue; } // ----------------------------------------------------------------------------------- -PolyClipSelection::PolyClipSelection() +PolyClipSelection::PolyClipSelection() { } @@ -459,20 +431,23 @@ int PolyClipSelection::popupMenu() QAction* ci = menu.addAction(QObject::tr("Inner")); QAction* co = menu.addAction(QObject::tr("Outer")); QAction* ca = menu.addAction(QObject::tr("Cancel")); - if (getPositions().size() < 3) { + + if(getPositions().size() < 3) { ci->setEnabled(false); co->setEnabled(false); } + QAction* id = menu.exec(QCursor::pos()); - if (id == ci) { + + if(id == ci) { m_bInner = true; return Finish; } - else if (id == co) { + else if(id == co) { m_bInner = false; return Finish; } - else if (id == ca) + else if(id == ca) return Cancel; else return Restart; @@ -481,89 +456,28 @@ 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; - m_bClose = false; } -void BrushSelection::initialize() -{ - QPixmap p(cursor_cut_scissors); - QCursor cursor(p, 4, 4); - _pcView3D->getWidget()->setCursor(cursor); -} -void BrushSelection::terminate() +BrushSelection::~BrushSelection() { + } void BrushSelection::setColor(float r, float g, float b, float a) { - this->r = r; - this->g = g; - this->b = b; - this->a = a; + polyline.setColor(r,g,b,a); } void BrushSelection::setLineWidth(float l) { - this->l = l; + polyline.setLineWidth(l); } void BrushSelection::setClosed(bool on) { - this->m_bClose = on; -} - -void BrushSelection::draw () -{ - if (mustRedraw){ - if (_cNodeVector.size() > 1) { - QPoint start = _cNodeVector.front(); - GLPainter p; - p.begin(_pcView3D); - p.setLineWidth(this->l); - p.setColor(this->r, this->g, this->b, this->a); - for (std::vector::iterator it = _cNodeVector.begin()+1; it != _cNodeVector.end(); ++it) { - p.drawLine(start.x(),start.y(),it->x(), it->y()); - start = *it; - } - p.end(); - } - - // recursive call, but no infinite loop - mustRedraw = false; - draw(); - } - if (m_bWorking) { - GLPainter p; - p.begin(_pcView3D); - p.setLineWidth(this->l); - p.setColor(this->r, this->g, this->b, this->a); - if (m_bClose && !_cNodeVector.empty()) { - // We have to redraw the whole polyline when using XOR because otherwise the curve looks 'dirty'. - QPoint start = _cNodeVector.front(); - for (std::vector::iterator it = _cNodeVector.begin()+1; it != _cNodeVector.end(); ++it) { - p.drawLine(start.x(),start.y(),it->x(), it->y()); - start = *it; - } - start = _cNodeVector.front(); - p.setLineStipple(2, 0x3F3F); - p.setLogicOp(GL_XOR); - p.drawLine(m_iXold, m_iYold, start.x(),start.y()); - p.drawLine(m_iXnew, m_iYnew, start.x(),start.y()); - p.resetLogicOp(); - p.resetLineStipple(); - } - p.drawLine(m_iXnew, m_iYnew, m_iXold, m_iYold); - p.end(); - } -} - -BrushSelection::~BrushSelection() -{ + //TODO: closed = false is not supported yet } int BrushSelection::popupMenu() @@ -572,112 +486,51 @@ int BrushSelection::popupMenu() QAction* fi = menu.addAction(QObject::tr("Finish")); menu.addAction(QObject::tr("Clear")); QAction* ca = menu.addAction(QObject::tr("Cancel")); - if (getPositions().size() < 3) + + if(getPositions().size() < 3) fi->setEnabled(false); + QAction* id = menu.exec(QCursor::pos()); - if (id == fi) + + if(id == fi) return Finish; - else if (id == ca) + 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) +int BrushSelection::locationEvent(const SoLocation2Event* const e, const QPoint& pos) { // do all the drawing stuff for us QPoint clPoint = pos; - if (m_bWorking) { + if(polyline.isWorking()) { // 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()) + + 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()) + + if(clPoint.y() < r.top()) clPoint.setY(r.top()); - if (clPoint.y() > r.bottom()) + + 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) + + if(abs(last[0]-curr[0]) > 20 || abs(last[1]-curr[1]) > 20) _clPoly.push_back(curr); - _cNodeVector.push_back(clPoint); + + polyline.addNode(clPoint); + polyline.setCoords(clPoint.x(), clPoint.y()); } m_iXnew = clPoint.x(); @@ -689,160 +542,21 @@ int BrushSelection::locationEvent(const SoLocation2Event * const e, const QPoint return Continue; } -int BrushSelection::keyboardEvent( const SoKeyboardEvent * const e ) -{ - return Continue; -} - // ----------------------------------------------------------------------------------- -RectangleSelection::RectangleSelection() +RectangleSelection::RectangleSelection() : RubberbandSelection() { - m_bWorking = false; + rubberband.setColor(0.0,0.0,1.0,1.0); } RectangleSelection::~RectangleSelection() { } -void RectangleSelection::initialize() -{ -} - -void RectangleSelection::terminate() -{ -} - -void RectangleSelection::draw () -{ - if (m_bWorking) { - GLPainter p; - p.begin(_pcView3D); - p.setColor(1.0, 1.0, 0.0, 0.0); - p.setLogicOp(GL_XOR); - p.setLineWidth(3.0f); - p.setLineStipple(2, 0x3F3F); - p.drawRect(m_iXold, m_iYold, m_iXnew, m_iYnew); - p.end(); - } -} - -int RectangleSelection::mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ) -{ - const int button = e->getButton(); - const SbBool press = e->getState() == SoButtonEvent::DOWN ? TRUE : FALSE; - - int ret = Continue; - - if (press) { - switch ( button ) - { - case SoMouseButtonEvent::BUTTON1: - { - m_bWorking = true; - m_iXold = m_iXnew = pos.x(); - m_iYold = m_iYnew = pos.y(); - } break; - default: - { - } break; - } - } - else { - switch (button) { - case SoMouseButtonEvent::BUTTON1: - { - releaseMouseModel(); - m_bWorking = false; - _clPoly.push_back(e->getPosition()); - ret = Finish; - } break; - default: - { - } break; - } - } - - return ret; -} - -int RectangleSelection::locationEvent( const SoLocation2Event * const e, const QPoint& pos ) -{ - draw(); - m_iXnew = pos.x(); - m_iYnew = pos.y(); - draw(); - return Continue; -} - -int RectangleSelection::keyboardEvent( const SoKeyboardEvent * const e ) -{ - return Continue; -} - // ----------------------------------------------------------------------------------- -class RubberbandSelection::Private : public Gui::GLGraphicsItem -{ - Gui::View3DInventorViewer* viewer; - int x_old, y_old, x_new, y_new; - bool working; -public: - Private(Gui::View3DInventorViewer* v) : viewer(v) - { - x_old = y_old = x_new = y_new = 0; - working = false; - } - ~Private() - { - } - void setWorking(bool on) - { - working = on; - } - void setCoords(int x1, int y1, int x2, int y2) - { - x_old = x1; - y_old = y1; - x_new = x2; - y_new = y2; - } - void paintGL() - { - if (!working) - return; - const SbViewportRegion vp = viewer->getSoRenderManager()->getViewportRegion(); - SbVec2s size = vp.getViewportSizePixels(); - - glMatrixMode(GL_PROJECTION); - glOrtho(0, size[0], size[1], 0, 0, 100); - glMatrixMode(GL_MODELVIEW); - glDisable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glLineWidth(4.0); - glColor4f(1.0f, 1.0f, 1.0f, 0.2f); - glRecti(x_old, y_old, x_new, y_new); - glColor4f(1.0, 1.0, 0.0, 0.5); - glLineStipple(3, 0xAAAA); - glEnable(GL_LINE_STIPPLE); - - glBegin(GL_LINE_LOOP); - glVertex2i(x_old, y_old); - glVertex2i(x_new, y_old); - glVertex2i(x_new, y_new); - glVertex2i(x_old, y_new); - glEnd(); - - glLineWidth(1.0); - glDisable(GL_LINE_STIPPLE); - glDisable(GL_BLEND); - } -}; - RubberbandSelection::RubberbandSelection() { - d = 0; } RubberbandSelection::~RubberbandSelection() @@ -851,9 +565,10 @@ RubberbandSelection::~RubberbandSelection() void RubberbandSelection::initialize() { - d = new Private(_pcView3D); - _pcView3D->addGraphicsItem(d); - + rubberband.setViewer(_pcView3D); + rubberband.setWorking(false); + rubberband.setColor(1.0, 1.0, 0.0, 0.5); + _pcView3D->addGraphicsItem(&rubberband); if (QGLFramebufferObject::hasOpenGLFramebufferObjects()) { _pcView3D->setRenderFramebuffer(true); } @@ -862,68 +577,71 @@ void RubberbandSelection::initialize() void RubberbandSelection::terminate() { - _pcView3D->removeGraphicsItem(d); - delete d; d = 0; - + _pcView3D->removeGraphicsItem(&rubberband); if (QGLFramebufferObject::hasOpenGLFramebufferObjects()) { _pcView3D->setRenderFramebuffer(false); } _pcView3D->redraw(); } -void RubberbandSelection::draw () +void RubberbandSelection::draw() { + _pcView3D->redraw(); } -int RubberbandSelection::mouseButtonEvent(const SoMouseButtonEvent * const e, const QPoint& pos) +int RubberbandSelection::mouseButtonEvent(const SoMouseButtonEvent* const e, const QPoint& pos) { const int button = e->getButton(); const SbBool press = e->getState() == SoButtonEvent::DOWN ? TRUE : FALSE; int ret = Continue; - if (press) { - switch (button) + if(press) { + switch(button) { case SoMouseButtonEvent::BUTTON1: - { - d->setWorking(true); - m_iXold = m_iXnew = pos.x(); - m_iYold = m_iYnew = pos.y(); - } break; + { + rubberband.setWorking(true); + m_iXold = m_iXnew = pos.x(); + m_iYold = m_iYnew = pos.y(); + } + break; + default: - { - } break; + { + } break; } } else { - switch (button) { - case SoMouseButtonEvent::BUTTON1: - { - d->setWorking(false); - releaseMouseModel(); - _clPoly.push_back(e->getPosition()); - ret = Finish; - } break; - default: - { - } break; + switch(button) { + case SoMouseButtonEvent::BUTTON1: + { + rubberband.setWorking(false); + releaseMouseModel(); + _clPoly.push_back(e->getPosition()); + ret = Finish; + } + break; + + default: + { + } break; } } return ret; } -int RubberbandSelection::locationEvent(const SoLocation2Event * const e, const QPoint& pos) +int RubberbandSelection::locationEvent(const SoLocation2Event* const e, const QPoint& pos) { - m_iXnew = pos.x(); + m_iXnew = pos.x(); m_iYnew = pos.y(); - d->setCoords(m_iXold, m_iYold, m_iXnew, m_iYnew); - _pcView3D->redraw(); + rubberband.setCoords(m_iXold, m_iYold, m_iXnew, m_iYnew); + draw(); return Continue; } -int RubberbandSelection::keyboardEvent(const SoKeyboardEvent * const e) +int RubberbandSelection::keyboardEvent(const SoKeyboardEvent* const e) { return Continue; } @@ -949,3 +667,4 @@ void BoxZoomSelection::terminate() SbBox2s box(xmin, ymin, xmax, ymax); _pcView3D->boxZoom(box); } + diff --git a/src/Gui/MouseSelection.h b/src/Gui/MouseSelection.h index a160d5074e..8766fe8ed9 100644 --- a/src/Gui/MouseSelection.h +++ b/src/Gui/MouseSelection.h @@ -28,6 +28,7 @@ #include #include #include +#include "GLPainter.h" // forwards class QMouseEvent; @@ -47,7 +48,7 @@ class View3DInventorViewer; /** * The mouse selection base class * In derived classes you must implement the methods @ref initialize() and @ref terminate() - * For all drawing stuff you just have to reimplement the @ref draw() method. + * For all drawing stuff you just have to reimplement the @ref draw() method. * In general you need not to do anything else. * \author Werner Mayer and Jürgen Riegel */ @@ -57,33 +58,43 @@ public: enum { Continue=0, Restart=1, Finish=2, Cancel=3 }; AbstractMouseSelection(); - virtual ~AbstractMouseSelection(void){} + virtual ~AbstractMouseSelection(void) {} /// implement this in derived classes virtual void initialize() = 0; /// implement this in derived classes - virtual void terminate () = 0; + virtual void terminate() = 0; void grabMouseModel(Gui::View3DInventorViewer*); void releaseMouseModel(void); - const std::vector& getPositions() const { return _clPoly; } - SbBool isInner() const { return m_bInner; } + const std::vector& getPositions() const { + return _clPoly; + } + SbBool isInner() const { + return m_bInner; + } void redraw(); /** @name Mouse events*/ //@{ - int handleEvent(const SoEvent * const ev, const SbViewportRegion& vp); + int handleEvent(const SoEvent* const ev, const SbViewportRegion& vp); //@} protected: - virtual int mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ){ return 0; }; - virtual int locationEvent ( const SoLocation2Event * const e, const QPoint& pos ){ return 0; }; - virtual int keyboardEvent ( const SoKeyboardEvent * const e ) { return 0; }; + virtual int mouseButtonEvent(const SoMouseButtonEvent* const e, const QPoint& pos) { + return 0; + }; + virtual int locationEvent(const SoLocation2Event* const e, const QPoint& pos) { + return 0; + }; + virtual int keyboardEvent(const SoKeyboardEvent* const e) { + return 0; + }; /// drawing stuff - virtual void draw (){}; + virtual void draw() {}; protected: - Gui::View3DInventorViewer*_pcView3D; + Gui::View3DInventorViewer* _pcView3D; QCursor m_cPrevCursor; int m_iXold, m_iYold; int m_iXnew, m_iYnew; @@ -103,7 +114,7 @@ class GuiExport BaseMouseSelection : public AbstractMouseSelection { public: BaseMouseSelection(); - virtual ~BaseMouseSelection(){} + virtual ~BaseMouseSelection() {}; }; // ----------------------------------------------------------------------------------- @@ -119,24 +130,19 @@ public: PolyPickerSelection(); virtual ~PolyPickerSelection(); - /// set the new mouse cursor virtual void initialize(); - /// do nothing virtual void terminate(); protected: - virtual int mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ); - virtual int locationEvent ( const SoLocation2Event * const e, const QPoint& pos ); - virtual int keyboardEvent ( const SoKeyboardEvent * const e ); + virtual int mouseButtonEvent(const SoMouseButtonEvent* const e, const QPoint& pos); + virtual int locationEvent(const SoLocation2Event* const e, const QPoint& pos); + virtual int keyboardEvent(const SoKeyboardEvent* const e); /// draw the polygon - virtual void draw (); + virtual void draw(); virtual int popupMenu(); -protected: - std::vector _cNodeVector; - int m_iRadius, m_iNodes; - bool m_bWorking; + Gui::Polyline polyline; }; // ----------------------------------------------------------------------------------- @@ -162,39 +168,19 @@ protected: * The brush selection class * \author Werner Mayer */ -class GuiExport BrushSelection : public BaseMouseSelection +class GuiExport BrushSelection : public PolyPickerSelection { public: BrushSelection(); - virtual ~BrushSelection(); + ~BrushSelection(); - /// set the new mouse cursor - virtual void initialize(); - /// do nothing - virtual void terminate(); - - // Settings - void setColor(float r, float g, float b, float a=0); - void setLineWidth(float); - void setClosed(bool); + void setLineWidth(float l); + void setClosed(bool c); + void setColor(float r, float g, float b, float a = 1.0); protected: - virtual int mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ); - virtual int locationEvent ( const SoLocation2Event * const e, const QPoint& pos ); - virtual int keyboardEvent ( const SoKeyboardEvent * const e ); - - /// draw the polygon - virtual void draw (); virtual int popupMenu(); - -protected: - std::vector _cNodeVector; - int m_iNodes; - bool m_bWorking; - bool m_bClose; - -private: - float r,g,b,a,l; + virtual int locationEvent(const SoLocation2Event* const e, const QPoint& pos); }; // ----------------------------------------------------------------------------------- @@ -204,37 +190,7 @@ private: * Draws a rectangle for selection * \author Werner Mayer */ -class GuiExport RectangleSelection : public BaseMouseSelection -{ -public: - RectangleSelection(); - virtual ~RectangleSelection(); - - /// do nothing - virtual void initialize(); - /// do nothing - virtual void terminate(); - -protected: - virtual int mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ); - virtual int locationEvent ( const SoLocation2Event * const e, const QPoint& pos ); - virtual int keyboardEvent ( const SoKeyboardEvent * const e ); - - /// draw the rectangle - virtual void draw (); - -private: - bool m_bWorking; -}; - -// ----------------------------------------------------------------------------------- - -/** - * The selection mouse model class - * Draws a rectangle for selection - * \author Werner Mayer - */ -class GuiExport RubberbandSelection : public BaseMouseSelection +class GuiExport RubberbandSelection : public BaseMouseSelection { public: RubberbandSelection(); @@ -246,16 +202,29 @@ public: virtual void terminate(); protected: - virtual int mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos ); - virtual int locationEvent ( const SoLocation2Event * const e, const QPoint& pos ); - virtual int keyboardEvent ( const SoKeyboardEvent * const e ); + virtual int mouseButtonEvent(const SoMouseButtonEvent* const e, const QPoint& pos); + virtual int locationEvent(const SoLocation2Event* const e, const QPoint& pos); + virtual int keyboardEvent(const SoKeyboardEvent* const e); /// draw the rectangle - virtual void draw (); + virtual void draw(); -private: - class Private; - Private* d; +protected: + Gui::Rubberband rubberband; +}; + +// ----------------------------------------------------------------------------------- + +/** + * The selection mouse model class + * Draws a rectangle for selection + * \author Werner Mayer + */ +class GuiExport RectangleSelection : public RubberbandSelection +{ +public: + RectangleSelection(); + virtual ~RectangleSelection(); }; // ----------------------------------------------------------------------------------- @@ -265,7 +234,7 @@ private: * Draws a rectangle for box zooming * \author Werner Mayer */ -class GuiExport BoxZoomSelection : public RubberbandSelection +class GuiExport BoxZoomSelection : public RubberbandSelection { public: BoxZoomSelection(); diff --git a/src/Gui/NavigationStyle.cpp b/src/Gui/NavigationStyle.cpp index 8f98c06491..06d89b3a17 100644 --- a/src/Gui/NavigationStyle.cpp +++ b/src/Gui/NavigationStyle.cpp @@ -1226,13 +1226,15 @@ SbBool NavigationStyle::processEvent(const SoEvent * const ev) else if (hd==AbstractMouseSelection::Finish) { pcPolygon = mouseSelection->getPositions(); clipInner = mouseSelection->isInner(); - delete mouseSelection; mouseSelection = 0; + delete mouseSelection; + mouseSelection = 0; syncWithEvent(ev); return NavigationStyle::processSoEvent(ev); } else if (hd==AbstractMouseSelection::Cancel) { pcPolygon.clear(); - delete mouseSelection; mouseSelection = 0; + delete mouseSelection; + mouseSelection = 0; syncWithEvent(ev); return NavigationStyle::processSoEvent(ev); }