1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <private/qtmultimediaglobal_p.h>
5#include "qvideowidget_p.h"
6
7#include <QtCore/qobject.h>
8#include <QtMultimedia/qtmultimediaglobal.h>
9#include <qvideosink.h>
10#include <private/qvideowindow_p.h>
11
12#include <qobject.h>
13#include <qvideoframeformat.h>
14#include <qpainter.h>
15
16#include <qapplication.h>
17#include <qevent.h>
18#include <qboxlayout.h>
19#include <qnamespace.h>
20
21#include <qwindow.h>
22#include <private/qhighdpiscaling_p.h>
23
24#ifdef Q_OS_WIN
25#include <QtCore/qt_windows.h>
26#endif
27
28using namespace Qt;
29
30QT_BEGIN_NAMESPACE
31
32/*!
33 \class QVideoWidget
34
35
36 \brief The QVideoWidget class provides a widget which presents video
37 produced by a media object.
38 \ingroup multimedia
39 \ingroup multimedia_video
40 \inmodule QtMultimediaWidgets
41
42 Attaching a QVideoWidget to a QMediaPlayer or QCamera allows it to display the
43 video or image output of that object.
44
45 \snippet multimedia-snippets/video.cpp Video widget
46
47 \b {Note}: Only a single display output can be attached to a media
48 object at one time.
49
50 \sa QCamera, QMediaPlayer, QGraphicsVideoItem
51*/
52/*!
53 \variable QVideoWidget::d_ptr
54 \internal
55*/
56/*!
57 Constructs a new video widget.
58
59 The \a parent is passed to QWidget.
60*/
61QVideoWidget::QVideoWidget(QWidget *parent)
62 : QWidget(parent, {})
63 , d_ptr(new QVideoWidgetPrivate)
64{
65 d_ptr->q_ptr = this;
66 d_ptr->videoWindow = new QVideoWindow;
67 d_ptr->videoWindow->setFlag(Qt::WindowTransparentForInput, on: true);
68 d_ptr->windowContainer = QWidget::createWindowContainer(window: d_ptr->videoWindow, parent: this, flags: Qt::WindowTransparentForInput);
69 d_ptr->windowContainer->move(ax: 0, ay: 0);
70 d_ptr->windowContainer->resize(size());
71
72 connect(sender: d_ptr->videoWindow, signal: &QVideoWindow::aspectRatioModeChanged, context: this, slot: &QVideoWidget::aspectRatioModeChanged);
73}
74
75/*!
76 Destroys a video widget.
77*/
78QVideoWidget::~QVideoWidget()
79{
80 delete d_ptr->videoWindow;
81 delete d_ptr;
82}
83
84/*!
85 Returns the QVideoSink instance.
86*/
87QVideoSink *QVideoWidget::videoSink() const
88{
89 return d_ptr->videoWindow->videoSink();
90}
91
92/*!
93 \property QVideoWidget::aspectRatioMode
94 \brief how video is scaled with respect to its aspect ratio.
95*/
96
97Qt::AspectRatioMode QVideoWidget::aspectRatioMode() const
98{
99 return d_ptr->videoWindow->aspectRatioMode();
100}
101
102void QVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode)
103{
104 d_ptr->videoWindow->setAspectRatioMode(mode);
105}
106
107/*!
108 \property QVideoWidget::fullScreen
109 \brief whether video display is confined to a window or is fullScreen.
110*/
111
112void QVideoWidget::setFullScreen(bool fullScreen)
113{
114 Q_D(QVideoWidget);
115 if (isFullScreen() == fullScreen)
116 return;
117
118 Qt::WindowFlags flags = windowFlags();
119
120 if (fullScreen) {
121 // get the position of the widget in global coordinates
122 QPoint position = mapToGlobal(QPoint(0,0));
123 d->nonFullScreenFlags = flags & (Qt::Window | Qt::SubWindow);
124 d_ptr->nonFullscreenPos = pos();
125 flags |= Qt::Window;
126 flags &= ~Qt::SubWindow;
127 setWindowFlags(flags);
128 // move the widget to the position it had on screen, so that showFullScreen() will
129 // place it on the correct screen
130 move(position);
131
132 showFullScreen();
133 } else {
134 flags &= ~(Qt::Window | Qt::SubWindow); //clear the flags...
135 flags |= d->nonFullScreenFlags; //then we reset the flags (window and subwindow)
136 setWindowFlags(flags);
137
138 showNormal();
139 move(d_ptr->nonFullscreenPos);
140 d_ptr->nonFullscreenPos = {};
141 }
142}
143
144/*!
145 Returns the size hint for the current back end,
146 if there is one, or else the size hint from QWidget.
147 */
148QSize QVideoWidget::sizeHint() const
149{
150 auto size = videoSink()->videoSize();
151 if (size.isValid())
152 return size;
153
154 return QWidget::sizeHint();
155}
156
157/*!
158 \reimp
159 Current event \a event.
160 Returns the value of the base class QWidget::event(QEvent *event) function.
161*/
162bool QVideoWidget::event(QEvent *event)
163{
164 Q_D(QVideoWidget);
165
166 if (event->type() == QEvent::WindowStateChange) {
167 bool fullScreen = bool(windowState() & Qt::WindowFullScreen);
168 if (fullScreen != d->wasFullScreen) {
169 emit fullScreenChanged(fullScreen);
170 d->wasFullScreen = fullScreen;
171 }
172 }
173
174 return QWidget::event(event);
175}
176
177/*!
178 \reimp
179 Handles the show \a event.
180 */
181void QVideoWidget::showEvent(QShowEvent *event)
182{
183 QWidget::showEvent(event);
184}
185
186/*!
187 \reimp
188 Handles the hide \a event.
189*/
190void QVideoWidget::hideEvent(QHideEvent *event)
191{
192 QWidget::hideEvent(event);
193}
194
195/*!
196 \reimp
197 Handles the resize \a event.
198 */
199void QVideoWidget::resizeEvent(QResizeEvent *event)
200{
201 d_ptr->windowContainer->resize(event->size());
202 QWidget::resizeEvent(event);
203}
204
205/*!
206 \reimp
207 Handles the move \a event.
208 */
209void QVideoWidget::moveEvent(QMoveEvent * /*event*/)
210{
211}
212
213QT_END_NAMESPACE
214
215#include "moc_qvideowidget.cpp"
216

source code of qtmultimedia/src/multimediawidgets/qvideowidget.cpp