Add API to step though parameter enumerations

This commit is contained in:
Robin Gareus 2017-07-02 21:04:22 +02:00
parent 0310f89971
commit 7ed775a716
2 changed files with 59 additions and 0 deletions

View File

@ -77,6 +77,17 @@ struct LIBARDOUR_API ParameterDescriptor : public Evoral::ParameterDescriptor
float compute_delta (float from, float to) const;
float apply_delta (float value, float delta) const;
/* find the closest scale-point, return the internal value of
* the prev/next scale-point (no wrap-around)
*
* If the given parameter is not en enum, the given val is returned.
*
* @param val internal (not interface) value
* @param prev if true, step to prev scale-point, otherwise next
* @return internal value, suitable for set_value()
*/
float step_enum (float val, bool prev) const;
/** Set step, smallstep, and largestep, based on current description. */
void update_steps();

View File

@ -17,6 +17,7 @@
675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include "pbd/control_math.h"
@ -162,6 +163,16 @@ ParameterDescriptor::update_steps()
if (rangesteps < 2) {
rangesteps = 0;
}
if (enumeration) {
if (!scale_points || scale_points->empty ()) {
enumeration = false;
}
}
if (integer_step) {
if (lower >= upper) {
integer_step = false;
}
}
if (unit == ParameterDescriptor::MIDI_NOTE) {
step = smallstep = 1; // semitone
@ -425,4 +436,41 @@ ParameterDescriptor::apply_delta (float val, float delta) const
}
}
float
ParameterDescriptor::step_enum (float val, bool prev) const
{
if (!enumeration) {
return val;
}
assert (scale_points && !scale_points->empty ());
float rv = scale_points->begin()->second;
float delta = fabsf (val - rv);
std::vector<float> avail;
for (ScalePoints::const_iterator i = scale_points->begin (); i != scale_points->end (); ++i) {
float s = i->second;
avail.push_back (s);
if (fabsf (val - s) < delta) {
rv = s;
delta = fabsf (val - s);
}
}
/* ScalePoints map is sorted by text string */
std::sort (avail.begin (), avail.end ());
std::vector<float>::const_iterator it = std::find (avail.begin (), avail.end (), rv);
assert (it != avail.end());
if (prev) {
if (it == avail.begin()) {
return rv;
}
return *(--it);
} else {
if (++it == avail.end()) {
return rv;
}
return *(it);
}
}
} // namespace ARDOUR