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:
parent
1522d3848c
commit
814bd922ca
12
qtox.pro
12
qtox.pro
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
69
src/video/genericnetcamview.cpp
Normal file
69
src/video/genericnetcamview.cpp
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
49
src/video/genericnetcamview.h
Normal file
49
src/video/genericnetcamview.h
Normal 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
|
235
src/video/groupnetcamview.cpp
Normal file
235
src/video/groupnetcamview.cpp
Normal 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);
|
||||||
|
}
|
59
src/video/groupnetcamview.h
Normal file
59
src/video/groupnetcamview.h
Normal 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
|
|
@ -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());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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..."));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
190
src/widget/tool/flowlayout.cpp
Normal file
190
src/widget/tool/flowlayout.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
76
src/widget/tool/flowlayout.h
Normal file
76
src/widget/tool/flowlayout.h
Normal 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
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user