Developer Documentation
ContextMenu.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 CoreWidget - IMPLEMENTATION
49//
50//=============================================================================
51
52
53//== INCLUDES =================================================================
54
55
56#include "CoreWidget.hh"
57
58//== IMPLEMENTATION ==========================================================
59
60void CoreWidget::slotCustomContextMenu( const QPoint& _point ) {
61
62
63 // Calculate popup position. Use the position from the viewer which was clicked on.
64 const QPoint popupPosition = examiner_widgets_[PluginFunctions::activeExaminer()]->glMapToGlobal(_point);
65 const QPointF scenePosF = examiner_widgets_[PluginFunctions::activeExaminer()]->mapToScene(QPointF(_point.x(), _point.y()));
66 const QPoint scenePos = PluginFunctions::adjustForDevicePixelRatio(QPoint (scenePosF.x(), scenePosF.y()));
67
68 // Call function to adapt the menu to the currently used contex.
69 updatePopupMenu(scenePos);
70
71 // If the menu is not correctly initialized, dont try to show it.
72 if ( !contextMenu_->isEmpty () )
73 contextMenu_->popup( popupPosition );
74
75}
76
78 contextMenu_->hide();
79}
80
90
91 QString nodeName = QString(_node->name().c_str());
92 QAction* typeEntry = new QAction( nodeName ,_menu );
93 _menu->addAction( typeEntry );
94
95 _menu->addSeparator();
96
97 emit updateContextMenuNode(_node->id());
98
99 addContextMenus( _menu , CONTEXTNODEMENU, _node->id() ) ;
100}
101
111void CoreWidget::updatePopupMenuCoordsysNode(QMenu* _menu , const int /*_part*/) {
112
113 QString iconPath = OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator();
114
115 QAction* typeEntry = new QAction(tr("Viewer Settings"),_menu);
116 _menu->addAction( typeEntry );
117 typeEntry->setDisabled(true);
118 _menu->addSeparator();
119
120 QAction* orthogonalCoordsys = 0;
122 orthogonalCoordsys = new QAction( tr("Switch to Orthogonal coordinate system"), _menu );
123 orthogonalCoordsys->setIcon( QIcon(iconPath+"orthogonal.png") );
124 } else {
125 orthogonalCoordsys = new QAction( tr("Switch to Perspective coordinate system"), _menu );
126 orthogonalCoordsys->setIcon( QIcon(iconPath+"perspective.png") );
127 }
128 connect( orthogonalCoordsys,SIGNAL( triggered() ), this, SLOT( slotContextSwitchCoordsysProjection() ) );
129 _menu->addAction(orthogonalCoordsys);
130
131 //====================================================================================================
132 // DrawModes
133 //====================================================================================================
135 if (! viewerDrawMenu_->isEmpty())
136 _menu->addMenu( viewerDrawMenu_ );
137
138 //====================================================================================================
139 // RenderingOptions
140 //====================================================================================================
141
142 QMenu* renderingOptionsMenu = new QMenu(tr("Rendering Options"),_menu);
143 renderingOptionsMenu->setIcon( QIcon(iconPath+"core_renderingOptions.png") );
144 _menu->addMenu(renderingOptionsMenu);
145
146 QAction* projectionAction = 0;
148 projectionAction = new QAction( tr("Switch to Orthogonal Projection"), renderingOptionsMenu );
149 projectionAction->setIcon( QIcon(iconPath+"orthogonal.png") );
150 projectionAction->setToolTip( tr("Switch to perspective orthogonal mode."));
151 } else {
152 projectionAction = new QAction( tr("Switch to Perspective Projection"), renderingOptionsMenu );
153 projectionAction->setIcon( QIcon(iconPath+"perspective.png") );
154 projectionAction->setToolTip( tr("Switch to perspective projection mode."));
155 }
156
157 projectionAction->setCheckable( false );
158 projectionAction->setToolTip( tr("Switch between <b>perspective</b> and "
159 "<b>parrallel</b> projection mode."));
160 projectionAction->setWhatsThis( tr("Switch projection modes<br><br>"
161 "Switch between <b>perspective</b> and "
162 "<b>parrallel</b> projection mode."));
163 connect( projectionAction,SIGNAL( triggered() ), this, SLOT( slotContextSwitchProjection() ) );
164 renderingOptionsMenu->addAction( projectionAction );
165
166
167 QAction* animation = renderingOptionsMenu->addAction(tr("Animation"));
168
169 animation->setToolTip(tr("Animate rotation of objects"));
170 animation->setCheckable( true );
171 animation->setIcon( QIcon(iconPath+"animation.png") );
172 animation->setChecked( PluginFunctions::viewerProperties(PluginFunctions::activeExaminer()).animation() );
173 connect(animation, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeAnimation(bool) ) );
174
175
176 //====================================================================================================
177
178 QAction* backfaceCulling = renderingOptionsMenu->addAction(tr("Backface Culling"));
179 backfaceCulling->setToolTip(tr("Enable backface culling"));
180 backfaceCulling->setCheckable( true );
181 backfaceCulling->setIcon( QIcon(iconPath+"backFaceCulling.png") );
182 backfaceCulling->setChecked( PluginFunctions::viewerProperties().backFaceCulling() );
183 connect(backfaceCulling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeBackFaceCulling(bool) ) );
184
185 //====================================================================================================
186
187 QAction* twoSidedLighting = renderingOptionsMenu->addAction(tr("Two-sided Lighting"));
188 twoSidedLighting->setToolTip(tr("Enable two-sided lighting"));
189 twoSidedLighting->setCheckable( true );
190 twoSidedLighting->setIcon( QIcon(iconPath+"twosidedLighting.png") );
191 twoSidedLighting->setChecked( PluginFunctions::viewerProperties().twoSidedLighting() );
192 connect(twoSidedLighting, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeTwoSidedLighting(bool) ) );
193
194 //====================================================================================================
195
196 QAction* multisampling = renderingOptionsMenu->addAction(tr("Multisampling"));
197 multisampling->setToolTip(tr("Enable Multisampling"));
198 multisampling->setCheckable( true );
199 multisampling->setIcon( QIcon(iconPath+"multiSampling.png") );
200 multisampling->setChecked( PluginFunctions::viewerProperties().multisampling() );
201 connect(multisampling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMultisampling(bool) ) );
202
203 //====================================================================================================
204
205 QAction* mipmapping = renderingOptionsMenu->addAction(tr("Mipmapping"));
206 mipmapping->setToolTip(tr("Enable Mipmapping"));
207 mipmapping->setCheckable( true );
208 mipmapping->setIcon( QIcon(iconPath+"mipmapping.png") );
209 mipmapping->setChecked( PluginFunctions::viewerProperties().mipmapping() );
210 connect(mipmapping, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMipmapping(bool) ) );
211
212 //============================================================================================================
213 // Renderer Menu
214 //============================================================================================================
215
216 if ( renderManager().available() > 1 ) {
217 QMenu* rendererMenu = new QMenu(tr("Renderers"),_menu);
218 rendererMenu->setIcon(QIcon(iconPath+"renderers.png"));
219
220 _menu->addMenu(rendererMenu);
221
222 // Recreate actionGroup
223 QActionGroup* groupRenderer = new QActionGroup( this );
224 groupRenderer->setExclusive( true );
225
226
227 // Get the options action for the currently active renderer
228 if( renderManager()[ renderManager().activeId(PluginFunctions::activeExaminer() )]->optionsAction != 0 ) {
229 rendererMenu->addAction(renderManager()[ renderManager().activeId(PluginFunctions::activeExaminer() ) ]->optionsAction );
230
231 }
232
233 QAction* showRendererDialog = new QAction(tr("Show renderer manager"),this);
234 connect(showRendererDialog,SIGNAL(triggered()),this,SLOT(slotShowRenderManager()));
235 rendererMenu->addAction(showRendererDialog);
236
237 QAction* showRendererObjectWidget = new QAction(tr("Show render objects"),this);
238 connect(showRendererObjectWidget,SIGNAL(triggered()),this,SLOT(slotShowRenderObjectWidget()));
239 rendererMenu->addAction(showRendererObjectWidget);
240
241 rendererMenu->addSeparator();
242
243 for ( unsigned int i = 0 ; i < renderManager().available() ; ++i) {
244
245 // Add a new Action with the renderer name
246 QAction * action = new QAction( renderManager()[i]->name, groupRenderer );
247 action->setCheckable( true );
248
249 // Check if this processor is currently active
250 if ( renderManager().activeId(PluginFunctions::activeExaminer() ) == i )
251 action->setChecked(true);
252
253 // Remember the id for the processor
254 action->setData(QVariant(i));
255 }
256
257 // Add all new actions from the group to the menu
258 rendererMenu->addActions( groupRenderer->actions() );
259
260 // Connect signal of group to our managing slot
261 connect( groupRenderer , SIGNAL( triggered( QAction * ) ),
262 this , SLOT( slotRenderMenu( QAction * ) ) );
263
264 }
265
266 //============================================================================================================
267 // Viewing Direction Menu
268 //============================================================================================================
269
270 QMenu* viewingDirectionMenu = new QMenu( tr("Viewing Direction"), _menu);
271 viewingDirectionMenu->setIcon(QIcon(iconPath+"core_viewingDirection.png"));
272 _menu->addMenu(viewingDirectionMenu);
273
274 QActionGroup* dirGroup = new QActionGroup(this);
275
276 QAction* viewAction;
277 // freeView
278 viewAction = new QAction( tr("Free View"), viewingDirectionMenu );
279 viewAction->setIcon( QIcon(iconPath+"orthogonal.png") );
280 viewAction->setCheckable( true );
281 viewAction->setData( PluginFunctions::VIEW_FREE );
282 viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_FREE );
283 viewingDirectionMenu->addAction( viewAction );
284 dirGroup->addAction(viewAction);
285 viewingDirectionMenu->addSeparator();
286 // TOP
287 viewAction = new QAction( tr("Top View"), viewingDirectionMenu );
288 viewAction->setIcon( QIcon(iconPath+"viewcontrol_top.png") );
289 viewAction->setCheckable( true );
290 viewAction->setData( PluginFunctions::VIEW_TOP );
291 viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_TOP );
292 viewingDirectionMenu->addAction( viewAction );
293 dirGroup->addAction(viewAction);
294 // BOTTOM
295 viewAction = new QAction( tr("Bottom View"), viewingDirectionMenu );
296 viewAction->setIcon( QIcon(iconPath+"viewcontrol_bottom.png") );
297 viewAction->setCheckable( true );
298 viewAction->setData( PluginFunctions::VIEW_BOTTOM );
299 viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_BOTTOM );
300 viewingDirectionMenu->addAction( viewAction );
301 dirGroup->addAction(viewAction);
302 // LEFT
303 viewAction = new QAction( tr("Left View"), viewingDirectionMenu );
304 viewAction->setIcon( QIcon(iconPath+"viewcontrol_left.png") );
305 viewAction->setCheckable( true );
306 viewAction->setData( PluginFunctions::VIEW_LEFT );
307 viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_LEFT );
308 viewingDirectionMenu->addAction( viewAction );
309 dirGroup->addAction(viewAction);
310 // RIGHT
311 viewAction = new QAction( tr("Right View"), viewingDirectionMenu );
312 viewAction->setIcon( QIcon(iconPath+"viewcontrol_right.png") );
313 viewAction->setCheckable( true );
314 viewAction->setData( PluginFunctions::VIEW_RIGHT );
315 viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_RIGHT );
316 viewingDirectionMenu->addAction( viewAction );
317 dirGroup->addAction(viewAction);
318 // FRONT
319 viewAction = new QAction( tr("Front View"), viewingDirectionMenu );
320 viewAction->setIcon( QIcon(iconPath+"viewcontrol_front.png") );
321 viewAction->setCheckable( true );
322 viewAction->setData( PluginFunctions::VIEW_FRONT );
323 viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_FRONT );
324 viewingDirectionMenu->addAction( viewAction );
325 dirGroup->addAction(viewAction);
326 // BACK
327 viewAction = new QAction( tr("Back View"), viewingDirectionMenu );
328 viewAction->setIcon( QIcon(iconPath+"viewcontrol_back.png") );
329 viewAction->setCheckable( true );
330 viewAction->setData( PluginFunctions::VIEW_BACK );
331 viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_BACK );
332 viewingDirectionMenu->addAction( viewAction );
333 dirGroup->addAction(viewAction);
334
335 viewingDirectionMenu->addSeparator();
336
337 connect( dirGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotSetViewingDirection(QAction*) ) );
338
339 //===========================================================================
340 // Check box to determine whether rotation should be locked or not
341
342 QAction* lockAction = viewingDirectionMenu->addAction("Lock rotation");
343 lockAction->setCheckable( true );
344 lockAction->setIcon( QIcon(iconPath+"lock_rotation.png") );
345 lockAction->setToolTip(tr("Lock rotation in current examiner"));
346 lockAction->setChecked( PluginFunctions::viewerProperties().rotationLocked() );
347 viewingDirectionMenu->addAction( lockAction );
348
349 connect( lockAction, SIGNAL(triggered(bool)), this, SLOT(slotLockRotation(bool) ) );
350
351 //====================================================================================================
352 // Other Toplevel Action
353 //====================================================================================================
354
355 _menu->addSeparator();
356
357 //====================================================================================================
358
359 //============================================================================================================
360 // Post processor Manager
361 //============================================================================================================
362
363 QAction* showPostProcessorDialog = new QAction(tr("Show post processor manager"),this);
364 showPostProcessorDialog->setIcon(QIcon(iconPath+"postprocessors.png"));
365 connect(showPostProcessorDialog,SIGNAL(triggered()),this,SLOT(slotShowPostProcessorManager()));
366 _menu->addAction(showPostProcessorDialog);
367
368 _menu->addSeparator();
369
370 //====================================================================================================
371
372 QAction* homeAction = new QAction(tr("Restore home view"),_menu);
373 homeAction->setIcon( QIcon(iconPath+"go-home.png") );
374 homeAction->setCheckable( false );
375 homeAction->setToolTip(tr("Restore <b>home</b> view."));
376 homeAction->setWhatsThis( tr("Restore home view<br><br>"
377 "Resets the view to the home view"));
378 _menu->addAction( homeAction );
379 connect( homeAction,SIGNAL( triggered() ), this, SLOT( slotContextHomeView() ) );
380
381 QAction* setHomeAction = new QAction( tr("Set Home View") , _menu );
382 setHomeAction->setIcon( QIcon(iconPath+"set-home.png") );
383 setHomeAction->setCheckable( false );
384 setHomeAction->setToolTip(tr("Set <b>home</b> view"));
385 setHomeAction->setWhatsThis( tr("Store home view<br><br>"
386 "Stores the current view as the home view"));
387 _menu->addAction( setHomeAction);
388 connect( setHomeAction,SIGNAL( triggered() ), this, SLOT( slotContextSetHomeView() ) );
389
390 QAction* viewAllAction = new QAction( tr("View all"), _menu );
391 viewAllAction->setIcon( QIcon(iconPath+"viewall.png") );
392 viewAllAction->setCheckable( false );
393 viewAllAction->setToolTip(tr("View all."));
394 viewAllAction->setWhatsThis( tr("View all<br><br>"
395 "Move the objects in the scene so that"
396 " the whole scene is visible."));
397 connect( viewAllAction,SIGNAL( triggered() ), this, SLOT( slotContextViewAll() ) );
398 _menu->addAction( viewAllAction);
399
400
401 _menu->addSeparator();
402
403 //====================================================================================================
404
405 QAction* copyView = _menu->addAction(tr("Copy View"));
406 copyView->setToolTip(tr("Copy current view, window size and toolbar size to clipboard. Hold Ctrl to generate C/C++/JavaScipt-Style string."));
407 copyView->setIcon( QIcon(iconPath+"edit-copy.png") );
408 connect(copyView, SIGNAL(triggered()), this, SLOT(slotCopyView()) );
409
410 //====================================================================================================
411
412 QAction* pasteView = _menu->addAction(tr("Paste View"));
413 pasteView->setToolTip(tr("Paste current view from clipboard"));
414 pasteView->setIcon( QIcon(iconPath+"edit-paste.png") );
415 connect(pasteView, SIGNAL(triggered()), this , SLOT( slotPasteView( ) ) );
416
417 //====================================================================================================
418
419 QAction* pasteViewAndWindow = _menu->addAction(tr("Paste View and Window Size"));
420 pasteViewAndWindow->setToolTip(tr("Paste current view, window size and the toolbox size from clipboard"));
421 pasteViewAndWindow->setIcon( QIcon(iconPath+"edit-paste.png") );
422 connect(pasteViewAndWindow, SIGNAL(triggered()), this , SLOT( slotPasteViewAndWindow( ) ) );
423
424 //====================================================================================================
425
426 QAction* snapshot_examiner = _menu->addAction(tr("Examiner Snapshot"));
427 snapshot_examiner->setToolTip(tr("Take a snapshot of the current examiner"));
428 snapshot_examiner->setIcon( QIcon(iconPath+"snapshot.png") );
429 connect(snapshot_examiner, SIGNAL(triggered()), this, SLOT( slotExaminerSnapshot() ) );
430
431 //====================================================================================================
432
433 QAction* snapshot_viewer = _menu->addAction(tr("Viewer Snapshot"));
434 snapshot_viewer->setToolTip(tr("Take a snapshot of the whole viewer"));
435 snapshot_viewer->setIcon( QIcon(iconPath+"snapshot.png") );
436 connect(snapshot_viewer, SIGNAL(triggered()), this, SLOT( viewerSnapshotDialog() ) );
437
438}
439
449void CoreWidget::updatePopupMenuBackground(QMenu* _menu , const QPoint& /*_point*/) {
450
451 //====================================================================================================
452 // DrawModes
453 //====================================================================================================
455 _menu->addMenu( viewerDrawMenu_ );
456
457 _menu->addSeparator();
458
459 QAction* action = _menu->addAction(tr("Set Background Color"));
460 action->setToolTip(tr("Set the background color for the current viewer"));
461 action->setStatusTip(tr("Set the background color for the current viewer"));
462 action->setWhatsThis(tr("Set the background color for the current viewer"));
463 action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"BackgroundColor.png") );
464 connect(action, SIGNAL(triggered()), this, SLOT(slotSetContextBackgroundColor()) );
465
466 /*
467 * Show coordsys context menu of coordsys if
468 * invisible...
469 */
470
472 ACG::SceneGraph::BaseNode* coordSys = root->find("Core Coordsys Node");
473
474 if(!coordSys->visible()) {
475
476 if(!coordSysMenu_) {
477 coordSysMenu_ = new QMenu(tr("Viewer Settings"), _menu);
479 }
480 _menu->addSeparator();
481 _menu->addMenu(coordSysMenu_);
482 }
483
484 // Tell Plugins to update their context Menu
486
488
489}
490
499void CoreWidget::updatePopupMenuObject(QMenu* _menu , BaseObjectData* _object ) {
500
501 QAction* typeEntry = new QAction( typeName(_object->dataType())+QString(": ")+_object->name() ,_menu);
502 typeEntry->setIcon(typeIcon(_object->dataType()));
503 _menu->addAction( typeEntry );
504
505 _menu->addSeparator( );
506
507 // Tell Plugins to update their context Menu
508 emit updateContextMenu(_object->id() );
509
510 if ( addContextMenus( _menu , CONTEXTOBJECTMENU , _object->id() ) )
511 _menu->addSeparator();
512
513 // Add picking Menu
514 if (pickMenu_ != 0 && pickMenu_->actions().size() > 0) {
515 pickMenu_->setTitle(tr("&Picking"));
516 contextMenu_->addMenu( pickMenu_ );
517 pickMenu_->setTearOffEnabled(true);
518 }
519}
520
521bool CoreWidget::addContextMenus( QMenu* _menu , ContextMenuType _type , int _id ) {
522
523 bool added = false;
524
525 QMap< QString , QAction* > menuMap; //QMap sorts by key
526 QMap< QString , QAction* > actionMap;
527
528 // Add context menus from plugins
529 for ( uint i = 0 ; i < contextMenus_.size(); ++i ) {
530
531 if ( contextMenus_[i].type != _type )
532 continue;
533
534 switch (contextMenus_[i].type) {
536 break;
538 BaseObjectData* object;
539 if ( !PluginFunctions::getObject(_id, object) ) {
540 emit log(LOGERR,tr("Cant get object for objectContextMenu"));
541 continue;
542 }
543
544 // Datatype does not match
545 if ( ! object->dataType( contextMenus_[i].contextType ) )
546 continue;
547
548 break;
549 case CONTEXTNODEMENU:
550 break;
551
552 }
553
554 QMenu* menu = contextMenus_[i].action->menu();
555
556 if (menu == 0) //is it a menu
557 actionMap[ contextMenus_[i].action->text() ] = contextMenus_[i].action;
558 else
559 menuMap[ contextMenus_[i].action->text() ] = contextMenus_[i].action;
560
561 added = true;
562
563 // Get all Actions in the menu and its submenus.
564 // Set their data to the picked Object id
565
566
567 QList< QAction *> allActions;
568 if ( menu == 0) {
569 allActions.push_back(contextMenus_[i].action);
570 } else {
571 allActions = menu->actions();
572 }
573
574 while ( !allActions.empty() ) {
575 QList< QAction *> tmpList;
576
577 // Set userdata of all actions to the picked Object Id
578 for ( int j = 0 ; j < allActions.size(); ++j ) {
579 allActions[j]->setData( QVariant( _id ) );
580 if ( allActions[j]->menu() != 0 )
581 tmpList << allActions[j]->menu()->actions();
582 }
583
584 allActions = tmpList;
585 }
586
587 }
588
589 //find the currently selected view mode
590 int id = -1;
591 for (int i=0; i<viewModes_.size(); i++) {
592 if (viewModes_[i]->name == OpenFlipper::Options::currentViewMode()) {
593 id = i;
594 break;
595 }
596 }
597
598 // Default to mode all (0) if not found
599 if ( id == -1 ) {
600 emit log(LOGERR, tr("Unable to find view mode %1.").arg(OpenFlipper::Options::currentViewMode()) );
601 id = 0;
602 }
603
605
606 //first add all menus
607 QMapIterator<QString, QAction*> it(menuMap);
608
609 QStringList visible = viewModes_[id]->visibleContextMenus;
610 if (visible.contains("ALL_THAT_EXIST")) {
611 //this plugin adds all context menus, no special configuration so far.
612 visible = viewModes_[0]->visibleContextMenus;
613 }
614
615 // Remove Plugin Name from string
616 visible.replaceInStrings(QRegularExpression(".*>"), "");
617
618 // Remove accelerator specifications
619 visible.replaceInStrings("&", "");
620
621 while (it.hasNext()) {
622 it.next();
623
624 for ( int i = 0 ; i < visible.size(); ++i ) {
625 if ( it.key().contains(visible[i]) ) {
626 _menu->addAction( it.value() );
627 }
628 }
629 }
630
631 _menu->addSeparator();
632
633 //then all actions
634 QMapIterator<QString, QAction*> it2(actionMap);
635
636 while (it2.hasNext()) {
637 it2.next();
638
639 for ( int i = 0 ; i < visible.size(); ++i ) {
640 if ( it2.key().contains(visible[i]) ) {
641 _menu->addAction( it2.value() );
642 }
643 }
644 }
645
646 return added;
647}
648
649
650
657void CoreWidget::updatePopupMenu(const QPoint& _point) {
658
659 // Clear the complete context menu.
660 contextMenu_->clear();
661
662 // Clear the selection context menu part.
663 contextSelectionMenu_->clear();
664
665 // =============================================================================
666 // First do a picking on the current position to check which context we are in.
667 // =============================================================================
668
669 enum CONTEXTTYPE {
670 COORDSYSCONTEXT ,BACKGROUNDCONTEXT ,OBJECTCONTEXT, NODECONTEXT
671 } context = BACKGROUNDCONTEXT;
672
673 // Do picking in the gl area to find an object
674 size_t node_idx, target_idx;
675 ACG::Vec3d hit_point;
676 BaseObjectData* object = 0;
678
679 if (examiner_widgets_[PluginFunctions::activeExaminer()]->pick( ACG::SceneGraph::PICK_ANYTHING,_point,node_idx, target_idx, &hit_point ) ) {
680
681 if ( PluginFunctions::getPickedObject(node_idx, object) ) {
682 context = OBJECTCONTEXT;
683 } else {
685 if ( node != 0 && ( node->name() == "Core Coordsys Node") )
686 context = COORDSYSCONTEXT;
687 else
688 context = NODECONTEXT;
689 }
690 }
691
692 // =============================================================================
693 // Depending on the context create the basic context menu.
694 // =============================================================================
695
696 QIcon icon;
697
698 switch (context) {
699 case BACKGROUNDCONTEXT:
701 return;
702 break;
703 case OBJECTCONTEXT:
705 return;
706 break;
707 case COORDSYSCONTEXT:
709 return;
710 break;
711 case NODECONTEXT:
713 return;
714 break;
715 }
716
717}
718
719
721 std::cerr << "Todo : slotSnapShotName only sets name for current viewer" << std::endl;
722
724
725 fname.replace('%', '$');
726 fname = QFileDialog::getSaveFileName ( 0,
727 tr("Save snapshot name"),
728 OpenFlipperSettings().value("Core/CurrentDir").toString());
729
730 if (!fname.isEmpty())
731 {
732 fname.replace('$', '%');
733
734
735 // Get the chosen directory and remember it.
736 QFileInfo fileInfo(fname);
737 OpenFlipperSettings().setValue("Core/CurrentDir", fileInfo.absolutePath() );
738
740 QString msg=tr("next snapshot: ");
741 statusBar()->showMessage(msg);
742 }
743
744}
745
747 MenuInfo info;
748 info.action = _entry;
749 info.type = _type;
750
751 contextMenus_.push_back(info);
753}
754
755void CoreWidget::slotAddContextItem( QAction* _entry , DataType _dataType ,ContextMenuType _type ) {
756 MenuInfo info;
757 info.action = _entry;
758 info.contextType = _dataType;
759 info.type = _type;
760
761 contextMenus_.push_back(info);
763}
764
766 int id = -1;
767 // Find the plugin which added this Context Menu
768 for ( uint i = 0 ; i < plugins().size(); ++i ) {
769 if ( plugins()[i].plugin == sender() ) {
770 id = i;
771 break;
772 }
773 }
774
775 // Find the scripting plugin because we assign this context menu to it as we did not find the original sender
776 if ( id == -1 ) {
777 for ( uint i = 0 ; i < plugins().size(); ++i ) {
778 if ( plugins()[i].name == "Scripting" ) {
779 id = i;
780 break;
781 }
782 }
783
784
785 if ( id == -1 ) {
786 std::cerr << "Unknown sender plugin when adding Context Menu!" << std::endl;
787 return;
788 }
789 }
790
791 plugins()[id].contextMenus.push_back( std::pair< QString,QAction* >( plugins()[id].name + "->" + _entry->text(), _entry) );
792
793 // add widget name to viewMode 'all'
794 if ( !viewModes_[0]->visibleContextMenus.contains(plugins()[id].name + "->" + _entry->text()) ){
795 viewModes_[0]->visibleContextMenus << plugins()[id].name + "->" + _entry->text();
796 viewModes_[0]->visibleContextMenus.sort();
797 }
798
799 setViewMode( OpenFlipper::Options::currentViewMode() );
800}
801
803 if ( drawGroupViewer_ ) {
804
805 disconnect( drawGroupViewer_ , SIGNAL( triggered( QAction * ) ),
806 this , SLOT( slotViewerDrawMenu( QAction * ) ) );
807 delete( drawGroupViewer_ );
809
810 }
811
812 // Recreate drawGroup
813 drawGroupViewer_ = new QActionGroup( this );
814 drawGroupViewer_->setExclusive( false );
815
816 connect( drawGroupViewer_ , SIGNAL( triggered( QAction * ) ),
817 this , SLOT( slotViewerDrawMenu( QAction * ) ) );
818
819 if ( !viewerDrawMenu_ ) {
820
821 QIcon icon;
822 icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"drawModes.png");
823 viewerDrawMenu_ = new QMenu(tr("Set Draw Mode"));
824 viewerDrawMenu_->setTearOffEnabled(true);
825 viewerDrawMenu_->setIcon(icon);
826
827 connect(viewerDrawMenu_,SIGNAL(aboutToShow () ) , this, SLOT(slotUpdateGlobalDrawMenu() ) );
828 }
829
832 }
834
835 // Collect available draw modes
836 // Single pass action, draw modes independent from multipass rendering
839 availableGlobalDrawModes_ = actionAvailable.drawModes();
840
841 // Get currently active drawModes (first viewer only )
842 // TODO: create combination from all viewers!
844
845 // Convert to ids
846 std::vector< ACG::SceneGraph::DrawModes::DrawMode > availDrawModeIds;
847 availDrawModeIds = availableGlobalDrawModes_.getAtomicDrawModes() ;
848
849 viewerDrawMenu_->clear();
850
851 for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
852 {
853 ACG::SceneGraph::DrawModes::DrawMode id = availDrawModeIds[i];
854 std::string descr = id.description();
855
856 QCheckBox *checkBox = new QCheckBox(QString(descr.c_str()), viewerDrawMenuWidget_);
857 checkBox->setChecked(activeDrawModes.containsAtomicDrawMode(id));
858 QWidgetAction *checkableAction = new QWidgetAction(drawGroupViewer_);
859 checkableAction->setText(descr.c_str());
860 checkableAction->setDefaultWidget(checkBox);
861 connect(checkBox, SIGNAL(toggled(bool) ), checkableAction, SLOT(trigger() ) );
862 }
863
864 viewerDrawMenu_->addActions( drawGroupViewer_->actions() );
865
866}
867
868void CoreWidget::slotViewerDrawMenu(QAction * _action) {
869
870 //======================================================================================
871 // Get the mode toggled
872 //======================================================================================
874 std::vector< ACG::SceneGraph::DrawModes::DrawMode > availDrawModeIds;
876 for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
877 {
878 QString descr = QString( availDrawModeIds[i].description().c_str() );
879
880 if ( descr == _action->text() ) {
881 mode = availDrawModeIds[i];
882 break;
883 }
884 }
885
886 if ( qApp->keyboardModifiers() & Qt::ShiftModifier )
888 else
889 {
890 contextMenu_->hide();
892 }
893
894}
895
896void CoreWidget::slotPostProcessorMenu( QAction * _action) {
897 unsigned int mode = _action->data().toUInt();
898 postProcessorManager().setActive(mode,PluginFunctions::activeExaminer());
899}
900
901void CoreWidget::slotRenderMenu( QAction * _action) {
902 unsigned int mode = _action->data().toUInt();
903 renderManager().setActive(mode,PluginFunctions::activeExaminer());
904
905 QString defaultRendererKey = "Viewer" + QString::number(PluginFunctions::activeExaminer())+"/DefaultRenderer";
906 QString defaultRendererName = renderManager()[mode]->name;
907 OpenFlipperSettings().setValue(defaultRendererKey,defaultRendererName);
908}
909
910//=============================================================================
@ CONTEXTBACKGROUNDMENU
The Menu will be shown when the background was picked.
@ CONTEXTOBJECTMENU
The Menu will be shown when an object was picked.
@ CONTEXTNODEMENU
The Menu will be shown when a node was picked.
DLLEXPORT QIcon & typeIcon(DataType _id)
Get an QIcon associated with the given DataType.
Definition: Types.cc:212
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:154
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
@ LOGERR
unsigned int id() const
Definition: BaseNode.hh:423
std::string name() const
Returns: name of node (needs not be unique)
Definition: BaseNode.hh:415
bool visible()
Is node visible (status == Active)?
Definition: BaseNode.hh:409
ChildIter find(BaseNode *_node)
Definition: BaseNode.hh:346
DrawModes::DrawMode drawModes() const
Get the collected draw modes.
Definition: SceneGraph.hh:582
std::vector< DrawMode > getAtomicDrawModes() const
Separates this drawMode into a list of all separate atomic draw modes.
Definition: DrawModes.cc:485
bool containsAtomicDrawMode(const DrawMode &_atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
Definition: DrawModes.cc:510
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:728
bool dataType(DataType _type) const
Definition: BaseObject.cc:219
int id() const
Definition: BaseObject.cc:188
QMenu * contextMenu_
context Menu for the gl area
Definition: CoreWidget.hh:998
void slotContextHomeView()
Set the active viewer to home position.
void slotSnapshotName()
Set the snapShot name for all examiners.
Definition: ContextMenu.cc:720
void updatePopupMenuCoordsysNode(QMenu *_menu, const int _part)
Update context Menu when Coordsys node has been clicked on.
Definition: ContextMenu.cc:111
void slotSetContextBackgroundColor()
Set Background Color for one viewer.
void slotLocalChangeBackFaceCulling(bool _backFaceCulling)
Set backface culling for active viewer.
void updateContextMenuNode(int)
tells the plugins to update their context menu when a node is picked
std::vector< MenuInfo > contextMenus_
All real context menu entries.
Definition: CoreWidget.hh:1004
void slotCopyView()
Copy view from the last active examiner.
void slotPasteView()
Paste the view to the last active examiner.
QMenu * pickMenu_
Definition: CoreWidget.hh:1579
std::vector< glViewer * > examiner_widgets_
Examiner Widget.
Definition: CoreWidget.hh:684
QVector< ViewMode * > & viewModes_
List of currently available viewModes.
Definition: CoreWidget.hh:589
void slotAddContextItem(QAction *_entry, ContextMenuType _type)
called by plugins to add a new context menu item
Definition: ContextMenu.cc:746
QMenu * contextSelectionMenu_
Context Menu containing all selection elements.
Definition: CoreWidget.hh:1001
void slotLocalChangeMultisampling(bool _multisampling)
Set multisampling for active viewer.
QMenu * coordSysMenu_
Definition: CoreWidget.hh:1017
void slotSetViewingDirection(QAction *_action)
Change the viewing direction from context-menu.
void slotPasteViewAndWindow()
Paste the view, the window and toolbox size to the last active examiner.
void slotContextViewAll()
Change view on active viewer to view complete scene.
void updateContextMenu(int)
tells the plugins to update their context menu when an object is picked
void viewerSnapshotDialog()
Create a snapshot of the whole app with fileDialog.
void slotShowRenderObjectWidget()
Shows the widget containing the current render objects.
bool addContextMenus(QMenu *_menu, ContextMenuType _type, int _id=-1)
Definition: ContextMenu.cc:521
void slotAddContextItemToViewMode(QAction *_entry)
called by slotAddContextItem to add the item to the view mode
Definition: ContextMenu.cc:765
QMenu * viewerDrawMenu_
Draw Menu for per Viewer Draw Modes.
Definition: CoreWidget.hh:1010
std::vector< PluginInfo > & plugins()
Convenient way to access plugin list.
Definition: CoreWidget.cc:679
void updatePopupMenuBackground(QMenu *_menu, const QPoint &_point)
Update context Menu when background has been clicked on.
Definition: ContextMenu.cc:449
void slotUpdateViewerDrawMenu()
Creates a draw Menu for the currently active Viewer.
Definition: ContextMenu.cc:802
void updateContextMenuBackground()
tells the plugins to update their context menu when the background is picked
void slotPostProcessorMenu(QAction *_action)
Called when a different post processor has been chosen.
Definition: ContextMenu.cc:896
void slotContextSetHomeView()
Set the active viewers home position.
void slotContextSwitchCoordsysProjection()
Toggle coordsys projection mode of the active viewer.
void slotLocalChangeMipmapping(bool _mipmapping)
Set mipmapping for active viewer.
ACG::SceneGraph::DrawModes::DrawMode availableGlobalDrawModes_
This variable holds the global draw menu.
Definition: CoreWidget.hh:907
void slotHideContextMenu()
Hide the context menu.
Definition: ContextMenu.cc:77
void slotCustomContextMenu(const QPoint &_point)
This slot is called by the examiner widgets gl area when a context menu is requested.
Definition: ContextMenu.cc:60
void updatePopupMenu(const QPoint &_point)
check current context and initialize context menu according to this context.
Definition: ContextMenu.cc:657
QWidget * viewerDrawMenuWidget_
owns all the checkboxes of viewerDrawMenu_
Definition: CoreWidget.hh:1013
void slotLocalChangeTwoSidedLighting(bool _lighting)
Set two-sided lighting for active viewer.
void slotLocalChangeAnimation(bool _animation)
Set the animation mode for active viewer.
void slotContextSwitchProjection()
Toggle projection mode of the active viewer.
void updatePopupMenuNode(QMenu *_menu, ACG::SceneGraph::BaseNode *_node)
Update context Menu when an arbitrary node has been clicked on.
Definition: ContextMenu.cc:89
QActionGroup * drawGroupViewer_
DrawGroup for per Viewer Draw Modes.
Definition: CoreWidget.hh:1007
void slotUpdateGlobalDrawMenu()
Setup and update the global draw menu.
Definition: MenuBar.cc:850
void updatePopupMenuObject(QMenu *_menu, BaseObjectData *_object)
Update popup Menu when an object has been clicked on.
Definition: ContextMenu.cc:499
void slotLockRotation(bool _lock)
Lock rotation in current examiner widget.
void slotRenderMenu(QAction *_action)
Called when a different renderer has been chosen.
Definition: ContextMenu.cc:901
void setViewMode(const QString &_mode, bool _expandAll=false)
Set the view Mode to the given Mode.
Definition: viewMode.cc:318
void slotExaminerSnapshot()
Create a snapshot of the last active examiner.
void slotShowRenderManager()
shows the widget for the rendermanager
ACG::SceneGraph::CoordsysNode::ProjectionMode getCoordsysProjection()
Toggle coordsys projection mode of the active viewer.
void slotViewerDrawMenu(QAction *_action)
Called when a coordsys drawMode has been changed.
Definition: ContextMenu.cc:868
Predefined datatypes.
Definition: DataTypes.hh:83
DataType contextType
Type of objects for which the context Menu should be visible.
Definition: CoreWidget.hh:172
QAction * action
The context item.
Definition: CoreWidget.hh:169
ContextMenuType type
Type of the context Menu ( Context for what type .. Background,Object,Node)
Definition: CoreWidget.hh:175
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void setActive(unsigned int _active, int _viewerId)
set the active post processor for viewer
void setActive(unsigned int _active, int _id)
set the active renderer
size_t available()
number of available renderers
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
void snapshotBaseFileName(const QString &_fname)
@ PERSPECTIVE_PROJECTION
perspective
BaseNode * find_node(BaseNode *_root, unsigned int _node_idx)
Find a node in the scene graph.
Definition: SceneGraph.cc:77
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:137
@ PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
QPoint adjustForDevicePixelRatio(const QPoint &point)
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
ACG::SceneGraph::BaseNode * getRootNode()
Get the root node for data objects.
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
ACG::SceneGraph::DrawModes::DrawMode drawMode(int _viewer)
Get the current draw Mode of a Viewer.
unsigned int activeExaminer()
Get the id of the examiner which got the last mouse events.
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node