wheel accumulator (smooth wheel support)

master
zetaPRIME 2022-03-18 21:41:59 -04:00
parent 7b566929a2
commit b4b9918c7d
3 changed files with 22 additions and 9 deletions

2
notes
View File

@ -36,7 +36,7 @@ TODO {
- shift+drag fine tuning
- alt+drag to move reference point without changing value
- global switch between horizontal and vertical
> scrollwheel support!
- scrollwheel support!
}
ping-pong for delay

View File

@ -119,9 +119,22 @@ void KnobGadget::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidg
namespace { // interaction tracking vars
int acc = 0;
int wAcc = 0;
double trackVal;
inline double stepRound(double v, double s) { return std::round(v / s) * s; }
int accumulate(int& acc, int step) {
int sgn = acc < 0 ? -1 : 1;
int rm = std::abs(acc) % step;
int diff = (std::abs(acc)-rm)*sgn / step;
acc = rm*sgn;
return diff;
}
}
void KnobGadget::hoverEnterEvent(QGraphicsSceneHoverEvent*) {
wAcc = 0; //reset wheel accumulator on hovering over a new knob
}
void KnobGadget::mousePressEvent(QGraphicsSceneMouseEvent* e) {
@ -156,19 +169,15 @@ void KnobGadget::mouseMoveEvent(QGraphicsSceneMouseEvent* e) {
if (UIConfig::verticalKnobs) acc -= curPos.y() - lastPos.y();
else acc += curPos.x() - lastPos.x();
// handle accumulation math
int sgn = acc < 0 ? -1 : 1;
int rm = std::abs(acc) % stepPx;
int diff = (std::abs(acc)-rm)*sgn / stepPx;
acc = rm*sgn;
auto d = accumulate(acc, stepPx);
auto mod = e->modifiers();
if (mod.testFlag(Qt::AltModifier)) trackVal = std::clamp(trackVal, min, max); // soft release; just keep track within range
else if (mod.testFlag(Qt::ShiftModifier) && subStep > 0) {
trackVal = stepRound(trackVal + subStep*diff, subStep);
trackVal = stepRound(trackVal + subStep*d, subStep);
fSet(std::clamp(trackVal, min, max));
} else if (step > 0) {
trackVal = stepRound(trackVal + step*diff, step);
trackVal = stepRound(trackVal + step*d, step);
fSet(std::clamp(trackVal, min, max));
}
}
@ -177,7 +186,10 @@ void KnobGadget::mouseMoveEvent(QGraphicsSceneMouseEvent* e) {
void KnobGadget::wheelEvent(QGraphicsSceneWheelEvent* e) {
if (highlighted) return;
auto d = e->delta()/120;
wAcc += e->delta();
auto d = accumulate(wAcc, 120);
auto mod = e->modifiers();
if (mod.testFlag(Qt::ShiftModifier) && subStep > 0) {
fSet(std::clamp(stepRound(get()+subStep*d, subStep), min, max));

View File

@ -49,6 +49,7 @@ namespace Xybrid::UI {
QPainterPath shape() const override;
void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) override;
void hoverEnterEvent(QGraphicsSceneHoverEvent*) override;
void mousePressEvent(QGraphicsSceneMouseEvent*) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;