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