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

115 lines
3.8 KiB
C++

#pragma once
#include <QWidget>
#include <QImage>
#include <QString>
#include <QPoint>
#include <QTimer>
class QSlider;
class QPushButton;
class QLabel;
class VideoPlayerEngine;
/* Отрисовка кадра на чёрном фоне. zoomEnabled включает колесо до физического 1:1 и drag с ограничением краёв. */
class VideoRenderWidget : public QWidget {
Q_OBJECT
public:
explicit VideoRenderWidget(QWidget* parent = nullptr, bool zoomEnabled = false);
void setFrame(const QImage& img);
void clearFrame();
protected:
bool event(QEvent* event) override;
void paintEvent(QPaintEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
void wheelEvent(QWheelEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
private:
qreal frameScale() const;
void constrainView(const char* reason);
void finishDrag();
QImage m_frame;
const bool m_zoomEnabled;
qreal m_scale = 0; // Физические пиксели на пиксель кадра; 0 — автоматическое вписывание.
QPointF m_offset; // Смещение от центра в пикселях исходного кадра.
QPointF m_lastMouse;
bool m_panning = false;
};
/* Отдельное окно плеера без рамки: drag-перенос, dblclick/Alt+Enter — fullscreen,
* Esc — выход/закрытие, timeline + play/pause/close. */
class VideoPlayerWindow : public QWidget {
Q_OBJECT
public:
explicit VideoPlayerWindow(QWidget* parent = nullptr);
~VideoPlayerWindow() override;
void playFile(const QString& path);
signals:
void closed();
protected:
void keyPressEvent(QKeyEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent* event) override;
void closeEvent(QCloseEvent* event) override;
void resizeEvent(QResizeEvent* event) override;
bool eventFilter(QObject* obj, QEvent* event) override;
private slots:
void onEngineOpened(int width, int height, qint64 durationMs, bool hasAudio);
void onPositionChanged(qint64 ms);
void onStateChanged(int state);
void onError(const QString& msg);
void onFramePresented();
void onSliderPressed();
void onSliderReleased();
void onPlayPause();
void onClose();
void onFinished();
void showControls();
void hideControls();
private:
enum ResizeMode {
ResizeNone = 0,
ResizeLeft, ResizeRight, ResizeTop, ResizeBottom,
ResizeTopLeft, ResizeTopRight, ResizeBottomLeft, ResizeBottomRight
};
void toggleFullscreen();
void updateTimeLabels(qint64 posMs);
void setControlsVisible(bool visible);
QSize fitWindowSize(int vw, int vh) const;
ResizeMode hitTestResize(const QPoint& localPos) const;
void updateResizeCursor(const QPoint& localPos);
void applyResize(const QPoint& globalPos);
void beginResize(ResizeMode m, const QPoint& globalPos);
VideoRenderWidget* m_render = nullptr;
QWidget* m_controls = nullptr;
QSlider* m_slider = nullptr;
QPushButton* m_playBtn = nullptr;
QPushButton* m_closeBtn = nullptr;
QLabel* m_timeLabel = nullptr;
VideoPlayerEngine* m_engine = nullptr;
bool m_fullscreen = false;
bool m_sliderDragging = false;
bool m_dragging = false;
QPoint m_dragStart;
QPoint m_windowStart;
ResizeMode m_resizeMode = ResizeNone;
QRect m_resizeStartGeom;
QPoint m_resizeStartGlobal;
QTimer* m_hideTimer = nullptr;
};