Browse Source

chatgui: latch radio PTT on double click and release on next press

master
evgeny 4 days ago
parent
commit
37485820b5
  1. 47
      tools/chatgui/src/radiopanel.cpp
  2. 4
      tools/chatgui/src/radiopanel.h

47
tools/chatgui/src/radiopanel.cpp

@ -16,6 +16,7 @@ extern "C" {
#include <QActionGroup>
#include <QSignalBlocker>
#include <QStyle>
#include <QMouseEvent>
#include <cstring>
RadioPanel::RadioPanel(QWidget* parent) : QWidget(parent) {
@ -52,13 +53,18 @@ RadioPanel::RadioPanel(QWidget* parent) : QWidget(parent) {
m_ptt = new QPushButton(QStringLiteral("PTT"), this);
m_ptt->setObjectName(QStringLiteral("radioPttButton"));
m_ptt->setAccessibleName(QCoreApplication::translate("ChatGui", "Hold to talk"));
m_ptt->setToolTip(QCoreApplication::translate("ChatGui", "Hold the button or a global shortcut to transmit"));
m_ptt->installEventFilter(this);
m_ptt->setFixedSize(64, 34);
m_ptt->setStyleSheet("QPushButton[transmitting=\"true\"] { background: #27ae60; color: white; }");
row->addWidget(m_ptt);
auto* engine = RadioAudioEngine::instance();
connect(m_ptt, &QPushButton::pressed, engine, &RadioAudioEngine::talkBegin);
connect(m_ptt, &QPushButton::released, engine, &RadioAudioEngine::talkEnd);
connect(m_ptt, &QPushButton::pressed, this, [this, engine]() {
if (m_pttLatched) setPttLatched(false, "button-pressed");
else engine->talkBegin();
});
connect(m_ptt, &QPushButton::released, this, [this, engine]() {
if (!m_pttLatched) engine->talkEnd();
});
connect(m_vad, &QPushButton::clicked, this, [this](bool checked) {
RadioAudioEngine::instance()->applySettings({{QStringLiteral("radio_vad_enabled"), checked ? 1 : 0}});
updateState();
@ -69,12 +75,47 @@ RadioPanel::RadioPanel(QWidget* parent) : QWidget(parent) {
updateDevices();
}
RadioPanel::~RadioPanel() {
if (m_pttLatched) setPttLatched(false, "panel-destroyed");
}
/* Второе нажатие Qt приходит как DoubleClick: не отдаём его обычному переключателю pressed. */
bool RadioPanel::eventFilter(QObject* watched, QEvent* event) {
if (watched == m_ptt && event->type() == QEvent::MouseButtonDblClick && m_ptt->isEnabled()) {
auto* mouse = static_cast<QMouseEvent*>(event);
if (mouse->button() == Qt::LeftButton && m_ptt->rect().contains(mouse->pos())) {
setPttLatched(true, "double-click");
return true;
}
}
return QWidget::eventFilter(watched, event);
}
/* Фиксация владеет только кнопочным PTT; хоткей и автоматическая передача остаются независимыми. */
void RadioPanel::setPttLatched(bool latched, const char* reason) {
if (m_pttLatched == latched) return;
m_pttLatched = latched;
auto* engine = RadioAudioEngine::instance();
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "RadioPanel: PTT %s group=%016llx reason=%s",
latched ? "latched (click to release)" : "latch released", (unsigned long long)engine->groupId(), reason);
if (latched) engine->talkBegin();
else engine->talkEnd();
updateState();
}
void RadioPanel::updateState() {
auto* engine = RadioAudioEngine::instance();
if (m_pttLatched && (!engine->isActive() || !engine->captureAvailable()))
setPttLatched(false, engine->isActive() ? "microphone-unavailable" : "radio-stopped");
QSignalBlocker blocker(m_vad);
m_vad->setChecked(engine->vadEnabled());
m_vad->setEnabled(engine->isActive() && engine->settingsReady() && !engine->settingsBusy());
m_ptt->setEnabled(engine->isActive() && engine->captureAvailable());
m_ptt->setText(m_pttLatched ? QStringLiteral("PTT \U0001F512") : QStringLiteral("PTT"));
m_ptt->setToolTip(m_pttLatched ? QCoreApplication::translate("ChatGui", "PTT locked. Click to release.")
: QCoreApplication::translate("ChatGui", "Hold to talk, or double-click to lock PTT. Click again to release. Global shortcuts also work."));
m_ptt->setAccessibleName(m_pttLatched ? QCoreApplication::translate("ChatGui", "PTT locked. Click to release.")
: QCoreApplication::translate("ChatGui", "Hold to talk"));
bool transmitting = engine->isTransmitting();
if (m_ptt->property("transmitting").toBool() != transmitting || !m_ptt->property("transmitting").isValid()) {
m_ptt->setProperty("transmitting", transmitting);

4
tools/chatgui/src/radiopanel.h

@ -12,7 +12,10 @@ class RadioPanel : public QWidget {
Q_OBJECT
public:
explicit RadioPanel(QWidget* parent = nullptr);
~RadioPanel() override;
private:
bool eventFilter(QObject* watched, QEvent* event) override;
void setPttLatched(bool latched, const char* reason);
void updateState();
void updateDevices();
void populateDevices(QToolButton* button, bool capture);
@ -20,4 +23,5 @@ private:
QToolButton *m_input, *m_output;
QPushButton *m_vad, *m_ptt;
QLabel* m_status;
bool m_pttLatched = false;
};

Loading…
Cancel
Save