Skip to content
This repository has been archived by the owner on Feb 12, 2023. It is now read-only.

Commit

Permalink
feat(chat): full screen video chat
Browse files Browse the repository at this point in the history
Implements #2922 and #2514.
This change adds:
- a button for enabling full screen mode
- a panel with buttons for controlling the chat in full screen mode
- a button to toggle video preview
- new icons

fix(chat): fix buttons in full screen video call
feat(chat): add hotkey for exiting full screen video
fix(chat): use screen res to position button panel
fix(chat): dont remove video widget on window close
  • Loading branch information
tox-user committed May 10, 2018
1 parent 3751cf7 commit d6df888
Show file tree
Hide file tree
Showing 13 changed files with 584 additions and 24 deletions.
7 changes: 7 additions & 0 deletions res.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,24 @@
<file>ui/chatArea/scrollBarLeftArrow.svg</file>
<file>ui/chatArea/scrollBarRightArrow.svg</file>
<file>ui/chatForm/buttons.css</file>
<file>ui/chatForm/fullScreenButtons.css</file>
<file>ui/chatForm/callButton.svg</file>
<file>ui/chatForm/micButton.svg</file>
<file>ui/chatForm/micButtonRed.svg</file>
<file>ui/chatForm/videoButton.svg</file>
<file>ui/chatForm/videoButtonRed.svg</file>
<file>ui/chatForm/volButton.svg</file>
<file>ui/chatForm/volButtonRed.svg</file>
<file>ui/chatForm/videoPreview.svg</file>
<file>ui/chatForm/videoPreviewRed.svg</file>
<file>ui/chatForm/emoteButton.svg</file>
<file>ui/chatForm/fileButton.svg</file>
<file>ui/chatForm/screenshotButton.svg</file>
<file>ui/chatForm/searchDownButton.svg</file>
<file>ui/chatForm/searchHideButton.svg</file>
<file>ui/chatForm/searchUpButton.svg</file>
<file>ui/chatForm/sendButton.svg</file>
<file>ui/chatForm/exitFullScreenButton.svg</file>
<file>ui/emoticonWidget/dot_page.svg</file>
<file>ui/emoticonWidget/dot_page_current.svg</file>
<file>ui/emoticonWidget/dot_page_hover.svg</file>
Expand Down
190 changes: 168 additions & 22 deletions src/video/genericnetcamview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,88 @@

#include "genericnetcamview.h"

#include <QApplication>
#include <QBoxLayout>
#include <QFrame>
#include <QDesktopWidget>
#include <QKeyEvent>
#include <QPushButton>
#include <QVariant>

namespace
{
const auto BTN_STATE_NONE = QVariant("none");
const auto BTN_STATE_RED = QVariant("red");
const int BTN_PANEL_HEIGHT = 55;
const int BTN_PANEL_WIDTH = 250;
const auto BTN_STYLE_SHEET_PATH = QStringLiteral(":/ui/chatForm/fullScreenButtons.css");
}

GenericNetCamView::GenericNetCamView(QWidget* parent)
: QWidget(parent)
{
verLayout = new QVBoxLayout(this);
setWindowTitle(tr("Tox video"));

int spacing = verLayout->spacing();
verLayout->setSpacing(0);
buttonLayout = new QHBoxLayout();

toggleMessagesButton = new QPushButton();
enterFullScreenButton = new QPushButton();
enterFullScreenButton->setText(tr("Full Screen"));

QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addStretch();
button = new QPushButton();
buttonLayout->addWidget(button);
buttonLayout->setSizeConstraint(QLayout::SetMinimumSize);
connect(button, &QPushButton::clicked, this, &GenericNetCamView::showMessageClicked);
buttonLayout->addWidget(toggleMessagesButton);
buttonLayout->addWidget(enterFullScreenButton);

verLayout->addSpacing(spacing);
verLayout->addLayout(buttonLayout);
verLayout->addSpacing(spacing);
connect(toggleMessagesButton, &QPushButton::clicked, this, &GenericNetCamView::showMessageClicked);
connect(enterFullScreenButton, &QPushButton::clicked, this, &GenericNetCamView::toggleFullScreen);

QFrame* lineFrame = new QFrame(this);
lineFrame->setStyleSheet("border: 1px solid #c1c1c1;");
lineFrame->setFrameShape(QFrame::HLine);
lineFrame->setMaximumHeight(1);
verLayout->addWidget(lineFrame);
verLayout->addLayout(buttonLayout);
verLayout->setContentsMargins(0, 0, 0, 0);

setShowMessages(false);

setStyleSheet("NetCamView { background-color: #c1c1c1; }");
buttonPanel = new QFrame(this);
buttonPanel->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
buttonPanel->setGeometry(0, 0, BTN_PANEL_WIDTH, BTN_PANEL_HEIGHT);

QHBoxLayout* buttonPanelLayout = new QHBoxLayout(buttonPanel);
buttonPanelLayout->setContentsMargins(20, 0, 20, 0);

videoPreviewButton = createButton("videoPreviewButton", "none");
videoPreviewButton->setToolTip(tr("Toggle video preview"));

volumeButton = createButton("volButtonFullScreen", "none");
volumeButton->setToolTip(tr("Mute audio"));

microphoneButton = createButton("micButtonFullScreen", "none");
microphoneButton->setToolTip(tr("Mute microphone"));

endVideoButton = createButton("videoButtonFullScreen", "none");
endVideoButton->setToolTip(tr("End video call"));

exitFullScreenButton = createButton("exitFullScreenButton", "none");
exitFullScreenButton->setToolTip(tr("Exit full screen"));

connect(videoPreviewButton, &QPushButton::clicked, this, &GenericNetCamView::toggleVideoPreview);
connect(volumeButton, &QPushButton::clicked, this, &GenericNetCamView::volMuteToggle);
connect(microphoneButton, &QPushButton::clicked, this, &GenericNetCamView::micMuteToggle);
connect(endVideoButton, &QPushButton::clicked, this, &GenericNetCamView::endVideoCall);
connect(exitFullScreenButton, &QPushButton::clicked, this, &GenericNetCamView::toggleFullScreen);

buttonPanelLayout->addStretch();
buttonPanelLayout->addWidget(videoPreviewButton);
buttonPanelLayout->addWidget(volumeButton);
buttonPanelLayout->addWidget(microphoneButton);
buttonPanelLayout->addWidget(endVideoButton);
buttonPanelLayout->addWidget(exitFullScreenButton);
buttonPanelLayout->addStretch();
}

QSize GenericNetCamView::getSurfaceMinSize()
{
QSize surfaceSize = videoSurface->minimumSize();
QSize buttonSize = button->size();
QSize buttonSize = toggleMessagesButton->size();
QSize panelSize(0, 45);

return surfaceSize + buttonSize + panelSize;
Expand All @@ -66,13 +109,116 @@ QSize GenericNetCamView::getSurfaceMinSize()
void GenericNetCamView::setShowMessages(bool show, bool notify)
{
if (!show) {
button->setText(tr("Hide Messages"));
button->setIcon(QIcon());
toggleMessagesButton->setText(tr("Hide Messages"));
toggleMessagesButton->setIcon(QIcon());
return;
}

button->setText(tr("Show Messages"));
toggleMessagesButton->setText(tr("Show Messages"));

if (notify) {
toggleMessagesButton->setIcon(QIcon(":/ui/chatArea/info.svg"));
}
}

void GenericNetCamView::toggleFullScreen()
{
if (isFullScreen()) {
exitFullScreen();
} else {
enterFullScreen();
}
}

void GenericNetCamView::enterFullScreen()
{
setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
showFullScreen();
enterFullScreenButton->hide();
toggleMessagesButton->hide();

const auto screenSize = QApplication::desktop()->screenGeometry(this);
buttonPanel->setGeometry((screenSize.width() / 2) - buttonPanel->width() / 2,
screenSize.height() - BTN_PANEL_HEIGHT - 25, BTN_PANEL_WIDTH, BTN_PANEL_HEIGHT);
buttonPanel->show();
buttonPanel->activateWindow();
buttonPanel->raise();
}

void GenericNetCamView::exitFullScreen()
{
setWindowFlags(Qt::Widget);
showNormal();
buttonPanel->hide();
enterFullScreenButton->show();
toggleMessagesButton->show();
}

void GenericNetCamView::endVideoCall()
{
toggleFullScreen();
emit videoCallEnd();
}

void GenericNetCamView::toggleVideoPreview()
{
toggleButtonState(videoPreviewButton);
emit videoPreviewToggle();
}

QPushButton *GenericNetCamView::createButton(const QString& name, const QString& state)
{
QPushButton* btn = new QPushButton();
btn->setAttribute(Qt::WA_LayoutUsesWidgetRect);
btn->setObjectName(name);
btn->setProperty("state", QVariant(state));
btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));

return btn;
}

void GenericNetCamView::updateMuteVolButton(bool isMuted)
{
updateButtonState(volumeButton, !isMuted);
}

void GenericNetCamView::updateMuteMicButton(bool isMuted)
{
updateButtonState(microphoneButton, !isMuted);
}

void GenericNetCamView::toggleButtonState(QPushButton* btn)
{
if (btn->property("state") == BTN_STATE_RED) {
btn->setProperty("state", BTN_STATE_NONE);
} else {
btn->setProperty("state", BTN_STATE_RED);
}

btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
}

void GenericNetCamView::updateButtonState(QPushButton* btn, bool active)
{
if (active) {
btn->setProperty("state", BTN_STATE_NONE);
} else {
btn->setProperty("state", BTN_STATE_RED);
}

btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
}

if (notify)
button->setIcon(QIcon(":/ui/chatArea/info.svg"));
void GenericNetCamView::keyPressEvent(QKeyEvent *event)
{
int key = event->key();
if (key == Qt::Key_Escape && isFullScreen()) {
exitFullScreen();
}
}

void GenericNetCamView::closeEvent(QCloseEvent *event)
{
exitFullScreen();
event->ignore();
}
30 changes: 29 additions & 1 deletion src/video/genericnetcamview.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
#ifndef GENERICNETCAMVIEW_H
#define GENERICNETCAMVIEW_H

#include <QFrame>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>

#include "src/video/videosurface.h"
#include "src/widget/style.h"

class GenericNetCamView : public QWidget
{
Expand All @@ -35,16 +37,42 @@ class GenericNetCamView : public QWidget

signals:
void showMessageClicked();
void videoCallEnd();
void volMuteToggle();
void micMuteToggle();
void videoPreviewToggle();

public slots:
void setShowMessages(bool show, bool notify = false);
void updateMuteVolButton(bool isMuted);
void updateMuteMicButton(bool isMuted);

protected:
QVBoxLayout* verLayout;
VideoSurface* videoSurface;

private:
QPushButton* button;
QHBoxLayout* buttonLayout = nullptr;
QPushButton* toggleMessagesButton = nullptr;
QPushButton* enterFullScreenButton = nullptr;
QFrame* buttonPanel = nullptr;
QPushButton* videoPreviewButton = nullptr;
QPushButton* volumeButton = nullptr;
QPushButton* microphoneButton = nullptr;
QPushButton* endVideoButton = nullptr;
QPushButton* exitFullScreenButton = nullptr;

private:
QPushButton* createButton(const QString& name, const QString& state);
void toggleFullScreen();
void enterFullScreen();
void exitFullScreen();
void endVideoCall();
void toggleVideoPreview();
void toggleButtonState(QPushButton* btn);
void updateButtonState(QPushButton* btn, bool active);
void keyPressEvent(QKeyEvent *event) override;
void closeEvent(QCloseEvent *event) override;
};

#endif // GENERICNETCAMVIEW_H
10 changes: 9 additions & 1 deletion src/video/netcamview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ NetCamView::NetCamView(int friendId, QWidget* parent)
const ToxPk pk = FriendList::findFriend(friendId)->getPublicKey();
videoSurface = new VideoSurface(Nexus::getProfile()->loadAvatar(pk), this);
videoSurface->setMinimumHeight(256);
videoSurface->setContentsMargins(6, 6, 6, 6);

verLayout->insertWidget(0, videoSurface, 1);

Expand Down Expand Up @@ -145,3 +144,12 @@ void NetCamView::updateFrameSize(QSize size)
else
selfFrame->setMaximumHeight(selfFrame->maximumWidth() / selfVideoSurface->getRatio());
}

void NetCamView::toggleVideoPreview()
{
if (selfFrame->isHidden()) {
selfFrame->show();
} else {
selfFrame->hide();
}
}
1 change: 1 addition & 0 deletions src/video/netcamview.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class NetCamView : public GenericNetCamView

void setSource(VideoSource* s);
void setTitle(const QString& title);
void toggleVideoPreview();

protected:
void showEvent(QShowEvent* event) final override;
Expand Down
10 changes: 10 additions & 0 deletions src/widget/form/chatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,10 @@ GenericNetCamView* ChatForm::createNetcam()
CoreAV* av = Core::getInstance()->getAv();
VideoSource* source = av->getVideoSourceFromCall(friendId);
view->show(source, f->getDisplayedName());
connect(view, &GenericNetCamView::videoCallEnd, this, &ChatForm::onVideoCallTriggered);
connect(view, &GenericNetCamView::volMuteToggle, this, &ChatForm::onVolMuteToggle);
connect(view, &GenericNetCamView::micMuteToggle, this, &ChatForm::onMicMuteToggle);
connect(view, &GenericNetCamView::videoPreviewToggle, view, &NetCamView::toggleVideoPreview);
return view;
}

Expand Down Expand Up @@ -907,6 +911,9 @@ void ChatForm::updateMuteMicButton()
bool active = av->isCallActive(f);
bool inputMuted = av->isCallInputMuted(f);
headWidget->updateMuteMicButton(active, inputMuted);
if (netcam) {
netcam->updateMuteMicButton(inputMuted);
}
}

void ChatForm::updateMuteVolButton()
Expand All @@ -915,6 +922,9 @@ void ChatForm::updateMuteVolButton()
bool active = av->isCallActive(f);
bool outputMuted = av->isCallOutputMuted(f);
headWidget->updateMuteVolButton(active, outputMuted);
if (netcam) {
netcam->updateMuteVolButton(outputMuted);
}
}

void ChatForm::startCounter()
Expand Down
Loading

0 comments on commit d6df888

Please sign in to comment.