add dynamic multiselect for material targets

This commit is contained in:
unknown 2019-04-04 15:43:04 -07:00
parent fd245b61ab
commit 4f4ec064e4
2 changed files with 209 additions and 65 deletions

View file

@ -2522,7 +2522,19 @@ var PropertiesTool = function (opts) {
type: 'propertyRangeReply',
propertyRanges: propertyRanges,
});
}
} else if (data.type === "materialTargetRequest") {
var properties = Entities.getEntityProperties(data.entityID, ["type", "parentID"]);
var parentModel = properties.parentID !== Uuid.NULL &&
Entities.getEntityProperties(properties.parentID, ["type"]).type === "Model";
var parentModelData;
if (properties.type === "Material" && parentModel) {
parentModelData = Graphics.getModel(properties.parentID);
}
emitScriptEvent({
type: 'materialTargetReply',
materialTargetData: parentModelData,
});
}
};
HMD.displayModeChanged.connect(function() {

View file

@ -650,23 +650,10 @@ const GROUPS = [
propertyID: "materialData",
},
{
label: "Select Submesh",
type: "bool",
propertyID: "selectSubmesh",
},
{
label: "Submesh to Replace",
type: "number-draggable",
min: 0,
step: 1,
propertyID: "submeshToReplace",
indentedLabel: true,
},
{
label: "Material to Replace",
type: "string",
propertyID: "materialNameToReplace",
indentedLabel: true,
label: "Material Target",
type: "dynamic-multiselect",
propertyUpdate: materialTargetPropertyUpdate,
propertyID: "parentMaterialName",
},
{
label: "Priority",
@ -1588,6 +1575,8 @@ function getPropertyInputElement(propertyID) {
return { red: property.elNumberR.elInput, green: property.elNumberG.elInput, blue: property.elNumberB.elInput };
case 'icon':
return property.elLabel;
case 'dynamic-multiselect':
return property.elDivOptions;
default:
return undefined;
}
@ -1710,6 +1699,10 @@ function resetProperties() {
property.elInput.imageLoad(property.elInput.value);
break;
}
case 'dynamic-multiselect': {
resetDynamicMultiselectProperty(property.elDivOptions);
break;
}
}
let showPropertyRules = properties[propertyID].showPropertyRules;
@ -2386,7 +2379,7 @@ function createTextureProperty(property, elProperty) {
return elResult;
}
function createButtonsProperty(property, elProperty, elLabel) {
function createButtonsProperty(property, elProperty) {
let elementID = property.elementID;
let propertyData = property.data;
@ -2399,6 +2392,42 @@ function createButtonsProperty(property, elProperty, elLabel) {
return elProperty;
}
function createDynamicMultiselectProperty(property, elProperty) {
let elementID = property.elementID;
let propertyData = property.data;
elProperty.className = "dynamic-multiselect";
let elDivOptions = document.createElement('div');
elDivOptions.setAttribute("id", elementID + "-options");
let elDivButtons = document.createElement('div');
elDivButtons.setAttribute("id", elDivOptions.getAttribute("id") + "-buttons");
let elLabel = document.createElement('label');
elLabel.innerText = "No Options";
elDivOptions.appendChild(elLabel);
let buttons = [ { id: "selectAll", label: "Select All", className: "black", onClick: selectAllMaterialTarget },
{ id: "clearAll", label: "Clear All", className: "black", onClick: clearAllMaterialTarget } ];
addButtons(elDivButtons, elementID, buttons, false);
elProperty.appendChild(elDivOptions);
elProperty.appendChild(elDivButtons);
return elDivOptions;
}
function resetDynamicMultiselectProperty(elDivOptions) {
let elInputs = elDivOptions.getElementsByTagName("input");
while (elInputs.length > 0) {
let elDivOption = elInputs[0].parentNode;
elDivOption.parentNode.removeChild(elDivOption);
}
elDivOptions.firstChild.style.display = "none";
elDivOptions.parentNode.lastChild.style.display = "block";
}
function createTupleNumberInput(property, subLabel) {
let propertyElementID = property.elementID;
let propertyData = property.data;
@ -2522,6 +2551,10 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI
property.elProperty = createButtonsProperty(property, elProperty);
break;
}
case 'dynamic-multiselect': {
property.elDivOptions = createDynamicMultiselectProperty(property, elProperty);
break;
}
case 'placeholder':
case 'sub-header': {
break;
@ -3058,7 +3091,7 @@ function setDropdownValue(event) {
/**
* TEXTAREA / PARENT MATERIAL NAME FUNCTIONS
* TEXTAREA FUNCTIONS
*/
function setTextareaScrolling(element) {
@ -3066,16 +3099,139 @@ function setTextareaScrolling(element) {
element.setAttribute("scrolling", isScrolling ? "true" : "false");
}
function showParentMaterialNameBox(number, elNumber, elString) {
if (number) {
$('#property-submeshToReplace').parent().show();
$('#property-materialNameToReplace').parent().hide();
elString.value = "";
} else {
$('#property-materialNameToReplace').parent().show();
$('#property-submeshToReplace').parent().hide();
elNumber.value = 0;
/**
* MATERIAL TARGET FUNCTIONS
*/
function setMaterialTargetData(materialTargetData) {
let elDivOptions = getPropertyInputElement("parentMaterialName");
resetDynamicMultiselectProperty(elDivOptions);
if (materialTargetData === undefined) {
elDivOptions.firstChild.style.display = "block";
elDivOptions.parentNode.lastChild.style.display = "none";
return;
}
let numMeshes = materialTargetData.numMeshes;
for (let i = 0; i < numMeshes; ++i) {
addMaterialTarget(elDivOptions, i, false);
}
let materialNames = materialTargetData.materialNames;
let materialNamesAdded = [];
for (let i = 0; i < materialNames.length; ++i) {
let materialName = materialNames[i];
if (materialNamesAdded.indexOf(materialName) === -1) {
addMaterialTarget(elDivOptions, materialName, true);
materialNamesAdded.push(materialName);
}
}
materialTargetPropertyUpdate(elDivOptions.propertyValue);
}
function addMaterialTarget(elDivOptions, targetID, isMaterialName) {
let elementID = elDivOptions.getAttribute("id");
elementID += isMaterialName ? "-material-" : "-mesh-";
elementID += targetID;
let elDiv = document.createElement('div');
elDiv.className = "materialTargetDiv";
elDiv.onclick = onToggleMaterialTarget;
elDivOptions.appendChild(elDiv);
let elInput = document.createElement('input');
elInput.className = "materialTargetInput";
elInput.setAttribute("type", "checkbox");
elInput.setAttribute("id", elementID);
elInput.setAttribute("targetID", targetID);
elInput.setAttribute("isMaterialName", isMaterialName);
elDiv.appendChild(elInput);
let elLabel = document.createElement('label');
elLabel.setAttribute("for", elementID);
elLabel.innerText = isMaterialName ? "Material " + targetID : "Mesh Index " + targetID;
elDiv.appendChild(elLabel);
return elDiv;
}
function onToggleMaterialTarget(event) {
let elTarget = event.target;
if (elTarget instanceof HTMLInputElement) {
sendMaterialTargetProperty();
}
event.stopPropagation();
}
function setAllMaterialTargetInputs(checked) {
let elDivOptions = getPropertyInputElement("parentMaterialName");
let elInputs = elDivOptions.getElementsByClassName("materialTargetInput");
for (let i = 0; i < elInputs.length; ++i) {
elInputs[i].checked = checked;
}
}
function selectAllMaterialTarget() {
setAllMaterialTargetInputs(true);
sendMaterialTargetProperty();
}
function clearAllMaterialTarget() {
setAllMaterialTargetInputs(false);
sendMaterialTargetProperty();
}
function sendMaterialTargetProperty() {
let elDivOptions = getPropertyInputElement("parentMaterialName");
let elInputs = elDivOptions.getElementsByClassName("materialTargetInput");
let materialTargetList = "";
for (let i = 0; i < elInputs.length; ++i) {
let elInput = elInputs[i];
if (elInput.checked) {
let targetID = elInput.getAttribute("targetID");
if (elInput.getAttribute("isMaterialName") === "true") {
materialTargetList += "mat::" + targetID + ",";
} else {
materialTargetList += targetID + ",";
}
}
}
if (materialTargetList !== "") {
materialTargetList = materialTargetList.substring(0, materialTargetList.length - 1);
materialTargetList = "[" + materialTargetList + "]";
}
updateProperty("parentMaterialName", materialTargetList, false);
}
function materialTargetPropertyUpdate(propertyValue) {
let elDivOptions = getPropertyInputElement("parentMaterialName");
let elInputs = elDivOptions.getElementsByClassName("materialTargetInput");
if (propertyValue.charAt(0) === '[') {
propertyValue = propertyValue.substring(1, propertyValue.length);
}
if (propertyValue.charAt(propertyValue.length - 1) === ']') {
propertyValue = propertyValue.substring(0, propertyValue.length - 1);
}
let materialTargets = propertyValue.split(",");
for (let i = 0; i < elInputs.length; ++i) {
let elInput = elInputs[i];
let targetID = elInput.getAttribute("targetID");
let materialTargetName = targetID;
if (elInput.getAttribute("isMaterialName") === "true") {
materialTargetName = "mat::" + targetID;
}
elInput.checked = materialTargets.indexOf(materialTargetName) >= 0;
}
elDivOptions.propertyValue = propertyValue;
}
@ -3504,6 +3660,12 @@ function loaded() {
property.elInput.imageLoad(property.elInput.value);
break;
}
case 'dynamic-multiselect': {
if (property.data.propertyUpdate) {
property.data.propertyUpdate(propertyValue);
}
break;
}
}
let showPropertyRules = property.showPropertyRules;
@ -3517,22 +3679,6 @@ function loaded() {
}
updateVisibleSpaceModeProperties();
if (selectedEntityProperties.type === "Material") {
let elParentMaterialNameString = getPropertyInputElement("materialNameToReplace");
let elParentMaterialNameNumber = getPropertyInputElement("submeshToReplace");
let elParentMaterialNameCheckbox = getPropertyInputElement("selectSubmesh");
let parentMaterialName = selectedEntityProperties.parentMaterialName;
if (parentMaterialName.startsWith(MATERIAL_PREFIX_STRING)) {
elParentMaterialNameString.value = parentMaterialName.replace(MATERIAL_PREFIX_STRING, "");
showParentMaterialNameBox(false, elParentMaterialNameNumber, elParentMaterialNameString);
elParentMaterialNameCheckbox.checked = false;
} else {
elParentMaterialNameNumber.value = parseInt(parentMaterialName);
showParentMaterialNameBox(true, elParentMaterialNameNumber, elParentMaterialNameString);
elParentMaterialNameCheckbox.checked = true;
}
}
let json = null;
try {
@ -3580,6 +3726,10 @@ function loaded() {
hideMaterialDataSaved();
}
if (hasSelectedEntityChanged && selectedEntityProperties.type === "Material") {
EventBridge.emitWebEvent(JSON.stringify({ type: 'materialTargetRequest', entityID: selectedEntityProperties.id }));
}
let activeElement = document.activeElement;
if (doSelectElement && typeof activeElement.select !== "undefined") {
activeElement.select();
@ -3629,6 +3779,8 @@ function loaded() {
}
}
}
} else if (data.type === 'materialTargetReply') {
setMaterialTargetData(data.materialTargetData);
}
});
@ -3698,26 +3850,6 @@ function loaded() {
elDiv.insertBefore(elMaterialDataEditor, elMaterialData);
elDiv.insertBefore(elMaterialDataEditorStatus, elMaterialData);
// Special Property Callbacks
let elParentMaterialNameString = getPropertyInputElement("materialNameToReplace");
let elParentMaterialNameNumber = getPropertyInputElement("submeshToReplace");
let elParentMaterialNameCheckbox = getPropertyInputElement("selectSubmesh");
elParentMaterialNameString.addEventListener('change', function () {
updateProperty("parentMaterialName", MATERIAL_PREFIX_STRING + this.value, false);
});
elParentMaterialNameNumber.addEventListener('change', function () {
updateProperty("parentMaterialName", this.value, false);
});
elParentMaterialNameCheckbox.addEventListener('change', function () {
if (this.checked) {
updateProperty("parentMaterialName", elParentMaterialNameNumber.value, false);
showParentMaterialNameBox(true, elParentMaterialNameNumber, elParentMaterialNameString);
} else {
updateProperty("parentMaterialName", MATERIAL_PREFIX_STRING + elParentMaterialNameString.value, false);
showParentMaterialNameBox(false, elParentMaterialNameNumber, elParentMaterialNameString);
}
});
// Collapsible sections
let elCollapsible = document.getElementsByClassName("collapse-icon");