TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/plugin/interact/ParamRectangleFromCenterSize.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_PLUGIN_INTERACT_PARAMRECTANGLEFROMCENTERSIZE_HPP_
00002 #define _TUTTLE_PLUGIN_INTERACT_PARAMRECTANGLEFROMCENTERSIZE_HPP_
00003 
00004 #include "InteractObject.hpp"
00005 #include "PointInteract.hpp"
00006 #include "ParamPoint.hpp"
00007 #include "overlay.hpp"
00008 #include <terry/globals.hpp>
00009 #include <tuttle/plugin/ofxToGil/point.hpp>
00010 
00011 #include <ofxsParam.h>
00012 
00013 #include <boost/lexical_cast.hpp>
00014 
00015 namespace tuttle {
00016 namespace plugin {
00017 namespace interact {
00018 
00019 template<ECoordinateSystem coord>
00020 struct CoordinateSystemNotCentered
00021 {
00022         static const ECoordinateSystem value = coord;
00023 };
00024 template<>
00025 struct CoordinateSystemNotCentered<eCoordinateSystemXXcn>
00026 {
00027         static const ECoordinateSystem value = eCoordinateSystemXXn;
00028 };
00029 template<>
00030 struct CoordinateSystemNotCentered<eCoordinateSystemXYc>
00031 {
00032         static const ECoordinateSystem value = eCoordinateSystemXYc;
00033 };
00034 
00035 template<class TFrame, ECoordinateSystem coord>
00036 class ParamRectangleFromCenterSize : public PointInteract
00037 {
00038 public:
00039         ParamRectangleFromCenterSize( const InteractInfos& infos, OFX::Double2DParam* paramCenter, OFX::Double2DParam* paramSize, const TFrame& frame );
00040         ~ParamRectangleFromCenterSize();
00041 
00042 private:
00043         ParamPoint<TFrame, coord> _center;
00044         ParamPoint<TFrame, CoordinateSystemNotCentered<coord>::value> _size;
00045         TFrame _frame;
00046 
00047         /**
00048          *         T
00049          *  TL___________ TR
00050          *    |         |
00051          * L  |    C    |  R
00052          *    |         |
00053          *    |_________|
00054          *  BL           BR
00055          *         B
00056          */
00057         enum ESelectType
00058         {
00059                 eSelectTypeNone,
00060                 eSelectTypeT,
00061                 eSelectTypeL,
00062                 eSelectTypeR,
00063                 eSelectTypeB,
00064                 eSelectTypeTL,
00065                 eSelectTypeTR,
00066                 eSelectTypeBL,
00067                 eSelectTypeBR,
00068                 eSelectTypeC
00069         };
00070         static std::string mapESelectTypeToString( const ESelectType& s )
00071         {
00072                 switch( s )
00073                 {
00074                         case eSelectTypeNone:
00075                                 return "eSelectTypeNone";
00076                         case eSelectTypeT:
00077                                 return "eSelectTypeT";
00078                         case eSelectTypeL:
00079                                 return "eSelectTypeL";
00080                         case eSelectTypeR:
00081                                 return "eSelectTypeR";
00082                         case eSelectTypeB:
00083                                 return "eSelectTypeB";
00084                         case eSelectTypeTL:
00085                                 return "eSelectTypeTL";
00086                         case eSelectTypeTR:
00087                                 return "eSelectTypeTR";
00088                         case eSelectTypeBL:
00089                                 return "eSelectTypeBL";
00090                         case eSelectTypeBR:
00091                                 return "eSelectTypeBR";
00092                         case eSelectTypeC:
00093                                 return "eSelectTypeC";
00094                 }
00095                 BOOST_THROW_EXCEPTION( std::invalid_argument( "ESelectType: " + boost::lexical_cast<std::string>( s ) ) );
00096                 return "";
00097         }
00098 
00099         ESelectType _selectType;
00100 
00101 public:
00102         bool draw( const OFX::DrawArgs& args ) const;
00103 
00104         ESelectType selectType( const OFX::PenArgs& args ) const;
00105 
00106         MotionType intersect( const OFX::PenArgs& args );
00107         bool      isIn( const OfxRectD& );
00108 
00109         Point2 getPoint() const
00110         {
00111                 return _center.getPoint();
00112         }
00113 
00114         void setPoint( const Scalar x, const Scalar y )
00115         {
00116                 if( _selectType == eSelectTypeC )
00117                         return _center.setPoint( x, y );
00118 
00119                 Point2 pCenter = _center.getPoint();
00120                 Point2 pSize   = _size.getPoint();
00121 
00122                 OfxRectD frameRect = _frame.getFrame( this->getTime() );
00123                 Point2 mouse( x - frameRect.x1, y - frameRect.y1 ); // relative to frame
00124                 mouse = mouse - pCenter; // relative to pointCenter
00125                 switch( _selectType )
00126                 {
00127                         case eSelectTypeL:
00128                         {
00129                                 _size.setPoint( std::abs( mouse.x ), pSize.y );
00130                                 break;
00131                         }
00132                         case eSelectTypeR:
00133                         {
00134                                 _size.setPoint( std::abs( mouse.x ), pSize.y );
00135                                 break;
00136                         }
00137                         case eSelectTypeT:
00138                         {
00139                                 _size.setPoint( pSize.x, std::abs( mouse.y ) );
00140                                 break;
00141                         }
00142                         case eSelectTypeB:
00143                         {
00144                                 _size.setPoint( pSize.x, std::abs( mouse.y ) );
00145                                 break;
00146                         }
00147                         case eSelectTypeTL:
00148                         {
00149                                 // todo
00150                                 break;
00151                         }
00152                         case eSelectTypeTR:
00153                         {
00154                                 // todo
00155                                 break;
00156                         }
00157                         case eSelectTypeBL:
00158                         {
00159                                 // todo
00160                                 break;
00161                         }
00162                         case eSelectTypeBR:
00163                         {
00164                                 // todo
00165                                 break;
00166                         }
00167                         case eSelectTypeC:
00168                         {
00169                                 assert( false );
00170                                 break;
00171                         }
00172                         case eSelectTypeNone:
00173                         {
00174                                 assert( false );
00175                                 break;
00176                         }
00177                 }
00178         }
00179 
00180 };
00181 
00182 template<class TFrame, ECoordinateSystem coord>
00183 ParamRectangleFromCenterSize<TFrame, coord>::ParamRectangleFromCenterSize( const InteractInfos& infos, OFX::Double2DParam* paramCenter, OFX::Double2DParam* paramSize, const TFrame& frame )
00184         : PointInteract( infos )
00185         , _center( infos, paramCenter, frame )
00186         , _size( infos, paramSize, frame )
00187         , _frame( frame )
00188 {}
00189 
00190 template<class TFrame, ECoordinateSystem coord>
00191 ParamRectangleFromCenterSize<TFrame, coord>::~ParamRectangleFromCenterSize() {}
00192 
00193 template<class TFrame, ECoordinateSystem coord>
00194 bool ParamRectangleFromCenterSize<TFrame, coord>::draw( const OFX::DrawArgs& args ) const
00195 {
00196         _center.draw( args );
00197         overlay::displayPointRect( _center.getPoint(), _size.getPoint() );
00198         return true;
00199 }
00200 
00201 template<class TFrame, ECoordinateSystem coord>
00202 typename ParamRectangleFromCenterSize<TFrame, coord>::ESelectType ParamRectangleFromCenterSize<TFrame, coord>::selectType( const OFX::PenArgs& args ) const
00203 {
00204         const Point2 p              = ofxToGil( args.penPosition );
00205         const double margeCanonical = this->getMarge() * args.pixelScale.x;
00206 
00207         TUTTLE_LOG_VAR( TUTTLE_TRACE, this->getMarge() );
00208         TUTTLE_LOG_VAR( TUTTLE_TRACE, args.pixelScale.x );
00209         TUTTLE_LOG_VAR( TUTTLE_TRACE, margeCanonical );
00210         const OfxRectD rod = _frame.getFrame( this->getTime() );
00211         //const Point2 rodSize( rod.x2 - rod.x1, rod.y2 - rod.y1 );
00212         const Point2 pCenter = _center.getPoint();
00213         const Point2 pSize   = _size.getPoint();
00214         const Point2 min     = pCenter - pSize;
00215         const Point2 max     = pCenter + pSize;
00216 
00217         if( std::abs( min.x - p.x ) < margeCanonical ) // left
00218         {
00219                 if( std::abs( min.y - p.y ) < margeCanonical ) // top
00220                         return eSelectTypeTL;
00221                 else if( std::abs( max.y - p.y ) < margeCanonical ) // bottom
00222                         return eSelectTypeBL;
00223                 else if( p.y > min.y && p.y < max.y )
00224                         return eSelectTypeL;
00225         }
00226         else if( std::abs( max.x - p.x ) < margeCanonical ) // right
00227         {
00228                 if( std::abs( max.y - p.y ) < margeCanonical ) // bottom
00229                         return eSelectTypeBR;
00230                 else if( std::abs( min.y - p.y ) < margeCanonical ) // top
00231                         return eSelectTypeTR;
00232                 else if( p.y > min.y && p.y < max.y )
00233                         return eSelectTypeR;
00234         }
00235         else if( std::abs( min.y - p.y ) < margeCanonical && p.x > min.x && p.x < max.x )
00236                 return eSelectTypeT;
00237         else if( std::abs( max.y - p.y ) < margeCanonical && p.x > min.x && p.x < max.x )
00238                 return eSelectTypeB;
00239         return eSelectTypeNone;
00240 }
00241 
00242 template<class TFrame, ECoordinateSystem coord>
00243 MotionType ParamRectangleFromCenterSize<TFrame, coord>::intersect( const OFX::PenArgs& args )
00244 {
00245         // intersect center point
00246         MotionType m = _center.intersect( args );
00247         if( m._mode != eMotionNone )
00248         {
00249                 TUTTLE_TLOG( TUTTLE_TRACE, "intersect center." );
00250                 _selectType = eSelectTypeC;
00251                 return m;
00252         }
00253         // intersect borders
00254         _selectType = selectType( args );
00255         TUTTLE_TLOG( TUTTLE_TRACE, "_selectType : " << mapESelectTypeToString( _selectType ) );
00256         if( _selectType != eSelectTypeNone )
00257         {
00258                 m._mode = eMotionTranslate;
00259                 m._axis = eAxisXY;
00260                 return m;
00261         }
00262         m._mode = eMotionNone;
00263         m._axis = eAxisNone;
00264         return m;
00265 }
00266 
00267 template<class TFrame, ECoordinateSystem coord>
00268 bool ParamRectangleFromCenterSize<TFrame, coord>::isIn( const OfxRectD& rect )
00269 {
00270         _selectType = eSelectTypeNone;
00271         Point2 pCenter = _center.getPoint();
00272         Point2 pSize   = _size.getPoint();
00273         Point2 min     = pCenter - pSize;
00274         Point2 max     = pCenter + pSize;
00275         if( rect.x1 <= min.x  && rect.x2 >= max.x &&
00276             rect.y1 <= min.y  && rect.y2 >= max.y )
00277         {
00278                 return true;
00279         }
00280         return false;
00281 }
00282 
00283 }
00284 }
00285 }
00286 
00287 #endif
00288