Implement ganged switches
This commit is contained in:
parent
7a6e674756
commit
81e7e1a5b3
|
@ -1,3 +1,4 @@
|
|||
|
||||
#include "channelwidget.h"
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
@ -26,13 +27,17 @@ ChannelWidget::ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber,
|
|||
line.setFrameShadow(QFrame::Sunken);
|
||||
vlayout.addWidget(&line);
|
||||
|
||||
// Add Unganged option first
|
||||
gangcombo.addItem("Unganged");
|
||||
|
||||
hlayout.addStretch();
|
||||
hlayout.addWidget(&ganglabel);
|
||||
hlayout.addWidget(&gangcombo);
|
||||
hlayout.addWidget(&checkbox);
|
||||
|
||||
// Connect signals
|
||||
connect(&checkbox, &QCheckBox::toggled, this, &ChannelWidget::onChannelToggled);
|
||||
connect(&gangcombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ChannelWidget::onGangComboChanged);
|
||||
|
||||
setFixedHeight(96);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
@ -93,5 +98,74 @@ void ChannelWidget::onChannelToggled(bool checked)
|
|||
setEnabled(false); // Gray out the widget
|
||||
}
|
||||
}
|
||||
|
||||
// Emit state change signal for other channels that might be ganged to this one
|
||||
emit channelStateChanged(deviceSerial, channelNumber, checked);
|
||||
}
|
||||
|
||||
void ChannelWidget::onGangComboChanged(int index)
|
||||
{
|
||||
if (index == 0) {
|
||||
// Unganged selected - reset ganged channel tracking
|
||||
gangedDeviceSerial = 0;
|
||||
gangedChannelNumber = 0;
|
||||
checkbox.setEnabled(true);
|
||||
checkbox.setChecked(false);
|
||||
checkbox.setChecked(false); // Reset to false to avoid leaving it checked when unganged
|
||||
} else {
|
||||
// A ganged channel was selected
|
||||
QString currentText = gangcombo.currentText();
|
||||
QStringList parts = currentText.split(", ");
|
||||
if (parts.size() == 2) {
|
||||
bool ok1, ok2;
|
||||
uint16_t gangedSerial = parts[0].toUInt(&ok1);
|
||||
uint16_t gangedChannel = parts[1].toUInt(&ok2);
|
||||
|
||||
if (ok1 && ok2) {
|
||||
setGangedChannel(gangedSerial, gangedChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelWidget::onOtherChannelStateChanged(uint16_t deviceSerial, uint16_t channelNumber, bool checked)
|
||||
{
|
||||
// If this channel is ganged to the channel that changed state
|
||||
if (gangedDeviceSerial == deviceSerial && gangedChannelNumber == channelNumber) {
|
||||
// Update our checkbox state to follow the ganged channel
|
||||
checkbox.blockSignals(true);
|
||||
checkbox.setChecked(checked);
|
||||
checkbox.blockSignals(false);
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelWidget::updateGangCombo()
|
||||
{
|
||||
// Clear existing items except "Unganged"
|
||||
while (gangcombo.count() > 1) {
|
||||
gangcombo.removeItem(1);
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelWidget::updateCheckboxState()
|
||||
{
|
||||
// If we're ganged, update our state to match the ganged channel
|
||||
if (gangedDeviceSerial != 0 && gangedChannelNumber != 0) {
|
||||
checkbox.setEnabled(false);
|
||||
// We need to check the state of the ganged channel and sync
|
||||
// This would typically be done by querying the actual channel state
|
||||
// but for now we'll assume the ganged channel's state is known
|
||||
} else {
|
||||
checkbox.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelWidget::setGangedChannel(uint16_t gangedDeviceSerial, uint16_t gangedChannelNumber)
|
||||
{
|
||||
this->gangedDeviceSerial = gangedDeviceSerial;
|
||||
this->gangedChannelNumber = gangedChannelNumber;
|
||||
|
||||
// Update checkbox state to follow the ganged channel
|
||||
updateCheckboxState();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
#ifndef CHANNELWIDGET_H
|
||||
#define CHANNELWIDGET_H
|
||||
|
||||
|
@ -23,13 +25,25 @@ public:
|
|||
uint16_t getChannelNumber() const;
|
||||
bool isChecked() const;
|
||||
|
||||
signals:
|
||||
void channelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber);
|
||||
// Accessors for MainWindow to populate and access the gang combo
|
||||
QComboBox* getGangCombo() { return &gangcombo; }
|
||||
void setGangedChannel(uint16_t deviceSerial, uint16_t channelNumber);
|
||||
|
||||
public slots:
|
||||
void onOtherChannelStateChanged(uint16_t deviceSerial, uint16_t channelNumber, bool checked);
|
||||
|
||||
private slots:
|
||||
void onChannelToggled(bool checked);
|
||||
void onGangComboChanged(int index);
|
||||
|
||||
signals:
|
||||
void channelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber);
|
||||
void channelStateChanged(uint16_t deviceSerial, uint16_t channelNumber, bool checked);
|
||||
|
||||
private:
|
||||
void updateGangCombo();
|
||||
void updateCheckboxState();
|
||||
|
||||
uint16_t deviceSerial;
|
||||
uint16_t channelNumber;
|
||||
std::shared_ptr<struct eismultiplexer> multiplexer;
|
||||
|
@ -42,8 +56,11 @@ private:
|
|||
QVBoxLayout vlayout;
|
||||
QHBoxLayout hlayout;
|
||||
QVBoxLayout labellayout;
|
||||
|
||||
// Track the channel this one is ganged to (if any)
|
||||
uint16_t gangedDeviceSerial = 0;
|
||||
uint16_t gangedChannelNumber = 0;
|
||||
};
|
||||
|
||||
#endif // CHANNELWIDGET_H
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
|
||||
|
||||
#include <eismultiplexer.h>
|
||||
#include <QMessageBox>
|
||||
#include "mainwindow.h"
|
||||
|
@ -35,6 +37,7 @@ void MainWindow::enumerateDevices()
|
|||
return;
|
||||
}
|
||||
|
||||
// First pass: create all widgets without connecting signals
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
uint16_t serial = serials[i];
|
||||
|
@ -61,9 +64,33 @@ void MainWindow::enumerateDevices()
|
|||
tr("Failed to connect to device with serial %1").arg(serial));
|
||||
qWarning()<<"Failed to connect to device with serial"<<serial<<"eismultiplexer_connect returned"<<ret;
|
||||
}
|
||||
ui->channelLayout->addStretch();
|
||||
}
|
||||
ui->channelLayout->addStretch();
|
||||
|
||||
// Second pass: populate gang combos and connect signals
|
||||
for (const auto& widget : channels) {
|
||||
// Populate gang combo with all other channels
|
||||
for (const auto& otherWidget : channels) {
|
||||
if (widget->getDeviceSerial() != otherWidget->getDeviceSerial() ||
|
||||
widget->getChannelNumber() != otherWidget->getChannelNumber()) {
|
||||
QString channelText = QString::asprintf("%04u, %u",
|
||||
otherWidget->getDeviceSerial(),
|
||||
otherWidget->getChannelNumber());
|
||||
widget->getGangCombo()->addItem(channelText);
|
||||
}
|
||||
}
|
||||
|
||||
// Connect state change signals
|
||||
for (const auto& otherWidget : channels) {
|
||||
if (widget.get() != otherWidget.get()) {
|
||||
connect(otherWidget.get(), &ChannelWidget::channelStateChanged,
|
||||
widget.get(), &ChannelWidget::onOtherChannelStateChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui->statusbar->showMessage("Ready");
|
||||
|
||||
free(serials);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue