From 4fcf77abf31a3f9dc93ea72acf22d2ebf7f57786 Mon Sep 17 00:00:00 2001 From: arturo castro Date: Tue, 9 May 2017 11:56:34 +0200 Subject: [PATCH 1/4] ofParameter / ofxSlider: logarithmic scale --- addons/ofxGui/src/ofxSlider.cpp | 4 +- libs/openFrameworks/types/ofParameter.h | 112 ++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/addons/ofxGui/src/ofxSlider.cpp b/addons/ofxGui/src/ofxSlider.cpp index a8ecb244ec4..0e2fceb2118 100644 --- a/addons/ofxGui/src/ofxSlider.cpp +++ b/addons/ofxGui/src/ofxSlider.cpp @@ -213,7 +213,7 @@ void ofxSlider::generateDraw(){ bg.setFilled(true); bg.rectangle(b); - float valAsPct = ofMap( value, value.getMin(), value.getMax(), 0, b.width-2, true ); + float valAsPct = ofClamp(value.getPctScaled(),0,1); bar.setFillColor(thisFillColor); bar.setFilled(true); bar.rectangle(b.x+1, b.y+1, valAsPct, b.height-2); @@ -308,7 +308,7 @@ bool ofxSlider::setValue(float mx, float my, bool bCheck){ } } if( bGuiActive ){ - value = ofMap(mx, b.x, b.x + b.width, value.getMin(), value.getMax(), true); + value.setPctScaled(ofMap(mx, b.x, b.x + b.width, 0, 1, true)); return true; } return false; diff --git a/libs/openFrameworks/types/ofParameter.h b/libs/openFrameworks/types/ofParameter.h index 1eacb282b59..3031275c8d7 100644 --- a/libs/openFrameworks/types/ofParameter.h +++ b/libs/openFrameworks/types/ofParameter.h @@ -424,6 +424,12 @@ namespace priv{ +enum class ofParameterScale{ + Linear, + Logarithmic, +}; + + /// \brief ofParameter holds a value and notifies its listeners when it changes. /// /// ofParameter can be used as the value itself. For example an `ofParameter` @@ -442,6 +448,7 @@ class ofParameter: public ofAbstractParameter{ ofParameter(const ParameterType & v); ofParameter(const string& name, const ParameterType & v); ofParameter(const string& name, const ParameterType & v, const ParameterType & min, const ParameterType & max); + ofParameter(const string& name, const ParameterType & v, const ParameterType & min, const ParameterType & max, ofParameterScale scale); const ParameterType & get() const; const ParameterType * operator->() const; @@ -520,6 +527,15 @@ class ofParameter: public ofAbstractParameter{ void setMin(const ParameterType & min); void setMax(const ParameterType & max); + template + typename std::enable_if::value, void>::type setScale(ofParameterScale scale); + template + typename std::enable_if::value, ofParameterScale>::type getScale() const; + template + typename std::enable_if::value, void>::type setPctScaled(double value); + template + typename std::enable_if::value, double>::type getPctScaled() const; + void setSerializable(bool serializable); shared_ptr newReference() const; @@ -542,6 +558,37 @@ class ofParameter: public ofAbstractParameter{ protected: private: + template + class Scale; + + template + class Scale::value, T>::type>{ + public: + ofParameterScale scale; + Scale():scale(ofParameterScale::Linear){} + Scale(ofParameterScale scale):scale(scale){} + Scale & operator=(ofParameterScale scale){ + this->scale = scale; + return *this; + } + operator ofParameterScale(){ + return scale; + } + }; + + template + class Scale::value, T>::type>{ + public: + Scale(){} + Scale(ofParameterScale){} + Scale & operator=(ofParameterScale){ + return *this; + } + operator ofParameterScale(){ + return ofParameterScale::Linear; + } + }; + class Value{ public: Value() @@ -573,6 +620,15 @@ class ofParameter: public ofAbstractParameter{ ,bInNotify(false) ,serializable(true){} + Value(string name, ParameterType v, ParameterType min, ParameterType max, ofParameterScale scale) + :name(name) + ,value(v) + ,min(min) + ,max(max) + ,bInNotify(false) + ,serializable(true) + ,scale(scale){} + string name; ParameterType value; ParameterType min, max; @@ -580,6 +636,7 @@ class ofParameter: public ofAbstractParameter{ bool bInNotify; bool serializable; vector> parents; + Scale scale; }; shared_ptr obj; @@ -618,6 +675,10 @@ ofParameter::ofParameter(const string& name, const ParameterType :obj(std::make_shared(name, v, min, max)) ,setMethod(std::bind(&ofParameter::eventsSetValue, this, std::placeholders::_1)){} +template +ofParameter::ofParameter(const string& name, const ParameterType & v, const ParameterType & min, const ParameterType & max, ofParameterScale scale) +:obj(std::make_shared(name, v, min, max, scale)) +,setMethod(std::bind(&ofParameter::eventsSetValue, this, std::placeholders::_1)){} template inline ofParameter & ofParameter::operator=(const ofParameter & v){ @@ -796,6 +857,57 @@ void ofParameter::disableEvents(){ setMethod = std::bind(&ofParameter::noEventsSetValue, this, std::placeholders::_1); } + +template +template +typename std::enable_if::value, void>::type ofParameter::setScale(ofParameterScale scale){ + obj->scale = scale; +} + +template +template +typename std::enable_if::value, ofParameterScale>::type ofParameter::getScale() const{ + return obj->scale; +} + +template +template +typename std::enable_if::value, void>::type ofParameter::setPctScaled(double pct){ + switch(static_cast(obj->scale)){ + case ofParameterScale::Linear: + set(ofMap(pct, 0, 1, obj->min, obj->max)); + break; + case ofParameterScale::Logarithmic:{ + auto offset = obj->min > 0 ? 0 : 1 - obj->min; + auto min = obj->min + offset; + auto max = obj->max + offset; + auto minv = log(min); + auto maxv = log(max); + auto scale = (maxv - minv); + set(exp(minv + scale * pct) - offset); + }break; + } +} + +template +template +typename std::enable_if::value, double>::type ofParameter::getPctScaled() const{ + switch(static_cast(obj->scale)){ + case ofParameterScale::Logarithmic:{ + auto offset = obj->min > 0 ? 0 : 1 - obj->min; + auto min = obj->min + offset; + auto max = obj->max + offset; + auto minv = log(min); + auto maxv = log(max); + auto scale = (maxv - minv); + return (log(obj->value + offset) - minv) / scale; + } + case ofParameterScale::Linear: + default: + return ofMap(obj->value, obj->min, obj->max, 0, 1); + } +} + template inline ParameterType ofParameter::operator++(int){ ParameterType r = obj->value; From 3bf55f58286fef33fdf03bd4beeb3583a9da99c1 Mon Sep 17 00:00:00 2001 From: arturo castro Date: Tue, 16 May 2017 13:32:07 +0200 Subject: [PATCH 2/4] ofPArameter: fix setScale --- libs/openFrameworks/types/ofParameter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/openFrameworks/types/ofParameter.h b/libs/openFrameworks/types/ofParameter.h index 3031275c8d7..25d4e4996b0 100644 --- a/libs/openFrameworks/types/ofParameter.h +++ b/libs/openFrameworks/types/ofParameter.h @@ -567,7 +567,7 @@ class ofParameter: public ofAbstractParameter{ ofParameterScale scale; Scale():scale(ofParameterScale::Linear){} Scale(ofParameterScale scale):scale(scale){} - Scale & operator=(ofParameterScale scale){ + Scale & operator=(ofParameterScale scale){ this->scale = scale; return *this; } @@ -581,7 +581,7 @@ class ofParameter: public ofAbstractParameter{ public: Scale(){} Scale(ofParameterScale){} - Scale & operator=(ofParameterScale){ + Scale & operator=(ofParameterScale){ return *this; } operator ofParameterScale(){ From 71d14970a3559115220262310d5095b421c225ad Mon Sep 17 00:00:00 2001 From: arturo castro Date: Thu, 18 May 2017 13:36:17 +0200 Subject: [PATCH 3/4] ofSetMutuallyExclusive: sets several parameters as mutually exclusive --- libs/openFrameworks/types/ofParameter.h | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/libs/openFrameworks/types/ofParameter.h b/libs/openFrameworks/types/ofParameter.h index 25d4e4996b0..cb9b2dc439f 100644 --- a/libs/openFrameworks/types/ofParameter.h +++ b/libs/openFrameworks/types/ofParameter.h @@ -480,6 +480,11 @@ class ofParameter: public ofAbstractParameter{ return obj->changedE.newListener(args...); } + template + void ownListener(Args...args) { + obj->ownListeners.push_back(obj->changedE.newListener(args...)); + } + void enableEvents(); void disableEvents(); bool isSerializable() const; @@ -635,7 +640,8 @@ class ofParameter: public ofAbstractParameter{ ofEvent changedE; bool bInNotify; bool serializable; - vector> parents; + std::vector> parents; + std::vector ownListeners; Scale scale; }; @@ -1509,3 +1515,35 @@ template void ofReadOnlyParameter::setParent(ofParameterGroup & _parent){ parameter.setParent(_parent); } + + +template +inline void ofSetMutuallyExclusive(ofParameter & p1, ofParameter & p2, Args&... parameters){ + p1.ownListener([p2](bool & enabled) mutable{ + if(enabled){ + p2.set(false); + } + }); + p2.ownListener([p1](bool & enabled) mutable{ + if(enabled){ + p1.set(false); + } + }); + + ofSetMutuallyExclusive(p1, parameters...); + ofSetMutuallyExclusive(p2, parameters...); +} + +template<> +inline void ofSetMutuallyExclusive(ofParameter & p1, ofParameter & p2){ + p1.ownListener([p2](bool & enabled) mutable{ + if(enabled){ + p2.set(false); + } + }); + p2.ownListener([p1](bool & enabled) mutable{ + if(enabled){ + p1.set(false); + } + }); +} From e6f854ccef2af7d134f6d16d133c58a86ee56fcd Mon Sep 17 00:00:00 2001 From: arturo castro Date: Tue, 23 May 2017 00:39:09 +0200 Subject: [PATCH 4/4] ofParameterLink: sets the same value to a collection of parmeters when any of them changes --- libs/openFrameworks/types/ofParameter.h | 33 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libs/openFrameworks/types/ofParameter.h b/libs/openFrameworks/types/ofParameter.h index cb9b2dc439f..863d63629d8 100644 --- a/libs/openFrameworks/types/ofParameter.h +++ b/libs/openFrameworks/types/ofParameter.h @@ -1517,23 +1517,15 @@ void ofReadOnlyParameter::setParent(ofParameterGroup & _pa } +/// Sets to false every other parameter when one of them is set to true template inline void ofSetMutuallyExclusive(ofParameter & p1, ofParameter & p2, Args&... parameters){ - p1.ownListener([p2](bool & enabled) mutable{ - if(enabled){ - p2.set(false); - } - }); - p2.ownListener([p1](bool & enabled) mutable{ - if(enabled){ - p1.set(false); - } - }); - + ofSetMutuallyExclusive(p1, p2); ofSetMutuallyExclusive(p1, parameters...); ofSetMutuallyExclusive(p2, parameters...); } +/// Sets to false every other parameter when one of them is set to true template<> inline void ofSetMutuallyExclusive(ofParameter & p1, ofParameter & p2){ p1.ownListener([p2](bool & enabled) mutable{ @@ -1547,3 +1539,22 @@ inline void ofSetMutuallyExclusive(ofParameter & p1, ofParameter & p } }); } + +/// Sets the same value to every other passed parameter when any changes +template +inline void ofParameterLink(ofParameter & p1, ofParameter & p2, Args&... parameters){ + ofParameterLink(p1, p2); + ofParameterLink(p1, parameters...); + ofParameterLink(p2, parameters...); +} + +/// Sets the same value to every other passed parameter when any changes +template +inline void ofParameterLink(ofParameter & p1, ofParameter & p2){ + p1.ownListener([p2](T & v) mutable{ + p2.set(v); + }); + p2.ownListener([p1](T & v) mutable{ + p1.set(v); + }); +}