various other fixes and stability improvements

qcpfix
Phil Taylor 2023-03-26 16:08:53 +01:00
rodzic 03c45663dc
commit 6fd0d4e763
5 zmienionych plików z 153 dodań i 141 usunięć

Wyświetl plik

@ -22,7 +22,7 @@ controllerSetup::~controllerSetup()
void controllerSetup::hideEvent(QHideEvent *event)
{
qDebug(logUsbControl()) << "Controller window hiding";
qDebug(logUsbControl()) << "Controller window hideEvent()";
updateDialog->hide();
}
@ -63,6 +63,12 @@ void controllerSetup::init()
udLayout->addWidget(buttonLatch,3,1);
udLayout->setAlignment(buttonLatch,Qt::AlignRight);
buttonIcon = new QPushButton("Icon");
udLayout->addWidget(buttonIcon,4,0);
iconLabel = new QLabel("<None>");
udLayout->addWidget(iconLabel,4,1);
udLayout->setAlignment(iconLabel,Qt::AlignCenter);
udLayout->setSizeConstraint(QLayout::SetFixedSize);
updateDialog->hide();
@ -71,6 +77,7 @@ void controllerSetup::init()
connect(onEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(onEventIndexChanged(int)));
connect(knobEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(knobEventIndexChanged(int)));
connect(buttonColor, SIGNAL(clicked()), this, SLOT(buttonColorClicked()));
connect(buttonIcon, SIGNAL(clicked()), this, SLOT(buttonIconClicked()));
connect(buttonLatch, SIGNAL(stateChanged(int)), this, SLOT(latchStateChanged(int)));
}
@ -81,87 +88,90 @@ void controllerSetup::mousePressed(controllerScene* scene, QPoint p)
// Receive mouse event from the scene
qDebug() << "Looking for knob or button at Point x=" << p.x() << " y=" << p.y();
bool found = false;
QPoint gp = this->mapToGlobal(p);
for (auto b = buttons->begin(); b != buttons->end(); b++)
// Did the user click on a button?
auto b = std::find_if(buttons->begin(), buttons->end(), [p, this](BUTTON& b)
{ return (b.parent != Q_NULLPTR && b.pos.contains(p) && b.page == b.parent->currentPage && ui->tabWidget->currentWidget()->objectName() == b.path ); });
if (b != buttons->end())
{
if (b->parent != Q_NULLPTR && b->parent != Q_NULLPTR && b->pos.contains(p) && b->page == b->parent->currentPage && ui->tabWidget->currentWidget()->objectName() == b->path)
{
found = true;
currentButton = b;
qDebug() << "Button" << currentButton->num << "On Event" << currentButton->onCommand->text << "Off Event" << currentButton->offCommand->text;
currentButton = b;
currentKnob = Q_NULLPTR;
qDebug() << "Button" << currentButton->num << "On Event" << currentButton->onCommand->text << "Off Event" << currentButton->offCommand->text;
updateDialog->setWindowTitle(QString("Update button %0").arg(b->num));
updateDialog->setWindowTitle(QString("Update button %0").arg(b->num));
onEvent->blockSignals(true);
onEvent->setCurrentIndex(onEvent->findData(currentButton->onCommand->index));
onEvent->show();
onLabel->show();
onEvent->blockSignals(false);
onEvent->blockSignals(true);
onEvent->setCurrentIndex(onEvent->findData(currentButton->onCommand->index));
onEvent->show();
onLabel->show();
onEvent->blockSignals(false);
offEvent->blockSignals(true);
offEvent->setCurrentIndex(offEvent->findData(currentButton->offCommand->index));
offEvent->show();
offLabel->show();
offEvent->blockSignals(false);
knobEvent->hide();
knobLabel->hide();
offEvent->blockSignals(true);
offEvent->setCurrentIndex(offEvent->findData(currentButton->offCommand->index));
offEvent->show();
offLabel->show();
offEvent->blockSignals(false);
knobEvent->hide();
knobLabel->hide();
buttonLatch->blockSignals(true);
buttonLatch->setChecked(currentButton->toggle);
buttonLatch->blockSignals(false);
buttonLatch->blockSignals(true);
buttonLatch->setChecked(currentButton->toggle);
buttonLatch->blockSignals(false);
buttonLatch->show();
buttonColor->show();
//currentKnob = Q_NULLPTR;
break;
}
}
buttonLatch->show();
buttonColor->show();
buttonIcon->show();
iconLabel->show();
if (!found) {
for (auto k = knobs->begin(); k != knobs->end(); k++)
{
if (k->parent != Q_NULLPTR && k->pos.contains(p) && k->page == k->parent->currentPage && ui->tabWidget->currentWidget()->objectName() == k->path)
{
found = true;
currentKnob = k;
qDebug() << "Knob" << currentKnob->num << "Event" << currentKnob->command->text;
updateDialog->setWindowTitle(QString("Update knob %0").arg(k->num));
knobEvent->blockSignals(true);
knobEvent->setCurrentIndex(knobEvent->findData(currentKnob->command->index));
knobEvent->show();
knobLabel->show();
knobEvent->blockSignals(false);
onEvent->hide();
offEvent->hide();
onLabel->hide();
offLabel->hide();
buttonLatch->hide();
buttonColor->hide();
//currentButton = Q_NULLPTR;
break;
}
}
}
if(found)
{
updateDialog->show();
updateDialog->move(gp);
updateDialog->adjustSize();
updateDialog->raise();
}
else
{
updateDialog->hide();
// currentButton = Q_NULLPTR;
//currentKnob = Q_NULLPTR;
} else {
// It wasn't a button so was it a knob?
auto k = std::find_if(knobs->begin(), knobs->end(), [p, this](KNOB& k)
{ return (k.parent != Q_NULLPTR && k.pos.contains(p) && k.page == k.parent->currentPage && ui->tabWidget->currentWidget()->objectName() == k.path ); });
if (k != knobs->end())
{
currentKnob = k;
currentButton = Q_NULLPTR;
qDebug() << "Knob" << currentKnob->num << "Event" << currentKnob->command->text;
updateDialog->setWindowTitle(QString("Update knob %0").arg(k->num));
knobEvent->blockSignals(true);
knobEvent->setCurrentIndex(knobEvent->findData(currentKnob->command->index));
knobEvent->show();
knobLabel->show();
knobEvent->blockSignals(false);
onEvent->hide();
offEvent->hide();
onLabel->hide();
offLabel->hide();
buttonLatch->hide();
buttonColor->hide();
buttonIcon->hide();
iconLabel->hide();
updateDialog->show();
updateDialog->move(gp);
updateDialog->adjustSize();
updateDialog->raise();
}
else
{
// It wasn't either so hide the updateDialog();
updateDialog->hide();
currentButton = Q_NULLPTR;
currentKnob = Q_NULLPTR;
}
}
}
void controllerSetup::onEventIndexChanged(int index) {
Q_UNUSED(index);
// If command is changed, delete current command and deep copy the new command
@ -230,6 +240,19 @@ void controllerSetup::buttonColorClicked()
}
}
void controllerSetup::buttonIconClicked()
{
QString file = QFileDialog::getOpenFileName(this,"Select Icon Filename",".","Images (*png *.jpg)");
if (!file.isEmpty()) {
QFileInfo info = QFileInfo(file);
iconLabel->setText(info.fileName());
QImage image;
image.load(file);
currentButton->icon = image.scaled(currentButton->parent->type.iconSize,currentButton->parent->type.iconSize);
emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,&currentButton->icon, Q_NULLPTR);
}
}
void controllerSetup::latchStateChanged(int state)
{
if (currentButton != Q_NULLPTR) {
@ -458,9 +481,6 @@ void controllerSetup::newDevice(USBDEVICE* dev, CONTROLLER* cntrl, QVector<BUTTO
helpText->setAlignment(Qt::AlignCenter);
layout->addWidget(helpText);
onEvent->blockSignals(true);
offEvent->blockSignals(true);
knobEvent->blockSignals(true);
@ -469,20 +489,6 @@ void controllerSetup::newDevice(USBDEVICE* dev, CONTROLLER* cntrl, QVector<BUTTO
offEvent->clear();
knobEvent->clear();
/*
onEvent->setMaxVisibleItems(5);
offEvent->setMaxVisibleItems(5);
knobEvent->setMaxVisibleItems(5);
onEvent->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
offEvent->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
knobEvent->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
onEvent->setStyleSheet("combobox-popup: 0;");
offEvent->setStyleSheet("combobox-popup: 0;");
knobEvent->setStyleSheet("combobox-popup: 0;");
*/
for (COMMAND& c : *commands) {
if (c.cmdType == commandButton || c.text == "None") {
onEvent->addItem(c.text, c.index);
@ -498,10 +504,6 @@ void controllerSetup::newDevice(USBDEVICE* dev, CONTROLLER* cntrl, QVector<BUTTO
offEvent->blockSignals(false);
knobEvent->blockSignals(false);
onEvent->hide();
offEvent->hide();
knobEvent->hide();
locker.unlock();
pageChanged(dev,1);
locker.relock();
@ -587,6 +589,8 @@ void controllerSetup::pageChanged(USBDEVICE* dev, int val)
if (val < 1)
val = dev->pages;
updateDialog->hide(); // Hide the dialog if the page changes.
QMutexLocker locker(mutex);
int lastPage = dev->currentPage;

Wyświetl plik

@ -19,6 +19,7 @@
#include <QPushButton>
#include <QScopedPointer>
#include <QCheckBox>
#include <QFileDialog>
#include <QDebug>
#include <QObject>
@ -83,6 +84,7 @@ public slots:
void speedChanged(USBDEVICE* dev, int index);
void colorPicker(USBDEVICE* dev);
void buttonColorClicked();
void buttonIconClicked();
void latchStateChanged(int state);
void timeoutChanged(USBDEVICE* dev, int val);
@ -118,6 +120,8 @@ private:
QLabel* knobLabel;
QPushButton* buttonColor;
QCheckBox *buttonLatch;
QPushButton* buttonIcon;
QLabel* iconLabel;
QString deviceName;
QMutex* mutex;

Wyświetl plik

@ -328,9 +328,9 @@ void usbController::run()
if (dev.handle)
{
qInfo(logUsbControl()) << QString("Connected to device: %0 from %1 S/N %2").arg(dev.product).arg(dev.manufacturer).arg(dev.serial);
hid_set_nonblocking(dev.handle, 1);
devicesConnected++;
dev.connected=true;
hid_set_nonblocking(dev.handle, 1);
locker.unlock(); // Unlock the mutex so other devices can use it
@ -656,7 +656,6 @@ void usbController::runTimer()
}
}
qInfo(logUsbControl()) << "DATA:" << data;
}
// Step through all buttons and emit ones that have been pressed.
@ -668,7 +667,7 @@ void usbController::runTimer()
for (unsigned char i = 0; i <dev.type.buttons; i++)
{
auto but = std::find_if(buttonList->begin(), buttonList->end(), [dev, i](const BUTTON& b)
{ return (b.path == dev.path && b.num == i); });
{ return (b.path == dev.path && b.page == dev.currentPage && b.num == i); });
if (but != buttonList->end()) {
if ((!but->isOn) && ((tempButtons >> i & 1) && !(dev.buttons >> i & 1)))
{
@ -755,7 +754,7 @@ void usbController::runTimer()
for (unsigned char i = 0; i < dev.knobValues.size(); i++)
{
auto kb = std::find_if(knobList->begin(), knobList->end(), [dev, i](const KNOB& k)
{ return (k.command && k.path == dev.path && k.num == i && dev.knobValues[i] != dev.knobPrevious[i]); });
{ return (k.command && k.path == dev.path && k.page == dev.currentPage && k.num == i && dev.knobValues[i] != dev.knobPrevious[i]); });
if (kb != knobList->end()) {
// sendCommand mustn't be deleted so we ensure it stays in-scope by declaring it private.
@ -865,14 +864,15 @@ void usbController::ledControl(bool on, unsigned char num)
void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 val, QString text, QImage* img, QColor* color)
{
if (!dev->connected)
if (dev == Q_NULLPTR || !dev->connected || dev->disabled || !dev->handle)
return;
QMutexLocker locker(mutex);
QByteArray data(64, 0x0);
QByteArray data2;
int res=0;
bool sdv1=false;
switch (dev->type.model)
{
case QuickKeys:
@ -975,36 +975,8 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 v
case StreamDeckMini:
case StreamDeckMiniV2:
data.resize(17);
switch (feature)
{
case usbFeatureType::featureFirmware:
data[0] = 0x04;
hid_get_feature_report(dev->handle,(unsigned char*)data.data(),(size_t)data.size());
qInfo(logUsbControl()) << QString("%0: Firmware = %1").arg(dev->product).arg(QString::fromLatin1(data.mid(5,8)));
break;
case usbFeatureType::featureSerial:
data[0] = 0x03;
hid_get_feature_report(dev->handle,(unsigned char*)data.data(),(size_t)data.size());
qInfo(logUsbControl()) << QString("%0: Firmware = %1").arg(dev->product).arg(QString::fromLatin1(data.mid(2,12)));
break;
case usbFeatureType::featureReset:
data[0] = (qint8)0x0b;
data[1] = (qint8)0x63;
hid_send_feature_report(dev->handle, (const unsigned char*)data.constData(), data.size());
case usbFeatureType::featureBrightness:
data[0] = (qint8)0x05;
data[1] = (qint8)0x55;
data[2] = (qint8)0xaa;
data[3] = (qint8)0xd1;
data[4] = (qint8)0x01;
data[5] = val*25;
hid_send_feature_report(dev->handle, (const unsigned char*)data.constData(), data.size());
break;
default:
break;
}
break;
sdv1=true;
// Allow pass through.
// Below are StreamDeck Generation 2 h/w
case StreamDeckOriginalMK2:
case StreamDeckOriginalV2:
@ -1016,18 +988,31 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 v
switch (feature)
{
case usbFeatureType::featureFirmware:
data[0] = 0x05;
if (sdv1) {
data[0] = 0x04;
} else {
data[0] = 0x05;
}
hid_get_feature_report(dev->handle,(unsigned char*)data.data(),(size_t)data.size());
qInfo(logUsbControl()) << QString("%0: Firmware = %1").arg(dev->product).arg(QString::fromLatin1(data.mid(2,12)));
break;
case usbFeatureType::featureSerial:
data[0] = 0x06;
if (sdv1) {
data[0] = 0x03;
} else {
data[0] = 0x06;
}
hid_get_feature_report(dev->handle,(unsigned char*)data.data(),(size_t)data.size());
qInfo(logUsbControl()) << QString("%0: Serial Number = %1").arg(dev->product).arg(QString::fromLatin1(data.mid(5,8)));
break;
case usbFeatureType::featureReset:
data[0] = (qint8)0x03;
data[1] = (qint8)0x02;
if (sdv1) {
data[0] = (qint8)0x0b;
data[1] = (qint8)0x63;
} else {
data[0] = (qint8)0x03;
data[1] = (qint8)0x02;
}
hid_send_feature_report(dev->handle, (const unsigned char*)data.constData(), data.size());
break;
case usbFeatureType::featureResetKeys:
@ -1037,9 +1022,18 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 v
res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
break;
case usbFeatureType::featureBrightness:
data[0] = (qint8)0x03;
data[1] = (qint8)0x08;
data[2] = val*25; // Stream Deck brightness is in %
if (sdv1) {
data[0] = (qint8)0x05;
data[1] = (qint8)0x55;
data[2] = (qint8)0xaa;
data[3] = (qint8)0xd1;
data[4] = (qint8)0x01;
data[5] = val*25;
} else {
data[0] = (qint8)0x03;
data[1] = (qint8)0x08;
data[2] = val*25; // Stream Deck brightness is in %
}
res = hid_send_feature_report(dev->handle, (const unsigned char*)data.constData(), data.size());
break;
case usbFeatureType::featureColor:
@ -1068,6 +1062,7 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 v
{
if (img != Q_NULLPTR)
{
*img = img->scaled(800,100);
data2.clear();
QBuffer buffer(&data2);
img->save(&buffer, "JPG");
@ -1106,14 +1101,21 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 v
case usbFeatureType::featureButton: {
if (val < 8) {
QImage butImage(dev->type.iconSize,dev->type.iconSize, QImage::Format_RGB888);
QPainter butPaint(&butImage);
butPaint.setFont(QFont("times",16));
if (color == Q_NULLPTR)
butPaint.fillRect(butImage.rect(), (*controllers)[dev->path].color);
if (img != Q_NULLPTR)
{
butImage = *img;
}
else
butPaint.fillRect(butImage.rect(), *color);
{
QPainter butPaint(&butImage);
butPaint.setFont(QFont("times",16));
if (color == Q_NULLPTR)
butPaint.fillRect(butImage.rect(), (*controllers)[dev->path].color);
else
butPaint.fillRect(butImage.rect(), *color);
butPaint.drawText(butImage.rect(),Qt::AlignCenter | Qt::AlignVCenter, text);
butPaint.drawText(butImage.rect(),Qt::AlignCenter | Qt::AlignVCenter, text);
}
QBuffer butBuffer(&data2);
butImage.save(&butBuffer, "JPG");
//butImage.save("test.jpg");

Wyświetl plik

@ -161,6 +161,7 @@ struct BUTTON {
QString off;
QString path;
QColor background = Qt::white;
QImage icon;
bool toggle = false;
bool isOn = false;
};
@ -198,7 +199,7 @@ struct CONTROLLER {
QColor color=Qt::white;
int pages=1;
cmds lcd=cmdNone;
USBDEVICE* dev;
USBDEVICE* dev = Q_NULLPTR;
};

Wyświetl plik

@ -5258,18 +5258,19 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e
wf->xAxis->setRange(0, spectWidth-1);
wf->replot();
// Send to USB Controllers if requested
usbMap::const_iterator i = usbControllers.constBegin();
while (i != usbControllers.constEnd())
{
if (i.value().dev != Q_NULLPTR && i.value().lcd == cmdLCDWaterfall )
if (i.value().dev != Q_NULLPTR && i.value().dev->connected && i.value().lcd == cmdLCDWaterfall )
{
lcdImage = wf->toPixmap(800,100,1.0).toImage();
lcdImage = plot->toPixmap().toImage();
emit sendControllerRequest(i.value().dev, usbFeatureType::featureLCD, 0, "", &lcdImage);
}
else if (i.value().dev != Q_NULLPTR && i.value().lcd == cmdLCDSpectrum)
else if (i.value().dev != Q_NULLPTR && i.value().dev->connected && i.value().lcd == cmdLCDSpectrum)
{
lcdImage = plot->toPixmap(800,100,1.0).toImage();
lcdImage = plot->toPixmap().toImage();
emit sendControllerRequest(i.value().dev, usbFeatureType::featureLCD, 0, "", &lcdImage);
}
++i;