24 #include "qglviewer.h"
26 #include "keyFrameInterpolator.h"
27 #include "manipulatedCameraFrame.h"
29 # include <QtAlgorithms>
31 # include <QApplication>
34 # include <QMessageBox>
35 # include <QPushButton>
36 # include <QTabWidget>
37 # include <QTextStream>
38 # include <QMouseEvent>
45 using namespace qglviewer;
48 QList<QGLViewer*> QGLViewer::QGLViewerPool_;
68 void QGLViewer::defaultConstructor()
74 int poolIndex = QGLViewer::QGLViewerPool_.indexOf(NULL);
75 setFocusPolicy(Qt::StrongFocus);
78 QGLViewer::QGLViewerPool_.replace(poolIndex,
this);
80 QGLViewer::QGLViewerPool_.append(
this);
85 setDefaultShortcuts();
86 setDefaultMouseBindings();
88 setSnapshotFileName(tr(
"snapshot",
"Default snapshot file name"));
89 initializeSnapshotFormats();
90 setSnapshotCounter(0);
91 setSnapshotQuality(95);
96 fpsString_ = tr(
"%1Hz",
"Frames per seconds, in Hertz").arg(
"?");
103 manipulatedFrame_ = NULL;
104 manipulatedFrameIsACamera_ =
false;
105 mouseGrabberIsAManipulatedFrame_ =
false;
106 mouseGrabberIsAManipulatedCameraFrame_ =
false;
107 displayMessage_ =
false;
108 connect(&messageTimer_, SIGNAL(timeout()), SLOT(hideMessage()));
109 messageTimer_.setSingleShot(
true);
111 setMouseGrabber(NULL);
115 setStateFileName(
".qglviewer.xml");
118 setAxisIsDrawn(
false);
119 setGridIsDrawn(
false);
120 setFPSIsDisplayed(
false);
121 setCameraIsEdited(
false);
122 setTextIsEnabled(
true);
123 setStereoDisplay(
false);
126 setFullScreen(
false);
128 animationTimerId_ = 0;
130 setAnimationPeriod(40);
132 selectBuffer_ = NULL;
133 setSelectBufferSize(4*1000);
134 setSelectRegionWidth(3);
135 setSelectRegionHeight(3);
138 bufferTextureId_ = 0;
139 bufferTextureMaxU_ = 0.0;
140 bufferTextureMaxV_ = 0.0;
141 bufferTextureWidth_ = 0;
142 bufferTextureHeight_ = 0;
143 previousBufferTextureFormat_ = 0;
144 previousBufferTextureInternalFormat_ = 0;
145 currentlyPressedKey_ = Qt::Key(0);
147 setAttribute(Qt::WA_NoSystemBackground);
152 #if !defined QT3_SUPPORT
161 : QGLWidget(parent, shareWidget, flags)
162 { defaultConstructor(); }
166 QGLViewer::QGLViewer(QGLContext *context, QWidget* parent,
const QGLWidget* shareWidget, Qt::WindowFlags flags)
167 : QGLWidget(context, parent, shareWidget, flags)
168 { defaultConstructor(); }
174 QGLViewer::QGLViewer(
const QGLFormat& format, QWidget* parent,
const QGLWidget* shareWidget, Qt::WindowFlags flags)
175 : QGLWidget(format, parent, shareWidget, flags)
176 { defaultConstructor(); }
177 #endif // QT3_SUPPORT
190 QGLViewer::QGLViewerPool_.replace(QGLViewer::QGLViewerPool_.indexOf(
this), NULL);
193 delete[] selectBuffer_;
203 static QString QGLViewerVersionString()
205 return QString::number((QGLVIEWER_VERSION & 0xff0000) >> 16) +
"." +
206 QString::number((QGLVIEWER_VERSION & 0x00ff00) >> 8) +
"." +
207 QString::number(QGLVIEWER_VERSION & 0x0000ff);
210 static Qt::KeyboardModifiers keyboardModifiersFromState(
int state) {
212 return Qt::KeyboardModifiers(state & 0xFF000000);
216 static Qt::MouseButton mouseButtonFromState(
int state) {
218 return Qt::MouseButton(state & 0xFFFF);
242 glEnable(GL_LIGHTING);
243 glEnable(GL_DEPTH_TEST);
244 glEnable(GL_COLOR_MATERIAL);
251 if (format().stereo())
253 glDrawBuffer(GL_BACK_RIGHT);
254 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
255 glDrawBuffer(GL_BACK_LEFT);
256 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
259 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
266 QTimer::singleShot( 100,
this, SLOT(delayedFullScreen()) );
279 for (
int view=1; view>=0; --view)
284 if (
camera()->frame()->isManipulated())
296 if (
camera()->frame()->isManipulated())
319 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
342 glMatrixMode(GL_MODELVIEW);
348 glPushAttrib(GL_ALL_ATTRIB_BITS);
351 glDisable(GL_TEXTURE_1D);
352 glDisable(GL_TEXTURE_2D);
353 #ifdef GL_TEXTURE_3D // OpenGL 1.2 Only...
354 glDisable(GL_TEXTURE_3D);
357 glDisable(GL_TEXTURE_GEN_Q);
358 glDisable(GL_TEXTURE_GEN_R);
359 glDisable(GL_TEXTURE_GEN_S);
360 glDisable(GL_TEXTURE_GEN_T);
362 #ifdef GL_RESCALE_NORMAL // OpenGL 1.2 Only...
363 glEnable(GL_RESCALE_NORMAL);
366 glDisable(GL_COLOR_MATERIAL);
379 const unsigned int maxCounter = 20;
380 if (++fpsCounter_ == maxCounter)
382 f_p_s_ = 1000.0 * maxCounter / fpsTime_.restart();
383 fpsString_ = tr(
"%1Hz",
"Frames per seconds, in Hertz").arg(f_p_s_, 0,
'f', ((f_p_s_ < 10.0)?1:0));
393 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
394 glDisable(GL_LIGHTING);
395 glDisable(GL_DEPTH_TEST);
398 if (displayMessage_)
drawText(10, height()-10, message_);
416 glDrawBuffer(GL_BACK_LEFT);
418 glDrawBuffer(GL_BACK_RIGHT);
421 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
451 cameraIsEdited_ = edit;
467 void QGLViewer::setDefaultShortcuts()
473 setShortcut(ENABLE_TEXT, Qt::SHIFT+Qt::Key_Question);
488 setShortcut(SNAPSHOT_TO_CLIPBOARD, Qt::CTRL+Qt::Key_C);
490 keyboardActionDescription_[DISPLAY_FPS] = tr(
"Toggles the display of the FPS",
"DISPLAY_FPS action description");
491 keyboardActionDescription_[SAVE_SCREENSHOT] = tr(
"Saves a screenshot",
"SAVE_SCREENSHOT action description");
492 keyboardActionDescription_[FULL_SCREEN] = tr(
"Toggles full screen display",
"FULL_SCREEN action description");
493 keyboardActionDescription_[DRAW_AXIS] = tr(
"Toggles the display of the world axis",
"DRAW_AXIS action description");
494 keyboardActionDescription_[DRAW_GRID] = tr(
"Toggles the display of the XY grid",
"DRAW_GRID action description");
495 keyboardActionDescription_[CAMERA_MODE] = tr(
"Changes camera mode (observe or fly)",
"CAMERA_MODE action description");
496 keyboardActionDescription_[STEREO] = tr(
"Toggles stereo display",
"STEREO action description");
497 keyboardActionDescription_[HELP] = tr(
"Opens this help window",
"HELP action description");
498 keyboardActionDescription_[ANIMATION] = tr(
"Starts/stops the animation",
"ANIMATION action description");
499 keyboardActionDescription_[EDIT_CAMERA] = tr(
"Toggles camera paths display",
"EDIT_CAMERA action description");
500 keyboardActionDescription_[ENABLE_TEXT] = tr(
"Toggles the display of the text",
"ENABLE_TEXT action description");
501 keyboardActionDescription_[EXIT_VIEWER] = tr(
"Exits program",
"EXIT_VIEWER action description");
502 keyboardActionDescription_[MOVE_CAMERA_LEFT] = tr(
"Moves camera left",
"MOVE_CAMERA_LEFT action description");
503 keyboardActionDescription_[MOVE_CAMERA_RIGHT] = tr(
"Moves camera right",
"MOVE_CAMERA_RIGHT action description");
504 keyboardActionDescription_[MOVE_CAMERA_UP] = tr(
"Moves camera up",
"MOVE_CAMERA_UP action description");
505 keyboardActionDescription_[MOVE_CAMERA_DOWN] = tr(
"Moves camera down",
"MOVE_CAMERA_DOWN action description");
506 keyboardActionDescription_[INCREASE_FLYSPEED] = tr(
"Increases fly speed",
"INCREASE_FLYSPEED action description");
507 keyboardActionDescription_[DECREASE_FLYSPEED] = tr(
"Decreases fly speed",
"DECREASE_FLYSPEED action description");
508 keyboardActionDescription_[SNAPSHOT_TO_CLIPBOARD] = tr(
"Copies a snapshot to clipboard",
"SNAPSHOT_TO_CLIPBOARD action description");
529 void QGLViewer::setDefaultMouseBindings()
531 const Qt::KeyboardModifiers cameraKeyboardModifiers = Qt::NoModifier;
532 const Qt::KeyboardModifiers frameKeyboardModifiers = Qt::ControlModifier;
535 for (
int handler=0; handler<2; ++handler)
538 Qt::KeyboardModifiers modifiers = (mh == FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers;
544 setMouseBinding(Qt::Key_R, modifiers, Qt::LeftButton, mh, SCREEN_ROTATE);
550 setMouseBinding(Qt::ShiftModifier, Qt::MidButton, CAMERA, ZOOM_ON_REGION);
558 setMouseBinding(Qt::NoModifier, Qt::MidButton, SHOW_ENTIRE_SCENE,
true);
561 setMouseBinding(frameKeyboardModifiers, Qt::LeftButton, ALIGN_FRAME,
true);
563 setMouseBinding(frameKeyboardModifiers, Qt::RightButton, CENTER_FRAME,
true);
566 setMouseBinding(Qt::Key_Z, Qt::NoModifier, Qt::LeftButton, ZOOM_ON_PIXEL);
567 setMouseBinding(Qt::Key_Z, Qt::NoModifier, Qt::RightButton, ZOOM_TO_FIT);
575 const Qt::KeyboardModifiers macKeyboardModifiers = Qt::AltModifier;
577 setMouseBinding(macKeyboardModifiers, Qt::LeftButton, CAMERA, TRANSLATE);
578 setMouseBinding(macKeyboardModifiers, Qt::LeftButton, CENTER_SCENE,
true);
579 setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, Qt::LeftButton, CENTER_FRAME,
true);
580 setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, Qt::LeftButton, FRAME, TRANSLATE);
610 disconnect(this->
camera()->frame(), SIGNAL(manipulated()),
this, SLOT(update()));
611 disconnect(this->
camera()->frame(), SIGNAL(spun()),
this, SLOT(update()));
614 connect(camera->
frame(), SIGNAL(manipulated()), SLOT(update()));
615 connect(camera->
frame(), SIGNAL(spun()), SLOT(update()));
617 connectAllCameraKFIInterpolatedSignals(
false);
619 connectAllCameraKFIInterpolatedSignals();
624 void QGLViewer::connectAllCameraKFIInterpolatedSignals(
bool connection)
626 for (QMap<int, KeyFrameInterpolator*>::ConstIterator it =
camera()->kfi_.begin(), end=
camera()->kfi_.end(); it != end; ++it)
629 connect(
camera()->keyFrameInterpolator(it.key()), SIGNAL(interpolated()), SLOT(update()));
631 disconnect(
camera()->keyFrameInterpolator(it.key()), SIGNAL(interpolated()),
this, SLOT(update()));
635 connect(
camera()->interpolationKfi_, SIGNAL(interpolated()), SLOT(update()));
637 disconnect(
camera()->interpolationKfi_, SIGNAL(interpolated()),
this, SLOT(update()));
658 static GLUquadric* quadric = gluNewQuadric();
663 glGetBooleanv(light, &lightIsOn);
672 glGetLightfv(light, GL_DIFFUSE, color);
676 glGetLightfv(light, GL_POSITION, pos);
680 glTranslatef(pos[0]/pos[3], pos[1]/pos[3], pos[2]/pos[3]);
683 glGetLightfv(light, GL_SPOT_CUTOFF, &cutOff);
687 glGetLightfv(light, GL_SPOT_DIRECTION, dir);
690 gluCylinder(quadric, 0.0, 0.7 * length * sin(cutOff * M_PI / 180.0), 0.7 * length * cos(cutOff * M_PI / 180.0), 12, 1);
693 gluSphere(quadric, 0.2*length, 10, 10);
698 Vec dir(pos[0], pos[1], pos[2]);
702 glMultMatrixd(fr.
matrix());
746 if (tileRegion_ != NULL) {
747 renderText((x-tileRegion_->xMin) * width() / (tileRegion_->xMax - tileRegion_->xMin),
748 (y-tileRegion_->yMin) * height() / (tileRegion_->yMax - tileRegion_->yMin), text,
scaledFont(fnt));
750 renderText(x, y, text, fnt);
767 displayMessage_ =
true;
769 messageTimer_.start(delay);
774 void QGLViewer::hideMessage()
776 displayMessage_ =
false;
791 void QGLViewer::displayFPS()
793 drawText(10,
int(1.5*((QApplication::font().pixelSize()>0)?QApplication::font().pixelSize():QApplication::font().pointSize())), fpsString_);
829 glMatrixMode(GL_PROJECTION);
832 if (tileRegion_ != NULL)
834 glOrtho(tileRegion_->xMin, tileRegion_->xMax, tileRegion_->yMin, tileRegion_->yMax, 0.0, -1.0);
836 glOrtho(tileRegion_->xMin, tileRegion_->xMax, tileRegion_->yMax, tileRegion_->yMin, 0.0, -1.0);
839 glOrtho(0, width(), 0, height(), 0.0, -1.0);
841 glOrtho(0, width(), height(), 0, 0.0, -1.0);
843 glMatrixMode(GL_MODELVIEW);
854 glMatrixMode(GL_PROJECTION);
857 glMatrixMode(GL_MODELVIEW);
877 animationStarted_ =
true;
883 animationStarted_ =
false;
884 if (animationTimerId_ != 0)
885 killTimer(animationTimerId_);
1019 glRenderMode(GL_SELECT);
1023 glMatrixMode(GL_PROJECTION);
1025 static GLint viewport[4];
1080 GLint nbHits = glRenderMode(GL_RENDER);
1092 for (
int i=1; i<nbHits; ++i)
1107 delete[] selectBuffer_;
1108 selectBufferSize_ = size;
1112 static QString mouseButtonsString(Qt::MouseButtons b)
1115 bool addAmpersand =
false;
1116 if (b & Qt::LeftButton) { result += QGLViewer::tr(
"Left",
"left mouse button"); addAmpersand=
true; }
1117 if (b & Qt::MidButton) {
if (addAmpersand) result +=
" & "; result += QGLViewer::tr(
"Middle",
"middle mouse button"); addAmpersand=
true; }
1118 if (b & Qt::RightButton) {
if (addAmpersand) result +=
" & "; result += QGLViewer::tr(
"Right",
"right mouse button"); }
1122 void QGLViewer::performClickAction(ClickAction ca,
const QMouseEvent*
const e)
1129 case NO_CLICK_ACTION :
1131 case ZOOM_ON_PIXEL :
1141 case RAP_FROM_PIXEL :
1142 if (!
camera()->setPivotPointFromPixel(e->pos()))
1147 case RAP_IS_CENTER :
1159 case SHOW_ENTIRE_SCENE :
1195 ClickBindingPrivate cbp(e->modifiers(), e->button(),
false, (Qt::MouseButtons)(e->buttons() & ~(e->button())), currentlyPressedKey_);
1197 if (clickBinding_.contains(cbp)) {
1198 performClickAction(clickBinding_[cbp], e);
1202 if (mouseGrabberIsAManipulatedFrame_)
1204 for (QMap<MouseBindingPrivate, MouseActionPrivate>::ConstIterator it=mouseBinding_.begin(), end=mouseBinding_.end(); it!=end; ++it)
1205 if ((it.value().handler == FRAME) && (it.key().button == e->button()))
1208 if (mouseGrabberIsAManipulatedCameraFrame_)
1210 mf->ManipulatedFrame::startAction(it.value().action, it.value().withConstraint);
1211 mf->ManipulatedFrame::mousePressEvent(e,
camera());
1215 mf->
startAction(it.value().action, it.value().withConstraint);
1228 const MouseBindingPrivate mbp(e->modifiers(), e->button(), currentlyPressedKey_);
1230 if (mouseBinding_.contains(mbp))
1232 MouseActionPrivate map = mouseBinding_[mbp];
1233 switch (map.handler)
1242 if (manipulatedFrameIsACamera_)
1244 manipulatedFrame()->ManipulatedFrame::startAction(map.action, map.withConstraint);
1255 if (map.action == SCREEN_ROTATE)
1302 if (mouseGrabberIsAManipulatedCameraFrame_)
1314 if (
camera()->frame()->isManipulated())
1318 if (
camera()->frame()->action_ == ZOOM_ON_REGION)
1323 if (manipulatedFrameIsACamera_)
1328 if (hasMouseTracking())
1330 Q_FOREACH (
MouseGrabber* mg, MouseGrabber::MouseGrabberPool())
1357 if (mouseGrabberIsAManipulatedCameraFrame_)
1375 if (manipulatedFrameIsACamera_)
1396 if (mouseGrabberIsAManipulatedFrame_)
1398 for (QMap<WheelBindingPrivate, MouseActionPrivate>::ConstIterator it=wheelBinding_.begin(), end=wheelBinding_.end(); it!=end; ++it)
1399 if (it.value().handler == FRAME)
1402 if (mouseGrabberIsAManipulatedCameraFrame_)
1404 mf->ManipulatedFrame::startAction(it.value().action, it.value().withConstraint);
1405 mf->ManipulatedFrame::wheelEvent(e,
camera());
1409 mf->
startAction(it.value().action, it.value().withConstraint);
1422 WheelBindingPrivate wbp(e->modifiers(), currentlyPressedKey_);
1424 if (wheelBinding_.contains(wbp))
1426 MouseActionPrivate map = wheelBinding_[wbp];
1427 switch (map.handler)
1435 if (manipulatedFrameIsACamera_)
1437 manipulatedFrame()->ManipulatedFrame::startAction(map.action, map.withConstraint);
1461 ClickBindingPrivate cbp(e->modifiers(), e->button(),
true, (Qt::MouseButtons)(e->buttons() & ~(e->button())), currentlyPressedKey_);
1462 if (clickBinding_.contains(cbp))
1463 performClickAction(clickBinding_[cbp], e);
1477 if (format().stereo())
1482 glDrawBuffer(GL_BACK_LEFT);
1483 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1484 glDrawBuffer(GL_BACK_RIGHT);
1485 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1494 QMessageBox::warning(
this, tr(
"Stereo not supported",
"Message box window title"), tr(
"Stereo is not supported on this display."));
1505 if (fullScreen_ == fullScreen)
return;
1507 fullScreen_ = fullScreen;
1509 QWidget* tlw = topLevelWidget();
1513 prevPos_ = topLevelWidget()->pos();
1514 tlw->showFullScreen();
1520 tlw->move(prevPos_);
1547 disabledMouseGrabbers_.remove(reinterpret_cast<size_t>(mouseGrabber));
1549 disabledMouseGrabbers_[
reinterpret_cast<size_t>(
mouseGrabber)];
1556 case QGLViewer::NO_MOUSE_ACTION :
return QString::null;
1557 case QGLViewer::ROTATE :
return QGLViewer::tr(
"Rotates",
"ROTATE mouse action");
1558 case QGLViewer::ZOOM :
return QGLViewer::tr(
"Zooms",
"ZOOM mouse action");
1559 case QGLViewer::TRANSLATE :
return QGLViewer::tr(
"Translates",
"TRANSLATE mouse action");
1560 case QGLViewer::MOVE_FORWARD :
return QGLViewer::tr(
"Moves forward",
"MOVE_FORWARD mouse action");
1561 case QGLViewer::LOOK_AROUND :
return QGLViewer::tr(
"Looks around",
"LOOK_AROUND mouse action");
1562 case QGLViewer::MOVE_BACKWARD :
return QGLViewer::tr(
"Moves backward",
"MOVE_BACKWARD mouse action");
1563 case QGLViewer::SCREEN_ROTATE :
return QGLViewer::tr(
"Rotates in screen plane",
"SCREEN_ROTATE mouse action");
1564 case QGLViewer::ROLL :
return QGLViewer::tr(
"Rolls",
"ROLL mouse action");
1565 case QGLViewer::DRIVE :
return QGLViewer::tr(
"Drives",
"DRIVE mouse action");
1566 case QGLViewer::SCREEN_TRANSLATE :
return QGLViewer::tr(
"Horizontally/Vertically translates",
"SCREEN_TRANSLATE mouse action");
1567 case QGLViewer::ZOOM_ON_REGION :
return QGLViewer::tr(
"Zooms on region for",
"ZOOM_ON_REGION mouse action");
1569 return QString::null;
1576 case QGLViewer::NO_CLICK_ACTION :
return QString::null;
1577 case QGLViewer::ZOOM_ON_PIXEL :
return QGLViewer::tr(
"Zooms on pixel",
"ZOOM_ON_PIXEL click action");
1578 case QGLViewer::ZOOM_TO_FIT :
return QGLViewer::tr(
"Zooms to fit scene",
"ZOOM_TO_FIT click action");
1579 case QGLViewer::SELECT :
return QGLViewer::tr(
"Selects",
"SELECT click action");
1580 case QGLViewer::RAP_FROM_PIXEL :
return QGLViewer::tr(
"Sets pivot point",
"RAP_FROM_PIXEL click action");
1581 case QGLViewer::RAP_IS_CENTER :
return QGLViewer::tr(
"Resets pivot point",
"RAP_IS_CENTER click action");
1582 case QGLViewer::CENTER_FRAME :
return QGLViewer::tr(
"Centers manipulated frame",
"CENTER_FRAME click action");
1583 case QGLViewer::CENTER_SCENE :
return QGLViewer::tr(
"Centers scene",
"CENTER_SCENE click action");
1584 case QGLViewer::SHOW_ENTIRE_SCENE :
return QGLViewer::tr(
"Shows entire scene",
"SHOW_ENTIRE_SCENE click action");
1585 case QGLViewer::ALIGN_FRAME :
return QGLViewer::tr(
"Aligns manipulated frame",
"ALIGN_FRAME click action");
1586 case QGLViewer::ALIGN_CAMERA :
return QGLViewer::tr(
"Aligns camera",
"ALIGN_CAMERA click action");
1588 return QString::null;
1591 static QString keyString(
int key)
1593 # if QT_VERSION >= 0x040100
1594 return QKeySequence(key).toString(QKeySequence::NativeText);
1596 return QString(QKeySequence(key));
1600 QString QGLViewer::formatClickActionPrivate(ClickBindingPrivate cbp)
1602 bool buttonsBefore = cbp.buttonsBefore != Qt::NoButton;
1603 QString keyModifierString = keyString(cbp.modifiers + cbp.key);
1604 if (!keyModifierString.isEmpty()) {
1607 keyModifierString +=
" ";
1610 if (!keyModifierString.endsWith(
'+'))
1611 keyModifierString +=
"+";
1615 return tr(
"%1%2%3%4%5%6",
"Modifier / button or wheel / double click / with / button / pressed")
1616 .arg(keyModifierString)
1617 .arg(mouseButtonsString(cbp.button)+(cbp.button == Qt::NoButton ? tr(
"Wheel",
"Mouse wheel") :
""))
1618 .arg(cbp.doubleClick ? tr(
" double click",
"Suffix after mouse button") :
"")
1619 .arg(buttonsBefore ? tr(
" with ",
"As in : Left button with Ctrl pressed") :
"")
1620 .arg(buttonsBefore ? mouseButtonsString(cbp.buttonsBefore) :
"")
1621 .arg(buttonsBefore ? tr(
" pressed",
"As in : Left button with Ctrl pressed") :
"");
1624 bool QGLViewer::isValidShortcutKey(
int key) {
1625 return (key >= Qt::Key_Any && key < Qt::Key_Escape) || (key >= Qt::Key_F1 && key <= Qt::Key_F35);
1634 qWarning(
"setMouseBindingDescription(int state,...) is deprecated. Use the modifier/button equivalent");
1636 mouseButtonFromState(state),
1683 ClickBindingPrivate cbp(modifiers, button, doubleClick, buttonsBefore, key);
1685 if (description.isEmpty())
1686 mouseDescription_.remove(cbp);
1688 mouseDescription_[cbp] = description;
1691 static QString tableLine(
const QString& left,
const QString& right)
1693 static bool even =
false;
1694 const QString tdtd(
"</b></td><td>");
1695 const QString tdtr(
"</td></tr>\n");
1697 QString res(
"<tr bgcolor=\"");
1700 res +=
"#eeeeff\">";
1702 res +=
"#ffffff\">";
1703 res +=
"<td><b>" + left + tdtd + right + tdtr;
1720 QString text(
"<center><table border=\"1\" cellspacing=\"0\" cellpadding=\"4\">\n");
1721 const QString trtd(
"<tr><td>");
1722 const QString tdtr(
"</td></tr>\n");
1723 const QString tdtd(
"</td><td>");
1725 text += QString(
"<tr bgcolor=\"#aaaacc\"><th align=\"center\">%1</th><th align=\"center\">%2</th></tr>\n").
1726 arg(tr(
"Button(s)",
"Buttons column header in help window mouse tab")).arg(tr(
"Description",
"Description column header in help window mouse tab"));
1728 QMap<ClickBindingPrivate, QString> mouseBinding;
1731 for (QMap<ClickBindingPrivate, QString>::ConstIterator itm=mouseDescription_.begin(), endm=mouseDescription_.end(); itm!=endm; ++itm)
1732 mouseBinding[itm.key()] = itm.value();
1734 for (QMap<ClickBindingPrivate, QString>::ConstIterator it=mouseBinding.begin(), end=mouseBinding.end(); it != end; ++it)
1737 if (it.value().isNull())
1740 text += tableLine(formatClickActionPrivate(it.key()), it.value());
1744 if (!mouseBinding.isEmpty())
1746 mouseBinding.clear();
1747 text += QString(
"<tr bgcolor=\"#aaaacc\"><td colspan=2>%1</td></tr>\n").arg(tr(
"Standard mouse bindings",
"In help window mouse tab"));
1753 for (QMap<MouseBindingPrivate, MouseActionPrivate>::ConstIterator itmb=mouseBinding_.begin(), endmb=mouseBinding_.end();
1754 itmb != endmb; ++itmb)
1756 ClickBindingPrivate cbp(itmb.key().modifiers, itmb.key().button,
false, Qt::NoButton, itmb.key().key);
1758 QString text = mouseActionString(itmb.value().action);
1762 switch (itmb.value().handler)
1764 case CAMERA: text +=
" " + tr(
"camera",
"Suffix after action");
break;
1765 case FRAME: text +=
" " + tr(
"manipulated frame",
"Suffix after action");
break;
1767 if (!(itmb.value().withConstraint))
1770 mouseBinding[cbp] = text;
1773 for (QMap<WheelBindingPrivate, MouseActionPrivate>::ConstIterator itw=wheelBinding_.begin(), endw=wheelBinding_.end(); itw != endw; ++itw)
1775 ClickBindingPrivate cbp(itw.key().modifiers, Qt::NoButton,
false, Qt::NoButton, itw.key().key);
1777 QString text = mouseActionString(itw.value().action);
1781 switch (itw.value().handler)
1783 case CAMERA: text +=
" " + tr(
"camera",
"Suffix after action");
break;
1784 case FRAME: text +=
" " + tr(
"manipulated frame",
"Suffix after action");
break;
1786 if (!(itw.value().withConstraint))
1790 mouseBinding[cbp] = text;
1793 for (QMap<ClickBindingPrivate, ClickAction>::ConstIterator itcb=clickBinding_.begin(), endcb=clickBinding_.end(); itcb!=endcb; ++itcb)
1794 mouseBinding[itcb.key()] = clickActionString(itcb.value());
1796 for (QMap<ClickBindingPrivate, QString>::ConstIterator it2=mouseBinding.begin(), end2=mouseBinding.end(); it2 != end2; ++it2)
1798 if (it2.value().isNull())
1801 text += tableLine(formatClickActionPrivate(it2.key()), it2.value());
1804 text +=
"</table></center>";
1825 if (description.isEmpty())
1826 keyDescription_.remove(key);
1828 keyDescription_[key] = description;
1831 QString QGLViewer::cameraPathKeysString()
const
1833 if (pathIndex_.isEmpty())
1834 return QString::null;
1837 keys.reserve(pathIndex_.count());
1838 for (QMap<Qt::Key, int>::ConstIterator i = pathIndex_.begin(), endi=pathIndex_.end(); i != endi; ++i)
1839 keys.push_back(i.key());
1842 QVector<int>::const_iterator it = keys.begin(), end = keys.end();
1843 QString res = keyString(*it);
1845 const int maxDisplayedKeys = 6;
1846 int nbDisplayedKeys = 0;
1847 int previousKey = (*it);
1850 while ((it != end) && (nbDisplayedKeys < maxDisplayedKeys-1))
1855 if ((*it) == previousKey + 1)
1859 res +=
", " + keyString(*it);
1864 if ((*it) == previousKey + 1)
1868 res +=
", " + keyString(previousKey);
1869 res +=
", " + keyString(*it);
1870 nbDisplayedKeys += 2;
1875 if ((*it) != previousKey + 1)
1877 res +=
".." + keyString(previousKey);
1878 res +=
", " + keyString(*it);
1879 nbDisplayedKeys += 2;
1889 res +=
", " + keyString(previousKey);
1891 res +=
".." + keyString(previousKey);
1908 QString text(
"<center><table border=\"1\" cellspacing=\"0\" cellpadding=\"4\">\n");
1909 text += QString(
"<tr bgcolor=\"#aaaacc\"><th align=\"center\">%1</th><th align=\"center\">%2</th></tr>\n").
1910 arg(QGLViewer::tr(
"Key(s)",
"Keys column header in help window mouse tab")).arg(QGLViewer::tr(
"Description",
"Description column header in help window mouse tab"));
1912 QMap<int, QString> keyDescription;
1915 for (QMap<int, QString>::ConstIterator kd=keyDescription_.begin(), kdend=keyDescription_.end(); kd!=kdend; ++kd)
1916 keyDescription[kd.key()] = kd.value();
1919 for (QMap<int, QString>::ConstIterator kb=keyDescription.begin(), endb=keyDescription.end(); kb!=endb; ++kb)
1920 text += tableLine(keyString(kb.key()), kb.value());
1924 if (!keyDescription.isEmpty())
1926 keyDescription.clear();
1927 text += QString(
"<tr bgcolor=\"#aaaacc\"><td colspan=2>%1</td></tr>\n").arg(QGLViewer::tr(
"Standard viewer keys",
"In help window keys tab"));
1932 for (QMap<KeyboardAction, unsigned int>::ConstIterator it=keyboardBinding_.begin(), end=keyboardBinding_.end(); it != end; ++it)
1933 if ((it.value() != 0) && ((!cameraIsInRotateMode()) || ((it.key() != INCREASE_FLYSPEED) && (it.key() != DECREASE_FLYSPEED))))
1934 keyDescription[it.value()] = keyboardActionDescription_[it.key()];
1937 for (QMap<int, QString>::ConstIterator kb2=keyDescription.begin(), endb2=keyDescription.end(); kb2!=endb2; ++kb2)
1938 text += tableLine(keyString(kb2.key()), kb2.value());
1942 const QString cpks = cameraPathKeysString();
1945 text +=
"<tr bgcolor=\"#ccccff\"><td colspan=2>\n";
1946 text += QGLViewer::tr(
"Camera paths are controlled using the %1 keys (noted <i>Fx</i> below):",
"Help window key tab camera keys").arg(cpks) +
"</td></tr>\n";
1947 text += tableLine(keyString(
playPathKeyboardModifiers()) +
"<i>" + QGLViewer::tr(
"Fx",
"Generic function key (F1..F12)") +
"</i>",
1948 QGLViewer::tr(
"Plays path (or resets saved position)"));
1950 QGLViewer::tr(
"Adds a key frame to path (or defines a position)"));
1951 text += tableLine(keyString(
addKeyFrameKeyboardModifiers()) +
"<i>" + QGLViewer::tr(
"Fx",
"Generic function key (F1..F12)") +
"</i>+<i>" + QGLViewer::tr(
"Fx",
"Generic function key (F1..F12)") +
"</i>",
1952 QGLViewer::tr(
"Deletes path (or saved position)"));
1954 text +=
"</table></center>";
1979 bool resize =
false;
1983 static QString label[] = {tr(
"&Help",
"Help window tab title"), tr(
"&Keyboard",
"Help window tab title"), tr(
"&Mouse",
"Help window tab title"), tr(
"&About",
"Help window about title")};
1988 helpWidget_ =
new QTabWidget(NULL);
1989 helpWidget()->setWindowTitle(tr(
"Help",
"Help window title"));
1992 for (
int i=0; i<4; ++i)
1994 QTextEdit* tab =
new QTextEdit(NULL);
1995 tab->setReadOnly(
true);
1999 # include "qglviewer-icon.xpm"
2000 QPixmap pixmap(qglviewer_icon);
2001 tab->document()->addResource(QTextDocument::ImageResource,
2002 QUrl(
"mydata://qglviewer-icon.xpm"), QVariant(pixmap));
2007 for (
int i=0; i<4; ++i)
2015 case 3 : text = QString(
"<center><br><img src=\"mydata://qglviewer-icon.xpm\">") + tr(
2016 "<h1>libQGLViewer</h1>"
2017 "<h3>Version %1</h3><br>"
2018 "A versatile 3D viewer based on OpenGL and Qt<br>"
2019 "Copyright 2002-%2 Gilles Debunne<br>"
2020 "<code>%3</code>").arg(QGLViewerVersionString()).arg(
"2014").arg(
"http://www.libqglviewer.com") +
2021 QString(
"</center>");
2026 QTextEdit* textEdit = (QTextEdit*)(
helpWidget()->widget(i));
2027 textEdit->setHtml(text);
2028 textEdit->setText(text);
2030 if (resize && (textEdit->height() > height))
2031 height = textEdit->height();
2074 const Qt::Key key = Qt::Key(e->key());
2076 const Qt::KeyboardModifiers modifiers = e->modifiers();
2078 QMap<KeyboardAction, unsigned int>::ConstIterator it=keyboardBinding_.begin(), end=keyboardBinding_.end();
2079 const unsigned int target = key | modifiers;
2080 while ((it != end) && (it.value() != target))
2084 handleKeyboardAction(it.key());
2086 if (pathIndex_.contains(Qt::Key(key)))
2089 int index = pathIndex_[Qt::Key(key)];
2092 static QTime doublePress;
2096 int elapsed = doublePress.restart();
2097 if ((elapsed < 250) && (index==previousPathId_))
2102 if (index != previousPathId_)
2110 previousPathId_ = index;
2114 int elapsed = doublePress.restart();
2115 if ((elapsed < 250) && (index==previousPathId_))
2117 if (
camera()->keyFrameInterpolator(index))
2119 disconnect(
camera()->keyFrameInterpolator(index), SIGNAL(interpolated()),
this, SLOT(update()));
2120 if (
camera()->keyFrameInterpolator(index)->numberOfKeyFrames() > 1)
2121 displayMessage(tr(
"Path %1 deleted",
"Feedback message").arg(index));
2123 displayMessage(tr(
"Position %1 deleted",
"Feedback message").arg(index));
2132 connect(
camera()->keyFrameInterpolator(index), SIGNAL(interpolated()), SLOT(update()));
2135 displayMessage(tr(
"Path %1, position %2 added",
"Feedback message").arg(index).arg(nbKF));
2137 displayMessage(tr(
"Position %1 saved",
"Feedback message").arg(index));
2139 previousPathId_ = index;
2143 if (isValidShortcutKey(key)) currentlyPressedKey_ = key;
2148 void QGLViewer::keyReleaseEvent(QKeyEvent * e) {
2149 if (isValidShortcutKey(e->key())) currentlyPressedKey_ = Qt::Key(0);
2152 void QGLViewer::handleKeyboardAction(KeyboardAction
id)
2160 case EXIT_VIEWER : saveStateToFileForAllViewers(); qApp->closeAllWindows();
break;
2161 case SAVE_SCREENSHOT :
saveSnapshot(
false,
false);
break;
2165 case HELP :
help();
break;
2170 displayMessage(cameraIsInRotateMode()?tr(
"Camera in observer mode",
"Feedback message"):tr(
"Camera in fly mode",
"Feedback message"));
2173 case MOVE_CAMERA_LEFT :
2177 case MOVE_CAMERA_RIGHT :
2181 case MOVE_CAMERA_UP :
2185 case MOVE_CAMERA_DOWN :
2202 glViewport( 0, 0, GLint(width), GLint(height) );
2229 keyboardBinding_[action] = key;
2249 if (keyboardBinding_.contains(action))
2250 return keyboardBinding_[action];
2256 void QGLViewer::setKeyboardAccelerator(KeyboardAction action,
int key)
2258 qWarning(
"setKeyboardAccelerator is deprecated. Use setShortcut instead.");
2262 int QGLViewer::keyboardAccelerator(KeyboardAction action)
const
2264 qWarning(
"keyboardAccelerator is deprecated. Use shortcut instead.");
2288 for (QMap<Qt::Key, int>::ConstIterator it = pathIndex_.begin(), end=pathIndex_.end(); it != end; ++it)
2289 if (it.value() == index)
2308 pathIndex_.remove(Qt::Key(-key));
2310 pathIndex_[Qt::Key(key)] = index;
2316 playPathKeyboardModifiers_ = modifiers;
2322 addKeyFrameKeyboardModifiers_ = modifiers;
2336 return addKeyFrameKeyboardModifiers_;
2349 return playPathKeyboardModifiers_;
2354 Qt::KeyboardModifiers QGLViewer::addKeyFrameStateKey()
const
2356 qWarning(
"addKeyFrameStateKey has been renamed addKeyFrameKeyboardModifiers");
2359 Qt::KeyboardModifiers QGLViewer::playPathStateKey()
const
2361 qWarning(
"playPathStateKey has been renamed playPathKeyboardModifiers");
2365 void QGLViewer::setAddKeyFrameStateKey(
int buttonState)
2367 qWarning(
"setAddKeyFrameStateKey has been renamed setAddKeyFrameKeyboardModifiers");
2371 void QGLViewer::setPlayPathStateKey(
int buttonState)
2373 qWarning(
"setPlayPathStateKey has been renamed setPlayPathKeyboardModifiers");
2377 Qt::Key QGLViewer::keyFrameKey(
int index)
const
2379 qWarning(
"keyFrameKey has been renamed pathKey.");
2383 Qt::KeyboardModifiers QGLViewer::playKeyFramePathStateKey()
const
2385 qWarning(
"playKeyFramePathStateKey has been renamed playPathKeyboardModifiers.");
2389 void QGLViewer::setKeyFrameKey(
int index,
int key)
2391 qWarning(
"setKeyFrameKey is deprecated, use setPathKey instead, with swapped parameters.");
2395 void QGLViewer::setPlayKeyFramePathStateKey(
int buttonState)
2397 qWarning(
"setPlayKeyFramePathStateKey has been renamed setPlayPathKeyboardModifiers.");
2446 qWarning(
"setHandlerKeyboardModifiers is deprecated, call setMouseBinding() instead");
2448 QMap<MouseBindingPrivate, MouseActionPrivate> newMouseBinding;
2449 QMap<WheelBindingPrivate, MouseActionPrivate> newWheelBinding;
2450 QMap<ClickBindingPrivate, ClickAction> newClickBinding_;
2452 QMap<MouseBindingPrivate, MouseActionPrivate>::Iterator mit;
2453 QMap<WheelBindingPrivate, MouseActionPrivate>::Iterator wit;
2456 for (mit = mouseBinding_.begin(); mit != mouseBinding_.end(); ++mit)
2457 if ((mit.value().handler != handler) || (mit.value().action == ZOOM_ON_REGION))
2458 newMouseBinding[mit.key()] = mit.value();
2460 for (wit = wheelBinding_.begin(); wit != wheelBinding_.end(); ++wit)
2461 if (wit.value().handler != handler)
2462 newWheelBinding[wit.key()] = wit.value();
2465 for (mit = mouseBinding_.begin(); mit != mouseBinding_.end(); ++mit)
2466 if ((mit.value().handler == handler) && (mit.value().action != ZOOM_ON_REGION))
2468 MouseBindingPrivate mbp(modifiers, mit.key().button, mit.key().key);
2469 newMouseBinding[mbp] = mit.value();
2472 for (wit = wheelBinding_.begin(); wit != wheelBinding_.end(); ++wit)
2473 if (wit.value().handler == handler)
2475 WheelBindingPrivate wbp(modifiers, wit.key().key);
2476 newWheelBinding[wbp] = wit.value();
2480 for (QMap<ClickBindingPrivate, ClickAction>::ConstIterator cb=clickBinding_.begin(), end=clickBinding_.end(); cb != end; ++cb)
2481 if (((handler==CAMERA) && ((cb.value() == CENTER_SCENE) || (cb.value() == ALIGN_CAMERA))) ||
2482 ((handler==FRAME) && ((cb.value() == CENTER_FRAME) || (cb.value() == ALIGN_FRAME))))
2484 ClickBindingPrivate cbp(modifiers, cb.key().button, cb.key().doubleClick, cb.key().buttonsBefore, cb.key().key);
2485 newClickBinding_[cbp] = cb.value();
2488 newClickBinding_[cb.key()] = cb.value();
2490 mouseBinding_ = newMouseBinding;
2491 wheelBinding_ = newWheelBinding;
2492 clickBinding_ = newClickBinding_;
2495 void QGLViewer::setHandlerStateKey(MouseHandler handler,
int buttonState)
2497 qWarning(
"setHandlerStateKey has been renamed setHandlerKeyboardModifiers");
2501 void QGLViewer::setMouseStateKey(MouseHandler handler,
int buttonState)
2503 qWarning(
"setMouseStateKey has been renamed setHandlerKeyboardModifiers.");
2513 qWarning(
"setMouseBinding(int state, MouseHandler...) is deprecated. Use the modifier/button equivalent");
2515 mouseButtonFromState(state),
2527 setMouseBinding(Qt::Key(0), modifiers, button, handler, action, withConstraint);
2564 if ((handler == FRAME) && ((action == MOVE_FORWARD) || (action == MOVE_BACKWARD) ||
2565 (action == ROLL) || (action == LOOK_AROUND) ||
2566 (action == ZOOM_ON_REGION))) {
2567 qWarning(
"Cannot bind %s to FRAME", mouseActionString(action).toLatin1().constData());
2571 if (button == Qt::NoButton) {
2572 qWarning(
"No mouse button specified in setMouseBinding");
2576 MouseActionPrivate map;
2577 map.handler = handler;
2578 map.action = action;
2579 map.withConstraint = withConstraint;
2581 MouseBindingPrivate mbp(modifiers, button, key);
2582 if (action == NO_MOUSE_ACTION)
2583 mouseBinding_.remove(mbp);
2585 mouseBinding_.insert(mbp, map);
2587 ClickBindingPrivate cbp(modifiers, button,
false, Qt::NoButton, key);
2588 clickBinding_.remove(cbp);
2597 qWarning(
"setMouseBinding(int state, ClickAction...) is deprecated. Use the modifier/button equivalent");
2599 mouseButtonFromState(state),
2612 setMouseBinding(Qt::Key(0), modifiers, button, action, doubleClick, buttonsBefore);
2637 if ((buttonsBefore != Qt::NoButton) && !doubleClick) {
2638 qWarning(
"Buttons before is only meaningful when doubleClick is true in setMouseBinding().");
2642 if (button == Qt::NoButton) {
2643 qWarning(
"No mouse button specified in setMouseBinding");
2647 ClickBindingPrivate cbp(modifiers, button, doubleClick, buttonsBefore, key);
2650 if (action == NO_CLICK_ACTION)
2651 clickBinding_.remove(cbp);
2653 clickBinding_.insert(cbp, action);
2655 if ((!doubleClick) && (buttonsBefore == Qt::NoButton)) {
2656 MouseBindingPrivate mbp(modifiers, button, key);
2657 mouseBinding_.remove(mbp);
2666 setWheelBinding(Qt::Key(0), modifiers, handler, action, withConstraint);
2682 if ((action != ZOOM) && (action != MOVE_FORWARD) && (action != MOVE_BACKWARD) && (action != NO_MOUSE_ACTION)) {
2683 qWarning(
"Cannot bind %s to wheel", mouseActionString(action).toLatin1().constData());
2687 if ((handler == FRAME) && (action != ZOOM) && (action != NO_MOUSE_ACTION)) {
2688 qWarning(
"Cannot bind %s to FRAME wheel", mouseActionString(action).toLatin1().constData());
2692 MouseActionPrivate map;
2693 map.handler = handler;
2694 map.action = action;
2695 map.withConstraint = withConstraint;
2697 WheelBindingPrivate wbp(modifiers, key);
2698 if (action == NO_MOUSE_ACTION)
2699 wheelBinding_.remove(wbp);
2701 wheelBinding_[wbp] = map;
2709 mouseBinding_.clear();
2710 clickBinding_.clear();
2711 wheelBinding_.clear();
2719 keyboardBinding_.clear();
2728 qWarning(
"mouseAction(int state,...) is deprecated. Use the modifier/button equivalent");
2729 return mouseAction(Qt::Key(0), keyboardModifiersFromState(state), mouseButtonFromState(state));
2748 MouseBindingPrivate mbp(modifiers, button, key);
2749 if (mouseBinding_.contains(mbp))
2750 return mouseBinding_[mbp].action;
2752 return NO_MOUSE_ACTION;
2760 qWarning(
"mouseHandler(int state,...) is deprecated. Use the modifier/button equivalent");
2761 return mouseHandler(Qt::Key(0), keyboardModifiersFromState(state), mouseButtonFromState(state));
2778 MouseBindingPrivate mbp(modifiers, button, key);
2779 if (mouseBinding_.contains(mbp))
2780 return mouseBinding_[mbp].handler;
2792 qWarning(
"mouseButtonState() is deprecated. Use mouseButtons() and keyboardModifiers() instead");
2793 for (QMap<MouseBindingPrivate, MouseActionPrivate>::ConstIterator it=mouseBinding_.begin(), end=mouseBinding_.end(); it != end; ++it)
2794 if ( (it.value().handler == handler) && (it.value().action == action) && (it.value().withConstraint == withConstraint) )
2795 return (
int) it.key().modifiers | (int) it.key().button;
2797 return Qt::NoButton;
2809 Qt::Key& key, Qt::KeyboardModifiers& modifiers)
const
2811 for (QMap<WheelBindingPrivate, MouseActionPrivate>::ConstIterator it=wheelBinding_.begin(), end=wheelBinding_.end(); it != end; ++it)
2812 if ( (it.value().handler == handler) && (it.value().action == action) && (it.value().withConstraint == withConstraint) ) {
2814 modifiers = it.key().modifiers;
2819 modifiers = Qt::NoModifier;
2830 Qt::Key& key, Qt::KeyboardModifiers& modifiers, Qt::MouseButton& button)
const
2832 for (QMap<MouseBindingPrivate, MouseActionPrivate>::ConstIterator it=mouseBinding_.begin(), end=mouseBinding_.end(); it != end; ++it)
2833 if ( (it.value().handler == handler) && (it.value().action == action) && (it.value().withConstraint == withConstraint) ) {
2835 modifiers = it.key().modifiers;
2836 button = it.key().button;
2841 modifiers = Qt::NoModifier;
2842 button = Qt::NoButton;
2853 WheelBindingPrivate wbp(modifiers, key);
2854 if (wheelBinding_.contains(wbp))
2855 return wheelBinding_[wbp].action;
2857 return NO_MOUSE_ACTION;
2866 WheelBindingPrivate wbp(modifiers, key);
2867 if (wheelBinding_.contains(wbp))
2868 return wheelBinding_[wbp].handler;
2877 bool doubleClick, Qt::MouseButtons buttonsBefore)
const {
2878 ClickBindingPrivate cbp(modifiers, button, doubleClick, buttonsBefore, key);
2879 if (clickBinding_.contains(cbp))
2880 return clickBinding_[cbp];
2882 return NO_CLICK_ACTION;
2890 qWarning(
"wheelAction() is deprecated. Use the new wheelAction() method with a key parameter instead");
2898 qWarning(
"wheelHandler() is deprecated. Use the new wheelHandler() method with a key parameter instead");
2907 qWarning(
"wheelButtonState() is deprecated. Use the wheelAction() and wheelHandler() instead");
2908 for (QMap<WheelBindingPrivate, MouseActionPrivate>::ConstIterator it=wheelBinding_.begin(), end=wheelBinding_.end(); it!=end; ++it)
2909 if ( (it.value().handler == handler) && (it.value().action == action) && (it.value().withConstraint == withConstraint) )
2910 return it.key().key + it.key().modifiers;
2920 qWarning(
"clickAction(int state,...) is deprecated. Use the modifier/button equivalent");
2922 keyboardModifiersFromState(state),
2923 mouseButtonFromState(state),
2933 qWarning(
"getClickButtonState(int state,...) is deprecated. Use the modifier/button equivalent");
2934 Qt::KeyboardModifiers modifiers;
2935 Qt::MouseButton button;
2938 state = (int) modifiers | (
int) button | (int) key;
2951 for (QMap<ClickBindingPrivate, ClickAction>::ConstIterator it=clickBinding_.begin(), end=clickBinding_.end(); it != end; ++it)
2952 if (it.value() == action) {
2953 modifiers = it.key().modifiers;
2954 button = it.key().button;
2955 doubleClick = it.key().doubleClick;
2956 buttonsBefore = it.key().buttonsBefore;
2961 modifiers = Qt::NoModifier;
2962 button = Qt::NoButton;
2963 doubleClick =
false;
2964 buttonsBefore = Qt::NoButton;
2971 bool QGLViewer::cameraIsInRotateMode()
const
2975 Qt::KeyboardModifiers modifiers;
2976 Qt::MouseButton button;
2978 return button != Qt::NoButton;
2996 Qt::KeyboardModifiers modifiers;
2997 Qt::MouseButton button;
2999 bool rotateMode = button != Qt::NoButton;
3017 setMouseBinding(Qt::NoModifier, Qt::LeftButton, NO_CLICK_ACTION,
true);
3018 setMouseBinding(Qt::NoModifier, Qt::MidButton, NO_CLICK_ACTION,
true);
3019 setMouseBinding(Qt::NoModifier, Qt::RightButton, NO_CLICK_ACTION,
true);
3030 setMouseBinding(Qt::Key_R, modifiers, Qt::LeftButton, CAMERA, SCREEN_ROTATE);
3033 setMouseBinding(Qt::NoModifier, Qt::MidButton, SHOW_ENTIRE_SCENE,
true);
3063 disconnect(
manipulatedFrame(), SIGNAL(manipulated()),
this, SLOT(update()));
3068 manipulatedFrame_ = frame;
3106 if (visualHint_ & 1)
3108 const float size = 15.0;
3111 glDisable(GL_LIGHTING);
3112 glDisable(GL_DEPTH_TEST);
3115 glVertex2f(proj.x - size, proj.y);
3116 glVertex2f(proj.x + size, proj.y);
3117 glVertex2f(proj.x, proj.y - size);
3118 glVertex2f(proj.x, proj.y + size);
3120 glEnable(GL_DEPTH_TEST);
3130 if (
camera()->frame()->action_ == SCREEN_ROTATE)
3147 glDisable(GL_LIGHTING);
3148 glDisable(GL_DEPTH_TEST);
3151 glVertex2f(pnt.x, pnt.y);
3152 glVertex2f(mf->prevPos_.x(), mf->prevPos_.y());
3154 glEnable(GL_DEPTH_TEST);
3159 if (
camera()->frame()->action_ == ZOOM_ON_REGION)
3162 glDisable(GL_LIGHTING);
3163 glDisable(GL_DEPTH_TEST);
3165 glBegin(GL_LINE_LOOP);
3171 glEnable(GL_DEPTH_TEST);
3181 visualHint_ = visualHint_ | mask;
3207 static GLUquadric* quadric = gluNewQuadric();
3210 radius = 0.05 * length;
3212 const float head = 2.5*(radius / length) + 0.1;
3213 const float coneRadiusCoef = 4.0 - 5.0 * head;
3215 gluCylinder(quadric, radius, radius, length * (1.0 - head/coneRadiusCoef), nbSubdivisions, 1);
3216 glTranslatef(0.0, 0.0, length * (1.0 - head));
3217 gluCylinder(quadric, coneRadiusCoef * radius, 0.0, head * length, nbSubdivisions, 1);
3218 glTranslatef(0.0, 0.0, -length * (1.0 - head));
3228 glTranslatef(from[0],from[1],from[2]);
3229 const Vec dir = to-from;
3255 const float charWidth = length / 40.0;
3256 const float charHeight = length / 30.0;
3257 const float charShift = 1.04 * length;
3259 GLboolean lighting, colorMaterial;
3260 glGetBooleanv(GL_LIGHTING, &lighting);
3261 glGetBooleanv(GL_COLOR_MATERIAL, &colorMaterial);
3263 glDisable(GL_LIGHTING);
3267 glVertex3f(charShift, charWidth, -charHeight);
3268 glVertex3f(charShift, -charWidth, charHeight);
3269 glVertex3f(charShift, -charWidth, -charHeight);
3270 glVertex3f(charShift, charWidth, charHeight);
3272 glVertex3f( charWidth, charShift, charHeight);
3273 glVertex3f(0.0, charShift, 0.0);
3274 glVertex3f(-charWidth, charShift, charHeight);
3275 glVertex3f(0.0, charShift, 0.0);
3276 glVertex3f(0.0, charShift, 0.0);
3277 glVertex3f(0.0, charShift, -charHeight);
3279 glVertex3f(-charWidth, charHeight, charShift);
3280 glVertex3f( charWidth, charHeight, charShift);
3281 glVertex3f( charWidth, charHeight, charShift);
3282 glVertex3f(-charWidth, -charHeight, charShift);
3283 glVertex3f(-charWidth, -charHeight, charShift);
3284 glVertex3f( charWidth, -charHeight, charShift);
3287 glEnable(GL_LIGHTING);
3288 glDisable(GL_COLOR_MATERIAL);
3291 color[0] = 0.7f; color[1] = 0.7f; color[2] = 1.0f; color[3] = 1.0f;
3292 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
3295 color[0] = 1.0f; color[1] = 0.7f; color[2] = 0.7f; color[3] = 1.0f;
3296 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
3298 glRotatef(90.0, 0.0, 1.0, 0.0);
3302 color[0] = 0.7f; color[1] = 1.0f; color[2] = 0.7f; color[3] = 1.0f;
3303 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
3305 glRotatef(-90.0, 1.0, 0.0, 0.0);
3310 glEnable(GL_COLOR_MATERIAL);
3312 glDisable(GL_LIGHTING);
3324 glGetBooleanv(GL_LIGHTING, &lighting);
3326 glDisable(GL_LIGHTING);
3329 for (
int i=0; i<=nbSubdivisions; ++i)
3331 const float pos = size*(2.0*i/nbSubdivisions-1.0);
3332 glVertex2f(pos, -size);
3333 glVertex2f(pos, +size);
3334 glVertex2f(-size, pos);
3335 glVertex2f( size, pos);
3340 glEnable(GL_LIGHTING);
3348 void QGLViewer::saveStateToFileForAllViewers()
3376 QString name = stateFileName_;
3381 if (fi.suffix().isEmpty())
3384 name = fi.absolutePath() +
'/' + fi.completeBaseName() + QString::number(
QGLViewer::QGLViewerIndex(
this)) +
"." + fi.suffix();
3404 QFileInfo fileInfo(name);
3406 if (fileInfo.isDir())
3408 QMessageBox::warning(
this, tr(
"Save to file error",
"Message box window title"), tr(
"State file name (%1) references a directory instead of a file.").arg(name));
3412 const QString dirName = fileInfo.absolutePath();
3413 if (!QFileInfo(dirName).exists())
3416 if (!(dir.mkdir(dirName)))
3418 QMessageBox::warning(
this, tr(
"Save to file error",
"Message box window title"), tr(
"Unable to create directory %1").arg(dirName));
3425 if (f.open(QIODevice::WriteOnly))
3427 QTextStream out(&f);
3428 QDomDocument doc(
"QGLVIEWER");
3429 doc.appendChild(
domElement(
"QGLViewer", doc));
3435 QMessageBox::warning(
this, tr(
"Save to file error",
"Message box window title"), tr(
"Unable to save to file %1").arg(name) +
":\n" + f.errorString());
3465 QFileInfo fileInfo(name);
3467 if (!fileInfo.isFile())
3471 if (!fileInfo.isReadable())
3473 QMessageBox::warning(
this, tr(
"Problem in state restoration",
"Message box window title"), tr(
"File %1 is not readable.").arg(name));
3479 if (f.open(QIODevice::ReadOnly))
3484 QDomElement main = doc.documentElement();
3489 QMessageBox::warning(
this, tr(
"Open file error",
"Message box window title"), tr(
"Unable to open file %1").arg(name) +
":\n" + f.errorString());
3530 QDomElement de = document.createElement(name);
3531 de.setAttribute(
"version", QGLViewerVersionString());
3533 QDomElement stateNode = document.createElement(
"State");
3535 stateNode.appendChild(DomUtils::QColorDomElement(
foregroundColor(),
"foregroundColor", document));
3536 stateNode.appendChild(DomUtils::QColorDomElement(
backgroundColor(),
"backgroundColor", document));
3539 de.appendChild(stateNode);
3541 QDomElement displayNode = document.createElement(
"Display");
3542 DomUtils::setBoolAttribute(displayNode,
"axisIsDrawn",
axisIsDrawn());
3543 DomUtils::setBoolAttribute(displayNode,
"gridIsDrawn",
gridIsDrawn());
3544 DomUtils::setBoolAttribute(displayNode,
"FPSIsDisplayed",
FPSIsDisplayed());
3545 DomUtils::setBoolAttribute(displayNode,
"cameraIsEdited",
cameraIsEdited());
3547 de.appendChild(displayNode);
3549 QDomElement geometryNode = document.createElement(
"Geometry");
3550 DomUtils::setBoolAttribute(geometryNode,
"fullScreen",
isFullScreen());
3553 geometryNode.setAttribute(
"prevPosX", QString::number(prevPos_.x()));
3554 geometryNode.setAttribute(
"prevPosY", QString::number(prevPos_.y()));
3558 QWidget* tlw = topLevelWidget();
3559 geometryNode.setAttribute(
"width", QString::number(tlw->width()));
3560 geometryNode.setAttribute(
"height", QString::number(tlw->height()));
3561 geometryNode.setAttribute(
"posX", QString::number(tlw->pos().x()));
3562 geometryNode.setAttribute(
"posY", QString::number(tlw->pos().y()));
3564 de.appendChild(geometryNode);
3616 const QString version = element.attribute(
"version");
3618 if (version[0] !=
'2')
3620 qWarning(
"State file created using QGLViewer version %s may not be correctly read.", version.toLatin1().constData());
3622 QDomElement child=element.firstChild().toElement();
3624 while (!child.isNull())
3626 if (child.tagName() ==
"State")
3634 QDomElement ch=child.firstChild().toElement();
3635 while (!ch.isNull())
3637 if (ch.tagName() ==
"foregroundColor")
3639 if (ch.tagName() ==
"backgroundColor")
3641 ch = ch.nextSibling().toElement();
3645 if (child.tagName() ==
"Display")
3648 setAxisIsDrawn(DomUtils::boolFromDom(child,
"axisIsDrawn",
false));
3649 setGridIsDrawn(DomUtils::boolFromDom(child,
"gridIsDrawn",
false));
3652 tmpCameraIsEdited = DomUtils::boolFromDom(child,
"cameraIsEdited",
false);
3656 if (child.tagName() ==
"Geometry")
3658 setFullScreen(DomUtils::boolFromDom(child,
"fullScreen",
false));
3662 prevPos_.setX(DomUtils::intFromDom(child,
"prevPosX", 0));
3663 prevPos_.setY(DomUtils::intFromDom(child,
"prevPosY", 0));
3667 int width = DomUtils::intFromDom(child,
"width", 600);
3668 int height = DomUtils::intFromDom(child,
"height", 400);
3669 topLevelWidget()->resize(width, height);
3673 pos.setX(DomUtils::intFromDom(child,
"posX", 0));
3674 pos.setY(DomUtils::intFromDom(child,
"posY", 0));
3675 topLevelWidget()->move(pos);
3679 if (child.tagName() ==
"Camera")
3681 connectAllCameraKFIInterpolatedSignals(
false);
3683 connectAllCameraKFIInterpolatedSignals();
3689 child = child.nextSibling().toElement();
3696 cameraIsEdited_ = tmpCameraIsEdited;
3697 if (cameraIsEdited_)
3710 if (!fileName.isEmpty())
3713 qWarning(
"saveToFile() is deprecated, use saveStateToFile() instead.");
3721 if (!fileName.isEmpty())
3724 qWarning(
"restoreFromFile() is deprecated, use restoreStateFromFile() instead.");
3789 while (h < height())
3794 if ((w != bufferTextureWidth_) || (h != bufferTextureHeight_))
3796 bufferTextureWidth_ = w;
3797 bufferTextureHeight_ = h;
3798 bufferTextureMaxU_ = width() / float(bufferTextureWidth_);
3799 bufferTextureMaxV_ = height() / float(bufferTextureHeight_);
3805 glGenTextures(1, &bufferTextureId_);
3806 glBindTexture(GL_TEXTURE_2D, bufferTextureId_);
3807 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3808 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3812 glBindTexture(GL_TEXTURE_2D, bufferTextureId_);
3814 if ((format != previousBufferTextureFormat_) ||
3815 (internalFormat != previousBufferTextureInternalFormat_))
3817 previousBufferTextureFormat_ = format;
3818 previousBufferTextureInternalFormat_ = internalFormat;
3824 if (format == GL_NONE)
3825 format = internalFormat;
3827 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, bufferTextureWidth_, bufferTextureHeight_, 0, format, GL_UNSIGNED_BYTE, NULL);
3830 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width(), height());
3841 if (glIsTexture(bufferTextureId_))
3842 return bufferTextureId_;