diff --git a/scripts/system/controllers/controllerModules/mouseHMD.js b/scripts/system/controllers/controllerModules/mouseHMD.js index 27fe82ca19..172923a8e2 100644 --- a/scripts/system/controllers/controllerModules/mouseHMD.js +++ b/scripts/system/controllers/controllerModules/mouseHMD.js @@ -29,6 +29,7 @@ function MouseHMD() { var _this = this; + this.hmdWasActive = HMD.active; this.mouseMoved = false; this.mouseActivity = new TimeLock(5000); this.handControllerActivity = new TimeLock(4000); @@ -102,6 +103,8 @@ this.isReady = function(controllerData, deltaTime) { var now = Date.now(); + var hmdChanged = this.hmdWasActive !== HMD.active; + this.hmdWasActive = HMD.active; this.triggersPressed(controllerData, now); if (HMD.active) { if (!this.mouseActivity.expired(now) && _this.handControllerActivity.expired()) { @@ -110,7 +113,7 @@ } else { Reticle.visible = false; } - } else if (!Reticle.visible) { + } else if (hmdChanged && !Reticle.visible) { Reticle.visible = true; } diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 48fdb8e565..077d50ddde 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -2223,6 +2223,7 @@ var PropertiesTool = function (opts) { // are selected or if no entity is selected this will be `null`. var currentSelectedEntityID = null; var statusMonitor = null; + var blockPropertyUpdates = false; that.setVisible = function (newVisible) { visible = newVisible; @@ -2260,6 +2261,10 @@ var PropertiesTool = function (opts) { }; function updateSelections(selectionUpdated) { + if (blockPropertyUpdates) { + return; + } + var data = { type: 'update', spaceMode: selectionDisplay.getSpaceMode() @@ -2356,7 +2361,9 @@ var PropertiesTool = function (opts) { } } pushCommandForSelections(); + blockPropertyUpdates = data.blockUpdateCallback === true; selectionManager._update(false, this); + blockPropertyUpdates = false; } else if (data.type === 'saveUserData' || data.type === 'saveMaterialData') { //the event bridge and json parsing handle our avatar id string differently. var actualID = data.id.split('"')[1]; @@ -2466,6 +2473,8 @@ var PropertiesTool = function (opts) { tooltips: Script.require('./assets/data/createAppTooltips.json'), hmdActive: HMD.active, }); + } else if (data.type === "updateProperties") { + updateSelections(true); } }; diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index 4d1d008f7f..c08cac2ce4 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -8,11 +8,14 @@ const DELTA_X_FOCUS_THRESHOLD = 1; -function DraggableNumber(min, max, step, decimals) { +function DraggableNumber(min, max, step, decimals, dragStart, dragEnd) { this.min = min; this.max = max; this.step = step !== undefined ? step : 1; this.decimals = decimals; + this.dragStartFunction = dragStart; + this.dragEndFunction = dragEnd; + this.dragging = false; this.initialMouseEvent = null; this.lastMouseEvent = null; this.valueChangeFunction = null; @@ -41,22 +44,32 @@ DraggableNumber.prototype = { }, documentMouseMove: function(event) { - if (this.lastMouseEvent) { - let initialValue = this.elInput.value; - let dx = event.clientX - this.lastMouseEvent.clientX; - let changeValue = dx !== 0; - if (changeValue) { - while (dx !== 0) { - if (dx > 0) { - this.stepUp(); - --dx; - } else { - this.stepDown(); - ++dx; + if (this.initialMouseEvent) { + let dxFromInitial = event.clientX - this.initialMouseEvent.clientX; + if (Math.abs(dxFromInitial) > DELTA_X_FOCUS_THRESHOLD && this.lastMouseEvent) { + let initialValue = this.elInput.value; + let dx = event.clientX - this.lastMouseEvent.clientX; + let changeValue = dx !== 0; + if (changeValue) { + while (dx !== 0) { + if (dx > 0) { + this.elInput.stepUp(); + --dx; + } else { + this.elInput.stepDown(); + ++dx; + } + } + this.inputChange(); + if (this.valueChangeFunction) { + this.valueChangeFunction(); } } - if (this.valueChangeFunction) { - this.valueChangeFunction(); + if (!this.dragging) { + if (this.dragStartFunction) { + this.dragStartFunction(); + } + this.dragging = true; } } this.lastMouseEvent = event; @@ -64,6 +77,12 @@ DraggableNumber.prototype = { }, documentMouseUp: function(event) { + if (this.dragging) { + if (this.dragEndFunction) { + this.dragEndFunction(); + } + this.dragging = false; + } this.lastMouseEvent = null; document.removeEventListener("mousemove", this.onDocumentMouseMove); document.removeEventListener("mouseup", this.onDocumentMouseUp); @@ -72,11 +91,17 @@ DraggableNumber.prototype = { stepUp: function() { this.elInput.stepUp(); this.inputChange(); + if (this.valueChangeFunction) { + this.valueChangeFunction(); + } }, stepDown: function() { this.elInput.stepDown(); this.inputChange(); + if (this.valueChangeFunction) { + this.valueChangeFunction(); + } }, setValue: function(newValue) { diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index d3e0751732..78e3cd4dc8 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1641,7 +1641,7 @@ function updateVisibleSpaceModeProperties() { * PROPERTY UPDATE FUNCTIONS */ -function updateProperty(originalPropertyName, propertyValue, isParticleProperty) { +function updateProperty(originalPropertyName, propertyValue, isParticleProperty, blockUpdateCallback) { let propertyUpdate = {}; // if this is a compound property name (i.e. animation.running) then split it by . up to 3 times let splitPropertyName = originalPropertyName.split('.'); @@ -1667,7 +1667,7 @@ function updateProperty(originalPropertyName, propertyValue, isParticleProperty) }); particleSyncDebounce(); } else { - updateProperties(propertyUpdate); + updateProperties(propertyUpdate, blockUpdateCallback); } } @@ -1676,66 +1676,89 @@ var particleSyncDebounce = _.debounce(function () { particlePropertyUpdates = {}; }, DEBOUNCE_TIMEOUT); -function updateProperties(propertiesToUpdate) { +function updateProperties(propertiesToUpdate, blockUpdateCallback) { + if (blockUpdateCallback === undefined) { + blockUpdateCallback = false; + } EventBridge.emitWebEvent(JSON.stringify({ id: lastEntityID, type: "update", - properties: propertiesToUpdate + properties: propertiesToUpdate, + blockUpdateCallback: blockUpdateCallback })); } -function createEmitTextPropertyUpdateFunction(propertyName, isParticleProperty) { +function createEmitTextPropertyUpdateFunction(property) { return function() { - updateProperty(propertyName, this.value, isParticleProperty); + updateProperty(property.name, this.value, property.isParticleProperty); }; } -function createEmitCheckedPropertyUpdateFunction(propertyName, inverse, isParticleProperty) { +function createEmitCheckedPropertyUpdateFunction(property) { return function() { - updateProperty(propertyName, inverse ? !this.checked : this.checked, isParticleProperty); + updateProperty(property.name, property.data.inverse ? !this.checked : this.checked, property.isParticleProperty); }; } -function createEmitNumberPropertyUpdateFunction(propertyName, multiplier, isParticleProperty) { +function createDragStartFunction(property) { return function() { + property.dragging = true; + }; +} + +function createDragEndFunction(property) { + return function() { + property.dragging = false; + EventBridge.emitWebEvent(JSON.stringify({ + type: "updateProperties" + })); + }; +} + +function createEmitNumberPropertyUpdateFunction(property) { + return function() { + let multiplier = property.data.multiplier; if (multiplier === undefined) { multiplier = 1; } let value = parseFloat(this.value) * multiplier; - updateProperty(propertyName, value, isParticleProperty); + updateProperty(property.name, value, property.isParticleProperty, property.dragging); }; } -function createEmitVec2PropertyUpdateFunction(propertyName, elX, elY, multiplier, isParticleProperty) { +function createEmitVec2PropertyUpdateFunction(property) { return function () { + let multiplier = property.data.multiplier; if (multiplier === undefined) { multiplier = 1; } let newValue = { - x: elX.value * multiplier, - y: elY.value * multiplier + x: property.elNumberX.elInput.value * multiplier, + y: property.elNumberY.elInput.value * multiplier }; - updateProperty(propertyName, newValue, isParticleProperty); + updateProperty(property.name, newValue, property.isParticleProperty, property.dragging); }; } -function createEmitVec3PropertyUpdateFunction(propertyName, elX, elY, elZ, multiplier, isParticleProperty) { +function createEmitVec3PropertyUpdateFunction(property) { return function() { + let multiplier = property.data.multiplier; if (multiplier === undefined) { multiplier = 1; } let newValue = { - x: elX.value * multiplier, - y: elY.value * multiplier, - z: elZ.value * multiplier + x: property.elNumberX.elInput.value * multiplier, + y: property.elNumberY.elInput.value * multiplier, + z: property.elNumberZ.elInput.value * multiplier }; - updateProperty(propertyName, newValue, isParticleProperty); + updateProperty(property.name, newValue, property.isParticleProperty, property.dragging); }; } -function createEmitColorPropertyUpdateFunction(propertyName, elRed, elGreen, elBlue, isParticleProperty) { +function createEmitColorPropertyUpdateFunction(property) { return function() { - emitColorPropertyUpdate(propertyName, elRed.value, elGreen.value, elBlue.value, isParticleProperty); + emitColorPropertyUpdate(property.name, property.elNumberR.elInput.value, property.elNumberG.elInput.value, + property.elNumberB.elInput.value, property.isParticleProperty); }; } @@ -1760,10 +1783,10 @@ function updateCheckedSubProperty(propertyName, propertyValue, subPropertyElemen updateProperty(propertyName, propertyValue, isParticleProperty); } -function createImageURLUpdateFunction(propertyName, isParticleProperty) { +function createImageURLUpdateFunction(property) { return function () { let newTextures = JSON.stringify({ "tex.picture": this.value }); - updateProperty(propertyName, newTextures, isParticleProperty); + updateProperty(property.name, newTextures, property.isParticleProperty); }; } @@ -1773,7 +1796,6 @@ function createImageURLUpdateFunction(propertyName, isParticleProperty) { */ function createStringProperty(property, elProperty) { - let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; @@ -1787,7 +1809,7 @@ function createStringProperty(property, elProperty) { `) - elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); + elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(property)); elProperty.appendChild(elInput); @@ -1826,30 +1848,29 @@ function createBoolProperty(property, elProperty) { elInput, propertyName, property.isParticleProperty); }); } else { - elInput.addEventListener('change', createEmitCheckedPropertyUpdateFunction(propertyName, propertyData.inverse, - property.isParticleProperty)); + elInput.addEventListener('change', createEmitCheckedPropertyUpdateFunction(property)); } return elInput; } function createNumberProperty(property, elProperty) { - let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; elProperty.className = "draggable-number"; - let elDraggableNumber = new DraggableNumber(propertyData.min, propertyData.max, - propertyData.step, propertyData.decimals); + let dragStartFunction = createDragStartFunction(property); + let dragEndFunction = createDragEndFunction(property); + let elDraggableNumber = new DraggableNumber(propertyData.min, propertyData.max, propertyData.step, + propertyData.decimals, dragStartFunction, dragEndFunction); let defaultValue = propertyData.defaultValue; if (defaultValue !== undefined) { elDraggableNumber.elInput.value = defaultValue; } - let valueChangeFunction = createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, - property.isParticleProperty); + let valueChangeFunction = createEmitNumberPropertyUpdateFunction(property); elDraggableNumber.setValueChangeFunction(valueChangeFunction); elDraggableNumber.elInput.setAttribute("id", elementID); @@ -1863,22 +1884,18 @@ function createNumberProperty(property, elProperty) { } function createVec3Property(property, elProperty) { - let propertyName = property.name; - let elementID = property.elementID; let propertyData = property.data; elProperty.className = propertyData.vec3Type + " fstuple"; - let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER], - propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); - let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER], - propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); - let elNumberZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_NUMBER], - propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); + let elNumberX = createTupleNumberInput(property, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER]); + let elNumberY = createTupleNumberInput(property, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER]); + let elNumberZ = createTupleNumberInput(property, propertyData.subLabels[VECTOR_ELEMENTS.Z_NUMBER]); + elProperty.appendChild(elNumberX.elDiv); + elProperty.appendChild(elNumberY.elDiv); + elProperty.appendChild(elNumberZ.elDiv); - let valueChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, - elNumberZ.elInput, propertyData.multiplier, - property.isParticleProperty); + let valueChangeFunction = createEmitVec3PropertyUpdateFunction(property); elNumberX.setValueChangeFunction(valueChangeFunction); elNumberY.setValueChangeFunction(valueChangeFunction); elNumberZ.setValueChangeFunction(valueChangeFunction); @@ -1891,8 +1908,6 @@ function createVec3Property(property, elProperty) { } function createVec2Property(property, elProperty) { - let propertyName = property.name; - let elementID = property.elementID; let propertyData = property.data; elProperty.className = propertyData.vec2Type + " fstuple"; @@ -1902,13 +1917,12 @@ function createVec2Property(property, elProperty) { elProperty.appendChild(elTuple); - let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER], - propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); - let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER], - propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); + let elNumberX = createTupleNumberInput(property, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER]); + let elNumberY = createTupleNumberInput(property, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER]); + elProperty.appendChild(elNumberX.elDiv); + elProperty.appendChild(elNumberY.elDiv); - let valueChangeFunction = createEmitVec2PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, - propertyData.multiplier, property.isParticleProperty); + let valueChangeFunction = createEmitVec2PropertyUpdateFunction(property); elNumberX.setValueChangeFunction(valueChangeFunction); elNumberY.setValueChangeFunction(valueChangeFunction); @@ -1921,6 +1935,7 @@ function createVec2Property(property, elProperty) { function createColorProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; + let propertyData = property.data; elProperty.className = "rgb fstuple"; @@ -1934,12 +1949,24 @@ function createColorProperty(property, elProperty) { elProperty.appendChild(elColorPicker); elProperty.appendChild(elTuple); - let elNumberR = createTupleNumberInput(elTuple, elementID, "red", COLOR_MIN, COLOR_MAX, COLOR_STEP); - let elNumberG = createTupleNumberInput(elTuple, elementID, "green", COLOR_MIN, COLOR_MAX, COLOR_STEP); - let elNumberB = createTupleNumberInput(elTuple, elementID, "blue", COLOR_MIN, COLOR_MAX, COLOR_STEP); + if (propertyData.min === undefined) { + propertyData.min = COLOR_MIN; + } + if (propertyData.max === undefined) { + propertyData.max = COLOR_MAX; + } + if (propertyData.step === undefined) { + propertyData.step = COLOR_STEP; + } - let valueChangeFunction = createEmitColorPropertyUpdateFunction(propertyName, elNumberR.elInput, elNumberG.elInput, - elNumberB.elInput, property.isParticleProperty); + let elNumberR = createTupleNumberInput(property, "red"); + let elNumberG = createTupleNumberInput(property, "green"); + let elNumberB = createTupleNumberInput(property, "blue"); + elTuple.appendChild(elNumberR.elDiv); + elTuple.appendChild(elNumberG.elDiv); + elTuple.appendChild(elNumberB.elDiv); + + let valueChangeFunction = createEmitColorPropertyUpdateFunction(property); elNumberR.setValueChangeFunction(valueChangeFunction); elNumberG.setValueChangeFunction(valueChangeFunction); elNumberB.setValueChangeFunction(valueChangeFunction); @@ -1978,7 +2005,6 @@ function createColorProperty(property, elProperty) { } function createDropdownProperty(property, propertyID, elProperty) { - let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; @@ -1995,7 +2021,7 @@ function createDropdownProperty(property, propertyID, elProperty) { elInput.add(option); } - elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); + elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(property)); elProperty.appendChild(elInput); @@ -2003,7 +2029,6 @@ function createDropdownProperty(property, propertyID, elProperty) { } function createTextareaProperty(property, elProperty) { - let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; @@ -2015,7 +2040,7 @@ function createTextareaProperty(property, elProperty) { elInput.readOnly = true; } - elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); + elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(property)); elProperty.appendChild(elInput); @@ -2107,7 +2132,9 @@ function createButtonsProperty(property, elProperty, elLabel) { return elProperty; } -function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, step, decimals) { +function createTupleNumberInput(property, subLabel) { + let propertyElementID = property.elementID; + let propertyData = property.data; let elementID = propertyElementID + "-" + subLabel.toLowerCase(); let elLabel = document.createElement('label'); @@ -2116,11 +2143,13 @@ function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, elLabel.setAttribute("for", elementID); elLabel.style.visibility = "visible"; - let elDraggableNumber = new DraggableNumber(min, max, step, decimals); + let dragStartFunction = createDragStartFunction(property); + let dragEndFunction = createDragEndFunction(property); + let elDraggableNumber = new DraggableNumber(propertyData.min, propertyData.max, propertyData.step, + propertyData.decimals, dragStartFunction, dragEndFunction); elDraggableNumber.elInput.setAttribute("id", elementID); elDraggableNumber.elDiv.className += " fstuple"; elDraggableNumber.elText.insertBefore(elLabel, elDraggableNumber.elLeftArrow); - elTuple.appendChild(elDraggableNumber.elDiv); return elDraggableNumber; } @@ -2393,7 +2422,7 @@ function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults, r userDataElement.value = propertyUpdate.userData; - updateProperties(propertyUpdate); + updateProperties(propertyUpdate, false); } var editor = null; @@ -3311,7 +3340,7 @@ function loaded() { } }); - getPropertyInputElement("image").addEventListener('change', createImageURLUpdateFunction('textures', false)); + getPropertyInputElement("image").addEventListener('change', createImageURLUpdateFunction(properties['textures'])); // Collapsible sections let elCollapsible = document.getElementsByClassName("collapse-icon"); @@ -3406,7 +3435,7 @@ function loaded() { let propertyID = elDropdown.getAttribute("propertyID"); let property = properties[propertyID]; property.elInput = dt; - dt.addEventListener('change', createEmitTextPropertyUpdateFunction(property.name, property.isParticleProperty)); + dt.addEventListener('change', createEmitTextPropertyUpdateFunction(property)); } elDropdowns = document.getElementsByTagName("select");