From d8217e9a7917cdf9ea5bab3978365ff332c9ee3b Mon Sep 17 00:00:00 2001 From: humbletim Date: Tue, 23 Oct 2018 22:42:06 -0400 Subject: [PATCH 01/18] synthesize key release events on Desktop focus change --- interface/src/Application.cpp | 5 +++++ interface/src/Application.h | 1 + 2 files changed, 6 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e515a22403..c3196e69b1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4069,6 +4069,10 @@ void Application::focusOutEvent(QFocusEvent* event) { SpacemouseManager::getInstance().ManagerFocusOutEvent(); #endif + synthesizeKeyReleasEvents(); +} + +void Application::synthesizeKeyReleasEvents() { // synthesize events for keys currently pressed, since we may not get their release events // Because our key event handlers may manipulate _keysPressed, lets swap the keys pressed into a local copy, // clearing the existing list. @@ -4694,6 +4698,7 @@ void Application::idle() { if (_keyboardDeviceHasFocus && activeFocusItem != offscreenUi->getRootItem()) { _keyboardMouseDevice->pluginFocusOutEvent(); _keyboardDeviceHasFocus = false; + synthesizeKeyReleasEvents(); } else if (activeFocusItem == offscreenUi->getRootItem()) { _keyboardDeviceHasFocus = true; } diff --git a/interface/src/Application.h b/interface/src/Application.h index c3896a64e4..6a46032a73 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -541,6 +541,7 @@ private: void keyReleaseEvent(QKeyEvent* event); void focusOutEvent(QFocusEvent* event); + void synthesizeKeyReleasEvents(); void focusInEvent(QFocusEvent* event); void mouseMoveEvent(QMouseEvent* event); From 44d0a7254cc00fd5f450bb695cc1eabad331b07e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 8 Nov 2018 14:53:33 -0800 Subject: [PATCH 02/18] Update the styling for the Entity Properties window --- scripts/system/html/css/edit-style.css | 404 +++++----- scripts/system/html/css/jsoneditor.css | 10 +- scripts/system/html/entityProperties.html | 13 + scripts/system/html/js/entityProperties.js | 863 ++++++++++++--------- 4 files changed, 714 insertions(+), 576 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 7d2350e1c8..8137d6e659 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -70,12 +70,11 @@ } body { - padding: 21px 21px 21px 21px; color: #afafaf; background-color: #404040; font-family: Raleway-Regular; - font-size: 15px; + font-size: 12px; -webkit-touch-callout: none; -webkit-user-select: none; @@ -425,9 +424,9 @@ input[type=checkbox] { } input[type=checkbox] + label { padding-left: 24px; - background-position-y: 6px; background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACpSURBVDhPY2xoaGD68+dPMSMjY9L////VgTQjAw4AlH8PxLOPHj1azWxjY1MBVNsBFBfBpwkEgNKcQGwtJyfHyATkF0KEiQdAzYlMQEIUyicFyDD9+/ePgRxMvsb///4zkIOZ/v0HmkAGHginYjGNGAzS+BpdkAj8mun/3//92DyPD//993cG88nTJ4+Zm5p/BSZeJYb/DEJADEzNOPF7hn8Mk69cvVIPAHN5pyfo70F5AAAAAElFTkSuQmCC); + cursor: pointer; } input[type=checkbox]:enabled + label:hover { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAClSURBVDhPY2hoaGD6//9/6b9//64D8T8gGycASr/7+/dv5/79+1kYgIxKqDjRAKiniRFIv2JgYBAFYlLAE0aQ66AckgDjjx8/yNP44cMH8jS+fPmSPI0PHz4kT+PNmzfJ03jp0iXyNJ46dYo8jYcPHyYnAbxm+vnzZz8wLhlIwd+/f5/BrKSkdExCQuLrnz9/lIBpUAiIQekXF34PTGmTT548WQ8AokXg+rhVtPYAAAAASUVORK5CYII=); @@ -455,6 +454,15 @@ input[type=checkbox]:checked + label:hover { color: #ffffff; } +.icon { + font-family: HiFi-Glyphs; + color: white; +} + +#property-type-icon { + font-size: 50px; +} + .selectable { -webkit-touch-callout: text; -webkit-user-select: text; @@ -483,9 +491,11 @@ input[type=checkbox]:checked + label:hover { #properties-list { display: flex; flex-direction: column; + + margin-top: 16px; } -#properties-list fieldset { +#properties-list .fieldset { position: relative; /* 0.1px on the top is to prevent margin collapsing between this and it's first child */ margin: 0 -21px 21px -21px; @@ -495,71 +505,101 @@ input[type=checkbox]:checked + label:hover { box-shadow: 0 -1px 0 rgb(37,37,37); } -#properties-list fieldset.fstuple, #properties-list fieldset.fsrow { +#properties-list .fieldset.fstuple, #properties-list .fieldset.fsrow { margin-top: 21px; border: none; box-shadow: none; } -#properties-list > fieldset[data-collapsed="true"] + fieldset { +#properties-list > .fieldset[data-collapsed="true"] + .fieldset { margin-top: 0; } -#properties-list > fieldset[data-collapsed="true"] > *:not(legend) { +#properties-list > .fieldset[data-collapsed="true"] > *:not(div.legend) { display: none !important; } -#properties-list legend + fieldset { - margin-top: 0; - border: none; - box-shadow: none; -} - -#properties-list > fieldset > legend { - position: relative; - display: table; - width: 100%; - margin: 21px -21px 0 -21px; - padding: 14px 21px 0 21px; - font-family: Raleway-Regular; - font-size: 12px; - color: #afafaf; - height: 28px; - text-transform: uppercase; - outline: none; - background-color: #404040; - border: none; +.section-header { + padding: 0 16px; border-top: 1px rgb(90,90,90) solid; - box-shadow: 0 -1px 0 rgb(37,37,37), 0 4px 4px 0 rgba(0,0,0,0.75); + box-shadow: 1px -1px 0 rgb(37,37,37); + border-bottom: 1px solid rgb(37, 37, 37); } div.section-header, hr { - display: table; - width: 100%; - margin: 21px -21px 0 -21px; - padding: 14px 21px 0 21px; + display: flex; + flex-flow: row nowrap; + + padding: 10px 16px; font-family: Raleway-Regular; font-size: 12px; color: #afafaf; height: 28px; text-transform: uppercase; outline: none; + margin-bottom: 10px; + align-items: center; } -div.section-header:first-child { - margin-top: -2px; - padding-top: 0; - background: none; - height: auto; +.section.minor { + margin: 0 21px; + box-shadow: 1px -1px 0 rgb(37,37,37); + border-left: 1px solid #575757; } -#properties-list > fieldset > legend span, .section-header span { - font-family: HiFi-Glyphs; +.container.property { + padding: 0 16px; +} + +.stretch { + width: 100%; +} + +div.section-header .label { + width: 100%; +} + +.section.minor div.section-header { + border-right: 0; +} + +div.section[collapsed="true"] > .container { + display: none; +} + +div.section[collapsed="true"], div.section[collapsed="true"] > .section-header { + margin-bottom: 0; +} + +.section.major { + margin-bottom: 20px; +} + +.section.minor.last { + margin-bottom: 20px; + border-bottom: 1px solid rgb(37,37,37); +} + +.section-header { + background-color: #373737; +} + +.section-header { + cursor: pointer; +} + +.section-header span { font-size: 30px; - float: right; - position: absolute; - top: 4px; - right: 13px; + font-family: HiFi-Glyphs; +} + +.triple-label { + text-transform: uppercase; + padding: 6px 0; +} + +.triple-item { + margin-right: 10px; } .section-header[collapsed="true"] { @@ -582,9 +622,6 @@ hr { } .property { - display: table; - width: 100%; - margin-top: 21px; min-height: 28px; } @@ -592,6 +629,10 @@ hr { width: auto; } +span.indented { + padding-left: 16px; +} + .property label, .number label { display: table-cell; vertical-align: middle; @@ -604,13 +645,13 @@ hr { font-size: 13px; } -.property legend, .number legend { +.property div.legend, .number div.legend { display: table-cell; vertical-align: middle; font-family: Raleway-SemiBold; font-size: 14px; } -.property legend .unit, .number legend .unit { +.property div.legend .unit, .number div.legend .unit { margin-left: 8px; font-family: Raleway-Light; font-size: 13px; @@ -623,16 +664,26 @@ hr { .value label { display: inline-block; vertical-align: top; - width: 48px; } -.value legend { +.value div.legend { display: inline-block; vertical-align: top; width: 48px; } .value span { - font-family: FiraSans-SemiBold; font-size: 15px; + margin-right: 4px; +} + +#placeholder-property-type { + display: flex; + align-items: center; + width: auto; + margin-right: 20px; +} + +#placeholder-property-locked { + margin-left: 6px; } .checkbox + .checkbox { @@ -659,33 +710,6 @@ hr { height: 1.8rem; } -.text label, .url label, .number label, .textarea label, .xy label, .wh label, .rgb label, .xyz label, .pyr label, .dropdown label, .gen label { - float: left; - margin-left: 1px; - margin-bottom: 3px; - margin-top: -2px; -} - -.text legend, .url legend, .number legend, .textarea legend, .xy legend, .wh legend, .rgb legend, .xyz legend, .pyr legend, .dropdown legend, .gen legend { - float: left; - margin-left: 1px; - margin-bottom: 3px; - margin-top: -2px; -} - -.xy > div, .wh > div, .xyz > div, .pyr > div, .gen > div { - clear: both; -} - -.number > input { - clear: both; - float: left; -} -.number > span { - clear: both; - float: left; -} - .dropdown { position: relative; margin-bottom: -17px; @@ -697,6 +721,7 @@ hr { .dropdown dl { clear: both; + cursor: pointer; } .dropdown dl { font-family: FiraSans-SemiBold; @@ -705,7 +730,7 @@ hr { height: 28px; padding: 0 28px 0 12px; color: #afafaf; - background: linear-gradient(#7d7d7d 20%, #686a68 100%); + background: #575757; position: relative; } .dropdown dl[dropped="true"] { @@ -812,27 +837,20 @@ div.refresh input[type="button"] { .color-picker { box-sizing: border-box; - float: left; - margin-bottom: 21px; - width: 36px; - height: 36px; - border: 4px solid #afafaf; - border-radius: 4px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABTSURBVChTjcxBDoAwCETRwTs33sFjwB6uaCE1Ggvav5qQF7CSqu40dllHjYiOT3gh3yV8Ii+Fb+RNMEP9hm3sKENmBhG5P1aImWMH/EMerSAAOAFgTC/R8ZXSXAAAAABJRU5ErkJggg==); - background-position: bottom right; - background-repeat: no-repeat; + width: 26px; + height: 26px; + border: 3px solid #2B2B2B; + cursor: pointer; } .color-picker:focus { outline: none; } .color-picker[active="true"] { border-color: #000; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABDSURBVChTjcoLCkAhCETRNq0tf97Y5xGZ1gVJ45TH6njThIO+xk2UwhWFcEdH6JCqOuiQiMDi/hcii3crRRb/7ggAPvIMVihQwvSXAAAAAElFTkSuQmCC); } .color-picker[disabled="disabled"] { border-color: #afafaf; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABTSURBVChTjcxBDoAwCETRwTs33sFjwB6uaCE1Ggvav5qQF7CSqu40dllHjYiOT3gh3yV8Ii+Fb+RNMEP9hm3sKENmBhG5P1aImWMH/EMerSAAOAFgTC/R8ZXSXAAAAABJRU5ErkJggg==); } .colpick[disabled="disabled"] { @@ -848,89 +866,15 @@ div.refresh input[type="button"] { clear: both; } -.rgb legend { +.rgb div.legend { float: left; margin-top: 10px; margin-left: 21px; } -.rgb legend + * { +.rgb div.legend + * { clear: both; } -.tuple div { - display: inline-block; - position: relative; - margin-right: 6px; -} -.tuple div:last-child { - margin-right: 0; -} - -.tuple label { - margin-right: -6px; -} - -.xy .tuple input { - padding-left: 25px; -} -.wh .tuple input { - padding-left: 45px; -} -.rgb .tuple input { - padding-left: 65px; -} -.xyz .tuple input { - padding-left: 25px; -} -.pyr .tuple input { - padding-left: 40px; -} - -.tuple div > label:first-child { - float: left; -} -.tuple div > label + input { - clear: both; - float: left; -} -.tuple div input + label { - display: inline !important; - float: none !important; - position: absolute; - margin-top: 8px; - margin-left: 6px; - left: 0; - font-family: FiraSans-SemiBold; - font-size: 12px; -} -.tuple .red + label, .tuple .x + label, .tuple .pitch + label, .tuple .width + label { - color: #e2334d; -} -.tuple .green + label, .tuple .y + label, .tuple .yaw + label, .tuple .height + label { - color: #1ac567; -} -.tuple .blue + label, .tuple .z + label, .tuple .roll + label { - color: #1080b8; -} - -.tuple .red:focus, .tuple .x:focus, .tuple .pitch:focus, .tuple .width:focus { - outline-color: #e2334d; -} -.tuple .green:focus, .tuple .y:focus, .tuple .yaw:focus, .tuple .height:focus { - outline-color: #1ac567; -} -.tuple .blue:focus, .tuple .z:focus, .tuple .roll:focus { - outline-color: #1080b8; -} - -.xyz .buttons input { - margin-top: 14px; -} -.xyz .buttons span { - word-wrap: nowrap; - white-space: nowrap; -} - .row .property { width: auto; display: inline-block; @@ -984,12 +928,12 @@ div.refresh input[type="button"] { width: 50%; } -#properties-list fieldset .two-column { +#properties-list .fieldset .two-column { padding-top: 10px; display: flex; } -#properties-list .two-column fieldset { +#properties-list .two-column .fieldset { width: 50%; margin: 0; padding: 0; @@ -1002,7 +946,7 @@ div.refresh input[type="button"] { top: -10px; } -#properties-list .two-column fieldset legend { +#properties-list .two-column .fieldset div.legend { width: 100%; margin: 21px -21px 0 -21px; padding: 16px 0 0 21px; @@ -1018,11 +962,11 @@ div.refresh input[type="button"] { margin-top: 6px; } -fieldset .checkbox-sub-props { +.fieldset .checkbox-sub-props { margin-top: 0; } -fieldset .checkbox-sub-props .property:first-child { +.fieldset .checkbox-sub-props .property:first-child { margin-top: 0; } @@ -1069,6 +1013,7 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { body#entity-list-body { padding-bottom: 0; + margin: 16px; } #entity-list-header { @@ -1449,7 +1394,6 @@ th#entity-hasScript { border-top: none !important; box-shadow: none !important; margin-bottom: 5px !important; - top: -15px; } #properties-base #property-type-icon { @@ -1468,6 +1412,7 @@ th#entity-hasScript { display: inline-block; } +/* #properties-base #div-property-locked { position: absolute; top: 6px; @@ -1488,6 +1433,7 @@ th#entity-hasScript { #properties-base #div-property-visible label { background-position-y: 1px; } +*/ #properties-base .checkbox label span { font-family: HiFi-Glyphs; @@ -1514,16 +1460,17 @@ th#entity-hasScript { } input#property-scale-button-rescale { + margin-top: 6px; min-width: 50px; - margin-left: 6px; } input#property-scale-button-reset { + margin-top: 6px; margin-right: 0; } -#property-userData-button-clear, +#property-userData-button-edit, #property-materialData-button-clear { - margin-bottom: 10px; + margin: 6px 0 6px 0; } #property-userData-static, @@ -1545,15 +1492,6 @@ input#property-scale-button-reset { display: none; } -#div-property-serverScripts-status label { - position: relative; - top: 8px; -} -#property-serverScripts-status { - position: relative; - top: 5px; - right: -20px; -} #div-property-collisionSoundURL[style*="display: none"] + .property { margin-top: 0; @@ -1620,3 +1558,101 @@ input.rename-entity { bottom: 0; margin-top: 5px; } + +.container { + display: flex; + flex-flow: row nowrap; + justify-content: space-around; + margin-bottom: 8px; + min-height: 28px; +} + +.container > label { + margin-top: 6px; + width: 200px; +} + +.container > div.checkbox { + padding-top: 6px; +} + +.container > .value { + width: 100%; +} + +.container .row { + display: flex; + flex-flow: row nowrap; +} + +.container.shrink { + width: min-content; +} + +.fstuple { + display: flex; + flex-flow: row; +} +.fstuple input { + margin-left: 4px; + margin-right: 10px; +} +.fstuple label.red, .fstuple label.x { + color: #C62147; +} +.fstuple label.green, .fstuple label.y { + color: #359D85; +} +.fstuple label.blue, .fstuple label.z { + color: #0093C5; +} + +.xyz.fstuple, .pyr.fstuple { + position: relative; + left: -12px; +} + +.rgb.fstuple .tuple { + display: none; +} + +input.number-slider { + background: #575757; + border-radius: 4px; + color: white; +} + +.fstuple > div { + display: flex; + align-items: center; + justify-content: left; +} + +.flex-row { + display: flex; + flex-flow: row; +} + +.flex-column { + display: flex; + flex-flow: column; +} + +.flex-center { + align-items: center; +} + +.flex-evenly-spaced { + flex: 1; +} + +#property-serverScripts-status { + font-family: Raleway-Light; + font-size: 14px; + margin: 6px 0; +} + +#property-name, #property-id { + display: flex; + width: 100%; +} diff --git a/scripts/system/html/css/jsoneditor.css b/scripts/system/html/css/jsoneditor.css index ce83b45ff3..eedef60a7f 100644 --- a/scripts/system/html/css/jsoneditor.css +++ b/scripts/system/html/css/jsoneditor.css @@ -223,8 +223,6 @@ div.jsoneditor-tree table.jsoneditor-tree { div.jsoneditor-outer { width: 100%; - height: 100%; - min-height: 150px; margin: -35px 0 0 0; padding: 0 0 0 0; -moz-box-sizing: border-box; @@ -233,20 +231,18 @@ div.jsoneditor-outer { overflow-y: auto; } -textarea.jsoneditor-text, .ace-jsoneditor { - min-height: 150px; + min-height: 150px; + height: auto !important; } div.jsoneditor-tree { width: 100%; - height: 100%; position: relative; } textarea.jsoneditor-text { width: 100%; - height: 100%; margin: 0; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; @@ -931,4 +927,4 @@ table.jsoneditor-search button.jsoneditor-previous { table.jsoneditor-search button.jsoneditor-previous:hover { background-position: -148px -49px; -} \ No newline at end of file +} diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index b56ad346e2..6af8ee992a 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -28,6 +28,19 @@
+
+ +
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index b66d7e19c6..e5e7426dd2 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -29,7 +29,7 @@ const ICON_FOR_TYPE = { const DEGREES_TO_RADIANS = Math.PI / 180.0; -const NO_SELECTION = "No selection"; +const NO_SELECTION = "w"; const GROUPS = [ { @@ -40,17 +40,22 @@ const GROUPS = [ type: "icon", icons: ICON_FOR_TYPE, propertyID: "type", + replaceID: "placeholder-property-type", }, { label: "Name", type: "string", propertyID: "name", + placeholder: "Name", + replaceID: "placeholder-property-name", }, { label: "ID", type: "string", propertyID: "id", + placeholder: "ID", readOnly: true, + replaceID: "placeholder-property-id", }, { label: "Description", @@ -68,16 +73,18 @@ const GROUPS = [ propertyID: "parentJointIndex", }, { - label: "Locked", + label: "", glyph: "", type: "bool", propertyID: "locked", + replaceID: "placeholder-property-locked", }, { - label: "Visible", + label: "", glyph: "", type: "bool", propertyID: "visible", + replaceID: "placeholder-property-visible", }, ] }, @@ -457,6 +464,7 @@ const GROUPS = [ { label: "Image", type: "string", + placeholder: "URL", propertyID: "image", }, ] @@ -634,6 +642,7 @@ const GROUPS = [ { id: "particles_emit", label: "EMIT", + isMinor: true, properties: [ { label: "Emit Rate", @@ -686,7 +695,7 @@ const GROUPS = [ vec3Type: "pyr", step: 0.01, round: 100, - subLabels: [ "pitch", "yaw", "roll" ], + subLabels: [ "x", "y", "z" ], unit: "deg", propertyID: "emitOrientation", }, @@ -700,35 +709,42 @@ const GROUPS = [ { id: "particles_size", label: "SIZE", + isMinor: true, properties: [ { + type: "triple", label: "Size", - type: "slider", - min: 0, - max: 4, - step: 0.01, - decimals: 2, - propertyID: "particleRadius", - }, - { - label: "Size Start", - type: "slider", - min: 0, - max: 4, - step: 0.01, - decimals: 2, - propertyID: "radiusStart", - fallbackProperty: "particleRadius", - }, - { - label: "Size Finish", - type: "slider", - min: 0, - max: 4, - step: 0.01, - decimals: 2, - propertyID: "radiusFinish", - fallbackProperty: "particleRadius", + properties: [ + { + label: "Start", + type: "slider", + min: 0, + max: 4, + step: 0.01, + decimals: 2, + propertyID: "radiusStart", + fallbackProperty: "particleRadius", + }, + { + label: "Middle", + type: "slider", + min: 0, + max: 4, + step: 0.01, + decimals: 2, + propertyID: "particleRadius", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 4, + step: 0.01, + decimals: 2, + propertyID: "radiusFinish", + fallbackProperty: "particleRadius", + }, + ] }, { label: "Size Spread", @@ -744,24 +760,31 @@ const GROUPS = [ { id: "particles_color", label: "COLOR", + isMinor: true, properties: [ { + type: "triple", label: "Color", - type: "color", - propertyID: "particleColor", - propertyName: "color", // actual entity property name - }, - { - label: "Color Start", - type: "color", - propertyID: "colorStart", - fallbackProperty: "color", - }, - { - label: "Color Finish", - type: "color", - propertyID: "colorFinish", - fallbackProperty: "color", + properties: [ + { + label: "Start", + type: "color", + propertyID: "colorStart", + fallbackProperty: "color", + }, + { + label: "Middle", + type: "color", + propertyID: "particleColor", + propertyName: "color", // actual entity property name + }, + { + label: "Finish", + type: "color", + propertyID: "colorFinish", + fallbackProperty: "color", + }, + ] }, { label: "Color Spread", @@ -773,35 +796,42 @@ const GROUPS = [ { id: "particles_alpha", label: "ALPHA", + isMinor: true, properties: [ { + type: "triple", label: "Alpha", - type: "slider", - min: 0, - max: 1, - step: 0.01, - decimals: 2, - propertyID: "alpha", - }, - { - label: "Alpha Start", - type: "slider", - min: 0, - max: 1, - step: 0.01, - decimals: 2, - propertyID: "alphaStart", - fallbackProperty: "alpha", - }, - { - label: "Alpha Finish", - type: "slider", - min: 0, - max: 1, - step: 0.01, - decimals: 2, - propertyID: "alphaFinish", - fallbackProperty: "alpha", + properties: [ + { + label: "Start", + type: "slider", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "alphaStart", + fallbackProperty: "alpha", + }, + { + label: "Middle", + type: "slider", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "alpha", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "alphaFinish", + fallbackProperty: "alpha", + }, + ] }, { label: "Alpha Spread", @@ -817,6 +847,7 @@ const GROUPS = [ { id: "particles_acceleration", label: "ACCELERATION", + isMinor: true, properties: [ { label: "Emit Acceleration", @@ -841,41 +872,48 @@ const GROUPS = [ { id: "particles_spin", label: "SPIN", + isMinor: true, properties: [ { - label: "Spin", - type: "slider", - min: -360, - max: 360, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "particleSpin", - }, - { - label: "Spin Start", - type: "slider", - min: -360, - max: 360, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "spinStart", - fallbackProperty: "particleSpin", - }, - { - label: "Spin Finish", - type: "slider", - min: -360, - max: 360, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "spinFinish", - fallbackProperty: "particleSpin", + type: "triple", + label: "Alpha", + properties: [ + { + label: "Start", + type: "slider", + min: -360, + max: 360, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "spinStart", + fallbackProperty: "particleSpin", + }, + { + label: "Middle", + type: "slider", + min: -360, + max: 360, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "particleSpin", + }, + { + label: "Finish", + type: "slider", + min: -360, + max: 360, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "spinFinish", + fallbackProperty: "particleSpin", + }, + ] }, { label: "Spin Spread", @@ -898,51 +936,64 @@ const GROUPS = [ { id: "particles_constraints", label: "CONSTRAINTS", + isMinor: true, properties: [ { - label: "Horizontal Angle Start", - type: "slider", - min: 0, - max: 180, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "polarStart", + type: "triple", + label: "Horizontal Angle", + properties: [ + { + label: "Start", + type: "slider", + min: -180, + max: 0, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "polarStart", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 180, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "polarFinish", + }, + ], }, { - label: "Horizontal Angle Finish", - type: "slider", - min: 0, - max: 180, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "polarFinish", - }, - { - label: "Vertical Angle Start", - type: "slider", - min: -180, - max: 0, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "azimuthStart", - }, - { - label: "Vertical Angle Finish", - type: "slider", - min: 0, - max: 180, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "azimuthFinish", - }, + type: "triple", + label: "Vertical Angle", + properties: [ + { + label: "Start", + type: "slider", + min: 0, + max: 180, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "azimuthStart", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 180, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "azimuthFinish", + }, + ] + } ] }, { @@ -964,7 +1015,7 @@ const GROUPS = [ vec3Type: "pyr", step: 0.1, decimals: 4, - subLabels: [ "pitch", "yaw", "roll" ], + subLabels: [ "x", "y", "z" ], unit: "deg", propertyID: "rotation", }, @@ -1023,6 +1074,7 @@ const GROUPS = [ }, { label: "Clone Lifetime", + indentedLabel: true, type: "number", unit: "s", propertyID: "cloneLifetime", @@ -1030,18 +1082,21 @@ const GROUPS = [ }, { label: "Clone Limit", + indentedLabel: true, type: "number", propertyID: "cloneLimit", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Dynamic", + indentedLabel: true, type: "bool", propertyID: "cloneDynamic", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Avatar Entity", + indentedLabel: true, type: "bool", propertyID: "cloneAvatarEntity", showPropertyRule: { "cloneable": "true" }, @@ -1078,6 +1133,12 @@ const GROUPS = [ buttons: [ { id: "reload", label: "F", className: "glyph", onClick: reloadServerScripts } ], propertyID: "serverScripts", }, + { + label: "Server Script Status", + type: "placeholder", + indentedLabel: true, + propertyID: "serverScriptStatus", + }, { label: "Lifetime", type: "number", @@ -1104,12 +1165,6 @@ const GROUPS = [ inverse: true, propertyID: "collisionless", }, - { - label: "Collides With", - type: "sub-header", - propertyID: "collidesWithHeader", // not actually a property but used for naming/storing this element - showPropertyRule: { "collisionless": "false" }, - }, { label: "Static Entities", type: "bool", @@ -1188,7 +1243,7 @@ const GROUPS = [ vec3Type: "pyr", multiplier: DEGREES_TO_RADIANS, decimals: 4, - subLabels: [ "pitch", "yaw", "roll" ], + subLabels: [ "x", "y", "z" ], unit: "deg/s", propertyID: "angularVelocity", }, @@ -1327,6 +1382,12 @@ function debugPrint(message) { ); } +function createElementFromHTML(htmlString) { + var elTemplate = document.createElement('template'); + elTemplate.innerHTML = htmlString.trim(); + return elTemplate.content.firstChild; +} + /** * GENERAL PROPERTY/GROUP FUNCTIONS @@ -1399,8 +1460,8 @@ function disableProperties() { } function showPropertyElement(propertyID, show) { - let elProperty = properties[propertyID].elProperty; - elProperty.style.display = show ? "table" : "none"; + let elProperty = properties[propertyID].elContainer; + elProperty.style.display = show ? "flex" : "none"; } function resetProperties() { @@ -1457,7 +1518,6 @@ function resetProperties() { } case 'icon': { property.elSpan.style.display = "none"; - property.elLabel.innerHTML = propertyData.label; break; } case 'texture': { @@ -1658,23 +1718,23 @@ function createImageURLUpdateFunction(propertyName, isParticleProperty) { * PROPERTY ELEMENT CREATION FUNCTIONS */ -function createStringProperty(property, elProperty, elLabel) { +function createStringProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property text"; + elProperty.className = "text"; - let elInput = document.createElement('input'); - elInput.setAttribute("id", elementID); - elInput.setAttribute("type", "text"); - if (propertyData.readOnly) { - elInput.readOnly = true; - } + let elInput = createElementFromHTML(` + + `) + elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); - elProperty.appendChild(elLabel); elProperty.appendChild(elInput); if (propertyData.buttons !== undefined) { @@ -1684,18 +1744,18 @@ function createStringProperty(property, elProperty, elLabel) { return elInput; } -function createBoolProperty(property, elProperty, elLabel) { +function createBoolProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property checkbox"; + elProperty.className = "checkbox"; if (propertyData.glyph !== undefined) { - elLabel.innerText = " " + propertyData.label; let elSpan = document.createElement('span'); elSpan.innerHTML = propertyData.glyph; - elLabel.insertBefore(elSpan, elLabel.firstChild); + elSpan.className = 'icon'; + elProperty.appendChild(elSpan); } let elInput = document.createElement('input'); @@ -1703,7 +1763,7 @@ function createBoolProperty(property, elProperty, elLabel) { elInput.setAttribute("type", "checkbox"); elProperty.appendChild(elInput); - elProperty.appendChild(elLabel); + elProperty.appendChild(createElementFromHTML(``)); let subPropertyOf = propertyData.subPropertyOf; if (subPropertyOf !== undefined) { @@ -1717,14 +1777,12 @@ function createBoolProperty(property, elProperty, elLabel) { return elInput; } -function createNumberProperty(property, elProperty, elLabel) { +function createNumberProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property number"; - - addUnit(propertyData.unit, elLabel); + elProperty.className = "number"; let elInput = document.createElement('input'); elInput.setAttribute("id", elementID); @@ -1746,7 +1804,6 @@ function createNumberProperty(property, elProperty, elLabel) { elInput.addEventListener('change', createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, propertyData.decimals, property.isParticleProperty)); - elProperty.appendChild(elLabel); elProperty.appendChild(elInput); if (propertyData.buttons !== undefined) { @@ -1756,10 +1813,10 @@ function createNumberProperty(property, elProperty, elLabel) { return elInput; } -function createSliderProperty(property, elProperty, elLabel) { +function createSliderProperty(property, elProperty) { let propertyData = property.data; - elProperty.className = "property range"; + elProperty.className = "range"; let elDiv = document.createElement("div"); elDiv.className = "slider-wrapper"; @@ -1809,7 +1866,6 @@ function createSliderProperty(property, elProperty, elLabel) { updateProperty(property.name, sliderValue, property.isParticleProperty); }; - elDiv.appendChild(elLabel); elDiv.appendChild(elSlider); elDiv.appendChild(elInput); elProperty.appendChild(elDiv); @@ -1820,26 +1876,23 @@ function createSliderProperty(property, elProperty, elLabel) { return elResult; } -function createVec3Property(property, elProperty, elLabel) { +function createVec3Property(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property " + propertyData.vec3Type + " fstuple"; + elProperty.className = propertyData.vec3Type + " fstuple"; - let elTuple = document.createElement('div'); - elTuple.className = "tuple"; + //let elTuple = document.createElement('div'); + //elTuple.className = "tuple"; - addUnit(propertyData.unit, elLabel); + //elProperty.appendChild(elTuple); - elProperty.appendChild(elLabel); - elProperty.appendChild(elTuple); - - let elInputX = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], + let elInputX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], propertyData.min, propertyData.max, propertyData.step); - let elInputY = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], + let elInputY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], propertyData.min, propertyData.max, propertyData.step); - let elInputZ = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_INPUT], + let elInputZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_INPUT], propertyData.min, propertyData.max, propertyData.step); let inputChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elInputX, elInputY, elInputZ, @@ -1855,19 +1908,16 @@ function createVec3Property(property, elProperty, elLabel) { return elResult; } -function createVec2Property(property, elProperty, elLabel) { +function createVec2Property(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property " + propertyData.vec2Type + " fstuple"; + elProperty.className = propertyData.vec2Type + " fstuple"; let elTuple = document.createElement('div'); elTuple.className = "tuple"; - addUnit(propertyData.unit, elLabel); - - elProperty.appendChild(elLabel); elProperty.appendChild(elTuple); let elInputX = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], @@ -1886,11 +1936,11 @@ function createVec2Property(property, elProperty, elLabel) { return elResult; } -function createColorProperty(property, elProperty, elLabel) { +function createColorProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; - elProperty.className = "property rgb fstuple"; + elProperty.className = "rgb fstuple"; let elColorPicker = document.createElement('div'); elColorPicker.className = "color-picker"; @@ -1900,7 +1950,6 @@ function createColorProperty(property, elProperty, elLabel) { elTuple.className = "tuple"; elProperty.appendChild(elColorPicker); - elProperty.appendChild(elLabel); elProperty.appendChild(elTuple); let elInputR = createTupleNumberInput(elTuple, elementID, "red", COLOR_MIN, COLOR_MAX, COLOR_STEP); @@ -1916,7 +1965,7 @@ function createColorProperty(property, elProperty, elLabel) { let colorPickerID = "#" + elementID; colorPickers[colorPickerID] = $(colorPickerID).colpick({ colorScheme: 'dark', - layout: 'hex', + layout: 'rgbhex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { @@ -1946,12 +1995,12 @@ function createColorProperty(property, elProperty, elLabel) { return elResult; } -function createDropdownProperty(property, propertyID, elProperty, elLabel) { +function createDropdownProperty(property, propertyID, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property dropdown"; + elProperty.className = "dropdown"; let elInput = document.createElement('select'); elInput.setAttribute("id", elementID); @@ -1966,24 +2015,17 @@ function createDropdownProperty(property, propertyID, elProperty, elLabel) { elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); - elProperty.appendChild(elLabel); elProperty.appendChild(elInput); return elInput; } -function createTextareaProperty(property, elProperty, elLabel) { +function createTextareaProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property textarea"; - - elProperty.appendChild(elLabel); - - if (propertyData.buttons !== undefined) { - addButtons(elProperty, elementID, propertyData.buttons, true); - } + elProperty.className = "textarea"; let elInput = document.createElement('textarea'); elInput.setAttribute("id", elementID); @@ -1994,35 +2036,35 @@ function createTextareaProperty(property, elProperty, elLabel) { elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); elProperty.appendChild(elInput); + + if (propertyData.buttons !== undefined) { + addButtons(elProperty, elementID, propertyData.buttons, true); + } return elInput; } -function createIconProperty(property, elProperty, elLabel) { +function createIconProperty(property, elProperty) { let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property value"; - - elLabel.setAttribute("id", elementID); - elLabel.innerHTML = " " + propertyData.label; + elProperty.className = "value"; let elSpan = document.createElement('span'); elSpan.setAttribute("id", elementID + "-icon"); + elSpan.className = 'icon'; elProperty.appendChild(elSpan); - elProperty.appendChild(elLabel); let elResult = []; elResult[ICON_ELEMENTS.ICON] = elSpan; - elResult[ICON_ELEMENTS.LABEL] = elLabel; return elResult; } -function createTextureProperty(property, elProperty, elLabel) { +function createTextureProperty(property, elProperty) { let elementID = property.elementID; - elProperty.className = "property texture"; + elProperty.className = "texture"; let elDiv = document.createElement("div"); let elImage = document.createElement("img"); @@ -2063,9 +2105,8 @@ function createTextureProperty(property, elProperty, elLabel) { }; elInput.onchange = elInput.oninput; - elProperty.appendChild(elLabel); - elProperty.appendChild(elDiv); elProperty.appendChild(elInput); + elProperty.appendChild(elDiv); let elResult = []; elResult[TEXTURE_ELEMENTS.IMAGE] = elImage; @@ -2077,11 +2118,10 @@ function createButtonsProperty(property, elProperty, elLabel) { let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property text"; + elProperty.className = "text"; let hasLabel = propertyData.label !== undefined; if (hasLabel) { - elProperty.appendChild(elLabel); } if (propertyData.buttons !== undefined) { @@ -2096,33 +2136,25 @@ function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, let elDiv = document.createElement('div'); let elLabel = document.createElement('label'); - elLabel.innerText = subLabel[0].toUpperCase() + subLabel.slice(1) + ":"; + elLabel.className = subLabel; + elLabel.innerText = subLabel[0].toUpperCase() + subLabel.slice(1); elLabel.setAttribute("for", elementID); let elInput = document.createElement('input'); - elInput.className = subLabel; + elInput.className = subLabel + " number-slider"; elInput.setAttribute("id", elementID); elInput.setAttribute("type", "number"); elInput.setAttribute("min", min); elInput.setAttribute("max", max); elInput.setAttribute("step", step); - elDiv.appendChild(elInput); elDiv.appendChild(elLabel); + elDiv.appendChild(elInput); elTuple.appendChild(elDiv); return elInput; } -function addUnit(unit, elLabel) { - if (unit !== undefined) { - let elSpan = document.createElement('span'); - elSpan.className = "unit"; - elSpan.innerHTML = unit; - elLabel.appendChild(elSpan); - } -} - function addButtons(elProperty, propertyID, buttons, newRow) { let elDiv = document.createElement('div'); elDiv.className = "row"; @@ -2666,29 +2698,120 @@ function showParentMaterialNameBox(number, elNumber, elString) { } } +function createProperty(propertyData, propertyElementID, propertyName, propertyID, elProperty) { + let property = { + data: propertyData, + elementID: propertyElementID, + name: propertyName, + elProperty: elProperty, + }; + let propertyType = propertyData.type; + + switch (propertyType) { + case 'string': { + property.elInput = createStringProperty(property, elProperty); + break; + } + case 'bool': { + property.elInput = createBoolProperty(property, elProperty); + break; + } + case 'number': { + property.elInput = createNumberProperty(property, elProperty); + break; + } + case 'slider': { + let elSlider = createSliderProperty(property, elProperty); + property.elSlider = elSlider[SLIDER_ELEMENTS.SLIDER]; + property.elInput = elSlider[SLIDER_ELEMENTS.NUMBER_INPUT]; + break; + } + case 'vec3': { + let elVec3 = createVec3Property(property, elProperty); + property.elInputX = elVec3[VECTOR_ELEMENTS.X_INPUT]; + property.elInputY = elVec3[VECTOR_ELEMENTS.Y_INPUT]; + property.elInputZ = elVec3[VECTOR_ELEMENTS.Z_INPUT]; + break; + } + case 'vec2': { + let elVec2 = createVec2Property(property, elProperty); + property.elInputX = elVec2[VECTOR_ELEMENTS.X_INPUT]; + property.elInputY = elVec2[VECTOR_ELEMENTS.Y_INPUT]; + break; + } + case 'color': { + let elColor = createColorProperty(property, elProperty); + property.elColorPicker = elColor[COLOR_ELEMENTS.COLOR_PICKER]; + property.elInputR = elColor[COLOR_ELEMENTS.RED_INPUT]; + property.elInputG = elColor[COLOR_ELEMENTS.GREEN_INPUT]; + property.elInputB = elColor[COLOR_ELEMENTS.BLUE_INPUT]; + break; + } + case 'dropdown': { + property.elInput = createDropdownProperty(property, propertyID, elProperty); + break; + } + case 'textarea': { + property.elInput = createTextareaProperty(property, elProperty); + break; + } + case 'icon': { + let elIcon = createIconProperty(property, elProperty); + property.elSpan = elIcon[ICON_ELEMENTS.ICON]; + property.elLabel = elIcon[ICON_ELEMENTS.LABEL]; + break; + } + case 'texture': { + let elTexture = createTextureProperty(property, elProperty); + property.elImage = elTexture[TEXTURE_ELEMENTS.IMAGE]; + property.elInput = elTexture[TEXTURE_ELEMENTS.TEXT_INPUT]; + break; + } + case 'buttons': { + property.elProperty = createButtonsProperty(property, elProperty); + break; + } + case 'placeholder': + case 'sub-header': { + break; + } + default: { + console.log("EntityProperties - Unknown property type " + + propertyType + " set to property " + propertyID); + break; + } + } + + return property; +} + function loaded() { openEventBridge(function() { let elPropertiesList = document.getElementById("properties-list"); + + let templatePropertyRow = document.getElementById('property-row'); - GROUPS.forEach(function(group) { + GROUPS.forEach(function(group) { let elGroup; if (group.addToGroup !== undefined) { let fieldset = document.getElementById("properties-" + group.addToGroup); elGroup = document.createElement('div'); fieldset.appendChild(elGroup); } else { - elGroup = document.createElement('fieldset'); - elGroup.className = "major"; + elGroup = document.createElement('div'); + elGroup.className = 'section ' + (group.isMinor ? "minor" : "major"); elGroup.setAttribute("id", "properties-" + group.id); elPropertiesList.appendChild(elGroup); } if (group.label !== undefined) { - let elLegend = document.createElement('legend'); + let elLegend = document.createElement('div'); elLegend.className = "section-header"; - elLegend.innerText = group.label; + + elLegend.appendChild(createElementFromHTML(`
${group.label}
`)); + let elSpan = document.createElement('span'); elSpan.className = ".collapse-icon"; elSpan.innerText = "M"; @@ -2703,143 +2826,117 @@ function loaded() { let propertyElementID = "property-" + propertyID; propertyElementID = propertyElementID.replace('.', '-'); - let elProperty; - if (propertyType === "sub-header") { - elProperty = document.createElement('legend'); - elProperty.className = "sub-section-header"; - elProperty.innerText = propertyData.label; - } else { - elProperty = document.createElement('div'); - elProperty.setAttribute("id", "div-" + propertyElementID); - } + let elContainer, elLabel; - if (group.twoColumn && propertyData.column !== undefined && propertyData.column !== -1) { - let columnName = group.id + "column" + propertyData.column; - let elColumn = document.getElementById(columnName); - if (!elColumn) { - let columnDivName = group.id + "columnDiv"; - let elColumnDiv = document.getElementById(columnDivName); - if (!elColumnDiv) { - elColumnDiv = document.createElement('div'); - elColumnDiv.className = "two-column"; - elColumnDiv.setAttribute("id", group.id + "columnDiv"); - elGroup.appendChild(elColumnDiv); - } - elColumn = document.createElement('fieldset'); - elColumn.className = "column"; - elColumn.setAttribute("id", columnName); - elColumnDiv.appendChild(elColumn); + if (propertyData.replaceID === undefined) { + // Create subheader, or create new property and append it. + if (propertyType === "sub-header") { + elContainer = createElementFromHTML( + `
${propertyData.label}
`); + } else { + elContainer = document.createElement('div'); + elContainer.setAttribute("id", "div-" + propertyElementID); + elContainer.className = 'property container'; } - elColumn.appendChild(elProperty); - } else { - elGroup.appendChild(elProperty); - } - - let elLabel = document.createElement('label'); - elLabel.innerText = propertyData.label; - elLabel.setAttribute("for", propertyElementID); - createAppTooltip.registerTooltipElement(elLabel, propertyID); - - let property = { - data: propertyData, - elementID: propertyElementID, - name: propertyName, - isParticleProperty: group.id.includes("particles"), - elProperty: elProperty - }; - properties[propertyID] = property; - - switch (propertyType) { - case 'string': { - properties[propertyID].elInput = createStringProperty(property, elProperty, elLabel); - break; + if (group.twoColumn && propertyData.column !== undefined && propertyData.column !== -1) { + let columnName = group.id + "column" + propertyData.column; + let elColumn = document.getElementById(columnName); + if (!elColumn) { + let columnDivName = group.id + "columnDiv"; + let elColumnDiv = document.getElementById(columnDivName); + if (!elColumnDiv) { + elColumnDiv = document.createElement('div'); + elColumnDiv.className = "two-column"; + elColumnDiv.setAttribute("id", group.id + "columnDiv"); + elGroup.appendChild(elColumnDiv); + } + elColumn = document.createElement('fieldset'); + elColumn.className = "column"; + elColumn.setAttribute("id", columnName); + elColumnDiv.appendChild(elColumn); + } + elColumn.appendChild(elContainer); + } else { + elGroup.appendChild(elContainer); } - case 'bool': { - properties[propertyID].elInput = createBoolProperty(property, elProperty, elLabel); - break; - } - case 'number': { - properties[propertyID].elInput = createNumberProperty(property, elProperty, elLabel); - break; - } - case 'slider': { - let elSlider = createSliderProperty(property, elProperty, elLabel); - properties[propertyID].elSlider = elSlider[SLIDER_ELEMENTS.SLIDER]; - properties[propertyID].elInput = elSlider[SLIDER_ELEMENTS.NUMBER_INPUT]; - break; - } - case 'vec3': { - let elVec3 = createVec3Property(property, elProperty, elLabel); - properties[propertyID].elInputX = elVec3[VECTOR_ELEMENTS.X_INPUT]; - properties[propertyID].elInputY = elVec3[VECTOR_ELEMENTS.Y_INPUT]; - properties[propertyID].elInputZ = elVec3[VECTOR_ELEMENTS.Z_INPUT]; - break; - } - case 'vec2': { - let elVec2 = createVec2Property(property, elProperty, elLabel); - properties[propertyID].elInputX = elVec2[VECTOR_ELEMENTS.X_INPUT]; - properties[propertyID].elInputY = elVec2[VECTOR_ELEMENTS.Y_INPUT]; - break; - } - case 'color': { - let elColor = createColorProperty(property, elProperty, elLabel); - properties[propertyID].elColorPicker = elColor[COLOR_ELEMENTS.COLOR_PICKER]; - properties[propertyID].elInputR = elColor[COLOR_ELEMENTS.RED_INPUT]; - properties[propertyID].elInputG = elColor[COLOR_ELEMENTS.GREEN_INPUT]; - properties[propertyID].elInputB = elColor[COLOR_ELEMENTS.BLUE_INPUT]; - break; - } - case 'dropdown': { - properties[propertyID].elInput = createDropdownProperty(property, propertyID, elProperty, elLabel); - break; - } - case 'textarea': { - properties[propertyID].elInput = createTextareaProperty(property, elProperty, elLabel); - break; - } - case 'icon': { - let elIcon = createIconProperty(property, elProperty, elLabel); - properties[propertyID].elSpan = elIcon[ICON_ELEMENTS.ICON]; - properties[propertyID].elLabel = elIcon[ICON_ELEMENTS.LABEL]; - break; - } - case 'texture': { - let elTexture = createTextureProperty(property, elProperty, elLabel); - properties[propertyID].elImage = elTexture[TEXTURE_ELEMENTS.IMAGE]; - properties[propertyID].elInput = elTexture[TEXTURE_ELEMENTS.TEXT_INPUT]; - break; - } - case 'buttons': { - properties[propertyID].elProperty = createButtonsProperty(property, elProperty, elLabel); - break; - } - case 'sub-header': { - break; - } - default: { - console.log("EntityProperties - Unknown property type " + - propertyType + " set to property " + propertyID); - break; + + elLabel = document.createElement('label'); + elLabel.setAttribute("for", propertyElementID); + if (propertyData.indentedLabel || propertyData.showPropertyRule !== undefined) { + let elSpan = document.createElement('span'); + elSpan.className = 'indented'; + elSpan.innerText = propertyData.label; + elLabel.appendChild(elSpan); + } else { + elLabel.innerText = propertyData.label; } + elContainer.appendChild(elLabel); + } else { + elContainer = document.getElementById(propertyData.replaceID); } - - let showPropertyRule = propertyData.showPropertyRule; - if (showPropertyRule !== undefined) { - let dependentProperty = Object.keys(showPropertyRule)[0]; - let dependentPropertyValue = showPropertyRule[dependentProperty]; - if (properties[dependentProperty] === undefined) { - properties[dependentProperty] = {}; + + if (elLabel) { + createAppTooltip.registerTooltipElement(elLabel, propertyID); + } + + let elProperty = createElementFromHTML('
'); + elContainer.appendChild(elProperty); + + if (propertyType == 'triple') { + elProperty.className = 'flex-row'; + for (var i = 0; i < propertyData.properties.length; ++i) { + let innerPropertyData = propertyData.properties[i]; + + let elWrapper = createElementFromHTML('
'); + + let propertyID = innerPropertyData.propertyID; + let propertyName = innerPropertyData.propertyName !== undefined ? innerPropertyData.propertyName : propertyID; + let propertyElementID = "property-" + propertyID; + propertyElementID = propertyElementID.replace('.', '-'); + + elWrapper.appendChild(createElementFromHTML(`
${innerPropertyData.label}
`)); + elProperty.appendChild(elWrapper); + + let property = createProperty(innerPropertyData, propertyElementID, propertyName, propertyID, elWrapper.childNodes[0]); + property.isParticleProperty = group.id.includes("particles"); + property.elContainer = elContainer; + + if (property.type !== 'placeholder') { + properties[propertyID] = property; + } } - if (properties[dependentProperty].showPropertyRules === undefined) { - properties[dependentProperty].showPropertyRules = {}; + } else { + let property = createProperty(propertyData, propertyElementID, propertyName, propertyID, elProperty); + property.elementID = propertyElementID; + property.name = propertyName; + property.isParticleProperty = group.id.includes("particles"); + property.elContainer = elContainer; + + if (property.type !== 'placeholder') { + properties[propertyID] = property; + } + + let showPropertyRule = propertyData.showPropertyRule; + if (showPropertyRule !== undefined) { + let dependentProperty = Object.keys(showPropertyRule)[0]; + let dependentPropertyValue = showPropertyRule[dependentProperty]; + if (properties[dependentProperty] === undefined) { + properties[dependentProperty] = {}; + } + if (properties[dependentProperty].showPropertyRules === undefined) { + properties[dependentProperty].showPropertyRules = {}; + } + properties[dependentProperty].showPropertyRules[propertyID] = dependentPropertyValue; } - properties[dependentProperty].showPropertyRules[propertyID] = dependentPropertyValue; } }); elGroups[group.id] = elGroup; }); + + let minorSections = document.querySelectorAll(".section.minor"); + minorSections[minorSections.length - 1].className += " last"; if (window.EventBridge !== undefined) { EventBridge.scriptEventReceived.connect(function(data) { @@ -2874,6 +2971,10 @@ function loaded() { resetProperties(); showGroupsForType("None"); + + let elIcon = properties.type.elSpan; + elIcon.innerText = NO_SELECTION; + elIcon.style.display = 'inline-block'; deleteJSONEditor(); getPropertyInputElement("userData").value = ""; @@ -3063,7 +3164,6 @@ function loaded() { case 'icon': { property.elSpan.innerHTML = propertyData.icons[propertyValue]; property.elSpan.style.display = "inline-block"; - property.elLabel.innerHTML = propertyValue; break; } case 'texture': { @@ -3175,34 +3275,27 @@ function loaded() { } // Server Script Status - let serverScriptProperty = properties["serverScripts"]; - let elServerScript = serverScriptProperty.elInput; - let serverScriptElementID = serverScriptProperty.elementID; - let serverScriptStatusElementID = serverScriptElementID + "-status"; - let elDiv = document.createElement('div'); - elDiv.className = "property"; - elDiv.setAttribute("id", "div-" + serverScriptStatusElementID); - let elLabel = document.createElement('label'); - elLabel.setAttribute("for", serverScriptStatusElementID); - elLabel.innerText = "Server Script Status"; - createAppTooltip.registerTooltipElement(elLabel, "serverScriptsStatus"); - let elServerScriptStatus = document.createElement('span'); + let elServerScriptStatusOuter = document.getElementById('div-property-serverScriptStatus'); + let elServerScriptStatusContainer = document.getElementById('div-property-serverScriptStatus').childNodes[1]; + let serverScriptStatusElementID = 'property-serverScripts-status'; + createAppTooltip.registerTooltipElement(elServerScriptStatusOuter.childNodes[0], "serverScriptsStatus"); + let elServerScriptStatus = document.createElement('div'); elServerScriptStatus.setAttribute("id", serverScriptStatusElementID); - elDiv.appendChild(elLabel); - elDiv.appendChild(elServerScriptStatus); - elServerScript.parentNode.appendChild(elDiv); + elServerScriptStatusContainer.appendChild(elServerScriptStatus); // Server Script Error + let elServerScripts = getPropertyInputElement("serverScripts"); elDiv = document.createElement('div'); elDiv.className = "property"; let elServerScriptError = document.createElement('textarea'); - elServerScriptError.setAttribute("id", serverScriptElementID + "-error"); + let serverScriptErrorElementID = 'property-serverScripts-error'; + elServerScriptError.setAttribute("id", serverScriptErrorElementID); elDiv.appendChild(elServerScriptError); - elServerScript.parentNode.appendChild(elDiv); + elServerScriptStatusContainer.appendChild(elDiv); let elScript = getPropertyInputElement("script"); - elScript.parentNode.className = "property url refresh"; - elServerScript.parentNode.className = "property url refresh"; + elScript.parentNode.className = "url refresh"; + elServerScripts.parentNode.className = "url refresh"; // User Data let userDataProperty = properties["userData"]; @@ -3262,7 +3355,7 @@ function loaded() { let elCollapsible = document.getElementsByClassName("section-header"); let toggleCollapsedEvent = function(event) { - let element = event.target.parentNode.parentNode; + let element = this.parentNode; let isCollapsed = element.dataset.collapsed !== "true"; element.dataset.collapsed = isCollapsed ? "true" : false; element.setAttribute("collapsed", isCollapsed ? "true" : "false"); @@ -3271,7 +3364,7 @@ function loaded() { for (let collapseIndex = 0, numCollapsibles = elCollapsible.length; collapseIndex < numCollapsibles; ++collapseIndex) { let curCollapsibleElement = elCollapsible[collapseIndex]; - curCollapsibleElement.getElementsByTagName('span')[0].addEventListener("click", toggleCollapsedEvent, true); + curCollapsibleElement.addEventListener("click", toggleCollapsedEvent, true); } // Textarea scrollbars From 3b57e45fdd2b4225e91fe091a2afa81429929e74 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 8 Nov 2018 16:33:25 -0800 Subject: [PATCH 03/18] Remove redundant dimensions in default entity properties --- scripts/system/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index c8811bd603..705e0fc8c4 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -466,7 +466,6 @@ const DEFAULT_ENTITY_PROPERTIES = { isSpotlight: false, exponent: 1.0, cutoff: 75.0, - dimensions: { x: 20, y: 20, z: 20 }, }, }; From 615ffebb2cb4850a1c2793bce55909f31d7293d4 Mon Sep 17 00:00:00 2001 From: David Back Date: Fri, 9 Nov 2018 13:14:05 -0800 Subject: [PATCH 04/18] new draggable numbers WIP --- scripts/system/html/css/edit-style.css | 38 ++- scripts/system/html/entityProperties.html | 1 + scripts/system/html/js/draggableNumber.js | 92 ++++++++ scripts/system/html/js/entityProperties.js | 258 +++++++-------------- 4 files changed, 204 insertions(+), 185 deletions(-) create mode 100644 scripts/system/html/js/draggableNumber.js diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 8137d6e659..5107ad8a3d 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -309,6 +309,34 @@ input[type=number].hover-down::-webkit-inner-spin-button:after { color: #ffffff; } +.draggable-number { + position: relative; + right: 10px; +} +.draggable-number span { + position: relative; + top: -2px; + display: inline-block; + font-family: hifi-glyphs; + font-size: 20px; + z-index: 2; +} +.draggable-number.left-arrow { + left: 18px; + transform: rotate(180deg); +} +.draggable-number.right-arrow { + right: 18px; +} +.draggable-number input { +} +.draggable-number input::selection { +} +.draggable-number input::-webkit-inner-spin-button { + -webkit-appearance: none; + visibility: hidden; +} + input[type=range] { -webkit-appearance: none; background: #2e2e2e; @@ -1460,11 +1488,9 @@ th#entity-hasScript { } input#property-scale-button-rescale { - margin-top: 6px; min-width: 50px; } input#property-scale-button-reset { - margin-top: 6px; margin-right: 0; } @@ -1593,9 +1619,9 @@ input.rename-entity { display: flex; flex-flow: row; } -.fstuple input { - margin-left: 4px; - margin-right: 10px; +.fstuple label { + position: relative; + left: 10px; } .fstuple label.red, .fstuple label.x { color: #C62147; @@ -1609,7 +1635,7 @@ input.rename-entity { .xyz.fstuple, .pyr.fstuple { position: relative; - left: -12px; + left: -19px; } .rgb.fstuple .tuple { diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 6af8ee992a..01395368b0 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -22,6 +22,7 @@ + diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js new file mode 100644 index 0000000000..62fa02c6f9 --- /dev/null +++ b/scripts/system/html/js/draggableNumber.js @@ -0,0 +1,92 @@ +// draggableNumber.js +// +// Created by David Back on 7 Nov 2018 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +debugPrint = function (message) { + console.log(message); +}; + +function DraggableNumber(min, max, step) { + this.min = min; + this.max = max; + this.step = step !== undefined ? step : 1; + this.startEvent = null; + this.initialize(); +} + +DraggableNumber.prototype = { + onMouseDown: function(event) { + let that = this.draggableNumber; + that.mouseDown(event); + }, + + mouseDown: function(event) { + this.startEvent = event; + document.addEventListener("mousemove", this.onMouseMove); + document.addEventListener("mouseup", this.onMouseUp); + }, + + mouseMove: function(event, that) { + if (this.startEvent) { + let dx = event.clientX - this.startEvent.clientX; + let valueChange = dx * this.step; + let newValue = parseFloat(this.elInput.value) + valueChange; + if (this.min !== undefined && newValue < this.min) { + newValue = this.min; + } else if (this.max !== undefined && newValue > this.max) { + newValue = this.max; + } + this.elInput.value = newValue; + this.inputChangeFunction(); + this.startEvent = event; + } + }, + + mouseUp: function(event) { + this.startEvent = null; + document.removeEventListener("mousemove", this.onMouseMove); + document.removeEventListener("mouseup", this.onMouseUp); + }, + + setInputChangeFunction: function(inputChangeFunction) { + this.inputChangeFunction = inputChangeFunction.bind(this.elInput); + this.elInput.addEventListener('change', this.inputChangeFunction); + }, + + initialize: function() { + this.onMouseMove = this.mouseMove.bind(this); + this.onMouseUp = this.mouseUp.bind(this); + + this.elDiv = document.createElement('div'); + this.elDiv.className = "draggable-number"; + + this.elInput = document.createElement('input'); + this.elInput.setAttribute("type", "number"); + if (this.min !== undefined) { + this.elInput.setAttribute("min", this.min); + } + if (this.max !== undefined) { + this.elInput.setAttribute("max", this.max); + } + if (this.step !== undefined) { + this.elInput.setAttribute("step", this.step); + } + this.elInput.draggableNumber = this; + this.elInput.addEventListener("mousedown", this.onMouseDown); + + this.elLeftArrow = document.createElement('span'); + this.elRightArrow = document.createElement('span'); + this.elLeftArrow.className = 'draggable-number left-arrow'; + this.elLeftArrow.innerHTML = 'D'; + this.elRightArrow.className = 'draggable-number right-arrow'; + this.elRightArrow.innerHTML = 'D'; + + this.elDiv.appendChild(this.elLeftArrow); + this.elDiv.appendChild(this.elInput); + this.elDiv.appendChild(this.elRightArrow); + } +}; diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index e5e7426dd2..5ea810a069 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -309,7 +309,7 @@ const GROUPS = [ }, { label: "Background Blend", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -331,7 +331,7 @@ const GROUPS = [ }, { label: "Glare Angle", - type: "slider", + type: "number", min: 0, max: 180, step: 1, @@ -347,7 +347,7 @@ const GROUPS = [ }, { label: "Bloom Intensity", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -357,7 +357,7 @@ const GROUPS = [ }, { label: "Bloom Threshold", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -367,7 +367,7 @@ const GROUPS = [ }, { label: "Bloom Size", - type: "slider", + type: "number", min: 0, max: 2, step: 0.01, @@ -615,7 +615,7 @@ const GROUPS = [ }, { label: "Lifespan", - type: "slider", + type: "number", unit: "s", min: 0.01, max: 10, @@ -625,7 +625,7 @@ const GROUPS = [ }, { label: "Max Particles", - type: "slider", + type: "number", min: 1, max: 10000, step: 1, @@ -646,7 +646,7 @@ const GROUPS = [ properties: [ { label: "Emit Rate", - type: "slider", + type: "number", min: 1, max: 1000, step: 1, @@ -654,7 +654,7 @@ const GROUPS = [ }, { label: "Emit Speed", - type: "slider", + type: "number", min: 0, max: 5, step: 0.01, @@ -663,7 +663,7 @@ const GROUPS = [ }, { label: "Speed Spread", - type: "slider", + type: "number", min: 0, max: 5, step: 0.01, @@ -682,7 +682,7 @@ const GROUPS = [ }, { label: "Emit Radius Start", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -717,7 +717,7 @@ const GROUPS = [ properties: [ { label: "Start", - type: "slider", + type: "number", min: 0, max: 4, step: 0.01, @@ -727,7 +727,7 @@ const GROUPS = [ }, { label: "Middle", - type: "slider", + type: "number", min: 0, max: 4, step: 0.01, @@ -736,7 +736,7 @@ const GROUPS = [ }, { label: "Finish", - type: "slider", + type: "number", min: 0, max: 4, step: 0.01, @@ -748,7 +748,7 @@ const GROUPS = [ }, { label: "Size Spread", - type: "slider", + type: "number", min: 0, max: 4, step: 0.01, @@ -804,7 +804,7 @@ const GROUPS = [ properties: [ { label: "Start", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -814,7 +814,7 @@ const GROUPS = [ }, { label: "Middle", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -823,7 +823,7 @@ const GROUPS = [ }, { label: "Finish", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -835,7 +835,7 @@ const GROUPS = [ }, { label: "Alpha Spread", - type: "slider", + type: "number", min: 0, max: 1, step: 0.01, @@ -880,7 +880,7 @@ const GROUPS = [ properties: [ { label: "Start", - type: "slider", + type: "number", min: -360, max: 360, step: 1, @@ -892,7 +892,7 @@ const GROUPS = [ }, { label: "Middle", - type: "slider", + type: "number", min: -360, max: 360, step: 1, @@ -903,7 +903,7 @@ const GROUPS = [ }, { label: "Finish", - type: "slider", + type: "number", min: -360, max: 360, step: 1, @@ -917,7 +917,7 @@ const GROUPS = [ }, { label: "Spin Spread", - type: "slider", + type: "number", min: 0, max: 360, step: 1, @@ -944,7 +944,7 @@ const GROUPS = [ properties: [ { label: "Start", - type: "slider", + type: "number", min: -180, max: 0, step: 1, @@ -955,7 +955,7 @@ const GROUPS = [ }, { label: "Finish", - type: "slider", + type: "number", min: 0, max: 180, step: 1, @@ -972,7 +972,7 @@ const GROUPS = [ properties: [ { label: "Start", - type: "slider", + type: "number", min: 0, max: 180, step: 1, @@ -983,7 +983,7 @@ const GROUPS = [ }, { label: "Finish", - type: "slider", + type: "number", min: 0, max: 180, step: 1, @@ -1348,11 +1348,6 @@ const COLOR_ELEMENTS = { BLUE_INPUT: 3, }; -const SLIDER_ELEMENTS = { - SLIDER: 0, - NUMBER_INPUT: 1, -}; - const ICON_ELEMENTS = { ICON: 0, LABEL: 1, @@ -1399,7 +1394,6 @@ function getPropertyInputElement(propertyID) { case 'string': case 'bool': case 'number': - case 'slider': case 'dropdown': case 'textarea': case 'texture': @@ -1478,16 +1472,12 @@ function resetProperties() { property.elInput.checked = false; break; } - case 'number': - case 'slider': { + case 'number': { if (propertyData.defaultValue !== undefined) { property.elInput.value = propertyData.defaultValue; } else { property.elInput.value = ""; } - if (property.elSlider !== undefined) { - property.elSlider.value = property.elInput.value; - } break; } case 'vec3': @@ -1782,98 +1772,21 @@ function createNumberProperty(property, elProperty) { let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "number"; + elProperty.className = "property draggable-number"; - let elInput = document.createElement('input'); - elInput.setAttribute("id", elementID); - elInput.setAttribute("type", "number"); - if (propertyData.min !== undefined) { - elInput.setAttribute("min", propertyData.min); - } - if (propertyData.max !== undefined) { - elInput.setAttribute("max", propertyData.max); - } - if (propertyData.step !== undefined) { - elInput.setAttribute("step", propertyData.step); - } - - let defaultValue = propertyData.defaultValue; - if (defaultValue !== undefined) { - elInput.value = defaultValue; - } - - elInput.addEventListener('change', createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, propertyData.decimals, property.isParticleProperty)); - - elProperty.appendChild(elInput); + let elDraggableNumber = new DraggableNumber(propertyData.min, propertyData.max, propertyData.step); + + let inputChangeFunction = createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, propertyData.decimals, property.isParticleProperty); + elDraggableNumber.setInputChangeFunction(inputChangeFunction); + elDraggableNumber.elInput.setAttribute("id", elementID); + elProperty.appendChild(elDraggableNumber.elDiv); + if (propertyData.buttons !== undefined) { - addButtons(elProperty, elementID, propertyData.buttons, true); + addButtons(elDraggableNumber.elDiv, elementID, propertyData.buttons, false); } - return elInput; -} - -function createSliderProperty(property, elProperty) { - let propertyData = property.data; - - elProperty.className = "range"; - - let elDiv = document.createElement("div"); - elDiv.className = "slider-wrapper"; - - let elSlider = document.createElement("input"); - elSlider.setAttribute("type", "range"); - - let elInput = document.createElement("input"); - elInput.setAttribute("type", "number"); - - if (propertyData.min !== undefined) { - elInput.setAttribute("min", propertyData.min); - elSlider.setAttribute("min", propertyData.min); - } - if (propertyData.max !== undefined) { - elInput.setAttribute("max", propertyData.max); - elSlider.setAttribute("max", propertyData.max); - elSlider.setAttribute("data-max", propertyData.max); - } - if (propertyData.step !== undefined) { - elInput.setAttribute("step", propertyData.step); - elSlider.setAttribute("step", propertyData.step); - } - - elInput.onchange = function (event) { - let inputValue = event.target.value; - elSlider.value = inputValue; - if (propertyData.multiplier !== undefined) { - inputValue *= propertyData.multiplier; - } - updateProperty(property.name, inputValue, property.isParticleProperty); - }; - elSlider.oninput = function (event) { - let sliderValue = event.target.value; - if (propertyData.step === 1) { - if (sliderValue > 0) { - elInput.value = Math.floor(sliderValue); - } else { - elInput.value = Math.ceil(sliderValue); - } - } else { - elInput.value = sliderValue; - } - if (propertyData.multiplier !== undefined) { - sliderValue *= propertyData.multiplier; - } - updateProperty(property.name, sliderValue, property.isParticleProperty); - }; - - elDiv.appendChild(elSlider); - elDiv.appendChild(elInput); - elProperty.appendChild(elDiv); - - let elResult = []; - elResult[SLIDER_ELEMENTS.SLIDER] = elSlider; - elResult[SLIDER_ELEMENTS.NUMBER_INPUT] = elInput; - return elResult; + return elDraggableNumber.elInput; } function createVec3Property(property, elProperty) { @@ -1888,23 +1801,24 @@ function createVec3Property(property, elProperty) { //elProperty.appendChild(elTuple); - let elInputX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], - propertyData.min, propertyData.max, propertyData.step); - let elInputY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], - propertyData.min, propertyData.max, propertyData.step); - let elInputZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_INPUT], - propertyData.min, propertyData.max, propertyData.step); + let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], + propertyData.min, propertyData.max, propertyData.step); + let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], + propertyData.min, propertyData.max, propertyData.step); + let elNumberZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_INPUT], + propertyData.min, propertyData.max, propertyData.step); - let inputChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elInputX, elInputY, elInputZ, - propertyData.multiplier, property.isParticleProperty); - elInputX.addEventListener('change', inputChangeFunction); - elInputY.addEventListener('change', inputChangeFunction); - elInputZ.addEventListener('change', inputChangeFunction); + let inputChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, + elNumberZ.elInput, propertyData.multiplier, + property.isParticleProperty); + elNumberX.setInputChangeFunction(inputChangeFunction); + elNumberY.setInputChangeFunction(inputChangeFunction); + elNumberZ.setInputChangeFunction(inputChangeFunction); let elResult = []; - elResult[VECTOR_ELEMENTS.X_INPUT] = elInputX; - elResult[VECTOR_ELEMENTS.Y_INPUT] = elInputY; - elResult[VECTOR_ELEMENTS.Z_INPUT] = elInputZ; + elResult[VECTOR_ELEMENTS.X_INPUT] = elNumberX.elInput; + elResult[VECTOR_ELEMENTS.Y_INPUT] = elNumberY.elInput; + elResult[VECTOR_ELEMENTS.Z_INPUT] = elNumberZ.elInput; return elResult; } @@ -1920,19 +1834,19 @@ function createVec2Property(property, elProperty) { elProperty.appendChild(elTuple); - let elInputX = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], - propertyData.min, propertyData.max, propertyData.step); - let elInputY = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], - propertyData.min, propertyData.max, propertyData.step); + let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], + propertyData.min, propertyData.max, propertyData.step); + let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], + propertyData.min, propertyData.max, propertyData.step); - let inputChangeFunction = createEmitVec2PropertyUpdateFunction(propertyName, elInputX, elInputY, + let inputChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, propertyData.multiplier, property.isParticleProperty); - elInputX.addEventListener('change', inputChangeFunction); - elInputY.addEventListener('change', inputChangeFunction); + elNumberX.setInputChangeFunction(inputChangeFunction); + elNumberY.setInputChangeFunction(inputChangeFunction); let elResult = []; - elResult[VECTOR_ELEMENTS.X_INPUT] = elInputX; - elResult[VECTOR_ELEMENTS.Y_INPUT] = elInputY; + elResult[VECTOR_ELEMENTS.X_INPUT] = elNumberX.elInput; + elResult[VECTOR_ELEMENTS.Y_INPUT] = elNumberY.elInput; return elResult; } @@ -1952,15 +1866,15 @@ function createColorProperty(property, elProperty) { elProperty.appendChild(elColorPicker); elProperty.appendChild(elTuple); - let elInputR = createTupleNumberInput(elTuple, elementID, "red", COLOR_MIN, COLOR_MAX, COLOR_STEP); - let elInputG = createTupleNumberInput(elTuple, elementID, "green", COLOR_MIN, COLOR_MAX, COLOR_STEP); - let elInputB = createTupleNumberInput(elTuple, elementID, "blue", COLOR_MIN, COLOR_MAX, COLOR_STEP); + let elNumberR = createTupleNumberInput(elTuple, elementID, "red", COLOR_MIN, COLOR_MAX, COLOR_STEP); + let elNumberG = createTupleNumberInput(elTuple, elementID, "green", COLOR_MIN, COLOR_MAX, COLOR_STEP); + let elNumberB = createTupleNumberInput(elTuple, elementID, "blue", COLOR_MIN, COLOR_MAX, COLOR_STEP); - let inputChangeFunction = createEmitColorPropertyUpdateFunction(propertyName, elInputR, elInputG, elInputB, - property.isParticleProperty); - elInputR.addEventListener('change', inputChangeFunction); - elInputG.addEventListener('change', inputChangeFunction); - elInputB.addEventListener('change', inputChangeFunction); + let inputChangeFunction = createEmitColorPropertyUpdateFunction(propertyName, elNumberR.elInput, elNumberG.elInput, + elNumberB.elInput, property.isParticleProperty); + elNumberR.setInputChangeFunction(inputChangeFunction); + elNumberG.setInputChangeFunction(inputChangeFunction); + elNumberB.setInputChangeFunction(inputChangeFunction); let colorPickerID = "#" + elementID; colorPickers[colorPickerID] = $(colorPickerID).colpick({ @@ -1989,9 +1903,9 @@ function createColorProperty(property, elProperty) { let elResult = []; elResult[COLOR_ELEMENTS.COLOR_PICKER] = elColorPicker; - elResult[COLOR_ELEMENTS.RED_INPUT] = elInputR; - elResult[COLOR_ELEMENTS.GREEN_INPUT] = elInputG; - elResult[COLOR_ELEMENTS.BLUE_INPUT] = elInputB; + elResult[COLOR_ELEMENTS.RED_INPUT] = elNumberR.elInput; + elResult[COLOR_ELEMENTS.GREEN_INPUT] = elNumberG.elInput; + elResult[COLOR_ELEMENTS.BLUE_INPUT] = elNumberB.elInput; return elResult; } @@ -2125,7 +2039,7 @@ function createButtonsProperty(property, elProperty, elLabel) { } if (propertyData.buttons !== undefined) { - addButtons(elProperty, elementID, propertyData.buttons, hasLabel); + addButtons(elProperty, elementID, propertyData.buttons, false); } return elProperty; @@ -2134,25 +2048,17 @@ function createButtonsProperty(property, elProperty, elLabel) { function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, step) { let elementID = propertyElementID + "-" + subLabel.toLowerCase(); - let elDiv = document.createElement('div'); let elLabel = document.createElement('label'); elLabel.className = subLabel; elLabel.innerText = subLabel[0].toUpperCase() + subLabel.slice(1); elLabel.setAttribute("for", elementID); - let elInput = document.createElement('input'); - elInput.className = subLabel + " number-slider"; - elInput.setAttribute("id", elementID); - elInput.setAttribute("type", "number"); - elInput.setAttribute("min", min); - elInput.setAttribute("max", max); - elInput.setAttribute("step", step); + let elDraggableNumber = new DraggableNumber(min, max, step); + elDraggableNumber.elInput.setAttribute("id", elementID); + elDraggableNumber.elDiv.insertBefore(elLabel, elDraggableNumber.elLeftArrow); + elTuple.appendChild(elDraggableNumber.elDiv); - elDiv.appendChild(elLabel); - elDiv.appendChild(elInput); - elTuple.appendChild(elDiv); - - return elInput; + return elDraggableNumber; } function addButtons(elProperty, propertyID, buttons, newRow) { @@ -2720,12 +2626,6 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI property.elInput = createNumberProperty(property, elProperty); break; } - case 'slider': { - let elSlider = createSliderProperty(property, elProperty); - property.elSlider = elSlider[SLIDER_ELEMENTS.SLIDER]; - property.elInput = elSlider[SLIDER_ELEMENTS.NUMBER_INPUT]; - break; - } case 'vec3': { let elVec3 = createVec3Property(property, elProperty); property.elInputX = elVec3[VECTOR_ELEMENTS.X_INPUT]; From 08d9eda7d7115a785fb8f72fd63039df91a5378d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Nov 2018 17:08:10 -0800 Subject: [PATCH 05/18] fix property bugs / style issues --- scripts/system/html/css/edit-style.css | 55 +++++++++++----------- scripts/system/html/js/draggableNumber.js | 8 +++- scripts/system/html/js/entityProperties.js | 18 ++++--- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 5107ad8a3d..cb8dd7bcbc 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -309,34 +309,6 @@ input[type=number].hover-down::-webkit-inner-spin-button:after { color: #ffffff; } -.draggable-number { - position: relative; - right: 10px; -} -.draggable-number span { - position: relative; - top: -2px; - display: inline-block; - font-family: hifi-glyphs; - font-size: 20px; - z-index: 2; -} -.draggable-number.left-arrow { - left: 18px; - transform: rotate(180deg); -} -.draggable-number.right-arrow { - right: 18px; -} -.draggable-number input { -} -.draggable-number input::selection { -} -.draggable-number input::-webkit-inner-spin-button { - -webkit-appearance: none; - visibility: hidden; -} - input[type=range] { -webkit-appearance: none; background: #2e2e2e; @@ -903,6 +875,33 @@ div.refresh input[type="button"] { clear: both; } +.draggable-number { + position: relative; + right: 10px; +} +.draggable-number span { + position: relative; + top: -2px; + display: inline-block; + font-family: hifi-glyphs; + font-size: 20px; + z-index: 2; +} +.draggable-number.left-arrow { + left: 17px; + transform: rotate(180deg); +} +.draggable-number.right-arrow { + right: 17px; +} +.draggable-number.fstuple span { + top: 0; +} +.draggable-number input::-webkit-inner-spin-button { + -webkit-appearance: none; + visibility: hidden; +} + .row .property { width: auto; display: inline-block; diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index 62fa02c6f9..30ad6f1b5c 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -15,6 +15,7 @@ function DraggableNumber(min, max, step) { this.max = max; this.step = step !== undefined ? step : 1; this.startEvent = null; + this.inputChangeFunction = null; this.initialize(); } @@ -41,7 +42,9 @@ DraggableNumber.prototype = { newValue = this.max; } this.elInput.value = newValue; - this.inputChangeFunction(); + if (this.inputChangeFunction) { + this.inputChangeFunction(); + } this.startEvent = event; } }, @@ -53,6 +56,9 @@ DraggableNumber.prototype = { }, setInputChangeFunction: function(inputChangeFunction) { + if (this.inputChangeFunction) { + this.elInput.removeEventListener('change', this.inputChangeFunction); + } this.inputChangeFunction = inputChangeFunction.bind(this.elInput); this.elInput.addEventListener('change', this.inputChangeFunction); }, diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 5ea810a069..204b97918e 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -254,7 +254,7 @@ const GROUPS = [ buttons: [ { id: "copy", label: "Copy from Skybox", className: "black", onClick: copySkyboxURLToAmbientURL } ], propertyID: "copyURLToAmbient", - showPropertyRule: { "skyboxMode": "enabled" }, + showPropertyRule: { "ambientLightMode": "enabled" }, }, { label: "Haze", @@ -1772,9 +1772,14 @@ function createNumberProperty(property, elProperty) { let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property draggable-number"; + elProperty.className = "draggable-number"; let elDraggableNumber = new DraggableNumber(propertyData.min, propertyData.max, propertyData.step); + + let defaultValue = propertyData.defaultValue; + if (defaultValue !== undefined) { + elDraggableNumber.elInput.value = defaultValue; + } let inputChangeFunction = createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, propertyData.decimals, property.isParticleProperty); elDraggableNumber.setInputChangeFunction(inputChangeFunction); @@ -1839,7 +1844,7 @@ function createVec2Property(property, elProperty) { let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], propertyData.min, propertyData.max, propertyData.step); - let inputChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, + let inputChangeFunction = createEmitVec2PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, propertyData.multiplier, property.isParticleProperty); elNumberX.setInputChangeFunction(inputChangeFunction); elNumberY.setInputChangeFunction(inputChangeFunction); @@ -1871,7 +1876,7 @@ function createColorProperty(property, elProperty) { let elNumberB = createTupleNumberInput(elTuple, elementID, "blue", COLOR_MIN, COLOR_MAX, COLOR_STEP); let inputChangeFunction = createEmitColorPropertyUpdateFunction(propertyName, elNumberR.elInput, elNumberG.elInput, - elNumberB.elInput, property.isParticleProperty); + elNumberB.elInput, property.isParticleProperty); elNumberR.setInputChangeFunction(inputChangeFunction); elNumberG.setInputChangeFunction(inputChangeFunction); elNumberB.setInputChangeFunction(inputChangeFunction); @@ -2055,6 +2060,7 @@ function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, let elDraggableNumber = new DraggableNumber(min, max, step); elDraggableNumber.elInput.setAttribute("id", elementID); + elDraggableNumber.elDiv.className += " fstuple"; elDraggableNumber.elDiv.insertBefore(elLabel, elDraggableNumber.elLeftArrow); elTuple.appendChild(elDraggableNumber.elDiv); @@ -2766,10 +2772,10 @@ function loaded() { if (propertyData.indentedLabel || propertyData.showPropertyRule !== undefined) { let elSpan = document.createElement('span'); elSpan.className = 'indented'; - elSpan.innerText = propertyData.label; + elSpan.innerText = propertyData.label !== undefined ? propertyData.label : ""; elLabel.appendChild(elSpan); } else { - elLabel.innerText = propertyData.label; + elLabel.innerText = propertyData.label !== undefined ? propertyData.label : ""; } elContainer.appendChild(elLabel); } else { From 0160ab23ab2efd745238c582ddcf6b864b08a4cc Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Nov 2018 17:23:51 -0800 Subject: [PATCH 06/18] fix color pickers --- scripts/system/html/css/edit-style.css | 3 +++ scripts/system/html/js/entityProperties.js | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index cb8dd7bcbc..7aa08b35cd 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -853,6 +853,9 @@ div.refresh input[type="button"] { border-color: #afafaf; } +.colpick { + z-index: 3; +} .colpick[disabled="disabled"] { display: none !important; } diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 204b97918e..c26d581ec3 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1892,9 +1892,9 @@ function createColorProperty(property, elProperty) { // 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[colorPickerID].colpickSetColor({ - "r": elInputR.value, - "g": elInputG.value, - "b": elInputB.value + "r": elNumberR.elInput.value, + "g": elNumberG.elInput.value, + "b": elNumberB.elInput.value }); }, onHide: function(colpick) { From 4eab623fd8a22484c0d833bc1272aca79a6b990e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Nov 2018 17:25:48 -0800 Subject: [PATCH 07/18] remove debugPrint function --- scripts/system/html/js/draggableNumber.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index 30ad6f1b5c..e961bbb4a7 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -6,10 +6,6 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -debugPrint = function (message) { - console.log(message); -}; - function DraggableNumber(min, max, step) { this.min = min; this.max = max; From 25df605459c45669f822e3e95d0b7e5b09ace4bb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 8 Nov 2018 14:53:33 -0800 Subject: [PATCH 08/18] Update the styling for the Entity Properties window --- scripts/system/html/css/edit-style.css | 403 +++++----- scripts/system/html/css/jsoneditor.css | 10 +- scripts/system/html/entityProperties.html | 13 + scripts/system/html/js/entityProperties.js | 869 ++++++++++++--------- 4 files changed, 717 insertions(+), 578 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index e4b33414ab..c09655b451 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -70,12 +70,11 @@ } body { - padding: 21px 21px 21px 21px; color: #afafaf; background-color: #404040; font-family: Raleway-Regular; - font-size: 15px; + font-size: 12px; -webkit-touch-callout: none; -webkit-user-select: none; @@ -425,9 +424,9 @@ input[type=checkbox] { } input[type=checkbox] + label { padding-left: 24px; - background-position-y: 6px; background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACpSURBVDhPY2xoaGD68+dPMSMjY9L////VgTQjAw4AlH8PxLOPHj1azWxjY1MBVNsBFBfBpwkEgNKcQGwtJyfHyATkF0KEiQdAzYlMQEIUyicFyDD9+/ePgRxMvsb///4zkIOZ/v0HmkAGHginYjGNGAzS+BpdkAj8mun/3//92DyPD//993cG88nTJ4+Zm5p/BSZeJYb/DEJADEzNOPF7hn8Mk69cvVIPAHN5pyfo70F5AAAAAElFTkSuQmCC); + cursor: pointer; } input[type=checkbox]:enabled + label:hover { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAClSURBVDhPY2hoaGD6//9/6b9//64D8T8gGycASr/7+/dv5/79+1kYgIxKqDjRAKiniRFIv2JgYBAFYlLAE0aQ66AckgDjjx8/yNP44cMH8jS+fPmSPI0PHz4kT+PNmzfJ03jp0iXyNJ46dYo8jYcPHyYnAbxm+vnzZz8wLhlIwd+/f5/BrKSkdExCQuLrnz9/lIBpUAiIQekXF34PTGmTT548WQ8AokXg+rhVtPYAAAAASUVORK5CYII=); @@ -455,6 +454,15 @@ input[type=checkbox]:checked + label:hover { color: #ffffff; } +.icon { + font-family: HiFi-Glyphs; + color: white; +} + +#property-type-icon { + font-size: 50px; +} + .selectable { -webkit-touch-callout: text; -webkit-user-select: text; @@ -483,9 +491,11 @@ input[type=checkbox]:checked + label:hover { #properties-list { display: flex; flex-direction: column; + + margin-top: 16px; } -#properties-list fieldset { +#properties-list .fieldset { position: relative; /* 0.1px on the top is to prevent margin collapsing between this and it's first child */ margin: 0 -21px 21px -21px; @@ -495,71 +505,101 @@ input[type=checkbox]:checked + label:hover { box-shadow: 0 -1px 0 rgb(37,37,37); } -#properties-list fieldset.fstuple, #properties-list fieldset.fsrow { +#properties-list .fieldset.fstuple, #properties-list .fieldset.fsrow { margin-top: 21px; border: none; box-shadow: none; } -#properties-list > fieldset[data-collapsed="true"] + fieldset { +#properties-list > .fieldset[data-collapsed="true"] + .fieldset { margin-top: 0; } -#properties-list > fieldset[data-collapsed="true"] > *:not(legend) { +#properties-list > .fieldset[data-collapsed="true"] > *:not(div.legend) { display: none !important; } -#properties-list legend + fieldset { - margin-top: 0; - border: none; - box-shadow: none; -} - -#properties-list > fieldset > legend { - position: relative; - display: table; - width: 100%; - margin: 21px -21px 0 -21px; - padding: 14px 21px 0 21px; - font-family: Raleway-Regular; - font-size: 12px; - color: #afafaf; - height: 28px; - text-transform: uppercase; - outline: none; - background-color: #404040; - border: none; +.section-header { + padding: 0 16px; border-top: 1px rgb(90,90,90) solid; - box-shadow: 0 -1px 0 rgb(37,37,37), 0 4px 4px 0 rgba(0,0,0,0.75); + box-shadow: 1px -1px 0 rgb(37,37,37); + border-bottom: 1px solid rgb(37, 37, 37); } div.section-header, hr { - display: table; - width: 100%; - margin: 21px -21px 0 -21px; - padding: 14px 21px 0 21px; + display: flex; + flex-flow: row nowrap; + + padding: 10px 16px; font-family: Raleway-Regular; font-size: 12px; color: #afafaf; height: 28px; text-transform: uppercase; outline: none; + margin-bottom: 10px; + align-items: center; } -div.section-header:first-child { - margin-top: -2px; - padding-top: 0; - background: none; - height: auto; +.section.minor { + margin: 0 21px; + box-shadow: 1px -1px 0 rgb(37,37,37); + border-left: 1px solid #575757; } -#properties-list > fieldset > legend span, .section-header span { - font-family: HiFi-Glyphs; +.container.property { + padding: 0 16px; +} + +.stretch { + width: 100%; +} + +div.section-header .label { + width: 100%; +} + +.section.minor div.section-header { + border-right: 0; +} + +div.section[collapsed="true"] > .container { + display: none; +} + +div.section[collapsed="true"], div.section[collapsed="true"] > .section-header { + margin-bottom: 0; +} + +.section.major { + margin-bottom: 20px; +} + +.section.minor.last { + margin-bottom: 20px; + border-bottom: 1px solid rgb(37,37,37); +} + +.section-header { + background-color: #373737; +} + +.section-header { + cursor: pointer; +} + +.section-header span { font-size: 30px; - float: right; - position: absolute; - top: 4px; - right: 13px; + font-family: HiFi-Glyphs; +} + +.triple-label { + text-transform: uppercase; + padding: 6px 0; +} + +.triple-item { + margin-right: 10px; } .section-header[collapsed="true"] { @@ -582,9 +622,6 @@ hr { } .property { - display: table; - width: 100%; - margin-top: 21px; min-height: 28px; } @@ -592,6 +629,10 @@ hr { width: auto; } +span.indented { + padding-left: 16px; +} + .property label, .number label { display: table-cell; vertical-align: middle; @@ -604,13 +645,13 @@ hr { font-size: 13px; } -.property legend, .number legend { +.property div.legend, .number div.legend { display: table-cell; vertical-align: middle; font-family: Raleway-SemiBold; font-size: 14px; } -.property legend .unit, .number legend .unit { +.property div.legend .unit, .number div.legend .unit { margin-left: 8px; font-family: Raleway-Light; font-size: 13px; @@ -623,16 +664,26 @@ hr { .value label { display: inline-block; vertical-align: top; - width: 48px; } -.value legend { +.value div.legend { display: inline-block; vertical-align: top; width: 48px; } .value span { - font-family: FiraSans-SemiBold; font-size: 15px; + margin-right: 4px; +} + +#placeholder-property-type { + display: flex; + align-items: center; + width: auto; + margin-right: 20px; +} + +#placeholder-property-locked { + margin-left: 6px; } .checkbox + .checkbox { @@ -659,33 +710,6 @@ hr { height: 1.8rem; } -.text label, .url label, .number label, .textarea label, .xy label, .wh label, .rgb label, .xyz label, .pyr label, .dropdown label, .gen label { - float: left; - margin-left: 1px; - margin-bottom: 3px; - margin-top: -2px; -} - -.text legend, .url legend, .number legend, .textarea legend, .xy legend, .wh legend, .rgb legend, .xyz legend, .pyr legend, .dropdown legend, .gen legend { - float: left; - margin-left: 1px; - margin-bottom: 3px; - margin-top: -2px; -} - -.xy > div, .wh > div, .xyz > div, .pyr > div, .gen > div { - clear: both; -} - -.number > input { - clear: both; - float: left; -} -.number > span { - clear: both; - float: left; -} - .dropdown { position: relative; margin-bottom: -17px; @@ -697,6 +721,7 @@ hr { .dropdown dl { clear: both; + cursor: pointer; } .dropdown dl { font-family: FiraSans-SemiBold; @@ -705,7 +730,7 @@ hr { height: 28px; padding: 0 28px 0 12px; color: #afafaf; - background: linear-gradient(#7d7d7d 20%, #686a68 100%); + background: #575757; position: relative; } .dropdown dl[dropped="true"] { @@ -812,27 +837,20 @@ div.refresh input[type="button"] { .color-picker { box-sizing: border-box; - float: left; - margin-bottom: 21px; - width: 36px; - height: 36px; - border: 4px solid #afafaf; - border-radius: 4px; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABTSURBVChTjcxBDoAwCETRwTs33sFjwB6uaCE1Ggvav5qQF7CSqu40dllHjYiOT3gh3yV8Ii+Fb+RNMEP9hm3sKENmBhG5P1aImWMH/EMerSAAOAFgTC/R8ZXSXAAAAABJRU5ErkJggg==); - background-position: bottom right; - background-repeat: no-repeat; + width: 26px; + height: 26px; + border: 3px solid #2B2B2B; + cursor: pointer; } .color-picker:focus { outline: none; } .color-picker[active="true"] { border-color: #000; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABDSURBVChTjcoLCkAhCETRNq0tf97Y5xGZ1gVJ45TH6njThIO+xk2UwhWFcEdH6JCqOuiQiMDi/hcii3crRRb/7ggAPvIMVihQwvSXAAAAAElFTkSuQmCC); } .color-picker[disabled="disabled"] { border-color: #afafaf; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABTSURBVChTjcxBDoAwCETRwTs33sFjwB6uaCE1Ggvav5qQF7CSqu40dllHjYiOT3gh3yV8Ii+Fb+RNMEP9hm3sKENmBhG5P1aImWMH/EMerSAAOAFgTC/R8ZXSXAAAAABJRU5ErkJggg==); } .colpick[disabled="disabled"] { @@ -848,89 +866,15 @@ div.refresh input[type="button"] { clear: both; } -.rgb legend { +.rgb div.legend { float: left; margin-top: 10px; margin-left: 21px; } -.rgb legend + * { +.rgb div.legend + * { clear: both; } -.tuple div { - display: inline-block; - position: relative; - margin-right: 6px; -} -.tuple div:last-child { - margin-right: 0; -} - -.tuple label { - margin-right: -6px; -} - -.xy .tuple input { - padding-left: 25px; -} -.wh .tuple input { - padding-left: 45px; -} -.rgb .tuple input { - padding-left: 65px; -} -.xyz .tuple input { - padding-left: 25px; -} -.pyr .tuple input { - padding-left: 40px; -} - -.tuple div > label:first-child { - float: left; -} -.tuple div > label + input { - clear: both; - float: left; -} -.tuple div input + label { - display: inline !important; - float: none !important; - position: absolute; - margin-top: 8px; - margin-left: 6px; - left: 0; - font-family: FiraSans-SemiBold; - font-size: 12px; -} -.tuple .red + label, .tuple .x + label, .tuple .pitch + label, .tuple .width + label { - color: #e2334d; -} -.tuple .green + label, .tuple .y + label, .tuple .yaw + label, .tuple .height + label { - color: #1ac567; -} -.tuple .blue + label, .tuple .z + label, .tuple .roll + label { - color: #1080b8; -} - -.tuple .red:focus, .tuple .x:focus, .tuple .pitch:focus, .tuple .width:focus { - outline-color: #e2334d; -} -.tuple .green:focus, .tuple .y:focus, .tuple .yaw:focus, .tuple .height:focus { - outline-color: #1ac567; -} -.tuple .blue:focus, .tuple .z:focus, .tuple .roll:focus { - outline-color: #1080b8; -} - -.xyz .buttons input { - margin-top: 14px; -} -.xyz .buttons span { - word-wrap: nowrap; - white-space: nowrap; -} - .row .property { width: auto; display: inline-block; @@ -984,12 +928,12 @@ div.refresh input[type="button"] { width: 50%; } -#properties-list fieldset .two-column { +#properties-list .fieldset .two-column { padding-top: 10px; display: flex; } -#properties-list .two-column fieldset { +#properties-list .two-column .fieldset { width: 50%; margin: 0; padding: 0; @@ -1002,7 +946,7 @@ div.refresh input[type="button"] { top: -10px; } -#properties-list .two-column fieldset legend { +#properties-list .two-column .fieldset div.legend { width: 100%; margin: 21px -21px 0 -21px; padding: 16px 0 0 21px; @@ -1018,11 +962,11 @@ div.refresh input[type="button"] { margin-top: 6px; } -fieldset .checkbox-sub-props { +.fieldset .checkbox-sub-props { margin-top: 0; } -fieldset .checkbox-sub-props .property:first-child { +.fieldset .checkbox-sub-props .property:first-child { margin-top: 0; } @@ -1069,6 +1013,7 @@ textarea:enabled[scrolling="true"]::-webkit-resizer { body#entity-list-body { padding-bottom: 0; + margin: 16px; } #entity-list-header { @@ -1448,7 +1393,6 @@ th#entity-hasScript { border-top: none !important; box-shadow: none !important; margin-bottom: 5px !important; - top: -15px; } #properties-base #property-type-icon { @@ -1467,6 +1411,7 @@ th#entity-hasScript { display: inline-block; } +/* #properties-base #div-property-locked { position: absolute; top: 6px; @@ -1487,6 +1432,7 @@ th#entity-hasScript { #properties-base #div-property-visible label { background-position-y: 1px; } +*/ #properties-base .checkbox label span { font-family: HiFi-Glyphs; @@ -1513,16 +1459,17 @@ th#entity-hasScript { } input#property-scale-button-rescale { + margin-top: 6px; min-width: 50px; - margin-left: 6px; } input#property-scale-button-reset { + margin-top: 6px; margin-right: 0; } -#property-userData-button-clear, +#property-userData-button-edit, #property-materialData-button-clear { - margin-bottom: 10px; + margin: 6px 0 6px 0; } #property-userData-static, @@ -1544,15 +1491,6 @@ input#property-scale-button-reset { display: none; } -#div-property-serverScripts-status label { - position: relative; - top: 8px; -} -#property-serverScripts-status { - position: relative; - top: 5px; - right: -20px; -} #div-property-collisionSoundURL[style*="display: none"] + .property { margin-top: 0; @@ -1637,3 +1575,100 @@ input.rename-entity { content: "\e02c"; } +.container { + display: flex; + flex-flow: row nowrap; + justify-content: space-around; + margin-bottom: 8px; + min-height: 28px; +} + +.container > label { + margin-top: 6px; + width: 200px; +} + +.container > div.checkbox { + padding-top: 6px; +} + +.container > .value { + width: 100%; +} + +.container .row { + display: flex; + flex-flow: row nowrap; +} + +.container.shrink { + width: min-content; +} + +.fstuple { + display: flex; + flex-flow: row; +} +.fstuple input { + margin-left: 4px; + margin-right: 10px; +} +.fstuple label.red, .fstuple label.x { + color: #C62147; +} +.fstuple label.green, .fstuple label.y { + color: #359D85; +} +.fstuple label.blue, .fstuple label.z { + color: #0093C5; +} + +.xyz.fstuple, .pyr.fstuple { + position: relative; + left: -12px; +} + +.rgb.fstuple .tuple { + display: none; +} + +input.number-slider { + background: #575757; + border-radius: 4px; + color: white; +} + +.fstuple > div { + display: flex; + align-items: center; + justify-content: left; +} + +.flex-row { + display: flex; + flex-flow: row; +} + +.flex-column { + display: flex; + flex-flow: column; +} + +.flex-center { + align-items: center; +} + +.flex-evenly-spaced { + flex: 1; +} + +#property-serverScripts-status { + font-family: Raleway-Light; + font-size: 14px; + margin: 6px 0; +} + +#property-name, #property-id { + display: flex; + width: 100%; +} diff --git a/scripts/system/html/css/jsoneditor.css b/scripts/system/html/css/jsoneditor.css index ce83b45ff3..eedef60a7f 100644 --- a/scripts/system/html/css/jsoneditor.css +++ b/scripts/system/html/css/jsoneditor.css @@ -223,8 +223,6 @@ div.jsoneditor-tree table.jsoneditor-tree { div.jsoneditor-outer { width: 100%; - height: 100%; - min-height: 150px; margin: -35px 0 0 0; padding: 0 0 0 0; -moz-box-sizing: border-box; @@ -233,20 +231,18 @@ div.jsoneditor-outer { overflow-y: auto; } -textarea.jsoneditor-text, .ace-jsoneditor { - min-height: 150px; + min-height: 150px; + height: auto !important; } div.jsoneditor-tree { width: 100%; - height: 100%; position: relative; } textarea.jsoneditor-text { width: 100%; - height: 100%; margin: 0; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; @@ -931,4 +927,4 @@ table.jsoneditor-search button.jsoneditor-previous { table.jsoneditor-search button.jsoneditor-previous:hover { background-position: -148px -49px; -} \ No newline at end of file +} diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index b56ad346e2..6af8ee992a 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -28,6 +28,19 @@
+
+ +
+
+
+
+
+
+
+
+
+
+
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index f2c84d2f36..5d77c56b4a 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -29,7 +29,7 @@ const ICON_FOR_TYPE = { const DEGREES_TO_RADIANS = Math.PI / 180.0; -const NO_SELECTION = "No selection"; +const NO_SELECTION = "w"; const PROPERTY_SPACE_MODE = { ALL: 0, @@ -46,17 +46,22 @@ const GROUPS = [ type: "icon", icons: ICON_FOR_TYPE, propertyID: "type", + replaceID: "placeholder-property-type", }, { label: "Name", type: "string", propertyID: "name", + placeholder: "Name", + replaceID: "placeholder-property-name", }, { label: "ID", type: "string", propertyID: "id", + placeholder: "ID", readOnly: true, + replaceID: "placeholder-property-id", }, { label: "Description", @@ -74,16 +79,18 @@ const GROUPS = [ propertyID: "parentJointIndex", }, { - label: "Locked", + label: "", glyph: "", type: "bool", propertyID: "locked", + replaceID: "placeholder-property-locked", }, { - label: "Visible", + label: "", glyph: "", type: "bool", propertyID: "visible", + replaceID: "placeholder-property-visible", }, ] }, @@ -463,6 +470,7 @@ const GROUPS = [ { label: "Image", type: "string", + placeholder: "URL", propertyID: "image", }, ] @@ -640,6 +648,7 @@ const GROUPS = [ { id: "particles_emit", label: "EMIT", + isMinor: true, properties: [ { label: "Emit Rate", @@ -692,7 +701,7 @@ const GROUPS = [ vec3Type: "pyr", step: 0.01, round: 100, - subLabels: [ "pitch", "yaw", "roll" ], + subLabels: [ "x", "y", "z" ], unit: "deg", propertyID: "emitOrientation", }, @@ -706,35 +715,42 @@ const GROUPS = [ { id: "particles_size", label: "SIZE", + isMinor: true, properties: [ { + type: "triple", label: "Size", - type: "slider", - min: 0, - max: 4, - step: 0.01, - decimals: 2, - propertyID: "particleRadius", - }, - { - label: "Size Start", - type: "slider", - min: 0, - max: 4, - step: 0.01, - decimals: 2, - propertyID: "radiusStart", - fallbackProperty: "particleRadius", - }, - { - label: "Size Finish", - type: "slider", - min: 0, - max: 4, - step: 0.01, - decimals: 2, - propertyID: "radiusFinish", - fallbackProperty: "particleRadius", + properties: [ + { + label: "Start", + type: "slider", + min: 0, + max: 4, + step: 0.01, + decimals: 2, + propertyID: "radiusStart", + fallbackProperty: "particleRadius", + }, + { + label: "Middle", + type: "slider", + min: 0, + max: 4, + step: 0.01, + decimals: 2, + propertyID: "particleRadius", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 4, + step: 0.01, + decimals: 2, + propertyID: "radiusFinish", + fallbackProperty: "particleRadius", + }, + ] }, { label: "Size Spread", @@ -750,24 +766,31 @@ const GROUPS = [ { id: "particles_color", label: "COLOR", + isMinor: true, properties: [ { + type: "triple", label: "Color", - type: "color", - propertyID: "particleColor", - propertyName: "color", // actual entity property name - }, - { - label: "Color Start", - type: "color", - propertyID: "colorStart", - fallbackProperty: "color", - }, - { - label: "Color Finish", - type: "color", - propertyID: "colorFinish", - fallbackProperty: "color", + properties: [ + { + label: "Start", + type: "color", + propertyID: "colorStart", + fallbackProperty: "color", + }, + { + label: "Middle", + type: "color", + propertyID: "particleColor", + propertyName: "color", // actual entity property name + }, + { + label: "Finish", + type: "color", + propertyID: "colorFinish", + fallbackProperty: "color", + }, + ] }, { label: "Color Spread", @@ -779,35 +802,42 @@ const GROUPS = [ { id: "particles_alpha", label: "ALPHA", + isMinor: true, properties: [ { + type: "triple", label: "Alpha", - type: "slider", - min: 0, - max: 1, - step: 0.01, - decimals: 2, - propertyID: "alpha", - }, - { - label: "Alpha Start", - type: "slider", - min: 0, - max: 1, - step: 0.01, - decimals: 2, - propertyID: "alphaStart", - fallbackProperty: "alpha", - }, - { - label: "Alpha Finish", - type: "slider", - min: 0, - max: 1, - step: 0.01, - decimals: 2, - propertyID: "alphaFinish", - fallbackProperty: "alpha", + properties: [ + { + label: "Start", + type: "slider", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "alphaStart", + fallbackProperty: "alpha", + }, + { + label: "Middle", + type: "slider", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "alpha", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 1, + step: 0.01, + decimals: 2, + propertyID: "alphaFinish", + fallbackProperty: "alpha", + }, + ] }, { label: "Alpha Spread", @@ -823,6 +853,7 @@ const GROUPS = [ { id: "particles_acceleration", label: "ACCELERATION", + isMinor: true, properties: [ { label: "Emit Acceleration", @@ -847,41 +878,48 @@ const GROUPS = [ { id: "particles_spin", label: "SPIN", + isMinor: true, properties: [ { - label: "Spin", - type: "slider", - min: -360, - max: 360, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "particleSpin", - }, - { - label: "Spin Start", - type: "slider", - min: -360, - max: 360, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "spinStart", - fallbackProperty: "particleSpin", - }, - { - label: "Spin Finish", - type: "slider", - min: -360, - max: 360, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "spinFinish", - fallbackProperty: "particleSpin", + type: "triple", + label: "Alpha", + properties: [ + { + label: "Start", + type: "slider", + min: -360, + max: 360, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "spinStart", + fallbackProperty: "particleSpin", + }, + { + label: "Middle", + type: "slider", + min: -360, + max: 360, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "particleSpin", + }, + { + label: "Finish", + type: "slider", + min: -360, + max: 360, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "spinFinish", + fallbackProperty: "particleSpin", + }, + ] }, { label: "Spin Spread", @@ -904,51 +942,64 @@ const GROUPS = [ { id: "particles_constraints", label: "CONSTRAINTS", + isMinor: true, properties: [ { - label: "Horizontal Angle Start", - type: "slider", - min: 0, - max: 180, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "polarStart", + type: "triple", + label: "Horizontal Angle", + properties: [ + { + label: "Start", + type: "slider", + min: -180, + max: 0, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "polarStart", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 180, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "polarFinish", + }, + ], }, { - label: "Horizontal Angle Finish", - type: "slider", - min: 0, - max: 180, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "polarFinish", - }, - { - label: "Vertical Angle Start", - type: "slider", - min: -180, - max: 0, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "azimuthStart", - }, - { - label: "Vertical Angle Finish", - type: "slider", - min: 0, - max: 180, - step: 1, - decimals: 0, - multiplier: DEGREES_TO_RADIANS, - unit: "deg", - propertyID: "azimuthFinish", - }, + type: "triple", + label: "Vertical Angle", + properties: [ + { + label: "Start", + type: "slider", + min: 0, + max: 180, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "azimuthStart", + }, + { + label: "Finish", + type: "slider", + min: 0, + max: 180, + step: 1, + decimals: 0, + multiplier: DEGREES_TO_RADIANS, + unit: "deg", + propertyID: "azimuthFinish", + }, + ] + } ] }, { @@ -981,7 +1032,7 @@ const GROUPS = [ vec3Type: "pyr", step: 0.1, decimals: 4, - subLabels: [ "pitch", "yaw", "roll" ], + subLabels: [ "x", "y", "z" ], unit: "deg", propertyID: "rotation", spaceMode: PROPERTY_SPACE_MODE.WORLD, @@ -992,7 +1043,7 @@ const GROUPS = [ vec3Type: "pyr", step: 0.1, decimals: 4, - subLabels: [ "pitch", "yaw", "roll" ], + subLabels: [ "x", "y", "z" ], unit: "deg", propertyID: "localRotation", spaceMode: PROPERTY_SPACE_MODE.LOCAL, @@ -1065,6 +1116,7 @@ const GROUPS = [ }, { label: "Clone Lifetime", + indentedLabel: true, type: "number", unit: "s", propertyID: "cloneLifetime", @@ -1072,18 +1124,21 @@ const GROUPS = [ }, { label: "Clone Limit", + indentedLabel: true, type: "number", propertyID: "cloneLimit", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Dynamic", + indentedLabel: true, type: "bool", propertyID: "cloneDynamic", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Avatar Entity", + indentedLabel: true, type: "bool", propertyID: "cloneAvatarEntity", showPropertyRule: { "cloneable": "true" }, @@ -1120,6 +1175,12 @@ const GROUPS = [ buttons: [ { id: "reload", label: "F", className: "glyph", onClick: reloadServerScripts } ], propertyID: "serverScripts", }, + { + label: "Server Script Status", + type: "placeholder", + indentedLabel: true, + propertyID: "serverScriptStatus", + }, { label: "Lifetime", type: "number", @@ -1146,12 +1207,6 @@ const GROUPS = [ inverse: true, propertyID: "collisionless", }, - { - label: "Collides With", - type: "sub-header", - propertyID: "collidesWithHeader", // not actually a property but used for naming/storing this element - showPropertyRule: { "collisionless": "false" }, - }, { label: "Static Entities", type: "bool", @@ -1230,7 +1285,7 @@ const GROUPS = [ vec3Type: "pyr", multiplier: DEGREES_TO_RADIANS, decimals: 4, - subLabels: [ "pitch", "yaw", "roll" ], + subLabels: [ "x", "y", "z" ], unit: "deg/s", propertyID: "localAngularVelocity", }, @@ -1370,6 +1425,12 @@ function debugPrint(message) { ); } +function createElementFromHTML(htmlString) { + var elTemplate = document.createElement('template'); + elTemplate.innerHTML = htmlString.trim(); + return elTemplate.content.firstChild; +} + /** * GENERAL PROPERTY/GROUP FUNCTIONS @@ -1442,8 +1503,8 @@ function disableProperties() { } function showPropertyElement(propertyID, show) { - let elProperty = properties[propertyID].elProperty; - elProperty.style.display = show ? "table" : "none"; + let elProperty = properties[propertyID].elContainer; + elProperty.style.display = show ? "flex" : "none"; } function resetProperties() { @@ -1500,7 +1561,6 @@ function resetProperties() { } case 'icon': { property.elSpan.style.display = "none"; - property.elLabel.innerHTML = propertyData.label; break; } case 'texture': { @@ -1701,23 +1761,23 @@ function createImageURLUpdateFunction(propertyName, isParticleProperty) { * PROPERTY ELEMENT CREATION FUNCTIONS */ -function createStringProperty(property, elProperty, elLabel) { +function createStringProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property text"; + elProperty.className = "text"; - let elInput = document.createElement('input'); - elInput.setAttribute("id", elementID); - elInput.setAttribute("type", "text"); - if (propertyData.readOnly) { - elInput.readOnly = true; - } + let elInput = createElementFromHTML(` + + `) + elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); - elProperty.appendChild(elLabel); elProperty.appendChild(elInput); if (propertyData.buttons !== undefined) { @@ -1727,18 +1787,18 @@ function createStringProperty(property, elProperty, elLabel) { return elInput; } -function createBoolProperty(property, elProperty, elLabel) { +function createBoolProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property checkbox"; + elProperty.className = "checkbox"; if (propertyData.glyph !== undefined) { - elLabel.innerText = " " + propertyData.label; let elSpan = document.createElement('span'); elSpan.innerHTML = propertyData.glyph; - elLabel.insertBefore(elSpan, elLabel.firstChild); + elSpan.className = 'icon'; + elProperty.appendChild(elSpan); } let elInput = document.createElement('input'); @@ -1746,7 +1806,7 @@ function createBoolProperty(property, elProperty, elLabel) { elInput.setAttribute("type", "checkbox"); elProperty.appendChild(elInput); - elProperty.appendChild(elLabel); + elProperty.appendChild(createElementFromHTML(``)); let subPropertyOf = propertyData.subPropertyOf; if (subPropertyOf !== undefined) { @@ -1760,14 +1820,12 @@ function createBoolProperty(property, elProperty, elLabel) { return elInput; } -function createNumberProperty(property, elProperty, elLabel) { +function createNumberProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property number"; - - addUnit(propertyData.unit, elLabel); + elProperty.className = "number"; let elInput = document.createElement('input'); elInput.setAttribute("id", elementID); @@ -1789,7 +1847,6 @@ function createNumberProperty(property, elProperty, elLabel) { elInput.addEventListener('change', createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, propertyData.decimals, property.isParticleProperty)); - elProperty.appendChild(elLabel); elProperty.appendChild(elInput); if (propertyData.buttons !== undefined) { @@ -1799,10 +1856,10 @@ function createNumberProperty(property, elProperty, elLabel) { return elInput; } -function createSliderProperty(property, elProperty, elLabel) { +function createSliderProperty(property, elProperty) { let propertyData = property.data; - elProperty.className = "property range"; + elProperty.className = "range"; let elDiv = document.createElement("div"); elDiv.className = "slider-wrapper"; @@ -1852,7 +1909,6 @@ function createSliderProperty(property, elProperty, elLabel) { updateProperty(property.name, sliderValue, property.isParticleProperty); }; - elDiv.appendChild(elLabel); elDiv.appendChild(elSlider); elDiv.appendChild(elInput); elProperty.appendChild(elDiv); @@ -1863,26 +1919,23 @@ function createSliderProperty(property, elProperty, elLabel) { return elResult; } -function createVec3Property(property, elProperty, elLabel) { +function createVec3Property(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property " + propertyData.vec3Type + " fstuple"; + elProperty.className = propertyData.vec3Type + " fstuple"; - let elTuple = document.createElement('div'); - elTuple.className = "tuple"; + //let elTuple = document.createElement('div'); + //elTuple.className = "tuple"; - addUnit(propertyData.unit, elLabel); + //elProperty.appendChild(elTuple); - elProperty.appendChild(elLabel); - elProperty.appendChild(elTuple); - - let elInputX = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], + let elInputX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], propertyData.min, propertyData.max, propertyData.step); - let elInputY = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], + let elInputY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], propertyData.min, propertyData.max, propertyData.step); - let elInputZ = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_INPUT], + let elInputZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_INPUT], propertyData.min, propertyData.max, propertyData.step); let inputChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elInputX, elInputY, elInputZ, @@ -1898,19 +1951,16 @@ function createVec3Property(property, elProperty, elLabel) { return elResult; } -function createVec2Property(property, elProperty, elLabel) { +function createVec2Property(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property " + propertyData.vec2Type + " fstuple"; + elProperty.className = propertyData.vec2Type + " fstuple"; let elTuple = document.createElement('div'); elTuple.className = "tuple"; - addUnit(propertyData.unit, elLabel); - - elProperty.appendChild(elLabel); elProperty.appendChild(elTuple); let elInputX = createTupleNumberInput(elTuple, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], @@ -1929,11 +1979,11 @@ function createVec2Property(property, elProperty, elLabel) { return elResult; } -function createColorProperty(property, elProperty, elLabel) { +function createColorProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; - elProperty.className = "property rgb fstuple"; + elProperty.className = "rgb fstuple"; let elColorPicker = document.createElement('div'); elColorPicker.className = "color-picker"; @@ -1943,7 +1993,6 @@ function createColorProperty(property, elProperty, elLabel) { elTuple.className = "tuple"; elProperty.appendChild(elColorPicker); - elProperty.appendChild(elLabel); elProperty.appendChild(elTuple); let elInputR = createTupleNumberInput(elTuple, elementID, "red", COLOR_MIN, COLOR_MAX, COLOR_STEP); @@ -1959,7 +2008,7 @@ function createColorProperty(property, elProperty, elLabel) { let colorPickerID = "#" + elementID; colorPickers[colorPickerID] = $(colorPickerID).colpick({ colorScheme: 'dark', - layout: 'hex', + layout: 'rgbhex', color: '000000', submit: false, // We don't want to have a submission button onShow: function(colpick) { @@ -1989,12 +2038,12 @@ function createColorProperty(property, elProperty, elLabel) { return elResult; } -function createDropdownProperty(property, propertyID, elProperty, elLabel) { +function createDropdownProperty(property, propertyID, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property dropdown"; + elProperty.className = "dropdown"; let elInput = document.createElement('select'); elInput.setAttribute("id", elementID); @@ -2009,24 +2058,17 @@ function createDropdownProperty(property, propertyID, elProperty, elLabel) { elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); - elProperty.appendChild(elLabel); elProperty.appendChild(elInput); return elInput; } -function createTextareaProperty(property, elProperty, elLabel) { +function createTextareaProperty(property, elProperty) { let propertyName = property.name; let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property textarea"; - - elProperty.appendChild(elLabel); - - if (propertyData.buttons !== undefined) { - addButtons(elProperty, elementID, propertyData.buttons, true); - } + elProperty.className = "textarea"; let elInput = document.createElement('textarea'); elInput.setAttribute("id", elementID); @@ -2037,35 +2079,35 @@ function createTextareaProperty(property, elProperty, elLabel) { elInput.addEventListener('change', createEmitTextPropertyUpdateFunction(propertyName, property.isParticleProperty)); elProperty.appendChild(elInput); + + if (propertyData.buttons !== undefined) { + addButtons(elProperty, elementID, propertyData.buttons, true); + } return elInput; } -function createIconProperty(property, elProperty, elLabel) { +function createIconProperty(property, elProperty) { let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property value"; - - elLabel.setAttribute("id", elementID); - elLabel.innerHTML = " " + propertyData.label; + elProperty.className = "value"; let elSpan = document.createElement('span'); elSpan.setAttribute("id", elementID + "-icon"); + elSpan.className = 'icon'; elProperty.appendChild(elSpan); - elProperty.appendChild(elLabel); let elResult = []; elResult[ICON_ELEMENTS.ICON] = elSpan; - elResult[ICON_ELEMENTS.LABEL] = elLabel; return elResult; } -function createTextureProperty(property, elProperty, elLabel) { +function createTextureProperty(property, elProperty) { let elementID = property.elementID; - elProperty.className = "property texture"; + elProperty.className = "texture"; let elDiv = document.createElement("div"); let elImage = document.createElement("img"); @@ -2106,9 +2148,8 @@ function createTextureProperty(property, elProperty, elLabel) { }; elInput.onchange = elInput.oninput; - elProperty.appendChild(elLabel); - elProperty.appendChild(elDiv); elProperty.appendChild(elInput); + elProperty.appendChild(elDiv); let elResult = []; elResult[TEXTURE_ELEMENTS.IMAGE] = elImage; @@ -2120,11 +2161,10 @@ function createButtonsProperty(property, elProperty, elLabel) { let elementID = property.elementID; let propertyData = property.data; - elProperty.className = "property text"; + elProperty.className = "text"; let hasLabel = propertyData.label !== undefined; if (hasLabel) { - elProperty.appendChild(elLabel); } if (propertyData.buttons !== undefined) { @@ -2139,33 +2179,25 @@ function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, let elDiv = document.createElement('div'); let elLabel = document.createElement('label'); - elLabel.innerText = subLabel[0].toUpperCase() + subLabel.slice(1) + ":"; + elLabel.className = subLabel; + elLabel.innerText = subLabel[0].toUpperCase() + subLabel.slice(1); elLabel.setAttribute("for", elementID); let elInput = document.createElement('input'); - elInput.className = subLabel; + elInput.className = subLabel + " number-slider"; elInput.setAttribute("id", elementID); elInput.setAttribute("type", "number"); elInput.setAttribute("min", min); elInput.setAttribute("max", max); elInput.setAttribute("step", step); - elDiv.appendChild(elInput); elDiv.appendChild(elLabel); + elDiv.appendChild(elInput); elTuple.appendChild(elDiv); return elInput; } -function addUnit(unit, elLabel) { - if (unit !== undefined) { - let elSpan = document.createElement('span'); - elSpan.className = "unit"; - elSpan.innerHTML = unit; - elLabel.appendChild(elSpan); - } -} - function addButtons(elProperty, propertyID, buttons, newRow) { let elDiv = document.createElement('div'); elDiv.className = "row"; @@ -2716,32 +2748,125 @@ function updateVisibleSpaceModeProperties() { let propertySpaceMode = property.spaceMode; if (propertySpaceMode !== PROPERTY_SPACE_MODE.ALL) { showPropertyElement(propertyID, propertySpaceMode === currentSpaceMode); + } else { + showPropertyElement(propertyID, true); } } } } +function createProperty(propertyData, propertyElementID, propertyName, propertyID, elProperty) { + let property = { + data: propertyData, + elementID: propertyElementID, + name: propertyName, + elProperty: elProperty, + }; + let propertyType = propertyData.type; + + switch (propertyType) { + case 'string': { + property.elInput = createStringProperty(property, elProperty); + break; + } + case 'bool': { + property.elInput = createBoolProperty(property, elProperty); + break; + } + case 'number': { + property.elInput = createNumberProperty(property, elProperty); + break; + } + case 'slider': { + let elSlider = createSliderProperty(property, elProperty); + property.elSlider = elSlider[SLIDER_ELEMENTS.SLIDER]; + property.elInput = elSlider[SLIDER_ELEMENTS.NUMBER_INPUT]; + break; + } + case 'vec3': { + let elVec3 = createVec3Property(property, elProperty); + property.elInputX = elVec3[VECTOR_ELEMENTS.X_INPUT]; + property.elInputY = elVec3[VECTOR_ELEMENTS.Y_INPUT]; + property.elInputZ = elVec3[VECTOR_ELEMENTS.Z_INPUT]; + break; + } + case 'vec2': { + let elVec2 = createVec2Property(property, elProperty); + property.elInputX = elVec2[VECTOR_ELEMENTS.X_INPUT]; + property.elInputY = elVec2[VECTOR_ELEMENTS.Y_INPUT]; + break; + } + case 'color': { + let elColor = createColorProperty(property, elProperty); + property.elColorPicker = elColor[COLOR_ELEMENTS.COLOR_PICKER]; + property.elInputR = elColor[COLOR_ELEMENTS.RED_INPUT]; + property.elInputG = elColor[COLOR_ELEMENTS.GREEN_INPUT]; + property.elInputB = elColor[COLOR_ELEMENTS.BLUE_INPUT]; + break; + } + case 'dropdown': { + property.elInput = createDropdownProperty(property, propertyID, elProperty); + break; + } + case 'textarea': { + property.elInput = createTextareaProperty(property, elProperty); + break; + } + case 'icon': { + let elIcon = createIconProperty(property, elProperty); + property.elSpan = elIcon[ICON_ELEMENTS.ICON]; + property.elLabel = elIcon[ICON_ELEMENTS.LABEL]; + break; + } + case 'texture': { + let elTexture = createTextureProperty(property, elProperty); + property.elImage = elTexture[TEXTURE_ELEMENTS.IMAGE]; + property.elInput = elTexture[TEXTURE_ELEMENTS.TEXT_INPUT]; + break; + } + case 'buttons': { + property.elProperty = createButtonsProperty(property, elProperty); + break; + } + case 'placeholder': + case 'sub-header': { + break; + } + default: { + console.log("EntityProperties - Unknown property type " + + propertyType + " set to property " + propertyID); + break; + } + } + + return property; +} + function loaded() { openEventBridge(function() { let elPropertiesList = document.getElementById("properties-list"); + + let templatePropertyRow = document.getElementById('property-row'); - GROUPS.forEach(function(group) { + GROUPS.forEach(function(group) { let elGroup; if (group.addToGroup !== undefined) { let fieldset = document.getElementById("properties-" + group.addToGroup); elGroup = document.createElement('div'); fieldset.appendChild(elGroup); } else { - elGroup = document.createElement('fieldset'); - elGroup.className = "major"; + elGroup = document.createElement('div'); + elGroup.className = 'section ' + (group.isMinor ? "minor" : "major"); elGroup.setAttribute("id", "properties-" + group.id); elPropertiesList.appendChild(elGroup); } if (group.label !== undefined) { - let elLegend = document.createElement('legend'); + let elLegend = document.createElement('div'); elLegend.className = "section-header"; - elLegend.innerText = group.label; + + elLegend.appendChild(createElementFromHTML(`
${group.label}
`)); + let elSpan = document.createElement('span'); elSpan.className = ".collapse-icon"; elSpan.innerText = "M"; @@ -2757,145 +2882,119 @@ function loaded() { let propertyElementID = "property-" + propertyID; propertyElementID = propertyElementID.replace('.', '-'); - let elProperty; - if (propertyType === "sub-header") { - elProperty = document.createElement('legend'); - elProperty.className = "sub-section-header"; - elProperty.innerText = propertyData.label; - } else { - elProperty = document.createElement('div'); - elProperty.setAttribute("id", "div-" + propertyElementID); - } + let elContainer, elLabel; - if (group.twoColumn && propertyData.column !== undefined && propertyData.column !== -1) { - let columnName = group.id + "column" + propertyData.column; - let elColumn = document.getElementById(columnName); - if (!elColumn) { - let columnDivName = group.id + "columnDiv"; - let elColumnDiv = document.getElementById(columnDivName); - if (!elColumnDiv) { - elColumnDiv = document.createElement('div'); - elColumnDiv.className = "two-column"; - elColumnDiv.setAttribute("id", group.id + "columnDiv"); - elGroup.appendChild(elColumnDiv); - } - elColumn = document.createElement('fieldset'); - elColumn.className = "column"; - elColumn.setAttribute("id", columnName); - elColumnDiv.appendChild(elColumn); + if (propertyData.replaceID === undefined) { + // Create subheader, or create new property and append it. + if (propertyType === "sub-header") { + elContainer = createElementFromHTML( + `
${propertyData.label}
`); + } else { + elContainer = document.createElement('div'); + elContainer.setAttribute("id", "div-" + propertyElementID); + elContainer.className = 'property container'; } - elColumn.appendChild(elProperty); - } else { - elGroup.appendChild(elProperty); - } - - let elLabel = document.createElement('label'); - elLabel.innerText = propertyData.label; - elLabel.setAttribute("for", propertyElementID); - createAppTooltip.registerTooltipElement(elLabel, propertyID); - - let property = { - data: propertyData, - elementID: propertyElementID, - name: propertyName, - isParticleProperty: group.id.includes("particles"), - elProperty, - spaceMode: propertySpaceMode, - }; - properties[propertyID] = property; - - switch (propertyType) { - case 'string': { - properties[propertyID].elInput = createStringProperty(property, elProperty, elLabel); - break; + if (group.twoColumn && propertyData.column !== undefined && propertyData.column !== -1) { + let columnName = group.id + "column" + propertyData.column; + let elColumn = document.getElementById(columnName); + if (!elColumn) { + let columnDivName = group.id + "columnDiv"; + let elColumnDiv = document.getElementById(columnDivName); + if (!elColumnDiv) { + elColumnDiv = document.createElement('div'); + elColumnDiv.className = "two-column"; + elColumnDiv.setAttribute("id", group.id + "columnDiv"); + elGroup.appendChild(elColumnDiv); + } + elColumn = document.createElement('fieldset'); + elColumn.className = "column"; + elColumn.setAttribute("id", columnName); + elColumnDiv.appendChild(elColumn); + } + elColumn.appendChild(elContainer); + } else { + elGroup.appendChild(elContainer); } - case 'bool': { - properties[propertyID].elInput = createBoolProperty(property, elProperty, elLabel); - break; - } - case 'number': { - properties[propertyID].elInput = createNumberProperty(property, elProperty, elLabel); - break; - } - case 'slider': { - let elSlider = createSliderProperty(property, elProperty, elLabel); - properties[propertyID].elSlider = elSlider[SLIDER_ELEMENTS.SLIDER]; - properties[propertyID].elInput = elSlider[SLIDER_ELEMENTS.NUMBER_INPUT]; - break; - } - case 'vec3': { - let elVec3 = createVec3Property(property, elProperty, elLabel); - properties[propertyID].elInputX = elVec3[VECTOR_ELEMENTS.X_INPUT]; - properties[propertyID].elInputY = elVec3[VECTOR_ELEMENTS.Y_INPUT]; - properties[propertyID].elInputZ = elVec3[VECTOR_ELEMENTS.Z_INPUT]; - break; - } - case 'vec2': { - let elVec2 = createVec2Property(property, elProperty, elLabel); - properties[propertyID].elInputX = elVec2[VECTOR_ELEMENTS.X_INPUT]; - properties[propertyID].elInputY = elVec2[VECTOR_ELEMENTS.Y_INPUT]; - break; - } - case 'color': { - let elColor = createColorProperty(property, elProperty, elLabel); - properties[propertyID].elColorPicker = elColor[COLOR_ELEMENTS.COLOR_PICKER]; - properties[propertyID].elInputR = elColor[COLOR_ELEMENTS.RED_INPUT]; - properties[propertyID].elInputG = elColor[COLOR_ELEMENTS.GREEN_INPUT]; - properties[propertyID].elInputB = elColor[COLOR_ELEMENTS.BLUE_INPUT]; - break; - } - case 'dropdown': { - properties[propertyID].elInput = createDropdownProperty(property, propertyID, elProperty, elLabel); - break; - } - case 'textarea': { - properties[propertyID].elInput = createTextareaProperty(property, elProperty, elLabel); - break; - } - case 'icon': { - let elIcon = createIconProperty(property, elProperty, elLabel); - properties[propertyID].elSpan = elIcon[ICON_ELEMENTS.ICON]; - properties[propertyID].elLabel = elIcon[ICON_ELEMENTS.LABEL]; - break; - } - case 'texture': { - let elTexture = createTextureProperty(property, elProperty, elLabel); - properties[propertyID].elImage = elTexture[TEXTURE_ELEMENTS.IMAGE]; - properties[propertyID].elInput = elTexture[TEXTURE_ELEMENTS.TEXT_INPUT]; - break; - } - case 'buttons': { - properties[propertyID].elProperty = createButtonsProperty(property, elProperty, elLabel); - break; - } - case 'sub-header': { - break; - } - default: { - console.log("EntityProperties - Unknown property type " + - propertyType + " set to property " + propertyID); - break; + + elLabel = document.createElement('label'); + elLabel.setAttribute("for", propertyElementID); + if (propertyData.indentedLabel || propertyData.showPropertyRule !== undefined) { + let elSpan = document.createElement('span'); + elSpan.className = 'indented'; + elSpan.innerText = propertyData.label; + elLabel.appendChild(elSpan); + } else { + elLabel.innerText = propertyData.label; } + elContainer.appendChild(elLabel); + } else { + elContainer = document.getElementById(propertyData.replaceID); } - - let showPropertyRule = propertyData.showPropertyRule; - if (showPropertyRule !== undefined) { - let dependentProperty = Object.keys(showPropertyRule)[0]; - let dependentPropertyValue = showPropertyRule[dependentProperty]; - if (properties[dependentProperty] === undefined) { - properties[dependentProperty] = {}; + + + if (elLabel) { + createAppTooltip.registerTooltipElement(elLabel, propertyID); + } + + let elProperty = createElementFromHTML('
'); + elContainer.appendChild(elProperty); + + if (propertyType == 'triple') { + elProperty.className = 'flex-row'; + for (var i = 0; i < propertyData.properties.length; ++i) { + let innerPropertyData = propertyData.properties[i]; + + let elWrapper = createElementFromHTML('
'); + + let propertyID = innerPropertyData.propertyID; + let propertyName = innerPropertyData.propertyName !== undefined ? innerPropertyData.propertyName : propertyID; + let propertyElementID = "property-" + propertyID; + propertyElementID = propertyElementID.replace('.', '-'); + + elWrapper.appendChild(createElementFromHTML(`
${innerPropertyData.label}
`)); + elProperty.appendChild(elWrapper); + + let property = createProperty(innerPropertyData, propertyElementID, propertyName, propertyID, elWrapper.childNodes[0]); + property.isParticleProperty = group.id.includes("particles"); + property.elContainer = elContainer; + property.spaceMode = propertySpaceMode; + + if (property.type !== 'placeholder') { + properties[propertyID] = property; + } } - if (properties[dependentProperty].showPropertyRules === undefined) { - properties[dependentProperty].showPropertyRules = {}; + } else { + let property = createProperty(propertyData, propertyElementID, propertyName, propertyID, elProperty); + property.isParticleProperty = group.id.includes("particles"); + property.elContainer = elContainer; + property.spaceMode = propertySpaceMode; + + if (property.type !== 'placeholder') { + properties[propertyID] = property; + } + + let showPropertyRule = propertyData.showPropertyRule; + if (showPropertyRule !== undefined) { + let dependentProperty = Object.keys(showPropertyRule)[0]; + let dependentPropertyValue = showPropertyRule[dependentProperty]; + if (properties[dependentProperty] === undefined) { + properties[dependentProperty] = {}; + } + if (properties[dependentProperty].showPropertyRules === undefined) { + properties[dependentProperty].showPropertyRules = {}; + } + properties[dependentProperty].showPropertyRules[propertyID] = dependentPropertyValue; } - properties[dependentProperty].showPropertyRules[propertyID] = dependentPropertyValue; } }); elGroups[group.id] = elGroup; }); + let minorSections = document.querySelectorAll(".section.minor"); + minorSections[minorSections.length - 1].className += " last"; + updateVisibleSpaceModeProperties(); if (window.EventBridge !== undefined) { @@ -2934,6 +3033,10 @@ function loaded() { resetProperties(); showGroupsForType("None"); + + let elIcon = properties.type.elSpan; + elIcon.innerText = NO_SELECTION; + elIcon.style.display = 'inline-block'; deleteJSONEditor(); getPropertyInputElement("userData").value = ""; @@ -3123,7 +3226,6 @@ function loaded() { case 'icon': { property.elSpan.innerHTML = propertyData.icons[propertyValue]; property.elSpan.style.display = "inline-block"; - property.elLabel.innerHTML = propertyValue; break; } case 'texture': { @@ -3240,34 +3342,27 @@ function loaded() { } // Server Script Status - let serverScriptProperty = properties["serverScripts"]; - let elServerScript = serverScriptProperty.elInput; - let serverScriptElementID = serverScriptProperty.elementID; - let serverScriptStatusElementID = serverScriptElementID + "-status"; - let elDiv = document.createElement('div'); - elDiv.className = "property"; - elDiv.setAttribute("id", "div-" + serverScriptStatusElementID); - let elLabel = document.createElement('label'); - elLabel.setAttribute("for", serverScriptStatusElementID); - elLabel.innerText = "Server Script Status"; - createAppTooltip.registerTooltipElement(elLabel, "serverScriptsStatus"); - let elServerScriptStatus = document.createElement('span'); + let elServerScriptStatusOuter = document.getElementById('div-property-serverScriptStatus'); + let elServerScriptStatusContainer = document.getElementById('div-property-serverScriptStatus').childNodes[1]; + let serverScriptStatusElementID = 'property-serverScripts-status'; + createAppTooltip.registerTooltipElement(elServerScriptStatusOuter.childNodes[0], "serverScriptsStatus"); + let elServerScriptStatus = document.createElement('div'); elServerScriptStatus.setAttribute("id", serverScriptStatusElementID); - elDiv.appendChild(elLabel); - elDiv.appendChild(elServerScriptStatus); - elServerScript.parentNode.appendChild(elDiv); + elServerScriptStatusContainer.appendChild(elServerScriptStatus); // Server Script Error + let elServerScripts = getPropertyInputElement("serverScripts"); elDiv = document.createElement('div'); elDiv.className = "property"; let elServerScriptError = document.createElement('textarea'); - elServerScriptError.setAttribute("id", serverScriptElementID + "-error"); + let serverScriptErrorElementID = 'property-serverScripts-error'; + elServerScriptError.setAttribute("id", serverScriptErrorElementID); elDiv.appendChild(elServerScriptError); - elServerScript.parentNode.appendChild(elDiv); + elServerScriptStatusContainer.appendChild(elDiv); let elScript = getPropertyInputElement("script"); - elScript.parentNode.className = "property url refresh"; - elServerScript.parentNode.className = "property url refresh"; + elScript.parentNode.className = "url refresh"; + elServerScripts.parentNode.className = "url refresh"; // User Data let userDataProperty = properties["userData"]; @@ -3327,7 +3422,7 @@ function loaded() { let elCollapsible = document.getElementsByClassName("section-header"); let toggleCollapsedEvent = function(event) { - let element = event.target.parentNode.parentNode; + let element = this.parentNode; let isCollapsed = element.dataset.collapsed !== "true"; element.dataset.collapsed = isCollapsed ? "true" : false; element.setAttribute("collapsed", isCollapsed ? "true" : "false"); @@ -3336,7 +3431,7 @@ function loaded() { for (let collapseIndex = 0, numCollapsibles = elCollapsible.length; collapseIndex < numCollapsibles; ++collapseIndex) { let curCollapsibleElement = elCollapsible[collapseIndex]; - curCollapsibleElement.getElementsByTagName('span')[0].addEventListener("click", toggleCollapsedEvent, true); + curCollapsibleElement.addEventListener("click", toggleCollapsedEvent, true); } // Textarea scrollbars From a020a09e8c35b7359fb7842ecf5dc8f14c5d630b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 8 Nov 2018 16:33:25 -0800 Subject: [PATCH 09/18] Remove redundant dimensions in default entity properties --- scripts/system/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index d3e9a475ac..35aeac7ab5 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -466,7 +466,6 @@ const DEFAULT_ENTITY_PROPERTIES = { isSpotlight: false, exponent: 1.0, cutoff: 75.0, - dimensions: { x: 20, y: 20, z: 20 }, }, }; From a787f55506f73c2617ce12e5fd6b2d129c9bb03e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 12 Nov 2018 12:28:11 -0800 Subject: [PATCH 10/18] Remove dead code and cleanup JS styling for entity properties redesign --- scripts/system/html/css/edit-style.css | 23 ------------------ scripts/system/html/js/entityProperties.js | 28 +++++----------------- 2 files changed, 6 insertions(+), 45 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index c09655b451..aa7ed821c1 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -1411,29 +1411,6 @@ th#entity-hasScript { display: inline-block; } -/* -#properties-base #div-property-locked { - position: absolute; - top: 6px; - right: 140px; - display: table-cell; - vertical-align: middle; -} - -#properties-base #div-property-visible { - position: absolute; - top: 26px; - right: 20px; - display: table-cell; - vertical-align: middle; -} - -#properties-base #div-property-locked label, -#properties-base #div-property-visible label { - background-position-y: 1px; -} -*/ - #properties-base .checkbox label span { font-family: HiFi-Glyphs; font-size: 20px; diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 5d77c56b4a..a236e406ce 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1116,7 +1116,6 @@ const GROUPS = [ }, { label: "Clone Lifetime", - indentedLabel: true, type: "number", unit: "s", propertyID: "cloneLifetime", @@ -1124,21 +1123,18 @@ const GROUPS = [ }, { label: "Clone Limit", - indentedLabel: true, type: "number", propertyID: "cloneLimit", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Dynamic", - indentedLabel: true, type: "bool", propertyID: "cloneDynamic", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Avatar Entity", - indentedLabel: true, type: "bool", propertyID: "cloneAvatarEntity", showPropertyRule: { "cloneable": "true" }, @@ -1426,7 +1422,7 @@ function debugPrint(message) { } function createElementFromHTML(htmlString) { - var elTemplate = document.createElement('template'); + let elTemplate = document.createElement('template'); elTemplate.innerHTML = htmlString.trim(); return elTemplate.content.firstChild; } @@ -1926,11 +1922,6 @@ function createVec3Property(property, elProperty) { elProperty.className = propertyData.vec3Type + " fstuple"; - //let elTuple = document.createElement('div'); - //elTuple.className = "tuple"; - - //elProperty.appendChild(elTuple); - let elInputX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], propertyData.min, propertyData.max, propertyData.step); let elInputY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], @@ -2099,9 +2090,7 @@ function createIconProperty(property, elProperty) { elProperty.appendChild(elSpan); - let elResult = []; - elResult[ICON_ELEMENTS.ICON] = elSpan; - return elResult; + return elSpan; } function createTextureProperty(property, elProperty) { @@ -2164,9 +2153,6 @@ function createButtonsProperty(property, elProperty, elLabel) { elProperty.className = "text"; let hasLabel = propertyData.label !== undefined; - if (hasLabel) { - } - if (propertyData.buttons !== undefined) { addButtons(elProperty, elementID, propertyData.buttons, hasLabel); } @@ -2813,9 +2799,7 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI break; } case 'icon': { - let elIcon = createIconProperty(property, elProperty); - property.elSpan = elIcon[ICON_ELEMENTS.ICON]; - property.elLabel = elIcon[ICON_ELEMENTS.LABEL]; + property.elSpan = createIconProperty(property, elProperty); break; } case 'texture': { @@ -2834,7 +2818,7 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI } default: { console.log("EntityProperties - Unknown property type " + - propertyType + " set to property " + propertyID); + propertyType + " set to property " + propertyID); break; } } @@ -2940,9 +2924,9 @@ function loaded() { let elProperty = createElementFromHTML('
'); elContainer.appendChild(elProperty); - if (propertyType == 'triple') { + if (propertyType === 'triple') { elProperty.className = 'flex-row'; - for (var i = 0; i < propertyData.properties.length; ++i) { + for (let i = 0; i < propertyData.properties.length; ++i) { let innerPropertyData = propertyData.properties[i]; let elWrapper = createElementFromHTML('
'); From b3ccce9a3f23a4c8038176b5a3a8097547b0e5f6 Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 12 Nov 2018 17:30:21 -0800 Subject: [PATCH 11/18] merge follow-up --- scripts/system/html/css/edit-style.css | 32 ---------------------- scripts/system/html/js/entityProperties.js | 22 ++++----------- 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 1a1d4adaaf..7b62cdc9aa 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -876,7 +876,6 @@ div.refresh input[type="button"] { } .rgb div.legend + * { clear: both; -<<<<<<< HEAD } .draggable-number { @@ -904,8 +903,6 @@ div.refresh input[type="button"] { .draggable-number input::-webkit-inner-spin-button { -webkit-appearance: none; visibility: hidden; -======= ->>>>>>> a787f55506f73c2617ce12e5fd6b2d129c9bb03e } .row .property { @@ -1444,32 +1441,6 @@ th#entity-hasScript { display: inline-block; } -<<<<<<< HEAD -/* -#properties-base #div-property-locked { - position: absolute; - top: 6px; - right: 140px; - display: table-cell; - vertical-align: middle; -} - -#properties-base #div-property-visible { - position: absolute; - top: 26px; - right: 20px; - display: table-cell; - vertical-align: middle; -} - -#properties-base #div-property-locked label, -#properties-base #div-property-visible label { - background-position-y: 1px; -} -*/ - -======= ->>>>>>> a787f55506f73c2617ce12e5fd6b2d129c9bb03e #properties-base .checkbox label span { font-family: HiFi-Glyphs; font-size: 20px; @@ -1708,8 +1679,6 @@ input.number-slider { #toggle-space-mode.space-mode-world::before { content: "\e02c"; } -<<<<<<< HEAD -======= .container { display: flex; @@ -1808,4 +1777,3 @@ input.number-slider { display: flex; width: 100%; } ->>>>>>> a787f55506f73c2617ce12e5fd6b2d129c9bb03e diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 5a3f783c51..7c34e1841b 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1390,11 +1390,6 @@ const COLOR_ELEMENTS = { BLUE_INPUT: 3, }; -const ICON_ELEMENTS = { - ICON: 0, - LABEL: 1, -}; - const TEXTURE_ELEMENTS = { IMAGE: 0, TEXT_INPUT: 1, @@ -1622,7 +1617,9 @@ function updateVisibleSpaceModeProperties() { let propertySpaceMode = property.spaceMode; if (propertySpaceMode !== PROPERTY_SPACE_MODE.ALL) { showPropertyElement(propertyID, propertySpaceMode === currentSpaceMode); - } + } else { + showPropertyElement(propertyID, true); + } } } } @@ -2189,9 +2186,7 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI break; } case 'icon': { - let elIcon = createIconProperty(property, elProperty); - property.elSpan = elIcon[ICON_ELEMENTS.ICON]; - property.elLabel = elIcon[ICON_ELEMENTS.LABEL]; + property.elSpan = createIconProperty(property, elProperty); break; } case 'texture': { @@ -2853,7 +2848,6 @@ function loaded() { let property = createProperty(innerPropertyData, propertyElementID, propertyName, propertyID, elWrapper.childNodes[0]); property.isParticleProperty = group.id.includes("particles"); property.elContainer = elContainer; - property.spaceMode = propertySpaceMode; if (property.type !== 'placeholder') { @@ -2978,7 +2972,6 @@ function loaded() { let typeProperty = properties["type"]; typeProperty.elSpan.innerHTML = typeProperty.data.icons[type]; typeProperty.elSpan.style.display = "inline-block"; - typeProperty.elLabel.innerHTML = type + " (" + data.selections.length + ")"; disableProperties(); } else { @@ -3025,7 +3018,6 @@ function loaded() { let isPropertyNotNumber = false; switch (propertyData.type) { case 'number': - case 'slider': isPropertyNotNumber = isNaN(propertyValue) || propertyValue === null; break; case 'vec3': @@ -3057,8 +3049,7 @@ function loaded() { } break; } - case 'number': - case 'slider': { + case 'number': { let multiplier = propertyData.multiplier !== undefined ? propertyData.multiplier : 1; let value = propertyValue / multiplier; if (propertyData.round !== undefined) { @@ -3069,9 +3060,6 @@ function loaded() { } else { property.elInput.value = value; } - if (property.elSlider !== undefined) { - property.elSlider.value = property.elInput.value; - } break; } case 'vec3': From 91db81cd9410673d859e0e9d58c634546eed766e Mon Sep 17 00:00:00 2001 From: David Back Date: Tue, 13 Nov 2018 15:10:53 -0800 Subject: [PATCH 12/18] merge fix --- interface/src/avatar/AvatarManager.cpp | 2 +- interface/src/avatar/AvatarManager.h | 8 +- scripts/system/html/css/edit-style.css | 98 ---------------------- scripts/system/html/js/entityProperties.js | 6 +- 4 files changed, 6 insertions(+), 108 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 5bed6a36d9..76ad49b1f4 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -837,7 +837,7 @@ void AvatarManager::setAvatarSortCoefficient(const QString& name, const QScriptV } } -QVariantMap AvatarManager::getPalData(const QList specificAvatarIdentifiers) { +QVariantMap AvatarManager::getPalData(const QStringList& specificAvatarIdentifiers) { QJsonArray palData; auto avatarMap = getHashCopy(); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index c8901065af..75dbbc7abb 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -184,11 +184,11 @@ public: * than iterating over each avatar and obtaining data about them in JavaScript, as that method * locks and unlocks each avatar's data structure potentially hundreds of times per update tick. * @function AvatarManager.getPalData - * @param {string[]} [specificAvatarIdentifiers] - A list of specific Avatar Identifiers about - * which you want to get PAL data - * @returns {object} + * @param {string[]} [specificAvatarIdentifiers=[]] - The list of IDs of the avatars you want the PAL data for. + * If an empty list, the PAL data for all nearby avatars is returned. + * @returns {object[]} An array of objects, each object being the PAL data for an avatar. */ - Q_INVOKABLE QVariantMap getPalData(const QList specificAvatarIdentifiers = QList()); + Q_INVOKABLE QVariantMap getPalData(const QStringList& specificAvatarIdentifiers = QStringList()); float getMyAvatarSendRate() const { return _myAvatarSendRate.rate(); } int getIdentityRequestsSent() const { return _identityRequestsSent; } diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 7b62cdc9aa..28d9115c54 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -1565,104 +1565,6 @@ input.rename-entity { margin-top: 5px; } -.container { - display: flex; - flex-flow: row nowrap; - justify-content: space-around; - margin-bottom: 8px; - min-height: 28px; -} - -.container > label { - margin-top: 6px; - width: 200px; -} - -.container > div.checkbox { - padding-top: 6px; -} - -.container > .value { - width: 100%; -} - -.container .row { - display: flex; - flex-flow: row nowrap; -} - -.container.shrink { - width: min-content; -} - -.fstuple { - display: flex; - flex-flow: row; -} -.fstuple label { - position: relative; - left: 10px; -} -.fstuple label.red, .fstuple label.x { - color: #C62147; -} -.fstuple label.green, .fstuple label.y { - color: #359D85; -} -.fstuple label.blue, .fstuple label.z { - color: #0093C5; -} - -.xyz.fstuple, .pyr.fstuple { - position: relative; - left: -19px; -} - -.rgb.fstuple .tuple { - display: none; -} - -input.number-slider { - background: #575757; - border-radius: 4px; - color: white; -} - -.fstuple > div { - display: flex; - align-items: center; - justify-content: left; -} - -.flex-row { - display: flex; - flex-flow: row; -} - -.flex-column { - display: flex; - flex-flow: column; -} - -.flex-center { - align-items: center; -} - -.flex-evenly-spaced { - flex: 1; -} - -#property-serverScripts-status { - font-family: Raleway-Light; - font-size: 14px; - margin: 6px 0; -} - -#property-name, #property-id { - display: flex; - width: 100%; -} - #toggle-space-mode::before { font-family: HiFi-Glyphs; font-size: 20px; diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 81876cb6df..d4ea980292 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1116,7 +1116,6 @@ const GROUPS = [ }, { label: "Clone Lifetime", - indentedLabel: true, type: "number", unit: "s", propertyID: "cloneLifetime", @@ -1124,21 +1123,18 @@ const GROUPS = [ }, { label: "Clone Limit", - indentedLabel: true, type: "number", propertyID: "cloneLimit", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Dynamic", - indentedLabel: true, type: "bool", propertyID: "cloneDynamic", showPropertyRule: { "cloneable": "true" }, }, { label: "Clone Avatar Entity", - indentedLabel: true, type: "bool", propertyID: "cloneAvatarEntity", showPropertyRule: { "cloneable": "true" }, @@ -2193,7 +2189,7 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI } default: { console.log("EntityProperties - Unknown property type " + - propertyType + " set to property " + propertyID); + propertyType + " set to property " + propertyID); break; } } From 8db81d9ce6451739739d94493a41ed7153b84e26 Mon Sep 17 00:00:00 2001 From: David Back Date: Tue, 13 Nov 2018 16:04:08 -0800 Subject: [PATCH 13/18] restructure draggable numbers to be more like blender --- scripts/system/html/css/edit-style.css | 72 ++++++-- scripts/system/html/js/draggableNumber.js | 145 ++++++++++----- scripts/system/html/js/entityProperties.js | 204 ++++++++++++++------- 3 files changed, 302 insertions(+), 119 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 28d9115c54..883e0ab9d7 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -880,30 +880,76 @@ div.refresh input[type="button"] { .draggable-number { position: relative; - right: 10px; +} +.draggable-number div { + height: 28px; + width: 92px; +} +.draggable-number.text { + display: inline-block; + color: #afafaf; + background-color: #252525; + font-family: FiraSans-SemiBold; + font-size: 15px; + margin: 0; + padding: 0 16px; + height: 28px; + width: 100%; + line-height: 2; +} +.draggable-number.text:hover { + cursor: ew-resize; } .draggable-number span { - position: relative; - top: -2px; + position: absolute; display: inline-block; - font-family: hifi-glyphs; + font-family: HiFi-Glyphs; font-size: 20px; z-index: 2; } +.draggable-number span:hover { + cursor: default; +} .draggable-number.left-arrow { - left: 17px; + top: -5px; + right: 106px; transform: rotate(180deg); } .draggable-number.right-arrow { - right: 17px; + top: -5px; + left: 106px; } -.draggable-number.fstuple span { +.draggable-number input[type=number] { + position: absolute; + right: 0; + width: 100%; +} +.draggable-number input[type=button] { + position: absolute; top: 0; } .draggable-number input::-webkit-inner-spin-button { -webkit-appearance: none; visibility: hidden; } +.draggable-number.fstuple { + height: 28px; + width: 124px; + left: 12px; +} +.draggable-number.fstuple + .draggable-number.fstuple { + padding-left: 28px; +} +.draggable-number.fstuple input { + right: -10px; +} +.draggable-number.fstuple .sublabel { + position: absolute; + top: 0; + left: -16px; + font-family: FiraSans-SemiBold; + font-size: 15px; +} .row .property { width: auto; @@ -921,10 +967,10 @@ div.refresh input[type="button"] { .property.texture { display: block; } -.property.texture input{ +.property.texture input { margin: 0.4rem 0; } -.texture-image img{ +.texture-image img { padding: 0; margin: 0; width: 100%; @@ -1466,12 +1512,12 @@ th#entity-hasScript { } input#property-scale-button-rescale { - margin-top: 6px; min-width: 50px; + left: 152px; } input#property-scale-button-reset { - margin-top: 6px; margin-right: 0; + left: 250px; } #property-userData-button-edit, @@ -1661,6 +1707,10 @@ input.number-slider { flex-flow: column; } +.flex-column + .flex-column { + padding-left: 50px; +} + .flex-center { align-items: center; } diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index e961bbb4a7..326854bc92 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -6,67 +6,125 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +const DELTA_X_FOCUS_THRESHOLD = 2; + function DraggableNumber(min, max, step) { this.min = min; this.max = max; this.step = step !== undefined ? step : 1; - this.startEvent = null; - this.inputChangeFunction = null; + this.initialMouseEvent = null; + this.lastMouseEvent = null; + this.valueChangeFunction = null; this.initialize(); } DraggableNumber.prototype = { - onMouseDown: function(event) { - let that = this.draggableNumber; - that.mouseDown(event); - }, - mouseDown: function(event) { - this.startEvent = event; - document.addEventListener("mousemove", this.onMouseMove); - document.addEventListener("mouseup", this.onMouseUp); + if (event.target === this.elText) { + this.initialMouseEvent = event; + this.lastMouseEvent = event; + document.addEventListener("mousemove", this.onMouseMove); + document.addEventListener("mouseup", this.onMouseUp); + } }, - mouseMove: function(event, that) { - if (this.startEvent) { - let dx = event.clientX - this.startEvent.clientX; - let valueChange = dx * this.step; - let newValue = parseFloat(this.elInput.value) + valueChange; - if (this.min !== undefined && newValue < this.min) { - newValue = this.min; - } else if (this.max !== undefined && newValue > this.max) { - newValue = this.max; - } - this.elInput.value = newValue; - if (this.inputChangeFunction) { - this.inputChangeFunction(); - } - this.startEvent = event; + mouseMove: function(event) { + if (this.lastMouseEvent) { + let dx = event.clientX - this.lastMouseEvent.clientX; + let inputChanged = dx !== 0; + if (inputChanged) { + while (dx !== 0) { + if (dx > 0) { + this.stepUp(); + --dx; + } else { + this.stepDown(); + ++dx; + } + } + if (this.valueChangeFunction) { + this.valueChangeFunction(); + } + } + this.lastMouseEvent = event; } }, mouseUp: function(event) { - this.startEvent = null; - document.removeEventListener("mousemove", this.onMouseMove); - document.removeEventListener("mouseup", this.onMouseUp); + if (this.initialMouseEvent) { + let dx = event.clientX - this.initialMouseEvent.clientX; + if (dx <= DELTA_X_FOCUS_THRESHOLD) { + this.elInput.style.visibility = "visible"; + this.elText.style.visibility = "hidden"; + } + this.initialMouseEvent = null; + this.lastMouseEvent = null; + document.removeEventListener("mousemove", this.onMouseMove); + document.removeEventListener("mouseup", this.onMouseUp); + } }, - - setInputChangeFunction: function(inputChangeFunction) { - if (this.inputChangeFunction) { - this.elInput.removeEventListener('change', this.inputChangeFunction); + + stepUp: function() { + this.elInput.stepUp(); + this.inputChange(); + }, + + stepDown: function() { + this.elInput.stepDown(); + this.inputChange(); + }, + + setValue: function(newValue) { + this.elInput.value = newValue; + this.elText.firstChild.data = newValue; + }, + + setValueChangeFunction: function(valueChangeFunction) { + if (this.valueChangeFunction) { + this.elInput.removeEventListener("change", this.valueChangeFunction); } - this.inputChangeFunction = inputChangeFunction.bind(this.elInput); - this.elInput.addEventListener('change', this.inputChangeFunction); + this.valueChangeFunction = valueChangeFunction.bind(this.elInput); + this.elInput.addEventListener("change", this.valueChangeFunction); }, + + inputChange: function() { + this.setValue(this.elInput.value); + }, + + inputBlur: function() { + this.elInput.style.visibility = "hidden"; + this.elText.style.visibility = "visible"; + }, initialize: function() { + this.onMouseDown = this.mouseDown.bind(this); this.onMouseMove = this.mouseMove.bind(this); this.onMouseUp = this.mouseUp.bind(this); + this.onStepUp = this.stepUp.bind(this); + this.onStepDown = this.stepDown.bind(this); + this.onInputChange = this.inputChange.bind(this); + this.onInputBlur = this.inputBlur.bind(this); this.elDiv = document.createElement('div'); this.elDiv.className = "draggable-number"; + + this.elText = document.createElement('label'); + this.elText.className = "draggable-number text"; + this.elText.innerText = " "; + this.elText.style.visibility = "visible"; + this.elText.addEventListener("mousedown", this.onMouseDown); + + this.elLeftArrow = document.createElement('span'); + this.elRightArrow = document.createElement('span'); + this.elLeftArrow.className = 'draggable-number left-arrow'; + this.elLeftArrow.innerHTML = 'D'; + this.elLeftArrow.addEventListener("click", this.onStepDown); + this.elRightArrow.className = 'draggable-number right-arrow'; + this.elRightArrow.innerHTML = 'D'; + this.elRightArrow.addEventListener("click", this.onStepUp); this.elInput = document.createElement('input'); + this.elInput.className = "draggable-number input"; this.elInput.setAttribute("type", "number"); if (this.min !== undefined) { this.elInput.setAttribute("min", this.min); @@ -77,18 +135,13 @@ DraggableNumber.prototype = { if (this.step !== undefined) { this.elInput.setAttribute("step", this.step); } - this.elInput.draggableNumber = this; - this.elInput.addEventListener("mousedown", this.onMouseDown); - - this.elLeftArrow = document.createElement('span'); - this.elRightArrow = document.createElement('span'); - this.elLeftArrow.className = 'draggable-number left-arrow'; - this.elLeftArrow.innerHTML = 'D'; - this.elRightArrow.className = 'draggable-number right-arrow'; - this.elRightArrow.innerHTML = 'D'; + this.elInput.style.visibility = "hidden"; + this.elInput.addEventListener("change", this.onInputChange); + this.elInput.addEventListener("blur", this.onInputBlur); - this.elDiv.appendChild(this.elLeftArrow); - this.elDiv.appendChild(this.elInput); - this.elDiv.appendChild(this.elRightArrow); + this.elText.appendChild(this.elLeftArrow); + this.elText.appendChild(this.elInput); + this.elText.appendChild(this.elRightArrow); + this.elDiv.appendChild(this.elText); } }; diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index d4ea980292..cf7360b927 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1374,16 +1374,16 @@ const PROPERTY_NAME_DIVISION = { }; const VECTOR_ELEMENTS = { - X_INPUT: 0, - Y_INPUT: 1, - Z_INPUT: 2, + X_NUMBER: 0, + Y_NUMBER: 1, + Z_NUMBER: 2, }; const COLOR_ELEMENTS = { COLOR_PICKER: 0, - RED_INPUT: 1, - GREEN_INPUT: 2, - BLUE_INPUT: 3, + RED_NUMBER: 1, + GREEN_NUMBER: 2, + BLUE_NUMBER: 3, }; const TEXTURE_ELEMENTS = { @@ -1417,16 +1417,17 @@ function getPropertyInputElement(propertyID) { switch (property.data.type) { case 'string': case 'bool': - case 'number': case 'dropdown': case 'textarea': case 'texture': return property.elInput; + case 'number': + return property.elNumber.elInput; case 'vec3': case 'vec2': - return { x: property.elInputX, y: property.elInputY, z: property.elInputZ }; + return { x: property.elNumberX.elInput, y: property.elNumberY.elInput, z: property.elNumberZ.elInput }; case 'color': - return { red: property.elInputR, green: property.elInputG, blue: property.elInputB }; + return { red: property.elNumberR.elInput, green: property.elNumberG.elInput, blue: property.elNumberB.elInput }; case 'icon': return property.elLabel; default: @@ -1498,26 +1499,26 @@ function resetProperties() { } case 'number': { if (propertyData.defaultValue !== undefined) { - property.elInput.value = propertyData.defaultValue; + property.elNumber.setValue(propertyData.defaultValue); } else { - property.elInput.value = ""; + property.elNumber.setValue(""); } break; } case 'vec3': case 'vec2': { - property.elInputX.value = ""; - property.elInputY.value = ""; - if (property.elInputZ !== undefined) { - property.elInputZ.value = ""; + property.elNumberX.setValue(""); + property.elNumberY.setValue(""); + if (property.elNumberZ !== undefined) { + property.elNumberZ.setValue(""); } break; } case 'color': { property.elColorPicker.style.backgroundColor = "rgb(" + 0 + "," + 0 + "," + 0 + ")"; - property.elInputR.value = ""; - property.elInputG.value = ""; - property.elInputB.value = ""; + property.elNumberR.setValue(""); + property.elNumberG.setValue(""); + property.elNumberB.setValue(""); break; } case 'dropdown': { @@ -1819,17 +1820,17 @@ function createNumberProperty(property, elProperty) { elDraggableNumber.elInput.value = defaultValue; } - let inputChangeFunction = createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, propertyData.decimals, property.isParticleProperty); - elDraggableNumber.setInputChangeFunction(inputChangeFunction); + let valueChangeFunction = createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, property.isParticleProperty); + elDraggableNumber.setValueChangeFunction(valueChangeFunction); elDraggableNumber.elInput.setAttribute("id", elementID); elProperty.appendChild(elDraggableNumber.elDiv); if (propertyData.buttons !== undefined) { - addButtons(elDraggableNumber.elDiv, elementID, propertyData.buttons, false); + addButtons(elDraggableNumber.elText, elementID, propertyData.buttons, false); } - return elDraggableNumber.elInput; + return elDraggableNumber; } function createVec3Property(property, elProperty) { @@ -1839,24 +1840,24 @@ function createVec3Property(property, elProperty) { elProperty.className = propertyData.vec3Type + " fstuple"; - let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], + let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER], propertyData.min, propertyData.max, propertyData.step); - let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], + let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER], propertyData.min, propertyData.max, propertyData.step); - let elNumberZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_INPUT], + let elNumberZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_NUMBER], propertyData.min, propertyData.max, propertyData.step); - let inputChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, + let valueChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, elNumberZ.elInput, propertyData.multiplier, property.isParticleProperty); - elNumberX.setInputChangeFunction(inputChangeFunction); - elNumberY.setInputChangeFunction(inputChangeFunction); - elNumberZ.setInputChangeFunction(inputChangeFunction); + elNumberX.setValueChangeFunction(valueChangeFunction); + elNumberY.setValueChangeFunction(valueChangeFunction); + elNumberZ.setValueChangeFunction(valueChangeFunction); let elResult = []; - elResult[VECTOR_ELEMENTS.X_INPUT] = elNumberX.elInput; - elResult[VECTOR_ELEMENTS.Y_INPUT] = elNumberY.elInput; - elResult[VECTOR_ELEMENTS.Z_INPUT] = elNumberZ.elInput; + elResult[VECTOR_ELEMENTS.X_NUMBER] = elNumberX; + elResult[VECTOR_ELEMENTS.Y_NUMBER] = elNumberY; + elResult[VECTOR_ELEMENTS.Z_NUMBER] = elNumberZ; return elResult; } @@ -1872,19 +1873,19 @@ function createVec2Property(property, elProperty) { elProperty.appendChild(elTuple); - let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_INPUT], + let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER], propertyData.min, propertyData.max, propertyData.step); - let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_INPUT], + let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER], propertyData.min, propertyData.max, propertyData.step); - let inputChangeFunction = createEmitVec2PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, + let valueChangeFunction = createEmitVec2PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, propertyData.multiplier, property.isParticleProperty); - elNumberX.setInputChangeFunction(inputChangeFunction); - elNumberY.setInputChangeFunction(inputChangeFunction); + elNumberX.setValueChangeFunction(valueChangeFunction); + elNumberY.setValueChangeFunction(valueChangeFunction); let elResult = []; - elResult[VECTOR_ELEMENTS.X_INPUT] = elNumberX.elInput; - elResult[VECTOR_ELEMENTS.Y_INPUT] = elNumberY.elInput; + elResult[VECTOR_ELEMENTS.X_NUMBER] = elNumberX; + elResult[VECTOR_ELEMENTS.Y_NUMBER] = elNumberY; return elResult; } @@ -1908,11 +1909,11 @@ function createColorProperty(property, elProperty) { let elNumberG = createTupleNumberInput(elTuple, elementID, "green", COLOR_MIN, COLOR_MAX, COLOR_STEP); let elNumberB = createTupleNumberInput(elTuple, elementID, "blue", COLOR_MIN, COLOR_MAX, COLOR_STEP); - let inputChangeFunction = createEmitColorPropertyUpdateFunction(propertyName, elNumberR.elInput, elNumberG.elInput, + let valueChangeFunction = createEmitColorPropertyUpdateFunction(propertyName, elNumberR.elInput, elNumberG.elInput, elNumberB.elInput, property.isParticleProperty); - elNumberR.setInputChangeFunction(inputChangeFunction); - elNumberG.setInputChangeFunction(inputChangeFunction); - elNumberB.setInputChangeFunction(inputChangeFunction); + elNumberR.setValueChangeFunction(valueChangeFunction); + elNumberG.setValueChangeFunction(valueChangeFunction); + elNumberB.setValueChangeFunction(valueChangeFunction); let colorPickerID = "#" + elementID; colorPickers[colorPickerID] = $(colorPickerID).colpick({ @@ -1941,9 +1942,9 @@ function createColorProperty(property, elProperty) { let elResult = []; elResult[COLOR_ELEMENTS.COLOR_PICKER] = elColorPicker; - elResult[COLOR_ELEMENTS.RED_INPUT] = elNumberR.elInput; - elResult[COLOR_ELEMENTS.GREEN_INPUT] = elNumberG.elInput; - elResult[COLOR_ELEMENTS.BLUE_INPUT] = elNumberB.elInput; + elResult[COLOR_ELEMENTS.RED_NUMBER] = elNumberR; + elResult[COLOR_ELEMENTS.GREEN_NUMBER] = elNumberG; + elResult[COLOR_ELEMENTS.BLUE_NUMBER] = elNumberB; return elResult; } @@ -2081,14 +2082,14 @@ function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, let elementID = propertyElementID + "-" + subLabel.toLowerCase(); let elLabel = document.createElement('label'); - elLabel.className = subLabel; + elLabel.className = "sublabel " + subLabel; elLabel.innerText = subLabel[0].toUpperCase() + subLabel.slice(1); elLabel.setAttribute("for", elementID); let elDraggableNumber = new DraggableNumber(min, max, step); elDraggableNumber.elInput.setAttribute("id", elementID); elDraggableNumber.elDiv.className += " fstuple"; - elDraggableNumber.elDiv.insertBefore(elLabel, elDraggableNumber.elLeftArrow); + elDraggableNumber.elText.insertBefore(elLabel, elDraggableNumber.elLeftArrow); elTuple.appendChild(elDraggableNumber.elDiv); return elDraggableNumber; @@ -2189,7 +2190,7 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI } default: { console.log("EntityProperties - Unknown property type " + - propertyType + " set to property " + propertyID); + propertyType + " set to property " + propertyID); break; } } @@ -2716,6 +2717,85 @@ function showParentMaterialNameBox(number, elNumber, elString) { } } +function createProperty(propertyData, propertyElementID, propertyName, propertyID, elProperty) { + let property = { + data: propertyData, + elementID: propertyElementID, + name: propertyName, + elProperty: elProperty, + }; + let propertyType = propertyData.type; + + switch (propertyType) { + case 'string': { + property.elInput = createStringProperty(property, elProperty); + break; + } + case 'bool': { + property.elInput = createBoolProperty(property, elProperty); + break; + } + case 'number': { + property.elNumber = createNumberProperty(property, elProperty); + break; + } + case 'vec3': { + let elVec3 = createVec3Property(property, elProperty); + property.elNumberX = elVec3[VECTOR_ELEMENTS.X_NUMBER]; + property.elNumberY = elVec3[VECTOR_ELEMENTS.Y_NUMBER]; + property.elNumberZ = elVec3[VECTOR_ELEMENTS.Z_NUMBER]; + break; + } + case 'vec2': { + let elVec2 = createVec2Property(property, elProperty); + property.elNumberX = elVec2[VECTOR_ELEMENTS.X_NUMBER]; + property.elNumberY = elVec2[VECTOR_ELEMENTS.Y_NUMBER]; + break; + } + case 'color': { + let elColor = createColorProperty(property, elProperty); + property.elColorPicker = elColor[COLOR_ELEMENTS.COLOR_PICKER]; + property.elNumberR = elColor[COLOR_ELEMENTS.RED_NUMBER]; + property.elNumberG = elColor[COLOR_ELEMENTS.GREEN_NUMBER]; + property.elNumberB = elColor[COLOR_ELEMENTS.BLUE_NUMBER]; + break; + } + case 'dropdown': { + property.elInput = createDropdownProperty(property, propertyID, elProperty); + break; + } + case 'textarea': { + property.elInput = createTextareaProperty(property, elProperty); + break; + } + case 'icon': { + property.elSpan = createIconProperty(property, elProperty); + break; + } + case 'texture': { + let elTexture = createTextureProperty(property, elProperty); + property.elImage = elTexture[TEXTURE_ELEMENTS.IMAGE]; + property.elInput = elTexture[TEXTURE_ELEMENTS.TEXT_INPUT]; + break; + } + case 'buttons': { + property.elProperty = createButtonsProperty(property, elProperty); + break; + } + case 'placeholder': + case 'sub-header': { + break; + } + default: { + console.log("EntityProperties - Unknown property type " + + propertyType + " set to property " + propertyID); + break; + } + } + + return property; +} + function loaded() { openEventBridge(function() { @@ -3040,9 +3120,9 @@ function loaded() { value = Math.round(value.round) / propertyData.round; } if (propertyData.decimals !== undefined) { - property.elInput.value = value.toFixed(propertyData.decimals); + property.elNumber.setValue(value.toFixed(propertyData.decimals)); } else { - property.elInput.value = value; + property.elNumber.setValue(value); } break; } @@ -3058,16 +3138,16 @@ function loaded() { valueZ = Math.round(valueZ * propertyData.round) / propertyData.round; } if (propertyData.decimals !== undefined) { - property.elInputX.value = valueX.toFixed(propertyData.decimals); - property.elInputY.value = valueY.toFixed(propertyData.decimals); - if (property.elInputZ !== undefined) { - property.elInputZ.value = valueZ.toFixed(propertyData.decimals); + property.elNumberX.setValue(valueX.toFixed(propertyData.decimals)); + property.elNumberY.setValue(valueY.toFixed(propertyData.decimals)); + if (property.elNumberZ !== undefined) { + property.elNumberZ.setValue(valueZ.toFixed(propertyData.decimals)); } } else { - property.elInputX.value = valueX; - property.elInputY.value = valueY; - if (property.elInputZ !== undefined) { - property.elInputZ.value = valueZ; + property.elNumberX.setValue(valueX); + property.elNumberY.setValue(valueY); + if (property.elNumberZ !== undefined) { + property.elNumberZ.setValue(valueZ); } } break; @@ -3076,9 +3156,9 @@ function loaded() { property.elColorPicker.style.backgroundColor = "rgb(" + propertyValue.red + "," + propertyValue.green + "," + propertyValue.blue + ")"; - property.elInputR.value = propertyValue.red; - property.elInputG.value = propertyValue.green; - property.elInputB.value = propertyValue.blue; + property.elNumberR.setValue(propertyValue.red); + property.elNumberG.setValue(propertyValue.green); + property.elNumberB.setValue(propertyValue.blue); break; } case 'dropdown': { From 1aa048f4d61d1c8f506349eb446daa05f8f88312 Mon Sep 17 00:00:00 2001 From: David Back Date: Tue, 13 Nov 2018 17:56:31 -0800 Subject: [PATCH 14/18] style and decimal fixes --- scripts/system/html/css/edit-style.css | 7 +- scripts/system/html/js/draggableNumber.js | 163 +++++++++++---------- scripts/system/html/js/entityProperties.js | 43 +++--- 3 files changed, 108 insertions(+), 105 deletions(-) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 84f01e6205..3a291bf27b 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -252,7 +252,7 @@ input.search:focus { box-shadow: 0 0 0 1px #00b4ef; } -input:disabled, textarea:disabled { +input:disabled, textarea:disabled, .draggable-number.text[disabled="disabled"] { background-color: #383838; color: #afafaf; } @@ -1446,11 +1446,6 @@ input#property-scale-button-reset { left: 250px; } -#property-userData-button-edit, -#property-materialData-button-clear { - margin: 6px 0 6px 0; -} - #property-userData-static, #property-materialData-static { display: none; diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index 326854bc92..7e5d9d524a 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -6,13 +6,14 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -const DELTA_X_FOCUS_THRESHOLD = 2; +const DELTA_X_FOCUS_THRESHOLD = 1; -function DraggableNumber(min, max, step) { +function DraggableNumber(min, max, step, decimals) { this.min = min; this.max = max; this.step = step !== undefined ? step : 1; - this.initialMouseEvent = null; + this.decimals = decimals; + this.initialMouseEvent = null; this.lastMouseEvent = null; this.valueChangeFunction = null; this.initialize(); @@ -20,64 +21,68 @@ function DraggableNumber(min, max, step) { DraggableNumber.prototype = { mouseDown: function(event) { - if (event.target === this.elText) { - this.initialMouseEvent = event; - this.lastMouseEvent = event; - document.addEventListener("mousemove", this.onMouseMove); - document.addEventListener("mouseup", this.onMouseUp); - } + if (event.target === this.elText) { + this.initialMouseEvent = event; + this.lastMouseEvent = event; + document.addEventListener("mousemove", this.onMouseMove); + document.addEventListener("mouseup", this.onMouseUp); + } }, mouseMove: function(event) { if (this.lastMouseEvent) { let dx = event.clientX - this.lastMouseEvent.clientX; - let inputChanged = dx !== 0; - if (inputChanged) { - while (dx !== 0) { - if (dx > 0) { - this.stepUp(); - --dx; - } else { - this.stepDown(); - ++dx; - } - } - if (this.valueChangeFunction) { - this.valueChangeFunction(); - } - } + let inputChanged = dx !== 0; + if (inputChanged) { + while (dx !== 0) { + if (dx > 0) { + this.stepUp(); + --dx; + } else { + this.stepDown(); + ++dx; + } + } + if (this.valueChangeFunction) { + this.valueChangeFunction(); + } + } this.lastMouseEvent = event; } }, mouseUp: function(event) { - if (this.initialMouseEvent) { - let dx = event.clientX - this.initialMouseEvent.clientX; - if (dx <= DELTA_X_FOCUS_THRESHOLD) { - this.elInput.style.visibility = "visible"; - this.elText.style.visibility = "hidden"; - } - this.initialMouseEvent = null; - this.lastMouseEvent = null; - document.removeEventListener("mousemove", this.onMouseMove); - document.removeEventListener("mouseup", this.onMouseUp); - } + if (this.initialMouseEvent) { + let dx = event.clientX - this.initialMouseEvent.clientX; + if (dx <= DELTA_X_FOCUS_THRESHOLD) { + this.elInput.style.visibility = "visible"; + this.elText.style.visibility = "hidden"; + } + this.initialMouseEvent = null; + this.lastMouseEvent = null; + document.removeEventListener("mousemove", this.onMouseMove); + document.removeEventListener("mouseup", this.onMouseUp); + } + }, + + stepUp: function() { + this.elInput.stepUp(); + this.inputChange(); + }, + + stepDown: function() { + this.elInput.stepDown(); + this.inputChange(); + }, + + setValue: function(newValue) { + if (newValue !== "" && this.decimals !== undefined) { + this.elInput.value = parseFloat(newValue).toFixed(this.decimals); + } else { + this.elInput.value = newValue; + } + this.elText.firstChild.data = this.elInput.value; }, - - stepUp: function() { - this.elInput.stepUp(); - this.inputChange(); - }, - - stepDown: function() { - this.elInput.stepDown(); - this.inputChange(); - }, - - setValue: function(newValue) { - this.elInput.value = newValue; - this.elText.firstChild.data = newValue; - }, setValueChangeFunction: function(valueChangeFunction) { if (this.valueChangeFunction) { @@ -86,45 +91,45 @@ DraggableNumber.prototype = { this.valueChangeFunction = valueChangeFunction.bind(this.elInput); this.elInput.addEventListener("change", this.valueChangeFunction); }, - - inputChange: function() { - this.setValue(this.elInput.value); - }, - - inputBlur: function() { - this.elInput.style.visibility = "hidden"; - this.elText.style.visibility = "visible"; - }, + + inputChange: function() { + this.setValue(this.elInput.value); + }, + + inputBlur: function() { + this.elInput.style.visibility = "hidden"; + this.elText.style.visibility = "visible"; + }, initialize: function() { - this.onMouseDown = this.mouseDown.bind(this); + this.onMouseDown = this.mouseDown.bind(this); this.onMouseMove = this.mouseMove.bind(this); this.onMouseUp = this.mouseUp.bind(this); - this.onStepUp = this.stepUp.bind(this); - this.onStepDown = this.stepDown.bind(this); - this.onInputChange = this.inputChange.bind(this); - this.onInputBlur = this.inputBlur.bind(this); + this.onStepUp = this.stepUp.bind(this); + this.onStepDown = this.stepDown.bind(this); + this.onInputChange = this.inputChange.bind(this); + this.onInputBlur = this.inputBlur.bind(this); this.elDiv = document.createElement('div'); this.elDiv.className = "draggable-number"; - - this.elText = document.createElement('label'); - this.elText.className = "draggable-number text"; - this.elText.innerText = " "; - this.elText.style.visibility = "visible"; - this.elText.addEventListener("mousedown", this.onMouseDown); - - this.elLeftArrow = document.createElement('span'); + + this.elText = document.createElement('label'); + this.elText.className = "draggable-number text"; + this.elText.innerText = " "; + this.elText.style.visibility = "visible"; + this.elText.addEventListener("mousedown", this.onMouseDown); + + this.elLeftArrow = document.createElement('span'); this.elRightArrow = document.createElement('span'); this.elLeftArrow.className = 'draggable-number left-arrow'; this.elLeftArrow.innerHTML = 'D'; - this.elLeftArrow.addEventListener("click", this.onStepDown); + this.elLeftArrow.addEventListener("click", this.onStepDown); this.elRightArrow.className = 'draggable-number right-arrow'; this.elRightArrow.innerHTML = 'D'; - this.elRightArrow.addEventListener("click", this.onStepUp); + this.elRightArrow.addEventListener("click", this.onStepUp); this.elInput = document.createElement('input'); - this.elInput.className = "draggable-number input"; + this.elInput.className = "draggable-number input"; this.elInput.setAttribute("type", "number"); if (this.min !== undefined) { this.elInput.setAttribute("min", this.min); @@ -135,13 +140,13 @@ DraggableNumber.prototype = { if (this.step !== undefined) { this.elInput.setAttribute("step", this.step); } - this.elInput.style.visibility = "hidden"; - this.elInput.addEventListener("change", this.onInputChange); - this.elInput.addEventListener("blur", this.onInputBlur); + this.elInput.style.visibility = "hidden"; + this.elInput.addEventListener("change", this.onInputChange); + this.elInput.addEventListener("blur", this.onInputBlur); this.elText.appendChild(this.elLeftArrow); this.elText.appendChild(this.elInput); this.elText.appendChild(this.elRightArrow); - this.elDiv.appendChild(this.elText); + this.elDiv.appendChild(this.elText); } }; diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index cf7360b927..a9233f0dce 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1450,10 +1450,11 @@ function disableChildren(el, selector) { } function enableProperties() { - enableChildren(document.getElementById("properties-list"), "input, textarea, checkbox, .dropdown dl, .color-picker"); + enableChildren(document.getElementById("properties-list"), + "input, textarea, checkbox, .dropdown dl, .color-picker , .draggable-number.text"); enableChildren(document, ".colpick"); + let elLocked = getPropertyInputElement("locked"); - if (elLocked.checked === false) { removeStaticUserData(); removeStaticMaterialData(); @@ -1461,13 +1462,14 @@ function enableProperties() { } function disableProperties() { - disableChildren(document.getElementById("properties-list"), "input, textarea, checkbox, .dropdown dl, .color-picker"); + disableChildren(document.getElementById("properties-list"), + "input, textarea, checkbox, .dropdown dl, .color-picker, .draggable-number.text"); disableChildren(document, ".colpick"); for (let pickKey in colorPickers) { colorPickers[pickKey].colpickHide(); } + let elLocked = getPropertyInputElement("locked"); - if (elLocked.checked === true) { if ($('#property-userData-editor').css('display') === "block") { showStaticUserData(); @@ -1797,10 +1799,12 @@ function createBoolProperty(property, elProperty) { let subPropertyOf = propertyData.subPropertyOf; if (subPropertyOf !== undefined) { elInput.addEventListener('change', function() { - updateCheckedSubProperty(subPropertyOf, selectedEntityProperties[subPropertyOf], elInput, propertyName, property.isParticleProperty); + updateCheckedSubProperty(subPropertyOf, selectedEntityProperties[subPropertyOf], + elInput, propertyName, property.isParticleProperty); }); } else { - elInput.addEventListener('change', createEmitCheckedPropertyUpdateFunction(propertyName, propertyData.inverse, property.isParticleProperty)); + elInput.addEventListener('change', createEmitCheckedPropertyUpdateFunction(propertyName, propertyData.inverse, + property.isParticleProperty)); } return elInput; @@ -1813,14 +1817,16 @@ function createNumberProperty(property, elProperty) { elProperty.className = "draggable-number"; - let elDraggableNumber = new DraggableNumber(propertyData.min, propertyData.max, propertyData.step); + let elDraggableNumber = new DraggableNumber(propertyData.min, propertyData.max, + propertyData.step, propertyData.decimals); let defaultValue = propertyData.defaultValue; if (defaultValue !== undefined) { elDraggableNumber.elInput.value = defaultValue; } - let valueChangeFunction = createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, property.isParticleProperty); + let valueChangeFunction = createEmitNumberPropertyUpdateFunction(propertyName, propertyData.multiplier, + property.isParticleProperty); elDraggableNumber.setValueChangeFunction(valueChangeFunction); elDraggableNumber.elInput.setAttribute("id", elementID); @@ -1841,11 +1847,11 @@ function createVec3Property(property, elProperty) { elProperty.className = propertyData.vec3Type + " fstuple"; let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER], - propertyData.min, propertyData.max, propertyData.step); + propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER], - propertyData.min, propertyData.max, propertyData.step); + propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); let elNumberZ = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Z_NUMBER], - propertyData.min, propertyData.max, propertyData.step); + propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); let valueChangeFunction = createEmitVec3PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, elNumberZ.elInput, propertyData.multiplier, @@ -1874,9 +1880,9 @@ function createVec2Property(property, elProperty) { elProperty.appendChild(elTuple); let elNumberX = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.X_NUMBER], - propertyData.min, propertyData.max, propertyData.step); + propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); let elNumberY = createTupleNumberInput(elProperty, elementID, propertyData.subLabels[VECTOR_ELEMENTS.Y_NUMBER], - propertyData.min, propertyData.max, propertyData.step); + propertyData.min, propertyData.max, propertyData.step, propertyData.decimals); let valueChangeFunction = createEmitVec2PropertyUpdateFunction(propertyName, elNumberX.elInput, elNumberY.elInput, propertyData.multiplier, property.isParticleProperty); @@ -2078,15 +2084,16 @@ function createButtonsProperty(property, elProperty, elLabel) { return elProperty; } -function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, step) { +function createTupleNumberInput(elTuple, propertyElementID, subLabel, min, max, step, decimals) { let elementID = propertyElementID + "-" + subLabel.toLowerCase(); let elLabel = document.createElement('label'); elLabel.className = "sublabel " + subLabel; elLabel.innerText = subLabel[0].toUpperCase() + subLabel.slice(1); elLabel.setAttribute("for", elementID); + elLabel.style.visibility = "visible"; - let elDraggableNumber = new DraggableNumber(min, max, step); + let elDraggableNumber = new DraggableNumber(min, max, step, decimals); elDraggableNumber.elInput.setAttribute("id", elementID); elDraggableNumber.elDiv.className += " fstuple"; elDraggableNumber.elText.insertBefore(elLabel, elDraggableNumber.elLeftArrow); @@ -3119,11 +3126,7 @@ function loaded() { if (propertyData.round !== undefined) { value = Math.round(value.round) / propertyData.round; } - if (propertyData.decimals !== undefined) { - property.elNumber.setValue(value.toFixed(propertyData.decimals)); - } else { - property.elNumber.setValue(value); - } + property.elNumber.setValue(value); break; } case 'vec3': From 010f7121a377c9d7cb7a505de5eabc116ae79915 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Nov 2018 15:27:18 +1300 Subject: [PATCH 15/18] Fix Goto app clicks not working Includes better card highlighting fix. --- interface/resources/qml/hifi/Card.qml | 23 +++++++++++------------ interface/resources/qml/hifi/Feed.qml | 1 - 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/interface/resources/qml/hifi/Card.qml b/interface/resources/qml/hifi/Card.qml index f7147e1264..d7fafcc165 100644 --- a/interface/resources/qml/hifi/Card.qml +++ b/interface/resources/qml/hifi/Card.qml @@ -49,7 +49,6 @@ Item { property string defaultThumbnail: Qt.resolvedUrl("../../images/default-domain.gif"); property int shadowHeight: 10; property bool hovered: false - property bool scrolling: false HifiConstants { id: hifi } @@ -238,7 +237,7 @@ Item { property var unhoverThunk: function () { }; Rectangle { anchors.fill: parent - visible: root.hovered && !root.scrolling + visible: root.hovered color: "transparent" border.width: 4 border.color: hifiStyleConstants.colors.primaryHighlight @@ -252,17 +251,17 @@ Item { goFunction("hifi://" + hifiUrl); } hoverEnabled: true; - onEntered: { - Tablet.playSound(TabletEnums.ButtonHover); - hoverThunk(); + onContainsMouseChanged: { + // Use onContainsMouseChanged rather than onEntered and onExited because the latter aren't always + // triggered correctly - e.g., if drag rightwards from right hand side of a card to the next card + // onExited doesn't fire, in which case can end up with two cards highlighted. + if (containsMouse) { + Tablet.playSound(TabletEnums.ButtonHover); + hoverThunk(); + } else { + unhoverThunk(); + } } - onExited: unhoverThunk(); - onCanceled: unhoverThunk(); - } - MouseArea { - // This second mouse area causes onEntered to fire on the first if you scroll just a little and the cursor stays on - // the original card. I.e., the original card is re-highlighted if the cursor is on it after scrolling finishes. - anchors.fill: parent } StateImage { id: actionIcon; diff --git a/interface/resources/qml/hifi/Feed.qml b/interface/resources/qml/hifi/Feed.qml index 6928fc6f02..1e89971938 100644 --- a/interface/resources/qml/hifi/Feed.qml +++ b/interface/resources/qml/hifi/Feed.qml @@ -141,7 +141,6 @@ Column { textSizeSmall: root.textSizeSmall; stackShadowNarrowing: root.stackShadowNarrowing; shadowHeight: root.stackedCardShadowHeight; - scrolling: scroll.moving hoverThunk: function () { hovered = true; From 9c5d31834143fa5e10e4ea2c3c78a0ea63c3bbda Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 15 Nov 2018 10:15:30 +1300 Subject: [PATCH 16/18] Fix highlighting --- interface/resources/qml/hifi/Card.qml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/hifi/Card.qml b/interface/resources/qml/hifi/Card.qml index d7fafcc165..5c89a07b08 100644 --- a/interface/resources/qml/hifi/Card.qml +++ b/interface/resources/qml/hifi/Card.qml @@ -244,13 +244,9 @@ Item { z: 1 } MouseArea { - anchors.fill: parent; - acceptedButtons: Qt.LeftButton; - onClicked: { - Tablet.playSound(TabletEnums.ButtonClick); - goFunction("hifi://" + hifiUrl); - } - hoverEnabled: true; + anchors.fill: parent + acceptedButtons: Qt.LeftButton + hoverEnabled: true onContainsMouseChanged: { // Use onContainsMouseChanged rather than onEntered and onExited because the latter aren't always // triggered correctly - e.g., if drag rightwards from right hand side of a card to the next card @@ -263,6 +259,17 @@ Item { } } } + MouseArea { + // Separate MouseArea for click handling so that it doesn't interfere with hovering and interaction + // with containing ListView. + anchors.fill: parent + acceptedButtons: Qt.LeftButton + hoverEnabled: false + onClicked: { + Tablet.playSound(TabletEnums.ButtonClick); + goFunction("hifi://" + hifiUrl); + } + } StateImage { id: actionIcon; visible: !isAnnouncement; From d8f5e0f7088e6b5122a116fb50b4fec81f3a615e Mon Sep 17 00:00:00 2001 From: David Back Date: Wed, 14 Nov 2018 14:32:17 -0800 Subject: [PATCH 17/18] add min/max/step for some properties, remove duplicate createProperty, improve switch between states --- scripts/system/html/js/draggableNumber.js | 42 ++++---- scripts/system/html/js/entityProperties.js | 110 +++++---------------- 2 files changed, 46 insertions(+), 106 deletions(-) diff --git a/scripts/system/html/js/draggableNumber.js b/scripts/system/html/js/draggableNumber.js index 7e5d9d524a..1f4bc21441 100644 --- a/scripts/system/html/js/draggableNumber.js +++ b/scripts/system/html/js/draggableNumber.js @@ -24,16 +24,28 @@ DraggableNumber.prototype = { if (event.target === this.elText) { this.initialMouseEvent = event; this.lastMouseEvent = event; - document.addEventListener("mousemove", this.onMouseMove); - document.addEventListener("mouseup", this.onMouseUp); + document.addEventListener("mousemove", this.onDocumentMouseMove); + document.addEventListener("mouseup", this.onDocumentMouseUp); } }, - mouseMove: function(event) { + mouseUp: function(event) { + if (event.target === this.elText && this.initialMouseEvent) { + let dx = event.clientX - this.initialMouseEvent.clientX; + if (dx <= DELTA_X_FOCUS_THRESHOLD) { + this.elInput.style.visibility = "visible"; + this.elText.style.visibility = "hidden"; + } + this.initialMouseEvent = null; + } + }, + + documentMouseMove: function(event) { if (this.lastMouseEvent) { + let initialValue = this.elInput.value; let dx = event.clientX - this.lastMouseEvent.clientX; - let inputChanged = dx !== 0; - if (inputChanged) { + let changeValue = dx !== 0; + if (changeValue) { while (dx !== 0) { if (dx > 0) { this.stepUp(); @@ -51,18 +63,10 @@ DraggableNumber.prototype = { } }, - mouseUp: function(event) { - if (this.initialMouseEvent) { - let dx = event.clientX - this.initialMouseEvent.clientX; - if (dx <= DELTA_X_FOCUS_THRESHOLD) { - this.elInput.style.visibility = "visible"; - this.elText.style.visibility = "hidden"; - } - this.initialMouseEvent = null; - this.lastMouseEvent = null; - document.removeEventListener("mousemove", this.onMouseMove); - document.removeEventListener("mouseup", this.onMouseUp); - } + documentMouseUp: function(event) { + this.lastMouseEvent = null; + document.removeEventListener("mousemove", this.onDocumentMouseMove); + document.removeEventListener("mouseup", this.onDocumentMouseUp); }, stepUp: function() { @@ -103,8 +107,9 @@ DraggableNumber.prototype = { initialize: function() { this.onMouseDown = this.mouseDown.bind(this); - this.onMouseMove = this.mouseMove.bind(this); this.onMouseUp = this.mouseUp.bind(this); + this.onDocumentMouseMove = this.documentMouseMove.bind(this); + this.onDocumentMouseUp = this.documentMouseUp.bind(this); this.onStepUp = this.stepUp.bind(this); this.onStepDown = this.stepDown.bind(this); this.onInputChange = this.inputChange.bind(this); @@ -118,6 +123,7 @@ DraggableNumber.prototype = { this.elText.innerText = " "; this.elText.style.visibility = "visible"; this.elText.addEventListener("mousedown", this.onMouseDown); + this.elText.addEventListener("mouseup", this.onMouseUp); this.elLeftArrow = document.createElement('span'); this.elRightArrow = document.createElement('span'); diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index a9233f0dce..ae5748cbc8 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1288,24 +1288,36 @@ const GROUPS = [ { label: "Angular Damping", type: "number", + min: 0, + max: 1, + step: 0.01, decimals: 4, propertyID: "angularDamping", }, { label: "Bounciness", type: "number", + min: 0, + max: 1, + step: 0.01, decimals: 4, propertyID: "restitution", }, { label: "Friction", type: "number", + min: 0, + max: 10, + step: 0.1, decimals: 4, propertyID: "friction", }, { label: "Density", type: "number", + min: 100, + max: 10000, + step: 1, decimals: 4, propertyID: "density", }, @@ -1314,6 +1326,7 @@ const GROUPS = [ type: "vec3", vec3Type: "xyz", subLabels: [ "x", "y", "z" ], + decimals: 4, unit: "m/s2", propertyID: "gravity", }, @@ -2145,28 +2158,28 @@ function createProperty(propertyData, propertyElementID, propertyName, propertyI break; } case 'number': { - property.elInput = createNumberProperty(property, elProperty); + property.elNumber = createNumberProperty(property, elProperty); break; } case 'vec3': { let elVec3 = createVec3Property(property, elProperty); - property.elInputX = elVec3[VECTOR_ELEMENTS.X_INPUT]; - property.elInputY = elVec3[VECTOR_ELEMENTS.Y_INPUT]; - property.elInputZ = elVec3[VECTOR_ELEMENTS.Z_INPUT]; + property.elNumberX = elVec3[VECTOR_ELEMENTS.X_NUMBER]; + property.elNumberY = elVec3[VECTOR_ELEMENTS.Y_NUMBER]; + property.elNumberZ = elVec3[VECTOR_ELEMENTS.Z_NUMBER]; break; } case 'vec2': { let elVec2 = createVec2Property(property, elProperty); - property.elInputX = elVec2[VECTOR_ELEMENTS.X_INPUT]; - property.elInputY = elVec2[VECTOR_ELEMENTS.Y_INPUT]; + property.elNumberX = elVec2[VECTOR_ELEMENTS.X_NUMBER]; + property.elNumberY = elVec2[VECTOR_ELEMENTS.Y_NUMBER]; break; } case 'color': { let elColor = createColorProperty(property, elProperty); property.elColorPicker = elColor[COLOR_ELEMENTS.COLOR_PICKER]; - property.elInputR = elColor[COLOR_ELEMENTS.RED_INPUT]; - property.elInputG = elColor[COLOR_ELEMENTS.GREEN_INPUT]; - property.elInputB = elColor[COLOR_ELEMENTS.BLUE_INPUT]; + property.elNumberR = elColor[COLOR_ELEMENTS.RED_NUMBER]; + property.elNumberG = elColor[COLOR_ELEMENTS.GREEN_NUMBER]; + property.elNumberB = elColor[COLOR_ELEMENTS.BLUE_NUMBER]; break; } case 'dropdown': { @@ -2724,85 +2737,6 @@ function showParentMaterialNameBox(number, elNumber, elString) { } } -function createProperty(propertyData, propertyElementID, propertyName, propertyID, elProperty) { - let property = { - data: propertyData, - elementID: propertyElementID, - name: propertyName, - elProperty: elProperty, - }; - let propertyType = propertyData.type; - - switch (propertyType) { - case 'string': { - property.elInput = createStringProperty(property, elProperty); - break; - } - case 'bool': { - property.elInput = createBoolProperty(property, elProperty); - break; - } - case 'number': { - property.elNumber = createNumberProperty(property, elProperty); - break; - } - case 'vec3': { - let elVec3 = createVec3Property(property, elProperty); - property.elNumberX = elVec3[VECTOR_ELEMENTS.X_NUMBER]; - property.elNumberY = elVec3[VECTOR_ELEMENTS.Y_NUMBER]; - property.elNumberZ = elVec3[VECTOR_ELEMENTS.Z_NUMBER]; - break; - } - case 'vec2': { - let elVec2 = createVec2Property(property, elProperty); - property.elNumberX = elVec2[VECTOR_ELEMENTS.X_NUMBER]; - property.elNumberY = elVec2[VECTOR_ELEMENTS.Y_NUMBER]; - break; - } - case 'color': { - let elColor = createColorProperty(property, elProperty); - property.elColorPicker = elColor[COLOR_ELEMENTS.COLOR_PICKER]; - property.elNumberR = elColor[COLOR_ELEMENTS.RED_NUMBER]; - property.elNumberG = elColor[COLOR_ELEMENTS.GREEN_NUMBER]; - property.elNumberB = elColor[COLOR_ELEMENTS.BLUE_NUMBER]; - break; - } - case 'dropdown': { - property.elInput = createDropdownProperty(property, propertyID, elProperty); - break; - } - case 'textarea': { - property.elInput = createTextareaProperty(property, elProperty); - break; - } - case 'icon': { - property.elSpan = createIconProperty(property, elProperty); - break; - } - case 'texture': { - let elTexture = createTextureProperty(property, elProperty); - property.elImage = elTexture[TEXTURE_ELEMENTS.IMAGE]; - property.elInput = elTexture[TEXTURE_ELEMENTS.TEXT_INPUT]; - break; - } - case 'buttons': { - property.elProperty = createButtonsProperty(property, elProperty); - break; - } - case 'placeholder': - case 'sub-header': { - break; - } - default: { - console.log("EntityProperties - Unknown property type " + - propertyType + " set to property " + propertyID); - break; - } - } - - return property; -} - function loaded() { openEventBridge(function() { From dfed7976826d5faf700c18ed50aaab32474fa5ad Mon Sep 17 00:00:00 2001 From: David Back Date: Wed, 14 Nov 2018 15:44:30 -0800 Subject: [PATCH 18/18] set more min/max/steps --- scripts/system/html/js/entityProperties.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index ae5748cbc8..5bb130b124 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1264,6 +1264,7 @@ const GROUPS = [ label: "Linear Velocity", type: "vec3", vec3Type: "xyz", + step: 0.1, decimals: 4, subLabels: [ "x", "y", "z" ], unit: "m/s", @@ -1272,6 +1273,9 @@ const GROUPS = [ { label: "Linear Damping", type: "number", + min: 0, + max: 1, + step: 0.01, decimals: 2, propertyID: "damping", }, @@ -1326,6 +1330,7 @@ const GROUPS = [ type: "vec3", vec3Type: "xyz", subLabels: [ "x", "y", "z" ], + step: 0.1, decimals: 4, unit: "m/s2", propertyID: "gravity",