TuttleOFX  1
TuttleOFX/libraries/tuttle/src/tuttle/plugin/interact/ParamRectangleFromTwoCorners.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_PLUGIN_INTERACT_PARAMRECTANGLEFROMTWOCORNERS_HPP_
00002 #define _TUTTLE_PLUGIN_INTERACT_PARAMRECTANGLEFROMTWOCORNERS_HPP_
00003 
00004 #include "Frame.hpp"
00005 #include "InteractInfos.hpp"
00006 #include "InteractObject.hpp"
00007 #include "PointInteract.hpp"
00008 #include "overlay.hpp"
00009 #include <terry/globals.hpp>
00010 #include <tuttle/plugin/ofxToGil/point.hpp>
00011 #include <ofxsParam.h>
00012 
00013 namespace tuttle {
00014 namespace plugin {
00015 namespace interact {
00016 
00017 template<class TFrame, ECoordinateSystem coord>
00018 class ParamRectangleFromTwoCorners : public PointInteract
00019 {
00020 public:
00021         ParamRectangleFromTwoCorners( const InteractInfos& infos, OFX::Double2DParam* paramA, OFX::Double2DParam* paramB, const TFrame& relativeClip );
00022         ~ParamRectangleFromTwoCorners();
00023 
00024 private:
00025         OFX::Double2DParam* _paramA; ///< same as TL (min)
00026         OFX::Double2DParam* _paramB; ///< same as BR (max)
00027         TFrame _relativeFrame;
00028 
00029         /**
00030          *         T
00031          *  TL___________ TR
00032          *    |         |
00033          * L  |    C    |  R
00034          *    |         |
00035          *    |_________|
00036          *  BL           BR
00037          *         B
00038          */
00039         enum ESelectType
00040         {
00041                 eSelectTypeNone,
00042                 eSelectTypeT,
00043                 eSelectTypeL,
00044                 eSelectTypeR,
00045                 eSelectTypeB,
00046                 eSelectTypeTL,
00047                 eSelectTypeTR,
00048                 eSelectTypeBL,
00049                 eSelectTypeBR,
00050                 eSelectTypeC
00051         };
00052         ESelectType _selectType;
00053 
00054 public:
00055         bool draw( const OFX::DrawArgs& args ) const;
00056 
00057         ESelectType selectType( const OFX::PenArgs& args ) const;
00058 
00059         MotionType intersect( const OFX::PenArgs& args );
00060         bool      isIn( const OfxRectD& );
00061 
00062         Point2 getPoint() const
00063         {
00064                 if( !_relativeFrame.isEnabled() )
00065                         return Point2( 0, 0 ); // throw to stop overlay ?
00066                 OfxRectD rod = _relativeFrame.getFrame( this->getTime() );
00067                 Point2 rodSize( rod.x2 - rod.x1, rod.y2 - rod.y1 );
00068                 return pointNormalizedXXcToCanonicalXY( ofxToGil( ( _paramB->getValue() + _paramA->getValue() ) * 0.5 ), rodSize ) + Point2( rod.x1, rod.y1 );
00069         }
00070 
00071         void setPoint( const Scalar x, const Scalar y )
00072         {
00073                 OfxRectD imgRod = _relativeFrame.getFrame( this->getTime() );
00074                 Point2 imgRodSize( imgRod.x2 - imgRod.x1, imgRod.y2 - imgRod.y1 );
00075                 Point2 mouse( x - imgRod.x1, y - imgRod.y1 );
00076 
00077                 mouse = pointCanonicalXYToNormalizedXXc( mouse, imgRodSize );
00078                 Point2 currentPos = pointCanonicalXYToNormalizedXXc( getPoint(), imgRodSize );
00079                 OfxPointD pA      = _paramA->getValue();
00080                 OfxPointD pB      = _paramB->getValue();
00081                 switch( _selectType )
00082                 {
00083                         case eSelectTypeT:
00084                         {
00085                                 _paramB->setValue( pB.x, mouse.y );
00086                                 break;
00087                         }
00088                         case eSelectTypeL:
00089                         {
00090                                 _paramA->setValue( mouse.x, pA.y );
00091                                 break;
00092                         }
00093                         case eSelectTypeR:
00094                         {
00095                                 _paramB->setValue( mouse.x, pB.y );
00096                                 break;
00097                         }
00098                         case eSelectTypeB:
00099                         {
00100                                 _paramA->setValue( pA.x, mouse.y );
00101                                 break;
00102                         }
00103                         case eSelectTypeTL:
00104                         {
00105                                 _paramA->setValue( mouse.x, pA.y );
00106                                 _paramB->setValue( pB.x, mouse.y );
00107                                 break;
00108                         }
00109                         case eSelectTypeTR:
00110                         {
00111                                 _paramB->setValue( mouse.x, mouse.y );
00112                                 break;
00113                         }
00114                         case eSelectTypeBL:
00115                         {
00116                                 _paramA->setValue( mouse.x, mouse.y );
00117                                 break;
00118                         }
00119                         case eSelectTypeBR:
00120                         {
00121                                 _paramA->setValue( pA.x, mouse.y );
00122                                 _paramB->setValue( mouse.x, pB.y );
00123                                 break;
00124                         }
00125                         case eSelectTypeC:
00126                         {
00127                                 Point2 shift = mouse - currentPos;
00128                                 _paramA->setValue( pA.x + shift.x, pA.y + shift.y );
00129                                 _paramB->setValue( pB.x + shift.x, pB.y + shift.y );
00130                                 break;
00131                         }
00132                         case eSelectTypeNone:
00133                         {
00134                                 assert( false );
00135                                 break;
00136                         }
00137                 }
00138         }
00139 
00140 };
00141 
00142 template<class TFrame, ECoordinateSystem coord>
00143 ParamRectangleFromTwoCorners<TFrame, coord>::ParamRectangleFromTwoCorners( const InteractInfos& infos, OFX::Double2DParam* paramA, OFX::Double2DParam* paramB, const TFrame& relativeFrame )
00144         : PointInteract( infos )
00145         , _paramA( paramA )
00146         , _paramB( paramB )
00147         , _relativeFrame( relativeFrame )
00148 {}
00149 
00150 template<class TFrame, ECoordinateSystem coord>
00151 ParamRectangleFromTwoCorners<TFrame, coord>::~ParamRectangleFromTwoCorners() {}
00152 
00153 template<class TFrame, ECoordinateSystem coord>
00154 bool ParamRectangleFromTwoCorners<TFrame, coord>::draw( const OFX::DrawArgs& args ) const
00155 {
00156         PointInteract::draw( args );
00157         OfxRectD rod = _relativeFrame.getFrame( this->getTime() );
00158         Point2 rodSize( rod.x2 - rod.x1, rod.y2 - rod.y1 );
00159         Point2 pA( pointNormalizedXXcToCanonicalXY( ofxToGil( _paramA->getValue() ), rodSize ) + Point2( rod.x1, rod.y1 ) );
00160         Point2 pB( pointNormalizedXXcToCanonicalXY( ofxToGil( _paramB->getValue() ), rodSize ) + Point2( rod.x1, rod.y1 ) );
00161         overlay::displayRect( pA, pB );
00162         return true;
00163 }
00164 
00165 template<class TFrame, ECoordinateSystem coord>
00166 typename ParamRectangleFromTwoCorners<TFrame, coord>::ESelectType ParamRectangleFromTwoCorners<TFrame, coord>::selectType( const OFX::PenArgs& args ) const
00167 {
00168         const Point2 p        = ofxToGil( args.penPosition );
00169         double scale          = args.pixelScale.x;
00170         double margeCanonical = getMarge() * scale;
00171         OfxRectD rod          = _relativeFrame.getFrame( this->getTime() );
00172         Point2 rodSize( rod.x2 - rod.x1, rod.y2 - rod.y1 );
00173         Point2 a = pointNormalizedXXcToCanonicalXY( ofxToGil( _paramA->getValue() ), rodSize ) + Point2( rod.x1, rod.y1 );
00174         Point2 b = pointNormalizedXXcToCanonicalXY( ofxToGil( _paramB->getValue() ), rodSize ) + Point2( rod.x1, rod.y1 );
00175         Point2 min, max;
00176 
00177         min.x = std::min( a.x, b.x );
00178         min.y = std::min( a.y, b.y );
00179         max.x = std::max( a.x, b.x );
00180         max.y = std::max( a.y, b.y );
00181 
00182         if( std::abs( a.x - p.x ) < margeCanonical )
00183         {
00184                 if( std::abs( b.y - p.y ) < margeCanonical )
00185                         return eSelectTypeTL;
00186                 else if( std::abs( a.y - p.y ) < margeCanonical )
00187                         return eSelectTypeBL;
00188                 else if( p.y > min.y && p.y < max.y )
00189                         return eSelectTypeL;
00190         }
00191         else if( std::abs( b.x - p.x ) < margeCanonical )
00192         {
00193                 if( std::abs( a.y - p.y ) < margeCanonical )
00194                         return eSelectTypeBR;
00195                 else if( std::abs( b.y - p.y ) < margeCanonical )
00196                         return eSelectTypeTR;
00197                 else if( p.y > min.y && p.y < max.y )
00198                         return eSelectTypeR;
00199         }
00200         else if( std::abs( b.y - p.y ) < margeCanonical && p.x > min.x && p.x < max.x )
00201                 return eSelectTypeT;
00202         else if( std::abs( a.y - p.y ) < margeCanonical && p.x > min.x && p.x < max.x )
00203                 return eSelectTypeB;
00204         return eSelectTypeNone;
00205 }
00206 
00207 template<class TFrame, ECoordinateSystem coord>
00208 MotionType ParamRectangleFromTwoCorners<TFrame, coord>::intersect( const OFX::PenArgs& args )
00209 {
00210         MotionType m;
00211         m._mode = eMotionTranslate;
00212         _selectType     = selectType( args );
00213         if( _selectType != eSelectTypeNone )
00214         {
00215                 m._axis = eAxisXY;
00216                 return m;
00217         }
00218         m = PointInteract::intersect( args );
00219         if( m._axis != eAxisNone )
00220         {
00221                 _selectType = eSelectTypeC;
00222         }
00223         return m;
00224 }
00225 
00226 template<class TFrame, ECoordinateSystem coord>
00227 bool ParamRectangleFromTwoCorners<TFrame, coord>::isIn( const OfxRectD& rect )
00228 {
00229         _selectType = eSelectTypeNone;
00230         const OfxRectD rod = _relativeFrame.getFrame( this->getTime() );
00231         Point2 rodSize( rod.x2 - rod.x1, rod.y2 - rod.y1 );
00232         Point2 a = pointNormalizedXXcToCanonicalXY( ofxToGil( _paramA->getValue() ), rodSize ) + Point2( rod.x1, rod.y1 );
00233         Point2 b = pointNormalizedXXcToCanonicalXY( ofxToGil( _paramB->getValue() ), rodSize ) + Point2( rod.x1, rod.y1 );
00234         Point2 min, max;
00235         min.x = std::min( a.x, b.x );
00236         min.y = std::min( a.y, b.y );
00237         max.x = std::max( a.x, b.x );
00238         max.y = std::max( a.y, b.y );
00239         if( rect.x1 <= min.x  && rect.x2 >= max.x &&
00240             rect.y1 <= min.y  && rect.y2 >= max.y )
00241         {
00242                 return true;
00243         }
00244         return false;
00245 }
00246 
00247 }
00248 }
00249 }
00250 
00251 #endif
00252