qTox  Version: nightly | Commit: bc751c8e1cac455f9690654fcfe0f560d2d7dfdd
netcamview.cpp
Go to the documentation of this file.
1 /*
2  Copyright © 2014-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 "netcamview.h"
21 #include "camerasource.h"
22 #include "src/core/core.h"
23 #include "src/friendlist.h"
24 #include "src/model/friend.h"
25 #include "src/nexus.h"
28 #include "src/video/videosurface.h"
30 #include "src/widget/style.h"
31 
32 #include <QApplication>
33 #include <QBoxLayout>
34 #include <QScreen>
35 #include <QFrame>
36 #include <QLabel>
37 #include <QCloseEvent>
38 #include <QPushButton>
39 #include <QDesktopWidget>
40 
41 namespace
42 {
43 const auto BTN_STATE_NONE = QVariant("none");
44 const auto BTN_STATE_RED = QVariant("red");
45 const int BTN_PANEL_HEIGHT = 55;
46 const int BTN_PANEL_WIDTH = 250;
47 const auto BTN_STYLE_SHEET_PATH = QStringLiteral("chatForm/fullScreenButtons.css");
48 }
49 
50 NetCamView::NetCamView(ToxPk friendPk, QWidget* parent)
51  : selfFrame{nullptr}
52  , friendPk{friendPk}
53  , e(false)
54 {
55  verLayout = new QVBoxLayout(this);
56  setWindowTitle(tr("Tox video"));
57 
58  buttonLayout = new QHBoxLayout();
59 
60  toggleMessagesButton = new QPushButton();
61  enterFullScreenButton = new QPushButton();
62  enterFullScreenButton->setText(tr("Full Screen"));
63 
64  buttonLayout->addStretch();
65  buttonLayout->addWidget(toggleMessagesButton);
66  buttonLayout->addWidget(enterFullScreenButton);
67 
68  connect(toggleMessagesButton, &QPushButton::clicked, this, &NetCamView::showMessageClicked);
69  connect(enterFullScreenButton, &QPushButton::clicked, this, &NetCamView::toggleFullScreen);
70 
71  verLayout->addLayout(buttonLayout);
72  verLayout->setContentsMargins(0, 0, 0, 0);
73 
74  setShowMessages(false);
75 
76  setStyleSheet("NetCamView { background-color: #c1c1c1; }");
77  buttonPanel = new QFrame(this);
78  buttonPanel->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
79  buttonPanel->setGeometry(0, 0, BTN_PANEL_WIDTH, BTN_PANEL_HEIGHT);
80 
81  QHBoxLayout* buttonPanelLayout = new QHBoxLayout(buttonPanel);
82  buttonPanelLayout->setContentsMargins(20, 0, 20, 0);
83 
84  videoPreviewButton = createButton("videoPreviewButton", "none");
85  videoPreviewButton->setToolTip(tr("Toggle video preview"));
86 
87  volumeButton = createButton("volButtonFullScreen", "none");
88  volumeButton->setToolTip(tr("Mute audio"));
89 
90  microphoneButton = createButton("micButtonFullScreen", "none");
91  microphoneButton->setToolTip(tr("Mute microphone"));
92 
93  endVideoButton = createButton("videoButtonFullScreen", "none");
94  endVideoButton->setToolTip(tr("End video call"));
95 
96  exitFullScreenButton = createButton("exitFullScreenButton", "none");
97  exitFullScreenButton->setToolTip(tr("Exit full screen"));
98 
99  connect(videoPreviewButton, &QPushButton::clicked, this, &NetCamView::toggleVideoPreview);
100  connect(volumeButton, &QPushButton::clicked, this, &NetCamView::volMuteToggle);
101  connect(microphoneButton, &QPushButton::clicked, this, &NetCamView::micMuteToggle);
102  connect(endVideoButton, &QPushButton::clicked, this, &NetCamView::endVideoCall);
103  connect(exitFullScreenButton, &QPushButton::clicked, this, &NetCamView::toggleFullScreen);
104 
105  buttonPanelLayout->addStretch();
106  buttonPanelLayout->addWidget(videoPreviewButton);
107  buttonPanelLayout->addWidget(volumeButton);
108  buttonPanelLayout->addWidget(microphoneButton);
109  buttonPanelLayout->addWidget(endVideoButton);
110  buttonPanelLayout->addWidget(exitFullScreenButton);
111  buttonPanelLayout->addStretch();
112 
113  videoSurface = new VideoSurface(Nexus::getProfile()->loadAvatar(friendPk), this);
114  videoSurface->setMinimumHeight(256);
115 
116  verLayout->insertWidget(0, videoSurface, 1);
117 
118  selfVideoSurface = new VideoSurface(Nexus::getProfile()->loadAvatar(), this, true);
119  selfVideoSurface->setObjectName(QStringLiteral("CamVideoSurface"));
120  selfVideoSurface->setMouseTracking(true);
121  selfVideoSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
122 
123  selfFrame = new MovableWidget(videoSurface);
124  selfFrame->show();
125 
126  QHBoxLayout* frameLayout = new QHBoxLayout(selfFrame);
127  frameLayout->addWidget(selfVideoSurface);
128  frameLayout->setMargin(0);
129 
130  updateRatio();
131  connections +=
132  connect(selfVideoSurface, &VideoSurface::ratioChanged, this, &NetCamView::updateRatio);
133 
134  connections += connect(videoSurface, &VideoSurface::boundaryChanged, [this]() {
135  QRect boundingRect = videoSurface->getBoundingRect();
136  updateFrameSize(boundingRect.size());
137  selfFrame->setBoundary(boundingRect);
138  });
139 
140  connections += connect(videoSurface, &VideoSurface::ratioChanged, [this]() {
141  selfFrame->setMinimumWidth(selfFrame->minimumHeight() * selfVideoSurface->getRatio());
142  QRect boundingRect = videoSurface->getBoundingRect();
143  updateFrameSize(boundingRect.size());
144  selfFrame->resetBoundary(boundingRect);
145  });
146 
147  connections += connect(Nexus::getProfile(), &Profile::selfAvatarChanged,
148  [this](const QPixmap& pixmap) { selfVideoSurface->setAvatar(pixmap); });
149 
150  connections += connect(Nexus::getProfile(), &Profile::friendAvatarChanged,
151  [this](ToxPk friendPk, const QPixmap& pixmap) {
152  if (this->friendPk == friendPk)
153  videoSurface->setAvatar(pixmap);
154  });
155 
156  QRect videoSize = Settings::getInstance().getCamVideoRes();
157  qDebug() << "SIZER" << videoSize;
158 }
159 
161 {
162  for (QMetaObject::Connection conn : connections)
163  disconnect(conn);
164 }
165 
166 void NetCamView::show(VideoSource* source, const QString& title)
167 {
168  setSource(source);
170 
171  setTitle(title);
172  QWidget::show();
173 }
174 
176 {
177  setSource(nullptr);
178  selfVideoSurface->setSource(nullptr);
179 
180  if (selfFrame)
181  selfFrame->deleteLater();
182 
183  selfFrame = nullptr;
184 
185  QWidget::hide();
186 }
187 
189 {
191 }
192 
193 void NetCamView::setTitle(const QString& title)
194 {
195  setWindowTitle(title);
196 }
197 
198 void NetCamView::showEvent(QShowEvent* event)
199 {
200  Q_UNUSED(event)
202 }
203 
205 {
206  selfFrame->setMinimumWidth(selfFrame->minimumHeight() * selfVideoSurface->getRatio());
208 }
209 
211 {
212  selfFrame->setMaximumSize(size.height() / 3, size.width() / 3);
213 
214  if (selfFrame->maximumWidth() > selfFrame->maximumHeight())
215  selfFrame->setMaximumWidth(selfFrame->maximumHeight() * selfVideoSurface->getRatio());
216  else
217  selfFrame->setMaximumHeight(selfFrame->maximumWidth() / selfVideoSurface->getRatio());
218 }
219 
221 {
222  QSize surfaceSize = videoSurface->minimumSize();
223  QSize buttonSize = toggleMessagesButton->size();
224  QSize panelSize(0, 45);
225 
226  return surfaceSize + buttonSize + panelSize;
227 }
228 
229 void NetCamView::setShowMessages(bool show, bool notify)
230 {
231  if (!show) {
232  toggleMessagesButton->setText(tr("Hide messages"));
233  toggleMessagesButton->setIcon(QIcon());
234  return;
235  }
236 
237  toggleMessagesButton->setText(tr("Show messages"));
238 
239  if (notify) {
240  toggleMessagesButton->setIcon(QIcon(Style::getImagePath("chatArea/info.svg")));
241  }
242 }
243 
245 {
246  if (isFullScreen()) {
247  exitFullScreen();
248  } else {
249  enterFullScreen();
250  }
251 }
252 
254 {
255  setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
256  showFullScreen();
257  enterFullScreenButton->hide();
258  toggleMessagesButton->hide();
259 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
260  const auto screenSize = QGuiApplication::screenAt(this->pos())->geometry();
261 #else
262  const QRect screenSize = QApplication::desktop()->screenGeometry(this);
263 #endif
264  buttonPanel->setGeometry((screenSize.width() / 2) - buttonPanel->width() / 2,
265  screenSize.height() - BTN_PANEL_HEIGHT - 25, BTN_PANEL_WIDTH, BTN_PANEL_HEIGHT);
266  buttonPanel->show();
267  buttonPanel->activateWindow();
268  buttonPanel->raise();
269 }
270 
272 {
273  setWindowFlags(Qt::Widget);
274  showNormal();
275  buttonPanel->hide();
276  enterFullScreenButton->show();
277  toggleMessagesButton->show();
278 }
279 
281 {
283  emit videoCallEnd();
284 }
285 
287 {
289  if (selfFrame->isHidden()) {
290  selfFrame->show();
291  } else {
292  selfFrame->hide();
293  }
294 }
295 
296 QPushButton* NetCamView::createButton(const QString& name, const QString& state)
297 {
298  QPushButton* btn = new QPushButton();
299  btn->setAttribute(Qt::WA_LayoutUsesWidgetRect);
300  btn->setObjectName(name);
301  btn->setProperty("state", QVariant(state));
302  btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
303 
304  return btn;
305 }
306 
308 {
309  updateButtonState(volumeButton, !isMuted);
310 }
311 
313 {
315 }
316 
317 void NetCamView::toggleButtonState(QPushButton* btn)
318 {
319  if (btn->property("state") == BTN_STATE_RED) {
320  btn->setProperty("state", BTN_STATE_NONE);
321  } else {
322  btn->setProperty("state", BTN_STATE_RED);
323  }
324 
325  btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
326 }
327 
328 void NetCamView::updateButtonState(QPushButton* btn, bool active)
329 {
330  if (active) {
331  btn->setProperty("state", BTN_STATE_NONE);
332  } else {
333  btn->setProperty("state", BTN_STATE_RED);
334  }
335 
336  btn->setStyleSheet(Style::getStylesheet(BTN_STYLE_SHEET_PATH));
337 }
338 
339 void NetCamView::keyPressEvent(QKeyEvent *event)
340 {
341  int key = event->key();
342  if (key == Qt::Key_Escape && isFullScreen()) {
343  exitFullScreen();
344  }
345 }
346 
347 void NetCamView::closeEvent(QCloseEvent *event)
348 {
349  exitFullScreen();
350  event->ignore();
351 }
profile.h
style.h
NetCamView::showEvent
void showEvent(QShowEvent *event)
Definition: netcamview.cpp:198
friend.h
friendlist.h
settings.h
VideoSource
An abstract source of video frames.
Definition: videosource.h:29
netcamview.h
NetCamView::closeEvent
void closeEvent(QCloseEvent *event)
Definition: netcamview.cpp:347
NetCamView::videoCallEnd
void videoCallEnd()
NetCamView::buttonPanel
QFrame * buttonPanel
Definition: netcamview.h:92
VideoSurface::getBoundingRect
QRect getBoundingRect() const
Definition: videosurface.cpp:88
NetCamView::hide
virtual void hide()
Definition: netcamview.cpp:175
Style::getImagePath
static const QString getImagePath(const QString &filename)
Definition: style.cpp:182
NetCamView::microphoneButton
QPushButton * microphoneButton
Definition: netcamview.h:95
NetCamView::toggleButtonState
void toggleButtonState(QPushButton *btn)
Definition: netcamview.cpp:317
NetCamView::show
virtual void show(VideoSource *source, const QString &title)
Definition: netcamview.cpp:166
NetCamView::exitFullScreen
void exitFullScreen()
Definition: netcamview.cpp:271
NetCamView::micMuteToggle
void micMuteToggle()
Nexus::getProfile
static Profile * getProfile()
Get current user profile.
Definition: nexus.cpp:290
NetCamView::~NetCamView
~NetCamView()
Definition: netcamview.cpp:160
NetCamView::endVideoCall
void endVideoCall()
Definition: netcamview.cpp:280
NetCamView::NetCamView
NetCamView(ToxPk friendPk, QWidget *parent=nullptr)
Definition: netcamview.cpp:50
NetCamView::createButton
QPushButton * createButton(const QString &name, const QString &state)
Definition: netcamview.cpp:296
MovableWidget
Definition: movablewidget.h:24
NetCamView::getSurfaceMinSize
QSize getSurfaceMinSize()
Definition: netcamview.cpp:220
NetCamView::toggleMessagesButton
QPushButton * toggleMessagesButton
Definition: netcamview.h:91
ToxPk
This class represents a Tox Public Key, which is a part of Tox ID.
Definition: toxpk.h:26
camerasource.h
Profile::friendAvatarChanged
void friendAvatarChanged(const ToxPk &friendPk, const QPixmap &pixmap)
NetCamView::updateMuteVolButton
void updateMuteVolButton(bool isMuted)
Definition: netcamview.cpp:307
MovableWidget::resetBoundary
void resetBoundary(QRect newBoundary)
Definition: movablewidget.cpp:37
NetCamView::connections
QVector< QMetaObject::Connection > connections
Definition: netcamview.h:89
Settings::getCamVideoRes
QRect getCamVideoRes() const override
Definition: settings.cpp:1832
NetCamView::videoSurface
VideoSurface * videoSurface
Definition: netcamview.h:56
VideoSurface::getRatio
float getRatio() const
Definition: videosurface.cpp:95
NetCamView::setSource
void setSource(VideoSource *s)
Definition: netcamview.cpp:188
MovableWidget::setRatio
void setRatio(float r)
Definition: movablewidget.cpp:88
videosurface.h
NetCamView::updateRatio
void updateRatio()
Definition: netcamview.cpp:204
VideoSurface::setSource
void setSource(VideoSource *src)
Update source.
Definition: videosurface.cpp:78
NetCamView::keyPressEvent
void keyPressEvent(QKeyEvent *event)
Definition: netcamview.cpp:339
Settings::getInstance
static Settings & getInstance()
Returns the singleton instance.
Definition: settings.cpp:88
NetCamView::selfFrame
MovableWidget * selfFrame
Definition: netcamview.h:86
NetCamView::toggleFullScreen
void toggleFullScreen()
Definition: netcamview.cpp:244
movablewidget.h
VideoSurface::ratioChanged
void ratioChanged()
CameraSource::getInstance
static CameraSource & getInstance()
Returns the singleton instance.
Definition: camerasource.cpp:128
NetCamView::enterFullScreenButton
QPushButton * enterFullScreenButton
Definition: netcamview.h:57
NetCamView::volumeButton
QPushButton * volumeButton
Definition: netcamview.h:94
NetCamView::toggleVideoPreview
void toggleVideoPreview()
Definition: netcamview.cpp:286
NetCamView::updateFrameSize
void updateFrameSize(QSize size)
Definition: netcamview.cpp:210
VideoSurface::boundaryChanged
void boundaryChanged()
Style::getStylesheet
static const QString getStylesheet(const QString &filename, const QFont &baseFont=QFont())
Definition: style.cpp:165
NetCamView::updateButtonState
void updateButtonState(QPushButton *btn, bool active)
Definition: netcamview.cpp:328
core.h
NetCamView::setTitle
void setTitle(const QString &title)
Definition: netcamview.cpp:193
NetCamView::enterFullScreen
void enterFullScreen()
Definition: netcamview.cpp:253
NetCamView::videoPreviewButton
QPushButton * videoPreviewButton
Definition: netcamview.h:93
NetCamView::showMessageClicked
void showMessageClicked()
NetCamView::setShowMessages
void setShowMessages(bool show, bool notify=false)
Definition: netcamview.cpp:229
NetCamView::selfVideoSurface
VideoSurface * selfVideoSurface
Definition: netcamview.h:85
NetCamView::updateMuteMicButton
void updateMuteMicButton(bool isMuted)
Definition: netcamview.cpp:312
VideoSurface
Definition: videosurface.h:27
NetCamView::volMuteToggle
void volMuteToggle()
Profile::selfAvatarChanged
void selfAvatarChanged(const QPixmap &pixmap)
nexus.h