most of KnobGadget rework

master
zetaPRIME 2022-03-18 21:05:56 -04:00
parent 930992025d
commit fd81de5040
6 changed files with 70 additions and 20 deletions

21
notes
View File

@ -31,18 +31,19 @@ parameters {
}
TODO {
immediate frontburner {
revert action
distortion effect
! KnobGadget rework {
- switch to relative position per frame
- shift+drag fine tuning
- alt+drag to move reference point without changing value
- global switch between horizontal and vertical
scrollwheel support!
}
KnobGadget rework {
switch to relative position per frame
shift+drag fine tuning
alt+drag to move reference point without changing value
global switch between horizontal and vertical
}
ping-pong for delay
revert-to-saved menu action
distortion effect
automation node {
listens for one specific param

View File

@ -0,0 +1,5 @@
#include "uiconfig.h"
using namespace Xybrid::Config;
bool UIConfig::verticalKnobs = false;

8
xybrid/config/uiconfig.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
namespace Xybrid::Config {
namespace UIConfig {
/// Determines if KnobGadgets turn with vertical mouse movement instead of horizontal.
extern bool verticalKnobs;
}
}

View File

@ -134,7 +134,7 @@ void SVF::onGadgetCreated() {
return qs("?");
};
(new KnobGadget(l))->bind(frequency)->setLabel(qs("Freq"))->setRange(0.0, 16000.0, 25.0, KnobGadget::NoStep)->setDefault(6400.0);
(new KnobGadget(l))->bind(frequency)->setLabel(qs("Freq"))->setRange(0.0, 16000.0, 25.0, KnobGadget::NoStep, 1.0)->setDefault(6400.0);
(new KnobGadget(l))->bind(resonance)->setLabel(qs("Res"))->setTextFunc(KnobGadget::textPercent)->setRange(0.0, 1.0, 0.01)->setDefault(0.0);
(new KnobGadget(l))->bind(mode)->setLabel(qs("Mode"))->setTextFunc(modetxt)->setRange(0, Notch, 1, KnobGadget::BigStep)->setDefault(0);
}

View File

@ -5,6 +5,9 @@ using namespace Xybrid::UI;
#include "ui/gadgets/layoutgadget.h"
#include "nodelib/basics.h"
#include "config/uiconfig.h"
using namespace Xybrid::Config;
#include <cmath>
#include <QDebug>
@ -114,13 +117,27 @@ void KnobGadget::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidg
painter->drawPie(ir, 250*16 + static_cast<int>(-320.0*16*proportion), 0);
}
namespace { // interaction tracking vars
QPoint lastPos;
int acc = 0;
double trackVal;
inline double stepRound(double v, double s) { return std::round(v / s) * s; }
//
}
void KnobGadget::mousePressEvent(QGraphicsSceneMouseEvent* e) {
if (e->button() == Qt::LeftButton) {
highlighted = true;
startVal = get();
if (step != 0.0) {
startVal = std::round(startVal / step) * step;
}
trackVal = get();
auto mod = e->modifiers();
if (mod.testFlag(Qt::AltModifier)) ; // no rounding until alt released
else if (mod.testFlag(Qt::ShiftModifier) && subStep > 0.0)
trackVal = stepRound(trackVal, subStep);
else if (step > 0.0)
trackVal = stepRound(trackVal, step);
fSet(trackVal);
lastPos = e->screenPos();
} else if (e->button() == Qt::RightButton) {
fSet(defaultVal);
e->accept();
@ -137,9 +154,26 @@ void KnobGadget::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) {
void KnobGadget::mouseMoveEvent(QGraphicsSceneMouseEvent* e) {
if (highlighted) {
auto tdelta = (e->screenPos().x() - e->buttonDownScreenPos(Qt::LeftButton).x());
tdelta /= stepPx;
fSet(std::clamp(startVal + tdelta * step, min, max));
auto curPos = e->screenPos();
if (UIConfig::verticalKnobs) acc -= curPos.y() - lastPos.y();
else acc += curPos.x() - lastPos.x();
lastPos = curPos;
// 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 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);
fSet(std::clamp(trackVal, min, max));
} else {
trackVal = stepRound(trackVal + step*diff, step);
fSet(std::clamp(trackVal, min, max));
}
}
update();
}

View File

@ -13,7 +13,7 @@ namespace Xybrid::UI {
Q_OBJECT
bool highlighted = false;
double startVal;
//double startVal;
double lastVal = 0.0;
bool dirty = true;
@ -36,6 +36,7 @@ namespace Xybrid::UI {
double min = 0.0;
double max = 1.0;
double step = 0.01;
double subStep = -1;
int stepPx = SmallStep;
double defaultVal = 0.0;
@ -56,11 +57,12 @@ namespace Xybrid::UI {
inline KnobGadget* setLabel(const QString& s) { label->setText(s); dirty = true; update(); return this; }
inline KnobGadget* setTextFunc(const std::function<QString(double)>& f) { fText = f; dirty = true; update(); return this; }
inline KnobGadget* setRange(double min, double max, double step = -1, int px = -1) {
inline KnobGadget* setRange(double min, double max, double step = -1, int px = -1, double sub = -1) {
this->min = min;
this->max = max;
if (step > 0) this->step = step;
if (px > 0) stepPx = px;
if (sub > 0) subStep = sub;
update();
return this;
}