BlenderNavigationStyle.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::BlenderNavigationStyle, Gui::UserNavigationStyle);
00055
00056 BlenderNavigationStyle::BlenderNavigationStyle() : lockButton1(FALSE)
00057 {
00058 }
00059
00060 BlenderNavigationStyle::~BlenderNavigationStyle()
00061 {
00062 }
00063
00064 const char* BlenderNavigationStyle::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 SHIFT and middle mouse button");
00071 case NavigationStyle::DRAGGING:
00072 return QT_TR_NOOP("Press 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 BlenderNavigationStyle::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->lockrecenter = TRUE;
00171 this->button1down = press;
00172 if (press && (this->currentmode == NavigationStyle::SEEK_WAIT_MODE)) {
00173 newmode = NavigationStyle::SEEK_MODE;
00174 this->seekToPoint(pos);
00175 processed = TRUE;
00176 }
00177
00178
00179
00180
00181 else if (press && (this->currentmode == NavigationStyle::PANNING ||
00182 this->currentmode == NavigationStyle::ZOOMING)) {
00183 newmode = NavigationStyle::DRAGGING;
00184 this->centerTime = ev->getTime();
00185 processed = TRUE;
00186 }
00187 else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
00188 SbTime tmp = (ev->getTime() - this->centerTime);
00189 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00190 if (tmp.getValue() < dci) {
00191 newmode = NavigationStyle::ZOOMING;
00192 }
00193 processed = TRUE;
00194 }
00195 else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
00196 this->setViewing(false);
00197 processed = TRUE;
00198 }
00199 else if (viewer->isEditing() && (this->currentmode == NavigationStyle::SPINNING)) {
00200 processed = TRUE;
00201 }
00202 break;
00203 case SoMouseButtonEvent::BUTTON2:
00204
00205
00206 this->lockrecenter = TRUE;
00207 if (!viewer->isEditing()) {
00208
00209
00210 if (this->currentmode != NavigationStyle::ZOOMING &&
00211 this->currentmode != NavigationStyle::PANNING &&
00212 this->currentmode != NavigationStyle::DRAGGING) {
00213 if (this->isPopupMenuEnabled()) {
00214 if (!press) {
00215 this->openPopupMenu(event->getPosition());
00216 }
00217 }
00218 }
00219 }
00220
00221 if (press && (this->currentmode == NavigationStyle::PANNING ||
00222 this->currentmode == NavigationStyle::ZOOMING)) {
00223 newmode = NavigationStyle::DRAGGING;
00224 this->centerTime = ev->getTime();
00225 processed = TRUE;
00226 }
00227 else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
00228 SbTime tmp = (ev->getTime() - this->centerTime);
00229 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00230 if (tmp.getValue() < dci) {
00231 newmode = NavigationStyle::ZOOMING;
00232 }
00233 processed = TRUE;
00234 }
00235 this->button2down = press;
00236 break;
00237 case SoMouseButtonEvent::BUTTON3:
00238 if (press) {
00239 this->centerTime = ev->getTime();
00240 float ratio = vp.getViewportAspectRatio();
00241 SbViewVolume vv = viewer->getCamera()->getViewVolume(ratio);
00242 this->panningplane = vv.getPlane(viewer->getCamera()->focalDistance.getValue());
00243 this->lockrecenter = FALSE;
00244 }
00245 else {
00246 SbTime tmp = (ev->getTime() - this->centerTime);
00247 float dci = (float)QApplication::doubleClickInterval()/1000.0f;
00248
00249 if (tmp.getValue() < dci && !this->lockrecenter) {
00250 if (!this->lookAtPoint(pos)) {
00251 panToCenter(panningplane, posn);
00252 this->interactiveCountDec();
00253 }
00254 processed = TRUE;
00255 }
00256 }
00257 this->button3down = press;
00258 break;
00259 case SoMouseButtonEvent::BUTTON4:
00260 if (this->invertZoom)
00261 zoom(viewer->getCamera(), -0.05f);
00262 else
00263 zoom(viewer->getCamera(), 0.05f);
00264 processed = TRUE;
00265 break;
00266 case SoMouseButtonEvent::BUTTON5:
00267 if (this->invertZoom)
00268 zoom(viewer->getCamera(), 0.05f);
00269 else
00270 zoom(viewer->getCamera(), -0.05f);
00271 processed = TRUE;
00272 break;
00273 default:
00274 break;
00275 }
00276 }
00277
00278
00279 if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) {
00280 this->lockrecenter = TRUE;
00281 const SoLocation2Event * const event = (const SoLocation2Event *) ev;
00282 if (this->currentmode == NavigationStyle::ZOOMING) {
00283 this->zoomByCursor(posn, prevnormalized);
00284 processed = TRUE;
00285 }
00286 else if (this->currentmode == NavigationStyle::PANNING) {
00287 float ratio = vp.getViewportAspectRatio();
00288 panCamera(viewer->getCamera(), ratio, this->panningplane, posn, prevnormalized);
00289 processed = TRUE;
00290 }
00291 else if (this->currentmode == NavigationStyle::DRAGGING) {
00292 this->addToLog(event->getPosition(), event->getTime());
00293 this->spin(posn);
00294 processed = TRUE;
00295 }
00296 }
00297
00298
00299 if (type.isDerivedFrom(SoMotion3Event::getClassTypeId())) {
00300 SoMotion3Event * const event = (SoMotion3Event *) ev;
00301 SoCamera * const camera = viewer->getCamera();
00302
00303 SbVec3f dir = event->getTranslation();
00304 if (camera->getTypeId().isDerivedFrom(SoOrthographicCamera::getClassTypeId())){
00305 static float zoomConstant(-.03f);
00306 dir[2] = 0.0;
00307
00308 SoOrthographicCamera *oCam = static_cast<SoOrthographicCamera *>(camera);
00309 oCam->scaleHeight(1.0-event->getTranslation()[2] * zoomConstant);
00310 }
00311 camera->orientation.getValue().multVec(dir,dir);
00312 camera->position = camera->position.getValue() + dir;
00313 camera->orientation = event->getRotation() * camera->orientation.getValue();
00314 processed = TRUE;
00315 }
00316
00317 enum {
00318 BUTTON1DOWN = 1 << 0,
00319 BUTTON3DOWN = 1 << 1,
00320 CTRLDOWN = 1 << 2,
00321 SHIFTDOWN = 1 << 3,
00322 BUTTON2DOWN = 1 << 4
00323 };
00324 unsigned int combo =
00325 (this->button1down ? BUTTON1DOWN : 0) |
00326 (this->button2down ? BUTTON2DOWN : 0) |
00327 (this->button3down ? BUTTON3DOWN : 0) |
00328 (this->ctrldown ? CTRLDOWN : 0) |
00329 (this->shiftdown ? SHIFTDOWN : 0);
00330
00331 switch (combo) {
00332 case 0:
00333 if (curmode == NavigationStyle::SPINNING) { break; }
00334 newmode = NavigationStyle::IDLE;
00335
00336
00337 if (this->lockButton1) {
00338 this->lockButton1 = FALSE;
00339 processed = TRUE;
00340 }
00341
00342
00343
00344
00345
00346 break;
00347 case BUTTON1DOWN:
00348
00349 if (curmode == NavigationStyle::SPINNING || this->lockButton1)
00350 newmode = NavigationStyle::IDLE;
00351 else
00352 newmode = NavigationStyle::SELECTION;
00353 break;
00354 case SHIFTDOWN|BUTTON3DOWN:
00355 newmode = NavigationStyle::PANNING;
00356 break;
00357 case BUTTON3DOWN:
00358 newmode = NavigationStyle::DRAGGING;
00359 break;
00360 case CTRLDOWN|SHIFTDOWN|BUTTON2DOWN:
00361 newmode = NavigationStyle::ZOOMING;
00362 break;
00363
00364 default:
00365 break;
00366 }
00367
00368 if (newmode != curmode) {
00369 this->setViewingMode(newmode);
00370 }
00371
00372
00373
00374
00375 if (this->button1down && this->button3down)
00376 this->lockButton1 = TRUE;
00377
00378
00379
00380 if (!processed)
00381 processed = inherited::processSoEvent(ev);
00382 else
00383 return TRUE;
00384
00385 return processed;
00386 }