mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-22 10:42:29 +01:00
Refactor video wizard into a single wizard
This commit is contained in:
parent
b41242a938
commit
bd5516fb41
@ -64,16 +64,11 @@ set(QML
|
||||
qml/Create/Wizards/GodotWallpaper.qml
|
||||
qml/Create/Wizards/HTMLWallpaper.qml
|
||||
qml/Create/Wizards/HTMLWidget.qml
|
||||
qml/Create/Wizards/Importh264/Importh264.qml
|
||||
qml/Create/Wizards/Importh264/Importh264Convert.qml
|
||||
qml/Create/Wizards/Importh264/Importh264Init.qml
|
||||
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml
|
||||
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperInit.qml
|
||||
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperFileSelect.qml
|
||||
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperSettings.qml
|
||||
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperResult.qml
|
||||
qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaperVideoImportConvert.qml
|
||||
qml/Create/Wizards/ImportWebm/ImportWebm.qml
|
||||
qml/Create/Wizards/ImportWebm/ImportWebmConvert.qml
|
||||
qml/Create/Wizards/ImportWebm/ImportWebmInit.qml
|
||||
qml/Create/Wizards/QMLWallpaper.qml
|
||||
qml/Create/Wizards/QMLWidget.qml
|
||||
qml/Create/Wizards/WebsiteWallpaper.qml
|
||||
|
@ -34,7 +34,6 @@ class Create : public QObject {
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
QML_UNCREATABLE("")
|
||||
Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
|
||||
|
||||
Q_PROPERTY(QString workingDir READ workingDir WRITE setWorkingDir NOTIFY workingDirChanged)
|
||||
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
|
||||
@ -45,13 +44,22 @@ public:
|
||||
|
||||
Create();
|
||||
|
||||
enum class VideoCodec {
|
||||
VP8,
|
||||
VP9,
|
||||
AV1,
|
||||
H264
|
||||
};
|
||||
Q_ENUM(VideoCodec)
|
||||
Q_INVOKABLE void cancel();
|
||||
|
||||
Q_INVOKABLE void createWallpaperStart(
|
||||
QString videoPath,
|
||||
ScreenPlay::Video::VideoCodec codec,
|
||||
const int quality = 50);
|
||||
|
||||
Q_INVOKABLE void saveWallpaper(const QString title,
|
||||
const QString description,
|
||||
QString filePath,
|
||||
QString previewImagePath,
|
||||
const QString youtube,
|
||||
const ScreenPlay::Video::VideoCodec codec,
|
||||
const QVector<QString> tags);
|
||||
|
||||
Q_INVOKABLE void abortAndCleanup();
|
||||
|
||||
float progress() const { return m_progress; }
|
||||
QString workingDir() const { return m_workingDir; }
|
||||
@ -68,22 +76,6 @@ signals:
|
||||
void finished();
|
||||
|
||||
public slots:
|
||||
void cancel();
|
||||
|
||||
void createWallpaperStart(QString videoPath, Create::VideoCodec codec = Create::VideoCodec::VP9, const int quality = 50);
|
||||
|
||||
void importH264(QString videoPath);
|
||||
|
||||
void saveWallpaper(const QString title,
|
||||
const QString description,
|
||||
QString filePath,
|
||||
QString previewImagePath,
|
||||
const QString youtube,
|
||||
const ScreenPlay::Create::VideoCodec codec,
|
||||
const QVector<QString> tags);
|
||||
|
||||
void abortAndCleanup();
|
||||
|
||||
void setProgress(float progress)
|
||||
{
|
||||
if (qFuzzyCompare(m_progress, progress))
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <QtMath>
|
||||
|
||||
#include "ScreenPlay/createimportstates.h"
|
||||
#include "ScreenPlayUtil/contenttypes.h"
|
||||
|
||||
namespace ScreenPlay {
|
||||
|
||||
@ -30,8 +31,12 @@ class CreateImportVideo : public QObject {
|
||||
Q_PROPERTY(float progress READ progress WRITE setProgress NOTIFY progressChanged)
|
||||
|
||||
public:
|
||||
explicit CreateImportVideo(const QString& videoPath, const QString& exportPath, const QString& codec, const int quality, std::atomic<bool>& interrupt);
|
||||
explicit CreateImportVideo(const QString& videoPath, const QString& exportPath, std::atomic<bool>& interrupt);
|
||||
explicit CreateImportVideo(
|
||||
const QString& videoPath,
|
||||
const QString& exportPath,
|
||||
const ScreenPlay::Video::VideoCodec targetCodec,
|
||||
const int quality,
|
||||
std::atomic<bool>& interrupt);
|
||||
|
||||
enum class Executable {
|
||||
FFMPEG,
|
||||
@ -50,7 +55,8 @@ public:
|
||||
QString m_videoPath;
|
||||
QString m_exportPath;
|
||||
QString m_format;
|
||||
QString m_codec;
|
||||
Video::VideoCodec m_targetCodec;
|
||||
Video::VideoCodec m_sourceCodec;
|
||||
|
||||
const int m_quality = 50;
|
||||
int m_numberOfFrames { 0 };
|
||||
|
@ -23,10 +23,8 @@
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include "ScreenPlay/globalvariables.h"
|
||||
#include "ScreenPlay/profilelistmodel.h"
|
||||
#include "ScreenPlay/settings.h"
|
||||
#include "ScreenPlayUtil/projectfile.h"
|
||||
#include "ScreenPlayUtil/util.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -17,7 +17,7 @@ Rectangle {
|
||||
property alias model: listView.model
|
||||
property StackView stackView
|
||||
|
||||
width: 380
|
||||
width: 340
|
||||
state: expanded ? "" : "inactive"
|
||||
layer.enabled: true
|
||||
Component.onCompleted: expanded = true
|
||||
@ -56,19 +56,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("Video Import h264 (.mp4)")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/Importh264/Importh264.qml"
|
||||
category: "Video Wallpaper"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("Video Import VP8 & VP9 (.webm)")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/ImportWebm/ImportWebm.qml"
|
||||
category: "Video Wallpaper"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("Video import (all types)")
|
||||
headline: qsTr("Import Video")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/ImportVideoAndConvert/CreateWallpaper.qml"
|
||||
category: "Video Wallpaper"
|
||||
objectName: "videoImportConvert"
|
||||
@ -83,25 +71,25 @@ Rectangle {
|
||||
ListElement {
|
||||
headline: qsTr("3D Engine Wallpaper (Godot 4.2)")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/GodotWallpaper.qml"
|
||||
category: "3D Engine & Code Wallpaper"
|
||||
category: "3D Engine & \nCode Wallpaper"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("QML Wallpaper")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/QMLWallpaper.qml"
|
||||
category: "3D Engine & Code Wallpaper"
|
||||
category: "3D Engine & \nCode Wallpaper"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("HTML5 Wallpaper")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/HTMLWallpaper.qml"
|
||||
category: "3D Engine & Code Wallpaper"
|
||||
category: "3D Engine & \nCode Wallpaper"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
headline: qsTr("Website Wallpaper")
|
||||
source: "qrc:/qml/ScreenPlayApp/qml/Create/Wizards/WebsiteWallpaper.qml"
|
||||
category: "3D Engine & Code Wallpaper"
|
||||
category: "3D Engine & \nCode Wallpaper"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
@ -123,9 +111,10 @@ Rectangle {
|
||||
}
|
||||
|
||||
section.delegate: Item {
|
||||
height: 60
|
||||
height: headline.contentHeight + 20
|
||||
|
||||
Text {
|
||||
id:headline
|
||||
font.pointSize: 18
|
||||
color: Material.primaryTextColor
|
||||
text: section
|
||||
|
@ -19,18 +19,20 @@ Item {
|
||||
anchors.fill: parent
|
||||
interactive: false
|
||||
clip: true
|
||||
|
||||
CreateWallpaperInit {
|
||||
onNext: function (filePath, codec) {
|
||||
startConvert(filePath, codec);
|
||||
CreateWallpaperFileSelect {
|
||||
onNext: function (filePath) {
|
||||
createWallpaperVideoImportConvert.filePath = filePath
|
||||
swipeView.currentIndex = 1
|
||||
}
|
||||
}
|
||||
|
||||
function startConvert(filePath, codec) {
|
||||
root.wizardStarted();
|
||||
swipeView.currentIndex = 1;
|
||||
createWallpaperVideoImportConvert.codec = codec;
|
||||
createWallpaperVideoImportConvert.filePath = filePath;
|
||||
App.create.createWallpaperStart(filePath, codec, quality);
|
||||
CreateWallpaperSettings {
|
||||
id: createWallpaperSettings
|
||||
onNext: function (codec,quality) {
|
||||
root.wizardStarted()
|
||||
swipeView.currentIndex = 2
|
||||
createWallpaperVideoImportConvert.codec = codec
|
||||
App.create.createWallpaperStart(createWallpaperVideoImportConvert.filePath, codec, quality)
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +42,6 @@ Item {
|
||||
onAbort: root.wizardExited()
|
||||
}
|
||||
|
||||
CreateWallpaperResult {
|
||||
}
|
||||
CreateWallpaperResult {}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import "../../"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property var allowedVideoFileEndings: ["*.webm", "*.mkv", "*.mp4", "*.mpg", "*.mp2", "*.mpeg", "*.ogv", "*.avi", "*.wmv", "*.m4v", "*.3gp"]
|
||||
|
||||
signal next(var filePath)
|
||||
|
||||
@ -29,7 +30,7 @@ Item {
|
||||
|
||||
Util.Headline {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Import a .mp4 video")
|
||||
text: qsTr("Import Video Wallpaper")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@ -42,37 +43,37 @@ Item {
|
||||
Layout.fillHeight: true
|
||||
spacing: 40
|
||||
|
||||
Text {
|
||||
id: txtDescription
|
||||
|
||||
text: qsTr("ScreenPlay v0.15 and up can play *.mp4 (also more known as h264). This can improove performance on older systems.")
|
||||
color: Material.primaryTextColor
|
||||
Layout.fillWidth: true
|
||||
font.pointSize: 13
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
font.family: App.settings.font
|
||||
}
|
||||
|
||||
DropArea {
|
||||
id: dropArea
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
onExited: {
|
||||
bg.color = Qt.darker(Material.backgroundColor);
|
||||
}
|
||||
onEntered: {
|
||||
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
|
||||
drag.accept(Qt.LinkAction);
|
||||
}
|
||||
onDropped: {
|
||||
let file = App.util.toLocal(drop.urls[0]);
|
||||
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
|
||||
if (file.endsWith(".mp4"))
|
||||
root.next(drop.urls[0]);
|
||||
else
|
||||
txtFile.text = qsTr("Invalid file type. Must be valid h264 (*.mp4)!");
|
||||
bg.color = Qt.darker(Material.backgroundColor)
|
||||
}
|
||||
onEntered: drag => {
|
||||
bg.color = Qt.darker(
|
||||
Qt.darker(Material.backgroundColor))
|
||||
drag.accept(Qt.LinkAction)
|
||||
}
|
||||
onDropped: drop => {
|
||||
let file = App.util.toLocal(drop.urls[0])
|
||||
bg.color = Qt.darker(
|
||||
Qt.darker(Material.backgroundColor))
|
||||
let found = false
|
||||
for (let ending in root.allowedVideoFileEndings) {
|
||||
if (file.endsWith(ending)) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
root.next(drop.urls[0])
|
||||
} else {
|
||||
txtFile.text = qsTr(
|
||||
"Invalid file type. Must be valid video!")
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: bg
|
||||
@ -94,7 +95,8 @@ Item {
|
||||
Text {
|
||||
id: txtFile
|
||||
|
||||
text: qsTr("Drop a *.mp4 file here or use 'Select file' below.")
|
||||
text: qsTr("Drag and drop your video here. Supported video formats are:\n\n%1").arg(
|
||||
root.allowedVideoFileEndings.join(" "))
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
color: Material.primaryTextColor
|
||||
font.pointSize: 13
|
||||
@ -123,7 +125,8 @@ Item {
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
font.family: App.settings.font
|
||||
onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
|
||||
onClicked: Qt.openUrlExternally(
|
||||
"https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
|
||||
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
@ -137,7 +140,7 @@ Item {
|
||||
highlighted: true
|
||||
font.family: App.settings.font
|
||||
onClicked: {
|
||||
fileDialogImportVideo.open();
|
||||
fileDialogImportVideo.open()
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
@ -145,7 +148,7 @@ Item {
|
||||
|
||||
nameFilters: ["Video files (*.mp4)"]
|
||||
onAccepted: {
|
||||
root.next(fileDialogImportVideo.currentFile);
|
||||
root.next(fileDialogImportVideo.currentFile)
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ Item {
|
||||
|
||||
property int quality: sliderQuality.slider.value
|
||||
|
||||
signal next(var filePath, var codec)
|
||||
signal next(var codec, var quality)
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 40
|
||||
@ -29,14 +29,13 @@ Item {
|
||||
Util.Headline {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Import any video type")
|
||||
text: qsTr("Import Video Wallpaper - Select Codec")
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txtDescription
|
||||
|
||||
text: qsTr("Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. If both have bad performance you can also try a QML wallpaper! Supported video formats are: \n
|
||||
*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv")
|
||||
text: qsTr("Depending on your PC configuration it is better to convert your wallpaper to a specific video codec. We skip encoding if the input format matches the ouput format.")
|
||||
color: Material.primaryTextColor
|
||||
Layout.fillWidth: true
|
||||
font.pointSize: 13
|
||||
@ -63,11 +62,15 @@ Item {
|
||||
Layout.preferredWidth: 400
|
||||
textRole: "text"
|
||||
valueRole: "value"
|
||||
currentIndex: 1
|
||||
currentIndex: 0
|
||||
font.family: App.settings.font
|
||||
|
||||
model: ListModel {
|
||||
id: model
|
||||
ListElement {
|
||||
text: "✨h.264 (Better for all hardware)"
|
||||
value: Util.Video.VideoCodec.H264
|
||||
}
|
||||
|
||||
ListElement {
|
||||
text: "VP8 (Better for older hardware)"
|
||||
@ -86,7 +89,7 @@ Item {
|
||||
id: sliderQuality
|
||||
|
||||
iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/icon_settings.svg"
|
||||
headline: qsTr("Quality slider. Lower value means better quality.")
|
||||
headline: qsTr("Set video quality. Lower value means better quality.")
|
||||
Layout.preferredWidth: 400
|
||||
|
||||
slider {
|
||||
@ -107,7 +110,8 @@ Item {
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
font.family: App.settings.font
|
||||
onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
|
||||
onClicked: Qt.openUrlExternally(
|
||||
"https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
|
||||
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
@ -116,23 +120,15 @@ Item {
|
||||
}
|
||||
|
||||
Button {
|
||||
objectName: "createWallpaperInitFileSelectButton"
|
||||
text: qsTr("Select file")
|
||||
objectName: "createWallpaperStartImportButton"
|
||||
text: qsTr("Start import")
|
||||
highlighted: true
|
||||
font.family: App.settings.font
|
||||
onClicked: {
|
||||
fileDialogImportVideo.open();
|
||||
let a = Util.Video.VideoCodec.H264
|
||||
let targetCodec = comboBoxCodec.currentValue
|
||||
root.next(a, sliderQuality.slider.value)
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: fileDialogImportVideo
|
||||
|
||||
nameFilters: ["Video files (*.mp4 *.mpg *.mp2 *.mpeg *.ogv *.avi *.wmv *.m4v *.3gp *.flv)"]
|
||||
onAccepted: {
|
||||
root.next(fileDialogImportVideo.currentFile, model.get(comboBoxCodec.currentIndex).value);
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
@ -12,7 +12,7 @@ Item {
|
||||
|
||||
property bool conversionFinishedSuccessful: false
|
||||
property bool canSave: false
|
||||
property var codec: Create.VP8
|
||||
property var codec: Util.Video.VideoCodec.H264
|
||||
property string filePath
|
||||
|
||||
signal abort
|
||||
@ -335,7 +335,14 @@ Item {
|
||||
onClicked: {
|
||||
if (conversionFinishedSuccessful) {
|
||||
btnSave.enabled = false;
|
||||
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, codec, textFieldTags.getTags());
|
||||
App.create.saveWallpaper(
|
||||
textFieldName.text,
|
||||
textFieldDescription.text,
|
||||
root.filePath,
|
||||
previewSelector.imageSource,
|
||||
textFieldYoutubeURL.text,
|
||||
root.codec,
|
||||
textFieldTags.getTags());
|
||||
savePopup.open();
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import ScreenPlayApp
|
||||
import ScreenPlay
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
signal wizardStarted
|
||||
signal wizardExited
|
||||
signal next
|
||||
|
||||
SwipeView {
|
||||
id: swipeView
|
||||
|
||||
anchors.fill: parent
|
||||
interactive: false
|
||||
clip: true
|
||||
|
||||
ImportWebmInit {
|
||||
onNext: function (filePath) {
|
||||
root.wizardStarted();
|
||||
swipeView.currentIndex = 1;
|
||||
createWallpaperVideoImportConvert.filePath = filePath;
|
||||
App.util.setNavigationActive(false);
|
||||
App.create.createWallpaperStart(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
ImportWebmConvert {
|
||||
id: createWallpaperVideoImportConvert
|
||||
|
||||
onExit: root.wizardExited()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,373 +0,0 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import ScreenPlayApp
|
||||
import ScreenPlay
|
||||
import ScreenPlayUtil as Util
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property bool conversionFinishedSuccessful: false
|
||||
property bool canSave: false
|
||||
property string filePath
|
||||
|
||||
signal exit
|
||||
signal save
|
||||
|
||||
function basename(str) {
|
||||
let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1));
|
||||
let filename = filenameWithExtentions.split('.').slice(0, -1).join('.');
|
||||
return filename;
|
||||
}
|
||||
|
||||
function checkCanSave() {
|
||||
if (canSave && conversionFinishedSuccessful)
|
||||
btnSave.enabled = true;
|
||||
else
|
||||
btnSave.enabled = false;
|
||||
}
|
||||
|
||||
onCanSaveChanged: root.checkCanSave()
|
||||
onFilePathChanged: {
|
||||
textFieldName.text = basename(filePath);
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onCreateWallpaperStateChanged(state) {
|
||||
switch (state) {
|
||||
case Import.State.AnalyseVideo:
|
||||
txtConvert.text = qsTr("AnalyseVideo...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewImage:
|
||||
txtConvert.text = qsTr("Generating preview image...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewThumbnailImage:
|
||||
txtConvert.text = qsTr("Generating preview thumbnail image...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewImageFinished:
|
||||
imgPreview.source = "file:///" + App.create.workingDir + "/preview.jpg";
|
||||
imgPreview.visible = true;
|
||||
break;
|
||||
case Import.State.ConvertingPreviewVideo:
|
||||
txtConvert.text = qsTr("Generating 5 second preview video...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewGif:
|
||||
txtConvert.text = qsTr("Generating preview gif...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewGifFinished:
|
||||
gifPreview.source = "file:///" + App.create.workingDir + "/preview.gif";
|
||||
imgPreview.visible = false;
|
||||
gifPreview.visible = true;
|
||||
gifPreview.playing = true;
|
||||
break;
|
||||
case Import.State.ConvertingAudio:
|
||||
txtConvert.text = qsTr("Converting Audio...");
|
||||
break;
|
||||
case Import.State.ConvertingVideo:
|
||||
txtConvert.text = qsTr("Converting Video... This can take some time!");
|
||||
break;
|
||||
case Import.State.ConvertingVideoError:
|
||||
txtConvert.text = qsTr("Converting Video ERROR!");
|
||||
break;
|
||||
case Import.State.AnalyseVideoError:
|
||||
txtConvert.text = qsTr("Analyse Video ERROR!");
|
||||
break;
|
||||
case Import.State.Finished:
|
||||
txtConvert.text = "";
|
||||
conversionFinishedSuccessful = true;
|
||||
busyIndicator.running = false;
|
||||
btnExit.enabled = false;
|
||||
root.checkCanSave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function onProgressChanged(progress) {
|
||||
var percentage = Math.floor(progress * 100);
|
||||
if (percentage > 100 || progress > 0.95)
|
||||
percentage = 100;
|
||||
if (percentage === NaN)
|
||||
print(progress, percentage);
|
||||
txtConvertNumber.text = percentage + "%";
|
||||
}
|
||||
|
||||
target: App.create
|
||||
}
|
||||
|
||||
Util.Headline {
|
||||
id: txtHeadline
|
||||
|
||||
text: qsTr("Import a video to a wallpaper")
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
margins: 40
|
||||
bottomMargin: 0
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: wrapperLeft
|
||||
|
||||
width: parent.width * 0.66
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: txtHeadline.bottom
|
||||
margins: 30
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: imgWrapper
|
||||
|
||||
color: Material.color(Material.Grey)
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
rightMargin: 20
|
||||
bottom: previewSelector.top
|
||||
bottomMargin: 20
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
Image {
|
||||
id: imgPreview
|
||||
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
AnimatedImage {
|
||||
id: gifPreview
|
||||
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
playing: true
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: shadow
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
id: gradientStop0
|
||||
position: 1
|
||||
color: "#DD000000"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
id: gradientStop1
|
||||
position: 0
|
||||
color: "#00000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: busyIndicator
|
||||
|
||||
anchors.centerIn: parent
|
||||
running: true
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txtConvertNumber
|
||||
|
||||
color: "white"
|
||||
font.pointSize: 21
|
||||
font.family: App.settings.font
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 40
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txtConvert
|
||||
|
||||
color: Material.secondaryTextColor
|
||||
text: qsTr("Generating preview video...")
|
||||
font.pointSize: 14
|
||||
font.family: App.settings.font
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Util.ImageSelector {
|
||||
id: previewSelector
|
||||
|
||||
height: 80
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 20
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: wrapperRight
|
||||
|
||||
width: parent.width * 0.33
|
||||
|
||||
anchors {
|
||||
top: txtHeadline.bottom
|
||||
topMargin: 30
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column
|
||||
|
||||
spacing: 0
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
left: parent.left
|
||||
margins: 30
|
||||
top: parent.top
|
||||
topMargin: 0
|
||||
bottom: column1.top
|
||||
bottomMargin: 50
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: textFieldName
|
||||
|
||||
placeholderText: qsTr("Name (required!)")
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
onTextChanged: {
|
||||
if (textFieldName.text.length >= 3)
|
||||
canSave = true;
|
||||
else
|
||||
canSave = false;
|
||||
}
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: textFieldDescription
|
||||
|
||||
placeholderText: qsTr("Description")
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: textFieldYoutubeURL
|
||||
|
||||
placeholderText: qsTr("Youtube URL")
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Util.TagSelector {
|
||||
id: textFieldTags
|
||||
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: column1
|
||||
|
||||
height: 80
|
||||
width: childrenRect.width
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 30
|
||||
bottomMargin: -10
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
Button {
|
||||
id: btnExit
|
||||
|
||||
text: qsTr("Abort")
|
||||
Material.accent: Material.color(Material.Red)
|
||||
highlighted: true
|
||||
font.family: App.settings.font
|
||||
onClicked: {
|
||||
root.exit();
|
||||
App.create.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: btnSave
|
||||
objectName: "btnSave"
|
||||
text: qsTr("Save")
|
||||
enabled: false
|
||||
Material.background: Material.accent
|
||||
Material.foreground: "white"
|
||||
font.family: App.settings.font
|
||||
onClicked: {
|
||||
if (conversionFinishedSuccessful) {
|
||||
btnSave.enabled = false;
|
||||
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Util.Video.VideoCodec.VP9, textFieldTags.getTags());
|
||||
savePopup.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: savePopup
|
||||
|
||||
modal: true
|
||||
focus: true
|
||||
width: 250
|
||||
anchors.centerIn: parent
|
||||
height: 200
|
||||
onOpened: timerSave.start()
|
||||
|
||||
BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
running: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Save Wallpaper...")
|
||||
color: Material.primaryTextColor
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 30
|
||||
font.family: App.settings.font
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: timerSave
|
||||
|
||||
interval: 1000 + Math.random() * 1000
|
||||
onTriggered: {
|
||||
savePopup.close();
|
||||
App.util.setNavigationActive(true);
|
||||
root.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
import ScreenPlayApp
|
||||
import ScreenPlay
|
||||
import ScreenPlayUtil as Util
|
||||
import "../../"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
signal next(var filePath)
|
||||
|
||||
ColumnLayout {
|
||||
id: wrapper
|
||||
|
||||
spacing: 40
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: btnOpenDocs.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 20
|
||||
}
|
||||
|
||||
Util.Headline {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Import a .webm video")
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
spacing: 40
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 40
|
||||
|
||||
Text {
|
||||
id: txtDescription
|
||||
|
||||
text: qsTr("When importing webm we can skip the long conversion. When you get unsatisfying results with the ScreenPlay importer from 'ideo import and convert (all types)' you can also convert via the free and open source HandBrake!")
|
||||
color: Material.primaryTextColor
|
||||
Layout.fillWidth: true
|
||||
font.pointSize: 13
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
font.family: App.settings.font
|
||||
}
|
||||
|
||||
DropArea {
|
||||
id: dropArea
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
onExited: {
|
||||
bg.color = Qt.darker(Material.backgroundColor);
|
||||
}
|
||||
onEntered: {
|
||||
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
|
||||
drag.accept(Qt.LinkAction);
|
||||
}
|
||||
onDropped: {
|
||||
let file = App.util.toLocal(drop.urls[0]);
|
||||
bg.color = Qt.darker(Qt.darker(Material.backgroundColor));
|
||||
if (file.endsWith(".webm"))
|
||||
root.next(drop.urls[0]);
|
||||
else
|
||||
txtFile.text = qsTr("Invalid file type. Must be valid VP8 or VP9 (*.webm)!");
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: bg
|
||||
|
||||
anchors.fill: parent
|
||||
radius: 3
|
||||
color: Qt.darker(Material.backgroundColor)
|
||||
}
|
||||
|
||||
Image {
|
||||
id: bgPattern
|
||||
|
||||
anchors.fill: parent
|
||||
fillMode: Image.Tile
|
||||
opacity: 0.2
|
||||
source: "qrc:/qml/ScreenPlayApp/assets/images/noisy-texture-3.png"
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txtFile
|
||||
|
||||
text: qsTr("Drop a *.webm file here or use 'Select file' below.")
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
color: Material.primaryTextColor
|
||||
font.pointSize: 13
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
font.family: App.settings.font
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 40
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: btnOpenDocs
|
||||
|
||||
text: qsTr("Open Documentation")
|
||||
Material.accent: Material.color(Material.LightGreen)
|
||||
highlighted: true
|
||||
icon.source: "qrc:/qml/ScreenPlayApp/assets/icons/icon_document.svg"
|
||||
icon.color: "white"
|
||||
icon.width: 16
|
||||
icon.height: 16
|
||||
font.family: App.settings.font
|
||||
onClicked: Qt.openUrlExternally("https://kelteseth.gitlab.io/ScreenPlayDocs/wallpaper/wallpaper/#performance")
|
||||
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
margins: 20
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: qsTr("Select file")
|
||||
highlighted: true
|
||||
font.family: App.settings.font
|
||||
onClicked: {
|
||||
fileDialogImportVideo.open();
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: fileDialogImportVideo
|
||||
|
||||
nameFilters: ["Video files (*.webm)"]
|
||||
onAccepted: {
|
||||
root.next(fileDialogImportVideo.currentFile);
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
margins: 20
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import ScreenPlayApp
|
||||
import ScreenPlay
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
signal wizardStarted
|
||||
signal wizardExited
|
||||
signal next
|
||||
|
||||
SwipeView {
|
||||
id: swipeView
|
||||
|
||||
anchors.fill: parent
|
||||
interactive: false
|
||||
clip: true
|
||||
|
||||
Importh264Init {
|
||||
onNext: function (filePath) {
|
||||
root.wizardStarted();
|
||||
swipeView.currentIndex = 1;
|
||||
createWallpaperVideoImportConvert.filePath = filePath;
|
||||
App.util.setNavigationActive(false);
|
||||
App.create.importH264(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
Importh264Convert {
|
||||
id: createWallpaperVideoImportConvert
|
||||
|
||||
onExit: root.wizardExited()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,374 +0,0 @@
|
||||
import QtQuick
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Controls.Material
|
||||
import QtQuick.Layouts
|
||||
import ScreenPlayApp
|
||||
import ScreenPlay
|
||||
import ScreenPlayUtil as Util
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property bool conversionFinishedSuccessful: false
|
||||
property bool canSave: false
|
||||
property string filePath
|
||||
|
||||
signal exit
|
||||
signal save
|
||||
|
||||
function basename(str) {
|
||||
let filenameWithExtentions = (str.slice(str.lastIndexOf("/") + 1));
|
||||
let filename = filenameWithExtentions.split('.').slice(0, -1).join('.');
|
||||
return filename;
|
||||
}
|
||||
|
||||
function checkCanSave() {
|
||||
if (canSave && conversionFinishedSuccessful)
|
||||
btnSave.enabled = true;
|
||||
else
|
||||
btnSave.enabled = false;
|
||||
}
|
||||
|
||||
onCanSaveChanged: root.checkCanSave()
|
||||
onFilePathChanged: {
|
||||
textFieldName.text = basename(filePath);
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onCreateWallpaperStateChanged(state) {
|
||||
switch (state) {
|
||||
case Import.State.AnalyseVideo:
|
||||
txtConvert.text = qsTr("AnalyseVideo...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewImage:
|
||||
txtConvert.text = qsTr("Generating preview image...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewThumbnailImage:
|
||||
txtConvert.text = qsTr("Generating preview thumbnail image...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewImageFinished:
|
||||
imgPreview.source = "file:///" + App.create.workingDir + "/preview.jpg";
|
||||
imgPreview.visible = true;
|
||||
break;
|
||||
case Import.State.ConvertingPreviewVideo:
|
||||
txtConvert.text = qsTr("Generating 5 second preview video...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewGif:
|
||||
txtConvert.text = qsTr("Generating preview gif...");
|
||||
break;
|
||||
case Import.State.ConvertingPreviewGifFinished:
|
||||
gifPreview.source = "file:///" + App.create.workingDir + "/preview.gif";
|
||||
imgPreview.visible = false;
|
||||
gifPreview.visible = true;
|
||||
gifPreview.playing = true;
|
||||
break;
|
||||
case Import.State.ConvertingAudio:
|
||||
txtConvert.text = qsTr("Converting Audio...");
|
||||
break;
|
||||
case Import.State.ConvertingVideo:
|
||||
txtConvert.text = qsTr("Converting Video... This can take some time!");
|
||||
break;
|
||||
case Import.State.ConvertingVideoError:
|
||||
txtConvert.text = qsTr("Converting Video ERROR!");
|
||||
break;
|
||||
case Import.State.AnalyseVideoError:
|
||||
txtConvert.text = qsTr("Analyse Video ERROR!");
|
||||
break;
|
||||
case Import.State.Finished:
|
||||
txtConvert.text = "";
|
||||
conversionFinishedSuccessful = true;
|
||||
busyIndicator.running = false;
|
||||
btnExit.enabled = false;
|
||||
root.checkCanSave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function onProgressChanged(progress) {
|
||||
var percentage = Math.floor(progress * 100);
|
||||
if (percentage > 100 || progress > 0.95)
|
||||
percentage = 100;
|
||||
if (percentage === NaN)
|
||||
print(progress, percentage);
|
||||
txtConvertNumber.text = percentage + "%";
|
||||
}
|
||||
|
||||
target: App.create
|
||||
}
|
||||
|
||||
Util.Headline {
|
||||
id: txtHeadline
|
||||
|
||||
text: qsTr("Import a video to a wallpaper")
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
margins: 40
|
||||
bottomMargin: 0
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: wrapperLeft
|
||||
|
||||
width: parent.width * 0.66
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: txtHeadline.bottom
|
||||
margins: 30
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: imgWrapper
|
||||
|
||||
color: Material.color(Material.Grey)
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
rightMargin: 20
|
||||
bottom: previewSelector.top
|
||||
bottomMargin: 20
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
Image {
|
||||
id: imgPreview
|
||||
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
AnimatedImage {
|
||||
id: gifPreview
|
||||
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
playing: true
|
||||
visible: false
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: shadow
|
||||
anchors.fill: parent
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
id: gradientStop0
|
||||
position: 1
|
||||
color: "#DD000000"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
id: gradientStop1
|
||||
position: 0
|
||||
color: "#00000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusyIndicator {
|
||||
id: busyIndicator
|
||||
|
||||
anchors.centerIn: parent
|
||||
running: true
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txtConvertNumber
|
||||
|
||||
color: "white"
|
||||
font.pointSize: 21
|
||||
font.family: App.settings.font
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 40
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: txtConvert
|
||||
|
||||
color: Material.secondaryTextColor
|
||||
text: qsTr("Generating preview video...")
|
||||
font.pointSize: 14
|
||||
font.family: App.settings.font
|
||||
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Util.ImageSelector {
|
||||
id: previewSelector
|
||||
|
||||
height: 80
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 20
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: wrapperRight
|
||||
|
||||
width: parent.width * 0.33
|
||||
|
||||
anchors {
|
||||
top: txtHeadline.bottom
|
||||
topMargin: 30
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: column
|
||||
|
||||
spacing: 0
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
left: parent.left
|
||||
margins: 30
|
||||
top: parent.top
|
||||
topMargin: 0
|
||||
bottom: column1.top
|
||||
bottomMargin: 50
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: textFieldName
|
||||
|
||||
placeholderText: qsTr("Name (required!)")
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
onTextChanged: {
|
||||
if (textFieldName.text.length >= 3)
|
||||
canSave = true;
|
||||
else
|
||||
canSave = false;
|
||||
}
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: textFieldDescription
|
||||
|
||||
placeholderText: qsTr("Description")
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Util.TextField {
|
||||
id: textFieldYoutubeURL
|
||||
|
||||
placeholderText: qsTr("Youtube URL")
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Util.TagSelector {
|
||||
id: textFieldTags
|
||||
|
||||
width: parent.width
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: column1
|
||||
|
||||
height: 80
|
||||
width: childrenRect.width
|
||||
spacing: 10
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 30
|
||||
bottomMargin: -10
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
Button {
|
||||
id: btnExit
|
||||
|
||||
text: qsTr("Abort")
|
||||
Material.background: Material.Red
|
||||
Material.foreground: "white"
|
||||
font.family: App.settings.font
|
||||
onClicked: {
|
||||
root.exit();
|
||||
App.create.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: btnSave
|
||||
objectName: "btnSave"
|
||||
text: qsTr("Save")
|
||||
enabled: false
|
||||
Material.background: Material.accent
|
||||
Material.foreground: "white"
|
||||
font.family: App.settings.font
|
||||
onClicked: {
|
||||
if (conversionFinishedSuccessful) {
|
||||
btnSave.enabled = false;
|
||||
App.create.saveWallpaper(textFieldName.text, textFieldDescription.text, root.filePath, previewSelector.imageSource, textFieldYoutubeURL.text, Create.H264, textFieldTags.getTags());
|
||||
savePopup.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Popup {
|
||||
id: savePopup
|
||||
|
||||
modal: true
|
||||
focus: true
|
||||
width: 250
|
||||
anchors.centerIn: parent
|
||||
height: 200
|
||||
onOpened: timerSave.start()
|
||||
|
||||
BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
running: true
|
||||
}
|
||||
|
||||
Text {
|
||||
text: qsTr("Save Wallpaper...")
|
||||
color: Material.primaryTextColor
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 30
|
||||
font.family: App.settings.font
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: timerSave
|
||||
|
||||
interval: 1000 + Math.random() * 1000
|
||||
onTriggered: {
|
||||
savePopup.close();
|
||||
App.util.setNavigationActive(true);
|
||||
root.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -340,9 +340,15 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
MessageDialog {
|
||||
id: errorDialog
|
||||
buttons: MessageDialog.Ok
|
||||
|
||||
Dialog {
|
||||
id: dialog
|
||||
standardButtons: Dialog.Ok
|
||||
title: qsTr("Export Godot project")
|
||||
property alias message: messageText.text
|
||||
Text {
|
||||
id: messageText
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
@ -375,21 +381,22 @@ Item {
|
||||
absoluteStoragePath,
|
||||
App.globalVariables.godotEditorExecutablePath).then(
|
||||
result => {
|
||||
if(!result.success){
|
||||
errorDialog.text = ("Error exporting Godot")
|
||||
errorDialog.informativeText = result.messag
|
||||
errorDialog.open()
|
||||
return
|
||||
if (!result.success) {
|
||||
dialog.title = ("Error exporting Godot")
|
||||
dialog.message = result.message
|
||||
dialog.open()
|
||||
} else {
|
||||
const screenFile = item.m_file
|
||||
let success = App.screenPlayManager.createWallpaper(
|
||||
root.type,
|
||||
cbVideoFillMode.currentValue,
|
||||
absoluteStoragePath,
|
||||
previewImage, screenFile,
|
||||
activeMonitors, volume,
|
||||
1, {}, true)
|
||||
}
|
||||
const screenFile = item.m_file
|
||||
let success = App.screenPlayManager.createWallpaper(
|
||||
root.type,
|
||||
cbVideoFillMode.currentValue,
|
||||
absoluteStoragePath,
|
||||
previewImage, screenFile,
|
||||
activeMonitors, volume,
|
||||
1, {}, true)
|
||||
})
|
||||
root.state = "inactive"
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "ScreenPlay/create.h"
|
||||
#include "ScreenPlayUtil/util.h"
|
||||
#include "qguiapplication.h"
|
||||
|
||||
namespace ScreenPlay {
|
||||
|
||||
@ -43,7 +44,7 @@ void Create::reset()
|
||||
/*!
|
||||
\brief Starts the process.
|
||||
*/
|
||||
void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, const int quality)
|
||||
void Create::createWallpaperStart(QString videoPath, ScreenPlay::Video::VideoCodec target_codec, const int quality)
|
||||
{
|
||||
reset();
|
||||
ScreenPlay::Util util;
|
||||
@ -63,19 +64,6 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
|
||||
return;
|
||||
}
|
||||
|
||||
QString target_codec;
|
||||
switch (codec) {
|
||||
case Create::VideoCodec::VP8:
|
||||
target_codec = "vp8";
|
||||
break;
|
||||
case Create::VideoCodec::VP9:
|
||||
target_codec = "vp9";
|
||||
break;
|
||||
case Create::VideoCodec::AV1:
|
||||
target_codec = "av1";
|
||||
break;
|
||||
}
|
||||
|
||||
m_createImportFuture = QtConcurrent::run(QThreadPool::globalInstance(), [videoPath, target_codec, quality, this]() {
|
||||
CreateImportVideo import(videoPath, workingDir(), target_codec, quality, m_interrupt);
|
||||
QObject::connect(&import, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged, Qt::ConnectionType::QueuedConnection);
|
||||
@ -134,13 +122,7 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
|
||||
}
|
||||
}
|
||||
|
||||
// Skip convert for webm
|
||||
if (import.m_isWebm) {
|
||||
emit createWallpaperStateChanged(Import::State::Finished);
|
||||
return;
|
||||
}
|
||||
|
||||
qInfo() << "createWallpaperVideo()";
|
||||
qInfo() << "createWallpaperVideo";
|
||||
if (!import.createWallpaperVideo() || m_interrupt) {
|
||||
emit createWallpaperStateChanged(Import::State::Failed);
|
||||
emit import.abortAndCleanup();
|
||||
@ -157,91 +139,6 @@ void Create::createWallpaperStart(QString videoPath, Create::VideoCodec codec, c
|
||||
m_createImportFutureWatcher.setFuture(m_createImportFuture);
|
||||
}
|
||||
|
||||
void Create::importH264(QString videoPath)
|
||||
{
|
||||
reset();
|
||||
ScreenPlay::Util util;
|
||||
videoPath = util.toLocal(videoPath);
|
||||
|
||||
const QDir installedDir = util.toLocal(m_globalVariables->localStoragePath().toString());
|
||||
|
||||
// Create a temp dir so we can later alter it to the workshop id
|
||||
const QDateTime date = QDateTime::currentDateTime();
|
||||
const auto folderName = date.toString("ddMMyyyyhhmmss");
|
||||
setWorkingDir(installedDir.path() + "/" + folderName);
|
||||
|
||||
if (!installedDir.mkdir(folderName)) {
|
||||
qInfo() << "Unable to create folder with name: " << folderName << " at: " << installedDir;
|
||||
emit createWallpaperStateChanged(Import::State::CreateTmpFolderError);
|
||||
emit abortCreateWallpaper();
|
||||
return;
|
||||
}
|
||||
|
||||
m_createImportFuture = QtConcurrent::run(QThreadPool::globalInstance(), [videoPath, this]() {
|
||||
CreateImportVideo import(videoPath, workingDir(), m_interrupt);
|
||||
QObject::connect(&import, &CreateImportVideo::createWallpaperStateChanged, this, &Create::createWallpaperStateChanged, Qt::ConnectionType::QueuedConnection);
|
||||
QObject::connect(&import, &CreateImportVideo::abortAndCleanup, this, &Create::abortAndCleanup, Qt::ConnectionType::QueuedConnection);
|
||||
QObject::connect(
|
||||
&import, &CreateImportVideo::processOutput, this, [this](const QString text) {
|
||||
appendFfmpegOutput(text + "\n");
|
||||
},
|
||||
Qt::ConnectionType::QueuedConnection);
|
||||
|
||||
if (!import.createWallpaperInfo() || m_interrupt) {
|
||||
emit createWallpaperStateChanged(Import::State::Failed);
|
||||
emit import.abortAndCleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
qInfo() << "createWallpaperImageThumbnailPreview()";
|
||||
if (!import.createWallpaperImageThumbnailPreview() || m_interrupt) {
|
||||
emit createWallpaperStateChanged(Import::State::Failed);
|
||||
emit import.abortAndCleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
qInfo() << "createWallpaperImagePreview()";
|
||||
if (!import.createWallpaperImagePreview() || m_interrupt) {
|
||||
emit createWallpaperStateChanged(Import::State::Failed);
|
||||
emit import.abortAndCleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip preview convert for webm
|
||||
if (!import.createWallpaperVideoPreview() || m_interrupt) {
|
||||
emit createWallpaperStateChanged(Import::State::Failed);
|
||||
emit import.abortAndCleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
qInfo() << "createWallpaperGifPreview()";
|
||||
if (!import.createWallpaperGifPreview() || m_interrupt) {
|
||||
emit createWallpaperStateChanged(Import::State::Failed);
|
||||
emit import.abortAndCleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// If the video has no audio we can skip the extraction
|
||||
if (!import.m_skipAudio) {
|
||||
qInfo() << "extractWallpaperAudio()";
|
||||
if (!import.extractWallpaperAudio() || m_interrupt) {
|
||||
emit createWallpaperStateChanged(Import::State::Failed);
|
||||
emit import.abortAndCleanup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
emit createWallpaperStateChanged(Import::State::Finished);
|
||||
return;
|
||||
});
|
||||
|
||||
QObject::connect(&m_createImportFutureWatcher, &QFutureWatcherBase::finished, this, [this]() {
|
||||
if (m_interrupt)
|
||||
abortAndCleanup();
|
||||
});
|
||||
|
||||
m_createImportFutureWatcher.setFuture(m_createImportFuture);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief When converting of the wallpaper steps where successful.
|
||||
@ -252,7 +149,7 @@ void Create::saveWallpaper(
|
||||
QString filePath,
|
||||
QString previewImagePath,
|
||||
const QString youtube,
|
||||
const Create::VideoCodec codec,
|
||||
const ScreenPlay::Video::VideoCodec codec,
|
||||
const QVector<QString> tags)
|
||||
{
|
||||
ScreenPlay::Util util;
|
||||
@ -282,13 +179,13 @@ void Create::saveWallpaper(
|
||||
}
|
||||
|
||||
QFileInfo filePathFile(filePath);
|
||||
if (filePath.endsWith(".webm") || filePath.endsWith(".mp4")) {
|
||||
if (!QFile::copy(filePath, m_workingDir + "/" + filePathFile.fileName())) {
|
||||
qDebug() << "Could not copy" << filePath << " to " << m_workingDir + "/" + filePathFile.fileName();
|
||||
emit createWallpaperStateChanged(Import::State::CopyFilesError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if (filePath.endsWith(".webm") || filePath.endsWith(".mp4")) {
|
||||
// if (!QFile::copy(filePath, m_workingDir + "/" + filePathFile.fileName())) {
|
||||
// qDebug() << "Could not copy" << filePath << " to " << m_workingDir + "/" + filePathFile.fileName();
|
||||
// emit createWallpaperStateChanged(Import::State::CopyFilesError);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
emit createWallpaperStateChanged(Import::State::CopyFilesFinished);
|
||||
emit createWallpaperStateChanged(Import::State::CreateProjectFile);
|
||||
|
||||
@ -296,8 +193,17 @@ void Create::saveWallpaper(
|
||||
obj.insert("description", description);
|
||||
obj.insert("title", title);
|
||||
obj.insert("youtube", youtube);
|
||||
obj.insert("videoCodec", QVariant::fromValue<VideoCodec>(codec).toString());
|
||||
obj.insert("file", filePathFile.completeBaseName() + (codec == VideoCodec::H264 ? ".mp4" : ".webm"));
|
||||
obj.insert("videoCodec", QVariant::fromValue<Video::VideoCodec>(codec).toString());
|
||||
|
||||
QString fileEnding;
|
||||
if (codec == Video::VideoCodec::H264)
|
||||
fileEnding = ".mp4";
|
||||
if (codec == Video::VideoCodec::AV1)
|
||||
fileEnding = ".mkv";
|
||||
if (codec == Video::VideoCodec::VP8 || codec == Video::VideoCodec::VP9)
|
||||
fileEnding = ".webm";
|
||||
|
||||
obj.insert("file", filePathFile.completeBaseName() + fileEnding);
|
||||
obj.insert("previewGIF", "preview.gif");
|
||||
obj.insert("previewWEBM", "preview.webm");
|
||||
obj.insert("preview", previewImageFile.exists() ? previewImageFile.fileName() : "preview.jpg");
|
||||
|
@ -24,7 +24,7 @@ namespace ScreenPlay {
|
||||
CreateImportVideo::CreateImportVideo(
|
||||
const QString& videoPath,
|
||||
const QString& exportPath,
|
||||
const QString& codec,
|
||||
const ScreenPlay::Video::VideoCodec targetCodec,
|
||||
const int quality,
|
||||
std::atomic<bool>& interrupt)
|
||||
: QObject(nullptr)
|
||||
@ -33,17 +33,7 @@ CreateImportVideo::CreateImportVideo(
|
||||
{
|
||||
m_videoPath = videoPath;
|
||||
m_exportPath = exportPath;
|
||||
m_codec = codec;
|
||||
setupFFMPEG();
|
||||
}
|
||||
|
||||
CreateImportVideo::CreateImportVideo(const QString& videoPath, const QString& exportPath, std::atomic<bool>& interrupt)
|
||||
: QObject(nullptr)
|
||||
, m_quality(0)
|
||||
, m_interrupt(interrupt)
|
||||
{
|
||||
m_videoPath = videoPath;
|
||||
m_exportPath = exportPath;
|
||||
m_targetCodec = targetCodec;
|
||||
setupFFMPEG();
|
||||
}
|
||||
|
||||
@ -86,10 +76,6 @@ void CreateImportVideo::setupFFMPEG()
|
||||
*/
|
||||
bool CreateImportVideo::createWallpaperInfo()
|
||||
{
|
||||
if (m_videoPath.endsWith(".webm") || m_videoPath.endsWith(".mkv")) {
|
||||
m_isWebm = true;
|
||||
}
|
||||
|
||||
// Get video info
|
||||
QStringList args;
|
||||
args.append("-print_format");
|
||||
@ -138,12 +124,7 @@ bool CreateImportVideo::createWallpaperInfo()
|
||||
emit createWallpaperStateChanged(Import::State::AnalyseVideoError);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_isWebm) {
|
||||
return analyzeWebmReadFrames(obj.value());
|
||||
} else {
|
||||
return analyzeVideo(obj.value());
|
||||
}
|
||||
return analyzeVideo(obj.value());
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -165,6 +146,15 @@ bool CreateImportVideo::analyzeWebmReadFrames(const QJsonObject& obj)
|
||||
const QJsonObject firstStream = streams.first().toObject();
|
||||
qInfo() << "streams:" << streams;
|
||||
|
||||
for (const auto& stream : streams) {
|
||||
QString codec_type = stream.toObject().value("codec_type").toString();
|
||||
if (codec_type == "audio") {
|
||||
m_skipAudio = false;
|
||||
} else {
|
||||
m_skipAudio = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool okParseNumberOfFrames { false };
|
||||
int numberOfFrames = firstStream.value("nb_read_frames").toString().toInt(&okParseNumberOfFrames);
|
||||
if (!okParseNumberOfFrames) {
|
||||
@ -202,6 +192,37 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
|
||||
{
|
||||
// Check for audio and video streams
|
||||
const QJsonArray arrayStream = obj.value("streams").toArray();
|
||||
// Get framerate
|
||||
const QJsonArray streams = obj.value("streams").toArray();
|
||||
if (streams.empty()) {
|
||||
qDebug() << "Error container does not have any video streams";
|
||||
emit processOutput("Error container does not have any video streams");
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonObject firstStream = streams.first().toObject();
|
||||
const QString codecName = firstStream.value("codec_name").toVariant().toString();
|
||||
|
||||
// It is not that important to check for all codecs,
|
||||
// we just need a check for the important once to skip
|
||||
// import convertion if it is the same codec.
|
||||
if (codecName == "vp8") {
|
||||
m_sourceCodec = Video::VideoCodec::VP8;
|
||||
} else if (codecName == "vp9") {
|
||||
m_sourceCodec = Video::VideoCodec::VP9;
|
||||
} else if (codecName == "av1") {
|
||||
m_sourceCodec = Video::VideoCodec::AV1;
|
||||
} else if (codecName == "h264") {
|
||||
m_sourceCodec = Video::VideoCodec::H264;
|
||||
} else if (codecName == "hevc") {
|
||||
m_sourceCodec = Video::VideoCodec::H265; // HEVC is H.265
|
||||
} else {
|
||||
m_sourceCodec = Video::VideoCodec::Unknown;
|
||||
}
|
||||
|
||||
if (m_sourceCodec == Video::VideoCodec::VP8 || m_sourceCodec == Video::VideoCodec::VP9) {
|
||||
return analyzeWebmReadFrames(obj);
|
||||
}
|
||||
|
||||
bool hasAudioStream { false };
|
||||
bool hasVideoStream { false };
|
||||
@ -257,16 +278,6 @@ bool CreateImportVideo::analyzeVideo(const QJsonObject& obj)
|
||||
|
||||
m_length = static_cast<int>(tmpLength);
|
||||
|
||||
// Get framerate
|
||||
const QJsonArray streams = obj.value("streams").toArray();
|
||||
if (streams.empty()) {
|
||||
qDebug() << "Error container does not have any video streams";
|
||||
emit processOutput("Error container does not have any video streams");
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonObject firstStream = streams.first().toObject();
|
||||
|
||||
// The paramter gets us the exact framerate
|
||||
// "avg_frame_rate":"47850000/797509"
|
||||
// so we need no calc the value by dividing the two numbers
|
||||
@ -519,6 +530,18 @@ bool CreateImportVideo::createWallpaperImagePreview()
|
||||
*/
|
||||
bool CreateImportVideo::createWallpaperVideo()
|
||||
{
|
||||
const QFileInfo sourceFile(m_videoPath);
|
||||
|
||||
if (m_sourceCodec == m_targetCodec) {
|
||||
qInfo() << "Skip video convert because they are the same";
|
||||
if (!QFile::copy(sourceFile.absoluteFilePath(), m_exportPath + "/" + sourceFile.fileName())) {
|
||||
qDebug() << "Could not copy" << sourceFile.absoluteFilePath() << " to " << m_exportPath;
|
||||
return false;
|
||||
}
|
||||
emit createWallpaperStateChanged(Import::State::Finished);
|
||||
return true;
|
||||
}
|
||||
|
||||
emit createWallpaperStateChanged(Import::State::ConvertingVideo);
|
||||
|
||||
connect(m_process.get(), &QProcess::readyReadStandardOutput, this, [&]() {
|
||||
@ -543,6 +566,26 @@ bool CreateImportVideo::createWallpaperVideo()
|
||||
emit processOutput(tmpOut);
|
||||
});
|
||||
|
||||
QString targetCodec;
|
||||
QString targetFileEnding;
|
||||
if (m_targetCodec == Video::VideoCodec::VP8)
|
||||
targetCodec = "libvpx";
|
||||
targetFileEnding = ".webm";
|
||||
if (m_targetCodec == Video::VideoCodec::VP8)
|
||||
targetCodec = "libvpx";
|
||||
targetFileEnding = ".webm";
|
||||
if (m_targetCodec == Video::VideoCodec::AV1)
|
||||
targetCodec = "libaom-av1";
|
||||
targetFileEnding = ".mkv";
|
||||
if (m_targetCodec == Video::VideoCodec::H264) {
|
||||
targetFileEnding = ".mp4";
|
||||
if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows) {
|
||||
targetCodec = "h264_mf";
|
||||
} else {
|
||||
targetCodec = "libx264";
|
||||
}
|
||||
}
|
||||
|
||||
QStringList args;
|
||||
args.append("-hide_banner");
|
||||
args.append("-y");
|
||||
@ -550,12 +593,7 @@ bool CreateImportVideo::createWallpaperVideo()
|
||||
args.append("-i");
|
||||
args.append(m_videoPath);
|
||||
args.append("-c:v");
|
||||
if (m_codec == "vp8")
|
||||
args.append("libvpx");
|
||||
if (m_codec == "vp9")
|
||||
args.append("libvpx-vp9");
|
||||
if (m_codec == "av1")
|
||||
args.append("libaom-av1");
|
||||
args.append(targetCodec);
|
||||
args.append("-b:v");
|
||||
args.append("13000k");
|
||||
args.append("-threads");
|
||||
@ -593,12 +631,7 @@ bool CreateImportVideo::createWallpaperVideo()
|
||||
args.append("-i");
|
||||
args.append(m_videoPath);
|
||||
args.append("-c:v");
|
||||
if (m_codec == "vp8")
|
||||
args.append("libvpx");
|
||||
if (m_codec == "vp9")
|
||||
args.append("libvpx-vp9");
|
||||
if (m_codec == "av1")
|
||||
args.append("libaom-av1");
|
||||
args.append(targetCodec);
|
||||
args.append("-b:v");
|
||||
args.append("13000k");
|
||||
args.append("-threads");
|
||||
@ -617,8 +650,7 @@ bool CreateImportVideo::createWallpaperVideo()
|
||||
args.append(QString::number(m_quality));
|
||||
args.append("-pass");
|
||||
args.append("2");
|
||||
const QFileInfo file(m_videoPath);
|
||||
const QString convertedFileAbsolutePath { m_exportPath + "/" + file.completeBaseName() + ".webm" };
|
||||
const QString convertedFileAbsolutePath { m_exportPath + "/" + sourceFile.completeBaseName() + targetFileEnding };
|
||||
args.append(convertedFileAbsolutePath);
|
||||
|
||||
const QString ffmpegOutput = waitForFinished(args);
|
||||
@ -696,7 +728,7 @@ QString CreateImportVideo::waitForFinished(
|
||||
{
|
||||
|
||||
m_process = std::make_unique<QProcess>();
|
||||
QObject::connect(m_process.get(), &QProcess::errorOccurred, [=, this](QProcess::ProcessError error) {
|
||||
QObject::connect(m_process.get(), &QProcess::errorOccurred, this, [=, this](QProcess::ProcessError error) {
|
||||
qDebug() << "error enum val = " << error << m_process->errorString();
|
||||
emit createWallpaperStateChanged(Import::State::AnalyseVideoError);
|
||||
m_process->terminate();
|
||||
|
@ -5,9 +5,6 @@
|
||||
#include <QQmlEngine>
|
||||
#include <QtCore/qmetatype.h>
|
||||
|
||||
// We must package everything into a class for
|
||||
// qml to be able to have typed enums. Making
|
||||
// qml enums unscoped as default was a mistake.
|
||||
namespace ScreenPlay {
|
||||
|
||||
class ContentTypes : public QObject {
|
||||
|
@ -12,7 +12,7 @@ Item {
|
||||
property string iconSource: "qrc:/qml/ScreenPlayApp/assets/icons/icon_volume.svg"
|
||||
property alias slider: slider
|
||||
|
||||
height: 70
|
||||
height: 80
|
||||
|
||||
Text {
|
||||
id: txtHeadline
|
||||
@ -40,7 +40,7 @@ Item {
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
Image {
|
||||
ColorImage {
|
||||
id: imgIcon
|
||||
|
||||
width: 20
|
||||
|
Loading…
Reference in New Issue
Block a user