diff --git a/res.qrc b/res.qrc
index d6a18972a..da45a6b57 100644
--- a/res.qrc
+++ b/res.qrc
@@ -53,10 +53,16 @@
ui/chatArea/scrollBarLeftArrow.svg
ui/chatArea/scrollBarRightArrow.svg
ui/chatForm/buttons.css
+ ui/chatForm/fullScreenButtons.css
ui/chatForm/callButton.svg
ui/chatForm/micButton.svg
+ ui/chatForm/micButtonRed.svg
ui/chatForm/videoButton.svg
+ ui/chatForm/videoButtonRed.svg
ui/chatForm/volButton.svg
+ ui/chatForm/volButtonRed.svg
+ ui/chatForm/videoPreview.svg
+ ui/chatForm/videoPreviewRed.svg
ui/chatForm/emoteButton.svg
ui/chatForm/fileButton.svg
ui/chatForm/screenshotButton.svg
@@ -64,6 +70,7 @@
ui/chatForm/searchHideButton.svg
ui/chatForm/searchUpButton.svg
ui/chatForm/sendButton.svg
+ ui/chatForm/exitFullScreenButton.svg
ui/emoticonWidget/dot_page.svg
ui/emoticonWidget/dot_page_current.svg
ui/emoticonWidget/dot_page_hover.svg
diff --git a/src/video/genericnetcamview.cpp b/src/video/genericnetcamview.cpp
index 69af582d0..7b7db2091 100644
--- a/src/video/genericnetcamview.cpp
+++ b/src/video/genericnetcamview.cpp
@@ -19,9 +19,21 @@
#include "genericnetcamview.h"
+#include
#include
-#include
+#include
+#include
#include
+#include
+
+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)
@@ -29,35 +41,66 @@ GenericNetCamView::GenericNetCamView(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);
+
+ connect(toggleMessagesButton, &QPushButton::clicked, this, &GenericNetCamView::showMessageClicked);
+ connect(enterFullScreenButton, &QPushButton::clicked, this, &GenericNetCamView::toggleFullScreen);
- 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);
+ 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;
@@ -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)
- button->setIcon(QIcon(":/ui/chatArea/info.svg"));
+ 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));
+}
+
+void GenericNetCamView::keyPressEvent(QKeyEvent *event)
+{
+ int key = event->key();
+ if (key == Qt::Key_Escape && isFullScreen()) {
+ exitFullScreen();
+ }
+}
+
+void GenericNetCamView::closeEvent(QCloseEvent *event)
+{
+ exitFullScreen();
+ event->ignore();
}
diff --git a/src/video/genericnetcamview.h b/src/video/genericnetcamview.h
index d141037eb..272afd15e 100644
--- a/src/video/genericnetcamview.h
+++ b/src/video/genericnetcamview.h
@@ -20,11 +20,13 @@
#ifndef GENERICNETCAMVIEW_H
#define GENERICNETCAMVIEW_H
+#include
#include
#include
#include
#include "src/video/videosurface.h"
+#include "src/widget/style.h"
class GenericNetCamView : public QWidget
{
@@ -35,16 +37,42 @@ public:
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
diff --git a/src/video/netcamview.cpp b/src/video/netcamview.cpp
index ffb79fdc2..10a6f27e3 100644
--- a/src/video/netcamview.cpp
+++ b/src/video/netcamview.cpp
@@ -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);
@@ -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();
+ }
+}
diff --git a/src/video/netcamview.h b/src/video/netcamview.h
index 4e8f3449c..a76c44a67 100644
--- a/src/video/netcamview.h
+++ b/src/video/netcamview.h
@@ -42,6 +42,7 @@ public:
void setSource(VideoSource* s);
void setTitle(const QString& title);
+ void toggleVideoPreview();
protected:
void showEvent(QShowEvent* event) final override;
diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp
index 492a8d895..f57875f16 100644
--- a/src/widget/form/chatform.cpp
+++ b/src/widget/form/chatform.cpp
@@ -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;
}
@@ -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()
@@ -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()
diff --git a/ui/chatForm/exitFullScreenButton.svg b/ui/chatForm/exitFullScreenButton.svg
new file mode 100644
index 000000000..6e7159f0a
--- /dev/null
+++ b/ui/chatForm/exitFullScreenButton.svg
@@ -0,0 +1,42 @@
+
+
+
+
diff --git a/ui/chatForm/fullScreenButtons.css b/ui/chatForm/fullScreenButtons.css
new file mode 100644
index 000000000..da0596378
--- /dev/null
+++ b/ui/chatForm/fullScreenButtons.css
@@ -0,0 +1,78 @@
+QFrame
+{
+ background-color: rgba(50, 50, 50, 0.6);
+ border-radius: 20px;
+}
+
+QAbstractButton
+{
+ background-color: transparent;
+ background-repeat: none;
+ background-position: center;
+ border: none;
+ border-radius: 5px;
+}
+
+QAbstractButton:hover
+{
+ background-color: rgba(255,255,255, 0.2);
+}
+
+QAbstractButton:pressed
+{
+ background-color: rgba(0,0,0, 0.2);
+}
+
+QAbstractButton#volButtonFullScreen
+{
+ background-image: url(":/ui/chatForm/volButton.svg");
+ width: 11px;
+ height: 9px;
+ padding: 12px;
+}
+
+QAbstractButton#micButtonFullScreen
+{
+ background-image: url(":/ui/chatForm/micButton.svg");
+ width: 11px;
+ height: 9px;
+ padding: 12px;
+}
+
+QAbstractButton#videoButtonFullScreen
+{
+ background-image: url(":/ui/chatForm/videoButtonRed.svg");
+ width: 37px;
+ height: 33px;
+}
+
+QAbstractButton#videoPreviewButton
+{
+ background-image: url(":/ui/chatForm/videoPreview.svg");
+ width: 13px;
+ height: 13px;
+ padding: 10px;
+}
+
+QAbstractButton#exitFullScreenButton
+{
+ background-image: url(":/ui/chatForm/exitFullScreenButton.svg");
+ width: 30px;
+ height: 30px;
+ padding: 1px;
+}
+
+QAbstractButton#volButtonFullScreen[state="red"]
+{
+ background-image: url(":/ui/chatForm/volButtonRed.svg");
+}
+
+QAbstractButton#micButtonFullScreen[state="red"]
+{
+ background-image: url(":/ui/chatForm/micButtonRed.svg");
+}
+
+QAbstractButton#videoPreviewButton[state="red"]
+{
+ background-image: url(":/ui/chatForm/videoPreviewRed.svg");
+}
diff --git a/ui/chatForm/micButtonRed.svg b/ui/chatForm/micButtonRed.svg
new file mode 100644
index 000000000..8a8979014
--- /dev/null
+++ b/ui/chatForm/micButtonRed.svg
@@ -0,0 +1,67 @@
+
+
diff --git a/ui/chatForm/videoButtonRed.svg b/ui/chatForm/videoButtonRed.svg
new file mode 100644
index 000000000..c292b1b33
--- /dev/null
+++ b/ui/chatForm/videoButtonRed.svg
@@ -0,0 +1,29 @@
+
+
+
+
diff --git a/ui/chatForm/videoPreview.svg b/ui/chatForm/videoPreview.svg
new file mode 100644
index 000000000..be8ffeb00
--- /dev/null
+++ b/ui/chatForm/videoPreview.svg
@@ -0,0 +1,42 @@
+
+
+
+
diff --git a/ui/chatForm/videoPreviewRed.svg b/ui/chatForm/videoPreviewRed.svg
new file mode 100644
index 000000000..ec7501430
--- /dev/null
+++ b/ui/chatForm/videoPreviewRed.svg
@@ -0,0 +1,41 @@
+
+
+
+
diff --git a/ui/chatForm/volButtonRed.svg b/ui/chatForm/volButtonRed.svg
new file mode 100644
index 000000000..5934f4539
--- /dev/null
+++ b/ui/chatForm/volButtonRed.svg
@@ -0,0 +1,61 @@
+
+