diff options
Diffstat (limited to 'examples')
47 files changed, 423 insertions, 403 deletions
diff --git a/examples/multimedia/video/qmlvideo/CMakeLists.txt b/examples/multimedia/video/qmlvideo/CMakeLists.txt index fc7e2bd10..43975d584 100644 --- a/examples/multimedia/video/qmlvideo/CMakeLists.txt +++ b/examples/multimedia/video/qmlvideo/CMakeLists.txt @@ -36,18 +36,21 @@ target_compile_definitions(qmlvideoexample PUBLIC PERFORMANCEMONITOR_SUPPORT ) +add_subdirectory(qmlvideo) +add_subdirectory(performancemonitor) +add_subdirectory(frequencymonitor) + target_link_libraries(qmlvideoexample PRIVATE Qt::Core Qt::Gui Qt::Multimedia Qt::Qml Qt::Quick + qmlvideo + performancemonitor + frequencymonitor ) -add_subdirectory(qmlvideo) -add_subdirectory(performancemonitor) -add_subdirectory(frequencymonitor) - install(TARGETS qmlvideoexample RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" diff --git a/examples/multimedia/video/qmlvideo/main.cpp b/examples/multimedia/video/qmlvideo/main.cpp index 15df44dd2..94c5bfea0 100644 --- a/examples/multimedia/video/qmlvideo/main.cpp +++ b/examples/multimedia/video/qmlvideo/main.cpp @@ -3,6 +3,7 @@ #include "performancemonitor.h" #include "trace.h" +#include "qmlvideo/videosingleton.h" #ifdef PERFORMANCEMONITOR_SUPPORT # include "performancemonitordeclarative.h" #endif @@ -78,16 +79,21 @@ int main(int argc, char *argv[]) url2 = QUrl::fromLocalFile(source2); } + const QStringList moviesLocation = QStandardPaths::standardLocations(QStandardPaths::MoviesLocation); + const QUrl videoPath = QUrl::fromLocalFile(moviesLocation.isEmpty() ? app.applicationDirPath() + : moviesLocation.front()); + QQuickView viewer; + VideoSingleton* singleton = viewer.engine()->singletonInstance<VideoSingleton*>("qmlvideo", "VideoSingleton"); + singleton->setVideoPath(videoPath); + singleton->setSource1(source1); + singleton->setSource2(source2); + singleton->setVolume(volume); viewer.loadFromModule("qmlvideo", "Main"); QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QQuickView::close); - QQuickItem *rootObject = viewer.rootObject(); - rootObject->setProperty("source1", url1); - rootObject->setProperty("source2", url2); - rootObject->setProperty("volume", volume); - #ifdef PERFORMANCEMONITOR_SUPPORT + QQuickItem *rootObject = viewer.rootObject(); if (performanceMonitorState.valid) { rootObject->setProperty("perfMonitorsLogging", performanceMonitorState.logging); rootObject->setProperty("perfMonitorsVisible", performanceMonitorState.visible); @@ -95,12 +101,6 @@ int main(int argc, char *argv[]) QObject::connect(&viewer, SIGNAL(afterRendering()), rootObject, SLOT(qmlFramePainted())); #endif - const QStringList moviesLocation = - QStandardPaths::standardLocations(QStandardPaths::MoviesLocation); - const QUrl videoPath = QUrl::fromLocalFile(moviesLocation.isEmpty() ? app.applicationDirPath() - : moviesLocation.front()); - viewer.rootContext()->setContextProperty("videoPath", videoPath); - QMetaObject::invokeMethod(rootObject, "init"); auto setupView = [&viewer]() { diff --git a/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml b/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml index 12253be62..5b501b104 100644 --- a/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml +++ b/examples/multimedia/video/qmlvideo/performancemonitor/PerformanceItem.qml @@ -41,8 +41,7 @@ Rectangle { State { name: "hidden" PropertyChanges { - target: root - opacity: 0 + root.opacity: 0 } } ] @@ -64,19 +63,19 @@ Rectangle { function createQmlFrameRateItem() { let component = Qt.createComponent("frequencymonitor", "FrequencyItem") if (component.status === Component.Ready) - d.qmlFrameRateItem = component.createObject(column, { label: "QML frame rate", - displayed: root.displayed, + d.qmlFrameRateItem = component.createObject(column, { label: qsTr("QML frame rate"), + displayed: root.displayed, logging: root.logging - }) + }); } function createVideoFrameRateItem() { let component = Qt.createComponent("frequencymonitor", "FrequencyItem") if (component.status === Component.Ready) - d.videoFrameRateItem = component.createObject(column, { label: "Video frame rate", - displayed: root.displayed, + d.videoFrameRateItem = component.createObject(column, { label: qsTr("Video frame rate"), + displayed: root.displayed, logging: root.logging - }) + }); videoFrameRateActiveConnections.target = d.videoFrameRateItem } @@ -87,13 +86,11 @@ Rectangle { } function videoFramePainted() { - if (d.videoFrameRateItem) - d.videoFrameRateItem.notify() + d.videoFrameRateItem?.notify() } function qmlFramePainted() { - if (d.qmlFrameRateItem) - d.qmlFrameRateItem.notify() + d.qmlFrameRateItem?.notify() } onVideoActiveChanged: { diff --git a/examples/multimedia/video/qmlvideo/qmlvideo.pro b/examples/multimedia/video/qmlvideo/qmlvideo.pro index cabdddbe0..b61339264 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo.pro +++ b/examples/multimedia/video/qmlvideo/qmlvideo.pro @@ -12,27 +12,29 @@ DEFINES += \ PERFORMANCEMONITOR_SUPPORT SOURCES += \ - main.cpp \ frequencymonitor.cpp \ frequencymonitordeclarative.cpp \ + main.cpp \ performancemonitor.cpp \ - performancemonitordeclarative.cpp + performancemonitordeclarative.cpp \ + qmlvideo/videosingleton.cpp + +INCLUDEPATH += qmlvideo + +DEFINES += QMLVIDEO_LIB HEADERS += \ - trace.h \ frequencymonitor.h \ performancemonitor.h \ - performancemonitordeclarative.h + performancemonitordeclarative.h \ + trace.h \ + qmlvideo/videosingleton.h resources.files = \ - qmlvideo/images/folder.png \ - qmlvideo/images/leaves.jpg \ - qmlvideo/images/up.png \ frequencymonitor/FrequencyItem.qml \ frequencymonitor/qmldir \ performancemonitor/PerformanceItem.qml \ performancemonitor/qmldir \ - qmlvideo/Button.qml \ qmlvideo/CameraBasic.qml \ qmlvideo/CameraDrag.qml \ qmlvideo/CameraDummy.qml \ @@ -46,6 +48,7 @@ resources.files = \ qmlvideo/CameraSpin.qml \ qmlvideo/Content.qml \ qmlvideo/ErrorDialog.qml \ + qmlvideo/Main.qml \ qmlvideo/Scene.qml \ qmlvideo/SceneBasic.qml \ qmlvideo/SceneDrag.qml \ @@ -74,13 +77,19 @@ resources.files = \ qmlvideo/VideoRotate.qml \ qmlvideo/VideoSeek.qml \ qmlvideo/VideoSpin.qml \ - qmlvideo/Main.qml \ + qmlvideo/images/folder.png \ + qmlvideo/images/leaves.jpg \ + qmlvideo/images/up.png \ qmlvideo/qmldir resources.prefix = /qt/qml/ RESOURCES += resources +CONFIG += qmltypes +QML_IMPORT_NAME = qmlvideo +QML_IMPORT_MAJOR_VERSION = 1 + target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video/qmlvideo INSTALLS += target diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Button.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Button.qml deleted file mode 100644 index 3e33d418a..000000000 --- a/examples/multimedia/video/qmlvideo/qmlvideo/Button.qml +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause - -import QtQuick - -Item { - id: root - - property string text - property color bgColor: "#757575" - property color bgColorSelected: "#bdbdbd" - property color textColor: "white" - property color textColorSelected: "black" - property alias enabled: mouseArea.enabled - property alias radius: bgr.radius - - signal clicked - - Rectangle { - id: bgr - anchors.fill: parent - color: mouseArea.pressed ? bgColorSelected : bgColor - radius: height / 15 - - Text { - id: text - anchors.centerIn: parent - text: root.text - font.pixelSize: 0.4 * parent.height - color: mouseArea.pressed ? textColorSelected : textColor - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - - MouseArea { - id: mouseArea - anchors.fill: parent - onClicked: { - root.clicked() - } - } - } -} diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt b/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt index f81a29386..84a65710e 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CMakeLists.txt @@ -9,8 +9,11 @@ set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/multimedia/video/qmlvideo/qmlvide qt_add_qml_module(qmlvideo URI qmlvideo + SOURCES + videosingleton.cpp + videosingleton.h + qmlvideo_global.h QML_FILES - "Button.qml" "CameraBasic.qml" "CameraDrag.qml" "CameraDummy.qml" @@ -24,6 +27,7 @@ qt_add_qml_module(qmlvideo "CameraSpin.qml" "Content.qml" "ErrorDialog.qml" + "Main.qml" "Scene.qml" "SceneBasic.qml" "SceneDrag.qml" @@ -52,13 +56,14 @@ qt_add_qml_module(qmlvideo "VideoRotate.qml" "VideoSeek.qml" "VideoSpin.qml" - "Main.qml" RESOURCES "images/folder.png" "images/leaves.jpg" "images/up.png" ) +target_compile_definitions(qmlvideo PRIVATE QMLVIDEO_LIB) + target_link_libraries(qmlvideo PRIVATE Qt6::Core Qt6::Gui diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml index 4c85f358c..77072c6c9 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraBasic.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneBasic { contentType: "camera" started: true diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml index a733548dd..2ea3672c6 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDrag.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneDrag { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml index cf59c04f1..c9d14e595 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraDummy.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls // Item which is loaded by CameraItem if Qt Multimedia is not available Rectangle { @@ -13,12 +14,11 @@ Rectangle { signal sizeChanged signal framePainted - Text { + Label { anchors.fill: parent anchors.margins: 10 - color: "white" horizontalAlignment: Text.AlignHCenter - text: "Failed to create Camera item\n\nCheck that Qt Multimedia is installed" + text: qsTr("Failed to create Camera item\n\nCheck that Qt Multimedia is installed") verticalAlignment: Text.AlignVCenter wrapMode: Text.Wrap } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml index 03e3d2661..b204e74ab 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreen.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneFullScreen { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml index dd6874f16..ff7a40253 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraFullScreenInverted.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneFullScreenInverted { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml index 1f7db298b..c4c5da914 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraMove.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneMove { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml index 3b152ca5d..13136be00 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraOverlay.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneOverlay { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml index 327541982..d89eef3ad 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraResize.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneResize { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml index 86cac7a1b..8394fb6fd 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraRotate.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneRotate { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml b/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml index 55a51430d..642a0edfd 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/CameraSpin.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneSpin { contentType: "camera" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml index b808002e1..b08d19325 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/Content.qml @@ -6,7 +6,7 @@ import frequencymonitor Rectangle { id: root - border.color: "white" + border.color: palette.window border.width: showBorder ? 1 : 0 color: "transparent" property string contentType // "camera" or "video" @@ -17,6 +17,7 @@ Rectangle { property bool started: false property bool showFrameRate: false property bool showBorder: false + property alias contentItem: contentLoader.item signal initialized signal error @@ -29,8 +30,7 @@ Rectangle { Connections { id: framePaintedConnection function onFramePainted() { - if (frameRateLoader.item) - frameRateLoader.item.notify() + (frameRateLoader.item as FrequencyItem)?.notify() root.videoFramePainted() } ignoreUnknownSignals: true @@ -40,15 +40,20 @@ Rectangle { id: errorConnection function onFatalError() { console.log("[qmlvideo] Content.onFatalError") - stop() + root.stop() root.error() } ignoreUnknownSignals: true } + Component { + id: frequencyItem + FrequencyItem {} + } + Loader { id: frameRateLoader - sourceComponent: root.showFrameRate ? FrequencyItem : undefined + sourceComponent: root.showFrameRate ? frequencyItem : undefined onLoaded: { item.parent = root item.anchors.top = root.top @@ -58,13 +63,13 @@ Rectangle { } onWidthChanged: { - if (contentItem()) - contentItem().width = width + if (root.contentItem) + root.contentItem.width = width } onHeightChanged: { - if (contentItem()) - contentItem().height = height + if (root.contentItem) + root.contentItem.height = height } function initialize() { @@ -105,6 +110,7 @@ Rectangle { } } + // qmllint disable function stop() { if (contentLoader.item) { contentLoader.item.stop() @@ -113,7 +119,7 @@ Rectangle { root.started = false } } + // qmllint enable - function contentItem() { return contentLoader.item } - function updateRootSize() { root.height = contentItem().height } + function updateRootSize() { root.height = (root.contentItem as Item).height } } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml b/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml index ce79b150f..f06079a35 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/ErrorDialog.qml @@ -16,8 +16,7 @@ Rectangle { State { name: "on" PropertyChanges { - target: root - opacity: 1.0 + root.opacity: 1.0 } } ] @@ -42,8 +41,8 @@ Rectangle { Rectangle { anchors.centerIn: parent - width: dialogWidth - height: dialogHeight + width: root.dialogWidth + height: root.dialogHeight radius: 5 color: "white" diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml index aabafcb2c..49b94590c 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/Main.qml @@ -2,43 +2,39 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls +import QtQuick.Layouts import QtQuick.Dialogs import performancemonitor Rectangle { id: root anchors.fill: parent - color: "black" + color: palette.window - property string source1 - property string source2 - property color bgColor: "black" - property real volume: 0.25 property bool perfMonitorsLogging: false property bool perfMonitorsVisible: false - QtObject { - id: d - property int itemHeight: root.height > root.width ? root.width / 10 : root.height / 10 - property int buttonHeight: 0.8 * itemHeight - property int margins: 5 - } - Loader { id: performanceLoader Connections { - target: inner + target: columnLayout function onVisibleChanged() { if (performanceLoader.item) - performanceLoader.item.enabled = !inner.visible + performanceLoader.item.enabled = !columnLayout.visible } ignoreUnknownSignals: true } + Component { + id: performanceItem + PerformanceItem {} + } + function init() { var enabled = root.perfMonitorsLogging || root.perfMonitorsVisible - sourceComponent = enabled ? PerformanceItem : undefined + sourceComponent = enabled ? performanceItem : undefined } onLoaded: { @@ -51,106 +47,58 @@ Rectangle { } } - Rectangle { - id: inner + ColumnLayout { + id: columnLayout anchors.fill: parent - color: root.bgColor + spacing: 5 Button { id: openFile1Button - anchors { - top: parent.top - left: parent.left - right: exitButton.left - margins: d.margins - } - bgColor: "#212121" - bgColorSelected: "#757575" - textColorSelected: "white" - height: d.buttonHeight - text: (root.source1 == "") ? "Select file 1" : root.source1 + text: (VideoSingleton.source1 == '') ? qsTr("Select file 1") : VideoSingleton.source1 + Component.onCompleted: console.log("source1: " + VideoSingleton.source1) onClicked: { - fileBrowser.setFirstSource = true - fileBrowser.open() + fileDialog.setFirstSource = true + fileDialog.open() } + + Layout.fillWidth: true } Button { id: openFile2Button - anchors { - top: openFile1Button.bottom - left: parent.left - right: exitButton.left - margins: d.margins - } - bgColor: "#212121" - bgColorSelected: "#757575" - textColorSelected: "white" - height: d.buttonHeight - text: (root.source2 == "") ? "Select file 2" : root.source2 + text: (VideoSingleton.source2 == '') ? qsTr("Select file 2") : VideoSingleton.source2 + Component.onCompleted: console.log("source2: " + VideoSingleton.source2) onClicked: { - fileBrowser.setFirstSource = false - fileBrowser.open() + fileDialog.setFirstSource = false + fileDialog.open() } - } - Button { - id: exitButton - anchors { - top: parent.top - right: parent.right - margins: d.margins - } - bgColor: "#212121" - bgColorSelected: "#757575" - textColorSelected: "white" - width: parent.width / 10 - height: d.buttonHeight - text: "Exit" - onClicked: Qt.quit() + Layout.fillWidth: true } - Row { - id: modes - anchors.top: openFile2Button.bottom - anchors.margins: 0 - anchors.topMargin: 5 - Button { - width: root.width / 2 - height: 0.8 * d.itemHeight - bgColor: "#212121" - radius: 0 - text: "Video Modes" - enabled: false - } - Button { - width: root.width / 2 - height: 0.8 * d.itemHeight - bgColor: "#212121" - radius: 0 - text: "Camera Modes" - enabled: false + RowLayout { + Layout.fillWidth: true + + Label { + text: qsTr("Video Modes") + + horizontalAlignment: Qt.AlignHCenter + Layout.preferredWidth: 50 + Layout.fillWidth: true } - } + Label { + text: qsTr("Camera Modes") - Rectangle { - id: divider - height: 1 - width: parent.width - color: "black" - anchors.top: modes.bottom + horizontalAlignment: Qt.AlignHCenter + Layout.preferredWidth: 50 + Layout.fillWidth: true + } } SceneSelectionPanel { id: sceneSelectionPanel - itemHeight: d.itemHeight - color: "#212121" - anchors { - top: divider.bottom - left: parent.left - right: parent.right - bottom: parent.bottom - } + itemHeight: Math.min(width / 10, height / 10) + color: palette.dark radius: 0 onSceneSourceChanged: { sceneLoader.source = sceneSource @@ -162,16 +110,15 @@ Rectangle { } else { scene = sceneLoader.item if (scene) { - if (scene.contentType === "video" && source1 === "") { - errorDialog.show("You must first select a video file") + if (scene.contentType === "video" && VideoSingleton.source1 === "") { + errorDialog.show(qsTr("You must first select a video file")) sceneSource = "" } else { scene.parent = root - scene.color = root.bgColor - scene.buttonHeight = d.buttonHeight - scene.source1 = source1 - scene.source2 = source2 - scene.volume = volume + scene.color = root.palette.window + scene.source1 = VideoSingleton.source1 + scene.source2 = VideoSingleton.source2 + scene.volume = VideoSingleton.volume scene.anchors.fill = root scene.close.connect(closeScene) scene.content.initialize() @@ -180,8 +127,11 @@ Rectangle { } } videoFramePaintedConnection.target = scene - inner.visible = innerVisible + columnLayout.visible = innerVisible } + + Layout.fillWidth: true + Layout.fillHeight: true } } @@ -191,42 +141,46 @@ Rectangle { Connections { id: videoFramePaintedConnection + // qmllint disable function onVideoFramePainted() { if (performanceLoader.item) performanceLoader.item.videoFramePainted() } + // qmllint enable ignoreUnknownSignals: true } FileDialog { - id: fileBrowser + id: fileDialog property bool setFirstSource - onAccepted: { + onAccepted: function() { if (setFirstSource) - root.source1 = currentFile + VideoSingleton.source1 = selectedFile else - root.source2 = currentFile + VideoSingleton.source2 = selectedFile } } ErrorDialog { id: errorDialog anchors.fill: root - dialogWidth: d.itemHeight * 5 - dialogHeight: d.itemHeight * 3 + dialogWidth: Math.min(root.width, root.height) * 0.5 + dialogHeight: Math.min(root.width, root.height) * 0.3 enabled: false } // Called from main() once root properties have been set function init() { performanceLoader.init() - fileBrowser.currentFolder = videoPath + fileDialog.currentFolder = VideoSingleton.videoPath } + // qmllint disable function qmlFramePainted() { if (performanceLoader.item) performanceLoader.item.qmlFramePainted() } + // qmllint enable function closeScene() { sceneSelectionPanel.sceneSource = "" diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml b/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml index c2903f63d..e16478d41 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/Scene.qml @@ -2,11 +2,11 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls Rectangle { id: root - color: "black" - property alias buttonHeight: closeButton.height + color: palette.window property string source1 property string source2 property int contentWidth: parent.width / 2 @@ -24,13 +24,8 @@ Rectangle { right: parent.right margins: root.margins } - width: Math.max(parent.width, parent.height) / 12 - height: Math.min(parent.width, parent.height) / 12 z: 2.0 - bgColor: "#212121" - bgColorSelected: "#757575" - textColorSelected: "white" - text: "Back" + text: qsTr("Back") onClicked: root.close() } } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml index 69b3a9ef4..8ad6c99b8 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneBasic.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls Scene { id: root @@ -21,15 +22,14 @@ Scene { onVideoFramePainted: root.videoFramePainted() } - Text { + Label { anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom margins: 20 } - text: content.started ? "Tap the screen to stop content" - : "Tap the screen to start content" - color: "#e0e0e0" + text: content.started ? qsTr("Tap the screen to stop content") + : qsTr("Tap the screen to start content") z: 2.0 } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml index 3e9997f37..ec8564311 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreen.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls Scene { id: root @@ -19,8 +20,10 @@ Scene { states: [ State { name: "fullScreen" - PropertyChanges { target: content; width: content.parent.width } - PropertyChanges { target: content; height: content.parent.height } + PropertyChanges { + content.width: content.parent.width + content.height: content.parent.height + } } ] @@ -49,14 +52,13 @@ Scene { onVideoFramePainted: root.videoFramePainted() } - Text { + Label { anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom margins: 20 } - text: "Tap on the content to toggle full-screen mode" - color: "#e0e0e0" + text: qsTr("Tap on the content to toggle full-screen mode") z: 2.0 } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml index 837c440f9..cb96ac134 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneFullScreenInverted.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls Scene { id: root @@ -20,7 +21,7 @@ Scene { states: [ State { name: "nonFullScreen" - PropertyChanges { target: content; width: content.parent.contentWidth } + PropertyChanges { content.width: root.contentWidth } } ] @@ -43,7 +44,7 @@ Scene { MouseArea { anchors.fill: parent - onClicked: content.state = (content.state == "nonFullScreen") ? "baseState" : "nonFullScreen" + onClicked: content.state = (content.state === "nonFullScreen") ? "baseState" : "nonFullScreen" } onVideoFramePainted: root.videoFramePainted() @@ -54,14 +55,13 @@ Scene { } } - Text { + Label { anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom margins: 20 } - text: "Tap on the content to toggle full-screen mode" - color: "#e0e0e0" + text: qsTr("Tap on the content to toggle full-screen mode") z: 2.0 } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml index c8fe939d7..d1512831e 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMove.qml @@ -19,7 +19,7 @@ Scene { SequentialAnimation on x { id: animation loops: Animation.Infinite - property int from: margin + property int from: root.margin property int to: 100 property int duration: 1500 running: false diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml index 54571b055..f93dabcdd 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneMulti.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls Scene { id: root @@ -24,28 +25,30 @@ Scene { id: root color: "transparent" - function content() { - return root.parent - } + signal start + signal stop - Text { + Label { anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom margins: 20 } - text: content() ? content().started ? "Tap to stop" : "Tap to start" : "" - color: "#e0e0e0" + // qmllint disable + text: root.started ? qsTr("Tap to stop") : qsTr("Tap to start") + // qmllint enable } MouseArea { anchors.fill: parent + // qmllint disable onClicked: { - if (content().started) - content().stop() + if (root.started) + root.stop() else - content().start() + root.start() } + // qmllint enable } } } @@ -63,14 +66,19 @@ Scene { showBorder: true showFrameRate: started source: parent.source1 - width: itemWidth + width: root.itemWidth volume: parent.volume Loader { id: video1StartStopLoader + + property bool started: parent.started + onLoaded: { item.parent = video1 item.anchors.fill = video1 + item.start.connect(video1.start) + item.stop.connect(video1.stop) } } @@ -79,17 +87,19 @@ Scene { Rectangle { id: cameraHolder + + property bool started: false + anchors { horizontalCenter: parent.horizontalCenter top: parent.top topMargin: root.itemTopMargin } border.width: 1 - border.color: "white" + border.color: palette.base color: "transparent" - width: itemWidth + width: root.itemWidth height: width - property bool started: false Loader { id: cameraLoader @@ -98,7 +108,7 @@ Scene { item.anchors.centerIn = cameraHolder item.contentType = "camera" item.showFrameRate = true - item.width = itemWidth + item.width = root.itemWidth item.z = 1.0 cameraErrorConnection.target = item item.initialize() @@ -107,17 +117,22 @@ Scene { Loader { id: cameraStartStopLoader + + property bool started: parent.started + sourceComponent: startStopComponent onLoaded: { item.parent = cameraHolder item.anchors.fill = cameraHolder item.z = 2.0 + item.start.connect(cameraHolder.start) + item.stop.connect(cameraHolder.stop) } } Connections { id: cameraErrorConnection - onError: { + function onError() { console.log("[qmlvideo] SceneMulti.camera.onError") cameraHolder.stop() } @@ -148,14 +163,19 @@ Scene { showBorder: true showFrameRate: started source: parent.source2 - width: itemWidth + width: root.itemWidth volume: parent.volume Loader { id: video2StartStopLoader + + property bool started: parent.started + onLoaded: { item.parent = video2 item.anchors.fill = video2 + item.start.connect(video2.start) + item.stop.connect(video2.stop) } } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml index 96c7af802..5863d618c 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneOverlay.qml @@ -29,7 +29,7 @@ Scene { SequentialAnimation on x { id: xAnimation loops: Animation.Infinite - property int from: margin + property int from: root.margin property int to: 100 property int duration: 1500 running: false @@ -50,7 +50,7 @@ Scene { SequentialAnimation on y { id: yAnimation loops: Animation.Infinite - property int from: margin + property int from: root.margin property int to: 180 property int duration: 1500 running: false diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml index c38d4e1ce..1362522e6 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneRotate.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls Scene { id: root @@ -26,10 +27,8 @@ Scene { bottom: rotateNegativeButton.top margins: parent.margins } - width: Math.max(parent.width, parent.height) / 10 - height: root.buttonHeight - text: "Rotate +" + delta - onClicked: content.rotation = content.rotation + delta + text: qsTr("Rotate +%1").arg(root.delta) + onClicked: content.rotation = content.rotation + root.delta } Button { @@ -39,10 +38,8 @@ Scene { verticalCenter: parent.verticalCenter margins: parent.margins } - width: Math.max(parent.width, parent.height) / 10 - height: root.buttonHeight - text: "Rotate -" + delta - onClicked: content.rotation = content.rotation - delta + text: qsTr("Rotate -%1").arg(root.delta) + onClicked: content.rotation = content.rotation - root.delta } Button { @@ -52,8 +49,6 @@ Scene { verticalCenter: parent.verticalCenter margins: parent.margins } - width: Math.max(parent.width, parent.height) / 25 - height: root.buttonHeight enabled: false text: content.rotation % 360 } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml index 0bced4372..0301f5452 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SceneSelectionPanel.qml @@ -2,6 +2,9 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls + +pragma ComponentBehavior: Bound Rectangle { id: root @@ -10,48 +13,51 @@ Rectangle { ListModel { id: videolist - ListElement { name: "Multi"; source: "SceneMulti.qml" } - ListElement { name: "Video"; source: "VideoBasic.qml" } - ListElement { name: "Drag"; source: "VideoDrag.qml" } - ListElement { name: "Fillmode"; source: "VideoFillMode.qml" } - ListElement { name: "Fullscreen"; source: "VideoFullScreen.qml" } - ListElement { name: "Fullscreen-inverted"; source: "VideoFullScreenInverted.qml" } - ListElement { name: "Metadata"; source: "VideoMetadata.qml" } - ListElement { name: "Move"; source: "VideoMove.qml" } - ListElement { name: "Overlay"; source: "VideoOverlay.qml" } - ListElement { name: "Playback Rate"; source: "VideoPlaybackRate.qml" } - ListElement { name: "Resize"; source: "VideoResize.qml" } - ListElement { name: "Rotate"; source: "VideoRotate.qml" } - ListElement { name: "Spin"; source: "VideoSpin.qml" } - ListElement { name: "Seek"; source: "VideoSeek.qml" } + ListElement { name: qsTr("Multi"); source: "SceneMulti.qml" } + ListElement { name: qsTr("Video"); source: "VideoBasic.qml" } + ListElement { name: qsTr("Drag"); source: "VideoDrag.qml" } + ListElement { name: qsTr("Fillmode"); source: "VideoFillMode.qml" } + ListElement { name: qsTr("Fullscreen"); source: "VideoFullScreen.qml" } + ListElement { name: qsTr("Fullscreen-inverted"); source: "VideoFullScreenInverted.qml" } + ListElement { name: qsTr("Metadata"); source: "VideoMetadata.qml" } + ListElement { name: qsTr("Move"); source: "VideoMove.qml" } + ListElement { name: qsTr("Overlay"); source: "VideoOverlay.qml" } + ListElement { name: qsTr("Playback Rate"); source: "VideoPlaybackRate.qml" } + ListElement { name: qsTr("Resize"); source: "VideoResize.qml" } + ListElement { name: qsTr("Rotate"); source: "VideoRotate.qml" } + ListElement { name: qsTr("Spin"); source: "VideoSpin.qml" } + ListElement { name: qsTr("Seek"); source: "VideoSeek.qml" } } ListModel { id: cameralist - ListElement { name: "Camera"; source: "CameraBasic.qml" } - ListElement { name: "Drag"; source: "CameraDrag.qml" } - ListElement { name: "Fullscreen"; source: "CameraFullScreen.qml" } - ListElement { name: "Fullscreen-inverted"; source: "CameraFullScreenInverted.qml" } - ListElement { name: "Move"; source: "CameraMove.qml" } - ListElement { name: "Overlay"; source: "CameraOverlay.qml" } - ListElement { name: "Resize"; source: "CameraResize.qml" } - ListElement { name: "Rotate"; source: "CameraRotate.qml" } - ListElement { name: "Spin"; source: "CameraSpin.qml" } + ListElement { name: qsTr("Camera"); source: "CameraBasic.qml" } + ListElement { name: qsTr("Drag"); source: "CameraDrag.qml" } + ListElement { name: qsTr("Fullscreen"); source: "CameraFullScreen.qml" } + ListElement { name: qsTr("Fullscreen-inverted"); source: "CameraFullScreenInverted.qml" } + ListElement { name: qsTr("Move"); source: "CameraMove.qml" } + ListElement { name: qsTr("Overlay"); source: "CameraOverlay.qml" } + ListElement { name: qsTr("Resize"); source: "CameraResize.qml" } + ListElement { name: qsTr("Rotate"); source: "CameraRotate.qml" } + ListElement { name: qsTr("Spin"); source: "CameraSpin.qml" } } Component { id: leftDelegate Item { width: root.width / 2 - height: 0.8 * itemHeight + height: 0.8 * root.itemHeight + + required property string name + required property string source Button { anchors.fill: parent anchors.margins: 5 anchors.rightMargin: 2.5 anchors.bottomMargin: 0 - text: name - onClicked: root.sceneSource = source + text: parent.name + onClicked: root.sceneSource = parent.source } } } @@ -60,22 +66,25 @@ Rectangle { id: rightDelegate Item { width: root.width / 2 - height: 0.8 * itemHeight + height: 0.8 * root.itemHeight + + required property string name + required property string source Button { anchors.fill: parent anchors.margins: 5 anchors.leftMargin: 2.5 anchors.bottomMargin: 0 - text: name - onClicked: root.sceneSource = source + text: parent.name + onClicked: root.sceneSource = parent.source } } } Flickable { anchors.fill: parent - contentHeight: (itemHeight * videolist.count) + 10 + contentHeight: (root.itemHeight * videolist.count) + 10 clip: true Row { diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml b/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml index 392f8afb2..646e5e8ef 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/SeekControl.qml @@ -15,7 +15,7 @@ Item { Rectangle { id: background anchors.fill: parent - color: "white" + color: palette.base opacity: 0.3 radius: parent.height / 15 } @@ -24,7 +24,7 @@ Item { id: progressBar anchors { left: parent.left; top: parent.top; bottom: parent.bottom } width: seekControl.duration == 0 ? 0 : background.width * seekControl.playPosition / seekControl.duration - color: "black" + color: palette.highlight opacity: 0.7 } @@ -33,9 +33,9 @@ Item { anchors { left: parent.left; top: parent.top; bottom: parent.bottom; leftMargin: 10 } horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter - color: "white" + color: palette.windowText smooth: true - text: formatTime(playPosition) + text: seekControl.formatTime(seekControl.playPosition) } Text { @@ -43,16 +43,16 @@ Item { anchors { right: parent.right; top: parent.top; bottom: parent.bottom; rightMargin: 10 } horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter - color: "white" + color: palette.windowText smooth: true - text: formatTime(duration) + text: seekControl.formatTime(seekControl.duration) } Rectangle { id: progressHandle height: parent.height width: parent.height / 2 - color: "white" + color: palette.accent opacity: 0.5 anchors.verticalCenter: progressBar.verticalCenter x: seekControl.duration == 0 ? 0 : seekControl.playPosition / seekControl.duration * background.width @@ -96,8 +96,8 @@ Item { function formatTime(timeInMs) { if (!timeInMs || timeInMs <= 0) return "0:00" - var seconds = timeInMs / 1000; - var minutes = Math.floor(seconds / 60) + let seconds = timeInMs / 1000; + let minutes = Math.floor(seconds / 60) seconds = Math.floor(seconds % 60) if (seconds < 10) seconds = "0" + seconds; return minutes + ":" + seconds diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml index 83ef7cb6b..15c25c978 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoBasic.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneBasic { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml index ab0502e7c..4a5c5d49b 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDrag.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneDrag { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml index addc5bc3e..a30b9ebf6 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoDummy.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls // Item which is loaded by VideoItem if Qt Multimedia is not available Rectangle { @@ -18,12 +19,11 @@ Rectangle { signal sizeChanged signal framePainted - Text { + Label { anchors.fill: parent anchors.margins: 10 - color: "white" horizontalAlignment: Text.AlignHCenter - text: "Failed to create Video item\n\nCheck that Qt Multimedia is installed" + text: qsTr("Failed to create Video item\n\nCheck that Qt Multimedia is installed") verticalAlignment: Text.AlignVCenter wrapMode: Text.Wrap } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml index 86216d17f..af950c735 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFillMode.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls import QtMultimedia Scene { @@ -24,24 +25,24 @@ Scene { verticalCenter: parent.verticalCenter margins: parent.margins } - width: Math.max(parent.width, parent.height) / 5 - height: root.buttonHeight - text: "PreserveAspectFit" + text: qsTr("PreserveAspectFit") + // qmllint disable onClicked: { if (!content.dummy) { - var video = content.contentItem() + let video = content.contentItem if (video.fillMode === VideoOutput.Stretch) { video.fillMode = VideoOutput.PreserveAspectFit - text = "PreserveAspectFit" + text = qsTr("PreserveAspectFit") } else if (video.fillMode === VideoOutput.PreserveAspectFit) { video.fillMode = VideoOutput.PreserveAspectCrop - text = "PreserveAspectCrop" + text = qsTr("PreserveAspectCrop") } else { video.fillMode = VideoOutput.Stretch - text = "Stretch" + text = qsTr("Stretch") } } } + // qmllint enable } Component.onCompleted: root.content = content diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml index 1fec029a9..e49faadb6 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreen.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneFullScreen { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml index 0ff5037ec..0bf82941e 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoFullScreenInverted.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneFullScreenInverted { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml index d9b529607..f83cbffe9 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMetadata.qml @@ -2,14 +2,17 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls import QtMultimedia +pragma ComponentBehavior: Bound + Scene { id: root property string contentType: "video" Content { - id: content + id: videoContent anchors.centerIn: parent width: parent.contentWidth contentType: "video" @@ -26,61 +29,52 @@ Scene { id: metadata Column { anchors.fill: parent - property var videoMetaData: content.contentItem().metaData - Text { - color: "#e0e0e0" - text: "Title:" + videoMetaData.value(MediaMetaData.Title) + // qmllint disable + property var videoMetaData: videoContent.contentItem?.metaData + // qmllint enable + Label { + text: qsTr("Title: %1").arg(parent.videoMetaData?.value(MediaMetaData.Title) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Resolution:" + videoMetaData.value(MediaMetaData.Resolution) + Label { + text: qsTr("Resolution: %1").arg(parent.videoMetaData?.value(MediaMetaData.Resolution) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Media type:" + videoMetaData.value(MediaMetaData.MediaType) + Label { + text: qsTr("Media type: %1").arg(parent.videoMetaData?.value(MediaMetaData.MediaType) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Video codec:" + videoMetaData.value(MediaMetaData.VideoCodec) + Label { + text: qsTr("Video codec: %1").arg(parent.videoMetaData?.value(MediaMetaData.VideoCodec) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Video bit rate:" + videoMetaData.value(MediaMetaData.VideoBitRate) + Label { + text: qsTr("Video bit rate: %1").arg(parent.videoMetaData?.value(MediaMetaData.VideoBitRate) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Video frame rate:" +videoMetaData.value(MediaMetaData.VideoFrameRate) + Label { + text: qsTr("Video frame rate: %1").arg(parent.videoMetaData?.value(MediaMetaData.VideoFrameRate) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Audio codec:" + videoMetaData.value(MediaMetaData.AudioCodec) + Label { + text: qsTr("Audio codec: %1").arg(parent.videoMetaData?.value(MediaMetaData.AudioCodec) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Audio bit rate:" + videoMetaData.value(MediaMetaData.AudioBitRate) + Label { + text: qsTr("Audio bit rate: %1").arg(parent.videoMetaData?.value(MediaMetaData.AudioBitRate) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Date:" + videoMetaData.value(MediaMetaData.Date) + Label { + text: qsTr("Date: %1").arg(parent.videoMetaData?.value(MediaMetaData.Date) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Description:" + videoMetaData.value(MediaMetaData.Description) + Label { + text: qsTr("Description: %1").arg(parent.videoMetaData?.value(MediaMetaData.Description) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Copyright:" + videoMetaData.value(MediaMetaData.Copyright) + Label { + text: qsTr("Copyright: %1").arg(parent.videoMetaData?.value(MediaMetaData.Copyright) ?? qsTr("Unknown")) } - Text { - color: "#e0e0e0" - text: "Seekable:" + content.contentItem().seekable + Label { + // qmllint disable + text: qsTr("Seekable: %1").arg(videoContent.contentItem?.seekable ?? qsTr("Unknown")) + // qmllint enable } - Text { - color: "#e0e0e0" - text: "Orientation:" + videoMetaData.value(MediaMetaData.Orientation) + Label { + text: qsTr("Orientation: %1").arg(parent.videoMetaData?.value(MediaMetaData.Orientation) ?? qsTr("Unknown")) } } } - Component.onCompleted: root.content = content + Component.onCompleted: root.content = videoContent } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml index abfa32b25..2b9230f3c 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoMove.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneMove { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml index e664c36d6..576b33ff9 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoOverlay.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneOverlay { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml index 614dcd424..55e38ef19 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoPlaybackRate.qml @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick +import QtQuick.Controls Scene { id: root @@ -26,12 +27,10 @@ Scene { bottom: decreaseButton.top margins: parent.margins } - width: Math.max(parent.width, parent.height) / 10 - height: root.buttonHeight - text: "Increase" + text: qsTr("Increase") onClicked: { - var video = content.contentItem() - video.playbackRate += delta + let video = (content.contentItem as VideoItem) + video.playbackRate += root.delta } } @@ -42,12 +41,10 @@ Scene { verticalCenter: parent.verticalCenter margins: parent.margins } - width: Math.max(parent.width, parent.height) / 10 - height: root.buttonHeight - text: "Decrease" + text: qsTr("Decrease") onClicked: { - var video = content.contentItem() - video.playbackRate -= delta + let video = (content.contentItem as VideoItem) + video.playbackRate -= root.delta } } @@ -58,10 +55,10 @@ Scene { verticalCenter: parent.verticalCenter margins: parent.margins } - width: Math.max(parent.width, parent.height) / 25 - height: root.buttonHeight enabled: false - text: Math.round(10 * content.contentItem().playbackRate) / 10 + // qmllint disable + text: Math.round(10 * content.contentItem?.playbackRate ?? 1) / 10 + // qmllint enable } Component.onCompleted: root.content = content diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml index a530d96b7..88fe7a2d2 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoResize.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneResize { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml index ec74a55ea..d429ec413 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoRotate.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneRotate { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml index 3c16ddd70..5e2584fb6 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSeek.qml @@ -25,9 +25,11 @@ Scene { margins: 10 bottom: parent.bottom } - duration: content.contentItem() ? content.contentItem().duration : 0 - playPosition: content.contentItem() ? content.contentItem().position : 0 - onSeekPositionChanged: content.contentItem().seek(seekPosition); + // qmllint disable + duration: content.contentItem?.duration ?? 0 + playPosition: content.contentItem?.position ?? 0 + onSeekPositionChanged: content.contentItem?.seek(seekPosition); + // qmllint enable } Component.onCompleted: root.content = content diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml index f6ba42d0e..7c365ddc7 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml +++ b/examples/multimedia/video/qmlvideo/qmlvideo/VideoSpin.qml @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -import QtQuick - SceneSpin { contentType: "video" } diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/qmldir b/examples/multimedia/video/qmlvideo/qmlvideo/qmldir index a43cb40ba..1cba13d95 100644 --- a/examples/multimedia/video/qmlvideo/qmlvideo/qmldir +++ b/examples/multimedia/video/qmlvideo/qmlvideo/qmldir @@ -1,6 +1,5 @@ module qmlvideo -Button 1.0 Button.qml CameraBasic 1.0 CameraBasic.qml CameraDrag 1.0 CameraDrag.qml CameraDummy 1.0 CameraDummy.qml diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/qmlvideo_global.h b/examples/multimedia/video/qmlvideo/qmlvideo/qmlvideo_global.h new file mode 100644 index 000000000..8df5b5b64 --- /dev/null +++ b/examples/multimedia/video/qmlvideo/qmlvideo/qmlvideo_global.h @@ -0,0 +1,10 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include <QtCore/QtGlobal> + +#if defined(QMLVIDEO_LIB) +#define QMLVIDEO_LIB_EXPORT Q_DECL_EXPORT +#else +#define QMLVIDEO_LIB_EXPORT Q_DECL_IMPORT +#endif diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.cpp b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.cpp new file mode 100644 index 000000000..2b02fa505 --- /dev/null +++ b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.cpp @@ -0,0 +1,54 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "videosingleton.h" + +VideoSingleton::VideoSingleton(QObject * parent) : QObject(parent) +{ } + +QUrl VideoSingleton::source1() const +{ + return m_source1; +} +void VideoSingleton::setSource1(const QUrl &source1) +{ + if (source1 == m_source1) + return; + m_source1 = source1; + emit source1Changed(); +} +QUrl VideoSingleton::source2() const +{ + return m_source2; +} +void VideoSingleton::setSource2(const QUrl &source2) +{ + if (source2 == m_source2) + return; + m_source2 = source2; + emit source2Changed(); +} +qreal VideoSingleton::volume() const +{ + return m_volume; +} +void VideoSingleton::setVolume(qreal volume) +{ + if (volume == m_volume) + return; + m_volume = volume; + emit volumeChanged(); +} +QUrl VideoSingleton::videoPath() const +{ + return m_videoPath; +} +void VideoSingleton::setVideoPath(const QUrl &videoPath) +{ + if (m_videoPath == videoPath) + return; + m_videoPath = videoPath; + emit videoPathChanged(); +} + +#include "moc_videosingleton.cpp" diff --git a/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.h b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.h new file mode 100644 index 000000000..3e0d56247 --- /dev/null +++ b/examples/multimedia/video/qmlvideo/qmlvideo/videosingleton.h @@ -0,0 +1,48 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef QMLVIDEOSINGLETON_H +#define QMLVIDEOSINGLETON_H + +#include "qmlvideo_global.h" + +#include <QtQml/qqml.h> + +class QMLVIDEO_LIB_EXPORT VideoSingleton : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUrl source1 READ source1 WRITE setSource1 NOTIFY source1Changed FINAL) + Q_PROPERTY(QUrl source2 READ source2 WRITE setSource2 NOTIFY source2Changed FINAL) + Q_PROPERTY(QUrl videoPath READ videoPath WRITE setVideoPath NOTIFY videoPathChanged FINAL) + Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged FINAL) + QML_SINGLETON + QML_ELEMENT + +public: + explicit VideoSingleton(QObject *parent = nullptr); + + QUrl source1() const; + void setSource1(const QUrl &source1); + QUrl source2() const; + void setSource2(const QUrl &source2); + QUrl videoPath() const; + void setVideoPath(const QUrl &videoPath); + qreal volume() const; + void setVolume(qreal volume); + +Q_SIGNALS: + void source1Changed(); + void source2Changed(); + void volumeChanged(); + void videoPathChanged(); + +private: + QUrl m_source1; + QUrl m_source2; + QUrl m_videoPath; + qreal m_volume = 0.5; +}; + +QML_DECLARE_TYPE(VideoSingleton); + +#endif // QMLVIDEOSINGLETON_H |