Chris@1303: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@1303: 
Chris@1303: /*
Chris@1303:     Sonic Visualiser
Chris@1303:     An audio file viewer and annotation editor.
Chris@1303:     Centre for Digital Music, Queen Mary, University of London.
Chris@1303:     
Chris@1303:     This program is free software; you can redistribute it and/or
Chris@1303:     modify it under the terms of the GNU General Public License as
Chris@1303:     published by the Free Software Foundation; either version 2 of the
Chris@1303:     License, or (at your option) any later version.  See the file
Chris@1303:     COPYING included with this distribution for more information.
Chris@1303: */
Chris@1303: 
Chris@1303: #ifndef SV_WHEEL_COUNTER_H
Chris@1303: #define SV_WHEEL_COUNTER_H
Chris@1303: 
Chris@1303: #include <QWheelEvent>
Chris@1303: 
Chris@1303: /**
Chris@1303:  * Manage the little bit of tedious book-keeping associated with
Chris@1303:  * translating vertical wheel events into up/down notch counts
Chris@1303:  */
Chris@1303: class WheelCounter
Chris@1303: {
Chris@1303: public:
Chris@1303:     WheelCounter() : m_pendingWheelAngle(0) { }
Chris@1303: 
Chris@1303:     ~WheelCounter() { }
Chris@1303: 
Chris@1303:     int count(QWheelEvent *e) {
Chris@1303:         
Chris@1303:         e->accept();
Chris@1303:     
Chris@1303:         int delta = e->angleDelta().y();
Chris@1303:         if (delta == 0) {
Chris@1303:             return 0;
Chris@1303:         }
Chris@1303: 
Chris@1303:         if (e->phase() == Qt::ScrollBegin ||
Chris@1303:             std::abs(delta) >= 120 ||
Chris@1303:             (delta > 0 && m_pendingWheelAngle < 0) ||
Chris@1303:             (delta < 0 && m_pendingWheelAngle > 0)) {
Chris@1303:             m_pendingWheelAngle = delta;
Chris@1303:         } else {
Chris@1303:             m_pendingWheelAngle += delta;
Chris@1303:         }
Chris@1303: 
Chris@1303:         if (abs(m_pendingWheelAngle) >= 600) {
Chris@1303:             // Sometimes on Linux we're seeing absurdly extreme angles
Chris@1303:             // on the first wheel event -- discard those entirely
Chris@1303:             m_pendingWheelAngle = 0;
Chris@1303:             return 0;
Chris@1303:         }
Chris@1303: 
Chris@1303:         int count = m_pendingWheelAngle / 120;
Chris@1303:         m_pendingWheelAngle -= count * 120;
Chris@1303:         return count;
Chris@1303:     }
Chris@1303: 
Chris@1303: private:
Chris@1303:     int m_pendingWheelAngle;
Chris@1303: };
Chris@1303: 
Chris@1303: #endif