diff --git a/src/components/components/PropertyRow.js b/src/components/components/PropertyRow.js index 775c75982..fffe766d9 100644 --- a/src/components/components/PropertyRow.js +++ b/src/components/components/PropertyRow.js @@ -2,7 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; +import { faRotateLeft } from '@fortawesome/free-solid-svg-icons'; +import { AwesomeIcon } from '../AwesomeIcon'; import BooleanWidget from '../widgets/BooleanWidget'; import ColorWidget from '../widgets/ColorWidget'; import InputWidget from '../widgets/InputWidget'; @@ -36,7 +38,7 @@ export default class PropertyRow extends React.Component { this.id = props.componentname + ':' + props.name; } - getWidget() { + getType() { const props = this.props; let type = props.schema.type; @@ -57,6 +59,13 @@ export default class PropertyRow extends React.Component { type = 'boolean'; } + return type; + } + + getWidget() { + const props = this.props; + const type = this.getType(); + let value = type === 'selector' ? props.entity.getDOMAttribute(props.componentname)?.[props.name] @@ -152,18 +161,49 @@ export default class PropertyRow extends React.Component { } } + isPropertyExplicitlySet() { + const props = this.props; + if (props.isSingle) { + return props.entity.getDOMAttribute(props.componentname) !== null; + } else { + return ( + (props.entity.getDOMAttribute(props.componentname) || {})[ + props.name + ] !== undefined + ); + } + } + render() { const props = this.props; - const value = - props.schema.type === 'selector' - ? props.entity.getDOMAttribute(props.componentname)?.[props.name] - : JSON.stringify(props.data); - const title = - props.name + '\n - type: ' + props.schema.type + '\n - value: ' + value; + const type = this.getType(); + const isPropertyDefined = this.isPropertyDefined(); + const isPropertyExplicitlySet = this.isPropertyExplicitlySet(); + let title = props.name + '\n - type: ' + type; + if (type === 'number' || type === 'int') { + const schema = props.schema; + if (schema.hasOwnProperty('min') && schema.min !== -Infinity) { + title += '\n - min: ' + schema.min; + } + if (schema.hasOwnProperty('max') && schema.max !== Infinity) { + title += '\n - max: ' + schema.max; + } + } + if (!isPropertyDefined) { + if (isPropertyExplicitlySet) { + title += '\n\nexplicitly set to default value'; + } else { + title += '\n\ndefault value'; + } + } else { + title += '\n\nmodified value'; + } const className = clsx({ propertyRow: true, - propertyRowDefined: this.isPropertyDefined() + propertyRowDefined: isPropertyDefined, + propertyRowExplicitlySetToDefault: + !isPropertyDefined && isPropertyExplicitlySet }); return ( @@ -172,6 +212,22 @@ export default class PropertyRow extends React.Component { {props.name} {this.getWidget()} + {isPropertyExplicitlySet && type !== 'map' && ( + + )} ); } diff --git a/src/lib/entity.js b/src/lib/entity.js index a9904ef93..94224be69 100644 --- a/src/lib/entity.js +++ b/src/lib/entity.js @@ -250,7 +250,7 @@ function stringifyComponentValue(schema, data) { function _multi() { var propertyBag = {}; Object.keys(data).forEach(function (name) { - if (schema[name]) { + if (schema[name] && data[name] !== undefined) { propertyBag[name] = schema[name].stringify(data[name]); } }); diff --git a/src/lib/history.js b/src/lib/history.js index 4fb110d79..c1aebac95 100644 --- a/src/lib/history.js +++ b/src/lib/history.js @@ -18,13 +18,21 @@ Events.on('entityupdate', (payload) => { if (payload.property) { updates[entity.id][payload.component] = updates[entity.id][payload.component] || {}; - if (component.schema[payload.property]) { + if (value === null) { + delete updates[entity.id][payload.component][payload.property]; + } else if (component.schema[payload.property]) { value = component.schema[payload.property].stringify(payload.value); + updates[entity.id][payload.component][payload.property] = value; + } else { + updates[entity.id][payload.component][payload.property] = value; } - updates[entity.id][payload.component][payload.property] = value; } else { - value = component.schema.stringify(payload.value); - updates[entity.id][payload.component] = value; + if (value === null) { + delete updates[entity.id][payload.component]; + } else { + value = component.schema.stringify(payload.value); + updates[entity.id][payload.component] = value; + } } } }); diff --git a/src/style/components.styl b/src/style/components.styl index ad0487701..686535ada 100644 --- a/src/style/components.styl +++ b/src/style/components.styl @@ -69,11 +69,16 @@ display flex font-size 13px min-height 30px - padding 2px 15px + padding 2px 30px 2px 15px + position relative + + &:has(.vec3) + padding-right 15px .text cursor default display inline-block + flex-shrink 0 overflow hidden padding-right 10px text-overflow ellipsis @@ -112,7 +117,7 @@ input.string box-sizing border-box padding-left 8px - width 165px + width 150px input[type="text"]:focus, input.string:focus @@ -130,6 +135,25 @@ color var(--color-property-defined) font-weight 600 +.propertyRowExplicitlySetToDefault .text + font-style italic + font-weight 600 + +.propertyRow .reset-button + background none + border none + color var(--color-base-content) + cursor pointer + opacity 0.6 + padding 2px + position absolute + right 8px + top 50% + transform translateY(-50%) + + &:hover + opacity 1 + #addComponentContainer align-items center background var(--color-base-200) diff --git a/src/style/widgets.styl b/src/style/widgets.styl index 8c6df2271..9e67f9e17 100644 --- a/src/style/widgets.styl +++ b/src/style/widgets.styl @@ -2,4 +2,4 @@ .select-widget display inline-block - width 157px \ No newline at end of file + width 142px \ No newline at end of file