diff --git a/include/Quantity.hpp b/include/Quantity.hpp index 30fac8b2..62fc7aa7 100644 --- a/include/Quantity.hpp +++ b/include/Quantity.hpp @@ -42,14 +42,10 @@ struct Quantity { /** Returns the value, possibly transformed for displaying. Useful for logarithmic scaling, multiplying by 100 for percentages, etc. */ - virtual float getDisplayValue() { - return getValue(); - } + virtual float getDisplayValue(); /** Inversely transforms the display value and sets the value. */ - virtual void setDisplayValue(float displayValue) { - setValue(displayValue); - } + virtual void setDisplayValue(float displayValue); /** The number of total decimal places for generating the display value string. */ virtual int getDisplayPrecision(); @@ -57,6 +53,7 @@ struct Quantity { /** Returns a string representation of the display value. */ virtual std::string getDisplayValueString(); + /** Sets the value from a display string. */ virtual void setDisplayValueString(std::string s); /** The name of the quantity. */ @@ -77,65 +74,29 @@ struct Quantity { // Helper methods /** Resets the value to the default value. */ - void reset() { - setValue(getDefaultValue()); - } - + void reset(); /** Sets the value to a uniform random value between the bounds. */ - void randomize() { - if (isBounded()) - setScaledValue(random::uniform()); - } - + void randomize(); /** Checks whether the value is at the min value. */ - bool isMin() { - return getValue() <= getMinValue(); - } - + bool isMin(); /** Checks whether the value is at the max value. */ - bool isMax() { - return getValue() >= getMaxValue(); - } - + bool isMax(); /** Sets the value to the min value. */ - void setMin() { - setValue(getMinValue()); - } - + void setMin(); /** Sets the value to the max value. */ - void setMax() { - setValue(getMaxValue()); - } - + void setMax(); /** Sets value from the range 0 to 1. */ - void setScaledValue(float scaledValue) { - setValue(math::rescale(scaledValue, 0.f, 1.f, getMinValue(), getMaxValue())); - } - + void setScaledValue(float scaledValue); /** Returns the value rescaled to the range 0 to 1. */ - float getScaledValue() { - return math::rescale(getValue(), getMinValue(), getMaxValue(), 0.f, 1.f); - } - + float getScaledValue(); /** The difference between the max and min values. */ - float getRange() { - return getMaxValue() - getMinValue(); - } - + float getRange(); /** Checks whether the bounds are finite. */ - bool isBounded() { - return std::isfinite(getMinValue()) && std::isfinite(getMaxValue()); - } - + bool isBounded(); /** Adds an amount to the value. */ - void moveValue(float deltaValue) { - setValue(getValue() + deltaValue); - } - + void moveValue(float deltaValue); /** Adds an amount to the value scaled to the range 0 to 1. */ - void moveScaledValue(float deltaScaledValue) { - moveValue(deltaScaledValue * getRange()); - } + void moveScaledValue(float deltaScaledValue); }; diff --git a/src/Quantity.cpp b/src/Quantity.cpp index 3cab297f..ae9e010c 100644 --- a/src/Quantity.cpp +++ b/src/Quantity.cpp @@ -6,6 +6,14 @@ namespace rack { +float Quantity::getDisplayValue() { + return getValue(); +} + +void Quantity::setDisplayValue(float displayValue) { + setValue(displayValue); +} + int Quantity::getDisplayPrecision() { return 5; } @@ -31,5 +39,65 @@ std::string Quantity::getString() { return s; } +void Quantity::reset() { + setValue(getDefaultValue()); +} + +void Quantity::randomize() { + if (isBounded()) + setScaledValue(random::uniform()); +} + +bool Quantity::isMin() { + return getValue() <= getMinValue(); +} + +bool Quantity::isMax() { + return getValue() >= getMaxValue(); +} + +void Quantity::setMin() { + setValue(getMinValue()); +} + +void Quantity::setMax() { + setValue(getMaxValue()); +} + +void Quantity::setScaledValue(float scaledValue) { + if (!isBounded()) + setValue(scaledValue); + else + setValue(math::rescale(scaledValue, 0.f, 1.f, getMinValue(), getMaxValue())); +} + +float Quantity::getScaledValue() { + if (!isBounded()) + return getValue(); + else if (getMinValue() == getMaxValue()) + return 0.f; + else + return math::rescale(getValue(), getMinValue(), getMaxValue(), 0.f, 1.f); +} + +float Quantity::getRange() { + return getMaxValue() - getMinValue(); +} + +bool Quantity::isBounded() { + return std::isfinite(getMinValue()) && std::isfinite(getMaxValue()); +} + +void Quantity::moveValue(float deltaValue) { + setValue(getValue() + deltaValue); +} + +void Quantity::moveScaledValue(float deltaScaledValue) { + if (!isBounded()) + moveValue(deltaScaledValue); + else + moveValue(deltaScaledValue * getRange()); +} + } // namespace rack diff --git a/src/app/SvgKnob.cpp b/src/app/SvgKnob.cpp index b1194d20..24bfe6cc 100644 --- a/src/app/SvgKnob.cpp +++ b/src/app/SvgKnob.cpp @@ -37,13 +37,17 @@ void SvgKnob::onChange(const event::Change& e) { if (pq) { float value = pq->getSmoothValue(); float angle; - if (pq->isBounded()) { - angle = math::rescale(value, pq->getMinValue(), pq->getMaxValue(), minAngle, maxAngle); - } - else { + if (!pq->isBounded()) { // Center unbounded knobs angle = math::rescale(value, -1.f, 1.f, minAngle, maxAngle); } + else if (pq->getMinValue() == pq->getMaxValue()) { + // Center 0 range + angle = math::rescale(0.f, -1.f, 1.f, minAngle, maxAngle); + } + else { + angle = math::rescale(value, pq->getMinValue(), pq->getMaxValue(), minAngle, maxAngle); + } angle = std::fmod(angle, 2 * M_PI); tw->identity(); // Rotate SVG