Skip to content

Commit afee6b6

Browse files
committed
Merge branch 'master' into dev
2 parents 7332dbb + 0c89bc9 commit afee6b6

6 files changed

Lines changed: 107 additions & 67 deletions

File tree

src/components/components/Component.js

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import PropertyRow from './PropertyRow';
66
import Collapsible from '../Collapsible';
77
import copy from 'clipboard-copy';
88
import { getComponentClipboardRepresentation } from '../../lib/entity';
9+
import { shouldShowProperty } from '../../lib/utils';
910
import Events from '../../lib/Events';
1011

1112
const isSingleProperty = AFRAME.schema.isSingleProperty;
@@ -93,30 +94,7 @@ export default class Component extends React.Component {
9394

9495
return Object.keys(componentData.schema)
9596
.sort()
96-
.filter((propertyName) => {
97-
if (!componentData.schema[propertyName].if) {
98-
return true;
99-
}
100-
let showProperty = true;
101-
for (const [conditionKey, conditionValue] of Object.entries(
102-
componentData.schema[propertyName].if
103-
)) {
104-
if (Array.isArray(conditionValue)) {
105-
if (
106-
conditionValue.indexOf(componentData.data[conditionKey]) === -1
107-
) {
108-
showProperty = false;
109-
break;
110-
}
111-
} else {
112-
if (conditionValue !== componentData.data[conditionKey]) {
113-
showProperty = false;
114-
break;
115-
}
116-
}
117-
}
118-
return showProperty;
119-
})
97+
.filter((propertyName) => shouldShowProperty(propertyName, componentData))
12098
.map((propertyName) => (
12199
<PropertyRow
122100
key={propertyName}
@@ -131,21 +109,13 @@ export default class Component extends React.Component {
131109
};
132110

133111
render() {
134-
let componentName = this.props.name;
135-
let subComponentName = '';
136-
if (componentName.indexOf('__') !== -1) {
137-
subComponentName = componentName;
138-
componentName = componentName.substr(0, componentName.indexOf('__'));
139-
}
112+
const componentName = this.props.name;
140113

141114
return (
142115
<Collapsible collapsed={this.props.isCollapsed}>
143116
<div className="componentHeader collapsible-header">
144-
<span
145-
className="componentTitle"
146-
title={subComponentName || componentName}
147-
>
148-
<span>{subComponentName || componentName}</span>
117+
<span className="componentTitle" title={componentName}>
118+
<span>{componentName}</span>
149119
</span>
150120
<div className="componentHeaderActions">
151121
<a
@@ -157,7 +127,7 @@ export default class Component extends React.Component {
157127
copy(
158128
getComponentClipboardRepresentation(
159129
this.state.entity,
160-
(subComponentName || componentName).toLowerCase()
130+
componentName.toLowerCase()
161131
)
162132
);
163133
}}

src/components/components/PropertyRow.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import TextureWidget from '../widgets/TextureWidget';
1212
import Vec4Widget from '../widgets/Vec4Widget';
1313
import Vec3Widget from '../widgets/Vec3Widget';
1414
import Vec2Widget from '../widgets/Vec2Widget';
15+
import { equal } from '../../lib/utils';
1516

1617
export default class PropertyRow extends React.Component {
1718
static propTypes = {
@@ -128,6 +129,30 @@ export default class PropertyRow extends React.Component {
128129
}
129130
}
130131

132+
isPropertyDefined() {
133+
const props = this.props;
134+
let definedValue;
135+
let defaultValue;
136+
// getDOMAttribute returns null if the component doesn't exist, and
137+
// in the case of a multi-properties component it returns undefined
138+
// if it exists but has the default values.
139+
if (props.isSingle) {
140+
definedValue = props.entity.getDOMAttribute(props.componentname);
141+
if (definedValue === null) return false;
142+
defaultValue =
143+
props.entity.components[props.componentname].schema.default;
144+
return !equal(definedValue, defaultValue);
145+
} else {
146+
definedValue = (props.entity.getDOMAttribute(props.componentname) || {})[
147+
props.name
148+
];
149+
if (definedValue === undefined) return false;
150+
defaultValue =
151+
props.entity.components[props.componentname].schema[props.name].default;
152+
return !equal(definedValue, defaultValue);
153+
}
154+
}
155+
131156
render() {
132157
const props = this.props;
133158
const value =
@@ -139,10 +164,7 @@ export default class PropertyRow extends React.Component {
139164

140165
const className = clsx({
141166
propertyRow: true,
142-
propertyRowDefined: props.isSingle
143-
? !!props.entity.getDOMAttribute(props.componentname)
144-
: props.name in
145-
(props.entity.getDOMAttribute(props.componentname) || {})
167+
propertyRowDefined: this.isPropertyDefined()
146168
});
147169

148170
return (

src/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ Inspector.prototype = {
297297

298298
/**
299299
* Closes the editor and gives the control back to the scene
300-
* @return {[type]} [description]
301300
*/
302301
close: function () {
303302
this.opened = false;

src/lib/entity.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ export function updateEntity(entity, component, property, value) {
3636
* Remove an entity.
3737
*
3838
* @param {Element} entity Entity to remove.
39-
* @param {boolean} force (Optional) If true it won't ask for confirmation.
39+
* @param {boolean} [force=false] If true it won't ask for confirmation.
4040
*/
41-
export function removeEntity(entity, force) {
41+
export function removeEntity(entity, force = false) {
4242
if (entity) {
4343
if (
4444
force === true ||
@@ -80,9 +80,9 @@ export function findClosestEntity(entity) {
8080

8181
/**
8282
* Remove the selected entity
83-
* @param {boolean} force (Optional) If true it won't ask for confirmation
83+
* @param {boolean} [force=false] If true it won't ask for confirmation.
8484
*/
85-
export function removeSelectedEntity(force) {
85+
export function removeSelectedEntity(force = false) {
8686
if (AFRAME.INSPECTOR.selectedEntity) {
8787
removeEntity(AFRAME.INSPECTOR.selectedEntity, force);
8888
}
@@ -640,14 +640,27 @@ export function createUniqueId() {
640640

641641
export function getComponentClipboardRepresentation(entity, componentName) {
642642
entity.flushToDOM();
643-
const data = entity.getDOMAttribute(componentName);
643+
let data = entity.getDOMAttribute(componentName);
644644
if (!data) {
645645
return componentName;
646646
}
647647

648-
const schema = entity.components[componentName].schema;
649-
const attributes = stringifyComponentValue(schema, data);
650-
return `${componentName}="${attributes}"`;
648+
const component = entity.components[componentName];
649+
const schema = component.schema;
650+
// If multi-properties component, filter out properties that are the same as their default value
651+
if (!isSingleProperty(schema)) {
652+
data = { ...data };
653+
654+
for (const [propertyName, value] of Object.entries(data)) {
655+
const defaultValue = getDefaultValue(component, propertyName);
656+
if (equal(value, defaultValue)) {
657+
delete data[propertyName];
658+
}
659+
}
660+
}
661+
662+
const properties = stringifyComponentValue(schema, data);
663+
return `${componentName}="${properties}"`;
651664
}
652665

653666
const NOT_COMPONENTS = ['id', 'class', 'mixin'];

src/lib/utils.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,44 @@ export function areVectorsEqual(v1, v2) {
103103
Object.is(v1.w, v2.w)
104104
);
105105
}
106+
107+
/**
108+
* Check if a property should be shown in the UI based on the `if` object
109+
* condition included in the schema for the property.
110+
*
111+
* When more than one property is used in the object, this applies a logical AND.
112+
* When the value is an array, it means one of the entries in this array.
113+
*
114+
* Example in the light component:
115+
* ```js
116+
* {
117+
* penumbra: {default: 0, min: 0, max: 1, if: {type: ['spot']}},
118+
* }
119+
* ```
120+
*
121+
* @param {string} propertyName - The name of the property
122+
* @param {Component} component - The component instance
123+
* @returns {boolean} Whether the property should be shown
124+
*/
125+
export function shouldShowProperty(propertyName, component) {
126+
if (!component.schema[propertyName].if) {
127+
return true;
128+
}
129+
let showProperty = true;
130+
for (const [conditionKey, conditionValue] of Object.entries(
131+
component.schema[propertyName].if
132+
)) {
133+
if (Array.isArray(conditionValue)) {
134+
if (conditionValue.indexOf(component.data[conditionKey]) === -1) {
135+
showProperty = false;
136+
break;
137+
}
138+
} else {
139+
if (conditionValue !== component.data[conditionKey]) {
140+
showProperty = false;
141+
break;
142+
}
143+
}
144+
}
145+
return showProperty;
146+
}

src/style/components.styl

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
@import './lib';
22

3-
propertyRowDefined() {
4-
.propertyRowDefined {
5-
{block}
6-
}
7-
}
8-
93
.components
104
background-color $bg
115
color $white
@@ -14,18 +8,6 @@ propertyRowDefined() {
148
position fixed
159
width 331px
1610

17-
div.vec2,
18-
div.vec3,
19-
div.vec4
20-
display inline
21-
22-
.vec2 input.number,
23-
.vec3 input.number
24-
width 40px
25-
26-
.vec4 input.number
27-
width 34px
28-
2911
.collapsible-header
3012
align-items center
3113
display flex
@@ -112,6 +94,19 @@ div.vec4
11294
vertical-align middle
11395
width 118px
11496

97+
input.number
98+
width 40px
99+
100+
.vec2 input.number,
101+
.vec3 input.number
102+
width 40px
103+
104+
.vec4 input.number
105+
width 34px
106+
107+
.vec2, .vec3, vec4
108+
display inline
109+
115110
.map_value
116111
margin 0 0 0 5px
117112
width 68px

0 commit comments

Comments
 (0)