TuttleOFX  1
ofxsInteract.h
Go to the documentation of this file.
00001 #ifndef _ofxsInteract_H_
00002 #define _ofxsInteract_H_
00003 /*
00004  * OFX Support Library, a library that skins the OFX plug-in API with C++ classes.
00005  * Copyright (C) 2004-2005 The Open Effects Association Ltd
00006  * Author Bruno Nicoletti bruno@thefoundry.co.uk
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the following disclaimer.
00013  * Redistributions in binary form must reproduce the above copyright notice,
00014  * this list of conditions and the following disclaimer in the documentation
00015  * and/or other materials provided with the distribution.
00016  * Neither the name The Open Effects Association Ltd, nor the names of its
00017  * contributors may be used to endorse or promote products derived from this
00018  * software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00022  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00023  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
00024  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00025  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00027  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  * The Open Effects Association Ltd
00032  * 1 Wardour St
00033  * London W1D 6PA
00034  * England
00035  *
00036  *
00037  *
00038  */
00039 
00040 /** @file This file contains core code that wraps OFX 'objects' with C++ classes.
00041  *
00042  * This file only holds code that is visible to a plugin implementation, and so hides much
00043  * of the direct OFX objects and any library side only functions.
00044  */
00045 #include "ofxsCore.h"
00046 #include <ofxPixels.h>
00047 
00048 #include <list>
00049 
00050 /** @brief Nasty macro used to define empty protected copy ctors and assign ops */
00051 #define mDeclareProtectedAssignAndCC( CLASS ) \
00052     CLASS& operator=( const CLASS& v1 ) { assert( false ); return *this; }      \
00053     CLASS( const CLASS &v ) { assert( false ); }
00054 
00055 /** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries.
00056  */
00057 namespace OFX {
00058 
00059 /** @brief forward declaration */
00060 class ImageEffect;
00061   class Param;
00062 
00063 /// all image effect interacts have these argumens
00064 struct InteractArgs
00065 {
00066         /// ctor
00067         InteractArgs( const PropertySet& props );
00068         double time;             /**< @brief The current effect time to draw at */
00069         OfxPointD renderScale;      /**< @brief The current render scale being applied to any image that would be fetched */
00070 };
00071 
00072 /** @brief struct to pass arguments into OFX::Interact::draw */
00073 struct DrawArgs : public InteractArgs
00074 {
00075         DrawArgs( const PropertySet& props );
00076 
00077         OfxPointD pixelScale;       /**< @brief The pixel scale */
00078         OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */
00079 };
00080 
00081 /** @brief POD  to pass arguments into OFX::Interact pen actions */
00082 struct PenArgs : public InteractArgs
00083 {
00084         PenArgs( const PropertySet& props );
00085 
00086         OfxPointD pixelScale;       /**< @brief The pixel scale */
00087         OfxPointD penPosition;      /**< @brief The current pen position */
00088         double penPressure;      /**< @brief The normalised pressure on the pen */
00089 };
00090 
00091 /** @brief  struct to pass arguments into OFX::Interact key actions
00092  *
00093  * Note
00094  * - some keys cannot be represented as UTF8 strings (eg: the key pad page down key kOfxKey_KP_Page_Up), in which case the key string will be set to "".
00095  * - some UTF8 symbols (generally non-English language ones) cannot be represented by one of the keySymbols, in which case the UTF8 string will be set to some non empty value, but the keySymbol will be set to kOfxKey_Unknown.
00096  * - in no case will keyString be set to "" and keySymbol be set to kOfxKey_Unknown.
00097  */
00098 struct KeyArgs : public InteractArgs
00099 {
00100         KeyArgs( const PropertySet& props );
00101 
00102         int keySymbol;        /**< @brief The key represented as one of the entries in ofxKeySyms.h, see note in OFX::KeyArgs */
00103         std::string keyString;        /**< @brief That key as a UTF8 string, see note in OFX::KeyArgs */
00104 };
00105 
00106 /** @brief struct to pass arguments into OFX::Interact focus actions */
00107 struct FocusArgs : public InteractArgs
00108 {
00109         FocusArgs( const PropertySet& props );
00110 
00111         OfxPointD pixelScale;       /**< @brief The current effect time to draw at */
00112         OfxRGBColourD backGroundColour; /**< @brief The current background colour, ignore the A */
00113 };
00114 
00115 class InteractI
00116 {
00117 public:
00118         virtual ~InteractI() = 0;
00119                 ////////////////////////////////////////////////////////////////////////////////
00120         // override the below in derived classes to do something useful
00121 
00122         /** @brief the function called to draw in the interact */
00123         virtual bool draw( const DrawArgs& args );
00124 
00125         /** @brief the function called to handle pen motion in the interact
00126          *
00127          * returns true if the interact trapped the action in some sense. This will block the action being passed to
00128          * any other interact that may share the viewer.
00129          */
00130         virtual bool penMotion( const PenArgs& args );
00131 
00132         /** @brief the function called to handle pen down events in the interact
00133          *
00134          * returns true if the interact trapped the action in some sense. This will block the action being passed to
00135          * any other interact that may share the viewer.
00136          */
00137         virtual bool penDown( const PenArgs& args );
00138 
00139         /** @brief the function called to handle pen up events in the interact
00140          *
00141          * returns true if the interact trapped the action in some sense. This will block the action being passed to
00142          * any other interact that may share the viewer.
00143          */
00144         virtual bool penUp( const PenArgs& args );
00145 
00146         /** @brief the function called to handle key down events in the interact
00147          *
00148          * returns true if the interact trapped the action in some sense. This will block the action being passed to
00149          * any other interact that may share the viewer.
00150          */
00151         virtual bool keyDown( const KeyArgs& args );
00152 
00153         /** @brief the function called to handle key up events in the interact
00154          *
00155          * returns true if the interact trapped the action in some sense. This will block the action being passed to
00156          * any other interact that may share the viewer.
00157          */
00158         virtual bool keyUp( const KeyArgs& args );
00159 
00160         /** @brief the function called to handle key down repeat events in the interact
00161          *
00162          * returns true if the interact trapped the action in some sense. This will block the action being passed to
00163          * any other interact that may share the viewer.
00164          */
00165         virtual bool keyRepeat( const KeyArgs& args );
00166 
00167         /** @brief Called when the interact is given input focus */
00168         virtual void gainFocus( const FocusArgs& args );
00169 
00170         /** @brief Called when the interact is loses input focus */
00171         virtual void loseFocus( const FocusArgs& args );
00172 };
00173 
00174 /** @brief Wraps up an OFX interact object for an Image Effect. It won't work for any other plug-in type at present (it would need to be broken into a hierarchy of classes).
00175  */
00176 class Interact : public InteractI
00177 {
00178 protected:
00179         OfxInteractHandle _interactHandle;    /**< @brief The handle for this interact */
00180         PropertySet _interactProperties; /**< @brief The property set on this interact */
00181         std::list<Param*> _slaveParams;       /**< @brief List of params we are currently slaved to */
00182         ImageEffect* _effect;                   /**< @brief The instance we are associated with */
00183 
00184 private:
00185         static const int kMagic = 0x06012013; ///< magic number for Interact, and current day :-)
00186         const int _magic; ///< to check for handles being nice
00187         
00188 public:
00189         /** @brief ctor */
00190         Interact( OfxInteractHandle handle );
00191 
00192         /** @brief virtual destructor */
00193         virtual ~Interact() = 0;
00194 
00195         bool verifyMagic() const { return this != NULL && _magic == kMagic; }
00196         
00197         PropertySet& getProperties() { return _interactProperties; }
00198 
00199         /** @brief The bitdepth of each component in the openGL frame buffer */
00200         int getBitDepth( void ) const;
00201 
00202         /** @brief Does the openGL frame buffer have an alpha */
00203         bool hasAlpha( void ) const;
00204 
00205         /** @brief Returns the size of a real screen pixel under the interact's cannonical projection */
00206         OfxPointD getPixelScale( void ) const;
00207 
00208         /** @brief the background colour */
00209         OfxRGBColourD getBackgroundColour( void ) const;
00210 
00211         /** @brief Set a param that the interact should be redrawn on if its value changes */
00212         void addParamToSlaveTo( Param* p );
00213 
00214         /** @brief Remova a param that the interact should be redrawn on if its value changes */
00215         void removeParamToSlaveTo( Param* p );
00216 
00217         /** @brief Request a redraw */
00218         void requestRedraw( void ) const;
00219 
00220         /** @brief Swap a buffer in the case of a double bufferred interact, this is possibly a silly one */
00221         void swapBuffers( void ) const;
00222 };
00223 
00224 /** @brief an interact for an image effect overlay */
00225 class OverlayInteract : public Interact
00226 {
00227 public:
00228         /** @brief ctor */
00229         OverlayInteract( OfxInteractHandle handle );
00230 
00231         /** @brief dtor */
00232         virtual ~OverlayInteract();
00233 };
00234 
00235 class InteractDescriptor
00236 {
00237 public:
00238         InteractDescriptor() : _props( 0 ) {}
00239         virtual ~InteractDescriptor() = 0;
00240         void                         setPropertySet( OFX::PropertySet* props ) { _props = props; }
00241         virtual Interact*            createInstance( OfxInteractHandle handle, ImageEffect* effect ) = 0;
00242         void                         setHasAlpha();
00243         bool                         getHasAlpha() const;
00244         void                         setBitDepth();
00245         int                          getBitDepth() const;
00246         virtual void                 describe() {}
00247 
00248 protected:
00249         OFX::PropertySet* _props;
00250 };
00251 
00252 typedef InteractDescriptor EffectOverlayDescriptor;
00253 
00254 class NoOverlayDescriptor : public OFX::EffectOverlayDescriptor
00255 {
00256 public:
00257     OFX::Interact* createInstance( OfxInteractHandle handle, OFX::ImageEffect *effect )
00258     {
00259         return new OFX::OverlayInteract( handle );
00260     }
00261 };
00262 
00263 class ParamInteractDescriptor : public InteractDescriptor
00264 {
00265 public:
00266         ParamInteractDescriptor() : InteractDescriptor() {}
00267         virtual ~ParamInteractDescriptor() {}
00268         void         setInteractSizeAspect( double asp );
00269         void         setInteractMinimumSize( int x, int y );
00270         void         setInteractPreferredSize( int x, int y );
00271         virtual void setParamName( const std::string& pName ) { _paramName = pName; }
00272 
00273 protected:
00274         std::string _paramName;
00275 };
00276 
00277 class ParamInteract : public Interact
00278 {
00279 public:
00280         ParamInteract( OfxInteractHandle handle, ImageEffect* effect );
00281         virtual ~ParamInteract() {}
00282         double    getInteractSizeAspect() const;
00283         OfxPointI getInteractMinimumSize() const;
00284         OfxPointI getInteractPreferredSize() const;
00285         OfxPointI getInteractSize() const;
00286 
00287 protected:
00288         ImageEffect* _effect;
00289 };
00290 
00291 namespace Private {
00292 OfxStatus interactMainEntry( const char*          actionRaw,
00293                              const void*          handleRaw,
00294                              OfxPropertySetHandle inArgsRaw,
00295                              OfxPropertySetHandle outArgsRaw,
00296                              InteractDescriptor&  desc );
00297 }
00298 
00299 class EffectInteractWrap
00300 {
00301 public:
00302         virtual ~EffectInteractWrap() = 0;
00303         virtual OfxPluginEntryPoint* getMainEntry() = 0;
00304         virtual InteractDescriptor& getDescriptor() =0;
00305 };
00306 
00307 class ParamInteractWrap : public EffectInteractWrap
00308 {
00309 public:
00310         virtual ~ParamInteractWrap() = 0;
00311         virtual OfxPluginEntryPoint* getMainEntry() = 0;
00312         virtual ParamInteractDescriptor& getDescriptor() =0;
00313 };
00314 
00315 template<class DESC>
00316 class InteractMainEntry
00317 {
00318   public:
00319     virtual ~InteractMainEntry() = 0;
00320 protected:
00321         static OfxStatus overlayInteractMainEntry( const char* action, const void* handle, OfxPropertySetHandle in, OfxPropertySetHandle out )
00322         {
00323                 static DESC desc;
00324                 return OFX::Private::interactMainEntry( action, handle, in, out, desc );
00325         }
00326 };
00327 
00328 template<class DESC>
00329 InteractMainEntry<DESC>::~InteractMainEntry() {}
00330 
00331 template<class DESC>
00332 class DefaultEffectOverlayWrap : public InteractMainEntry<DESC>, public EffectInteractWrap
00333 {
00334 public:
00335       typedef DESC Descriptor;
00336       Descriptor _descriptor;
00337   public:
00338     OfxPluginEntryPoint* getMainEntry() { return InteractMainEntry<DESC>::overlayInteractMainEntry; }
00339 
00340     OFX::InteractDescriptor& getDescriptor() { return _descriptor; }
00341 };
00342 
00343 template<class DESC>
00344 class DefaultParamInteractWrap : public InteractMainEntry<DESC>, public ParamInteractWrap
00345 {
00346 public:
00347         typedef DESC Descriptor;
00348         Descriptor _descriptor;
00349 public:
00350         OfxPluginEntryPoint* getMainEntry() { return InteractMainEntry<DESC>::overlayInteractMainEntry; }
00351 
00352         OFX::ParamInteractDescriptor& getDescriptor() { return _descriptor; }
00353 
00354         void setParamName( const std::string& pName ) { _paramNameStatic = pName; }
00355 
00356 protected:
00357         static std::string _paramNameStatic;
00358 };
00359 
00360 template<class DESC> std::string OFX::DefaultParamInteractWrap<DESC>::_paramNameStatic;
00361 
00362 }
00363 
00364 
00365 #undef mDeclareProtectedAssignAndCC
00366 
00367 #endif
00368