diff --git a/qml/Components/Create.qml b/qml/Components/Create.qml index de008b2e..40072669 100644 --- a/qml/Components/Create.qml +++ b/qml/Components/Create.qml @@ -1,7 +1,6 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Dialogs 1.2 - import Qt.labs.platform 1.0 CustomPage { @@ -31,92 +30,13 @@ CustomPage { source: "qrc:/assets/fonts/LibreBaskerville-Italic.ttf" } - Item { + CreateLeftArea { id: leftArea width: parent.width * .5 anchors { top: parent.top - bottom: parent.bottom left: parent.left - } - Column { - id: column - anchors.fill: parent - anchors.margins: 30 - spacing: 30 - - TextField { - id: txtTitle - width: parent.width - height: 60 - text: qsTr("") - placeholderText: "Title" - } - TextField { - id: txtDescription - width: parent.width - height: 60 - text: qsTr("") - placeholderText: "Description" - } - TextField { - id: txtTags - width: parent.width - height: 60 - text: qsTr("") - placeholderText: "Tags" - } - TextField { - id: txtYouTube - width: parent.width - height: 60 - text: qsTr("") - placeholderText: "YouTube Preview" - } - - Row { - id: rowVisible - width: parent.width - height: 50 - Text { - id: txtVisibleDescription - height: parent.height - text: qsTr("Visible") - font.pixelSize: 12 - verticalAlignment: Text.AlignVCenter - } - - ComboBox { - id: cbVisibility - model: ["Public", "Friends only", "Private"] - } - - spacing: 30 - } - - Button { - id: btnSubmit - text: qsTr("Create New Wallpaper") - onClicked: { - //TODO wait for callback - steamWorkshop.createWorkshopItem() - - steamWorkshop.submitWorkshopItem( - txtTitle.text.toString(), - txtDescription.text.toString(), "english", - cbVisibility.currentIndex, - fileDialogOpenVideo.currentFile, - fileDialogOpenPreview.currentFile) - tiItemUpdate.start() - } - } - } - CheckDelegate { - id: checkDelegate - opacity: 0 - text: qsTr("By submitting this item, you agree to the workshop terms of service") - onCheckedChanged: Qt.openUrlExternally( - "http://steamcommunity.com/sharedfiles/workshoplegalagreement") + margins: 10 } } @@ -142,8 +62,8 @@ CustomPage { height: parent.height FileDropperSingleFile { anchors.fill: parent - z:99 - descriptionTitle: "Set Video" + z: 99 + descriptionTitle: "Drop your video here" isVideo: true imagePath: "qrc:/assets/icons/icon_tv.svg" } @@ -155,7 +75,7 @@ CustomPage { FileDropperSingleFile { anchors.fill: parent - z:99 + z: 99 descriptionTitle: "Set Preview Image" imagePath: "qrc:/assets/icons/icon_single_image.svg" } @@ -172,7 +92,7 @@ CustomPage { } FileDropperSingleFile { anchors.fill: parent - z:99 + z: 99 descriptionTitle: "Add additional images" imagePath: "qrc:/assets/icons/icon_multiple_images.svg" } @@ -181,7 +101,7 @@ CustomPage { Timer { id: tiItemUpdate - interval: 500 + interval: 100 running: false repeat: true onTriggered: { diff --git a/qml/Components/CreateLeftArea.qml b/qml/Components/CreateLeftArea.qml new file mode 100644 index 00000000..0684dfe3 --- /dev/null +++ b/qml/Components/CreateLeftArea.qml @@ -0,0 +1,213 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtQuick.Dialogs 1.2 + +import Qt.labs.platform 1.0 + +Rectangle { + id: leftArea + radius: 3 + height: column.childrenRect.height + (6 * 30) + state: "workshop" + property int steamWorkshopHeight + + Row { + id: rowUseSteamWorkshop + height: 40 + anchors { + top: parent.top + right: parent.right + left: parent.left + margins: 30 + } + + Switch { + id: switchUseSteamWorkshop + checked: true + onCheckedChanged: { + if (switchUseSteamWorkshop.checked) { + leftArea.state = "workshop" + } else { + leftArea.state = "local" + } + } + } + Text { + id: txtUseSteamWorkshop + text: qsTr("Upload Wallpaper to Steam Workshop") + anchors.bottom: parent.bottom + anchors.bottomMargin: 0 + anchors.top: parent.top + anchors.topMargin: 0 + verticalAlignment: Text.AlignVCenter + font.pointSize: 12 + renderType: Text.NativeRendering + font.family: font_Roboto_Regular.name + } + } + + Column { + id: column + anchors { + top: rowUseSteamWorkshop.bottom + right: parent.right + left: parent.left + margins: 30 + } + spacing: 30 + + TextField { + id: txtTitle + width: parent.width + height: 60 + text: qsTr("") + placeholderText: "Title" + } + + Column { + spacing: 30 + id: useSteamWorkshopFieldsWrapper + height: 300 + anchors { + right: parent.right + left: parent.left + } + + TextField { + id: txtDescription + width: parent.width + height: 60 + text: qsTr("") + placeholderText: "Description" + } + + TextField { + id: txtTags + width: parent.width + height: 60 + text: qsTr("") + placeholderText: "Tags" + } + TextField { + id: txtYouTube + width: parent.width + height: 60 + text: qsTr("") + placeholderText: "YouTube Preview" + } + + Row { + id: rowVisible + width: parent.width + height: 50 + Text { + id: txtVisibleDescription + height: parent.height + text: qsTr("Visible") + font.pixelSize: 12 + verticalAlignment: Text.AlignVCenter + } + + ComboBox { + id: cbVisibility + model: ["Public", "Friends only", "Private"] + } + + spacing: 30 + } + } + + Button { + id: btnSubmit + text: qsTr("Create New Workshop Wallpaper") + onClicked: { + if (switchUseSteamWorkshop) { + //TODO wait for callback + steamWorkshop.createWorkshopItem() + + steamWorkshop.submitWorkshopItem( + txtTitle.text.toString(), + txtDescription.text.toString(), "english", + cbVisibility.currentIndex, + fileDialogOpenVideo.currentFile, + fileDialogOpenPreview.currentFile) + tiItemUpdate.start() + } else { + steamWorkshop.createLocalWorkshopItem( + txtTitle.text.toString(), + fileDialogOpenVideo.currentFile, + fileDialogOpenPreview.currentFile) + } + } + } + CheckDelegate { + id: checkDelegate + opacity: 0 + visible: false + text: qsTr("By submitting this item, you agree to the workshop terms of service") + onCheckedChanged: { + if (checkDelegate.visible) { + Qt.openUrlExternally( + "http://steamcommunity.com/sharedfiles/workshoplegalagreement") + } + } + } + } + + states: [ + State { + name: "local" + PropertyChanges { + target: useSteamWorkshopFieldsWrapper + visible: false + height: 0 + } + PropertyChanges { + target: txtUseSteamWorkshop + color: "black" + } + PropertyChanges { + target: btnSubmit + text: qsTr("Create Local Wallpaper") + } + }, + State { + name: "workshop" + PropertyChanges { + target: useSteamWorkshopFieldsWrapper + visible: true + height: 200 + } + PropertyChanges { + target: txtUseSteamWorkshop + color: "orange" + } + PropertyChanges { + target: btnSubmit + text: qsTr("Upload Wallpaper to Steam Workshop") + } + } + ] + transitions: [ + Transition { + from: "local" + to: "workshop" + + PropertyAnimation { + property: "height" + duration: 300 + easing.type: Easing.InOutQuad + } + }, + Transition { + from: "workshop" + to: "local" + + PropertyAnimation { + property: "height" + duration: 200 + easing.type: Easing.InOutQuad + } + } + ] +} diff --git a/qml/Components/CreateVideoPreviewSmall.qml b/qml/Components/CreateVideoPreviewSmall.qml new file mode 100644 index 00000000..27a9539a --- /dev/null +++ b/qml/Components/CreateVideoPreviewSmall.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 +import QtAV 1.07 + +Rectangle { + id: createVideoPreviewSmall + property url source + + + Video { + id: previewVideo + anchors.fill: parent + z: 99 + source: createVideoPreviewSmall.source + onSourceChanged: { + print(previewVideo.error + previewVideo.errorString + previewVideo.source) + //previewVideo.source = createVideoPreviewSmall.source; + previewVideo.play() + } + onPlaying: { + print("playing") + } + + + onErrorChanged: { + print(previewVideo.error + previewVideo.errorString) + } + + //videoCodecPriority: ["CUDA", "D3D11", "DXVA", "VAAPI", "FFmpeg"] + } +} diff --git a/qml/Components/FileDropperSingleFile.qml b/qml/Components/FileDropperSingleFile.qml index fb388679..6fdf046e 100644 --- a/qml/Components/FileDropperSingleFile.qml +++ b/qml/Components/FileDropperSingleFile.qml @@ -1,6 +1,7 @@ -import QtQuick 2.7 +import QtQuick 2.9 import QtQuick.Dialogs 1.2 + Rectangle { property color background: "white" @@ -8,6 +9,7 @@ Rectangle { property url imagePath: "qrc:/assets/icons/icon_plus.svg" //FIXME in 5.10 with an enum property bool isVideo: false + property url externalFilePath id: fileDropperSingleFile color: fileDropperSingleFile.background @@ -16,6 +18,24 @@ Rectangle { radius: 4 state: "" + Component.onCompleted: { + if (isVideo) { + + } else { + + } + } + + Image { + id: previewImage + anchors.fill: parent + z: 98 + visible: false + } + + + + FontLoader { id: font_LibreBaskerville source: "qrc:/assets/fonts/LibreBaskerville-Italic.ttf" @@ -23,10 +43,10 @@ Rectangle { Item { id: column - height:imageIcon.height + txtSplashInput.contentHeight + height: imageIcon.height + txtSplashInput.contentHeight anchors { - right:parent.right - left:parent.left + right: parent.right + left: parent.left verticalCenter: parent.verticalCenter } @@ -38,7 +58,7 @@ Rectangle { sourceSize.width: 32 source: fileDropperSingleFile.imagePath anchors { - top:parent.top + top: parent.top horizontalCenter: parent.horizontalCenter } } @@ -46,11 +66,11 @@ Rectangle { id: txtSplashInput text: descriptionTitle anchors { - top:imageIcon.bottom + top: imageIcon.bottom topMargin: 10 horizontalCenter: parent.horizontalCenter } - height:40 + height: 40 font.pointSize: 12 color: "#626262" horizontalAlignment: Text.AlignHCenter @@ -58,21 +78,54 @@ Rectangle { font.italic: true renderType: Text.NativeRendering } - } DropArea { + id: dropper anchors.fill: parent onEntered: { fileDropperSingleFile.state = "fileEntered" } + onDropped: { fileDropperSingleFile.state = "fileDropped" + if (drop.hasUrls) { + if (isVideo) { + if (validateVideoFileExtension(drop.urls[0])) { + videoPreviewLoader.setSource("CreateVideoPreviewSmall.qml",{"source":drop.urls[0]}) + + } + } else { + if (validateImageFileExtension(drop.urls[0])) { + previewImage.source = drop.urls[0] + previewImage.visible = true + } + } + } } onExited: { fileDropperSingleFile.state = "empty" } + function validateImageFileExtension(filePath) { + var tmp = filePath.split('.').pop() + return tmp === "png" || tmp === "jpg" + } + + function validateVideoFileExtension(filePath) { + var tmp = filePath.split('.').pop() + return tmp === "vp9" || tmp === "mp4" + } + } + Loader { + id:videoPreviewLoader + asynchronous: true + anchors.fill: parent + z: 97 + onLoaded: { + //videoPreviewLoader.item.playVideo(drop.urls[0]); + } + } /* FIXME: For now only drag n drop Workshop @@ -99,7 +152,6 @@ Rectangle { } }*/ - states: [ State { name: "fileEntered" @@ -116,7 +168,6 @@ Rectangle { target: fileDropperSingleFile color: "#ffbf49" } - }, State { name: "empty" diff --git a/qml/Components/Workshop.qml b/qml/Components/Workshop.qml index 958ec0fb..9a64022c 100644 --- a/qml/Components/Workshop.qml +++ b/qml/Components/Workshop.qml @@ -9,91 +9,80 @@ CustomPage { steamWorkshop.searchWorkshop() } - Connections{ - target: steamWorkshop - onWorkshopSearched:{ - busyIndicator.running = false - txtBusyIndicator.visible = false - bannerTxt.text = workshopListModel.getBannerText() - bannerImg.source = workshopListModel.getBannerUrl(); - } + Flickable { + anchors.fill: parent + flickableDirection: Flickable.VerticalFlick - } - BusyIndicator { - id: busyIndicator - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - running: true - Material.accent: Material.Orange - } - - Text { - id: txtBusyIndicator - text: qsTr("Searching for workshop content. Please stand by") - anchors.top: busyIndicator.bottom - anchors.topMargin: 30 - anchors.horizontalCenter: parent.horizontalCenter - } - - Rectangle { - id: banner - color: "#131313" - height: 250 - anchors { - top: parent.top - right: parent.right - left:parent.left - } - Image { - id: bannerImg - anchors.fill: parent - fillMode: Image.PreserveAspectCrop - - } - - Text { - id: bannerTxt - text: "loading" - font.pixelSize: 36 - color: "white" - } - } - - Item { - id: searchBar - height:70 - anchors { - top: banner.bottom - right: parent.right - left:parent.left - } - } - - Item { - anchors { - top: searchBar.bottom - right: parent.right - bottom: parent.bottom - left:parent.left - } GridView { id: gridView - boundsBehavior: Flickable.DragOverBounds cacheBuffer: 1000 - maximumFlickVelocity: 10000 + maximumFlickVelocity: 5000 anchors.fill: parent cellWidth: 330 cellHeight: 200 - anchors.margins: 30 - model: workshopListModel - delegate: Rectangle { + + boundsBehavior: Flickable.StopAtBounds + //boundsBehavior: Flickable.OvershootBounds + header: Item { + height: 500 + anchors { + right: parent.right + left: parent.left + } + Connections { + target: steamWorkshop + onWorkshopSearched: { + bannerTxt.text = workshopListModel.getBannerText() + bannerImg.source = workshopListModel.getBannerUrl() + } + } + + Rectangle { + id: banner + color: "#131313" + height: 350 + anchors { + top: parent.top + right: parent.right + left: parent.left + } + Image { + id: bannerImg + anchors.fill: parent + asynchronous: true + fillMode: Image.PreserveAspectCrop + } + + Text { + id: bannerTxt + text: "loading" + font.pixelSize: 36 + color: "white" + } + } + + Item { + id: searchBar + height: 70 + anchors { + top: banner.bottom + right: parent.right + left: parent.left + } + } + } + + model: workshopListModel + + delegate: Rectangle { color: "steelblue" - id:delegate + id: delegate width: 180 - height:100 + height: 100 focus: true + Image { id: img anchors.fill: parent @@ -106,18 +95,18 @@ CustomPage { id: namea anchors.fill: parent text: workshopTitle - color:"white" + color: "white" } - - } add: Transition { - NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 } + NumberAnimation { + property: "opacity" + from: 0 + to: 1.0 + duration: 400 + } } } } - - - } diff --git a/qml/main.qml b/qml/main.qml index 5c91394f..536487a3 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -13,7 +13,6 @@ ApplicationWindow { minimumHeight: 768 minimumWidth: 1050 - Component.onCompleted: { setX(Screen.width / 2 - width / 2); setY(Screen.height / 2 - height / 2); diff --git a/qtquickcontrols2.conf b/qtquickcontrols2.conf index 0c8980f8..910ccede 100644 --- a/qtquickcontrols2.conf +++ b/qtquickcontrols2.conf @@ -11,5 +11,5 @@ Theme=Light [Material] Theme=Light -;Accent=BlueGrey -;Primary=BlueGray +Accent=Orange +Primary=Orange diff --git a/src/installedlistmodel.cpp b/src/installedlistmodel.cpp index 62072440..331b2e0e 100644 --- a/src/installedlistmodel.cpp +++ b/src/installedlistmodel.cpp @@ -75,7 +75,6 @@ void InstalledListModel::loadScreens() for (auto&& item : list) { tmpPath = m_absoluteStoragePath.toString() +"/" +item.baseName() + "/project.json"; - qDebug() << tmpPath; if (!QFile(tmpPath).exists()) continue; diff --git a/src/monitorlistmodel.cpp b/src/monitorlistmodel.cpp index 39304cac..b775fdc9 100644 --- a/src/monitorlistmodel.cpp +++ b/src/monitorlistmodel.cpp @@ -20,8 +20,6 @@ QHash MonitorListModel::roleNames() const QRect MonitorListModel::getAbsoluteDesktopSize() { -// qDebug() << _monitorList.at(0)._availableVirtualGeometry; -// qDebug() << _monitorList.at(0)._availableGeometry; return _monitorList.at(0)._availableVirtualGeometry; } @@ -145,7 +143,6 @@ Monitor::Monitor(QString manufacturer, QString model, QString name, QSize size, _availableGeometry = availableGeometry; _availableVirtualGeometry = availableVirtualGeometry; - //qDebug() << _availableGeometry << " " << availableVirtualGeometry; _number = number; // FIXME: Use a better way to create an id // because name and manufacturer are allways empty diff --git a/src/profile.h b/src/profile.h index c23dec27..54462ea9 100644 --- a/src/profile.h +++ b/src/profile.h @@ -10,6 +10,7 @@ public: Profile(); Profile(QUrl absolutePath, QString id, QString version, QString wallpaperId, QRect rect, bool isLooping); + QUrl m_absolutePath; QString m_id; QString m_version = ""; diff --git a/src/settings.cpp b/src/settings.cpp index 2b1b70f8..e3819275 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -67,8 +67,6 @@ Settings::Settings(ProfileListModel* plm, MonitorListModel* mlm, InstalledListMo steamTmpUrl.cd("content"); steamTmpUrl.cd("672870"); - qDebug() << steamTmpUrl.path(); - m_absoluteStoragePath = steamTmpUrl.path(); } else { m_absoluteStoragePath = configObj.value("absoluteStoragePath").toString(); diff --git a/src/steamworkshop.cpp b/src/steamworkshop.cpp index c510f4fb..f009ca05 100644 --- a/src/steamworkshop.cpp +++ b/src/steamworkshop.cpp @@ -24,7 +24,6 @@ void SteamWorkshop::submitWorkshopItem(QString title, QString description, QStri QString video = QString(tmpVideoPath).remove(0, 8); QString thumb = QString(absolutePreviewPath.toString()).remove(0, 8); - qDebug() << video << thumb; SteamUGC()->SetItemTitle(m_UGCUpdateHandle, QByteArray(title.toLatin1()).data()); SteamUGC()->SetItemDescription(m_UGCUpdateHandle, QByteArray(description.toLatin1()).data()); SteamUGC()->SetItemUpdateLanguage(m_UGCUpdateHandle, QByteArray(language.toLatin1()).data()); @@ -49,6 +48,11 @@ void SteamWorkshop::getAPICallInfo() qDebug() << SteamUtils()->GetAPICallFailureReason(m_searchCall); } +void SteamWorkshop::createLocalWorkshopItem(QString title, QUrl videoPath, QUrl previewPath) +{ + +} + void SteamWorkshop::onWorkshopItemCreated(CreateItemResult_t* pCallback, bool bIOFailure) { if (bIOFailure) @@ -65,7 +69,7 @@ void SteamWorkshop::searchWorkshop() m_AppId, m_AppId, 1); - + SteamUGC()->SetAllowCachedResponse(m_UGCSearchHandle, 3000); //Important: First send the request to get the Steam API Call // then set the handler m_searchCall = SteamUGC()->SendQueryUGCRequest(m_UGCSearchHandle);