Developer Documentation

QtBaseViewer_qt.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42
43
44
45
46 //=============================================================================
47 //
48 // CLASS QtBaseViewer - IMPLEMENTATION
49 //
50 //=============================================================================
51
52
53 //== INCLUDES =================================================================
54
55 #include "QtBaseViewer.hh"
56 #include "QtGLGraphicsScene.hh"
57 #include "QtGLGraphicsView.hh"
58 //#include "QtSceneGraphWidget.hh"
59 #include "QtWheel.hh"
60
61 #include <QMimeData>
62 #include <QToolButton>
63
64 #include <QClipboard>
65 #include <QApplication>
66 #include <QPushButton>
67 #include <QStatusBar>
68 #include <QColorDialog>
69 #include <QFileDialog>
70 #include <QTimer>
71
72 #include <QGLFormat>
73 #include <QGLWidget>
74
75 #include <QDesktopWidget>
76 #include <QButtonGroup>
77
78 #include <QGraphicsWidget>
79 #include <QGraphicsGridLayout>
80 #include <QGraphicsProxyWidget>
81
82 #include "move.xpm"
83 #include "light.xpm"
84 #include "info.xpm"
85 #include "home.xpm"
86 #include "set_home.xpm"
87 #include "viewall.xpm"
88 #include "pick.xpm"
89 #include "persp.xpm"
90 #include "ortho.xpm"
91 #include "scenegraph.xpm"
92 #include "mono.xpm"
93
94
95 #define homeIcon home_xpm
96 #define sethomeIcon set_home_xpm
97 #define moveIcon move_xpm
98 #define lightIcon light_xpm
99 #define questionIcon info_xpm
100 #define viewallIcon viewall_xpm
101 #define pickIcon pick_xpm
102 #define perspectiveIcon persp_xpm
103 #define orthoIcon ortho_xpm
104 #define sceneGraphIcon scenegraph_xpm
105 #define monoIcon mono_xpm
106
107
108 #ifdef max
109 # undef max
110 #endif
111
112 #ifdef min
113 # undef min
114 #endif
115
116
117 //== NAMESPACES ===============================================================
118
119 namespace ACG {
120 namespace QtWidgets {
121
122
123 //== IMPLEMENTATION ==========================================================
124
125 static const char VIEW_MAGIC[] =
126 "ACG::QtWidgets::QGLViewerWidget encoded view";
127
128 //== IMPLEMENTATION ==========================================================
129
130
131 void QtBaseViewer::makeCurrent() {
132 glWidget_->makeCurrent();
133 }
134
135 void QtBaseViewer::swapBuffers() {
136 glWidget_->swapBuffers();
137 }
138
139
140
141 void
142 QtBaseViewer::copyToImage( QImage& _image,
143 unsigned int /* _l */ , unsigned int /* _t */ ,
144 unsigned int /* _w */ , unsigned int /* _h */ ,
145 GLenum /* _buffer */ )
146 {
147 makeCurrent();
148 _image = glWidget_->grabFrameBuffer(true);
149 }
150
151
152 void
153 QtBaseViewer::createWidgets(const QGLFormat* _format,
154 QStatusBar* _sb,
155 const QtBaseViewer* _share)
156 {
157 statusbar_=privateStatusBar_=0;
158 setStatusBar(_sb);
159 drawMenu_=0;
160 funcMenu_=0;
161 pickMenu_=0;
162
163
164 // contains splitter and eventually status bar
165 // QT3: Q3VBoxLayout* layout=new Q3VBoxLayout(this,0,0,"toplevel layout");
166 QVBoxLayout* layout=new QVBoxLayout(this);
167 layout->setSpacing( 0 );
168 layout->setMargin( 0 );
169
170 // contains glarea and buttons
171
172 // QT3: Q3Frame* work=new Q3Frame(this,"box-glarea-buttons");
173 QFrame* work=new QFrame(this);
174
175 layout->addWidget(work,1); // gets all stretch
176
177
178 // private status bar
179 assert(statusbar_!=0);
180 if (privateStatusBar_!=0)
181 layout->addWidget(privateStatusBar_,0); // no stretch
182
183
184 // Construct GL context & widget
185 QGLWidget* share = 0;
186 if (_share) share = _share->glWidget_;
187
188 QGLFormat format;
189 format.setAlpha(true);
190 if (_format!=0) format = *_format;
191
192 glWidget_ = new QGLWidget(format, 0, share);
193 glView_ = new QtGLGraphicsView(this, work);
194 glScene_ = new QtGLGraphicsScene (this);
195
196 glView_->setViewport(glWidget_);
197 glView_->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
198 glView_->setScene(glScene_);
199 glView_->setFrameStyle(QFrame::NoFrame);
200
201 wheelZ_=new QtWheel( 0,"wheel-z",QtWheel::Vertical);
202 wheelZ_->setMinimumSize(wheelZ_->sizeHint());
203 wheelZ_->setMaximumSize(wheelZ_->sizeHint());
204 connect(wheelZ_,SIGNAL(angleChangedBy(double)),
205 this,SLOT(slotWheelZ(double)));
206 wheelZ_->setToolTip( "Translate along <b>z-axis</b>.");
207 wheelZ_->setWhatsThis( "Translate along <b>z-axis</b>.");
208 if ((options_&ShowWheelZ)==0)
209 wheelZ_->hide();
210
211 wheelY_=new QtWheel( 0,"wheel-y",QtWheel::Horizontal);
212 wheelY_->setMinimumSize(wheelY_->sizeHint());
213 wheelY_->setMaximumSize(wheelY_->sizeHint());
214 connect(wheelY_,SIGNAL(angleChangedBy(double)),
215 this,SLOT(slotWheelY(double)));
216 wheelY_->setToolTip("Rotate around <b>y-axis</b>.");
217 wheelY_->setWhatsThis( "Rotate around <b>y-axis</b>.");
218 if ((options_&ShowWheelY)==0)
219 wheelY_->hide();
220
221 wheelX_=new QtWheel( 0,"wheel-x",QtWheel::Vertical);
222 wheelX_->setMinimumSize(wheelX_->sizeHint());
223 wheelX_->setMaximumSize(wheelX_->sizeHint());
224 connect(wheelX_,SIGNAL(angleChangedBy(double)),
225 this,SLOT(slotWheelX(double)));
226 wheelX_->setToolTip("Rotate around <b>x-axis</b>.");
227 wheelX_->setWhatsThis( "Rotate around <b>x-axis</b>.");
228 if ((options_&ShowWheelX)==0)
229 wheelX_->hide();
230
231
232 QGraphicsWidget *wheelX = glScene_->addWidget (wheelX_);
233 QGraphicsWidget *wheelY = glScene_->addWidget (wheelY_);
234 QGraphicsWidget *wheelZ = glScene_->addWidget (wheelZ_);
235
236 wheelX_->setWindowOpacity (0.5);
237 wheelY_->setWindowOpacity (0.5);
238 wheelZ_->setWindowOpacity (0.5);
239
240 wheelX->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
241 wheelY->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
242 wheelZ->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
243
244 glBaseLayout_ = new QGraphicsGridLayout;
245 glBaseLayout_->addItem(wheelX, 1, 0);
246 glBaseLayout_->addItem(wheelY, 2, 1);
247 glBaseLayout_->addItem(wheelZ, 1, 3);
248
249 glBaseLayout_->setColumnStretchFactor(0,0);
250 glBaseLayout_->setColumnStretchFactor(1,0);
251 glBaseLayout_->setColumnStretchFactor(2,1);
252 glBaseLayout_->setColumnStretchFactor(3,0);
253
254 glBaseLayout_->setRowStretchFactor(0,1);
255 glBaseLayout_->setRowStretchFactor(1,0);
256 glBaseLayout_->setRowStretchFactor(2,0);
257
258 glBase_ = new QGraphicsWidget;
259 glBase_->setLayout(glBaseLayout_);
260 glScene_->addItem(glBase_);
261 glBase_->setGeometry (glScene_->sceneRect ());
262 //QRectF r = glScene_->sceneRect ();
263
264 connect ( glScene_, SIGNAL( sceneRectChanged( const QRectF & ) ),
265 this, SLOT( sceneRectChanged( const QRectF & ) ) );
266
267 // If popupEnabled_ this signal will not be emitted!
268 // If popupEnabled_ is set to false the Contextmenu Mode will be set to customContextMenuRequested
269 // and this signal will be emitted on right click
270 connect( glView_ , SIGNAL( customContextMenuRequested( const QPoint& ) ) ,
271 this , SIGNAL( signalCustomContextMenuRequested( const QPoint& ) ) );
272
273 // is stereo possible ?
274 if (format.stereo())
275 std::cerr << "Stereo buffer requested: "
276 << (glWidget_->format().stereo() ? "ok\n" : "failed\n");
277
278
279 // toolbar
280 buttonBar_= new QToolBar( "Viewer Toolbar", work );
281 buttonBar_->setOrientation(Qt::Vertical);
282
283 moveButton_ = new QToolButton( buttonBar_ );
284 moveButton_->setIcon( QPixmap(moveIcon) );
285 moveButton_->setMinimumSize( 16, 16 );
286 moveButton_->setMaximumSize( 32, 32 );
287 moveButton_->setToolTip( "Switch to <b>move</b> mode." );
288 moveButton_->setWhatsThis(
289 "Switch to <b>move</b> mode.<br>"
290 "<ul><li><b>Rotate</b> using <b>left</b> mouse button.</li>"
291 "<li><b>Translate</b> using <b>middle</b> mouse button.</li>"
292 "<li><b>Zoom</b> using <b>left+middle</b> mouse buttons.</li></ul>" );
293 QObject::connect( moveButton_, SIGNAL( clicked() ),
294 this, SLOT( examineMode() ) );
295
296 buttonBar_->addWidget( moveButton_)->setText("Move");
297
298 lightButton_ = new QToolButton( buttonBar_ );
299 lightButton_->setIcon( QPixmap(lightIcon) );
300 lightButton_->setMinimumSize( 16, 16 );
301 lightButton_->setMaximumSize( 32, 32 );
302 lightButton_->setToolTip("Switch to <b>light</b> mode.");
303 lightButton_->setWhatsThis(
304 "Switch to <b>light</b> mode.<br>"
305 "Rotate lights using left mouse button.");
306 QObject::connect( lightButton_, SIGNAL( clicked() ),
307 this, SLOT( lightMode() ) );
308 buttonBar_->addWidget( lightButton_)->setText("Light");
309
310
311 pickButton_ = new QToolButton( buttonBar_ );
312 pickButton_->setIcon( QPixmap(pickIcon) );
313 pickButton_->setMinimumSize( 16, 16 );
314 pickButton_->setMaximumSize( 32, 32 );
315 pickButton_->setToolTip("Switch to <b>picking</b> mode.");
316 pickButton_->setWhatsThis(
317 "Switch to <b>picking</b> mode.<br>"
318 "Use picking functions like flipping edges.<br>"
319 "To change the mode use the right click<br>"
320 "context menu in the viewer.");
321 QObject::connect( pickButton_, SIGNAL( clicked() ),
322 this, SLOT( pickingMode() ) );
323 buttonBar_->addWidget( pickButton_)->setText("Pick");
324
325
326 questionButton_ = new QToolButton( buttonBar_ );
327 questionButton_->setIcon( QPixmap(questionIcon) );
328 questionButton_->setMinimumSize( 16, 16 );
329 questionButton_->setMaximumSize( 32, 32 );
330 questionButton_->setToolTip("Switch to <b>identification</b> mode.");
331 questionButton_->setWhatsThis(
332 "Switch to <b>identification</b> mode.<br>"
333 "Use identification mode to get information "
334 "about objects. Click on an object and see "
335 "the log output for information about the "
336 "object.");
337 QObject::connect( questionButton_, SIGNAL( clicked() ),
338 this, SLOT( questionMode() ) );
339 buttonBar_->addWidget( questionButton_)->setText("Question");
340
341 buttonBar_->addSeparator();
342
343 homeButton_ = new QToolButton( buttonBar_ );
344 homeButton_->setIcon( QPixmap(homeIcon) );
345 homeButton_->setMinimumSize( 16, 16 );
346 homeButton_->setMaximumSize( 32, 32 );
347 homeButton_->setCheckable( false );
348 homeButton_->setToolTip("Restore <b>home</b> view.");
349 homeButton_->setWhatsThis(
350 "Restore home view<br><br>"
351 "Resets the view to the home view");
352 QObject::connect( homeButton_, SIGNAL( clicked() ),
353 this, SLOT( home() ) );
354 buttonBar_->addWidget( homeButton_)->setText("Home");
355
356
357 setHomeButton_ = new QToolButton( buttonBar_ );
358 setHomeButton_->setIcon( QPixmap(sethomeIcon) );
359 setHomeButton_->setMinimumSize( 16, 16 );
360 setHomeButton_->setMaximumSize( 32, 32 );
361 setHomeButton_->setCheckable( false );
362 setHomeButton_->setToolTip("Set <b>home</b> view");
363 setHomeButton_->setWhatsThis(
364 "Store home view<br><br>"
365 "Stores the current view as the home view");
366 QObject::connect( setHomeButton_, SIGNAL( clicked() ),
367 this, SLOT( setHome() ) );
368 buttonBar_->addWidget( setHomeButton_)->setText("Set Home");
369
370
371 viewAllButton_ = new QToolButton( buttonBar_ );
372 viewAllButton_->setIcon( QPixmap(viewallIcon) );
373 viewAllButton_->setMinimumSize( 16, 16 );
374 viewAllButton_->setMaximumSize( 32, 32 );
375 viewAllButton_->setCheckable( false );
376 viewAllButton_->setToolTip("View all.");
377 viewAllButton_->setWhatsThis(
378 "View all<br><br>"
379 "Move the objects in the scene so that"
380 " the whole scene is visible.");
381 QObject::connect( viewAllButton_, SIGNAL( clicked() ),
382 this, SLOT( viewAll() ) );
383 buttonBar_->addWidget( viewAllButton_)->setText("View all");
384
385
386 projectionButton_ = new QToolButton( buttonBar_ );
387 projectionButton_->setIcon( QPixmap(perspectiveIcon) );
388 projectionButton_->setMinimumSize( 16, 16 );
389 projectionButton_->setMaximumSize( 32, 32 );
390 projectionButton_->setCheckable( false );
391 projectionButton_->setToolTip(
392 "Switch between <b>perspective</b> and "
393 "<b>parrallel</b> projection mode.");
394 projectionButton_->setWhatsThis(
395 "Switch projection modes<br><br>"
396 "Switch between <b>perspective</b> and "
397 "<b>parrallel</b> projection mode.");
398 QObject::connect( projectionButton_, SIGNAL( clicked() ),
399 this, SLOT( toggleProjectionMode() ) );
400 buttonBar_->addWidget( projectionButton_)->setText( "Projection" );
401
402
403 if (glWidget_->format().stereo())
404 {
405 stereoButton_ = new QToolButton( buttonBar_ );
406 stereoButton_->setIcon( QPixmap(monoIcon) );
407 stereoButton_->setMinimumSize( 16, 16 );
408 stereoButton_->setMaximumSize( 32, 32 );
409 stereoButton_->setCheckable( true );
410 stereoButton_->setToolTip( "Toggle stereo viewing");
411 stereoButton_->setWhatsThis(
412 "Toggle stereo mode<br><br>"
413 "Use this button to switch between stereo "
414 "and mono view. To use this feature you need "
415 "a stereo capable graphics card and a stereo "
416 "display/projection system.");
417 QObject::connect( stereoButton_, SIGNAL( clicked() ),
418 this, SLOT( toggleStereoMode() ) );
419 buttonBar_->addWidget( stereoButton_)->setText( "Stereo");
420 }
421
422 buttonBar_->addSeparator();
423
424 sceneGraphButton_ = new QToolButton( buttonBar_ );
425 sceneGraphButton_->setIcon( QPixmap(sceneGraphIcon) );
426 sceneGraphButton_->setMinimumSize( 16, 16 );
427 sceneGraphButton_->setMaximumSize( 32, 32 );
428 sceneGraphButton_->setCheckable( false );
429 sceneGraphButton_->setToolTip("Toggle scene graph viewer.");
430 sceneGraphButton_->setWhatsThis(
431 "Toggle scene graph viewer<br><br>"
432 "The scene graph viewer enables you to examine the "
433 "displayed scene graph and to modify certain nodes.<br><br>"
434 "There are three modi for the scene graph viewer:"
435 "<ul><li><b>hidden</b></li>"
436 "<li><b>split</b>: share space</li>"
437 "<li><b>dialog</b>: own dialog window</li></ul>"
438 "This button toggles between these modi.");
439 QObject::connect( sceneGraphButton_, SIGNAL( clicked() ),
440 this, SLOT( showSceneGraphDialog() ) );
441 buttonBar_->addWidget( sceneGraphButton_)->setText( "SceneGraph" );
442
443 glLayout_ = new QGridLayout(work);
444 glLayout_->setSpacing( 0 );
445 glLayout_->setMargin( 0 );
446
447 glLayout_->addWidget(glView_, 0,0);
448 glLayout_->addWidget(buttonBar_, 0,1);
449
450 glLayout_->setColumnStretch(0,1);
451 glLayout_->setColumnStretch(1,0);
452
453 if (!(options_ & ShowToolBar))
454 buttonBar_->hide();
455
456 }
457
458 bool QtBaseViewer::hasOpenGL()
459 {
460 return QGLFormat::hasOpenGL();
461 }
462
463 //=============================================================================
464 } // namespace QtWidgets
465 } // namespace ACG
466 //=============================================================================
ACG::QtWidgets::QtBaseViewer::showSceneGraphDialog
virtual void showSceneGraphDialog()
show scenegraph widget
Definition: QtBaseViewer.cc:1749
ACG
Namespace providing different geometric functions concerning angles.
Definition: BaseObjectData.hh:68
ACG::QtWidgets::QtBaseViewer::ShowWheelY
Show wheel for rotation around y-axis (bottom)?
Definition: QtBaseViewer.hh:172
ACG::QtWidgets::QtWheel::sizeHint
virtual QSize sizeHint() const
reimplemented
Definition: QtWheel.cc:425
ACG::QtWidgets::QtBaseViewer::slotWheelX
virtual void slotWheelX(double _dAngle)
process signals from wheelX_
Definition: QtBaseViewer.cc:1787
ACG::QtWidgets::QtBaseViewer::signalCustomContextMenuRequested
void signalCustomContextMenuRequested(const QPoint &)
ACG::QtWidgets::QtBaseViewer::swapBuffers
virtual void swapBuffers()
Swaps the screen contents with the off-screen buffer.
Definition: QtBaseViewer_qt.cc:135
ACG::QtWidgets::QtBaseViewer::ShowWheelX
Show wheel for rotation around x-axis (left)?
Definition: QtBaseViewer.hh:170
ACG::QtWidgets::QtWheel
Definition: QtWheel.hh:101
ACG::QtWidgets::QtBaseViewer::toggleProjectionMode
virtual void toggleProjectionMode()
toggle projection mode
Definition: QtBaseViewer.cc:475
ACG::QtWidgets::QtBaseViewer::slotWheelZ
virtual void slotWheelZ(double _dist)
process signals from wheelZ_
Definition: QtBaseViewer.cc:1809
ACG::QtWidgets::QtBaseViewer::viewAll
virtual void viewAll()
view the whole scene
Definition: QtBaseViewer.cc:949
ACG::QtWidgets::QtBaseViewer::copyToImage
void copyToImage(QImage &_image, GLenum _buffer=GL_BACK)
copy current framebuffer to an QImage
Definition: QtBaseViewer.hh:434
ACG::QtWidgets::QtBaseViewer::pickingMode
virtual void pickingMode()
Definition: QtBaseViewerPicking.cc:335
ACG::QtWidgets::QtBaseViewer::questionMode
virtual void questionMode()
calls actionMode() with QuestionMode (cf. ActionMode)
Definition: QtBaseViewer.hh:559
ACG::QtWidgets::QtBaseViewer
Definition: QtBaseViewer.hh:129
ACG::QtWidgets::QtBaseViewer::lightMode
virtual void lightMode()
calls actionMode() with LightMode (cf. ActionMode)
Definition: QtBaseViewer.hh:557
ACG::QtWidgets::QtBaseViewer::setHome
virtual void setHome()
set home position
Definition: QtBaseViewer.cc:919
ACG::QtWidgets::QtBaseViewer::makeCurrent
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
Definition: QtBaseViewer_qt.cc:131
ACG::QtWidgets::QtBaseViewer::toggleStereoMode
virtual void toggleStereoMode()
toggle stereo mode
Definition: QtBaseViewerStereo.cc:94
ACG::QtWidgets::QtBaseViewer::examineMode
virtual void examineMode()
calls actionMode() with ExamineMode (cf. ActionMode)
Definition: QtBaseViewer.hh:555
ACG::QtWidgets::QtGLGraphicsView
Definition: QtGLGraphicsView.hh:69
ACG::QtWidgets::QtBaseViewer::sceneRectChanged
virtual void sceneRectChanged(const QRectF &rect)
process graphics scene size changes
Definition: QtBaseViewer.cc:1824
ACG::QtWidgets::QtBaseViewer::ShowWheelZ
Definition: QtBaseViewer.hh:176
ACG::QtWidgets::QtBaseViewer::home
virtual void home()
go to home pos
Definition: QtBaseViewer.cc:929
ACG::QtWidgets::QtBaseViewer::setStatusBar
void setStatusBar(QStatusBar *_sb)
Definition: QtBaseViewer.cc:326
ACG::QtWidgets::QtBaseViewer::ShowToolBar
Definition: QtBaseViewer.hh:160
ACG::QtWidgets::QtBaseViewer::slotWheelY
virtual void slotWheelY(double _dAngle)
process signals from wheelX_
Definition: QtBaseViewer.cc:1798
ACG::QtWidgets::QtGLGraphicsScene
Definition: QtGLGraphicsScene.hh:74