comparison widgets/LevelPanWidget.cpp @ 1302:f3d3fab250ac

Proper handling for wheel rotation distance
author Chris Cannam
date Fri, 22 Jun 2018 13:41:54 +0100
parents e8368466fa34
children 13f5f84fbfad
comparison
equal deleted inserted replaced
1301:e8368466fa34 1302:f3d3fab250ac
72 m_monitorLeft(-1), 72 m_monitorLeft(-1),
73 m_monitorRight(-1), 73 m_monitorRight(-1),
74 m_editable(true), 74 m_editable(true),
75 m_editing(false), 75 m_editing(false),
76 m_includeMute(true), 76 m_includeMute(true),
77 m_includeHalfSteps(true) 77 m_includeHalfSteps(true),
78 m_pendingWheelAngle(0)
78 { 79 {
79 setToolTip(tr("Drag vertically to adjust level, horizontally to adjust pan")); 80 setToolTip(tr("Drag vertically to adjust level, horizontally to adjust pan"));
80 setLevel(1.0); 81 setLevel(1.0);
81 setPan(0.0); 82 setPan(0.0);
82 } 83 }
107 if (notch > m_maxNotch) notch = m_maxNotch; 108 if (notch > m_maxNotch) notch = m_maxNotch;
108 if (!m_includeHalfSteps) { 109 if (!m_includeHalfSteps) {
109 notch = (notch / 2) * 2; 110 notch = (notch / 2) * 2;
110 } 111 }
111 return notch; 112 return notch;
113 }
114
115 int
116 LevelPanWidget::clampPan(int pan) const
117 {
118 if (pan < -maxPan) pan = -maxPan;
119 if (pan > maxPan) pan = maxPan;
120 return pan;
112 } 121 }
113 122
114 int 123 int
115 LevelPanWidget::audioLevelToNotch(float audioLevel) const 124 LevelPanWidget::audioLevelToNotch(float audioLevel) const
116 { 125 {
149 158
150 int 159 int
151 LevelPanWidget::audioPanToPan(float audioPan) const 160 LevelPanWidget::audioPanToPan(float audioPan) const
152 { 161 {
153 int pan = int(round(audioPan * maxPan)); 162 int pan = int(round(audioPan * maxPan));
154 if (pan < -maxPan) pan = -maxPan; 163 pan = clampPan(pan);
155 if (pan > maxPan) pan = maxPan;
156 return pan; 164 return pan;
157 } 165 }
158 166
159 float 167 float
160 LevelPanWidget::panToAudioPan(int pan) const 168 LevelPanWidget::panToAudioPan(int pan) const
274 } 282 }
275 283
276 void 284 void
277 LevelPanWidget::wheelEvent(QWheelEvent *e) 285 LevelPanWidget::wheelEvent(QWheelEvent *e)
278 { 286 {
279 if (e->modifiers() & Qt::ControlModifier) { 287 e->accept();
280 if (e->delta() > 0) { 288
281 if (m_pan < maxPan) { 289 int dy = e->angleDelta().y();
282 ++m_pan; 290 if (dy == 0) {
283 emitPanChanged(); 291 return;
284 update(); 292 }
285 } 293
294 if (e->phase() == Qt::ScrollBegin ||
295 std::abs(dy) >= 120 ||
296 (dy > 0 && m_pendingWheelAngle < 0) ||
297 (dy < 0 && m_pendingWheelAngle > 0)) {
298 m_pendingWheelAngle = dy;
299 } else {
300 m_pendingWheelAngle += dy;
301 }
302
303 if (abs(m_pendingWheelAngle) >= 600) {
304 // discard absurd results
305 m_pendingWheelAngle = 0;
306 return;
307 }
308
309 while (abs(m_pendingWheelAngle) >= 120) {
310
311 int sign = (m_pendingWheelAngle < 0 ? -1 : 1);
312
313 if (e->modifiers() & Qt::ControlModifier) {
314 m_pan += sign;
315 m_pan = clampPan(m_pan);
316 emitPanChanged();
317 update();
286 } else { 318 } else {
287 if (m_pan > -maxPan) { 319 m_notch += sign;
288 --m_pan; 320 m_notch = clampNotch(m_notch);
289 emitPanChanged(); 321 emitLevelChanged();
290 update(); 322 update();
291 }
292 } 323 }
293 } else { 324
294 if (e->delta() > 0) { 325 m_pendingWheelAngle -= sign * 120;
295 if (m_notch < m_maxNotch) {
296 ++m_notch;
297 emitLevelChanged();
298 update();
299 }
300 } else {
301 if (m_notch > m_minNotch) {
302 --m_notch;
303 emitLevelChanged();
304 update();
305 }
306 }
307 } 326 }
308 } 327 }
309 328
310 int 329 int
311 LevelPanWidget::coordsToNotch(QRectF rect, QPointF loc) const 330 LevelPanWidget::coordsToNotch(QRectF rect, QPointF loc) const
328 347
329 int npan = maxPan * 2 + 1; 348 int npan = maxPan * 2 + 1;
330 double cell = w / npan; 349 double cell = w / npan;
331 350
332 int pan = int((loc.x() - rect.x()) / cell) - maxPan; 351 int pan = int((loc.x() - rect.x()) / cell) - maxPan;
333 if (pan < -maxPan) pan = -maxPan; 352 pan = clampPan(pan);
334 if (pan > maxPan) pan = maxPan;
335 353
336 return pan; 354 return pan;
337 } 355 }
338 356
339 QSizeF 357 QSizeF