Chris@132
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@132
|
2
|
Chris@132
|
3 /*
|
Chris@132
|
4 Sonic Visualiser
|
Chris@132
|
5 An audio file viewer and annotation editor.
|
Chris@132
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@132
|
7 This file copyright 2006 Chris Cannam.
|
Chris@132
|
8
|
Chris@132
|
9 This program is free software; you can redistribute it and/or
|
Chris@132
|
10 modify it under the terms of the GNU General Public License as
|
Chris@132
|
11 published by the Free Software Foundation; either version 2 of the
|
Chris@132
|
12 License, or (at your option) any later version. See the file
|
Chris@132
|
13 COPYING included with this distribution for more information.
|
Chris@132
|
14 */
|
Chris@132
|
15
|
Chris@132
|
16 #include "Thumbwheel.h"
|
Chris@132
|
17
|
Chris@132
|
18 #include <QMouseEvent>
|
Chris@132
|
19 #include <QPaintEvent>
|
Chris@132
|
20 #include <QWheelEvent>
|
Chris@132
|
21 #include <QPainter>
|
Chris@132
|
22
|
Chris@132
|
23 #include <cmath>
|
Chris@132
|
24 #include <iostream>
|
Chris@132
|
25
|
Chris@132
|
26 Thumbwheel::Thumbwheel(int min, int max, int defaultValue,
|
Chris@132
|
27 Qt::Orientation orientation,
|
Chris@132
|
28 QWidget *parent) :
|
Chris@132
|
29 QWidget(parent),
|
Chris@132
|
30 m_min(min),
|
Chris@132
|
31 m_max(max),
|
Chris@132
|
32 m_default(defaultValue),
|
Chris@132
|
33 m_value((min + max) / 2),
|
Chris@132
|
34 m_orientation(orientation),
|
Chris@132
|
35 m_tracking(true),
|
Chris@132
|
36 m_showScale(true),
|
Chris@132
|
37 m_clicked(false),
|
Chris@132
|
38 m_clickValue(m_value)
|
Chris@132
|
39 {
|
Chris@132
|
40 if (max <= min) max = min + 1;
|
Chris@132
|
41 m_speed = float(max - min) / 300.f;
|
Chris@132
|
42 }
|
Chris@132
|
43
|
Chris@132
|
44 Thumbwheel::~Thumbwheel()
|
Chris@132
|
45 {
|
Chris@132
|
46 }
|
Chris@132
|
47
|
Chris@132
|
48 void
|
Chris@132
|
49 Thumbwheel::setValue(int value)
|
Chris@132
|
50 {
|
Chris@132
|
51 if (value < m_min) value = m_min;
|
Chris@132
|
52 if (value > m_max) value = m_max;
|
Chris@132
|
53 m_value = value;
|
Chris@132
|
54 update();
|
Chris@132
|
55 }
|
Chris@132
|
56
|
Chris@132
|
57 int
|
Chris@132
|
58 Thumbwheel::getValue() const
|
Chris@132
|
59 {
|
Chris@132
|
60 return m_value;
|
Chris@132
|
61 }
|
Chris@132
|
62
|
Chris@132
|
63 void
|
Chris@132
|
64 Thumbwheel::setSpeed(float speed)
|
Chris@132
|
65 {
|
Chris@132
|
66 m_speed = speed;
|
Chris@132
|
67 }
|
Chris@132
|
68
|
Chris@132
|
69 float
|
Chris@132
|
70 Thumbwheel::getSpeed() const
|
Chris@132
|
71 {
|
Chris@132
|
72 return m_speed;
|
Chris@132
|
73 }
|
Chris@132
|
74
|
Chris@132
|
75 void
|
Chris@132
|
76 Thumbwheel::setTracking(bool tracking)
|
Chris@132
|
77 {
|
Chris@132
|
78 m_tracking = tracking;
|
Chris@132
|
79 }
|
Chris@132
|
80
|
Chris@132
|
81 bool
|
Chris@132
|
82 Thumbwheel::getTracking() const
|
Chris@132
|
83 {
|
Chris@132
|
84 return m_tracking;
|
Chris@132
|
85 }
|
Chris@132
|
86
|
Chris@132
|
87 void
|
Chris@132
|
88 Thumbwheel::setShowScale(bool showScale)
|
Chris@132
|
89 {
|
Chris@132
|
90 m_showScale = showScale;
|
Chris@132
|
91 }
|
Chris@132
|
92
|
Chris@132
|
93 bool
|
Chris@132
|
94 Thumbwheel::getShowScale() const
|
Chris@132
|
95 {
|
Chris@132
|
96 return m_showScale;
|
Chris@132
|
97 }
|
Chris@132
|
98
|
Chris@132
|
99 void
|
Chris@132
|
100 Thumbwheel::mousePressEvent(QMouseEvent *e)
|
Chris@132
|
101 {
|
Chris@132
|
102 m_clicked = true;
|
Chris@132
|
103 m_clickPos = e->pos();
|
Chris@132
|
104 m_clickValue = m_value;
|
Chris@132
|
105 }
|
Chris@132
|
106
|
Chris@132
|
107 void
|
Chris@132
|
108 Thumbwheel::mouseDoubleClickEvent(QMouseEvent *)
|
Chris@132
|
109 {
|
Chris@132
|
110 setValue(m_default);
|
Chris@132
|
111 emit valueChanged(getValue());
|
Chris@132
|
112 }
|
Chris@132
|
113
|
Chris@132
|
114 void
|
Chris@132
|
115 Thumbwheel::mouseMoveEvent(QMouseEvent *e)
|
Chris@132
|
116 {
|
Chris@132
|
117 int dist = 0;
|
Chris@132
|
118 if (m_orientation == Qt::Horizontal) {
|
Chris@132
|
119 dist = e->x() - m_clickPos.x();
|
Chris@132
|
120 } else {
|
Chris@132
|
121 dist = e->y() - m_clickPos.y();
|
Chris@132
|
122 }
|
Chris@132
|
123 int value = m_clickValue + lrintf(m_speed * dist);
|
Chris@132
|
124 if (value < m_min) value = m_min;
|
Chris@132
|
125 if (value > m_max) value = m_max;
|
Chris@132
|
126 if (value != m_value) {
|
Chris@132
|
127 setValue(value);
|
Chris@132
|
128 if (m_tracking) emit valueChanged(getValue());
|
Chris@132
|
129 }
|
Chris@132
|
130 }
|
Chris@132
|
131
|
Chris@132
|
132 void
|
Chris@132
|
133 Thumbwheel::mouseReleaseEvent(QMouseEvent *e)
|
Chris@132
|
134 {
|
Chris@132
|
135 bool reallyTracking = m_tracking;
|
Chris@132
|
136 m_tracking = true;
|
Chris@132
|
137 mouseMoveEvent(e);
|
Chris@132
|
138 m_tracking = reallyTracking;
|
Chris@132
|
139 }
|
Chris@132
|
140
|
Chris@132
|
141 void
|
Chris@132
|
142 Thumbwheel::wheelEvent(QWheelEvent *e)
|
Chris@132
|
143 {
|
Chris@132
|
144 int step = lrintf(m_speed);
|
Chris@132
|
145 if (step == 0) step = 1;
|
Chris@132
|
146
|
Chris@132
|
147 if (e->delta() > 0) {
|
Chris@132
|
148 setValue(m_value + step);
|
Chris@132
|
149 } else {
|
Chris@132
|
150 setValue(m_value - step);
|
Chris@132
|
151 }
|
Chris@132
|
152
|
Chris@132
|
153 emit valueChanged(getValue());
|
Chris@132
|
154 }
|
Chris@132
|
155
|
Chris@132
|
156 void
|
Chris@132
|
157 Thumbwheel::paintEvent(QPaintEvent *)
|
Chris@132
|
158 {
|
Chris@132
|
159 float distance = float(m_value - m_min) / float(m_max - m_min);
|
Chris@132
|
160 float rotation = distance * 1.5f * M_PI;
|
Chris@132
|
161
|
Chris@132
|
162 // std::cerr << "value = " << m_value << ", min = " << m_min << ", max = " << m_max << ", rotation = " << rotation << std::endl;
|
Chris@132
|
163
|
Chris@132
|
164 int w = (m_orientation == Qt::Horizontal ? width() : height());
|
Chris@132
|
165
|
Chris@132
|
166 // total number of notches on the entire wheel
|
Chris@132
|
167 int notches = 25;
|
Chris@132
|
168
|
Chris@132
|
169 // radius of the wheel including invisible part
|
Chris@132
|
170 int radius = w / 2 + 2;
|
Chris@132
|
171
|
Chris@132
|
172 QPainter paint(this);
|
Chris@132
|
173 paint.fillRect(rect(), palette().background().color());
|
Chris@132
|
174 paint.setRenderHint(QPainter::Antialiasing, true);
|
Chris@132
|
175
|
Chris@132
|
176 for (int i = 0; i < notches; ++i) {
|
Chris@132
|
177
|
Chris@132
|
178 float a0 = (2.f * M_PI * i) / notches + rotation;
|
Chris@132
|
179 float a1 = a0 + M_PI / (notches * 2);
|
Chris@132
|
180 float a2 = (2.f * M_PI * (i + 1)) / notches + rotation;
|
Chris@132
|
181
|
Chris@132
|
182 float depth = cosf((a0 + a2) / 2);
|
Chris@132
|
183 if (depth < 0) continue;
|
Chris@132
|
184
|
Chris@132
|
185 float x0 = radius * sinf(a0) + w/2;
|
Chris@132
|
186 float x1 = radius * sinf(a1) + w/2;
|
Chris@132
|
187 float x2 = radius * sinf(a2) + w/2;
|
Chris@132
|
188 if (x2 < 0 || x0 > w) continue;
|
Chris@132
|
189
|
Chris@132
|
190 if (x0 < 0) x0 = 0;
|
Chris@132
|
191 if (x2 > w) x2 = w;
|
Chris@132
|
192
|
Chris@132
|
193 int grey = lrintf(255 * depth);
|
Chris@132
|
194 QColor fc = QColor(grey, grey, grey);
|
Chris@132
|
195 QColor oc = palette().dark().color();
|
Chris@132
|
196
|
Chris@132
|
197 paint.setPen(oc);
|
Chris@132
|
198 paint.setBrush(fc);
|
Chris@132
|
199
|
Chris@132
|
200 if (m_orientation == Qt::Horizontal) {
|
Chris@132
|
201 paint.drawRect(QRectF(x1, 0, x2 - x1, height()));
|
Chris@132
|
202 } else {
|
Chris@132
|
203 paint.drawRect(QRectF(0, x1, width(), x2 - x1));
|
Chris@132
|
204 }
|
Chris@132
|
205
|
Chris@132
|
206 if (m_showScale) {
|
Chris@132
|
207
|
Chris@132
|
208 paint.setBrush(oc);
|
Chris@132
|
209
|
Chris@132
|
210 float prop;
|
Chris@132
|
211 if (i >= notches / 4) {
|
Chris@132
|
212 prop = float(notches - (((i - float(notches) / 4.f) * 4.f) / 3.f))
|
Chris@132
|
213 / notches;
|
Chris@132
|
214 } else {
|
Chris@132
|
215 prop = 0.f;
|
Chris@132
|
216 }
|
Chris@132
|
217
|
Chris@132
|
218 if (m_orientation == Qt::Horizontal) {
|
Chris@132
|
219 paint.drawRect(QRectF(x1, height() - height() * prop,
|
Chris@132
|
220 x2 - x1, height() * prop));
|
Chris@132
|
221 } else {
|
Chris@132
|
222 paint.drawRect(QRectF(0, x1, width() * prop, x2 - x1));
|
Chris@132
|
223 }
|
Chris@132
|
224 }
|
Chris@132
|
225
|
Chris@132
|
226 paint.setPen(oc);
|
Chris@132
|
227 paint.setBrush(palette().background().color());
|
Chris@132
|
228
|
Chris@132
|
229 if (m_orientation == Qt::Horizontal) {
|
Chris@132
|
230 paint.drawRect(QRectF(x0, 0, x1 - x0, height()));
|
Chris@132
|
231 } else {
|
Chris@132
|
232 paint.drawRect(QRectF(0, x0, width(), x1 - x0));
|
Chris@132
|
233 }
|
Chris@132
|
234 }
|
Chris@132
|
235 }
|
Chris@132
|
236
|
Chris@132
|
237 QSize
|
Chris@132
|
238 Thumbwheel::sizeHint() const
|
Chris@132
|
239 {
|
Chris@132
|
240 if (m_orientation == Qt::Horizontal) {
|
Chris@132
|
241 return QSize(80, 12);
|
Chris@132
|
242 } else {
|
Chris@132
|
243 return QSize(12, 80);
|
Chris@132
|
244 }
|
Chris@132
|
245 }
|
Chris@132
|
246
|