mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
parent
366478fca9
commit
91bcd211a7
|
@ -410,8 +410,6 @@ set(${PROJECT_NAME}_SOURCES
|
|||
src/video/corevideosource.h
|
||||
src/video/genericnetcamview.cpp
|
||||
src/video/genericnetcamview.h
|
||||
src/video/groupnetcamview.cpp
|
||||
src/video/groupnetcamview.h
|
||||
src/video/ivideosettings.h
|
||||
src/video/netcamview.cpp
|
||||
src/video/netcamview.h
|
||||
|
|
|
@ -1,247 +0,0 @@
|
|||
/*
|
||||
Copyright © 2015-2019 by The qTox Project Contributors
|
||||
|
||||
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/audio/audio.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/core/toxpk.h"
|
||||
#include "src/friendlist.h"
|
||||
#include "src/model/friend.h"
|
||||
#include "src/nexus.h"
|
||||
#include "src/persistence/profile.h"
|
||||
#include "src/video/videosurface.h"
|
||||
#include "src/widget/tool/croppinglabel.h"
|
||||
#include <QBoxLayout>
|
||||
#include <QMap>
|
||||
#include <QScrollArea>
|
||||
#include <QSplitter>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QDebug>
|
||||
class LabeledVideo : public QFrame
|
||||
{
|
||||
public:
|
||||
LabeledVideo(const QPixmap& avatar, QString fontColorString, QWidget* parent = nullptr, bool expanding = true)
|
||||
: QFrame(parent)
|
||||
{
|
||||
qDebug() << "Created expanding? " << expanding;
|
||||
videoSurface = new VideoSurface(avatar, nullptr, expanding);
|
||||
videoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
videoSurface->setMinimumHeight(32);
|
||||
|
||||
connect(videoSurface, &VideoSurface::ratioChanged, this, &LabeledVideo::updateSize);
|
||||
label = new CroppingLabel(this);
|
||||
label->setTextFormat(Qt::PlainText);
|
||||
label->setStyleSheet(QString("color: %1").arg(fontColorString));
|
||||
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->addWidget(videoSurface, 1);
|
||||
layout->addWidget(label);
|
||||
}
|
||||
|
||||
~LabeledVideo() {}
|
||||
|
||||
VideoSurface* getVideoSurface() const
|
||||
{
|
||||
return videoSurface;
|
||||
}
|
||||
|
||||
void setText(const QString& text)
|
||||
{
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
QString getText() const
|
||||
{
|
||||
return label->text();
|
||||
}
|
||||
|
||||
void setActive(bool active = true)
|
||||
{
|
||||
if (active)
|
||||
setStyleSheet("QFrame { background-color: #414141; border-radius: 10px; }");
|
||||
else
|
||||
setStyleSheet(QString());
|
||||
}
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent* event) final
|
||||
{
|
||||
updateSize();
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void updateSize()
|
||||
{
|
||||
if (videoSurface->isExpanding()) {
|
||||
int width = videoSurface->height() * videoSurface->getRatio();
|
||||
videoSurface->setMinimumWidth(width);
|
||||
videoSurface->setMaximumWidth(width);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CroppingLabel* label;
|
||||
VideoSurface* videoSurface;
|
||||
};
|
||||
|
||||
GroupNetCamView::GroupNetCamView(int group, QWidget* parent)
|
||||
: GenericNetCamView(parent)
|
||||
, group(group)
|
||||
{
|
||||
videoLabelSurface = new LabeledVideo(QPixmap(), "white", this, false);
|
||||
videoSurface = videoLabelSurface->getVideoSurface();
|
||||
videoSurface->setMinimumHeight(256);
|
||||
videoSurface->setContentsMargins(6, 6, 6, 0);
|
||||
videoLabelSurface->setContentsMargins(0, 0, 0, 0);
|
||||
videoLabelSurface->layout()->setMargin(0);
|
||||
videoLabelSurface->setStyleSheet("QFrame { background-color: black; }");
|
||||
|
||||
// remove full screen button in audio group chat since it's useless there
|
||||
enterFullScreenButton->hide();
|
||||
|
||||
QSplitter* splitter = new QSplitter(Qt::Vertical, this);
|
||||
splitter->setChildrenCollapsible(false);
|
||||
verLayout->insertWidget(0, splitter, 1);
|
||||
splitter->addWidget(videoLabelSurface);
|
||||
splitter->setStyleSheet(
|
||||
"QSplitter { background-color: black; } QSplitter::handle { background-color: black; }");
|
||||
|
||||
QScrollArea* scrollArea = new QScrollArea();
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
// Note this is needed to prevent oscillations that result in segfaults
|
||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
scrollArea->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum));
|
||||
|
||||
scrollArea->setFrameStyle(QFrame::NoFrame);
|
||||
QWidget* widget = new QWidget(nullptr);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
horLayout = new QHBoxLayout(widget);
|
||||
horLayout->addStretch(1);
|
||||
|
||||
selfVideoSurface = new LabeledVideo(Nexus::getProfile()->loadAvatar(), "black", this);
|
||||
horLayout->addWidget(selfVideoSurface);
|
||||
|
||||
horLayout->addStretch(1);
|
||||
splitter->addWidget(scrollArea);
|
||||
scrollArea->setWidget(widget);
|
||||
|
||||
QTimer* timer = new QTimer(this);
|
||||
timer->setInterval(1000);
|
||||
connect(timer, &QTimer::timeout, this, &GroupNetCamView::onUpdateActivePeer);
|
||||
timer->start();
|
||||
|
||||
connect(Nexus::getProfile(), &Profile::selfAvatarChanged, [this](const QPixmap& pixmap) {
|
||||
selfVideoSurface->getVideoSurface()->setAvatar(pixmap);
|
||||
setActive();
|
||||
});
|
||||
connect(Core::getInstance(), &Core::usernameSet, [this](const QString& username) {
|
||||
selfVideoSurface->setText(username);
|
||||
setActive();
|
||||
});
|
||||
|
||||
connect(Nexus::getProfile(), &Profile::friendAvatarChanged, this,
|
||||
&GroupNetCamView::friendAvatarChanged);
|
||||
|
||||
selfVideoSurface->setText(Core::getInstance()->getUsername());
|
||||
}
|
||||
|
||||
void GroupNetCamView::clearPeers()
|
||||
{
|
||||
for (const auto& peerPk : videoList.keys()) {
|
||||
removePeer(peerPk);
|
||||
}
|
||||
}
|
||||
|
||||
void GroupNetCamView::addPeer(const ToxPk& peer, const QString& name)
|
||||
{
|
||||
QPixmap groupAvatar = Nexus::getProfile()->loadAvatar(peer);
|
||||
LabeledVideo* labeledVideo = new LabeledVideo(groupAvatar, "black", this);
|
||||
labeledVideo->setText(name);
|
||||
horLayout->insertWidget(horLayout->count() - 1, labeledVideo);
|
||||
PeerVideo peerVideo;
|
||||
peerVideo.video = labeledVideo;
|
||||
videoList.insert(peer, peerVideo);
|
||||
|
||||
setActive();
|
||||
}
|
||||
|
||||
void GroupNetCamView::removePeer(const ToxPk& peer)
|
||||
{
|
||||
auto peerVideo = videoList.find(peer);
|
||||
|
||||
if (peerVideo != videoList.end()) {
|
||||
LabeledVideo* labeledVideo = peerVideo.value().video;
|
||||
horLayout->removeWidget(labeledVideo);
|
||||
labeledVideo->deleteLater();
|
||||
videoList.remove(peer);
|
||||
|
||||
setActive();
|
||||
}
|
||||
}
|
||||
|
||||
void GroupNetCamView::onUpdateActivePeer()
|
||||
{
|
||||
setActive();
|
||||
}
|
||||
|
||||
void GroupNetCamView::setActive(const ToxPk& peer)
|
||||
{
|
||||
if (peer.isEmpty()) {
|
||||
videoLabelSurface->setText(selfVideoSurface->getText());
|
||||
activePeer = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO(sudden6): check if we can remove the code, it won't be reached right now
|
||||
#if 0
|
||||
auto peerVideo = videoList.find(peer);
|
||||
|
||||
if (peerVideo != videoList.end()) {
|
||||
// When group video exists:
|
||||
// videoSurface->setSource(peerVideo.value()->getVideoSurface()->source);
|
||||
|
||||
auto lastVideo = videoList.find(activePeer);
|
||||
|
||||
if (lastVideo != videoList.end())
|
||||
lastVideo.value().video->setActive(false);
|
||||
|
||||
LabeledVideo* labeledVideo = peerVideo.value().video;
|
||||
videoLabelSurface->setText(labeledVideo->getText());
|
||||
videoLabelSurface->getVideoSurface()->setAvatar(labeledVideo->getVideoSurface()->getAvatar());
|
||||
labeledVideo->setActive();
|
||||
|
||||
activePeer = peer;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GroupNetCamView::friendAvatarChanged(ToxPk friendPk, const QPixmap& pixmap)
|
||||
{
|
||||
auto peerVideo = videoList.find(friendPk);
|
||||
|
||||
if (peerVideo != videoList.end()) {
|
||||
peerVideo.value().video->getVideoSurface()->setAvatar(pixmap);
|
||||
setActive();
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
Copyright © 2015-2019 by The qTox Project Contributors
|
||||
|
||||
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 "src/core/toxpk.h"
|
||||
|
||||
#include <QMap>
|
||||
|
||||
class LabeledVideo;
|
||||
class QHBoxLayout;
|
||||
|
||||
class GroupNetCamView : public GenericNetCamView
|
||||
{
|
||||
public:
|
||||
GroupNetCamView(int group, QWidget* parent = nullptr);
|
||||
void clearPeers();
|
||||
void addPeer(const ToxPk& peer, const QString& name);
|
||||
void removePeer(const ToxPk& peer);
|
||||
|
||||
private slots:
|
||||
void onUpdateActivePeer();
|
||||
void friendAvatarChanged(ToxPk friendPk, const QPixmap& pixmap);
|
||||
|
||||
private:
|
||||
struct PeerVideo
|
||||
{
|
||||
LabeledVideo* video;
|
||||
};
|
||||
|
||||
void setActive(const ToxPk& peer = ToxPk{});
|
||||
|
||||
QHBoxLayout* horLayout;
|
||||
QMap<ToxPk, PeerVideo> videoList;
|
||||
LabeledVideo* videoLabelSurface;
|
||||
LabeledVideo* selfVideoSurface;
|
||||
int activePeer;
|
||||
int group;
|
||||
};
|
||||
|
||||
#endif // GROUPNETCAMVIEW_H
|
|
@ -28,7 +28,6 @@
|
|||
#include "src/model/friend.h"
|
||||
#include "src/friendlist.h"
|
||||
#include "src/model/group.h"
|
||||
#include "src/video/groupnetcamview.h"
|
||||
#include "src/widget/chatformheader.h"
|
||||
#include "src/widget/flowlayout.h"
|
||||
#include "src/widget/form/chatform.h"
|
||||
|
@ -44,6 +43,7 @@
|
|||
#include <QRegularExpression>
|
||||
#include <QTimer>
|
||||
#include <QToolButton>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -211,10 +211,6 @@ void GroupChatForm::updateUserNames()
|
|||
peerLabels.insert(peerPk, label);
|
||||
}
|
||||
|
||||
if (netcam != nullptr) {
|
||||
static_cast<GroupNetCamView*>(netcam)->clearPeers();
|
||||
}
|
||||
|
||||
// add the labels in alphabetical order into the layout
|
||||
auto nickLabelList = peerLabels.values();
|
||||
|
||||
|
@ -261,9 +257,6 @@ void GroupChatForm::peerAudioPlaying(ToxPk peerPk)
|
|||
peerAudioTimers[peerPk] = new QTimer(this);
|
||||
peerAudioTimers[peerPk]->setSingleShot(true);
|
||||
connect(peerAudioTimers[peerPk], &QTimer::timeout, [this, peerPk] {
|
||||
if (netcam) {
|
||||
static_cast<GroupNetCamView*>(netcam)->removePeer(peerPk);
|
||||
}
|
||||
auto it = peerLabels.find(peerPk);
|
||||
if (it != peerLabels.end()) {
|
||||
peerLabels[peerPk]->setProperty("playingAudio", LABEL_PEER_NOT_PLAYING_AUDIO);
|
||||
|
@ -273,11 +266,6 @@ void GroupChatForm::peerAudioPlaying(ToxPk peerPk)
|
|||
delete peerAudioTimers[peerPk];
|
||||
peerAudioTimers[peerPk] = nullptr;
|
||||
});
|
||||
if (netcam) {
|
||||
static_cast<GroupNetCamView*>(netcam)->removePeer(peerPk);
|
||||
const auto nameIt = group->getPeerList().find(peerPk);
|
||||
static_cast<GroupNetCamView*>(netcam)->addPeer(peerPk, nameIt.value());
|
||||
}
|
||||
}
|
||||
|
||||
peerLabels[peerPk]->setStyleSheet(Style::getStylesheet(PEER_LABEL_STYLE_SHEET_PATH));
|
||||
|
@ -342,7 +330,6 @@ void GroupChatForm::onCallClicked()
|
|||
audioInputFlag = true;
|
||||
audioOutputFlag = true;
|
||||
inCall = true;
|
||||
showNetcam();
|
||||
} else {
|
||||
leaveGroupCall();
|
||||
}
|
||||
|
@ -360,17 +347,7 @@ void GroupChatForm::onCallClicked()
|
|||
|
||||
GenericNetCamView* GroupChatForm::createNetcam()
|
||||
{
|
||||
auto view = new GroupNetCamView(group->getId(), this);
|
||||
|
||||
const auto& names = group->getPeerList();
|
||||
const auto ownPk = Core::getInstance()->getSelfPublicKey();
|
||||
for (const auto& peerPk : names.keys()) {
|
||||
auto timerIt = peerAudioTimers.find(peerPk);
|
||||
if (peerPk != ownPk && timerIt != peerAudioTimers.end()) {
|
||||
static_cast<GroupNetCamView*>(view)->addPeer(peerPk, names.find(peerPk).value());
|
||||
}
|
||||
}
|
||||
return view;
|
||||
return static_cast<GenericNetCamView*>(nullptr);
|
||||
}
|
||||
|
||||
void GroupChatForm::keyPressEvent(QKeyEvent* ev)
|
||||
|
@ -477,5 +454,4 @@ void GroupChatForm::leaveGroupCall()
|
|||
audioInputFlag = false;
|
||||
audioOutputFlag = false;
|
||||
inCall = false;
|
||||
hideNetcam();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user