TuttleOFX
1
|
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