diff --git a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/CreateWallpaperWizard.qml b/ScreenPlay/qml/Create/Wizards/CreateWallpaper/CreateWallpaperWizard.qml index b0c791cc..cdb0599f 100644 --- a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/CreateWallpaperWizard.qml +++ b/ScreenPlay/qml/Create/Wizards/CreateWallpaper/CreateWallpaperWizard.qml @@ -12,6 +12,7 @@ Item { state: "out" property string filePath + property bool canNext: false //Blocks some MouseArea from create page MouseArea { @@ -24,9 +25,10 @@ Item { print(state) if (state === Create.State.ConvertingPreviewGifError || state === Create.State.ConvertingPreviewVideoError - || state === Create.State.AnalyseVideoError) - { + || state === Create.State.ConvertingPreviewImageError + || state === Create.State.AnalyseVideoError) { createNew.state = "error" + return } } } @@ -77,8 +79,8 @@ Item { height: 560 Item { - id: wrapperSteps - z:10 + id: wrapperContent + z: 10 anchors.fill: parent Text { @@ -98,140 +100,148 @@ Item { } } - SwipeView { - id: view - clip: true - currentIndex: 0 - interactive: false - onCurrentIndexChanged: { - - } - + Item { + id: wrapperLeft + width: parent.width * .5 anchors { + left: parent.left top: txtHeadline.bottom - right: parent.right - bottom: indicator.top - left: parent.left - margins: 40 - bottomMargin: 20 - topMargin: 0 - } - - Page_0 { - id: page_0 - onCanNextChanged: { - if (canNext) { - btnNext.state = "enabledPage0" - } else { - if (gifCreated) { - btnNext.state = "diabledPage0NoTitle" - } else { - btnNext.state = "diabledPage0" - } - } - } - onGifCreatedChanged: { - if (gifCreated) { - btnNext.state = "diabledPage0NoTitle" - } - } - } - Page_1 { - id: secondPage - } - Page_2 { - id: thirdPage - } - } - - PageIndicator { - id: indicator - count: view.count - currentIndex: view.currentIndex - anchors { + margins: 30 bottom: parent.bottom - bottomMargin: 20 - left: parent.left - leftMargin: 40 } - delegate: Item { - width: txtStep.paintedWidth + 20 - height: 30 - property bool filled + Rectangle { + id: imgWrapper + width: 425 + height: 247 + anchors { + top: parent.top + left: parent.left + } + + color: "gray" + + BusyIndicator { + id: busyIndicator + anchors.centerIn: parent + running: true + } + Text { - id: txtStep - text: { - switch (index) { - case 0: - return "1. Configure" - case 1: - return "2. Convert" - case 2: - return "3. Finish" - default: - return "Undefiend" - } - } - color: view.currentIndex == index ? "orange" : "gray" - renderType: Text.NativeRendering - font.family: "Roboto" + id: txtConvert + color: "white" + text: qsTr("Generating preview video...") font.pixelSize: 14 anchors { - left: parent.left - verticalCenter: parent.verticalCenter + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + bottomMargin: 30 } + } - MouseArea { - anchors.fill: parent - onClicked: { + Connections { + target: screenPlayCreate - if (!page_0.canNext || !page_0.gifCreated) - return - - view.setCurrentIndex(index) + onCreateWallpaperStateChanged: { + if (state === Create.State.ConvertingPreviewGif) { + txtConvert.text = qsTr( + "Generating preview gif...") } - cursorShape: Qt.PointingHandCursor + if (state === Create.State.ConvertingPreviewGifFinished) { + imgPreview.source = "file:///" + + screenPlayCreate.workingDir + "/preview.gif" + imgPreview.visible = true + + } + } + } + + AnimatedImage { + id: imgPreview + asynchronous: true + playing: true + visible: false + anchors.fill: parent + } + } + + } + + Item { + id: wrapperRight + width: parent.width * .5 + anchors { + top: txtHeadline.bottom + topMargin: 30 + bottom: parent.bottom + right: parent.right + } + + Column { + id: column + spacing: 20 + anchors.fill: parent + anchors.margins: 30 + anchors.topMargin: 0 + + TextField { + id: textField + placeholderText: qsTr("Name") + anchors.right: parent.right + anchors.left: parent.left + onTextChanged: { + if (textField.text.length >= 3 ) { + canNext = true + + } else { + canNext = false + } + } + } + + TextField { + id: textField1 + placeholderText: qsTr("Description") + anchors.right: parent.right + anchors.left: parent.left + } + + TextField { + id: textField2 + placeholderText: qsTr("Youtube URL") + anchors.right: parent.right + anchors.left: parent.left + } + + TextField { + id: textField3 + placeholderText: qsTr("Tags") + anchors.right: parent.right + anchors.left: parent.left + } + } + + NextButton { + id: btnFinish + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + margins: 30 + } + onClicked: { + if (btnFinish.state === "enabled" && canNext) { + screenPlayCreate.createWallpaperProjectFile( + textField.text, textField1.text) } } } - } - - Row { - width: childrenRect.width - height: 50 - spacing: 20 - anchors { - bottom: parent.bottom - right: parent.right - margins: 20 - rightMargin: 40 - } - Button { - text: qsTr("Back") - Material.background: Material.Gray - Material.foreground: "white" - - icon.source: "qrc:/assets/icons/icon_arrow_left.svg" - icon.color: "white" - icon.width: 16 - icon.height: 16 - onClicked: { - if (view.currentIndex > 0) - view.setCurrentIndex(view.currentIndex - 1) - } - } - NextButton { - id: btnNext - state: "diabledPage0" - onClicked: { - - if (!page_0.canNext || !page_0.gifCreated) - return - - if (view.currentIndex < view.count - 1) - view.setCurrentIndex(view.currentIndex + 1) + Connections { + target: screenPlayCreate + onCreateWallpaperStateChanged: { + if (state === Create.State.ConvertingVideoFinished) { + btnFinish.state = "enabled" + } } } } @@ -240,6 +250,7 @@ Item { Item { id: wrapperError anchors.fill: parent + opacity: 0 Text { id: txtErrorHeadline @@ -250,7 +261,7 @@ Item { horizontalCenter: parent.horizontalCenter } height: 40 - font.family: "Roboto" + font.family: "Segoe UI, Roboto" font.weight: Font.Light color: Material.color(Material.Red) renderType: Text.NativeRendering @@ -273,13 +284,13 @@ Item { Flickable { anchors.fill: parent clip: true - contentHeight: txtFFMPEG.paintedHeight + contentHeight: txtFFMPEGDebug.paintedHeight ScrollBar.vertical: ScrollBar { snapMode: ScrollBar.SnapOnRelease policy: ScrollBar.AlwaysOn } Text { - id: txtFFMPEG + id: txtFFMPEGDebug anchors { top: parent.top right: parent.right @@ -289,12 +300,12 @@ Item { wrapMode: Text.WordWrap color: "#626262" renderType: Text.NativeRendering - height: txtFFMPEG.paintedHeight + height: txtFFMPEGDebug.paintedHeight } Connections { target: screenPlayCreate onProcessOutput: { - txtFFMPEG.text = text + txtFFMPEGDebug.text = text } } } @@ -316,6 +327,43 @@ Item { } } + Item { + id: wrapperSuccess + anchors.fill: parent + opacity: 0 + + Text { + id: txtSuccessHeadline + text: qsTr("An error occurred!") + anchors { + top: parent.top + topMargin: 30 + horizontalCenter: parent.horizontalCenter + } + height: 40 + font.family: "Segoe UI, Roboto" + font.weight: Font.Light + color: Material.color(Material.Orange) + renderType: Text.NativeRendering + font.pixelSize: 32 + } + + Button { + id: btnSuccessBack + text: qsTr("Back to create!") + Material.background: Material.Orange + Material.foreground: "white" + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + margins: 10 + } + onClicked: { + utility.setNavigation("Create") + } + } + } + MouseArea { anchors { top: parent.top @@ -397,15 +445,35 @@ Item { opacity: .4 } PropertyChanges { - target: wrapperSteps + target: wrapperContent opacity: 0 - z:0 + z: 0 + } + PropertyChanges { + target: wrapperError + opacity: 1 + } + }, + State { + name: "success" + PropertyChanges { + target: wrapper + anchors.topMargin: 40 + opacity: 1 + } + PropertyChanges { + target: effect + opacity: .4 + } + PropertyChanges { + target: wrapperContent + opacity: 0 + z: 0 } PropertyChanges { target: wrapperError opacity: 1 } - } ] transitions: [ @@ -483,7 +551,7 @@ Item { to: "error" SequentialAnimation { PropertyAnimation { - target: wrapperSteps + target: wrapperContent duration: 600 property: "opacity" easing.type: Easing.InOutQuad @@ -498,6 +566,33 @@ Item { easing.type: Easing.InOutQuad } } + }, + Transition { + from: "in" + to: "success" + SequentialAnimation { + PropertyAnimation { + target: wrapperContent + duration: 600 + property: "opacity" + easing.type: Easing.InOutQuad + } + PauseAnimation { + duration: 50 + } + PropertyAnimation { + target: wrapperSuccess + duration: 200 + property: "opacity" + easing.type: Easing.InOutQuad + } + } } ] } + +/*##^## Designer { + D{i:0;autoSize:true;height:767;width:1366} +} + ##^##*/ + diff --git a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/NextButton.qml b/ScreenPlay/qml/Create/Wizards/CreateWallpaper/NextButton.qml index a0c09097..c0406984 100644 --- a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/NextButton.qml +++ b/ScreenPlay/qml/Create/Wizards/CreateWallpaper/NextButton.qml @@ -8,44 +8,25 @@ import QtQuick.Layouts 1.3 Button { id: root text: qsTr("Next") + state: "disabled" Material.background: Material.Orange Material.foreground: "white" - icon.source: "qrc:/assets/icons/icon_arrow_right.svg" - icon.color: "white" - icon.width: 16 - icon.height: 16 - states: [ State { name: "enabled" PropertyChanges { target: root + text: qsTr("Finish") } }, State { - name: "diabledPage0" + name: "disabled" PropertyChanges { target: root - text: qsTr("Creating preview") + text: qsTr("Creating") Material.background: Material.Grey } - }, - State { - name: "diabledPage0NoTitle" - PropertyChanges { - target: root - text: qsTr("No title set!") - Material.background: Material.Grey - } - }, - State { - name: "enabledPage0" - PropertyChanges { - target: root - text: qsTr("Next") - Material.background: Material.Orange - } } ] // TODO find a way to smoothly change with on text change diff --git a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_0.qml b/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_0.qml deleted file mode 100644 index d02cffd0..00000000 --- a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_0.qml +++ /dev/null @@ -1,163 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import QtGraphicalEffects 1.0 -import net.aimber.create 1.0 - -Rectangle { - id: root - - property bool canNext: false - property bool gifCreated: false - - Item { - id: rectangle1 - width: parent.width * .5 - anchors { - top: parent.top - bottom: parent.bottom - left: parent.left - } - RectangularGlow { - id: effect - anchors { - top: imgWrapper.top - left: imgWrapper.left - right: imgWrapper.right - topMargin: 3 - } - - height: imgWrapper.height - width: imgWrapper.width - cached: true - glowRadius: 3 - spread: 0.2 - color: "black" - opacity: 0.4 - cornerRadius: 15 - } - - Rectangle { - id: imgWrapper - width: parent.width * .9 - anchors { - top: parent.top - margins: parent.width * .05 - right: parent.right - left: parent.left - } - - height: 200 - color: "gray" - - BusyIndicator { - id: busyIndicator - anchors.centerIn: parent - running: true - } - - Text { - id: txtConvert - color: "white" - text: qsTr("Generating preview video...") - font.pixelSize: 14 - anchors { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom - bottomMargin: 30 - } - } - - Connections { - target: screenPlayCreate - - onCreateWallpaperStateChanged: { - if (state === Create.State.ConvertingPreviewGif) { - txtConvert.text = qsTr("Generating preview gif...") - - } - - if (state === Create.State.ConvertingPreviewGifFinished) { - imgPreview.source = "file:///" - + screenPlayCreate.workingDir + "/preview.gif" - imgPreview.visible = true - gifCreated = true - } - } - } - - AnimatedImage { - id: imgPreview - asynchronous: true - playing: true - visible: false - anchors.fill: parent - } - } - - ScrollView { - anchors { - top: imgWrapper.bottom - right: parent.right - bottom: parent.bottom - left: parent.left - margins: 20 - } - Text { - id: txtOut - width: parent.width - } - } - } - - Rectangle { - id: rectangle - width: parent.width * .5 - anchors { - top: parent.top - bottom: parent.bottom - right: parent.right - } - - Column { - id: column - spacing: 20 - anchors.fill: parent - anchors.margins: 30 - - TextField { - id: textField - placeholderText: qsTr("Name") - anchors.right: parent.right - anchors.left: parent.left - onTextChanged: { - if (textField.text.length >= 3 && gifCreated) { - canNext = true - } else { - canNext = false - } - } - } - - TextField { - id: textField1 - placeholderText: qsTr("Description") - anchors.right: parent.right - anchors.left: parent.left - } - - TextField { - id: textField2 - placeholderText: qsTr("Youtube URL") - anchors.right: parent.right - anchors.left: parent.left - } - - TextField { - id: textField3 - placeholderText: qsTr("Tags") - anchors.right: parent.right - anchors.left: parent.left - } - } - } -} diff --git a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_1.qml b/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_1.qml deleted file mode 100644 index 551b7225..00000000 --- a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_1.qml +++ /dev/null @@ -1,162 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls 2.3 -import QtQuick.Controls.Material 2.3 -import net.aimber.create 1.0 - -Item { - id: root - - Connections { - target: screenPlayCreate - onCreateWallpaperStateChanged: { - print(state) - if (state === Create.State.ConvertingVideoFinished) { - root.state = "finished" - } - } - } - - Rectangle { - id: wrapperProgressbar - height: parent.height * .5 - z:1 - anchors { - top: parent.top - right: parent.right - left: parent.left - } - - Text { - id: txtProgress - text: Math.floor(screenPlayCreate.progress) + "%" - font.pixelSize: 42 - color: "#626262" - renderType: Text.NativeRendering - anchors { - horizontalCenter: parent.horizontalCenter - bottom: progressBar.top - bottomMargin: 30 - } - } - - ProgressBar { - id: progressBar - value: screenPlayCreate.progress - from: 0 - to: 100 - anchors { - horizontalCenter: parent.horizontalCenter - bottom: parent.bottom - bottomMargin: 30 - } - } - } - - Rectangle { - id: wrapperFFMPEGOutput - color: "#eeeeee" - radius: 3 - z:1 - anchors { - top: wrapperProgressbar.bottom - topMargin: 30 - right: parent.right - bottom: parent.bottom - left: parent.left - } - - Flickable { - anchors.fill: parent - focus: true - clip: true - contentHeight: txtFFMPEG.paintedHeight - ScrollBar.vertical: ScrollBar { - snapMode: ScrollBar.SnapOnRelease - policy: ScrollBar.AlwaysOn - } - Text { - id: txtFFMPEG - anchors { - top: parent.top - right: parent.right - left: parent.left - margins: 20 - } - wrapMode: Text.WordWrap - color: "#626262" - text: "asasas" - renderType: Text.NativeRendering - height: txtFFMPEG.paintedHeight - } - } - } - - Item { - id: wrapperFinished - z:0 - anchors.fill: parent - opacity: 0 - - Text { - id: txtDone - text: qsTr("Video creation successful!") - font.pixelSize: 42 - color: Material.color(Material.Green) - renderType: Text.NativeRendering - anchors { - horizontalCenter: parent.horizontalCenter - top: parent.top - topMargin: 30 - - } - } - } - - Connections { - target: screenPlayCreate - onProcessOutput: { - txtFFMPEG.text += text - } - } - states: [ - State { - name: "finished" - PropertyChanges { - target: wrapperProgressbar - opacity:0 - } - PropertyChanges { - target: wrapperFFMPEGOutput - opacity:0 - } - PropertyChanges { - target: wrapperFinished - opacity:1 - } - } - ] - transitions: [ - Transition { - from: "0" - to: "finished" - PropertyAnimation { - target: wrapperFFMPEGOutput - duration: 200 - property: "opacity" - easing.type: Easing.InOutQuad - } - PropertyAnimation { - target: wrapperProgressbar - duration: 200 - property: "opacity" - easing.type: Easing.InOutQuad - } - PropertyAnimation { - target: wrapperFinished - duration: 200 - property: "opacity" - easing.type: Easing.InOutQuad - } - } - ] -} diff --git a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_2.qml b/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_2.qml deleted file mode 100644 index 2859ccad..00000000 --- a/ScreenPlay/qml/Create/Wizards/CreateWallpaper/Page_2.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.9 - -Item { - -} diff --git a/ScreenPlay/qml/Installed/ScreenPlayItem.qml b/ScreenPlay/qml/Installed/ScreenPlayItem.qml index 79be0c35..ecd3b9ef 100644 --- a/ScreenPlay/qml/Installed/ScreenPlayItem.qml +++ b/ScreenPlay/qml/Installed/ScreenPlayItem.qml @@ -2,6 +2,7 @@ import QtQuick 2.9 import QtGraphicalEffects 1.0 import QtQuick.Controls 2.3 import QtQuick.Controls.Styles 1.4 + Item { id: screenPlayItem width: 320 @@ -140,6 +141,16 @@ Item { sourceImage: Qt.resolvedUrl( "file:///" + screenPlayItem.absoluteStoragePath + "/" + screenPreview) + sourceImageGIF: { + if (screenPreviewGIF === undefined) { + return "" + } else { + return Qt.resolvedUrl( + "file:///" + screenPlayItem.absoluteStoragePath + + "/" + screenPreviewGIF) + + } + } } Image { @@ -181,7 +192,7 @@ Item { color: "#2F2F2F" font.pointSize: 9 renderType: Text.NativeRendering - font.family: "Roboto" + font.family: "Segoe UI, Roboto" } } } @@ -198,12 +209,16 @@ Item { cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.LeftButton | Qt.RightButton onEntered: { - if (!hasMenuOpen) + if (!hasMenuOpen) { screenPlayItem.state = "hover" + screenPlayItemImage.enter() + } } onExited: { - if (!hasMenuOpen) + if (!hasMenuOpen) { screenPlayItem.state = "visible" + screenPlayItemImage.exit() + } } onClicked: { diff --git a/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml b/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml index 39ce106d..10a3270f 100644 --- a/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml +++ b/ScreenPlay/qml/Installed/ScreenPlayItemImage.qml @@ -4,13 +4,46 @@ Item { id: screenPlayItemImage width: 320 height: 121 - anchors.bottomMargin: 0 state: "loading" property string sourceImage: "" + property string sourceImageGIF: "" - onSourceImageChanged: { - image.source = screenPlayItemImage.sourceImage + function enter() { + if (screenPlayItemImage.sourceImageGIF != "") { + imgGIFPreview.playing = true + } + } + + function exit() { + imgGIFPreview.playing = false + } + + Image { + id: image + anchors.fill: parent + antialiasing: false + asynchronous: true + fillMode: Image.PreserveAspectCrop + source: screenPlayItemImage.sourceImage.trim() + + onStatusChanged: { + if (image.status === Image.Ready) { + screenPlayItemImage.state = "loaded" + } else if (image.status === Image.Error) { + source = "qrc:/assets/images/missingPreview.png" + screenPlayItemImage.state = "loaded" + } + } + } + + AnimatedImage { + id: imgGIFPreview + asynchronous: true + playing: false + anchors.fill: parent + fillMode: Image.PreserveAspectCrop + source: screenPlayItemImage.sourceImageGIF.trim() } states: [ @@ -61,34 +94,4 @@ Item { } } ] - - - Image { - id:image - anchors.fill: parent - antialiasing: false - asynchronous: true - - //sourceSize: Qt.size(320,121) - fillMode: Image.PreserveAspectCrop - source: screenPlayItemImage.sourceImage.trim() - - onStatusChanged: { - - if (image.status === Image.Ready){ - screenPlayItemImage.state = "loaded" - } else if(image.status === Image.Error){ - source = "qrc:/assets/images/missingPreview.png" - screenPlayItemImage.state = "loaded" - } - - } - } - - Text { - id: text1 - text: "" - anchors.fill: parent - font.pixelSize: 12 - } } diff --git a/ScreenPlay/src/create.cpp b/ScreenPlay/src/create.cpp index 554ac7cd..6f1e5db5 100644 --- a/ScreenPlay/src/create.cpp +++ b/ScreenPlay/src/create.cpp @@ -55,8 +55,7 @@ void Create::createWallpaperStart(QString videoPath) QDir dir; dir.cd(this->m_settings->localStoragePath().toString()); - CreateWallpaperData createWallpaperData; - createWallpaperData.videoPath = videoPath; + m_createWallpaperData.videoPath = videoPath; // Create a temp dir so we can later alter it to the workshop id auto folderName = QString("_tmp_" + QTime::currentTime().toString()).replace(":", ""); @@ -64,28 +63,25 @@ void Create::createWallpaperStart(QString videoPath) if (!dir.mkdir(folderName)) return; - createWallpaperData.exportPath = dir.path() + "/" + folderName; - m_workingDir = createWallpaperData.exportPath; + m_createWallpaperData.exportPath = dir.path() + "/" + folderName; + m_workingDir = m_createWallpaperData.exportPath; // If we return early/false this means the creation // process did not work // Todo: cleanup! - if (!this->createWallpaperInfo(createWallpaperData)) + if (!this->createWallpaperInfo()) return; - if (!this->createWallpaperVideoPreview(createWallpaperData)) + if (!this->createWallpaperVideoPreview()) return; - if (!this->createWallpaperVideo(createWallpaperData)) - return; - - if (!this->createWallpaperProjectFile(createWallpaperData)) + if (!this->createWallpaperVideo()) return; }); } -bool Create::createWallpaperInfo(CreateWallpaperData& createWallpaperData) +bool Create::createWallpaperInfo() { // Get video info QStringList args; @@ -93,7 +89,7 @@ bool Create::createWallpaperInfo(CreateWallpaperData& createWallpaperData) args.append("json"); args.append("-show_format"); args.append("-show_streams"); - args.append(createWallpaperData.videoPath); + args.append(m_createWallpaperData.videoPath); QScopedPointer pro(new QProcess()); pro.data()->setArguments(args); @@ -131,7 +127,7 @@ bool Create::createWallpaperInfo(CreateWallpaperData& createWallpaperData) int length = 0; length = static_cast(tmpLength); - createWallpaperData.length = length; + m_createWallpaperData.length = length; // Get framerate QJsonArray arrSteams = obj.value("streams").toArray(); @@ -158,15 +154,15 @@ bool Create::createWallpaperInfo(CreateWallpaperData& createWallpaperData) float value2 = static_cast(avgFrameRateList.at(1).toInt()); framerate = qCeil(value1 / value2); - createWallpaperData.framerate = framerate; + m_createWallpaperData.framerate = framerate; return true; } -bool Create::createWallpaperVideoPreview(CreateWallpaperData& createWallpaperData) +bool Create::createWallpaperVideoPreview() { - qDebug() << createWallpaperData.length << createWallpaperData.framerate; + qDebug() << m_createWallpaperData.length << m_createWallpaperData.framerate; QStringList args; // args.append("-hide_banner"); args.append("-loglevel"); @@ -174,17 +170,17 @@ bool Create::createWallpaperVideoPreview(CreateWallpaperData& createWallpaperDat args.append("-y"); args.append("-stats"); args.append("-i"); - args.append(createWallpaperData.videoPath); + args.append(m_createWallpaperData.videoPath); args.append("-speed"); args.append("ultrafast"); args.append("-vf"); // We allways want to have a 5 second clip via 24fps -> 120 frames // Divided by the number of frames we can skip (timeInSeconds * Framrate) // scale & crop parameter: https://unix.stackexchange.com/a/284731 - args.append("select='not(mod(n," + QString::number((createWallpaperData.length / 5)) + "))',setpts=N/FRAME_RATE/TB,crop=in_h*16/9:in_h,scale=-2:400"); + args.append("select='not(mod(n," + QString::number((m_createWallpaperData.length / 5)) + "))',setpts=N/FRAME_RATE/TB,crop=in_h*16/9:in_h,scale=-2:400"); // Disable audio args.append("-an"); - args.append(createWallpaperData.exportPath + "/preview.mp4"); + args.append(m_createWallpaperData.exportPath + "/preview.mp4"); QScopedPointer proConvertPreviewMP4(new QProcess()); proConvertPreviewMP4.data()->setArguments(args); @@ -203,7 +199,7 @@ bool Create::createWallpaperVideoPreview(CreateWallpaperData& createWallpaperDat } QString tmpErr = proConvertPreviewMP4.data()->readAllStandardError(); if (!tmpErr.isEmpty()) { - QFile previewVideo(createWallpaperData.exportPath + "/preview.mp4"); + QFile previewVideo(m_createWallpaperData.exportPath + "/preview.mp4"); if (!previewVideo.exists() && !(previewVideo.size() > 0)) { emit processOutput(tmpErr); emit createWallpaperStateChanged(Create::State::ConvertingPreviewVideoError); @@ -227,10 +223,10 @@ bool Create::createWallpaperVideoPreview(CreateWallpaperData& createWallpaperDat args.append("-y"); args.append("-stats"); args.append("-i"); - args.append(createWallpaperData.exportPath + "/preview.mp4"); + args.append(m_createWallpaperData.exportPath + "/preview.mp4"); args.append("-filter_complex"); args.append("[0:v] fps=12,scale=w=480:h=-1,split [a][b];[a] palettegen=stats_mode=single [p];[b][p] paletteuse=new=1"); - args.append(createWallpaperData.exportPath + "/preview.gif"); + args.append(m_createWallpaperData.exportPath + "/preview.gif"); QScopedPointer proConvertGif(new QProcess()); proConvertGif.data()->setArguments(args); @@ -242,7 +238,7 @@ bool Create::createWallpaperVideoPreview(CreateWallpaperData& createWallpaperDat proConvertGif.data()->waitForFinished(-1); QString tmpErrGif = proConvertGif.data()->readAllStandardError(); if (!tmpErrGif.isEmpty()) { - QFile previewGif(createWallpaperData.exportPath + "/preview.gif"); + QFile previewGif(m_createWallpaperData.exportPath + "/preview.gif"); if (!previewGif.exists() && !(previewGif.size() > 0)) { emit createWallpaperStateChanged(Create::State::ConvertingPreviewGifError); return false; @@ -253,10 +249,51 @@ bool Create::createWallpaperVideoPreview(CreateWallpaperData& createWallpaperDat proConvertGif.data()->close(); emit createWallpaperStateChanged(Create::State::ConvertingPreviewGifFinished); + /* + * + * Create png + * + */ + + emit createWallpaperStateChanged(Create::State::ConvertingPreviewImage); + args.clear(); + args.append("-y"); + args.append("-stats"); + args.append("-ss"); + args.append("00:00:02"); + args.append("-i"); + args.append(m_createWallpaperData.videoPath); + args.append("-vframes"); + args.append("1"); + args.append("-q:v"); + args.append("2"); + args.append(m_createWallpaperData.exportPath + "/preview.png"); + + QScopedPointer proConvertImage(new QProcess()); + proConvertImage.data()->setArguments(args); + qDebug() << "Start converting video to preview gif"; +#ifdef Q_OS_WIN + proConvertImage.data()->setProgram(QApplication::applicationDirPath() + "/ffmpeg.exe"); +#endif + proConvertImage.data()->start(); + proConvertImage.data()->waitForFinished(-1); + QString tmpErrImg = proConvertImage.data()->readAllStandardError(); + if (!tmpErrImg.isEmpty()) { + QFile previewImg(m_createWallpaperData.exportPath + "/preview.png"); + if (!previewImg.exists() && !(previewImg.size() > 0)) { + emit createWallpaperStateChanged(Create::State::ConvertingPreviewImageError); + return false; + } + } + + this->processOutput(proConvertImage.data()->readAll()); + proConvertImage.data()->close(); + emit createWallpaperStateChanged(Create::State::ConvertingPreviewImageFinished); + return true; } -bool Create::createWallpaperVideo(CreateWallpaperData& createWallpaperData) +bool Create::createWallpaperVideo() { emit createWallpaperStateChanged(Create::State::ConvertingVideo); @@ -265,7 +302,7 @@ bool Create::createWallpaperVideo(CreateWallpaperData& createWallpaperData) args.append("-y"); args.append("-stats"); args.append("-i"); - args.append(createWallpaperData.videoPath); + args.append(m_createWallpaperData.videoPath); args.append("-c:v"); args.append("libvpx-vp9"); args.append("-crf"); @@ -280,7 +317,7 @@ bool Create::createWallpaperVideo(CreateWallpaperData& createWallpaperData) args.append("yuv420p"); args.append("-b:v"); args.append("0"); - args.append(createWallpaperData.exportPath + "/video.webm"); + args.append(m_createWallpaperData.exportPath + "/video.webm"); QScopedPointer proConvertVideo(new QProcess()); proConvertVideo.data()->setArguments(args); @@ -290,6 +327,7 @@ bool Create::createWallpaperVideo(CreateWallpaperData& createWallpaperData) connect(proConvertVideo.data(), &QProcess::readyReadStandardOutput, this, [&]() { QString tmpOut = proConvertVideo.data()->readAllStandardOutput(); + qDebug() << tmpOut << m_createWallpaperData.length; auto tmpList = tmpOut.split(QRegExp("\\s+"), QString::SkipEmptyParts); if (tmpList.length() > 2) { bool ok = false; @@ -298,7 +336,7 @@ bool Create::createWallpaperVideo(CreateWallpaperData& createWallpaperData) if (!ok) return; - float progress = currentFrame / createWallpaperData.length; + float progress = currentFrame / m_createWallpaperData.length; this->setProgress(progress); } @@ -311,12 +349,14 @@ bool Create::createWallpaperVideo(CreateWallpaperData& createWallpaperData) #endif proConvertVideo.data()->start(QIODevice::ReadOnly); proConvertVideo.data()->waitForFinished(-1); + disconnect(proConvertVideo.data(), &QProcess::readyReadStandardOutput, 0, 0); + QString out = proConvertVideo.data()->readAllStandardOutput(); this->processOutput(out); QString tmpErrVideo = proConvertVideo.data()->readAllStandardError(); if (!tmpErrVideo.isEmpty()) { - QFile video(createWallpaperData.exportPath + "/video.webm"); + QFile video(m_createWallpaperData.exportPath + "/video.webm"); if (!video.exists() && !(video.size() > 0)) { emit createWallpaperStateChanged(Create::State::ConvertingVideoError); return false; @@ -329,27 +369,29 @@ bool Create::createWallpaperVideo(CreateWallpaperData& createWallpaperData) return true; } -bool Create::createWallpaperProjectFile(CreateWallpaperData& createWallpaperData) +bool Create::createWallpaperProjectFile(const QString title, const QString description) { //Copy Project File - QFile configFile(createWallpaperData.exportPath + "/project.json"); + QFile configFile(m_createWallpaperData.exportPath + "/project.json"); if (!configFile.open(QIODevice::ReadWrite | QIODevice::Text)) { - return false; } - // QTextStream out(&configFile); - // QJsonObject configObj; + QTextStream out(&configFile); + QJsonObject configObj; - // configObj.insert("file", videoPath.fileName()); - // configObj.insert("preview", previewPath.fileName()); - // //TODO - // configObj.insert("description", ""); - // configObj.insert("title", title); + configObj.insert("description", description); + configObj.insert("title", title); - // QJsonDocument configJsonDocument(configObj); - // out << configJsonDocument.toJson(); + configObj.insert("file", "video.webm"); + configObj.insert("preview", "preview.png"); + configObj.insert("previewGIF", "preview.gif"); + configObj.insert("previewMP4", "preview.mp4"); + configObj.insert("type", "video"); + + QJsonDocument configJsonDocument(configObj); + out << configJsonDocument.toJson(); configFile.close(); return true; } diff --git a/ScreenPlay/src/create.h b/ScreenPlay/src/create.h index c58a836d..2bb174c2 100644 --- a/ScreenPlay/src/create.h +++ b/ScreenPlay/src/create.h @@ -89,10 +89,10 @@ public slots: // Steps to convert any video to a wallpaper broken down into // several methods in this order: void createWallpaperStart(QString videoPath); - bool createWallpaperInfo(CreateWallpaperData& createWallpaperData); - bool createWallpaperVideoPreview(CreateWallpaperData& createWallpaperData); - bool createWallpaperVideo(CreateWallpaperData& createWallpaperData); - bool createWallpaperProjectFile(CreateWallpaperData& createWallpaperData); + bool createWallpaperInfo(); + bool createWallpaperVideoPreview(); + bool createWallpaperVideo(); + bool createWallpaperProjectFile(const QString title, const QString description); void setWorkingDir(QString workingDir) { @@ -116,7 +116,7 @@ public slots: private: Settings* m_settings; QMLUtilities* m_utils; - + CreateWallpaperData m_createWallpaperData; QString m_workingDir; float m_progress = 0.0f; }; diff --git a/ScreenPlay/src/installedlistmodel.cpp b/ScreenPlay/src/installedlistmodel.cpp index cd830bd6..45bbba1e 100644 --- a/ScreenPlay/src/installedlistmodel.cpp +++ b/ScreenPlay/src/installedlistmodel.cpp @@ -28,6 +28,8 @@ QVariant InstalledListModel::data(const QModelIndex& index, int role) const return m_screenPlayFiles.at(index.row()).m_title; case PreviewRole: return m_screenPlayFiles.at(index.row()).m_preview; + case PreviewGIFRole: + return m_screenPlayFiles.at(index.row()).m_previewGIF; case TypeRole: return m_screenPlayFiles.at(index.row()).m_type; case FolderIdRole: @@ -50,6 +52,7 @@ QHash InstalledListModel::roleNames() const { TitleRole, "screenTitle" }, { TypeRole, "screenType" }, { PreviewRole, "screenPreview" }, + { PreviewGIFRole, "screenPreviewGIF" }, { FolderIdRole, "screenFolderId" }, { FileIdRole, "screenFile" }, { AbsoluteStoragePathRole, "screenAbsoluteStoragePath" }, @@ -125,6 +128,10 @@ void InstalledListModel::loadScreens() if (fileEnding.endsWith(".webm") || (obj.value("type").toString() == "qmlScene") || fileEnding.endsWith(".html")) emit addInstalledItem(obj, item.baseName()); + + if(obj.value("type") == "qmlWidget") + emit addInstalledItem(obj, item.baseName()); + } } emit installedLoadingFinished(); @@ -143,6 +150,7 @@ QVariantMap InstalledListModel::get(QString folderId) if (m_screenPlayFiles[i].m_folderId == folderId) { map.insert("screenTitle", m_screenPlayFiles[i].m_title); map.insert("screenPreview", m_screenPlayFiles[i].m_preview); + map.insert("screenPreviewGIF", m_screenPlayFiles[i].m_previewGIF); map.insert("screenFile", m_screenPlayFiles[i].m_file); map.insert("screenType", m_screenPlayFiles[i].m_type); map.insert("screenAbsoluteStoragePath", m_screenPlayFiles[i].m_absoluteStoragePath); diff --git a/ScreenPlay/src/installedlistmodel.h b/ScreenPlay/src/installedlistmodel.h index def852cb..cc6db38c 100644 --- a/ScreenPlay/src/installedlistmodel.h +++ b/ScreenPlay/src/installedlistmodel.h @@ -43,6 +43,7 @@ public: TitleRole, TypeRole, PreviewRole, + PreviewGIFRole, FolderIdRole, FileIdRole, AbsoluteStoragePathRole, diff --git a/ScreenPlay/src/projectfile.cpp b/ScreenPlay/src/projectfile.cpp index 306d379f..f027c681 100644 --- a/ScreenPlay/src/projectfile.cpp +++ b/ScreenPlay/src/projectfile.cpp @@ -12,6 +12,9 @@ ProjectFile::ProjectFile(QJsonObject obj, QString folderName, QUrl absolutePath) if (obj.contains("preview")) m_preview = obj.value("preview"); + if (obj.contains("previewGIF")) + m_previewGIF = obj.value("previewGIF"); + if (obj.contains("title")) m_title = obj.value("title"); diff --git a/ScreenPlay/src/projectfile.h b/ScreenPlay/src/projectfile.h index e8ed2ca0..fbc9ff69 100644 --- a/ScreenPlay/src/projectfile.h +++ b/ScreenPlay/src/projectfile.h @@ -23,6 +23,7 @@ public: QVariant m_description; QVariant m_file; QVariant m_preview; + QVariant m_previewGIF; QVariant m_title; QString m_folderId; QUrl m_absoluteStoragePath; diff --git a/ScreenPlayWindow/SPWResources.qrc b/ScreenPlayWindow/SPWResources.qrc index 5f6483ac..69145a82 100644 --- a/ScreenPlayWindow/SPWResources.qrc +++ b/ScreenPlayWindow/SPWResources.qrc @@ -1,5 +1,5 @@ - main.qml + qml/main.qml diff --git a/ScreenPlayWindow/main.qml b/ScreenPlayWindow/qml/main.qml similarity index 100% rename from ScreenPlayWindow/main.qml rename to ScreenPlayWindow/qml/main.qml diff --git a/ScreenPlayWindow/src/SPWmainwindow.cpp b/ScreenPlayWindow/src/SPWmainwindow.cpp index fc12fb62..9dee8250 100644 --- a/ScreenPlayWindow/src/SPWmainwindow.cpp +++ b/ScreenPlayWindow/src/SPWmainwindow.cpp @@ -121,7 +121,7 @@ MainWindow::MainWindow(int i, QString projectPath, QString id, QString decoder, m_quickRenderer = QSharedPointer(new QQuickView(this)); m_quickRenderer.data()->rootContext()->setContextProperty("mainwindow", this); - m_quickRenderer.data()->setSource(QUrl("qrc:/main.qml")); + m_quickRenderer.data()->setSource(QUrl("qrc:/qml/main.qml")); m_quickRenderer.data()->setGeometry(0, 0, width(), height()); m_quickRenderer.data()->setResizeMode(QQuickView::ResizeMode::SizeRootObjectToView); m_quickRenderer.data()->setFlags(flags | Qt::FramelessWindowHint | Qt::WindowStaysOnBottomHint); diff --git a/scripts/package.bat b/scripts/package.bat index 1d7ef32c..8be7de03 100644 --- a/scripts/package.bat +++ b/scripts/package.bat @@ -29,6 +29,7 @@ xcopy C:\Qt\Tools\QtCreator\bin\ssleay32.dll ..\PACKAGE cd .. windeployqt.exe --release --qmldir ScreenPlay/qml PACKAGE/ScreenPlay.exe +windeployqt.exe --release --qmldir ScreenPlayWindow/qml PACKAGE/ScreenPlayWindow.exe cd PACKAGE @@ -37,4 +38,6 @@ del /f *.moc del /f *.h del /f *.obj del /f *.res +del /f *.exp +del /f *.lib