Developer Documentation
picking.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 //
49 // CLASS CoreWidget - IMPLEMENTATION
50 //
51 //=============================================================================
52 
53 
54 //== INCLUDES =================================================================
55 
56 #include "CoreWidget.hh"
57 
59 
60 //-----------------------------------------------------------------------------
61 
63 
64  // update Buttons
65  moveButton_->setChecked(false);
66  pickButton_->setChecked(false);
67  questionButton_->setChecked(false);
68 
69  switch (_am)
70  {
71  case Viewer::ExamineMode:
72  moveButton_->setChecked(true);
73  break;
74  case Viewer::LightMode:
75  break;
76  case Viewer::PickingMode:
77  pickButton_->setChecked(true);
78  break;
79  case Viewer::QuestionMode:
80  questionButton_->setChecked(true);
81  break;
82  }
83 
84  if (_am != actionMode_) {
86  actionMode_ = _am;
87 
88  // update cursor
89  switch ( _am )
90  {
91  case Viewer::ExamineMode:
92  cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_move.png" ) ,0,0 ));
93  break;
94  case Viewer::LightMode:
95  cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_light.png" ) ,0,0 ));
96  break;
97  case Viewer::PickingMode:
98  cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_arrow.png" ) ,0,0 ));
99  if (pick_mode_idx_ != -1) {
101  }
102  break;
103  case Viewer::QuestionMode:
104  cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_whatsthis.png" ) ,0,0 ));
105  break;
106  }
107 
108  // Update pickmode toolbar
109  switch ( _am ) {
110  case Viewer::PickingMode:
111  // Show the pickMode Toolbar for this picking mode if it is set
112  if (pick_mode_idx_ != -1) {
113  if (pick_modes_[pick_mode_idx_].toolbar() )
115  else
116  hidePickToolBar();
117  }
118  break;
119 
120  default:
121  hidePickToolBar();
122  break;
123  }
124 
125  unsigned int maxPases = 1;
126  ACG::Vec3d bbmin,bbmax;
128 
129  //update Viewers
130  for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ) {
131 
132  examiner_widgets_[i]->sceneGraph( PluginFunctions::getSceneGraphRootNode(), maxPases,bbmin,bbmax );
133  examiner_widgets_[i]->trackMouse(false);
134 
135  if(_am == Viewer::PickingMode) {
136  if (pick_mode_idx_ != -1) {
137  examiner_widgets_[i]->trackMouse(pick_modes_[pick_mode_idx_].tracking() );
138  }
139  }
140  }
141 
142  //emit pickmodeChanged with either the name of the current pickmode or an empty string
143  if( pickingMode() )
145  else
146  emit(signalPickModeChanged(""));
147  }
148 }
149 
150 //-----------------------------------------------------------------------------
151 
153  _am = actionMode_;
154 }
155 
156 //-----------------------------------------------------------------------------
157 
158 void CoreWidget::setPickMode(const std::string& _mode){
159 
160  for (unsigned int i=0; i<pick_modes_.size(); ++i)
161  {
162  if (pick_modes_[i].name() == _mode)
163  {
164  pickMode( i );
165  updatePickMenu();
166  return;
167  }
168  }
169 }
170 
171 //-----------------------------------------------------------------------------
172 
173 void CoreWidget::getPickMode(std::string& _mode){
174  _mode = pick_mode_name_;
175 }
176 
177 //-----------------------------------------------------------------------------
178 
179 void CoreWidget::setActivePickToolBar(QToolBar* _tool) {
180 
181  if(_tool != 0) {
182 
183  // Hide all picking toolbars
184  hidePickToolBar();
185 
186  bool showInScene = OpenFlipperSettings().value("Core/Gui/ToolBars/PickToolbarInScene", true).toBool();
187 
188 #ifdef WIN32 //workaround for coreprofile since qt 5.9 is simply too buggy on windows
189  //remove this entire ifdef, as soon as qt can render on windows
190  //(qpainter does not work on coreprofiles)
191  if(OpenFlipper::Options::coreProfile())
192  showInScene = false;
193 #endif
194 
195  if ( showInScene ) {
196 
197  // Try to find toolbar in local map ( if it is in the gl scene
198  PickToolBarMap::iterator ret = curPickingToolbarItems_.find(_tool);
199  if(ret == curPickingToolbarItems_.end()) {
200 
201  // Set horizontal orientation
202  _tool->setOrientation(Qt::Horizontal);
203 
204  // Update size as the orientation changed
205  _tool->adjustSize();
206 
207  // Add widget to the gl scene
208  QGraphicsProxyWidget* item = glScene_->addWidget(_tool);
209 
210  // Put it into center of the screen
211  int midP = (glScene_->width() / 2) - (int)(_tool->width() / 2);
212  item->setPos(midP, 3);
213 
214  item->show();
215 
216  // Remember it as being part of the scene
217  curPickingToolbarItems_.insert(std::pair<QToolBar*,QGraphicsProxyWidget*>(_tool,item));
218  } else {
219  // Widget has already been added once, so just show it
220  ret->second->show();
221  }
222  } else {
223 
224  // Try to find toolbar in local map
225  // If its in there, we need to remove it from the graphics scene before adding it
226  // to the side toolbar.
227  PickToolBarMap::iterator ret = curPickingToolbarItems_.find(_tool);
228  if(ret != curPickingToolbarItems_.end()) {
229 
230  glScene_->removeItem(ret->second);
231  ret->first->setParent(0);
232 
233  // remove from list of widgets in glScene
234  curPickingToolbarItems_.erase(ret);
235  }
236 
237  pickToolBarExternal_ = _tool;
238 
239  // Check whether this toolbar has been displayed before
240  if(registeredToolbars_.count(_tool) == 0) {
241 
242  /*
243  * This code makes sure that the orientation and size
244  * of a toolbar is only set once (the first time it is added).
245  * In some cases, the user wants to move the toolbar somewhere
246  * else and thus this check makes sure that it does not
247  * loose its position and orientation after a pickmode change.
248  */
249 
250  // Adjust its size and orientation
251  pickToolBarExternal_->setOrientation(Qt::Vertical);
252  pickToolBarExternal_->adjustSize();
253 
254  addToolBar(Qt::LeftToolBarArea,_tool);
255 
256  // Add to registered toolbars
257  registeredToolbars_.insert(_tool);
258  }
259 
260  _tool->show();
261  }
262  } else {
263  hidePickToolBar();
264  }
265 }
266 
267 //-----------------------------------------------------------------------------
268 
270 
271  // Hide all picking toolbars
272  for(PickToolBarMap::iterator it = curPickingToolbarItems_.begin();
273  it != curPickingToolbarItems_.end(); ++it) {
274  it->second->hide();
275  }
276 
277  // if a toolbar is in the global scene, we remove it here.
278  if ( pickToolBarExternal_ != 0 ) {
279  pickToolBarExternal_->hide();
280  pickToolBarExternal_ = NULL;
281  }
282 
283 
284 
285 
286 }
287 
288 //-----------------------------------------------------------------------------
289 
291 {
292  if (pickMenu_ != 0) {
293  pickMenu_->clear();
294  } else {
295  pickMenu_ = new QMenu( 0 );
296  connect( pickMenu_, SIGNAL( aboutToHide() ),
297  this, SLOT( hidePopupMenus() ) );
298  }
299 
300  QActionGroup * ag = new QActionGroup( pickMenu_ );
301  ag->setExclusive( true );
302 
303  for (unsigned int i=0; i<pick_modes_.size(); ++i) {
304  if ( !pick_modes_[i].visible() )
305  continue;
306 
307  if (pick_modes_[i].name() == "Separator")
308  {
309  if ((i > 0) && (i<pick_modes_.size()-1)) // not first, not last
310  pickMenu_->addSeparator();
311  }
312  else
313  {
314  QAction* ac = new QAction( pick_modes_[i].name().c_str(), ag );
315  ac->setData( QVariant( i ) );
316  ac->setCheckable( true );
317 
318  if ((int)i == pick_mode_idx_)
319  ac->setChecked( true );
320 
321  pickMenu_->addAction( ac );
322  }
323  }
324 
325  connect( ag, SIGNAL( triggered( QAction * ) ),
326  this, SLOT( actionPickMenu( QAction * ) ));
327 }
328 
329 //-----------------------------------------------------------------------------
330 
331 
332 void CoreWidget::actionPickMenu( QAction * _action )
333 {
334  int _id = _action->data().toInt();
335  if (_id < (int) pick_modes_.size() )
336  {
337  pickMode( _id );
338  }
339 
340  setPickingMode();
341 
342  hidePopupMenus();
343 }
344 
345 //-----------------------------------------------------------------------------
346 
347 
349 {
350 
351  if ( pickMenu_ )
352  {
353  pickMenu_->blockSignals(true);
354  pickMenu_->hide();
355  pickMenu_->blockSignals(false);
356  }
357 }
358 
359 //-----------------------------------------------------------------------------
360 
361 
362 void CoreWidget::pickMode( int _id )
363 {
364  if (_id < (int) pick_modes_.size() )
365  {
366  pick_mode_idx_ = _id;
368 
369  if (pick_modes_[pick_mode_idx_].toolbar() )
371  else
372  hidePickToolBar();
373 
374  // adjust mouse tracking
375  if ( pickingMode() )
376  for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
377  examiner_widgets_[i]->trackMouse(pick_modes_[pick_mode_idx_].tracking() );
378 
379  // adjust Cursor
380  if ( pickingMode() )
382 
383  // emit signal
385  }
386 }
387 
388 
389 //-----------------------------------------------------------------------------
390 
391 
392 void CoreWidget::addPickMode(const std::string& _name,
393  bool _tracking,
394  int _pos,
395  bool _visible,
396  QCursor _cursor)
397 {
398 
399  if ((unsigned int)_pos < pick_modes_.size())
400  {
401  std::vector<PickMode>::iterator it = pick_modes_.begin();
402  it += _pos+1;
403  pick_modes_.insert(it, PickMode(_name, _tracking, _visible, _cursor));
404  }
405  else
406  pick_modes_.push_back(PickMode(_name, _tracking, _visible, _cursor));
407 
408  updatePickMenu();
409 }
410 
411 //-----------------------------------------------------------------------------
412 
413 void CoreWidget::setPickModeCursor(const std::string& _name, QCursor _cursor)
414 {
415  for (uint i=0; i < pick_modes_.size(); i++)
416  if ( pick_modes_[i].name() == _name ){
417  pick_modes_[i].cursor( _cursor );
418 
419  //switch cursor if pickMode is active
420  if (pick_mode_name_ == _name && pickingMode() )
421  cursorPainter_->setCursor(_cursor);
422  break;
423  }
424 }
425 
426 //-----------------------------------------------------------------------------
427 
428 void CoreWidget::setPickModeMouseTracking(const std::string& _name, bool _mouseTracking)
429 {
430  for (uint i=0; i < pick_modes_.size(); i++)
431  if ( pick_modes_[i].name() == _name ){
432 
433  pick_modes_[i].tracking(_mouseTracking );
434 
435  //switch cursor if pickMode is active
436  if (pick_mode_name_ == _name && pickingMode() )
437  for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
438  examiner_widgets_[i]->trackMouse(_mouseTracking);
439  break;
440  }
441 }
442 
443 //-----------------------------------------------------------------------------
444 
445 void CoreWidget::setPickModeToolbar( const std::string& _mode , QToolBar * _toolbar )
446 {
447 
448  // Get the pickmode that belongs to the given name
449  for (uint i=0; i < pick_modes_.size(); i++)
450  if ( pick_modes_[i].name() == _mode ){
451 
452  // Set the new toolbar for that mode
453  pick_modes_[i].toolbar( _toolbar );
454 
455  // Activate the toolbar if this mode is currently active
456  if (pick_mode_name_ == _mode && pickingMode() )
457  setActivePickToolBar(_toolbar);
458 
459  break;
460  }
461 }
462 
463 //-----------------------------------------------------------------------------
464 
465 void CoreWidget::removePickModeToolbar( const std::string& _mode )
466 {
467  for (uint i=0; i < pick_modes_.size(); i++)
468  if ( pick_modes_[i].name() == _mode ){
469 
470  pick_modes_[i].toolbar(0);
471 
472  if (pick_mode_name_ == _mode && pickingMode() )
473  hidePickToolBar();
474  break;
475  }
476 }
477 
478 //-----------------------------------------------------------------------------
479 
481 {
482  pick_modes_.clear();
483  pick_mode_idx_ = -1;
484  pick_mode_name_ = "";
485  updatePickMenu();
486 }
487 
488 
489 //-----------------------------------------------------------------------------
490 
491 void CoreWidget::expandToolBoxWidget(QWidget *widget, bool expand) {
492  toolBox_->expand(widget, expand);
493 }
494 
495 
496 const std::string& CoreWidget::pickMode() const
497 {
498  return pick_mode_name_;
499 }
500 
501 
502 
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void setPickModeMouseTracking(const std::string &_name, bool _mouseTracking)
set mouseTracking for the pick mode
Definition: picking.cc:428
void hidePopupMenus()
Definition: picking.cc:348
void removePickModeToolbar(const std::string &_mode)
Removes the additional toolbar of the given PickMode.
Definition: picking.cc:465
void setPickModeToolbar(const std::string &_mode, QToolBar *_toolbar)
Set the additional toolbar of the given PickMode.
Definition: picking.cc:445
void actionPickMenu(QAction *_action)
Definition: picking.cc:332
void addPickMode(const std::string &_name, bool _mouse_tracking=false, int _pos=-1, bool _visible=true, QCursor _cursor=Qt::ArrowCursor)
add pick mode
Definition: picking.cc:392
CursorPainter * cursorPainter_
Cursor handling.
Definition: CoreWidget.hh:750
QToolButton * moveButton_
Called by Plugins to add a Toolbar.
Definition: CoreWidget.hh:826
Viewer::ActionMode actionMode_
Definition: CoreWidget.hh:1471
void setCursor(const QCursor &_cursor)
Sets the current used cursor.
QtGLGraphicsScene * glScene_
graphics scene used to paint gl context and widgets
Definition: CoreWidget.hh:710
void setActionMode(const Viewer::ActionMode _am)
Definition: picking.cc:62
SideArea * toolBox_
Toolbox.
Definition: CoreWidget.hh:734
void getPickMode(std::string &_name)
Definition: picking.cc:173
ActionMode
Enum listing action modes of the viewers.
void signalPickModeChanged(const std::string &)
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
Analyze the SceneGraph <ACG/Scenegraph/SceneGraphAnalysis.hh>
void setPickModeCursor(const std::string &_name, QCursor _cursor)
set a new cursor for the pick mode
Definition: picking.cc:413
Viewer::ActionMode lastActionMode_
Definition: CoreWidget.hh:1471
void setPickingMode()
Definition: CoreWidget.hh:1463
QMenu * pickMenu_
Definition: CoreWidget.hh:1572
QToolBar * pickToolBarExternal_
Extra toolbar not in scene for picking.
Definition: CoreWidget.hh:744
QToolButton * pickButton_
Called by Plugins to add a Toolbar.
Definition: CoreWidget.hh:827
Struct containing information about pickModes.
Definition: CoreWidget.hh:179
bool pickingMode()
Definition: CoreWidget.hh:1455
void setPickMode(const std::string &_name)
Definition: picking.cc:158
std::vector< PickMode > pick_modes_
Definition: CoreWidget.hh:1576
void expandToolBoxWidget(QWidget *widget, bool expand)
Definition: picking.cc:491
void setActivePickToolBar(QToolBar *_tool)
Set toolbar to be active pick toolbar.
Definition: picking.cc:179
void clearPickModes()
Definition: picking.cc:480
void getActionMode(Viewer::ActionMode &_am)
Definition: picking.cc:152
QToolButton * questionButton_
Called by Plugins to add a Toolbar.
Definition: CoreWidget.hh:828
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
std::vector< glViewer *> examiner_widgets_
Examiner Widget.
Definition: CoreWidget.hh:677
int pick_mode_idx_
Definition: CoreWidget.hh:1584
void hidePickToolBar()
Hide picking toolbar.
Definition: picking.cc:269
std::set< QToolBar * > registeredToolbars_
Store all toolbars that once have been registered.
Definition: CoreWidget.hh:747
void updatePickMenu()
update pick mode menu
Definition: picking.cc:290
PickToolBarMap curPickingToolbarItems_
Handle to picking toolbar.
Definition: CoreWidget.hh:741
std::string pick_mode_name_
Definition: CoreWidget.hh:1580
const std::string & pickMode() const
Definition: picking.cc:496
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node