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.
This commit is contained in:
@@ -174,8 +174,7 @@ private:
|
||||
BoolModel m_volumeKnob;
|
||||
FloatModel m_volumeRatio;
|
||||
|
||||
QPoint m_mouseOffset;
|
||||
QPoint m_origMousePos;
|
||||
QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
|
||||
float m_leftOver;
|
||||
bool m_buttonPressed;
|
||||
|
||||
|
||||
@@ -73,8 +73,9 @@ protected:
|
||||
virtual void mouseDoubleClickEvent( QMouseEvent * _me );
|
||||
|
||||
private:
|
||||
float m_remainder; //!< floating offset of spinbox in [-0.5, 0.5]
|
||||
bool m_mouseMoving;
|
||||
QPoint m_origMousePos;
|
||||
QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
|
||||
int m_displayOffset;
|
||||
void enterValue();
|
||||
|
||||
|
||||
@@ -497,8 +497,8 @@ float Knob::getValue( const QPoint & _p )
|
||||
{
|
||||
float value;
|
||||
|
||||
// arcane mathemagicks for calculating knob movement
|
||||
value = ( ( _p.y() + _p.y() * qMin( qAbs( _p.y() / 2.5f ), 6.0f ) ) ) / 12.0f;
|
||||
// knob value increase is linear to mouse movement
|
||||
value = .4f * _p.y();
|
||||
|
||||
// if shift pressed we want slower movement
|
||||
if( gui->mainWindow()->isShiftPressed() )
|
||||
@@ -587,13 +587,11 @@ void Knob::mousePressEvent( QMouseEvent * _me )
|
||||
}
|
||||
|
||||
const QPoint & p = _me->pos();
|
||||
m_origMousePos = p;
|
||||
m_mouseOffset = QPoint(0, 0);
|
||||
m_lastMousePos = p;
|
||||
m_leftOver = 0.0f;
|
||||
|
||||
emit sliderPressed();
|
||||
|
||||
QApplication::setOverrideCursor( Qt::BlankCursor );
|
||||
s_textFloat->setText( displayValue() );
|
||||
s_textFloat->moveGlobal( this,
|
||||
QPoint( width() + 2, 0 ) );
|
||||
@@ -618,12 +616,13 @@ void Knob::mousePressEvent( QMouseEvent * _me )
|
||||
|
||||
void Knob::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( m_buttonPressed && _me->pos() != m_origMousePos )
|
||||
if( m_buttonPressed && _me->pos() != m_lastMousePos )
|
||||
{
|
||||
m_mouseOffset = _me->pos() - m_origMousePos;
|
||||
setPosition( m_mouseOffset );
|
||||
// knob position is changed depending on last mouse position
|
||||
setPosition( _me->pos() - m_lastMousePos );
|
||||
emit sliderMoved( model()->value() );
|
||||
QCursor::setPos( mapToGlobal( m_origMousePos ) );
|
||||
// original position for next time is current position
|
||||
m_lastMousePos = _me->pos();
|
||||
}
|
||||
s_textFloat->setText( displayValue() );
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <QApplication>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
@@ -40,8 +41,9 @@
|
||||
LcdSpinBox::LcdSpinBox( int numDigits, QWidget* parent, const QString& name ) :
|
||||
LcdWidget( numDigits, parent, name ),
|
||||
IntModelView( new IntModel( 0, 0, 0, NULL, name, true ), this ),
|
||||
m_remainder( 0.f ),
|
||||
m_mouseMoving( false ),
|
||||
m_origMousePos(),
|
||||
m_lastMousePos(),
|
||||
m_displayOffset( 0 )
|
||||
{
|
||||
}
|
||||
@@ -52,8 +54,9 @@ LcdSpinBox::LcdSpinBox( int numDigits, QWidget* parent, const QString& name ) :
|
||||
LcdSpinBox::LcdSpinBox( int numDigits, const QString& style, QWidget* parent, const QString& name ) :
|
||||
LcdWidget( numDigits, parent, name ),
|
||||
IntModelView( new IntModel( 0, 0, 0, NULL, name, true ), this ),
|
||||
m_remainder( 0.f ),
|
||||
m_mouseMoving( false ),
|
||||
m_origMousePos(),
|
||||
m_lastMousePos(),
|
||||
m_displayOffset( 0 )
|
||||
{
|
||||
}
|
||||
@@ -98,8 +101,7 @@ void LcdSpinBox::mousePressEvent( QMouseEvent* event )
|
||||
event->y() < cellHeight() + 2 )
|
||||
{
|
||||
m_mouseMoving = true;
|
||||
m_origMousePos = event->globalPos();
|
||||
QApplication::setOverrideCursor( Qt::BlankCursor );
|
||||
m_lastMousePos = event->globalPos();
|
||||
|
||||
AutomatableModel *thisModel = model();
|
||||
if( thisModel )
|
||||
@@ -121,15 +123,20 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event )
|
||||
{
|
||||
if( m_mouseMoving )
|
||||
{
|
||||
int dy = event->globalY() - m_origMousePos.y();
|
||||
if( event->modifiers() & Qt::ShiftModifier )
|
||||
dy = qBound( -4, dy/4, 4 );
|
||||
if( dy > 1 || dy < -1 )
|
||||
int dy = event->globalY() - m_lastMousePos.y();
|
||||
if( dy )
|
||||
{
|
||||
model()->setInitValue( model()->value() -
|
||||
dy / 2 * model()->step<int>() );
|
||||
float fdy = static_cast<float>(dy);
|
||||
if( event->modifiers() & Qt::ShiftModifier ) {
|
||||
fdy = qBound( -4.f, fdy/4.f, 4.f );
|
||||
}
|
||||
float floatValNotRounded =
|
||||
model()->value() + m_remainder - fdy / 2.f * model()->step<int>();
|
||||
float floatValRounded = roundf( floatValNotRounded );
|
||||
m_remainder = floatValNotRounded - floatValRounded;
|
||||
model()->setInitValue( floatValRounded );
|
||||
emit manualChange();
|
||||
QCursor::setPos( m_origMousePos );
|
||||
m_lastMousePos = event->globalPos();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,10 +149,7 @@ void LcdSpinBox::mouseReleaseEvent( QMouseEvent* )
|
||||
if( m_mouseMoving )
|
||||
{
|
||||
model()->restoreJournallingState();
|
||||
|
||||
QCursor::setPos( m_origMousePos );
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
m_mouseMoving = false;
|
||||
}
|
||||
}
|
||||
@@ -187,5 +191,3 @@ void LcdSpinBox::enterValue()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user