diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerApp.qml b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerApp.qml index 9d3a347a11..b4293d5eee 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerApp.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerApp.qml @@ -76,7 +76,7 @@ Item { InfoBox { id: errorPopup - property string errorMessage; + property string errorMessage boxWidth: 380 boxHeight: 293 @@ -181,16 +181,16 @@ Item { errorPopup.show("Project Folder Already Exists", "A folder with that name already exists at that location. Please choose a different project name or location."); break; case AvatarProjectStatus.ERROR_CREATE_CREATING_DIRECTORIES: - errorPopup.show("Project Folders Creation Error", "There was a problem during the creation of the Avatar Project directories. Please select a project location with write permissions."); + errorPopup.show("Project Folders Creation Error", "There was a problem creating the Avatar Project directory. Please check the project location and try again."); break; case AvatarProjectStatus.ERROR_CREATE_FIND_MODEL: - errorPopup.show("Cannot Find Model File", "There was a problem while trying to find the specified model file. Please verify if it exist at the specified location."); + errorPopup.show("Cannot Find Model File", "There was a problem while trying to find the specified model file. Please verify that it exists at the specified location."); break; case AvatarProjectStatus.ERROR_CREATE_OPEN_MODEL: - errorPopup.show("Cannot Open Model File", "There was a problem while trying to open the specified model file. Please verify if you have read permissions at the specified location."); + errorPopup.show("Cannot Open Model File", "There was a problem while trying to open the specified model file."); break; case AvatarProjectStatus.ERROR_CREATE_READ_MODEL: - errorPopup.show("Error Read Model File", "There was a problem while trying to read the specified model file. Please verify if the model file is supported by High Fidelity."); + errorPopup.show("Error Read Model File", "There was a problem while trying to read the specified model file. Please check that the file is a valid FBX file and try again."); break; case AvatarProjectStatus.ERROR_CREATE_WRITE_FST: errorPopup.show("Error Writing Project File", "There was a problem while trying to write the FST file."); @@ -202,13 +202,13 @@ Item { errorPopup.show("Project Missing", "Project folder cannot be found. Please locate the folder and copy/move it to its original location."); break; case AvatarProjectStatus.ERROR_OPEN_FIND_FST: - errorPopup.show("File Missing", "We cannot find the project file (avatar.fst) in the folder. Please locate it and move to the project folder."); + errorPopup.show("File Missing", "We cannot find the project file (.fst) in the project folder. Please locate it and move it to the project folder."); break; case AvatarProjectStatus.ERROR_OPEN_OPEN_FST: - errorPopup.show("File Read Error", "We cannot read the project file (avatar.fst). Please make sure that it is not in use by another program."); + errorPopup.show("File Read Error", "We cannot read the project file (.fst)."); break; case AvatarProjectStatus.ERROR_OPEN_FIND_MODEL: - errorPopup.show("File Missing", "We cannot find the avatar model file (.fbx) in the folder. Please locate it and move to the project folder."); + errorPopup.show("File Missing", "We cannot find the avatar model file (.fbx) in the project folder. Please locate it and move it to the project folder."); break; default: errorPopup.show("Error Message Missing", "Error message missing for status " + status); diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml index 845fdeb99f..25201bf81e 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarPackagerHeader.qml @@ -35,7 +35,6 @@ ShadowRectangle { anchors.bottom: parent.bottom anchors.left: parent.left anchors.leftMargin: 16 - anchors.verticalCenter: back.verticalCenter text: "◀" @@ -48,7 +47,6 @@ ShadowRectangle { anchors.bottom: parent.bottom anchors.left: root.backButtonVisible ? back.right : parent.left anchors.leftMargin: root.backButtonVisible ? 11 : 21 - anchors.verticalCenter: title.verticalCenter anchors.right: docs.left states: [ State { @@ -136,7 +134,6 @@ ShadowRectangle { anchors.bottom: parent.bottom anchors.right: parent.right anchors.rightMargin: 16 - anchors.verticalCenter: docs.verticalCenter text: qsTr("Docs") diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml index 59dd1ac5c9..85ef821a4a 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarProject.qml @@ -16,10 +16,10 @@ Item { Style { id: style } - property int colorScheme; - property var uploader: null; + property int colorScheme + property var uploader: null - property bool hasSuccessfullyUploaded: true; + property bool hasSuccessfullyUploaded: true visible: false anchors.fill: parent @@ -44,7 +44,7 @@ Item { HifiControls.Button { id: uploadButton - visible: !AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded + visible: AvatarPackagerCore.currentAvatarProject && !AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded enabled: Account.loggedIn anchors.verticalCenter: parent.verticalCenter @@ -62,7 +62,7 @@ Item { HifiControls.Button { id: updateButton - visible: AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded + visible: AvatarPackagerCore.currentAvatarProject && AvatarPackagerCore.currentAvatarProject.fst.hasMarketplaceID && !root.hasSuccessfullyUploaded enabled: Account.loggedIn anchors.verticalCenter: parent.verticalCenter @@ -175,9 +175,9 @@ Item { } function showConfirmUploadPopup() { - popup.titleText = 'Overwrite Avatar' + popup.titleText = 'Overwrite Avatar'; popup.bodyText = 'You have previously uploaded the avatar file from this project.' + - ' This will overwrite that avatar and you won’t be able to access the older version.' + ' This will overwrite that avatar and you won’t be able to access the older version.'; popup.button1text = 'CREATE NEW'; popup.button2text = 'OVERWRITE'; @@ -185,7 +185,7 @@ Item { popup.onButton2Clicked = function() { popup.close(); uploadUpdate(); - } + }; popup.onButton1Clicked = function() { popup.close(); showConfirmCreateNewPopup(); @@ -195,9 +195,9 @@ Item { } function showConfirmCreateNewPopup(confirmCallback) { - popup.titleText = 'Create New' + popup.titleText = 'Create New'; popup.bodyText = 'This will upload your current files with the same avatar name.' + - ' You will lose the ability to update the previously uploaded avatar. Are you sure you want to continue?' + ' You will lose the ability to update the previously uploaded avatar. Are you sure you want to continue?'; popup.button1text = 'CANCEL'; popup.button2text = 'CONFIRM'; @@ -277,7 +277,7 @@ Item { size: 20 - text: AvatarPackagerCore.currentAvatarProject.projectFiles.length + " files in project. See list" + text: AvatarPackagerCore.currentAvatarProject ? AvatarPackagerCore.currentAvatarProject.projectFiles.length + " files in project. See list" : "" onLinkActivated: fileListPopup.open() } diff --git a/interface/resources/qml/hifi/avatarPackager/AvatarProjectCard.qml b/interface/resources/qml/hifi/avatarPackager/AvatarProjectCard.qml index a758d3936a..25222c814c 100644 --- a/interface/resources/qml/hifi/avatarPackager/AvatarProjectCard.qml +++ b/interface/resources/qml/hifi/avatarPackager/AvatarProjectCard.qml @@ -21,7 +21,7 @@ Item { property color hoverBackgroundColor: "#E3E3E3" property color pressedBackgroundColor: "#6A6A6A" - signal open; + signal open state: mouseArea.pressed ? "pressed" : (mouseArea.containsMouse ? "hover" : "normal") states: [ diff --git a/interface/resources/qml/hifi/avatarPackager/RalewayButton.qml b/interface/resources/qml/hifi/avatarPackager/RalewayButton.qml index 18cce8138f..86742ddccd 100644 --- a/interface/resources/qml/hifi/avatarPackager/RalewayButton.qml +++ b/interface/resources/qml/hifi/avatarPackager/RalewayButton.qml @@ -8,13 +8,11 @@ import TabletScriptingInterface 1.0 RalewaySemiBold { id: root - anchors.fill: textItem + property color idleColor: "white" + property color hoverColor: "#AFAFAF" + property color pressedColor: "#575757" - property var idleColor: "white" - property var hoverColor: "#AFAFAF" - property var pressedColor: "#575757" - - color: clickable.hovered ? root.hoverColor : (clickable.pressed ? root.pressedColor : root.idleColor); + color: clickable.hovered ? root.hoverColor : (clickable.pressed ? root.pressedColor : root.idleColor) signal clicked() diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 87b1542648..810e21daf5 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -145,10 +145,6 @@ Menu::Menu() { assetServerAction->setEnabled(nodeList->getThisNodeCanWriteAssets()); } - // Edit > Package Avatar as .fst... - addActionToQMenuAndActionHash(editMenu, MenuOption::PackageModel, 0, - qApp, SLOT(packageModel())); - // Edit > Avatar Packager #ifndef Q_OS_ANDROID action = addActionToQMenuAndActionHash(editMenu, MenuOption::AvatarPackager); @@ -654,6 +650,8 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ShowTrackedObjects, 0, false, qApp, SLOT(setShowTrackedObjects(bool))); + addActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::PackageModel, 0, qApp, SLOT(packageModel())); + // Developer > Hands >>> MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false, diff --git a/interface/src/avatar/AvatarPackager.cpp b/interface/src/avatar/AvatarPackager.cpp index 941aff6943..fa70eee374 100644 --- a/interface/src/avatar/AvatarPackager.cpp +++ b/interface/src/avatar/AvatarPackager.cpp @@ -95,7 +95,7 @@ void AvatarPackager::addCurrentProjectToRecentProjects() { emit recentProjectsChanged(); } -QVariantList AvatarPackager::recentProjectsToVariantList(bool includeProjectPaths) { +QVariantList AvatarPackager::recentProjectsToVariantList(bool includeProjectPaths) const { QVariantList result; for (const auto& project : _recentProjects) { QVariantMap projectVariant; diff --git a/interface/src/avatar/AvatarPackager.h b/interface/src/avatar/AvatarPackager.h index c9c5b9d312..4416ec5806 100644 --- a/interface/src/avatar/AvatarPackager.h +++ b/interface/src/avatar/AvatarPackager.h @@ -69,7 +69,9 @@ public: const QString& textureFolder); Q_INVOKABLE AvatarProjectStatus::AvatarProjectStatus openAvatarProject(const QString& avatarProjectFSTPath); - Q_INVOKABLE bool isValidNewProjectName(const QString& projectPath, const QString& projectName) { return AvatarProject::isValidNewProjectName(projectPath, projectName); } + Q_INVOKABLE bool isValidNewProjectName(const QString& projectPath, const QString& projectName) { + return AvatarProject::isValidNewProjectName(projectPath, projectName); + } signals: void avatarProjectChanged(); @@ -78,21 +80,21 @@ signals: private: Q_INVOKABLE AvatarProject* getAvatarProject() const { return _currentAvatarProject; }; Q_INVOKABLE QString getAvatarProjectsPath() const { return AvatarProject::getDefaultProjectsPath(); } - Q_INVOKABLE QVariantList getRecentProjects() { return recentProjectsToVariantList(true); } + Q_INVOKABLE QVariantList getRecentProjects() const { return recentProjectsToVariantList(true); } void setAvatarProject(AvatarProject* avatarProject); void addCurrentProjectToRecentProjects(); - AvatarProject* _currentAvatarProject{ nullptr }; + AvatarProject* _currentAvatarProject { nullptr }; QVector _recentProjects; - QVariantList recentProjectsToVariantList(bool includeProjectPaths); + QVariantList recentProjectsToVariantList(bool includeProjectPaths) const; void recentProjectsFromVariantList(QVariantList projectsVariant); - Setting::Handle _recentProjectsSetting{ "io.highfidelity.avatarPackager.recentProjects", QVariantList() }; + Setting::Handle _recentProjectsSetting { "io.highfidelity.avatarPackager.recentProjects", QVariantList() }; }; #endif // hifi_AvatarPackager_h diff --git a/interface/src/avatar/AvatarProject.cpp b/interface/src/avatar/AvatarProject.cpp index 20556ce5ed..728917e673 100644 --- a/interface/src/avatar/AvatarProject.cpp +++ b/interface/src/avatar/AvatarProject.cpp @@ -169,8 +169,8 @@ QStringList AvatarProject::getScriptPaths(const QDir& scriptsDir) const { return result; } - for (auto& script : scriptsDir.entryInfoList({}, flags)) { - if (script.fileName().endsWith(".js")) { + for (const auto& script : scriptsDir.entryInfoList({}, flags)) { + if (script.fileName().toLower().endsWith(".js")) { result.push_back("scripts/" + script.fileName()); } } @@ -243,7 +243,7 @@ MarketplaceItemUploader* AvatarProject::upload(bool updateExisting) { return uploader; } -void AvatarProject::openInInventory() { +void AvatarProject::openInInventory() const { constexpr int TIME_TO_WAIT_FOR_INVENTORY_TO_OPEN_MS { 1000 }; auto tablet = dynamic_cast( @@ -256,6 +256,5 @@ void AvatarProject::openInInventory() { // I'm not a fan of this, but it's the only current option. QTimer::singleShot(TIME_TO_WAIT_FOR_INVENTORY_TO_OPEN_MS, [name, tablet]() { tablet->sendToQml(QVariantMap({ { "method", "updatePurchases" }, { "filterText", name } })); - }); } diff --git a/interface/src/avatar/AvatarProject.h b/interface/src/avatar/AvatarProject.h index 2a655409e1..1710282a3e 100644 --- a/interface/src/avatar/AvatarProject.h +++ b/interface/src/avatar/AvatarProject.h @@ -56,7 +56,7 @@ class AvatarProject : public QObject { public: Q_INVOKABLE MarketplaceItemUploader* upload(bool updateExisting); - Q_INVOKABLE void openInInventory(); + Q_INVOKABLE void openInInventory() const; Q_INVOKABLE QStringList getProjectFiles() const; Q_INVOKABLE QString getProjectName() const { return _fst->getName(); }