1 /*
2     Copyright © 2015-2019 by The qTox Project Contributors
3 
4     This file is part of qTox, a Qt-based graphical interface for Tox.
5 
6     qTox is libre software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10 
11     qTox is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with qTox.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "genericnetcamview.h"
21 
22 #include <QApplication>
23 #include <QScreen>
24 #include <QBoxLayout>
25 #include <QDesktopWidget>
26 #include <QKeyEvent>
27 #include <QPushButton>
28 #include <QVariant>
29 
30 namespace
31 {
32 const auto BTN_STATE_NONE = QVariant("none");
33 const auto BTN_STATE_RED = QVariant("red");
34 const int BTN_PANEL_HEIGHT = 55;
35 const int BTN_PANEL_WIDTH = 250;
36 const auto BTN_STYLE_SHEET_PATH = QStringLiteral("chatForm/fullScreenButtons.css");
37 }
38 
GenericNetCamView(QWidget * parent)39 GenericNetCamView::GenericNetCamView(QWidget* parent)
40     : QWidget(parent)
41 {
42     verLayout = new QVBoxLayout(this);
43     setWindowTitle(tr("Tox video"));
44 
45     buttonLayout = new QHBoxLayout();
46 
47     toggleMessagesButton = new QPushButton();
48     enterFullScreenButton = new QPushButton();
49     enterFullScreenButton->setText(tr("Full Screen"));
50 
51     buttonLayout->addStretch();
52     buttonLayout->addWidget(toggleMessagesButton);
53     buttonLayout->addWidget(enterFullScreenButton);
54 
55     connect(toggleMessagesButton, &QPushButton::clicked, this, &GenericNetCamView::showMessageClicked);
56     connect(enterFullScreenButton, &QPushButton::clicked, this, &GenericNetCamView::toggleFullScreen);
57 
58     verLayout->addLayout(buttonLayout);
59     verLayout->setContentsMargins(0, 0, 0, 0);
60 
61     setShowMessages(false);
62 
63     setStyleSheet("NetCamView { background-color: #c1c1c1; }");
64     buttonPanel = new QFrame(this);
65     buttonPanel->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
66     buttonPanel->setGeometry(0, 0, BTN_PANEL_WIDTH, BTN_PANEL_HEIGHT);
67 
68     QHBoxLayout* buttonPanelLayout = new QHBoxLayout(buttonPanel);
69     buttonPanelLayout->setContentsMargins(20, 0, 20, 0);
70 
71     videoPreviewButton = createButton("videoPreviewButton", "none");
72     videoPreviewButton->setToolTip(tr("Toggle video preview"));
73 
74     volumeButton = createButton("volButtonFullScreen", "none");
75     volumeButton->setToolTip(tr("Mute audio"));
76 
77     microphoneButton = createButton("micButtonFullScreen", "none");
78     microphoneButton->setToolTip(tr("Mute microphone"));
79 
80     endVideoButton = createButton("videoButtonFullScreen", "none");
81     endVideoButton->setToolTip(tr("End video call"));
82 
83     exitFullScreenButton = createButton("exitFullScreenButton", "none");
84     exitFullScreenButton->setToolTip(tr("Exit full screen"));
85 
86     connect(videoPreviewButton, &QPushButton::clicked, this, &GenericNetCamView::toggleVideoPreview);
87     connect(volumeButton, &QPushButton::clicked, this, &GenericNetCamView::volMuteToggle);
88     connect(microphoneButton, &QPushButton::clicked, this, &GenericNetCamView::micMuteToggle);
89     connect(endVideoButton, &QPushButton::clicked, this, &GenericNetCamView::endVideoCall);
90     connect(exitFullScreenButton, &QPushButton::clicked, this, &GenericNetCamView::toggleFullScreen);
91 
92     buttonPanelLayout->addStretch();
93     buttonPanelLayout->addWidget(videoPreviewButton);
94     buttonPanelLayout->addWidget(volumeButton);
95     buttonPanelLayout->addWidget(microphoneButton);
96     buttonPanelLayout->addWidget(endVideoButton);
97     buttonPanelLayout->addWidget(exitFullScreenButton);
98     buttonPanelLayout->addStretch();
99 }
100 
getSurfaceMinSize()101 QSize GenericNetCamView::getSurfaceMinSize()
102 {
103     QSize surfaceSize = videoSurface->minimumSize();
104     QSize buttonSize = toggleMessagesButton->size();
105     QSize panelSize(0, 45);
106 
107     return surfaceSize + buttonSize + panelSize;
108 }
109 
setShowMessages(bool show,bool notify)110 void GenericNetCamView::setShowMessages(bool show, bool notify)
111 {
112     if (!show) {
113         toggleMessagesButton->setText(tr("Hide Messages"));
114         toggleMessagesButton->setIcon(QIcon());
115         return;
116     }
117 
118     toggleMessagesButton->setText(tr("Show Messages"));
119 
120     if (notify) {
121         toggleMessagesButton->setIcon(QIcon(Style::getImagePath("chatArea/info.svg")));
122     }
123 }
124 
toggleFullScreen()125 void GenericNetCamView::toggleFullScreen()
126 {
127     if (isFullScreen()) {
128         exitFullScreen();
129     } else {
130         enterFullScreen();
131     }
132 }
133 
enterFullScreen()134 void GenericNetCamView::enterFullScreen()
135 {
136     setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
137     showFullScreen();
138     enterFullScreenButton->hide();
139     toggleMessagesButton->hide();
140 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
141     const auto screenSize = QGuiApplication::screenAt(this->pos())->geometry();
142 #else
143     const QRect screenSize = QApplication::desktop()->screenGeometry(this);
144 #endif
145     buttonPanel->setGeometry((screenSize.width() / 2) - buttonPanel->width() / 2,
146             screenSize.height() - BTN_PANEL_HEIGHT - 25, BTN_PANEL_WIDTH, BTN_PANEL_HEIGHT);
147     buttonPanel->show();
148     buttonPanel->activateWindow();
149     buttonPanel->raise();
150 }
151 
exitFullScreen()152 void GenericNetCamView::exitFullScreen()
153 {
154     setWindowFlags(Qt::Widget);
155     showNormal();
156     buttonPanel->hide();
157     enterFullScreenButton->show();
158     toggleMessagesButton->show();
159 }
160 
endVideoCall()161 void GenericNetCamView::endVideoCall()
162 {
163     toggleFullScreen();
164     emit videoCallEnd();
165 }
166 
toggleVideoPreview()167 void GenericNetCamView::toggleVideoPreview()
168 {
169     toggleButtonState(videoPreviewButton);
170     emit videoPreviewToggle();
171 }
172 
createButton(const QString & name,const QString & state)173 QPushButton *GenericNetCamView::createButton(const QString& name, const QString& state)
174 {
175     QPushButton* btn = new QPushButton();
176     btn->setAttribute(Qt::WA_LayoutUsesWidgetRect);
177     btn->setObjectName(name);
178     btn->setProperty("state", QVariant(state));
179     btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
180 
181     return btn;
182 }
183 
updateMuteVolButton(bool isMuted)184 void GenericNetCamView::updateMuteVolButton(bool isMuted)
185 {
186     updateButtonState(volumeButton, !isMuted);
187 }
188 
updateMuteMicButton(bool isMuted)189 void GenericNetCamView::updateMuteMicButton(bool isMuted)
190 {
191     updateButtonState(microphoneButton, !isMuted);
192 }
193 
toggleButtonState(QPushButton * btn)194 void GenericNetCamView::toggleButtonState(QPushButton* btn)
195 {
196     if (btn->property("state") == BTN_STATE_RED) {
197         btn->setProperty("state", BTN_STATE_NONE);
198     } else {
199         btn->setProperty("state", BTN_STATE_RED);
200     }
201 
202     btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
203 }
204 
updateButtonState(QPushButton * btn,bool active)205 void GenericNetCamView::updateButtonState(QPushButton* btn, bool active)
206 {
207     if (active) {
208         btn->setProperty("state", BTN_STATE_NONE);
209     } else {
210         btn->setProperty("state", BTN_STATE_RED);
211     }
212 
213     btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
214 }
215 
keyPressEvent(QKeyEvent * event)216 void GenericNetCamView::keyPressEvent(QKeyEvent *event)
217 {
218     int key = event->key();
219     if (key == Qt::Key_Escape && isFullScreen()) {
220         exitFullScreen();
221     }
222 }
223 
closeEvent(QCloseEvent * event)224 void GenericNetCamView::closeEvent(QCloseEvent *event)
225 {
226     exitFullScreen();
227     event->ignore();
228 }
229