picking.cc 15.1 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33 34 35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36 37 38 39 40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58




//=============================================================================
//
//  CLASS CoreWidget - IMPLEMENTATION
//
//=============================================================================


//== INCLUDES =================================================================

#include "CoreWidget.hh"

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/common/GlobalOptions.hh>
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
59
#include <OpenFlipper/widgets/glWidget/CursorPainter.hh>
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

//-----------------------------------------------------------------------------

void CoreWidget::setActionMode(const Viewer::ActionMode _am){
  if (_am != actionMode_) {
    lastActionMode_ = actionMode_;
    actionMode_ = _am;


    // update Buttons

    moveButton_->setDown(false);
    pickButton_->setDown(false);
    questionButton_->setDown(false);

    switch (_am)
    {
      case Viewer::ExamineMode:
        moveButton_->setDown(true);
        break;
      case Viewer::LightMode:
        break;
      case Viewer::PickingMode:
        pickButton_->setDown(true);
        break;
      case Viewer::QuestionMode:
        questionButton_->setDown(true);
        break;
    }

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
90 91 92 93
    // update cursor
    switch ( _am )
    {
      case Viewer::ExamineMode:
94
        cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_move.png"  ) ,0,0 ));
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
95
        break;
Jan Möbius's avatar
Jan Möbius committed
96
      case Viewer::LightMode:
97
        cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_light.png"  ) ,0,0 ));
Jan Möbius's avatar
Jan Möbius committed
98
        break;
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
99
      case Viewer::PickingMode:
100
        cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_arrow.png"  ) ,0,0 ));
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
101
        if (pick_mode_idx_ != -1) {
102
          cursorPainter_->setCursor(pick_modes_[pick_mode_idx_].cursor() );
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
103 104 105
        }
        break;
      case Viewer::QuestionMode:
106
        cursorPainter_->setCursor(QCursor( QPixmap( OpenFlipper::Options::iconDirStr() + QDir::separator() + "cursor_whatsthis.png"  ) ,0,0 ));
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
107 108
        break;
    }
109 110 111

    // Update pickmode toolbar
    switch ( _am ) {
112
      case Viewer::ExamineMode:
113
        hidePickToolBar();
114
        break;
115

116 117
      case Viewer::PickingMode:
        // Show the pickMode Toolbar for this picking mode if it is set
118 119
        if (pick_mode_idx_ != -1) {
          if (pick_modes_[pick_mode_idx_].toolbar() )
120
            setActivePickToolBar(pick_modes_[pick_mode_idx_].toolbar());
121
          else
122
            hidePickToolBar();
123 124
        }
        break;
125 126

      default:
127 128
        break;
    }
129

130 131
    //update Viewers
    for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i ) {
132

133 134
      examiner_widgets_[i]->sceneGraph( PluginFunctions::getSceneGraphRootNode() );
      examiner_widgets_[i]->trackMouse(false);
135 136 137 138 139 140

      if(_am == Viewer::PickingMode) {
          if (pick_mode_idx_ != -1) {
                examiner_widgets_[i]->trackMouse(pick_modes_[pick_mode_idx_].tracking() );
          }
      }
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
    }

    //emit pickmodeChanged with either the name of the current pickmode or an empty string
    if( pickingMode() )
      emit(signalPickModeChanged(pick_mode_name_));
    else
      emit(signalPickModeChanged(""));
  }
}

//-----------------------------------------------------------------------------

void CoreWidget::getActionMode(Viewer::ActionMode& _am){
  _am = actionMode_;
}

//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
159
void CoreWidget::setPickMode(const std::string& _mode){
160 161 162

  for (unsigned int i=0; i<pick_modes_.size(); ++i)
  {
163
    if (pick_modes_[i].name() == _mode)
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
    {
      pickMode( i );
      updatePickMenu();
      return;
    }
  }
}

//-----------------------------------------------------------------------------

void CoreWidget::getPickMode(std::string& _mode){
  _mode = pick_mode_name_;
}

//-----------------------------------------------------------------------------

180 181 182 183
void CoreWidget::setActivePickToolBar(QToolBar* _tool) {

    if(_tool != 0) {

184 185
      // Hide all picking toolbars
      hidePickToolBar();
186

187
      if ( OpenFlipperSettings().value("Core/Gui/ToolBars/PickToolbarInScene",false).toBool() ) {
188 189

        // Try to find toolbar in local map ( if it is in the gl scene
190 191
        PickToolBarMap::iterator ret = curPickingToolbarItems_.find(_tool);
        if(ret == curPickingToolbarItems_.end()) {
192 193 194 195 196 197 198 199

          // Set horizontal orientation
          _tool->setOrientation(Qt::Horizontal);

          // Update size as the orientation changed
          _tool->adjustSize();

          // Add widget to the gl scene
Jan Möbius's avatar
Jan Möbius committed
200
          QGraphicsProxyWidget* item = glScene_->addWidget(_tool);
201 202 203 204 205 206 207 208

          // Put it into center of the screen
          int midP = (glScene_->width() / 2) - (int)(_tool->width() / 2);
          item->setPos(midP, 3);

          item->show();

          // Remember it as being part of the scene
Jan Möbius's avatar
Jan Möbius committed
209
          curPickingToolbarItems_.insert(std::pair<QToolBar*,QGraphicsProxyWidget*>(_tool,item));
210
        } else {
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
          // Widget has already been added once, so just show it
          ret->second->show();
        }
      } else {

        // Try to find toolbar in local map
        // If its in there, we need to remove it from the graphics scene before adding it
        // to the side toolbar.
        PickToolBarMap::iterator ret = curPickingToolbarItems_.find(_tool);
        if(ret != curPickingToolbarItems_.end()) {

          glScene_->removeItem(ret->second);
          ret->first->setParent(0);

          // remove from list of widgets in glScene
          curPickingToolbarItems_.erase(ret);
227
        }
228 229 230

        pickToolBarExternal_ = _tool;

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
        // Check whether this toolbar has been displayed before
        if(registeredToolbars_.count(_tool) == 0) {

          /*
           * This code makes sure that the orientation and size
           * of a toolbar is only set once (the first time it is added).
           * In some cases, the user wants to move the toolbar somewhere
           * else and thus this check makes sure that it does not
           * loose its position and orientation after a pickmode change.
           */

          // Adjust its size and orientation
          pickToolBarExternal_->setOrientation(Qt::Vertical);
          pickToolBarExternal_->adjustSize();

          addToolBar(Qt::LeftToolBarArea,_tool);

          // Add to registered toolbars
          registeredToolbars_.insert(_tool);
        }

252 253
        _tool->show();
      }
254 255 256 257 258 259 260 261 262
    } else {
        hidePickToolBar();
    }
}

//-----------------------------------------------------------------------------

void CoreWidget::hidePickToolBar() {

263 264 265 266 267 268 269 270 271
  // Hide all picking toolbars
  for(PickToolBarMap::iterator it = curPickingToolbarItems_.begin();
      it != curPickingToolbarItems_.end(); ++it) {
    it->second->hide();
  }

  // if a toolbar is in the global scene, we remove it here.
  if ( pickToolBarExternal_ != 0 ) {
    pickToolBarExternal_->hide();
272
    pickToolBarExternal_ = NULL;
273 274 275 276 277
  }




278 279 280 281
}

//-----------------------------------------------------------------------------

282 283
void CoreWidget::updatePickMenu()
{
284 285 286 287 288 289 290
  if (pickMenu_ != 0) {
    pickMenu_->clear();
  } else {
    pickMenu_ = new QMenu( 0 );
    connect( pickMenu_, SIGNAL( aboutToHide() ),
         this, SLOT( hidePopupMenus() ) );
  }
291 292 293 294 295

  QActionGroup * ag = new QActionGroup( pickMenu_ );
  ag->setExclusive( true );

  for (unsigned int i=0; i<pick_modes_.size(); ++i) {
296
    if ( !pick_modes_[i].visible() )
297 298
      continue;

299
    if (pick_modes_[i].name() == "Separator")
300 301 302 303 304 305
    {
      if ((i > 0) && (i<pick_modes_.size()-1)) // not first, not last
        pickMenu_->addSeparator();
    }
    else
    {
306
      QAction* ac = new QAction( pick_modes_[i].name().c_str(), ag );
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
      ac->setData( QVariant( i ) );
      ac->setCheckable( true );

      if ((int)i == pick_mode_idx_)
        ac->setChecked( true );

      pickMenu_->addAction( ac );
    }
  }

  connect( ag, SIGNAL( triggered( QAction * ) ),
     this, SLOT( actionPickMenu( QAction * ) ));
}

//-----------------------------------------------------------------------------


void CoreWidget::actionPickMenu( QAction * _action )
{
  int _id = _action->data().toInt();
  if (_id < (int) pick_modes_.size() )
  {
    pickMode( _id );
  }

  setPickingMode();

  hidePopupMenus();
}

//-----------------------------------------------------------------------------


void CoreWidget::hidePopupMenus()
{

  if ( pickMenu_ )
  {
    pickMenu_->blockSignals(true);
    pickMenu_->hide();
    pickMenu_->blockSignals(false);
  }
}

//-----------------------------------------------------------------------------


void CoreWidget::pickMode( int _id )
{
  if (_id < (int) pick_modes_.size() )
  {
    pick_mode_idx_  = _id;
359
    pick_mode_name_ = pick_modes_[pick_mode_idx_].name();
360

361
    if (pick_modes_[pick_mode_idx_].toolbar() )
362
      setActivePickToolBar(pick_modes_[pick_mode_idx_].toolbar());
363
    else
364
      hidePickToolBar();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
365

366 367 368
    // adjust mouse tracking
    if ( pickingMode() )
      for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
369
        examiner_widgets_[i]->trackMouse(pick_modes_[pick_mode_idx_].tracking() );
370 371 372

    // adjust Cursor
    if ( pickingMode() )
373
        cursorPainter_->setCursor( pick_modes_[pick_mode_idx_].cursor() );
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407

    // emit signal
    emit(signalPickModeChanged(pick_mode_name_));
  }
}


//-----------------------------------------------------------------------------


void CoreWidget::addPickMode(const std::string& _name,
                               bool _tracking,
                               int  _pos,
                               bool _visible,
                               QCursor _cursor)
{

  if ((unsigned int)_pos < pick_modes_.size())
  {
    std::vector<PickMode>::iterator it = pick_modes_.begin();
    it += _pos+1;
    pick_modes_.insert(it, PickMode(_name, _tracking, _visible, _cursor));
  }
  else
    pick_modes_.push_back(PickMode(_name, _tracking, _visible, _cursor));

  updatePickMenu();
}

//-----------------------------------------------------------------------------

void CoreWidget::setPickModeCursor(const std::string& _name, QCursor _cursor)
{
  for (uint i=0; i < pick_modes_.size(); i++)
408
    if ( pick_modes_[i].name() == _name ){
409
      pick_modes_[i].cursor( _cursor );
410 411 412

      //switch cursor if pickMode is active
      if (pick_mode_name_ == _name && pickingMode() )
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
413
          cursorPainter_->setCursor(_cursor);
414 415 416 417 418 419 420 421 422
      break;
    }
}

//-----------------------------------------------------------------------------

void CoreWidget::setPickModeMouseTracking(const std::string& _name, bool _mouseTracking)
{
  for (uint i=0; i < pick_modes_.size(); i++)
423 424 425
    if ( pick_modes_[i].name() == _name ){

      pick_modes_[i].tracking(_mouseTracking );
426 427 428 429 430 431 432 433 434 435 436

      //switch cursor if pickMode is active
      if (pick_mode_name_ == _name && pickingMode() )
        for ( unsigned int i = 0 ; i < OpenFlipper::Options::examinerWidgets() ; ++i )
          examiner_widgets_[i]->trackMouse(_mouseTracking);
      break;
    }
}

//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
437
void CoreWidget::setPickModeToolbar( const std::string& _mode , QToolBar * _toolbar )
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
438
{
439
  // Get the pickmode that belongs to the given name
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
440
  for (uint i=0; i < pick_modes_.size(); i++)
441
    if ( pick_modes_[i].name() == _mode ){
442 443

      // Set the new toolbar for that mode
444
      pick_modes_[i].toolbar( _toolbar );
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
445

446
      // Activate the toolbar if this mode is currently active
447
      if (pick_mode_name_ == _mode && pickingMode() )
448
        setActivePickToolBar(_toolbar);
449

Jan Möbius's avatar
Dennis:  
Jan Möbius committed
450 451 452 453 454 455
      break;
    }
}

//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
456
void CoreWidget::removePickModeToolbar( const std::string& _mode )
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
457 458
{
  for (uint i=0; i < pick_modes_.size(); i++)
459 460 461
    if ( pick_modes_[i].name() == _mode ){

      pick_modes_[i].toolbar(0);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
462 463

      if (pick_mode_name_ == _mode && pickingMode() )
464
        hidePickToolBar();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
465 466 467 468 469
      break;
    }
}

//-----------------------------------------------------------------------------
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489

void CoreWidget::clearPickModes()
{
  pick_modes_.clear();
  pick_mode_idx_  = -1;
  pick_mode_name_ = "";
  updatePickMenu();
}


//-----------------------------------------------------------------------------


const std::string& CoreWidget::pickMode() const
{
  return pick_mode_name_;
}