diff --git a/src/axis.cpp b/src/axis.cpp index 1a9417b..2751246 100644 --- a/src/axis.cpp +++ b/src/axis.cpp @@ -13,7 +13,9 @@ Axis::Axis( int i, QObject *parent ) : QObject(parent) { isOn = false; isDown = false; state = 0; + interpretation = ZeroOne; gradient = false; + absolute = false; toDefault(); tick = 0; } @@ -117,8 +119,20 @@ bool Axis::read( QTextStream &stream ) { else return false; } //the rest of the options are keywords without integers - else if (*it == "gradient") { + else if (*it == "zeroone") { + interpretation = ZeroOne; + gradient = false; + absolute = false; + } + else if (*it == "absolute") { + interpretation = AbsolutePos; gradient = true; + absolute = true; + } + else if (*it == "gradient") { + interpretation = Gradient; + gradient = true; + absolute = false; } else if (*it == "throttle+") { throttle = 1; @@ -157,7 +171,8 @@ void Axis::timerCalled() { void Axis::write( QTextStream &stream ) { stream << "\tAxis " << (index+1) << ": "; - if (gradient) stream << "gradient, "; + stream << ((interpretation == ZeroOne)?"ZeroOne": + (interpretation == Gradient)?"Gradient":"Absolute") << ", "; if (throttle > 0) stream << "throttle+, "; else if (throttle < 0) stream << "throttle-, "; if (dZone != DZONE) stream << "dZone " << dZone << ", "; @@ -235,7 +250,9 @@ void Axis::jsevent( int value ) { void Axis::toDefault() { release(); + interpretation = ZeroOne; gradient = false; + absolute = false; throttle = 0; maxSpeed = 100; transferCurve = Quadratic; @@ -254,7 +271,9 @@ void Axis::toDefault() { } bool Axis::isDefault() { - return (gradient == false) && + return (interpretation == ZeroOne) && + (gradient == false) && + (absolute == false) && (throttle == 0) && (maxSpeed == 100) && (dZone == DZONE) && @@ -414,7 +433,7 @@ void Axis::move( bool press ) { //if not gradient, always go full speed. else dist = maxSpeed; - e.type = FakeEvent::MouseMove; + e.type = absolute ? FakeEvent::MouseMoveAbsolute : FakeEvent::MouseMove; if (mode == MousePosVert) { e.move.x = 0; e.move.y = dist; diff --git a/src/axis.h b/src/axis.h index 50c3e26..b10b822 100644 --- a/src/axis.h +++ b/src/axis.h @@ -22,6 +22,7 @@ class Axis : public QObject { Q_OBJECT //each axis can create a key press or move the mouse in one of four directions. + enum Interpretation { ZeroOne, Gradient, AbsolutePos }; enum Mode {Keyboard, MousePosVert, MouseNegVert, MousePosHor, MouseNegHor}; enum TransferCurve {Linear, Quadratic, Cubic, QuadraticExtreme, PowerFunction}; @@ -76,7 +77,9 @@ class Axis : public QObject { float inverseRange; //actual axis settings: + Interpretation interpretation; bool gradient; + bool absolute; int maxSpeed; //0..MAXMOUSESPEED unsigned int transferCurve; float sensitivity; diff --git a/src/axis_edit.cpp b/src/axis_edit.cpp index e17797b..816447a 100644 --- a/src/axis_edit.cpp +++ b/src/axis_edit.cpp @@ -23,9 +23,12 @@ AxisEdit::AxisEdit( Axis* ax ) QVBoxLayout* v2 = new QVBoxLayout(); v2->setMargin(5); v2->setSpacing(5); - chkGradient = new QCheckBox(tr("&Gradient"), this); - chkGradient->setChecked(axis->gradient); - connect(chkGradient, SIGNAL(toggled(bool)), this, SLOT( gradientChanged( bool ))); + chkGradient = new QComboBox(this); + chkGradient->insertItem((int) Axis::ZeroOne, tr("Use 0 or max always"), Qt::DisplayRole); + chkGradient->insertItem((int) Axis::Gradient, tr("Relative movement (previously gradient)"), Qt::DisplayRole); + chkGradient->insertItem((int) Axis::AbsolutePos, tr("Absolute movement (direct position)"), Qt::DisplayRole); + chkGradient->setCurrentIndex( axis->interpretation ); + connect(chkGradient, SIGNAL(activated(int)), this, SLOT( gradientChanged( int ))); v2->addWidget(chkGradient); cmbMode = new QComboBox(this); @@ -103,6 +106,7 @@ AxisEdit::AxisEdit( Axis* ax ) connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); v->addWidget(buttonBox); + gradientChanged( axis->interpretation ); modeChanged( axis->mode ); transferCurveChanged( axis->transferCurve ); throttleChanged( axis->throttle + 1 ); @@ -116,9 +120,10 @@ void AxisEdit::show() { void AxisEdit::setState( int val ) { slider->setValue( val ); } -void AxisEdit::gradientChanged( bool on ) { - cmbTransferCurve->setEnabled(on); - if (on) { +void AxisEdit::gradientChanged( int index ) { + bool gradient = index != Axis::ZeroOne; + cmbTransferCurve->setEnabled(gradient); + if (gradient) { transferCurveChanged( axis->transferCurve ); } else { @@ -135,7 +140,7 @@ void AxisEdit::modeChanged( int index ) { else { mouseBox->setEnabled(true); keyBox->setEnabled(false); - if (chkGradient->isChecked()) { + if ((Axis::Interpretation)chkGradient->currentIndex() != Axis::ZeroOne) { cmbTransferCurve->setEnabled(true); transferCurveChanged( axis->transferCurve ); } @@ -172,7 +177,9 @@ void AxisEdit::throttleChanged( int index ) { } void AxisEdit::accept() { - axis->gradient = chkGradient->isChecked(); + axis->interpretation = (Axis::Interpretation)chkGradient->currentIndex(); + axis->gradient = axis->interpretation != Axis::ZeroOne; + axis->absolute = axis->interpretation == Axis::AbsolutePos; axis->maxSpeed = spinSpeed->value(); axis->transferCurve = (Axis::TransferCurve)cmbTransferCurve->currentIndex(); axis->sensitivity = spinSensitivity->value(); diff --git a/src/axis_edit.h b/src/axis_edit.h index 4d8319b..6a708b3 100644 --- a/src/axis_edit.h +++ b/src/axis_edit.h @@ -24,7 +24,7 @@ class AxisEdit : public QDialog { void setState( int val ); protected slots: //slots for GUI events - void gradientChanged( bool on ); + void gradientChanged( int index ); void modeChanged( int index ); void transferCurveChanged( int index ); void throttleChanged( int index ); @@ -33,8 +33,7 @@ class AxisEdit : public QDialog { //the associated Axis that needs to be set. Axis *axis; //the important parts of the dialog: - QCheckBox *chkGradient; - QComboBox *cmbMode, *cmbThrottle, *cmbTransferCurve; + QComboBox *chkGradient, *cmbMode, *cmbThrottle, *cmbTransferCurve; QFrame *mouseBox, *keyBox; QSpinBox *spinSpeed; QLabel *lblSensitivity; diff --git a/src/event.cpp b/src/event.cpp index dc07786..08d3a37 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -11,6 +11,19 @@ void sendevent(const FakeEvent &e) { XTestFakeRelativeMotionEvent(display, e.move.x, e.move.y, 0); break; + case FakeEvent::MouseMoveAbsolute: + { + Screen* screen = XDefaultScreenOfDisplay(display); + static int rememberX = 0, rememberY = 0; + if (e.move.x) rememberX = e.move.x; + if (e.move.y) rememberY = e.move.y; + const int scaledX100 = rememberX * (XWidthOfScreen(screen)/2) / 100; + const int scaledY100 = rememberY * (XHeightOfScreen(screen)/2) / 100; + XTestFakeMotionEvent(display, DefaultScreen(display), + XWidthOfScreen(screen)/2 + scaledX100, + XHeightOfScreen(screen)/2 + scaledY100, 0); + break; + } case FakeEvent::KeyUp: if (e.keycode == 0) return; XTestFakeKeyEvent(display, e.keycode, false, 0); diff --git a/src/event.h b/src/event.h index 7b8ca3a..584756c 100644 --- a/src/event.h +++ b/src/event.h @@ -8,7 +8,7 @@ struct FakeEvent { //types of events QJoyPad can create. //KeyRelease, KeyPress, ButtonRelease, ButtonPress, and MouseMove - enum EventType {KeyUp, KeyDown, MouseUp, MouseDown, MouseMove}; + enum EventType {KeyUp, KeyDown, MouseUp, MouseDown, MouseMove, MouseMoveAbsolute}; EventType type; union {