MouseSelection.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2005 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <qapplication.h>
00028 # include <qevent.h>
00029 # include <qpainter.h>
00030 # include <qpixmap.h>
00031 # include <QMenu>
00032 # include <Inventor/SbBox.h>
00033 # include <Inventor/events/SoEvent.h>
00034 # include <Inventor/events/SoKeyboardEvent.h>
00035 # include <Inventor/events/SoLocation2Event.h>
00036 # include <Inventor/events/SoMouseButtonEvent.h>
00037 #endif
00038 
00039 #include <Base/Console.h>
00040 
00041 #include "MouseSelection.h"
00042 #include "View3DInventor.h"
00043 #include "View3DInventorViewer.h"
00044 
00045 using namespace Gui; 
00046 
00047 AbstractMouseSelection::AbstractMouseSelection() : _pcView3D(0)
00048 {
00049     m_bInner = true;
00050     mustRedraw = false;
00051 }
00052 
00053 void AbstractMouseSelection::grabMouseModel( Gui::View3DInventorViewer* viewer )
00054 {
00055     _pcView3D=viewer;
00056     m_cPrevCursor = _pcView3D->getWidget()->cursor();
00057 
00058     // do initialization of your mousemodel
00059     initialize();
00060 }
00061 
00062 void AbstractMouseSelection::releaseMouseModel()
00063 {
00064     // do termination of your mousemodel
00065     terminate();
00066 
00067     _pcView3D->getWidget()->setCursor(m_cPrevCursor);
00068     _pcView3D = 0;
00069 }
00070 
00071 void AbstractMouseSelection::redraw()
00072 {
00073     // Note: For any reason it does not work to do a redraw in the actualRedraw() method of the
00074     // viewer class. So, we do the redraw when the user continues moving the cursor. E.g. have
00075     // a look to PolyPickerSelection::draw()
00076     mustRedraw = true;
00077 }
00078 
00079 int AbstractMouseSelection::handleEvent(const SoEvent * const ev, const SbViewportRegion& vp)
00080 {
00081     int ret=Continue;
00082 
00083     const SbVec2s& sz = vp.getWindowSize(); 
00084     short w,h; sz.getValue(w,h);
00085 
00086     SbVec2s loc = ev->getPosition();
00087     short x,y; loc.getValue(x,y);
00088     y = h-y; // the origin is at the left bottom corner (instead of left top corner)
00089 
00090     if (ev->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
00091         const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
00092         const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00093 
00094         if (press) {
00095             _clPoly.push_back(ev->getPosition());
00096             ret = mouseButtonEvent(static_cast<const SoMouseButtonEvent*>(ev), QPoint(x,y));
00097         }
00098         else {
00099             ret = mouseButtonEvent(static_cast<const SoMouseButtonEvent*>(ev), QPoint(x,y));
00100         }
00101     }
00102     else if (ev->getTypeId().isDerivedFrom(SoLocation2Event::getClassTypeId())) {
00103         ret = locationEvent(static_cast<const SoLocation2Event*>(ev), QPoint(x,y));
00104     }
00105     else if (ev->getTypeId().isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
00106         ret = keyboardEvent(static_cast<const SoKeyboardEvent*>(ev));
00107     }
00108 
00109     if (ret == Restart)
00110         _clPoly.clear();
00111 
00112     return ret;
00113 }
00114 
00115 // -----------------------------------------------------------------------------------
00116 
00117 BaseMouseSelection::BaseMouseSelection()
00118   : AbstractMouseSelection()
00119 {
00120 }
00121 
00122 // -----------------------------------------------------------------------------------
00123 #if 0
00124 /* XPM */
00125 static const char *cursor_polypick[]={
00126 "32 32 2 1",
00127 "# c #646464",
00128 ". c None",
00129 "................................",
00130 "................................",
00131 ".......#........................",
00132 ".......#........................",
00133 ".......#........................",
00134 "................................",
00135 ".......#........................",
00136 "..###.###.###...................",
00137 ".......#...............#........",
00138 "......................##........",
00139 ".......#..............#.#.......",
00140 ".......#.............#..#.......",
00141 ".......#............#...#.......",
00142 "....................#....#......",
00143 "...................#.....#......",
00144 "..................#......#......",
00145 "............#.....#.......#.....",
00146 "...........#.##..#........#.....",
00147 "..........#....##.........#.....",
00148 ".........#...............#......",
00149 "........#................#......",
00150 ".......#................#.......",
00151 "......#.................#.......",
00152 ".....#.................#........",
00153 "....#####..............#........",
00154 ".........#########....#.........",
00155 "..................#####.........",
00156 "................................",
00157 "................................",
00158 "................................",
00159 "................................",
00160 "................................"};
00161 
00162 /* XPM */
00163 static const char *cursor_scissors[]={
00164 "32 32 3 1",
00165 "# c #000000",
00166 "+ c #ffffff",
00167 ". c None",
00168 "....+...........................",
00169 "....+...........................",
00170 "....+...........................",
00171 "................................",
00172 "+++.+.+++.......................",
00173 "................................",
00174 "....+...........................",
00175 "....+...................#####...",
00176 "....+.................########..",
00177 ".....................#########..",
00178 ".....###............##########..",
00179 "....##++##.........#####...###..",
00180 "...#++++++##.......####...####..",
00181 "...##+++++++#......####.######..",
00182 ".....#+++++++##....##########...",
00183 "......##+++++++##.##########....",
00184 "........##+++++++#########......",
00185 "..........#+++++++#####.........",
00186 "...........##+++++####..........",
00187 "...........##+++++###...........",
00188 ".........##+++++++########......",
00189 "........##+++++++###########....",
00190 "......##+++++++##.###########...",
00191 "....##+++++++##....##########...",
00192 "...#+++++++##......####..#####..",
00193 "...#++++++#........#####..####..",
00194 "....##++##..........#####..###..",
00195 "......#.............##########..",
00196 ".....................#########..",
00197 ".......................######...",
00198 "................................",
00199 "................................"};
00200 #endif
00201 static const char *cursor_cut_scissors[]={
00202 "32 32 6 1",
00203 "a c #800000",
00204 "c c #808080",
00205 "+ c #c0c0c0",
00206 "b c #ff0000",
00207 "# c #ffffff",
00208 ". c None",
00209 "....#...........................",
00210 "....#...........................",
00211 "....#...........................",
00212 "................................",
00213 "###.#.###.......................",
00214 "................................",
00215 "....#...........................",
00216 "....#...................aaaaa...",
00217 "....#.................aabbbbba..",
00218 ".....................abbbbbbba..",
00219 ".....ccc............abbaaaaabb..",
00220 "....cc++cc.........babaa...aba..",
00221 "...c+#++++cc.......abba...abba..",
00222 "...cc+#+++++c......abba.aabbaa..",
00223 ".....c+++++#+cc....abbaaabbaa...",
00224 "......cc+#+++#+cc.aabbbbbbaa....",
00225 "........cc+#+++#+cabbbaaaa......",
00226 "..........c+++++++abbaa.........",
00227 "...........cc+++#+aaaa..........",
00228 "...........cc+#+++caa...........",
00229 ".........cc+++++#+cbbaaaaa......",
00230 "........cc+#+++#+cabbabbbaaa....",
00231 "......cc+#+++#+cc.aaabbbbbbaa...",
00232 "....cc+#+++#+cc....abbaaaabba...",
00233 "...c++#++#+cc......abba..aabba..",
00234 "...c+###++c........aabaa..aaba..",
00235 "....cc++cc..........abbaa..aba..",
00236 "......c.............aabbaaaaba..",
00237 ".....................baabbbbba..",
00238 ".......................aaaaaa...",
00239 "................................",
00240 "................................"};
00241 
00242 PolyPickerSelection::PolyPickerSelection() 
00243 {
00244     m_iRadius    = 2;
00245     m_iNodes     = 0;
00246     m_bWorking   = false;
00247 }
00248 
00249 void PolyPickerSelection::initialize()
00250 {
00251     QPixmap p(cursor_cut_scissors);
00252     QCursor cursor(p, 4, 4);
00253     _pcView3D->getWidget()->setCursor(cursor);
00254 }
00255 
00256 void PolyPickerSelection::terminate()
00257 {
00258 //  _pcView3D->getGLWidget()->releaseMouse();
00259 }
00260 
00261 void PolyPickerSelection::draw ()
00262 {
00263     if (mustRedraw){
00264         if (_cNodeVector.size() > 1) {
00265             QPoint start = _cNodeVector.front();
00266             for (std::vector<QPoint>::iterator it = _cNodeVector.begin()+1; it != _cNodeVector.end(); ++it) {
00267                 _pcView3D->drawLine(start.x(),start.y(),it->x(), it->y() );
00268                 start = *it;
00269             }
00270         }
00271 
00272         // recursive call, but no infinite loop
00273         mustRedraw = false;
00274         draw();
00275     }
00276     if (m_bWorking) {
00277         if (m_iNodes < int(_cNodeVector.size())) {
00278             m_iNodes = int(_cNodeVector.size());
00279 
00280             if (_cNodeVector.size() > 2) {
00281                 QPoint start = _cNodeVector.front();
00282                 _pcView3D->drawLine(m_iXnew,m_iYnew,start.x(), start.y() );
00283             }
00284         }
00285         else {
00286             _pcView3D->drawLine(m_iXnew,m_iYnew,m_iXold,m_iYold);
00287             if (_cNodeVector.size() > 1) {
00288                 QPoint start = _cNodeVector.front();
00289                 _pcView3D->drawLine(m_iXnew,m_iYnew,start.x(), start.y());
00290             }
00291         }
00292     }
00293 }
00294 
00295 PolyPickerSelection::~PolyPickerSelection()
00296 {
00297 }
00298 
00299 int PolyPickerSelection::popupMenu()
00300 {
00301     QMenu menu;
00302     QAction* fi = menu.addAction(QObject::tr("Finish"));
00303     menu.addAction(QObject::tr("Clear"));
00304     QAction* ca = menu.addAction(QObject::tr("Cancel"));
00305     if (getPositions().size() < 3)
00306         fi->setEnabled(false);
00307     QAction* id = menu.exec(QCursor::pos());
00308     if (id == fi)
00309         return Finish;
00310     else if (id == ca)
00311         return Cancel;
00312     else
00313         return Restart;
00314 }
00315 
00316 int PolyPickerSelection::mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos )
00317 {
00318     const int button = e->getButton();
00319     const SbBool press = e->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00320 
00321     if (press) {
00322         switch (button)
00323         {
00324         case SoMouseButtonEvent::BUTTON1:
00325             {
00326                 // start working from now on
00327                 if (!m_bWorking) {
00328                     m_bWorking = true;
00329                     // clear the old polygon
00330                     _cNodeVector.clear();
00331                     _pcView3D->getGLWidget()->update();
00332 //                  _pcView3D->getGLWidget()->grabMouse();
00333                 }
00334 
00335                 _cNodeVector.push_back(pos);
00336 
00337                 m_iXnew = pos.x();  m_iYnew = pos.y();
00338                 m_iXold = pos.x();  m_iYold = pos.y();
00339             }   break;
00340         case SoMouseButtonEvent::BUTTON2:
00341             {
00342                 if (_cNodeVector.size() > 0) {
00343                     if (_cNodeVector.back() != pos)
00344                         _cNodeVector.push_back(pos);
00345                     m_iXnew = pos.x();  m_iYnew = pos.y();
00346                     m_iXold = pos.x();  m_iYold = pos.y();
00347                 }
00348 
00349                 QCursor cur = _pcView3D->getWidget()->cursor();
00350                 _pcView3D->getWidget()->setCursor(m_cPrevCursor);
00351 //              _pcView3D->getGLWidget()->releaseMouse();
00352 
00353                 int id = popupMenu();
00354                 if (id == Finish || id == Cancel) {
00355                     releaseMouseModel();
00356                 }
00357                 else if (id == Restart) {
00358                     m_bWorking = false;
00359                     m_iNodes = 0;
00360                     _pcView3D->getWidget()->setCursor(cur);
00361                 }
00362                 return id;
00363             }   break;
00364         default:
00365             {
00366             }   break;
00367         }
00368     }
00369 
00370     return Continue;
00371 }
00372 
00373 int PolyPickerSelection::locationEvent( const SoLocation2Event * const e, const QPoint& pos )
00374 {
00375     // do all the drawing stuff for us
00376     QPoint clPoint = pos;
00377 
00378     if (m_bWorking) {
00379         // check the position
00380         QRect r = _pcView3D->getGLWidget()->rect();
00381         if (!r.contains(clPoint)) {
00382             if (clPoint.x() < r.left())
00383                 clPoint.setX( r.left());
00384             if (clPoint.x() > r.right())
00385                 clPoint.setX(r.right());
00386             if (clPoint.y() < r.top())
00387                 clPoint.setY(r.top());
00388             if (clPoint.y() > r.bottom())
00389                 clPoint.setY(r.bottom());
00390 
00391 #ifdef FC_OS_WINDOWS
00392             QPoint newPos = _pcView3D->getGLWidget()->mapToGlobal(clPoint);
00393             QCursor::setPos(newPos);
00394 #endif
00395         }
00396     }
00397 
00398     draw();
00399     m_iXnew = clPoint.x();
00400     m_iYnew = clPoint.y();
00401     draw();
00402 
00403     return Continue;
00404 }
00405 
00406 int PolyPickerSelection::keyboardEvent( const SoKeyboardEvent * const e )
00407 {
00408     return Continue;
00409 }
00410 
00411 // -----------------------------------------------------------------------------------
00412 
00413 PolyClipSelection::PolyClipSelection() 
00414 {
00415 }
00416 
00417 PolyClipSelection::~PolyClipSelection()
00418 {
00419 }
00420 
00421 int PolyClipSelection::popupMenu()
00422 {
00423     QMenu menu;
00424     QAction* ci = menu.addAction(QObject::tr("Inner"));
00425     QAction* co = menu.addAction(QObject::tr("Outer"));
00426     QAction* ca = menu.addAction(QObject::tr("Cancel"));
00427     if (getPositions().size() < 3) {
00428         ci->setEnabled(false);
00429         co->setEnabled(false);
00430     }
00431     QAction* id = menu.exec(QCursor::pos());
00432     if (id == ci) {
00433         m_bInner = true;
00434         return Finish;
00435     }
00436     else if (id == co) {
00437         m_bInner = false;
00438         return Finish;
00439     }
00440     else if (id == ca)
00441         return Cancel;
00442     else
00443         return Restart;
00444 }
00445 
00446 // -----------------------------------------------------------------------------------
00447 
00448 RectangleSelection::RectangleSelection()
00449 {
00450     m_bWorking = false;
00451 }
00452 
00453 RectangleSelection::~RectangleSelection()
00454 {
00455 }
00456 
00457 void RectangleSelection::initialize()
00458 {
00459 }
00460 
00461 void RectangleSelection::terminate()
00462 {
00463 }
00464 
00465 void RectangleSelection::draw ()
00466 {
00467     if (m_bWorking)
00468         _pcView3D->drawRect(m_iXold, m_iYold, m_iXnew, m_iYnew);
00469 }
00470 
00471 int RectangleSelection::mouseButtonEvent( const SoMouseButtonEvent * const e, const QPoint& pos )
00472 {
00473     const int button = e->getButton();
00474     const SbBool press = e->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00475 
00476     int ret = Continue;
00477 
00478     if (press) {
00479         switch ( button )
00480         {
00481         case SoMouseButtonEvent::BUTTON1:
00482             {
00483                 m_bWorking = true;
00484                 m_iXold = m_iXnew = pos.x(); 
00485                 m_iYold = m_iYnew = pos.y();
00486             }   break;
00487         default:
00488             {
00489             }   break;
00490         }
00491     }
00492     else {
00493         switch (button) {
00494             case SoMouseButtonEvent::BUTTON1:
00495                 {
00496                     releaseMouseModel();
00497                     m_bWorking = false;
00498                     ret = Finish;
00499                 }   break;
00500             default:
00501                 {
00502                 }   break;
00503         }
00504     }
00505 
00506     return ret;
00507 }
00508 
00509 int RectangleSelection::locationEvent( const SoLocation2Event * const e, const QPoint& pos )
00510 {
00511     draw();
00512     m_iXnew = pos.x(); 
00513     m_iYnew = pos.y();
00514     draw();
00515     return Continue;
00516 }
00517 
00518 int RectangleSelection::keyboardEvent( const SoKeyboardEvent * const e )
00519 {
00520     return Continue;
00521 }
00522 
00523 // -----------------------------------------------------------------------------------
00524 
00525 BoxZoomSelection::BoxZoomSelection()
00526 {
00527 }
00528 
00529 BoxZoomSelection::~BoxZoomSelection()
00530 {
00531 }
00532 
00533 void BoxZoomSelection::terminate()
00534 {
00535     int xmin = std::min<int>(m_iXold, m_iXnew);
00536     int xmax = std::max<int>(m_iXold, m_iXnew);
00537     int ymin = std::min<int>(m_iYold, m_iYnew);
00538     int ymax = std::max<int>(m_iYold, m_iYnew);
00539     SbBox2s box(xmin, ymin, xmax, ymax);
00540     _pcView3D->boxZoom(box);
00541 }

Generated on Wed Nov 23 19:00:24 2011 for FreeCAD by  doxygen 1.6.1