Add API to step though parameter enumerations
This commit is contained in:
parent
0310f89971
commit
7ed775a716
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user