CADNavigationStyle.cpp
Go to the documentation of this file.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 #ifndef _PreComp_
00026 # include <cfloat>
00027 # include "InventorAll.h"
00028 # include <QAction>
00029 # include <QActionGroup>
00030 # include <QApplication>
00031 # include <QByteArray>
00032 # include <QCursor>
00033 # include <QList>
00034 # include <QMenu>
00035 # include <QMetaObject>
00036 # include <QRegExp>
00037 #endif
00038
00039 #include <Inventor/sensors/SoTimerSensor.h>
00040
00041 #include <App/Application.h>
00042 #include "NavigationStyle.h"
00043 #include "View3DInventorViewer.h"
00044 #include "Application.h"
00045 #include "MenuManager.h"
00046 #include "MouseSelection.h"
00047
00048 using namespace Gui;
00049
00050
00051
00052
00053
00054 TYPESYSTEM_SOURCE(Gui::CADNavigationStyle, Gui::UserNavigationStyle);
00055
00056 CADNavigationStyle::CADNavigationStyle() : lockButton1(FALSE)
00057 {
00058 }
00059
00060 CADNavigationStyle::~CADNavigationStyle()
00061 {
00062 }
00063
00064 const char* CADNavigationStyle::mouseButtons(ViewerMode mode)
00065 {
00066 switch (mode) {
00067 case NavigationStyle::SELECTION:
00068 return QT_TR_NOOP("Press left mouse button");
00069 case NavigationStyle::PANNING:
00070 return QT_TR_NOOP("Press middle mouse button");
00071 case NavigationStyle::DRAGGING:
00072 return QT_TR_NOOP("Press left and middle mouse button");
00073 case NavigationStyle::ZOOMING:
00074 return QT_TR_NOOP("Scroll middle mouse button");
00075 default:
00076 return "No description";
00077 }
00078 }
00079
00080 SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
00081 {
00082 #if 0
00083
00084
00085
00086 if (this->isSeekMode()) { return inherited::processSoEvent(ev); }
00087 #else
00088 if (!this->isSeekMode() && this->isViewing())
00089 this->setViewing(false);
00090 #endif
00091
00092 const SoType type(ev->getTypeId());
00093
00094 const SbViewportRegion & vp = viewer->getViewportRegion();
00095 const SbVec2s size(vp.getViewportSizePixels());
00096 const SbVec2f prevnormalized = this->lastmouseposition;
00097 const SbVec2s pos(ev->getPosition());
00098 const SbVec2f posn((float) pos[0] / (float) SoQtMax((int)(size[0] - 1), 1),
00099 (float) pos[1] / (float) SoQtMax((int)(size[1] - 1), 1));
00100
00101 this->lastmouseposition = posn;
00102
00103
00104
00105
00106
00107 SbBool processed = FALSE;
00108
00109 const ViewerMode curmode = this->currentmode;
00110 ViewerMode newmode = curmode;
00111
00112
00113
00114 if (this->ctrldown != ev->wasCtrlDown()) {
00115 this->ctrldown = ev->wasCtrlDown();
00116 }
00117 if (this->shiftdown != ev->wasShiftDown()) {
00118 this->shiftdown = ev->wasShiftDown();
00119 }
00120 if (this->altdown != ev->wasAltDown()) {
00121 this->altdown = ev->wasAltDown();
00122 }
00123
00124
00125 if (!processed && !viewer->isEditing()) {
00126 processed = handleEventInForeground(ev);
00127 if (processed)
00128 return TRUE;
00129 }
00130
00131
00132 if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
00133 const SoKeyboardEvent * const event = (const SoKeyboardEvent *) ev;
00134 const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00135 switch (event->getKey()) {
00136 case SoKeyboardEvent::LEFT_CONTROL:
00137 case SoKeyboardEvent::RIGHT_CONTROL:
00138 this->ctrldown = press;
00139 break;
00140 case SoKeyboardEvent::LEFT_SHIFT:
00141 case SoKeyboardEvent::RIGHT_SHIFT:
00142 this->shiftdown = press;
00143 break;
00144 case SoKeyboardEvent::LEFT_ALT:
00145 case SoKeyboardEvent::RIGHT_ALT:
00146 this->altdown = press;
00147 break;
00148 case SoKeyboardEvent::H:
00149 processed = TRUE;
00150 viewer->saveHomePosition();
00151 break;
00152 case SoKeyboardEvent::S:
00153 case SoKeyboardEvent::HOME:
00154 case SoKeyboardEvent::LEFT_ARROW:
00155 case SoKeyboardEvent::UP_ARROW:
00156 case SoKeyboardEvent::RIGHT_ARROW:
00157 case SoKeyboardEvent::DOWN_ARROW:
00158 if (!this->isViewing())
00159 this->setViewing(true);
00160 break;
00161 default:
00162 break;
00163 }
00164 }
00165
00166
00167 if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
00168 const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
00169 const int button = event->getButton();
00170 const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00171
00172
00173 switch (button) {
00174 case SoMouseButtonEvent::BUTTON1:
00175 this->lockrecenter = TRUE;
00176 this->button1down = press;
00177 #if 0 // disable to avoid interferences where this key combination is used, too
00178 if (press && ev->wasShiftDown() &&
00179 (this->currentmode != NavigationStyle::SELECTION)) {
00180 this->centerTime = ev->getTime();
00181 float ratio = vp.getViewportAspectRatio();
00182 SbViewVolume vv = viewer->getCamera()->getViewVolume(ratio);
00183 this->panningplane = vv.getPlane(viewer->getCamera()->focalDistance.getValue());
00184 this->lockrecenter = FALSE;
00185 }
00186 else if (!press && ev->wasShiftDown() &&
00187 (this->currentmode != NavigationStyle::SELECTION)) {
00188 SbTime tmp = (ev->getTime() - this->centerTime);
00189 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00190
00191 if (tmp.getValue() < dci && !this->lockrecenter) {
00192 if (!this->moveToPoint(pos)) {
00193 panToCenter(panningplane, posn);
00194 this->interactiveCountDec();
00195 }
00196 processed = TRUE;
00197 }
00198 }
00199 else
00200 #endif
00201 if (press && (this->currentmode == NavigationStyle::SEEK_WAIT_MODE)) {
00202 newmode = NavigationStyle::SEEK_MODE;
00203 this->seekToPoint(pos);
00204 processed = TRUE;
00205 }
00206
00207
00208
00209
00210 else if (press && (this->currentmode == NavigationStyle::PANNING ||
00211 this->currentmode == NavigationStyle::ZOOMING)) {
00212 newmode = NavigationStyle::DRAGGING;
00213 this->centerTime = ev->getTime();
00214 processed = TRUE;
00215 }
00216 else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
00217 SbTime tmp = (ev->getTime() - this->centerTime);
00218 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00219 if (tmp.getValue() < dci) {
00220 newmode = NavigationStyle::ZOOMING;
00221 }
00222 processed = TRUE;
00223 }
00224 else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
00225 this->setViewing(false);
00226 processed = TRUE;
00227 }
00228 else if (viewer->isEditing() && (this->currentmode == NavigationStyle::SPINNING)) {
00229 processed = TRUE;
00230 }
00231 break;
00232 case SoMouseButtonEvent::BUTTON2:
00233
00234
00235 this->lockrecenter = TRUE;
00236 if (!viewer->isEditing()) {
00237
00238
00239 if (this->currentmode != NavigationStyle::ZOOMING &&
00240 this->currentmode != NavigationStyle::PANNING &&
00241 this->currentmode != NavigationStyle::DRAGGING) {
00242 if (this->isPopupMenuEnabled()) {
00243 if (!press) {
00244 this->openPopupMenu(event->getPosition());
00245 }
00246 }
00247 }
00248 }
00249
00250 if (press && (this->currentmode == NavigationStyle::PANNING ||
00251 this->currentmode == NavigationStyle::ZOOMING)) {
00252 newmode = NavigationStyle::DRAGGING;
00253 this->centerTime = ev->getTime();
00254 processed = TRUE;
00255 }
00256 else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
00257 SbTime tmp = (ev->getTime() - this->centerTime);
00258 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00259 if (tmp.getValue() < dci) {
00260 newmode = NavigationStyle::ZOOMING;
00261 }
00262 processed = TRUE;
00263 }
00264 this->button2down = press;
00265 break;
00266 case SoMouseButtonEvent::BUTTON3:
00267 if (press) {
00268 this->centerTime = ev->getTime();
00269 float ratio = vp.getViewportAspectRatio();
00270 SbViewVolume vv = viewer->getCamera()->getViewVolume(ratio);
00271 this->panningplane = vv.getPlane(viewer->getCamera()->focalDistance.getValue());
00272 this->lockrecenter = FALSE;
00273 }
00274 else {
00275 SbTime tmp = (ev->getTime() - this->centerTime);
00276 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00277
00278 if (tmp.getValue() < dci && !this->lockrecenter) {
00279 if (!this->lookAtPoint(pos)) {
00280 panToCenter(panningplane, posn);
00281 this->interactiveCountDec();
00282 }
00283 processed = TRUE;
00284 }
00285 }
00286 this->button3down = press;
00287 break;
00288 case SoMouseButtonEvent::BUTTON4:
00289 if (this->invertZoom)
00290 zoom(viewer->getCamera(), -0.05f);
00291 else
00292 zoom(viewer->getCamera(), 0.05f);
00293 processed = TRUE;
00294 break;
00295 case SoMouseButtonEvent::BUTTON5:
00296 if (this->invertZoom)
00297 zoom(viewer->getCamera(), 0.05f);
00298 else
00299 zoom(viewer->getCamera(), -0.05f);
00300 processed = TRUE;
00301 break;
00302 default:
00303 break;
00304 }
00305 }
00306
00307
00308 if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) {
00309 this->lockrecenter = TRUE;
00310 const SoLocation2Event * const event = (const SoLocation2Event *) ev;
00311 if (this->currentmode == NavigationStyle::ZOOMING) {
00312 this->zoomByCursor(posn, prevnormalized);
00313 processed = TRUE;
00314 }
00315 else if (this->currentmode == NavigationStyle::PANNING) {
00316 float ratio = vp.getViewportAspectRatio();
00317 panCamera(viewer->getCamera(), ratio, this->panningplane, posn, prevnormalized);
00318 processed = TRUE;
00319 }
00320 else if (this->currentmode == NavigationStyle::DRAGGING) {
00321 this->addToLog(event->getPosition(), event->getTime());
00322 this->spin(posn);
00323 processed = TRUE;
00324 }
00325 }
00326
00327
00328 if (type.isDerivedFrom(SoMotion3Event::getClassTypeId())) {
00329 SoMotion3Event * const event = (SoMotion3Event *) ev;
00330 SoCamera * const camera = viewer->getCamera();
00331
00332 SbVec3f dir = event->getTranslation();
00333 if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())){
00334 static float zoomConstant(-.03f);
00335 dir[2] = 0.0;
00336
00337 SoOrthographicCamera *oCam = static_cast<SoOrthographicCamera *>(camera);
00338 oCam->scaleHeight(1.0-event->getTranslation()[2] * zoomConstant);
00339 }
00340 camera->orientation.getValue().multVec(dir,dir);
00341 camera->position = camera->position.getValue() + dir;
00342 camera->orientation = event->getRotation() * camera->orientation.getValue();
00343 processed = TRUE;
00344 }
00345
00346 enum {
00347 BUTTON1DOWN = 1 << 0,
00348 BUTTON3DOWN = 1 << 1,
00349 CTRLDOWN = 1 << 2,
00350 SHIFTDOWN = 1 << 3,
00351 BUTTON2DOWN = 1 << 4
00352 };
00353 unsigned int combo =
00354 (this->button1down ? BUTTON1DOWN : 0) |
00355 (this->button2down ? BUTTON2DOWN : 0) |
00356 (this->button3down ? BUTTON3DOWN : 0) |
00357 (this->ctrldown ? CTRLDOWN : 0) |
00358 (this->shiftdown ? SHIFTDOWN : 0);
00359
00360 switch (combo) {
00361 case 0:
00362 if (curmode == NavigationStyle::SPINNING) { break; }
00363 newmode = NavigationStyle::IDLE;
00364
00365
00366 if (this->lockButton1) {
00367 this->lockButton1 = FALSE;
00368 processed = TRUE;
00369 }
00370
00371
00372
00373
00374
00375 break;
00376 case BUTTON1DOWN:
00377
00378 if (curmode == NavigationStyle::SPINNING || this->lockButton1)
00379 newmode = NavigationStyle::IDLE;
00380 else
00381 newmode = NavigationStyle::SELECTION;
00382 break;
00383 case BUTTON3DOWN:
00384 if (curmode == NavigationStyle::SPINNING) { break; }
00385 else if (newmode == NavigationStyle::ZOOMING) { break; }
00386 newmode = NavigationStyle::PANNING;
00387
00388 if (curmode == NavigationStyle::DRAGGING) {
00389 if (doSpin()) {
00390 newmode = NavigationStyle::SPINNING;
00391 break;
00392 }
00393 }
00394 break;
00395 case CTRLDOWN|BUTTON2DOWN:
00396 newmode = NavigationStyle::PANNING;
00397 break;
00398 case SHIFTDOWN|BUTTON2DOWN:
00399 newmode = NavigationStyle::DRAGGING;
00400 break;
00401 case CTRLDOWN|SHIFTDOWN|BUTTON2DOWN:
00402 newmode = NavigationStyle::ZOOMING;
00403 break;
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 default:
00423
00424
00425
00426
00427
00428
00429 break;
00430 }
00431
00432 if (newmode != curmode) {
00433 this->setViewingMode(newmode);
00434 }
00435
00436
00437
00438
00439 if (this->button1down && this->button3down)
00440 this->lockButton1 = TRUE;
00441
00442
00443
00444 if (!processed)
00445 processed = inherited::processSoEvent(ev);
00446 else
00447 return TRUE;
00448
00449 return processed;
00450 }