Browse Source

Place radio controls above desktop chat messages

master
evgeny 1 day ago
parent
commit
d1e2220e54
  1. 72
      tools/chatgui/src/messagelist.cpp
  2. 7
      tools/chatgui/src/messagelist.h

72
tools/chatgui/src/messagelist.cpp

@ -49,6 +49,7 @@ void chat_core_save_ui_state_trampoline(void* arg);
}
#include "radio_audio_engine.h"
#include "radiopanel.h"
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
@ -393,6 +394,10 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
layout->addWidget(header);
}
m_radioPanel = new RadioPanel(this);
m_radioPanel->hide();
layout->addWidget(m_radioPanel);
m_view->setModel(m_model);
auto* msgDelegate = new MessageDelegate(this);
msgDelegate->setVideoOpenCallback([this](const QString& path) {
@ -424,24 +429,6 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
m_view->setBackgroundImage("../resources/bg.png");
layout->addWidget(m_view, 1);
/* ── плавающая PTT-кнопка поверх чата (видна при включённой рации) ── */
m_pttBtn = new QPushButton(QString::fromUtf8("\xF0\x9F\x8E\xA4"), this);
m_pttBtn->setFixedSize(96, 96);
m_pttBtn->setCursor(Qt::PointingHandCursor);
m_pttBtn->setToolTip(QStringLiteral("Держите и говорите"));
m_pttBtn->setStyleSheet(
"QPushButton { border: 3px solid white; border-radius: 48px; background: #e74c3c; color: white; font-size: 36px; }"
"QPushButton[transmitting=\"true\"] { background: #27ae60; }");
m_pttBtn->setProperty("transmitting", false);
m_pttBtn->hide();
connect(RadioAudioEngine::instance(), &RadioAudioEngine::talkingChanged, this, [this](bool) { updateRadioUi(); });
connect(m_pttBtn, &QPushButton::pressed, this, []() {
RadioAudioEngine::instance()->talkBegin();
});
connect(m_pttBtn, &QPushButton::released, this, []() {
RadioAudioEngine::instance()->talkEnd();
});
if (s_icons.empty()) {
for (const auto &cat : builtinEmojiSet()) {
for (const auto &e : cat.items) {
@ -1226,49 +1213,38 @@ void MessageList::onRadioToggled(bool on) {
if (groupId == 0) return;
struct radio_set_active_arg* a = (struct radio_set_active_arg*)u_malloc(sizeof(*a));
if (!a) return;
if (!a) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: active request allocation failed group=%016llx", (unsigned long long)groupId);
QSignalBlocker blocker(m_radioBtn);
m_radioBtn->setChecked(m_radioOn);
return;
}
a->inst = gui_bridge_get_inst();
a->group_id = groupId;
a->on = on ? 1 : 0;
gui_bridge_post_uasync_fn(radio_set_active_trampoline, a);
m_radioOn = on;
if (on) {
RadioAudioEngine::instance()->start(groupId);
if (RadioAudioEngine::instance()->start(groupId) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: radio start failed group=%016llx", (unsigned long long)groupId);
auto* undo = static_cast<radio_set_active_arg*>(u_calloc(1, sizeof(radio_set_active_arg)));
if (undo) {
undo->inst = gui_bridge_get_inst(); undo->group_id = groupId;
gui_bridge_post_uasync_fn(radio_set_active_trampoline, undo);
} else DEBUG_ERROR(DEBUG_CATEGORY_RADIO, "RadioPanel: cannot cancel failed radio subscription");
QSignalBlocker blocker(m_radioBtn);
m_radioBtn->setChecked(false);
return;
}
} else {
RadioAudioEngine::instance()->stop();
m_talkingLabel->hide();
}
m_radioOn = on;
updateRadioUi();
}
void MessageList::updateRadioUi() {
if (!m_pttBtn) return;
auto* audio = RadioAudioEngine::instance();
bool transmitting = audio->isTalking() && audio->groupId() == m_currentChannelId.toULongLong();
if (m_pttBtn->property("transmitting").toBool() != transmitting) {
m_pttBtn->setProperty("transmitting", transmitting);
m_pttBtn->style()->unpolish(m_pttBtn);
m_pttBtn->style()->polish(m_pttBtn);
m_pttBtn->update();
}
bool show = m_radioOn && !isDmChannel(m_currentChannelId);
m_pttBtn->setVisible(show);
if (show) {
m_pttBtn->raise();
layoutPttButton();
}
}
void MessageList::layoutPttButton() {
if (!m_pttBtn || !m_pttBtn->isVisible()) return;
int w = width();
int x = (w - m_pttBtn->width()) / 2;
int y = 48; /* под шапкой, поверх списка сообщений */
m_pttBtn->move(x, y);
}
void MessageList::resizeEvent(QResizeEvent* event) {
QWidget::resizeEvent(event);
layoutPttButton();
m_radioPanel->setVisible(show);
}

7
tools/chatgui/src/messagelist.h

@ -15,6 +15,7 @@ class ChannelList;
class AudioRecorder;
class QLabel;
class QPushButton;
class RadioPanel;
class MessageList : public QWidget {
Q_OBJECT
@ -42,9 +43,6 @@ signals:
void openVideoRequested(const QString& filePath);
void openImageRequested(const QString& filePath);
protected:
void resizeEvent(QResizeEvent* event) override;
private:
ChatView *m_view;
QStandardItemModel *m_model;
@ -66,7 +64,7 @@ private:
quint64 m_callPeer = 0;
quint64 m_callGroup = 0;
QPushButton* m_radioBtn = nullptr; /* шапка: переключатель рации */
QPushButton* m_pttBtn = nullptr; /* плавающая кнопка PTT поверх чата */
RadioPanel* m_radioPanel = nullptr; /* верхняя панель устройств, VAD и PTT */
bool m_radioOn = false;
QThreadPool m_thumbnailPool;
QSet<QString> m_thumbnailJobs;
@ -79,7 +77,6 @@ private:
void prepareVideoThumbnail(const QString& path);
void onRadioToggled(bool on);
void updateRadioUi();
void layoutPttButton();
static bool isDmChannel(const QString& channelId);
static QString dmConvId(const QString& channelId);
};

Loading…
Cancel
Save