From 5a843b13427e3d884f6779abb3af55efd67fc3c7 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 14 Dec 2017 11:03:59 -0800 Subject: [PATCH 01/46] adding support for filters to get old properties --- libraries/entities/src/EntityEditFilters.cpp | 11 ++++-- libraries/entities/src/EntityEditFilters.h | 2 +- libraries/entities/src/EntityTree.cpp | 2 +- .../entity_edit_filters/postition-example.js | 36 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 scripts/tutorials/entity_edit_filters/postition-example.js diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 550c8f17c4..09c165e9cb 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -42,7 +42,7 @@ QList EntityEditFilters::getZonesByPosition(glm::vec3& position) { } bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, - EntityTree::FilterType filterType, EntityItemID& itemID) { + EntityTree::FilterType filterType, EntityItemID& itemID, EntityItemPointer& existingEntity) { // get the ids of all the zones (plus the global entity edit filter) that the position // lies within @@ -68,9 +68,15 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper propertiesIn.setDesiredProperties(oldProperties); auto in = QJsonValue::fromVariant(inputValues.toVariant()); // grab json copy now, because the inputValues might be side effected by the filter. + + // get the current properties for then entity and include them for the filter call + auto currentProperties = existingEntity ? existingEntity->getProperties() : EntityItemProperties(); + QScriptValue currentValues = currentProperties.copyToScriptValue(filterData.engine, false, true, true); + QScriptValueList args; args << inputValues; args << filterType; + args << currentValues; QScriptValue result = filterData.filterFn.call(_nullObjectForFilter, args); if (filterData.uncaughtExceptions()) { @@ -182,8 +188,8 @@ static bool hadUncaughtExceptions(QScriptEngine& engine, const QString& fileName void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { qDebug() << "script request completed for entity " << entityID; auto scriptRequest = qobject_cast(sender()); - const QString urlString = scriptRequest->getUrl().toString(); if (scriptRequest && scriptRequest->getResult() == ResourceRequest::Success) { + const QString urlString = scriptRequest->getUrl().toString(); auto scriptContents = scriptRequest->getData(); qInfo() << "Downloaded script:" << scriptContents; QScriptProgram program(scriptContents, urlString); @@ -227,6 +233,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { } } } else if (scriptRequest) { + const QString urlString = scriptRequest->getUrl().toString(); qCritical() << "Failed to download script at" << urlString; // See HTTPResourceRequest::onRequestFinished for interpretation of codes. For example, a 404 is code 6 and 403 is 3. A timeout is 2. Go figure. qCritical() << "ResourceRequest error was" << scriptRequest->getResult(); diff --git a/libraries/entities/src/EntityEditFilters.h b/libraries/entities/src/EntityEditFilters.h index 6aeb347603..f25c3c092e 100644 --- a/libraries/entities/src/EntityEditFilters.h +++ b/libraries/entities/src/EntityEditFilters.h @@ -43,7 +43,7 @@ public: void removeFilter(EntityItemID entityID); bool filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, - EntityTree::FilterType filterType, EntityItemID& entityID); + EntityTree::FilterType filterType, EntityItemID& entityID, EntityItemPointer& existingEntity); signals: void filterAdded(EntityItemID id, bool success); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index e62399ce95..aa7215f53f 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1099,7 +1099,7 @@ bool EntityTree::filterProperties(EntityItemPointer& existingEntity, EntityItemP if (entityEditFilters) { auto position = existingEntity ? existingEntity->getWorldPosition() : propertiesIn.getPosition(); auto entityID = existingEntity ? existingEntity->getEntityItemID() : EntityItemID(); - accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType, entityID); + accepted = entityEditFilters->filter(position, propertiesIn, propertiesOut, wasChanged, filterType, entityID, existingEntity); } return accepted; diff --git a/scripts/tutorials/entity_edit_filters/postition-example.js b/scripts/tutorials/entity_edit_filters/postition-example.js new file mode 100644 index 0000000000..00f7391809 --- /dev/null +++ b/scripts/tutorials/entity_edit_filters/postition-example.js @@ -0,0 +1,36 @@ +function filter(properties, type, originalProperties) { + + /* Clamp position changes.*/ + var maxChange = 5; + function sign(val) { + if (val > 0) { + return 1; + } else if (val < 0) { + return -1; + } else { + return 0; + } + } + + function clamp(val, min, max) { + if (val > max) { + val = max; + } else if (val < min) { + val = min; + } + return val; + } + + + if (properties.position) { + /* Random near-zero value used as "zero" to prevent two sequential updates from being + exactly the same (which would cause them to be ignored) */ + var nearZero = 0.0001 * Math.random() + 0.001; + var maxFudgeChange = (maxChange + nearZero); + properties.position.x = clamp(properties.position.x, originalProperties.position.x - maxFudgeChange, originalProperties.position.x + maxFudgeChange); + properties.position.y = clamp(properties.position.y, originalProperties.position.y - maxFudgeChange, originalProperties.position.y + maxFudgeChange); + properties.position.z = clamp(properties.position.z, originalProperties.position.z - maxFudgeChange, originalProperties.position.z + maxFudgeChange); + } + + return properties; +} \ No newline at end of file From 17288386aeddbad5ce953087903a744e23d08105 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 14 Dec 2017 12:20:03 -0800 Subject: [PATCH 02/46] implement support for zone properties in filters --- libraries/entities/src/EntityEditFilters.cpp | 25 +++++++++++++++++++ .../keep-in-zone-example.js | 24 ++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 scripts/tutorials/entity_edit_filters/keep-in-zone-example.js diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 09c165e9cb..13be7ebc7d 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -73,12 +73,37 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper auto currentProperties = existingEntity ? existingEntity->getProperties() : EntityItemProperties(); QScriptValue currentValues = currentProperties.copyToScriptValue(filterData.engine, false, true, true); + // get the zone properties + auto zoneEntity = _tree->findEntityByEntityItemID(id); + auto zoneProperties = zoneEntity ? zoneEntity->getProperties() : EntityItemProperties(); + QScriptValue zoneValues = zoneProperties.copyToScriptValue(filterData.engine, false, true, true); + + if (zoneEntity) { + bool success = true; + AABox aaBox = zoneEntity->getAABox(success); + + if (success) { + QScriptValue boundingBox = filterData.engine->newObject(); + QScriptValue bottomRightNear = vec3toScriptValue(filterData.engine, aaBox.getCorner()); + QScriptValue topFarLeft = vec3toScriptValue(filterData.engine, aaBox.calcTopFarLeft()); + QScriptValue center = vec3toScriptValue(filterData.engine, aaBox.calcCenter()); + QScriptValue boundingBoxDimensions = vec3toScriptValue(filterData.engine, aaBox.getDimensions()); + boundingBox.setProperty("brn", bottomRightNear); + boundingBox.setProperty("tfl", topFarLeft); + boundingBox.setProperty("center", center); + boundingBox.setProperty("dimensions", boundingBoxDimensions); + zoneValues.setProperty("boundingBox", boundingBox); + } + } + QScriptValueList args; args << inputValues; args << filterType; args << currentValues; + args << zoneValues; QScriptValue result = filterData.filterFn.call(_nullObjectForFilter, args); + if (filterData.uncaughtExceptions()) { return false; } diff --git a/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js new file mode 100644 index 0000000000..13355129f5 --- /dev/null +++ b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js @@ -0,0 +1,24 @@ +function filter(properties, type, originalProperties, zoneProperties) { + + var nearZero = 0.0001 * Math.random() + 0.001; + + /* Clamp position changes to bounding box of zone.*/ + function clamp(val, min, max) { + /* Random near-zero value used as "zero" to prevent two sequential updates from being + exactly the same (which would cause them to be ignored) */ + if (val > max) { + val = max - nearZero; + } else if (val < min) { + val = min + nearZero; + } + return val; + } + + if (properties.position) { + properties.position.x = clamp(properties.position.x, zoneProperties.boundingBox.brn.x, zoneProperties.boundingBox.tfl.x); + properties.position.y = clamp(properties.position.y, zoneProperties.boundingBox.brn.y, zoneProperties.boundingBox.tfl.y); + properties.position.z = clamp(properties.position.z, zoneProperties.boundingBox.brn.z, zoneProperties.boundingBox.tfl.z); + } + + return properties; +} \ No newline at end of file From 32d05bc163c16303ef5625e65df73f756228080d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 19 Dec 2017 07:34:56 -0800 Subject: [PATCH 03/46] CR feedback --- scripts/tutorials/entity_edit_filters/keep-in-zone-example.js | 2 +- .../{postition-example.js => position-example.js} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename scripts/tutorials/entity_edit_filters/{postition-example.js => position-example.js} (99%) diff --git a/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js index 13355129f5..9013edda96 100644 --- a/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js +++ b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js @@ -21,4 +21,4 @@ function filter(properties, type, originalProperties, zoneProperties) { } return properties; -} \ No newline at end of file +} diff --git a/scripts/tutorials/entity_edit_filters/postition-example.js b/scripts/tutorials/entity_edit_filters/position-example.js similarity index 99% rename from scripts/tutorials/entity_edit_filters/postition-example.js rename to scripts/tutorials/entity_edit_filters/position-example.js index 00f7391809..5f17f04542 100644 --- a/scripts/tutorials/entity_edit_filters/postition-example.js +++ b/scripts/tutorials/entity_edit_filters/position-example.js @@ -33,4 +33,4 @@ function filter(properties, type, originalProperties) { } return properties; -} \ No newline at end of file +} From 8aa0525f4536b965a6b3bd1586291ca38df164a7 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 10 Jan 2018 10:32:28 -0800 Subject: [PATCH 04/46] CR style feedback --- .../keep-in-zone-example.js | 15 +++++++- .../entity_edit_filters/position-example.js | 37 +++++++++++-------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js index 9013edda96..eb9cfbeb4d 100644 --- a/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js +++ b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js @@ -1,8 +1,21 @@ +// +// keep-in-zone-example.js +// +// +// Created by Brad Hefta-Gaub to use Entities on Dec. 15, 2017 +// Copyright 2017 High Fidelity, Inc. +// +// This sample entity edit filter script will keep any entity inside the bounding box of the zone this filter is applied to. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + function filter(properties, type, originalProperties, zoneProperties) { var nearZero = 0.0001 * Math.random() + 0.001; - /* Clamp position changes to bounding box of zone.*/ + /* Clamp position changes to bounding box of zone.*/ function clamp(val, min, max) { /* Random near-zero value used as "zero" to prevent two sequential updates from being exactly the same (which would cause them to be ignored) */ diff --git a/scripts/tutorials/entity_edit_filters/position-example.js b/scripts/tutorials/entity_edit_filters/position-example.js index 5f17f04542..a6cafe6bcb 100644 --- a/scripts/tutorials/entity_edit_filters/position-example.js +++ b/scripts/tutorials/entity_edit_filters/position-example.js @@ -1,16 +1,20 @@ +// +// position-example.js +// +// +// Created by Brad Hefta-Gaub to use Entities on Dec. 15, 2017 +// Copyright 2017 High Fidelity, Inc. +// +// This sample entity edit filter script will only allow position to be changed by no more than 5 meters on any axis. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + function filter(properties, type, originalProperties) { - - /* Clamp position changes.*/ - var maxChange = 5; - function sign(val) { - if (val > 0) { - return 1; - } else if (val < 0) { - return -1; - } else { - return 0; - } - } + + /* Clamp position changes.*/ + var maxChange = 5; function clamp(val, min, max) { if (val > max) { @@ -27,9 +31,12 @@ function filter(properties, type, originalProperties) { exactly the same (which would cause them to be ignored) */ var nearZero = 0.0001 * Math.random() + 0.001; var maxFudgeChange = (maxChange + nearZero); - properties.position.x = clamp(properties.position.x, originalProperties.position.x - maxFudgeChange, originalProperties.position.x + maxFudgeChange); - properties.position.y = clamp(properties.position.y, originalProperties.position.y - maxFudgeChange, originalProperties.position.y + maxFudgeChange); - properties.position.z = clamp(properties.position.z, originalProperties.position.z - maxFudgeChange, originalProperties.position.z + maxFudgeChange); + properties.position.x = clamp(properties.position.x, originalProperties.position.x + - maxFudgeChange, originalProperties.position.x + maxFudgeChange); + properties.position.y = clamp(properties.position.y, originalProperties.position.y + - maxFudgeChange, originalProperties.position.y + maxFudgeChange); + properties.position.z = clamp(properties.position.z, originalProperties.position.z + - maxFudgeChange, originalProperties.position.z + maxFudgeChange); } return properties; From 612f9621b449f07a64425312d8cc16533b675cd0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 11 Jan 2018 10:00:49 -0800 Subject: [PATCH 05/46] adding filter properties to allow optimization --- libraries/entities/src/EntityEditFilters.cpp | 136 ++++++++++++++---- libraries/entities/src/EntityEditFilters.h | 6 + .../keep-in-zone-example.js | 4 + .../entity_edit_filters/position-example.js | 2 + 4 files changed, 117 insertions(+), 31 deletions(-) diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 13be7ebc7d..2b0dcc9f73 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -61,6 +61,7 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper if (filterData.rejectAll) { return false; } + auto oldProperties = propertiesIn.getDesiredProperties(); auto specifiedProperties = propertiesIn.getChangedProperties(); propertiesIn.setDesiredProperties(specifiedProperties); @@ -69,38 +70,44 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper auto in = QJsonValue::fromVariant(inputValues.toVariant()); // grab json copy now, because the inputValues might be side effected by the filter. - // get the current properties for then entity and include them for the filter call - auto currentProperties = existingEntity ? existingEntity->getProperties() : EntityItemProperties(); - QScriptValue currentValues = currentProperties.copyToScriptValue(filterData.engine, false, true, true); - - // get the zone properties - auto zoneEntity = _tree->findEntityByEntityItemID(id); - auto zoneProperties = zoneEntity ? zoneEntity->getProperties() : EntityItemProperties(); - QScriptValue zoneValues = zoneProperties.copyToScriptValue(filterData.engine, false, true, true); - - if (zoneEntity) { - bool success = true; - AABox aaBox = zoneEntity->getAABox(success); - - if (success) { - QScriptValue boundingBox = filterData.engine->newObject(); - QScriptValue bottomRightNear = vec3toScriptValue(filterData.engine, aaBox.getCorner()); - QScriptValue topFarLeft = vec3toScriptValue(filterData.engine, aaBox.calcTopFarLeft()); - QScriptValue center = vec3toScriptValue(filterData.engine, aaBox.calcCenter()); - QScriptValue boundingBoxDimensions = vec3toScriptValue(filterData.engine, aaBox.getDimensions()); - boundingBox.setProperty("brn", bottomRightNear); - boundingBox.setProperty("tfl", topFarLeft); - boundingBox.setProperty("center", center); - boundingBox.setProperty("dimensions", boundingBoxDimensions); - zoneValues.setProperty("boundingBox", boundingBox); - } - } - QScriptValueList args; args << inputValues; args << filterType; - args << currentValues; - args << zoneValues; + + // get the current properties for then entity and include them for the filter call + if (existingEntity && filterData.wantsOriginalProperties) { + auto currentProperties = existingEntity->getProperties(filterData.includedOriginalProperties); + QScriptValue currentValues = currentProperties.copyToScriptValue(filterData.engine, false, true, true); + args << currentValues; + } + + + // get the zone properties + if (filterData.wantsZoneProperties) { + auto zoneEntity = _tree->findEntityByEntityItemID(id); + if (zoneEntity) { + auto zoneProperties = zoneEntity->getProperties(filterData.includedZoneProperties); + QScriptValue zoneValues = zoneProperties.copyToScriptValue(filterData.engine, false, true, true); + + if (filterData.wantsZoneBoundingBox) { + bool success = true; + AABox aaBox = zoneEntity->getAABox(success); + if (success) { + QScriptValue boundingBox = filterData.engine->newObject(); + QScriptValue bottomRightNear = vec3toScriptValue(filterData.engine, aaBox.getCorner()); + QScriptValue topFarLeft = vec3toScriptValue(filterData.engine, aaBox.calcTopFarLeft()); + QScriptValue center = vec3toScriptValue(filterData.engine, aaBox.calcCenter()); + QScriptValue boundingBoxDimensions = vec3toScriptValue(filterData.engine, aaBox.getDimensions()); + boundingBox.setProperty("brn", bottomRightNear); + boundingBox.setProperty("tfl", topFarLeft); + boundingBox.setProperty("center", center); + boundingBox.setProperty("dimensions", boundingBoxDimensions); + zoneValues.setProperty("boundingBox", boundingBox); + } + } + args << zoneValues; + } + } QScriptValue result = filterData.filterFn.call(_nullObjectForFilter, args); @@ -245,8 +252,75 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { delete engine; filterData.rejectAll=true; } - - + + // check to see if the filterFn has properties asking for Original props + QScriptValue wantsOriginalPropertiesValue = filterData.filterFn.property("wantsOriginalProperties"); + // if the wantsOriginalProperties is a boolean, or a string, or list of strings, then evaluate as follows: + // - boolean - true - include all original properties + // false - no properties at all + // - string - empty - no properties at all + // any valid property - include just that property in the Original properties + // - list of strings - include only those properties in the Original properties + if (wantsOriginalPropertiesValue.isBool()) { + filterData.wantsOriginalProperties = wantsOriginalPropertiesValue.toBool(); + } else if (wantsOriginalPropertiesValue.isString()) { + auto stringValue = wantsOriginalPropertiesValue.toString(); + filterData.wantsOriginalProperties = !stringValue.isEmpty(); + if (filterData.wantsOriginalProperties) { + EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties); + } + } else if (wantsOriginalPropertiesValue.isArray()) { + auto length = wantsOriginalPropertiesValue.property("length").toInteger(); + for (int i; i < length; i++) { + auto stringValue = wantsOriginalPropertiesValue.property(i).toString(); + if (!stringValue.isEmpty()) { + filterData.wantsOriginalProperties = true; + break; + } + } + if (filterData.wantsOriginalProperties) { + EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties); + } + } + + // check to see if the filterFn has properties asking for Zone props + QScriptValue wantsZonePropertiesValue = filterData.filterFn.property("wantsZoneProperties"); + // if the wantsZoneProperties is a boolean, or a string, or list of strings, then evaluate as follows: + // - boolean - true - include all Zone properties + // false - no properties at all + // - string - empty - no properties at all + // any valid property - include just that property in the Zone properties + // - list of strings - include only those properties in the Zone properties + if (wantsZonePropertiesValue.isBool()) { + filterData.wantsZoneProperties = wantsZonePropertiesValue.toBool(); + filterData.wantsZoneBoundingBox = filterData.wantsZoneProperties; // include this too + } else if (wantsZonePropertiesValue.isString()) { + auto stringValue = wantsZonePropertiesValue.toString(); + filterData.wantsZoneProperties = !stringValue.isEmpty(); + if (filterData.wantsZoneProperties) { + EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties); + } + } else if (wantsZonePropertiesValue.isArray()) { + auto length = wantsZonePropertiesValue.property("length").toInteger(); + for (int i; i < length; i++) { + auto stringValue = wantsZonePropertiesValue.property(i).toString(); + if (!stringValue.isEmpty()) { + filterData.wantsZoneProperties = true; + + // boundingBox is a special case since it's not a true EntityPropertyFlag, so we + // need to detect it here. + if (stringValue == "boundingBox") { + filterData.wantsZoneBoundingBox = true; + break; // we can break here, since there are no other special cases + } + + } + } + if (filterData.wantsZoneProperties) { + EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties); + } + } + _lock.lockForWrite(); _filterDataMap.insert(entityID, filterData); _lock.unlock(); diff --git a/libraries/entities/src/EntityEditFilters.h b/libraries/entities/src/EntityEditFilters.h index f25c3c092e..be3df50d3f 100644 --- a/libraries/entities/src/EntityEditFilters.h +++ b/libraries/entities/src/EntityEditFilters.h @@ -28,6 +28,12 @@ class EntityEditFilters : public QObject, public Dependency { public: struct FilterData { QScriptValue filterFn; + bool wantsOriginalProperties { false }; + bool wantsZoneProperties { false }; + EntityPropertyFlags includedOriginalProperties; + EntityPropertyFlags includedZoneProperties; + bool wantsZoneBoundingBox { false }; + std::function uncaughtExceptions; QScriptEngine* engine; bool rejectAll; diff --git a/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js index eb9cfbeb4d..6d83ce1410 100644 --- a/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js +++ b/scripts/tutorials/entity_edit_filters/keep-in-zone-example.js @@ -35,3 +35,7 @@ function filter(properties, type, originalProperties, zoneProperties) { return properties; } + +filter.wantsOriginalProperties = true; +filter.wantsZoneProperties = true; +filter; \ No newline at end of file diff --git a/scripts/tutorials/entity_edit_filters/position-example.js b/scripts/tutorials/entity_edit_filters/position-example.js index a6cafe6bcb..01eabee7db 100644 --- a/scripts/tutorials/entity_edit_filters/position-example.js +++ b/scripts/tutorials/entity_edit_filters/position-example.js @@ -41,3 +41,5 @@ function filter(properties, type, originalProperties) { return properties; } +filter.wantsOriginalProperties = true; +filter; \ No newline at end of file From 25f5eb6b4fc3288d23b193e274996f72153cdec5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 18 Jan 2018 15:08:13 -0800 Subject: [PATCH 06/46] named property example --- libraries/entities/src/EntityEditFilters.cpp | 3 +++ scripts/tutorials/entity_edit_filters/position-example.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 2b0dcc9f73..a69a8ce7d1 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -299,6 +299,9 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { filterData.wantsZoneProperties = !stringValue.isEmpty(); if (filterData.wantsZoneProperties) { EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties); + if (stringValue == "boundingBox") { + filterData.wantsZoneBoundingBox = true; + } } } else if (wantsZonePropertiesValue.isArray()) { auto length = wantsZonePropertiesValue.property("length").toInteger(); diff --git a/scripts/tutorials/entity_edit_filters/position-example.js b/scripts/tutorials/entity_edit_filters/position-example.js index 01eabee7db..314ba0fd9f 100644 --- a/scripts/tutorials/entity_edit_filters/position-example.js +++ b/scripts/tutorials/entity_edit_filters/position-example.js @@ -41,5 +41,5 @@ function filter(properties, type, originalProperties) { return properties; } -filter.wantsOriginalProperties = true; +filter.wantsOriginalProperties = "position"; filter; \ No newline at end of file From c96e395a46df93b652a22d605f2b2ceb4bf68b64 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 25 Jan 2018 12:13:32 -0800 Subject: [PATCH 07/46] fix warning --- libraries/entities/src/EntityEditFilters.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index a69a8ce7d1..f5bf699e02 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -271,7 +271,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { } } else if (wantsOriginalPropertiesValue.isArray()) { auto length = wantsOriginalPropertiesValue.property("length").toInteger(); - for (int i; i < length; i++) { + for (int i = 0; i < length; i++) { auto stringValue = wantsOriginalPropertiesValue.property(i).toString(); if (!stringValue.isEmpty()) { filterData.wantsOriginalProperties = true; @@ -305,7 +305,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { } } else if (wantsZonePropertiesValue.isArray()) { auto length = wantsZonePropertiesValue.property("length").toInteger(); - for (int i; i < length; i++) { + for (int i = 0; i < length; i++) { auto stringValue = wantsZonePropertiesValue.property(i).toString(); if (!stringValue.isEmpty()) { filterData.wantsZoneProperties = true; From aea16fe071d1731f783d6f93482c1161e2d513c2 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 25 Jan 2018 15:01:29 -0800 Subject: [PATCH 08/46] add delete filter support --- libraries/entities/src/EntityEditFilters.cpp | 1 + libraries/entities/src/EntityTree.cpp | 18 ++++++++++++++++++ libraries/entities/src/EntityTree.h | 3 ++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index f5bf699e02..4e48c671cb 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -245,6 +245,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { entitiesObject.setProperty("ADD_FILTER_TYPE", EntityTree::FilterType::Add); entitiesObject.setProperty("EDIT_FILTER_TYPE", EntityTree::FilterType::Edit); entitiesObject.setProperty("PHYSICS_FILTER_TYPE", EntityTree::FilterType::Physics); + entitiesObject.setProperty("ERASE_FILTER_TYPE", EntityTree::FilterType::Erase); global.setProperty("Entities", entitiesObject); filterData.filterFn = global.property("filter"); if (!filterData.filterFn.isFunction()) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 9ab9f63245..629281749e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1928,6 +1928,24 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons #endif EntityItemID entityItemID(entityID); + + EntityItemPointer existingEntity; + + auto startLookup = usecTimestampNow(); + existingEntity = findEntityByEntityItemID(entityItemID); + auto endLookup = usecTimestampNow(); + _totalLookupTime += endLookup - startLookup; + + auto startFilter = usecTimestampNow(); + FilterType filterType = FilterType::Erase; + EntityItemProperties dummyProperties; + bool wasChanged = false; + + bool allowed = (sourceNode->isAllowedEditor()) || filterProperties(existingEntity, dummyProperties, dummyProperties, wasChanged, filterType); + auto endFilter = usecTimestampNow(); + + _totalFilterTime += endFilter - startFilter; + entityItemIDsToDelete << entityItemID; if (wantEditLogging() || wantTerseEditLogging()) { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 11a747d624..ba786fbe98 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -57,7 +57,8 @@ public: enum FilterType { Add, Edit, - Physics + Physics, + Erase }; EntityTree(bool shouldReaverage = false); virtual ~EntityTree(); From 6192625942a34242688cb5e087b3fed99ed7e954 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 25 Jan 2018 15:01:50 -0800 Subject: [PATCH 09/46] add delete filter support --- .../prevent-erase-in-zone-example.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 scripts/tutorials/entity_edit_filters/prevent-erase-in-zone-example.js diff --git a/scripts/tutorials/entity_edit_filters/prevent-erase-in-zone-example.js b/scripts/tutorials/entity_edit_filters/prevent-erase-in-zone-example.js new file mode 100644 index 0000000000..356cc55079 --- /dev/null +++ b/scripts/tutorials/entity_edit_filters/prevent-erase-in-zone-example.js @@ -0,0 +1,24 @@ +// +// prevent-erase-in-zone-example.js +// +// +// Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018 +// Copyright 2018 High Fidelity, Inc. +// +// This sample entity edit filter script will keep prevent any entity inside the zone from being erased. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +function filter(properties, type, originalProperties, zoneProperties) { + + if (type == Entities.ERASE_FILTER_TYPE) { + return false; + } + return properties; +} + +filter.wantsOriginalProperties = true; +filter.wantsZoneProperties = true; +filter; \ No newline at end of file From aa82ad885561411daf1d97778193f22cd18b612b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 26 Jan 2018 14:57:36 -0800 Subject: [PATCH 10/46] adjust client to only delete entities on server echo --- libraries/entities/src/EntityScriptingInterface.cpp | 5 ++++- libraries/entities/src/EntityTree.cpp | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 206065beeb..877225de77 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -585,7 +585,10 @@ void EntityScriptingInterface::deleteEntity(QUuid id) { if (entity->getLocked()) { shouldDelete = false; } else { - _entityTree->deleteEntity(entityID); + // only delete local entities, server entities will round trip through the server filters + if (entity->getClientOnly()) { + _entityTree->deleteEntity(entityID); + } } } }); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 629281749e..8071a8f9b7 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1946,12 +1946,16 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons _totalFilterTime += endFilter - startFilter; - entityItemIDsToDelete << entityItemID; - - if (wantEditLogging() || wantTerseEditLogging()) { - qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID; + if (allowed) { + entityItemIDsToDelete << entityItemID; + if (wantEditLogging() || wantTerseEditLogging()) { + qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID; + } + } else if (wantEditLogging() || wantTerseEditLogging()) { + qCDebug(entities) << "User [" << sourceNode->getUUID() << "] attempted to deleteentity. ID:" << entityItemID << " Filter rejected erase."; } + } deleteEntities(entityItemIDsToDelete, true, true); } From a3d86a02423eeaa22fe373b29531d0fc1f77a52b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 26 Jan 2018 17:37:24 -0800 Subject: [PATCH 11/46] cleanup --- libraries/entities/src/EntityEditFilters.cpp | 2 +- libraries/entities/src/EntityTree.cpp | 62 ++++++++++--------- libraries/entities/src/EntityTree.h | 4 +- ...e.js => prevent-delete-in-zone-example.js} | 6 +- 4 files changed, 41 insertions(+), 33 deletions(-) rename scripts/tutorials/entity_edit_filters/{prevent-erase-in-zone-example.js => prevent-delete-in-zone-example.js} (81%) diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 4e48c671cb..4b66b61d93 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -245,7 +245,7 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { entitiesObject.setProperty("ADD_FILTER_TYPE", EntityTree::FilterType::Add); entitiesObject.setProperty("EDIT_FILTER_TYPE", EntityTree::FilterType::Edit); entitiesObject.setProperty("PHYSICS_FILTER_TYPE", EntityTree::FilterType::Physics); - entitiesObject.setProperty("ERASE_FILTER_TYPE", EntityTree::FilterType::Erase); + entitiesObject.setProperty("DELETE_FILTER_TYPE", EntityTree::FilterType::Delete); global.setProperty("Entities", entitiesObject); filterData.filterFn = global.property("filter"); if (!filterData.filterFn.isFunction()) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 8071a8f9b7..57540092da 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1850,6 +1850,37 @@ void EntityTree::forgetEntitiesDeletedBefore(quint64 sinceTime) { } +bool EntityTree::shouldEraseEntity(EntityItemID entityID, const SharedNodePointer& sourceNode) { + EntityItemPointer existingEntity; + + auto startLookup = usecTimestampNow(); + existingEntity = findEntityByEntityItemID(entityID); + auto endLookup = usecTimestampNow(); + _totalLookupTime += endLookup - startLookup; + + auto startFilter = usecTimestampNow(); + FilterType filterType = FilterType::Delete; + EntityItemProperties dummyProperties; + bool wasChanged = false; + + bool allowed = (sourceNode->isAllowedEditor()) || filterProperties(existingEntity, dummyProperties, dummyProperties, wasChanged, filterType); + auto endFilter = usecTimestampNow(); + + _totalFilterTime += endFilter - startFilter; + + if (allowed) { + if (wantEditLogging() || wantTerseEditLogging()) { + qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityID; + } + } + else if (wantEditLogging() || wantTerseEditLogging()) { + qCDebug(entities) << "User [" << sourceNode->getUUID() << "] attempted to deleteentity. ID:" << entityID << " Filter rejected erase."; + } + + return allowed; +} + + // TODO: consider consolidating processEraseMessageDetails() and processEraseMessage() int EntityTree::processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode) { #ifdef EXTRA_ERASE_DEBUGGING @@ -1877,12 +1908,10 @@ int EntityTree::processEraseMessage(ReceivedMessage& message, const SharedNodePo #endif EntityItemID entityItemID(entityID); - entityItemIDsToDelete << entityItemID; - if (wantEditLogging() || wantTerseEditLogging()) { - qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID; + if (shouldEraseEntity(entityID, sourceNode)) { + entityItemIDsToDelete << entityItemID; } - } deleteEntities(entityItemIDsToDelete, true, true); } @@ -1929,33 +1958,10 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons EntityItemID entityItemID(entityID); - EntityItemPointer existingEntity; - - auto startLookup = usecTimestampNow(); - existingEntity = findEntityByEntityItemID(entityItemID); - auto endLookup = usecTimestampNow(); - _totalLookupTime += endLookup - startLookup; - - auto startFilter = usecTimestampNow(); - FilterType filterType = FilterType::Erase; - EntityItemProperties dummyProperties; - bool wasChanged = false; - - bool allowed = (sourceNode->isAllowedEditor()) || filterProperties(existingEntity, dummyProperties, dummyProperties, wasChanged, filterType); - auto endFilter = usecTimestampNow(); - - _totalFilterTime += endFilter - startFilter; - - if (allowed) { + if (shouldEraseEntity(entityID, sourceNode)) { entityItemIDsToDelete << entityItemID; - if (wantEditLogging() || wantTerseEditLogging()) { - qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityItemID; - } - } else if (wantEditLogging() || wantTerseEditLogging()) { - qCDebug(entities) << "User [" << sourceNode->getUUID() << "] attempted to deleteentity. ID:" << entityItemID << " Filter rejected erase."; } - } deleteEntities(entityItemIDsToDelete, true, true); } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index ba786fbe98..4c5fcdb0f7 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -58,7 +58,7 @@ public: Add, Edit, Physics, - Erase + Delete }; EntityTree(bool shouldReaverage = false); virtual ~EntityTree(); @@ -194,6 +194,8 @@ public: int processEraseMessage(ReceivedMessage& message, const SharedNodePointer& sourceNode); int processEraseMessageDetails(const QByteArray& buffer, const SharedNodePointer& sourceNode); + bool shouldEraseEntity(EntityItemID entityID, const SharedNodePointer& sourceNode); + EntityTreeElementPointer getContainingElement(const EntityItemID& entityItemID) /*const*/; void addEntityMapEntry(EntityItemPointer entity); diff --git a/scripts/tutorials/entity_edit_filters/prevent-erase-in-zone-example.js b/scripts/tutorials/entity_edit_filters/prevent-delete-in-zone-example.js similarity index 81% rename from scripts/tutorials/entity_edit_filters/prevent-erase-in-zone-example.js rename to scripts/tutorials/entity_edit_filters/prevent-delete-in-zone-example.js index 356cc55079..94ee58738d 100644 --- a/scripts/tutorials/entity_edit_filters/prevent-erase-in-zone-example.js +++ b/scripts/tutorials/entity_edit_filters/prevent-delete-in-zone-example.js @@ -1,11 +1,11 @@ // -// prevent-erase-in-zone-example.js +// prevent-delete-in-zone-example.js // // // Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018 // Copyright 2018 High Fidelity, Inc. // -// This sample entity edit filter script will keep prevent any entity inside the zone from being erased. +// This sample entity edit filter script will keep prevent any entity inside the zone from being deleted. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -13,7 +13,7 @@ function filter(properties, type, originalProperties, zoneProperties) { - if (type == Entities.ERASE_FILTER_TYPE) { + if (type == Entities.DELETE_FILTER_TYPE) { return false; } return properties; From b883d006c83f6c333d74be14a4b22a90950a8cd1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 26 Jan 2018 18:26:48 -0800 Subject: [PATCH 12/46] add flags to support asking for specific messages, update examples --- libraries/entities/src/EntityEditFilters.cpp | 26 +++++++++++++++++++ libraries/entities/src/EntityEditFilters.h | 6 +++++ .../prevent-all-deletes.js | 22 ++++++++++++++++ .../prevent-delete-in-zone-example.js | 8 +++--- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 scripts/tutorials/entity_edit_filters/prevent-all-deletes.js diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 4b66b61d93..cd1982bdb4 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -62,6 +62,16 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper return false; } + // check to see if this filter wants to filter this message type + if ((!filterData.wantsToFilterEdit && filterType == EntityTree::FilterType::Edit) || + (!filterData.wantsToFilterPhysics && filterType == EntityTree::FilterType::Physics) || + (!filterData.wantsToFilterDelete && filterType == EntityTree::FilterType::Delete) || + (!filterData.wantsToFilterAdd && filterType == EntityTree::FilterType::Add)) { + + wasChanged = false; + return true; // accept the message + } + auto oldProperties = propertiesIn.getDesiredProperties(); auto specifiedProperties = propertiesIn.getChangedProperties(); propertiesIn.setDesiredProperties(specifiedProperties); @@ -254,6 +264,22 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { filterData.rejectAll=true; } + // if the wantsToFilterEdit is a boolean evaluate as a boolean, otherwise assume true + QScriptValue wantsToFilterAddValue = filterData.filterFn.property("wantsToFilterAdd"); + filterData.wantsToFilterAdd = wantsToFilterAddValue.isBool() ? wantsToFilterAddValue.toBool() : true; + + // if the wantsToFilterEdit is a boolean evaluate as a boolean, otherwise assume true + QScriptValue wantsToFilterEditValue = filterData.filterFn.property("wantsToFilterEdit"); + filterData.wantsToFilterEdit = wantsToFilterEditValue.isBool() ? wantsToFilterEditValue.toBool() : true; + + // if the wantsToFilterPhysics is a boolean evaluate as a boolean, otherwise assume true + QScriptValue wantsToFilterPhysicsValue = filterData.filterFn.property("wantsToFilterPhysics"); + filterData.wantsToFilterPhysics = wantsToFilterPhysicsValue.isBool() ? wantsToFilterPhysicsValue.toBool() : true; + + // if the wantsToFilterDelete is a boolean evaluate as a boolean, otherwise assume false + QScriptValue wantsToFilterDeleteValue = filterData.filterFn.property("wantsToFilterDelete"); + filterData.wantsToFilterDelete = wantsToFilterDeleteValue.isBool() ? wantsToFilterDeleteValue.toBool() : false; + // check to see if the filterFn has properties asking for Original props QScriptValue wantsOriginalPropertiesValue = filterData.filterFn.property("wantsOriginalProperties"); // if the wantsOriginalProperties is a boolean, or a string, or list of strings, then evaluate as follows: diff --git a/libraries/entities/src/EntityEditFilters.h b/libraries/entities/src/EntityEditFilters.h index be3df50d3f..cb99c97762 100644 --- a/libraries/entities/src/EntityEditFilters.h +++ b/libraries/entities/src/EntityEditFilters.h @@ -30,6 +30,12 @@ public: QScriptValue filterFn; bool wantsOriginalProperties { false }; bool wantsZoneProperties { false }; + + bool wantsToFilterAdd { true }; + bool wantsToFilterEdit { true }; + bool wantsToFilterPhysics { true }; + bool wantsToFilterDelete { true }; + EntityPropertyFlags includedOriginalProperties; EntityPropertyFlags includedZoneProperties; bool wantsZoneBoundingBox { false }; diff --git a/scripts/tutorials/entity_edit_filters/prevent-all-deletes.js b/scripts/tutorials/entity_edit_filters/prevent-all-deletes.js new file mode 100644 index 0000000000..0e2c54a04a --- /dev/null +++ b/scripts/tutorials/entity_edit_filters/prevent-all-deletes.js @@ -0,0 +1,22 @@ +// +// prevent-all-deletes.js +// +// +// Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018 +// Copyright 2018 High Fidelity, Inc. +// +// This sample entity edit filter script will prevent deletes of any entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +function filter() { + return false; // all deletes are blocked +} + +filter.wantsToFilterAdd = false; // don't run on adds +filter.wantsToFilterEdit = false; // don't run on edits +filter.wantsToFilterPhysics = false; // don't run on physics +filter.wantsToFilterDelete = true; // do run on deletes +filter; \ No newline at end of file diff --git a/scripts/tutorials/entity_edit_filters/prevent-delete-in-zone-example.js b/scripts/tutorials/entity_edit_filters/prevent-delete-in-zone-example.js index 94ee58738d..521bb94d00 100644 --- a/scripts/tutorials/entity_edit_filters/prevent-delete-in-zone-example.js +++ b/scripts/tutorials/entity_edit_filters/prevent-delete-in-zone-example.js @@ -5,13 +5,14 @@ // Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018 // Copyright 2018 High Fidelity, Inc. // -// This sample entity edit filter script will keep prevent any entity inside the zone from being deleted. +// This sample entity edit filter script will get all edits, adds, physcis, and deletes, but will only block +// deletes, and will pass through all others. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -function filter(properties, type, originalProperties, zoneProperties) { +function filter(properties, type) { if (type == Entities.DELETE_FILTER_TYPE) { return false; @@ -19,6 +20,5 @@ function filter(properties, type, originalProperties, zoneProperties) { return properties; } -filter.wantsOriginalProperties = true; -filter.wantsZoneProperties = true; +filter.wantsToFilterDelete = true; // do run on deletes filter; \ No newline at end of file From efc63a41e9551583c3eeb62c41e52e37789594c9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 26 Jan 2018 18:49:55 -0800 Subject: [PATCH 13/46] make sure true results for delete actually work, add more examples --- libraries/entities/src/EntityEditFilters.cpp | 13 +++++++++- ...event-add-of-entities-named-bob-example.js | 26 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 scripts/tutorials/entity_edit_filters/prevent-add-of-entities-named-bob-example.js diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index cd1982bdb4..12bf1ac231 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -125,7 +125,7 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper return false; } - if (result.isObject()){ + if (result.isObject()) { // make propertiesIn reflect the changes, for next filter... propertiesIn.copyFromScriptValue(result, false); @@ -134,6 +134,17 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper // Javascript objects are == only if they are the same object. To compare arbitrary values, we need to use JSON. auto out = QJsonValue::fromVariant(result.toVariant()); wasChanged |= (in != out); + } else if (result.isBool()) { + + // if the filter returned false, then it's authoritative + if (!result.toBool()) { + return false; + } + + // otherwise, assume it wants to pass all properties + propertiesOut = propertiesIn; + wasChanged = false; + } else { return false; } diff --git a/scripts/tutorials/entity_edit_filters/prevent-add-of-entities-named-bob-example.js b/scripts/tutorials/entity_edit_filters/prevent-add-of-entities-named-bob-example.js new file mode 100644 index 0000000000..03fbe97430 --- /dev/null +++ b/scripts/tutorials/entity_edit_filters/prevent-add-of-entities-named-bob-example.js @@ -0,0 +1,26 @@ +// +// prevent-add-of-entities-named-bob-example.js +// +// +// Created by Brad Hefta-Gaub to use Entities on Jan. 25, 2018 +// Copyright 2018 High Fidelity, Inc. +// +// This sample entity edit filter script will get all edits, adds, physcis, and deletes, but will only block +// deletes, and will pass through all others. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +function filter(properties, type) { + if (properties.name == "bob") { + return false; + } + return properties; +} + +filter.wantsToFilterAdd = true; // do run on add +filter.wantsToFilterEdit = false; // do not run on edit +filter.wantsToFilterPhysics = false; // do not run on physics +filter.wantsToFilterDelete = false; // do not run on delete +filter; \ No newline at end of file From 71a8e96d5a209a6435c480748559b9f05f1ef543 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 2 Feb 2018 18:14:12 -0800 Subject: [PATCH 14/46] fix several CR requests --- libraries/entities/src/EntityEditFilters.cpp | 29 ++++++++++---------- libraries/entities/src/EntityTree.cpp | 3 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/entities/src/EntityEditFilters.cpp b/libraries/entities/src/EntityEditFilters.cpp index 12bf1ac231..676b1ce518 100644 --- a/libraries/entities/src/EntityEditFilters.cpp +++ b/libraries/entities/src/EntityEditFilters.cpp @@ -41,8 +41,8 @@ QList EntityEditFilters::getZonesByPosition(glm::vec3& position) { return zones; } -bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, bool& wasChanged, - EntityTree::FilterType filterType, EntityItemID& itemID, EntityItemPointer& existingEntity) { +bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& propertiesIn, EntityItemProperties& propertiesOut, + bool& wasChanged, EntityTree::FilterType filterType, EntityItemID& itemID, EntityItemPointer& existingEntity) { // get the ids of all the zones (plus the global entity edit filter) that the position // lies within @@ -115,6 +115,15 @@ bool EntityEditFilters::filter(glm::vec3& position, EntityItemProperties& proper zoneValues.setProperty("boundingBox", boundingBox); } } + + // If this is an add or delete, or original properties weren't requested + // there won't be original properties in the args, but zone properties need + // to be the fourth parameter, so we need to pad the args accordingly + int EXPECTED_ARGS = 3; + if (args.length() < EXPECTED_ARGS) { + args << QScriptValue(); + } + assert(args.length() == EXPECTED_ARGS); // we MUST have 3 args by now! args << zoneValues; } } @@ -308,17 +317,8 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties); } } else if (wantsOriginalPropertiesValue.isArray()) { - auto length = wantsOriginalPropertiesValue.property("length").toInteger(); - for (int i = 0; i < length; i++) { - auto stringValue = wantsOriginalPropertiesValue.property(i).toString(); - if (!stringValue.isEmpty()) { - filterData.wantsOriginalProperties = true; - break; - } - } - if (filterData.wantsOriginalProperties) { - EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties); - } + EntityPropertyFlagsFromScriptValue(wantsOriginalPropertiesValue, filterData.includedOriginalProperties); + filterData.wantsOriginalProperties = !filterData.includedOriginalProperties.isEmpty(); } // check to see if the filterFn has properties asking for Zone props @@ -336,9 +336,10 @@ void EntityEditFilters::scriptRequestFinished(EntityItemID entityID) { auto stringValue = wantsZonePropertiesValue.toString(); filterData.wantsZoneProperties = !stringValue.isEmpty(); if (filterData.wantsZoneProperties) { - EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties); if (stringValue == "boundingBox") { filterData.wantsZoneBoundingBox = true; + } else { + EntityPropertyFlagsFromScriptValue(wantsZonePropertiesValue, filterData.includedZoneProperties); } } } else if (wantsZonePropertiesValue.isArray()) { diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 4cc643bae6..d5dc6399f4 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1882,8 +1882,7 @@ bool EntityTree::shouldEraseEntity(EntityItemID entityID, const SharedNodePointe if (wantEditLogging() || wantTerseEditLogging()) { qCDebug(entities) << "User [" << sourceNode->getUUID() << "] deleting entity. ID:" << entityID; } - } - else if (wantEditLogging() || wantTerseEditLogging()) { + } else if (wantEditLogging() || wantTerseEditLogging()) { qCDebug(entities) << "User [" << sourceNode->getUUID() << "] attempted to deleteentity. ID:" << entityID << " Filter rejected erase."; } From d842e532ee61e80b444e860ee851651dddeda741 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 4 Feb 2018 14:02:30 +1300 Subject: [PATCH 15/46] Remove Window.customPrompt() from JavaScript API --- interface/src/Application.cpp | 1 - .../scripting/WindowScriptingInterface.cpp | 22 ------------------- .../src/scripting/WindowScriptingInterface.h | 20 ----------------- libraries/ui/src/OffscreenUi.cpp | 17 -------------- libraries/ui/src/OffscreenUi.h | 2 -- 5 files changed, 62 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1a54c94d53..31c0b3555c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5857,7 +5857,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe DependencyManager::get().data()->setToolbarScriptingInterface(toolbarScriptingInterface); scriptEngine->registerGlobalObject("Window", DependencyManager::get().data()); - qScriptRegisterMetaType(scriptEngine.data(), CustomPromptResultToScriptValue, CustomPromptResultFromScriptValue); scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, LocationScriptingInterface::locationSetter, "Window"); // register `location` on the global object. diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index d419d7484b..65873dc1dc 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -32,20 +32,6 @@ static const QString LAST_BROWSE_LOCATION_SETTING = "LastBrowseLocation"; static const QString LAST_BROWSE_ASSETS_LOCATION_SETTING = "LastBrowseAssetsLocation"; -QScriptValue CustomPromptResultToScriptValue(QScriptEngine* engine, const CustomPromptResult& result) { - if (!result.value.isValid()) { - return QScriptValue::UndefinedValue; - } - - Q_ASSERT(result.value.userType() == qMetaTypeId()); - return engine->toScriptValue(result.value.toMap()); -} - -void CustomPromptResultFromScriptValue(const QScriptValue& object, CustomPromptResult& result) { - result.value = object.toVariant(); -} - - WindowScriptingInterface::WindowScriptingInterface() { const DomainHandler& domainHandler = DependencyManager::get()->getDomainHandler(); connect(&domainHandler, &DomainHandler::connectedToDomain, this, &WindowScriptingInterface::domainChanged); @@ -140,14 +126,6 @@ void WindowScriptingInterface::disconnectedFromDomain() { emit domainChanged(""); } -CustomPromptResult WindowScriptingInterface::customPrompt(const QVariant& config) { - CustomPromptResult result; - bool ok = false; - auto configMap = config.toMap(); - result.value = OffscreenUi::getCustomInfo(OffscreenUi::ICON_NONE, "", configMap, &ok); - return ok ? result : CustomPromptResult(); -} - QString fixupPathForMac(const QString& directory) { // On OS X `directory` does not work as expected unless a file is included in the path, so we append a bogus // filename if the directory is valid. diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index dc71611c5b..d5f40b83c6 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -22,17 +22,6 @@ #include -class CustomPromptResult { -public: - QVariant value; -}; - -Q_DECLARE_METATYPE(CustomPromptResult); - -QScriptValue CustomPromptResultToScriptValue(QScriptEngine* engine, const CustomPromptResult& result); -void CustomPromptResultFromScriptValue(const QScriptValue& object, CustomPromptResult& result); - - /**jsdoc * The Window API provides various facilities not covered elsewhere: window dimensions, window focus, normal or entity camera * view, clipboard, announcements, user connections, common dialog boxes, snapshots, file import, domain changes, domain @@ -142,15 +131,6 @@ public slots: */ void promptAsync(const QString& message = "", const QString& defaultText = ""); - /**jsdoc - * Prompt the user for input in a custom, modal dialog. - * @deprecated This function is deprecated and will soon be removed. - * @function Window.customPrompt - * @param {object} config - Configures the modal dialog. - * @returns {object} The user's response. - */ - CustomPromptResult customPrompt(const QVariant& config); - /**jsdoc * Prompt the user to choose a directory. Displays a modal dialog that navigates the directory tree. * @function Window.browseDir diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 221f5013bf..f28e1954e4 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -384,19 +384,6 @@ QString OffscreenUi::getItem(const Icon icon, const QString& title, const QStrin return result.toString(); } -QVariant OffscreenUi::getCustomInfo(const Icon icon, const QString& title, const QVariantMap& config, bool* ok) { - if (ok) { - *ok = false; - } - - QVariant result = DependencyManager::get()->customInputDialog(icon, title, config); - if (ok && result.isValid()) { - *ok = true; - } - - return result; -} - ModalDialogListener* OffscreenUi::getTextAsync(const Icon icon, const QString& title, const QString& label, const QString& text) { return DependencyManager::get()->inputDialogAsync(icon, title, label, text); } @@ -418,10 +405,6 @@ ModalDialogListener* OffscreenUi::getItemAsync(const Icon icon, const QString& t return inputDialogListener; } -ModalDialogListener* OffscreenUi::getCustomInfoAsync(const Icon icon, const QString& title, const QVariantMap& config) { - return DependencyManager::get()->customInputDialogAsync(icon, title, config); -} - QVariant OffscreenUi::inputDialog(const Icon icon, const QString& title, const QString& label, const QVariant& current) { if (QThread::currentThread() != thread()) { QVariant result; diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index ab3a209820..8e10ebde08 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -231,10 +231,8 @@ public: static QString getText(const Icon icon, const QString & title, const QString & label, const QString & text = QString(), bool * ok = 0); static QString getItem(const Icon icon, const QString & title, const QString & label, const QStringList & items, int current = 0, bool editable = true, bool * ok = 0); - static QVariant getCustomInfo(const Icon icon, const QString& title, const QVariantMap& config, bool* ok = 0); static ModalDialogListener* getTextAsync(const Icon icon, const QString & title, const QString & label, const QString & text = QString()); static ModalDialogListener* getItemAsync(const Icon icon, const QString & title, const QString & label, const QStringList & items, int current = 0, bool editable = true); - static ModalDialogListener* getCustomInfoAsync(const Icon icon, const QString& title, const QVariantMap& config); unsigned int getMenuUserDataId() const; QList &getModalDialogListeners(); From 8e2a3e8c99ff2bc1f36349db28d5d9a92d3dbfc7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 4 Feb 2018 14:15:48 +1300 Subject: [PATCH 16/46] Remove Overlays.getOverlayObject() from JavaScript API --- interface/src/ui/overlays/Overlays.cpp | 15 --------------- interface/src/ui/overlays/Overlays.h | 9 --------- scripts/system/libraries/WebTablet.js | 4 ---- 3 files changed, 28 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 6898b5ed2b..35274e4fbe 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -388,21 +388,6 @@ QString Overlays::getOverlayType(OverlayID overlayId) { return ""; } -QObject* Overlays::getOverlayObject(OverlayID id) { - if (QThread::currentThread() != thread()) { - QObject* result; - PROFILE_RANGE(script, __FUNCTION__); - BLOCKING_INVOKE_METHOD(this, "getOverlayObject", Q_RETURN_ARG(QObject*, result), Q_ARG(OverlayID, id)); - return result; - } - - Overlay::Pointer thisOverlay = getOverlay(id); - if (thisOverlay) { - return qobject_cast(&(*thisOverlay)); - } - return nullptr; -} - OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) { if (!_enabled) { return UNKNOWN_OVERLAY_ID; diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 113ee92b80..2da375f6e4 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -227,15 +227,6 @@ public slots: */ QString getOverlayType(OverlayID overlayId); - /**jsdoc - * Get the overlay script object. - * @function Overlays.getOverlayObject - * @deprecated This function is deprecated and will soon be removed. - * @param {Uuid} overlayID - The ID of the overlay to get the script object of. - * @returns {object} The script object for the overlay if found. - */ - QObject* getOverlayObject(OverlayID id); - /**jsdoc * Get the ID of the 2D overlay at a particular point on the screen or HUD. * @function Overlays.getOverlayAtPoint diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 05b4963280..2b7c0343e2 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -305,10 +305,6 @@ WebTablet.prototype.setScriptURL = function (scriptURL) { Overlays.editOverlay(this.webOverlayID, { scriptURL: scriptURL }); }; -WebTablet.prototype.getOverlayObject = function () { - return Overlays.getOverlayObject(this.webOverlayID); -}; - WebTablet.prototype.setWidth = function (width) { // imported from libraries/utils.js resizeTablet(width); From dd5cc8677d5a86f0772170b407916ecd2a84db63 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 4 Feb 2018 14:46:49 +1300 Subject: [PATCH 17/46] Remove Overlays.findRayIntersectionVector() from JavaScript API --- interface/src/ui/overlays/Overlays.h | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 2da375f6e4..3efe94c206 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -98,6 +98,11 @@ public: OverlayID addOverlay(Overlay* overlay) { return addOverlay(Overlay::Pointer(overlay)); } OverlayID addOverlay(const Overlay::Pointer& overlay); + RayToOverlayIntersectionResult findRayIntersectionVector(const PickRay& ray, bool precisionPicking, + const QVector& overlaysToInclude, + const QVector& overlaysToDiscard, + bool visibleOnly = false, bool collidableOnly = false); + bool mousePressEvent(QMouseEvent* event); bool mouseDoublePressEvent(QMouseEvent* event); bool mouseReleaseEvent(QMouseEvent* event); @@ -347,28 +352,6 @@ public slots: bool visibleOnly = false, bool collidableOnly = false); - // TODO: Apart from the name, this function signature on JavaScript is identical to that of findRayIntersection() and should - // probably be removed from the JavaScript API so as not to cause confusion. - /**jsdoc - * Find the closest 3D overlay intersected by a {@link PickRay}. - * @function Overlays.findRayIntersectionVector - * @deprecated Use {@link Overlays.findRayIntersection} instead; it has identical parameters and results. - * @param {PickRay} pickRay - The PickRay to use for finding overlays. - * @param {boolean} [precisionPicking=false] - Unused; exists to match Entity API. - * @param {Array.} [overlayIDsToInclude=[]] - Whitelist for intersection test. If empty then the result isn't limited - * to overlays in the list. - * @param {Array.} [overlayIDsToExclude=[]] - Blacklist for intersection test. If empty then the result doesn't - * exclude overlays in the list. - * @param {boolean} [visibleOnly=false] - Unused; exists to match Entity API. - * @param {boolean} [collidableOnly=false] - Unused; exists to match Entity API. - * @returns {Overlays.RayToOverlayIntersectionResult} The closest 3D overlay intersected by pickRay, taking - * into account overlayIDsToInclude and overlayIDsToExclude if they're not empty. - */ - RayToOverlayIntersectionResult findRayIntersectionVector(const PickRay& ray, bool precisionPicking, - const QVector& overlaysToInclude, - const QVector& overlaysToDiscard, - bool visibleOnly = false, bool collidableOnly = false); - /**jsdoc * Return a list of 3D overlays with bounding boxes that touch a search sphere. * @function Overlays.findOverlays From 0c0734a255a181cc6c5ee1f1d62f972d894d01cf Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 4 Feb 2018 14:54:14 +1300 Subject: [PATCH 18/46] Remove unused Overlays property, borderSize, and associated code --- interface/src/Application.cpp | 1 - interface/src/ui/overlays/Cube3DOverlay.cpp | 13 ------------- interface/src/ui/overlays/Cube3DOverlay.h | 5 ----- interface/src/ui/overlays/Shape3DOverlay.cpp | 12 ------------ interface/src/ui/overlays/Shape3DOverlay.h | 5 ----- scripts/developer/debugging/queryAACubeInspector.js | 1 - scripts/system/libraries/entitySelectionTool.js | 12 ++++-------- 7 files changed, 4 insertions(+), 45 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 31c0b3555c..bc567c0452 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4717,7 +4717,6 @@ void Application::setKeyboardFocusHighlight(const glm::vec3& position, const glm if (_keyboardFocusHighlightID == UNKNOWN_OVERLAY_ID || !getOverlays().isAddedOverlay(_keyboardFocusHighlightID)) { _keyboardFocusHighlight = std::make_shared(); _keyboardFocusHighlight->setAlpha(1.0f); - _keyboardFocusHighlight->setBorderSize(1.0f); _keyboardFocusHighlight->setColor({ 0xFF, 0xEF, 0x00 }); _keyboardFocusHighlight->setIsSolid(false); _keyboardFocusHighlight->setPulseMin(0.5); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index f13f782482..29c4f592f5 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -125,13 +125,6 @@ Cube3DOverlay* Cube3DOverlay::createClone() const { void Cube3DOverlay::setProperties(const QVariantMap& properties) { Volume3DOverlay::setProperties(properties); - - auto borderSize = properties["borderSize"]; - - if (borderSize.isValid()) { - float value = borderSize.toFloat(); - setBorderSize(value); - } } /**jsdoc @@ -177,14 +170,8 @@ void Cube3DOverlay::setProperties(const QVariantMap& properties) { * parentID is an avatar skeleton. A value of 65535 means "no joint". * * @property {Vec3} dimensions - The dimensions of the overlay. Synonyms: scale, size. - * - * @property {number} borderSize - Not used. */ QVariant Cube3DOverlay::getProperty(const QString& property) { - if (property == "borderSize") { - return _borderSize; - } - return Volume3DOverlay::getProperty(property); } diff --git a/interface/src/ui/overlays/Cube3DOverlay.h b/interface/src/ui/overlays/Cube3DOverlay.h index e7b58ad911..5d83cbb2c1 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.h +++ b/interface/src/ui/overlays/Cube3DOverlay.h @@ -29,10 +29,6 @@ public: virtual Cube3DOverlay* createClone() const override; - float getBorderSize() const { return _borderSize; } - - void setBorderSize(float value) { _borderSize = value; } - void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -40,7 +36,6 @@ protected: Transform evalRenderTransform() override; private: - float _borderSize; // edges on a cube std::array _geometryIds; }; diff --git a/interface/src/ui/overlays/Shape3DOverlay.cpp b/interface/src/ui/overlays/Shape3DOverlay.cpp index 97342a80ab..64acdcccdb 100644 --- a/interface/src/ui/overlays/Shape3DOverlay.cpp +++ b/interface/src/ui/overlays/Shape3DOverlay.cpp @@ -99,13 +99,6 @@ void Shape3DOverlay::setProperties(const QVariantMap& properties) { } } } - - auto borderSize = properties["borderSize"]; - - if (borderSize.isValid()) { - float value = borderSize.toFloat(); - setBorderSize(value); - } } /**jsdoc @@ -153,13 +146,8 @@ void Shape3DOverlay::setProperties(const QVariantMap& properties) { * @property {Vec3} dimensions - The dimensions of the overlay. Synonyms: scale, size. * * @property {Shape} shape=Hexagon - The geometrical shape of the overlay. - * @property {number} borderSize - Not used. */ QVariant Shape3DOverlay::getProperty(const QString& property) { - if (property == "borderSize") { - return _borderSize; - } - if (property == "shape") { return shapeStrings[_shape]; } diff --git a/interface/src/ui/overlays/Shape3DOverlay.h b/interface/src/ui/overlays/Shape3DOverlay.h index 7fc95ec981..0196c707d7 100644 --- a/interface/src/ui/overlays/Shape3DOverlay.h +++ b/interface/src/ui/overlays/Shape3DOverlay.h @@ -30,10 +30,6 @@ public: virtual Shape3DOverlay* createClone() const override; - float getBorderSize() const { return _borderSize; } - - void setBorderSize(float value) { _borderSize = value; } - void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -41,7 +37,6 @@ protected: Transform evalRenderTransform() override; private: - float _borderSize; GeometryCache::Shape _shape { GeometryCache::Hexagon }; }; diff --git a/scripts/developer/debugging/queryAACubeInspector.js b/scripts/developer/debugging/queryAACubeInspector.js index 2d585ffce4..d8a87c3cf5 100644 --- a/scripts/developer/debugging/queryAACubeInspector.js +++ b/scripts/developer/debugging/queryAACubeInspector.js @@ -40,7 +40,6 @@ function updateOverlay(entityID, queryAACube) { blue: 255 }, alpha: 1, - // borderSize: ..., solid: false }); } diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index b8ba146757..4133447f97 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -339,8 +339,7 @@ SelectionDisplay = (function() { solid: grabberSolid, visible: false, dashed: false, - drawInFront: true, - borderSize: 1.4 + drawInFront: true }; var grabberPropertiesEdge = { @@ -351,8 +350,7 @@ SelectionDisplay = (function() { solid: grabberSolid, visible: false, dashed: false, - drawInFront: true, - borderSize: 1.4 + drawInFront: true }; var grabberPropertiesFace = { @@ -363,8 +361,7 @@ SelectionDisplay = (function() { solid: grabberSolid, visible: false, dashed: false, - drawInFront: true, - borderSize: 1.4 + drawInFront: true }; var grabberPropertiesCloner = { @@ -375,8 +372,7 @@ SelectionDisplay = (function() { solid: grabberSolid, visible: false, dashed: false, - drawInFront: true, - borderSize: 1.4 + drawInFront: true }; var spotLightLineProperties = { From 42498314f1d783727707a0a8b9b3c54f31580371 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 4 Feb 2018 14:59:06 +1300 Subject: [PATCH 19/46] Remove further unused variable noticed in passing --- interface/src/ui/ApplicationOverlay.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.h b/interface/src/ui/ApplicationOverlay.h index b36b4f02df..23055cf246 100644 --- a/interface/src/ui/ApplicationOverlay.h +++ b/interface/src/ui/ApplicationOverlay.h @@ -42,8 +42,6 @@ private: int _domainStatusBorder; int _magnifierBorder; - ivec2 _previousBorderSize{ -1 }; - gpu::TexturePointer _uiTexture; gpu::TexturePointer _overlayDepthTexture; gpu::TexturePointer _overlayColorTexture; From efddec621f4f98581227285529fec80ebfb986f2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 4 Feb 2018 15:16:20 +1300 Subject: [PATCH 20/46] Remove Menu.addActionGroup() and removeActionGroup() from JavaScript API --- interface/src/Menu.cpp | 1 + .../src/scripting/MenuScriptingInterface.cpp | 16 ---------------- .../src/scripting/MenuScriptingInterface.h | 7 ------- libraries/ui/src/ui/Menu.cpp | 18 ------------------ libraries/ui/src/ui/Menu.h | 3 --- 5 files changed, 1 insertion(+), 44 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index f3d8ea2344..464de87fdb 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -210,6 +210,7 @@ Menu::Menu() { auto avatarEntitiesBookmarks = DependencyManager::get(); avatarEntitiesBookmarks->setupMenus(this, avatarMenu); + // Display menu ---------------------------------- // FIXME - this is not yet matching Alan's spec because it doesn't have // menus for "2D"/"3D" - we need to add support for detecting the appropriate diff --git a/interface/src/scripting/MenuScriptingInterface.cpp b/interface/src/scripting/MenuScriptingInterface.cpp index d9372978e8..551cb36e65 100644 --- a/interface/src/scripting/MenuScriptingInterface.cpp +++ b/interface/src/scripting/MenuScriptingInterface.cpp @@ -94,22 +94,6 @@ bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString& return result; } -void MenuScriptingInterface::addActionGroup(const QString& groupName, const QStringList& actionList, - const QString& selected) { - static const char* slot = SLOT(menuItemTriggered()); - QMetaObject::invokeMethod(Menu::getInstance(), "addActionGroup", - Q_ARG(const QString&, groupName), - Q_ARG(const QStringList&, actionList), - Q_ARG(const QString&, selected), - Q_ARG(QObject*, this), - Q_ARG(const char*, slot)); -} - -void MenuScriptingInterface::removeActionGroup(const QString& groupName) { - QMetaObject::invokeMethod(Menu::getInstance(), "removeActionGroup", - Q_ARG(const QString&, groupName)); -} - bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) { if (QThread::currentThread() == qApp->thread()) { return Menu::getInstance()->isOptionChecked(menuOption); diff --git a/interface/src/scripting/MenuScriptingInterface.h b/interface/src/scripting/MenuScriptingInterface.h index 59cfc76d21..b4f6178d33 100644 --- a/interface/src/scripting/MenuScriptingInterface.h +++ b/interface/src/scripting/MenuScriptingInterface.h @@ -163,13 +163,6 @@ public slots: */ bool menuItemExists(const QString& menuName, const QString& menuitem); - /** - * TODO: Not working; don't document until fixed. - */ - void addActionGroup(const QString& groupName, const QStringList& actionList, - const QString& selected = QString()); - void removeActionGroup(const QString& groupName); - /**jsdoc * Check whether a checkable menu item is checked. * @function Menu.isOptionChecked diff --git a/libraries/ui/src/ui/Menu.cpp b/libraries/ui/src/ui/Menu.cpp index 4e61eba28f..577e2564a7 100644 --- a/libraries/ui/src/ui/Menu.cpp +++ b/libraries/ui/src/ui/Menu.cpp @@ -539,24 +539,6 @@ void Menu::setGroupingIsVisible(const QString& grouping, bool isVisible) { QMenuBar::repaint(); } -void Menu::addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected, QObject* receiver, const char* slot) { - auto menu = addMenu(groupName); - - QActionGroup* actionGroup = new QActionGroup(menu); - actionGroup->setExclusive(true); - - for (auto action : actionList) { - auto item = addCheckableActionToQMenuAndActionHash(menu, action, 0, action == selected, receiver, slot); - actionGroup->addAction(item); - } - - QMenuBar::repaint(); -} - -void Menu::removeActionGroup(const QString& groupName) { - removeMenu(groupName); -} - MenuWrapper::MenuWrapper(ui::Menu& rootMenu, QMenu* menu) : _rootMenu(rootMenu), _realMenu(menu) { auto offscreenUi = DependencyManager::get(); offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) { diff --git a/libraries/ui/src/ui/Menu.h b/libraries/ui/src/ui/Menu.h index 25f8f74063..4ca69b44e6 100644 --- a/libraries/ui/src/ui/Menu.h +++ b/libraries/ui/src/ui/Menu.h @@ -110,9 +110,6 @@ public slots: void removeSeparator(const QString& menuName, const QString& separatorName); void removeMenuItem(const QString& menuName, const QString& menuitem); bool menuItemExists(const QString& menuName, const QString& menuitem); - void addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected = QString(), - QObject* receiver = nullptr, const char* slot = nullptr); - void removeActionGroup(const QString& groupName); bool isOptionChecked(const QString& menuOption) const; void setIsOptionChecked(const QString& menuOption, bool isChecked); From 615e54620b3a0e8da9160a37b956ff012b5943d2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 4 Feb 2018 15:38:33 +1300 Subject: [PATCH 21/46] Remove Menu.isInfoViewVisible() and closeInfoView() from JavaScript API --- .../src/scripting/MenuScriptingInterface.cpp | 16 ---------------- interface/src/scripting/MenuScriptingInterface.h | 6 ------ libraries/ui/src/ui/Menu.cpp | 10 ---------- libraries/ui/src/ui/Menu.h | 3 --- scripts/system/help.js | 10 ---------- 5 files changed, 45 deletions(-) diff --git a/interface/src/scripting/MenuScriptingInterface.cpp b/interface/src/scripting/MenuScriptingInterface.cpp index 551cb36e65..d6dc2fa703 100644 --- a/interface/src/scripting/MenuScriptingInterface.cpp +++ b/interface/src/scripting/MenuScriptingInterface.cpp @@ -131,19 +131,3 @@ void MenuScriptingInterface::setMenuEnabled(const QString& menuOption, bool isCh void MenuScriptingInterface::triggerOption(const QString& menuOption) { QMetaObject::invokeMethod(Menu::getInstance(), "triggerOption", Q_ARG(const QString&, menuOption)); } - -void MenuScriptingInterface::closeInfoView(const QString& path) { - QMetaObject::invokeMethod(Menu::getInstance(), "closeInfoView", Q_ARG(const QString&, path)); -} - -bool MenuScriptingInterface::isInfoViewVisible(const QString& path) { - if (QThread::currentThread() == qApp->thread()) { - return Menu::getInstance()->isInfoViewVisible(path); - } - - bool result; - BLOCKING_INVOKE_METHOD(Menu::getInstance(), "isInfoViewVisible", - Q_RETURN_ARG(bool, result), Q_ARG(const QString&, path)); - return result; -} - diff --git a/interface/src/scripting/MenuScriptingInterface.h b/interface/src/scripting/MenuScriptingInterface.h index b4f6178d33..649c444eaf 100644 --- a/interface/src/scripting/MenuScriptingInterface.h +++ b/interface/src/scripting/MenuScriptingInterface.h @@ -215,12 +215,6 @@ public slots: */ void setMenuEnabled(const QString& menuName, bool isEnabled); - /** - * TODO: Not used or useful; will not document until used. - */ - void closeInfoView(const QString& path); - bool isInfoViewVisible(const QString& path); - signals: /**jsdoc * Triggered when a menu item is clicked (or triggered by {@link Menu.triggerOption}). diff --git a/libraries/ui/src/ui/Menu.cpp b/libraries/ui/src/ui/Menu.cpp index 577e2564a7..d4566dc151 100644 --- a/libraries/ui/src/ui/Menu.cpp +++ b/libraries/ui/src/ui/Menu.cpp @@ -268,16 +268,6 @@ bool Menu::isOptionChecked(const QString& menuOption) const { return false; } -void Menu::closeInfoView(const QString& path) { - auto offscreenUi = DependencyManager::get(); - offscreenUi->hide(path); -} - -bool Menu::isInfoViewVisible(const QString& path) { - auto offscreenUi = DependencyManager::get(); - return offscreenUi->isVisible(path); -} - void Menu::triggerOption(const QString& menuOption) { QAction* action = _actionHash.value(menuOption); if (action) { diff --git a/libraries/ui/src/ui/Menu.h b/libraries/ui/src/ui/Menu.h index 4ca69b44e6..2977a5330a 100644 --- a/libraries/ui/src/ui/Menu.h +++ b/libraries/ui/src/ui/Menu.h @@ -122,9 +122,6 @@ public slots: void toggleDeveloperMenus(); void toggleAdvancedMenus(); - bool isInfoViewVisible(const QString& path); - void closeInfoView(const QString& path); - void triggerOption(const QString& menuOption); static bool isSomeSubmenuShown() { return _isSomeSubmenuShown; } diff --git a/scripts/system/help.js b/scripts/system/help.js index 9ab7fa3fb3..494b0a2cdb 100644 --- a/scripts/system/help.js +++ b/scripts/system/help.js @@ -47,22 +47,12 @@ button.clicked.connect(onClicked); tablet.screenChanged.connect(onScreenChanged); - var POLL_RATE = 500; - var interval = Script.setInterval(function () { - var visible = Menu.isInfoViewVisible('InfoView_html/help.html'); - if (visible !== enabled) { - enabled = visible; - button.editProperties({isActive: enabled}); - } - }, POLL_RATE); - Script.scriptEnding.connect(function () { if (onHelpScreen) { tablet.gotoHomeScreen(); } button.clicked.disconnect(onClicked); tablet.screenChanged.disconnect(onScreenChanged); - Script.clearInterval(interval); if (tablet) { tablet.removeButton(button); } From e3f9cce6e6a3548c917f909b473f3bbb9bcfe105 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 6 Feb 2018 12:14:33 +1300 Subject: [PATCH 22/46] Fix Record app dialog not always opening successfully --- .../marketplace/record/html/js/record.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/unpublishedScripts/marketplace/record/html/js/record.js b/unpublishedScripts/marketplace/record/html/js/record.js index aae4d1c89a..39278e9d7e 100644 --- a/unpublishedScripts/marketplace/record/html/js/record.js +++ b/unpublishedScripts/marketplace/record/html/js/record.js @@ -252,16 +252,17 @@ function onFinishOnOpenClicked() { } function signalBodyLoaded() { - EventBridge.emitWebEvent(JSON.stringify({ - type: EVENT_BRIDGE_TYPE, - action: BODY_LOADED_ACTION - })); + var EVENTBRIDGE_OPEN_DELAY = 500; // Delay required to ensure EventBridge is ready for use. + setTimeout(function () { + EventBridge.scriptEventReceived.connect(onScriptEventReceived); + EventBridge.emitWebEvent(JSON.stringify({ + type: EVENT_BRIDGE_TYPE, + action: BODY_LOADED_ACTION + })); + }, EVENTBRIDGE_OPEN_DELAY); } function onBodyLoaded() { - - EventBridge.scriptEventReceived.connect(onScriptEventReceived); - elRecordings = document.getElementById("recordings"); elRecordingsTable = document.getElementById("recordings-table"); From 7f6471fcd189ad04feaa3cec153583bb3752df69 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 6 Feb 2018 13:24:41 +1300 Subject: [PATCH 23/46] Fix recording just made not being automatically played back --- unpublishedScripts/marketplace/record/record.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unpublishedScripts/marketplace/record/record.js b/unpublishedScripts/marketplace/record/record.js index 68c7ea3f5a..dda78dbd02 100644 --- a/unpublishedScripts/marketplace/record/record.js +++ b/unpublishedScripts/marketplace/record/record.js @@ -139,7 +139,8 @@ } function setMappingCallback(status) { - if (status !== "") { + // FIXME: "" is for RC < 63, null is for RC >= 63. Remove the former when RC63 is no longer used. + if (status !== "" && status !== null) { error("Error mapping recording to " + mappingPath + " on Asset Server!", status); return; } From 75cf22ca7fe7bab1c59ca08d4d99bccf0eba9cf6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 7 Feb 2018 09:45:21 +1300 Subject: [PATCH 24/46] Remove support for old High Fidelity versions --- unpublishedScripts/marketplace/record/record.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/unpublishedScripts/marketplace/record/record.js b/unpublishedScripts/marketplace/record/record.js index dda78dbd02..08400dbb85 100644 --- a/unpublishedScripts/marketplace/record/record.js +++ b/unpublishedScripts/marketplace/record/record.js @@ -139,8 +139,7 @@ } function setMappingCallback(status) { - // FIXME: "" is for RC < 63, null is for RC >= 63. Remove the former when RC63 is no longer used. - if (status !== "" && status !== null) { + if (status !== null) { error("Error mapping recording to " + mappingPath + " on Asset Server!", status); return; } From adb6f66a05a7ce4d9181712e5c24b8222983e70b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 8 Feb 2018 09:51:48 +1300 Subject: [PATCH 25/46] Handle tablet entities and overlays not being available --- scripts/system/audio.js | 5 +++-- .../system/controllers/controllerDispatcher.js | 2 +- .../controllers/controllerModules/inEditMode.js | 7 ++++--- .../controllerModules/inVREditMode.js | 5 +++-- .../controllerModules/nearParentGrabOverlay.js | 4 ++-- .../controllers/controllerModules/stylusInput.js | 4 ++-- scripts/system/controllers/grab.js | 5 ++++- scripts/system/edit.js | 8 ++++---- scripts/system/help.js | 5 ++--- scripts/system/libraries/WebTablet.js | 5 ++++- scripts/system/libraries/entitySelectionTool.js | 11 ++++++++--- scripts/system/libraries/utils.js | 14 ++++++++++++++ scripts/system/marketplaces/marketplaces.js | 5 +++-- scripts/system/menu.js | 5 +++-- scripts/system/tablet-ui/tabletUI.js | 16 ++++++++-------- scripts/system/tablet-users.js | 5 ++--- .../marketplace/shapes/modules/laser.js | 12 +++++++++++- 17 files changed, 78 insertions(+), 40 deletions(-) diff --git a/scripts/system/audio.js b/scripts/system/audio.js index a93177ca38..ee82c0c6ea 100644 --- a/scripts/system/audio.js +++ b/scripts/system/audio.js @@ -42,8 +42,9 @@ function onClicked() { // for toolbar-mode: go back to home screen, this will close the window. tablet.gotoHomeScreen(); } else { - var entity = HMD.tabletID; - Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) }); + if (HMD.tabletID) { + Entities.editEntity(HMD.tabletID, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) }); + } tablet.loadQMLSource(AUDIO_QML_SOURCE); } } diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 16f1d086b7..b2455b3f5a 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -146,7 +146,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); }; this.setIgnorePointerItems = function() { - if (HMD.tabletID !== this.tabletID) { + if (HMD.tabletID && HMD.tabletID !== this.tabletID) { this.tabletID = HMD.tabletID; Pointers.setIgnoreItems(_this.leftPointer, _this.blacklist); Pointers.setIgnoreItems(_this.rightPointer, _this.blacklist); diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index 763258573d..202290f2df 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -32,7 +32,7 @@ Script.include("/~/system/libraries/utils.js"); this.nearTablet = function(overlays) { for (var i = 0; i < overlays.length; i++) { - if (overlays[i] === HMD.tabletID) { + if (HMD.tabletID && overlays[i] === HMD.tabletID) { return true; } } @@ -44,7 +44,8 @@ Script.include("/~/system/libraries/utils.js"); }; this.pointingAtTablet = function(objectID) { - return objectID === HMD.tabletScreenID || objectID === HMD.homeButtonID; + return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) + || (HMD.homeButtonID && objectID === HMD.homeButtonID); }; this.sendPickData = function(controllerData) { @@ -106,7 +107,7 @@ Script.include("/~/system/libraries/utils.js"); if (nearOverlay) { var nearOverlayReady = nearOverlay.isReady(controllerData); - if (nearOverlayReady.active && nearOverlay.grabbedThingID === HMD.tabletID) { + if (nearOverlayReady.active && HMD.tabletID && nearOverlay.grabbedThingID === HMD.tabletID) { return this.exitModule(); } } diff --git a/scripts/system/controllers/controllerModules/inVREditMode.js b/scripts/system/controllers/controllerModules/inVREditMode.js index 38eca65dd3..7b78d5e1c4 100644 --- a/scripts/system/controllers/controllerModules/inVREditMode.js +++ b/scripts/system/controllers/controllerModules/inVREditMode.js @@ -31,7 +31,8 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); ); this.pointingAtTablet = function (objectID) { - return objectID === HMD.tabletScreenID || objectID === HMD.homeButtonID; + return (HMD.tabletScreenID && objectID === HMD.tabletScreenID) + || (HMD.homeButtonID && objectID === HMD.homeButtonID); }; this.isReady = function (controllerData) { @@ -76,7 +77,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); : "LeftNearParentingGrabOverlay"); if (nearOverlay) { var nearOverlayReady = nearOverlay.isReady(controllerData); - if (nearOverlayReady.active && nearOverlay.grabbedThingID === HMD.tabletID) { + if (nearOverlayReady.active && HMD.tabletID && nearOverlay.grabbedThingID === HMD.tabletID) { return makeRunningValues(false, [], []); } } diff --git a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js index fa0fe31de2..0f876816b3 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js @@ -117,7 +117,7 @@ Script.include("/~/system/libraries/utils.js"); Overlays.editOverlay(this.grabbedThingID, reparentProps); // resizeTablet to counter adjust offsets to account for change of scale from sensorToWorldMatrix - if (this.grabbedThingID === HMD.tabletID) { + if (HMD.tabletID && this.grabbedThingID === HMD.tabletID) { resizeTablet(getTabletWidthFromSettings(), reparentProps.parentJointIndex); } @@ -143,7 +143,7 @@ Script.include("/~/system/libraries/utils.js"); }); // resizeTablet to counter adjust offsets to account for change of scale from sensorToWorldMatrix - if (this.grabbedThingID === HMD.tabletID) { + if (HMD.tabletID && this.grabbedThingID === HMD.tabletID) { resizeTablet(getTabletWidthFromSettings(), this.previousParentJointIndex[this.grabbedThingID]); } } diff --git a/scripts/system/controllers/controllerModules/stylusInput.js b/scripts/system/controllers/controllerModules/stylusInput.js index aa65135289..a512fd89db 100644 --- a/scripts/system/controllers/controllerModules/stylusInput.js +++ b/scripts/system/controllers/controllerModules/stylusInput.js @@ -20,7 +20,7 @@ Script.include("/~/system/libraries/controllers.js"); var stylusTargetIDs = []; for (var index = 0; index < stylusTargets.length; index++) { var stylusTarget = stylusTargets[index]; - if (stylusTarget.distance <= maxNormalDistance && stylusTarget.id !== HMD.tabletID) { + if (stylusTarget.distance <= maxNormalDistance && !(HMD.tabletID && stylusTarget.id === HMD.tabletID)) { stylusTargetIDs.push(stylusTarget.id); } } @@ -96,7 +96,7 @@ Script.include("/~/system/libraries/controllers.js"); var i, stylusTarget; for (i = 0; i < candidateOverlays.length; i++) { - if (candidateOverlays[i] !== HMD.tabletID && + if (!(HMD.tabletID && candidateOverlays[i] === HMD.tabletID) && Overlays.getProperty(candidateOverlays[i], "visible")) { stylusTarget = getOverlayDistance(controllerPosition, candidateOverlays[i]); if (stylusTarget) { diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index a51cea67f8..b62cb3dd90 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -263,7 +263,10 @@ function Grabber() { filter: Picks.PICK_OVERLAYS, enabled: true }); - RayPick.setIncludeItems(this.mouseRayOverlays, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); + var tabletItems = getMainTabletIDs(); + if (tabletItems.length > 0) { + RayPick.setIncludeItems(this.mouseRayOverlays, tabletItems); + } var renderStates = [{name: "grabbed", end: beacon}]; this.mouseRayEntities = Pointers.createPointer(PickType.Ray, { joint: "Mouse", diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 863c185cb4..42c1cc4b51 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -31,6 +31,7 @@ Script.include([ "libraries/entityCameraTool.js", "libraries/gridTool.js", "libraries/entityList.js", + "libraries/utils.js", "particle_explorer/particleExplorerTool.js", "libraries/entityIconOverlayManager.js" ]); @@ -733,8 +734,7 @@ function findClickedEntity(event) { } var pickRay = Camera.computePickRay(event.x, event.y); - - var overlayResult = Overlays.findRayIntersection(pickRay, true, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); + var overlayResult = Overlays.findRayIntersection(pickRay, true, getMainTabletIDs()); if (overlayResult.intersects) { return null; } @@ -922,7 +922,7 @@ function mouseReleaseEvent(event) { function wasTabletClicked(event) { var rayPick = Camera.computePickRay(event.x, event.y); - var result = Overlays.findRayIntersection(rayPick, true, [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID]); + var result = Overlays.findRayIntersection(rayPick, true, getMainTabletIDs()); return result.intersects; } @@ -945,7 +945,7 @@ function mouseClickEvent(event) { toolBar.setActive(true); var pickRay = result.pickRay; var foundEntity = result.entityID; - if (foundEntity === HMD.tabletID) { + if (HMD.tabletID && foundEntity === HMD.tabletID) { return; } properties = Entities.getEntityProperties(foundEntity); diff --git a/scripts/system/help.js b/scripts/system/help.js index 9ab7fa3fb3..6fe0da8a86 100644 --- a/scripts/system/help.js +++ b/scripts/system/help.js @@ -30,9 +30,8 @@ if (onHelpScreen) { tablet.gotoHomeScreen(); } else { - var tabletEntity = HMD.tabletID; - if (tabletEntity) { - Entities.editEntity(tabletEntity, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})}); + if (HMD.tabletID) { + Entities.editEntity(HMD.tabletID, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})}); } Menu.triggerOption('Help...'); onHelpScreen = true; diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 05b4963280..c4ad2b43a7 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -334,7 +334,7 @@ WebTablet.prototype.destroy = function () { }; WebTablet.prototype.geometryChanged = function (geometry) { - if (!HMD.active) { + if (!HMD.active && HMD.tabletID) { var tabletProperties = {}; // compute position, rotation & parentJointIndex of the tablet this.calculateTabletAttachmentProperties(NO_HANDS, false, tabletProperties); @@ -462,6 +462,9 @@ WebTablet.prototype.calculateTabletAttachmentProperties = function (hand, useMou }; WebTablet.prototype.onHmdChanged = function () { + if (!HMD.tabletID) { + return; + } var tabletProperties = {}; // compute position, rotation & parentJointIndex of the tablet this.calculateTabletAttachmentProperties(NO_HANDS, false, tabletProperties); diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index b8ba146757..eea541a430 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -19,7 +19,10 @@ HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; SPACE_LOCAL = "local"; SPACE_WORLD = "world"; -Script.include("./controllers.js"); +Script.include([ + "./controllers.js", + "./utils.js" +]); function objectTranslationPlanePoint(position, dimensions) { var newPosition = { x: position.x, y: position.y, z: position.z }; @@ -3650,7 +3653,8 @@ SelectionDisplay = (function() { var pickRay = generalComputePickRay(event.x, event.y); // TODO_Case6491: Move this out to setup just to make it once - var interactiveOverlays = [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID, selectionBox]; + var interactiveOverlays = getMainTabletIDs(); + interactiveOverlays.push(selectionBox); for (var key in grabberTools) { if (grabberTools.hasOwnProperty(key)) { interactiveOverlays.push(key); @@ -3663,7 +3667,8 @@ SelectionDisplay = (function() { var results = testRayIntersect(pickRay, interactiveOverlays); if (results.intersects) { var hitOverlayID = results.overlayID; - if ((hitOverlayID === HMD.tabletID) || (hitOverlayID === HMD.tabletScreenID) || (hitOverlayID === HMD.homeButtonID)) { + if ((HMD.tabletID && hitOverlayID === HMD.tabletID) || (HMD.tabletScreenID && hitOverlayID === HMD.tabletScreenID) + || (HMD.homeButtonID && hitOverlayID === HMD.homeButtonID)) { // EARLY EXIT-(mouse clicks on the tablet should override the edit affordances) return false; } diff --git a/scripts/system/libraries/utils.js b/scripts/system/libraries/utils.js index bc83cc582c..442a9f6d24 100644 --- a/scripts/system/libraries/utils.js +++ b/scripts/system/libraries/utils.js @@ -428,3 +428,17 @@ resizeTablet = function (width, newParentJointIndex, sensorToWorldScaleOverride) dimensions: { x: homeButtonDim, y: homeButtonDim, z: homeButtonDim } }); }; + +getMainTabletIDs = function () { + var tabletIDs = []; + if (HMD.tabletID) { + tabletIDs.push(HMD.tabletID); + } + if (HMD.tabletScreenID) { + tabletIDs.push(HMD.tabletScreenID); + } + if (HMD.homeButtonID) { + tabletIDs.push(HMD.homeButtonID); + } + return tabletIDs; +}; \ No newline at end of file diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index facb932eb0..5d905f7553 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -104,8 +104,9 @@ var selectionDisplay = null; // for gridTool.js to ignore tablet.gotoHomeScreen(); } else { Wallet.refreshWalletStatus(); - var entity = HMD.tabletID; - Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) }); + if (HMD.tabletID) { + Entities.editEntity(HMD.tabletID, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) }); + } showMarketplace(); } } diff --git a/scripts/system/menu.js b/scripts/system/menu.js index c7a44d3e48..c27dae6780 100644 --- a/scripts/system/menu.js +++ b/scripts/system/menu.js @@ -28,8 +28,9 @@ var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet- // for toolbar-mode: go back to home screen, this will close the window. tablet.gotoHomeScreen(); } else { - var entity = HMD.tabletID; - Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})}); + if (HMD.tabletID) { + Entities.editEntity(HMD.tabletID, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) }); + } tablet.gotoMenuScreen(); } } diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index 36a1cbcdd9..100d0e82ee 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -41,14 +41,14 @@ if (!UIWebTablet) { return false; } - if (Overlays.getProperty(HMD.tabletID, "type") != "model") { + if (Overlays.getProperty(HMD.tabletID, "type") !== "model") { if (debugTablet) { print("TABLET is invalid due to frame: " + JSON.stringify(Overlays.getProperty(HMD.tabletID, "type"))); } return false; } - if (Overlays.getProperty(HMD.homeButtonID, "type") != "circle3d" || - Overlays.getProperty(HMD.tabletScreenID, "type") != "web3d") { + if (Overlays.getProperty(HMD.homeButtonID, "type") !== "circle3d" || + Overlays.getProperty(HMD.tabletScreenID, "type") !== "web3d") { if (debugTablet) { print("TABLET is invalid due to other"); } @@ -112,7 +112,7 @@ } function showTabletUI() { - checkTablet() + checkTablet(); if (!tabletRezzed || !tabletIsValid()) { closeTabletUI(); @@ -157,7 +157,7 @@ } function closeTabletUI() { - checkTablet() + checkTablet(); gTablet.tabletShown = false; if (UIWebTablet) { if (UIWebTablet.onClose) { @@ -178,14 +178,14 @@ print("TABLET closeTabletUI, UIWebTablet is null"); } tabletRezzed = false; - gTablet = null + gTablet = null; } function updateShowTablet() { var now = Date.now(); - checkTablet() + checkTablet(); // close the WebTablet if it we go into toolbar mode. var tabletShown = gTablet.tabletShown; @@ -270,7 +270,7 @@ } if (channel === "home") { if (UIWebTablet) { - checkTablet() + checkTablet(); gTablet.landscape = false; } } diff --git a/scripts/system/tablet-users.js b/scripts/system/tablet-users.js index 6181173818..92aefd1e80 100644 --- a/scripts/system/tablet-users.js +++ b/scripts/system/tablet-users.js @@ -48,9 +48,8 @@ // for toolbar-mode: go back to home screen, this will close the window. tablet.gotoHomeScreen(); } else { - var tabletEntity = HMD.tabletID; - if (tabletEntity) { - Entities.editEntity(tabletEntity, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})}); + if (HMD.tabletID) { + Entities.editEntity(HMD.tabletID, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})}); } shouldActivateButton = true; tablet.gotoWebScreen(USERS_URL); diff --git a/unpublishedScripts/marketplace/shapes/modules/laser.js b/unpublishedScripts/marketplace/shapes/modules/laser.js index d5feda0e1f..067b605047 100644 --- a/unpublishedScripts/marketplace/shapes/modules/laser.js +++ b/unpublishedScripts/marketplace/shapes/modules/laser.js @@ -173,8 +173,18 @@ Laser = function (side) { // Normal laser operation with trigger. intersection = Overlays.findRayIntersection(pickRay, PRECISION_PICKING, NO_INCLUDE_IDS, NO_EXCLUDE_IDS, VISIBLE_ONLY); + var tabletIDs = []; + if (HMD.tabletID) { + tabletIDs.push(HMD.tabletID); + } + if (HMD.tabletScreenID) { + tabletIDs.push(HMD.tabletScreenID); + } + if (HMD.homeButtonID) { + tabletIDs.push(HMD.homeButtonID); + } if (Reticle.pointingAtSystemOverlay || (intersection.overlayID - && [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID].indexOf(intersection.overlayID) !== -1)) { + && tabletIDs.indexOf(intersection.overlayID) !== -1)) { // No laser if pointing at HUD overlay or tablet; system provides lasers for these cases. if (isLaserOn) { isLaserOn = false; From 2fc954909bf8b721f5aecbfa26aa37494da6409a Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 23 Jan 2018 14:41:46 -0500 Subject: [PATCH 26/46] [Case 4315] Fixes black color preview for color pickers (details below). The original/starting color preview in the picker was black as opposed to reflecting the entity's color upon clicking the color picker. Known Issue(s)/TODO(s): * Color preview restore color functionality isn't working. * Clicking the initial color preview doesn't restore the color. * The original color preview isn't being visually retained when the user changes the color via the picker. Tested HMD & Desktop Modes. Changes Committed: modified: scripts/system/html/js/entityProperties.js --- scripts/system/html/js/entityProperties.js | 94 +++++++++++++++++----- 1 file changed, 74 insertions(+), 20 deletions(-) diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 7008d0df66..be9bba5f0d 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -29,7 +29,7 @@ var ICON_FOR_TYPE = { var EDITOR_TIMEOUT_DURATION = 1500; var KEY_P = 80; // Key code for letter p used for Parenting hotkey. -var colorPickers = []; +var colorPickers = {}; var lastEntityID = null; function debugPrint(message) { @@ -69,8 +69,8 @@ function enableProperties() { 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(); + for (var pickKey in colorPickers) { + colorPickers[pickKey].colpickHide(); } var elLocked = document.getElementById("property-locked"); @@ -83,7 +83,6 @@ function disableProperties() { function showElements(els, show) { for (var i = 0; i < els.length; i++) { els[i].style.display = (show) ? 'table' : 'none'; - } } @@ -1304,13 +1303,19 @@ function loaded() { elColorRed.addEventListener('change', colorChangeFunction); elColorGreen.addEventListener('change', colorChangeFunction); elColorBlue.addEventListener('change', colorChangeFunction); - colorPickers.push($('#property-color-control2').colpick({ + colorPickers['#property-color-control2'] = $('#property-color-control2').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-color-control2').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-color-control2'].colpickSetColor({ + "r": elColorRed.value, + "g": elColorGreen.value, + "b": elColorBlue.value}); }, onHide: function(colpick) { $('#property-color-control2').attr('active', 'false'); @@ -1319,7 +1324,7 @@ function loaded() { $(el).css('background-color', '#' + hex); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b); } - })); + }); elLightSpotLight.addEventListener('change', createEmitCheckedPropertyUpdateFunction('isSpotlight')); @@ -1328,13 +1333,20 @@ function loaded() { elLightColorRed.addEventListener('change', lightColorChangeFunction); elLightColorGreen.addEventListener('change', lightColorChangeFunction); elLightColorBlue.addEventListener('change', lightColorChangeFunction); - colorPickers.push($('#property-light-color').colpick({ + colorPickers['#property-light-color'] = $('#property-light-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-light-color').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-light-color'].colpickSetColor({ + "r": elLightColorRed.value, + "g": elLightColorGreen.value, + "b": elLightColorBlue.value + }); }, onHide: function(colpick) { $('#property-light-color').attr('active', 'false'); @@ -1343,7 +1355,7 @@ function loaded() { $(el).css('background-color', '#' + hex); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b); } - })); + }); elLightIntensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('intensity', 1)); elLightFalloffRadius.addEventListener('change', createEmitNumberPropertyUpdateFunction('falloffRadius', 1)); @@ -1383,13 +1395,20 @@ function loaded() { elTextTextColorRed.addEventListener('change', textTextColorChangeFunction); elTextTextColorGreen.addEventListener('change', textTextColorChangeFunction); elTextTextColorBlue.addEventListener('change', textTextColorChangeFunction); - colorPickers.push($('#property-text-text-color').colpick({ + colorPickers['#property-text-text-color'] = $('#property-text-text-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-text-text-color').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-text-text-color'].colpickSetColor({ + "r": elTextTextColorRed.value, + "g": elTextTextColorGreen.value, + "b": elTextTextColorBlue.value + }); }, onHide: function(colpick) { $('#property-text-text-color').attr('active', 'false'); @@ -1399,7 +1418,7 @@ function loaded() { $(el).attr('active', 'false'); emitColorPropertyUpdate('textColor', rgb.r, rgb.g, rgb.b); } - })); + }); var textBackgroundColorChangeFunction = createEmitColorPropertyUpdateFunction( 'backgroundColor', elTextBackgroundColorRed, elTextBackgroundColorGreen, elTextBackgroundColorBlue); @@ -1407,13 +1426,20 @@ function loaded() { elTextBackgroundColorRed.addEventListener('change', textBackgroundColorChangeFunction); elTextBackgroundColorGreen.addEventListener('change', textBackgroundColorChangeFunction); elTextBackgroundColorBlue.addEventListener('change', textBackgroundColorChangeFunction); - colorPickers.push($('#property-text-background-color').colpick({ + colorPickers['#property-text-background-color'] = $('#property-text-background-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-text-background-color').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-text-background-color'].colpickSetColor({ + "r": elTextBackgroundColorRed.value, + "g": elTextBackgroundColorGreen.value, + "b": elTextBackgroundColorBlue.value + }); }, onHide: function(colpick) { $('#property-text-background-color').attr('active', 'false'); @@ -1422,7 +1448,7 @@ function loaded() { $(el).css('background-color', '#' + hex); emitColorPropertyUpdate('backgroundColor', rgb.r, rgb.g, rgb.b); } - })); + }); // Key light var keyLightModeChanged = createZoneComponentModeChangedFunction('keyLightMode', @@ -1432,13 +1458,20 @@ function loaded() { elZoneKeyLightModeDisabled.addEventListener('change', keyLightModeChanged); elZoneKeyLightModeEnabled.addEventListener('change', keyLightModeChanged); - colorPickers.push($('#property-zone-key-light-color').colpick({ + colorPickers['#property-zone-key-light-color'] = $('#property-zone-key-light-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-key-light-color').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-zone-key-light-color'].colpickSetColor({ + "r": elZoneKeyLightColorRed.value, + "g": elZoneKeyLightColorGreen.value, + "b": elZoneKeyLightColorBlue.value + }); }, onHide: function(colpick) { $('#property-zone-key-light-color').attr('active', 'false'); @@ -1447,7 +1480,7 @@ function loaded() { $(el).css('background-color', '#' + hex); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'keyLight'); } - })); + }); var zoneKeyLightColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('keyLight', 'color', elZoneKeyLightColorRed, elZoneKeyLightColorGreen, elZoneKeyLightColorBlue); @@ -1501,13 +1534,20 @@ function loaded() { elZoneHazeRange.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeRange')); - colorPickers.push($('#property-zone-haze-color').colpick({ + colorPickers['#property-zone-haze-color'] = $('#property-zone-haze-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-haze-color').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-zone-haze-color'].colpickSetColor({ + "r": elZoneHazeColorRed.value, + "g": elZoneHazeColorGreen.value, + "b": elZoneHazeColorBlue.value + }); }, onHide: function(colpick) { $('#property-zone-haze-color').attr('active', 'false'); @@ -1516,7 +1556,7 @@ function loaded() { $(el).css('background-color', '#' + hex); emitColorPropertyUpdate('hazeColor', rgb.r, rgb.g, rgb.b, 'haze'); } - })); + }); var zoneHazeColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('haze', 'hazeColor', elZoneHazeColorRed, elZoneHazeColorGreen, @@ -1526,13 +1566,20 @@ function loaded() { elZoneHazeColorGreen.addEventListener('change', zoneHazeColorChangeFunction); elZoneHazeColorBlue.addEventListener('change', zoneHazeColorChangeFunction); - colorPickers.push($('#property-zone-haze-glare-color').colpick({ + colorPickers['#property-zone-haze-glare-color'] = $('#property-zone-haze-glare-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-haze-glare-color').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-zone-haze-glare-color'].colpickSetColor({ + "r": elZoneHazeGlareColorRed.value, + "g": elZoneHazeGlareColorGreen.value, + "b": elZoneHazeGlareColorBlue.value + }); }, onHide: function(colpick) { $('#property-zone-haze-glare-color').attr('active', 'false'); @@ -1541,7 +1588,7 @@ function loaded() { $(el).css('background-color', '#' + hex); emitColorPropertyUpdate('hazeGlareColor', rgb.r, rgb.g, rgb.b, 'haze'); } - })); + }); var zoneHazeGlareColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('haze', 'hazeGlareColor', elZoneHazeGlareColorRed, elZoneHazeGlareColorGreen, @@ -1568,13 +1615,20 @@ function loaded() { elZoneSkyboxColorRed.addEventListener('change', zoneSkyboxColorChangeFunction); elZoneSkyboxColorGreen.addEventListener('change', zoneSkyboxColorChangeFunction); elZoneSkyboxColorBlue.addEventListener('change', zoneSkyboxColorChangeFunction); - colorPickers.push($('#property-zone-skybox-color').colpick({ + colorPickers['#property-zone-skybox-color'] = $('#property-zone-skybox-color').colpick({ colorScheme: 'dark', layout: 'hex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-skybox-color').attr('active', 'true'); + // The original color preview within the picker needs to be updated on show because + // prior to the picker being shown we don't have access to the selections' starting color. + colorPickers['#property-zone-skybox-color'].colpickSetColor({ + "r": elZoneSkyboxColorRed.value, + "g": elZoneSkyboxColorGreen.value, + "b": elZoneSkyboxColorBlue.value + }); }, onHide: function(colpick) { $('#property-zone-skybox-color').attr('active', 'false'); @@ -1583,7 +1637,7 @@ function loaded() { $(el).css('background-color', '#' + hex); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'skybox'); } - })); + }); elZoneSkyboxURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('skybox', 'url')); From 6c5961820ca208f7e1396f555e9a3681281ba1fa Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 23 Jan 2018 15:12:53 -0500 Subject: [PATCH 27/46] [Case 4315] Fixes Color Picker preview restore functionality (details below). * The original color preview is now visually retained when the user changes the color via the picker when using the Non-Submit configuration (No OK button). * Clicking the initial old color preview section restores the original/initial color of the object. Tested Desktop & HMD Modes. Changes Committed: modified: scripts/system/html/css/colpick.css modified: scripts/system/html/js/colpick.js --- scripts/system/html/css/colpick.css | 8 ++++---- scripts/system/html/js/colpick.js | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/scripts/system/html/css/colpick.css b/scripts/system/html/css/colpick.css index 98417a5e9a..fc50c4b3fb 100644 --- a/scripts/system/html/css/colpick.css +++ b/scripts/system/html/css/colpick.css @@ -279,7 +279,7 @@ colpick Color Picker / colpick.com } /*full layout with no submit button*/ -.colpick_full_ns .colpick_submit, .colpick_full_ns .colpick_current_color{ +.colpick_full_ns .colpick_submit { display:none; } .colpick_full_ns .colpick_new_color { @@ -320,11 +320,11 @@ colpick Color Picker / colpick.com } /*rgbhex layout, no submit button*/ -.colpick_rgbhex_ns .colpick_submit, .colpick_rgbhex_ns .colpick_current_color{ +.colpick_rgbhex_ns .colpick_submit { display:none; } .colpick_rgbhex_ns .colpick_new_color{ - width:68px; + width:34px; border: 1px solid #8f8f8f; } .colpick_rgbhex_ns .colpick_rgb_r { @@ -379,7 +379,7 @@ colpick Color Picker / colpick.com } /*hex layout, no submit button*/ -.colpick_hex_ns .colpick_submit, .colpick_hex_ns .colpick_current_color { +.colpick_hex_ns .colpick_submit { display:none; } .colpick_hex_ns .colpick_hex_field { diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index f808262e9e..99054c6103 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -302,6 +302,9 @@ For usage and examples: colpick.com/plugin setSelector(col, cal.get(0)); setHue(col, cal.get(0)); setNewColor(col, cal.get(0)); + // If the user triggered this behavior, then any prior color change should be negated. + cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), + hsbToRgb(col), cal.data('colpick').el, 0]); }; return { init: function (opt) { From 35bf8f1d01f6b1bb8172eb887cf354e08afa7558 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 16:24:54 -0500 Subject: [PATCH 28/46] [Case 4315] ESLint Pass; Simple errors addressed (details below). Initial ESLint Pass on colpick.js. Issue Count reduced from 185 to 100 via: eslint -c .eslintrc.js scripts/system/html/js/colpick.js --fix Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 149 +++++++++++++++++------------- 1 file changed, 85 insertions(+), 64 deletions(-) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index 99054c6103..b19cbe0bae 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -25,15 +25,15 @@ For usage and examples: colpick.com/plugin submitText: 'OK', height: 156 }, - //Fill the inputs of the plugin - fillRGBFields = function (hsb, cal) { + // Fill the inputs of the plugin + fillRGBFields = function (hsb, cal) { var rgb = hsbToRgb(hsb); $(cal).data('colpick').fields .eq(1).val(rgb.r).end() .eq(2).val(rgb.g).end() .eq(3).val(rgb.b).end(); }, - fillHSBFields = function (hsb, cal) { + fillHSBFields = function (hsb, cal) { $(cal).data('colpick').fields .eq(4).val(Math.round(hsb.h)).end() .eq(5).val(Math.round(hsb.s)).end() @@ -42,7 +42,7 @@ For usage and examples: colpick.com/plugin fillHexFields = function (hsb, cal) { $(cal).data('colpick').fields.eq(0).val(hsbToHex(hsb)); }, - //Set the round selector position + // Set the round selector position setSelector = function (hsb, cal) { $(cal).data('colpick').selector.css('backgroundColor', '#' + hsbToHex({h: hsb.h, s: 100, b: 100})); $(cal).data('colpick').selectorIndic.css({ @@ -50,18 +50,18 @@ For usage and examples: colpick.com/plugin top: parseInt($(cal).data('colpick').height * (100-hsb.b)/100, 10) }); }, - //Set the hue selector position + // Set the hue selector position setHue = function (hsb, cal) { $(cal).data('colpick').hue.css('top', parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsb.h/360, 10)); }, - //Set current and new colors + // Set current and new colors setCurrentColor = function (hsb, cal) { $(cal).data('colpick').currentColor.css('backgroundColor', '#' + hsbToHex(hsb)); }, setNewColor = function (hsb, cal) { $(cal).data('colpick').newColor.css('backgroundColor', '#' + hsbToHex(hsb)); }, - //Called when the new color is changed + // Called when the new color is changed change = function (ev) { var cal = $(this).parent().parent(), col; if (this.parentNode.className.indexOf('_hex') > 0) { @@ -93,7 +93,7 @@ For usage and examples: colpick.com/plugin setNewColor(col, cal.get(0)); cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 0]); }, - //Change style on blur and on focus of inputs + // Change style on blur and on focus of inputs blur = function (ev) { $(this).parent().removeClass('colpick_focus'); }, @@ -101,7 +101,7 @@ For usage and examples: colpick.com/plugin $(this).parent().parent().data('colpick').fields.parent().removeClass('colpick_focus'); $(this).parent().addClass('colpick_focus'); }, - //Increment/decrement arrows functions + // Increment/decrement arrows functions downIncrement = function (ev) { ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; var field = $(this).parent().find('input').focus(); @@ -130,7 +130,7 @@ For usage and examples: colpick.com/plugin $(document).off('mousemove', moveIncrement); return false; }, - //Hue slider functions + // Hue slider functions downHue = function (ev) { ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; var current = { @@ -143,7 +143,7 @@ For usage and examples: colpick.com/plugin var pageY = ((ev.type == 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( current.cal.data('colpick') - .fields.eq(4).val(parseInt(360*(current.cal.data('colpick').height - (pageY - current.y))/current.cal.data('colpick').height, 10)) + .fields.eq(4).val(parseInt(360*(current.cal.data('colpick').height - (pageY - current.y))/current.cal.data('colpick').height, 10)) .get(0), [current.cal.data('colpick').livePreview] ); @@ -153,7 +153,7 @@ For usage and examples: colpick.com/plugin var pageY = ((ev.type == 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( ev.data.cal.data('colpick') - .fields.eq(4).val(parseInt(360*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.y))))/ev.data.cal.data('colpick').height, 10)) + .fields.eq(4).val(parseInt(360*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.y))))/ev.data.cal.data('colpick').height, 10)) .get(0), [ev.data.preview] ); @@ -166,7 +166,7 @@ For usage and examples: colpick.com/plugin $(document).off('mousemove touchmove',moveHue); return false; }, - //Color selector functions + // Color selector functions downSelector = function (ev) { ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; var current = { @@ -179,7 +179,7 @@ For usage and examples: colpick.com/plugin $(document).on('mousemove touchmove',current,moveSelector); var payeX,pageY; - if(ev.type == 'touchstart') { + if (ev.type == 'touchstart') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; } else { @@ -189,16 +189,16 @@ For usage and examples: colpick.com/plugin change.apply( current.cal.data('colpick').fields - .eq(6).val(parseInt(100*(current.cal.data('colpick').height - (pageY - current.pos.top))/current.cal.data('colpick').height, 10)).end() - .eq(5).val(parseInt(100*(pageX - current.pos.left)/current.cal.data('colpick').height, 10)) - .get(0), + .eq(6).val(parseInt(100*(current.cal.data('colpick').height - (pageY - current.pos.top))/current.cal.data('colpick').height, 10)).end() + .eq(5).val(parseInt(100*(pageX - current.pos.left)/current.cal.data('colpick').height, 10)) + .get(0), [current.preview] ); return false; }, moveSelector = function (ev) { var payeX,pageY; - if(ev.type == 'touchmove') { + if (ev.type == 'touchmove') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; } else { @@ -208,9 +208,9 @@ For usage and examples: colpick.com/plugin change.apply( ev.data.cal.data('colpick').fields - .eq(6).val(parseInt(100*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.pos.top))))/ev.data.cal.data('colpick').height, 10)).end() - .eq(5).val(parseInt(100*(Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageX - ev.data.pos.left))))/ev.data.cal.data('colpick').height, 10)) - .get(0), + .eq(6).val(parseInt(100*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.pos.top))))/ev.data.cal.data('colpick').height, 10)).end() + .eq(5).val(parseInt(100*(Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageX - ev.data.pos.left))))/ev.data.cal.data('colpick').height, 10)) + .get(0), [ev.data.preview] ); return false; @@ -222,7 +222,7 @@ For usage and examples: colpick.com/plugin $(document).off('mousemove touchmove',moveSelector); return false; }, - //Submit button + // Submit button clickSubmit = function (ev) { var cal = $(this).parent(); var col = cal.data('colpick').color; @@ -230,7 +230,7 @@ For usage and examples: colpick.com/plugin setCurrentColor(col, cal.get(0)); cal.data('colpick').onSubmit(col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el); }, - //Show/hide the color picker + // Show/hide the color picker show = function (ev) { // Prevent the trigger of any direct parent ev.stopPropagation(); @@ -248,9 +248,11 @@ For usage and examples: colpick.com/plugin if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) != false) { cal.show(); } - //Hide when user clicks outside + // Hide when user clicks outside $('html').mousedown({cal:cal}, hide); - cal.mousedown(function(ev){ev.stopPropagation();}) + cal.mousedown(function(ev){ + ev.stopPropagation(); + }); }, hide = function (ev) { if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) != false) { @@ -265,7 +267,7 @@ For usage and examples: colpick.com/plugin w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth) }; }, - //Fix the values if the user enters a negative or high value + // Fix the values if the user enters a negative or high value fixHSB = function (hsb) { return { h: Math.min(360, Math.max(0, hsb.h)), @@ -309,8 +311,8 @@ For usage and examples: colpick.com/plugin return { init: function (opt) { opt = $.extend({}, defaults, opt||{}); - //Set color - if (typeof opt.color == 'string') { + // Set color + if (typeof opt.color === 'string') { opt.color = hexToHsb(opt.color); } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) { opt.color = rgbToHsb(opt.color); @@ -320,44 +322,44 @@ For usage and examples: colpick.com/plugin return this; } - //For each selected DOM element + // For each selected DOM element return this.each(function () { - //If the element does not have an ID + // If the element does not have an ID if (!$(this).data('colpickId')) { var options = $.extend({}, opt); options.origColor = opt.color; - //Generate and assign a random ID + // Generate and assign a random ID var id = 'collorpicker_' + parseInt(Math.random() * 1000); $(this).data('colpickId', id); - //Set the tpl's ID and get the HTML + // Set the tpl's ID and get the HTML var cal = $(tpl).attr('id', id); - //Add class according to layout + // Add class according to layout cal.addClass('colpick_'+options.layout+(options.submit?'':' colpick_'+options.layout+'_ns')); - //Add class if the color scheme is not default - if(options.colorScheme != 'light') { + // Add class if the color scheme is not default + if (options.colorScheme != 'light') { cal.addClass('colpick_'+options.colorScheme); } - //Setup submit button + // Setup submit button cal.find('div.colpick_submit').html(options.submitText).click(clickSubmit); - //Setup input fields + // Setup input fields options.fields = cal.find('input').change(change).blur(blur).focus(focus); cal.find('div.colpick_field_arrs').mousedown(downIncrement).end().find('div.colpick_current_color').click(restoreOriginal); - //Setup hue selector + // Setup hue selector options.selector = cal.find('div.colpick_color').on('mousedown touchstart',downSelector); options.selectorIndic = options.selector.find('div.colpick_selector_outer'); - //Store parts of the plugin + // Store parts of the plugin options.el = this; options.hue = cal.find('div.colpick_hue_arrs'); huebar = options.hue.parent(); - //Paint the hue bar + // Paint the hue bar var UA = navigator.userAgent.toLowerCase(); var isIE = navigator.appName === 'Microsoft Internet Explorer'; var IEver = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0; var ngIE = ( isIE && IEver < 10 ); var stops = ['#ff0000','#ff0080','#ff00ff','#8000ff','#0000ff','#0080ff','#00ffff','#00ff80','#00ff00','#80ff00','#ffff00','#ff8000','#ff0000']; - if(ngIE) { + if (ngIE) { var i, div; - for(i=0; i<=11; i++) { + for (i=0; i<=11; i++) { div = $('
').attr('style','height:8.333333%; filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+'); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+')";'); huebar.append(div); } @@ -368,7 +370,7 @@ For usage and examples: colpick.com/plugin cal.find('div.colpick_hue').on('mousedown touchstart',downHue); options.newColor = cal.find('div.colpick_new_color'); options.currentColor = cal.find('div.colpick_current_color'); - //Store options and fill with default color + // Store options and fill with default color cal.data('colpick', options); fillRGBFields(options.color, cal.get(0)); fillHSBFields(options.color, cal.get(0)); @@ -377,7 +379,7 @@ For usage and examples: colpick.com/plugin setSelector(options.color, cal.get(0)); setCurrentColor(options.color, cal.get(0)); setNewColor(options.color, cal.get(0)); - //Append to body if flat=false, else show in place + // Append to body if flat=false, else show in place if (options.flat) { cal.appendTo(this).show(); cal.css({ @@ -394,7 +396,7 @@ For usage and examples: colpick.com/plugin } }); }, - //Shows the picker + // Shows the picker showPicker: function() { return this.each( function () { if ($(this).data('colpickId')) { @@ -402,7 +404,7 @@ For usage and examples: colpick.com/plugin } }); }, - //Hides the picker + // Hides the picker hidePicker: function() { return this.each( function () { if ($(this).data('colpickId')) { @@ -410,10 +412,10 @@ For usage and examples: colpick.com/plugin } }); }, - //Sets a color as new and current (default) + // Sets a color as new and current (default) setColor: function(col, setCurrent) { setCurrent = (typeof setCurrent === "undefined") ? 1 : setCurrent; - if (typeof col == 'string') { + if (typeof col === 'string') { col = hexToHsb(col); } else if (col.r != undefined && col.g != undefined && col.b != undefined) { col = rgbToHsb(col); @@ -435,7 +437,7 @@ For usage and examples: colpick.com/plugin setNewColor(col, cal.get(0)); cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 1]); - if(setCurrent) { + if (setCurrent) { setCurrentColor(col, cal.get(0)); } } @@ -443,7 +445,7 @@ For usage and examples: colpick.com/plugin } }; }(); - //Color space convertions + // Color space convertions var hexToRgb = function (hex) { var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)}; @@ -459,12 +461,20 @@ For usage and examples: colpick.com/plugin hsb.b = max; hsb.s = max != 0 ? 255 * delta / max : 0; if (hsb.s != 0) { - if (rgb.r == max) hsb.h = (rgb.g - rgb.b) / delta; - else if (rgb.g == max) hsb.h = 2 + (rgb.b - rgb.r) / delta; - else hsb.h = 4 + (rgb.r - rgb.g) / delta; - } else hsb.h = -1; + if (rgb.r == max) { + hsb.h = (rgb.g - rgb.b) / delta; + } else if (rgb.g == max) { + hsb.h = 2 + (rgb.b - rgb.r) / delta; + } else { + hsb.h = 4 + (rgb.r - rgb.g) / delta; + } + } else { + hsb.h = -1; + } hsb.h *= 60; - if (hsb.h < 0) hsb.h += 360; + if (hsb.h < 0) { + hsb.h += 360; + } hsb.s *= 100/255; hsb.b *= 100/255; return hsb; @@ -474,20 +484,30 @@ For usage and examples: colpick.com/plugin var h = hsb.h; var s = hsb.s*255/100; var v = hsb.b*255/100; - if(s == 0) { + if (s == 0) { rgb.r = rgb.g = rgb.b = v; } else { var t1 = v; var t2 = (255-s)*v/255; var t3 = (t1-t2)*(h%60)/60; - if(h==360) h = 0; - if(h<60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3} - else if(h<120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3} - else if(h<180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3} - else if(h<240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3} - else if(h<300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3} - else if(h<360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3} - else {rgb.r=0; rgb.g=0; rgb.b=0} + if (h==360) { + h = 0; + } + if (h<60) { + rgb.r=t1; rgb.b=t2; rgb.g=t2+t3; + } else if (h<120) { + rgb.g=t1; rgb.b=t2; rgb.r=t1-t3; + } else if (h<180) { + rgb.g=t1; rgb.r=t2; rgb.b=t2+t3; + } else if (h<240) { + rgb.b=t1; rgb.r=t2; rgb.g=t1-t3; + } else if (h<300) { + rgb.b=t1; rgb.g=t2; rgb.r=t2+t3; + } else if (h<360) { + rgb.r=t1; rgb.g=t2; rgb.b=t1-t3; + } else { + rgb.r=0; rgb.g=0; rgb.b=0; + } } return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)}; }; @@ -524,3 +544,4 @@ For usage and examples: colpick.com/plugin } }); })(jQuery); + From 691aafcf29e20ef2507cf71c3ea1b383fb0f2242 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 16:42:43 -0500 Subject: [PATCH 29/46] [Case 4315] ESLint Pass 2 for colpick.js (details below). Resolves all error Line exceeds the maximum line length of 128 max-len issues. Issue Count reduced from 85 to 70. Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 78 +++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index b19cbe0bae..feb584aa1d 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -1,6 +1,7 @@ /* colpick Color Picker -Copyright 2013 Jose Vargas. Licensed under GPL license. Based on Stefan Petre's Color Picker www.eyecon.ro, dual licensed under the MIT and GPL licenses +Copyright 2013 Jose Vargas. Licensed under GPL license. Based on Stefan Petre's Color Picker www.eyecon.ro, dual licensed +under the MIT and GPL licenses For usage and examples: colpick.com/plugin */ @@ -8,7 +9,31 @@ For usage and examples: colpick.com/plugin (function ($) { var colpick = function () { var - tpl = '
#
R
G
B
H
S
B
', + tpl = '
' + + '
' + + '
' + + '
' + + '
' + + '
#
' + + '
' + + '
R
' + + '
' + + '
' + + '
G
' + + '
' + + '
B
' + + '
' + + '
' + + '
H
' + + '
' + + '
' + + '
S
' + + '
' + + '
' + + '
B
' + + '
' + + '
' + + '
', defaults = { showEvent: 'click', onShow: function () {}, @@ -52,7 +77,8 @@ For usage and examples: colpick.com/plugin }, // Set the hue selector position setHue = function (hsb, cal) { - $(cal).data('colpick').hue.css('top', parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsb.h/360, 10)); + $(cal).data('colpick').hue.css('top', + parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsb.h / 360, 10)); }, // Set current and new colors setCurrentColor = function (hsb, cal) { @@ -91,7 +117,8 @@ For usage and examples: colpick.com/plugin setSelector(col, cal.get(0)); setHue(col, cal.get(0)); setNewColor(col, cal.get(0)); - cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 0]); + cal.data('colpick').onChange.apply(cal.parent(), + [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 0]); }, // Change style on blur and on focus of inputs blur = function (ev) { @@ -107,7 +134,8 @@ For usage and examples: colpick.com/plugin var field = $(this).parent().find('input').focus(); var current = { el: $(this).parent().addClass('colpick_slider'), - max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255), + max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : + (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255), y: ev.pageY, field: field, val: parseInt(field.val(), 10), @@ -143,7 +171,8 @@ For usage and examples: colpick.com/plugin var pageY = ((ev.type == 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( current.cal.data('colpick') - .fields.eq(4).val(parseInt(360*(current.cal.data('colpick').height - (pageY - current.y))/current.cal.data('colpick').height, 10)) + .fields.eq(4).val(parseInt(360 * (current.cal.data('colpick').height - + (pageY - current.y)) / current.cal.data('colpick').height, 10)) .get(0), [current.cal.data('colpick').livePreview] ); @@ -153,7 +182,9 @@ For usage and examples: colpick.com/plugin var pageY = ((ev.type == 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( ev.data.cal.data('colpick') - .fields.eq(4).val(parseInt(360*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.y))))/ev.data.cal.data('colpick').height, 10)) + .fields.eq(4).val(parseInt(360 * (ev.data.cal.data('colpick').height - + Math.max(0, Math.min(ev.data.cal.data('colpick').height, (pageY - ev.data.y)))) / + ev.data.cal.data('colpick').height, 10)) .get(0), [ev.data.preview] ); @@ -189,7 +220,8 @@ For usage and examples: colpick.com/plugin change.apply( current.cal.data('colpick').fields - .eq(6).val(parseInt(100*(current.cal.data('colpick').height - (pageY - current.pos.top))/current.cal.data('colpick').height, 10)).end() + .eq(6).val(parseInt(100 * (current.cal.data('colpick').height - (pageY - current.pos.top)) / + current.cal.data('colpick').height, 10)).end() .eq(5).val(parseInt(100*(pageX - current.pos.left)/current.cal.data('colpick').height, 10)) .get(0), [current.preview] @@ -208,8 +240,11 @@ For usage and examples: colpick.com/plugin change.apply( ev.data.cal.data('colpick').fields - .eq(6).val(parseInt(100*(ev.data.cal.data('colpick').height - Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageY - ev.data.pos.top))))/ev.data.cal.data('colpick').height, 10)).end() - .eq(5).val(parseInt(100*(Math.max(0,Math.min(ev.data.cal.data('colpick').height,(pageX - ev.data.pos.left))))/ev.data.cal.data('colpick').height, 10)) + .eq(6).val(parseInt(100 * (ev.data.cal.data('colpick').height - + Math.max(0, Math.min(ev.data.cal.data('colpick').height, (pageY - ev.data.pos.top)))) / + ev.data.cal.data('colpick').height, 10)).end() + .eq(5).val(parseInt(100 * (Math.max(0, Math.min(ev.data.cal.data('colpick').height, + (pageX - ev.data.pos.left)))) / ev.data.cal.data('colpick').height, 10)) .get(0), [ev.data.preview] ); @@ -343,7 +378,8 @@ For usage and examples: colpick.com/plugin cal.find('div.colpick_submit').html(options.submitText).click(clickSubmit); // Setup input fields options.fields = cal.find('input').change(change).blur(blur).focus(focus); - cal.find('div.colpick_field_arrs').mousedown(downIncrement).end().find('div.colpick_current_color').click(restoreOriginal); + cal.find('div.colpick_field_arrs').mousedown(downIncrement); + cal.find('div.colpick_current_color').click(restoreOriginal); // Setup hue selector options.selector = cal.find('div.colpick_color').on('mousedown touchstart',downSelector); options.selectorIndic = options.selector.find('div.colpick_selector_outer'); @@ -356,16 +392,27 @@ For usage and examples: colpick.com/plugin var isIE = navigator.appName === 'Microsoft Internet Explorer'; var IEver = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0; var ngIE = ( isIE && IEver < 10 ); - var stops = ['#ff0000','#ff0080','#ff00ff','#8000ff','#0000ff','#0080ff','#00ffff','#00ff80','#00ff00','#80ff00','#ffff00','#ff8000','#ff0000']; + var stops = ['#ff0000', '#ff0080', '#ff00ff', '#8000ff', '#0000ff', '#0080ff', '#00ffff', '#00ff80', + '#00ff00', '#80ff00', '#ffff00', '#ff8000', '#ff0000']; if (ngIE) { var i, div; for (i=0; i<=11; i++) { - div = $('
').attr('style','height:8.333333%; filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+'); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='+stops[i]+', endColorstr='+stops[i+1]+')";'); + div = $('
').attr('style', + 'height:8.333333%; filter:progid:' + + 'DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=' + stops[i] + + ', endColorstr=' + stops[i + 1] + + '); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=' + + stops[i] + ', endColorstr=' + stops[i + 1] + ')";'); huebar.append(div); } } else { stopList = stops.join(','); - huebar.attr('style','background:-webkit-linear-gradient(top,'+stopList+'); background: -o-linear-gradient(top,'+stopList+'); background: -ms-linear-gradient(top,'+stopList+'); background:-moz-linear-gradient(top,'+stopList+'); -webkit-linear-gradient(top,'+stopList+'); background:linear-gradient(to bottom,'+stopList+'); '); + huebar.attr('style', 'background:-webkit-linear-gradient(top,' + stopList + + '); background: -o-linear-gradient(top,' + stopList + + '); background: -ms-linear-gradient(top,' + stopList + + '); background:-moz-linear-gradient(top,' + stopList + + '); -webkit-linear-gradient(top,' + stopList + + '); background:linear-gradient(to bottom,' + stopList + '); '); } cal.find('div.colpick_hue').on('mousedown touchstart',downHue); options.newColor = cal.find('div.colpick_new_color'); @@ -436,7 +483,8 @@ For usage and examples: colpick.com/plugin setSelector(col, cal.get(0)); setNewColor(col, cal.get(0)); - cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 1]); + cal.data('colpick').onChange.apply(cal.parent(), + [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 1]); if (setCurrent) { setCurrentColor(col, cal.get(0)); } From 0a1e05326eeea6fdbb95aaf9176f19792ff6580e Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 16:49:44 -0500 Subject: [PATCH 30/46] [Case 4315] ESLint Pass 3, adds global declarations (details below). This resolves 23 error is not defined no-undef errors related to global objects. Issue Count reduced from 70 to 47. Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index feb584aa1d..0ac6996bde 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -6,6 +6,8 @@ under the MIT and GPL licenses For usage and examples: colpick.com/plugin */ +/* global console, document, Element, EventBridge, jQuery, navigator, window, _ $ */ + (function ($) { var colpick = function () { var From ef1fd19a982a67a5c1653671226d33f43c86f673 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 17:01:52 -0500 Subject: [PATCH 31/46] [Case 4315] ESLint Pass 4 for colpick.js (details below). Resolved payeX vs pageX issues. Resolved stopList & huebar undefined issues. Issue Count reduced from 47 to 29. Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index 0ac6996bde..44e887056a 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -211,7 +211,7 @@ For usage and examples: colpick.com/plugin $(document).on('mouseup touchend',current,upSelector); $(document).on('mousemove touchmove',current,moveSelector); - var payeX,pageY; + var pageX,pageY; if (ev.type == 'touchstart') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; @@ -231,7 +231,7 @@ For usage and examples: colpick.com/plugin return false; }, moveSelector = function (ev) { - var payeX,pageY; + var pageX,pageY; if (ev.type == 'touchmove') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; @@ -388,7 +388,7 @@ For usage and examples: colpick.com/plugin // Store parts of the plugin options.el = this; options.hue = cal.find('div.colpick_hue_arrs'); - huebar = options.hue.parent(); + var huebar = options.hue.parent(); // Paint the hue bar var UA = navigator.userAgent.toLowerCase(); var isIE = navigator.appName === 'Microsoft Internet Explorer'; @@ -408,7 +408,7 @@ For usage and examples: colpick.com/plugin huebar.append(div); } } else { - stopList = stops.join(','); + var stopList = stops.join(','); huebar.attr('style', 'background:-webkit-linear-gradient(top,' + stopList + '); background: -o-linear-gradient(top,' + stopList + '); background: -ms-linear-gradient(top,' + stopList + From 83749b16c7811028e0e81aea69f6f34e9d08f8d7 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 17:35:03 -0500 Subject: [PATCH 32/46] [Case 4315] ESLint Pass 5 resolves hex already defined issue (details below). * var hex was declared both the hexToRGB and hexToHsb functions. * hexToRGB was updated to have a more explicit var name * hexToRGB & hexToHSB also had the function param name updated to clarify the expected object type. Also error statements and early returns were added should an unsupported object type be received. * Issue Count is now 28 Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index 44e887056a..d748698cde 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -496,12 +496,22 @@ For usage and examples: colpick.com/plugin }; }(); // Color space convertions - var hexToRgb = function (hex) { - var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); - return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)}; + var hexToRgb = function (hexString) { + if (typeof hexString !== "string") { + print("Error - ColPick.js::hexToRgb expects string object."); + return; + } + + var hexNumber = parseInt(((hexString.indexOf('#') > -1) ? hexString.substring(1) : hexString), 16); + return { r: hexNumber >> 16, g: (hexNumber & 0x00FF00) >> 8, b: (hexNumber & 0x0000FF)}; }; - var hexToHsb = function (hex) { - return rgbToHsb(hexToRgb(hex)); + var hexToHsb = function (hexString) { + if (typeof hexString !== "string") { + print("Error - ColPick.js::hexToHsb expects string object."); + return; + } + + return rgbToHsb(hexToRgb(hexString)); }; var rgbToHsb = function (rgb) { var hsb = {h: 0, s: 0, b: 0}; From 59e0b8476aeca4fe7501df96d2488da7175db023 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 17:57:42 -0500 Subject: [PATCH 33/46] [Case 4315] ESLint Pass 6 Pt 1 for colpick.js (details below). First portion of vetted equality check fixes. Issue Count reduced from 28 to 8. Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index d748698cde..7c640633e3 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -170,7 +170,7 @@ For usage and examples: colpick.com/plugin $(document).on('mouseup touchend',current,upHue); $(document).on('mousemove touchmove',current,moveHue); - var pageY = ((ev.type == 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); + var pageY = ((ev.type === 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( current.cal.data('colpick') .fields.eq(4).val(parseInt(360 * (current.cal.data('colpick').height - @@ -181,7 +181,7 @@ For usage and examples: colpick.com/plugin return false; }, moveHue = function (ev) { - var pageY = ((ev.type == 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); + var pageY = ((ev.type === 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( ev.data.cal.data('colpick') .fields.eq(4).val(parseInt(360 * (ev.data.cal.data('colpick').height - @@ -212,7 +212,7 @@ For usage and examples: colpick.com/plugin $(document).on('mousemove touchmove',current,moveSelector); var pageX,pageY; - if (ev.type == 'touchstart') { + if (ev.type === 'touchstart') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; } else { @@ -232,7 +232,7 @@ For usage and examples: colpick.com/plugin }, moveSelector = function (ev) { var pageX,pageY; - if (ev.type == 'touchmove') { + if (ev.type === 'touchmove') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; } else { @@ -282,7 +282,7 @@ For usage and examples: colpick.com/plugin left -= calW; } cal.css({left: left + 'px', top: top + 'px'}); - if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) != false) { + if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) !== false) { cal.show(); } // Hide when user clicks outside @@ -292,13 +292,13 @@ For usage and examples: colpick.com/plugin }); }, hide = function (ev) { - if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) != false) { + if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) !== false) { ev.data.cal.hide(); } $('html').off('mousedown', hide); }, getViewport = function () { - var m = document.compatMode == 'CSS1Compat'; + var m = document.compatMode === 'CSS1Compat'; return { l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth) @@ -351,9 +351,9 @@ For usage and examples: colpick.com/plugin // Set color if (typeof opt.color === 'string') { opt.color = hexToHsb(opt.color); - } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) { + } else if (opt.color.r !== undefined && opt.color.g !== undefined && opt.color.b !== undefined) { opt.color = rgbToHsb(opt.color); - } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) { + } else if (opt.color.h !== undefined && opt.color.s !== undefined && opt.color.b !== undefined) { opt.color = fixHSB(opt.color); } else { return this; @@ -373,7 +373,7 @@ For usage and examples: colpick.com/plugin // Add class according to layout cal.addClass('colpick_'+options.layout+(options.submit?'':' colpick_'+options.layout+'_ns')); // Add class if the color scheme is not default - if (options.colorScheme != 'light') { + if (options.colorScheme !== 'light') { cal.addClass('colpick_'+options.colorScheme); } // Setup submit button @@ -466,9 +466,9 @@ For usage and examples: colpick.com/plugin setCurrent = (typeof setCurrent === "undefined") ? 1 : setCurrent; if (typeof col === 'string') { col = hexToHsb(col); - } else if (col.r != undefined && col.g != undefined && col.b != undefined) { + } else if (col.r !== undefined && col.g !== undefined && col.b !== undefined) { col = rgbToHsb(col); - } else if (col.h != undefined && col.s != undefined && col.b != undefined) { + } else if (col.h !== undefined && col.s !== undefined && col.b !== undefined) { col = fixHSB(col); } else { return this; From fed85a7a5309200fca79e4dbdb28a3ec4a21effd Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 18:12:57 -0500 Subject: [PATCH 34/46] [Case 4315] ESLint Pass 6 Pt 2 for colpick equality checks (details below). * Suppressing equality checking issues within color conversion helper functions. * These issues are suppressed as opposed to resolved because their resolution causes issues with the color picker's understanding of the color it's being set to along with the respective hue. This is likely due to rounding issues; however, it may also be something related to the equality operator implicit conversions semantics of JavaScript. It's something that can be looked into later if desired. * Bug Steps upon resolving check as opposed to suppressing them: - Select a shape entity for example. - Note the visual color and actual RGB values for that entity's color upon selection. - Click the Color Wheel. - Notice the automatic change of the color for the entity when the picker is shown. - If the issue doesn't show itself right away, alter the color for the entity close the picker, and repeat steps 2-3. * Issue Count reduced from 8 to 1 Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index 7c640633e3..94b5d8521c 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -519,11 +519,11 @@ For usage and examples: colpick.com/plugin var max = Math.max(rgb.r, rgb.g, rgb.b); var delta = max - min; hsb.b = max; - hsb.s = max != 0 ? 255 * delta / max : 0; - if (hsb.s != 0) { - if (rgb.r == max) { + hsb.s = max != 0 ? 255 * delta / max : 0; // eslint-disable-line eqeqeq + if (hsb.s != 0) { // eslint-disable-line eqeqeq + if (rgb.r == max) { // eslint-disable-line eqeqeq hsb.h = (rgb.g - rgb.b) / delta; - } else if (rgb.g == max) { + } else if (rgb.g == max) { // eslint-disable-line eqeqeq hsb.h = 2 + (rgb.b - rgb.r) / delta; } else { hsb.h = 4 + (rgb.r - rgb.g) / delta; @@ -544,13 +544,13 @@ For usage and examples: colpick.com/plugin var h = hsb.h; var s = hsb.s*255/100; var v = hsb.b*255/100; - if (s == 0) { + if (s == 0) { // eslint-disable-line eqeqeq rgb.r = rgb.g = rgb.b = v; } else { var t1 = v; var t2 = (255-s)*v/255; var t3 = (t1-t2)*(h%60)/60; - if (h==360) { + if (h==360) { // eslint-disable-line eqeqeq h = 0; } if (h<60) { @@ -578,7 +578,7 @@ For usage and examples: colpick.com/plugin rgb.b.toString(16) ]; $.each(hex, function (nr, val) { - if (val.length == 1) { + if (val.length == 1) { // eslint-disable-line eqeqeq hex[nr] = '0' + val; } }); From b058b346bd2059395f2fdc3e29455413979777f1 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 9 Feb 2018 18:25:50 -0500 Subject: [PATCH 35/46] [Case 4315] ESLint Pass 7 for colpick.js resolves regex error (details below). Issue Count for colpick is now 0. Changes Committed: modified: scripts/system/html/js/colpick.js --- scripts/system/html/js/colpick.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/html/js/colpick.js b/scripts/system/html/js/colpick.js index 94b5d8521c..199c624bc5 100644 --- a/scripts/system/html/js/colpick.js +++ b/scripts/system/html/js/colpick.js @@ -392,7 +392,7 @@ For usage and examples: colpick.com/plugin // Paint the hue bar var UA = navigator.userAgent.toLowerCase(); var isIE = navigator.appName === 'Microsoft Internet Explorer'; - var IEver = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0; + var IEver = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[.0-9]{0,})/ )[1] ) : 0; var ngIE = ( isIE && IEver < 10 ); var stops = ['#ff0000', '#ff0080', '#ff00ff', '#8000ff', '#0000ff', '#0080ff', '#00ffff', '#00ff80', '#00ff00', '#80ff00', '#ffff00', '#ff8000', '#ff0000']; From 2ff78493dbf68bd3d988aebfef44614e4e5a6b36 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 13 Feb 2018 10:11:18 +1300 Subject: [PATCH 36/46] A further guard --- scripts/system/controllers/controllerDispatcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index b2455b3f5a..345ab33c0d 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -479,7 +479,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); }; } function mouseReleaseOnOverlay(overlayID, event) { - if (overlayID === HMD.homeButtonID && event.button === "Primary") { + if (HMD.homeButtonID && overlayID === HMD.homeButtonID && event.button === "Primary") { Messages.sendLocalMessage("home", overlayID); } } From 6f27d1e5a92a20726c9aeffe5f5c0c5d255e2a93 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 14 Feb 2018 09:19:14 -0800 Subject: [PATCH 37/46] add additional example --- ...e-or-edit-of-entities-with-name-of-zone.js | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 scripts/tutorials/entity_edit_filters/prevent-add-delete-or-edit-of-entities-with-name-of-zone.js diff --git a/scripts/tutorials/entity_edit_filters/prevent-add-delete-or-edit-of-entities-with-name-of-zone.js b/scripts/tutorials/entity_edit_filters/prevent-add-delete-or-edit-of-entities-with-name-of-zone.js new file mode 100644 index 0000000000..0da03b822d --- /dev/null +++ b/scripts/tutorials/entity_edit_filters/prevent-add-delete-or-edit-of-entities-with-name-of-zone.js @@ -0,0 +1,40 @@ +// +// prevent-add-delete-or-edit-of-entities-with-name-of-zone.js +// +// +// Created by Brad Hefta-Gaub to use Entities on Feb. 14, 2018 +// Copyright 2018 High Fidelity, Inc. +// +// This sample entity edit filter script will get all edits, adds, physcis, and deletes, but will only block +// deletes, and will pass through all others. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +function filter(properties, type, originalProperties, zoneProperties) { + + // for adds, check the new properties, if the name is the same as the zone, prevent the add + // note: this case tests the example where originalProperties will be unknown, since as an + // add message, there is no existing entity to get proprties from. But we need to make sure + // zoneProperties is still set in the correct 4th parameter. + if (type == Entities.ADD_FILTER_TYPE) { + if (properties.name == zoneProperties.name) { + return false; + } + } else { + // for edits or deletes, check the "original" property for the entity against the zone's name + if (originalProperties.name == zoneProperties.name) { + return false; + } + } + return properties; +} + +filter.wantsToFilterAdd = true; // do run on add +filter.wantsToFilterEdit = true; // do not run on edit +filter.wantsToFilterPhysics = false; // do not run on physics +filter.wantsToFilterDelete = true; // do not run on delete +filter.wantsOriginalProperties = "name"; +filter.wantsZoneProperties = "name"; +filter; \ No newline at end of file From beb595266df7c23f50f6a1aa663dd353cb4468c1 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Thu, 15 Feb 2018 21:45:35 +0300 Subject: [PATCH 38/46] fix 4x 'fromQml' slots execution note: per discussion with Austion & Seth, TabletRoot should be the only entity sending 'sendToScript' signals to C++ --- libraries/qml/src/qml/OffscreenSurface.cpp | 2 +- libraries/ui/src/ui/OffscreenQmlSurface.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index 87fc8a3025..a84f3feb4d 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -331,9 +331,9 @@ void OffscreenSurface::finishQmlLoad(QQmlComponent* qmlComponent, qmlComponent->deleteLater(); onItemCreated(qmlContext, newItem); - connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant))); if (!rootCreated) { + connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant))); onRootCreated(); emit rootItemCreated(newItem); // Call this callback after rootitem is set, otherwise VrMenu wont work diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index ea34f3de76..749a60a578 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -305,7 +305,6 @@ void OffscreenQmlSurface::onItemCreated(QQmlContext* qmlContext, QQuickItem* new qmlContext->setContextProperty("eventBridgeWrapper", new EventBridgeWrapper(eventBridge, qmlContext)); } - connect(newItem, SIGNAL(sendToScript(QVariant)), this, SIGNAL(fromQml(QVariant))); } void OffscreenQmlSurface::onRootCreated() { From e5f953c103a5df5738b26affc6316ef751555e77 Mon Sep 17 00:00:00 2001 From: vladest Date: Sat, 17 Feb 2018 16:52:32 +0100 Subject: [PATCH 39/46] Make sure Flickable for GridView for TabletHome will not flick --- interface/resources/qml/hifi/tablet/TabletHome.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/hifi/tablet/TabletHome.qml b/interface/resources/qml/hifi/tablet/TabletHome.qml index cfff3a3273..1922b02f93 100644 --- a/interface/resources/qml/hifi/tablet/TabletHome.qml +++ b/interface/resources/qml/hifi/tablet/TabletHome.qml @@ -130,6 +130,7 @@ Item { flickableDirection: Flickable.AutoFlickIfNeeded keyNavigationEnabled: false highlightFollowsCurrentItem: false + interactive: false property int previousGridIndex: -1 From 65efeadf107e2a9171714d4a020c5f297338d453 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 19 Feb 2018 19:17:23 +1300 Subject: [PATCH 40/46] Fix selecting values when tabbing between entity properties fields --- scripts/system/html/js/entityProperties.js | 44 ++++------------------ 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index b27c852974..349516393a 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -497,15 +497,6 @@ function unbindAllInputs() { } } -function clearSelection() { - if (document.selection && document.selection.empty) { - document.selection.empty(); - } else if (window.getSelection) { - var sel = window.getSelection(); - sel.removeAllRanges(); - } -} - function loaded() { openEventBridge(function() { @@ -791,8 +782,10 @@ function loaded() { if (lastEntityID !== '"' + properties.id + '"' && lastEntityID !== null && editor !== null) { saveJSONUserData(true); } - // the event bridge and json parsing handle our avatar id string differently. + var doSelectElement = lastEntityID === '"' + properties.id + '"'; + + // the event bridge and json parsing handle our avatar id string differently. lastEntityID = '"' + properties.id + '"'; elID.value = properties.id; @@ -1138,12 +1131,10 @@ function loaded() { } var activeElement = document.activeElement; - - if (typeof activeElement.select !== "undefined") { + if (doSelectElement && typeof activeElement.select !== "undefined") { activeElement.select(); } } - clearSelection(); } }); } @@ -1682,34 +1673,13 @@ function loaded() { }; // 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; - // TODO FIXME: (JSHint) Functions declared within loops referencing - // an outer scoped variable may lead to confusing semantics. - els[i].onfocus = function(e) { - originalText = this.value; - this.select(); - clicked = false; - }; - // TODO FIXME: (JSHint) Functions declared within loops referencing - // an outer scoped variable may lead to confusing semantics. - els[i].onmouseup = function(e) { - if (!clicked && originalText === this.value) { - e.preventDefault(); - } - clicked = true; + els[i].onfocus = function (e) { + e.target.select(); }; } + bindAllNonJSONEditorElements(); }); From 9bde9f5a4f260d40b1af694ad86866d5451143c0 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 20 Feb 2018 12:36:11 -0800 Subject: [PATCH 41/46] Fix height of Optional Message in Send Money --- .../resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 7dd72b904e..9d05d3a7ef 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -923,7 +923,7 @@ Item { anchors.leftMargin: 20; anchors.right: parent.right; anchors.rightMargin: 20; - height: 140; + height: 95; FontLoader { id: firaSansSemiBold; source: "../../../../../fonts/FiraSans-SemiBold.ttf"; } TextArea { From eb29bdf5d2530606bfd34002ea7e384a1b00e906 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 20 Feb 2018 13:06:10 -0800 Subject: [PATCH 42/46] Don't allow tabs or newlines --- .../qml/hifi/commerce/wallet/sendMoney/SendMoney.qml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml index 9d05d3a7ef..f5b7f42a3f 100644 --- a/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml +++ b/interface/resources/qml/hifi/commerce/wallet/sendMoney/SendMoney.qml @@ -947,8 +947,14 @@ Item { wrapMode: TextEdit.Wrap; activeFocusOnPress: true; activeFocusOnTab: true; - // Workaround for no max length on TextAreas onTextChanged: { + // Don't allow tabs or newlines + if ((/[\n\r\t]/g).test(text)) { + var cursor = cursorPosition; + text = text.replace(/[\n\r\t]/g, ''); + cursorPosition = cursor-1; + } + // Workaround for no max length on TextAreas if (text.length > maximumLength) { var cursor = cursorPosition; text = previousText; From fd6f4b569f2bd1b875be0ea365ecd09b68cba2d8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 20 Feb 2018 13:19:31 -0800 Subject: [PATCH 43/46] Fix active focus issue --- .../qml/hifi/commerce/wallet/PassphraseModal.qml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index c586af9e80..f1692acb3d 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -75,8 +75,6 @@ Item { // TODO: Fix this unlikely bug onVisibleChanged: { if (visible) { - passphraseField.error = false; - passphraseField.focus = true; sendSignalToParent({method: 'disableHmdPreview'}); } else { sendSignalToParent({method: 'maybeEnableHmdPreview'}); @@ -206,6 +204,14 @@ Item { placeholderText: "passphrase"; activeFocusOnPress: true; activeFocusOnTab: true; + + onVisibleChanged: { + if (visible) { + error = false; + focus = true; + forceActiveFocus(); + } + } onFocusChanged: { root.keyboardRaised = focus; From bf73df12652955fda81749946d738e44635aeef4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 20 Feb 2018 15:45:47 -0800 Subject: [PATCH 44/46] more logging for fogbugz 11748 --- libraries/animation/src/Rig.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 01b7dfb0de..d6791ab0b8 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -434,9 +434,13 @@ void Rig::setJointRotation(int index, bool valid, const glm::quat& rotation, flo bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const { bool success { false }; - if (QThread::currentThread() == thread()) { + glm::vec3 originalPosition = position; + bool onOwnerThread = (QThread::currentThread() == thread()); + glm::vec3 poseSetTrans; + if (onOwnerThread) { if (isIndexValid(jointIndex)) { - position = (rotation * _internalPoseSet._absolutePoses[jointIndex].trans()) + translation; + poseSetTrans = _internalPoseSet._absolutePoses[jointIndex].trans(); + position = (rotation * poseSetTrans) + translation; success = true; } else { success = false; @@ -444,7 +448,8 @@ bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm: } else { QReadLocker readLock(&_externalPoseSetLock); if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) { - position = (rotation * _externalPoseSet._absolutePoses[jointIndex].trans()) + translation; + poseSetTrans = _externalPoseSet._absolutePoses[jointIndex].trans(); + position = (rotation * poseSetTrans) + translation; success = true; } else { success = false; @@ -452,7 +457,14 @@ bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm: } if (isNaN(position)) { - qCWarning(animation) << "Rig::getJointPositionInWorldFrame produces NaN"; + qCWarning(animation) << "Rig::getJointPositionInWorldFrame produced NaN." + << " is owner thread = " << onOwnerThread + << " position = " << originalPosition + << " translation = " << translation + << " rotation = " << rotation + << " poseSetTrans = " << poseSetTrans + << " success = " << success + << " jointIndex = " << jointIndex; success = false; position = glm::vec3(0.0f); } From 4dde178b931f04e02b2c1028dbcf17899fb48b5b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 21 Feb 2018 10:33:15 -0800 Subject: [PATCH 45/46] fix new material UI --- interface/resources/qml/hifi/tablet/NewMaterialDialog.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml b/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml index 226c17e8e2..c7fbc9d45a 100644 --- a/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml +++ b/interface/resources/qml/hifi/tablet/NewMaterialDialog.qml @@ -131,7 +131,7 @@ Rectangle { spacing: 5 anchors.horizontalCenter: column3.horizontalCenter - anchors.horizontalCenterOffset: -20 + anchors.horizontalCenterOffset: 0 Button { id: button1 From fa1f2267cf9ad18fc87863427c753b944146575e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 22 Feb 2018 10:06:00 +1300 Subject: [PATCH 46/46] Support RC63 --- unpublishedScripts/marketplace/record/record.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unpublishedScripts/marketplace/record/record.js b/unpublishedScripts/marketplace/record/record.js index 08400dbb85..8e49589e3c 100644 --- a/unpublishedScripts/marketplace/record/record.js +++ b/unpublishedScripts/marketplace/record/record.js @@ -139,7 +139,8 @@ } function setMappingCallback(status) { - if (status !== null) { + // FIXME: "" is for RC <= 63, null is for RC > 63. Remove the former when RC63 is no longer used. + if (status !== null && status !== "") { error("Error mapping recording to " + mappingPath + " on Asset Server!", status); return; }