From aad0be269380c161fa2872ce163ccb0ec5a96aa6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 29 Aug 2017 17:28:06 -0700 Subject: [PATCH 1/6] Set baking enabled mappings --- assignment-client/src/assets/AssetServer.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index f7a8ecf453..c5f52b4a82 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -1224,9 +1224,11 @@ bool AssetServer::setBakingEnabled(const AssetPathList& paths, bool enabled) { auto bakedMapping = getBakeMapping(hash, bakedFilename); if (enabled) { - // TODO - } else { - // TODO + removeBakedPathsForDeletedAsset(hash); + setMapping(bakedMapping, hash); + } else if (_fileMappings.value(bakedMapping) == hash) { + deleteMappings({ bakedMapping }); + maybeBake(path, hash); } } } From a9cfc01df36a25e45f3f9c0f943179955c65d7ab Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 31 Aug 2017 09:49:46 -0700 Subject: [PATCH 2/6] Set Baking Enabled API --- assignment-client/src/assets/AssetServer.cpp | 17 +++++++----- interface/resources/qml/AssetServer.qml | 13 +++++++++- .../AssetMappingsScriptingInterface.cpp | 26 ++++++++++++++++--- .../AssetMappingsScriptingInterface.h | 3 ++- libraries/networking/src/AssetUtils.cpp | 1 - libraries/networking/src/AssetUtils.h | 2 +- 6 files changed, 48 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index c5f52b4a82..a044ea172b 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -124,7 +124,7 @@ BakingStatus AssetServer::getAssetStatus(const AssetPath& path, const AssetHash& auto dotIndex = path.lastIndexOf("."); if (dotIndex == -1) { - return Unrelevant; + return Irrelevant; } auto extension = path.mid(dotIndex + 1); @@ -136,7 +136,7 @@ BakingStatus AssetServer::getAssetStatus(const AssetPath& path, const AssetHash& } else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) { bakedFilename = BAKED_TEXTURE_SIMPLE_NAME; } else { - return Unrelevant; + return Irrelevant; } auto bakedPath = HIDDEN_BAKED_CONTENT_FOLDER + hash + "/" + bakedFilename; @@ -1223,12 +1223,17 @@ bool AssetServer::setBakingEnabled(const AssetPathList& paths, bool enabled) { auto bakedMapping = getBakeMapping(hash, bakedFilename); - if (enabled) { + bool currentlyDisabled = (_fileMappings.value(bakedMapping) == hash); + + if (enabled && currentlyDisabled) { + QStringList bakedMappings{ bakedMapping }; + deleteMappings(bakedMappings); + maybeBake(path, hash); + qDebug() << "Enabled baking for" << path; + } else if (!enabled && !currentlyDisabled) { removeBakedPathsForDeletedAsset(hash); setMapping(bakedMapping, hash); - } else if (_fileMappings.value(bakedMapping) == hash) { - deleteMappings({ bakedMapping }); - maybeBake(path, hash); + qDebug() << "Disabled baking for" << path; } } } diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index a34de72270..294ad1a36c 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -606,7 +606,18 @@ ScrollingWindow { HifiControls.CheckBox { text: "Use baked (optimized) versions" colorScheme: root.colorScheme - enabled: selectedItems > 0 + enabled: selectedItems === 1 && assetProxyModel.data(treeView.selection.currentIndex, 0x105) !== "--" + checked: selectedItems === 1 && assetProxyModel.data(treeView.selection.currentIndex, 0x105) === "Baked"; + onClicked: { + var mappings = []; + for (var i in treeView.selection.selectedIndexes) { + var index = treeView.selection.selectedIndexes[i]; + var path = assetProxyModel.data(index, 0x100); + mappings.push(path); + } + print("Setting baking enabled:" + mappings + checked); + Assets.setBakingEnabled(mappings, checked); + } } } diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index f2929501ab..076a9f5ada 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -161,7 +161,23 @@ void AssetMappingsScriptingInterface::renameMapping(QString oldPath, QString new connect(request, &RenameMappingRequest::finished, this, [this, callback](RenameMappingRequest* request) mutable { if (callback.isCallable()) { - QJSValueList args { request->getErrorString() }; + QJSValueList args{ request->getErrorString() }; + callback.call(args); + } + + request->deleteLater(); + }); + + request->start(); +} + +void AssetMappingsScriptingInterface::setBakingEnabled(QStringList paths, bool enabled, QJSValue callback) { + auto assetClient = DependencyManager::get(); + auto request = assetClient->createSetBakingEnabledRequest(paths, enabled); + + connect(request, &SetBakingEnabledRequest::finished, this, [this, callback](SetBakingEnabledRequest* request) mutable { + if (callback.isCallable()) { + QJSValueList args{ request->getErrorString() }; callback.call(args); } @@ -214,18 +230,16 @@ void AssetMappingModel::refresh() { // start index at 1 to avoid empty string from leading slash for (int i = 1; i < length; ++i) { fullPath += (i == 1 ? "" : "/") + parts[i]; + bool isFolder = i < length - 1; auto it = _pathToItemMap.find(fullPath); if (it == _pathToItemMap.end()) { auto item = new QStandardItem(parts[i]); - bool isFolder = i < length - 1; - auto statusString = isFolder ? "--" : bakingStatusToString(mapping.second.status); item->setData(isFolder ? fullPath + "/" : fullPath, Qt::UserRole); item->setData(isFolder, Qt::UserRole + 1); item->setData(parts[i], Qt::UserRole + 2); item->setData("atp:" + fullPath, Qt::UserRole + 3); item->setData(fullPath, Qt::UserRole + 4); - item->setData(statusString, Qt::UserRole + 5); if (lastItem) { lastItem->appendRow(item); @@ -237,6 +251,10 @@ void AssetMappingModel::refresh() { } else { lastItem = it.value(); } + + // update status + auto statusString = isFolder ? "--" : bakingStatusToString(mapping.second.status); + lastItem->setData(statusString, Qt::UserRole + 5); } Q_ASSERT(fullPath == path); diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.h b/interface/src/scripting/AssetMappingsScriptingInterface.h index 0615c5e84d..e4059c1ff7 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.h +++ b/interface/src/scripting/AssetMappingsScriptingInterface.h @@ -66,10 +66,11 @@ public: Q_INVOKABLE void setMapping(QString path, QString hash, QJSValue callback = QJSValue()); Q_INVOKABLE void getMapping(QString path, QJSValue callback = QJSValue()); Q_INVOKABLE void uploadFile(QString path, QString mapping, QJSValue startedCallback = QJSValue(), QJSValue completedCallback = QJSValue(), bool dropEvent = false); - Q_INVOKABLE void deleteMappings(QStringList paths, QJSValue callback); + Q_INVOKABLE void deleteMappings(QStringList paths, QJSValue callback = QJSValue()); Q_INVOKABLE void deleteMapping(QString path, QJSValue callback) { deleteMappings(QStringList(path), callback = QJSValue()); } Q_INVOKABLE void getAllMappings(QJSValue callback = QJSValue()); Q_INVOKABLE void renameMapping(QString oldPath, QString newPath, QJSValue callback = QJSValue()); + Q_INVOKABLE void setBakingEnabled(QStringList paths, bool enabled, QJSValue callback = QJSValue()); protected: QSet _pendingRequests; diff --git a/libraries/networking/src/AssetUtils.cpp b/libraries/networking/src/AssetUtils.cpp index 4c26d2d633..3af0b1df47 100644 --- a/libraries/networking/src/AssetUtils.cpp +++ b/libraries/networking/src/AssetUtils.cpp @@ -97,7 +97,6 @@ QString bakingStatusToString(BakingStatus status) { return "Baked"; case Error: return "Error"; - case Unrelevant: default: return "--"; } diff --git a/libraries/networking/src/AssetUtils.h b/libraries/networking/src/AssetUtils.h index f8f0171a5d..be403e93b9 100644 --- a/libraries/networking/src/AssetUtils.h +++ b/libraries/networking/src/AssetUtils.h @@ -53,7 +53,7 @@ enum AssetMappingOperationType : uint8_t { }; enum BakingStatus { - Unrelevant, + Irrelevant, NotBaked, Pending, Baking, From cdfae714b55bb1fffdcb12d529f2a4378c12a09f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 31 Aug 2017 15:51:47 -0700 Subject: [PATCH 3/6] Remove baking tasks for hash once done --- assignment-client/src/assets/AssetServer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index a044ea172b..5b0343ca72 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -1163,6 +1163,8 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina } else { qWarning() << "Could not complete bake for" << originalAssetHash; } + + _pendingBakes.remove(originalAssetHash); } bool AssetServer::createMetaFile(AssetHash originalAssetHash) { From 2fd2bb1e92c4327b0445065b3e523e4de8db3cef Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 31 Aug 2017 16:00:55 -0700 Subject: [PATCH 4/6] Auto reload after changing baking enabled --- interface/resources/qml/AssetServer.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index 294ad1a36c..36ef3e69f8 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -616,7 +616,9 @@ ScrollingWindow { mappings.push(path); } print("Setting baking enabled:" + mappings + checked); - Assets.setBakingEnabled(mappings, checked); + Assets.setBakingEnabled(mappings, checked, function() { + reload(); + }); } } } From 9b857eb53bd2b136d9ea5f62916934540e1297b6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 31 Aug 2017 16:16:43 -0700 Subject: [PATCH 5/6] Ensure "enabled" binding stays in place --- interface/resources/qml/AssetServer.qml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index 36ef3e69f8..f4b434ae5a 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -604,10 +604,16 @@ ScrollingWindow { } HifiControls.CheckBox { + function isChecked() { + var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105); + var bakingDisabled = (status === "Not Baked" || status === "--"); + return selectedItems === 1 && !bakingDisabled; + } + text: "Use baked (optimized) versions" colorScheme: root.colorScheme enabled: selectedItems === 1 && assetProxyModel.data(treeView.selection.currentIndex, 0x105) !== "--" - checked: selectedItems === 1 && assetProxyModel.data(treeView.selection.currentIndex, 0x105) === "Baked"; + checked: isChecked() onClicked: { var mappings = []; for (var i in treeView.selection.selectedIndexes) { @@ -619,6 +625,8 @@ ScrollingWindow { Assets.setBakingEnabled(mappings, checked, function() { reload(); }); + + checked = Qt.binding(isChecked); } } } From 28402be37c7345cda5a2f3b3f1f4f9b3834fa02d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 31 Aug 2017 17:39:36 -0700 Subject: [PATCH 6/6] Fix status glyphs --- interface/resources/qml/AssetServer.qml | 126 +++++++++++++++++- interface/resources/qml/controls-uit/Tree.qml | 105 +-------------- 2 files changed, 131 insertions(+), 100 deletions(-) diff --git a/interface/resources/qml/AssetServer.qml b/interface/resources/qml/AssetServer.qml index f4b434ae5a..5e564f8626 100644 --- a/interface/resources/qml/AssetServer.qml +++ b/interface/resources/qml/AssetServer.qml @@ -10,6 +10,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 import QtQuick.Dialogs 1.2 as OriginalDialogs import Qt.labs.settings 1.0 @@ -527,7 +528,6 @@ ScrollingWindow { headerVisible: true sortIndicatorVisible: true - canEdit: true colorScheme: root.colorScheme modifyEl: renameEl @@ -542,8 +542,130 @@ ScrollingWindow { id: bakedColumn title: "Use Baked?" role: "baked" - width: 140 + width: 100 } + + itemDelegate: Loader { + id: itemDelegateLoader + + anchors { + left: parent ? parent.left : undefined + leftMargin: (styleData.column === 0 ? (2 + styleData.depth) : 1) * hifi.dimensions.tablePadding + right: parent ? parent.right : undefined + rightMargin: hifi.dimensions.tablePadding + verticalCenter: parent ? parent.verticalCenter : undefined + } + + function convertToGlyph(text) { + switch (text) { + case "Not Baked": + return hifi.glyphs.circleSlash; + case "Baked": + return hifi.glyphs.placemark; + case "Error": + return hifi.glyphs.alert; + default: + return ""; + } + } + + function getComponent() { + if ((styleData.column === 0) && styleData.selected) { + return textFieldComponent; + } else if (convertToGlyph(styleData.value) != "") { + return glyphComponent; + } else { + return labelComponent; + } + + } + sourceComponent: getComponent() + + Component { + id: labelComponent + FiraSansSemiBold { + text: styleData.value + size: hifi.fontSizes.tableText + color: colorScheme == hifi.colorSchemes.light + ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) + : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + + elide: Text.ElideRight + horizontalAlignment: styleData.column === 1 ? TextInput.AlignHCenter : TextInput.AlignLeft + } + } + Component { + id: glyphComponent + + HiFiGlyphs { + text: convertToGlyph(styleData.value) + size: hifi.dimensions.frameIconSize + color: colorScheme == hifi.colorSchemes.light + ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) + : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + + elide: Text.ElideRight + horizontalAlignment: TextInput.AlignHCenter + } + } + Component { + id: textFieldComponent + + TextField { + id: textField + readOnly: !activeFocus + + text: styleData.value + + FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } + font.family: firaSansSemiBold.name + font.pixelSize: hifi.fontSizes.textFieldInput + height: hifi.dimensions.tableRowHeight + + style: TextFieldStyle { + textColor: readOnly + ? hifi.colors.black + : (treeView.isLightColorScheme ? hifi.colors.black : hifi.colors.white) + background: Rectangle { + visible: !readOnly + color: treeView.isLightColorScheme ? hifi.colors.white : hifi.colors.black + border.color: hifi.colors.primaryHighlight + border.width: 1 + } + selectedTextColor: hifi.colors.black + selectionColor: hifi.colors.primaryHighlight + padding.left: readOnly ? 0 : hifi.dimensions.textPadding + padding.right: readOnly ? 0 : hifi.dimensions.textPadding + } + + validator: RegExpValidator { + regExp: /[^/]+/ + } + + Keys.onPressed: { + if (event.key == Qt.Key_Escape) { + text = styleData.value; + unfocusHelper.forceActiveFocus(); + event.accepted = true; + } + } + onAccepted: { + if (acceptableInput && styleData.selected) { + if (!modifyEl(selection.currentIndex, text)) { + text = styleData.value; + } + unfocusHelper.forceActiveFocus(); + } + } + + onReadOnlyChanged: { + // Have to explicily set keyboardRaised because automatic setting fails because readOnly is true at the time. + keyboardRaised = activeFocus; + } + } + } + } + MouseArea { propagateComposedEvents: true diff --git a/interface/resources/qml/controls-uit/Tree.qml b/interface/resources/qml/controls-uit/Tree.qml index ce7edfcaab..d94a8cdceb 100644 --- a/interface/resources/qml/controls-uit/Tree.qml +++ b/interface/resources/qml/controls-uit/Tree.qml @@ -19,7 +19,6 @@ TreeView { id: treeView property var treeModel: ListModel { } - property var canEdit: false property bool centerHeaderText: false property int colorScheme: hifi.colorSchemes.light readonly property bool isLightColorScheme: colorScheme == hifi.colorSchemes.light @@ -198,9 +197,7 @@ TreeView { : (styleData.alternate ? hifi.colors.tableRowDarkEven : hifi.colors.tableRowDarkOdd) } - itemDelegate: Loader { - id: itemDelegateLoader - + itemDelegate: FiraSansSemiBold { anchors { left: parent ? parent.left : undefined leftMargin: (2 + styleData.depth) * hifi.dimensions.tablePadding @@ -209,101 +206,13 @@ TreeView { verticalCenter: parent ? parent.verticalCenter : undefined } - function getComponent() { - if (treeView.canEdit && styleData.selected) { - return textFieldComponent; - } else { - if (styleData.value.startsWith("HifiGlyphs#")) { - return glyphComponent; - } else { - return labelComponent; - } - } - - } - sourceComponent: getComponent() - - Component { - id: labelComponent - FiraSansSemiBold { - - text: styleData.value - size: hifi.fontSizes.tableText - color: colorScheme == hifi.colorSchemes.light - ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) - : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) + text: styleData.value + size: hifi.fontSizes.tableText + color: colorScheme == hifi.colorSchemes.light + ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) + : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) - elide: Text.ElideRight - } - } - Component { - id: glyphComponent - HiFiGlyphs { - text: styleData.value.replace("HifiGlyphs#", "") - size: hifi.fontSizes.tableText - color: colorScheme == hifi.colorSchemes.light - ? (styleData.selected ? hifi.colors.black : hifi.colors.baseGrayHighlight) - : (styleData.selected ? hifi.colors.black : hifi.colors.lightGrayText) - - elide: Text.ElideRight - } - } - Component { - id: textFieldComponent - - TextField { - id: textField - readOnly: !activeFocus - - text: styleData.value - - FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } - font.family: firaSansSemiBold.name - font.pixelSize: hifi.fontSizes.textFieldInput - height: hifi.dimensions.tableRowHeight - - style: TextFieldStyle { - textColor: readOnly - ? hifi.colors.black - : (treeView.isLightColorScheme ? hifi.colors.black : hifi.colors.white) - background: Rectangle { - visible: !readOnly - color: treeView.isLightColorScheme ? hifi.colors.white : hifi.colors.black - border.color: hifi.colors.primaryHighlight - border.width: 1 - } - selectedTextColor: hifi.colors.black - selectionColor: hifi.colors.primaryHighlight - padding.left: readOnly ? 0 : hifi.dimensions.textPadding - padding.right: readOnly ? 0 : hifi.dimensions.textPadding - } - - validator: RegExpValidator { - regExp: /[^/]+/ - } - - Keys.onPressed: { - if (event.key == Qt.Key_Escape) { - text = styleData.value; - unfocusHelper.forceActiveFocus(); - event.accepted = true; - } - } - onAccepted: { - if (acceptableInput && styleData.selected) { - if (!modifyEl(selection.currentIndex, text)) { - text = styleData.value; - } - unfocusHelper.forceActiveFocus(); - } - } - - onReadOnlyChanged: { - // Have to explicily set keyboardRaised because automatic setting fails because readOnly is true at the time. - keyboardRaised = activeFocus; - } - } - } + elide: Text.ElideRight } Item {