#ifndef TDOUBLEPARAM_H
#define TDOUBLEPARAM_H
#include <memory>
// TnzCore includes
#include "tgeometry.h"
#include "tfilepath.h"
// TnzBase includes
#include "tparam.h"
#include "tparamchange.h"
// STD includes
#include <set>
#undef DVAPI
#undef DVVAR
#ifdef TPARAM_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
//=========================================================
// Forward declarations
class TDoubleParam;
class TDoubleKeyframe;
class TMeasure;
class TExpression;
class TDoubleKeyframe;
namespace TSyntax
{
class Grammar;
class CalculatorNodeVisitor;
}
#ifdef _WIN32
template class DVAPI TPersistDeclarationT<TDoubleParam>;
#endif
//=========================================================
//**************************************************************************
// TDoubleParam declaration
//**************************************************************************
class DVAPI TDoubleParam : public TParam
{
PERSIST_DECLARATION(TDoubleParam)
class Imp;
std::unique_ptr<Imp> m_imp;
public:
TDoubleParam(double v = 0.0);
TDoubleParam(const TDoubleParam &src);
~TDoubleParam();
TDoubleParam &operator=(const TDoubleParam &);
TParam *clone() const { return new TDoubleParam(*this); }
void copy(TParam *src);
std::string getMeasureName() const;
void setMeasureName(std::string name);
TMeasure *getMeasure() const;
void setValueRange(double min, double max, double step = 1.0);
bool getValueRange(double &min, double &max, double &step) const;
double getDefaultValue() const;
void setDefaultValue(double value);
double getValue(double frame, bool leftmost = false) const;
// note: if frame is a keyframe separating two segments of different types
// (e.g. expression and linear) then getValue(frame,true) can be != getValue(frame,false)
bool setValue(double frame, double value);
// returns the incoming speed vector for keyframe kIndex. kIndex-1 must be speedinout
// if kIndex is not speedinout and handle are linked then recomputes speed.y taking
// in account the next segment
TPointD getSpeedIn(int kIndex) const;
// returns the outcoming speed vector for keyframe kIndex. kIndex must be speedinout
TPointD getSpeedOut(int kIndex) const;
//TPointD getSpeed(double frame);
// a specific grammar defines expressions as 'peg2.ns' and allows to
// create a link to the appropriate data source (e.g.
// the correct stageobject tree)
const TSyntax::Grammar *getGrammar() const;
void setGrammar(const TSyntax::Grammar *grammar); // doesn't get ownership.
void accept(TSyntax::CalculatorNodeVisitor &visitor);
//! cycle controls extrapolation after the last keyframe
void enableCycle(bool enabled);
bool isCycleEnabled() const;
int getKeyframeCount() const;
void getKeyframes(std::set<double> &frames) const;
double keyframeIndexToFrame(int index) const;
const TDoubleKeyframe &getKeyframe(int index) const;
const TDoubleKeyframe &getKeyframeAt(double frame) const;
//! assign k to the kIndex-th keyframe; postcondition: m_frame order is maintained
void setKeyframe(int kIndex, const TDoubleKeyframe &k);
//! call setKeyframe(it.first,it.second) for each it in ks; postcondition: m_frame order is maintained
void setKeyframes(const std::map<int, TDoubleKeyframe> &ks);
//! create a keyframe in k.m_frame (if is needed) and assign k to it
void setKeyframe(const TDoubleKeyframe &k);
bool isKeyframe(double frame) const;
bool hasKeyframes() const;
void deleteKeyframe(double frame);
void clearKeyframes();
int getClosestKeyframe(double frame) const;
int getNextKeyframe(double frame) const;
int getPrevKeyframe(double frame) const;
void assignKeyframe(
double frame,
const TParamP &src, double srcFrame,
bool changedOnly);
bool isAnimatable() const { return true; }
void addObserver(TParamObserver *observer);
void removeObserver(TParamObserver *observer);
const std::set<TParamObserver *> &observers() const;
//! no keyframes, default value not changed
bool isDefault() const;
void loadData(TIStream &is);
void saveData(TOStream &os);
std::string getStreamTag() const;
std::string getValueAlias(double frame, int precision);
};
//---------------------------------------------------------
DEFINE_PARAM_SMARTPOINTER(TDoubleParam, double)
#endif // TDOUBLEPARAM_H