Merge pull request #11376 from Atlante45/feat/auto-bake

Pull Auto-Baking changes to TabletAssetServer.qml
This commit is contained in:
Ryan Huffman 2017-09-15 14:31:18 -07:00 committed by GitHub
commit eca7632111
2 changed files with 320 additions and 131 deletions

View file

@ -72,11 +72,11 @@ ScrollingWindow {
function doRenameFile(oldPath, newPath) { function doRenameFile(oldPath, newPath) {
if (newPath[0] != "/") { if (newPath[0] !== "/") {
newPath = "/" + newPath; newPath = "/" + newPath;
} }
if (oldPath[oldPath.length - 1] == '/' && newPath[newPath.length - 1] != '/') { if (oldPath[oldPath.length - 1] === '/' && newPath[newPath.length - 1] != '/') {
// this is a folder rename but the user neglected to add a trailing slash when providing a new path // this is a folder rename but the user neglected to add a trailing slash when providing a new path
newPath = newPath + "/"; newPath = newPath + "/";
} }
@ -302,7 +302,7 @@ ScrollingWindow {
object.selected.connect(function(destinationPath) { object.selected.connect(function(destinationPath) {
destinationPath = destinationPath.trim(); destinationPath = destinationPath.trim();
if (path == destinationPath) { if (path === destinationPath) {
return; return;
} }
if (fileExists(destinationPath)) { if (fileExists(destinationPath)) {
@ -363,7 +363,7 @@ ScrollingWindow {
running: false running: false
} }
property var uploadOpen: false; property bool uploadOpen: false;
Timer { Timer {
id: timer id: timer
} }

View file

@ -10,6 +10,7 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2 as OriginalDialogs import QtQuick.Dialogs 1.2 as OriginalDialogs
import Qt.labs.settings 1.0 import Qt.labs.settings 1.0
@ -105,12 +106,12 @@ Rectangle {
function askForOverwrite(path, callback) { function askForOverwrite(path, callback) {
var object = tabletRoot.messageBox({ var object = tabletRoot.messageBox({
icon: hifi.icons.question, icon: hifi.icons.question,
buttons: OriginalDialogs.StandardButton.Yes | OriginalDialogs.StandardButton.No, buttons: OriginalDialogs.StandardButton.Yes | OriginalDialogs.StandardButton.No,
defaultButton: OriginalDialogs.StandardButton.No, defaultButton: OriginalDialogs.StandardButton.No,
title: "Overwrite File", title: "Overwrite File",
text: path + "\n" + "This file already exists. Do you want to overwrite it?" text: path + "\n" + "This file already exists. Do you want to overwrite it?"
}); });
object.selected.connect(function(button) { object.selected.connect(function(button) {
if (button === OriginalDialogs.StandardButton.Yes) { if (button === OriginalDialogs.StandardButton.Yes) {
callback(); callback();
@ -149,9 +150,9 @@ Rectangle {
function handleGetMappingsError(errorString) { function handleGetMappingsError(errorString) {
errorMessageBox( errorMessageBox(
"There was a problem retreiving the list of assets from your Asset Server.\n" "There was a problem retreiving the list of assets from your Asset Server.\n"
+ errorString + errorString
); );
} }
function addToWorld() { function addToWorld() {
@ -179,25 +180,25 @@ Rectangle {
var SHAPE_TYPE_DEFAULT = SHAPE_TYPE_STATIC_MESH; var SHAPE_TYPE_DEFAULT = SHAPE_TYPE_STATIC_MESH;
var DYNAMIC_DEFAULT = false; var DYNAMIC_DEFAULT = false;
var prompt = tabletRoot.customInputDialog({ var prompt = tabletRoot.customInputDialog({
textInput: { textInput: {
label: "Model URL", label: "Model URL",
text: defaultURL text: defaultURL
}, },
comboBox: { comboBox: {
label: "Automatic Collisions", label: "Automatic Collisions",
index: SHAPE_TYPE_DEFAULT, index: SHAPE_TYPE_DEFAULT,
items: SHAPE_TYPES items: SHAPE_TYPES
}, },
checkBox: { checkBox: {
label: "Dynamic", label: "Dynamic",
checked: DYNAMIC_DEFAULT, checked: DYNAMIC_DEFAULT,
disableForItems: [ disableForItems: [
SHAPE_TYPE_STATIC_MESH SHAPE_TYPE_STATIC_MESH
], ],
checkStateOnDisable: false, checkStateOnDisable: false,
warningOnDisable: "Models with 'Exact' automatic collisions cannot be dynamic, and should not be used as floors" warningOnDisable: "Models with 'Exact' automatic collisions cannot be dynamic, and should not be used as floors"
} }
}); });
prompt.selected.connect(function (jsonResult) { prompt.selected.connect(function (jsonResult) {
if (jsonResult) { if (jsonResult) {
@ -205,23 +206,23 @@ Rectangle {
var url = result.textInput.trim(); var url = result.textInput.trim();
var shapeType; var shapeType;
switch (result.comboBox) { switch (result.comboBox) {
case SHAPE_TYPE_SIMPLE_HULL: case SHAPE_TYPE_SIMPLE_HULL:
shapeType = "simple-hull"; shapeType = "simple-hull";
break; break;
case SHAPE_TYPE_SIMPLE_COMPOUND: case SHAPE_TYPE_SIMPLE_COMPOUND:
shapeType = "simple-compound"; shapeType = "simple-compound";
break; break;
case SHAPE_TYPE_STATIC_MESH: case SHAPE_TYPE_STATIC_MESH:
shapeType = "static-mesh"; shapeType = "static-mesh";
break; break;
case SHAPE_TYPE_BOX: case SHAPE_TYPE_BOX:
shapeType = "box"; shapeType = "box";
break; break;
case SHAPE_TYPE_SPHERE: case SHAPE_TYPE_SPHERE:
shapeType = "sphere"; shapeType = "sphere";
break; break;
default: default:
shapeType = "none"; shapeType = "none";
} }
var dynamic = result.checkBox !== null ? result.checkBox : DYNAMIC_DEFAULT; var dynamic = result.checkBox !== null ? result.checkBox : DYNAMIC_DEFAULT;
@ -230,7 +231,7 @@ Rectangle {
print("Error: model cannot be both static mesh and dynamic. This should never happen."); print("Error: model cannot be both static mesh and dynamic. This should never happen.");
} else if (url) { } else if (url) {
var name = assetProxyModel.data(treeView.selection.currentIndex); var name = assetProxyModel.data(treeView.selection.currentIndex);
var addPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(MyAvatar.orientation))); var addPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getForward(MyAvatar.orientation)));
var gravity; var gravity;
if (dynamic) { if (dynamic) {
// Create a vector <0, -10, 0>. { x: 0, y: -10, z: 0 } won't work because Qt is dumb and this is a // Create a vector <0, -10, 0>. { x: 0, y: -10, z: 0 } won't work because Qt is dumb and this is a
@ -293,10 +294,10 @@ Rectangle {
} }
var object = tabletRoot.inputDialog({ var object = tabletRoot.inputDialog({
label: "Enter new path:", label: "Enter new path:",
current: path, current: path,
placeholderText: "Enter path here" placeholderText: "Enter path here"
}); });
object.selected.connect(function(destinationPath) { object.selected.connect(function(destinationPath) {
destinationPath = destinationPath.trim(); destinationPath = destinationPath.trim();
@ -339,12 +340,12 @@ Rectangle {
} }
var object = tabletRoot.messageBox({ var object = tabletRoot.messageBox({
icon: hifi.icons.question, icon: hifi.icons.question,
buttons: OriginalDialogs.StandardButton.Yes + OriginalDialogs.StandardButton.No, buttons: OriginalDialogs.StandardButton.Yes + OriginalDialogs.StandardButton.No,
defaultButton: OriginalDialogs.StandardButton.Yes, defaultButton: OriginalDialogs.StandardButton.Yes,
title: "Delete", title: "Delete",
text: modalMessage text: modalMessage
}); });
object.selected.connect(function(button) { object.selected.connect(function(button) {
if (button === OriginalDialogs.StandardButton.Yes) { if (button === OriginalDialogs.StandardButton.Yes) {
doDeleteFile(path); doDeleteFile(path);
@ -379,38 +380,38 @@ Rectangle {
var filename = fileUrl.slice(fileUrl.lastIndexOf('/') + 1); var filename = fileUrl.slice(fileUrl.lastIndexOf('/') + 1);
Assets.uploadFile(fileUrl, directory + filename, Assets.uploadFile(fileUrl, directory + filename,
function() { function() {
// Upload started // Upload started
uploadSpinner.visible = true; uploadSpinner.visible = true;
uploadButton.enabled = false; uploadButton.enabled = false;
uploadProgressLabel.text = "In progress..."; uploadProgressLabel.text = "In progress...";
}, },
function(err, path) { function(err, path) {
print(err, path); print(err, path);
if (err === "") { if (err === "") {
uploadProgressLabel.text = "Upload Complete"; uploadProgressLabel.text = "Upload Complete";
timer.interval = 1000; timer.interval = 1000;
timer.repeat = false; timer.repeat = false;
timer.triggered.connect(function() { timer.triggered.connect(function() {
uploadSpinner.visible = false; uploadSpinner.visible = false;
uploadButton.enabled = true; uploadButton.enabled = true;
uploadOpen = false; uploadOpen = false;
}); });
timer.start(); timer.start();
console.log("Asset Browser - finished uploading: ", fileUrl); console.log("Asset Browser - finished uploading: ", fileUrl);
reload(); reload();
} else { } else {
uploadSpinner.visible = false; uploadSpinner.visible = false;
uploadButton.enabled = true; uploadButton.enabled = true;
uploadOpen = false; uploadOpen = false;
if (err !== -1) { if (err !== -1) {
console.log("Asset Browser - error uploading: ", fileUrl, " - error ", err); console.log("Asset Browser - error uploading: ", fileUrl, " - error ", err);
var box = errorMessageBox("There was an error uploading:\n" + fileUrl + "\n" + err); var box = errorMessageBox("There was an error uploading:\n" + fileUrl + "\n" + err);
box.selected.connect(reload); box.selected.connect(reload);
} }
} }
}, dropping); }, dropping);
} }
function initiateUpload(url) { function initiateUpload(url) {
@ -421,9 +422,9 @@ Rectangle {
doUpload(fileUrl, true); doUpload(fileUrl, true);
} else { } else {
var browser = tabletRoot.fileDialog({ var browser = tabletRoot.fileDialog({
selectDirectory: false, selectDirectory: false,
dir: currentDirectory dir: currentDirectory
}); });
browser.canceled.connect(function() { browser.canceled.connect(function() {
uploadOpen = false; uploadOpen = false;
@ -445,11 +446,11 @@ Rectangle {
function errorMessageBox(message) { function errorMessageBox(message) {
return tabletRoot.messageBox({ return tabletRoot.messageBox({
icon: hifi.icons.warning, icon: hifi.icons.warning,
defaultButton: OriginalDialogs.StandardButton.Ok, defaultButton: OriginalDialogs.StandardButton.Ok,
title: "Error", title: "Error",
text: message text: message
}); });
} }
Column { Column {
@ -469,15 +470,6 @@ Rectangle {
height: 30 height: 30
spacing: hifi.dimensions.contentSpacing.x spacing: hifi.dimensions.contentSpacing.x
HifiControls.GlyphButton {
glyph: hifi.glyphs.reload
color: hifi.buttons.black
colorScheme: root.colorScheme
width: hifi.dimensions.controlLineHeight
onClicked: root.reload()
}
HifiControls.Button { HifiControls.Button {
text: "Add To World" text: "Add To World"
color: hifi.buttons.black color: hifi.buttons.black
@ -510,8 +502,193 @@ Rectangle {
onClicked: root.deleteFile() onClicked: root.deleteFile()
enabled: treeView.selection.hasSelection enabled: treeView.selection.hasSelection
} }
HifiControls.GlyphButton {
glyph: hifi.glyphs.reload
color: hifi.buttons.black
colorScheme: root.colorScheme
width: hifi.dimensions.controlLineHeight
onClicked: root.reload()
}
}
}
HifiControls.Tree {
id: treeView
anchors.top: assetDirectory.bottom
anchors.bottom: infoRow.top
anchors.margins: hifi.dimensions.contentMargin.x + 2 // Extra for border
anchors.left: parent.left
anchors.right: parent.right
treeModel: assetProxyModel
selectionMode: SelectionMode.ExtendedSelection
headerVisible: true
sortIndicatorVisible: true
colorScheme: root.colorScheme
modifyEl: renameEl
TableViewColumn {
id: nameColumn
title: "Name:"
role: "name"
width: treeView.width - bakedColumn.width;
}
TableViewColumn {
id: bakedColumn
title: "Use Baked?"
role: "baked"
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.check_2_01;
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
HifiControls.ToolTip {
anchors.fill: parent
visible: styleData.value === "Error"
toolTip: assetProxyModel.data(styleData.index, 0x106)
}
}
}
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 (!treeView.modifyEl(treeView.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
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if (!HMD.active) { // Popup only displays properly on desktop
var index = treeView.indexAt(mouse.x, mouse.y);
treeView.selection.setCurrentIndex(index, 0x0002);
contextMenu.currentIndex = index;
contextMenu.popup();
}
}
}
Menu { Menu {
id: contextMenu id: contextMenu
title: "Edit" title: "Edit"
@ -539,39 +716,51 @@ Rectangle {
} }
} }
} }
} }
HifiControls.Tree {
id: treeView
height: 290
anchors.leftMargin: hifi.dimensions.contentMargin.x + 2 // Extra for border
anchors.rightMargin: hifi.dimensions.contentMargin.x + 2 // Extra for border
anchors.left: parent.left
anchors.right: parent.right
treeModel: assetProxyModel Row {
canEdit: true id: infoRow
colorScheme: root.colorScheme anchors.left: treeView.left
selectionMode: SelectionMode.ExtendedSelection anchors.right: treeView.right
anchors.bottom: uploadSection.top
anchors.bottomMargin: hifi.dimensions.contentSpacing.y
spacing: hifi.dimensions.contentSpacing.x
RalewayRegular {
size: hifi.fontSizes.sectionName
font.capitalization: Font.AllUppercase
text: selectedItems + " items selected"
color: hifi.colors.lightGrayText
}
modifyEl: renameEl HifiControls.CheckBox {
function isChecked() {
var status = assetProxyModel.data(treeView.selection.currentIndex, 0x105);
var bakingDisabled = (status === "Not Baked" || status === "--");
return selectedItems === 1 && !bakingDisabled;
}
MouseArea { text: "Use baked (optimized) versions"
propagateComposedEvents: true colorScheme: root.colorScheme
anchors.fill: parent enabled: selectedItems === 1 && assetProxyModel.data(treeView.selection.currentIndex, 0x105) !== "--"
acceptedButtons: Qt.RightButton checked: isChecked()
onClicked: { onClicked: {
if (!HMD.active) { // Popup only displays properly on desktop var mappings = [];
var index = treeView.indexAt(mouse.x, mouse.y); for (var i in treeView.selection.selectedIndexes) {
treeView.selection.setCurrentIndex(index, 0x0002); var index = treeView.selection.selectedIndexes[i];
contextMenu.currentIndex = index; var path = assetProxyModel.data(index, 0x100);
contextMenu.popup(); mappings.push(path);
} }
print("Setting baking enabled:" + mappings + checked);
Assets.setBakingEnabled(mappings, checked, function() {
reload();
});
checked = Qt.binding(isChecked);
} }
} }
} }
HifiControls.TabletContentSection { HifiControls.TabletContentSection {
id: uploadSection id: uploadSection
name: "Upload A File" name: "Upload A File"