mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Keep aspect ratio of inner video
This commit is contained in:
parent
cd90d8d34b
commit
9d12c295be
6
qtox.pro
6
qtox.pro
|
@ -494,7 +494,8 @@ SOURCES += \
|
|||
src/widget/friendlistlayout.cpp \
|
||||
src/widget/genericchatitemlayout.cpp \
|
||||
src/widget/categorywidget.cpp \
|
||||
src/widget/tool/movablewidget.cpp
|
||||
src/widget/tool/movablewidget.cpp \
|
||||
src/widget/tool/aspectratiowidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/audio/audio.h \
|
||||
|
@ -538,4 +539,5 @@ HEADERS += \
|
|||
src/widget/friendlistlayout.h \
|
||||
src/widget/genericchatitemlayout.h \
|
||||
src/widget/categorywidget.h \
|
||||
src/widget/tool/movablewidget.h
|
||||
src/widget/tool/movablewidget.h \
|
||||
src/widget/tool/aspectratiowidget.h
|
||||
|
|
|
@ -1085,7 +1085,7 @@ QSplitter:handle{
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>284</width>
|
||||
<height>353</height>
|
||||
<height>341</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5"/>
|
||||
|
@ -1850,7 +1850,7 @@ QSplitter:handle{
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>775</width>
|
||||
<height>22</height>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
|
@ -33,23 +33,39 @@ NetCamView::NetCamView(QWidget* parent)
|
|||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
setWindowTitle(tr("Tox video"));
|
||||
setMinimumSize(320,240);
|
||||
|
||||
videoSurface = new VideoSurface(this);
|
||||
videoSurface->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum));
|
||||
videoSurface->setStyleSheet("background-color: blue;");
|
||||
videoSurface->setMinimum(128);
|
||||
|
||||
//mainLayout->addStretch();
|
||||
mainLayout->addWidget(videoSurface);
|
||||
//mainLayout->addStretch();
|
||||
mainLayout->addStretch(1);
|
||||
//QWidget* wid = new QWidget(this);
|
||||
//wid->setMinimumSize(600, 600);
|
||||
QVBoxLayout* horLayout = new QVBoxLayout();
|
||||
horLayout->addStretch(1);
|
||||
horLayout->addWidget(videoSurface);
|
||||
horLayout->addStretch(1);
|
||||
mainLayout->addLayout(horLayout);
|
||||
|
||||
selfVideoSurface = new VideoSurface(this);
|
||||
selfFrame = new MovableWidget(videoSurface);
|
||||
selfFrame->show();
|
||||
|
||||
selfVideoSurface = new VideoSurface(selfFrame);
|
||||
selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
|
||||
selfVideoSurface->setMinimumSize(QSize(160, 120));
|
||||
selfVideoSurface->setSource(&CameraSource::getInstance());
|
||||
selfVideoSurface->setMouseTracking(true);
|
||||
|
||||
connect(&CameraSource::getInstance(), &CameraSource::deviceOpened, [this]()
|
||||
QHBoxLayout* frameLayout = new QHBoxLayout(selfFrame);
|
||||
frameLayout->addWidget(selfVideoSurface);
|
||||
frameLayout->setMargin(0);
|
||||
|
||||
//mainLayout->addWidget(selfVideoSurface);
|
||||
mainLayout->addStretch(1);
|
||||
|
||||
/*connect(&CameraSource::getInstance(), &CameraSource::deviceOpened, [this]()
|
||||
{
|
||||
connect(selfVideoSurface, &VideoSurface::drewNewFrame, this, &NetCamView::updateSize);
|
||||
});
|
||||
});*/
|
||||
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout();
|
||||
buttonLayout->addStretch();
|
||||
|
@ -57,24 +73,29 @@ NetCamView::NetCamView(QWidget* parent)
|
|||
buttonLayout->addWidget(button);
|
||||
connect(button, &QPushButton::clicked, this, &NetCamView::showMessageClicked);
|
||||
|
||||
layout->addLayout(mainLayout);
|
||||
layout->addLayout(mainLayout, 1);
|
||||
layout->addLayout(buttonLayout);
|
||||
|
||||
setShowMessages(false);
|
||||
|
||||
setStyleSheet("NetCamView { background-color: #c1c1c1; }");
|
||||
}
|
||||
|
||||
void NetCamView::show(VideoSource *source, const QString &title)
|
||||
{
|
||||
setSource(source);
|
||||
//selfVideoSurface->setSource(&CameraSource::getInstance());
|
||||
setTitle(title);
|
||||
|
||||
QWidget::show();
|
||||
updateSize();
|
||||
//updateSize();
|
||||
}
|
||||
|
||||
void NetCamView::hide()
|
||||
{
|
||||
qDebug() << "jd";
|
||||
setSource(nullptr);
|
||||
selfVideoSurface->setSource(nullptr);
|
||||
|
||||
if (selfFrame)
|
||||
selfFrame->deleteLater();
|
||||
|
@ -109,6 +130,14 @@ void NetCamView::setShowMessages(bool show, bool notify)
|
|||
button->setIcon(QIcon());
|
||||
}
|
||||
}
|
||||
#include <QPainter>
|
||||
#include "src/widget/style.h"
|
||||
void NetCamView::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setBrush(Style::getColor(Style::ThemeDark));
|
||||
painter.drawRect(rect());
|
||||
}
|
||||
|
||||
void NetCamView::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
|
@ -118,53 +147,23 @@ 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();
|
||||
qDebug() << videoSurface->size();
|
||||
QSize usableSize = mainLayout->contentsRect().size();
|
||||
int possibleWidth = usableSize.height() * videoSurface->getRatio();
|
||||
|
||||
if (mainLayout->indexOf(selfVideoSurface) != -1)
|
||||
{
|
||||
QSize initial = videoSurface->sizeHint();
|
||||
|
||||
if (!hasRoom)
|
||||
{
|
||||
selfFrame = new MovableWidget(videoSurface);
|
||||
selfFrame->show();
|
||||
if (!initial.isValid())
|
||||
return;
|
||||
|
||||
QHBoxLayout* camLayout = new QHBoxLayout(selfFrame);
|
||||
camLayout->addWidget(selfVideoSurface);
|
||||
camLayout->setMargin(0);
|
||||
|
||||
//selfFrame->setBoundary(videoSurface->getRect());
|
||||
updateFrameSize();
|
||||
}
|
||||
}
|
||||
if (possibleWidth > usableSize.width())
|
||||
videoSurface->setSizeHint(usableSize.width(), usableSize.width() / videoSurface->getRatio());
|
||||
else
|
||||
{
|
||||
if (hasRoom)
|
||||
{
|
||||
if (selfFrame)
|
||||
selfFrame->deleteLater();
|
||||
videoSurface->setSizeHint(usableSize.height() * videoSurface->getRatio(), usableSize.height());
|
||||
|
||||
selfFrame = nullptr;
|
||||
videoSurface->updateGeometry();
|
||||
|
||||
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, QSize(frameHeight * ratio, frameHeight));
|
||||
QSize newSize = videoSurface->sizeHint();
|
||||
QSizeF initialSize = initial;
|
||||
selfFrame->setBoundary(newSize, initial, newSize.width() / initialSize.width(), newSize.height() / initialSize.height());
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define NETCAMVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "src/widget/tool/aspectratiowidget.h"
|
||||
|
||||
class QHBoxLayout;
|
||||
struct vpx_image;
|
||||
|
@ -50,9 +51,10 @@ public slots:
|
|||
void setShowMessages(bool show, bool notify = false);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void resizeEvent(QResizeEvent* event) final override;
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
void updateSize();
|
||||
|
||||
private:
|
||||
|
@ -63,6 +65,7 @@ private:
|
|||
VideoSurface* selfVideoSurface;
|
||||
MovableWidget* selfFrame;
|
||||
QPushButton* button;
|
||||
bool e = false;
|
||||
};
|
||||
|
||||
#endif // NETCAMVIEW_H
|
||||
|
|
|
@ -21,14 +21,16 @@
|
|||
#include "src/video/videoframe.h"
|
||||
#include <QPainter>
|
||||
#include <QLabel>
|
||||
|
||||
#include <QDebug>
|
||||
VideoSurface::VideoSurface(QWidget* parent)
|
||||
: QWidget{parent}
|
||||
: AspectRatioWidget{parent}
|
||||
, source{nullptr}
|
||||
, frameLock{false}
|
||||
, hasSubscribed{false}
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
qDebug() << "ddd" << minimumSize();
|
||||
setMinimum(128);
|
||||
setSizeHint(128, 128);
|
||||
}
|
||||
|
||||
VideoSurface::VideoSurface(VideoSource *source, QWidget* parent)
|
||||
|
@ -51,7 +53,7 @@ void VideoSurface::setSource(VideoSource *src)
|
|||
source = src;
|
||||
subscribe();
|
||||
}
|
||||
#include <QDebug>
|
||||
/*#include <QDebug>
|
||||
QRect VideoSurface::getRect() const
|
||||
{
|
||||
// Fast lock
|
||||
|
@ -77,7 +79,7 @@ QRect VideoSurface::getRect() const
|
|||
return QRect();
|
||||
}
|
||||
|
||||
QSize VideoSurface::getFrameSize()
|
||||
QSize VideoSurface::getFrameSize() const
|
||||
{
|
||||
// Fast lock
|
||||
{
|
||||
|
@ -93,12 +95,7 @@ QSize VideoSurface::getFrameSize()
|
|||
|
||||
frameLock = false;
|
||||
return frameSize;
|
||||
}
|
||||
|
||||
QSize VideoSurface::sizeHint() const
|
||||
{
|
||||
return getRect().size();
|
||||
}
|
||||
}*/
|
||||
|
||||
void VideoSurface::subscribe()
|
||||
{
|
||||
|
@ -140,6 +137,9 @@ void VideoSurface::onNewFrameAvailable(std::shared_ptr<VideoFrame> newFrame)
|
|||
|
||||
lastFrame = newFrame;
|
||||
frameLock = false;
|
||||
setRatio(lastFrame->getSize().width() / static_cast<float>(lastFrame->getSize().height()));
|
||||
///setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
updateGeometry();
|
||||
update();
|
||||
|
||||
emit drewNewFrame();
|
||||
|
@ -155,22 +155,22 @@ void VideoSurface::paintEvent(QPaintEvent*)
|
|||
}
|
||||
|
||||
QPainter painter(this);
|
||||
//painter.fillRect(painter.viewport(), Qt::black);
|
||||
painter.fillRect(painter.viewport(), QColor(193, 193, 193));
|
||||
if (lastFrame)
|
||||
{
|
||||
QSize frameSize = lastFrame->getSize();
|
||||
/*QSize frameSize = lastFrame->getSize();
|
||||
QRect rect = this->rect();
|
||||
int width = frameSize.width()*rect.height()/frameSize.height();
|
||||
rect.setLeft((rect.width()-width)/2);
|
||||
rect.setWidth(width);
|
||||
rect.setWidth(width);*/
|
||||
|
||||
QImage frame = lastFrame->toQImage(rect.size());
|
||||
painter.drawImage(rect, frame, frame.rect(), Qt::NoFormatConversion);
|
||||
QImage frame = lastFrame->toQImage(rect().size());
|
||||
painter.drawImage(rect(), frame, frame.rect(), Qt::NoFormatConversion);
|
||||
//qDebug() << "VIDEO 2" << rect;
|
||||
}
|
||||
frameLock = false;
|
||||
}
|
||||
#include <QResizeEvent>
|
||||
/*#include <QResizeEvent>
|
||||
void VideoSurface::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
// Locks aspect ratio.
|
||||
|
@ -196,4 +196,4 @@ void VideoSurface::resizeEvent(QResizeEvent* event)
|
|||
int width = ratio*event->size().width();
|
||||
setMaximumHeight(width);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "src/video/videosource.h"
|
||||
#include "src/widget/tool/aspectratiowidget.h"
|
||||
|
||||
class VideoSurface : public QWidget
|
||||
class VideoSurface : public AspectRatioWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -35,10 +36,8 @@ public:
|
|||
~VideoSurface();
|
||||
|
||||
void setSource(VideoSource* src); //NULL is a valid option
|
||||
QRect getRect() const;
|
||||
QSize getFrameSize();
|
||||
|
||||
virtual QSize sizeHint() const override;
|
||||
//QRect getRect() const;
|
||||
//QSize getFrameSize() const;
|
||||
|
||||
signals:
|
||||
void drewNewFrame();
|
||||
|
@ -48,7 +47,7 @@ protected:
|
|||
void unsubscribe();
|
||||
|
||||
virtual void paintEvent(QPaintEvent * event) final override;
|
||||
virtual void resizeEvent(QResizeEvent* event) final override;
|
||||
//virtual void resizeEvent(QResizeEvent* event) final override;
|
||||
|
||||
private slots:
|
||||
void onNewFrameAvailable(std::shared_ptr<VideoFrame> newFrame);
|
||||
|
|
|
@ -119,6 +119,8 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|||
|
||||
retranslateUi();
|
||||
Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this);
|
||||
|
||||
showNetcam();
|
||||
}
|
||||
|
||||
ChatForm::~ChatForm()
|
||||
|
@ -1098,6 +1100,7 @@ void ChatForm::showNetcam()
|
|||
if (!netcam)
|
||||
netcam = new NetCamView();
|
||||
|
||||
//connect(Widget::getInstance(), &Widget::resized, netcam, &NetCamView::updateSize);
|
||||
netcam->show(Core::getInstance()->getVideoSourceFromCall(callId), f->getDisplayedName());
|
||||
connect(netcam, &NetCamView::showMessageClicked, this, &ChatForm::onShowMessagesClicked);
|
||||
bodySplitter->insertWidget(0, netcam);
|
||||
|
|
131
src/widget/tool/aspectratiowidget.cpp
Normal file
131
src/widget/tool/aspectratiowidget.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
Copyright © 2015 by The qTox Project
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
qTox is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
qTox is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "aspectratiowidget.h"
|
||||
#include <QApplication>
|
||||
|
||||
AspectRatioWidget::AspectRatioWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ratioMode{RespectWidth}
|
||||
, ratioWidth{QWIDGETSIZE_MAX}
|
||||
{
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum));
|
||||
setRatio(1.33f);
|
||||
//setSizeHint(64, 64 / 1.33f);
|
||||
size_ = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
}
|
||||
|
||||
float AspectRatioWidget::getRatio() const
|
||||
{
|
||||
return ratio;
|
||||
}
|
||||
|
||||
bool AspectRatioWidget::aspectRatioRespected() const
|
||||
{
|
||||
int w = static_cast<int>(width() / ratio);
|
||||
return height() == w - 1 || height() == w || height() == w + 1;
|
||||
}
|
||||
#include <QDebug>
|
||||
QSize AspectRatioWidget::sizeHint() const
|
||||
{
|
||||
//return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||
return size_;
|
||||
switch (ratioMode)
|
||||
{
|
||||
case RespectWidth:
|
||||
return QSize(ratioWidth, width() / ratio);
|
||||
case RespectHeight:
|
||||
return QSize(height() * ratio, height());
|
||||
case MaximizeSize:
|
||||
default:
|
||||
return QSize(ratioWidth, ratioWidth);
|
||||
}
|
||||
}
|
||||
#include <QDebug>
|
||||
void AspectRatioWidget::setSizeHint(int width, int height)
|
||||
{
|
||||
size_ = QSize(width, height);
|
||||
}
|
||||
|
||||
void AspectRatioWidget::setMinimum(int minimumHieght)
|
||||
{
|
||||
setMinimumSize(minimumHieght * ratio, minimumHieght);
|
||||
}
|
||||
|
||||
void AspectRatioWidget::setRatio(float r)
|
||||
{
|
||||
if (ratio == r)
|
||||
return;
|
||||
|
||||
ratio = r;
|
||||
setMinimum(minimumHeight());
|
||||
}
|
||||
|
||||
void AspectRatioWidget::setRatioMode(RatioMode mode)
|
||||
{
|
||||
ratioMode = mode;
|
||||
|
||||
if (sizeHint().width() > 1)
|
||||
setMaximumWidth(sizeHint().width());
|
||||
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void AspectRatioWidget::setRatioWidth(int w)
|
||||
{
|
||||
ratioWidth = w;
|
||||
}
|
||||
|
||||
void AspectRatioWidgetList::updateAll()
|
||||
{
|
||||
if (isEmpty())
|
||||
return;
|
||||
|
||||
// Maximize the size of all of them, so that they will be equal.
|
||||
for (AspectRatioWidget* aspectWidget : *this)
|
||||
{
|
||||
aspectWidget->setUpdatesEnabled(false);
|
||||
aspectWidget->setRatioMode(AspectRatioWidget::MaximizeSize);
|
||||
}
|
||||
|
||||
// Need this to trigger layout recalculations.
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
|
||||
|
||||
// Now update heights.
|
||||
for (AspectRatioWidget* aspectWidget : *this)
|
||||
aspectWidget->setRatioMode(AspectRatioWidget::RespectWidth);
|
||||
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
|
||||
// if height does not fit, then decrease width.
|
||||
// Query only one. Assumes that all of them are next to each other.
|
||||
if (!at(0)->aspectRatioRespected())
|
||||
{
|
||||
for (AspectRatioWidget* aspectWidget : *this)
|
||||
aspectWidget->setRatioMode(AspectRatioWidget::RespectHeight);
|
||||
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
|
||||
for (AspectRatioWidget* aspectWidget : *this)
|
||||
{
|
||||
aspectWidget->setUpdatesEnabled(true);
|
||||
aspectWidget->update();
|
||||
}
|
||||
}
|
66
src/widget/tool/aspectratiowidget.h
Normal file
66
src/widget/tool/aspectratiowidget.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright © 2015 by The qTox Project
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
qTox is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
qTox is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with qTox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ASPECTRATIOWIDGET_H
|
||||
#define ASPECTRATIOWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class AspectRatioWidgetList;
|
||||
|
||||
class AspectRatioWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AspectRatioWidget(QWidget *parent = 0);
|
||||
float getRatio() const;
|
||||
bool aspectRatioRespected() const;
|
||||
virtual QSize sizeHint() const final override;
|
||||
void setSizeHint(int width, int height);
|
||||
void setMinimum(int minimumHieght);
|
||||
|
||||
protected:
|
||||
enum RatioMode
|
||||
{
|
||||
RespectWidth = 0,
|
||||
RespectHeight = 1,
|
||||
MaximizeSize = 2
|
||||
};
|
||||
|
||||
void setRatio(float r);
|
||||
void setRatioMode(RatioMode mode);
|
||||
void setRatioWidth(int w = QWIDGETSIZE_MAX);
|
||||
|
||||
friend class AspectRatioWidgetList;
|
||||
|
||||
private:
|
||||
RatioMode ratioMode;
|
||||
int ratioWidth;
|
||||
float ratio;
|
||||
QSize size_;
|
||||
};
|
||||
|
||||
class AspectRatioWidgetList : public QVector<AspectRatioWidget*>
|
||||
{
|
||||
public:
|
||||
// Must update all simultaneously.
|
||||
void updateAll();
|
||||
};
|
||||
|
||||
#endif // ASPECTRATIOWIDGET_H
|
|
@ -21,33 +21,45 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QGraphicsOpacityEffect>
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
|
||||
MovableWidget::MovableWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
: AspectRatioWidget(parent)
|
||||
{
|
||||
|
||||
setMouseTracking(true);
|
||||
setRatioWidth(64);
|
||||
setMinimum(64);
|
||||
setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored));
|
||||
resize(minimumSize());
|
||||
actualSize = minimumSize();
|
||||
}
|
||||
#include <QDebug>
|
||||
void MovableWidget::setBoundary(const QRect& boundary, QSize size)
|
||||
|
||||
void MovableWidget::setBoundary(QSize parentSize, QSize oldSize, float xPercent, float yPercent)
|
||||
{
|
||||
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());
|
||||
// NOTE: When called, the parentWidget has not resized yet.
|
||||
|
||||
if (size.isValid())
|
||||
resize(size);
|
||||
// Prevent division with 0.
|
||||
if (width() == oldSize.width() || height() == oldSize.height())
|
||||
return;
|
||||
|
||||
boundaryRect = boundary;
|
||||
widthEdge = boundaryRect.x() - width();
|
||||
checkBoundaryLeft(widthEdge);
|
||||
float percentageX = x() / static_cast<float>(oldSize.width() - width());
|
||||
float percentageY = y() / static_cast<float>(oldSize.height() - height());
|
||||
|
||||
QPoint moveTo = pos();
|
||||
moveTo.setX((abs(widthEdge) * 2 + boundaryRect.width() - width()) * xPercent);
|
||||
moveTo.setY((boundaryRect.height() - height()) * yPercent);
|
||||
checkBoundary(moveTo);
|
||||
actualSize.setWidth(actualSize.width() * xPercent);
|
||||
actualSize.setHeight(actualSize.height() * yPercent);
|
||||
|
||||
if (actualSize.width() == 0)
|
||||
actualSize.setWidth(1);
|
||||
|
||||
if (actualSize.height() == 0)
|
||||
actualSize.setHeight(1);
|
||||
|
||||
resize(QSize(round(actualSize.width()), round(actualSize.height())));
|
||||
updateGeometry();
|
||||
|
||||
actualPos = QPointF(percentageX * (parentSize.width() - width()), percentageY * (parentSize.height() - height()));
|
||||
|
||||
QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y()));
|
||||
move(moveTo);
|
||||
}
|
||||
|
||||
|
@ -55,27 +67,153 @@ void MovableWidget::mousePressEvent(QMouseEvent* event)
|
|||
{
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
moving = true;
|
||||
if (!(mode & Resize))
|
||||
mode |= Moving;
|
||||
|
||||
lastPoint = event->globalPos();
|
||||
}
|
||||
}
|
||||
|
||||
void MovableWidget::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
if (moving)
|
||||
if (mode & Moving)
|
||||
{
|
||||
QPoint moveTo = pos() - (lastPoint - event->globalPos());
|
||||
checkBoundary(moveTo);
|
||||
|
||||
move(moveTo);
|
||||
lastPoint = event->globalPos();
|
||||
|
||||
actualPos = pos();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
{
|
||||
if (event->x() < 6)
|
||||
mode |= ResizeLeft;
|
||||
else
|
||||
mode &= ~ResizeLeft;
|
||||
|
||||
if (event->y() < 6)
|
||||
mode |= ResizeUp;
|
||||
else
|
||||
mode &= ~ResizeUp;
|
||||
|
||||
if (event->x() > width() - 6)
|
||||
mode |= ResizeRight;
|
||||
else
|
||||
mode &= ~ResizeRight;
|
||||
|
||||
if (event->y() > height() - 6)
|
||||
mode |= ResizeDown;
|
||||
else
|
||||
mode &= ~ResizeDown;
|
||||
}
|
||||
|
||||
if (mode & Resize)
|
||||
{
|
||||
const Modes ResizeUpRight = ResizeUp | ResizeRight;
|
||||
const Modes ResizeUpLeft = ResizeUp | ResizeLeft;
|
||||
const Modes ResizeDownRight = ResizeDown | ResizeRight;
|
||||
const Modes ResizeDownLeft = ResizeDown | ResizeLeft;
|
||||
|
||||
if ((mode & ResizeUpRight) == ResizeUpRight || (mode & ResizeDownLeft) == ResizeDownLeft)
|
||||
setCursor(Qt::SizeBDiagCursor);
|
||||
else if ((mode & ResizeUpLeft) == ResizeUpLeft || (mode & ResizeDownRight) == ResizeDownRight)
|
||||
setCursor(Qt::SizeFDiagCursor);
|
||||
else if (mode & (ResizeLeft | ResizeRight))
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
else
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
QPoint lastPosition = pos();
|
||||
QPoint displacement = lastPoint - event->globalPos();
|
||||
QSize lastSize = size();
|
||||
|
||||
|
||||
if (mode & ResizeUp)
|
||||
{
|
||||
lastSize.setHeight(height() + displacement.y());
|
||||
|
||||
if (lastSize.height() > parentWidget()->height() / 2)
|
||||
lastPosition.setY(y() - displacement.y() + (lastSize.height() - parentWidget()->height() / 2));
|
||||
else
|
||||
lastPosition.setY(y() - displacement.y());
|
||||
}
|
||||
|
||||
if (mode & ResizeLeft)
|
||||
{
|
||||
lastSize.setWidth(width() + displacement.x());
|
||||
if (lastSize.width() > parentWidget()->width() / 2)
|
||||
lastPosition.setX(x() - displacement.x() + (lastSize.width() - parentWidget()->width() / 2));
|
||||
else
|
||||
lastPosition.setX(x() - displacement.x());
|
||||
}
|
||||
|
||||
if (mode & ResizeRight)
|
||||
lastSize.setWidth(width() - displacement.x());
|
||||
|
||||
if (mode & ResizeDown)
|
||||
lastSize.setHeight(height() - displacement.y());
|
||||
|
||||
if (lastSize.height() > parentWidget()->height() / 2)
|
||||
lastSize.setHeight(parentWidget()->height() / 2);
|
||||
|
||||
if (lastSize.width() > parentWidget()->width() / 2)
|
||||
lastSize.setWidth(parentWidget()->width() / 2);
|
||||
|
||||
if (mode & (ResizeLeft | ResizeRight))
|
||||
{
|
||||
if (mode & (ResizeUp | ResizeDown))
|
||||
{
|
||||
int height = lastSize.width() / getRatio();
|
||||
|
||||
if (!(mode & ResizeDown))
|
||||
lastPosition.setY(lastPosition.y() - (height - lastSize.height()));
|
||||
|
||||
resize(lastSize.width(), height);
|
||||
|
||||
if (lastSize.width() < minimumWidth())
|
||||
lastPosition.setX(pos().x());
|
||||
|
||||
if (height < minimumHeight())
|
||||
lastPosition.setY(pos().y());
|
||||
}
|
||||
else
|
||||
{
|
||||
resize(lastSize.width(), lastSize.width() / getRatio());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resize(lastSize.height() * getRatio(), lastSize.height());
|
||||
}
|
||||
|
||||
updateGeometry();
|
||||
|
||||
checkBoundary(lastPosition);
|
||||
|
||||
move(lastPosition);
|
||||
|
||||
lastPoint = event->globalPos();
|
||||
actualSize = size();
|
||||
actualPos = pos();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsetCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovableWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if (!(event->buttons() & Qt::LeftButton))
|
||||
moving = false;
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
|
@ -94,12 +232,17 @@ void MovableWidget::mouseDoubleClickEvent(QMouseEvent* event)
|
|||
setGraphicsEffect(nullptr);
|
||||
}
|
||||
}
|
||||
#include <QPainter>
|
||||
void MovableWidget::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setBrush(Qt::black);
|
||||
painter.drawRect(rect());
|
||||
//qDebug() << rect();
|
||||
}
|
||||
|
||||
void MovableWidget::checkBoundary(QPoint& point) const
|
||||
{
|
||||
if (boundaryRect.isNull())
|
||||
return;
|
||||
|
||||
int x1, y1, x2, y2;
|
||||
boundaryRect.getCoords(&x1, &y1, &x2, &y2);
|
||||
|
||||
|
@ -109,14 +252,14 @@ void MovableWidget::checkBoundary(QPoint& point) const
|
|||
|
||||
// Video boundary.
|
||||
|
||||
if (point.y() + height() <y1)
|
||||
/*if (point.y() + height() <y1)
|
||||
point.setY(y1 - height());
|
||||
|
||||
if (point.x() > x2)
|
||||
point.setX(x2);
|
||||
|
||||
if (point.y() > y2)
|
||||
point.setY(y2);
|
||||
point.setY(y2);*/
|
||||
|
||||
// Parent boundary.
|
||||
if (point.y() < 0)
|
||||
|
@ -134,6 +277,6 @@ void MovableWidget::checkBoundaryLeft(int &x) const
|
|||
if (x < 0)
|
||||
x = 0;
|
||||
|
||||
if (x + width() < boundaryRect.x())
|
||||
x = boundaryRect.x() - width();
|
||||
/*if (x + width() < boundaryRect.x())
|
||||
x = boundaryRect.x() - width();*/
|
||||
}
|
||||
|
|
|
@ -21,29 +21,42 @@
|
|||
#define MOVABLEWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "aspectratiowidget.h"
|
||||
|
||||
class MovableWidget : public QWidget
|
||||
class MovableWidget : public AspectRatioWidget
|
||||
{
|
||||
public:
|
||||
MovableWidget(QWidget* parent);
|
||||
void setBoundary(const QRect& boundary, QSize size = QSize());
|
||||
void setBoundary(QSize parentSize, QSize oldSize, float xPercent, float yPercent);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
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;
|
||||
typedef uint8_t Modes;
|
||||
|
||||
enum Mode : Modes
|
||||
{
|
||||
Moving = 0x01,
|
||||
ResizeLeft = 0x02,
|
||||
ResizeRight = 0x04,
|
||||
ResizeUp = 0x08,
|
||||
ResizeDown = 0x10,
|
||||
Resize = ResizeLeft | ResizeRight | ResizeUp | ResizeDown
|
||||
};
|
||||
|
||||
Modes mode = 0;
|
||||
QPoint lastPoint;
|
||||
QRect boundaryRect;
|
||||
QSizeF actualSize;
|
||||
QPointF actualPos;
|
||||
};
|
||||
|
||||
#endif // MOVABLEWIDGET_H
|
||||
|
|
|
@ -210,6 +210,7 @@ void Widget::init()
|
|||
// disable proportional scaling
|
||||
ui->mainSplitter->setStretchFactor(0,0);
|
||||
ui->mainSplitter->setStretchFactor(1,1);
|
||||
qDebug() << ui->mainSplitter->widget(0)->sizePolicy();
|
||||
|
||||
onStatusSet(Status::Offline);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user