@@ -18,10 +18,6 @@ struct ParamWidget : widget::OpaqueWidget { | |||
engine::Module* module = NULL; | |||
int paramId = -1; | |||
ui::Tooltip* tooltip = NULL; | |||
/** For triggering the Change event. `*/ | |||
float lastValue = NAN; | |||
ParamWidget(); | |||
~ParamWidget(); | |||
/** Configures ParamQuantity properties based on the type of ParamWidget. | |||
@@ -20,8 +20,6 @@ struct PortWidget : widget::OpaqueWidget { | |||
engine::Port::Type type = engine::Port::INPUT; | |||
int portId = -1; | |||
ui::Tooltip* tooltip = NULL; | |||
MultiLightWidget* plugLight; | |||
PortWidget(); | |||
@@ -22,9 +22,9 @@ struct SvgSlider : app::SliderKnob { | |||
SvgSlider(); | |||
void setBackgroundSvg(std::shared_ptr<Svg> svg); | |||
void setHandleSvg(std::shared_ptr<Svg> svg); | |||
void onChange(const ChangeEvent& e) override; | |||
void setHandlePos(math::Vec minHandlePos, math::Vec maxHandlePos); | |||
void setHandlePosCentered(math::Vec minHandlePosCentered, math::Vec maxHandlePosCentered); | |||
void onChange(const ChangeEvent& e) override; | |||
DEPRECATED void setBackgroundSVG(std::shared_ptr<Svg> svg) { | |||
setBackgroundSvg(svg); | |||
@@ -152,28 +152,44 @@ engine::ParamQuantity* ParamWidget::getParamQuantity() { | |||
return module->paramQuantities[paramId]; | |||
} | |||
ParamWidget::ParamWidget() {} | |||
ParamWidget::~ParamWidget() {} | |||
struct ParamWidget::Internal { | |||
ui::Tooltip* tooltip = NULL; | |||
/** For triggering the Change event. `*/ | |||
float lastValue = NAN; | |||
}; | |||
ParamWidget::ParamWidget() { | |||
internal = new Internal; | |||
} | |||
ParamWidget::~ParamWidget() { | |||
delete internal; | |||
} | |||
void ParamWidget::createTooltip() { | |||
if (!settings::tooltips) | |||
return; | |||
if (this->tooltip) | |||
if (internal->tooltip) | |||
return; | |||
if (!module) | |||
return; | |||
ParamTooltip* tooltip = new ParamTooltip; | |||
tooltip->paramWidget = this; | |||
APP->scene->addChild(tooltip); | |||
this->tooltip = tooltip; | |||
internal->tooltip = tooltip; | |||
} | |||
void ParamWidget::destroyTooltip() { | |||
if (!tooltip) | |||
if (!internal->tooltip) | |||
return; | |||
APP->scene->removeChild(tooltip); | |||
delete tooltip; | |||
tooltip = NULL; | |||
APP->scene->removeChild(internal->tooltip); | |||
delete internal->tooltip; | |||
internal->tooltip = NULL; | |||
} | |||
void ParamWidget::step() { | |||
@@ -181,16 +197,17 @@ void ParamWidget::step() { | |||
if (pq) { | |||
float value = pq->getSmoothValue(); | |||
// Dispatch change event when the ParamQuantity value changes | |||
if (value != lastValue) { | |||
if (value != internal->lastValue) { | |||
ChangeEvent eChange; | |||
onChange(eChange); | |||
lastValue = value; | |||
internal->lastValue = value; | |||
} | |||
} | |||
Widget::step(); | |||
} | |||
void ParamWidget::draw(const DrawArgs& args) { | |||
Widget::draw(args); | |||
@@ -210,6 +227,7 @@ void ParamWidget::draw(const DrawArgs& args) { | |||
} | |||
} | |||
void ParamWidget::onButton(const ButtonEvent& e) { | |||
OpaqueWidget::onButton(e); | |||
@@ -229,18 +247,22 @@ void ParamWidget::onButton(const ButtonEvent& e) { | |||
} | |||
} | |||
void ParamWidget::onDoubleClick(const DoubleClickEvent& e) { | |||
resetAction(); | |||
} | |||
void ParamWidget::onEnter(const EnterEvent& e) { | |||
createTooltip(); | |||
} | |||
void ParamWidget::onLeave(const LeaveEvent& e) { | |||
destroyTooltip(); | |||
} | |||
void ParamWidget::createContextMenu() { | |||
ui::Menu* menu = createMenu(); | |||
@@ -300,6 +322,7 @@ void ParamWidget::createContextMenu() { | |||
appendContextMenu(menu); | |||
} | |||
void ParamWidget::resetAction() { | |||
engine::ParamQuantity* pq = getParamQuantity(); | |||
if (pq && pq->resetEnabled && pq->isBounded()) { | |||
@@ -74,7 +74,13 @@ struct PlugLight : MultiLightWidget { | |||
}; | |||
struct PortWidget::Internal { | |||
ui::Tooltip* tooltip = NULL; | |||
}; | |||
PortWidget::PortWidget() { | |||
internal = new Internal; | |||
plugLight = new PlugLight; | |||
} | |||
@@ -86,6 +92,7 @@ PortWidget::~PortWidget() { | |||
// HACK | |||
if (module) | |||
APP->scene->rack->clearCablesOnPort(this); | |||
delete internal; | |||
} | |||
engine::Port* PortWidget::getPort() { | |||
@@ -109,22 +116,22 @@ engine::PortInfo* PortWidget::getPortInfo() { | |||
void PortWidget::createTooltip() { | |||
if (!settings::tooltips) | |||
return; | |||
if (this->tooltip) | |||
if (internal->tooltip) | |||
return; | |||
if (!module) | |||
return; | |||
PortTooltip* tooltip = new PortTooltip; | |||
tooltip->portWidget = this; | |||
APP->scene->addChild(tooltip); | |||
this->tooltip = tooltip; | |||
internal->tooltip = tooltip; | |||
} | |||
void PortWidget::destroyTooltip() { | |||
if (!tooltip) | |||
if (!internal->tooltip) | |||
return; | |||
APP->scene->removeChild(tooltip); | |||
delete tooltip; | |||
tooltip = NULL; | |||
APP->scene->removeChild(internal->tooltip); | |||
delete internal->tooltip; | |||
internal->tooltip = NULL; | |||
} | |||
void PortWidget::step() { | |||
@@ -34,27 +34,37 @@ void SvgSlider::setHandleSvg(std::shared_ptr<Svg> svg) { | |||
} | |||
void SvgSlider::onChange(const ChangeEvent& e) { | |||
engine::ParamQuantity* pq = getParamQuantity(); | |||
if (pq) { | |||
// Interpolate handle position | |||
float v = math::rescale(pq->getSmoothValue(), pq->getMinValue(), pq->getMaxValue(), 0.f, 1.f); | |||
handle->box.pos = minHandlePos.crossfade(maxHandlePos, v); | |||
fb->setDirty(); | |||
} | |||
ParamWidget::onChange(e); | |||
} | |||
void SvgSlider::setHandlePos(math::Vec minHandlePos, math::Vec maxHandlePos) { | |||
this->minHandlePos = minHandlePos; | |||
this->maxHandlePos = maxHandlePos; | |||
// Dispatch ChangeEvent since the handle position changed | |||
ChangeEvent eChange; | |||
onChange(eChange); | |||
} | |||
void SvgSlider::setHandlePosCentered(math::Vec minHandlePosCentered, math::Vec maxHandlePosCentered) { | |||
this->minHandlePos = minHandlePosCentered.minus(handle->box.size.div(2)); | |||
this->maxHandlePos = maxHandlePosCentered.minus(handle->box.size.div(2)); | |||
setHandlePos( | |||
minHandlePosCentered.minus(handle->box.size.div(2)), | |||
maxHandlePosCentered.minus(handle->box.size.div(2)) | |||
); | |||
} | |||
void SvgSlider::onChange(const ChangeEvent& e) { | |||
// Default position is max value | |||
float v = 1.f; | |||
engine::ParamQuantity* pq = getParamQuantity(); | |||
if (pq) { | |||
v = math::rescale(pq->getSmoothValue(), pq->getMinValue(), pq->getMaxValue(), 0.f, 1.f); | |||
} | |||
// Interpolate handle position | |||
handle->box.pos = minHandlePos.crossfade(maxHandlePos, v); | |||
fb->setDirty(); | |||
ParamWidget::onChange(e); | |||
} | |||