TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/plugin/interact/InteractScene.cpp
Go to the documentation of this file.
00001 #include "InteractScene.hpp"
00002 #include "overlay.hpp"
00003 
00004 #include <tuttle/plugin/ofxToGil/point.hpp>
00005 #include <tuttle/plugin/global.hpp>
00006 
00007 namespace tuttle {
00008 namespace plugin {
00009 namespace interact {
00010 
00011 
00012 InteractScene::InteractScene( OFX::ParamSet& params, const InteractInfos& infos )
00013         : _params( params )
00014         , _infos( infos )
00015         , _mouseDown( false )
00016         , _multiSelectionEnabled( true )
00017         , _creatingSelection( false )
00018         , _manipulator( NULL )
00019         , _manipulatorColor( NULL )
00020         , _hasSelection( false )
00021 {
00022         _selectionRect.x1 = _selectionRect.y1 = _selectionRect.x2 = _selectionRect.y2 = .0;
00023 }
00024 
00025 InteractScene::~InteractScene()
00026 {}
00027 
00028 bool InteractScene::draw( const OFX::DrawArgs& args ) const
00029 {
00030         bool result = false;
00031 
00032         result |= drawSelection( args );
00033 
00034         IsActiveFunctorVector::const_iterator itActive = _isActive.begin();
00035         ColorVector::const_iterator itColor = _colors.begin();
00036 
00037         for( InteractObjectsVector::const_iterator it = _objects.begin(), itEnd = _objects.end();
00038              it != itEnd;
00039              ++it, ++itActive, ++itColor )
00040         {
00041                 if( itActive->active() )
00042                 {
00043                         OfxRGBAColourD color = itColor->getColor( args.time );
00044                         glColor4d( color.r, color.g, color.b, color.a );
00045                         result |= it->draw( args );
00046                 }
00047         }
00048         return result;
00049 }
00050 
00051 bool InteractScene::penMotion( const OFX::PenArgs& args )
00052 {
00053         if( !_mouseDown )
00054                 return false;
00055 
00056         if( _creatingSelection )
00057         {
00058                 // create selection
00059 
00060                 TUTTLE_TLOG( TUTTLE_TRACE, "create a selection" );
00061                 _selectionRect.x2 = args.penPosition.x;
00062                 _selectionRect.y2 = args.penPosition.y;
00063                 _hasSelection = false;
00064 
00065                 IsActiveFunctorVector::iterator itActive = _isActive.begin();
00066                 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end();
00067                          it != itEnd;
00068                          ++it, ++itActive )
00069                 {
00070                         if( ! itActive->active() )
00071                                 continue;
00072                         if( it->isIn( _selectionRect ) )
00073                         {
00074                                 it->setSelected(true);
00075                                 _hasSelection = true;
00076                         }
00077                         else
00078                         {
00079                                 it->setSelected(false);
00080                         }
00081                 }
00082                 return true;
00083         }
00084 
00085         if( _selected.size() == 0 )
00086         {
00087                 TUTTLE_LOG_INFOS;
00088                 return false;
00089         }
00090 
00091         const Point2 penPosition = ofxToGil( args.penPosition );
00092         switch( _motionType._mode )
00093         {
00094                 case eMotionTranslate:
00095                 {
00096                         translate( penPosition - _beginPenPosition );
00097                         break;
00098                 }
00099                 case eMotionRotate:
00100                 {
00101                         if( _manipulator )
00102                         {
00103                                 rotate( _manipulator->getPosition(), penPosition, penPosition - _beginPenPosition );
00104                         }
00105                         break;
00106                 }
00107                 case eMotionScale:
00108                 {
00109                         if( _manipulator )
00110                                 scale( _manipulator->getPosition(), penPosition - _beginPenPosition );
00111                         break;
00112                 }
00113                 case eMotionNone:
00114                 {
00115                         TUTTLE_LOG_INFOS;
00116                         break;
00117                 }
00118         }
00119         return true;
00120 }
00121 
00122 bool InteractScene::penDown( const OFX::PenArgs& args )
00123 {
00124         //TUTTLE_LOG_TRACE("penDown");
00125         const Point2 penPosition = ofxToGil( args.penPosition );
00126         _mouseDown = true;
00127         _beginPenPosition = penPosition;
00128         _selectionRect.x1 = args.penPosition.x;
00129         _selectionRect.y1 = args.penPosition.y;
00130         _selectionRect.x2 = args.penPosition.x;
00131         _selectionRect.y2 = args.penPosition.y;
00132         _motionType._mode = eMotionNone;
00133         _motionType._axis = eAxisNone;
00134 
00135         bool result = false;
00136         SelectedObject oneSelectedObj;
00137 
00138         if( _hasSelection && _manipulator )
00139         {
00140                 _motionType = _manipulator->intersect( args );
00141                 if( _motionType._mode != eMotionNone )
00142                 {
00143                         result = true;
00144                 }
00145         }
00146         if( !result )
00147         {
00148                 IsActiveFunctorVector::iterator itActive = _isActive.begin();
00149                 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end();
00150                          it != itEnd;
00151                          ++it, ++itActive )
00152                 {
00153                         if( ! itActive->active() )
00154                                 continue;
00155                         MotionType m = it->intersect( args );
00156                         if( m._axis != eAxisNone )
00157                         {
00158                                 // first time
00159                                 if( _motionType._axis == eAxisNone )
00160                                 {
00161                                         oneSelectedObj = SelectedObject( &(*it), it->getPosition() );
00162                                         _motionType = m;
00163                                 }
00164                                 else if( m._axis == eAxisXY ) // if we already register an object X or Y and we found an XY intersection
00165                                 {
00166                                         oneSelectedObj = SelectedObject( &(*it), it->getPosition() );
00167                                         _motionType = m;
00168                                 }
00169                                 result = true;
00170                                 if( m._axis == eAxisXY )
00171                                         break;
00172                         }
00173                 }
00174         }
00175 
00176         if( _hasSelection )
00177         {
00178                 if( result )
00179                 {
00180                         bool objInSelection = false;
00181                         // compute the offset for each object
00182                         for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end();
00183                                  it != itEnd;
00184                                  ++it )
00185                         {
00186                                 it->second = it->first->getPosition();
00187                                 if( it->first == oneSelectedObj.first )
00188                                 {
00189                                         objInSelection = true;
00190                                 }
00191                         }
00192                         if( !objInSelection )
00193                         {
00194                                 _hasSelection = false;
00195                         }
00196                 }
00197                 else
00198                 {
00199                         _hasSelection = false;
00200                 }
00201         }
00202         if( ! _hasSelection )
00203         {
00204                 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end();
00205                          it != itEnd;
00206                          ++it )
00207                 {
00208                         it->setSelected(false);
00209                 }
00210                 _selected.clear();
00211                 if( result )
00212                 {
00213                         _selected.push_back( oneSelectedObj );
00214                 }
00215         }
00216 
00217         if( _multiSelectionEnabled )
00218         {
00219                 if( !result )
00220                 {
00221                         _hasSelection = false;
00222                         _creatingSelection = true;
00223                 }
00224         }
00225         
00226         if( _multiSelectionEnabled || result )
00227         {
00228                 _params.beginEditBlock( "InteractObjectsGroup" );
00229                 return true;
00230         }
00231         return false;
00232 }
00233 
00234 
00235 bool InteractScene::penUp( const OFX::PenArgs& args )
00236 {
00237         //TUTTLE_LOG_TRACE("penUp");
00238         bool result = false;
00239 
00240         if( _creatingSelection )
00241         {
00242                 _selectionRect.x2 = args.penPosition.x;
00243                 _selectionRect.y2 = args.penPosition.y;
00244 
00245                 _selected.clear();
00246                 //TUTTLE_LOG_VAR4( TUTTLE_TRACE, _selectionRect.x1, _selectionRect.y1, _selectionRect.x2, _selectionRect.y2 );
00247                 IsActiveFunctorVector::iterator itActive = _isActive.begin();
00248                 for( InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end();
00249                          it != itEnd;
00250                          ++it, ++itActive )
00251                 {
00252                         if( ! itActive->active() )
00253                                 continue;
00254                         if( it->isIn( _selectionRect ) )
00255                         {
00256                                 it->setSelected(true);
00257                                 _selected.push_back( SelectedObject( &(*it), it->getPosition() ) );
00258                                 _hasSelection = true;
00259                                 result = true;
00260                         }
00261                         else
00262                         {
00263                                 it->setSelected(false);
00264                         }
00265                 }
00266                 //TUTTLE_LOG_VAR( TUTTLE_TRACE, _selected.size() );
00267                 _creatingSelection = false;
00268         }
00269 
00270         _mouseDown = false;
00271         _creatingSelection = false;
00272         
00273         _params.endEditBlock();
00274 
00275         return result;
00276 }
00277 
00278 bool InteractScene::drawSelection( const OFX::DrawArgs& args ) const
00279 {
00280         bool result = false;
00281         if( _creatingSelection )
00282         {
00283                 glColor4d( 1.0, 1.0, 1.0, 0.5 );
00284                 overlay::displayRect( _selectionRect );
00285                 glColor4d( 1.0, 1.0, 1.0, 1.0 );
00286                 result = true;
00287         }
00288         else if( _hasSelection && _manipulator )
00289         {
00290                 if( _manipulatorColor )
00291                 {
00292                         OfxRGBAColourD color = _manipulatorColor->getColor( args.time );
00293                         glColor4d( color.r, color.g, color.b, color.a );
00294                 }
00295                 result |= _manipulator->draw( args );
00296         }
00297         return result;
00298 }
00299 
00300 void InteractScene::translate( const Point2& vec )
00301 {
00302         //TUTTLE_LOG_VAR2( TUTTLE_TRACE, vec.x, vec.y );
00303         Point2 newVec = vec;
00304         switch( _motionType._axis )
00305         {
00306                 case eAxisXY:
00307                 {
00308                         break;
00309                 }
00310                 case eAxisX:
00311                 {
00312                         newVec.y = 0;
00313                         break;
00314                 }
00315                 case eAxisY:
00316                 {
00317                         newVec.x = 0;
00318                         break;
00319                 }
00320                 case eAxisNone:
00321                 {
00322                         break;
00323                 }
00324         }
00325         for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end();
00326                  it != itEnd;
00327                  ++it )
00328         {
00329                 it->first->translate( it->second, newVec );
00330         }
00331 }
00332 
00333 void InteractScene::rotate( const Point2& center, const Point2& from, const Point2& vec )
00334 {
00335         for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end();
00336                  it != itEnd;
00337                  ++it )
00338         {
00339                 it->first->rotate( it->second, center, from, vec );
00340         }
00341 }
00342 
00343 void InteractScene::scale( const Point2& center, const Point2& factor )
00344 {
00345         Point2 newFactor = factor;
00346         switch( _motionType._axis )
00347         {
00348                 case eAxisXY:
00349                 {
00350                         break;
00351                 }
00352                 case eAxisX:
00353                 {
00354                         newFactor.y = 0;
00355                         break;
00356                 }
00357                 case eAxisY:
00358                 {
00359                         newFactor.x = 0;
00360                         break;
00361                 }
00362                 case eAxisNone:
00363                 {
00364                         break;
00365                 }
00366         }
00367         for( SelectedObjectVector::iterator it = _selected.begin(), itEnd = _selected.end();
00368                  it != itEnd;
00369                  ++it )
00370         {
00371                 it->first->scale( it->second, center, factor );
00372         }
00373 }
00374 
00375 }
00376 }
00377 }