diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerFooter.qml b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerFooter.qml index d7725b250e..e1d9396e04 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerFooter.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerFooter.qml @@ -18,8 +18,25 @@ Rectangle { property var background: Rectangle { anchors.fill: parent color: "#404040" - // TODO Use a shadow instead / border is just here for element debug purposes - border.width: 2; + + Rectangle { + id: topBorder1 + + anchors.top: parent.top + + color: "#252525" + height: 1 + width: parent.width + } + Rectangle { + id: topBorder2 + + anchors.top: topBorder1.bottom + + color: "#575757" + height: 1 + width: parent.width + } } } \ No newline at end of file diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml index 5f84452cc1..669748e7c9 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml @@ -8,11 +8,14 @@ import QtQuick.Controls 2.2 as Original import "../../controlsUit" 1.0 as HifiControls import "../../stylesUit" 1.0 + Item { id: root HifiConstants { id: hifi } + Style { id: style } + property int colorScheme; property var uploader: undefined; @@ -21,6 +24,7 @@ Item { anchors.margins: 10 property var footer: Item { + id: uploadFooter anchors.fill: parent anchors.rightMargin: 17 HifiControls.Button { @@ -91,7 +95,6 @@ Item { }; popup.open(); - //popup.forceActiveFocus(); } function showConfirmCreateNewPopup(confirmCallback) { @@ -102,30 +105,40 @@ Item { popup.button1text = 'CANCEL'; popup.button2text = 'CONFIRM'; - popup.onButton1Clicked = function() { popup.close() }; + popup.onButton1Clicked = function() { + popup.close() + }; popup.onButton2Clicked = function() { popup.close(); uploadNew(); }; popup.open(); - //popup.forceActiveFocus(); } - RalewaySemiBold { - id: avatarFBXNameLabel - size: 14 + RalewayRegular { + id: infoMessage + + color: 'white' + size: 20 + anchors.left: parent.left + anchors.right: parent.right anchors.top: parent.top - anchors.topMargin: 25 - anchors.bottomMargin: 25 - text: qsTr("FBX file here") + + anchors.bottomMargin: 24 + + wrapMode: Text.Wrap + + text: "Click \"Update\" to overwrite the hosted files and update the avatar in your inventory. You will have to “Wear” the avatar again to see changes." } HifiControls.Button { id: openFolderButton + + visible: false width: parent.width - anchors.top: avatarFBXNameLabel.bottom + anchors.top: infoMessage.bottom anchors.topMargin: 10 text: qsTr("Open Project Folder") colorScheme: root.colorScheme @@ -140,7 +153,8 @@ Item { visible: false - color: "white" + color: "#6A6A6A" + anchors.top: openFolderButton.bottom anchors.left: parent.left anchors.right: parent.right @@ -155,27 +169,39 @@ Item { model: AvatarPackagerCore.currentAvatarProject === null ? [] : AvatarPackagerCore.currentAvatarProject.projectFiles delegate: Rectangle { width: parent.width - height: fileText.implicitHeight + 10 - color: (index % 2 == 0) ? "white" : "grey" - Text { + height: fileText.implicitHeight + 8 + color: (index % 2 == 0) ? "#6A6A6A" : "grey" + RalewaySemiBold { id: fileText - anchors.top: parent.top + 5 - anchors.left: parent.left + 5 + size: 16 + elide: Text.ElideLeft + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 16 + anchors.rightMargin: 16 + anchors.topMargin: 4 + width: parent.width - 10 + color: "white" text: modelData } } } } - Text { + RalewayRegular { id: showFilesText + color: 'white' + linkColor: style.colors.blueHighlight + visible: AvatarPackagerCore.currentAvatarProject !== null anchors.bottom: loginRequiredMessage.top anchors.bottomMargin: 10 - font.pointSize: 12 + size: 20 + text: AvatarPackagerCore.currentAvatarProject.projectFiles.length + " files in the project. " + (fileList.visible ? "Hide" : "Show") + " list" onLinkActivated: fileList.visible = !fileList.visible @@ -214,19 +240,20 @@ Item { width: implicitWidth - font.pointSize: 20 + size: 48 text: "+" color: "black" } - Text { + RalewayRegular { id: loginWarningText anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 16 anchors.left: loginWarningGlyph.right anchors.right: parent.right text: "Please login to upload your avatar to High Fidelity hosting." - font.pointSize: 12 + size: 18 wrapMode: Text.Wrap } } diff --git a/interface/resources/qml/hifi/avatarPackager/Style.qml b/interface/resources/qml/hifi/avatarPackager/Style.qml new file mode 100644 index 0000000000..a1dcc8f0c1 --- /dev/null +++ b/interface/resources/qml/hifi/avatarPackager/Style.qml @@ -0,0 +1,20 @@ +import QtQuick 2.5 +import QtQuick.Window 2.2 + +import "../../stylesUit" 1.0 + +QtObject { + readonly property QtObject colors: QtObject { + readonly property color lightGrayBackground: "#f2f2f2" + readonly property color black: "#000000" + readonly property color white: "#ffffff" + readonly property color blueHighlight: "#00b4ef" + readonly property color inputFieldBackground: "#d4d4d4" + readonly property color yellowishOrange: "#ffb017" + readonly property color blueAccent: "#0093c5" + readonly property color greenHighlight: "#1fc6a6" + readonly property color lightGray: "#afafaf" + readonly property color redHighlight: "#ea4c5f" + readonly property color orangeAccent: "#ff6309" + } +} diff --git a/interface/src/avatar/AvatarProject.cpp b/interface/src/avatar/AvatarProject.cpp index 901c0621fb..2a2ec7c1cb 100644 --- a/interface/src/avatar/AvatarProject.cpp +++ b/interface/src/avatar/AvatarProject.cpp @@ -162,7 +162,7 @@ void AvatarProject::appendDirectory(QString prefix, QDir dir) { for (auto& entry : dir.entryInfoList({}, flags)) { if (entry.isFile()) { //_projectFiles.append(prefix + "/" + entry.fileName()); - _projectFiles.append(entry.absoluteFilePath()); + _projectFiles.append({ entry.absoluteFilePath(), prefix + "/" + entry.fileName() }); } else if (entry.isDir()) { appendDirectory(prefix + dir.dirName() + "/", entry.absoluteFilePath()); } @@ -174,13 +174,25 @@ void AvatarProject::refreshProjectFiles() { appendDirectory("", _directory); } +QStringList AvatarProject::getProjectFiles() const { + QStringList paths; + for (auto& path : _projectFiles) { + paths.append(path.relativePath); + } + return paths; +} + MarketplaceItemUploader* AvatarProject::upload(bool updateExisting) { QUuid itemID; if (updateExisting) { itemID = _fst->getMarketplaceID(); } + QStringList projectFilePaths; + for (auto& path : _projectFiles) { + projectFilePaths.append(path.absolutePath); + } auto uploader = new MarketplaceItemUploader(getProjectName(), "Empty description", QFileInfo(getFSTPath()).fileName(), itemID, - _projectFiles); + projectFilePaths); connect(uploader, &MarketplaceItemUploader::completed, this, [this, uploader]() { if (uploader->getError() == MarketplaceItemUploader::Error::None) { _fst->setMarketplaceID(uploader->getMarketplaceID()); diff --git a/interface/src/avatar/AvatarProject.h b/interface/src/avatar/AvatarProject.h index 3b4a4b74f9..d5cd7762a1 100644 --- a/interface/src/avatar/AvatarProject.h +++ b/interface/src/avatar/AvatarProject.h @@ -14,6 +14,7 @@ #define hifi_AvatarProject_h #include "MarketplaceItemUploader.h" +#include "ProjectFile.h" #include "FST.h" #include @@ -38,14 +39,16 @@ class AvatarProject : public QObject { public: Q_INVOKABLE MarketplaceItemUploader* upload(bool updateExisting); Q_INVOKABLE void openInInventory(); - Q_INVOKABLE QStringList getProjectFiles() const { return _projectFiles; } + Q_INVOKABLE QStringList getProjectFiles() const; /** * returns the AvatarProject or a nullptr on failure. */ static AvatarProject* openAvatarProject(const QString& path); - static AvatarProject* createAvatarProject(const QString& projectsFolder, const QString& avatarProjectName, - const QString& avatarModelPath, const QString& textureFolder); + static AvatarProject* createAvatarProject(const QString& projectsFolder, + const QString& avatarProjectName, + const QString& avatarModelPath, + const QString& textureFolder); static bool isValidNewProjectName(const QString& projectName); @@ -53,13 +56,14 @@ public: return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/High Fidelity Projects"; } +signals: + void projectFilesChanged(); + private: AvatarProject(const QString& fstPath, const QByteArray& data); AvatarProject(FST* fst); - ~AvatarProject() { - _fst->deleteLater(); - } + ~AvatarProject() { _fst->deleteLater(); } Q_INVOKABLE QString getProjectName() const { return _fst->getName(); } Q_INVOKABLE QString getProjectPath() const { return _projectPath; } @@ -75,7 +79,7 @@ private: FST* _fst; QDir _directory; - QStringList _projectFiles{}; + QList _projectFiles{}; QString _projectPath; }; diff --git a/libraries/avatars/src/ProjectFile.h b/libraries/avatars/src/ProjectFile.h new file mode 100644 index 0000000000..df92513a1b --- /dev/null +++ b/libraries/avatars/src/ProjectFile.h @@ -0,0 +1,11 @@ +#ifndef hifi_AvatarProjectFile_h +#define hifi_AvatarProjectFile_h + +class ProjectFilePath { + Q_GADGET; +public: + QString absolutePath; + QString relativePath; +}; + +#endif // hifi_AvatarProjectFile_h \ No newline at end of file