1 /*
2 OFX Support Library, a library that skins the OFX plug-in API with C++ classes.
3 Copyright (C) 2004-2005 The Open Effects Association Ltd
4 Author Bruno Nicoletti bruno@thefoundry.co.uk
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 * Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
14 * Neither the name The Open Effects Association Ltd, nor the names of its
15 contributors may be used to endorse or promote products derived from this
16 software without specific prior written permission.
17 
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 The Open Effects Association Ltd
30 1 Wardour St
31 London W1D 6PA
32 England
33 
34 
35 */
36 
37 /** @brief This file contains code that skins the ofx param suite */
38 
39 #include <cstring>
40 #ifdef DEBUG
41 #include <iostream>
42 #endif
43 #include "ofxsSupportPrivate.h"
44 #include "ofxParametricParam.h"
45 #ifdef OFX_EXTENSIONS_NUKE
46 #include "nuke/camera.h"
47 #endif
48 
49 template<typename T>
50 static inline void
unused(const T &)51 unused(const T&) {}
52 
53 #ifdef DEBUG
54 // We check that strings contained in StringParam are UTF-8 encoded
55 // See http://openfx.sourceforge.net/Documentation/1.4/ofxProgrammingReference.html#kOfxParamTypeString
56 //
57 // From http://stackoverflow.com/questions/1031645/how-to-detect-utf-8-in-plain-c
is_utf8(const char * string)58 static bool is_utf8(const char * string)
59 {
60   if(!string)
61     return 0;
62 
63   const unsigned char * bytes = (const unsigned char *)string;
64   while(*bytes)
65   {
66     if( (// ASCII
67          // use bytes[0] <= 0x7F to allow ASCII control characters
68          bytes[0] == 0x09 ||
69          bytes[0] == 0x0A ||
70          bytes[0] == 0x0D ||
71          (0x20 <= bytes[0] && bytes[0] <= 0x7E)
72          )
73        ) {
74       bytes += 1;
75       continue;
76     }
77 
78     if( (// non-overlong 2-byte
79          (0xC2 <= bytes[0] && bytes[0] <= 0xDF) &&
80          (0x80 <= bytes[1] && bytes[1] <= 0xBF)
81          )
82        ) {
83       bytes += 2;
84       continue;
85     }
86 
87     if( (// excluding overlongs
88          bytes[0] == 0xE0 &&
89          (0xA0 <= bytes[1] && bytes[1] <= 0xBF) &&
90          (0x80 <= bytes[2] && bytes[2] <= 0xBF)
91          ) ||
92        (// straight 3-byte
93         ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) ||
94          bytes[0] == 0xEE ||
95          bytes[0] == 0xEF) &&
96         (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
97         (0x80 <= bytes[2] && bytes[2] <= 0xBF)
98         ) ||
99        (// excluding surrogates
100         bytes[0] == 0xED &&
101         (0x80 <= bytes[1] && bytes[1] <= 0x9F) &&
102         (0x80 <= bytes[2] && bytes[2] <= 0xBF)
103         )
104        ) {
105       bytes += 3;
106       continue;
107     }
108 
109     if( (// planes 1-3
110          bytes[0] == 0xF0 &&
111          (0x90 <= bytes[1] && bytes[1] <= 0xBF) &&
112          (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
113          (0x80 <= bytes[3] && bytes[3] <= 0xBF)
114          ) ||
115        (// planes 4-15
116         (0xF1 <= bytes[0] && bytes[0] <= 0xF3) &&
117         (0x80 <= bytes[1] && bytes[1] <= 0xBF) &&
118         (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
119         (0x80 <= bytes[3] && bytes[3] <= 0xBF)
120         ) ||
121        (// plane 16
122         bytes[0] == 0xF4 &&
123         (0x80 <= bytes[1] && bytes[1] <= 0x8F) &&
124         (0x80 <= bytes[2] && bytes[2] <= 0xBF) &&
125         (0x80 <= bytes[3] && bytes[3] <= 0xBF)
126         )
127        ) {
128       bytes += 4;
129       continue;
130     }
131 
132     return 0;
133   }
134 
135   return 1;
136 }
137 #endif // DEBUG
138 
139 /** @brief The core 'OFX Support' namespace, used by plugin implementations. All code for these are defined in the common support libraries. */
140 namespace OFX {
141 
142   /** @brief dummy page positioning parameter to be passed to @ref OFX::PageParamDescriptor::addChild */
143   DummyParamDescriptor PageParamDescriptor::gSkipRow(kOfxParamPageSkipRow);
144 
145   /** @brief dummy page positioning parameter to be passed to @ref OFX::PageParamDescriptor::addChild */
146   DummyParamDescriptor PageParamDescriptor::gSkipColumn(kOfxParamPageSkipColumn);
147 
148   /** @brief turns a ParamTypeEnum into the char * that raw OFX uses */
mapParamTypeEnumToString(ParamTypeEnum v)149   const char * mapParamTypeEnumToString(ParamTypeEnum v)
150   {
151     switch(v)
152     {
153     case eStringParam : return kOfxParamTypeString ;
154     case eIntParam : return kOfxParamTypeInteger ;
155     case eInt2DParam : return kOfxParamTypeInteger2D ;
156     case eInt3DParam : return kOfxParamTypeInteger3D ;
157     case eDoubleParam : return kOfxParamTypeDouble ;
158     case eDouble2DParam : return kOfxParamTypeDouble2D ;
159     case eDouble3DParam : return kOfxParamTypeDouble3D ;
160     case eRGBParam : return kOfxParamTypeRGB ;
161     case eRGBAParam : return kOfxParamTypeRGBA ;
162     case eBooleanParam : return kOfxParamTypeBoolean ;
163     case eChoiceParam : return kOfxParamTypeChoice ;
164 #ifdef OFX_EXTENSIONS_RESOLVE
165     case eStrChoiceParam : return kOfxParamTypeStrChoice;
166 #endif
167     case eCustomParam : return kOfxParamTypeCustom ;
168     case eGroupParam : return kOfxParamTypeGroup ;
169     case ePageParam : return kOfxParamTypePage ;
170     case ePushButtonParam : return kOfxParamTypePushButton ;
171     case eParametricParam : return kOfxParamTypeParametric ;
172     default: assert(false);
173     }
174     return kOfxParamTypeInteger;
175   }
176 
177   static
isEqual(const char * t1,const char * t2)178   bool isEqual(const char* t1, const char* t2)
179   {
180     return strcmp(t1, t2)==0;
181   }
182 
183   static
mapParamTypeStringToEnum(const char * v)184   ParamTypeEnum mapParamTypeStringToEnum(const char * v)
185   {
186     if(isEqual(kOfxParamTypeString,v))
187       return eStringParam ;
188     else if(isEqual(kOfxParamTypeInteger,v))
189       return eIntParam ;
190     else if(isEqual(kOfxParamTypeInteger2D,v))
191       return eInt2DParam ;
192     else if(isEqual(kOfxParamTypeInteger3D,v))
193       return eInt3DParam ;
194     else if(isEqual(kOfxParamTypeDouble,v))
195       return eDoubleParam ;
196     else if(isEqual(kOfxParamTypeDouble2D,v))
197       return eDouble2DParam ;
198     else if(isEqual(kOfxParamTypeDouble3D,v))
199       return eDouble3DParam ;
200     else if(isEqual(kOfxParamTypeRGB,v))
201       return eRGBParam ;
202     else if(isEqual(kOfxParamTypeRGBA,v))
203       return eRGBAParam ;
204     else if(isEqual(kOfxParamTypeBoolean,v))
205       return eBooleanParam ;
206     else if(isEqual(kOfxParamTypeChoice,v))
207       return eChoiceParam ;
208 #ifdef OFX_EXTENSIONS_RESOLVE
209     else if (isEqual(kOfxParamTypeStrChoice, v))
210       return eStrChoiceParam;
211 #endif
212     else if(isEqual(kOfxParamTypeCustom ,v))
213       return eCustomParam ;
214     else if(isEqual(kOfxParamTypeGroup,v))
215       return eGroupParam ;
216     else if(isEqual(kOfxParamTypePage,v))
217       return ePageParam ;
218     else if(isEqual(kOfxParamTypePushButton,v))
219       return ePushButtonParam ;
220     else if(isEqual(kOfxParamTypeParametric,v))
221       return eParametricParam ;
222     else
223       assert(false);
224     return ePushButtonParam ;
225   }
226 
227 #ifdef OFX_EXTENSIONS_VEGAS
228   /** @brief map a std::string to a keyframe interpolation type */
mapToInterpolationEnum(const std::string & s)229   VegasInterpolationEnum mapToInterpolationEnum(const std::string &s) OFX_THROW(std::invalid_argument)
230   {
231     if(s == kOfxVegasKeyframeInterpolationUnknown) return eVegasInterpolationUnknown;
232     if(s == kOfxVegasKeyframeInterpolationLinear)  return eVegasInterpolationLinear;
233     if(s == kOfxVegasKeyframeInterpolationFast)    return eVegasInterpolationFast;
234     if(s == kOfxVegasKeyframeInterpolationSlow)    return eVegasInterpolationSlow;
235     if(s == kOfxVegasKeyframeInterpolationSmooth)  return eVegasInterpolationSmooth;
236     if(s == kOfxVegasKeyframeInterpolationSharp)   return eVegasInterpolationSharp;
237     if(s == kOfxVegasKeyframeInterpolationHold)    return eVegasInterpolationHold;
238     if(s == kOfxVegasKeyframeInterpolationManual)  return eVegasInterpolationManual;
239     if(s == kOfxVegasKeyframeInterpolationSplit)   return eVegasInterpolationSplit;
240     OFX::Log::error(true, "Unknown keyframe Interpolation '%s'", s.c_str());
241     throw std::invalid_argument(s);
242   }
243 
mapToInterpolationTypeEnum(OFX::VegasInterpolationEnum type)244   const char* mapToInterpolationTypeEnum(OFX::VegasInterpolationEnum type)
245   {
246          if(type == OFX::eVegasInterpolationUnknown) return kOfxVegasKeyframeInterpolationUnknown;
247     else if(type == OFX::eVegasInterpolationLinear)  return kOfxVegasKeyframeInterpolationLinear;
248     else if(type == OFX::eVegasInterpolationFast)    return kOfxVegasKeyframeInterpolationFast;
249     else if(type == OFX::eVegasInterpolationSlow)    return kOfxVegasKeyframeInterpolationSlow;
250     else if(type == OFX::eVegasInterpolationSmooth)  return kOfxVegasKeyframeInterpolationSmooth;
251     else if(type == OFX::eVegasInterpolationSharp)   return kOfxVegasKeyframeInterpolationSharp;
252     else if(type == OFX::eVegasInterpolationHold)    return kOfxVegasKeyframeInterpolationHold;
253     else if(type == OFX::eVegasInterpolationManual)  return kOfxVegasKeyframeInterpolationManual;
254     else if(type == OFX::eVegasInterpolationSplit)   return kOfxVegasKeyframeInterpolationSplit;
255     OFX::Log::error(true, "Unknown interpolation type enum '%d'", type);
256     return 0;
257   }
258 #endif
259 
260   ////////////////////////////////////////////////////////////////////////////////
261   // the base class for all param descriptors
262 
263   /** @brief ctor */
ParamDescriptor(const std::string & name,ParamTypeEnum type,OfxPropertySetHandle props)264   ParamDescriptor::ParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props)
265     : _paramName(name)
266     , _paramType(type)
267     , _paramProps(props)
268   {
269     // validate the properities on this descriptor
270     if(type != eDummyParam)
271       OFX::Validation::validateParameterProperties(type, props, true);
272   }
273 
~ParamDescriptor()274   ParamDescriptor::~ParamDescriptor()
275   {
276   }
277 
278   /** @brief set the label property */
279   void
setLabel(const std::string & label)280     ParamDescriptor::setLabel(const std::string &label)
281   {
282     _paramProps.propSetString(kOfxPropLabel, label);
283   }
284 
285   /** @brief set the label properties */
286   void
setLabels(const std::string & label,const std::string & shortLabel,const std::string & longLabel)287     ParamDescriptor::setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel)
288   {
289     setLabel(label);
290     _paramProps.propSetString(kOfxPropShortLabel, shortLabel, false);
291     _paramProps.propSetString(kOfxPropLongLabel, longLabel, false);
292   }
293 
294   /** @brief set the param hint */
295   void
setHint(const std::string & v)296     ParamDescriptor::setHint(const std::string &v)
297   {
298     _paramProps.propSetString(kOfxParamPropHint, v, false);
299   }
300 
301   /** @brief set the param label and hint */
302   void
setLabelAndHint(const std::string & label,const std::string & hint)303     ParamDescriptor::setLabelAndHint(const std::string &label, const std::string &hint)
304   {
305     setLabel(label);
306     setHint(hint);
307   }
308 
309   /** @brief set the script name, default is the name it was defined with */
310   void
setScriptName(const std::string & v)311     ParamDescriptor::setScriptName(const std::string &v)
312   {
313     _paramProps.propSetString(kOfxParamPropScriptName, v, false);
314   }
315 
316   /** @brief set the secretness of the param, defaults to false */
317   void
setIsSecret(bool v)318     ParamDescriptor::setIsSecret(bool v)
319   {
320     _paramProps.propSetInt(kOfxParamPropSecret, v);
321   }
322 
323   /** @brief set the if the param is enabled, defaults to true */
324   void
setEnabled(bool v)325     ParamDescriptor::setEnabled(bool v)
326   {
327     _paramProps.propSetInt(kOfxParamPropEnabled, v);
328   }
329 
330 #ifdef OFX_EXTENSIONS_VEGAS
331   /** @brief set if the parameter is expanded (Vegas specific), defaults to true */
332   void
setParameterExpanded(bool v)333     ParamDescriptor::setParameterExpanded(bool v)
334   {
335     _paramProps.propSetInt(kOfxParamPropParameterExpanded, v, false);
336   }
337 #endif
338 
339 #ifdef OFX_EXTENSIONS_NUKE
340   void
setLayoutHint(const ELayoutHint layoutHint,int padWidth)341     ParamDescriptor::setLayoutHint(const ELayoutHint layoutHint, int padWidth)
342   {
343     _paramProps.propSetInt(kOfxParamPropLayoutHint, static_cast<int>(layoutHint), false);
344     if (layoutHint == eLayoutHintNoNewLine) {
345       _paramProps.propSetInt(kOfxParamPropLayoutPadWidth, padWidth, false);
346     }
347   }
348 #endif
349 
350 #ifdef OFX_EXTENSIONS_NATRON
351     /** @brief When set to true, the parameter is specific to an effect instance of the plug-in and should have a
352      unique representation for each instance. See descripton of kNatronOfxImageEffectContextTracker for more details
353      on multiple instances and difference between shared and specific parameters.*/
354   void
setInstanceSpecific(bool isSpecific)355     ParamDescriptor::setInstanceSpecific(bool isSpecific)
356   {
357     _paramProps.propSetInt(kNatronOfxParamPropIsInstanceSpecific, (int)isSpecific, false);
358   }
359 
360   /*Indicates if the plug-in description is written in markdown or plain-text otherwise */
361   void
setDescriptionIsMarkdown(bool markdown)362     ParamDescriptor::setDescriptionIsMarkdown(bool markdown)
363   {
364     _paramProps.propSetInt(kNatronOfxPropDescriptionIsMarkdown, (int)markdown, 0, false);
365   }
366 
367   void
setInViewportLayoutHint(const ELayoutHint layoutHint,int padWidth)368     ParamDescriptor::setInViewportLayoutHint(const ELayoutHint layoutHint, int padWidth)
369   {
370     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextLayoutHint, static_cast<int>(layoutHint), false);
371     if (layoutHint == eLayoutHintNoNewLine) {
372       _paramProps.propSetInt(kNatronOfxParamPropInViewerContextLayoutPadWidth, padWidth, false);
373     }
374   }
375 
376   void
setInViewportLabel(const std::string & label)377     ParamDescriptor::setInViewportLabel(const std::string& label)
378   {
379     _paramProps.propSetString(kNatronOfxParamPropInViewerContextLabel, label, 0);
380   }
381 
382   void
setInViewportIsSecret(bool secret)383     ParamDescriptor::setInViewportIsSecret(bool secret)
384   {
385     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextSecret, (int)secret);
386   }
387 #endif
388 
389   /** @brief set the group param that is the parent of this one, default is to be ungrouped at the root level */
390   void
setParent(const GroupParamDescriptor & v)391     ParamDescriptor::setParent(const GroupParamDescriptor &v)
392   {
393     _paramProps.propSetString(kOfxParamPropParent, v.getName());
394   }
395 
396   /** @brief set the icon file name (SVG or PNG) */
397   void
setIcon(const std::string & v,bool pngFormat)398     ParamDescriptor::setIcon(const std::string &v, bool pngFormat)
399   {
400     _paramProps.propSetString(kOfxPropIcon, v, (int)pngFormat, false); // introduced in OFX 1.2
401   }
402 
403   bool
getHostHasNativeOverlayHandle() const404   ParamDescriptor::getHostHasNativeOverlayHandle() const
405   {
406     bool v = _paramProps.propGetInt(kOfxParamPropHasHostOverlayHandle, 0, false) != 0; // OFX 1.2
407     return v;
408   }
409 
410   void
setUseHostNativeOverlayHandle(bool use)411   ParamDescriptor::setUseHostNativeOverlayHandle(bool use)
412   {
413     _paramProps.propSetInt(kOfxParamPropUseHostOverlayHandle, use, 0, false); // OFX 1.2
414   }
415 
416   ////////////////////////////////////////////////////////////////////////////////
417   // the base class for all params that can hold a value
418 
419   /** @brief ctor */
ValueParamDescriptor(const std::string & name,ParamTypeEnum type,OfxPropertySetHandle props)420   ValueParamDescriptor::ValueParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props)
421     : ParamDescriptor(name, type, props)
422   {
423   }
424 
425   /** @brief dtor */
~ValueParamDescriptor()426   ValueParamDescriptor::~ValueParamDescriptor()
427   {
428   }
429 
430   /** @brief set whether the param can animate, defaults to true in most cases */
setAnimates(bool v)431   void ValueParamDescriptor::setAnimates(bool v)
432   {
433     _paramProps.propSetInt(kOfxParamPropAnimates, v);
434   }
435 
436   /** @brief set whether the param is persistent, defaults to true */
setIsPersistent(bool v)437   void ValueParamDescriptor::setIsPersistent(bool v)
438   {
439     _paramProps.propSetInt(kOfxParamPropPersistent, v);
440   }
441 
442   /** @brief Set's whether the value of the param is significant (ie: affects the rendered image), defaults to true */
setEvaluateOnChange(bool v)443   void ValueParamDescriptor::setEvaluateOnChange(bool v)
444   {
445     _paramProps.propSetInt(kOfxParamPropEvaluateOnChange, v);
446   }
447 
448   /** @brief Set's whether the value of the param is significant (ie: affects the rendered image), defaults to true */
setCanUndo(bool v)449   void ValueParamDescriptor::setCanUndo(bool v)
450   {
451     _paramProps.propSetInt(kOfxParamPropCanUndo, v, 0, false);
452   }
453 
454   /** @brief Set's how any cache should be invalidated if the parameter is changed, defaults to eCacheInvalidateValueChange */
setCacheInvalidation(CacheInvalidationEnum v)455   void ValueParamDescriptor::setCacheInvalidation(CacheInvalidationEnum v)
456   {
457     switch(v)
458     {
459     case eCacheInvalidateValueChange :
460       _paramProps.propSetString(kOfxParamPropCacheInvalidation, kOfxParamInvalidateValueChange);
461       break;
462 
463     case eCacheInvalidateValueChangeToEnd :
464       _paramProps.propSetString(kOfxParamPropCacheInvalidation, kOfxParamInvalidateValueChangeToEnd);
465       break;
466 
467     case eCacheInvalidateValueAll :
468       _paramProps.propSetString(kOfxParamPropCacheInvalidation, kOfxParamInvalidateAll);
469       break;
470     }
471   }
472 
setInteractDescriptor(ParamInteractDescriptor * desc)473   void ValueParamDescriptor::setInteractDescriptor(ParamInteractDescriptor* desc)
474   {
475     _interact.reset(desc);
476     _paramProps.propSetPointer(kOfxParamPropInteractV1, (void*)desc->getMainEntry());
477     desc->setParamName(getName());
478   }
479 
480   ////////////////////////////////////////////////////////////////////////////////
481   // int param descriptor
482 
483   /** @brief ctor */
IntParamDescriptor(const std::string & name,OfxPropertySetHandle props)484   IntParamDescriptor::IntParamDescriptor(const std::string &name, OfxPropertySetHandle props)
485     : ValueParamDescriptor(name, eIntParam, props)
486   {
487   }
488 
489   /** @brief set the default value, default is 0 */
490   void
setDefault(int v)491     IntParamDescriptor::setDefault(int v)
492   {
493     _paramProps.propSetInt(kOfxParamPropDefault, v);
494   }
495 
496   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
497   void
setRange(int min,int max)498     IntParamDescriptor::setRange(int min, int max)
499   {
500     _paramProps.propSetInt(kOfxParamPropMin, min);
501     _paramProps.propSetInt(kOfxParamPropMax, max);
502   }
503 
504   /** @brief set the display min and max, default is to be the same as the range param */
505   void
setDisplayRange(int min,int max)506     IntParamDescriptor::setDisplayRange(int min, int max)
507   {
508     _paramProps.propSetInt(kOfxParamPropDisplayMin, min);
509     _paramProps.propSetInt(kOfxParamPropDisplayMax, max);
510   }
511 
512   ////////////////////////////////////////////////////////////////////////////////
513   // 2D int param descriptor
514 
515   /** @brief ctor */
Int2DParamDescriptor(const std::string & name,OfxPropertySetHandle props)516   Int2DParamDescriptor::Int2DParamDescriptor(const std::string &name, OfxPropertySetHandle props)
517     : ValueParamDescriptor(name, eInt2DParam, props)
518   {
519   }
520 
521   /** @brief set the default value, default is 0 */
522   void
setDefault(int x,int y)523     Int2DParamDescriptor::setDefault(int x, int y)
524   {
525     int v[2] = {x, y};
526     _paramProps.propSetIntN(kOfxParamPropDefault, v, 2);
527   }
528 
529   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
530   void
setRange(int xmin,int ymin,int xmax,int ymax)531     Int2DParamDescriptor::setRange(int xmin, int ymin,
532     int xmax, int ymax)
533   {
534     int vmin[2] = {xmin, ymin};
535     _paramProps.propSetIntN(kOfxParamPropMin, vmin, 2);
536     int vmax[2] = {xmax, ymax};
537     _paramProps.propSetIntN(kOfxParamPropMax, vmax, 2);
538   }
539 
540   /** @brief set the display min and max, default is to be the same as the range param */
541   void
setDisplayRange(int xmin,int ymin,int xmax,int ymax)542     Int2DParamDescriptor::setDisplayRange(int xmin, int ymin,
543     int xmax, int ymax)
544   {
545     int vmin[2] = {xmin, ymin};
546     _paramProps.propSetIntN(kOfxParamPropDisplayMin, vmin, 2);
547     int vmax[2] = {xmax, ymax};
548     _paramProps.propSetIntN(kOfxParamPropDisplayMax, vmax, 2);
549   }
550 
setDimensionLabels(const std::string & x,const std::string & y)551   void Int2DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y)
552   {
553     _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0, false);
554     _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1, false);
555   }
556 
557   ////////////////////////////////////////////////////////////////////////////////
558   // 3D int param descriptor
559 
560   /** @brief ctor */
Int3DParamDescriptor(const std::string & name,OfxPropertySetHandle props)561   Int3DParamDescriptor::Int3DParamDescriptor(const std::string &name, OfxPropertySetHandle props)
562     : ValueParamDescriptor(name, eInt3DParam, props)
563   {
564   }
565 
566   /** @brief set the default value, default is 0 */
567   void
setDefault(int x,int y,int z)568     Int3DParamDescriptor::setDefault(int x, int y, int z)
569   {
570     int v[3] = {x, y, z};
571     _paramProps.propSetIntN(kOfxParamPropDefault, v, 3);
572   }
573 
574   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
575   void
setRange(int xmin,int ymin,int zmin,int xmax,int ymax,int zmax)576     Int3DParamDescriptor::setRange(int xmin, int ymin, int zmin,
577     int xmax, int ymax, int zmax)
578   {
579     int vmin[3] = {xmin, ymin, zmin};
580     _paramProps.propSetIntN(kOfxParamPropMin, vmin, 3);
581     int vmax[3] = {xmax, ymax, zmax};
582     _paramProps.propSetIntN(kOfxParamPropMax, vmax, 3);
583   }
584 
585   /** @brief set the display min and max, default is to be the same as the range param */
586   void
setDisplayRange(int xmin,int ymin,int zmin,int xmax,int ymax,int zmax)587     Int3DParamDescriptor::setDisplayRange(int xmin, int ymin, int zmin,
588     int xmax, int ymax, int zmax)
589   {
590     int vmin[3] = {xmin, ymin, zmin};
591     _paramProps.propSetIntN(kOfxParamPropDisplayMin, vmin, 3);
592     int vmax[3] = {xmax, ymax, zmax};
593     _paramProps.propSetIntN(kOfxParamPropDisplayMax, vmax, 3);
594   }
595 
setDimensionLabels(const std::string & x,const std::string & y,const std::string & z)596   void Int3DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y, const std::string& z)
597   {
598     _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0, false);
599     _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1, false);
600     _paramProps.propSetString(kOfxParamPropDimensionLabel, z, 2, false);
601   }
602 
603   ////////////////////////////////////////////////////////////////////////////////
604   // base class for all double param descriptors
605 
606   /** @brief hidden constructor */
BaseDoubleParamDescriptor(const std::string & name,ParamTypeEnum type,OfxPropertySetHandle props)607   BaseDoubleParamDescriptor::BaseDoubleParamDescriptor(const std::string &name, ParamTypeEnum type, OfxPropertySetHandle props)
608     : ValueParamDescriptor(name, type, props)
609   {
610   }
611 
612   /** @brief set the type of the double param, defaults to eDoubleTypePlain */
setDoubleType(DoubleTypeEnum v)613   void BaseDoubleParamDescriptor::setDoubleType(DoubleTypeEnum v)
614   {
615     switch(v)
616     {
617     case eDoubleTypePlain :
618       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypePlain);
619       break;
620     case eDoubleTypeAngle :
621       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeAngle);
622       break;
623     case eDoubleTypeScale :
624       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeScale);
625       break;
626     case eDoubleTypeTime :
627       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeTime);
628       break;
629     case eDoubleTypeAbsoluteTime :
630       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeAbsoluteTime);
631       break;
632     case eDoubleTypeX :
633       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeX);
634       break;
635     case eDoubleTypeXAbsolute :
636       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeXAbsolute);
637       break;
638     case eDoubleTypeY :
639       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeY);
640       break;
641     case eDoubleTypeYAbsolute :
642       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeYAbsolute);
643       break;
644     case eDoubleTypeXY :
645       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeXY);
646       break;
647     case eDoubleTypeXYAbsolute :
648       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeXYAbsolute);
649       break;
650 #ifdef kOfxParamDoubleTypeNormalisedX
651     case eDoubleTypeNormalisedX :
652       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedX);
653       break;
654     case eDoubleTypeNormalisedY :
655       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedY);
656       break;
657     case eDoubleTypeNormalisedXAbsolute :
658       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedXAbsolute);
659       break;
660     case eDoubleTypeNormalisedYAbsolute :
661       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedYAbsolute);
662       break;
663     case eDoubleTypeNormalisedXY :
664       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedXY);
665       break;
666     case eDoubleTypeNormalisedXYAbsolute :
667       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeNormalisedXYAbsolute);
668       break;
669 #endif
670 #ifdef OFX_EXTENSIONS_VEGAS
671     case eDoubleTypePolar :
672       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypePolar);
673       break;
674     case eDoubleTypeChrominance :
675       _paramProps.propSetString(kOfxParamPropDoubleType, kOfxParamDoubleTypeChrominance);
676       break;
677 #endif
678     }
679   }
680 
681   /** @brief returns true if the param descriptor prop kOfxParamPropDefaultCoordinateSystem is present */
supportsDefaultCoordinateSystem()682   bool BaseDoubleParamDescriptor::supportsDefaultCoordinateSystem()
683   {
684     //OfxStatus stat = Private::gPropSuite->propSetString(_paramProps.propSetHandle(), kOfxParamPropDefaultCoordinateSystem, 0, kOfxParamCoordinatesCanonical);
685     const char *value = NULL;
686     OfxStatus stat = Private::gPropSuite->propGetString(_paramProps.propSetHandle(), kOfxParamPropDefaultCoordinateSystem, 0, &value);
687     return (stat == kOfxStatOK);
688   }
689 
690   /** @brief set the type of coordinate system for default values */
setDefaultCoordinateSystem(DefaultCoordinateSystemEnum v)691   void BaseDoubleParamDescriptor::setDefaultCoordinateSystem(DefaultCoordinateSystemEnum v)
692   {
693     // this property was introduced with OpenFX 1.2
694     switch(v)
695     {
696     case eCoordinatesCanonical :
697       _paramProps.propSetString(kOfxParamPropDefaultCoordinateSystem, kOfxParamCoordinatesCanonical, false);
698       break;
699     case eCoordinatesNormalised :
700       _paramProps.propSetString(kOfxParamPropDefaultCoordinateSystem, kOfxParamCoordinatesNormalised, false);
701       break;
702     }
703   }
704 
705   /** @brief set the sensitivity of any gui slider */
setIncrement(double v)706   void BaseDoubleParamDescriptor::setIncrement(double v)
707   {
708     _paramProps.propSetDouble(kOfxParamPropIncrement, v);
709   }
710 
711   /** @brief set the number of digits printed after a decimal point in any gui */
setDigits(int v)712   void BaseDoubleParamDescriptor::setDigits(int v)
713   {
714     _paramProps.propSetInt(kOfxParamPropDigits, v);
715   }
716 
717   ////////////////////////////////////////////////////////////////////////////////
718   // double param descriptor
719 
720   /** @brief ctor */
DoubleParamDescriptor(const std::string & name,OfxPropertySetHandle props)721   DoubleParamDescriptor::DoubleParamDescriptor(const std::string &name, OfxPropertySetHandle props)
722     : BaseDoubleParamDescriptor(name, eDoubleParam, props)
723   {
724   }
725 
726   /** @brief set the default value, default is 0 */
727   void
setDefault(double v)728     DoubleParamDescriptor::setDefault(double v)
729   {
730     _paramProps.propSetDouble(kOfxParamPropDefault, v);
731   }
732 
733   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
734   void
setRange(double min,double max)735     DoubleParamDescriptor::setRange(double min, double max)
736   {
737     _paramProps.propSetDouble(kOfxParamPropMin, min);
738     _paramProps.propSetDouble(kOfxParamPropMax, max);
739   }
740 
741   /** @brief set the display min and max, default is to be the same as the range param */
742   void
setDisplayRange(double min,double max)743     DoubleParamDescriptor::setDisplayRange(double min, double max)
744   {
745     _paramProps.propSetDouble(kOfxParamPropDisplayMin, min);
746     _paramProps.propSetDouble(kOfxParamPropDisplayMax, max);
747   }
748 
749   ////////////////////////////////////////////////////////////////////////////////
750   // 2D double param descriptor
751 
752   /** @brief ctor */
Double2DParamDescriptor(const std::string & name,OfxPropertySetHandle props)753   Double2DParamDescriptor::Double2DParamDescriptor(const std::string &name, OfxPropertySetHandle props)
754     : BaseDoubleParamDescriptor(name, eDouble2DParam, props)
755   {
756   }
757 
758 #ifdef OFX_EXTENSIONS_NATRON
759   /**
760    * @brief Set as the
761    **/
setRectanglePart(RectangleParamPartEnum rectanglePart)762   void Double2DParamDescriptor::setRectanglePart(RectangleParamPartEnum rectanglePart)
763   {
764     int i;
765     switch (rectanglePart) {
766       case eRectangleParamPartNone:
767         i = 0;
768         break;
769       case eRectangleParamPartPosition:
770         i = 1;
771         break;
772       case eRectangleParamPartSize:
773         i = 2;
774         break;
775     }
776     _paramProps.propSetInt(kNatronOfxParamPropTypeRectangle, i, 0, false);
777   }
778 #endif
779 
780   /** @brief set the default value, default is 0 */
781   void
setDefault(double x,double y)782     Double2DParamDescriptor::setDefault(double x, double y)
783   {
784     double v[2] = {x, y};
785     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 2);
786   }
787 
788   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
789   void
setRange(double xmin,double ymin,double xmax,double ymax)790     Double2DParamDescriptor::setRange(double xmin, double ymin,
791     double xmax, double ymax)
792   {
793     double vmin[2] = {xmin, ymin};
794     _paramProps.propSetDoubleN(kOfxParamPropMin, vmin, 2);
795     double vmax[2] = {xmax, ymax};
796     _paramProps.propSetDoubleN(kOfxParamPropMax, vmax, 2);
797   }
798 
799   /** @brief set the display min and max, default is to be the same as the range param */
800   void
setDisplayRange(double xmin,double ymin,double xmax,double ymax)801     Double2DParamDescriptor::setDisplayRange(double xmin, double ymin,
802     double xmax, double ymax)
803   {
804     double vmin[2] = {xmin, ymin};
805     _paramProps.propSetDoubleN(kOfxParamPropDisplayMin, vmin, 2);
806     double vmax[2] = {xmax, ymax};
807     _paramProps.propSetDoubleN(kOfxParamPropDisplayMax, vmax, 2);
808   }
809 
setDimensionLabels(const std::string & x,const std::string & y)810   void Double2DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y)
811   {
812     _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0);
813     _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1);
814   }
815 
816 #ifdef OFX_EXTENSIONS_VEGAS
817   /** @brief set the color wheel level value, default is 0.75 */
setColorWheelLevel(double x)818   void Double2DParamDescriptor::setColorWheelLevel(double x)
819   {
820     _paramProps.propSetDouble(kOfxParamPropColorWheelLevel, x, false);
821   }
822 #endif
823 
824   ////////////////////////////////////////////////////////////////////////////////
825   // 3D double param descriptor
826 
827   /** @brief ctor */
Double3DParamDescriptor(const std::string & name,OfxPropertySetHandle props)828   Double3DParamDescriptor::Double3DParamDescriptor(const std::string &name, OfxPropertySetHandle props)
829     : BaseDoubleParamDescriptor(name, eDouble3DParam, props)
830   {
831   }
832 
833 #ifdef OFX_EXTENSIONS_NATRON
834   /**
835    * @brief Set the (1-based) matrix row
836    **/
setMatrixRow(int rowIndex)837   void Double3DParamDescriptor::setMatrixRow(int rowIndex)
838   {
839     _paramProps.propSetInt(kNatronOfxParamPropDoubleTypeMatrix3x3, rowIndex, 0, false);
840   }
841 #endif
842 
843   /** @brief set the default value, default is 0 */
844   void
setDefault(double x,double y,double z)845     Double3DParamDescriptor::setDefault(double x, double y, double z)
846   {
847     double v[3] = {x, y, z};
848     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 3);
849   }
850 
851   /** @brief set the hard min/max range, default is -DBL_MAX, DBL_MAX */
852   void
setRange(double xmin,double ymin,double zmin,double xmax,double ymax,double zmax)853     Double3DParamDescriptor::setRange(double xmin, double ymin, double zmin,
854     double xmax, double ymax, double zmax)
855   {
856     double vmin[3] = {xmin, ymin, zmin};
857     _paramProps.propSetDoubleN(kOfxParamPropMin, vmin, 3);
858     double vmax[3] = {xmax, ymax, zmax};
859     _paramProps.propSetDoubleN(kOfxParamPropMax, vmax, 3);
860   }
861 
862   /** @brief set the display min and max, default is to be the same as the range param */
863   void
setDisplayRange(double xmin,double ymin,double zmin,double xmax,double ymax,double zmax)864     Double3DParamDescriptor::setDisplayRange(double xmin, double ymin, double zmin,
865     double xmax, double ymax, double zmax)
866   {
867     double vmin[3] = {xmin, ymin, zmin};
868     _paramProps.propSetDoubleN(kOfxParamPropDisplayMin, vmin, 3);
869     double vmax[3] = {xmax, ymax, zmax};
870     _paramProps.propSetDoubleN(kOfxParamPropDisplayMax, vmax, 3);
871   }
872 
setDimensionLabels(const std::string & x,const std::string & y,const std::string & z)873   void Double3DParamDescriptor::setDimensionLabels(const std::string& x, const std::string& y, const std::string& z)
874   {
875     _paramProps.propSetString(kOfxParamPropDimensionLabel, x, 0);
876     _paramProps.propSetString(kOfxParamPropDimensionLabel, y, 1);
877     _paramProps.propSetString(kOfxParamPropDimensionLabel, z, 2);
878   }
879 
880   ////////////////////////////////////////////////////////////////////////////////
881   // RGB param descriptor
882 
883   /** @brief hidden constructor */
RGBParamDescriptor(const std::string & name,OfxPropertySetHandle props)884   RGBParamDescriptor::RGBParamDescriptor(const std::string &name, OfxPropertySetHandle props)
885     : ValueParamDescriptor(name, eRGBParam, props)
886   {
887   }
888 
889   /** @brief set the default value */
setDefault(double r,double g,double b)890   void  RGBParamDescriptor::setDefault(double r, double g, double b)
891   {
892     double v[3] = {r, g, b};
893     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 3);
894   }
895 
896   /** @brief set the hard min/max range, default is 0., 1. */
897   void
setRange(double rmin,double gmin,double bmin,double rmax,double gmax,double bmax)898     RGBParamDescriptor::setRange(double rmin, double gmin, double bmin,
899     double rmax, double gmax, double bmax)
900   {
901     double vmin[3] = {rmin, gmin, bmin};
902     _paramProps.propSetDoubleN(kOfxParamPropMin, vmin, 3);
903     double vmax[3] = {rmax, gmax, bmax};
904     _paramProps.propSetDoubleN(kOfxParamPropMax, vmax, 3);
905   }
906 
907   /** @brief set the display min and max, default is to be the same as the range param */
908   void
setDisplayRange(double rmin,double gmin,double bmin,double rmax,double gmax,double bmax)909     RGBParamDescriptor::setDisplayRange(double rmin, double gmin, double bmin,
910     double rmax, double gmax, double bmax)
911   {
912     double vmin[3] = {rmin, gmin, bmin};
913     _paramProps.propSetDoubleN(kOfxParamPropDisplayMin, vmin, 3);
914     double vmax[3] = {rmax, gmax, bmax};
915     _paramProps.propSetDoubleN(kOfxParamPropDisplayMax, vmax, 3);
916   }
917 
setDimensionLabels(const std::string & r,const std::string & g,const std::string & b)918   void RGBParamDescriptor::setDimensionLabels(const std::string& r, const std::string& g, const std::string& b)
919   {
920     _paramProps.propSetString(kOfxParamPropDimensionLabel, r, 0);
921     _paramProps.propSetString(kOfxParamPropDimensionLabel, g, 1);
922     _paramProps.propSetString(kOfxParamPropDimensionLabel, b, 2);
923   }
924 
925 #ifdef OFX_EXTENSIONS_VEGAS
926   /** @brief set the default UI color space of the RGB param, defaults to eColorSpaceHSV */
setDefaultColorSpace(ColorSpaceEnum v)927   void RGBParamDescriptor::setDefaultColorSpace(ColorSpaceEnum v)
928   {
929     switch(v)
930     {
931     case eColorSpaceRGB :
932       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceRGB, false);
933       break;
934     case eColorSpaceHSV :
935       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceHSV, false);
936       break;
937     case eColorSpaceHSL :
938       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceHSL, false);
939       break;
940     case eColorSpaceLab :
941       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceLab, false);
942       break;
943     }
944   }
945 #endif
946 
947   ////////////////////////////////////////////////////////////////////////////////
948   // RGBA param descriptor
949 
950   /** @brief hidden constructor */
RGBAParamDescriptor(const std::string & name,OfxPropertySetHandle props)951   RGBAParamDescriptor::RGBAParamDescriptor(const std::string &name, OfxPropertySetHandle props)
952     : ValueParamDescriptor(name, eRGBAParam, props)
953   {
954   }
955 
956   /** @brief set the default value */
setDefault(double r,double g,double b,double a)957   void  RGBAParamDescriptor::setDefault(double r, double g, double b, double a)
958   {
959     double v[4] = {r, g, b, a};
960     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 4);
961   }
962 
963 
964   /** @brief set the hard min/max range, default is 0., 1. */
965   void
setRange(double rmin,double gmin,double bmin,double amin,double rmax,double gmax,double bmax,double amax)966     RGBAParamDescriptor::setRange(double rmin, double gmin, double bmin, double amin,
967     double rmax, double gmax, double bmax, double amax)
968   {
969     double vmin[4] = {rmin, gmin, bmin, amin};
970     _paramProps.propSetDoubleN(kOfxParamPropMin, vmin, 4);
971     double vmax[4] = {rmax, gmax, bmax, amax};
972     _paramProps.propSetDoubleN(kOfxParamPropMax, vmax, 4);
973   }
974 
975   /** @brief set the display min and max, default is to be the same as the range param */
976   void
setDisplayRange(double rmin,double gmin,double bmin,double amin,double rmax,double gmax,double bmax,double amax)977     RGBAParamDescriptor::setDisplayRange(double rmin, double gmin, double bmin, double amin,
978     double rmax, double gmax, double bmax, double amax)
979   {
980     double vmin[4] = {rmin, gmin, bmin, amin};
981     _paramProps.propSetDoubleN(kOfxParamPropDisplayMin, vmin, 4);
982     double vmax[4] = {rmax, gmax, bmax, amax};
983     _paramProps.propSetDoubleN(kOfxParamPropDisplayMax, vmax, 4);
984   }
985 
setDimensionLabels(const std::string & r,const std::string & g,const std::string & b,const std::string & a)986   void RGBAParamDescriptor::setDimensionLabels(const std::string& r, const std::string& g, const std::string& b, const std::string& a)
987   {
988     _paramProps.propSetString(kOfxParamPropDimensionLabel, r, 0);
989     _paramProps.propSetString(kOfxParamPropDimensionLabel, g, 1);
990     _paramProps.propSetString(kOfxParamPropDimensionLabel, b, 2);
991     _paramProps.propSetString(kOfxParamPropDimensionLabel, a, 3);
992   }
993 
994 #ifdef OFX_EXTENSIONS_VEGAS
995   /** @brief set the default UI color space of the RGB param, defaults to eColorSpaceHSV */
setDefaultColorSpace(ColorSpaceEnum v)996   void RGBAParamDescriptor::setDefaultColorSpace(ColorSpaceEnum v)
997   {
998     switch(v)
999     {
1000     case eColorSpaceRGB :
1001       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceRGB, false);
1002       break;
1003     case eColorSpaceHSV :
1004       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceHSV, false);
1005       break;
1006     case eColorSpaceHSL :
1007       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceHSL, false);
1008       break;
1009     case eColorSpaceLab :
1010       _paramProps.propSetString(kOfxParamColorDefaultColorspace, kOfxParamColorColorspaceLab, false);
1011       break;
1012     }
1013   }
1014 #endif
1015 
1016   ////////////////////////////////////////////////////////////////////////////////
1017   // bool param descriptor
1018 
1019   /** @brief hidden constructor */
BooleanParamDescriptor(const std::string & name,OfxPropertySetHandle props)1020   BooleanParamDescriptor::BooleanParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1021     : ValueParamDescriptor(name, eBooleanParam, props)
1022   {
1023   }
1024 
1025   /** @brief set the default value */
setDefault(bool v)1026   void BooleanParamDescriptor::setDefault(bool v)
1027   {
1028     _paramProps.propSetInt(kOfxParamPropDefault, int(v));
1029   }
1030 
1031 #ifdef OFX_EXTENSIONS_NATRON
1032   /*If called, the parameter will be defined as an action in the host viewport toolbar. The parameter should be added to a group on which the property kNatronOfxParamPropInViewerContextIsInToolbar was set to 1 */
setAsInViewportToolbuttonAction()1033   void BooleanParamDescriptor::setAsInViewportToolbuttonAction()
1034   {
1035     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextIsInToolbar, 1);
1036   }
1037 
setAsToggableButton()1038   void BooleanParamDescriptor::setAsToggableButton()
1039   {
1040     _paramProps.propSetInt(kNatronOfxBooleanParamPropIsToggableButton, 1);
1041   }
1042 
1043   /*If called, the host can add an entry in the shortcut editor for this parameter when the user is using the viewport.
1044    The default value for the shortcut may be specified on the ImageEffectDescriptor by calling the function setDefaultParamInViewportShortcut()*/
setInViewportCanHaveShortcut()1045   void BooleanParamDescriptor::setInViewportCanHaveShortcut()
1046   {
1047     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextCanHaveShortcut, 1);
1048   }
1049 
1050 #endif
1051   ////////////////////////////////////////////////////////////////////////////////
1052   // choice param descriptor
1053 
1054   /** @brief hidden constructor */
ChoiceParamDescriptor(const std::string & name,OfxPropertySetHandle props)1055   ChoiceParamDescriptor::ChoiceParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1056     : ValueParamDescriptor(name, eChoiceParam, props)
1057   {
1058   }
1059 
1060   /** @brief set the default value */
setDefault(int v)1061   void ChoiceParamDescriptor::setDefault(int v)
1062   {
1063     _paramProps.propSetInt(kOfxParamPropDefault, v);
1064   }
1065 
1066   /** @brief how many options do we have */
getNOptions(void)1067   int ChoiceParamDescriptor::getNOptions(void)
1068   {
1069     int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
1070     return nCurrentValues;
1071   }
1072 
1073   /** @brief set the default value */
appendOption(const std::string & optionLabel,const std::string & optionHint,const std::string & optionEnum)1074   void ChoiceParamDescriptor::appendOption(const std::string &optionLabel, const std::string& optionHint, const std::string& optionEnum)
1075   {
1076     int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
1077     if(!optionHint.empty()) {
1078 #ifdef OFX_EXTENSIONS_TUTTLE
1079       // Choice label is an ofx extension. If the host doesn't support it,
1080       // we put this information into the parameter hint.
1081       // from https://github.com/tuttleofx/TuttleOFX/commit/ae6e14e99f62b5efa89e4de4a3bc33129ac6afd0
1082       if (_paramProps.propExists(kOfxParamPropChoiceLabelOption)) {
1083          _paramProps.propSetString(kOfxParamPropChoiceLabelOption, optionHint, nCurrentValues);
1084       } else
1085 #endif
1086       {
1087         // If the kOfxParamPropChoiceLabelOption doesn't exist, we put that information into the Hint.
1088         // It's better than nothing...
1089         std::string hint = _paramProps.propGetString(kOfxParamPropHint);
1090         if(!hint.empty()) {
1091           hint += "\n";
1092           if( nCurrentValues == 0 ) {
1093             hint += "\n";
1094           }
1095         }
1096         hint += optionLabel + ": " + optionHint;
1097         _paramProps.propSetString(kOfxParamPropHint, hint);
1098       }
1099     }
1100 #ifdef OFX_EXTENSIONS_NATRON
1101     if (_paramProps.propExists(kOfxParamPropChoiceEnum)) {
1102       _paramProps.propSetString(kOfxParamPropChoiceEnum, optionEnum.empty() ? optionLabel : optionEnum, nCurrentValues);
1103     }
1104 #else
1105     unused(optionEnum);
1106 #endif
1107     _paramProps.propSetString(kOfxParamPropChoiceOption, optionLabel, nCurrentValues);
1108   }
1109 
1110   /** @brief set the default value */
resetOptions(void)1111   void ChoiceParamDescriptor::resetOptions(void)
1112   {
1113     _paramProps.propReset(kOfxParamPropChoiceOption);
1114 #ifdef OFX_EXTENSIONS_TUTTLE
1115     if (_paramProps.propGetDimension(kOfxParamPropChoiceLabelOption, false) > 0) {
1116       _paramProps.propReset(kOfxParamPropChoiceLabelOption);
1117     }
1118 #endif
1119   }
1120 
1121   /** @brief set to the default value */
resetOptions(const std::vector<std::string> & newEntries,const std::vector<std::string> & newEntriesHint,const std::vector<std::string> & newEntriesEnum)1122   void ChoiceParamDescriptor::resetOptions(const std::vector<std::string>& newEntries,
1123                                            const std::vector<std::string>& newEntriesHint,
1124                                            const std::vector<std::string>& newEntriesEnum)
1125   {
1126     assert(newEntries.size() == newEntriesHint.size() || newEntriesHint.empty());
1127     assert(newEntries.size() == newEntriesEnum.size() || newEntriesEnum.empty());
1128 
1129     if ((newEntries.size() != newEntriesHint.size() && !newEntriesHint.empty()) ||
1130         (newEntries.size() != newEntriesEnum.size() && !newEntriesEnum.empty())) {
1131       // Invalid parameters or empty newEntries, reset the property
1132 #ifdef OFX_EXTENSIONS_TUTTLE
1133       if (_paramProps.propGetDimension(kOfxParamPropChoiceLabelOption, false) > 0) {
1134         _paramProps.propReset(kOfxParamPropChoiceLabelOption);
1135       }
1136 #endif
1137 #ifdef OFX_EXTENSIONS_NATRON
1138       if (_paramProps.propGetDimension(kOfxParamPropChoiceEnum, false) > 0) {
1139         _paramProps.propReset(kOfxParamPropChoiceEnum);
1140       }
1141 #endif
1142       _paramProps.propReset(kOfxParamPropChoiceOption);
1143     } else {
1144       // Set the new entries
1145 #ifdef OFX_EXTENSIONS_TUTTLE
1146       if (_paramProps.propExists(kOfxParamPropChoiceLabelOption)) {
1147         if (!newEntriesHint.empty()) {
1148           _paramProps.propSetStringN(kOfxParamPropChoiceLabelOption, newEntriesHint, false);
1149         } else {
1150           _paramProps.propReset(kOfxParamPropChoiceLabelOption);
1151         }
1152       }
1153 #endif
1154 #ifdef OFX_EXTENSIONS_NATRON
1155       if (_paramProps.propExists(kOfxParamPropChoiceEnum)) {
1156         if (!newEntriesEnum.empty()) {
1157           _paramProps.propSetStringN(kOfxParamPropChoiceEnum, newEntriesEnum, false);
1158         } else {
1159           _paramProps.propReset(kOfxParamPropChoiceEnum);
1160         }
1161       }
1162 #endif
1163       _paramProps.propSetStringN(kOfxParamPropChoiceOption, newEntries);
1164 
1165     }
1166   }
1167 
1168 
1169 #ifdef OFX_EXTENSIONS_NATRON
1170   /** @brief whether the menu should be cascading, and each option contains a slash-separated path to the item, defaults to false. */
setCascading(const bool v)1171   void ChoiceParamDescriptor::setCascading(const bool v)
1172   {
1173     _paramProps.propSetInt(kNatronOfxParamPropChoiceCascading, v, false);
1174   }
1175 
1176 #endif
1177 
1178 #ifdef OFX_EXTENSIONS_RESOLVE
1179   ////////////////////////////////////////////////////////////////////////////////
1180   // string choice param descriptor
1181 
1182   /** @brief hidden constructor */
StrChoiceParamDescriptor(const std::string & p_Name,OfxPropertySetHandle p_Props)1183   StrChoiceParamDescriptor::StrChoiceParamDescriptor(const std::string& p_Name, OfxPropertySetHandle p_Props)
1184       : ValueParamDescriptor(p_Name, eStrChoiceParam, p_Props)
1185   {
1186   }
1187 
1188   /** @brief set the default value */
setDefault(const std::string & p_DefaultValue)1189   void StrChoiceParamDescriptor::setDefault(const std::string& p_DefaultValue)
1190   {
1191       _paramProps.propSetString(kOfxParamPropDefault, p_DefaultValue);
1192   }
1193 
1194   /** @brief append an option */
appendOption(const std::string & p_Enum,const std::string & p_Option)1195   void StrChoiceParamDescriptor::appendOption(const std::string& p_Enum, const std::string& p_Option)
1196   {
1197       const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
1198       assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum));
1199 
1200       _paramProps.propSetString(kOfxParamPropChoiceEnum, p_Enum, numOptions);
1201       _paramProps.propSetString(kOfxParamPropChoiceOption, p_Option, numOptions);
1202   }
1203 
1204   /** @brief how many options do we have */
getNOptions()1205   int StrChoiceParamDescriptor::getNOptions()
1206   {
1207       const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
1208       assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum));
1209 
1210       return numOptions;
1211   }
1212 
1213   /** @brief clear all the options so as to add some new ones in */
resetOptions(void)1214   void StrChoiceParamDescriptor::resetOptions(void)
1215   {
1216       _paramProps.propReset(kOfxParamPropChoiceEnum);
1217       _paramProps.propReset(kOfxParamPropChoiceOption);
1218   }
1219 #endif
1220 
1221   ////////////////////////////////////////////////////////////////////////////////
1222   // string param descriptor
1223 
1224   /** @brief hidden ctor */
StringParamDescriptor(const std::string & name,OfxPropertySetHandle props)1225   StringParamDescriptor::StringParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1226     : ValueParamDescriptor(name, eStringParam, props)
1227   {
1228   }
1229 
1230   /** @brief set the default value, default is 0 */
setDefault(const std::string & v)1231   void StringParamDescriptor::setDefault(const std::string &v)
1232   {
1233     _paramProps.propSetString(kOfxParamPropDefault, v);
1234   }
1235 
1236   /** @brief sets the kind of the string param, defaults to eStringSingleLine */
setStringType(StringTypeEnum v)1237   void StringParamDescriptor::setStringType(StringTypeEnum v)
1238   {
1239     switch (v)
1240     {
1241     case eStringTypeSingleLine :
1242       _paramProps.propSetString(kOfxParamPropStringMode,  kOfxParamStringIsSingleLine);
1243       break;
1244     case eStringTypeMultiLine :
1245       _paramProps.propSetString(kOfxParamPropStringMode,  kOfxParamStringIsMultiLine);
1246       break;
1247     case eStringTypeFilePath :
1248       _paramProps.propSetString(kOfxParamPropStringMode,  kOfxParamStringIsFilePath);
1249       break;
1250     case eStringTypeDirectoryPath :
1251       _paramProps.propSetString(kOfxParamPropStringMode,  kOfxParamStringIsDirectoryPath);
1252       break;
1253     case eStringTypeLabel :
1254       _paramProps.propSetString(kOfxParamPropStringMode,  kOfxParamStringIsLabel);
1255       break;
1256     case eStringTypeRichTextFormat :
1257       _paramProps.propSetString(kOfxParamPropStringMode,  kOfxParamStringIsRichTextFormat);
1258       break;
1259     }
1260   }
1261 
1262   /** @brief if the string param is a file path, say that we are picking an existing file, defaults to true */
setFilePathExists(bool v)1263   void StringParamDescriptor::setFilePathExists(bool v)
1264   {
1265     _paramProps.propSetInt(kOfxParamPropStringFilePathExists, int(v));
1266   }
1267 
1268   ////////////////////////////////////////////////////////////////////////////////
1269   // custom param descriptor
1270 
1271   /** @brief hidden ctor */
CustomParamDescriptor(const std::string & name,OfxPropertySetHandle props)1272   CustomParamDescriptor::CustomParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1273     : ValueParamDescriptor(name, eCustomParam, props)
1274   {
1275   }
1276 
1277   /** @brief set the default value, default is 0 */
setDefault(const std::string & v)1278   void CustomParamDescriptor::setDefault(const std::string &v)
1279   {
1280     _paramProps.propSetString(kOfxParamPropDefault, v);
1281   }
1282 
setCustomInterpolation(bool v)1283   void CustomParamDescriptor::setCustomInterpolation(bool v)
1284   {
1285     _paramProps.propSetPointer(kOfxParamPropCustomInterpCallbackV1, v ? (void*)OFX::Private::customParamInterpolationV1Entry : NULL);
1286   }
1287 
1288   ////////////////////////////////////////////////////////////////////////////////
1289   // group param descriptor
1290 
1291   /** @brief hidden constructor */
GroupParamDescriptor(const std::string & name,OfxPropertySetHandle props)1292   GroupParamDescriptor::GroupParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1293     : ParamDescriptor(name, eGroupParam, props)
1294   {
1295   }
1296 
1297   /** @brief whether the initial state of a group is open or closed in a hierarchical layout, defaults to true */
setOpen(const bool v)1298   void GroupParamDescriptor::setOpen(const bool v)
1299   {
1300     _paramProps.propSetInt(kOfxParamPropGroupOpen, v, false); // introduced in OFX 1.2
1301   }
1302 
1303 #ifdef OFX_EXTENSIONS_NUKE
setAsTab()1304   void GroupParamDescriptor::setAsTab()
1305   {
1306     _paramProps.propSetInt(kFnOfxParamPropGroupIsTab, 1, false); // Nuke extension
1307   }
1308 #endif
1309 
1310 #ifdef OFX_EXTENSIONS_NATRON
setAsDialog()1311   void GroupParamDescriptor::setAsDialog()
1312   {
1313     _paramProps.propSetInt(kNatronOfxGroupParamPropIsDialog, 1, false);
1314   }
1315 
1316   void
setAsInViewportToolbutton(bool canHaveShortcut)1317     GroupParamDescriptor::setAsInViewportToolbutton(bool canHaveShortcut)
1318   {
1319     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextIsInToolbar, 1, false);
1320     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextCanHaveShortcut, (int)canHaveShortcut, false);
1321   }
1322 #endif
1323   ////////////////////////////////////////////////////////////////////////////////
1324   // page param descriptor
1325 
1326   /** @brief hidden constructor */
PageParamDescriptor(const std::string & name,OfxPropertySetHandle props)1327   PageParamDescriptor::PageParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1328     : ParamDescriptor(name, ePageParam, props)
1329   {
1330   }
1331 
1332 #ifdef OFX_EXTENSIONS_NATRON
1333 
setAsInViewportToolbar()1334   void PageParamDescriptor::setAsInViewportToolbar()
1335   {
1336     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextIsInToolbar, 1, 0);
1337   }
1338 #endif
1339 
1340   /** @brief adds a child parameter. Note the two existing pseudo params, gColumnSkip  and gRowSkip */
addChild(const ParamDescriptor & p)1341   void PageParamDescriptor::addChild(const ParamDescriptor &p)
1342   {
1343     int nKids = _paramProps.propGetDimension(kOfxParamPropPageChild);
1344     _paramProps.propSetString(kOfxParamPropPageChild, p.getName(), nKids);
1345   }
1346 
1347   ////////////////////////////////////////////////////////////////////////////////
1348   // pushbutton param descriptor
1349 
1350   /** @brief hidden constructor */
PushButtonParamDescriptor(const std::string & name,OfxPropertySetHandle props)1351   PushButtonParamDescriptor::PushButtonParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1352     : ParamDescriptor(name, ePushButtonParam, props)
1353   {
1354   }
1355 
1356 #ifdef OFX_EXTENSIONS_NATRON
1357   /*If called, the host can add an entry in the shortcut editor for this parameter when the user is using the viewport.
1358    The default value for the shortcut may be specified on the ImageEffectDescriptor by calling the function setDefaultParamInViewportShortcut()*/
setInViewportCanHaveShortcut()1359   void PushButtonParamDescriptor::setInViewportCanHaveShortcut()
1360   {
1361     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextCanHaveShortcut, 1, 0);
1362   }
1363 #endif
1364 
1365   ////////////////////////////////////////////////////////////////////////////////
1366   // parametric param descriptor
1367 
1368   /** @brief hidden constructor */
ParametricParamDescriptor(const std::string & name,OfxPropertySetHandle props)1369   ParametricParamDescriptor::ParametricParamDescriptor(const std::string &name, OfxPropertySetHandle props)
1370     : ParamDescriptor(name, eParametricParam, props)
1371     , _ofxParamHandle(NULL)
1372     , _paramSet(NULL)
1373   {
1374   }
1375 
setParamSet(ParamSetDescriptor & paramSet)1376   void ParametricParamDescriptor::setParamSet(ParamSetDescriptor& paramSet)
1377   {
1378     _paramSet = &paramSet;
1379     OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSet->getParamSetHandle(), getName().c_str(), &_ofxParamHandle, 0);
1380     throwSuiteStatusException(stat);
1381   }
1382 
setRange(const double min,const double max)1383   void ParametricParamDescriptor::setRange(const double min, const double max)
1384   {
1385     double r[2] = {min, max};
1386     _paramProps.propSetDoubleN(kOfxParamPropParametricRange, r, 2);
1387   }
1388 
1389 #ifdef OFX_EXTENSIONS_NATRON
supportsPeriodic()1390   bool ParametricParamDescriptor::supportsPeriodic()
1391   {
1392     return _paramProps.propExists(kNatronOfxParamPropParametricIsPeriodic);
1393   }
1394 
setPeriodic(bool periodic)1395   void ParametricParamDescriptor::setPeriodic(bool periodic)
1396   {
1397     _paramProps.propSetInt(kNatronOfxParamPropParametricIsPeriodic, (int)periodic, 0, false);
1398   }
1399 #endif
1400 
setDimension(const int dimension)1401   void ParametricParamDescriptor::setDimension(const int dimension)
1402   {
1403     _paramProps.propSetInt(kOfxParamPropParametricDimension, dimension);
1404   }
1405 
setDimensionLabel(const std::string & label,const int id)1406   void ParametricParamDescriptor::setDimensionLabel(const std::string& label, const int id)
1407   {
1408     _paramProps.propSetString(kOfxParamPropDimensionLabel, label, id);
1409   }
1410 
setDimensionRange(double min,double max,const int id)1411   void ParametricParamDescriptor::setDimensionRange(double min, double max, const int id)
1412   {
1413     _paramProps.propSetDouble(kOfxParamPropMin, min, id, false); // OFX 1.4 spec does not say this parameter exists
1414     _paramProps.propSetDouble(kOfxParamPropMax, max, id, false);
1415   }
1416 
setDimensionDisplayRange(double min,double max,const int id)1417   void ParametricParamDescriptor::setDimensionDisplayRange(double min, double max, const int id)
1418   {
1419     _paramProps.propSetDouble(kOfxParamPropDisplayMin, min, id, false); // OFX 1.4 spec does not say this parameter exists
1420     _paramProps.propSetDouble(kOfxParamPropDisplayMax, max, id, false);
1421   }
1422 
setUIColour(const int id,const OfxRGBColourD & color)1423   void ParametricParamDescriptor::setUIColour(const int id, const OfxRGBColourD& color)
1424   {
1425     _paramProps.propSetDouble(kOfxParamPropParametricUIColour, color.r, id*3 + 0);
1426     _paramProps.propSetDouble(kOfxParamPropParametricUIColour, color.g, id*3 + 1);
1427     _paramProps.propSetDouble(kOfxParamPropParametricUIColour, color.b, id*3 + 2);
1428   }
1429 
addControlPoint(const int id,const OfxTime time,const double x,const double y,const bool addKey)1430   void ParametricParamDescriptor::addControlPoint(const int id, const OfxTime time, const double x, const double y, const bool addKey)
1431   {
1432     if ( OFX::IsNaN(time) ) {
1433       throwSuiteStatusException(kOfxStatErrValue);
1434     }
1435     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamAddControlPoint(_ofxParamHandle, id, time, x, y, addKey);
1436     throwSuiteStatusException(stat);
1437   }
1438 
setIdentity(const int id)1439   void ParametricParamDescriptor::setIdentity(const int id)
1440   {
1441     addControlPoint(id, 0, 0, 0, false);
1442     addControlPoint(id, 0, 1, 1, false);
1443   }
1444 
setIdentity()1445   void ParametricParamDescriptor::setIdentity()
1446   {
1447     const int nbCurves = _paramProps.propGetInt(kOfxParamPropParametricDimension);
1448     for(int i = 0; i < nbCurves; ++i) {
1449       setIdentity(i);
1450     }
1451   }
1452 
setInteractDescriptor(ParamInteractDescriptor * desc)1453   void ParametricParamDescriptor::setInteractDescriptor(ParamInteractDescriptor* desc)
1454   {
1455     _interact.reset(desc);
1456     _paramProps.propSetPointer(kOfxParamPropParametricInteractBackground, (void*)desc->getMainEntry());
1457     desc->setParamName(getName());
1458   }
1459 
1460   ////////////////////////////////////////////////////////////////////////////////
1461   // Descriptor for a set of parameters
1462   /** @brief hidden ctor */
ParamSetDescriptor(void)1463   ParamSetDescriptor::ParamSetDescriptor(void)
1464     : _paramSetHandle(NULL)
1465   {
1466   }
1467 
getParamDescriptor(const std::string & name) const1468   ParamDescriptor* ParamSetDescriptor::getParamDescriptor(const std::string& name) const
1469   {
1470     std::map<std::string, ParamDescriptor*>::const_iterator it = _definedParams.find(name);
1471     if(it!=_definedParams.end())
1472       return it->second;
1473     return 0;
1474   }
1475 
1476   /** @brief set the param set handle */
1477   void
setParamSetHandle(OfxParamSetHandle h)1478     ParamSetDescriptor::setParamSetHandle(OfxParamSetHandle h)
1479   {
1480     // set me handle
1481     _paramSetHandle = h;
1482 
1483     if(h) {
1484       // fetch me props
1485       OfxPropertySetHandle props;
1486       OfxStatus stat = OFX::Private::gParamSuite->paramSetGetPropertySet(h, &props);
1487       _paramSetProps.propSetHandle(props);
1488       throwSuiteStatusException(stat);
1489     }
1490     else {
1491       _paramSetProps.propSetHandle(NULL);
1492     }
1493   }
1494 
1495   /** @brief dtor */
~ParamSetDescriptor()1496   ParamSetDescriptor::~ParamSetDescriptor()
1497   {
1498     // delete any descriptor we may have constructed
1499     std::map<std::string, ParamDescriptor *>::iterator iter;
1500     for(iter = _definedParams.begin(); iter != _definedParams.end(); ++iter) {
1501       if(iter->second) {
1502         delete iter->second;
1503         iter->second = NULL;
1504       }
1505     }
1506   }
1507 
1508   /** @brief estabilishes the order of page params. Do it by calling it in turn for each page */
1509   void
setPageParamOrder(PageParamDescriptor & p)1510     ParamSetDescriptor::setPageParamOrder(PageParamDescriptor &p)
1511   {
1512     int nPages = _paramSetProps.propGetDimension(kOfxPluginPropParamPageOrder);
1513     _paramSetProps.propSetString(kOfxPluginPropParamPageOrder, p.getName().c_str(), nPages);
1514   }
1515 
1516 
1517   /** @brief calls the raw OFX routine to define a param */
defineRawParam(const std::string & name,ParamTypeEnum paramType,OfxPropertySetHandle & props)1518   void ParamSetDescriptor::defineRawParam(const std::string &name, ParamTypeEnum paramType, OfxPropertySetHandle &props)
1519   {
1520     OfxStatus stat = OFX::Private::gParamSuite->paramDefine(_paramSetHandle, mapParamTypeEnumToString(paramType), name.c_str(), &props);
1521     throwSuiteStatusException(stat);
1522   }
1523 
1524   /** @brief if a param has been defined in this set, go find it */
1525   ParamDescriptor *
findPreviouslyDefinedParam(const std::string & name) const1526     ParamSetDescriptor::findPreviouslyDefinedParam(const std::string &name) const
1527   {
1528     // search
1529     std::map<std::string, ParamDescriptor *>::const_iterator search;
1530     search = _definedParams.find(name);
1531     if(search == _definedParams.end())
1532       return NULL;
1533     return search->second;
1534   }
1535 
1536   /** @brief Define an integer param, only callable from describe in context */
1537   IntParamDescriptor *
defineIntParam(const std::string & name)1538     ParamSetDescriptor::defineIntParam(const std::string &name)
1539   {
1540     IntParamDescriptor *param = NULL;
1541     defineParamDescriptor(name, eIntParam, param);
1542     return param;
1543   }
1544 
1545   /** @brief Define a 2D integer param */
defineInt2DParam(const std::string & name)1546   Int2DParamDescriptor *ParamSetDescriptor::defineInt2DParam(const std::string &name)
1547   {
1548     Int2DParamDescriptor *param = NULL;
1549     defineParamDescriptor(name, eInt2DParam, param);
1550     return param;
1551   }
1552 
1553   /** @brief Define a 3D integer param */
defineInt3DParam(const std::string & name)1554   Int3DParamDescriptor *ParamSetDescriptor::defineInt3DParam(const std::string &name)
1555   {
1556     Int3DParamDescriptor *param = NULL;
1557     defineParamDescriptor(name, eInt3DParam, param);
1558     return param;
1559   }
1560 
1561   /** @brief Define an double param, only callable from describe in context */
1562   DoubleParamDescriptor *
defineDoubleParam(const std::string & name)1563     ParamSetDescriptor::defineDoubleParam(const std::string &name)
1564   {
1565     DoubleParamDescriptor *param = NULL;
1566     defineParamDescriptor(name, eDoubleParam, param);
1567     return param;
1568   }
1569 
1570   /** @brief Define a 2D double param */
defineDouble2DParam(const std::string & name)1571   Double2DParamDescriptor *ParamSetDescriptor::defineDouble2DParam(const std::string &name)
1572   {
1573     Double2DParamDescriptor *param = NULL;
1574     defineParamDescriptor(name, eDouble2DParam, param);
1575     return param;
1576   }
1577 
1578   /** @brief Define a 3D double param */
defineDouble3DParam(const std::string & name)1579   Double3DParamDescriptor *ParamSetDescriptor::defineDouble3DParam(const std::string &name)
1580   {
1581     Double3DParamDescriptor *param = NULL;
1582     defineParamDescriptor(name, eDouble3DParam, param);
1583     return param;
1584   }
1585 
1586   /** @brief Define a string param */
defineStringParam(const std::string & name)1587   StringParamDescriptor *ParamSetDescriptor::defineStringParam(const std::string &name)
1588   {
1589     StringParamDescriptor *param = NULL;
1590     defineParamDescriptor(name, eStringParam, param);
1591     return param;
1592   }
1593 
1594   /** @brief Define a RGBA param */
defineRGBAParam(const std::string & name)1595   RGBAParamDescriptor *ParamSetDescriptor::defineRGBAParam(const std::string &name)
1596   {
1597     RGBAParamDescriptor *param = NULL;
1598     defineParamDescriptor(name, eRGBAParam, param);
1599     return param;
1600   }
1601 
1602   /** @brief Define an RGB  param */
defineRGBParam(const std::string & name)1603   RGBParamDescriptor *ParamSetDescriptor::defineRGBParam(const std::string &name)
1604   {
1605     RGBParamDescriptor *param = NULL;
1606     defineParamDescriptor(name, eRGBParam, param);
1607     return param;
1608   }
1609 
1610   /** @brief Define a Boolean  param */
defineBooleanParam(const std::string & name)1611   BooleanParamDescriptor *ParamSetDescriptor::defineBooleanParam(const std::string &name)
1612   {
1613     BooleanParamDescriptor *param = NULL;
1614     defineParamDescriptor(name, eBooleanParam, param);
1615     return param;
1616   }
1617 
1618   /** @brief Define a Choice param */
defineChoiceParam(const std::string & name)1619   ChoiceParamDescriptor *ParamSetDescriptor::defineChoiceParam(const std::string &name)
1620   {
1621     ChoiceParamDescriptor *param = NULL;
1622     defineParamDescriptor(name, eChoiceParam, param);
1623     return param;
1624   }
1625 
1626 #ifdef OFX_EXTENSIONS_RESOLVE
1627   /** @brief Define a String Choice param */
defineStrChoiceParam(const std::string & p_Name)1628   StrChoiceParamDescriptor* ParamSetDescriptor::defineStrChoiceParam(const std::string& p_Name)
1629   {
1630       StrChoiceParamDescriptor* param = NULL;
1631       defineParamDescriptor(p_Name, eStrChoiceParam, param);
1632       return param;
1633   }
1634 #endif
1635 
1636   /** @brief Define a group param */
defineGroupParam(const std::string & name)1637   GroupParamDescriptor *ParamSetDescriptor::defineGroupParam(const std::string &name)
1638   {
1639     GroupParamDescriptor *param = NULL;
1640     defineParamDescriptor(name, eGroupParam, param);
1641     return param;
1642   }
1643 
1644   /** @brief Define a Page param */
definePageParam(const std::string & name)1645   PageParamDescriptor *ParamSetDescriptor::definePageParam(const std::string &name)
1646   {
1647     PageParamDescriptor *param = NULL;
1648     defineParamDescriptor(name, ePageParam, param);
1649     return param;
1650   }
1651 
1652   /** @brief Define a push button  param */
definePushButtonParam(const std::string & name)1653   PushButtonParamDescriptor *ParamSetDescriptor::definePushButtonParam(const std::string &name)
1654   {
1655     PushButtonParamDescriptor *param = NULL;
1656     defineParamDescriptor(name, ePushButtonParam, param);
1657     return param;
1658   }
1659 
1660   /** @brief Define a parametric param */
defineParametricParam(const std::string & name)1661   ParametricParamDescriptor* ParamSetDescriptor::defineParametricParam(const std::string &name)
1662   {
1663     ParametricParamDescriptor* param = NULL;
1664     if (defineParamDescriptor(name, eParametricParam, param)) {
1665       // Parametric parameters need the ParamSet !
1666       param->setParamSet(*this);
1667     }
1668     return param;
1669   }
1670 
1671   /** @brief Define a custom param */
defineCustomParam(const std::string & name)1672   CustomParamDescriptor *ParamSetDescriptor::defineCustomParam(const std::string &name)
1673   {
1674     CustomParamDescriptor *param = NULL;
1675     defineParamDescriptor(name, eCustomParam, param);
1676     return param;
1677   }
1678 
1679   /** @brief Fetch an integer param */
1680   IntParamDescriptor *
fetchIntParam(const std::string & name) const1681     ParamSetDescriptor::fetchIntParam(const std::string &name) const
1682   {
1683     IntParamDescriptor *param = NULL;
1684     fetchParamDescriptor(name, eIntParam, param);
1685     return param;
1686   }
1687 
1688   /** @brief Fetch a 2D integer param */
fetchInt2DParam(const std::string & name) const1689   Int2DParamDescriptor *ParamSetDescriptor::fetchInt2DParam(const std::string &name) const
1690   {
1691     Int2DParamDescriptor *param = NULL;
1692     fetchParamDescriptor(name, eInt2DParam, param);
1693     return param;
1694   }
1695 
1696   /** @brief Fetch a 3D integer param */
fetchInt3DParam(const std::string & name) const1697   Int3DParamDescriptor *ParamSetDescriptor::fetchInt3DParam(const std::string &name) const
1698   {
1699     Int3DParamDescriptor *param = NULL;
1700     fetchParamDescriptor(name, eInt3DParam, param);
1701     return param;
1702   }
1703 
1704   /** @brief Fetch an double param */
fetchDoubleParam(const std::string & name) const1705   DoubleParamDescriptor *ParamSetDescriptor::fetchDoubleParam(const std::string &name) const
1706   {
1707     DoubleParamDescriptor *param = NULL;
1708     fetchParamDescriptor(name, eDoubleParam, param);
1709     return param;
1710   }
1711 
1712   /** @brief Fetch a 2D double param */
fetchDouble2DParam(const std::string & name) const1713   Double2DParamDescriptor *ParamSetDescriptor::fetchDouble2DParam(const std::string &name) const
1714   {
1715     Double2DParamDescriptor *param = NULL;
1716     fetchParamDescriptor(name, eDouble2DParam, param);
1717     return param;
1718   }
1719 
1720   /** @brief Fetch a 3D double param */
fetchDouble3DParam(const std::string & name) const1721   Double3DParamDescriptor *ParamSetDescriptor::fetchDouble3DParam(const std::string &name) const
1722   {
1723     Double3DParamDescriptor *param = NULL;
1724     fetchParamDescriptor(name, eDouble3DParam, param);
1725     return param;
1726   }
1727 
1728   /** @brief Fetch a string param */
fetchStringParam(const std::string & name) const1729   StringParamDescriptor *ParamSetDescriptor::fetchStringParam(const std::string &name) const
1730   {
1731     StringParamDescriptor *param = NULL;
1732     fetchParamDescriptor(name, eStringParam, param);
1733     return param;
1734   }
1735 
1736   /** @brief Fetch a RGBA param */
fetchRGBAParam(const std::string & name) const1737   RGBAParamDescriptor *ParamSetDescriptor::fetchRGBAParam(const std::string &name) const
1738   {
1739     RGBAParamDescriptor *param = NULL;
1740     fetchParamDescriptor(name, eRGBAParam, param);
1741     return param;
1742   }
1743 
1744   /** @brief Fetch an RGB  param */
fetchRGBParam(const std::string & name) const1745   RGBParamDescriptor *ParamSetDescriptor::fetchRGBParam(const std::string &name) const
1746   {
1747     RGBParamDescriptor *param = NULL;
1748     fetchParamDescriptor(name, eRGBParam, param);
1749     return param;
1750   }
1751 
1752   /** @brief Fetch a Boolean  param */
fetchBooleanParam(const std::string & name) const1753   BooleanParamDescriptor *ParamSetDescriptor::fetchBooleanParam(const std::string &name) const
1754   {
1755     BooleanParamDescriptor *param = NULL;
1756     fetchParamDescriptor(name, eBooleanParam, param);
1757     return param;
1758   }
1759 
1760   /** @brief Fetch a Choice param */
fetchChoiceParam(const std::string & name) const1761   ChoiceParamDescriptor *ParamSetDescriptor::fetchChoiceParam(const std::string &name) const
1762   {
1763     ChoiceParamDescriptor *param = NULL;
1764     fetchParamDescriptor(name, eChoiceParam, param);
1765     return param;
1766   }
1767 
1768   /** @brief Fetch a group param */
fetchGroupParam(const std::string & name) const1769   GroupParamDescriptor *ParamSetDescriptor::fetchGroupParam(const std::string &name) const
1770   {
1771     GroupParamDescriptor *param = NULL;
1772     fetchParamDescriptor(name, eGroupParam, param);
1773     return param;
1774   }
1775 
1776   /** @brief Fetch a Page param */
fetchPageParam(const std::string & name) const1777   PageParamDescriptor *ParamSetDescriptor::fetchPageParam(const std::string &name) const
1778   {
1779     PageParamDescriptor *param = NULL;
1780     fetchParamDescriptor(name, ePageParam, param);
1781     return param;
1782   }
1783 
1784   /** @brief Fetch a push button  param */
fetchPushButtonParam(const std::string & name) const1785   PushButtonParamDescriptor *ParamSetDescriptor::fetchPushButtonParam(const std::string &name) const
1786   {
1787     PushButtonParamDescriptor *param = NULL;
1788     fetchParamDescriptor(name, ePushButtonParam, param);
1789     return param;
1790   }
1791 
1792   /** @brief Fetch a custom param */
fetchCustomParam(const std::string & name) const1793   CustomParamDescriptor *ParamSetDescriptor::fetchCustomParam(const std::string &name) const
1794   {
1795     CustomParamDescriptor *param = NULL;
1796     fetchParamDescriptor(name, eCustomParam, param);
1797     return param;
1798   }
1799 
1800   /** @brief Fetch a parametric param */
fetchParametricParam(const std::string & name) const1801   ParametricParamDescriptor *ParamSetDescriptor::fetchParametricParam(const std::string &name) const
1802   {
1803     ParametricParamDescriptor *param = NULL;
1804     fetchParamDescriptor(name, eParametricParam, param);
1805     return param;
1806   }
1807 
1808   ////////////////////////////////////////////////////////////////////////////////
1809   /** @brief Base class for all param instances */
Param(const ParamSet * paramSet,const std::string & name,ParamTypeEnum type,OfxParamHandle handle)1810   Param::Param(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle)
1811     : _paramSet(paramSet)
1812     , _paramName(name)
1813     , _paramType(type)
1814     , _paramHandle(handle)
1815   {
1816     // fetch our property handle
1817     OfxPropertySetHandle propHandle;
1818     OfxStatus stat = OFX::Private::gParamSuite->paramGetPropertySet(handle, &propHandle);
1819     throwSuiteStatusException(stat);
1820     _paramProps.propSetHandle(propHandle);
1821 
1822     // and validate the properties
1823     OFX::Validation::validateParameterProperties(type, _paramProps, false);
1824   }
1825 
1826   /** @brief dtor */
~Param()1827   Param::~Param()
1828   {
1829   }
1830 
1831   /** @brief get name */
getName(void) const1832   const std::string &Param::getName(void) const
1833   {
1834     return _paramName;
1835   }
1836 
1837   /** @brief, set the label properties in a param */
setLabel(const std::string & label)1838   void Param::setLabel(const std::string &label)
1839   {
1840     _paramProps.propSetString(kOfxPropLabel, label);
1841   }
1842 
1843   /** @brief, set the label properties in a param */
setLabels(const std::string & label,const std::string & shortLabel,const std::string & longLabel)1844   void Param::setLabels(const std::string &label, const std::string &shortLabel, const std::string &longLabel)
1845   {
1846     setLabel(label);
1847     _paramProps.propSetString(kOfxPropShortLabel, shortLabel, false);
1848     _paramProps.propSetString(kOfxPropLongLabel, longLabel, false);
1849   }
1850 
1851   /** @brief set the secretness of the param, defaults to false */
setIsSecret(bool v)1852   void Param::setIsSecret(bool v)
1853   {
1854     _paramProps.propSetInt(kOfxParamPropSecret, v);
1855   }
1856 
1857   /** @brief set the param hint */
setHint(const std::string & v)1858   void Param::setHint(const std::string &v)
1859   {
1860     _paramProps.propSetString(kOfxParamPropHint, v, false);
1861   }
1862 
1863   /** @brief whether the param is enabled */
setEnabled(bool v)1864   void Param::setEnabled(bool v)
1865   {
1866     _paramProps.propSetInt(kOfxParamPropEnabled, v);
1867   }
1868 
1869   /** @brief set the private data pointer */
setDataPtr(void * ptr)1870   void Param::setDataPtr(void* ptr)
1871   {
1872     _paramProps.propSetPointer(kOfxParamPropDataPtr, ptr);
1873   }
1874 
1875   /** @brief fetch the label */
getLabel(std::string & label) const1876   void Param::getLabel(std::string &label) const
1877   {
1878     label      = _paramProps.propGetString(kOfxPropLabel);
1879   }
1880 
1881   /** @brief fetch the labels */
getLabels(std::string & label,std::string & shortLabel,std::string & longLabel) const1882   void Param::getLabels(std::string &label, std::string &shortLabel, std::string &longLabel) const
1883   {
1884     getLabel(label);
1885     shortLabel = _paramProps.propGetString(kOfxPropShortLabel, false);
1886     longLabel  = _paramProps.propGetString(kOfxPropLongLabel, false);
1887   }
1888 
1889   /** @brief get whether the param is secret */
getIsSecret(void) const1890   bool Param::getIsSecret(void) const
1891   {
1892     bool v = _paramProps.propGetInt(kOfxParamPropSecret) != 0;
1893     return v;
1894   }
1895 
1896   /** @brief whether the param is enabled */
getIsEnable(void) const1897   bool Param::getIsEnable(void) const
1898   {
1899     bool v = _paramProps.propGetInt(kOfxParamPropEnabled) != 0;
1900     return v;
1901   }
1902 
1903   /** @brief get the private data pointer */
getDataPtr(void) const1904   void* Param::getDataPtr(void) const
1905   {
1906     return   _paramProps.propGetPointer(kOfxParamPropDataPtr);
1907   }
1908 
1909   /** @brief get the param hint */
getHint(void) const1910   std::string Param::getHint(void) const
1911   {
1912     std::string v  = _paramProps.propGetString(kOfxParamPropHint, false);
1913     return v;
1914   }
1915 
1916   /** @brief get the script name */
getScriptName(void) const1917   std::string Param::getScriptName(void) const
1918   {
1919     std::string v  = _paramProps.propGetString(kOfxParamPropScriptName, false);
1920     return v;
1921   }
1922 
1923   /** @brief get the group param that is the parent of this one */
getParent(void) const1924   GroupParam *Param::getParent(void) const
1925   {
1926     std::string v  = _paramProps.propGetString(kOfxParamPropParent);
1927     if(v == "") return NULL;
1928     return _paramSet->fetchGroupParam(v);
1929   }
1930 
1931   /** @brief get the icon file name (SVG or PNG) */
getIcon(bool pngFormat) const1932   std::string Param::getIcon(bool pngFormat) const
1933   {
1934     std::string v  = _paramProps.propGetString(kOfxPropIcon, (int)pngFormat, false); // OFX 1.2
1935     return v;
1936   }
1937 
getHostHasNativeOverlayHandle() const1938   bool Param::getHostHasNativeOverlayHandle() const
1939   {
1940     bool v = _paramProps.propGetInt(kOfxParamPropHasHostOverlayHandle, 0, false) != 0; // OFX 1.2
1941     return v;
1942   }
1943 
1944 #ifdef OFX_EXTENSIONS_NATRON
1945   /*Set the label of the parameter that should be displayed on the host viewport*/
setInViewportLabel(const std::string & label)1946   void Param::setInViewportLabel(const std::string& label)
1947   {
1948     _paramProps.propSetString(kNatronOfxParamPropInViewerContextLabel, label, false);
1949   }
1950 
1951   /*Set whether the parameter should be secret or not in the host viewport. This is only relevant if the parameter has been added to the kNatronOfxImageEffectPropInViewerContextParamsOrder property on the image effect descriptor.*/
setInViewportIsSecret(bool secret)1952   void Param::setInViewportIsSecret(bool secret)
1953   {
1954     _paramProps.propSetInt(kNatronOfxParamPropInViewerContextSecret, (int)secret, false);
1955   }
1956 
1957 #endif
1958 
1959   ////////////////////////////////////////////////////////////////////////////////
1960   /** @brief Wraps up a value holding param */
1961 
1962   /** @brief hidden constructor */
ValueParam(const ParamSet * paramSet,const std::string & name,ParamTypeEnum type,OfxParamHandle handle)1963   ValueParam::ValueParam(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle)
1964     : Param(paramSet, name, type, handle)
1965   {
1966   }
1967 
1968   /** @brief dtor */
~ValueParam()1969   ValueParam::~ValueParam()
1970   {
1971   }
1972 
1973   /** @brief Set's whether the value of the param is significant (ie: affects the rendered image) */
1974   void
setEvaluateOnChange(bool v)1975     ValueParam::setEvaluateOnChange(bool v)
1976   {
1977     _paramProps.propSetInt(kOfxParamPropEvaluateOnChange, v);
1978   }
1979 
1980   /** @brief is the param animating */
1981   bool
getIsAnimating(void) const1982     ValueParam::getIsAnimating(void) const
1983   {
1984     return _paramProps.propGetInt(kOfxParamPropIsAnimating) != 0;
1985   }
1986 
1987   /** @brief is the param auto keing */
1988   bool
getIsAutoKeying(void) const1989     ValueParam::getIsAutoKeying(void) const
1990   {
1991     return _paramProps.propGetInt(kOfxParamPropIsAutoKeying) != 0;
1992   }
1993 
1994   /** @brief is the param persistent */
1995   bool
getIsPersistent(void) const1996     ValueParam::getIsPersistent(void) const
1997   {
1998     return _paramProps.propGetInt(kOfxParamPropPersistent) != 0;
1999   }
2000 
2001   /** @brief Get's whether the value of the param is significant (ie: affects the rendered image) */
2002   bool
getEvaluateOnChange(void) const2003     ValueParam::getEvaluateOnChange(void) const
2004   {
2005     return _paramProps.propGetInt(kOfxParamPropEvaluateOnChange) != 0;
2006   }
2007 
2008   /** @brief Get's whether the value of the param is significant (ie: affects the rendered image) */
2009   CacheInvalidationEnum
getCacheInvalidation(void) const2010     ValueParam::getCacheInvalidation(void) const
2011   {
2012     std::string v = _paramProps.propGetString(kOfxParamPropCacheInvalidation);
2013     if(v == kOfxParamInvalidateValueChange)
2014       return eCacheInvalidateValueChange;
2015     else if(v == kOfxParamInvalidateValueChangeToEnd)
2016       return eCacheInvalidateValueChangeToEnd;
2017     else // if(v == kOfxParamInvalidateAll)
2018       return eCacheInvalidateValueAll;
2019   }
2020 
2021   /** @brief if the param is animating, the number of keys in it, otherwise 0 */
2022   unsigned int
getNumKeys(void)2023     ValueParam::getNumKeys(void)
2024   {
2025     if(!OFX::Private::gParamSuite->paramGetNumKeys) throwHostMissingSuiteException("paramGetNumKeys");
2026     unsigned int v = 0;
2027     OfxStatus stat = OFX::Private::gParamSuite->paramGetNumKeys(_paramHandle, &v);
2028     throwSuiteStatusException(stat);
2029     return v;
2030   }
2031 
2032   /** @brief get the time of the nth key, nth must be between 0 and getNumKeys-1 */
2033   double
getKeyTime(int nthKey)2034     ValueParam::getKeyTime(int nthKey) OFX_THROW2(OFX::Exception::Suite, std::out_of_range)
2035   {
2036     if(!OFX::Private::gParamSuite->paramGetKeyTime) throwHostMissingSuiteException("paramGetKeyTime");
2037     double v = 0;
2038     OfxStatus stat = OFX::Private::gParamSuite->paramGetKeyTime(_paramHandle, nthKey, &v);
2039 
2040     // oops?
2041     if(stat == kOfxStatFailed) throw std::out_of_range("ValueParam::getKeyTime key index out of range");
2042     throwSuiteStatusException(stat);
2043     return v;
2044   }
2045 
2046   /** @brief find the index of a key by a time */
2047   int
getKeyIndex(double time,KeySearchEnum searchDir)2048     ValueParam::getKeyIndex(double time,
2049     KeySearchEnum searchDir)
2050   {
2051     if ( OFX::IsNaN(time) ) {
2052       throwSuiteStatusException(kOfxStatErrValue);
2053     }
2054     if(!OFX::Private::gParamSuite->paramGetKeyIndex) throwHostMissingSuiteException("paramGetKeyIndex");
2055     int v = 0;
2056 
2057     // turn enum into -1,0,1
2058     int dir = searchDir == eKeySearchBackwards ? -1 : (searchDir == eKeySearchNear ? 0 : 1);
2059 
2060     // call raw param function
2061     OfxStatus stat = OFX::Private::gParamSuite->paramGetKeyIndex(_paramHandle, time, dir, &v);
2062 
2063     // oops?
2064     if(stat == kOfxStatFailed) return -1; // if search failed, return -1
2065     throwSuiteStatusException(stat);
2066     return v;
2067   }
2068 
2069   /** @brief deletes a key at the given time */
2070   void
deleteKeyAtTime(double time)2071     ValueParam::deleteKeyAtTime(double time)
2072   {
2073     if ( OFX::IsNaN(time) ) {
2074       throwSuiteStatusException(kOfxStatErrValue);
2075     }
2076     if(!OFX::Private::gParamSuite->paramDeleteKey) throwHostMissingSuiteException("paramDeleteKey");
2077     OfxStatus stat = OFX::Private::gParamSuite->paramDeleteKey(_paramHandle, time);
2078     if(stat == kOfxStatFailed) return; // if no key at time, fail quietly
2079     throwSuiteStatusException(stat);
2080   }
2081 
2082   /** @brief delete all the keys */
2083   void
deleteAllKeys(void)2084     ValueParam::deleteAllKeys(void)
2085   {
2086     if(!OFX::Private::gParamSuite->paramDeleteAllKeys) throwHostMissingSuiteException("paramDeleteAllKeys");
2087     OfxStatus stat = OFX::Private::gParamSuite->paramDeleteAllKeys(_paramHandle);
2088     throwSuiteStatusException(stat);
2089   }
2090 
2091   /** @brief copy parameter from another, including any animation etc... */
copyFrom(const ValueParam & from,OfxTime dstOffset,const OfxRangeD * frameRange)2092   void ValueParam::copyFrom(const ValueParam& from, OfxTime dstOffset, const OfxRangeD *frameRange)
2093   {
2094     if(!OFX::Private::gParamSuite->paramCopy) throwHostMissingSuiteException("paramCopy");
2095     OfxStatus stat = OFX::Private::gParamSuite->paramCopy(_paramHandle, from._paramHandle, dstOffset, frameRange);
2096     throwSuiteStatusException(stat);
2097   }
2098 
2099 #ifdef OFX_EXTENSIONS_VEGAS
2100   /** @brief gets the interpolation type of a key at the given time */
getKeyInterpolation(double time)2101   VegasInterpolationEnum ValueParam::getKeyInterpolation(double time)
2102   {
2103     if ( OFX::IsNaN(time) ) {
2104       throwSuiteStatusException(kOfxStatErrValue);
2105     }
2106     if(!OFX::Private::gVegasKeyframeSuite) throwHostMissingSuiteException("vegasKeyframeSuite");
2107     char *cStr;
2108     OfxStatus stat = OFX::Private::gVegasKeyframeSuite->paramGetKeyInterpolation(_paramHandle, time, &cStr);
2109     throwSuiteStatusException(stat);
2110     return mapToInterpolationEnum(cStr);
2111   }
2112 
2113   /** @brief sets the interpolation type of a key at the given time */
setKeyInterpolation(double time,VegasInterpolationEnum interpolation)2114   void ValueParam::setKeyInterpolation(double time, VegasInterpolationEnum interpolation)
2115   {
2116     if ( OFX::IsNaN(time) ) {
2117       throwSuiteStatusException(kOfxStatErrValue);
2118     }
2119     if(!OFX::Private::gVegasKeyframeSuite) throwHostMissingSuiteException("vegasKeyframeSuite");
2120     OfxStatus stat = OFX::Private::gVegasKeyframeSuite->paramSetKeyInterpolation(_paramHandle, time, mapToInterpolationTypeEnum(interpolation));
2121     throwSuiteStatusException(stat);
2122   }
2123 #endif
2124 
2125   ////////////////////////////////////////////////////////////////////////////////
2126   // Wraps up an integer param */
2127 
2128   /** @brief hidden constructor */
IntParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)2129   IntParam::IntParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
2130     : ValueParam(paramSet, name, eIntParam, handle)
2131   {
2132   }
2133 
2134   /** @brief set the default value */
setDefault(int v)2135   void IntParam::setDefault(int v)
2136   {
2137     _paramProps.propSetInt(kOfxParamPropDefault, v);
2138   }
2139 
2140   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
setRange(int min,int max)2141   void IntParam::setRange(int min, int max)
2142   {
2143     _paramProps.propSetInt(kOfxParamPropMin, min);
2144     _paramProps.propSetInt(kOfxParamPropMax, max);
2145   }
2146 
2147   /** @brief set the display min and max, default is to be the same as the range param */
setDisplayRange(int min,int max)2148   void IntParam::setDisplayRange(int min, int max)
2149   {
2150     _paramProps.propSetInt(kOfxParamPropDisplayMin, min);
2151     _paramProps.propSetInt(kOfxParamPropDisplayMax, max);
2152   }
2153 
2154   /** @brief get the default value */
getDefault(int & v)2155   void IntParam::getDefault(int &v)
2156   {
2157     v = _paramProps.propGetInt(kOfxParamPropDefault);
2158   }
2159 
2160   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
getRange(int & min,int & max)2161   void IntParam::getRange(int &min, int &max)
2162   {
2163     min = _paramProps.propGetInt(kOfxParamPropMin);
2164     max = _paramProps.propGetInt(kOfxParamPropMax);
2165   }
2166 
2167   /** @brief set the display min and max, default is to be the same as the range param */
getDisplayRange(int & min,int & max)2168   void IntParam::getDisplayRange(int &min, int &max)
2169   {
2170     min = _paramProps.propGetInt(kOfxParamPropDisplayMin);
2171     max = _paramProps.propGetInt(kOfxParamPropDisplayMax);
2172   }
2173 
2174   /** @brief get value */
getValue(int & v) const2175   void IntParam::getValue(int &v) const
2176   {
2177     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &v);
2178     throwSuiteStatusException(stat);
2179   }
2180 
2181   /** @brief get the value at a time */
getValueAtTime(double t,int & v) const2182   void IntParam::getValueAtTime(double t, int &v) const
2183   {
2184     if ( OFX::IsNaN(t) ) {
2185       throwSuiteStatusException(kOfxStatErrValue);
2186     }
2187     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &v);
2188     throwSuiteStatusException(stat);
2189   }
2190 
2191   /** @brief set value */
setValue(int v)2192   void IntParam::setValue(int v)
2193   {
2194     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v);
2195     throwSuiteStatusException(stat);
2196   }
2197 
2198   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,int v)2199   void IntParam::setValueAtTime(double t, int v)
2200   {
2201     if ( OFX::IsNaN(t) ) {
2202       throwSuiteStatusException(kOfxStatErrValue);
2203     }
2204     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
2205     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v);
2206     throwSuiteStatusException(stat);
2207   }
2208 
2209   /** @brief delete all keys and set to default value */
resetToDefault()2210   void IntParam::resetToDefault()
2211   {
2212     deleteAllKeys();
2213     int v;
2214     getDefault(v);
2215     setValue(v);
2216   }
2217 
2218   ////////////////////////////////////////////////////////////////////////////////
2219   // 2D Int params
2220 
2221   /** @brief hidden constructor */
Int2DParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)2222   Int2DParam::Int2DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
2223     : ValueParam(paramSet, name, eInt2DParam, handle)
2224   {
2225   }
2226 
2227   /** @brief set the default value */
setDefault(int x,int y)2228   void Int2DParam::setDefault(int x, int y)
2229   {
2230     int v[2] = {x, y};
2231     _paramProps.propSetIntN(kOfxParamPropDefault, v, 2);
2232   }
2233 
2234   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
2235   void
setRange(int xmin,int ymin,int xmax,int ymax)2236     Int2DParam::setRange(int xmin, int ymin,
2237     int xmax, int ymax)
2238   {
2239     int vmin[2] = {xmin, ymin};
2240     _paramProps.propSetIntN(kOfxParamPropMin, vmin, 2);
2241     int vmax[2] = {xmax, ymax};
2242     _paramProps.propSetIntN(kOfxParamPropMax, vmax, 2);
2243   }
2244 
2245   /** @brief set the display min and max, default is to be the same as the range param */
2246   void
setDisplayRange(int xmin,int ymin,int xmax,int ymax)2247     Int2DParam::setDisplayRange(int xmin, int ymin,
2248     int xmax, int ymax)
2249   {
2250     int vmin[2] = {xmin, ymin};
2251     _paramProps.propSetIntN(kOfxParamPropDisplayMin, vmin, 2);
2252     int vmax[2] = {xmax, ymax};
2253     _paramProps.propSetIntN(kOfxParamPropDisplayMax, vmax, 2);
2254   }
2255 
2256   /** @brief het the default value */
getDefault(int & x,int & y)2257   void Int2DParam::getDefault(int &x, int &y)
2258   {
2259     x = _paramProps.propGetInt(kOfxParamPropDefault, 0);
2260     y = _paramProps.propGetInt(kOfxParamPropDefault, 1);
2261   }
2262 
2263 
2264   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
2265   void
getRange(int & xmin,int & ymin,int & xmax,int & ymax)2266     Int2DParam::getRange(int &xmin, int &ymin,
2267     int &xmax, int &ymax)
2268   {
2269     xmin = _paramProps.propGetInt(kOfxParamPropMin, 0);
2270     ymin = _paramProps.propGetInt(kOfxParamPropMin, 1);
2271     xmax = _paramProps.propGetInt(kOfxParamPropMax, 0);
2272     ymax = _paramProps.propGetInt(kOfxParamPropMax, 1);
2273   }
2274 
2275   /** @brief set the display min and max, default is to be the same as the range param */
2276   void
getDisplayRange(int & xmin,int & ymin,int & xmax,int & ymax)2277     Int2DParam::getDisplayRange(int &xmin, int &ymin,
2278     int &xmax, int &ymax)
2279   {
2280     xmin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 0);
2281     ymin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 1);
2282     xmax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 0);
2283     ymax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 1);
2284   }
2285 
2286   /** @brief get value */
getValue(int & x,int & y) const2287   void Int2DParam::getValue(int &x, int &y) const
2288   {
2289     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y);
2290     throwSuiteStatusException(stat);
2291   }
2292 
2293   /** @brief get the value at a time */
getValueAtTime(double t,int & x,int & y) const2294   void Int2DParam::getValueAtTime(double t, int &x, int &y) const
2295   {
2296     if ( OFX::IsNaN(t) ) {
2297       throwSuiteStatusException(kOfxStatErrValue);
2298     }
2299     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y);
2300     throwSuiteStatusException(stat);
2301   }
2302 
2303   /** @brief set value */
setValue(int x,int y)2304   void Int2DParam::setValue(int x, int y)
2305   {
2306     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y);
2307     throwSuiteStatusException(stat);
2308   }
2309 
2310   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,int x,int y)2311   void Int2DParam::setValueAtTime(double t, int x, int y)
2312   {
2313     if ( OFX::IsNaN(t) ) {
2314       throwSuiteStatusException(kOfxStatErrValue);
2315     }
2316     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
2317     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y);
2318     throwSuiteStatusException(stat);
2319   }
2320 
2321   /** @brief delete all keys and set to default value */
resetToDefault()2322   void Int2DParam::resetToDefault()
2323   {
2324     deleteAllKeys();
2325     int v0, v1;
2326     getDefault(v0, v1);
2327     setValue(v0, v1);
2328   }
2329 
2330 
2331   ////////////////////////////////////////////////////////////////////////////////
2332   // 3D Int params
2333 
2334   /** @brief hidden constructor */
Int3DParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)2335   Int3DParam::Int3DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
2336     : ValueParam(paramSet, name, eInt3DParam, handle)
2337   {
2338   }
2339 
2340   /** @brief set the default value */
setDefault(int x,int y,int z)2341   void Int3DParam::setDefault(int x, int y, int z)
2342   {
2343     int v[3] = {x, y, z};
2344     _paramProps.propSetIntN(kOfxParamPropDefault, v, 3);
2345   }
2346 
2347   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
2348   void
setRange(int xmin,int ymin,int zmin,int xmax,int ymax,int zmax)2349     Int3DParam::setRange(int xmin, int ymin, int zmin,
2350     int xmax, int ymax, int zmax)
2351   {
2352     int vmin[3] = {xmin, ymin, zmin};
2353     _paramProps.propSetIntN(kOfxParamPropMin, vmin, 3);
2354     int vmax[3] = {xmax, ymax, zmax};
2355     _paramProps.propSetIntN(kOfxParamPropMax, vmax, 3);
2356   }
2357 
2358   /** @brief set the display min and max, default is to be the same as the range param */
2359   void
setDisplayRange(int xmin,int ymin,int zmin,int xmax,int ymax,int zmax)2360     Int3DParam::setDisplayRange(int xmin, int ymin, int zmin,
2361     int xmax, int ymax, int zmax)
2362   {
2363     int vmin[3] = {xmin, ymin, zmin};
2364     _paramProps.propSetIntN(kOfxParamPropDisplayMin, vmin, 3);
2365     int vmax[3] = {xmax, ymax, zmax};
2366     _paramProps.propSetIntN(kOfxParamPropDisplayMax, vmax, 3);
2367   }
2368 
2369   /** @brief get the default value */
getDefault(int & x,int & y,int & z)2370   void Int3DParam::getDefault(int &x, int &y, int &z)
2371   {
2372     x = _paramProps.propGetInt(kOfxParamPropDefault, 0);
2373     y = _paramProps.propGetInt(kOfxParamPropDefault, 1);
2374     z = _paramProps.propGetInt(kOfxParamPropDefault, 2);
2375   }
2376 
2377 
2378   /** @brief set the hard min/max range, default is INT_MIN, INT_MAX */
2379   void
getRange(int & xmin,int & ymin,int & zmin,int & xmax,int & ymax,int & zmax)2380     Int3DParam::getRange(int &xmin, int &ymin, int &zmin,
2381     int &xmax, int &ymax, int &zmax)
2382   {
2383     xmin = _paramProps.propGetInt(kOfxParamPropMin, 0);
2384     ymin = _paramProps.propGetInt(kOfxParamPropMin, 1);
2385     zmin = _paramProps.propGetInt(kOfxParamPropMin, 2);
2386     xmax = _paramProps.propGetInt(kOfxParamPropMax, 0);
2387     ymax = _paramProps.propGetInt(kOfxParamPropMax, 1);
2388     zmax = _paramProps.propGetInt(kOfxParamPropMax, 2);
2389   }
2390 
2391   /** @brief set the display min and max, default is to be the same as the range param */
2392   void
getDisplayRange(int & xmin,int & ymin,int & zmin,int & xmax,int & ymax,int & zmax)2393     Int3DParam::getDisplayRange(int &xmin, int &ymin, int &zmin,
2394     int &xmax, int &ymax, int &zmax)
2395   {
2396     xmin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 0);
2397     ymin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 1);
2398     zmin = _paramProps.propGetInt(kOfxParamPropDisplayMin, 2);
2399     xmax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 0);
2400     ymax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 1);
2401     zmax = _paramProps.propGetInt(kOfxParamPropDisplayMax, 2);
2402   }
2403 
2404   /** @brief get value */
getValue(int & x,int & y,int & z) const2405   void Int3DParam::getValue(int &x, int &y, int &z) const
2406   {
2407     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y, &z);
2408     throwSuiteStatusException(stat);
2409   }
2410 
2411   /** @brief get the value at a time */
getValueAtTime(double t,int & x,int & y,int & z) const2412   void Int3DParam::getValueAtTime(double t, int &x, int &y, int &z) const
2413   {
2414     if ( OFX::IsNaN(t) ) {
2415       throwSuiteStatusException(kOfxStatErrValue);
2416     }
2417     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y, &z);
2418     throwSuiteStatusException(stat);
2419   }
2420 
2421   /** @brief set value */
setValue(int x,int y,int z)2422   void Int3DParam::setValue(int x, int y, int z)
2423   {
2424     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y, z);
2425     throwSuiteStatusException(stat);
2426   }
2427 
2428   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,int x,int y,int z)2429   void Int3DParam::setValueAtTime(double t, int x, int y, int z)
2430   {
2431     if ( OFX::IsNaN(t) ) {
2432       throwSuiteStatusException(kOfxStatErrValue);
2433     }
2434     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
2435     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y, z);
2436     throwSuiteStatusException(stat);
2437   }
2438 
2439   /** @brief delete all keys and set to default value */
resetToDefault()2440   void Int3DParam::resetToDefault()
2441   {
2442     deleteAllKeys();
2443     int v0, v1, v2;
2444     getDefault(v0, v1, v2);
2445     setValue(v0, v1, v2);
2446   }
2447 
2448   ////////////////////////////////////////////////////////////////////////////////
2449   // common base to all double params
2450 
2451   /** @brief hidden constructor */
BaseDoubleParam(const ParamSet * paramSet,const std::string & name,ParamTypeEnum type,OfxParamHandle handle)2452   BaseDoubleParam::BaseDoubleParam(const ParamSet *paramSet, const std::string &name, ParamTypeEnum type, OfxParamHandle handle)
2453     : ValueParam(paramSet, name, type, handle)
2454   {
2455   }
2456 
2457   /** @brief set the sensitivity of any gui slider */
setIncrement(double v)2458   void BaseDoubleParam::setIncrement(double v)
2459   {
2460     _paramProps.propSetDouble(kOfxParamPropIncrement, v);
2461   }
2462 
2463   /** @brief set the number of digits printed after a decimal point in any gui */
setDigits(int v)2464   void BaseDoubleParam::setDigits(int v)
2465   {
2466     _paramProps.propSetInt(kOfxParamPropDigits, v);
2467   }
2468 
2469   /** @brief get the sensitivity of any gui slider */
getIncrement(double & v)2470   void BaseDoubleParam::getIncrement(double &v)
2471   {
2472     v = _paramProps.propGetDouble(kOfxParamPropIncrement);
2473   }
2474 
2475   /** @brief get the number of digits printed after a decimal point in any gui */
getDigits(int & v)2476   void BaseDoubleParam::getDigits(int &v)
2477   {
2478     v = _paramProps.propGetInt(kOfxParamPropDigits);
2479   }
2480 
2481   /** @brief get the type of the double param, defaults to eDoubleTypePlain */
getDoubleType(DoubleTypeEnum & v)2482   void BaseDoubleParam::getDoubleType(DoubleTypeEnum &v)
2483   {
2484     std::string str = _paramProps.propGetString(kOfxParamPropDoubleType);
2485 
2486     if(str == kOfxParamDoubleTypePlain)
2487       v = eDoubleTypePlain;
2488     else if(str == kOfxParamDoubleTypeAngle)
2489       v = eDoubleTypeAngle;
2490     else if(str == kOfxParamDoubleTypeScale)
2491       v = eDoubleTypeScale;
2492     else if(str == kOfxParamDoubleTypeTime)
2493       v = eDoubleTypeTime;
2494     else if(str == kOfxParamDoubleTypeAbsoluteTime)
2495       v = eDoubleTypeAbsoluteTime;
2496     else if(str == kOfxParamDoubleTypeX)
2497       v = eDoubleTypeX;
2498     else if(str == kOfxParamDoubleTypeXAbsolute)
2499       v = eDoubleTypeXAbsolute;
2500     else if(str == kOfxParamDoubleTypeY)
2501       v = eDoubleTypeY;
2502     else if(str == kOfxParamDoubleTypeYAbsolute)
2503       v = eDoubleTypeYAbsolute;
2504     else if(str == kOfxParamDoubleTypeXY)
2505       v = eDoubleTypeXY;
2506     else if(str == kOfxParamDoubleTypeXYAbsolute)
2507       v = eDoubleTypeXYAbsolute;
2508 #ifdef kOfxParamDoubleTypeNormalisedX
2509     else if(str == kOfxParamDoubleTypeNormalisedX)
2510       v = eDoubleTypeNormalisedX;
2511     else if(str == kOfxParamDoubleTypeNormalisedY)
2512       v = eDoubleTypeNormalisedY;
2513     else if(str == kOfxParamDoubleTypeNormalisedXAbsolute)
2514       v = eDoubleTypeNormalisedXAbsolute;
2515     else if(str == kOfxParamDoubleTypeNormalisedYAbsolute)
2516       v = eDoubleTypeNormalisedYAbsolute;
2517     else if(str == kOfxParamDoubleTypeNormalisedXY)
2518       v = eDoubleTypeNormalisedXY;
2519     else if(str == kOfxParamDoubleTypeNormalisedXYAbsolute)
2520       v = eDoubleTypeNormalisedXYAbsolute;
2521 #endif
2522     else
2523       v = eDoubleTypePlain;
2524   }
2525 
2526   /** @brief get the type of coordinate system for default values */
getDefaultCoordinateSystem(DefaultCoordinateSystemEnum & v)2527   void BaseDoubleParam::getDefaultCoordinateSystem(DefaultCoordinateSystemEnum &v)
2528   {
2529     std::string str = _paramProps.propGetString(kOfxParamPropDefaultCoordinateSystem);
2530 
2531     if(str == kOfxParamCoordinatesNormalised)
2532       v = eCoordinatesNormalised;
2533     else
2534       v = eCoordinatesCanonical;
2535   }
2536 
2537   ////////////////////////////////////////////////////////////////////////////////
2538   // Wraps up an double param */
2539 
2540   /** @brief hidden constructor */
DoubleParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)2541   DoubleParam::DoubleParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
2542     : BaseDoubleParam(paramSet, name, eDoubleParam, handle)
2543   {
2544   }
2545 
2546   /** @brief set the default value */
setDefault(double v)2547   void DoubleParam::setDefault(double v)
2548   {
2549     _paramProps.propSetDouble(kOfxParamPropDefault, v);
2550   }
2551 
2552   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
setRange(double min,double max)2553   void DoubleParam::setRange(double min, double max)
2554   {
2555     _paramProps.propSetDouble(kOfxParamPropMin, min);
2556     _paramProps.propSetDouble(kOfxParamPropMax, max);
2557   }
2558 
2559   /** @brief set the display min and max, default is to be the same as the range param */
setDisplayRange(double min,double max)2560   void DoubleParam::setDisplayRange(double min, double max)
2561   {
2562     _paramProps.propSetDouble(kOfxParamPropDisplayMin, min);
2563     _paramProps.propSetDouble(kOfxParamPropDisplayMax, max);
2564   }
2565 
2566   /** @brief get the default value */
getDefault(double & v)2567   void DoubleParam::getDefault(double &v)
2568   {
2569     v = _paramProps.propGetDouble(kOfxParamPropDefault);
2570   }
2571 
2572   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
getRange(double & min,double & max)2573   void DoubleParam::getRange(double &min, double &max)
2574   {
2575     min = _paramProps.propGetDouble(kOfxParamPropMin);
2576     max = _paramProps.propGetDouble(kOfxParamPropMax);
2577   }
2578 
2579   /** @brief set the display min and max, default is to be the same as the range param */
getDisplayRange(double & min,double & max)2580   void DoubleParam::getDisplayRange(double &min, double &max)
2581   {
2582     min = _paramProps.propGetDouble(kOfxParamPropDisplayMin);
2583     max = _paramProps.propGetDouble(kOfxParamPropDisplayMax);
2584   }
2585 
2586   /** @brief get value */
getValue(double & v) const2587   void DoubleParam::getValue(double &v) const
2588   {
2589     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &v);
2590     throwSuiteStatusException(stat);
2591   }
2592 
2593   /** @brief get the value at a time */
getValueAtTime(double t,double & v) const2594   void DoubleParam::getValueAtTime(double t, double &v) const
2595   {
2596     if ( OFX::IsNaN(t) ) {
2597       throwSuiteStatusException(kOfxStatErrValue);
2598     }
2599     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &v);
2600     throwSuiteStatusException(stat);
2601   }
2602 
2603   /** @brief set value */
setValue(double v)2604   void DoubleParam::setValue(double v)
2605   {
2606     if ( OFX::IsNaN(v) ) {
2607       throwSuiteStatusException(kOfxStatErrValue);
2608     }
2609     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v);
2610     throwSuiteStatusException(stat);
2611   }
2612 
2613   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,double v)2614   void DoubleParam::setValueAtTime(double t, double v)
2615   {
2616     if ( OFX::IsNaN(t) ) {
2617       throwSuiteStatusException(kOfxStatErrValue);
2618     }
2619     if ( OFX::IsNaN(v) ) {
2620       throwSuiteStatusException(kOfxStatErrValue);
2621     }
2622     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
2623     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v);
2624     throwSuiteStatusException(stat);
2625   }
2626 
2627   /** @brief get the value at a time */
differentiate(double t,double & v)2628   void DoubleParam::differentiate(double t, double &v)
2629   {
2630     if ( OFX::IsNaN(t) ) {
2631       throwSuiteStatusException(kOfxStatErrValue);
2632     }
2633     if(!OFX::Private::gParamSuite->paramGetDerivative) throwHostMissingSuiteException("paramGetDerivative");
2634     OfxStatus stat = OFX::Private::gParamSuite->paramGetDerivative(_paramHandle, t, &v);
2635     throwSuiteStatusException(stat);
2636   }
2637 
2638   /** @brief get the value at a time */
integrate(double t1,double t2,double & v)2639   void DoubleParam::integrate(double t1, double t2, double &v)
2640   {
2641     if ( OFX::IsNaN(t1) || OFX::IsNaN(t2) ) {
2642       throwSuiteStatusException(kOfxStatErrValue);
2643     }
2644     if(!OFX::Private::gParamSuite->paramGetIntegral) throwHostMissingSuiteException("paramGetIntegral");
2645     OfxStatus stat = OFX::Private::gParamSuite->paramGetIntegral(_paramHandle, t1, t2, &v);
2646     throwSuiteStatusException(stat);
2647   }
2648 
2649   /** @brief delete all keys and set to default value */
resetToDefault()2650   void DoubleParam::resetToDefault()
2651   {
2652     deleteAllKeys();
2653     double v;
2654     getDefault(v);
2655     setValue(v);
2656   }
2657 
2658   ////////////////////////////////////////////////////////////////////////////////
2659   // 2D Double params
2660 
2661   /** @brief hidden constructor */
Double2DParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)2662   Double2DParam::Double2DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
2663     : BaseDoubleParam(paramSet, name, eDouble2DParam, handle)
2664   {
2665   }
2666 
2667   /** @brief set the default value */
setDefault(double x,double y)2668   void Double2DParam::setDefault(double x, double y)
2669   {
2670     double v[2] = {x, y};
2671     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 2);
2672   }
2673 
2674   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
2675   void
setRange(double xmin,double ymin,double xmax,double ymax)2676     Double2DParam::setRange(double xmin, double ymin,
2677     double xmax, double ymax)
2678   {
2679     double vmin[2] = {xmin, ymin};
2680     _paramProps.propSetDoubleN(kOfxParamPropMin, vmin, 2);
2681     double vmax[2] = {xmax, ymax};
2682     _paramProps.propSetDoubleN(kOfxParamPropMax, vmax, 2);
2683   }
2684 
2685   /** @brief set the display min and max, default is to be the same as the range param */
2686   void
setDisplayRange(double xmin,double ymin,double xmax,double ymax)2687     Double2DParam::setDisplayRange(double xmin, double ymin,
2688     double xmax, double ymax)
2689   {
2690     double vmin[2] = {xmin, ymin};
2691     _paramProps.propSetDoubleN(kOfxParamPropDisplayMin, vmin, 2);
2692     double vmax[2] = {xmax, ymax};
2693     _paramProps.propSetDoubleN(kOfxParamPropDisplayMax, vmax, 2);
2694   }
2695 
2696   /** @brief get the default value */
getDefault(double & x,double & y)2697   void Double2DParam::getDefault(double &x, double &y)
2698   {
2699     x = _paramProps.propGetDouble(kOfxParamPropDefault, 0);
2700     y = _paramProps.propGetDouble(kOfxParamPropDefault, 1);
2701   }
2702 
2703 
2704   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
2705   void
getRange(double & xmin,double & ymin,double & xmax,double & ymax)2706     Double2DParam::getRange(double &xmin, double &ymin,
2707     double &xmax, double &ymax)
2708   {
2709     xmin = _paramProps.propGetDouble(kOfxParamPropMin, 0);
2710     ymin = _paramProps.propGetDouble(kOfxParamPropMin, 1);
2711     xmax = _paramProps.propGetDouble(kOfxParamPropMax, 0);
2712     ymax = _paramProps.propGetDouble(kOfxParamPropMax, 1);
2713   }
2714 
2715   /** @brief set the display min and max, default is to be the same as the range param */
2716   void
getDisplayRange(double & xmin,double & ymin,double & xmax,double & ymax)2717     Double2DParam::getDisplayRange(double &xmin, double &ymin,
2718     double &xmax, double &ymax)
2719   {
2720     xmin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 0);
2721     ymin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 1);
2722     xmax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 0);
2723     ymax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 1);
2724   }
2725 
2726   /** @brief get value */
getValue(double & x,double & y) const2727   void Double2DParam::getValue(double &x, double &y) const
2728   {
2729     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y);
2730     throwSuiteStatusException(stat);
2731   }
2732 
2733   /** @brief get the value at a time */
getValueAtTime(double t,double & x,double & y) const2734   void Double2DParam::getValueAtTime(double t, double &x, double &y) const
2735   {
2736     if ( OFX::IsNaN(t) ) {
2737       throwSuiteStatusException(kOfxStatErrValue);
2738     }
2739     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y);
2740     throwSuiteStatusException(stat);
2741   }
2742 
2743   /** @brief set value */
setValue(double x,double y)2744   void Double2DParam::setValue(double x, double y)
2745   {
2746     if ( OFX::IsNaN(x) || OFX::IsNaN(y) ) {
2747       throwSuiteStatusException(kOfxStatErrValue);
2748     }
2749     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y);
2750     throwSuiteStatusException(stat);
2751   }
2752 
2753   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,double x,double y)2754   void Double2DParam::setValueAtTime(double t, double x, double y)
2755   {
2756     if ( OFX::IsNaN(t) ) {
2757       throwSuiteStatusException(kOfxStatErrValue);
2758     }
2759     if ( OFX::IsNaN(x) || OFX::IsNaN(y) ) {
2760       throwSuiteStatusException(kOfxStatErrValue);
2761     }
2762     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
2763     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y);
2764     throwSuiteStatusException(stat);
2765   }
2766 
2767   /** @brief get the value at a time */
differentiate(double t,double & x,double & y)2768   void Double2DParam::differentiate(double t, double &x, double &y)
2769   {
2770     if ( OFX::IsNaN(t) ) {
2771       throwSuiteStatusException(kOfxStatErrValue);
2772     }
2773     if(!OFX::Private::gParamSuite->paramGetDerivative) throwHostMissingSuiteException("paramGetDerivative");
2774     OfxStatus stat = OFX::Private::gParamSuite->paramGetDerivative(_paramHandle, t, &x, &y);
2775     throwSuiteStatusException(stat);
2776   }
2777 
2778   /** @brief get the value at a time */
integrate(double t1,double t2,double & x,double & y)2779   void Double2DParam::integrate(double t1, double t2, double &x, double &y)
2780   {
2781     if ( OFX::IsNaN(t1) || OFX::IsNaN(t2) ) {
2782       throwSuiteStatusException(kOfxStatErrValue);
2783     }
2784     if(!OFX::Private::gParamSuite->paramGetIntegral) throwHostMissingSuiteException("paramGetIntegral");
2785     OfxStatus stat = OFX::Private::gParamSuite->paramGetIntegral(_paramHandle, t1, t2, &x, &y);
2786     throwSuiteStatusException(stat);
2787   }
2788 
2789   /** @brief delete all keys and set to default value */
resetToDefault()2790   void Double2DParam::resetToDefault()
2791   {
2792     deleteAllKeys();
2793     double v0, v1;
2794     getDefault(v0, v1);
2795     setValue(v0, v1);
2796   }
2797 
2798   ////////////////////////////////////////////////////////////////////////////////
2799   // 3D Double params
2800 
2801   /** @brief hidden constructor */
Double3DParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)2802   Double3DParam::Double3DParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
2803     : BaseDoubleParam(paramSet, name, eDouble3DParam, handle)
2804   {
2805   }
2806 
2807   /** @brief set the default value */
setDefault(double x,double y,double z)2808   void Double3DParam::setDefault(double x, double y, double z)
2809   {
2810     double v[3] = {x, y, z};
2811     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 3);
2812   }
2813 
2814   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
2815   void
setRange(double xmin,double ymin,double zmin,double xmax,double ymax,double zmax)2816     Double3DParam::setRange(double xmin, double ymin, double zmin,
2817     double xmax, double ymax, double zmax)
2818   {
2819     double vmin[3] = {xmin, ymin, zmin};
2820     _paramProps.propSetDoubleN(kOfxParamPropMin, vmin, 3);
2821     double vmax[3] = {xmax, ymax, zmax};
2822     _paramProps.propSetDoubleN(kOfxParamPropMax, vmax, 3);
2823   }
2824 
2825   /** @brief set the display min and max, default is to be the same as the range param */
2826   void
setDisplayRange(double xmin,double ymin,double zmin,double xmax,double ymax,double zmax)2827     Double3DParam::setDisplayRange(double xmin, double ymin, double zmin,
2828     double xmax, double ymax, double zmax)
2829   {
2830     double vmin[3] = {xmin, ymin, zmin};
2831     _paramProps.propSetDoubleN(kOfxParamPropDisplayMin, vmin, 3);
2832     double vmax[3] = {xmax, ymax, zmax};
2833     _paramProps.propSetDoubleN(kOfxParamPropDisplayMax, vmax, 3);
2834   }
2835 
2836   /** @brief get the default value */
getDefault(double & x,double & y,double & z)2837   void Double3DParam::getDefault(double &x, double &y, double &z)
2838   {
2839     x = _paramProps.propGetDouble(kOfxParamPropDefault, 0);
2840     y = _paramProps.propGetDouble(kOfxParamPropDefault, 1);
2841     z = _paramProps.propGetDouble(kOfxParamPropDefault, 2);
2842   }
2843 
2844 
2845   /** @brief set the hard min/max range, default is DOUBLE_MIN, DOUBLE_MAX */
2846   void
getRange(double & xmin,double & ymin,double & zmin,double & xmax,double & ymax,double & zmax)2847     Double3DParam::getRange(double &xmin, double &ymin, double &zmin,
2848     double &xmax, double &ymax, double &zmax)
2849   {
2850     xmin = _paramProps.propGetDouble(kOfxParamPropMin, 0);
2851     ymin = _paramProps.propGetDouble(kOfxParamPropMin, 1);
2852     zmin = _paramProps.propGetDouble(kOfxParamPropMin, 2);
2853     xmax = _paramProps.propGetDouble(kOfxParamPropMax, 0);
2854     ymax = _paramProps.propGetDouble(kOfxParamPropMax, 1);
2855     zmax = _paramProps.propGetDouble(kOfxParamPropMax, 2);
2856   }
2857 
2858   /** @brief set the display min and max, default is to be the same as the range param */
2859   void
getDisplayRange(double & xmin,double & ymin,double & zmin,double & xmax,double & ymax,double & zmax)2860     Double3DParam::getDisplayRange(double &xmin, double &ymin, double &zmin,
2861     double &xmax, double &ymax, double &zmax)
2862   {
2863     xmin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 0);
2864     ymin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 1);
2865     zmin = _paramProps.propGetDouble(kOfxParamPropDisplayMin, 2);
2866     xmax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 0);
2867     ymax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 1);
2868     zmax = _paramProps.propGetDouble(kOfxParamPropDisplayMax, 2);
2869   }
2870 
2871   /** @brief get value */
getValue(double & x,double & y,double & z) const2872   void Double3DParam::getValue(double &x, double &y, double &z) const
2873   {
2874     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &x, &y, &z);
2875     throwSuiteStatusException(stat);
2876   }
2877 
2878   /** @brief get the value at a time */
getValueAtTime(double t,double & x,double & y,double & z) const2879   void Double3DParam::getValueAtTime(double t, double &x, double &y, double &z) const
2880   {
2881     if ( OFX::IsNaN(t) ) {
2882       throwSuiteStatusException(kOfxStatErrValue);
2883     }
2884     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &x, &y, &z);
2885     throwSuiteStatusException(stat);
2886   }
2887 
2888   /** @brief set value */
setValue(double x,double y,double z)2889   void Double3DParam::setValue(double x, double y, double z)
2890   {
2891     if ( OFX::IsNaN(x) || OFX::IsNaN(y) || OFX::IsNaN(z) ) {
2892       throwSuiteStatusException(kOfxStatErrValue);
2893     }
2894     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, x, y, z);
2895     throwSuiteStatusException(stat);
2896   }
2897 
2898   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,double x,double y,double z)2899   void Double3DParam::setValueAtTime(double t, double x, double y, double z)
2900   {
2901     if ( OFX::IsNaN(t) ) {
2902       throwSuiteStatusException(kOfxStatErrValue);
2903     }
2904     if ( OFX::IsNaN(x) || OFX::IsNaN(y) || OFX::IsNaN(z) ) {
2905       throwSuiteStatusException(kOfxStatErrValue);
2906     }
2907     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
2908     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, x, y, z);
2909     throwSuiteStatusException(stat);
2910   }
2911 
2912   /** @brief get the value at a time */
differentiate(double t,double & x,double & y,double & z)2913   void Double3DParam::differentiate(double t, double &x, double &y, double &z)
2914   {
2915     if ( OFX::IsNaN(t) ) {
2916       throwSuiteStatusException(kOfxStatErrValue);
2917     }
2918     if(!OFX::Private::gParamSuite->paramGetDerivative) throwHostMissingSuiteException("paramGetDerivative");
2919     OfxStatus stat = OFX::Private::gParamSuite->paramGetDerivative(_paramHandle, t, &x, &y, &z);
2920     throwSuiteStatusException(stat);
2921   }
2922 
2923   /** @brief get the value at a time */
integrate(double t1,double t2,double & x,double & y,double & z)2924   void Double3DParam::integrate(double t1, double t2, double &x, double &y, double &z)
2925   {
2926     if ( OFX::IsNaN(t1) || OFX::IsNaN(t2) ) {
2927       throwSuiteStatusException(kOfxStatErrValue);
2928     }
2929     if(!OFX::Private::gParamSuite->paramGetIntegral) throwHostMissingSuiteException("paramGetIntegral");
2930     OfxStatus stat = OFX::Private::gParamSuite->paramGetIntegral(_paramHandle, t1, t2, &x, &y, &z);
2931     throwSuiteStatusException(stat);
2932   }
2933 
2934   /** @brief delete all keys and set to default value */
resetToDefault()2935   void Double3DParam::resetToDefault()
2936   {
2937     deleteAllKeys();
2938     double v0, v1, v2;
2939     getDefault(v0, v1, v2);
2940     setValue(v0, v1, v2);
2941   }
2942 
2943   ////////////////////////////////////////////////////////////////////////////////
2944   // RGB colour param
2945   /** @brief hidden constructor */
RGBParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)2946   RGBParam::RGBParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
2947     : ValueParam(paramSet, name, eRGBParam, handle)
2948   {
2949   }
2950 
2951   /** @brief set the default value */
setDefault(double r,double g,double b)2952   void RGBParam::setDefault(double r, double g, double b)
2953   {
2954     double v[3] = {r, g, b};
2955     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 3);
2956   }
2957 
2958 
2959   /** @brief get the default value */
getDefault(double & r,double & g,double & b)2960   void RGBParam::getDefault(double &r, double &g, double &b)
2961   {
2962     r = _paramProps.propGetDouble(kOfxParamPropDefault, 0);
2963     g = _paramProps.propGetDouble(kOfxParamPropDefault, 1);
2964     b = _paramProps.propGetDouble(kOfxParamPropDefault, 2);
2965   }
2966 
2967   /** @brief get value */
getValue(double & r,double & g,double & b) const2968   void RGBParam::getValue(double &r, double &g, double &b) const
2969   {
2970     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &r, &g, &b);
2971     throwSuiteStatusException(stat);
2972   }
2973 
2974   /** @brief get the value at a time */
getValueAtTime(double t,double & r,double & g,double & b) const2975   void RGBParam::getValueAtTime(double t, double &r, double &g, double &b) const
2976   {
2977     if ( OFX::IsNaN(t) ) {
2978       throwSuiteStatusException(kOfxStatErrValue);
2979     }
2980     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &r, &g, &b);
2981     throwSuiteStatusException(stat);
2982   }
2983 
2984   /** @brief set value */
setValue(double r,double g,double b)2985   void RGBParam::setValue(double r, double g, double b)
2986   {
2987     if ( OFX::IsNaN(r) || OFX::IsNaN(g) || OFX::IsNaN(b) ) {
2988       throwSuiteStatusException(kOfxStatErrValue);
2989     }
2990     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, r, g, b);
2991     throwSuiteStatusException(stat);
2992   }
2993 
2994   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,double r,double g,double b)2995   void RGBParam::setValueAtTime(double t, double r, double g, double b)
2996   {
2997     if ( OFX::IsNaN(r) || OFX::IsNaN(g) || OFX::IsNaN(b) ) {
2998       throwSuiteStatusException(kOfxStatErrValue);
2999     }
3000     if ( OFX::IsNaN(t) ) {
3001       throwSuiteStatusException(kOfxStatErrValue);
3002     }
3003     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
3004     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, r, g, b);
3005     throwSuiteStatusException(stat);
3006   }
3007 
3008   /** @brief delete all keys and set to default value */
resetToDefault()3009   void RGBParam::resetToDefault()
3010   {
3011     deleteAllKeys();
3012     double v0, v1, v2;
3013     getDefault(v0, v1, v2);
3014     setValue(v0, v1, v2);
3015   }
3016 
3017   ////////////////////////////////////////////////////////////////////////////////
3018   // RGBA colour param
3019   /** @brief hidden constructor */
RGBAParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3020   RGBAParam::RGBAParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3021     : ValueParam(paramSet, name, eRGBAParam, handle)
3022   {
3023   }
3024 
3025   /** @brief set the default value */
setDefault(double r,double g,double b,double a)3026   void RGBAParam::setDefault(double r, double g, double b, double a)
3027   {
3028     double v[4] = {r, g, b, a};
3029     _paramProps.propSetDoubleN(kOfxParamPropDefault, v, 4);
3030   }
3031 
3032 
3033   /** @brief get the default value */
getDefault(double & r,double & g,double & b,double & a)3034   void RGBAParam::getDefault(double &r, double &g, double &b, double &a)
3035   {
3036     r = _paramProps.propGetDouble(kOfxParamPropDefault, 0);
3037     g = _paramProps.propGetDouble(kOfxParamPropDefault, 1);
3038     b = _paramProps.propGetDouble(kOfxParamPropDefault, 2);
3039     a = _paramProps.propGetDouble(kOfxParamPropDefault, 3);
3040   }
3041 
3042   /** @brief get value */
getValue(double & r,double & g,double & b,double & a) const3043   void RGBAParam::getValue(double &r, double &g, double &b, double &a) const
3044   {
3045     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &r, &g, &b, &a);
3046     throwSuiteStatusException(stat);
3047   }
3048 
3049   /** @brief get the value at a time */
getValueAtTime(double t,double & r,double & g,double & b,double & a) const3050   void RGBAParam::getValueAtTime(double t, double &r, double &g, double &b, double &a) const
3051   {
3052     if ( OFX::IsNaN(t) ) {
3053       throwSuiteStatusException(kOfxStatErrValue);
3054     }
3055     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &r, &g, &b, &a);
3056     throwSuiteStatusException(stat);
3057   }
3058 
3059   /** @brief set value */
setValue(double r,double g,double b,double a)3060   void RGBAParam::setValue(double r, double g, double b, double a)
3061   {
3062     if ( OFX::IsNaN(r) || OFX::IsNaN(g) || OFX::IsNaN(b) || OFX::IsNaN(a) ) {
3063       throwSuiteStatusException(kOfxStatErrValue);
3064     }
3065     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, r, g, b, a);
3066     throwSuiteStatusException(stat);
3067   }
3068 
3069   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,double r,double g,double b,double a)3070   void RGBAParam::setValueAtTime(double t, double r, double g, double b, double a)
3071   {
3072     if ( OFX::IsNaN(t) ) {
3073       throwSuiteStatusException(kOfxStatErrValue);
3074     }
3075     if ( OFX::IsNaN(r) || OFX::IsNaN(g) || OFX::IsNaN(b) || OFX::IsNaN(a) ) {
3076       throwSuiteStatusException(kOfxStatErrValue);
3077     }
3078     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
3079     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, r, g, b, a);
3080     throwSuiteStatusException(stat);
3081   }
3082 
3083   /** @brief delete all keys and set to default value */
resetToDefault()3084   void RGBAParam::resetToDefault()
3085   {
3086     deleteAllKeys();
3087     double v0, v1, v2, v3;
3088     getDefault(v0, v1, v2, v3);
3089     setValue(v0, v1, v2, v3);
3090   }
3091 
3092   ////////////////////////////////////////////////////////////////////////////////
3093   // Wraps up a string param */
3094 
3095   /** @brief hidden constructor */
StringParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3096   StringParam::StringParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3097     : ValueParam(paramSet, name, eStringParam, handle)
3098   {
3099   }
3100 
3101   /** @brief set the default value */
setDefault(const std::string & v)3102   void StringParam::setDefault(const std::string &v)
3103   {
3104     _paramProps.propSetString(kOfxParamPropDefault, v);
3105   }
3106 
3107   /** @brief get the default value */
getDefault(std::string & v)3108   void StringParam::getDefault(std::string &v)
3109   {
3110     v = _paramProps.propGetString(kOfxParamPropDefault);
3111   }
3112 
3113   /** @brief get value */
getValue(std::string & v) const3114   void StringParam::getValue(std::string &v) const
3115   {
3116     char *cStr;
3117     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &cStr);
3118     throwSuiteStatusException(stat);
3119 # ifdef DEBUG
3120     if (!is_utf8(cStr)) {
3121       std::cout << "Warning: string param '" << getName() << "' contains a non-UTF-8 string: " << cStr << std::endl;
3122     }
3123 # endif
3124     v = cStr;
3125   }
3126 
3127   /** @brief get the value at a time */
getValueAtTime(double t,std::string & v) const3128   void StringParam::getValueAtTime(double t, std::string &v) const
3129   {
3130     if ( OFX::IsNaN(t) ) {
3131       throwSuiteStatusException(kOfxStatErrValue);
3132     }
3133     char *cStr;
3134     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &cStr);
3135     throwSuiteStatusException(stat);
3136 # ifdef DEBUG
3137     if (!is_utf8(cStr)) {
3138       std::cout << "Warning: string param '" << getName() << "' contains a non-UTF-8 string: " << cStr << std::endl;
3139     }
3140 # endif
3141     v = cStr;
3142   }
3143 
3144   /** @brief set value */
setValue(const std::string & v)3145   void StringParam::setValue(const std::string &v)
3146   {
3147     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v.c_str());
3148     throwSuiteStatusException(stat);
3149 # ifdef DEBUG
3150     if (!is_utf8(v.c_str())) {
3151       std::cout << "Warning: string param '" << getName() << "' contains a non-UTF-8 string: " << v.c_str() << std::endl;
3152     }
3153 # endif
3154   }
3155 
3156   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,const std::string & v)3157   void StringParam::setValueAtTime(double t, const std::string &v)
3158   {
3159     if ( OFX::IsNaN(t) ) {
3160       throwSuiteStatusException(kOfxStatErrValue);
3161     }
3162     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
3163     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v.c_str());
3164     throwSuiteStatusException(stat);
3165 # ifdef DEBUG
3166     if (!is_utf8(v.c_str())) {
3167       std::cout << "Warning: string param '" << getName() << "' contains a non-UTF-8 string: " << v.c_str() << std::endl;
3168     }
3169 # endif
3170   }
3171 
3172   /** @brief delete all keys and set to default value */
resetToDefault()3173   void StringParam::resetToDefault()
3174   {
3175     deleteAllKeys();
3176     std::string v;
3177     getDefault(v);
3178     setValue(v);
3179   }
3180 
3181   ////////////////////////////////////////////////////////////////////////////////
3182   // Wraps up a Boolean integer param */
3183 
3184   /** @brief hidden constructor */
BooleanParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3185   BooleanParam::BooleanParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3186     : ValueParam(paramSet, name, eBooleanParam, handle)
3187   {
3188   }
3189 
3190   /** @brief set the default value */
setDefault(bool v)3191   void BooleanParam::setDefault(bool v)
3192   {
3193     _paramProps.propSetInt(kOfxParamPropDefault, v);
3194   }
3195 
3196   /** @brief get the default value */
getDefault(bool & v)3197   void BooleanParam::getDefault(bool &v)
3198   {
3199     v = _paramProps.propGetInt(kOfxParamPropDefault) != 0;
3200   }
3201 
3202   /** @brief get value */
getValue(bool & v) const3203   void BooleanParam::getValue(bool &v) const
3204   {
3205     int iVal;
3206     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &iVal);
3207     throwSuiteStatusException(stat);
3208     v = iVal != 0;
3209   }
3210 
3211   /** @brief get the value at a time */
getValueAtTime(double t,bool & v) const3212   void BooleanParam::getValueAtTime(double t, bool &v) const
3213   {
3214     if ( OFX::IsNaN(t) ) {
3215       throwSuiteStatusException(kOfxStatErrValue);
3216     }
3217     int iVal;
3218     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &iVal);
3219     throwSuiteStatusException(stat);
3220     v = iVal != 0;
3221   }
3222 
3223   /** @brief set value */
setValue(bool v)3224   void BooleanParam::setValue(bool v)
3225   {
3226     int iVal = v;
3227     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, iVal);
3228     throwSuiteStatusException(stat);
3229   }
3230 
3231   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,bool v)3232   void BooleanParam::setValueAtTime(double t, bool v)
3233   {
3234     if ( OFX::IsNaN(t) ) {
3235       throwSuiteStatusException(kOfxStatErrValue);
3236     }
3237     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
3238     int iVal = v;
3239     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, iVal);
3240     throwSuiteStatusException(stat);
3241   }
3242 
3243   /** @brief delete all keys and set to default value */
resetToDefault()3244   void BooleanParam::resetToDefault()
3245   {
3246     deleteAllKeys();
3247     bool v;
3248     getDefault(v);
3249     setValue(v);
3250   }
3251 
3252   ////////////////////////////////////////////////////////////////////////////////
3253   // Wraps up a choice integer param */
3254 
3255   /** @brief hidden constructor */
ChoiceParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3256   ChoiceParam::ChoiceParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3257     : ValueParam(paramSet, name, eChoiceParam, handle)
3258   {
3259   }
3260 
3261   /** @brief set the default value */
setDefault(int v)3262   void ChoiceParam::setDefault(int v)
3263   {
3264     _paramProps.propSetInt(kOfxParamPropDefault, v);
3265   }
3266 
3267   /** @brief get the default value */
getDefault(int & v)3268   void ChoiceParam::getDefault(int &v)
3269   {
3270     v = _paramProps.propGetInt(kOfxParamPropDefault);
3271   }
3272 
3273   /** @brief get value */
getValue(int & v) const3274   void ChoiceParam::getValue(int &v) const
3275   {
3276     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &v);
3277     throwSuiteStatusException(stat);
3278   }
3279 
3280   /** @brief get the value at a time */
getValueAtTime(double t,int & v) const3281   void ChoiceParam::getValueAtTime(double t, int &v) const
3282   {
3283     if ( OFX::IsNaN(t) ) {
3284       throwSuiteStatusException(kOfxStatErrValue);
3285     }
3286     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &v);
3287     throwSuiteStatusException(stat);
3288   }
3289 
3290   /** @brief set value */
setValue(int v)3291   void ChoiceParam::setValue(int v)
3292   {
3293     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v);
3294     throwSuiteStatusException(stat);
3295   }
3296 
3297   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,int v)3298   void ChoiceParam::setValueAtTime(double t, int v)
3299   {
3300     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
3301     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v);
3302     throwSuiteStatusException(stat);
3303   }
3304 
3305   /** @brief how many options do we have */
getNOptions(void)3306   int ChoiceParam::getNOptions(void)
3307   {
3308     int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
3309     return nCurrentValues;
3310   }
3311 
3312   /** @brief get the option value */
getOption(int ix,std::string & v)3313   void ChoiceParam::getOption(int ix, std::string &v)
3314   {
3315     v = _paramProps.propGetString(kOfxParamPropChoiceOption, ix);
3316   }
3317 
3318 #ifdef OFX_EXTENSIONS_NATRON
setEnum(int item,const std::string & name)3319   void ChoiceParam::setEnum(int item, const std::string &name)
3320   {
3321     _paramProps.propSetString(kOfxParamPropChoiceEnum, name, item, false);
3322   }
3323 
3324   /** @brief get the option enum */
getEnum(int ix,std::string & name)3325   void ChoiceParam::getEnum(int ix, std::string &name)
3326   {
3327     name = _paramProps.propGetString(kOfxParamPropChoiceEnum, ix, false);
3328   }
3329 #endif
3330 
getOptions(std::vector<std::string> * options,std::vector<std::string> * optionsHints,std::vector<std::string> * optionsNames)3331   void ChoiceParam::getOptions(std::vector<std::string>* options, std::vector<std::string>* optionsHints, std::vector<std::string>* optionsNames)
3332   {
3333     _paramProps.propGetStringN(kOfxParamPropChoiceOption, options);
3334 #ifdef OFX_EXTENSIONS_TUTTLE
3335     if (optionsHints) {
3336       _paramProps.propGetStringN(kOfxParamPropChoiceLabelOption, optionsHints, false);
3337     }
3338 #else
3339     unused(optionsHints);
3340 #endif
3341 #ifdef OFX_EXTENSIONS_NATRON
3342     if (optionsNames) {
3343       _paramProps.propGetStringN(kOfxParamPropChoiceEnum, optionsNames, false);
3344     }
3345 #else
3346     unused(optionsNames);
3347 #endif
3348   }
3349 
3350   /** @brief add another option */
appendOption(const std::string & optionLabel,const std::string & optionHint,const std::string & optionEnum)3351   void ChoiceParam::appendOption(const std::string &optionLabel, const std::string& optionHint, const std::string& optionEnum)
3352   {
3353     int nCurrentValues = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
3354     if(!optionHint.empty()) {
3355 #ifdef OFX_EXTENSIONS_TUTTLE
3356       // Choice label is an ofx extension. If the host doesn't support it,
3357       // we put this information into the parameter hint.
3358       // from https://github.com/tuttleofx/TuttleOFX/commit/ae6e14e99f62b5efa89e4de4a3bc33129ac6afd0
3359       try {
3360         // this property is an optional extension.
3361          _paramProps.propSetString(kOfxParamPropChoiceLabelOption, optionHint, nCurrentValues);
3362       } catch(std::exception&)
3363 #endif
3364       {
3365         // If the kOfxParamPropChoiceLabelOption doesn't exist, we put that information into the Hint.
3366         // It's better than nothing...
3367         std::string hint = _paramProps.propGetString(kOfxParamPropHint);
3368         if(!hint.empty()) {
3369           hint += "\n";
3370           if( nCurrentValues == 0 ) {
3371             hint += "\n";
3372           }
3373         }
3374         hint += optionLabel + ": " + optionHint;
3375         _paramProps.propSetString(kOfxParamPropHint, hint);
3376       }
3377     }
3378 #ifdef OFX_EXTENSIONS_NATRON
3379     if (_paramProps.propExists(kOfxParamPropChoiceEnum)) {
3380       _paramProps.propSetString(kOfxParamPropChoiceEnum, optionEnum.empty() ? optionLabel : optionEnum, nCurrentValues);
3381     }
3382 #else
3383     unused(optionEnum);
3384 #endif
3385     _paramProps.propSetString(kOfxParamPropChoiceOption, optionLabel, nCurrentValues);
3386   }
3387 
3388   /** @brief set the string of a specific option */
setOption(int item,const std::string & str)3389   void ChoiceParam::setOption(int item, const std::string &str)
3390   {
3391     _paramProps.propSetString(kOfxParamPropChoiceOption, str, item);
3392   }
3393 
3394   /** @brief set to the default value */
resetOptions(const std::vector<std::string> & newEntries,const std::vector<std::string> & newEntriesHint,const std::vector<std::string> & newEntriesEnum)3395   void ChoiceParam::resetOptions(const std::vector<std::string>& newEntries,
3396                                  const std::vector<std::string>& newEntriesHint,
3397                                  const std::vector<std::string>& newEntriesEnum)
3398   {
3399     assert(newEntries.size() == newEntriesHint.size() || newEntriesHint.empty());
3400     assert(newEntries.size() == newEntriesEnum.size() || newEntriesEnum.empty());
3401 
3402     if ((newEntries.size() != newEntriesHint.size() && !newEntriesHint.empty()) ||
3403         (newEntries.size() != newEntriesEnum.size() && !newEntriesEnum.empty())) {
3404       // Invalid parameters or empty newEntries, reset the property
3405 #ifdef OFX_EXTENSIONS_TUTTLE
3406       if (_paramProps.propGetDimension(kOfxParamPropChoiceLabelOption, false) > 0) {
3407         _paramProps.propReset(kOfxParamPropChoiceLabelOption);
3408       }
3409 #endif
3410 #ifdef OFX_EXTENSIONS_NATRON
3411       if (_paramProps.propGetDimension(kOfxParamPropChoiceEnum, false) > 0) {
3412         _paramProps.propReset(kOfxParamPropChoiceEnum);
3413       }
3414 #endif
3415       _paramProps.propReset(kOfxParamPropChoiceOption);
3416     } else {
3417       // Set the new entries
3418 #ifdef OFX_EXTENSIONS_TUTTLE
3419       if (_paramProps.propExists(kOfxParamPropChoiceLabelOption)) {
3420         if (!newEntriesHint.empty()) {
3421           _paramProps.propSetStringN(kOfxParamPropChoiceLabelOption, newEntriesHint, false);
3422         } else {
3423           _paramProps.propReset(kOfxParamPropChoiceLabelOption);
3424         }
3425       }
3426 #endif
3427 #ifdef OFX_EXTENSIONS_NATRON
3428       if (_paramProps.propExists(kOfxParamPropChoiceEnum)) {
3429         if (!newEntriesEnum.empty()) {
3430           _paramProps.propSetStringN(kOfxParamPropChoiceEnum, newEntriesEnum, false);
3431         } else {
3432           _paramProps.propReset(kOfxParamPropChoiceEnum);
3433         }
3434       }
3435 #endif
3436       _paramProps.propSetStringN(kOfxParamPropChoiceOption, newEntries);
3437 
3438     }
3439   }
3440 
3441   /** @brief delete all keys and set to default value */
resetToDefault()3442   void ChoiceParam::resetToDefault()
3443   {
3444     deleteAllKeys();
3445     int v;
3446     getDefault(v);
3447     setValue(v);
3448   }
3449 
3450 #ifdef OFX_EXTENSIONS_NATRON
3451     /** @brief whether the menu should be cascading, and each option contains a slash-separated path to the item, defaults to false. */
getIsCascading()3452     bool ChoiceParam::getIsCascading()
3453     {
3454         bool v = _paramProps.propGetInt(kNatronOfxParamPropChoiceCascading, false) != 0;
3455         return v;
3456     }
3457 
3458 #endif
3459 
3460 #ifdef OFX_EXTENSIONS_RESOLVE
3461   ////////////////////////////////////////////////////////////////////////////////
3462   // Wraps up a string choice param */
3463 
3464   /** @brief hidden constructor */
StrChoiceParam(const ParamSet * p_ParamSet,const std::string & p_Name,OfxParamHandle p_Handle)3465   StrChoiceParam::StrChoiceParam(const ParamSet* p_ParamSet, const std::string& p_Name, OfxParamHandle p_Handle)
3466       : StringParam(p_ParamSet, p_Name, p_Handle)
3467   {
3468       _paramType = eStrChoiceParam;
3469   }
3470 
3471   /** @brief how many options do we have */
getNOptions()3472   int StrChoiceParam::getNOptions()
3473   {
3474       const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
3475       assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum));
3476 
3477       return numOptions;
3478   }
3479 
3480   /** @brief add another option */
appendOption(const std::string & p_Enum,const std::string & p_Option)3481   void StrChoiceParam::appendOption(const std::string& p_Enum, const std::string& p_Option)
3482   {
3483       const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
3484       assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum));
3485 
3486       _paramProps.propSetString(kOfxParamPropChoiceEnum, p_Enum, numOptions);
3487       _paramProps.propSetString(kOfxParamPropChoiceOption, p_Option, numOptions);
3488   }
3489 
3490   /** @brief set the string of a specific option */
setOption(const std::string & p_Index,const std::string & p_Option)3491   void StrChoiceParam::setOption(const std::string& p_Index, const std::string& p_Option)
3492   {
3493       const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
3494       assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum));
3495 
3496       for (int i = 0; i < numOptions; ++i)
3497       {
3498           const std::string& enumStr = _paramProps.propGetString(kOfxParamPropChoiceEnum, i);
3499           if (enumStr == p_Index)
3500           {
3501               _paramProps.propSetString(kOfxParamPropChoiceOption, p_Option, i);
3502 
3503               return;
3504           }
3505       }
3506 
3507       throwSuiteStatusException(kOfxStatErrBadIndex);
3508   }
3509 
3510   /** @brief get the option value */
getOption(const std::string & p_Index,std::string & p_Option)3511   void StrChoiceParam::getOption(const std::string& p_Index, std::string& p_Option)
3512   {
3513       const int numOptions = _paramProps.propGetDimension(kOfxParamPropChoiceOption);
3514       assert(numOptions == _paramProps.propGetDimension(kOfxParamPropChoiceEnum));
3515 
3516       for (int i = 0; i < numOptions; ++i)
3517       {
3518           const std::string& enumStr = _paramProps.propGetString(kOfxParamPropChoiceEnum, i);
3519           if (enumStr == p_Index)
3520           {
3521               p_Option = _paramProps.propGetString(kOfxParamPropChoiceOption, i);
3522 
3523               return;
3524           }
3525       }
3526 
3527       throwSuiteStatusException(kOfxStatErrBadIndex);
3528   }
3529 
3530   /** @brief set to the default value */
resetOptions()3531   void StrChoiceParam::resetOptions()
3532   {
3533       _paramProps.propReset(kOfxParamPropChoiceEnum);
3534       _paramProps.propReset(kOfxParamPropChoiceOption);
3535   }
3536 #endif
3537 
3538   ////////////////////////////////////////////////////////////////////////////////
3539   // Wraps up a custom param */
3540 
3541   /** @brief hidden constructor */
CustomParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3542   CustomParam::CustomParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3543     : ValueParam(paramSet, name, eCustomParam, handle)
3544   {
3545   }
3546 
3547   /** @brief set the default value */
setDefault(const std::string & v)3548   void CustomParam::setDefault(const std::string &v)
3549   {
3550     _paramProps.propSetString(kOfxParamPropDefault, v);
3551   }
3552 
3553   /** @brief get the default value */
getDefault(std::string & v)3554   void CustomParam::getDefault(std::string &v)
3555   {
3556     v = _paramProps.propGetString(kOfxParamPropDefault);
3557   }
3558 
3559   /** @brief get value */
getValue(std::string & v) const3560   void CustomParam::getValue(std::string &v) const
3561   {
3562     char *cStr;
3563     OfxStatus stat = OFX::Private::gParamSuite->paramGetValue(_paramHandle, &cStr);
3564     throwSuiteStatusException(stat);
3565     v = cStr;
3566   }
3567 
3568   /** @brief get the value at a time */
getValueAtTime(double t,std::string & v) const3569   void CustomParam::getValueAtTime(double t, std::string &v) const
3570   {
3571     if ( OFX::IsNaN(t) ) {
3572       throwSuiteStatusException(kOfxStatErrValue);
3573     }
3574     char *cStr;
3575     OfxStatus stat = OFX::Private::gParamSuite->paramGetValueAtTime(_paramHandle, t, &cStr);
3576     throwSuiteStatusException(stat);
3577     v = cStr;
3578   }
3579 
3580   /** @brief set value */
setValue(const std::string & v)3581   void CustomParam::setValue(const std::string &v)
3582   {
3583     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, v.c_str());
3584     throwSuiteStatusException(stat);
3585   }
3586 
3587   /** @brief set value */
setValue(const char * str)3588   void CustomParam::setValue(const char* str)
3589   {
3590     OfxStatus stat = OFX::Private::gParamSuite->paramSetValue(_paramHandle, str);
3591     throwSuiteStatusException(stat);
3592   }
3593 
3594   /** @brief set the value at a time, implicitly adds a keyframe */
setValueAtTime(double t,const std::string & v)3595   void CustomParam::setValueAtTime(double t, const std::string &v)
3596   {
3597     if ( OFX::IsNaN(t) ) {
3598       throwSuiteStatusException(kOfxStatErrValue);
3599     }
3600     if(!OFX::Private::gParamSuite->paramSetValueAtTime) throwHostMissingSuiteException("paramSetValueAtTime");
3601     OfxStatus stat = OFX::Private::gParamSuite->paramSetValueAtTime(_paramHandle, t, v.c_str());
3602     throwSuiteStatusException(stat);
3603   }
3604 
3605   /** @brief delete all keys and set to default value */
resetToDefault()3606   void CustomParam::resetToDefault()
3607   {
3608     deleteAllKeys();
3609     std::string v;
3610     getDefault(v);
3611     setValue(v);
3612   }
3613 
3614   ////////////////////////////////////////////////////////////////////////////////
3615   // Wraps up a group param
3616   /** @brief hidden constructor */
GroupParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3617   GroupParam::GroupParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3618     : Param(paramSet, name, eGroupParam, handle)
3619   {
3620   }
3621 
3622   /** @brief whether the group is open or closed in a hierarchical layout */
getIsOpen()3623   bool GroupParam::getIsOpen()
3624   {
3625     bool v = _paramProps.propGetInt(kOfxParamPropGroupOpen, false) != 0; // introduced in OFX 1.2
3626     return v;
3627   }
3628 
3629   /** @brief whether the group is open or closed in a hierarchical layout, defaults to true */
setOpen(const bool v)3630   void GroupParam::setOpen(const bool v)
3631   {
3632     _paramProps.propSetInt(kOfxParamPropGroupOpen, v, false); // introduced in OFX 1.2
3633   }
3634 
3635   ////////////////////////////////////////////////////////////////////////////////
3636   // Wraps up a page param
3637 
3638   /** @brief hidden constructor */
PageParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3639   PageParam::PageParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3640     : Param(paramSet, name, ePageParam, handle)
3641   {
3642   }
3643 
3644   ////////////////////////////////////////////////////////////////////////////////
3645   // Wraps up a PushButton param
3646 
3647   /** @brief hidden constructor */
PushButtonParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3648   PushButtonParam::PushButtonParam(const ParamSet *paramSet, const std::string &name, OfxParamHandle handle)
3649     : Param(paramSet, name, ePushButtonParam, handle)
3650   {
3651   }
3652 
3653   ////////////////////////////////////////////////////////////////////////////////
3654   // Wraps up a Parametric param
3655 
3656   /** @brief hidden constructor */
ParametricParam(const ParamSet * paramSet,const std::string & name,OfxParamHandle handle)3657   ParametricParam::ParametricParam(const ParamSet* paramSet, const std::string &name, OfxParamHandle handle)
3658       : Param(paramSet, name, eParametricParam, handle)
3659   {}
3660 
getRange(double & min,double & max)3661   void ParametricParam::getRange(double &min, double &max)
3662   {
3663     double r[2] = {0., 0.};
3664     _paramProps.propGetDoubleN(kOfxParamPropParametricRange, r, 2);
3665     min = r[0];
3666     max = r[1];
3667   }
3668 
3669   /** @brief set the hard min/max range, default is -DBL_MAX, DBL_MAX */
setDimensionRange(int curveIndex,double min,double max)3670   void ParametricParam::setDimensionRange(int curveIndex, double min, double max)
3671   {
3672     // don't throw: the OFX 1.4 spec is not clear wether these properties exist
3673     _paramProps.propSetDouble(kOfxParamPropMin, min, curveIndex, false);
3674     _paramProps.propSetDouble(kOfxParamPropMax, max, curveIndex, false);
3675   }
3676 
3677   /** @brief set the display min and max, default is to be the same as the range param */
setDimensionDisplayRange(int curveIndex,double min,double max)3678   void ParametricParam::setDimensionDisplayRange(int curveIndex, double min, double max)
3679   {
3680     // don't throw: the OFX 1.4 spec is not clear wether these properties exist
3681     _paramProps.propSetDouble(kOfxParamPropDisplayMin, min, curveIndex, false);
3682     _paramProps.propSetDouble(kOfxParamPropDisplayMax, max, curveIndex, false);
3683   }
3684 
3685   /** @brief set the hard min/max range, default is -DBL_MAX, DBL_MAX */
getDimensionRange(int curveIndex,double & min,double & max)3686   void ParametricParam::getDimensionRange(int curveIndex, double &min, double &max)
3687   {
3688     min = _paramProps.propGetDouble(kOfxParamPropMin, curveIndex, false);
3689     max = _paramProps.propGetDouble(kOfxParamPropMax, curveIndex, false);
3690   }
3691 
3692   /** @brief set the display min and max, default is to be the same as the range param */
getDimensionDisplayRange(int curveIndex,double & min,double & max)3693   void ParametricParam::getDimensionDisplayRange(int curveIndex, double &min, double &max)
3694   {
3695     min = _paramProps.propGetDouble(kOfxParamPropDisplayMin, curveIndex, false);
3696     max = _paramProps.propGetDouble(kOfxParamPropDisplayMax, curveIndex, false);
3697   }
3698 
3699   /** @brief Evaluates a parametric parameter
3700 
3701       \arg curveIndex            which dimension to evaluate
3702       \arg time                  the time to evaluate to the parametric param at
3703       \arg parametricPosition    the position to evaluate the parametric param at
3704 
3705       @returns the double value is returned
3706   */
getValue(const int curveIndex,const OfxTime time,const double parametricPosition) const3707   double ParametricParam::getValue(const int curveIndex,
3708                                     const OfxTime time,
3709                                     const double parametricPosition) const
3710   {
3711     if ( OFX::IsNaN(time) ) {
3712       throwSuiteStatusException(kOfxStatErrValue);
3713     }
3714     double returnValue = 0.0;
3715     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamGetValue(_paramHandle,
3716                                                                                        curveIndex,
3717                                                                                        time,
3718                                                                                        parametricPosition,
3719                                                                                        &returnValue);
3720     throwSuiteStatusException(stat);
3721     return returnValue;
3722   }
3723 
3724   /** @brief Returns the number of control points in the parametric param.
3725 
3726       \arg curveIndex            which dimension to check
3727       \arg time                  the time to check
3728 
3729       @returns the integer value is returned
3730   */
getNControlPoints(const int curveIndex,const OfxTime time) const3731   int ParametricParam::getNControlPoints(const int curveIndex,
3732                                           const OfxTime time) const
3733   {
3734     if ( OFX::IsNaN(time) ) {
3735       throwSuiteStatusException(kOfxStatErrValue);
3736     }
3737     int returnValue = 0;
3738     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamGetNControlPoints(_paramHandle,
3739                                                                                                 curveIndex,
3740                                                                                                 time,
3741                                                                                                 &returnValue);
3742     throwSuiteStatusException(stat);
3743     return returnValue;
3744   }
3745 
3746   /** @brief Returns the key/value pair of the nth control point.
3747 
3748       \arg curveIndex            which dimension to check
3749       \arg time                  the time to check
3750       \arg nthCtl                the nth control point to get the value of
3751 
3752       @returns a pair with key and value
3753   */
getNthControlPoint(const int curveIndex,const OfxTime time,const int nthCtl) const3754   std::pair<double, double> ParametricParam::getNthControlPoint(const int curveIndex,
3755                                                                 const OfxTime time,
3756                                                                 const int nthCtl) const
3757   {
3758     if ( OFX::IsNaN(time) ) {
3759       throwSuiteStatusException(kOfxStatErrValue);
3760     }
3761     std::pair<double, double> returnValue;
3762     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamGetNthControlPoint(_paramHandle,
3763                                                                                                  curveIndex,
3764                                                                                                  time,
3765                                                                                                  nthCtl,
3766                                                                                                  &returnValue.first,
3767                                                                                                  &returnValue.second);
3768     throwSuiteStatusException(stat);
3769     return returnValue;
3770   }
3771 
3772   /** @brief Modifies an existing control point on a curve
3773 
3774       \arg curveIndex            which dimension to set
3775       \arg time                  the time to set the value at
3776       \arg nthCtl                the control point to modify
3777       \arg key                   key of the control point
3778       \arg value                 value of the control point
3779       \arg addAnimationKey       if the param is an animatable, setting this to true will
3780       force an animation keyframe to be set as well as a curve key,
3781       otherwise if false, a key will only be added if the curve is already
3782       animating.
3783 
3784       @returns
3785       - ::kOfxStatOK            - all was fine
3786       - ::kOfxStatErrBadHandle  - if the paramter handle was invalid
3787       - ::kOfxStatErrUnknown    - if the type is unknown
3788 
3789       This modifies an existing control point. Note that by changing key, the order of the
3790       control point may be modified (as you may move it before or after anther point). So be
3791       careful when iterating over a curves control points and you change a key.
3792   */
setNthControlPoints(const int curveIndex,const OfxTime time,const int nthCtl,const double key,const double value,const bool addAnimationKey)3793   void ParametricParam::setNthControlPoints(const int curveIndex,
3794                                              const OfxTime time,
3795                                              const int nthCtl,
3796                                              const double key,
3797                                              const double value,
3798                                              const bool addAnimationKey)
3799   {
3800     if ( OFX::IsNaN(time) ) {
3801       throwSuiteStatusException(kOfxStatErrValue);
3802     }
3803     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamSetNthControlPoint(_paramHandle,
3804                                                                                                  curveIndex,
3805                                                                                                  time,
3806                                                                                                  nthCtl,
3807                                                                                                  key,
3808                                                                                                  value,
3809                                                                                                  addAnimationKey);
3810     throwSuiteStatusException(stat);
3811   }
3812 
setNthControlPoints(const int curveIndex,const OfxTime time,const int nthCtl,const std::pair<double,double> ctrlPoint,const bool addAnimationKey)3813   void ParametricParam::setNthControlPoints(const int curveIndex,
3814                                              const OfxTime time,
3815                                              const int nthCtl,
3816                                              const std::pair<double, double> ctrlPoint,
3817                                              const bool addAnimationKey)
3818   {
3819     if ( OFX::IsNaN(time) ) {
3820       throwSuiteStatusException(kOfxStatErrValue);
3821     }
3822     setNthControlPoints(curveIndex,
3823                          time,
3824                          nthCtl,
3825                          ctrlPoint.first,
3826                          ctrlPoint.second,
3827                          addAnimationKey);
3828   }
3829 
3830   /** @brief Adds a control point to the curve.
3831 
3832       \arg curveIndex            which dimension to set
3833       \arg time                  the time to set the value at
3834       \arg key                   key of the control point
3835       \arg value                 value of the control point
3836       \arg addAnimationKey       if the param is an animatable, setting this to true will
3837       force an animation keyframe to be set as well as a curve key,
3838       otherwise if false, a key will only be added if the curve is already
3839       animating.
3840 
3841       This will add a new control point to the given dimension of a parametric parameter. If a key exists
3842       sufficiently close to 'key', then it will be set to the indicated control point.
3843   */
addControlPoint(const int curveIndex,const OfxTime time,const double key,const double value,const bool addAnimationKey)3844   void ParametricParam::addControlPoint(const int curveIndex,
3845                                          const OfxTime time,
3846                                          const double key,
3847                                          const double value,
3848                                          const bool addAnimationKey)
3849   {
3850     if ( OFX::IsNaN(time) ) {
3851       throwSuiteStatusException(kOfxStatErrValue);
3852     }
3853     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamAddControlPoint(_paramHandle, curveIndex, time, key, value, addAnimationKey);
3854     throwSuiteStatusException(stat);
3855   }
3856 
3857   /** @brief Deletes the nth control point from a parametric param.
3858 
3859       \arg curveIndex            which dimension to delete
3860       \arg nthCtl                the control point to delete
3861   */
deleteControlPoint(const int curveIndex,const int nthCtl)3862   void ParametricParam::deleteControlPoint(const int curveIndex,
3863                                             const int nthCtl)
3864   {
3865     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamDeleteControlPoint(_paramHandle, curveIndex, nthCtl);
3866     throwSuiteStatusException(stat);
3867   }
3868 
3869   /** @brief Delete all curve control points on the given param.
3870 
3871       \arg curveIndex            which dimension to clear
3872   */
deleteControlPoint(const int curveIndex)3873   void ParametricParam::deleteControlPoint(const int curveIndex)
3874   {
3875     OfxStatus stat = OFX::Private::gParametricParameterSuite->parametricParamDeleteAllControlPoints(_paramHandle, curveIndex);
3876     throwSuiteStatusException(stat);
3877   }
3878 
3879   ////////////////////////////////////////////////////////////////////////////////
3880   //  for a set of parameters
3881   /** @brief hidden ctor */
ParamSet(void)3882   ParamSet::ParamSet(void)
3883     : _paramSetHandle(NULL)
3884   {
3885   }
3886 
3887   /** @brief set the param set handle */
3888   void
setParamSetHandle(OfxParamSetHandle h)3889     ParamSet::setParamSetHandle(OfxParamSetHandle h)
3890   {
3891     // set me handle
3892     _paramSetHandle = h;
3893 
3894     if(h) {
3895       // fetch me props
3896       OfxPropertySetHandle props;
3897       OfxStatus stat = OFX::Private::gParamSuite->paramSetGetPropertySet(h, &props);
3898       _paramSetProps.propSetHandle(props);
3899       throwSuiteStatusException(stat);
3900     }
3901     else {
3902       _paramSetProps.propSetHandle(NULL);
3903     }
3904   }
3905 
3906   /** @brief dtor */
~ParamSet()3907   ParamSet::~ParamSet()
3908   {
3909     // delete any descriptor we may have constructed
3910     std::map<std::string, Param *>::iterator iter;
3911     for(iter = _fetchedParams.begin(); iter != _fetchedParams.end(); ++iter) {
3912       if(iter->second) {
3913         delete iter->second;
3914         iter->second = NULL;
3915       }
3916     }
3917   }
3918 
3919   /** @brief calls the raw OFX routine to fetch a param */
fetchRawParam(const std::string & name,ParamTypeEnum paramType,OfxParamHandle & handle) const3920   void ParamSet::fetchRawParam(const std::string &name, ParamTypeEnum paramType, OfxParamHandle &handle) const
3921   {
3922     OfxPropertySetHandle propHandle;
3923 
3924     OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle);
3925     throwSuiteStatusException(stat);
3926 
3927     PropertySet props(propHandle);
3928 
3929     // make sure it is of our type
3930     std::string paramTypeStr = props.propGetString(kOfxParamPropType);
3931     if(paramTypeStr != mapParamTypeEnumToString(paramType)) {
3932       std::string msg = std::string("Parameter \"") + name + std::string("\" exists but has type ") + paramTypeStr + std::string(" instead of ") + mapParamTypeEnumToString(paramType);
3933       throw OFX::Exception::TypeRequest(msg.c_str());
3934     }
3935   }
3936 
getParamType(const std::string & name) const3937   ParamTypeEnum ParamSet::getParamType(const std::string& name) const
3938   {
3939     OfxPropertySetHandle propHandle;
3940     OfxParamHandle handle;
3941     OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle);
3942     throwSuiteStatusException(stat);
3943     PropertySet props(propHandle);
3944     // make sure it is of our type
3945     std::string paramTypeStr = props.propGetString(kOfxParamPropType);
3946     return mapParamTypeStringToEnum(paramTypeStr.c_str());
3947   }
3948 
paramExists(const std::string & name) const3949   bool ParamSet::paramExists(const std::string& name) const
3950   {
3951     OfxParamHandle handle;
3952     OfxPropertySetHandle propHandle;
3953     OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle);
3954     if(stat!=kOfxStatOK)
3955       return false;
3956     return true;
3957   }
3958 
getParam(const std::string & name) const3959   Param* ParamSet::getParam(const std::string& name) const
3960   {
3961     OfxParamHandle handle;
3962     OfxPropertySetHandle propHandle;
3963     OfxStatus stat = OFX::Private::gParamSuite->paramGetHandle(_paramSetHandle, name.c_str(), &handle, &propHandle);
3964     throwSuiteStatusException(stat);
3965 
3966     PropertySet props(propHandle);
3967 
3968     // make sure it is of our type
3969     std::string paramTypeStr = props.propGetString(kOfxParamPropType);
3970     ParamTypeEnum t = mapParamTypeStringToEnum(paramTypeStr.c_str());
3971     switch(t)
3972     {
3973     case eStringParam :
3974       {
3975         StringParam* ptr = 0;
3976         fetchParam(name, t, ptr);
3977         return ptr;
3978       }
3979     case eIntParam :
3980       {
3981         IntParam* ptr = 0;
3982         fetchParam(name, t, ptr);
3983         return ptr;
3984       }
3985     case eInt2DParam :
3986       {
3987         Int2DParam* ptr = 0;
3988         fetchParam(name, t, ptr);
3989         return ptr;
3990       }
3991     case eInt3DParam :
3992       {
3993         Int3DParam* ptr = 0;
3994         fetchParam(name, t, ptr);
3995         return ptr;
3996       }
3997     case eDoubleParam :
3998       {
3999         DoubleParam* ptr = 0;
4000         fetchParam(name, t, ptr);
4001         return ptr;
4002       }
4003     case eDouble2DParam :
4004       {
4005         Double2DParam* ptr = 0;
4006         fetchParam(name, t, ptr);
4007         return ptr;
4008       }
4009     case eDouble3DParam :
4010       {
4011         Double3DParam* ptr = 0;
4012         fetchParam(name, t, ptr);
4013         return ptr;
4014       }
4015     case eRGBParam :
4016       {
4017         RGBParam* ptr = 0;
4018         fetchParam(name, t, ptr);
4019         return ptr;
4020       }
4021     case eRGBAParam :
4022       {
4023         RGBAParam* ptr = 0;
4024         fetchParam(name, t, ptr);
4025         return ptr;
4026       }
4027     case eBooleanParam :
4028       {
4029         BooleanParam* ptr = 0;
4030         fetchParam(name, t, ptr);
4031         return ptr;
4032       }
4033     case eChoiceParam :
4034       {
4035         ChoiceParam* ptr = 0;
4036         fetchParam(name, t, ptr);
4037         return ptr;
4038       }
4039 #ifdef OFX_EXTENSIONS_RESOLVE
4040     case eStrChoiceParam :
4041       {
4042         StrChoiceParam* ptr = 0;
4043         fetchParam(name, t, ptr);
4044         return ptr;
4045       }
4046 #endif
4047     case eCustomParam :
4048       {
4049         CustomParam* ptr = 0;
4050         fetchParam(name, t, ptr);
4051         return ptr;
4052       }
4053     case eGroupParam :
4054       {
4055         GroupParam* ptr = 0;
4056         fetchParam(name, t, ptr);
4057         return ptr;
4058       }
4059     case ePageParam :
4060       {
4061         PageParam* ptr = 0;
4062         fetchParam(name, t, ptr);
4063         return ptr;
4064       }
4065     case ePushButtonParam :
4066       {
4067         PushButtonParam* ptr = 0;
4068         fetchParam(name, t, ptr);
4069         return ptr;
4070       }
4071     case eParametricParam :
4072       {
4073         ParametricParam* ptr = 0;
4074         fetchParam(name, t, ptr);
4075         return ptr;
4076       }
4077     default:
4078       assert(false);
4079     }
4080     return 0;
4081   }
4082 
4083   /** @brief if a param has been fetched in this set, go find it */
4084   Param *
findPreviouslyFetchedParam(const std::string & name) const4085     ParamSet::findPreviouslyFetchedParam(const std::string &name) const
4086   {
4087     // search
4088     std::map<std::string, Param *>::const_iterator search;
4089     search = _fetchedParams.find(name);
4090     if(search == _fetchedParams.end())
4091       return NULL;
4092     return search->second;
4093   }
4094 
4095   /** @brief Fetch an integer param */
4096   IntParam *
fetchIntParam(const std::string & name) const4097     ParamSet::fetchIntParam(const std::string &name) const
4098   {
4099     IntParam *param = NULL;
4100     fetchParam(name, eIntParam, param);
4101     return param;
4102   }
4103 
4104   /** @brief Fetch a 2D integer param */
fetchInt2DParam(const std::string & name) const4105   Int2DParam *ParamSet::fetchInt2DParam(const std::string &name) const
4106   {
4107     Int2DParam *param = NULL;
4108     fetchParam(name, eInt2DParam, param);
4109     return param;
4110   }
4111 
4112   /** @brief Fetch a 3D integer param */
fetchInt3DParam(const std::string & name) const4113   Int3DParam *ParamSet::fetchInt3DParam(const std::string &name) const
4114   {
4115     Int3DParam *param = NULL;
4116     fetchParam(name, eInt3DParam, param);
4117     return param;
4118   }
4119 
4120   /** @brief Fetch an double param */
4121   DoubleParam *
fetchDoubleParam(const std::string & name) const4122     ParamSet::fetchDoubleParam(const std::string &name) const
4123   {
4124     DoubleParam *param = NULL;
4125     fetchParam(name, eDoubleParam, param);
4126     return param;
4127   }
4128 
4129   /** @brief Fetch a 2D double param */
fetchDouble2DParam(const std::string & name) const4130   Double2DParam *ParamSet::fetchDouble2DParam(const std::string &name) const
4131   {
4132     Double2DParam *param = NULL;
4133     fetchParam(name, eDouble2DParam, param);
4134     return param;
4135   }
4136 
4137   /** @brief Fetch a 3D double param */
fetchDouble3DParam(const std::string & name) const4138   Double3DParam *ParamSet::fetchDouble3DParam(const std::string &name) const
4139   {
4140     Double3DParam *param = NULL;
4141     fetchParam(name, eDouble3DParam, param);
4142     return param;
4143   }
4144 
4145   /** @brief Fetch a string param */
fetchStringParam(const std::string & name) const4146   StringParam *ParamSet::fetchStringParam(const std::string &name) const
4147   {
4148     StringParam *param = NULL;
4149     fetchParam(name, eStringParam, param);
4150     return param;
4151   }
4152 
4153   /** @brief Fetch a RGBA param */
fetchRGBAParam(const std::string & name) const4154   RGBAParam *ParamSet::fetchRGBAParam(const std::string &name) const
4155   {
4156     RGBAParam *param = NULL;
4157     fetchParam(name, eRGBAParam, param);
4158     return param;
4159   }
4160 
4161   /** @brief Fetch an RGB  param */
fetchRGBParam(const std::string & name) const4162   RGBParam *ParamSet::fetchRGBParam(const std::string &name) const
4163   {
4164     RGBParam *param = NULL;
4165     fetchParam(name, eRGBParam, param);
4166     return param;
4167   }
4168 
4169   /** @brief Fetch a Boolean  param */
fetchBooleanParam(const std::string & name) const4170   BooleanParam *ParamSet::fetchBooleanParam(const std::string &name) const
4171   {
4172     BooleanParam *param = NULL;
4173     fetchParam(name, eBooleanParam, param);
4174     return param;
4175   }
4176 
4177   /** @brief Fetch a Choice param */
fetchChoiceParam(const std::string & name) const4178   ChoiceParam *ParamSet::fetchChoiceParam(const std::string &name) const
4179   {
4180     ChoiceParam *param = NULL;
4181     fetchParam(name, eChoiceParam, param);
4182     return param;
4183   }
4184 
4185 #ifdef OFX_EXTENSIONS_RESOLVE
4186   /** @brief Fetch a Choice param */
fetchStrChoiceParam(const std::string & p_Name) const4187   StrChoiceParam* ParamSet::fetchStrChoiceParam(const std::string& p_Name) const
4188   {
4189       StrChoiceParam* param = NULL;
4190       fetchParam(p_Name, eStrChoiceParam, param);
4191       return param;
4192   }
4193 #endif
4194 
4195   /** @brief Fetch a group param */
fetchGroupParam(const std::string & name) const4196   GroupParam *ParamSet::fetchGroupParam(const std::string &name) const
4197   {
4198     GroupParam *param = NULL;
4199     fetchParam(name, eGroupParam, param);
4200     return param;
4201   }
4202 
4203   /** @brief Fetch a Page param */
fetchPageParam(const std::string & name) const4204   PageParam *ParamSet::fetchPageParam(const std::string &name) const
4205   {
4206     PageParam *param = NULL;
4207     fetchParam(name, ePageParam, param);
4208     return param;
4209   }
4210 
4211   /** @brief Fetch a push button  param */
fetchPushButtonParam(const std::string & name) const4212   PushButtonParam *ParamSet::fetchPushButtonParam(const std::string &name) const
4213   {
4214     PushButtonParam *param = NULL;
4215     fetchParam(name, ePushButtonParam, param);
4216     return param;
4217   }
4218 
4219   /** @brief Fetch a custom param */
fetchCustomParam(const std::string & name) const4220   CustomParam *ParamSet::fetchCustomParam(const std::string &name) const
4221   {
4222     CustomParam *param = NULL;
4223     fetchParam(name, eCustomParam, param);
4224     return param;
4225   }
4226 
4227   /** @brief Fetch a parametric param */
fetchParametricParam(const std::string & name) const4228   ParametricParam *ParamSet::fetchParametricParam(const std::string &name) const
4229   {
4230     ParametricParam *param = NULL;
4231     fetchParam(name, eParametricParam, param);
4232     return param;
4233   }
4234 
4235   /// open an undoblock
beginEditBlock(const std::string & name)4236   void ParamSet::beginEditBlock(const std::string &name)
4237   {
4238     OfxStatus stat = OFX::Private::gParamSuite->paramEditBegin(_paramSetHandle, name.c_str());
4239     throwSuiteStatusException(stat);
4240   }
4241 
4242   /// close an undoblock
endEditBlock()4243   void ParamSet::endEditBlock()
4244   {
4245     OfxStatus stat = OFX::Private::gParamSuite->paramEditEnd(_paramSetHandle);
4246     throwSuiteStatusException(stat);
4247   }
4248 
4249 };
4250