# HG changeset patch # User Chris Cannam # Date 1529684388 -3600 # Node ID 13f5f84fbfad264ca517870e71151966383a6e2e # Parent f3d3fab250ac9780029adf45485ab85e474878ba Collect the bits of bookkeeping for mouse wheel events, and use in all widgets diff -r f3d3fab250ac -r 13f5f84fbfad files.pri --- a/files.pri Fri Jun 22 13:41:54 2018 +0100 +++ b/files.pri Fri Jun 22 17:19:48 2018 +0100 @@ -87,6 +87,7 @@ widgets/TipDialog.h \ widgets/TransformFinder.h \ widgets/UnitConverter.h \ + widgets/WheelCounter.h \ widgets/WidgetScale.h \ widgets/WindowShapePreview.h \ widgets/WindowTypeSelector.h diff -r f3d3fab250ac -r 13f5f84fbfad widgets/LevelPanWidget.cpp --- a/widgets/LevelPanWidget.cpp Fri Jun 22 13:41:54 2018 +0100 +++ b/widgets/LevelPanWidget.cpp Fri Jun 22 17:19:48 2018 +0100 @@ -74,8 +74,7 @@ m_editable(true), m_editing(false), m_includeMute(true), - m_includeHalfSteps(true), - m_pendingWheelAngle(0) + m_includeHalfSteps(true) { setToolTip(tr("Drag vertically to adjust level, horizontally to adjust pan")); setLevel(1.0); @@ -284,45 +283,20 @@ void LevelPanWidget::wheelEvent(QWheelEvent *e) { - e->accept(); - - int dy = e->angleDelta().y(); - if (dy == 0) { + int delta = m_wheelCounter.count(e); + + if (delta == 0) { return; } - if (e->phase() == Qt::ScrollBegin || - std::abs(dy) >= 120 || - (dy > 0 && m_pendingWheelAngle < 0) || - (dy < 0 && m_pendingWheelAngle > 0)) { - m_pendingWheelAngle = dy; + if (e->modifiers() & Qt::ControlModifier) { + m_pan = clampPan(m_pan + delta); + emitPanChanged(); + update(); } else { - m_pendingWheelAngle += dy; - } - - if (abs(m_pendingWheelAngle) >= 600) { - // discard absurd results - m_pendingWheelAngle = 0; - return; - } - - while (abs(m_pendingWheelAngle) >= 120) { - - int sign = (m_pendingWheelAngle < 0 ? -1 : 1); - - if (e->modifiers() & Qt::ControlModifier) { - m_pan += sign; - m_pan = clampPan(m_pan); - emitPanChanged(); - update(); - } else { - m_notch += sign; - m_notch = clampNotch(m_notch); - emitLevelChanged(); - update(); - } - - m_pendingWheelAngle -= sign * 120; + m_notch = clampNotch(m_notch + delta); + emitLevelChanged(); + update(); } } diff -r f3d3fab250ac -r 13f5f84fbfad widgets/LevelPanWidget.h --- a/widgets/LevelPanWidget.h Fri Jun 22 13:41:54 2018 +0100 +++ b/widgets/LevelPanWidget.h Fri Jun 22 17:19:48 2018 +0100 @@ -17,6 +17,8 @@ #include +#include "WheelCounter.h" + /** * A simple widget for coarse level and pan control. */ @@ -98,7 +100,8 @@ bool m_editing; bool m_includeMute; bool m_includeHalfSteps; - int m_pendingWheelAngle; + + WheelCounter m_wheelCounter; int clampNotch(int notch) const; int clampPan(int pan) const; diff -r f3d3fab250ac -r 13f5f84fbfad widgets/Panner.cpp --- a/widgets/Panner.cpp Fri Jun 22 13:41:54 2018 +0100 +++ b/widgets/Panner.cpp Fri Jun 22 17:19:48 2018 +0100 @@ -64,6 +64,12 @@ void Panner::scroll(bool up) { + scroll(up, 1); +} + +void +Panner::scroll(bool up, int count) +{ float unit = m_scrollUnit; if (unit == 0.f) { unit = float(m_rectHeight) / (6 * float(height())); @@ -71,9 +77,9 @@ } if (!up) { - m_rectY += unit; + m_rectY += unit * count; } else { - m_rectY -= unit; + m_rectY -= unit * count; } normalise(); @@ -134,7 +140,8 @@ void Panner::wheelEvent(QWheelEvent *e) { - scroll(e->delta() > 0); + int delta = m_wheelCounter.count(e); + scroll(delta > 0, abs(delta)); } void diff -r f3d3fab250ac -r 13f5f84fbfad widgets/Panner.h --- a/widgets/Panner.h Fri Jun 22 13:41:54 2018 +0100 +++ b/widgets/Panner.h Fri Jun 22 17:19:48 2018 +0100 @@ -13,11 +13,13 @@ COPYING included with this distribution for more information. */ -#ifndef _PANNER_H_ -#define _PANNER_H_ +#ifndef SV_PANNER_H +#define SV_PANNER_H #include +#include "WheelCounter.h" + class Panner : public QWidget { Q_OBJECT @@ -109,6 +111,12 @@ */ void scroll(bool up); + /** + * Move up (if up is true) or down a bit. This is basically the + * same action as rolling the mouse wheel n notches. + */ + void scroll(bool up, int n); + void resetToDefault(); protected: @@ -145,6 +153,8 @@ QPoint m_clickPos; float m_dragStartX; float m_dragStartY; + + WheelCounter m_wheelCounter; }; #endif diff -r f3d3fab250ac -r 13f5f84fbfad widgets/Thumbwheel.cpp --- a/widgets/Thumbwheel.cpp Fri Jun 22 13:41:54 2018 +0100 +++ b/widgets/Thumbwheel.cpp Fri Jun 22 17:19:48 2018 +0100 @@ -426,15 +426,13 @@ void Thumbwheel::wheelEvent(QWheelEvent *e) { - int step = int(lrintf(m_speed)); - if (step == 0) step = 1; + int delta = m_wheelCounter.count(e); - if (e->delta() > 0) { - setValue(m_value + step); - } else { - setValue(m_value - step); + if (delta == 0) { + return; } - + + setValue(m_value + delta); emit valueChanged(getValue()); } diff -r f3d3fab250ac -r 13f5f84fbfad widgets/Thumbwheel.h --- a/widgets/Thumbwheel.h Fri Jun 22 13:41:54 2018 +0100 +++ b/widgets/Thumbwheel.h Fri Jun 22 17:19:48 2018 +0100 @@ -13,14 +13,16 @@ COPYING included with this distribution for more information. */ -#ifndef _THUMBWHEEL_H_ -#define _THUMBWHEEL_H_ +#ifndef SV_THUMBWHEEL_H +#define SV_THUMBWHEEL_H #include #include #include +#include "WheelCounter.h" + class RangeMapper; class Thumbwheel : public QWidget @@ -96,6 +98,7 @@ bool m_showTooltip; RangeMapper *m_rangeMapper; QImage m_cache; + WheelCounter m_wheelCounter; }; #endif diff -r f3d3fab250ac -r 13f5f84fbfad widgets/WheelCounter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/WheelCounter.h Fri Jun 22 17:19:48 2018 +0100 @@ -0,0 +1,65 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef SV_WHEEL_COUNTER_H +#define SV_WHEEL_COUNTER_H + +#include + +/** + * Manage the little bit of tedious book-keeping associated with + * translating vertical wheel events into up/down notch counts + */ +class WheelCounter +{ +public: + WheelCounter() : m_pendingWheelAngle(0) { } + + ~WheelCounter() { } + + int count(QWheelEvent *e) { + + e->accept(); + + int delta = e->angleDelta().y(); + if (delta == 0) { + return 0; + } + + if (e->phase() == Qt::ScrollBegin || + std::abs(delta) >= 120 || + (delta > 0 && m_pendingWheelAngle < 0) || + (delta < 0 && m_pendingWheelAngle > 0)) { + m_pendingWheelAngle = delta; + } else { + m_pendingWheelAngle += delta; + } + + if (abs(m_pendingWheelAngle) >= 600) { + // Sometimes on Linux we're seeing absurdly extreme angles + // on the first wheel event -- discard those entirely + m_pendingWheelAngle = 0; + return 0; + } + + int count = m_pendingWheelAngle / 120; + m_pendingWheelAngle -= count * 120; + return count; + } + +private: + int m_pendingWheelAngle; +}; + +#endif