| @@ -14,7 +14,10 @@ namespace engine { | |||
| struct Module; | |||
| /** A Quantity that wraps an engine::Param. */ | |||
| /** A Quantity that wraps an engine::Param. | |||
| If `smoothEnabled` is true, all methods access/modify the target value of the Engine's smoothing algorithm for a Param instead of the value directly. | |||
| */ | |||
| struct ParamQuantity : Quantity { | |||
| Module* module = NULL; | |||
| int paramId = -1; | |||
| @@ -64,11 +67,26 @@ struct ParamQuantity : Quantity { | |||
| bool snapEnabled = false; | |||
| Param* getParam(); | |||
| /** If smoothEnabled is true, requests to the engine to smoothly move to a target value each sample. */ | |||
| void setSmoothValue(float value); | |||
| float getSmoothValue(); | |||
| /** Deprecated. Use setValue() instead. */ | |||
| DEPRECATED void setSmoothValue(float value); | |||
| /** Deprecated. Use getValue() instead. */ | |||
| DEPRECATED float getSmoothValue(); | |||
| void setDirectValue(float value); | |||
| float getDirectValue(); | |||
| /** Sets the Param's smoothing target value, or direct value if smoothing is disabled. | |||
| Before Rack 2.3.0, this always set the Param's value directly. | |||
| For this behavior, use `setDirectValue()` instead. | |||
| */ | |||
| void setValue(float value) override; | |||
| /** Gets the Param's smoothing target value, or direct value if smoothing is disabled. | |||
| Before Rack 2.3.0, this always got the Param's value directly. | |||
| For this behavior, use `getDirectValue()` instead. | |||
| */ | |||
| float getValue() override; | |||
| float getMinValue() override; | |||
| float getMaxValue() override; | |||
| @@ -72,7 +72,7 @@ void Knob::onDragStart(const DragStartEvent& e) { | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (pq) { | |||
| internal->oldValue = pq->getSmoothValue(); | |||
| internal->oldValue = pq->getValue(); | |||
| internal->snapDelta = 0.f; | |||
| } | |||
| @@ -103,7 +103,7 @@ void Knob::onDragEnd(const DragEndEvent& e) { | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (pq) { | |||
| float newValue = pq->getSmoothValue(); | |||
| float newValue = pq->getValue(); | |||
| if (!std::isnan(internal->oldValue) && internal->oldValue != newValue) { | |||
| // Push ParamChange history action | |||
| history::ParamChange* h = new history::ParamChange; | |||
| @@ -150,7 +150,7 @@ void Knob::onDragMove(const DragMoveEvent& e) { | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (pq) { | |||
| float value = pq->getSmoothValue(); | |||
| float value = pq->getValue(); | |||
| // Ratio between parameter value scale / (angle range / 2*pi) | |||
| float rangeRatio; | |||
| @@ -224,7 +224,7 @@ void Knob::onDragMove(const DragMoveEvent& e) { | |||
| } | |||
| // Set value | |||
| pq->setSmoothValue(value); | |||
| pq->setValue(value); | |||
| } | |||
| internal->distDragged += e.mouseDelta.norm(); | |||
| @@ -254,7 +254,7 @@ void Knob::onHoverScroll(const HoverScrollEvent& e) { | |||
| if (!pq) | |||
| return; | |||
| float value = pq->getSmoothValue(); | |||
| float value = pq->getValue(); | |||
| // Set old value if unset | |||
| if (std::isnan(internal->oldValue)) { | |||
| internal->oldValue = value; | |||
| @@ -284,7 +284,7 @@ void Knob::onHoverScroll(const HoverScrollEvent& e) { | |||
| } | |||
| value += delta; | |||
| pq->setSmoothValue(value); | |||
| pq->setValue(value); | |||
| e.consume(this); | |||
| } | |||
| @@ -298,7 +298,7 @@ void Knob::onLeave(const LeaveEvent& e) { | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (pq) { | |||
| float newValue = pq->getSmoothValue(); | |||
| float newValue = pq->getValue(); | |||
| if (!std::isnan(internal->oldValue) && internal->oldValue != newValue) { | |||
| // Push ParamChange history action | |||
| history::ParamChange* h = new history::ParamChange; | |||
| @@ -172,7 +172,7 @@ void ParamWidget::destroyTooltip() { | |||
| void ParamWidget::step() { | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (pq) { | |||
| float value = pq->getSmoothValue(); | |||
| float value = pq->getValue(); | |||
| // Dispatch change event when the ParamQuantity value changes | |||
| if (value != internal->lastValue) { | |||
| ChangeEvent eChange; | |||
| @@ -35,7 +35,7 @@ void SvgKnob::onChange(const ChangeEvent& e) { | |||
| // Re-transform the widget::TransformWidget | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (pq) { | |||
| float value = pq->getSmoothValue(); | |||
| float value = pq->getValue(); | |||
| float angle; | |||
| if (!pq->isBounded()) { | |||
| // Number of rotations equals value for unbounded range | |||
| @@ -57,7 +57,7 @@ void SvgSlider::onChange(const ChangeEvent& e) { | |||
| float v = 1.f; | |||
| engine::ParamQuantity* pq = getParamQuantity(); | |||
| if (pq) { | |||
| v = math::rescale(pq->getSmoothValue(), pq->getMinValue(), pq->getMaxValue(), 0.f, 1.f); | |||
| v = pq->getScaledValue(); | |||
| } | |||
| // Interpolate handle position | |||
| @@ -1060,19 +1060,19 @@ void Engine::setParamValue(Module* module, int paramId, float value) { | |||
| internal->smoothModule = NULL; | |||
| internal->smoothParamId = 0; | |||
| } | |||
| module->params[paramId].value = value; | |||
| module->params[paramId].setValue(value); | |||
| } | |||
| float Engine::getParamValue(Module* module, int paramId) { | |||
| return module->params[paramId].value; | |||
| return module->params[paramId].getValue(); | |||
| } | |||
| void Engine::setParamSmoothValue(Module* module, int paramId, float value) { | |||
| // If another param is being smoothed, jump value | |||
| if (internal->smoothModule && !(internal->smoothModule == module && internal->smoothParamId == paramId)) { | |||
| internal->smoothModule->params[internal->smoothParamId].value = internal->smoothValue; | |||
| internal->smoothModule->params[internal->smoothParamId].setValue(internal->smoothValue); | |||
| } | |||
| internal->smoothParamId = paramId; | |||
| internal->smoothValue = value; | |||
| @@ -1084,7 +1084,7 @@ void Engine::setParamSmoothValue(Module* module, int paramId, float value) { | |||
| float Engine::getParamSmoothValue(Module* module, int paramId) { | |||
| if (internal->smoothModule == module && internal->smoothParamId == paramId) | |||
| return internal->smoothValue; | |||
| return module->params[paramId].value; | |||
| return module->params[paramId].getValue(); | |||
| } | |||
| @@ -250,7 +250,7 @@ void Module::paramsFromJson(json_t* rootJ) { | |||
| json_t* valueJ = json_object_get(paramJ, "value"); | |||
| if (valueJ) | |||
| pq->setValue(json_number_value(valueJ)); | |||
| pq->setDirectValue(json_number_value(valueJ)); | |||
| } | |||
| } | |||
| @@ -19,24 +19,26 @@ engine::Param* ParamQuantity::getParam() { | |||
| } | |||
| void ParamQuantity::setSmoothValue(float value) { | |||
| setValue(value); | |||
| } | |||
| float ParamQuantity::getSmoothValue() { | |||
| return getValue(); | |||
| } | |||
| void ParamQuantity::setDirectValue(float value) { | |||
| if (!module) | |||
| return; | |||
| value = math::clampSafe(value, getMinValue(), getMaxValue()); | |||
| if (snapEnabled) | |||
| value = std::round(value); | |||
| if (smoothEnabled) | |||
| APP->engine->setParamSmoothValue(module, paramId, value); | |||
| else | |||
| APP->engine->setParamValue(module, paramId, value); | |||
| APP->engine->setParamValue(module, paramId, value); | |||
| } | |||
| float ParamQuantity::getSmoothValue() { | |||
| float ParamQuantity::getDirectValue() { | |||
| if (!module) | |||
| return 0.f; | |||
| if (smoothEnabled) | |||
| return APP->engine->getParamSmoothValue(module, paramId); | |||
| else | |||
| return APP->engine->getParamValue(module, paramId); | |||
| return APP->engine->getParamValue(module, paramId); | |||
| } | |||
| void ParamQuantity::setValue(float value) { | |||
| @@ -45,13 +47,19 @@ void ParamQuantity::setValue(float value) { | |||
| value = math::clampSafe(value, getMinValue(), getMaxValue()); | |||
| if (snapEnabled) | |||
| value = std::round(value); | |||
| APP->engine->setParamValue(module, paramId, value); | |||
| if (smoothEnabled) | |||
| APP->engine->setParamSmoothValue(module, paramId, value); | |||
| else | |||
| APP->engine->setParamValue(module, paramId, value); | |||
| } | |||
| float ParamQuantity::getValue() { | |||
| if (!module) | |||
| return 0.f; | |||
| return APP->engine->getParamValue(module, paramId); | |||
| if (smoothEnabled) | |||
| return APP->engine->getParamSmoothValue(module, paramId); | |||
| else | |||
| return APP->engine->getParamValue(module, paramId); | |||
| } | |||
| float ParamQuantity::getMinValue() { | |||
| @@ -67,8 +75,7 @@ float ParamQuantity::getDefaultValue() { | |||
| } | |||
| float ParamQuantity::getDisplayValue() { | |||
| // We don't want the text to be smoothed (animated), so get the smooth target value. | |||
| float v = getSmoothValue(); | |||
| float v = getValue(); | |||
| if (displayBase == 0.f) { | |||
| // Linear | |||
| // v is unchanged | |||