Skip to content

Commit c6a1abe

Browse files
Fix #5194: Fix knobs moving too fast (#5360)
This PR fixes issues on systems where `QCursor::setPos()` has no effect or is not reliable. These issues included knobs moving to fast on some operating systems. Affected widgets are `Knob` and `LcdSpinBox`. With this PR, on all operating systems, the `setPos` calls are removed and the cursor is not hidden anymore, so the mouse keeps moving normally when changing values of one of the widgets. As now the previous pointer position keeps moving (instead of being reset to the original position using `QCursor::setPos`), the mathematics that translate pointer pixel distance to `Knob`/`LcdSpinBox` value increase have to be changed: * The `Knob` transition function is now linear and uses a new factor. * `LcdSpinBox` now uses float values and saves the current float remainder (this is actually a separate issue revealed by this fix), leading to a fluent, non hanging movement.
1 parent 3a985ff commit c6a1abe

File tree

4 files changed

+29
-28
lines changed

4 files changed

+29
-28
lines changed

include/Knob.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,7 @@ private slots:
174174
BoolModel m_volumeKnob;
175175
FloatModel m_volumeRatio;
176176

177-
QPoint m_mouseOffset;
178-
QPoint m_origMousePos;
177+
QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
179178
float m_leftOver;
180179
bool m_buttonPressed;
181180

include/LcdSpinBox.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ public slots:
7373
virtual void mouseDoubleClickEvent( QMouseEvent * _me );
7474

7575
private:
76+
float m_remainder; //!< floating offset of spinbox in [-0.5, 0.5]
7677
bool m_mouseMoving;
77-
QPoint m_origMousePos;
78+
QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
7879
int m_displayOffset;
7980
void enterValue();
8081

src/gui/widgets/Knob.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,8 @@ float Knob::getValue( const QPoint & _p )
497497
{
498498
float value;
499499

500-
// arcane mathemagicks for calculating knob movement
501-
value = ( ( _p.y() + _p.y() * qMin( qAbs( _p.y() / 2.5f ), 6.0f ) ) ) / 12.0f;
500+
// knob value increase is linear to mouse movement
501+
value = .4f * _p.y();
502502

503503
// if shift pressed we want slower movement
504504
if( gui->mainWindow()->isShiftPressed() )
@@ -587,13 +587,11 @@ void Knob::mousePressEvent( QMouseEvent * _me )
587587
}
588588

589589
const QPoint & p = _me->pos();
590-
m_origMousePos = p;
591-
m_mouseOffset = QPoint(0, 0);
590+
m_lastMousePos = p;
592591
m_leftOver = 0.0f;
593592

594593
emit sliderPressed();
595594

596-
QApplication::setOverrideCursor( Qt::BlankCursor );
597595
s_textFloat->setText( displayValue() );
598596
s_textFloat->moveGlobal( this,
599597
QPoint( width() + 2, 0 ) );
@@ -618,12 +616,13 @@ void Knob::mousePressEvent( QMouseEvent * _me )
618616

619617
void Knob::mouseMoveEvent( QMouseEvent * _me )
620618
{
621-
if( m_buttonPressed && _me->pos() != m_origMousePos )
619+
if( m_buttonPressed && _me->pos() != m_lastMousePos )
622620
{
623-
m_mouseOffset = _me->pos() - m_origMousePos;
624-
setPosition( m_mouseOffset );
621+
// knob position is changed depending on last mouse position
622+
setPosition( _me->pos() - m_lastMousePos );
625623
emit sliderMoved( model()->value() );
626-
QCursor::setPos( mapToGlobal( m_origMousePos ) );
624+
// original position for next time is current position
625+
m_lastMousePos = _me->pos();
627626
}
628627
s_textFloat->setText( displayValue() );
629628
}

src/gui/widgets/LcdSpinBox.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*
2424
*/
2525

26+
#include <cmath>
2627
#include <QApplication>
2728
#include <QLabel>
2829
#include <QMouseEvent>
@@ -40,8 +41,9 @@
4041
LcdSpinBox::LcdSpinBox( int numDigits, QWidget* parent, const QString& name ) :
4142
LcdWidget( numDigits, parent, name ),
4243
IntModelView( new IntModel( 0, 0, 0, NULL, name, true ), this ),
44+
m_remainder( 0.f ),
4345
m_mouseMoving( false ),
44-
m_origMousePos(),
46+
m_lastMousePos(),
4547
m_displayOffset( 0 )
4648
{
4749
}
@@ -52,8 +54,9 @@ LcdSpinBox::LcdSpinBox( int numDigits, QWidget* parent, const QString& name ) :
5254
LcdSpinBox::LcdSpinBox( int numDigits, const QString& style, QWidget* parent, const QString& name ) :
5355
LcdWidget( numDigits, parent, name ),
5456
IntModelView( new IntModel( 0, 0, 0, NULL, name, true ), this ),
57+
m_remainder( 0.f ),
5558
m_mouseMoving( false ),
56-
m_origMousePos(),
59+
m_lastMousePos(),
5760
m_displayOffset( 0 )
5861
{
5962
}
@@ -98,8 +101,7 @@ void LcdSpinBox::mousePressEvent( QMouseEvent* event )
98101
event->y() < cellHeight() + 2 )
99102
{
100103
m_mouseMoving = true;
101-
m_origMousePos = event->globalPos();
102-
QApplication::setOverrideCursor( Qt::BlankCursor );
104+
m_lastMousePos = event->globalPos();
103105

104106
AutomatableModel *thisModel = model();
105107
if( thisModel )
@@ -121,15 +123,20 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event )
121123
{
122124
if( m_mouseMoving )
123125
{
124-
int dy = event->globalY() - m_origMousePos.y();
125-
if( event->modifiers() & Qt::ShiftModifier )
126-
dy = qBound( -4, dy/4, 4 );
127-
if( dy > 1 || dy < -1 )
126+
int dy = event->globalY() - m_lastMousePos.y();
127+
if( dy )
128128
{
129-
model()->setInitValue( model()->value() -
130-
dy / 2 * model()->step<int>() );
129+
float fdy = static_cast<float>(dy);
130+
if( event->modifiers() & Qt::ShiftModifier ) {
131+
fdy = qBound( -4.f, fdy/4.f, 4.f );
132+
}
133+
float floatValNotRounded =
134+
model()->value() + m_remainder - fdy / 2.f * model()->step<int>();
135+
float floatValRounded = roundf( floatValNotRounded );
136+
m_remainder = floatValNotRounded - floatValRounded;
137+
model()->setInitValue( floatValRounded );
131138
emit manualChange();
132-
QCursor::setPos( m_origMousePos );
139+
m_lastMousePos = event->globalPos();
133140
}
134141
}
135142
}
@@ -142,10 +149,7 @@ void LcdSpinBox::mouseReleaseEvent( QMouseEvent* )
142149
if( m_mouseMoving )
143150
{
144151
model()->restoreJournallingState();
145-
146-
QCursor::setPos( m_origMousePos );
147152
QApplication::restoreOverrideCursor();
148-
149153
m_mouseMoving = false;
150154
}
151155
}
@@ -187,5 +191,3 @@ void LcdSpinBox::enterValue()
187191
}
188192
}
189193

190-
191-

0 commit comments

Comments
 (0)