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