mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Video: Initial video when call starts
This commit is contained in:
parent
814bd922ca
commit
50041a3140
3
qtox.pro
3
qtox.pro
|
@ -383,6 +383,7 @@ contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) {
|
|||
src/widget/form/setpassworddialog.cpp \
|
||||
src/widget/form/tabcompleter.cpp \
|
||||
src/ipc.cpp \
|
||||
src/widget/flowlayout.cpp \
|
||||
src/net/autoupdate.cpp \
|
||||
src/widget/tool/callconfirmwidget.cpp \
|
||||
src/widget/systemtrayicon.cpp \
|
||||
|
@ -493,7 +494,6 @@ SOURCES += \
|
|||
src/widget/genericchatitemlayout.cpp \
|
||||
src/widget/categorywidget.cpp \
|
||||
src/widget/tool/movablewidget.cpp \
|
||||
src/widget/tool/flowlayout.cpp \
|
||||
src/video/genericnetcamview.cpp \
|
||||
src/video/groupnetcamview.cpp
|
||||
|
||||
|
@ -540,6 +540,5 @@ HEADERS += \
|
|||
src/widget/genericchatitemlayout.h \
|
||||
src/widget/categorywidget.h \
|
||||
src/widget/tool/movablewidget.h \
|
||||
src/widget/tool/flowlayout.h \
|
||||
src/video/genericnetcamview.h \
|
||||
src/video/groupnetcamview.h
|
||||
|
|
|
@ -227,6 +227,7 @@ void Settings::loadGlobal()
|
|||
s.beginGroup("Video");
|
||||
videoDev = s.value("videoDev", "").toString();
|
||||
camVideoRes = s.value("camVideoRes",QSize()).toSize();
|
||||
camVideoFPS = s.value("camVideoFPS", 0).toUInt();
|
||||
s.endGroup();
|
||||
|
||||
// Read the embedded DHT bootsrap nodes list if needed
|
||||
|
@ -422,6 +423,7 @@ void Settings::saveGlobal()
|
|||
s.beginGroup("Video");
|
||||
s.setValue("videoDev", videoDev);
|
||||
s.setValue("camVideoRes",camVideoRes);
|
||||
s.setValue("camVideoFPS",camVideoFPS);
|
||||
s.endGroup();
|
||||
}
|
||||
|
||||
|
@ -1175,6 +1177,19 @@ void Settings::setCamVideoRes(QSize newValue)
|
|||
camVideoRes = newValue;
|
||||
}
|
||||
|
||||
unsigned short Settings::getCamVideoFPS() const
|
||||
{
|
||||
QMutexLocker locker{&bigLock};
|
||||
return camVideoFPS;
|
||||
}
|
||||
|
||||
void Settings::setCamVideoFPS(unsigned short newValue)
|
||||
{
|
||||
QMutexLocker locker{&bigLock};
|
||||
camVideoFPS = newValue;
|
||||
}
|
||||
|
||||
|
||||
QString Settings::getFriendAdress(const QString &publicKey) const
|
||||
{
|
||||
QMutexLocker locker{&bigLock};
|
||||
|
|
|
@ -163,6 +163,9 @@ public:
|
|||
QSize getCamVideoRes() const;
|
||||
void setCamVideoRes(QSize newValue);
|
||||
|
||||
unsigned short getCamVideoFPS() const;
|
||||
void setCamVideoFPS(unsigned short newValue);
|
||||
|
||||
bool isAnimationEnabled() const;
|
||||
void setAnimationEnabled(bool newValue);
|
||||
|
||||
|
@ -356,6 +359,7 @@ private:
|
|||
// Video
|
||||
QString videoDev;
|
||||
QSize camVideoRes;
|
||||
unsigned short camVideoFPS;
|
||||
|
||||
struct friendProp
|
||||
{
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#include <QTimer>
|
||||
#include <QMap>
|
||||
#include "src/audio/audio.h"
|
||||
|
||||
#include "src/widget/tool/flowlayout.h"
|
||||
#include "src/core/core.h"
|
||||
#include <QBoxLayout>
|
||||
|
||||
class LabeledVideo : public QFrame
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
: QFrame(parent)
|
||||
{
|
||||
//setFrameStyle(QFrame::Box);
|
||||
videoSurface = new VideoSurface(-1, 0, expanding);
|
||||
videoSurface = new VideoSurface(QPixmap(), 0, expanding);
|
||||
videoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
videoSurface->setMinimumHeight(96);
|
||||
//videoSurface->setMaximumHeight(96);
|
||||
|
@ -133,13 +133,13 @@ GroupNetCamView::GroupNetCamView(int group, QWidget *parent)
|
|||
//FlowLayout* horLayout = new FlowLayout(widget);
|
||||
horLayout->addStretch();
|
||||
|
||||
LabeledVideo* labeledVideo = new LabeledVideo(this);
|
||||
horLayout->addWidget(labeledVideo);
|
||||
horLayout->setAlignment(labeledVideo, Qt::AlignCenter | Qt::AlignHCenter);
|
||||
selfVideoSurface = new LabeledVideo(this);
|
||||
horLayout->addWidget(selfVideoSurface);
|
||||
horLayout->setAlignment(selfVideoSurface, Qt::AlignCenter | Qt::AlignHCenter);
|
||||
|
||||
horLayout->addStretch();
|
||||
verLayout->insertWidget(1, scrollArea);
|
||||
scrollArea->setMinimumHeight(labeledVideo->height());
|
||||
scrollArea->setMinimumHeight(selfVideoSurface->height());
|
||||
|
||||
connect(&Audio::getInstance(), &Audio::groupAudioPlayed, this, &GroupNetCamView::groupAudioPlayed);
|
||||
|
||||
|
@ -147,6 +147,18 @@ GroupNetCamView::GroupNetCamView(int group, QWidget *parent)
|
|||
timer->setInterval(1000);
|
||||
connect(timer, &QTimer::timeout, this, &GroupNetCamView::findActivePeer);
|
||||
timer->start();
|
||||
|
||||
connect(Core::getInstance(), &Core::selfAvatarChanged, [this]()
|
||||
{
|
||||
selfVideoSurface->update();
|
||||
findActivePeer();
|
||||
});
|
||||
connect(Core::getInstance(), &Core::usernameSet, [this](const QString& username)
|
||||
{
|
||||
selfVideoSurface->setText(username);
|
||||
findActivePeer();
|
||||
});
|
||||
selfVideoSurface->setText(Core::getInstance()->getUsername());
|
||||
}
|
||||
|
||||
void GroupNetCamView::clearPeers()
|
||||
|
@ -184,18 +196,16 @@ void GroupNetCamView::removePeer(int peer)
|
|||
findActivePeer();
|
||||
}
|
||||
}
|
||||
#include <QDebug>
|
||||
|
||||
void GroupNetCamView::setActive(int peer)
|
||||
{
|
||||
qDebug() << "HI: " << peer;
|
||||
if (peer == -1)
|
||||
{
|
||||
// Show self.
|
||||
videoLabelSurface->setText(selfVideoSurface->getText());
|
||||
return;
|
||||
}
|
||||
|
||||
auto peerVideo = videoList.find(peer);
|
||||
qDebug() << "BTW" << (peerVideo == videoList.end());
|
||||
|
||||
if (peerVideo != videoList.end())
|
||||
{
|
||||
|
|
|
@ -52,6 +52,7 @@ private:
|
|||
QHBoxLayout* horLayout;
|
||||
QMap<int, PeerVideo> videoList;
|
||||
LabeledVideo* videoLabelSurface;
|
||||
LabeledVideo* selfVideoSurface;
|
||||
int activePeer;
|
||||
int group;
|
||||
};
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
|
||||
#include "netcamview.h"
|
||||
#include "camerasource.h"
|
||||
#include "src/friend.h"
|
||||
#include "src/friendlist.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/video/videosurface.h"
|
||||
#include "src/widget/tool/movablewidget.h"
|
||||
#include "src/persistence/settings.h"
|
||||
#include <QLabel>
|
||||
#include <QBoxLayout>
|
||||
#include <QFrame>
|
||||
|
@ -30,13 +33,14 @@ NetCamView::NetCamView(int friendId, QWidget* parent)
|
|||
: GenericNetCamView(parent)
|
||||
, selfFrame{nullptr}
|
||||
{
|
||||
videoSurface = new VideoSurface(friendId, this);
|
||||
QString id = FriendList::findFriend(friendId)->getToxId().toString();
|
||||
videoSurface = new VideoSurface(Settings::getInstance().getSavedAvatar(id), this);
|
||||
videoSurface->setMinimumHeight(256);
|
||||
videoSurface->setContentsMargins(6, 6, 6, 6);
|
||||
|
||||
verLayout->insertWidget(0, videoSurface, 1);
|
||||
|
||||
selfVideoSurface = new VideoSurface(-1, this, true);
|
||||
selfVideoSurface = new VideoSurface(Settings::getInstance().getSavedAvatar(Core::getInstance()->getSelfId().toString()), this, true);
|
||||
selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
|
||||
selfVideoSurface->setMouseTracking(true);
|
||||
selfVideoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
@ -65,6 +69,13 @@ NetCamView::NetCamView(int friendId, QWidget* parent)
|
|||
updateFrameSize(boundingRect.size());
|
||||
selfFrame->resetBoundary(boundingRect);
|
||||
});
|
||||
|
||||
VideoMode videoMode;
|
||||
QSize videoSize = Settings::getInstance().getCamVideoRes();
|
||||
videoMode.width = videoSize.width();
|
||||
videoMode.height = videoSize.height();
|
||||
videoMode.FPS = Settings::getInstance().getCamVideoFPS();
|
||||
CameraSource::getInstance().open(Settings::getInstance().getVideoDev(), videoMode);
|
||||
}
|
||||
|
||||
void NetCamView::show(VideoSource *source, const QString &title)
|
||||
|
|
|
@ -32,20 +32,20 @@ float getSizeRatio(const QSize size)
|
|||
return size.width() / static_cast<float>(size.height());
|
||||
}
|
||||
|
||||
VideoSurface::VideoSurface(int friendId, QWidget* parent, bool expanding)
|
||||
VideoSurface::VideoSurface(const QPixmap& avatar, QWidget* parent, bool expanding)
|
||||
: QWidget{parent}
|
||||
, source{nullptr}
|
||||
, frameLock{false}
|
||||
, hasSubscribed{0}
|
||||
, friendId{friendId}
|
||||
, avatar{avatar}
|
||||
, ratio{1.0f}
|
||||
, expanding{expanding}
|
||||
{
|
||||
recalulateBounds();
|
||||
}
|
||||
|
||||
VideoSurface::VideoSurface(int friendId, VideoSource *source, QWidget* parent)
|
||||
: VideoSurface(friendId, parent)
|
||||
VideoSurface::VideoSurface(const QPixmap& avatar, VideoSource *source, QWidget* parent)
|
||||
: VideoSurface(avatar, parent)
|
||||
{
|
||||
setSource(source);
|
||||
}
|
||||
|
@ -82,6 +82,16 @@ float VideoSurface::getRatio() const
|
|||
return ratio;
|
||||
}
|
||||
|
||||
void VideoSurface::setAvatar(const QPixmap &pixmap)
|
||||
{
|
||||
avatar = pixmap;
|
||||
}
|
||||
|
||||
QPixmap VideoSurface::getAvatar() const
|
||||
{
|
||||
return avatar;
|
||||
}
|
||||
|
||||
void VideoSurface::subscribe()
|
||||
{
|
||||
assert(hasSubscribed >= 0);
|
||||
|
@ -154,21 +164,12 @@ void VideoSurface::paintEvent(QPaintEvent*)
|
|||
else
|
||||
{
|
||||
painter.fillRect(boundingRect, Qt::white);
|
||||
QPixmap avatar;
|
||||
QPixmap drawnAvatar = avatar;
|
||||
|
||||
QString userId;
|
||||
if (drawnAvatar.isNull())
|
||||
drawnAvatar = Style::scaleSvgImage(":/img/contact_dark.svg", boundingRect.width(), boundingRect.height());
|
||||
|
||||
if (friendId != -1)
|
||||
userId = FriendList::findFriend(friendId)->getToxId().toString();
|
||||
else
|
||||
userId = Core::getInstance()->getSelfId().toString();
|
||||
|
||||
avatar = Settings::getInstance().getSavedAvatar(userId);
|
||||
|
||||
if (avatar.isNull())
|
||||
avatar = Style::scaleSvgImage(":/img/contact_dark.svg", boundingRect.width(), boundingRect.height());
|
||||
|
||||
painter.drawPixmap(boundingRect, avatar, avatar.rect());
|
||||
painter.drawPixmap(boundingRect, drawnAvatar, drawnAvatar.rect());
|
||||
}
|
||||
|
||||
unlock();
|
||||
|
@ -185,7 +186,7 @@ void VideoSurface::showEvent(QShowEvent*)
|
|||
{
|
||||
//emit ratioChanged();
|
||||
}
|
||||
#include <QDebug>
|
||||
|
||||
void VideoSurface::recalulateBounds()
|
||||
{
|
||||
if (expanding)
|
||||
|
@ -209,8 +210,6 @@ void VideoSurface::recalulateBounds()
|
|||
boundingRect.setRect(pos.x(), pos.y(), size.width(), size.height());
|
||||
}
|
||||
|
||||
qDebug() << contentsRect();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,14 +30,16 @@ class VideoSurface : public QWidget
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
VideoSurface(int friendId, QWidget* parent = 0, bool expanding = false);
|
||||
VideoSurface(int friendId, VideoSource* source, QWidget* parent = 0);
|
||||
VideoSurface(const QPixmap& avatar, QWidget* parent = 0, bool expanding = false);
|
||||
VideoSurface(const QPixmap& avatar, VideoSource* source, QWidget* parent = 0);
|
||||
~VideoSurface();
|
||||
|
||||
bool isExpanding() const;
|
||||
void setSource(VideoSource* src); //NULL is a valid option
|
||||
QRect getBoundingRect() const;
|
||||
float getRatio() const;
|
||||
void setAvatar(const QPixmap& pixmap);
|
||||
QPixmap getAvatar() const;
|
||||
|
||||
signals:
|
||||
void ratioChanged();
|
||||
|
@ -64,7 +66,7 @@ private:
|
|||
std::shared_ptr<VideoFrame> lastFrame;
|
||||
std::atomic_bool frameLock; ///< Fast lock for lastFrame
|
||||
uint8_t hasSubscribed;
|
||||
int friendId;
|
||||
QPixmap avatar;
|
||||
float ratio;
|
||||
bool expanding;
|
||||
};
|
||||
|
|
|
@ -102,6 +102,7 @@ void AVForm::on_videoModescomboBox_currentIndexChanged(int index)
|
|||
QString devName = videoDeviceList[devIndex].first;
|
||||
VideoMode mode = videoModes[index];
|
||||
Settings::getInstance().setCamVideoRes(QSize(mode.width, mode.height));
|
||||
Settings::getInstance().setCamVideoFPS(mode.FPS);
|
||||
camera.open(devName, mode);
|
||||
}
|
||||
|
||||
|
@ -123,10 +124,11 @@ void AVForm::updateVideoModes(int curIndex)
|
|||
bodyUI->videoModescomboBox->clear();
|
||||
int prefResIndex = -1;
|
||||
QSize prefRes = Settings::getInstance().getCamVideoRes();
|
||||
unsigned short prefFPS = Settings::getInstance().getCamVideoFPS();
|
||||
for (int i=0; i<videoModes.size(); ++i)
|
||||
{
|
||||
VideoMode mode = videoModes[i];
|
||||
if (mode.width==prefRes.width() && mode.height==prefRes.height() && prefResIndex==-1)
|
||||
if (mode.width==prefRes.width() && mode.height==prefRes.height() && mode.FPS == prefFPS && prefResIndex==-1)
|
||||
prefResIndex = i;
|
||||
QString str;
|
||||
if (mode.height && mode.width)
|
||||
|
@ -192,9 +194,11 @@ void AVForm::onVideoDevChanged(int index)
|
|||
updateVideoModes(index);
|
||||
bodyUI->videoModescomboBox->blockSignals(previouslyBlocked);
|
||||
camera.open(dev);
|
||||
killVideoSurface();
|
||||
createVideoSurface();
|
||||
}
|
||||
|
||||
void AVForm::onResProbingFinished(QList<QSize> res)
|
||||
/*void AVForm::onResProbingFinished(QList<QSize> res)
|
||||
{
|
||||
QSize savedRes = Settings::getInstance().getCamVideoRes();
|
||||
int savedResIndex = -1;
|
||||
|
@ -215,7 +219,7 @@ void AVForm::onResProbingFinished(QList<QSize> res)
|
|||
bodyUI->videoModescomboBox->setCurrentIndex(savedResIndex);
|
||||
else
|
||||
bodyUI->videoModescomboBox->setCurrentIndex(bodyUI->videoModescomboBox->count()-1);
|
||||
}
|
||||
}*/
|
||||
|
||||
void AVForm::hideEvent(QHideEvent *)
|
||||
{
|
||||
|
@ -242,7 +246,7 @@ void AVForm::getVideoDevices()
|
|||
videoDevIndex = bodyUI->videoDevCombobox->count()-1;
|
||||
}
|
||||
//addItem changes currentIndex -> reset
|
||||
bodyUI->videoDevCombobox->setCurrentIndex(-1);
|
||||
//bodyUI->videoDevCombobox->setCurrentIndex(-1);
|
||||
bodyUI->videoDevCombobox->setCurrentIndex(videoDevIndex);
|
||||
bodyUI->videoDevCombobox->blockSignals(false);
|
||||
updateVideoModes(videoDevIndex);
|
||||
|
@ -361,7 +365,7 @@ void AVForm::createVideoSurface()
|
|||
{
|
||||
if (camVideoSurface)
|
||||
return;
|
||||
camVideoSurface = new VideoSurface(-1, bodyUI->CamFrame);
|
||||
camVideoSurface = new VideoSurface(QPixmap(), bodyUI->CamFrame);
|
||||
camVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
|
||||
camVideoSurface->setMinimumSize(QSize(160, 120));
|
||||
camVideoSurface->setSource(&camera);
|
||||
|
|
|
@ -63,7 +63,7 @@ private slots:
|
|||
|
||||
// camera
|
||||
void onVideoDevChanged(int index);
|
||||
void onResProbingFinished(QList<QSize> res);
|
||||
//void onResProbingFinished(QList<QSize> res);
|
||||
|
||||
virtual void hideEvent(QHideEvent*) final override;
|
||||
virtual void showEvent(QShowEvent*) final override;
|
||||
|
|
|
@ -1,190 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
#include "flowlayout.h"
|
||||
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
|
||||
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
|
||||
: m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::~FlowLayout()
|
||||
{
|
||||
QLayoutItem *item;
|
||||
while ((item = takeAt(0)))
|
||||
delete item;
|
||||
}
|
||||
|
||||
void FlowLayout::addItem(QLayoutItem *item)
|
||||
{
|
||||
itemList.append(item);
|
||||
}
|
||||
|
||||
int FlowLayout::horizontalSpacing() const
|
||||
{
|
||||
if (m_hSpace >= 0) {
|
||||
return m_hSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
|
||||
}
|
||||
}
|
||||
|
||||
int FlowLayout::verticalSpacing() const
|
||||
{
|
||||
if (m_vSpace >= 0) {
|
||||
return m_vSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
|
||||
}
|
||||
}
|
||||
|
||||
int FlowLayout::count() const
|
||||
{
|
||||
return itemList.size();
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::itemAt(int index) const
|
||||
{
|
||||
return itemList.value(index);
|
||||
}
|
||||
|
||||
QLayoutItem *FlowLayout::takeAt(int index)
|
||||
{
|
||||
if (index >= 0 && index < itemList.size())
|
||||
return itemList.takeAt(index);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Qt::Orientations FlowLayout::expandingDirections() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FlowLayout::hasHeightForWidth() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int FlowLayout::heightForWidth(int width) const
|
||||
{
|
||||
int height = doLayout(QRect(0, 0, width, 0), true);
|
||||
return height;
|
||||
}
|
||||
|
||||
void FlowLayout::setGeometry(const QRect &rect)
|
||||
{
|
||||
QLayout::setGeometry(rect);
|
||||
doLayout(rect, false);
|
||||
}
|
||||
|
||||
QSize FlowLayout::sizeHint() const
|
||||
{
|
||||
return minimumSize();
|
||||
}
|
||||
|
||||
QSize FlowLayout::minimumSize() const
|
||||
{
|
||||
QSize size;
|
||||
QLayoutItem *item;
|
||||
foreach (item, itemList)
|
||||
size = size.expandedTo(item->minimumSize());
|
||||
|
||||
size += QSize(2*margin(), 2*margin());
|
||||
return size;
|
||||
}
|
||||
|
||||
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
|
||||
{
|
||||
int left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
|
||||
int x = effectiveRect.x();
|
||||
int y = effectiveRect.y();
|
||||
int lineHeight = 0;
|
||||
|
||||
QLayoutItem *item;
|
||||
foreach (item, itemList) {
|
||||
QWidget *wid = item->widget();
|
||||
int spaceX = horizontalSpacing();
|
||||
if (spaceX == -1)
|
||||
spaceX = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
|
||||
int spaceY = verticalSpacing();
|
||||
if (spaceY == -1)
|
||||
spaceY = wid->style()->layoutSpacing(
|
||||
QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
|
||||
int nextX = x + item->sizeHint().width() + spaceX;
|
||||
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
|
||||
x = effectiveRect.x();
|
||||
y = y + lineHeight + spaceY;
|
||||
nextX = x + item->sizeHint().width() + spaceX;
|
||||
lineHeight = 0;
|
||||
}
|
||||
|
||||
if (!testOnly)
|
||||
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
|
||||
x = nextX;
|
||||
lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||
}
|
||||
return y + lineHeight - rect.y() + bottom;
|
||||
}
|
||||
|
||||
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
|
||||
{
|
||||
QObject *parent = this->parent();
|
||||
if (!parent) {
|
||||
return -1;
|
||||
} else if (parent->isWidgetType()) {
|
||||
QWidget *pw = static_cast<QWidget *>(parent);
|
||||
return pw->style()->pixelMetric(pm, 0, pw);
|
||||
} else {
|
||||
return static_cast<QLayout *>(parent)->spacing();
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FLOWLAYOUT_H
|
||||
#define FLOWLAYOUT_H
|
||||
|
||||
#include <QLayout>
|
||||
#include <QRect>
|
||||
#include <QStyle>
|
||||
class FlowLayout : public QLayout
|
||||
{
|
||||
public:
|
||||
explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
~FlowLayout();
|
||||
|
||||
void addItem(QLayoutItem *item) Q_DECL_OVERRIDE;
|
||||
int horizontalSpacing() const;
|
||||
int verticalSpacing() const;
|
||||
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
|
||||
bool hasHeightForWidth() const Q_DECL_OVERRIDE;
|
||||
int heightForWidth(int) const Q_DECL_OVERRIDE;
|
||||
int count() const Q_DECL_OVERRIDE;
|
||||
QLayoutItem *itemAt(int index) const Q_DECL_OVERRIDE;
|
||||
QSize minimumSize() const Q_DECL_OVERRIDE;
|
||||
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
|
||||
QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
QLayoutItem *takeAt(int index) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
int doLayout(const QRect &rect, bool testOnly) const;
|
||||
int smartSpacing(QStyle::PixelMetric pm) const;
|
||||
|
||||
QList<QLayoutItem *> itemList;
|
||||
int m_hSpace;
|
||||
int m_vSpace;
|
||||
};
|
||||
|
||||
#endif // FLOWLAYOUT_H
|
Loading…
Reference in New Issue
Block a user