Allow storing of icons and various other fixes

qcpfix
Phil Taylor 2023-03-26 23:23:40 +01:00
rodzic 6fd0d4e763
commit 75288b5e78
6 zmienionych plików z 190 dodań i 106 usunięć

Wyświetl plik

@ -55,13 +55,18 @@ void controllerSetup::init()
udLayout->addWidget(knobEvent,2,1);
knobLabel->setBuddy(knobEvent);
buttonColor = new QPushButton("Color");
udLayout->addWidget(buttonColor,3,0);
buttonLatch = new QCheckBox();
buttonLatch->setText("Toggle");
udLayout->addWidget(buttonLatch,3,1);
udLayout->setAlignment(buttonLatch,Qt::AlignRight);
udLayout->addWidget(buttonLatch,3,0);
QHBoxLayout* colorLayout = new QHBoxLayout();
udLayout->addLayout(colorLayout,3,1);
buttonOnColor = new QPushButton("Color");
colorLayout->addWidget(buttonOnColor);
buttonOffColor = new QPushButton("Pressed");
colorLayout->addWidget(buttonOffColor);
buttonIcon = new QPushButton("Icon");
udLayout->addWidget(buttonIcon,4,0);
@ -76,7 +81,8 @@ void controllerSetup::init()
connect(offEvent, SIGNAL(currentIndexChanged(int)), this, SLOT(offEventIndexChanged(int)));
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(buttonOnColor, SIGNAL(clicked()), this, SLOT(buttonOnColorClicked()));
connect(buttonOffColor, SIGNAL(clicked()), this, SLOT(buttonOffColorClicked()));
connect(buttonIcon, SIGNAL(clicked()), this, SLOT(buttonIconClicked()));
connect(buttonLatch, SIGNAL(stateChanged(int)), this, SLOT(latchStateChanged(int)));
@ -121,7 +127,8 @@ void controllerSetup::mousePressed(controllerScene* scene, QPoint p)
buttonLatch->blockSignals(false);
buttonLatch->show();
buttonColor->show();
buttonOnColor->show();
buttonOffColor->show();
buttonIcon->show();
iconLabel->show();
@ -152,7 +159,8 @@ void controllerSetup::mousePressed(controllerScene* scene, QPoint p)
onLabel->hide();
offLabel->hide();
buttonLatch->hide();
buttonColor->hide();
buttonOnColor->hide();
buttonOffColor->hide();
buttonIcon->hide();
iconLabel->hide();
@ -184,7 +192,7 @@ void controllerSetup::onEventIndexChanged(int index) {
currentButton->onText->setPos(currentButton->pos.center().x() - currentButton->onText->boundingRect().width() / 2,
(currentButton->pos.center().y() - currentButton->onText->boundingRect().height() / 2)-6);
// Signal that any button programming on the device should be completed.
emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text);
emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,Q_NULLPTR,&currentButton->backgroundOn);
}
}
@ -221,22 +229,32 @@ void controllerSetup::knobEventIndexChanged(int index) {
}
void controllerSetup::buttonColorClicked()
void controllerSetup::buttonOnColorClicked()
{
QColorDialog::ColorDialogOptions options;
options.setFlag(QColorDialog::ShowAlphaChannel, false);
options.setFlag(QColorDialog::DontUseNativeDialog, false);
QColor selColor = QColorDialog::getColor(initialColor, this, "Select Color", options);
QColor selColor = QColorDialog::getColor(currentButton->backgroundOn, this, "Select Color to use for unpressed button", options);
if(!selColor.isValid())
if(selColor.isValid() && currentButton != Q_NULLPTR)
{
return;
}
if (currentButton != Q_NULLPTR) {
QMutexLocker locker(mutex);
currentButton->background = selColor;
emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,Q_NULLPTR,&currentButton->background);
currentButton->backgroundOn = selColor;
emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,currentButton->icon,&currentButton->backgroundOn);
}
}
void controllerSetup::buttonOffColorClicked()
{
QColorDialog::ColorDialogOptions options;
options.setFlag(QColorDialog::ShowAlphaChannel, false);
options.setFlag(QColorDialog::DontUseNativeDialog, false);
QColor selColor = QColorDialog::getColor(currentButton->backgroundOff, this, "Select Color to use for pressed button", options);
if(selColor.isValid() && currentButton != Q_NULLPTR)
{
QMutexLocker locker(mutex);
currentButton->backgroundOff = selColor;
}
}
@ -248,8 +266,10 @@ void controllerSetup::buttonIconClicked()
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);
if (currentButton->icon != Q_NULLPTR)
delete currentButton->icon;
currentButton->icon = new QImage(image.scaled(currentButton->parent->type.iconSize,currentButton->parent->type.iconSize));
emit sendRequest(currentButton->parent,usbFeatureType::featureButton,currentButton->num,currentButton->onCommand->text,currentButton->icon, &currentButton->backgroundOn);
}
}
@ -622,7 +642,7 @@ void controllerSetup::pageChanged(USBDEVICE* dev, int val)
dev->scene->addItem(b->onText);
b->onText->setPos(b->pos.center().x() - b->onText->boundingRect().width() / 2,
(b->pos.center().y() - b->onText->boundingRect().height() / 2) - 6);
emit sendRequest(dev,usbFeatureType::featureButton,b->num,b->onCommand->text,Q_NULLPTR,&b->background);
emit sendRequest(dev,usbFeatureType::featureButton,b->num,b->onCommand->text,b->icon,&b->backgroundOn);
b->offText = new QGraphicsTextItem(b->offCommand->text);
b->offText->setDefaultTextColor(b->textColour);

Wyświetl plik

@ -83,7 +83,8 @@ public slots:
void orientationChanged(USBDEVICE* dev, int index);
void speedChanged(USBDEVICE* dev, int index);
void colorPicker(USBDEVICE* dev);
void buttonColorClicked();
void buttonOnColorClicked();
void buttonOffColorClicked();
void buttonIconClicked();
void latchStateChanged(int state);
@ -118,7 +119,8 @@ private:
QLabel* onLabel;
QLabel* offLabel;
QLabel* knobLabel;
QPushButton* buttonColor;
QPushButton* buttonOnColor;
QPushButton* buttonOffColor;
QCheckBox *buttonLatch;
QPushButton* buttonIcon;
QLabel* iconLabel;

Wyświetl plik

@ -412,6 +412,19 @@ typedef union streamdeck_image_header {
char packet[8];
} *streamdeck_image_header_t;
typedef union streamdeck_v1_image_header {
struct
{
quint8 cmd;
quint8 suffix;
quint16 index;
quint8 isLast;
quint8 button;
quint8 unused[10];
};
char packet[16];
} *streamdeck_v1_image_header_t;
typedef union streamdeck_lcd_header {
struct
{

Wyświetl plik

@ -686,7 +686,7 @@ void usbController::runTimer()
// Change the button text to reflect the off Button
if (but->offCommand->index != 0) {
locker.unlock();
sendRequest(&dev,usbFeatureType::featureButton,i,but->offCommand->text,Q_NULLPTR,&but->background);
sendRequest(&dev,usbFeatureType::featureButton,i,but->offCommand->text,but->icon,&but->backgroundOff);
locker.relock();
}
but->isOn=true;
@ -706,7 +706,7 @@ void usbController::runTimer()
emit button(but->offCommand);
}
locker.unlock();
sendRequest(&dev,usbFeatureType::featureButton,i,but->onCommand->text,Q_NULLPTR,&but->background);
sendRequest(&dev,usbFeatureType::featureButton,i,but->onCommand->text,but->icon,&but->backgroundOn);
locker.relock();
but->isOn=false;
}
@ -723,7 +723,7 @@ void usbController::runTimer()
}
// Change the button text to reflect the on Button
locker.unlock();
sendRequest(&dev,usbFeatureType::featureButton,i,but->onCommand->text,Q_NULLPTR,&but->background);
sendRequest(&dev,usbFeatureType::featureButton,i,but->onCommand->text,but->icon,&but->backgroundOn);
locker.relock();
but->isOn=false;
}
@ -757,7 +757,7 @@ void usbController::runTimer()
{ 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.
// sendCommand mustn't be deleted so we ensure it stays in-scope by declaring it private (we will only ever send one command).
sendCommand = *kb->command;
if (sendCommand.command != cmdSetFreq) {
int tempVal = dev.knobValues[i] * dev.sensitivity;
@ -1044,89 +1044,45 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 v
break;
case usbFeatureType::featureOverlay:
{
QImage image(800,100, QImage::Format_RGB888);
QPainter paint(&image);
if (val) {
paint.setFont(QFont("times",16));
paint.fillRect(image.rect(), (*controllers)[dev->path].color);
paint.drawText(image.rect(),Qt::AlignCenter | Qt::AlignVCenter, text);
QTimer::singleShot(val*1000, this, [=]() { sendRequest(dev,usbFeatureType::featureOverlay); });
} else {
paint.fillRect(image.rect(), (*controllers)[dev->path].color);
if (dev->type.model == usbDeviceType::StreamDeckPlus)
{
QImage image(800,100, QImage::Format_RGB888);
QPainter paint(&image);
if (val) {
paint.setFont(QFont("times",16));
paint.fillRect(image.rect(), (*controllers)[dev->path].color);
paint.drawText(image.rect(),Qt::AlignCenter | Qt::AlignVCenter, text);
QTimer::singleShot(val*1000, this, [=]() { sendRequest(dev,usbFeatureType::featureOverlay); });
} else {
paint.fillRect(image.rect(), (*controllers)[dev->path].color);
}
QBuffer buffer(&data2);
image.save(&buffer, "JPG");
}
QBuffer buffer(&data2);
image.save(&buffer, "JPG");
// Fall through
}
case usbFeatureType::featureLCD:
{
if (img != Q_NULLPTR)
if (dev->type.model == usbDeviceType::StreamDeckPlus)
{
*img = img->scaled(800,100);
data2.clear();
QBuffer buffer(&data2);
img->save(&buffer, "JPG");
}
quint32 rem = data2.size();
quint16 index = 0;
streamdeck_lcd_header h;
memset(h.packet, 0x0, sizeof(h)); // We can't be sure it is initialized with 0x00!
h.cmd = 0x02;
h.suffix = 0x0c;
h.x=0;
h.y=0;
h.width=800;
h.height=100;
while (rem > 0)
{
quint16 length = qMin(rem,dev->type.maxPayload-sizeof(h));
data.clear();
h.isLast = (quint8)(rem <= dev->type.maxPayload-sizeof(h) ? 1 : 0); // isLast ? 1 : 0,3
h.length = length;
h.index = index;
rem -= length;
data.append(QByteArray::fromRawData((const char*)h.packet,sizeof(h)));
data.append(data2.mid(0,length));
data.resize(dev->type.maxPayload);
memset(data.data()+length+sizeof(h),0x0,data.size()-(length+sizeof(h)));
res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
//qInfo(logUsbControl()) << "Sending" << (((quint8)data[7] << 8) | ((quint8)data[6] & 0xff)) << "total=" << data.size() << "payload=" << (((quint8)data[5] << 8) | ((quint8)data[4] & 0xff)) << "last" << (quint8)data[3];
data2.remove(0,length);
index++;
}
break;
}
case usbFeatureType::featureButton: {
if (val < 8) {
QImage butImage(dev->type.iconSize,dev->type.iconSize, QImage::Format_RGB888);
if (img != Q_NULLPTR)
{
butImage = *img;
QImage image = img->scaled(800,100,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
data2.clear();
QBuffer buffer(&data2);
image.save(&buffer, "JPG");
}
else
{
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);
}
QBuffer butBuffer(&data2);
butImage.save(&butBuffer, "JPG");
//butImage.save("test.jpg");
quint32 rem = data2.size();
quint16 index = 0;
streamdeck_image_header h;
streamdeck_lcd_header h;
memset(h.packet, 0x0, sizeof(h)); // We can't be sure it is initialized with 0x00!
h.cmd = 0x02;
h.suffix = 0x07;
h.button = val;
h.suffix = 0x0c;
h.x=0;
h.y=0;
h.width=800;
h.height=100;
while (rem > 0)
{
@ -1146,6 +1102,91 @@ void usbController::sendRequest(USBDEVICE *dev, usbFeatureType feature, quint8 v
index++;
}
}
break;
}
case usbFeatureType::featureButton: {
// StreamDeckPedal is the only model without oled buttons
// Plus has 12 buttons but only 8 oled
if (dev->type.model != usbDeviceType::StreamDeckPedal &&
((dev->type.model == usbDeviceType::StreamDeckPlus && val < 8) ||
(val < dev->type.buttons)))
{
if (val < 8) {
QImage butImage(dev->type.iconSize,dev->type.iconSize, QImage::Format_RGB888);
if (color != Q_NULLPTR)
butImage.fill(*color);
else
butImage.fill((*controllers)[dev->path].color);
QPainter butPaint(&butImage);
if ( img == Q_NULLPTR) {
butPaint.setFont(QFont("times",16));
butPaint.drawText(butImage.rect(),Qt::AlignCenter | Qt::AlignVCenter, text);
} else {
butPaint.setCompositionMode(QPainter::CompositionMode_SourceAtop);
butPaint.drawImage(0, 0, *img);
}
QBuffer butBuffer(&data2);
if (sdv1)
{
butImage.save(&butBuffer, "BMP");
quint32 rem = data2.size();
quint16 index = 0;
streamdeck_v1_image_header h1;
memset(h1.packet, 0x0, sizeof(h1)); // We can't be sure it is initialized with 0x00!
h1.cmd = 0x02;
h1.suffix = 0x01;
h1.button = val;
while (rem > 0)
{
quint16 length = qMin(rem,dev->type.maxPayload-sizeof(h1));
data.clear();
h1.isLast = (quint8)(rem <= dev->type.maxPayload-sizeof(h1) ? 1 : 0); // isLast ? 1 : 0,3
h1.index = index;
data.append(QByteArray::fromRawData((const char*)h1.packet,sizeof(h1)));
rem -= length;
data.append(data2.mid(0,length));
data.resize(dev->type.maxPayload);
memset(data.data()+length+sizeof(h1),0x0,data.size()-(length+sizeof(h1)));
res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
//qInfo(logUsbControl()) << "Sending" << (((quint8)data[7] << 8) | ((quint8)data[6] & 0xff)) << "total=" << data.size() << "payload=" << (((quint8)data[5] << 8) | ((quint8)data[4] & 0xff)) << "last" << (quint8)data[3];
data2.remove(0,length);
index++;
}
}
else
{
butImage.save(&butBuffer, "JPG");
quint32 rem = data2.size();
quint16 index = 0;
streamdeck_image_header h;
memset(h.packet, 0x0, sizeof(h)); // We can't be sure it is initialized with 0x00!
h.cmd = 0x02;
h.suffix = 0x07;
h.button = val;
while (rem > 0)
{
quint16 length = qMin(rem,dev->type.maxPayload-sizeof(h));
data.clear();
h.isLast = (quint8)(rem <= dev->type.maxPayload-sizeof(h) ? 1 : 0); // isLast ? 1 : 0,3
h.length = length;
h.index = index;
data.append(QByteArray::fromRawData((const char*)h.packet,sizeof(h)));
rem -= length;
data.append(data2.mid(0,length));
data.resize(dev->type.maxPayload);
memset(data.data()+length+sizeof(h),0x0,data.size()-(length+sizeof(h)));
res=hid_write(dev->handle, (const unsigned char*)data.constData(), data.size());
//qInfo(logUsbControl()) << "Sending" << (((quint8)data[7] << 8) | ((quint8)data[6] & 0xff)) << "total=" << data.size() << "payload=" << (((quint8)data[5] << 8) | ((quint8)data[4] & 0xff)) << "last" << (quint8)data[3];
data2.remove(0,length);
index++;
}
}
}
}
}
default:
break;

Wyświetl plik

@ -160,8 +160,9 @@ struct BUTTON {
QString on;
QString off;
QString path;
QColor background = Qt::white;
QImage icon;
QColor backgroundOn = Qt::lightGray;
QColor backgroundOff = Qt::blue;
QImage* icon = Q_NULLPTR;
bool toggle = false;
bool isOn = false;
};

Wyświetl plik

@ -2531,9 +2531,11 @@ void wfmain::loadSettings()
settings->value("Width", 0).toInt(),
settings->value("Height", 0).toInt());
butt.textColour.setNamedColor(settings->value("Colour", QColor(Qt::white).name(QColor::HexArgb)).toString());
butt.background.setNamedColor(settings->value("Background", QColor(Qt::white).name(QColor::HexArgb)).toString());
butt.backgroundOn.setNamedColor(settings->value("BackgroundOn", QColor(Qt::lightGray).name(QColor::HexArgb)).toString());
butt.backgroundOff.setNamedColor(settings->value("BackgroundOff", QColor(Qt::blue).name(QColor::HexArgb)).toString());
butt.toggle = settings->value("Toggle", false).toBool();
if (settings->value("Icon",NULL) != NULL)
butt.icon = new QImage(settings->value("Icon",NULL).value<QImage>());
butt.on = settings->value("OnCommand", "None").toString();
butt.off = settings->value("OffCommand", "None").toString();
if (!butt.path.isEmpty())
@ -3026,7 +3028,10 @@ void wfmain::saveSettings()
settings->setValue("Width", usbButtons[nb].pos.width());
settings->setValue("Height", usbButtons[nb].pos.height());
settings->setValue("Colour", usbButtons[nb].textColour.name(QColor::HexArgb));
settings->setValue("Background", usbButtons[nb].background.name(QColor::HexArgb));
settings->setValue("BackgroundOn", usbButtons[nb].backgroundOn.name(QColor::HexArgb));
settings->setValue("BackgroundOff", usbButtons[nb].backgroundOff.name(QColor::HexArgb));
if (usbButtons[nb].icon != Q_NULLPTR)
settings->setValue("Icon", *usbButtons[nb].icon);
settings->setValue("Toggle", usbButtons[nb].toggle);
if (usbButtons[nb].onCommand != Q_NULLPTR)
@ -5258,24 +5263,26 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e
wf->xAxis->setRange(0, spectWidth-1);
wf->replot();
#if defined (USB_CONTROLLER)
// Send to USB Controllers if requested
usbMap::const_iterator i = usbControllers.constBegin();
while (i != usbControllers.constEnd())
{
if (i.value().dev != Q_NULLPTR && i.value().dev->connected && i.value().lcd == cmdLCDWaterfall )
if (i.value().dev != Q_NULLPTR && i.value().dev->connected
&& i.value().dev->type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDWaterfall )
{
lcdImage = plot->toPixmap().toImage();
lcdImage = wf->toPixmap().toImage();
emit sendControllerRequest(i.value().dev, usbFeatureType::featureLCD, 0, "", &lcdImage);
}
else if (i.value().dev != Q_NULLPTR && i.value().dev->connected && i.value().lcd == cmdLCDSpectrum)
else if (i.value().dev != Q_NULLPTR && i.value().dev->connected
&& i.value().dev->type.model == usbDeviceType::StreamDeckPlus && i.value().lcd == cmdLCDSpectrum)
{
lcdImage = plot->toPixmap().toImage();
emit sendControllerRequest(i.value().dev, usbFeatureType::featureLCD, 0, "", &lcdImage);
}
++i;
}
#endif
}
oldPlotFloor = plotFloor;