From 8a680bc4f663cafeb431185bdeb115c9cb3232f8 Mon Sep 17 00:00:00 2001 From: tpoole Date: Tue, 4 Apr 2017 16:51:10 +0100 Subject: [PATCH] Added a lambda function parameterisation of NormalisableRange --- .../juce_core/maths/juce_NormalisableRange.h | 75 +++++++++++++++++-- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/modules/juce_core/maths/juce_NormalisableRange.h b/modules/juce_core/maths/juce_NormalisableRange.h index bbf845f2bc..ff31828604 100644 --- a/modules/juce_core/maths/juce_NormalisableRange.h +++ b/modules/juce_core/maths/juce_NormalisableRange.h @@ -103,11 +103,46 @@ public: checkInvariants(); } + #if JUCE_COMPILER_SUPPORTS_LAMBDAS + /** Creates a NormalisableRange with a given range and an injective mapping function. + + @param rangeStart The minimum value in the range. + @param rangeEnd The maximum value in the range. + @param convertFrom0To1Func A function which uses the current start and end of this NormalisableRange + and produces a mapped value from a normalised value. + @param convertTo0To1Func A function which uses the current start and end of this NormalisableRange + and produces a normalised value from a mapped value. + @param snapToLegalValueFunc A function which uses the current start and end of this NormalisableRange + to take a mapped value and snap it to the nearest legal value. + */ + NormalisableRange (ValueType rangeStart, + ValueType rangeEnd, + std::function convertFrom0To1Func, + std::function convertTo0To1Func, + std::function snapToLegalValueFunc = nullptr) noexcept + : start (rangeStart), + end (rangeEnd), + interval(), + skew (static_cast (1)), + symmetricSkew (false), + convertFrom0To1Function (convertFrom0To1Func), + convertTo0To1Function (convertTo0To1Func), + snapToLegalValueFunction (snapToLegalValueFunc) + { + checkInvariants(); + } + #endif + /** Uses the properties of this mapping to convert a non-normalised value to its 0->1 representation. */ ValueType convertTo0to1 (ValueType v) const noexcept { + #if JUCE_COMPILER_SUPPORTS_LAMBDAS + if (convertTo0To1Function != nullptr) + return convertTo0To1Function (start, end, v); + #endif + ValueType proportion = (v - start) / (end - start); if (skew == static_cast (1)) @@ -129,6 +164,11 @@ public: */ ValueType convertFrom0to1 (ValueType proportion) const noexcept { + #if JUCE_COMPILER_SUPPORTS_LAMBDAS + if (convertFrom0To1Function != nullptr) + return convertFrom0To1Function (start, end, proportion); + #endif + if (! symmetricSkew) { if (skew != static_cast (1) && proportion > ValueType()) @@ -147,10 +187,16 @@ public: return start + (end - start) / static_cast (2) * (static_cast (1) + distanceFromMiddle); } - /** Takes a non-normalised value and snaps it based on the interval property of - this NormalisedRange. */ + /** Takes a non-normalised value and snaps it based on either the interval property of + this NormalisedRange or the lambda function supplied to the constructor. + */ ValueType snapToLegalValue (ValueType v) const noexcept { + #if JUCE_COMPILER_SUPPORTS_LAMBDAS + if (snapToLegalValueFunction != nullptr) + return snapToLegalValueFunction (start, end, v); + #endif + if (interval > ValueType()) v = start + interval * std::floor ((v - start) / interval + static_cast (0.5)); @@ -163,10 +209,15 @@ public: return v; } + /** Returns the extent of the normalisable range. */ Range getRange() const noexcept { return Range (start, end); } /** Given a value which is between the start and end points, this sets the skew such that convertFrom0to1 (0.5) will return this value. + + If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the + constructor of this class then the skew value is ignored. + @param centrePointValue this must be greater than the start of the range and less than the end. */ void setSkewForCentre (ValueType centrePointValue) noexcept @@ -180,13 +231,18 @@ public: checkInvariants(); } - /** The start of the non-normalised range. */ + /** The minimum value of the non-normalised range. */ ValueType start; - /** The end of the non-normalised range. */ + /** The maximum value of the non-normalised range. */ ValueType end; - /** The snapping interval that should be used (in non-normalised value). Use 0 for a continuous range. */ + /** The snapping interval that should be used (for a non-normalised value). Use 0 for a + continuous range. + + If you have used a lambda function for snapToLegalValueFunction in the constructor of + this class then the interval is ignored. + */ ValueType interval; /** An optional skew factor that alters the way values are distribute across the range. @@ -197,6 +253,9 @@ public: A factor of 1.0 has no skewing effect at all. If the factor is < 1.0, the lower end of the range will fill more of the slider's length; if the factor is > 1.0, the upper end of the range will be expanded. + + If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the + constructor of this class then the skew value is ignored. */ ValueType skew; @@ -210,4 +269,10 @@ private: jassert (interval >= ValueType()); jassert (skew > ValueType()); } + + #if JUCE_COMPILER_SUPPORTS_LAMBDAS + std::function convertFrom0To1Function = nullptr, + convertTo0To1Function = nullptr, + snapToLegalValueFunction = nullptr; + #endif };