From a0db643acbc031ac04e6263f27eef09bdfdd451f Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 15 Oct 2026 00:34:07 +0200 Subject: [PATCH] Place camera thumbnail inside remote picture and document call layout --- doc/call_video.txt | 9 +++++++++ tools/chatgui/src/callwindow.cpp | 9 ++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/doc/call_video.txt b/doc/call_video.txt index 15f85532..36798808 100644 --- a/doc/call_video.txt +++ b/doc/call_video.txt @@ -524,3 +524,12 @@ HEVC wire level 93 преобразуется делением на 3. Глоб ChatGUI пересобран; test_call_video_encoder — 10/10 PASS в каждой локали, без skipped. Логи: /tmp/call-camera-locale-test-c.log, /tmp/call-camera-locale-test-ru.log. Работающий GUI автоматически не перезапускался; проверка полного звонка после исправления остаётся. + +Desktop UI: принимаемый кадр раскрывает окно на весь экран с сохранением пропорций. +Своя камера отображается миниатюрой поверх изображения собеседника; при отсутствии +входящего видео — миниатюрой в обычном окне. Без кадров видеоплощадка не занимает места. +Esc/F11, кнопка и двойной щелчок переключают полноэкранный режим; геометрия окна сохраняется. +Настройки камеры/кодека/битрейта/звука и диагностика свёрнуты под «Настройки звонка». +Preview берётся из того же QVideoFrame, отдельная камера не открывается; обновление до 10 fps. +После 5 секунд без новых показанных RX кадров изображение скрывается: отдельного VIDEO_OFF +в протоколе пока нет. Возобновление видео снова открывает полный экран. diff --git a/tools/chatgui/src/callwindow.cpp b/tools/chatgui/src/callwindow.cpp index d6e36dcf..5006aed1 100644 --- a/tools/chatgui/src/callwindow.cpp +++ b/tools/chatgui/src/callwindow.cpp @@ -197,6 +197,7 @@ CallWindow::CallWindow(QWidget* parent) m_panel = new QWidget(this); m_panel->setObjectName("callPanel"); m_panel->setMaximumWidth(640); m_panel->setStyleSheet("QWidget#callPanel { background: palette(window); border-radius: 12px; }"); root->addWidget(m_panel, 0, Qt::AlignHCenter | Qt::AlignBottom); + root->addStretch(1); QVBoxLayout* lay = new QVBoxLayout(m_panel); lay->setContentsMargins(16, 20, 16, 16); lay->setSpacing(8); @@ -400,6 +401,7 @@ void CallWindow::updateVideoPresentation() { } else leaveFullScreen(); } bool active = m_state == Active, settings = active && m_settingsBtn->isChecked(); + static_cast(layout())->setStretch(2, receiving ? 0 : 1); m_localPreview->setVisible(active && !receiving && !m_localImage.isNull()); m_avatarLabel->setVisible(!receiving); m_statusLabel->setVisible(!receiving); m_connectionLabel->setVisible(settings); m_bgpPathLabel->setVisible(settings && !m_bgpPathLabel->text().isEmpty()); @@ -416,10 +418,11 @@ void CallWindow::paintEvent(QPaintEvent* event) { if (!m_receivingVideo) return; QPainter painter(this); painter.fillRect(rect(), Qt::black); painter.setRenderHint(QPainter::SmoothPixmapTransform); QSize remote = m_remoteImage.size().scaled(size(), Qt::KeepAspectRatio); - painter.drawImage(QRect(QPoint((width() - remote.width()) / 2, (height() - remote.height()) / 2), remote), m_remoteImage); + QRect videoRect(QPoint((width() - remote.width()) / 2, (height() - remote.height()) / 2), remote); + painter.drawImage(videoRect, m_remoteImage); if (!m_localImage.isNull()) { - QSize preview = m_localImage.size().scaled(qMin(240, width() / 4), qMin(180, height() / 4), Qt::KeepAspectRatio); - QRect target(QPoint(width() - preview.width() - 20, 20), preview); + QSize preview = m_localImage.size().scaled(qMin(240, remote.width() / 4), qMin(180, remote.height() / 4), Qt::KeepAspectRatio); + QRect target(QPoint(videoRect.right() - preview.width() - 20, videoRect.top() + 20), preview); painter.setPen(QPen(Qt::white, 2)); painter.drawRect(target.adjusted(-1, -1, 1, 1)); painter.drawImage(target, m_localImage); }