InventorNavigationStyle.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::InventorNavigationStyle, Gui::UserNavigationStyle);
00055
00056 InventorNavigationStyle::InventorNavigationStyle()
00057 {
00058 }
00059
00060 InventorNavigationStyle::~InventorNavigationStyle()
00061 {
00062 }
00063
00064 const char* InventorNavigationStyle::mouseButtons(ViewerMode mode)
00065 {
00066 switch (mode) {
00067 case NavigationStyle::SELECTION:
00068 return QT_TR_NOOP("Press CTRL and 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 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 InventorNavigationStyle::processSoEvent(const SoEvent * const ev)
00081 {
00082
00083
00084
00085 if (this->isSeekMode()) { return inherited::processSoEvent(ev); }
00086
00087 const SoType type(ev->getTypeId());
00088
00089 const SbViewportRegion & vp = viewer->getViewportRegion();
00090 const SbVec2s size(vp.getViewportSizePixels());
00091 const SbVec2f prevnormalized = this->lastmouseposition;
00092 const SbVec2s pos(ev->getPosition());
00093 const SbVec2f posn((float) pos[0] / (float) SoQtMax((int)(size[0] - 1), 1),
00094 (float) pos[1] / (float) SoQtMax((int)(size[1] - 1), 1));
00095
00096 this->lastmouseposition = posn;
00097
00098
00099
00100
00101
00102 SbBool processed = FALSE;
00103
00104 const ViewerMode curmode = this->currentmode;
00105 ViewerMode newmode = curmode;
00106
00107
00108
00109 if (this->ctrldown != ev->wasCtrlDown()) {
00110 this->ctrldown = ev->wasCtrlDown();
00111 }
00112 if (this->shiftdown != ev->wasShiftDown()) {
00113 this->shiftdown = ev->wasShiftDown();
00114 }
00115 if (this->altdown != ev->wasAltDown()) {
00116 this->altdown = ev->wasAltDown();
00117 }
00118
00119
00120 if (!processed && !viewer->isEditing()) {
00121 processed = handleEventInForeground(ev);
00122 if (processed)
00123 return TRUE;
00124 }
00125
00126
00127 if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
00128 const SoKeyboardEvent * const event = (const SoKeyboardEvent *) ev;
00129 const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00130 switch (event->getKey()) {
00131 case SoKeyboardEvent::LEFT_CONTROL:
00132 case SoKeyboardEvent::RIGHT_CONTROL:
00133 this->ctrldown = press;
00134 break;
00135 case SoKeyboardEvent::LEFT_SHIFT:
00136 case SoKeyboardEvent::RIGHT_SHIFT:
00137 this->shiftdown = press;
00138 break;
00139 case SoKeyboardEvent::LEFT_ALT:
00140 case SoKeyboardEvent::RIGHT_ALT:
00141 this->altdown = press;
00142 break;
00143 case SoKeyboardEvent::H:
00144 processed = TRUE;
00145 viewer->saveHomePosition();
00146 break;
00147 case SoKeyboardEvent::S:
00148 case SoKeyboardEvent::HOME:
00149 case SoKeyboardEvent::LEFT_ARROW:
00150 case SoKeyboardEvent::UP_ARROW:
00151 case SoKeyboardEvent::RIGHT_ARROW:
00152 case SoKeyboardEvent::DOWN_ARROW:
00153 if (!this->isViewing())
00154 this->setViewing(true);
00155 break;
00156 default:
00157 break;
00158 }
00159 }
00160
00161
00162 if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
00163 const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
00164 const int button = event->getButton();
00165 const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
00166
00167
00168 switch (button) {
00169 case SoMouseButtonEvent::BUTTON1:
00170 this->button1down = press;
00171 if (press && ev->wasShiftDown() &&
00172 (this->currentmode != NavigationStyle::SELECTION)) {
00173 this->centerTime = ev->getTime();
00174 float ratio = vp.getViewportAspectRatio();
00175 SbViewVolume vv = viewer->getCamera()->getViewVolume(ratio);
00176 this->panningplane = vv.getPlane(viewer->getCamera()->focalDistance.getValue());
00177 this->lockrecenter = FALSE;
00178 }
00179 else if (!press && ev->wasShiftDown() &&
00180 (this->currentmode != NavigationStyle::SELECTION)) {
00181 SbTime tmp = (ev->getTime() - this->centerTime);
00182 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00183
00184 if (tmp.getValue() < dci && !this->lockrecenter) {
00185 if (!this->lookAtPoint(pos)) {
00186 panToCenter(panningplane, posn);
00187 this->interactiveCountDec();
00188 }
00189 processed = TRUE;
00190 }
00191 }
00192 else if (press && (this->currentmode == NavigationStyle::SEEK_WAIT_MODE)) {
00193 newmode = NavigationStyle::SEEK_MODE;
00194 this->seekToPoint(pos);
00195 processed = TRUE;
00196 this->lockrecenter = TRUE;
00197 }
00198 else if (press && (this->currentmode == NavigationStyle::IDLE)) {
00199 this->setViewing(true);
00200 processed = TRUE;
00201 this->lockrecenter = TRUE;
00202 }
00203 else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
00204 this->setViewing(false);
00205 processed = TRUE;
00206 this->lockrecenter = TRUE;
00207 }
00208 else if (viewer->isEditing() && (this->currentmode == NavigationStyle::SPINNING)) {
00209 processed = TRUE;
00210 this->lockrecenter = TRUE;
00211 }
00212 break;
00213 case SoMouseButtonEvent::BUTTON2:
00214
00215
00216 this->lockrecenter = TRUE;
00217 if (!viewer->isEditing()) {
00218
00219
00220 if (this->currentmode != NavigationStyle::ZOOMING &&
00221 this->currentmode != NavigationStyle::PANNING) {
00222 if (this->isPopupMenuEnabled()) {
00223 if (!press) {
00224 this->openPopupMenu(event->getPosition());
00225 }
00226 }
00227 }
00228 }
00229 break;
00230 case SoMouseButtonEvent::BUTTON3:
00231 if (press) {
00232 this->centerTime = ev->getTime();
00233 float ratio = vp.getViewportAspectRatio();
00234 SbViewVolume vv = viewer->getCamera()->getViewVolume(ratio);
00235 this->panningplane = vv.getPlane(viewer->getCamera()->focalDistance.getValue());
00236 this->lockrecenter = FALSE;
00237 }
00238 else {
00239 SbTime tmp = (ev->getTime() - this->centerTime);
00240 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00241
00242 if (tmp.getValue() < dci && !this->lockrecenter) {
00243 if (!this->lookAtPoint(pos)) {
00244 panToCenter(panningplane, posn);
00245 this->interactiveCountDec();
00246 }
00247 processed = TRUE;
00248 }
00249 }
00250 this->button3down = press;
00251 break;
00252 case SoMouseButtonEvent::BUTTON4:
00253 if (this->invertZoom)
00254 zoom(viewer->getCamera(), -0.05f);
00255 else
00256 zoom(viewer->getCamera(), 0.05f);
00257 processed = TRUE;
00258 break;
00259 case SoMouseButtonEvent::BUTTON5:
00260 if (this->invertZoom)
00261 zoom(viewer->getCamera(), 0.05f);
00262 else
00263 zoom(viewer->getCamera(), -0.05f);
00264 processed = TRUE;
00265 break;
00266 default:
00267 break;
00268 }
00269 }
00270
00271
00272 if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) {
00273 this->lockrecenter = TRUE;
00274 const SoLocation2Event * const event = (const SoLocation2Event *) ev;
00275 if (this->currentmode == NavigationStyle::ZOOMING) {
00276 this->zoomByCursor(posn, prevnormalized);
00277 processed = TRUE;
00278 }
00279 else if (this->currentmode == NavigationStyle::PANNING) {
00280 float ratio = vp.getViewportAspectRatio();
00281 panCamera(viewer->getCamera(), ratio, this->panningplane, posn, prevnormalized);
00282 processed = TRUE;
00283 }
00284 else if (this->currentmode == NavigationStyle::DRAGGING) {
00285 this->addToLog(event->getPosition(), event->getTime());
00286 this->spin(posn);
00287 processed = TRUE;
00288 }
00289 }
00290
00291
00292 if (type.isDerivedFrom(SoMotion3Event::getClassTypeId())) {
00293 SoMotion3Event * const event = (SoMotion3Event *) ev;
00294 SoCamera * const camera = viewer->getCamera();
00295 if (camera) {
00296 SbVec3f dir = event->getTranslation();
00297 camera->orientation.getValue().multVec(dir,dir);
00298 camera->position = camera->position.getValue() + dir;
00299 camera->orientation =
00300 event->getRotation() * camera->orientation.getValue();
00301 processed = TRUE;
00302 }
00303 }
00304
00305 enum {
00306 BUTTON1DOWN = 1 << 0,
00307 BUTTON3DOWN = 1 << 1,
00308 CTRLDOWN = 1 << 2,
00309 SHIFTDOWN = 1 << 3
00310 };
00311 unsigned int combo =
00312 (this->button1down ? BUTTON1DOWN : 0) |
00313 (this->button3down ? BUTTON3DOWN : 0) |
00314 (this->ctrldown ? CTRLDOWN : 0) |
00315 (this->shiftdown ? SHIFTDOWN : 0);
00316
00317 switch (combo) {
00318 case 0:
00319 if (curmode == NavigationStyle::SPINNING) { break; }
00320 newmode = NavigationStyle::IDLE;
00321
00322 if (curmode == NavigationStyle::DRAGGING) {
00323 if (doSpin())
00324 newmode = NavigationStyle::SPINNING;
00325 }
00326 break;
00327 case BUTTON1DOWN:
00328 newmode = NavigationStyle::DRAGGING;
00329 break;
00330 case BUTTON3DOWN:
00331 case SHIFTDOWN|BUTTON1DOWN:
00332 newmode = NavigationStyle::PANNING;
00333 break;
00334 case CTRLDOWN:
00335 case CTRLDOWN|BUTTON1DOWN:
00336 case CTRLDOWN|SHIFTDOWN:
00337 case CTRLDOWN|SHIFTDOWN|BUTTON1DOWN:
00338 newmode = NavigationStyle::SELECTION;
00339 break;
00340 case BUTTON1DOWN|BUTTON3DOWN:
00341 case CTRLDOWN|BUTTON3DOWN:
00342 newmode = NavigationStyle::ZOOMING;
00343 break;
00344
00345
00346
00347
00348
00349
00350
00351
00352 default:
00353
00354
00355 if ((curmode != NavigationStyle::SEEK_WAIT_MODE) &&
00356 (curmode != NavigationStyle::SEEK_MODE)) {
00357 newmode = NavigationStyle::IDLE;
00358 }
00359 break;
00360 }
00361
00362 if (newmode != curmode) {
00363 this->setViewingMode(newmode);
00364 }
00365
00366
00367
00368 if ((curmode == NavigationStyle::SELECTION || viewer->isEditing()) && !processed)
00369 processed = inherited::processSoEvent(ev);
00370 else
00371 return TRUE;
00372
00373 return processed;
00374 }