diff options
-rw-r--r-- | libs/ardour/ardour/parameter_descriptor.h | 11 | ||||
-rw-r--r-- | libs/ardour/parameter_descriptor.cc | 48 |
2 files changed, 59 insertions, 0 deletions
diff --git a/libs/ardour/ardour/parameter_descriptor.h b/libs/ardour/ardour/parameter_descriptor.h index c95b028aaa..87363bb2c3 100644 --- a/libs/ardour/ardour/parameter_descriptor.h +++ b/libs/ardour/ardour/parameter_descriptor.h @@ -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(); diff --git a/libs/ardour/parameter_descriptor.cc b/libs/ardour/parameter_descriptor.cc index 1a79191e56..9e02bc01ab 100644 --- a/libs/ardour/parameter_descriptor.cc +++ b/libs/ardour/parameter_descriptor.cc @@ -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 |