overte-JulianGro/scripts/system/html/js/entityProperties.js
hiflex a4406906f3 Fix the Face Camera checkbox on the text entity properties tab.
The checkbox appeared unchecked even if the underlying property was true.
2017-05-11 20:12:10 -05:00

1711 lines
79 KiB
JavaScript

// entityProperties.js
//
// Created by Ryan Huffman on 13 Nov 2014
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
var PI = 3.14159265358979;
var DEGREES_TO_RADIANS = PI / 180.0;
var RADIANS_TO_DEGREES = 180.0 / PI;
var ICON_FOR_TYPE = {
Box: "V",
Sphere: "n",
Shape: "n",
ParticleEffect: "",
Model: "",
Web: "q",
Text: "l",
Light: "p",
Zone: "o",
PolyVox: "",
Multiple: ""
}
var EDITOR_TIMEOUT_DURATION = 1500;
const KEY_P = 80; //Key code for letter p used for Parenting hotkey.
var colorPickers = [];
var lastEntityID = null;
debugPrint = function(message) {
EventBridge.emitWebEvent(
JSON.stringify({
type: "print",
message: message
})
);
};
function enableChildren(el, selector) {
els = el.querySelectorAll(selector);
for (var i = 0; i < els.length; i++) {
els[i].removeAttribute('disabled');
}
}
function disableChildren(el, selector) {
els = el.querySelectorAll(selector);
for (var i = 0; i < els.length; i++) {
els[i].setAttribute('disabled', 'disabled');
}
}
function enableProperties() {
enableChildren(document.getElementById("properties-list"), "input, textarea, checkbox, .dropdown dl, .color-picker");
enableChildren(document, ".colpick");
var elLocked = document.getElementById("property-locked");
if (elLocked.checked === false) {
removeStaticUserData();
}
}
function disableProperties() {
disableChildren(document.getElementById("properties-list"), "input, textarea, checkbox, .dropdown dl, .color-picker");
disableChildren(document, ".colpick");
for (var i = 0; i < colorPickers.length; i++) {
colorPickers[i].colpickHide();
}
var elLocked = document.getElementById("property-locked");
if ($('#userdata-editor').css('display') === "block" && elLocked.checked === true) {
showStaticUserData();
}
}
function showElements(els, show) {
for (var i = 0; i < els.length; i++) {
els[i].style.display = (show) ? 'table' : 'none';
}
}
function createEmitCheckedPropertyUpdateFunction(propertyName) {
return function() {
EventBridge.emitWebEvent(
'{"id":' + lastEntityID + ', "type":"update", "properties":{"' + propertyName + '":' + this.checked + '}}'
);
};
}
function createEmitCheckedToStringPropertyUpdateFunction(checkboxElement, name, propertyName) {
var newString = "";
if (checkboxElement.checked) {
newString += name + "";
} else {
}
}
function createEmitGroupCheckedPropertyUpdateFunction(group, propertyName) {
return function() {
var properties = {};
properties[group] = {};
properties[group][propertyName] = this.checked;
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: properties
})
);
};
}
function createEmitNumberPropertyUpdateFunction(propertyName, decimals) {
decimals = decimals == undefined ? 4 : decimals;
return function() {
var value = parseFloat(this.value).toFixed(decimals);
EventBridge.emitWebEvent(
'{"id":' + lastEntityID + ', "type":"update", "properties":{"' + propertyName + '":' + value + '}}'
);
};
}
function createEmitGroupNumberPropertyUpdateFunction(group, propertyName) {
return function() {
var properties = {};
properties[group] = {};
properties[group][propertyName] = this.value;
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: properties,
})
);
};
}
function createEmitTextPropertyUpdateFunction(propertyName) {
return function() {
var properties = {};
properties[propertyName] = this.value;
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: properties,
})
);
};
}
function createEmitGroupTextPropertyUpdateFunction(group, propertyName) {
return function() {
var properties = {};
properties[group] = {};
properties[group][propertyName] = this.value;
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: properties,
})
);
};
}
function createEmitVec3PropertyUpdateFunction(property, elX, elY, elZ) {
return function() {
var data = {
id: lastEntityID,
type: "update",
properties: {}
};
data.properties[property] = {
x: elX.value,
y: elY.value,
z: elZ.value,
};
EventBridge.emitWebEvent(JSON.stringify(data));
}
};
function createEmitGroupVec3PropertyUpdateFunction(group, property, elX, elY, elZ) {
return function() {
var data = {
id: lastEntityID,
type: "update",
properties: {}
};
data.properties[group] = {};
data.properties[group][property] = {
x: elX.value,
y: elY.value,
z: elZ ? elZ.value : 0,
};
EventBridge.emitWebEvent(JSON.stringify(data));
}
};
function createEmitVec3PropertyUpdateFunctionWithMultiplier(property, elX, elY, elZ, multiplier) {
return function() {
var data = {
id: lastEntityID,
type: "update",
properties: {}
};
data.properties[property] = {
x: elX.value * multiplier,
y: elY.value * multiplier,
z: elZ.value * multiplier,
};
EventBridge.emitWebEvent(JSON.stringify(data));
}
};
function createEmitColorPropertyUpdateFunction(property, elRed, elGreen, elBlue) {
return function() {
emitColorPropertyUpdate(property, elRed.value, elGreen.value, elBlue.value);
}
};
function emitColorPropertyUpdate(property, red, green, blue, group) {
var data = {
id: lastEntityID,
type: "update",
properties: {}
};
if (group) {
data.properties[group] = {};
data.properties[group][property] = {
red: red,
green: green,
blue: blue,
};
} else {
data.properties[property] = {
red: red,
green: green,
blue: blue,
};
}
EventBridge.emitWebEvent(JSON.stringify(data));
};
function createEmitGroupColorPropertyUpdateFunction(group, property, elRed, elGreen, elBlue) {
return function() {
var data = {
id: lastEntityID,
type: "update",
properties: {}
};
data.properties[group] = {};
data.properties[group][property] = {
red: elRed.value,
green: elGreen.value,
blue: elBlue.value,
};
EventBridge.emitWebEvent(JSON.stringify(data));
}
};
function updateCheckedSubProperty(propertyName, propertyValue, subPropertyElement, subPropertyString) {
if (subPropertyElement.checked) {
if (propertyValue.indexOf(subPropertyString)) {
propertyValue += subPropertyString + ',';
}
} else {
// We've unchecked, so remove
propertyValue = propertyValue.replace(subPropertyString + ",", "");
}
var _properties = {}
_properties[propertyName] = propertyValue;
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: _properties
})
);
}
function setUserDataFromEditor(noUpdate) {
var json = null;
try {
json = editor.get();
} catch (e) {
alert('Invalid JSON code - look for red X in your code ', +e)
}
if (json === null) {
return;
} else {
var text = editor.getText()
if (noUpdate === true) {
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "saveUserData",
properties: {
userData: text
},
})
);
return;
} else {
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: {
userData: text
},
})
);
}
}
}
function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults) {
var properties = {};
var parsedData = {};
try {
if ($('#userdata-editor').css('height') !== "0px") {
//if there is an expanded, we want to use its json.
parsedData = getEditorJSON();
} else {
parsedData = JSON.parse(userDataElement.value);
}
} catch (e) {}
if (!(groupName in parsedData)) {
parsedData[groupName] = {}
}
var keys = Object.keys(updateKeyPair);
keys.forEach(function (key) {
delete parsedData[groupName][key];
if (updateKeyPair[key] !== null && updateKeyPair[key] !== "null") {
if (updateKeyPair[key] instanceof Element) {
if(updateKeyPair[key].type === "checkbox") {
if (updateKeyPair[key].checked !== defaults[key]) {
parsedData[groupName][key] = updateKeyPair[key].checked;
}
} else {
var val = isNaN(updateKeyPair[key].value) ? updateKeyPair[key].value : parseInt(updateKeyPair[key].value);
if (val !== defaults[key]) {
parsedData[groupName][key] = val;
}
}
} else {
parsedData[groupName][key] = updateKeyPair[key];
}
}
});
if (Object.keys(parsedData[groupName]).length == 0) {
delete parsedData[groupName];
}
if (Object.keys(parsedData).length > 0) {
properties['userData'] = JSON.stringify(parsedData);
} else {
properties['userData'] = '';
}
userDataElement.value = properties['userData'];
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: properties,
})
);
}
function userDataChanger(groupName, keyName, values, userDataElement, defaultValue) {
var val = {}, def = {};
val[keyName] = values;
def[keyName] = defaultValue;
multiDataUpdater(groupName, val, userDataElement, def);
};
function setTextareaScrolling(element) {
var isScrolling = element.scrollHeight > element.offsetHeight;
element.setAttribute("scrolling", isScrolling ? "true" : "false");
};
var editor = null;
var editorTimeout = null;
var lastJSONString = null;
function createJSONEditor() {
var container = document.getElementById("userdata-editor");
var options = {
search: false,
mode: 'tree',
modes: ['code', 'tree'],
name: 'userData',
onModeChange: function() {
$('.jsoneditor-poweredBy').remove();
},
onError: function(e) {
alert('JSON editor:' + e)
},
onChange: function() {
var currentJSONString = editor.getText();
if (currentJSONString === '{"":""}') {
return;
}
$('#userdata-save').attr('disabled', false)
}
};
editor = new JSONEditor(container, options);
};
function hideNewJSONEditorButton() {
$('#userdata-new-editor').hide();
};
function hideClearUserDataButton() {
$('#userdata-clear').hide();
};
function showSaveUserDataButton() {
$('#userdata-save').show();
}
function hideSaveUserDataButton() {
$('#userdata-save').hide();
}
function showNewJSONEditorButton() {
$('#userdata-new-editor').show();
};
function showClearUserDataButton() {
$('#userdata-clear').show();
};
function showUserDataTextArea() {
$('#property-user-data').show();
};
function hideUserDataTextArea() {
$('#property-user-data').hide();
};
function showStaticUserData() {
if (editor !== null) {
$('#static-userdata').show();
$('#static-userdata').css('height', $('#userdata-editor').height())
$('#static-userdata').text(editor.getText());
}
};
function removeStaticUserData() {
$('#static-userdata').hide();
};
function setEditorJSON(json) {
editor.set(json)
if (editor.hasOwnProperty('expandAll')) {
editor.expandAll();
}
};
function getEditorJSON() {
return editor.get();
};
function deleteJSONEditor() {
if (editor !== null) {
editor.destroy();
editor = null;
}
};
var savedJSONTimer = null;
function saveJSONUserData(noUpdate) {
setUserDataFromEditor(noUpdate);
$('#userdata-saved').show();
$('#userdata-save').attr('disabled', true)
if (savedJSONTimer !== null) {
clearTimeout(savedJSONTimer);
}
savedJSONTimer = setTimeout(function() {
$('#userdata-saved').hide();
}, 1500)
}
function bindAllNonJSONEditorElements() {
var inputs = $('input');
var i;
for (i = 0; i < inputs.length; i++) {
var input = inputs[i];
var field = $(input);
field.on('focus', function(e) {
if (e.target.id === "userdata-new-editor" || e.target.id === "userdata-clear") {
return;
} else {
if ($('#userdata-editor').css('height') !== "0px") {
saveJSONUserData(true);
}
}
})
}
}
function unbindAllInputs() {
var inputs = $('input');
var i;
for (i = 0; i < inputs.length; i++) {
var input = inputs[i];
var field = $(input);
field.unbind();
}
}
function loaded() {
openEventBridge(function() {
var allSections = [];
var elID = document.getElementById("property-id");
var elType = document.getElementById("property-type");
var elTypeIcon = document.getElementById("type-icon");
var elName = document.getElementById("property-name");
var elLocked = document.getElementById("property-locked");
var elVisible = document.getElementById("property-visible");
var elPositionX = document.getElementById("property-pos-x");
var elPositionY = document.getElementById("property-pos-y");
var elPositionZ = document.getElementById("property-pos-z");
var elMoveSelectionToGrid = document.getElementById("move-selection-to-grid");
var elMoveAllToGrid = document.getElementById("move-all-to-grid");
var elDimensionsX = document.getElementById("property-dim-x");
var elDimensionsY = document.getElementById("property-dim-y");
var elDimensionsZ = document.getElementById("property-dim-z");
var elResetToNaturalDimensions = document.getElementById("reset-to-natural-dimensions");
var elRescaleDimensionsPct = document.getElementById("dimension-rescale-pct");
var elRescaleDimensionsButton = document.getElementById("dimension-rescale-button");
var elParentID = document.getElementById("property-parent-id");
var elParentJointIndex = document.getElementById("property-parent-joint-index");
var elRegistrationX = document.getElementById("property-reg-x");
var elRegistrationY = document.getElementById("property-reg-y");
var elRegistrationZ = document.getElementById("property-reg-z");
var elRotationX = document.getElementById("property-rot-x");
var elRotationY = document.getElementById("property-rot-y");
var elRotationZ = document.getElementById("property-rot-z");
var elLinearVelocityX = document.getElementById("property-lvel-x");
var elLinearVelocityY = document.getElementById("property-lvel-y");
var elLinearVelocityZ = document.getElementById("property-lvel-z");
var elLinearDamping = document.getElementById("property-ldamping");
var elAngularVelocityX = document.getElementById("property-avel-x");
var elAngularVelocityY = document.getElementById("property-avel-y");
var elAngularVelocityZ = document.getElementById("property-avel-z");
var elAngularDamping = document.getElementById("property-adamping");
var elRestitution = document.getElementById("property-restitution");
var elFriction = document.getElementById("property-friction");
var elGravityX = document.getElementById("property-grav-x");
var elGravityY = document.getElementById("property-grav-y");
var elGravityZ = document.getElementById("property-grav-z");
var elAccelerationX = document.getElementById("property-lacc-x");
var elAccelerationY = document.getElementById("property-lacc-y");
var elAccelerationZ = document.getElementById("property-lacc-z");
var elDensity = document.getElementById("property-density");
var elCollisionless = document.getElementById("property-collisionless");
var elDynamic = document.getElementById("property-dynamic");
var elCollideStatic = document.getElementById("property-collide-static");
var elCollideDynamic = document.getElementById("property-collide-dynamic");
var elCollideKinematic = document.getElementById("property-collide-kinematic");
var elCollideMyAvatar = document.getElementById("property-collide-myAvatar");
var elCollideOtherAvatar = document.getElementById("property-collide-otherAvatar");
var elCollisionSoundURL = document.getElementById("property-collision-sound-url");
var elGrabbable = document.getElementById("property-grabbable");
var elCloneable = document.getElementById("property-cloneable");
var elCloneableDynamic = document.getElementById("property-cloneable-dynamic");
var elCloneableGroup = document.getElementById("group-cloneable-group");
var elCloneableLifetime = document.getElementById("property-cloneable-lifetime");
var elCloneableLimit = document.getElementById("property-cloneable-limit");
var elWantsTrigger = document.getElementById("property-wants-trigger");
var elIgnoreIK = document.getElementById("property-ignore-ik");
var elLifetime = document.getElementById("property-lifetime");
var elScriptURL = document.getElementById("property-script-url");
var elScriptTimestamp = document.getElementById("property-script-timestamp");
var elReloadScriptsButton = document.getElementById("reload-script-button");
var elServerScripts = document.getElementById("property-server-scripts");
var elReloadServerScriptsButton = document.getElementById("reload-server-scripts-button");
var elServerScriptStatus = document.getElementById("server-script-status");
var elServerScriptError = document.getElementById("server-script-error");
var elUserData = document.getElementById("property-user-data");
var elClearUserData = document.getElementById("userdata-clear");
var elSaveUserData = document.getElementById("userdata-save");
var elJSONEditor = document.getElementById("userdata-editor");
var elNewJSONEditor = document.getElementById('userdata-new-editor');
var elColorSections = document.querySelectorAll(".color-section");
var elColor = document.getElementById("property-color");
var elColorRed = document.getElementById("property-color-red");
var elColorGreen = document.getElementById("property-color-green");
var elColorBlue = document.getElementById("property-color-blue");
var elShapeSections = document.querySelectorAll(".shape-section");
allSections.push(elShapeSections);
var elShape = document.getElementById("property-shape");
var elLightSections = document.querySelectorAll(".light-section");
allSections.push(elLightSections);
var elLightSpotLight = document.getElementById("property-light-spot-light");
var elLightColor = document.getElementById("property-light-color");
var elLightColorRed = document.getElementById("property-light-color-red");
var elLightColorGreen = document.getElementById("property-light-color-green");
var elLightColorBlue = document.getElementById("property-light-color-blue");
var elLightIntensity = document.getElementById("property-light-intensity");
var elLightFalloffRadius = document.getElementById("property-light-falloff-radius");
var elLightExponent = document.getElementById("property-light-exponent");
var elLightCutoff = document.getElementById("property-light-cutoff");
var elModelSections = document.querySelectorAll(".model-section");
allSections.push(elModelSections);
var elModelURL = document.getElementById("property-model-url");
var elShapeType = document.getElementById("property-shape-type");
var elCompoundShapeURL = document.getElementById("property-compound-shape-url");
var elModelAnimationURL = document.getElementById("property-model-animation-url");
var elModelAnimationPlaying = document.getElementById("property-model-animation-playing");
var elModelAnimationFPS = document.getElementById("property-model-animation-fps");
var elModelAnimationFrame = document.getElementById("property-model-animation-frame");
var elModelAnimationFirstFrame = document.getElementById("property-model-animation-first-frame");
var elModelAnimationLastFrame = document.getElementById("property-model-animation-last-frame");
var elModelAnimationLoop = document.getElementById("property-model-animation-loop");
var elModelAnimationHold = document.getElementById("property-model-animation-hold");
var elModelTextures = document.getElementById("property-model-textures");
var elModelOriginalTextures = document.getElementById("property-model-original-textures");
var elWebSections = document.querySelectorAll(".web-section");
allSections.push(elWebSections);
var elWebSourceURL = document.getElementById("property-web-source-url");
var elWebDPI = document.getElementById("property-web-dpi");
var elDescription = document.getElementById("property-description");
var elHyperlinkHref = document.getElementById("property-hyperlink-href");
var elHyperlinkSections = document.querySelectorAll(".hyperlink-section");
var elTextSections = document.querySelectorAll(".text-section");
allSections.push(elTextSections);
var elTextText = document.getElementById("property-text-text");
var elTextLineHeight = document.getElementById("property-text-line-height");
var elTextTextColor = document.getElementById("property-text-text-color");
var elTextFaceCamera = document.getElementById("property-text-face-camera");
var elTextTextColorRed = document.getElementById("property-text-text-color-red");
var elTextTextColorGreen = document.getElementById("property-text-text-color-green");
var elTextTextColorBlue = document.getElementById("property-text-text-color-blue");
var elTextBackgroundColor = document.getElementById("property-text-background-color");
var elTextBackgroundColorRed = document.getElementById("property-text-background-color-red");
var elTextBackgroundColorGreen = document.getElementById("property-text-background-color-green");
var elTextBackgroundColorBlue = document.getElementById("property-text-background-color-blue");
var elZoneSections = document.querySelectorAll(".zone-section");
allSections.push(elZoneSections);
var elZoneStageSunModelEnabled = document.getElementById("property-zone-stage-sun-model-enabled");
var elZoneKeyLightColor = document.getElementById("property-zone-key-light-color");
var elZoneKeyLightColorRed = document.getElementById("property-zone-key-light-color-red");
var elZoneKeyLightColorGreen = document.getElementById("property-zone-key-light-color-green");
var elZoneKeyLightColorBlue = document.getElementById("property-zone-key-light-color-blue");
var elZoneKeyLightIntensity = document.getElementById("property-zone-key-intensity");
var elZoneKeyLightAmbientIntensity = document.getElementById("property-zone-key-ambient-intensity");
var elZoneKeyLightDirectionX = document.getElementById("property-zone-key-light-direction-x");
var elZoneKeyLightDirectionY = document.getElementById("property-zone-key-light-direction-y");
var elZoneKeyLightDirectionZ = document.getElementById("property-zone-key-light-direction-z");
var elZoneKeyLightAmbientURL = document.getElementById("property-zone-key-ambient-url");
var elZoneStageLatitude = document.getElementById("property-zone-stage-latitude");
var elZoneStageLongitude = document.getElementById("property-zone-stage-longitude");
var elZoneStageAltitude = document.getElementById("property-zone-stage-altitude");
var elZoneStageAutomaticHourDay = document.getElementById("property-zone-stage-automatic-hour-day");
var elZoneStageDay = document.getElementById("property-zone-stage-day");
var elZoneStageHour = document.getElementById("property-zone-stage-hour");
var elZoneBackgroundMode = document.getElementById("property-zone-background-mode");
var elZoneSkyboxColor = document.getElementById("property-zone-skybox-color");
var elZoneSkyboxColorRed = document.getElementById("property-zone-skybox-color-red");
var elZoneSkyboxColorGreen = document.getElementById("property-zone-skybox-color-green");
var elZoneSkyboxColorBlue = document.getElementById("property-zone-skybox-color-blue");
var elZoneSkyboxURL = document.getElementById("property-zone-skybox-url");
var elZoneFlyingAllowed = document.getElementById("property-zone-flying-allowed");
var elZoneGhostingAllowed = document.getElementById("property-zone-ghosting-allowed");
var elZoneFilterURL = document.getElementById("property-zone-filter-url");
var elPolyVoxSections = document.querySelectorAll(".poly-vox-section");
allSections.push(elPolyVoxSections);
var elVoxelVolumeSizeX = document.getElementById("property-voxel-volume-size-x");
var elVoxelVolumeSizeY = document.getElementById("property-voxel-volume-size-y");
var elVoxelVolumeSizeZ = document.getElementById("property-voxel-volume-size-z");
var elVoxelSurfaceStyle = document.getElementById("property-voxel-surface-style");
var elXTextureURL = document.getElementById("property-x-texture-url");
var elYTextureURL = document.getElementById("property-y-texture-url");
var elZTextureURL = document.getElementById("property-z-texture-url");
if (window.EventBridge !== undefined) {
var properties;
EventBridge.scriptEventReceived.connect(function(data) {
data = JSON.parse(data);
if (data.type == "server_script_status") {
elServerScriptError.value = data.errorInfo;
elServerScriptError.style.display = data.errorInfo ? "block" : "none";
if (data.statusRetrieved === false) {
elServerScriptStatus.innerText = "Failed to retrieve status";
} else if (data.isRunning) {
var ENTITY_SCRIPT_STATUS = {
pending: "Pending",
loading: "Loading",
error_loading_script: "Error loading script",
error_running_script: "Error running script",
running: "Running",
unloaded: "Unloaded",
};
elServerScriptStatus.innerText = ENTITY_SCRIPT_STATUS[data.status] || data.status;
} else {
elServerScriptStatus.innerText = "Not running";
}
} else if (data.type == "update") {
if (!data.selections || data.selections.length == 0) {
if (editor !== null && lastEntityID !== null) {
saveJSONUserData(true);
deleteJSONEditor();
}
elTypeIcon.style.display = "none";
elType.innerHTML = "<i>No selection</i>";
elID.value = "";
disableProperties();
} else if (data.selections && data.selections.length > 1) {
deleteJSONEditor();
var selections = data.selections;
var ids = [];
var types = {};
var numTypes = 0;
for (var i = 0; i < selections.length; i++) {
ids.push(selections[i].id);
var type = selections[i].properties.type;
if (types[type] === undefined) {
types[type] = 0;
numTypes += 1;
}
types[type]++;
}
var type;
if (numTypes === 1) {
type = selections[0].properties.type;
} else {
type = "Multiple";
}
elType.innerHTML = type + " (" + data.selections.length + ")";
elTypeIcon.innerHTML = ICON_FOR_TYPE[type];
elTypeIcon.style.display = "inline-block";
elID.value = "";
disableProperties();
} else {
properties = data.selections[0].properties;
if (lastEntityID !== '"' + properties.id + '"' && lastEntityID !== null && editor !== null) {
saveJSONUserData(true);
}
//the event bridge and json parsing handle our avatar id string differently.
lastEntityID = '"' + properties.id + '"';
elID.value = properties.id;
elType.innerHTML = properties.type;
elTypeIcon.innerHTML = ICON_FOR_TYPE[properties.type];
elTypeIcon.style.display = "inline-block";
elLocked.checked = properties.locked;
elName.value = properties.name;
elVisible.checked = properties.visible;
elPositionX.value = properties.position.x.toFixed(4);
elPositionY.value = properties.position.y.toFixed(4);
elPositionZ.value = properties.position.z.toFixed(4);
elDimensionsX.value = properties.dimensions.x.toFixed(4);
elDimensionsY.value = properties.dimensions.y.toFixed(4);
elDimensionsZ.value = properties.dimensions.z.toFixed(4);
elParentID.value = properties.parentID;
elParentJointIndex.value = properties.parentJointIndex;
elRegistrationX.value = properties.registrationPoint.x.toFixed(4);
elRegistrationY.value = properties.registrationPoint.y.toFixed(4);
elRegistrationZ.value = properties.registrationPoint.z.toFixed(4);
elRotationX.value = properties.rotation.x.toFixed(4);
elRotationY.value = properties.rotation.y.toFixed(4);
elRotationZ.value = properties.rotation.z.toFixed(4);
elLinearVelocityX.value = properties.velocity.x.toFixed(4);
elLinearVelocityY.value = properties.velocity.y.toFixed(4);
elLinearVelocityZ.value = properties.velocity.z.toFixed(4);
elLinearDamping.value = properties.damping.toFixed(2);
elAngularVelocityX.value = (properties.angularVelocity.x * RADIANS_TO_DEGREES).toFixed(4);
elAngularVelocityY.value = (properties.angularVelocity.y * RADIANS_TO_DEGREES).toFixed(4);
elAngularVelocityZ.value = (properties.angularVelocity.z * RADIANS_TO_DEGREES).toFixed(4);
elAngularDamping.value = properties.angularDamping.toFixed(4);
elRestitution.value = properties.restitution.toFixed(4);
elFriction.value = properties.friction.toFixed(4);
elGravityX.value = properties.gravity.x.toFixed(4);
elGravityY.value = properties.gravity.y.toFixed(4);
elGravityZ.value = properties.gravity.z.toFixed(4);
elAccelerationX.value = properties.acceleration.x.toFixed(4);
elAccelerationY.value = properties.acceleration.y.toFixed(4);
elAccelerationZ.value = properties.acceleration.z.toFixed(4);
elDensity.value = properties.density.toFixed(4);
elCollisionless.checked = properties.collisionless;
elDynamic.checked = properties.dynamic;
elCollideStatic.checked = properties.collidesWith.indexOf("static") > -1;
elCollideKinematic.checked = properties.collidesWith.indexOf("kinematic") > -1;
elCollideDynamic.checked = properties.collidesWith.indexOf("dynamic") > -1;
elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1;
elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1;
elGrabbable.checked = properties.dynamic;
elWantsTrigger.checked = false;
elIgnoreIK.checked = true;
elCloneable.checked = false;
elCloneableDynamic.checked = false;
elCloneableGroup.style.display = elCloneable.checked ? "block": "none";
elCloneableLimit.value = 0;
elCloneableLifetime.value = 300;
var parsedUserData = {}
try {
parsedUserData = JSON.parse(properties.userData);
if ("grabbableKey" in parsedUserData) {
if ("grabbable" in parsedUserData["grabbableKey"]) {
elGrabbable.checked = parsedUserData["grabbableKey"].grabbable;
}
if ("wantsTrigger" in parsedUserData["grabbableKey"]) {
elWantsTrigger.checked = parsedUserData["grabbableKey"].wantsTrigger;
}
if ("ignoreIK" in parsedUserData["grabbableKey"]) {
elIgnoreIK.checked = parsedUserData["grabbableKey"].ignoreIK;
}
if ("cloneable" in parsedUserData["grabbableKey"]) {
elCloneable.checked = parsedUserData["grabbableKey"].cloneable;
elCloneableGroup.style.display = elCloneable.checked ? "block": "none";
elCloneableDynamic.checked = parsedUserData["grabbableKey"].cloneDynamic ? parsedUserData["grabbableKey"].cloneDynamic : properties.dynamic;
elDynamic.checked = elCloneable.checked ? false: properties.dynamic;
if (elCloneable.checked) {
if ("cloneLifetime" in parsedUserData["grabbableKey"]) {
elCloneableLifetime.value = parsedUserData["grabbableKey"].cloneLifetime ? parsedUserData["grabbableKey"].cloneLifetime : 300;
}
if ("cloneLimit" in parsedUserData["grabbableKey"]) {
elCloneableLimit.value = parsedUserData["grabbableKey"].cloneLimit ? parsedUserData["grabbableKey"].cloneLimit : 0;
}
}
}
}
} catch (e) {
}
elCollisionSoundURL.value = properties.collisionSoundURL;
elLifetime.value = properties.lifetime;
elScriptURL.value = properties.script;
elScriptTimestamp.value = properties.scriptTimestamp;
elServerScripts.value = properties.serverScripts;
var json = null;
try {
json = JSON.parse(properties.userData);
} catch (e) {
//normal text
deleteJSONEditor();
elUserData.value = properties.userData;
showUserDataTextArea();
showNewJSONEditorButton();
hideSaveUserDataButton();
}
if (json !== null) {
if (editor === null) {
createJSONEditor();
}
setEditorJSON(json);
showSaveUserDataButton();
hideUserDataTextArea();
hideNewJSONEditorButton();
}
elHyperlinkHref.value = properties.href;
elDescription.value = properties.description;
for (var i = 0; i < allSections.length; i++) {
for (var j = 0; j < allSections[i].length; j++) {
allSections[i][j].style.display = 'none';
}
}
for (var i = 0; i < elHyperlinkSections.length; i++) {
elHyperlinkSections[i].style.display = 'table';
}
if (properties.type == "Shape" || properties.type == "Box" || properties.type == "Sphere") {
for (var i = 0; i < elShapeSections.length; i++) {
elShapeSections[i].style.display = 'table';
}
elShape.value = properties.shape;
setDropdownText(elShape);
} else {
for (var i = 0; i < elShapeSections.length; i++) {
elShapeSections[i].style.display = 'none';
}
}
if (properties.type == "Shape" || properties.type == "Box" || properties.type == "Sphere" || properties.type == "ParticleEffect") {
for (var i = 0; i < elColorSections.length; i++) {
elColorSections[i].style.display = 'table';
}
elColorRed.value = properties.color.red;
elColorGreen.value = properties.color.green;
elColorBlue.value = properties.color.blue;
elColor.style.backgroundColor = "rgb(" + properties.color.red + "," + properties.color.green + "," + properties.color.blue + ")";
} else {
for (var i = 0; i < elColorSections.length; i++) {
elColorSections[i].style.display = 'none';
}
}
if (properties.type == "Model") {
for (var i = 0; i < elModelSections.length; i++) {
elModelSections[i].style.display = 'table';
}
elModelURL.value = properties.modelURL;
elShapeType.value = properties.shapeType;
setDropdownText(elShapeType);
elCompoundShapeURL.value = properties.compoundShapeURL;
elModelAnimationURL.value = properties.animation.url;
elModelAnimationPlaying.checked = properties.animation.running;
elModelAnimationFPS.value = properties.animation.fps;
elModelAnimationFrame.value = properties.animation.currentFrame;
elModelAnimationFirstFrame.value = properties.animation.firstFrame;
elModelAnimationLastFrame.value = properties.animation.lastFrame;
elModelAnimationLoop.checked = properties.animation.loop;
elModelAnimationHold.checked = properties.animation.hold;
elModelTextures.value = properties.textures;
setTextareaScrolling(elModelTextures);
elModelOriginalTextures.value = properties.originalTextures;
setTextareaScrolling(elModelOriginalTextures);
} else if (properties.type == "Web") {
for (var i = 0; i < elWebSections.length; i++) {
elWebSections[i].style.display = 'table';
}
for (var i = 0; i < elHyperlinkSections.length; i++) {
elHyperlinkSections[i].style.display = 'none';
}
elWebSourceURL.value = properties.sourceUrl;
elWebDPI.value = properties.dpi;
} else if (properties.type == "Text") {
for (var i = 0; i < elTextSections.length; i++) {
elTextSections[i].style.display = 'table';
}
elTextText.value = properties.text;
elTextLineHeight.value = properties.lineHeight.toFixed(4);
elTextFaceCamera.checked = properties.faceCamera;
elTextTextColor.style.backgroundColor = "rgb(" + properties.textColor.red + "," + properties.textColor.green + "," + properties.textColor.blue + ")";
elTextTextColorRed.value = properties.textColor.red;
elTextTextColorGreen.value = properties.textColor.green;
elTextTextColorBlue.value = properties.textColor.blue;
elTextBackgroundColorRed.value = properties.backgroundColor.red;
elTextBackgroundColorGreen.value = properties.backgroundColor.green;
elTextBackgroundColorBlue.value = properties.backgroundColor.blue;
} else if (properties.type == "Light") {
for (var i = 0; i < elLightSections.length; i++) {
elLightSections[i].style.display = 'table';
}
elLightSpotLight.checked = properties.isSpotlight;
elLightColor.style.backgroundColor = "rgb(" + properties.color.red + "," + properties.color.green + "," + properties.color.blue + ")";
elLightColorRed.value = properties.color.red;
elLightColorGreen.value = properties.color.green;
elLightColorBlue.value = properties.color.blue;
elLightIntensity.value = properties.intensity.toFixed(1);
elLightFalloffRadius.value = properties.falloffRadius.toFixed(1);
elLightExponent.value = properties.exponent.toFixed(2);
elLightCutoff.value = properties.cutoff.toFixed(2);
} else if (properties.type == "Zone") {
for (var i = 0; i < elZoneSections.length; i++) {
elZoneSections[i].style.display = 'table';
}
elZoneStageSunModelEnabled.checked = properties.stage.sunModelEnabled;
elZoneKeyLightColor.style.backgroundColor = "rgb(" + properties.keyLight.color.red + "," + properties.keyLight.color.green + "," + properties.keyLight.color.blue + ")";
elZoneKeyLightColorRed.value = properties.keyLight.color.red;
elZoneKeyLightColorGreen.value = properties.keyLight.color.green;
elZoneKeyLightColorBlue.value = properties.keyLight.color.blue;
elZoneKeyLightIntensity.value = properties.keyLight.intensity.toFixed(2);
elZoneKeyLightAmbientIntensity.value = properties.keyLight.ambientIntensity.toFixed(2);
elZoneKeyLightDirectionX.value = properties.keyLight.direction.x.toFixed(2);
elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2);
elZoneKeyLightAmbientURL.value = properties.keyLight.ambientURL;
elZoneStageLatitude.value = properties.stage.latitude.toFixed(2);
elZoneStageLongitude.value = properties.stage.longitude.toFixed(2);
elZoneStageAltitude.value = properties.stage.altitude.toFixed(2);
elZoneStageAutomaticHourDay.checked = properties.stage.automaticHourDay;
elZoneStageDay.value = properties.stage.day;
elZoneStageHour.value = properties.stage.hour;
elShapeType.value = properties.shapeType;
elCompoundShapeURL.value = properties.compoundShapeURL;
elZoneBackgroundMode.value = properties.backgroundMode;
setDropdownText(elZoneBackgroundMode);
elZoneSkyboxColor.style.backgroundColor = "rgb(" + properties.skybox.color.red + "," + properties.skybox.color.green + "," + properties.skybox.color.blue + ")";
elZoneSkyboxColorRed.value = properties.skybox.color.red;
elZoneSkyboxColorGreen.value = properties.skybox.color.green;
elZoneSkyboxColorBlue.value = properties.skybox.color.blue;
elZoneSkyboxURL.value = properties.skybox.url;
elZoneFlyingAllowed.checked = properties.flyingAllowed;
elZoneGhostingAllowed.checked = properties.ghostingAllowed;
elZoneFilterURL.value = properties.filterURL;
showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox');
} else if (properties.type == "PolyVox") {
for (var i = 0; i < elPolyVoxSections.length; i++) {
elPolyVoxSections[i].style.display = 'table';
}
elVoxelVolumeSizeX.value = properties.voxelVolumeSize.x.toFixed(2);
elVoxelVolumeSizeY.value = properties.voxelVolumeSize.y.toFixed(2);
elVoxelVolumeSizeZ.value = properties.voxelVolumeSize.z.toFixed(2);
elVoxelSurfaceStyle.value = properties.voxelSurfaceStyle;
setDropdownText(elVoxelSurfaceStyle);
elXTextureURL.value = properties.xTextureURL;
elYTextureURL.value = properties.yTextureURL;
elZTextureURL.value = properties.zTextureURL;
}
if (properties.locked) {
disableProperties();
elLocked.removeAttribute('disabled');
} else {
enableProperties();
elSaveUserData.disabled = true;
}
var activeElement = document.activeElement;
if (typeof activeElement.select !== "undefined") {
activeElement.select();
}
}
}
});
}
elLocked.addEventListener('change', createEmitCheckedPropertyUpdateFunction('locked'));
elName.addEventListener('change', createEmitTextPropertyUpdateFunction('name'));
elHyperlinkHref.addEventListener('change', createEmitTextPropertyUpdateFunction('href'));
elDescription.addEventListener('change', createEmitTextPropertyUpdateFunction('description'));
elVisible.addEventListener('change', createEmitCheckedPropertyUpdateFunction('visible'));
var positionChangeFunction = createEmitVec3PropertyUpdateFunction(
'position', elPositionX, elPositionY, elPositionZ);
elPositionX.addEventListener('change', positionChangeFunction);
elPositionY.addEventListener('change', positionChangeFunction);
elPositionZ.addEventListener('change', positionChangeFunction);
var dimensionsChangeFunction = createEmitVec3PropertyUpdateFunction(
'dimensions', elDimensionsX, elDimensionsY, elDimensionsZ);
elDimensionsX.addEventListener('change', dimensionsChangeFunction);
elDimensionsY.addEventListener('change', dimensionsChangeFunction);
elDimensionsZ.addEventListener('change', dimensionsChangeFunction);
elParentID.addEventListener('change', createEmitTextPropertyUpdateFunction('parentID'));
elParentJointIndex.addEventListener('change', createEmitNumberPropertyUpdateFunction('parentJointIndex'));
var registrationChangeFunction = createEmitVec3PropertyUpdateFunction(
'registrationPoint', elRegistrationX, elRegistrationY, elRegistrationZ);
elRegistrationX.addEventListener('change', registrationChangeFunction);
elRegistrationY.addEventListener('change', registrationChangeFunction);
elRegistrationZ.addEventListener('change', registrationChangeFunction);
var rotationChangeFunction = createEmitVec3PropertyUpdateFunction(
'rotation', elRotationX, elRotationY, elRotationZ);
elRotationX.addEventListener('change', rotationChangeFunction);
elRotationY.addEventListener('change', rotationChangeFunction);
elRotationZ.addEventListener('change', rotationChangeFunction);
var velocityChangeFunction = createEmitVec3PropertyUpdateFunction(
'velocity', elLinearVelocityX, elLinearVelocityY, elLinearVelocityZ);
elLinearVelocityX.addEventListener('change', velocityChangeFunction);
elLinearVelocityY.addEventListener('change', velocityChangeFunction);
elLinearVelocityZ.addEventListener('change', velocityChangeFunction);
elLinearDamping.addEventListener('change', createEmitNumberPropertyUpdateFunction('damping'));
var angularVelocityChangeFunction = createEmitVec3PropertyUpdateFunctionWithMultiplier(
'angularVelocity', elAngularVelocityX, elAngularVelocityY, elAngularVelocityZ, DEGREES_TO_RADIANS);
elAngularVelocityX.addEventListener('change', angularVelocityChangeFunction);
elAngularVelocityY.addEventListener('change', angularVelocityChangeFunction);
elAngularVelocityZ.addEventListener('change', angularVelocityChangeFunction);
elAngularDamping.addEventListener('change', createEmitNumberPropertyUpdateFunction('angularDamping'));
elRestitution.addEventListener('change', createEmitNumberPropertyUpdateFunction('restitution'));
elFriction.addEventListener('change', createEmitNumberPropertyUpdateFunction('friction'));
var gravityChangeFunction = createEmitVec3PropertyUpdateFunction(
'gravity', elGravityX, elGravityY, elGravityZ);
elGravityX.addEventListener('change', gravityChangeFunction);
elGravityY.addEventListener('change', gravityChangeFunction);
elGravityZ.addEventListener('change', gravityChangeFunction);
var accelerationChangeFunction = createEmitVec3PropertyUpdateFunction(
'acceleration', elAccelerationX, elAccelerationY, elAccelerationZ);
elAccelerationX.addEventListener('change', accelerationChangeFunction);
elAccelerationY.addEventListener('change', accelerationChangeFunction);
elAccelerationZ.addEventListener('change', accelerationChangeFunction);
elDensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('density'));
elCollisionless.addEventListener('change', createEmitCheckedPropertyUpdateFunction('collisionless'));
elDynamic.addEventListener('change', createEmitCheckedPropertyUpdateFunction('dynamic'));
elCollideDynamic.addEventListener('change', function() {
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideDynamic, 'dynamic');
});
elCollideKinematic.addEventListener('change', function() {
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideKinematic, 'kinematic');
});
elCollideStatic.addEventListener('change', function() {
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideStatic, 'static');
});
elCollideMyAvatar.addEventListener('change', function() {
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideMyAvatar, 'myAvatar');
});
elCollideOtherAvatar.addEventListener('change', function() {
updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideOtherAvatar, 'otherAvatar');
});
elGrabbable.addEventListener('change', function() {
if(elCloneable.checked) {
elGrabbable.checked = false;
}
userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic);
});
elCloneableDynamic.addEventListener('change', function (event){
userDataChanger("grabbableKey", "cloneDynamic", event.target, elUserData, -1);
});
elCloneable.addEventListener('change', function (event) {
var checked = event.target.checked;
if (checked) {
multiDataUpdater("grabbableKey",
{cloneLifetime: elCloneableLifetime, cloneLimit: elCloneableLimit, cloneDynamic: elCloneableDynamic, cloneable: event.target},
elUserData, {});
elCloneableGroup.style.display = "block";
EventBridge.emitWebEvent(
'{"id":' + lastEntityID + ', "type":"update", "properties":{"dynamic":false, "grabbable": false}}'
);
} else {
multiDataUpdater("grabbableKey",
{cloneLifetime: null, cloneLimit: null, cloneDynamic: null, cloneable: false},
elUserData, {});
elCloneableGroup.style.display = "none";
}
});
var numberListener = function (event) {
userDataChanger("grabbableKey", event.target.getAttribute("data-user-data-type"), parseInt(event.target.value), elUserData, false);
};
elCloneableLifetime.addEventListener('change', numberListener);
elCloneableLimit.addEventListener('change', numberListener);
elWantsTrigger.addEventListener('change', function() {
userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData, false);
});
elIgnoreIK.addEventListener('change', function() {
userDataChanger("grabbableKey", "ignoreIK", elIgnoreIK, elUserData, true);
});
elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL'));
elLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifetime'));
elScriptURL.addEventListener('change', createEmitTextPropertyUpdateFunction('script'));
elScriptTimestamp.addEventListener('change', createEmitNumberPropertyUpdateFunction('scriptTimestamp'));
elServerScripts.addEventListener('change', createEmitTextPropertyUpdateFunction('serverScripts'));
elServerScripts.addEventListener('change', function() {
// invalidate the current status (so that same-same updates can still be observed visually)
elServerScriptStatus.innerText = '[' + elServerScriptStatus.innerText + ']';
});
elClearUserData.addEventListener("click", function() {
deleteJSONEditor();
elUserData.value = "";
showUserDataTextArea();
showNewJSONEditorButton();
hideSaveUserDataButton();
var properties = {};
properties['userData'] = elUserData.value;
EventBridge.emitWebEvent(
JSON.stringify({
id: lastEntityID,
type: "update",
properties: properties,
})
);
});
elSaveUserData.addEventListener("click", function() {
saveJSONUserData(true);
});
elUserData.addEventListener('change', createEmitTextPropertyUpdateFunction('userData'));
elNewJSONEditor.addEventListener('click', function() {
deleteJSONEditor();
createJSONEditor();
var data = {};
setEditorJSON(data);
hideUserDataTextArea();
hideNewJSONEditorButton();
showSaveUserDataButton();
});
var colorChangeFunction = createEmitColorPropertyUpdateFunction(
'color', elColorRed, elColorGreen, elColorBlue);
elColorRed.addEventListener('change', colorChangeFunction);
elColorGreen.addEventListener('change', colorChangeFunction);
elColorBlue.addEventListener('change', colorChangeFunction);
colorPickers.push($('#property-color').colpick({
colorScheme: 'dark',
layout: 'hex',
color: '000000',
onShow: function(colpick) {
$('#property-color').attr('active', 'true');
},
onHide: function(colpick) {
$('#property-color').attr('active', 'false');
},
onSubmit: function(hsb, hex, rgb, el) {
$(el).css('background-color', '#' + hex);
$(el).colpickHide();
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
}
}));
elLightSpotLight.addEventListener('change', createEmitCheckedPropertyUpdateFunction('isSpotlight'));
var lightColorChangeFunction = createEmitColorPropertyUpdateFunction(
'color', elLightColorRed, elLightColorGreen, elLightColorBlue);
elLightColorRed.addEventListener('change', lightColorChangeFunction);
elLightColorGreen.addEventListener('change', lightColorChangeFunction);
elLightColorBlue.addEventListener('change', lightColorChangeFunction);
colorPickers.push($('#property-light-color').colpick({
colorScheme: 'dark',
layout: 'hex',
color: '000000',
onShow: function(colpick) {
$('#property-light-color').attr('active', 'true');
},
onHide: function(colpick) {
$('#property-light-color').attr('active', 'false');
},
onSubmit: function(hsb, hex, rgb, el) {
$(el).css('background-color', '#' + hex);
$(el).colpickHide();
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b);
}
}));
elLightIntensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('intensity', 1));
elLightFalloffRadius.addEventListener('change', createEmitNumberPropertyUpdateFunction('falloffRadius', 1));
elLightExponent.addEventListener('change', createEmitNumberPropertyUpdateFunction('exponent', 2));
elLightCutoff.addEventListener('change', createEmitNumberPropertyUpdateFunction('cutoff', 2));
elShape.addEventListener('change', createEmitTextPropertyUpdateFunction('shape'));
elWebSourceURL.addEventListener('change', createEmitTextPropertyUpdateFunction('sourceUrl'));
elWebDPI.addEventListener('change', createEmitNumberPropertyUpdateFunction('dpi'));
elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL'));
elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType'));
elCompoundShapeURL.addEventListener('change', createEmitTextPropertyUpdateFunction('compoundShapeURL'));
elModelAnimationURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('animation', 'url'));
elModelAnimationPlaying.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'running'));
elModelAnimationFPS.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'fps'));
elModelAnimationFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'currentFrame'));
elModelAnimationFirstFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'firstFrame'));
elModelAnimationLastFrame.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('animation', 'lastFrame'));
elModelAnimationLoop.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'loop'));
elModelAnimationHold.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('animation', 'hold'));
elModelTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures'));
elTextText.addEventListener('change', createEmitTextPropertyUpdateFunction('text'));
elTextFaceCamera.addEventListener('change', createEmitCheckedPropertyUpdateFunction('faceCamera'));
elTextLineHeight.addEventListener('change', createEmitNumberPropertyUpdateFunction('lineHeight'));
var textTextColorChangeFunction = createEmitColorPropertyUpdateFunction(
'textColor', elTextTextColorRed, elTextTextColorGreen, elTextTextColorBlue);
elTextTextColorRed.addEventListener('change', textTextColorChangeFunction);
elTextTextColorGreen.addEventListener('change', textTextColorChangeFunction);
elTextTextColorBlue.addEventListener('change', textTextColorChangeFunction);
colorPickers.push($('#property-text-text-color').colpick({
colorScheme: 'dark',
layout: 'hex',
color: '000000',
onShow: function(colpick) {
$('#property-text-text-color').attr('active', 'true');
},
onHide: function(colpick) {
$('#property-text-text-color').attr('active', 'false');
},
onSubmit: function(hsb, hex, rgb, el) {
$(el).css('background-color', '#' + hex);
$(el).colpickHide();
$(el).attr('active', 'false');
emitColorPropertyUpdate('textColor', rgb.r, rgb.g, rgb.b);
}
}));
var textBackgroundColorChangeFunction = createEmitColorPropertyUpdateFunction(
'backgroundColor', elTextBackgroundColorRed, elTextBackgroundColorGreen, elTextBackgroundColorBlue);
elTextBackgroundColorRed.addEventListener('change', textBackgroundColorChangeFunction);
elTextBackgroundColorGreen.addEventListener('change', textBackgroundColorChangeFunction);
elTextBackgroundColorBlue.addEventListener('change', textBackgroundColorChangeFunction);
colorPickers.push($('#property-text-background-color').colpick({
colorScheme: 'dark',
layout: 'hex',
color: '000000',
onShow: function(colpick) {
$('#property-text-background-color').attr('active', 'true');
},
onHide: function(colpick) {
$('#property-text-background-color').attr('active', 'false');
},
onSubmit: function(hsb, hex, rgb, el) {
$(el).css('background-color', '#' + hex);
$(el).colpickHide();
emitColorPropertyUpdate('backgroundColor', rgb.r, rgb.g, rgb.b);
}
}));
elZoneStageSunModelEnabled.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('stage', 'sunModelEnabled'));
colorPickers.push($('#property-zone-key-light-color').colpick({
colorScheme: 'dark',
layout: 'hex',
color: '000000',
onShow: function(colpick) {
$('#property-zone-key-light-color').attr('active', 'true');
},
onHide: function(colpick) {
$('#property-zone-key-light-color').attr('active', 'false');
},
onSubmit: function(hsb, hex, rgb, el) {
$(el).css('background-color', '#' + hex);
$(el).colpickHide();
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'keyLight');
}
}));
var zoneKeyLightColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('keyLight', 'color', elZoneKeyLightColorRed, elZoneKeyLightColorGreen, elZoneKeyLightColorBlue);
elZoneKeyLightColorRed.addEventListener('change', zoneKeyLightColorChangeFunction);
elZoneKeyLightColorGreen.addEventListener('change', zoneKeyLightColorChangeFunction);
elZoneKeyLightColorBlue.addEventListener('change', zoneKeyLightColorChangeFunction);
elZoneKeyLightIntensity.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('keyLight', 'intensity'));
elZoneKeyLightAmbientIntensity.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('keyLight', 'ambientIntensity'));
elZoneKeyLightAmbientURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('keyLight', 'ambientURL'));
var zoneKeyLightDirectionChangeFunction = createEmitGroupVec3PropertyUpdateFunction('keyLight', 'direction', elZoneKeyLightDirectionX, elZoneKeyLightDirectionY);
elZoneKeyLightDirectionX.addEventListener('change', zoneKeyLightDirectionChangeFunction);
elZoneKeyLightDirectionY.addEventListener('change', zoneKeyLightDirectionChangeFunction);
elZoneStageLatitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'latitude'));
elZoneStageLongitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'longitude'));
elZoneStageAltitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'altitude'));
elZoneStageAutomaticHourDay.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('stage', 'automaticHourDay'));
elZoneStageDay.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'day'));
elZoneStageHour.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'hour'));
elZoneBackgroundMode.addEventListener('change', createEmitTextPropertyUpdateFunction('backgroundMode'));
var zoneSkyboxColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('skybox', 'color',
elZoneSkyboxColorRed, elZoneSkyboxColorGreen, elZoneSkyboxColorBlue);
elZoneSkyboxColorRed.addEventListener('change', zoneSkyboxColorChangeFunction);
elZoneSkyboxColorGreen.addEventListener('change', zoneSkyboxColorChangeFunction);
elZoneSkyboxColorBlue.addEventListener('change', zoneSkyboxColorChangeFunction);
colorPickers.push($('#property-zone-skybox-color').colpick({
colorScheme: 'dark',
layout: 'hex',
color: '000000',
onShow: function(colpick) {
$('#property-zone-skybox-color').attr('active', 'true');
},
onHide: function(colpick) {
$('#property-zone-skybox-color').attr('active', 'false');
},
onSubmit: function(hsb, hex, rgb, el) {
$(el).css('background-color', '#' + hex);
$(el).colpickHide();
emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'skybox');
}
}));
elZoneSkyboxURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('skybox', 'url'));
elZoneFlyingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('flyingAllowed'));
elZoneGhostingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ghostingAllowed'));
elZoneFilterURL.addEventListener('change', createEmitTextPropertyUpdateFunction('filterURL'));
var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction(
'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ);
elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction);
elVoxelVolumeSizeY.addEventListener('change', voxelVolumeSizeChangeFunction);
elVoxelVolumeSizeZ.addEventListener('change', voxelVolumeSizeChangeFunction);
elVoxelSurfaceStyle.addEventListener('change', createEmitTextPropertyUpdateFunction('voxelSurfaceStyle'));
elXTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('xTextureURL'));
elYTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('yTextureURL'));
elZTextureURL.addEventListener('change', createEmitTextPropertyUpdateFunction('zTextureURL'));
elMoveSelectionToGrid.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "moveSelectionToGrid",
}));
});
elMoveAllToGrid.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "moveAllToGrid",
}));
});
elResetToNaturalDimensions.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "resetToNaturalDimensions",
}));
});
elRescaleDimensionsButton.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "rescaleDimensions",
percentage: parseFloat(elRescaleDimensionsPct.value),
}));
});
elReloadScriptsButton.addEventListener("click", function() {
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "reloadClientScripts"
}));
});
elReloadServerScriptsButton.addEventListener("click", function() {
// invalidate the current status (so that same-same updates can still be observed visually)
elServerScriptStatus.innerText = '[' + elServerScriptStatus.innerText + ']';
EventBridge.emitWebEvent(JSON.stringify({
type: "action",
action: "reloadServerScripts"
}));
});
document.addEventListener("keydown", function (keyDown) {
if (keyDown.keyCode === KEY_P && keyDown.ctrlKey) {
if (keyDown.shiftKey) {
EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' }));
} else {
EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' }));
}
}
});
window.onblur = function() {
// Fake a change event
var ev = document.createEvent("HTMLEvents");
ev.initEvent("change", true, true);
document.activeElement.dispatchEvent(ev);
}
// For input and textarea elements, select all of the text on focus
// WebKit-based browsers, such as is used with QWebView, have a quirk
// where the mouseup event comes after the focus event, causing the
// text to be deselected immediately after selecting all of the text.
// To make this work we block the first mouseup event after the elements
// received focus. If we block all mouseup events the user will not
// be able to click within the selected text.
// We also check to see if the value has changed to make sure we aren't
// blocking a mouse-up event when clicking on an input spinner.
var els = document.querySelectorAll("input, textarea");
for (var i = 0; i < els.length; i++) {
var clicked = false;
var originalText;
els[i].onfocus = function(e) {
originalText = this.value;
this.select();
clicked = false;
};
els[i].onmouseup = function(e) {
if (!clicked && originalText == this.value) {
e.preventDefault();
}
clicked = true;
};
}
bindAllNonJSONEditorElements();
});
// Collapsible sections
var elCollapsible = document.getElementsByClassName("section-header");
var toggleCollapsedEvent = function(event) {
var element = event.target;
if (element.nodeName !== "DIV") {
element = element.parentNode;
}
var isCollapsed = element.getAttribute("collapsed") !== "true";
element.setAttribute("collapsed", isCollapsed ? "true" : "false");
element.getElementsByTagName("span")[0].textContent = isCollapsed ? "L" : "M";
};
for (var i = 0, length = elCollapsible.length; i < length; i++) {
var element = elCollapsible[i];
element.addEventListener("click", toggleCollapsedEvent, true);
};
// Textarea scrollbars
var elTextareas = document.getElementsByTagName("TEXTAREA");
var textareaOnChangeEvent = function(event) {
setTextareaScrolling(event.target);
}
for (var i = 0, length = elTextareas.length; i < length; i++) {
var element = elTextareas[i];
setTextareaScrolling(element);
element.addEventListener("input", textareaOnChangeEvent, false);
element.addEventListener("change", textareaOnChangeEvent, false);
/* FIXME: Detect and update textarea scrolling attribute on resize. Unfortunately textarea doesn't have a resize
event; mouseup is a partial stand-in but doesn't handle resizing if mouse moves outside textarea rectangle. */
element.addEventListener("mouseup", textareaOnChangeEvent, false);
};
// Dropdowns
// For each dropdown the following replacement is created in place of the oriringal dropdown...
// Structure created:
// <dl dropped="true/false">
// <dt name="?" id="?" value="?"><span>display text</span><span>carat</span></dt>
// <dd>
// <ul>
// <li value="??>display text</li>
// <li>...</li>
// </ul>
// </dd>
// </dl>
function setDropdownText(dropdown) {
var lis = dropdown.parentNode.getElementsByTagName("li");
var text = "";
for (var i = 0; i < lis.length; i++) {
if (String(lis[i].getAttribute("value")) === String(dropdown.value)) {
text = lis[i].textContent;
}
}
dropdown.firstChild.textContent = text;
}
function toggleDropdown(event) {
var element = event.target;
if (element.nodeName !== "DT") {
element = element.parentNode;
}
element = element.parentNode;
var isDropped = element.getAttribute("dropped");
element.setAttribute("dropped", isDropped !== "true" ? "true" : "false");
}
function setDropdownValue(event) {
var dt = event.target.parentNode.parentNode.previousSibling;
dt.value = event.target.getAttribute("value");
dt.firstChild.textContent = event.target.textContent;
dt.parentNode.setAttribute("dropped", "false");
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", true, true);
dt.dispatchEvent(evt);
}
var elDropdowns = document.getElementsByTagName("select");
for (var i = 0; i < elDropdowns.length; i++) {
var options = elDropdowns[i].getElementsByTagName("option");
var selectedOption = 0;
for (var j = 0; j < options.length; j++) {
if (options[j].getAttribute("selected") === "selected") {
selectedOption = j;
}
}
var div = elDropdowns[i].parentNode;
var dl = document.createElement("dl");
div.appendChild(dl);
var dt = document.createElement("dt");
dt.name = elDropdowns[i].name;
dt.id = elDropdowns[i].id;
dt.addEventListener("click", toggleDropdown, true);
dl.appendChild(dt);
var span = document.createElement("span");
span.setAttribute("value", options[selectedOption].value);
span.textContent = options[selectedOption].firstChild.textContent;
dt.appendChild(span);
var span = document.createElement("span");
span.textContent = "5"; // caratDn
dt.appendChild(span);
var dd = document.createElement("dd");
dl.appendChild(dd);
var ul = document.createElement("ul");
dd.appendChild(ul);
for (var j = 0; j < options.length; j++) {
var li = document.createElement("li");
li.setAttribute("value", options[j].value);
li.textContent = options[j].firstChild.textContent;
li.addEventListener("click", setDropdownValue);
ul.appendChild(li);
}
}
elDropdowns = document.getElementsByTagName("select");
while (elDropdowns.length > 0) {
var el = elDropdowns[0];
el.parentNode.removeChild(el);
elDropdowns = document.getElementsByTagName("select");
}
augmentSpinButtons();
setUpKeyboardControl();
// Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked
document.addEventListener("contextmenu", function(event) {
event.preventDefault();
}, false);
setTimeout(function() {
EventBridge.emitWebEvent(JSON.stringify({ type: 'propertiesPageReady' }));
}, 1000);
}