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 bb0c6aa02c..bfd95410ce 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", }, @@ -1361,6 +1416,11 @@ var lastEntityID = null; var createAppTooltip = new CreateAppTooltip(); let currentSpaceMode = PROPERTY_SPACE_MODE.LOCAL; +function createElementFromHTML(htmlString) { + var elTemplate = document.createElement('template'); + elTemplate.innerHTML = htmlString.trim(); + return elTemplate.content.firstChild; +} /** * GENERAL PROPERTY/GROUP FUNCTIONS @@ -1433,8 +1493,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() { @@ -1491,7 +1551,6 @@ function resetProperties() { } case 'icon': { property.elSpan.style.display = "none"; - property.elLabel.innerHTML = propertyData.label; break; } case 'texture': { @@ -1692,23 +1751,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) { @@ -1718,18 +1777,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'); @@ -1737,7 +1796,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) { @@ -1751,14 +1810,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); @@ -1780,7 +1837,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) { @@ -1790,10 +1846,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"; @@ -1843,7 +1899,6 @@ function createSliderProperty(property, elProperty, elLabel) { updateProperty(property.name, sliderValue, property.isParticleProperty); }; - elDiv.appendChild(elLabel); elDiv.appendChild(elSlider); elDiv.appendChild(elInput); elProperty.appendChild(elDiv); @@ -1854,26 +1909,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, @@ -1889,19 +1941,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], @@ -1920,11 +1969,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"; @@ -1934,7 +1983,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); @@ -1950,7 +1998,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) { @@ -1980,12 +2028,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); @@ -2000,24 +2048,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); @@ -2028,35 +2069,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"); @@ -2097,9 +2138,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; @@ -2111,11 +2151,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) { @@ -2130,33 +2169,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"; @@ -2707,32 +2738,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"; @@ -2748,145 +2872,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) { @@ -2925,6 +3023,10 @@ function loaded() { resetProperties(); showGroupsForType("None"); + + let elIcon = properties.type.elSpan; + elIcon.innerText = NO_SELECTION; + elIcon.style.display = 'inline-block'; deleteJSONEditor(); getPropertyInputElement("userData").value = ""; @@ -3114,7 +3216,6 @@ function loaded() { case 'icon': { property.elSpan.innerHTML = propertyData.icons[propertyValue]; property.elSpan.style.display = "inline-block"; - property.elLabel.innerHTML = propertyValue; break; } case 'texture': { @@ -3231,34 +3332,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"]; @@ -3318,7 +3412,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"); @@ -3327,7 +3421,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