diff --git a/controllersetup.cpp b/controllersetup.cpp index d1ae6e7..d1f99c2 100644 --- a/controllersetup.cpp +++ b/controllersetup.cpp @@ -496,6 +496,7 @@ void controllerSetup::newDevice(USBDEVICE* dev) connect(&c->sens, &QSlider::valueChanged, [dev,this](int val) { this->sensitivityMoved(dev,val); }); + c->sensLayout.addStretch(0); c->pageLabel.setText("Page:"); c->sensLayout.addWidget(&c->pageLabel); c->page.setObjectName("Page SpinBox"); @@ -508,46 +509,46 @@ void controllerSetup::newDevice(USBDEVICE* dev) dev->pageSpin = &c->page; switch (dev->type.model) { - case shuttleXpress: - c->image.load(":/resources/shuttlexpress.png"); - break; - case shuttlePro2: - c->image.load(":/resources/shuttlepro.png"); - break; - case RC28: - c->image.load(":/resources/rc28.png"); - break; - case xBoxGamepad: - c->image.load(":/resources/xbox.png"); - break; - case eCoderPlus: - c->image.load(":/resources/ecoder.png"); - break; - case QuickKeys: - c->image.load(":/resources/quickkeys.png"); - break; - case StreamDeckOriginal: - case StreamDeckOriginalV2: - case StreamDeckOriginalMK2: - c->image.load(":/resources/streamdeck.png"); - break; - case StreamDeckMini: - case StreamDeckMiniV2: - c->image.load(":/resources/streamdeckmini.png"); - break; - case StreamDeckXL: - case StreamDeckXLV2: - c->image.load(":/resources/streamdeckxl.png"); - break; - case StreamDeckPlus: - c->image.load(":/resources/streamdeckplus.png"); - break; - case StreamDeckPedal: - c->image.load(":/resources/streamdeckpedal.png"); - break; - default: - this->adjustSize(); - break; + case shuttleXpress: + c->image.load(":/resources/shuttlexpress.png"); + break; + case shuttlePro2: + c->image.load(":/resources/shuttlepro.png"); + break; + case RC28: + c->image.load(":/resources/rc28.png"); + break; + case xBoxGamepad: + c->image.load(":/resources/xbox.png"); + break; + case eCoderPlus: + c->image.load(":/resources/ecoder.png"); + break; + case QuickKeys: + c->image.load(":/resources/quickkeys.png"); + break; + case StreamDeckOriginal: + case StreamDeckOriginalV2: + case StreamDeckOriginalMK2: + c->image.load(":/resources/streamdeck.png"); + break; + case StreamDeckMini: + case StreamDeckMiniV2: + c->image.load(":/resources/streamdeckmini.png"); + break; + case StreamDeckXL: + case StreamDeckXLV2: + c->image.load(":/resources/streamdeckxl.png"); + break; + case StreamDeckPlus: + c->image.load(":/resources/streamdeckplus.png"); + break; + case StreamDeckPedal: + c->image.load(":/resources/streamdeckpedal.png"); + break; + default: + this->adjustSize(); + break; } c->bgImage = new QGraphicsPixmapItem(QPixmap::fromImage(c->image)); @@ -656,6 +657,60 @@ void controllerSetup::newDevice(USBDEVICE* dev) connect(&c->page, qOverload(&QSpinBox::valueChanged), [dev, this](int index) { this->pageChanged(dev, index); }); +// Hide all controls that are not relevant to this controller +// We rely on being able to fallthrough case +#if defined __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif + + switch (dev->type.model) { + case QuickKeys: + break; + case StreamDeckPedal: + c->sensLabel.setVisible(false); + c->sens.setVisible(false); + case shuttleXpress: + case shuttlePro2: + case RC28: + case xBoxGamepad: + case eCoderPlus: + c->brightLabel.setVisible(false); + c->speedLabel.setVisible(false); + c->timeoutLabel.setVisible(false); + c->orientLabel.setVisible(false); + c->brightness.setVisible(false); + c->speed.setVisible(false); + c->timeout.setVisible(false); + c->orientation.setVisible(false); + c->color.setVisible(false); + break; + case StreamDeckOriginal: + case StreamDeckOriginalV2: + case StreamDeckOriginalMK2: + case StreamDeckMini: + case StreamDeckMiniV2: + case StreamDeckXL: + case StreamDeckXLV2: + c->sensLabel.setVisible(false); + c->sens.setVisible(false); // No knobs! + case StreamDeckPlus: + c->speedLabel.setVisible(false); + c->timeoutLabel.setVisible(false); + c->orientLabel.setVisible(false); + c->speed.setVisible(false); + c->timeout.setVisible(false); + c->orientation.setVisible(false); + break; + default: + break; + } + +// Don't allow fallthrough elsewhere in the file. +#if defined __GNUC__ +#pragma GCC diagnostic pop +#endif + // pageChanged will update the buttons/knobs for the tab (using qTimer ensures mutex is unlocked first) QTimer::singleShot(0, this, [=]() { pageChanged(dev,1); }); diff --git a/usbcontroller.cpp b/usbcontroller.cpp index 410b8da..d20a706 100644 --- a/usbcontroller.cpp +++ b/usbcontroller.cpp @@ -1,10 +1,6 @@ #if defined(USB_CONTROLLER) #include "usbcontroller.h" -// We rely on being able to fallthrough case -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" - #ifdef Q_OS_WIN #pragma comment (lib, "Setupapi.lib") #endif @@ -50,7 +46,7 @@ usbController::~usbController() sendRequest(dev,usbFeatureType::featureOverlay,60,"Goodbye from wfview"); if (dev->type.model == RC28) { - ledControl(false, 3); + sendRequest(dev,usbFeatureType::featureLEDControl,3,"off"); } emit removeDevice(dev); hid_close(dev->handle); @@ -261,7 +257,7 @@ void usbController::run() devs = hid_enumerate(0x0, 0x0); // Step through all currenly connected devices and add any newly discovered ones to usbDevices. while (devs) { - auto i = std::find_if(knownDevices.begin(), knownDevices.end(), [this,devs](const USBTYPE& d) + auto i = std::find_if(knownDevices.begin(), knownDevices.end(), [devs](const USBTYPE& d) { return ((devs->vendor_id == d.manufacturerId) && (devs->product_id == d.productId) && (d.usage == 0x00 || devs->usage == d.usage) && (d.usagePage == 0x00 || devs->usage_page == d.usagePage));}); @@ -327,10 +323,10 @@ void usbController::run() if (dev->type.model == RC28) { - ledControl(false, 0); - ledControl(false, 1); - ledControl(false, 2); - ledControl(true, 3); + QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,0,"off"); }); + QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,1,"off"); }); + QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,2,"off"); }); + QTimer::singleShot(0, this, [=]() { sendRequest(dev,usbFeatureType::featureLEDControl,3,"on"); }); } else if (dev->type.model == QuickKeys) { @@ -830,40 +826,12 @@ void usbController::sendToLCD(QImage* img) } } -/* - * All functions below here are for specific controllers -*/ -void usbController::ledControl(bool on, unsigned char num) -{ - // Currently this will act on ALL connected RC28 devices - // Not sure if this needs to change? - - QMutexLocker locker(mutex); - - for (auto devIt = devices->begin(); devIt != devices->end(); devIt++) - { - auto dev = &devIt.value(); - if (dev->connected && dev->type.model == RC28) { - QByteArray data(3, 0x0); - data[1] = 0x01; - static unsigned char ledNum = 0x07; - if (on) - ledNum &= ~(1UL << num); - else - ledNum |= 1UL << num; - - data[2] = ledNum; - - int res = hid_write(dev->handle, (const unsigned char*)data.constData(), data.size()); - - if (res < 0) { - qDebug(logUsbControl()) << "Unable to write(), Error:" << hid_error(dev->handle); - return; - } - } - } -} +// We rely on being able to fallthrough case +#if defined __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif /* This function will handle various commands for multiple models of controller * @@ -871,7 +839,6 @@ void usbController::ledControl(bool on, unsigned char num) * featureInit, featureFirmware, featureSerial, featureButton, featureSensitivity, featureBrightness, * featureOrientation, featureSpeed, featureColor, featureOverlay, featureTimeout, featurePages, featureDisable */ - void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, int val, QString text, QImage* img, QColor* color) { if (dev == Q_NULLPTR || !dev->connected || dev->disabled || !dev->handle) @@ -1281,15 +1248,27 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, int val, } break; case RC28: + data.resize(3); + memset(data.data(),0x0,data.size()); switch (feature) { case usbFeatureType::featureFirmware: data[0] = 63; data[1] = 0x02; - hid_write(dev->handle, (const unsigned char*)data.constData(), data.size()); + break; + case usbFeatureType::featureLEDControl: + data[1] = 0x01; + data[2] = 0x07; + if (text == "on") + data[2] &= ~(1UL << val); + else + data[2] |= 1UL << val; + break; default: + return; // No command break; } + res = hid_write(dev->handle, (const unsigned char*)data.constData(), data.size()); break; default: break; @@ -1299,6 +1278,11 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, int val, qInfo(logUsbControl()) << "Command" << feature << "returned" << res; } +// Don't allow fallthrough elsewhere in the file. +#if defined __GNUC__ +#pragma GCC diagnostic pop +#endif + void usbController::programDisable(USBDEVICE* dev, bool disabled) { dev->disabled = disabled; @@ -1311,7 +1295,7 @@ void usbController::programDisable(USBDEVICE* dev, bool disabled) sendRequest(dev,usbFeatureType::featureOverlay,60,"Goodbye from wfview"); if (dev->type.model == RC28) { - ledControl(false, 3); + sendRequest(dev,usbFeatureType::featureLEDControl,3,"off"); } QMutexLocker locker(mutex); @@ -2080,5 +2064,4 @@ void usbController::restoreController(USBDEVICE* dev, QString file) QTimer::singleShot(250, this, SLOT(run())); // Call run to cleanup connectons after 250ms } -#pragma GCC diagnostic pop #endif diff --git a/usbcontroller.h b/usbcontroller.h index ba722c5..1d4df0a 100644 --- a/usbcontroller.h +++ b/usbcontroller.h @@ -229,7 +229,6 @@ public slots: void init(QMutex* mut,usbDevMap* prefs ,QVector