1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Video: Add collapse/expand button, expand all the way, better self video output location

This commit is contained in:
TheSpiritXIII 2015-07-22 14:50:39 -04:00
parent 4c493b85a0
commit cd90d8d34b
10 changed files with 207 additions and 34 deletions

View File

@ -18,53 +18,69 @@
*/
#include "netcamview.h"
#include "camerasource.h"
#include "src/core/core.h"
#include "src/video/videosurface.h"
#include <QLabel>
#include <QHBoxLayout>
#include "src/widget/tool/movablewidget.h"
#include "camerasource.h"
#include <QLabel>
#include <QBoxLayout>
#include <QPushButton>
NetCamView::NetCamView(QWidget* parent)
: QWidget(parent)
, mainLayout(new QHBoxLayout())
, selfFrame{nullptr}
{
setLayout(mainLayout);
QVBoxLayout* layout = new QVBoxLayout(this);
setWindowTitle(tr("Tox video"));
setMinimumSize(320,240);
videoSurface = new VideoSurface(this);
//mainLayout->addStretch();
mainLayout->addWidget(videoSurface);
//mainLayout->addStretch();
selfFrame = new MovableWidget(videoSurface);
selfFrame->setStyleSheet("background-color: red;");
selfFrame->show();
selfVideoSurface = new VideoSurface(selfFrame);
selfVideoSurface = new VideoSurface(this);
selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
selfVideoSurface->setMinimumSize(QSize(160, 120));
selfVideoSurface->setSource(&CameraSource::getInstance());
QHBoxLayout* camLayout = new QHBoxLayout(selfFrame);
camLayout->addWidget(selfVideoSurface);
camLayout->setMargin(0);
connect(&CameraSource::getInstance(), &CameraSource::deviceOpened, this, &NetCamView::updateSize);
connect(&CameraSource::getInstance(), &CameraSource::deviceOpened, [this]()
{
connect(selfVideoSurface, &VideoSurface::drewNewFrame, this, &NetCamView::updateSize);
});
QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addStretch();
button = new QPushButton();
buttonLayout->addWidget(button);
connect(button, &QPushButton::clicked, this, &NetCamView::showMessageClicked);
layout->addLayout(mainLayout);
layout->addLayout(buttonLayout);
setShowMessages(false);
}
void NetCamView::show(VideoSource *source, const QString &title)
{
setSource(source);
setTitle(title);
selfFrame->setBoundary(videoSurface->getRect());
QWidget::show();
updateSize();
}
void NetCamView::hide()
{
setSource(nullptr);
if (selfFrame)
selfFrame->deleteLater();
selfFrame = nullptr;
QWidget::hide();
}
@ -78,6 +94,22 @@ void NetCamView::setTitle(const QString &title)
setWindowTitle(title);
}
void NetCamView::setShowMessages(bool show, bool notify)
{
if (show)
{
button->setText(tr("Show Messages"));
if (notify)
button->setIcon(QIcon("://ui/chatArea/info.svg"));
}
else
{
button->setText(tr("Hide Messages"));
button->setIcon(QIcon());
}
}
void NetCamView::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
@ -85,12 +117,54 @@ void NetCamView::resizeEvent(QResizeEvent* event)
}
void NetCamView::updateSize()
{
// Check there is room for a second video.
// If so, then we will show the user video there too.
//qDebug() << selfVideoSurface->getRect().size() == ;
bool hasRoom = selfVideoSurface->getRect().width() != 0 && videoSurface->getRect().width() * 2 < layout()->contentsRect().width() - layout()->margin();
if (mainLayout->indexOf(selfVideoSurface) != -1)
{
if (!hasRoom)
{
selfFrame = new MovableWidget(videoSurface);
selfFrame->show();
QHBoxLayout* camLayout = new QHBoxLayout(selfFrame);
camLayout->addWidget(selfVideoSurface);
camLayout->setMargin(0);
//selfFrame->setBoundary(videoSurface->getRect());
updateFrameSize();
}
}
else
{
if (hasRoom)
{
if (selfFrame)
selfFrame->deleteLater();
selfFrame = nullptr;
mainLayout->addWidget(selfVideoSurface);
}
else if (selfFrame)
{
updateFrameSize();
}
}
disconnect(selfVideoSurface, &VideoSurface::drewNewFrame, this, &NetCamView::updateSize);
}
void NetCamView::updateFrameSize()
{
QSize frameSize = selfVideoSurface->getFrameSize();
float ratio = frameSize.width() / static_cast<float>(frameSize.height());
QRect videoRect = videoSurface->getRect();
int frameHeight = videoRect.height() / 3.0f;
selfFrame->resize(frameHeight * ratio, frameHeight);
selfFrame->setBoundary(videoRect);
selfVideoSurface->resize(selfFrame->size());
//selfFrame->resize(frameHeight * ratio, frameHeight);
selfFrame->setBoundary(videoRect, QSize(frameHeight * ratio, frameHeight));
}

View File

@ -28,6 +28,7 @@ class VideoSurface;
class VideoSource;
class QFrame;
class MovableWidget;
class QPushButton;
class NetCamView : public QWidget
{
@ -42,6 +43,12 @@ public:
void setSource(VideoSource* s);
void setTitle(const QString& title);
signals:
void showMessageClicked();
public slots:
void setShowMessages(bool show, bool notify = false);
protected:
void resizeEvent(QResizeEvent* event) final override;
@ -49,10 +56,13 @@ private slots:
void updateSize();
private:
void updateFrameSize();
QHBoxLayout* mainLayout;
VideoSurface* videoSurface;
VideoSurface* selfVideoSurface;
MovableWidget* selfFrame;
QPushButton* button;
};
#endif // NETCAMVIEW_H

View File

@ -28,7 +28,7 @@ VideoSurface::VideoSurface(QWidget* parent)
, frameLock{false}
, hasSubscribed{false}
{
//setMinimumWidth(160);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
VideoSurface::VideoSurface(VideoSource *source, QWidget* parent)
@ -52,7 +52,7 @@ void VideoSurface::setSource(VideoSource *src)
subscribe();
}
#include <QDebug>
QRect VideoSurface::getRect()
QRect VideoSurface::getRect() const
{
// Fast lock
{
@ -95,6 +95,11 @@ QSize VideoSurface::getFrameSize()
return frameSize;
}
QSize VideoSurface::sizeHint() const
{
return getRect().size();
}
void VideoSurface::subscribe()
{
if (source && !hasSubscribed)
@ -136,6 +141,8 @@ void VideoSurface::onNewFrameAvailable(std::shared_ptr<VideoFrame> newFrame)
lastFrame = newFrame;
frameLock = false;
update();
emit drewNewFrame();
}
void VideoSurface::paintEvent(QPaintEvent*)
@ -148,7 +155,7 @@ void VideoSurface::paintEvent(QPaintEvent*)
}
QPainter painter(this);
//painter.fillRect(painter.viewport(), Qt::blue);
//painter.fillRect(painter.viewport(), Qt::black);
if (lastFrame)
{
QSize frameSize = lastFrame->getSize();
@ -166,6 +173,7 @@ void VideoSurface::paintEvent(QPaintEvent*)
#include <QResizeEvent>
void VideoSurface::resizeEvent(QResizeEvent* event)
{
// Locks aspect ratio.
QSize frameSize;
// Fast lock

View File

@ -35,9 +35,14 @@ public:
~VideoSurface();
void setSource(VideoSource* src); //NULL is a valid option
QRect getRect();
QRect getRect() const;
QSize getFrameSize();
virtual QSize sizeHint() const override;
signals:
void drewNewFrame();
protected:
void subscribe();
void unsubscribe();
@ -51,7 +56,7 @@ private slots:
private:
VideoSource* source;
std::shared_ptr<VideoFrame> lastFrame;
std::atomic_bool frameLock; ///< Fast lock for lastFrame
mutable std::atomic_bool frameLock; ///< Fast lock for lastFrame
bool hasSubscribed;
};

View File

@ -31,6 +31,7 @@
#include <QTemporaryFile>
#include <QGuiApplication>
#include <QStyle>
#include <QSplitter>
#include <cassert>
#include "chatform.h"
#include "src/core/core.h"
@ -88,6 +89,10 @@ ChatForm::ChatForm(Friend* chatFriend)
headTextLayout->addWidget(callDuration, 1, Qt::AlignCenter);
callDuration->hide();
chatWidget->setMinimumHeight(160);
connect(bodySplitter, &QSplitter::splitterMoved, this, &ChatForm::onSplitterMoved);
connect(this, &GenericChatForm::messageInserted, this, &ChatForm::onMessageInserted);
loadHistoryAction = menu.addAction(QString(), this, SLOT(onLoadHistory()));
connect(Core::getInstance(), &Core::fileSendStarted, this, &ChatForm::startFileSend);
@ -931,6 +936,31 @@ void ChatForm::onLoadHistory()
}
}
void ChatForm::onSplitterMoved(int, int)
{
if (netcam)
netcam->setShowMessages(bodySplitter->sizes()[1] == 0);
}
void ChatForm::onMessageInserted()
{
if (netcam && bodySplitter->sizes()[1] == 0)
netcam->setShowMessages(true, true);
}
void ChatForm::onShowMessagesClicked()
{
if (netcam)
{
if (bodySplitter->sizes()[1] == 0)
bodySplitter->setSizes({1, 1});
else
bodySplitter->setSizes({1, 0});
onSplitterMoved(0, 0);
}
}
void ChatForm::startCounter()
{
if (!callDurationTimer)
@ -1062,13 +1092,16 @@ void ChatForm::SendMessageStr(QString msg)
Widget::getInstance()->updateFriendActivity(f);
}
}
#include <QSplitter>
void ChatForm::showNetcam()
{
if (!netcam)
netcam = new NetCamView();
netcam->show(Core::getInstance()->getVideoSourceFromCall(callId), f->getDisplayedName());
connect(netcam, &NetCamView::showMessageClicked, this, &ChatForm::onShowMessagesClicked);
bodySplitter->insertWidget(0, netcam);
bodySplitter->setCollapsible(0, false);
}
void ChatForm::hideNetcam()
@ -1083,4 +1116,7 @@ void ChatForm::hideNetcam()
void ChatForm::retranslateUi()
{
loadHistoryAction->setText(tr("Load chat history..."));
if (netcam)
netcam->setShowMessages(chatWidget->isVisible());
}

View File

@ -100,6 +100,9 @@ private slots:
void onScreenshotClicked();
void onScreenshotTaken(const QPixmap &pixmap);
void doScreenshot();
void onSplitterMoved(int pos, int index);
void onMessageInserted();
void onShowMessagesClicked();
private:
void retranslateUi();

View File

@ -128,10 +128,14 @@ GenericChatForm::GenericChatForm(QWidget *parent)
setLayout(mainLayout);
bodySplitter = new QSplitter(Qt::Vertical, this);
bodySplitter->addWidget(chatWidget);
QWidget* contentWidget = new QWidget(this);
QVBoxLayout* contentLayout = new QVBoxLayout(contentWidget);
contentLayout->addWidget(chatWidget);
contentLayout->addLayout(mainFootLayout);
bodySplitter->addWidget(contentWidget);
mainLayout->addWidget(bodySplitter);
mainLayout->addLayout(mainFootLayout);
mainLayout->setMargin(0);
footButtonsSmall->addWidget(emoteButton);
@ -464,6 +468,7 @@ QString GenericChatForm::resolveToxId(const ToxId &id)
void GenericChatForm::insertChatMessage(ChatMessage::Ptr msg)
{
chatWidget->insertChatlineAtBottom(std::dynamic_pointer_cast<ChatLine>(msg));
emit messageInserted();
}
void GenericChatForm::hideEvent(QHideEvent* event)

View File

@ -71,6 +71,7 @@ signals:
void sendMessage(uint32_t, QString);
void sendAction(uint32_t, QString);
void chatAreaCleared();
void messageInserted();
public slots:
void focusInput();

View File

@ -19,18 +19,34 @@
#include "movablewidget.h"
#include <QMouseEvent>
#include <QGraphicsOpacityEffect>
#include <cmath>
MovableWidget::MovableWidget(QWidget *parent)
: QWidget(parent)
{
}
void MovableWidget::setBoundary(const QRect& boundary)
#include <QDebug>
void MovableWidget::setBoundary(const QRect& boundary, QSize size)
{
int widthEdge = boundaryRect.x() - width();
checkBoundaryLeft(widthEdge);
int widthRange = abs(widthEdge) * 2 + boundaryRect.width() - width();
float xPercent = static_cast<float>(x() - widthEdge) / widthRange;
qDebug() << xPercent << x() - widthEdge << widthRange;
float yPercent = static_cast<float>(y()) / (boundaryRect.height() - height());
if (size.isValid())
resize(size);
boundaryRect = boundary;
widthEdge = boundaryRect.x() - width();
checkBoundaryLeft(widthEdge);
QPoint moveTo = pos();
moveTo.setX((abs(widthEdge) * 2 + boundaryRect.width() - width()) * xPercent);
moveTo.setY((boundaryRect.height() - height()) * yPercent);
checkBoundary(moveTo);
move(moveTo);
}
@ -61,7 +77,7 @@ void MovableWidget::mouseReleaseEvent(QMouseEvent* event)
if (!(event->buttons() & Qt::LeftButton))
moving = false;
}
#include <QGraphicsOpacityEffect>
void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event)
{
if (!(event->buttons() & Qt::LeftButton))
@ -81,12 +97,17 @@ void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event)
void MovableWidget::checkBoundary(QPoint& point) const
{
if (boundaryRect.isNull())
return;
int x1, y1, x2, y2;
boundaryRect.getCoords(&x1, &y1, &x2, &y2);
x1 = point.x();
checkBoundaryLeft(x1);
point.setX(x1);
// Video boundary.
if (point.x() + width() < x1)
point.setX(x1 - width());
if (point.y() + height() <y1)
point.setY(y1 - height());
@ -98,9 +119,6 @@ void MovableWidget::checkBoundary(QPoint& point) const
point.setY(y2);
// Parent boundary.
if (point.x() < 0)
point.setX(0);
if (point.y() < 0)
point.setY(0);
@ -110,3 +128,12 @@ void MovableWidget::checkBoundary(QPoint& point) const
if (point.y() + height() > parentWidget()->height())
point.setY(parentWidget()->height() - height());
}
void MovableWidget::checkBoundaryLeft(int &x) const
{
if (x < 0)
x = 0;
if (x + width() < boundaryRect.x())
x = boundaryRect.x() - width();
}

View File

@ -26,7 +26,7 @@ class MovableWidget : public QWidget
{
public:
MovableWidget(QWidget* parent);
void setBoundary(const QRect& boundary);
void setBoundary(const QRect& boundary, QSize size = QSize());
protected:
void mousePressEvent(QMouseEvent* event);
@ -36,6 +36,10 @@ protected:
private:
void checkBoundary(QPoint& point) const;
void checkBoundaryTop(int &x) const;
void checkBoundaryBottom(int &x) const;
void checkBoundaryLeft(int &x) const;
void checkBoundaryRight(int &x) const;
bool moving = false;
QPoint lastPoint;