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 | |
28 | using namespace Qt; |
29 | |
30 | QT_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 | */ |
61 | QVideoWidget::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 | */ |
78 | QVideoWidget::~QVideoWidget() |
79 | { |
80 | delete d_ptr->videoWindow; |
81 | delete d_ptr; |
82 | } |
83 | |
84 | /*! |
85 | Returns the QVideoSink instance. |
86 | */ |
87 | QVideoSink *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 | |
97 | Qt::AspectRatioMode QVideoWidget::aspectRatioMode() const |
98 | { |
99 | return d_ptr->videoWindow->aspectRatioMode(); |
100 | } |
101 | |
102 | void 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 | |
112 | void 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 | */ |
148 | QSize 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 | */ |
162 | bool 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 | */ |
181 | void QVideoWidget::showEvent(QShowEvent *event) |
182 | { |
183 | QWidget::showEvent(event); |
184 | } |
185 | |
186 | /*! |
187 | \reimp |
188 | Handles the hide \a event. |
189 | */ |
190 | void QVideoWidget::hideEvent(QHideEvent *event) |
191 | { |
192 | QWidget::hideEvent(event); |
193 | } |
194 | |
195 | /*! |
196 | \reimp |
197 | Handles the resize \a event. |
198 | */ |
199 | void 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 | */ |
209 | void QVideoWidget::moveEvent(QMoveEvent * /*event*/) |
210 | { |
211 | } |
212 | |
213 | QT_END_NAMESPACE |
214 | |
215 | #include "moc_qvideowidget.cpp" |
216 | |