feat: video widget keep widget/height ratio

This commit is contained in:
rankun 2020-03-01 10:40:26 +08:00
commit 74f73e937e
9 changed files with 171 additions and 52 deletions

View file

@ -10,6 +10,7 @@
#include <QMessageBox> #include <QMessageBox>
#include "videoform.h" #include "videoform.h"
#include "qyuvopenglwidget.h"
#include "mousetap/mousetap.h" #include "mousetap/mousetap.h"
#include "ui_videoform.h" #include "ui_videoform.h"
#include "iconhelper.h" #include "iconhelper.h"
@ -60,14 +61,17 @@ void VideoForm::initUI()
} }
setMouseTracking(true); setMouseTracking(true);
ui->videoWidget->setMouseTracking(true); m_videoWidget = new QYUVOpenGLWidget();
ui->videoWidget->hide(); m_videoWidget->setMouseTracking(true);
m_videoWidget->hide();
ui->keepRadioWidget->setWidget(m_videoWidget);
ui->keepRadioWidget->setWidthHeightRadio(m_widthHeightRatio);
} }
void VideoForm::onGrabCursor(bool grab) void VideoForm::onGrabCursor(bool grab)
{ {
#if defined(Q_OS_WIN32) || defined(Q_OS_OSX) #if defined(Q_OS_WIN32) || defined(Q_OS_OSX)
MouseTap::getInstance()->enableMouseEventTap(ui->videoWidget, grab); MouseTap::getInstance()->enableMouseEventTap(m_videoWidget, grab);
#else #else
Q_UNUSED(grab) Q_UNUSED(grab)
#endif #endif
@ -75,16 +79,16 @@ void VideoForm::onGrabCursor(bool grab)
void VideoForm::updateRender(const AVFrame *frame) void VideoForm::updateRender(const AVFrame *frame)
{ {
if (ui->videoWidget->isHidden()) { if (m_videoWidget->isHidden()) {
if (m_loadingWidget) { if (m_loadingWidget) {
m_loadingWidget->close(); m_loadingWidget->close();
} }
ui->videoWidget->show(); m_videoWidget->show();
} }
updateShowSize(QSize(frame->width, frame->height)); updateShowSize(QSize(frame->width, frame->height));
ui->videoWidget->setFrameSize(QSize(frame->width, frame->height)); m_videoWidget->setFrameSize(QSize(frame->width, frame->height));
ui->videoWidget->updateTextures(frame->data[0], frame->data[1], frame->data[2], m_videoWidget->updateTextures(frame->data[0], frame->data[1], frame->data[2],
frame->linesize[0], frame->linesize[1], frame->linesize[2]); frame->linesize[0], frame->linesize[1], frame->linesize[2]);
} }
@ -145,9 +149,11 @@ void VideoForm::updateShowSize(const QSize &newSize)
{ {
if (m_frameSize != newSize) { if (m_frameSize != newSize) {
m_frameSize = newSize; m_frameSize = newSize;
m_widthHeightRatio = 1.0f * newSize.width() / newSize.height();
bool vertical = m_widthHeightRatio < 1 ? true : false; m_widthHeightRatio = 1.0f * newSize.width() / newSize.height();
ui->keepRadioWidget->setWidthHeightRadio(m_widthHeightRatio);
bool vertical = m_widthHeightRatio < 1.0f ? true : false;
QSize showSize = newSize; QSize showSize = newSize;
QDesktopWidget* desktop = QApplication::desktop(); QDesktopWidget* desktop = QApplication::desktop();
if (!desktop) { if (!desktop) {
@ -262,12 +268,12 @@ void VideoForm::setController(Controller *controller)
void VideoForm::mousePressEvent(QMouseEvent *event) void VideoForm::mousePressEvent(QMouseEvent *event)
{ {
if (ui->videoWidget->geometry().contains(event->pos())) { if (m_videoWidget->geometry().contains(event->pos())) {
if (!m_controller) { if (!m_controller) {
return; return;
} }
event->setLocalPos(ui->videoWidget->mapFrom(this, event->localPos().toPoint())); event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint()));
m_controller->mouseEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); m_controller->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
} else { } else {
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
m_dragPosition = event->globalPos() - frameGeometry().topLeft(); m_dragPosition = event->globalPos() - frameGeometry().topLeft();
@ -282,23 +288,23 @@ void VideoForm::mouseReleaseEvent(QMouseEvent *event)
if (!m_controller) { if (!m_controller) {
return; return;
} }
event->setLocalPos(ui->videoWidget->mapFrom(this, event->localPos().toPoint())); event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint()));
// local check // local check
QPointF local = event->localPos(); QPointF local = event->localPos();
if (local.x() < 0) { if (local.x() < 0) {
local.setX(0); local.setX(0);
} }
if (local.x() > ui->videoWidget->width()) { if (local.x() > m_videoWidget->width()) {
local.setX(ui->videoWidget->width()); local.setX(m_videoWidget->width());
} }
if (local.y() < 0) { if (local.y() < 0) {
local.setY(0); local.setY(0);
} }
if (local.y() > ui->videoWidget->height()) { if (local.y() > m_videoWidget->height()) {
local.setY(ui->videoWidget->height()); local.setY(m_videoWidget->height());
} }
event->setLocalPos(local); event->setLocalPos(local);
m_controller->mouseEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); m_controller->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
} else { } else {
m_dragPosition = QPoint(0, 0); m_dragPosition = QPoint(0, 0);
} }
@ -306,12 +312,12 @@ void VideoForm::mouseReleaseEvent(QMouseEvent *event)
void VideoForm::mouseMoveEvent(QMouseEvent *event) void VideoForm::mouseMoveEvent(QMouseEvent *event)
{ {
if (ui->videoWidget->geometry().contains(event->pos())) { if (m_videoWidget->geometry().contains(event->pos())) {
if (!m_controller) { if (!m_controller) {
return; return;
} }
event->setLocalPos(ui->videoWidget->mapFrom(this, event->localPos().toPoint())); event->setLocalPos(m_videoWidget->mapFrom(this, event->localPos().toPoint()));
m_controller->mouseEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); m_controller->mouseEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
} else if (!m_dragPosition.isNull()){ } else if (!m_dragPosition.isNull()){
if (event->buttons() & Qt::LeftButton) { if (event->buttons() & Qt::LeftButton) {
move(event->globalPos() - m_dragPosition); move(event->globalPos() - m_dragPosition);
@ -322,11 +328,11 @@ void VideoForm::mouseMoveEvent(QMouseEvent *event)
void VideoForm::wheelEvent(QWheelEvent *event) void VideoForm::wheelEvent(QWheelEvent *event)
{ {
if (ui->videoWidget->geometry().contains(event->pos())) { if (m_videoWidget->geometry().contains(event->pos())) {
if (!m_controller) { if (!m_controller) {
return; return;
} }
QPointF pos = ui->videoWidget->mapFrom(this, event->pos()); QPointF pos = m_videoWidget->mapFrom(this, event->pos());
/* /*
QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
@ -334,7 +340,7 @@ void VideoForm::wheelEvent(QWheelEvent *event)
*/ */
QWheelEvent wheelEvent(pos, event->globalPosF(), event->delta(), QWheelEvent wheelEvent(pos, event->globalPosF(), event->delta(),
event->buttons(), event->modifiers(), event->orientation()); event->buttons(), event->modifiers(), event->orientation());
m_controller->wheelEvent(&wheelEvent, ui->videoWidget->frameSize(), ui->videoWidget->size()); m_controller->wheelEvent(&wheelEvent, m_videoWidget->frameSize(), m_videoWidget->size());
} }
} }
@ -360,7 +366,7 @@ void VideoForm::keyPressEvent(QKeyEvent *event)
return; return;
} }
m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); m_controller->keyEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
} }
void VideoForm::keyReleaseEvent(QKeyEvent *event) void VideoForm::keyReleaseEvent(QKeyEvent *event)
@ -368,7 +374,7 @@ void VideoForm::keyReleaseEvent(QKeyEvent *event)
if (!m_controller) { if (!m_controller) {
return; return;
} }
m_controller->keyEvent(event, ui->videoWidget->frameSize(), ui->videoWidget->size()); m_controller->keyEvent(event, m_videoWidget->frameSize(), m_videoWidget->size());
} }
void VideoForm::paintEvent(QPaintEvent *paint) void VideoForm::paintEvent(QPaintEvent *paint)
@ -388,6 +394,32 @@ void VideoForm::showEvent(QShowEvent *event)
} }
} }
void VideoForm::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
QSize goodSize = ui->keepRadioWidget->goodSize();
if (goodSize.isEmpty()) {
return;
}
QSize curSize = size();
// 限制VideoForm尺寸不能小于keepRadioWidget good size
if (m_widthHeightRatio > 1.0f) {
// hor
if (curSize.height() <= goodSize.height()) {
setMinimumHeight(goodSize.height());
} else {
setMinimumHeight(0);
}
} else {
// ver
if (curSize.width() <= goodSize.width()) {
setMinimumWidth(goodSize.width());
} else {
setMinimumWidth(0);
}
}
}
void VideoForm::dragEnterEvent(QDragEnterEvent *event) void VideoForm::dragEnterEvent(QDragEnterEvent *event)
{ {
event->acceptProposedAction(); event->acceptProposedAction();

View file

@ -12,6 +12,7 @@ struct AVFrame;
class ToolForm; class ToolForm;
class Controller; class Controller;
class FileHandler; class FileHandler;
class QYUVOpenGLWidget;
class VideoForm : public QWidget class VideoForm : public QWidget
{ {
Q_OBJECT Q_OBJECT
@ -53,6 +54,7 @@ protected:
void paintEvent(QPaintEvent *); void paintEvent(QPaintEvent *);
void showEvent(QShowEvent *event); void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
void dragEnterEvent(QDragEnterEvent *event); void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event); void dragMoveEvent(QDragMoveEvent *event);
@ -64,6 +66,7 @@ private:
Ui::videoForm *ui; Ui::videoForm *ui;
QPointer<ToolForm> m_toolForm; QPointer<ToolForm> m_toolForm;
QPointer<QWidget> m_loadingWidget; QPointer<QWidget> m_loadingWidget;
QPointer<QYUVOpenGLWidget> m_videoWidget;
//inside member //inside member
QSize m_frameSize; QSize m_frameSize;

View file

@ -39,15 +39,15 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QYUVOpenGLWidget" name="videoWidget" native="true"/> <widget class="KeepRadioWidget" name="keepRadioWidget" native="true"/>
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>
<class>QYUVOpenGLWidget</class> <class>KeepRadioWidget</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>qyuvopenglwidget.h</header> <header location="global">keepradiowidget.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>

View file

@ -0,0 +1,74 @@
#include <QResizeEvent>
#include "keepradiowidget.h"
KeepRadioWidget::KeepRadioWidget(QWidget *parent) :
QWidget(parent)
{
}
KeepRadioWidget::~KeepRadioWidget()
{
}
void KeepRadioWidget::setWidget(QWidget *w)
{
if (!w) {
return;
}
w->setParent(this);
m_subWidget = w;
}
void KeepRadioWidget::setWidthHeightRadio(float widthHeightRadio)
{
if (fabs(m_widthHeightRadio - widthHeightRadio) < 0.000001f) {
return;
}
m_widthHeightRadio = widthHeightRadio;
adjustSubWidget();
}
const QSize KeepRadioWidget::goodSize()
{
if (!m_subWidget || m_widthHeightRadio < 0.0f) {
return QSize();
}
return m_subWidget->size();
}
void KeepRadioWidget::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
adjustSubWidget();
}
void KeepRadioWidget::adjustSubWidget()
{
if (!m_subWidget) {
return;
}
QSize curSize = size();
QPoint pos(0, 0);
int width = 0;
int height = 0;
if (m_widthHeightRadio > 1.0f) {
// base width
width = curSize.width();
height = curSize.width() / m_widthHeightRadio;
pos.setY((curSize.height() - height) / 2);
} else if (m_widthHeightRadio > 0.0f) {
// base height
height = curSize.height();
width = curSize.height() * m_widthHeightRadio;
pos.setX((curSize.width() - width) / 2);
} else {
// full widget
height = curSize.height();
width = curSize.width();
}
m_subWidget->setGeometry(pos.x(), pos.y(), width, height);
}

View file

@ -0,0 +1,29 @@
#ifndef KEEPRADIOWIDGET_H
#define KEEPRADIOWIDGET_H
#include <QWidget>
#include <QPointer>
class KeepRadioWidget : public QWidget
{
Q_OBJECT
public:
explicit KeepRadioWidget(QWidget *parent = nullptr);
~KeepRadioWidget();
void setWidget(QWidget* w);
void setWidthHeightRadio(float widthHeightRadio);
const QSize goodSize();
protected:
void resizeEvent(QResizeEvent *event);
void adjustSubWidget();
private:
float m_widthHeightRadio = -1.0f;
QPointer<QWidget> m_subWidget;
QSize m_goodSize;
};
#endif // KEEPRADIOWIDGET_H

View file

@ -3,7 +3,6 @@
#include <QStyle> #include <QStyle>
#include "magneticwidget.h" #include "magneticwidget.h"
#include "ui_magneticwidget.h"
MagneticWidget::MagneticWidget(QWidget* adsorbWidget, AdsorbPositions adsorbPos) MagneticWidget::MagneticWidget(QWidget* adsorbWidget, AdsorbPositions adsorbPos)
: QWidget(Q_NULLPTR) : QWidget(Q_NULLPTR)

View file

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MagneticWidget</class>
<widget class="QWidget" name="MagneticWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -1,8 +1,9 @@
FORMS += \ FORMS +=
$$PWD/magneticwidget.ui
HEADERS += \ HEADERS += \
$$PWD/keepradiowidget.h \
$$PWD/magneticwidget.h $$PWD/magneticwidget.h
SOURCES += \ SOURCES += \
$$PWD/keepradiowidget.cpp \
$$PWD/magneticwidget.cpp $$PWD/magneticwidget.cpp

View file

@ -8,7 +8,7 @@ PushFilePath=/sdcard/
# 最大fps仅支持Android 10以上 # 最大fps仅支持Android 10以上
MaxFps=60 MaxFps=60
# 是否显示手机皮肤0不显示 # 是否显示手机皮肤0不显示
UseSkin=1 UseSkin=0
# 是否渲染过期视频帧(跳过过期视频帧意味着更低的延迟) # 是否渲染过期视频帧(跳过过期视频帧意味着更低的延迟)
RenderExpiredFrames=0 RenderExpiredFrames=0
# 视频解码方式:-1 自动0 软解1 dx硬解2 opengl硬解 # 视频解码方式:-1 自动0 软解1 dx硬解2 opengl硬解