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