Files
utun2/tools/chatgui/src/streamgrid_window.h
T

73 lines
3.4 KiB
C++

/* Окно всех активных трансляций одного канала. Собственный catalogue owner не зависит от выбранного чата.
* Плитка сохраняет player/decoder/часы при перекладке; новая эпоха заменяет только соответствующий player.
* Своя плитка получает setLocalPreview до кодирования, без reader/audio; клик запрашивает управление.
* Чужая плитка разворачивается без пересоздания players; Esc/повторный клик возвращает сетку.
* Пропавшему источнику даётся дочитать FIN, затем плитка удаляется. Пустое окно ждёт новые публикации. */
#pragma once
#include <QWidget>
#include <QTimer>
#include <QElapsedTimer>
#include <QPointer>
#include <QVariant>
#include <vector>
#include <cstdint>
class StreamPlayerWindow;
class QGridLayout;
class QLabel;
class QPushButton;
class QCloseEvent;
class StreamGridWindow : public QWidget {
Q_OBJECT
public:
explicit StreamGridWindow(uint64_t group, QWidget* parent = nullptr);
~StreamGridWindow() override;
uint64_t group() const { return m_group; }
void onSources(const uint8_t* data, int length);
void setLocalPreview(uint64_t group, const QVariant& frame); // Последний QVideoFrame локального publisher, GUI-поток.
int tileCount() const { return static_cast<int>(m_tiles.size()); }
int gridSide() const { return m_side; }
uint64_t focusedSource() const { return m_focused; }
signals:
void publishRequested(quint64 group); // Открыть управление своей публикацией, сохранив это окно.
protected:
void closeEvent(QCloseEvent* event) override;
bool eventFilter(QObject* watched, QEvent* event) override;
private:
struct Tile {
uint64_t source, epoch;
QString name;
bool self = false, previewPresented = false;
QWidget* widget = nullptr; // Владеет player либо прямым preview, удаляется целиком.
QWidget* video = nullptr; // Поверхность изображения; сюда направлены клики.
StreamPlayerWindow* player = nullptr;
QLabel* status = nullptr; // Статус прямого preview; у remote им владеет player.
qint64 removeAt = -1, retryAt = 0;
unsigned failures = 0;
};
uint64_t m_group, m_owner;
std::vector<Tile> m_tiles;
QGridLayout* m_grid = nullptr;
QLabel* m_status = nullptr;
QLabel* m_empty = nullptr;
QPushButton* m_close = nullptr;
QVariant m_preview; // Только последний кадр издателя; сеть/декодер для self не открываются.
QTimer m_timer;
QElapsedTimer m_clock;
int m_side = 0;
bool m_watching = false, m_closed = false;
uint64_t m_focused = 0; // Source развёрнутой чужой плитки; 0 — сетка.
Qt::WindowStates m_gridWindowState;
QPointer<QObject> m_pressed;
QPoint m_pressPosition;
bool m_dragged = false;
void createTile(Tile& tile);
void updatePreview(Tile& tile);
void activateTile(uint64_t source);
void restoreGrid();
void arrange();
void tick();
void stop();
};