00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00059 initialize();
00060 }
00061
00062 void AbstractMouseSelection::releaseMouseModel()
00063 {
00064
00065 terminate();
00066
00067 _pcView3D->getWidget()->setCursor(m_cPrevCursor);
00068 _pcView3D = 0;
00069 }
00070
00071 void AbstractMouseSelection::redraw()
00072 {
00073
00074
00075
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;
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
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
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
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
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
00327 if (!m_bWorking) {
00328 m_bWorking = true;
00329
00330 _cNodeVector.clear();
00331 _pcView3D->getGLWidget()->update();
00332
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
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
00376 QPoint clPoint = pos;
00377
00378 if (m_bWorking) {
00379
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 }