Keep multiview captions and controls below video and use logarithmic volume
This commit is contained in:
1 parent
213a1010c2
commit
5a8807bf89
3 files changed
+24
-9
No files matched your search
@@ -29,10 +29,12 @@ QString text(const char* value) { return QCoreApplication::translate("ChatGui",
|
||||
StreamGridWindow::StreamGridWindow(uint64_t group, QWidget* parent)
|
||||
: QWidget(parent), m_group(group), m_owner(++nextOwner) {
|
||||
setWindowTitle(text("All active streams")); resize(1100, 750); m_clock.start();
|
||||
auto* layout = new QVBoxLayout(this); auto* controls = new QHBoxLayout;
|
||||
m_status = new QLabel(text("Connecting…"), this); controls->addWidget(m_status, 1);
|
||||
auto* fullscreen = new QPushButton(text("Fullscreen"), this); controls->addWidget(fullscreen);
|
||||
m_close = new QPushButton(text("Close player"), this); controls->addWidget(m_close); layout->addLayout(controls);
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
m_controls = new QWidget(this); m_controls->setObjectName(QStringLiteral("streamGridControls"));
|
||||
auto* controls = new QHBoxLayout(m_controls); controls->setContentsMargins(0, 0, 0, 0);
|
||||
m_status = new QLabel(text("Connecting…"), m_controls); controls->addWidget(m_status, 1);
|
||||
auto* fullscreen = new QPushButton(text("Fullscreen"), m_controls); controls->addWidget(fullscreen);
|
||||
m_close = new QPushButton(text("Close player"), m_controls); controls->addWidget(m_close);
|
||||
connect(fullscreen, &QPushButton::clicked, this, [this] { if (isFullScreen()) showNormal(); else showFullScreen(); });
|
||||
connect(m_close, &QPushButton::clicked, this, [this] { if (m_focused) restoreGrid(); else close(); });
|
||||
auto* escape = new QShortcut(QKeySequence(Qt::Key_Escape), this); escape->setContext(Qt::WidgetWithChildrenShortcut);
|
||||
@@ -44,6 +46,7 @@ StreamGridWindow::StreamGridWindow(uint64_t group, QWidget* parent)
|
||||
m_empty = new QLabel(text("Waiting for active streams…"), this); m_empty->setAlignment(Qt::AlignCenter);
|
||||
layout->addWidget(m_empty);
|
||||
m_grid = new QGridLayout; m_grid->setSpacing(4); layout->addLayout(m_grid, 1);
|
||||
layout->addWidget(m_controls);
|
||||
m_watching = gui_stream_watch(m_group, m_owner);
|
||||
connect(&m_timer, &QTimer::timeout, this, &StreamGridWindow::tick); m_timer.start(250);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop multiview opened group=%llx owner=%llu",
|
||||
@@ -59,8 +62,8 @@ void StreamGridWindow::createTile(Tile& tile) {
|
||||
tile.widget->setObjectName(QStringLiteral("streamPreview_%1").arg(tile.source));
|
||||
auto* layout = new QVBoxLayout(tile.widget); layout->setContentsMargins(3, 3, 3, 3); layout->setSpacing(2);
|
||||
tile.title = new QLabel(tile.name, tile.widget); tile.title->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
|
||||
tile.title->setToolTip(tile.name); layout->addWidget(tile.title);
|
||||
tile.status = new QLabel(text("Connecting…"), tile.widget); layout->addWidget(tile.status);
|
||||
tile.title->setToolTip(tile.name);
|
||||
tile.status = new QLabel(text("Connecting…"), tile.widget);
|
||||
#ifdef HAVE_STREAM_CAPTURE
|
||||
auto* preview = new VideoRenderWidget(tile.widget);
|
||||
tile.video = preview;
|
||||
@@ -68,12 +71,16 @@ void StreamGridWindow::createTile(Tile& tile) {
|
||||
tile.video = new QLabel(text("Video capture requires Qt Multimedia and FFmpeg"), tile.widget);
|
||||
#endif
|
||||
tile.video->setToolTip(text("Manage stream")); layout->addWidget(tile.video, 1);
|
||||
layout->addWidget(tile.title); layout->addWidget(tile.status);
|
||||
updatePreview(tile);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop multiview local preview group=%llx source=%llx epoch=%llx decoder=0 audio=0",
|
||||
(unsigned long long)m_group, (unsigned long long)tile.source, (unsigned long long)tile.epoch);
|
||||
} else {
|
||||
tile.player = new StreamPlayerWindow(m_group, tile.source, tile.epoch, tile.name, this, true);
|
||||
tile.widget = tile.player; tile.video = tile.player->findChild<VideoRenderWidget*>();
|
||||
connect(tile.player, &StreamPlayerWindow::fullscreenRequested, this,
|
||||
[this] { if (isFullScreen()) showNormal(); else showFullScreen(); });
|
||||
connect(tile.player, &StreamPlayerWindow::closeRequested, this, &StreamGridWindow::restoreGrid);
|
||||
}
|
||||
if (!tile.video) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop multiview tile has no video source=%llx", (unsigned long long)tile.source); return;
|
||||
@@ -215,12 +222,14 @@ void StreamGridWindow::arrange() {
|
||||
for (int i = 0; i < m_side; ++i) { m_grid->setRowStretch(i, 1); m_grid->setColumnStretch(i, 1); }
|
||||
for (size_t i = 0; i < m_tiles.size(); ++i) {
|
||||
auto& tile = m_tiles[i];
|
||||
if (tile.player) tile.player->setWindowControlsVisible(m_focused == tile.source);
|
||||
if (m_focused && m_focused != tile.source) { tile.widget->hide(); continue; }
|
||||
if (m_focused) m_grid->addWidget(tile.widget, 0, 0, m_side, m_side);
|
||||
else m_grid->addWidget(tile.widget, static_cast<int>(i) / m_side, static_cast<int>(i) % m_side);
|
||||
tile.widget->show();
|
||||
}
|
||||
m_empty->setVisible(m_tiles.empty());
|
||||
m_controls->setVisible(!m_focused);
|
||||
m_close->setText(text(m_focused ? "All active streams" : "Close player"));
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop multiview layout group=%llx tiles=%zu grid=%dx%d focused=%llx",
|
||||
(unsigned long long)m_group, m_tiles.size(), m_side, m_side, (unsigned long long)m_focused);
|
||||
|
||||
@@ -64,6 +64,7 @@ private:
|
||||
std::vector<Tile> m_tiles; // Каждый widget принадлежит окну; удаляется целиком при смене идентичности/stop.
|
||||
// Элементы интерфейса принадлежат QObject-дереву этого окна.
|
||||
QGridLayout* m_grid = nullptr;
|
||||
QWidget* m_controls = nullptr; // Общая нижняя панель сетки; при focus её заменяет нижняя панель выбранного player.
|
||||
QLabel* m_status = nullptr;
|
||||
QLabel* m_empty = nullptr;
|
||||
QPushButton* m_close = nullptr;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
#include <cmath>
|
||||
|
||||
extern "C" {
|
||||
#include "../../../lib/debug_config.h"
|
||||
@@ -199,7 +200,7 @@ StreamPlayerWindow::StreamPlayerWindow(uint64_t group, uint64_t source, uint64_t
|
||||
auto* volumeBox = new QWidget(bar); auto* volumeLayout = new QVBoxLayout(volumeBox);
|
||||
volumeLayout->setContentsMargins(0, 0, 0, 0); volumeLayout->setSpacing(0);
|
||||
auto* volume = new StreamVolumeSlider(volumeBox); volume->setObjectName(QStringLiteral("streamVolume"));
|
||||
volume->setAccessibleName(text("Stream volume")); volume->setToolTip(QStringLiteral("100%")); volumeLayout->addWidget(volume);
|
||||
volume->setAccessibleName(text("Stream volume")); volume->setToolTip(QStringLiteral("0 dB")); volumeLayout->addWidget(volume);
|
||||
auto* volumeLabel = new QLabel(text("Volume"), volumeBox); volumeLabel->setAlignment(Qt::AlignCenter);
|
||||
volumeLayout->addWidget(volumeLabel); controls->addWidget(volumeBox);
|
||||
m_fullscreen = new QPushButton(text("Fullscreen"), bar); m_fullscreen->setObjectName(QStringLiteral("streamFullscreen"));
|
||||
@@ -210,8 +211,12 @@ StreamPlayerWindow::StreamPlayerWindow(uint64_t group, uint64_t source, uint64_t
|
||||
setWindowControlsVisible(false); layout->setContentsMargins(3, 3, 3, 3); layout->setSpacing(2); setMinimumSize(0, 0);
|
||||
}
|
||||
connect(volume, &QSlider::valueChanged, this, [this, volume](int value) {
|
||||
m_playback->volume = value / 100.0f; volume->setToolTip(QStringLiteral("%1%").arg(value));
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop viewer volume id=%llu percent=%d", (unsigned long long)m_playback->id, value);
|
||||
const float decibels = (value - 100) * 0.6f;
|
||||
const float gain = value ? std::pow(10.0f, decibels / 20.0f) : 0.0f;
|
||||
m_playback->volume = gain;
|
||||
volume->setToolTip(value ? QStringLiteral("%1 dB").arg(decibels, 0, 'f', 1) : QStringLiteral("−∞ dB"));
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop viewer volume id=%llu position=%d gain=%.6f",
|
||||
(unsigned long long)m_playback->id, value, gain);
|
||||
});
|
||||
connect(m_fullscreen, &QPushButton::clicked, this, [this, embedded] {
|
||||
if (embedded) emit fullscreenRequested(); else if (isFullScreen()) showNormal(); else showFullScreen();
|
||||
|
||||
Reference in new issue
Block a user