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

Video: Group audio view avatars

This commit is contained in:
TheSpiritXIII 2015-08-18 13:40:11 -04:00
parent 1522d3848c
commit 814bd922ca
24 changed files with 916 additions and 219 deletions

View File

@ -357,7 +357,6 @@ contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) {
src/widget/form/loadhistorydialog.h \ src/widget/form/loadhistorydialog.h \
src/widget/form/setpassworddialog.h \ src/widget/form/setpassworddialog.h \
src/widget/form/tabcompleter.h \ src/widget/form/tabcompleter.h \
src/widget/flowlayout.h \
src/ipc.h \ src/ipc.h \
src/net/autoupdate.h \ src/net/autoupdate.h \
src/widget/tool/callconfirmwidget.h \ src/widget/tool/callconfirmwidget.h \
@ -383,7 +382,6 @@ contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) {
src/widget/form/loadhistorydialog.cpp \ src/widget/form/loadhistorydialog.cpp \
src/widget/form/setpassworddialog.cpp \ src/widget/form/setpassworddialog.cpp \
src/widget/form/tabcompleter.cpp \ src/widget/form/tabcompleter.cpp \
src/widget/flowlayout.cpp \
src/ipc.cpp \ src/ipc.cpp \
src/net/autoupdate.cpp \ src/net/autoupdate.cpp \
src/widget/tool/callconfirmwidget.cpp \ src/widget/tool/callconfirmwidget.cpp \
@ -494,7 +492,10 @@ SOURCES += \
src/widget/friendlistlayout.cpp \ src/widget/friendlistlayout.cpp \
src/widget/genericchatitemlayout.cpp \ src/widget/genericchatitemlayout.cpp \
src/widget/categorywidget.cpp \ src/widget/categorywidget.cpp \
src/widget/tool/movablewidget.cpp src/widget/tool/movablewidget.cpp \
src/widget/tool/flowlayout.cpp \
src/video/genericnetcamview.cpp \
src/video/groupnetcamview.cpp
HEADERS += \ HEADERS += \
src/audio/audio.h \ src/audio/audio.h \
@ -538,4 +539,7 @@ HEADERS += \
src/widget/friendlistlayout.h \ src/widget/friendlistlayout.h \
src/widget/genericchatitemlayout.h \ src/widget/genericchatitemlayout.h \
src/widget/categorywidget.h \ src/widget/categorywidget.h \
src/widget/tool/movablewidget.h src/widget/tool/movablewidget.h \
src/widget/tool/flowlayout.h \
src/video/genericnetcamview.h \
src/video/groupnetcamview.h

View File

@ -270,7 +270,7 @@ void Audio::playMono16Sound(const QByteArray& data)
alSourcePlay(alMainSource); alSourcePlay(alMainSource);
alDeleteBuffers(1, &buffer); alDeleteBuffers(1, &buffer);
} }
#include <QDebug>
void Audio::playGroupAudioQueued(Tox*,int group, int peer, const int16_t* data, void Audio::playGroupAudioQueued(Tox*,int group, int peer, const int16_t* data,
unsigned samples, uint8_t channels, unsigned sample_rate, void* core) unsigned samples, uint8_t channels, unsigned sample_rate, void* core)
{ {
@ -298,6 +298,13 @@ void Audio::playGroupAudio(int group, int peer, const int16_t* data,
alSourcef(call.alSources[peer], AL_GAIN, outputVolume); alSourcef(call.alSources[peer], AL_GAIN, outputVolume);
} }
size_t volume = 0;//data[1];
int bufsize = samples * 2 * channels;
for (int i = 0; i < bufsize; ++i)
volume += abs(data[i]);//std::max(volume, data[i]);
emit groupAudioPlayed(group, peer, volume / static_cast<float>(bufsize));
playAudioBuffer(call.alSources[peer], data, samples, channels, sample_rate); playAudioBuffer(call.alSources[peer], data, samples, channels, sample_rate);
} }

View File

@ -41,7 +41,7 @@ class QMutex;
struct Tox; struct Tox;
class AudioFilterer; class AudioFilterer;
class Audio : QObject class Audio : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -81,6 +81,9 @@ public slots:
void playGroupAudio(int group, int peer, const int16_t* data, void playGroupAudio(int group, int peer, const int16_t* data,
unsigned samples, uint8_t channels, unsigned sample_rate); unsigned samples, uint8_t channels, unsigned sample_rate);
signals:
void groupAudioPlayed(int group, int peer, unsigned short volume);
private: private:
explicit Audio()=default; explicit Audio()=default;
~Audio(); ~Audio();

View File

@ -75,12 +75,13 @@ void Group::updatePeer(int peerId, QString name)
QString toxid = id.publicKey; QString toxid = id.publicKey;
peers[peerId] = name; peers[peerId] = name;
toxids[toxid] = name; toxids[toxid] = name;
Friend *f = FriendList::findFriend(id); // I don't know what this is doing here but it changes back to the old name.
/*Friend *f = FriendList::findFriend(id);
if (f) if (f)
{ {
peers[peerId] = f->getDisplayedName(); peers[peerId] = f->getDisplayedName();
toxids[toxid] = f->getDisplayedName(); toxids[toxid] = f->getDisplayedName();
} }*/
widget->onUserListChanged(); widget->onUserListChanged();
chatForm->onUserListChanged(); chatForm->onUserListChanged();

View File

@ -276,8 +276,8 @@ int main(int argc, char *argv[])
logFile = nullptr; logFile = nullptr;
#endif #endif
CameraSource::destroyInstance();
Nexus::destroyInstance(); Nexus::destroyInstance();
CameraSource::destroyInstance();
Settings::destroyInstance(); Settings::destroyInstance();
qDebug() << "Clean exit with status"<<errorcode; qDebug() << "Clean exit with status"<<errorcode;
return errorcode; return errorcode;

View File

@ -0,0 +1,69 @@
/*
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 "genericnetcamview.h"
#include <QBoxLayout>
#include <QPushButton>
#include <QFrame>
GenericNetCamView::GenericNetCamView(QWidget *parent)
: QWidget(parent)
{
verLayout = new QVBoxLayout(this);
setWindowTitle(tr("Tox video"));
int spacing = verLayout->spacing();
verLayout->setSpacing(0);
QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addStretch();
button = new QPushButton();
buttonLayout->addWidget(button);
connect(button, &QPushButton::clicked, this, &GenericNetCamView::showMessageClicked);
verLayout->addSpacing(spacing);
verLayout->addLayout(buttonLayout);
verLayout->addSpacing(spacing);
QFrame* lineFrame = new QFrame(this);
lineFrame->setStyleSheet("border: 1px solid #c1c1c1;");
lineFrame->setFrameShape(QFrame::HLine);
lineFrame->setMaximumHeight(1);
verLayout->addWidget(lineFrame);
setShowMessages(false);
setStyleSheet("NetCamView { background-color: #c1c1c1; }");
}
void GenericNetCamView::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());
}
}

View File

@ -0,0 +1,49 @@
/*
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 GENERICNETCAMVIEW_H
#define GENERICNETCAMVIEW_H
#include <QWidget>
class VideoSurface;
class QPushButton;
class QVBoxLayout;
class GenericNetCamView : public QWidget
{
Q_OBJECT
public:
GenericNetCamView(QWidget* parent);
signals:
void showMessageClicked();
public slots:
void setShowMessages(bool show, bool notify = false);
protected:
QVBoxLayout* verLayout;
VideoSurface* videoSurface;
private:
QPushButton* button;
};
#endif // GENERICNETCAMVIEW_H

View File

@ -0,0 +1,235 @@
/*
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 "groupnetcamview.h"
#include "src/widget/tool/croppinglabel.h"
#include "src/video/videosurface.h"
#include <QScrollArea>
#include <QTimer>
#include <QMap>
#include "src/audio/audio.h"
#include "src/widget/tool/flowlayout.h"
class LabeledVideo : public QFrame
{
public:
LabeledVideo(QWidget* parent = 0, bool expanding = true)
: QFrame(parent)
{
//setFrameStyle(QFrame::Box);
videoSurface = new VideoSurface(-1, 0, expanding);
videoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
videoSurface->setMinimumHeight(96);
//videoSurface->setMaximumHeight(96);
connect(videoSurface, &VideoSurface::ratioChanged, this, &LabeledVideo::updateSize);
label = new CroppingLabel(this);
label->setText("Unknown");
label->setTextFormat(Qt::PlainText);
label->setStyleSheet("color: white");
//label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
//qDebug() << label->sizePolicy();
label->setAlignment(Qt::AlignCenter);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(videoSurface, 1);
layout->addWidget(label);
setMouseTracking(true);
}
~LabeledVideo()
{
}
VideoSurface* getVideoSurface() const
{
return videoSurface;
}
void setText(const QString& text)
{
label->setText(text);
}
QString getText() const
{
return label->text();
}
protected:
void resizeEvent(QResizeEvent* event) final override
{
QWidget::resizeEvent(event);
updateSize();
}
void mousePressEvent(QMouseEvent* event) final override
{
if (videoSurface->isExpanding())
{
setStyleSheet("QFrame { background-color: #414141; border-radius: 10px; }");
selected = true;
}
}
private slots:
void updateSize()
{
if (videoSurface->isExpanding())
{
int width = videoSurface->height() * videoSurface->getRatio();
videoSurface->setFixedWidth(width);
setMaximumWidth(width + layout()->margin() * 2);
}
}
private:
CroppingLabel* label;
VideoSurface* videoSurface;
bool selected = false;
};
GroupNetCamView::GroupNetCamView(int group, QWidget *parent)
: GenericNetCamView(parent)
, group(group)
{
videoLabelSurface = new LabeledVideo(this, false);
videoSurface = videoLabelSurface->getVideoSurface();
//videoSurface->setExpanding(false);
videoSurface->setMinimumHeight(256);
videoSurface->setContentsMargins(6, 6, 6, 6);
videoLabelSurface->setContentsMargins(0, 0, 0, 0);
videoLabelSurface->layout()->setMargin(0);
videoLabelSurface->setStyleSheet("QFrame { background-color: black; }");
verLayout->insertWidget(0, videoLabelSurface, 1);
QScrollArea* scrollArea = new QScrollArea();
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setStyleSheet("QScrollArea { background-color: black; }");
scrollArea->setFrameStyle(QFrame::NoFrame);
QWidget* widget = new QWidget(nullptr);
scrollArea->setWidget(widget);
scrollArea->setWidgetResizable(true);
horLayout = new QHBoxLayout(widget);
//FlowLayout* horLayout = new FlowLayout(widget);
horLayout->addStretch();
LabeledVideo* labeledVideo = new LabeledVideo(this);
horLayout->addWidget(labeledVideo);
horLayout->setAlignment(labeledVideo, Qt::AlignCenter | Qt::AlignHCenter);
horLayout->addStretch();
verLayout->insertWidget(1, scrollArea);
scrollArea->setMinimumHeight(labeledVideo->height());
connect(&Audio::getInstance(), &Audio::groupAudioPlayed, this, &GroupNetCamView::groupAudioPlayed);
QTimer* timer = new QTimer(this);
timer->setInterval(1000);
connect(timer, &QTimer::timeout, this, &GroupNetCamView::findActivePeer);
timer->start();
}
void GroupNetCamView::clearPeers()
{
QList<int> keys = videoList.keys();
for (int &i : keys)
removePeer(i);
}
void GroupNetCamView::addPeer(int peer, const QString& name)
{
LabeledVideo* labeledVideo = new LabeledVideo(this);
labeledVideo->setText(name);
horLayout->insertWidget(horLayout->count() - 1, labeledVideo);
horLayout->setAlignment(labeledVideo, Qt::AlignCenter | Qt::AlignHCenter);
PeerVideo peerVideo;
peerVideo.video = labeledVideo;
videoList.insert(peer, peerVideo);
findActivePeer();
}
void GroupNetCamView::removePeer(int peer)
{
auto peerVideo = videoList.find(peer);
if (peerVideo != videoList.end())
{
LabeledVideo* labeledVideo = peerVideo.value().video;
horLayout->removeWidget(labeledVideo);
labeledVideo->deleteLater();
videoList.remove(peer);
findActivePeer();
}
}
#include <QDebug>
void GroupNetCamView::setActive(int peer)
{
qDebug() << "HI: " << peer;
if (peer == -1)
{
// Show self.
return;
}
auto peerVideo = videoList.find(peer);
qDebug() << "BTW" << (peerVideo == videoList.end());
if (peerVideo != videoList.end())
{
// When group video exists:
// videoSurface->setSource(peerVideo.value()->getVideoSurface()->source);
videoLabelSurface->setText(peerVideo.value().video->getText());
}
}
void GroupNetCamView::groupAudioPlayed(int Group, int peer, unsigned short volume)
{
if (group != Group)
return;
auto peerVideo = videoList.find(peer);
if (peerVideo != videoList.end())
peerVideo.value().volume = volume;
}
void GroupNetCamView::findActivePeer()
{
int candidate = -1;
int maximum = 0;
for (auto peer = videoList.begin(); peer != videoList.end(); ++peer)
{
if (peer.value().volume > maximum)
{
maximum = peer.value().volume;
candidate = peer.key();
}
}
setActive(candidate);
}

View File

@ -0,0 +1,59 @@
/*
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 GROUPNETCAMVIEW_H
#define GROUPNETCAMVIEW_H
#include "genericnetcamview.h"
#include <QMap>
class LabeledVideo;
class QHBoxLayout;
class GroupNetCamView : public GenericNetCamView
{
public:
GroupNetCamView(int group, QWidget* parent = 0);
void clearPeers();
void addPeer(int peer, const QString &name);
void removePeer(int peer);
public slots:
void groupAudioPlayed(int group, int peer, unsigned short volume);
private slots:
void findActivePeer();
private:
struct PeerVideo
{
LabeledVideo* video;
unsigned short volume = 0;
};
void setActive(int peer);
QHBoxLayout* horLayout;
QMap<int, PeerVideo> videoList;
LabeledVideo* videoLabelSurface;
int activePeer;
int group;
};
#endif // GROUPNETCAMVIEW_H

View File

@ -1,5 +1,5 @@
/* /*
Copyright © 2014 by The qTox Project Copyright © 2014-2015 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox. This file is part of qTox, a Qt-based graphical interface for Tox.
@ -24,81 +24,55 @@
#include "src/widget/tool/movablewidget.h" #include "src/widget/tool/movablewidget.h"
#include <QLabel> #include <QLabel>
#include <QBoxLayout> #include <QBoxLayout>
#include <QPushButton>
#include <QFrame> #include <QFrame>
NetCamView::NetCamView(int friendId, QWidget* parent) NetCamView::NetCamView(int friendId, QWidget* parent)
: QWidget(parent) : GenericNetCamView(parent)
, mainLayout(new QHBoxLayout())
, selfFrame{nullptr} , selfFrame{nullptr}
{ {
QVBoxLayout* layout = new QVBoxLayout(this);
setWindowTitle(tr("Tox video"));
videoSurface = new VideoSurface(friendId, this); videoSurface = new VideoSurface(friendId, this);
videoSurface->setStyleSheet("background-color: blue;");
videoSurface->setMinimumHeight(256); videoSurface->setMinimumHeight(256);
videoSurface->setContentsMargins(6, 6, 6, 6); videoSurface->setContentsMargins(6, 6, 6, 6);
mainLayout->addWidget(videoSurface, 1); verLayout->insertWidget(0, videoSurface, 1);
selfFrame = new MovableWidget(videoSurface); selfVideoSurface = new VideoSurface(-1, this, true);
selfFrame->show();
selfVideoSurface = new VideoSurface(-1, selfFrame);
selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface")); selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
selfVideoSurface->setMouseTracking(true); selfVideoSurface->setMouseTracking(true);
selfVideoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); selfVideoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
selfFrame = new MovableWidget(videoSurface);
selfFrame->show();
QHBoxLayout* frameLayout = new QHBoxLayout(selfFrame); QHBoxLayout* frameLayout = new QHBoxLayout(selfFrame);
frameLayout->addWidget(selfVideoSurface); frameLayout->addWidget(selfVideoSurface);
frameLayout->setMargin(0); frameLayout->setMargin(0);
connect(&CameraSource::getInstance(), &CameraSource::deviceOpened, [this]() updateRatio();
{ connect(selfVideoSurface, &VideoSurface::ratioChanged, this, &NetCamView::updateRatio);
//qDebug() << "Device changed";
//selfFrame->setRatio(selfVideoSurface->getRatio());
//selfFrame->resetBoundary();
//connect(selfVideoSurface, &VideoSurface::drewNewFrame, this, &NetCamView::updateSize);
});
connect(selfVideoSurface, &VideoSurface::ratioChanged, [this]()
{
qDebug() << "Ratio changed";
selfFrame->setRatio(selfVideoSurface->getRatio());
});
connect(videoSurface, &VideoSurface::boundaryChanged, [this]() connect(videoSurface, &VideoSurface::boundaryChanged, [this]()
{ {
selfFrame->setBoundary(videoSurface->getBoundingRect()); QRect boundingRect = videoSurface->getBoundingRect();
updateFrameSize(boundingRect.size());
selfFrame->setBoundary(boundingRect);
}); });
QHBoxLayout* buttonLayout = new QHBoxLayout(); connect(videoSurface, &VideoSurface::ratioChanged, [this]()
buttonLayout->addStretch(); {
button = new QPushButton(); selfFrame->setMinimumWidth(selfFrame->minimumHeight() * selfVideoSurface->getRatio());
buttonLayout->addWidget(button); QRect boundingRect = videoSurface->getBoundingRect();
connect(button, &QPushButton::clicked, this, &NetCamView::showMessageClicked); updateFrameSize(boundingRect.size());
selfFrame->resetBoundary(boundingRect);
layout->addLayout(mainLayout, 1); });
layout->addLayout(buttonLayout);
QFrame* lineFrame = new QFrame(this);
lineFrame->setStyleSheet("border: 1px solid #c1c1c1;");
lineFrame->setFrameShape(QFrame::HLine);
lineFrame->setMaximumHeight(1);
layout->addWidget(lineFrame);
setShowMessages(false);
setStyleSheet("NetCamView { background-color: #c1c1c1; }");
} }
void NetCamView::show(VideoSource *source, const QString &title) void NetCamView::show(VideoSource *source, const QString &title)
{ {
setSource(source); setSource(source);
selfVideoSurface->setSource(&CameraSource::getInstance()); selfVideoSurface->setSource(&CameraSource::getInstance());
setTitle(title);
setTitle(title);
QWidget::show(); QWidget::show();
} }
@ -125,57 +99,23 @@ void NetCamView::setTitle(const QString &title)
setWindowTitle(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);
//updateSize();
}
void NetCamView::showEvent(QShowEvent *event) void NetCamView::showEvent(QShowEvent *event)
{ {
selfFrame->resetBoundary(videoSurface->getBoundingRect()); selfFrame->resetBoundary(videoSurface->getBoundingRect());
} }
void NetCamView::updateSize() void NetCamView::updateRatio()
{ {
qDebug() << selfFrame->geometry(); selfFrame->setMinimumWidth(selfFrame->minimumHeight() * selfVideoSurface->getRatio());
/*qDebug() << videoSurface->size(); selfFrame->setRatio(selfVideoSurface->getRatio());
QSize usableSize = mainLayout->contentsRect().size(); }
int possibleWidth = usableSize.height() * videoSurface->getRatio();
void NetCamView::updateFrameSize(QSize size)
QSize initial = videoSurface->sizeHint(); {
selfFrame->setMaximumSize(size.height() / 3, size.width() / 3);
if (!initial.isValid())
return; if (selfFrame->maximumWidth() > selfFrame->maximumHeight())
selfFrame->setMaximumWidth(selfFrame->maximumHeight() * selfVideoSurface->getRatio());
if (possibleWidth > usableSize.width()) else
videoSurface->setSizeHint(usableSize.width(), usableSize.width() / videoSurface->getRatio()); selfFrame->setMaximumHeight(selfFrame->maximumWidth() / selfVideoSurface->getRatio());
else
videoSurface->setSizeHint(usableSize.height() * videoSurface->getRatio(), usableSize.height());
videoSurface->updateGeometry();
QSize newSize = videoSurface->sizeHint();
QSizeF initialSize = initial;
selfFrame->setRatio(selfVideoSurface->getRatio());*/
//selfFrame->setRatio(selfVideoSurface->getRatio());
//selfFrame->resetBoundary(videoSurface->getBoundingRect());
//selfFrame->setBoundary(newSize, initial, newSize.width() / initialSize.width(), newSize.height() / initialSize.height());
} }

View File

@ -1,5 +1,5 @@
/* /*
Copyright © 2014 by The qTox Project Copyright © 2014-2015 by The qTox Project
This file is part of qTox, a Qt-based graphical interface for Tox. This file is part of qTox, a Qt-based graphical interface for Tox.
@ -20,18 +20,15 @@
#ifndef NETCAMVIEW_H #ifndef NETCAMVIEW_H
#define NETCAMVIEW_H #define NETCAMVIEW_H
#include <QWidget> #include "genericnetcamview.h"
#include "src/widget/tool/aspectratiowidget.h"
class QHBoxLayout; class QHBoxLayout;
struct vpx_image; struct vpx_image;
class VideoSurface;
class VideoSource; class VideoSource;
class QFrame; class QFrame;
class MovableWidget; class MovableWidget;
class QPushButton;
class NetCamView : public QWidget class NetCamView : public GenericNetCamView
{ {
Q_OBJECT Q_OBJECT
@ -44,27 +41,17 @@ public:
void setSource(VideoSource* s); void setSource(VideoSource* s);
void setTitle(const QString& title); void setTitle(const QString& title);
signals:
void showMessageClicked();
public slots:
void setShowMessages(bool show, bool notify = false);
protected: protected:
void resizeEvent(QResizeEvent* event) final override;
void showEvent(QShowEvent* event) final override; void showEvent(QShowEvent* event) final override;
public slots: private slots:
void updateSize(); void updateRatio();
private: private:
void updateFrameSize(); void updateFrameSize(QSize size);
QHBoxLayout* mainLayout;
VideoSurface* videoSurface;
VideoSurface* selfVideoSurface; VideoSurface* selfVideoSurface;
MovableWidget* selfFrame; MovableWidget* selfFrame;
QPushButton* button;
bool e = false; bool e = false;
}; };

View File

@ -25,19 +25,21 @@
#include "src/persistence/settings.h" #include "src/persistence/settings.h"
#include <QPainter> #include <QPainter>
#include <QLabel> #include <QLabel>
#include <cassert>
float getSizeRatio(const QSize size) float getSizeRatio(const QSize size)
{ {
return size.width() / static_cast<float>(size.height()); return size.width() / static_cast<float>(size.height());
} }
VideoSurface::VideoSurface(int friendId, QWidget* parent) VideoSurface::VideoSurface(int friendId, QWidget* parent, bool expanding)
: QWidget{parent} : QWidget{parent}
, source{nullptr} , source{nullptr}
, frameLock{false} , frameLock{false}
, hasSubscribed{false} , hasSubscribed{0}
, friendId{friendId} , friendId{friendId}
, ratio{1.0f} , ratio{1.0f}
, expanding{expanding}
{ {
recalulateBounds(); recalulateBounds();
} }
@ -53,6 +55,11 @@ VideoSurface::~VideoSurface()
unsubscribe(); unsubscribe();
} }
bool VideoSurface::isExpanding() const
{
return expanding;
}
void VideoSurface::setSource(VideoSource *src) void VideoSurface::setSource(VideoSource *src)
{ {
if (source == src) if (source == src)
@ -62,10 +69,9 @@ void VideoSurface::setSource(VideoSource *src)
source = src; source = src;
subscribe(); subscribe();
} }
#include <QDebug>
QRect VideoSurface::getBoundingRect() const QRect VideoSurface::getBoundingRect() const
{ {
qDebug() << boundingRect.bottomRight() << (QPoint(boundingRect.width(), boundingRect.height()) + boundingRect.topLeft());
QRect bRect = boundingRect; QRect bRect = boundingRect;
bRect.setBottomRight(QPoint(boundingRect.bottom() + 1, boundingRect.right() + 1)); bRect.setBottomRight(QPoint(boundingRect.bottom() + 1, boundingRect.right() + 1));
return boundingRect; return boundingRect;
@ -78,17 +84,23 @@ float VideoSurface::getRatio() const
void VideoSurface::subscribe() void VideoSurface::subscribe()
{ {
if (source && !hasSubscribed) assert(hasSubscribed >= 0);
if (source && hasSubscribed++ == 0)
{ {
source->subscribe(); source->subscribe();
hasSubscribed = true;
connect(source, &VideoSource::frameAvailable, this, &VideoSurface::onNewFrameAvailable); connect(source, &VideoSource::frameAvailable, this, &VideoSurface::onNewFrameAvailable);
} }
} }
void VideoSurface::unsubscribe() void VideoSurface::unsubscribe()
{ {
if (!source || !hasSubscribed) assert(hasSubscribed >= 0);
if (!source || hasSubscribed == 0)
return;
if (--hasSubscribed != 0)
return; return;
lock(); lock();
@ -98,10 +110,9 @@ void VideoSurface::unsubscribe()
ratio = 1.0f; ratio = 1.0f;
recalulateBounds(); recalulateBounds();
emit ratioChanged(); emit ratioChanged();
update(); emit boundaryChanged();
source->unsubscribe(); source->unsubscribe();
hasSubscribed = false;
disconnect(source, &VideoSource::frameAvailable, this, &VideoSurface::onNewFrameAvailable); disconnect(source, &VideoSource::frameAvailable, this, &VideoSurface::onNewFrameAvailable);
} }
@ -121,6 +132,7 @@ void VideoSurface::onNewFrameAvailable(std::shared_ptr<VideoFrame> newFrame)
ratio = newRatio; ratio = newRatio;
recalulateBounds(); recalulateBounds();
emit ratioChanged(); emit ratioChanged();
emit boundaryChanged();
} }
update(); update();
@ -166,33 +178,38 @@ void VideoSurface::resizeEvent(QResizeEvent* event)
{ {
QWidget::resizeEvent(event); QWidget::resizeEvent(event);
recalulateBounds(); recalulateBounds();
emit boundaryChanged();
} }
void VideoSurface::showEvent(QShowEvent*) void VideoSurface::showEvent(QShowEvent*)
{ {
//emit ratioChanged(); //emit ratioChanged();
} }
#include <QDebug>
void VideoSurface::recalulateBounds() void VideoSurface::recalulateBounds()
{ {
if (ratio == 0) if (expanding)
return; {
boundingRect = contentsRect();
QPoint pos; }
QSize size;
QSize usableSize = contentsRect().size();
int possibleWidth = usableSize.height() * ratio;
if (possibleWidth > usableSize.width())
size = (QSize(usableSize.width(), usableSize.width() / ratio));
else else
size = (QSize(possibleWidth, usableSize.height())); {
QPoint pos;
QSize size;
QSize usableSize = contentsRect().size();
int possibleWidth = usableSize.height() * ratio;
pos.setX(width() / 2 - size.width() / 2); if (possibleWidth > usableSize.width())
pos.setY(height() / 2 - size.height() / 2); size = (QSize(usableSize.width(), usableSize.width() / ratio));
boundingRect.setRect(pos.x(), pos.y(), size.width(), size.height()); else
size = (QSize(possibleWidth, usableSize.height()));
emit boundaryChanged(); pos.setX(width() / 2 - size.width() / 2);
pos.setY(height() / 2 - size.height() / 2);
boundingRect.setRect(pos.x(), pos.y(), size.width(), size.height());
}
qDebug() << contentsRect();
update(); update();
} }

View File

@ -30,10 +30,11 @@ class VideoSurface : public QWidget
Q_OBJECT Q_OBJECT
public: public:
VideoSurface(int friendId, QWidget* parent=0); VideoSurface(int friendId, QWidget* parent = 0, bool expanding = false);
VideoSurface(int friendId, VideoSource* source, QWidget* parent=0); VideoSurface(int friendId, VideoSource* source, QWidget* parent = 0);
~VideoSurface(); ~VideoSurface();
bool isExpanding() const;
void setSource(VideoSource* src); //NULL is a valid option void setSource(VideoSource* src); //NULL is a valid option
QRect getBoundingRect() const; QRect getBoundingRect() const;
float getRatio() const; float getRatio() const;
@ -62,9 +63,10 @@ private:
VideoSource* source; VideoSource* source;
std::shared_ptr<VideoFrame> lastFrame; std::shared_ptr<VideoFrame> lastFrame;
std::atomic_bool frameLock; ///< Fast lock for lastFrame std::atomic_bool frameLock; ///< Fast lock for lastFrame
bool hasSubscribed; uint8_t hasSubscribed;
int friendId; int friendId;
float ratio; float ratio;
bool expanding;
}; };
#endif // SELFCAMVIEW_H #endif // SELFCAMVIEW_H

View File

@ -42,7 +42,6 @@
#include "src/core/cstring.h" #include "src/core/cstring.h"
#include "src/widget/tool/callconfirmwidget.h" #include "src/widget/tool/callconfirmwidget.h"
#include "src/widget/friendwidget.h" #include "src/widget/friendwidget.h"
#include "src/video/netcamview.h"
#include "src/widget/form/loadhistorydialog.h" #include "src/widget/form/loadhistorydialog.h"
#include "src/widget/tool/chattextedit.h" #include "src/widget/tool/chattextedit.h"
#include "src/widget/widget.h" #include "src/widget/widget.h"
@ -53,6 +52,7 @@
#include "src/chatlog/chatlinecontentproxy.h" #include "src/chatlog/chatlinecontentproxy.h"
#include "src/chatlog/content/text.h" #include "src/chatlog/content/text.h"
#include "src/chatlog/chatlog.h" #include "src/chatlog/chatlog.h"
#include "src/video/netcamview.h"
#include "src/persistence/offlinemsgengine.h" #include "src/persistence/offlinemsgengine.h"
#include "src/widget/tool/screenshotgrabber.h" #include "src/widget/tool/screenshotgrabber.h"
#include "src/widget/tool/flyoutoverlaywidget.h" #include "src/widget/tool/flyoutoverlaywidget.h"
@ -77,7 +77,6 @@ ChatForm::ChatForm(Friend* chatFriend)
typingTimer.setSingleShot(true); typingTimer.setSingleShot(true);
netcam = nullptr;
callDurationTimer = nullptr; callDurationTimer = nullptr;
disableCallButtonsTimer = nullptr; disableCallButtonsTimer = nullptr;
@ -90,7 +89,6 @@ ChatForm::ChatForm(Friend* chatFriend)
callDuration->hide(); callDuration->hide();
chatWidget->setMinimumHeight(160); chatWidget->setMinimumHeight(160);
connect(bodySplitter, &QSplitter::splitterMoved, this, &ChatForm::onSplitterMoved);
connect(this, &GenericChatForm::messageInserted, this, &ChatForm::onMessageInserted); connect(this, &GenericChatForm::messageInserted, this, &ChatForm::onMessageInserted);
loadHistoryAction = menu.addAction(QString(), this, SLOT(onLoadHistory())); loadHistoryAction = menu.addAction(QString(), this, SLOT(onLoadHistory()));
@ -120,7 +118,7 @@ ChatForm::ChatForm(Friend* chatFriend)
retranslateUi(); retranslateUi();
Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this); Translator::registerHandler(std::bind(&ChatForm::retranslateUi, this), this);
showNetcam(); //showNetcam();
} }
ChatForm::~ChatForm() ChatForm::~ChatForm()
@ -751,6 +749,13 @@ void ChatForm::onAvatarChange(uint32_t FriendId, const QPixmap &pic)
avatar->setPixmap(pic); avatar->setPixmap(pic);
} }
GenericNetCamView *ChatForm::createNetcam()
{
NetCamView* view = new NetCamView(f->getFriendID(), this);
view->show(Core::getInstance()->getVideoSourceFromCall(callId), f->getDisplayedName());
return view;
}
void ChatForm::dragEnterEvent(QDragEnterEvent *ev) void ChatForm::dragEnterEvent(QDragEnterEvent *ev)
{ {
if (ev->mimeData()->hasUrls()) if (ev->mimeData()->hasUrls())
@ -938,31 +943,12 @@ void ChatForm::onLoadHistory()
} }
} }
void ChatForm::onSplitterMoved(int, int)
{
if (netcam)
netcam->setShowMessages(bodySplitter->sizes()[1] == 0);
}
void ChatForm::onMessageInserted() void ChatForm::onMessageInserted()
{ {
if (netcam && bodySplitter->sizes()[1] == 0) if (netcam && bodySplitter->sizes()[1] == 0)
netcam->setShowMessages(true, true); 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() void ChatForm::startCounter()
{ {
if (!callDurationTimer) if (!callDurationTimer)
@ -1095,27 +1081,6 @@ void ChatForm::SendMessageStr(QString msg)
} }
} }
void ChatForm::showNetcam()
{
if (!netcam)
netcam = new NetCamView(f->getFriendID());
//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);
bodySplitter->setCollapsible(0, false);
}
void ChatForm::hideNetcam()
{
if (!netcam)
return;
netcam->hide();
delete netcam;
netcam = nullptr;
}
void ChatForm::retranslateUi() void ChatForm::retranslateUi()
{ {
loadHistoryAction->setText(tr("Load chat history...")); loadHistoryAction->setText(tr("Load chat history..."));

View File

@ -30,7 +30,6 @@
class Friend; class Friend;
class FileTransferInstance; class FileTransferInstance;
class NetCamView;
class QPixmap; class QPixmap;
class CallConfirmWidget; class CallConfirmWidget;
class QHideEvent; class QHideEvent;
@ -100,16 +99,13 @@ private slots:
void onScreenshotClicked(); void onScreenshotClicked();
void onScreenshotTaken(const QPixmap &pixmap); void onScreenshotTaken(const QPixmap &pixmap);
void doScreenshot(); void doScreenshot();
void onSplitterMoved(int pos, int index);
void onMessageInserted(); void onMessageInserted();
void onShowMessagesClicked();
private: private:
void retranslateUi(); void retranslateUi();
protected: protected:
void showNetcam(); virtual GenericNetCamView* createNetcam() final override;
void hideNetcam();
// drag & drop // drag & drop
virtual void dragEnterEvent(QDragEnterEvent* ev) final override; virtual void dragEnterEvent(QDragEnterEvent* ev) final override;
virtual void dropEvent(QDropEvent* ev) final override; virtual void dropEvent(QDropEvent* ev) final override;
@ -119,7 +115,6 @@ protected:
private: private:
Friend* f; Friend* f;
CroppingLabel *statusMessageLabel; CroppingLabel *statusMessageLabel;
NetCamView* netcam;
int callId; int callId;
QLabel *callDuration; QLabel *callDuration;
QTimer *callDurationTimer; QTimer *callDurationTimer;

View File

@ -43,6 +43,7 @@
#include "src/chatlog/content/timestamp.h" #include "src/chatlog/content/timestamp.h"
#include "src/widget/tool/flyoutoverlaywidget.h" #include "src/widget/tool/flyoutoverlaywidget.h"
#include "src/widget/translator.h" #include "src/widget/translator.h"
#include "src/video/genericnetcamview.h"
GenericChatForm::GenericChatForm(QWidget *parent) GenericChatForm::GenericChatForm(QWidget *parent)
: QWidget(parent) : QWidget(parent)
@ -128,6 +129,7 @@ GenericChatForm::GenericChatForm(QWidget *parent)
setLayout(mainLayout); setLayout(mainLayout);
bodySplitter = new QSplitter(Qt::Vertical, this); bodySplitter = new QSplitter(Qt::Vertical, this);
connect(bodySplitter, &QSplitter::splitterMoved, this, &GenericChatForm::onSplitterMoved);
QWidget* contentWidget = new QWidget(this); QWidget* contentWidget = new QWidget(this);
QVBoxLayout* contentLayout = new QVBoxLayout(contentWidget); QVBoxLayout* contentLayout = new QVBoxLayout(contentWidget);
@ -201,6 +203,8 @@ GenericChatForm::GenericChatForm(QWidget *parent)
retranslateUi(); retranslateUi();
Translator::registerHandler(std::bind(&GenericChatForm::retranslateUi, this), this); Translator::registerHandler(std::bind(&GenericChatForm::retranslateUi, this), this);
netcam = nullptr;
} }
GenericChatForm::~GenericChatForm() GenericChatForm::~GenericChatForm()
@ -518,6 +522,25 @@ bool GenericChatForm::eventFilter(QObject* object, QEvent* event)
return false; return false;
} }
void GenericChatForm::onSplitterMoved(int, int)
{
if (netcam)
netcam->setShowMessages(bodySplitter->sizes()[1] == 0);
}
void GenericChatForm::onShowMessagesClicked()
{
if (netcam)
{
if (bodySplitter->sizes()[1] == 0)
bodySplitter->setSizes({1, 1});
else
bodySplitter->setSizes({1, 0});
onSplitterMoved(0, 0);
}
}
void GenericChatForm::retranslateUi() void GenericChatForm::retranslateUi()
{ {
sendButton->setToolTip(tr("Send message")); sendButton->setToolTip(tr("Send message"));
@ -529,3 +552,23 @@ void GenericChatForm::retranslateUi()
saveChatAction->setText(tr("Save chat log")); saveChatAction->setText(tr("Save chat log"));
clearAction->setText(tr("Clear displayed messages")); clearAction->setText(tr("Clear displayed messages"));
} }
void GenericChatForm::showNetcam()
{
if (!netcam)
netcam = createNetcam();
connect(netcam, &GenericNetCamView::showMessageClicked, this, &GenericChatForm::onShowMessagesClicked);
bodySplitter->insertWidget(0, netcam);
bodySplitter->setCollapsible(0, false);
}
void GenericChatForm::hideNetcam()
{
if (!netcam)
return;
netcam->hide();
delete netcam;
netcam = nullptr;
}

View File

@ -41,6 +41,7 @@ class MaskablePixmapWidget;
class Widget; class Widget;
class FlyoutOverlayWidget; class FlyoutOverlayWidget;
class QSplitter; class QSplitter;
class GenericNetCamView;
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
@ -87,11 +88,16 @@ protected slots:
void onSelectAllClicked(); void onSelectAllClicked();
void showFileMenu(); void showFileMenu();
void hideFileMenu(); void hideFileMenu();
void onShowMessagesClicked();
void onSplitterMoved(int pos, int index);
private: private:
void retranslateUi(); void retranslateUi();
protected: protected:
void showNetcam();
void hideNetcam();
virtual GenericNetCamView* createNetcam() = 0;
QString resolveToxId(const ToxId &id); QString resolveToxId(const ToxId &id);
void insertChatMessage(ChatMessage::Ptr msg); void insertChatMessage(ChatMessage::Ptr msg);
void adjustFileMenuPosition(); void adjustFileMenuPosition();
@ -122,6 +128,7 @@ protected:
bool audioInputFlag; bool audioInputFlag;
bool audioOutputFlag; bool audioOutputFlag;
QSplitter* bodySplitter; QSplitter* bodySplitter;
GenericNetCamView* netcam;
}; };
#endif // GENERICCHATFORM_H #endif // GENERICCHATFORM_H

View File

@ -29,6 +29,7 @@
#include "src/persistence/historykeeper.h" #include "src/persistence/historykeeper.h"
#include "src/widget/flowlayout.h" #include "src/widget/flowlayout.h"
#include "src/widget/translator.h" #include "src/widget/translator.h"
#include "src/video/groupnetcamview.h"
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QTimer>
#include <QPushButton> #include <QPushButton>
@ -191,7 +192,14 @@ void GroupChatForm::onUserListChanged()
orderizer[names[i]] = peerLabels[i]; orderizer[names[i]] = peerLabels[i];
if (group->isSelfPeerNumber(i)) if (group->isSelfPeerNumber(i))
peerLabels[i]->setStyleSheet("QLabel {color : green;}"); peerLabels[i]->setStyleSheet("QLabel {color : green;}");
if (netcam && !group->isSelfPeerNumber(i))
static_cast<GroupNetCamView*>(netcam)->addPeer(i, names[i]);
} }
if (netcam)
static_cast<GroupNetCamView*>(netcam)->clearPeers();
// now alphabetize and add to layout // now alphabetize and add to layout
names.sort(Qt::CaseInsensitive); names.sort(Qt::CaseInsensitive);
for (unsigned i=0; i<nNames; ++i) for (unsigned i=0; i<nNames; ++i)
@ -227,9 +235,24 @@ void GroupChatForm::peerAudioPlaying(int peer)
{ {
peerAudioTimers[peer] = new QTimer(this); peerAudioTimers[peer] = new QTimer(this);
peerAudioTimers[peer]->setSingleShot(true); peerAudioTimers[peer]->setSingleShot(true);
connect(peerAudioTimers[peer], &QTimer::timeout, [=]{this->peerLabels[peer]->setStyleSheet(""); connect(peerAudioTimers[peer], &QTimer::timeout, [this, peer]
delete this->peerAudioTimers[peer]; {
this->peerAudioTimers[peer] = nullptr;}); if (netcam)
static_cast<GroupNetCamView*>(netcam)->removePeer(peer);
if (peer >= peerLabels.size())
return;
peerLabels[peer]->setStyleSheet("");
delete peerAudioTimers[peer];
peerAudioTimers[peer] = nullptr;
});
if (netcam)
{
static_cast<GroupNetCamView*>(netcam)->removePeer(peer);
static_cast<GroupNetCamView*>(netcam)->addPeer(peer, group->getPeerList()[peer]);
}
} }
peerAudioTimers[peer]->start(500); peerAudioTimers[peer]->start(500);
} }
@ -308,6 +331,7 @@ void GroupChatForm::onCallClicked()
volButton->style()->polish(volButton); volButton->style()->polish(volButton);
volButton->setToolTip(tr("Mute call")); volButton->setToolTip(tr("Mute call"));
inCall = true; inCall = true;
showNetcam();
} }
else else
{ {
@ -324,9 +348,24 @@ void GroupChatForm::onCallClicked()
volButton->style()->polish(volButton); volButton->style()->polish(volButton);
volButton->setToolTip(""); volButton->setToolTip("");
inCall = false; inCall = false;
hideNetcam();
} }
} }
GenericNetCamView *GroupChatForm::createNetcam()
{
GroupNetCamView* view = new GroupNetCamView(group->getGroupId(), this);
QStringList names = group->getPeerList();
for (unsigned i=0; i<names.size(); ++i)
{
if (!group->isSelfPeerNumber(i))
static_cast<GroupNetCamView*>(view)->addPeer(i, names[i]);
}
return view;
}
void GroupChatForm::keyPressEvent(QKeyEvent* ev) void GroupChatForm::keyPressEvent(QKeyEvent* ev)
{ {
// Push to talk (CTRL+P) // Push to talk (CTRL+P)

View File

@ -49,6 +49,7 @@ private slots:
void onCallClicked(); void onCallClicked();
protected: protected:
virtual GenericNetCamView* createNetcam() final override;
virtual void keyPressEvent(QKeyEvent* ev) final override; virtual void keyPressEvent(QKeyEvent* ev) final override;
virtual void keyReleaseEvent(QKeyEvent* ev) final override; virtual void keyReleaseEvent(QKeyEvent* ev) final override;
// drag & drop // drag & drop

View File

@ -0,0 +1,190 @@
/****************************************************************************
**
** 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();
}
}

View File

@ -0,0 +1,76 @@
/****************************************************************************
**
** 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

View File

@ -24,6 +24,11 @@
#include <QDebug> #include <QDebug>
static float getNetcamX = 0.0f;
static float getNetcamY = 0.0f;
static float getNetcamW = 0.0f;
static float getNetcamH = 0.0f;
MovableWidget::MovableWidget(QWidget *parent) MovableWidget::MovableWidget(QWidget *parent)
: QWidget(parent) : QWidget(parent)
{ {
@ -35,7 +40,6 @@ MovableWidget::MovableWidget(QWidget *parent)
setRatio(1.0f); setRatio(1.0f);
resize(minimumSize()); resize(minimumSize());
actualPos = QPoint(0, 0); actualPos = QPoint(0, 0);
qDebug() << "SRE" << size();
//move() //move()
} }
@ -72,13 +76,17 @@ MovableWidget::MovableWidget(QWidget *parent)
void MovableWidget::resetBoundary(QRect newBoundary) void MovableWidget::resetBoundary(QRect newBoundary)
{ {
boundaryRect = newBoundary; boundaryRect = newBoundary;
resize(minimumSize());
//actualSize = QSize(getNetcamW * newBoundary.width(), getNetcamH * newBoundary.height());
resize(QSize(round(actualSize.width()), round(actualSize.height())));
//actualPos = QPointF(getNetcamX * (newBoundary.width() - width()), getNetcamY * (newBoundary.height() - height()));
QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y()));
checkBoundary(moveTo); checkBoundary(moveTo);
move(moveTo); move(moveTo);
actualPos = pos(); actualPos = moveTo;
actualSize = size();
qDebug() << "GEO" << geometry(); qDebug() << "GGGG" << geometry();
} }
void MovableWidget::setBoundary(QRect newBoundary) void MovableWidget::setBoundary(QRect newBoundary)
@ -89,7 +97,6 @@ void MovableWidget::setBoundary(QRect newBoundary)
return; return;
} }
qDebug() << geometry() << actualPos << actualSize;
float changeX = newBoundary.width() / static_cast<float>(boundaryRect.width()); float changeX = newBoundary.width() / static_cast<float>(boundaryRect.width());
float changeY = newBoundary.height() / static_cast<float>(boundaryRect.height()); float changeY = newBoundary.height() / static_cast<float>(boundaryRect.height());
@ -113,7 +120,9 @@ void MovableWidget::setBoundary(QRect newBoundary)
QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y())); QPoint moveTo = QPoint(round(actualPos.x()), round(actualPos.y()));
move(moveTo); move(moveTo);
qDebug() << "hhhhh" << geometry() << boundaryRect << newBoundary;
boundaryRect = newBoundary; boundaryRect = newBoundary;
} }
float MovableWidget::getRatio() const float MovableWidget::getRatio() const
@ -124,7 +133,6 @@ float MovableWidget::getRatio() const
void MovableWidget::setRatio(float r) void MovableWidget::setRatio(float r)
{ {
ratio = r; ratio = r;
setMinimumWidth(minimumHeight() * ratio);
resize(width(), width() / ratio); resize(width(), width() / ratio);
QPoint position = QPoint(actualPos.x(), actualPos.y()); QPoint position = QPoint(actualPos.x(), actualPos.y());
checkBoundary(position); checkBoundary(position);
@ -210,8 +218,8 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event)
{ {
lastSize.setHeight(height() + displacement.y()); lastSize.setHeight(height() + displacement.y());
if (lastSize.height() > boundaryRect.height() / 3) if (lastSize.height() > maximumHeight())
lastPosition.setY(y() - displacement.y() + (lastSize.height() - boundaryRect.height() / 3)); lastPosition.setY(y() - displacement.y() + (lastSize.height() - maximumHeight()));
else else
lastPosition.setY(y() - displacement.y()); lastPosition.setY(y() - displacement.y());
} }
@ -219,8 +227,8 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event)
if (mode & ResizeLeft) if (mode & ResizeLeft)
{ {
lastSize.setWidth(width() + displacement.x()); lastSize.setWidth(width() + displacement.x());
if (lastSize.width() > boundaryRect.width() / 3) if (lastSize.width() > maximumWidth())
lastPosition.setX(x() - displacement.x() + (lastSize.width() - boundaryRect.width() / 3)); lastPosition.setX(x() - displacement.x() + (lastSize.width() - maximumWidth()));
else else
lastPosition.setX(x() - displacement.x()); lastPosition.setX(x() - displacement.x());
} }
@ -231,11 +239,11 @@ void MovableWidget::mouseMoveEvent(QMouseEvent* event)
if (mode & ResizeDown) if (mode & ResizeDown)
lastSize.setHeight(height() - displacement.y()); lastSize.setHeight(height() - displacement.y());
if (lastSize.height() > boundaryRect.height() / 3) if (lastSize.height() > maximumHeight())
lastSize.setHeight(boundaryRect.height() / 3); lastSize.setHeight(maximumHeight());
if (lastSize.width() > boundaryRect.width() / 3) if (lastSize.width() > maximumWidth())
lastSize.setWidth(boundaryRect.width() / 3); lastSize.setWidth(maximumWidth());
if (mode & (ResizeLeft | ResizeRight)) if (mode & (ResizeLeft | ResizeRight))
{ {

View File

@ -21,7 +21,6 @@
#define MOVABLEWIDGET_H #define MOVABLEWIDGET_H
#include <QWidget> #include <QWidget>
#include "aspectratiowidget.h"
class MovableWidget : public QWidget class MovableWidget : public QWidget
{ {

View File

@ -1059,7 +1059,8 @@ void Widget::onGroupNamelistChanged(int groupnumber, int peernumber, uint8_t Cha
} }
else if (change == TOX_CHAT_CHANGE_PEER_NAME) // core overwrites old name before telling us it changed... else if (change == TOX_CHAT_CHANGE_PEER_NAME) // core overwrites old name before telling us it changed...
{ {
g->updatePeer(peernumber,Nexus::getCore()->getGroupPeerName(groupnumber, peernumber)); qDebug() << "UPDATING PEER";
g->updatePeer(peernumber, name);
} }
} }