| |
| |
| #include "tparamset.h" |
| #include "tundo.h" |
| |
| #include "tdoubleparam.h" |
| #include "tstream.h" |
| |
| #include <set> |
| |
| |
| |
| namespace { |
| void doRelease(const std::pair<TParam *, std::string> ¶m) { |
| param.first->release(); |
| } |
| }; |
| |
| |
| |
| class TParamSetImp final : public TParamObserver { |
| friend class TParamSet; |
| TParamSet *m_param; |
| std::vector<std::pair<TParam *, std::string>> m_params; |
| |
| |
| bool m_draggingEnabled, m_notificationEnabled; |
| |
| public: |
| TParamSetImp(TParamSet *param) |
| : m_param(param) |
| |
| , m_draggingEnabled(false) |
| , m_notificationEnabled(true) {} |
| |
| ~TParamSetImp() { |
| std::for_each(m_params.begin(), m_params.end(), doRelease); |
| } |
| |
| std::set<TParamObserver *> m_paramObservers; |
| |
| template <typename T> |
| void notify(const T &change); |
| |
| void onChange(const TParamChange &change) override {} |
| }; |
| |
| |
| |
| TParamSet::TParamSet(std::string name) |
| : TParam(name), m_imp(new TParamSetImp(this)) {} |
| |
| |
| |
| TParamSet::TParamSet(const TParamSet &src) |
| : TParam(src.getName()), m_imp(new TParamSetImp(this)) {} |
| |
| |
| |
| TParamSet::~TParamSet() { delete m_imp; } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void TParamSet::beginParameterChange() { |
| |
| |
| |
| |
| |
| |
| |
| |
| std::vector<TParam *> params; |
| |
| |
| |
| |
| |
| |
| |
| std::vector<std::pair<TParam *, std::string>>::iterator it2 = |
| m_imp->m_params.begin(); |
| for (; it2 != m_imp->m_params.end(); ++it2) params.push_back(it2->first); |
| |
| |
| }; |
| |
| |
| void TParamSet::endParameterChange(){ |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| }; |
| |
| |
| |
| void TParamSet::addParam(const TParamP ¶m, const std::string &name) { |
| std::pair<TParam *, std::string> paramToInsert = |
| std::make_pair(param.getPointer(), name); |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| std::find(m_imp->m_params.begin(), m_imp->m_params.end(), paramToInsert); |
| |
| if (it == m_imp->m_params.end()) { |
| param->addRef(); |
| param->addObserver(m_imp); |
| m_imp->m_params.push_back(paramToInsert); |
| |
| if (param->getName().empty()) param->setName(name); |
| |
| } |
| } |
| |
| |
| |
| void TParamSet::insertParam(const TParamP ¶m, const std::string &name, |
| int index) { |
| std::pair<TParam *, std::string> paramToInsert = |
| std::make_pair(param.getPointer(), name); |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| std::find(m_imp->m_params.begin(), m_imp->m_params.end(), paramToInsert); |
| |
| if (it == m_imp->m_params.end()) { |
| param->addRef(); |
| param->addObserver(m_imp); |
| it = m_imp->m_params.begin(); |
| int f; |
| for (f = 0; f < index; f++) it++; |
| m_imp->m_params.insert(it, paramToInsert); |
| if (param->getName().empty()) param->setName(name); |
| } |
| } |
| |
| |
| |
| namespace { |
| class matchesParam { |
| TParamP m_param; |
| |
| public: |
| matchesParam(const TParamP ¶m) : m_param(param) {} |
| bool operator()(const std::pair<TParam *, std::string> ¶m) { |
| return m_param.getPointer() == param.first; |
| } |
| }; |
| } |
| |
| |
| |
| void TParamSet::removeParam(const TParamP ¶m) { |
| std::vector<std::pair<TParam *, std::string>>::iterator it = std::find_if( |
| m_imp->m_params.begin(), m_imp->m_params.end(), matchesParam(param)); |
| if (it != m_imp->m_params.end()) { |
| param->removeObserver(m_imp); |
| |
| |
| |
| |
| |
| param->release(); |
| m_imp->m_params.erase(it); |
| } |
| } |
| |
| |
| |
| void TParamSet::removeAllParam() { |
| while (!m_imp->m_params.empty()) { |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| m_imp->m_params.begin(); |
| TParam *param = it->first; |
| param->removeObserver(m_imp); |
| param->release(); |
| m_imp->m_params.erase(it); |
| } |
| } |
| |
| |
| |
| int TParamSet::getParamCount() const { return m_imp->m_params.size(); } |
| |
| |
| |
| TParamP TParamSet::getParam(int i) const { |
| assert(i >= 0 && i < (int)m_imp->m_params.size()); |
| return m_imp->m_params[i].first; |
| } |
| |
| |
| |
| std::string TParamSet::getParamName(int i) const { |
| assert(i >= 0 && i < (int)m_imp->m_params.size()); |
| return m_imp->m_params[i].second; |
| } |
| |
| |
| |
| int TParamSet::getParamIdx(const std::string &name) const { |
| int i, paramsCount = m_imp->m_params.size(); |
| for (i = 0; i < paramsCount; ++i) |
| if (m_imp->m_params[i].second == name) break; |
| |
| return i; |
| } |
| |
| |
| |
| void TParamSet::getAnimatableParams(std::vector<TParamP> ¶ms, |
| bool recursive) { |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| m_imp->m_params.begin(); |
| for (; it != m_imp->m_params.end(); ++it) { |
| TParam *param = it->first; |
| |
| TDoubleParamP dparam = TParamP(param); |
| if (dparam) |
| params.push_back(dparam); |
| else { |
| TParamSetP paramset = TParamP(param); |
| if (paramset && recursive) |
| paramset->getAnimatableParams(params, recursive); |
| } |
| } |
| } |
| |
| |
| |
| void TParamSet::addObserver(TParamObserver *observer) { |
| |
| |
| |
| |
| m_imp->m_paramObservers.insert(observer); |
| } |
| |
| |
| |
| template <typename T> |
| void TParamSetImp::notify(const T &change) { |
| if (m_notificationEnabled) { |
| |
| |
| |
| |
| for (std::set<TParamObserver *>::iterator paramIt = |
| m_paramObservers.begin(); |
| paramIt != m_paramObservers.end(); ++paramIt) |
| (*paramIt)->onChange(change); |
| } |
| } |
| |
| |
| |
| void TParamSet::removeObserver(TParamObserver *observer) { |
| |
| |
| |
| |
| m_imp->m_paramObservers.erase(observer); |
| } |
| |
| |
| |
| void TParamSet::enableDragging(bool on) { |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| m_imp->m_params.begin(); |
| for (; it != m_imp->m_params.end(); ++it) { |
| TDoubleParamP dparam(it->first); |
| |
| |
| } |
| |
| m_imp->m_draggingEnabled = on; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void TParamSet::enableNotification(bool on) { |
| |
| |
| |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| m_imp->m_params.begin(); |
| for (; it != m_imp->m_params.end(); ++it) { |
| it->first->enableNotification(on); |
| } |
| |
| m_imp->m_notificationEnabled = on; |
| } |
| |
| |
| |
| bool TParamSet::isNotificationEnabled() const { |
| return m_imp->m_notificationEnabled; |
| } |
| |
| |
| |
| bool TParamSet::isKeyframe(double frame) const { |
| for (int i = 0; i < getParamCount(); i++) |
| if (getParam(i)->isKeyframe(frame)) return true; |
| return false; |
| } |
| |
| |
| |
| void TParamSet::getKeyframes(std::set<double> &frames) const { |
| for (int i = 0; i < getParamCount(); i++) getParam(i)->getKeyframes(frames); |
| } |
| |
| |
| |
| double TParamSet::keyframeIndexToFrame(int index) const { |
| std::set<double> frames; |
| getKeyframes(frames); |
| assert(0 <= index && index < (int)frames.size()); |
| std::set<double>::const_iterator it = frames.begin(); |
| std::advance(it, index); |
| return *it; |
| } |
| |
| |
| |
| int TParamSet::getNextKeyframe(double frame) const { |
| std::set<double> frames; |
| getKeyframes(frames); |
| std::set<double>::iterator it = frames.upper_bound(frame); |
| if (it == frames.end()) |
| return -1; |
| else |
| return std::distance(frames.begin(), it); |
| } |
| |
| |
| |
| int TParamSet::getPrevKeyframe(double frame) const { |
| std::set<double> frames; |
| getKeyframes(frames); |
| std::set<double>::iterator it = frames.lower_bound(frame); |
| if (it == frames.begin()) |
| return -1; |
| else { |
| --it; |
| return std::distance(frames.begin(), it); |
| } |
| } |
| |
| |
| |
| bool TParamSet::hasKeyframes() const { |
| for (int i = 0; i < getParamCount(); i++) |
| if (getParam(i)->hasKeyframes()) return true; |
| return false; |
| } |
| |
| |
| |
| int TParamSet::getKeyframeCount() const { |
| std::set<double> frames; |
| getKeyframes(frames); |
| return frames.size(); |
| } |
| |
| |
| |
| void TParamSet::deleteKeyframe(double frame) { |
| for (int i = 0; i < getParamCount(); i++) getParam(i)->deleteKeyframe(frame); |
| } |
| |
| |
| |
| void TParamSet::clearKeyframes() { |
| for (int i = 0; i < getParamCount(); i++) getParam(i)->clearKeyframes(); |
| } |
| |
| |
| |
| void TParamSet::assignKeyframe(double frame, const TParamP &src, |
| double srcFrame, bool changedOnly) { |
| TParamSetP paramSetSrc = src; |
| if (!paramSetSrc) return; |
| if (getParamCount() != paramSetSrc->getParamCount()) return; |
| for (int i = 0; i < getParamCount(); i++) |
| getParam(i)->assignKeyframe(frame, paramSetSrc->getParam(i), srcFrame, |
| changedOnly); |
| } |
| |
| |
| |
| TParam *TParamSet::clone() const { return new TParamSet(*this); } |
| |
| |
| |
| void TParamSet::copy(TParam *src) { |
| TParamSet *p = dynamic_cast<TParamSet *>(src); |
| if (!p) throw TException("invalid source for copy"); |
| int srcParamCount = p->getParamCount(); |
| removeAllParam(); |
| int i; |
| for (i = 0; i < srcParamCount; i++) { |
| TParamP param = p->getParam(i); |
| addParam(param->clone(), param->getName()); |
| } |
| } |
| |
| |
| |
| void TParamSet::loadData(TIStream &is) { |
| std::string tagName; |
| is.openChild(tagName); |
| while (!is.eos()) { |
| std::string paramName; |
| is.openChild(paramName); |
| TPersist *p = 0; |
| is >> p; |
| TParam *param = dynamic_cast<TParam *>(p); |
| assert(param); |
| addParam(param, paramName); |
| is.closeChild(); |
| } |
| is.closeChild(); |
| } |
| |
| |
| |
| void TParamSet::saveData(TOStream &os) { |
| os.openChild(getName()); |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| m_imp->m_params.begin(); |
| std::vector<std::pair<TParam *, std::string>>::iterator end = |
| m_imp->m_params.end(); |
| while (it != end) { |
| os.openChild(it->second); |
| |
| os << it->first; |
| os.closeChild(); |
| ++it; |
| } |
| os.closeChild(); |
| } |
| |
| |
| |
| std::string TParamSet::getValueAlias(double frame, int precision) { |
| std::string alias = "("; |
| |
| std::vector<std::pair<TParam *, std::string>>::iterator end = |
| m_imp->m_params.begin(); |
| std::advance(end, m_imp->m_params.size() - 1); |
| |
| std::vector<std::pair<TParam *, std::string>>::iterator it = |
| m_imp->m_params.begin(); |
| for (; it != end; ++it) |
| alias += it->first->getValueAlias(frame, precision) + ","; |
| |
| alias += it->first->getValueAlias(frame, precision); |
| |
| alias += ")"; |
| return alias; |
| } |
| |
| |
| |
| TPersistDeclarationT<TParamSet> TParamSet::m_declaration("TParamSet"); |
| |