1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#pragma once
#include <QMouseEvent>
#include <QWheelEvent>
#include <QColor>
#include <QCursor>
#include <QApplication>
#include <QPoint>
#include <QPixmap>
#include "util/math.h"
template <class T>
class KnobEventHandler {
public:
KnobEventHandler()
: m_bRightButtonPressed(false) {
QPixmap blankPixmap(32, 32);
blankPixmap.fill(QColor(0, 0, 0, 0));
m_blankCursor = QCursor(blankPixmap);
}
double valueFromMouseEvent(T* pWidget, QMouseEvent* e) {
QPoint cur(e->globalPos());
QPoint diff(cur - m_startPos);
double dist = sqrt(static_cast<double>(diff.x() * diff.x() + diff.y() * diff.y()));
bool y_dominant = abs(diff.y()) > abs(diff.x());
// if y is dominant, then thread an increase in dy as negative (y is
// pointed downward). Otherwise, if y is not dominant and x has
// decreased, then thread it as negative.
if ((y_dominant && diff.y() > 0) || (!y_dominant && diff.x() < 0)) {
dist = -dist;
}
// For legacy (MIDI) reasons this is tuned to 127.
double value = pWidget->getControlParameter() + dist / 127.0;
// Clamp to [0.0, 1.0]
value = math_clamp(value, 0.0, 1.0);
return value;
}
void mouseMoveEvent(T* pWidget, QMouseEvent* e) {
if (!m_bRightButtonPressed) {
QCursor::setPos(m_startPos);
double value = valueFromMouseEvent(pWidget, e);
pWidget->setControlParameterDown(value);
pWidget->inputActivity();
}
}
void mousePressEvent(T* pWidget, QMouseEvent* e) {
switch (e->button()) {
case Qt::RightButton:
pWidget->resetControlParameter();
m_bRightButtonPressed = true;
break;
case Qt::LeftButton:
case Qt::MiddleButton:
m_startPos = e->globalPos();
// Somehow using Qt::BlankCursor does not work on Windows
// https://mixxx.org/forums/viewtopic.php?p=40298#p40298
QApplication::setOverrideCursor(m_blankCursor);
break;
default:
break;
}
}
void mouseReleaseEvent(T* pWidget, QMouseEvent* e) {
double value = 0.0;
switch (e->button()) {
case Qt::LeftButton:
case Qt::MiddleButton:
QCursor::setPos(m_startPos);
QApplication::restoreOverrideCursor();
value = valueFromMouseEvent(pWidget, e);
pWidget->setControlParameterUp(value);
pWidget->inputActivity();
break;
case Qt::RightButton:
m_bRightButtonPressed = false;
break;
default:
break;
}
}
void wheelEvent(T* pWidget, QWheelEvent* e) {
// For legacy (MIDI) reasons this is tuned to 127.
double wheelDirection = e->angleDelta().y() / (120.0 * 127.0);
double newValue = pWidget->getControlParameter() + wheelDirection;
// Clamp to [0.0, 1.0]
newValue = math_clamp(newValue, 0.0, 1.0);
pWidget->setControlParameter(newValue);
pWidget->inputActivity();
e->accept();
}
private:
// True if right mouse button is pressed.
bool m_bRightButtonPressed;
// Starting point when left mouse button is pressed
QPoint m_startPos;
QCursor m_blankCursor;
};
|