Place radio controls above desktop chat messages
This commit is contained in:
1 parent
fa70093866
commit
d1e2220e54
2 files changed
+26
-53
No files matched your search
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
Reference in new issue
Block a user