From 73feeb3fce13485a4697cc6671fc6a4f6395ecd1 Mon Sep 17 00:00:00 2001 From: Lizard-13 Date: Mon, 24 Dec 2018 12:57:20 -0300 Subject: [PATCH 01/11] Physics main editor setup and custom polygon support --- Extensions/Physics2Behavior/JsExtension.js | 90 +++--- .../physics2runtimebehavior.js | 67 ++++- .../Editors/Physics2Editor/PolygonEditor.js | 11 + .../Editors/Physics2Editor/index.js | 267 ++++++++++++++++++ newIDE/app/src/BehaviorsEditor/index.js | 1 + .../PropertiesEditor/PropertiesMapToSchema.js | 5 + .../PropertiesRenderingService.js | 14 + newIDE/app/src/PropertiesEditor/index.js | 28 ++ 8 files changed, 432 insertions(+), 51 deletions(-) create mode 100644 newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js create mode 100644 newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js create mode 100644 newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js diff --git a/Extensions/Physics2Behavior/JsExtension.js b/Extensions/Physics2Behavior/JsExtension.js index 683333dab207..18b1a196b70a 100644 --- a/Extensions/Physics2Behavior/JsExtension.js +++ b/Extensions/Physics2Behavior/JsExtension.js @@ -67,6 +67,14 @@ module.exports = { behaviorContent.shapeOffsetY = parseFloat(newValue); return true; } + if (propertyName === 'polygonOrigin') { + behaviorContent.polygonOrigin = newValue; + return true; + } + if (propertyName === 'vertices') { + behaviorContent.vertices = JSON.parse(newValue); + return true; + } if (propertyName === 'density') { newValue = parseFloat(newValue); if (newValue < 0) newValue = 0; @@ -98,41 +106,23 @@ module.exports = { return true; } if (propertyName === 'layers') { - // The given binary string is reverse, fix it - newValue = newValue - .split('') - .reverse() - .join(''); - // Convert it into a decimal - newValue = parseInt(newValue, 2); - // If it can't be converted, cancel the edit - if (isNaN(newValue)) return false; - // Layers minimum and maximum values - if (newValue < 0) newValue = 0; - if (newValue > 65535) newValue = 65535; // 65535 is the decimal form of 1111111111111111 (16 layer bits flagged) - // Save the valid decimal - behaviorContent.layers = newValue; + behaviorContent.layers = parseInt(newValue); return true; } if (propertyName === 'masks') { - // Same than layers - newValue = newValue - .split('') - .reverse() - .join(''); - newValue = parseInt(newValue, 2); - if (isNaN(newValue)) return false; - if (newValue < 0) newValue = 0; - if (newValue > 65535) newValue = 65535; - behaviorContent.masks = newValue; + behaviorContent.masks = parseInt(newValue); return true; } - - return false; }; physics2Behavior.getProperties = function(behaviorContent) { var behaviorProperties = new gd.MapStringPropertyDescriptor(); + behaviorProperties.set( + 'dialog', + new gd.PropertyDescriptor(behaviorContent.type) + .setType('Dialog') + .addExtraInfo('physics2') + ); behaviorProperties.set( 'type', new gd.PropertyDescriptor(behaviorContent.type) @@ -169,8 +159,8 @@ module.exports = { .setLabel('Shape') .addExtraInfo('Box') .addExtraInfo('Circle') - // .addExtraInfo("Polygon") Needs an editor to be useful .addExtraInfo('Edge') + .addExtraInfo("Polygon") ); behaviorProperties.set( 'shapeDimensionA', @@ -196,6 +186,20 @@ module.exports = { .setType('Number') .setLabel('Shape Offset Y') ); + behaviorProperties.set( + 'polygonOrigin', + new gd.PropertyDescriptor(behaviorContent.polygonOrigin || "Center") + .setType('Choice') + .setLabel('Polygon Origin') + .addExtraInfo('Center') + .addExtraInfo('Origin') + .addExtraInfo('TopLeft') + ); + behaviorProperties.set( + 'vertices', + new gd.PropertyDescriptor(JSON.stringify(behaviorContent.vertices || [])) + .setLabel('Vertices') + ); behaviorProperties.set( 'density', new gd.PropertyDescriptor(behaviorContent.density.toString(10)) @@ -232,38 +236,22 @@ module.exports = { .setType('Number') .setLabel('Gravity Scale') ); - - // Waiting for a layers/masks editor - /* - // Transform the layers number into a binary string - var layers = behaviorContent.layers.toString(2); - // Reverse the string (so the first layer bit is shown at the left) - layers = layers - .split('') - .reverse() - .join(''); - // Add zeros until the total size is 16 - if (layers.length < 16) layers = layers + '0'.repeat(16 - layers.length); - // Expose the converted string behaviorProperties.set( 'layers', - new gd.PropertyDescriptor(layers).setLabel('Layers') + new gd.PropertyDescriptor(behaviorContent.layers.toString(10)) + .setType('Number') + .setLabel('Layers') ); - // Same than layers - var masks = behaviorContent.masks.toString(2); - masks = masks - .split('') - .reverse() - .join(''); - if (masks.length < 16) masks = masks + '0'.repeat(16 - masks.length); behaviorProperties.set( 'masks', - new gd.PropertyDescriptor(masks).setLabel('Masks') + new gd.PropertyDescriptor(behaviorContent.masks.toString(10)) + .setType('Number') + .setLabel('Masks') ); - */ return behaviorProperties; }; + physics2Behavior.setRawJSONContent( JSON.stringify({ type: 'Dynamic', @@ -275,6 +263,8 @@ module.exports = { shapeDimensionB: 0, shapeOffsetX: 0, shapeOffsetY: 0, + polygonOrigin: "Center", + vertices: [], density: 1.0, friction: 0.3, restitution: 0.1, diff --git a/Extensions/Physics2Behavior/physics2runtimebehavior.js b/Extensions/Physics2Behavior/physics2runtimebehavior.js index dd3f3ed01439..5fc4b040122b 100644 --- a/Extensions/Physics2Behavior/physics2runtimebehavior.js +++ b/Extensions/Physics2Behavior/physics2runtimebehavior.js @@ -203,6 +203,8 @@ gdjs.Physics2RuntimeBehavior = function(runtimeScene, behaviorData, owner) { this.shapeDimensionB = behaviorData.content.shapeDimensionB; this.shapeOffsetX = behaviorData.content.shapeOffsetX; this.shapeOffsetY = behaviorData.content.shapeOffsetY; + this.polygonOrigin = behaviorData.content.polygonOrigin; + this.polygon = this.getPolygon(behaviorData.content.vertices); this.density = behaviorData.content.density; this.friction = behaviorData.content.friction; this.restitution = behaviorData.content.restitution; @@ -227,6 +229,7 @@ gdjs.Physics2RuntimeBehavior = function(runtimeScene, behaviorData, owner) { this._objectOldAngle = 0; this._objectOldWidth = 0; this._objectOldHeight = 0; + this._verticesBuffer = 0; // Stores a Box2D pointer of created vertices }; gdjs.Physics2RuntimeBehavior.prototype = Object.create( @@ -251,6 +254,11 @@ gdjs.Physics2RuntimeBehavior.prototype.onDeActivate = function() { if (this._body !== null) { // When a body is deleted, Box2D removes automatically its joints, leaving an invalid pointer in our joints list this._sharedData.clearBodyJoints(this._body); + // Delete the vertices + if (this._verticesBuffer) { + Box2D._free(this._verticesBuffer); + this._verticesBuffer = 0; + } // Delete the body this._sharedData.world.DestroyBody(this._body); this._body = null; @@ -261,6 +269,15 @@ gdjs.Physics2RuntimeBehavior.prototype.ownerRemovedFromScene = function() { this.onDeActivate(); }; +gdjs.Physics2RuntimeBehavior.prototype.getPolygon = function(verticesData) { + var polygon = new gdjs.Polygon(); + var maxVertices = 8; + for (var i = 0, len = verticesData.length; i < Math.min(len, maxVertices); i++) { + polygon.vertices.push([verticesData[i].x, verticesData[i].y]); + } + return polygon; +}; + gdjs.Physics2RuntimeBehavior.prototype.createShape = function() { // Get the scaled offset var offsetX = this.shapeOffsetX @@ -290,7 +307,55 @@ gdjs.Physics2RuntimeBehavior.prototype.createShape = function() { // Set the offset shape.set_m_p(this.b2Vec2(offsetX, offsetY)); } else if (this.shape === 'Polygon') { - // Needs a vertices editor + shape = new Box2D.b2PolygonShape(); + // Not convex, fall back to a box + if (!this.polygon.isConvex()) { + var width = + (this.owner.getWidth() > 0 ? this.owner.getWidth() : 1) * + this._sharedData.invScaleX; + var height = + (this.owner.getHeight() > 0 ? this.owner.getHeight() : 1) * + this._sharedData.invScaleY; + // Set the shape box + shape.SetAsBox(width / 2, height / 2, this.b2Vec2(offsetX, offsetY), 0); + } else { + var originOffsetX = 0; + var originOffsetY = 0; + if(this.polygonOrigin === "Origin"){ + originOffsetX = (this.owner.getWidth() > 0 ? -this.owner.getWidth()/2 : 0) + + (this.owner.getX() - this.owner.getDrawableX()); + originOffsetY = (this.owner.getHeight() > 0 ? -this.owner.getHeight()/2 : 0) + + (this.owner.getY() - this.owner.getDrawableY()); + } + else if(this.polygonOrigin === "TopLeft"){ + originOffsetX = this.owner.getWidth() > 0 ? -this.owner.getWidth()/2 : 0; + originOffsetY = this.owner.getHeight() > 0 ? -this.owner.getHeight()/2 : 0; + } + // Generate vertices if not done already + if (!this._verticesBuffer) { + // Store the vertices using a memory allocation function + var buffer = Box2D._malloc( + this.polygon.vertices.length * 8, + 'float', + Box2D.ALLOC_STACK + ); + this._verticesBuffer = buffer; + } + // Overwrite the vertices stored in the buffer + var offset = 0; + for (var i = 0, len = this.polygon.vertices.length; i < len; i++) { + Box2D.HEAPF32[(this._verticesBuffer + offset) >> 2] = + (this.polygon.vertices[i][0] * this.shapeScale + originOffsetX) * this._sharedData.invScaleX + + offsetX; + Box2D.HEAPF32[(this._verticesBuffer + (offset + 4)) >> 2] = + (this.polygon.vertices[i][1] * this.shapeScale + originOffsetY) * this._sharedData.invScaleY + + offsetY; + offset += 8; + } + // Set the shape vertices + var b2Vertices = Box2D.wrapPointer(this._verticesBuffer, Box2D.b2Vec2); + shape.Set(b2Vertices, this.polygon.vertices.length); + } } else if (this.shape === 'Edge') { shape = new Box2D.b2EdgeShape(); // Length from the custom dimension or from the object width diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js new file mode 100644 index 000000000000..3d9840af62ec --- /dev/null +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js @@ -0,0 +1,11 @@ +// @flow +import * as React from 'react'; +import Checkbox from 'material-ui/Checkbox'; + +type Props = {||}; + +export default class PolygonEditor extends React.Component { + render() { + return ; + } +} diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js new file mode 100644 index 000000000000..078403ebfe0c --- /dev/null +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js @@ -0,0 +1,267 @@ +// @flow +import * as React from 'react'; +import { Line, Column } from '../../../UI/Grid'; +import Checkbox from 'material-ui/Checkbox'; +import SelectField from 'material-ui/SelectField'; +import MenuItem from 'material-ui/MenuItem'; +import SemiControlledTextField from '../../../UI/SemiControlledTextField'; +import PolygonEditor from './PolygonEditor.js'; + +type Props = {| + behavior: Object, + project: Object, +|}; + +export default class Physics2Editor extends React.Component { + _isBitEnabled(bitsValue: number, i: number) { + return !!(bitsValue & (1 << i)); + } + + _enableBit(bitsValue: number, i: number, enable: boolean) { + if (enable) bitsValue |= 1 << i; + else bitsValue &= ~(1 << i); + return bitsValue; + } + + renderBitProperty( + properties: Object, + isLayer: boolean, + pos: number, + spacing: boolean + ) { + const { behavior, project } = this.props; + const bitValues = parseInt( + properties.get(isLayer ? 'layers' : 'masks').getValue(), + 10 + ); + + return ( +
+ { + { + const newValue = this._enableBit(bitValues, pos, checked); + this.props.behavior.updateProperty( + isLayer ? 'layers' : 'masks', + newValue.toString(10), + this.props.project + ); + this.forceUpdate(); + }} + /> + } + {spacing && ( +
+ )} +
+ ); + } + + renderNumericProperty(properties: Object, name: string) { + return ( + { + this.props.behavior.updateProperty( + name, + newValue, + this.props.project + ); + this.forceUpdate(); + }} + type="number" + /> + ); + } + + render() { + const { behavior, project } = this.props; + const properties = behavior.getProperties(project); + const bits = Array(16).fill(null); + + return ( + + + { + behavior.updateProperty('type', newValue, project); + this.forceUpdate(); + }} + > + {[ + , + , + , + ]} + + + +
+ { + behavior.updateProperty('bullet', checked ? '1' : '0', project); + this.forceUpdate(); + }} + /> +
+
+ { + behavior.updateProperty( + 'fixedRotation', + checked ? '1' : '0', + project + ); + this.forceUpdate(); + }} + /> +
+
+ { + behavior.updateProperty( + 'canSleep', + checked ? '1' : '0', + project + ); + this.forceUpdate(); + }} + /> +
+
+ + { + behavior.updateProperty('shape', newValue, project); + this.forceUpdate(); + }} + > + {[ + , + , + , + , + ]} + + + + { + behavior.updateProperty('shapeDimensionA', newValue, project); + this.forceUpdate(); + }} + type="number" + /> + { + behavior.updateProperty('shapeDimensionB', newValue, project); + this.forceUpdate(); + }} + type="number" + /> + {this.renderNumericProperty(properties, 'shapeOffsetX')} + {this.renderNumericProperty(properties, 'shapeOffsetY')} + + + + + +
+ {this.renderNumericProperty(properties, 'density')} +
+
+ {this.renderNumericProperty(properties, 'gravityScale')} +
+
+ +
+ {this.renderNumericProperty(properties, 'friction')} +
+
+ {this.renderNumericProperty(properties, 'restitution')} +
+
+ +
+ {this.renderNumericProperty(properties, 'linearDamping')} +
+
+ {this.renderNumericProperty(properties, 'angularDamping')} +
+
+ + + {bits.map((value, index) => { + return this.renderBitProperty(properties, true, index, index === 7); + })} + + + + {bits.map((value, index) => { + return this.renderBitProperty( + properties, + false, + index, + index === 7 + ); + })} + +
+ ); + } +} diff --git a/newIDE/app/src/BehaviorsEditor/index.js b/newIDE/app/src/BehaviorsEditor/index.js index d527dc5728c7..e57241912bd2 100644 --- a/newIDE/app/src/BehaviorsEditor/index.js +++ b/newIDE/app/src/BehaviorsEditor/index.js @@ -182,6 +182,7 @@ export default class BehaviorsEditor extends Component { ) : ( diff --git a/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js b/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js index 0708e55b4e88..25030f1683bb 100644 --- a/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js +++ b/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js @@ -1,6 +1,7 @@ // @flow import { mapFor } from '../Utils/MapFor'; import { type Schema, type Instance } from '.'; +import PropertiesRenderingService from './PropertiesRenderingService'; /** * Transform a MapStringPropertyDescriptor to a schema that can be used in PropertiesEditor. @@ -27,11 +28,15 @@ export default ( .getExtraInfo() .toJSArray() .map(value => ({ value, label: value })); + const dialog = PropertiesRenderingService.getDialogComponent( + property.getExtraInfo().toJSArray()[0] + ); return { name, valueType, getChoices: valueType === 'choice' ? () => choices : undefined, + getDialog: valueType === 'dialog' ? () => dialog : undefined, getValue: instance => { // Instance custom properties are always stored as string, cast them if necessary const rawValue = getProperties(instance) diff --git a/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js b/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js new file mode 100644 index 000000000000..7df3a6c1c3f7 --- /dev/null +++ b/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js @@ -0,0 +1,14 @@ +// @flow +import Physics2Editor from '../BehaviorsEditor/Editors/Physics2Editor'; + +const components = { + physics2: Physics2Editor, +}; + +export default { + components, + getDialogComponent: (type: string) => { + if (components.hasOwnProperty(type)) return components[type]; + else return null; + }, +}; diff --git a/newIDE/app/src/PropertiesEditor/index.js b/newIDE/app/src/PropertiesEditor/index.js index 0979c1514a6c..5563c82c0c43 100644 --- a/newIDE/app/src/PropertiesEditor/index.js +++ b/newIDE/app/src/PropertiesEditor/index.js @@ -13,12 +13,14 @@ export type Instance = Object; // This could be improved using generics. export type Instances = Array; export type Field = Object; export type Schema = Array; +export type Project = Object; type Props = {| onInstancesModified?: Instances => void, instances: Instances, schema: Schema, mode?: 'column' | 'row', + project?: Project, |}; const styles = { @@ -225,9 +227,35 @@ export default class PropertiesEditor extends React.Component { ); }; + _renderDialog = (field: Field) => { + const EditorComponent = field.getDialog(); + + return ( + + ); + }; + render() { const { mode } = this.props; + for (var i = 0, len = this.props.schema.length; i < len; i++) { + if (this.props.schema[i].getDialog) { + return ( +
+ {this._renderDialog(this.props.schema[i])} +
+ ); + } + } + return (
Date: Fri, 28 Dec 2018 14:51:00 -0300 Subject: [PATCH 02/11] Add shape preview * Dynamic dimension labels in function of the shape * Preview box, circle and edge * Prevent invalid properties values --- Extensions/Physics2Behavior/JsExtension.js | 67 +++-- .../Editors/Physics2Editor/PolygonEditor.js | 13 +- .../Editors/Physics2Editor/ShapePreview.js | 76 ++++++ .../Editors/Physics2Editor/index.js | 237 +++++++++++++++--- newIDE/app/src/BehaviorsEditor/index.js | 3 + .../src/ObjectEditor/ObjectEditorDialog.js | 3 + .../PropertiesEditor/PropertiesMapToSchema.js | 8 +- .../PropertiesRenderingService.js | 11 +- newIDE/app/src/PropertiesEditor/index.js | 12 + 9 files changed, 359 insertions(+), 71 deletions(-) create mode 100644 newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js diff --git a/Extensions/Physics2Behavior/JsExtension.js b/Extensions/Physics2Behavior/JsExtension.js index 18b1a196b70a..b7af04927012 100644 --- a/Extensions/Physics2Behavior/JsExtension.js +++ b/Extensions/Physics2Behavior/JsExtension.js @@ -49,22 +49,26 @@ module.exports = { } if (propertyName === 'shapeDimensionA') { newValue = parseFloat(newValue); - if (newValue < 0) newValue = 0; + if (newValue !== newValue) return false; behaviorContent.shapeDimensionA = newValue; return true; } if (propertyName === 'shapeDimensionB') { newValue = parseFloat(newValue); - if (newValue < 0) newValue = 0; + if (newValue !== newValue) return false; behaviorContent.shapeDimensionB = newValue; return true; } if (propertyName === 'shapeOffsetX') { - behaviorContent.shapeOffsetX = parseFloat(newValue); + newValue = parseFloat(newValue); + if (newValue !== newValue) return false; + behaviorContent.shapeOffsetX = newValue; return true; } if (propertyName === 'shapeOffsetY') { - behaviorContent.shapeOffsetY = parseFloat(newValue); + newValue = parseFloat(newValue); + if (newValue !== newValue) return false; + behaviorContent.shapeOffsetY = newValue; return true; } if (propertyName === 'polygonOrigin') { @@ -76,33 +80,37 @@ module.exports = { return true; } if (propertyName === 'density') { - newValue = parseFloat(newValue); - if (newValue < 0) newValue = 0; - behaviorContent.density = newValue; + behaviorContent.density = parseFloat(newValue); return true; } if (propertyName === 'friction') { newValue = parseFloat(newValue); - if (newValue < 0) newValue = 0; + if (newValue !== newValue) return false; behaviorContent.friction = newValue; return true; } if (propertyName === 'restitution') { newValue = parseFloat(newValue); - if (newValue < 0) newValue = 0; + if (newValue !== newValue) return false; behaviorContent.restitution = newValue; return true; } if (propertyName === 'linearDamping') { - behaviorContent.linearDamping = parseFloat(newValue); + newValue = parseFloat(newValue); + if (newValue !== newValue) return false; + behaviorContent.linearDamping = newValue; return true; } if (propertyName === 'angularDamping') { - behaviorContent.angularDamping = parseFloat(newValue); + newValue = parseFloat(newValue); + if (newValue !== newValue) return false; + behaviorContent.angularDamping = newValue; return true; } if (propertyName === 'gravityScale') { - behaviorContent.gravityScale = parseFloat(newValue); + newValue = parseFloat(newValue); + if (newValue !== newValue) return false; + behaviorContent.gravityScale = newValue; return true; } if (propertyName === 'layers') { @@ -160,7 +168,7 @@ module.exports = { .addExtraInfo('Box') .addExtraInfo('Circle') .addExtraInfo('Edge') - .addExtraInfo("Polygon") + .addExtraInfo('Polygon') ); behaviorProperties.set( 'shapeDimensionA', @@ -188,7 +196,7 @@ module.exports = { ); behaviorProperties.set( 'polygonOrigin', - new gd.PropertyDescriptor(behaviorContent.polygonOrigin || "Center") + new gd.PropertyDescriptor(behaviorContent.polygonOrigin || 'Center') .setType('Choice') .setLabel('Polygon Origin') .addExtraInfo('Center') @@ -197,8 +205,9 @@ module.exports = { ); behaviorProperties.set( 'vertices', - new gd.PropertyDescriptor(JSON.stringify(behaviorContent.vertices || [])) - .setLabel('Vertices') + new gd.PropertyDescriptor( + JSON.stringify(behaviorContent.vertices || []) + ).setLabel('Vertices') ); behaviorProperties.set( 'density', @@ -239,14 +248,14 @@ module.exports = { behaviorProperties.set( 'layers', new gd.PropertyDescriptor(behaviorContent.layers.toString(10)) - .setType('Number') - .setLabel('Layers') + .setType('Number') + .setLabel('Layers') ); behaviorProperties.set( 'masks', new gd.PropertyDescriptor(behaviorContent.masks.toString(10)) - .setType('Number') - .setLabel('Masks') + .setType('Number') + .setLabel('Masks') ); return behaviorProperties; @@ -263,7 +272,7 @@ module.exports = { shapeDimensionB: 0, shapeOffsetX: 0, shapeOffsetY: 0, - polygonOrigin: "Center", + polygonOrigin: 'Center', vertices: [], density: 1.0, friction: 0.3, @@ -283,23 +292,27 @@ module.exports = { newValue ) { if (propertyName === 'gravityX') { - sharedContent.gravityX = parseInt(newValue, 10); + newValue = parseFloat(newValue); + if (newValue !== newValue) return false; + behaviorContent.gravityX = newValue; return true; } if (propertyName === 'gravityY') { - sharedContent.gravityY = parseInt(newValue, 10); + newValue = parseFloat(newValue); + if (newValue !== newValue) return false; + behaviorContent.gravityY = newValue; return true; } if (propertyName === 'scaleX') { newValue = parseInt(newValue, 10); - if (newValue <= 0) newValue = 1; - sharedContent.scaleX = newValue; + if (newValue !== newValue) return false; + behaviorContent.scaleX = newValue; return true; } if (propertyName === 'scaleY') { newValue = parseInt(newValue, 10); - if (newValue <= 0) newValue = 1; - sharedContent.scaleY = newValue; + if (newValue !== newValue) return false; + behaviorContent.scaleY = newValue; return true; } diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js index 3d9840af62ec..36255ffc1cd3 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js @@ -1,11 +1,18 @@ // @flow import * as React from 'react'; -import Checkbox from 'material-ui/Checkbox'; +import { Line } from '../../../UI/Grid'; -type Props = {||}; +type Vertice = { + x: number, + y: number, +}; + +type Props = {| + vertices: Array, +|}; export default class PolygonEditor extends React.Component { render() { - return ; + return ; } } diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js new file mode 100644 index 000000000000..5e5247682244 --- /dev/null +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js @@ -0,0 +1,76 @@ +// @flow +import * as React from 'react'; + +type Vertice = { + x: number, + y: number, +}; + +type Props = {| + shape: string, + dimensionA: number, + dimensionB: number, + offsetX: number, + offsetY: number, + polygonOrigin: string, + vertices: Array, + width: number, + height: number, +|}; + +type State = {| + image: string, +|}; + +export default class ShapePreview extends React.Component { + + render() { + + const {dimensionA, dimensionB, shape, offsetX, offsetY, width, height} = this.props; + const fixedWidth = dimensionA > 0 ? dimensionA : width > 0 ? width : 1; + const fixedHeight = dimensionB > 0 ? dimensionB : height > 0 ? height : 1; + + return ( +
+ {shape === 'Box' && ( + + + + )} + {shape === 'Circle' && ( + + 0 ? dimensionA : (width + height) > 0 ? (width + height) / 4 : 1} + /> + + )} + {shape === 'Edge' && ( + + + + )} +
+ ); + } +} diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js index 078403ebfe0c..44b667cdbdf1 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js @@ -5,14 +5,54 @@ import Checkbox from 'material-ui/Checkbox'; import SelectField from 'material-ui/SelectField'; import MenuItem from 'material-ui/MenuItem'; import SemiControlledTextField from '../../../UI/SemiControlledTextField'; +import ImagePreview from '../../../ResourcesList/ResourcePreview/ImagePreview'; +import ResourceSelector from '../../../ResourcesList/ResourceSelector'; +import ResourcesLoader from '../../../ResourcesLoader'; +import ShapePreview from './ShapePreview.js'; import PolygonEditor from './PolygonEditor.js'; +import { + type ResourceSource, + type ChooseResourceFunction, +} from '../../../ResourcesList/ResourceSource.flow'; +import { type ResourceExternalEditor } from '../../../ResourcesList/ResourceExternalEditor.flow'; type Props = {| behavior: Object, project: Object, + resourceSources: Array, + onChooseResource: ChooseResourceFunction, + resourceExternalEditors: Array, |}; -export default class Physics2Editor extends React.Component { +type State = {| + image: string, + imageWidth: number, + imageHeight: number, +|}; + +export default class Physics2Editor extends React.Component { + + resourcesLoader: typeof ResourcesLoader; + + constructor(props: Props) { + super(props); + + this.resourcesLoader = ResourcesLoader; + + this.state = { + image: '', + imageWidth: 9, + imageHeight: 0, + }; + } + + _setImageSize = (width: number, height: number) => { + this.setState({ + imageWidth: width, + imageHeight: height, + }); + } + _isBitEnabled(bitsValue: number, i: number) { return !!(bitsValue & (1 << i)); } @@ -29,7 +69,6 @@ export default class Physics2Editor extends React.Component { pos: number, spacing: boolean ) { - const { behavior, project } = this.props; const bitValues = parseInt( properties.get(isLayer ? 'layers' : 'masks').getValue(), 10 @@ -64,13 +103,21 @@ export default class Physics2Editor extends React.Component { ); } - renderNumericProperty(properties: Object, name: string) { + renderNumericProperty( + properties: Object, + name: string, + limit: boolean, + min: number, + step: number + ) { return ( { this.props.behavior.updateProperty( name, @@ -88,6 +135,7 @@ export default class Physics2Editor extends React.Component { const { behavior, project } = this.props; const properties = behavior.getProperties(project); const bits = Array(16).fill(null); + const shape = properties.get('shape').getValue(); return ( @@ -188,56 +236,177 @@ export default class Physics2Editor extends React.Component {
- { - behavior.updateProperty('shapeDimensionA', newValue, project); - this.forceUpdate(); - }} - type="number" - /> - { - behavior.updateProperty('shapeDimensionB', newValue, project); - this.forceUpdate(); - }} - type="number" - /> - {this.renderNumericProperty(properties, 'shapeOffsetX')} - {this.renderNumericProperty(properties, 'shapeOffsetY')} + {shape !== 'Polygon' && ( + { + behavior.updateProperty( + shape === 'Polygon' ? 'PolygonOriginX' : 'shapeDimensionA', + newValue, + project + ); + this.forceUpdate(); + }} + type="number" + /> + )} + {shape !== 'Polygon' && shape !== 'Circle' && ( + { + behavior.updateProperty( + shape === 'Polygon' ? 'PolygonOriginY' : 'shapeDimensionB', + newValue, + project + ); + this.forceUpdate(); + }} + type="number" + /> + )} + {shape === 'Polygon' && ( + { + behavior.updateProperty('polygonOrigin', newValue, project); + this.forceUpdate(); + }} + > + {[ + , + , + , + ]} + + )} + {this.renderNumericProperty(properties, 'shapeOffsetX', false, 0, 1)} + {this.renderNumericProperty(properties, 'shapeOffsetY', false, 0, 1)} - + + +
+ + + +
+
+ + { + this.setState({ image: resourceName }); + this.forceUpdate(); + }} + /> + +
+ {shape === 'Polygon' && ( + + )}
- {this.renderNumericProperty(properties, 'density')} + {this.renderNumericProperty(properties, 'density', true, 0, 0.1)}
- {this.renderNumericProperty(properties, 'gravityScale')} + {this.renderNumericProperty( + properties, + 'gravityScale', + false, + 0, + 0.1 + )}
- {this.renderNumericProperty(properties, 'friction')} + {this.renderNumericProperty(properties, 'friction', true, 0, 0.1)}
- {this.renderNumericProperty(properties, 'restitution')} + {this.renderNumericProperty( + properties, + 'restitution', + true, + 0, + 0.1 + )}
- {this.renderNumericProperty(properties, 'linearDamping')} + {this.renderNumericProperty( + properties, + 'linearDamping', + false, + 0, + 0.05 + )}
- {this.renderNumericProperty(properties, 'angularDamping')} + {this.renderNumericProperty( + properties, + 'angularDamping', + false, + 0, + 0.05 + )}
diff --git a/newIDE/app/src/BehaviorsEditor/index.js b/newIDE/app/src/BehaviorsEditor/index.js index e57241912bd2..cc3214803eb3 100644 --- a/newIDE/app/src/BehaviorsEditor/index.js +++ b/newIDE/app/src/BehaviorsEditor/index.js @@ -183,6 +183,9 @@ export default class BehaviorsEditor extends Component { schema={propertiesSchema} instances={[behavior]} project={project} + resourceSources={this.props.resourceSources} + onChooseResource={this.props.onChooseResource} + resourceExternalEditors={this.props.resourceExternalEditors} /> ) : ( diff --git a/newIDE/app/src/ObjectEditor/ObjectEditorDialog.js b/newIDE/app/src/ObjectEditor/ObjectEditorDialog.js index 9cb44dcfe37d..d05cb7c58c5e 100644 --- a/newIDE/app/src/ObjectEditor/ObjectEditorDialog.js +++ b/newIDE/app/src/ObjectEditor/ObjectEditorDialog.js @@ -106,6 +106,9 @@ export class ObjectEditorDialog extends Component<*, StateType> { this.forceUpdate() /*Force update to ensure dialog is properly positionned*/ diff --git a/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js b/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js index 25030f1683bb..8cf13ec93141 100644 --- a/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js +++ b/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js @@ -28,15 +28,15 @@ export default ( .getExtraInfo() .toJSArray() .map(value => ({ value, label: value })); - const dialog = PropertiesRenderingService.getDialogComponent( - property.getExtraInfo().toJSArray()[0] - ); return { name, valueType, getChoices: valueType === 'choice' ? () => choices : undefined, - getDialog: valueType === 'dialog' ? () => dialog : undefined, + getDialog: + valueType === 'dialog' + ? () => PropertiesRenderingService.getDialogComponent(property) + : undefined, getValue: instance => { // Instance custom properties are always stored as string, cast them if necessary const rawValue = getProperties(instance) diff --git a/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js b/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js index 7df3a6c1c3f7..ae6f62da95ab 100644 --- a/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js +++ b/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js @@ -7,8 +7,13 @@ const components = { export default { components, - getDialogComponent: (type: string) => { - if (components.hasOwnProperty(type)) return components[type]; - else return null; + getDialogComponent: (property: Object) => { + const extraInfoArray = property.getExtraInfo().toJSArray(); + if (!extraInfoArray) return null; + + if (components.hasOwnProperty(extraInfoArray[0])) + return components[extraInfoArray[0]]; + + return null; }, }; diff --git a/newIDE/app/src/PropertiesEditor/index.js b/newIDE/app/src/PropertiesEditor/index.js index 5563c82c0c43..e8b96c60b283 100644 --- a/newIDE/app/src/PropertiesEditor/index.js +++ b/newIDE/app/src/PropertiesEditor/index.js @@ -9,6 +9,12 @@ import MenuItem from 'material-ui/MenuItem'; import Edit from 'material-ui/svg-icons/image/edit'; import IconButton from 'material-ui/IconButton'; +import { + type ResourceSource, + type ChooseResourceFunction, +} from '../ResourcesList/ResourceSource.flow'; +import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow'; + export type Instance = Object; // This could be improved using generics. export type Instances = Array; export type Field = Object; @@ -21,6 +27,9 @@ type Props = {| schema: Schema, mode?: 'column' | 'row', project?: Project, + resourceSources?: Array, + onChooseResource?: ChooseResourceFunction, + resourceExternalEditors?: Array, |}; const styles = { @@ -235,6 +244,9 @@ export default class PropertiesEditor extends React.Component { key={field.name} behavior={this.props.instances[0]} project={this.props.project} + resourceSources={this.props.resourceSources} + onChooseResource={this.props.onChooseResource} + resourceExternalEditors={this.props.resourceExternalEditors} /> ); }; From 61101c9bcfe0debaa82c412c2e8520e27980f885 Mon Sep 17 00:00:00 2001 From: Lizard-13 Date: Sun, 30 Dec 2018 21:05:46 -0300 Subject: [PATCH 03/11] Add polygon editor --- .../Editors/Physics2Editor/PolygonEditor.js | 91 ++++++- .../Editors/Physics2Editor/ShapePreview.js | 229 ++++++++++++++---- .../Editors/Physics2Editor/index.js | 144 ++++++++++- newIDE/app/src/PropertiesEditor/index.js | 3 +- 4 files changed, 408 insertions(+), 59 deletions(-) diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js index 36255ffc1cd3..fb8b181b6fc3 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js @@ -1,18 +1,101 @@ // @flow import * as React from 'react'; -import { Line } from '../../../UI/Grid'; +import { + Table, + TableRow, + TableRowColumn, + TableBody, + TableHeader, + TableHeaderColumn, +} from 'material-ui/Table'; +import SemiControlledTextField from '../../../UI/SemiControlledTextField'; +import Warning from 'material-ui/svg-icons/alert/warning'; +import IconButton from 'material-ui/IconButton'; +import AddCircle from 'material-ui/svg-icons/content/add-circle'; +import Delete from 'material-ui/svg-icons/action/delete'; -type Vertice = { +type Vertex = { x: number, y: number, }; type Props = {| - vertices: Array, + vertices: Array, + onChangeVertexX: (newValue: number, index: number) => void, + onChangeVertexY: (newValue: number, index: number) => void, + onAdd: () => void, + onRemove: (index: number) => void, + hasWarning: boolean, |}; export default class PolygonEditor extends React.Component { render() { - return ; + const { + vertices, + onChangeVertexX, + onChangeVertexY, + onAdd, + onRemove, + hasWarning, + } = this.props; + + return ( + + + + + X + Y + + + + + {vertices.map((value, index) => { + return ( + + {hasWarning && } + + + onChangeVertexX(parseFloat(newValue) || 0, index) + } + type="number" + /> + + + + onChangeVertexY(parseFloat(newValue) || 0, index) + } + type="number" + /> + + + onRemove(index)}> + + + + + ); + })} + + + + + + + + + + + +
+ ); } } diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js index 5e5247682244..a6108d745e49 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/ShapePreview.js @@ -1,7 +1,7 @@ // @flow import * as React from 'react'; -type Vertice = { +type Vertex = { x: number, y: number, }; @@ -13,64 +13,201 @@ type Props = {| offsetX: number, offsetY: number, polygonOrigin: string, - vertices: Array, + vertices: Array, width: number, height: number, + onMoveVertex: (index: number, newX: number, newY: number) => void, |}; type State = {| - image: string, + draggedVertex: ?Vertex, + draggedIndex: number, |}; export default class ShapePreview extends React.Component { + constructor(props: Props) { + super(props); + this.state = { draggedVertex: null, draggedIndex: -1 }; + } - render() { - - const {dimensionA, dimensionB, shape, offsetX, offsetY, width, height} = this.props; + _svg: any; + + _onVertexDown = (vertex: Vertex, index: number) => { + if (this.state.draggedVertex) return; + this.setState({ draggedVertex: vertex, draggedIndex: index }); + }; + + _onMouseUp = () => { + const draggingWasDone = !!this.state.draggedVertex; + const { draggedVertex, draggedIndex } = this.state; + this.setState( + { + draggedVertex: null, + }, + () => { + if (draggingWasDone) + this.props.onMoveVertex( + draggedIndex, + Math.round(draggedVertex ? draggedVertex.x : 0), + Math.round(draggedVertex ? draggedVertex.y : 0) + ); + } + ); + }; + + _onMouseMove = (event: any) => { + const { offsetX, offsetY, polygonOrigin, width, height } = this.props; + const { draggedVertex } = this.state; + if (!draggedVertex) return; + + const pointOnScreen = this._svg.createSVGPoint(); + pointOnScreen.x = event.clientX; + pointOnScreen.y = event.clientY; + const screenToSvgMatrix = this._svg.getScreenCTM().inverse(); + const pointOnSvg = pointOnScreen.matrixTransform(screenToSvgMatrix); + + draggedVertex.x = + pointOnSvg.x - offsetX - (polygonOrigin === 'Center' ? width / 2 : 0); + draggedVertex.y = + pointOnSvg.y - offsetY - (polygonOrigin === 'Center' ? height / 2 : 0); + + this.forceUpdate(); + }; + + renderBox() { + const { + dimensionA, + dimensionB, + width, + height, + offsetX, + offsetY, + } = this.props; const fixedWidth = dimensionA > 0 ? dimensionA : width > 0 ? width : 1; const fixedHeight = dimensionB > 0 ? dimensionB : height > 0 ? height : 1; return ( -
- {shape === 'Box' && ( - - - - )} - {shape === 'Circle' && ( - - 0 ? dimensionA : (width + height) > 0 ? (width + height) / 4 : 1} - /> - - )} - {shape === 'Edge' && ( - - - - )} -
+ + ); + } + + renderCircle() { + const { dimensionA, width, height, offsetX, offsetY } = this.props; + + return ( + 0 + ? dimensionA + : width + height > 0 + ? (width + height) / 4 + : 1 + } + /> + ); + } + + renderEdge() { + const { + dimensionA, + dimensionB, + width, + height, + offsetX, + offsetY, + } = this.props; + const halfLength = + (dimensionA > 0 ? dimensionA : width > 0 ? width : 1) / 2; + const cos = Math.cos((dimensionB * Math.PI) / 180); + const sin = Math.sin((dimensionB * Math.PI) / 180); + + return ( + + ); + } + + renderPolygon() { + const { + vertices, + polygonOrigin, + width, + height, + offsetX, + offsetY, + } = this.props; + + return ( + + + `${vertex.x + + offsetX + + (polygonOrigin === 'Center' ? width / 2 : 0)},${vertex.y + + offsetY + + (polygonOrigin === 'Center' ? height / 2 : 0)}` + ) + .join(' ')} + /> + {vertices.map((vertex, index) => ( + this._onVertexDown(vertex, index)} + key={`vertex-${index}`} + fill="rgba(150,0,0,0.75)" + strokeWidth={1} + cx={ + vertex.x + offsetX + (polygonOrigin === 'Center' ? width / 2 : 0) + } + cy={ + vertex.y + offsetY + (polygonOrigin === 'Center' ? height / 2 : 0) + } + r={5} + /> + ))} + + ); + } + + render() { + const { shape } = this.props; + + return ( + (this._svg = svg)} + > + {shape === 'Box' && this.renderBox()} + {shape === 'Circle' && this.renderCircle()} + {shape === 'Edge' && this.renderEdge()} + {shape === 'Polygon' && this.renderPolygon()} + ); } } diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js index 44b667cdbdf1..1ac6fc77263b 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js @@ -18,7 +18,7 @@ import { type ResourceExternalEditor } from '../../../ResourcesList/ResourceExte type Props = {| behavior: Object, - project: Object, + project: gdProject, resourceSources: Array, onChooseResource: ChooseResourceFunction, resourceExternalEditors: Array, @@ -51,6 +51,38 @@ export default class Physics2Editor extends React.Component { imageWidth: width, imageHeight: height, }); + }; + + _isPolygonConvex(properties: Object) { + const vertices = JSON.parse(properties.get('vertices').getValue()); + // Get edges + var edges = []; + var v1 = null; + var v2 = null; + for (var i = 0; i < vertices.length; i++) { + v1 = vertices[i]; + if (i + 1 >= vertices.length) v2 = vertices[0]; + else v2 = vertices[i + 1]; + edges.push({ x: v2.x - v1.x, y: v2.y - v1.y }); + } + // Check convexity + if (edges.length < 3) return false; + + const zProductIsPositive = + edges[0].x * edges[0 + 1].y - edges[0].y * edges[0 + 1].x > 0; + + for (i = 1; i < edges.length - 1; ++i) { + var zCrossProduct = + edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x; + if (zCrossProduct > 0 !== zProductIsPositive) return false; + } + + var lastZCrossProduct = + edges[edges.length - 1].x * edges[0].y - + edges[edges.length - 1].y * edges[0].x; + if (lastZCrossProduct > 0 !== zProductIsPositive) return false; + + return true; } _isBitEnabled(bitsValue: number, i: number) { @@ -77,7 +109,7 @@ export default class Physics2Editor extends React.Component { return (
{ { render() { const { behavior, project } = this.props; + + // Parsing error temporary workaround + if ( + !Array.isArray( + JSON.parse( + behavior + .getProperties() + .get('vertices') + .getValue() + ) + ) + ) { + behavior.updateProperty('vertices', '[]', project); + } + const properties = behavior.getProperties(project); const bits = Array(16).fill(null); const shape = properties.get('shape').getValue(); @@ -317,7 +364,7 @@ export default class Physics2Editor extends React.Component { -
+
{ > { + let vertices = JSON.parse( + properties.get('vertices').getValue() + ); + vertices[index].x = newX; + vertices[index].y = newY; + behavior.updateProperty( + 'vertices', + JSON.stringify(vertices), + project + ); + this.forceUpdate(); + }} />
@@ -358,9 +426,71 @@ export default class Physics2Editor extends React.Component { {shape === 'Polygon' && ( { + let vertices = JSON.parse( + properties.get('vertices').getValue() + ); + vertices[index].x = newValue; + behavior.updateProperty( + 'vertices', + JSON.stringify(vertices), + project + ); + this.forceUpdate(); + }} + onChangeVertexY={(newValue, index) => { + let vertices = JSON.parse( + properties.get('vertices').getValue() + ); + vertices[index].y = newValue; + behavior.updateProperty( + 'vertices', + JSON.stringify(vertices), + project + ); + this.forceUpdate(); + }} + onAdd={() => { + let vertices = JSON.parse( + properties.get('vertices').getValue() + ); + vertices.push({ x: 0, y: 0 }); + behavior.updateProperty( + 'vertices', + JSON.stringify(vertices), + project + ); + this.forceUpdate(); + }} + onRemove={index => { + let vertices = JSON.parse( + properties.get('vertices').getValue() + ); + vertices.splice(index, 1); + behavior.updateProperty( + 'vertices', + JSON.stringify(vertices), + project + ); + this.forceUpdate(); + }} + hasWarning={!this._isPolygonConvex(properties)} /> )} + + { + behavior.updateProperty('vertices', newValue, project); + this.forceUpdate(); + }} + type="text" + /> +
{this.renderNumericProperty(properties, 'density', true, 0, 0.1)} diff --git a/newIDE/app/src/PropertiesEditor/index.js b/newIDE/app/src/PropertiesEditor/index.js index e8b96c60b283..d9223f641595 100644 --- a/newIDE/app/src/PropertiesEditor/index.js +++ b/newIDE/app/src/PropertiesEditor/index.js @@ -19,14 +19,13 @@ export type Instance = Object; // This could be improved using generics. export type Instances = Array; export type Field = Object; export type Schema = Array; -export type Project = Object; type Props = {| onInstancesModified?: Instances => void, instances: Instances, schema: Schema, mode?: 'column' | 'row', - project?: Project, + project?: gdProject, resourceSources?: Array, onChooseResource?: ChooseResourceFunction, resourceExternalEditors?: Array, From dfb93bd8bf031b09cb74117ffd16f6164118c146 Mon Sep 17 00:00:00 2001 From: Lizard-13 Date: Sun, 30 Dec 2018 21:36:18 -0300 Subject: [PATCH 04/11] Run prettier --- .../app/src/BehaviorsEditor/Editors/Physics2Editor/index.js | 1 - newIDE/app/src/BehaviorsEditor/index.js | 4 +++- newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js index 1ac6fc77263b..2bd7168e0c78 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js @@ -31,7 +31,6 @@ type State = {| |}; export default class Physics2Editor extends React.Component { - resourcesLoader: typeof ResourcesLoader; constructor(props: Props) { diff --git a/newIDE/app/src/BehaviorsEditor/index.js b/newIDE/app/src/BehaviorsEditor/index.js index cc3214803eb3..aaefdc08e151 100644 --- a/newIDE/app/src/BehaviorsEditor/index.js +++ b/newIDE/app/src/BehaviorsEditor/index.js @@ -185,7 +185,9 @@ export default class BehaviorsEditor extends Component { project={project} resourceSources={this.props.resourceSources} onChooseResource={this.props.onChooseResource} - resourceExternalEditors={this.props.resourceExternalEditors} + resourceExternalEditors={ + this.props.resourceExternalEditors + } /> ) : ( diff --git a/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js b/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js index ae6f62da95ab..5bcaa9340aec 100644 --- a/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js +++ b/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js @@ -10,10 +10,10 @@ export default { getDialogComponent: (property: Object) => { const extraInfoArray = property.getExtraInfo().toJSArray(); if (!extraInfoArray) return null; - + if (components.hasOwnProperty(extraInfoArray[0])) return components[extraInfoArray[0]]; - + return null; }, }; From ddd230f4821f30d51cf1965d107b2777d314bb24 Mon Sep 17 00:00:00 2001 From: Lizard-13 Date: Mon, 31 Dec 2018 19:16:15 -0300 Subject: [PATCH 05/11] Improve design --- .../Editors/Physics2Editor/PolygonEditor.js | 39 +- .../Editors/Physics2Editor/ShapePreview.js | 6 +- .../Editors/Physics2Editor/index.js | 469 ++++++++++-------- 3 files changed, 285 insertions(+), 229 deletions(-) diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js index fb8b181b6fc3..2bbff56aa27b 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js @@ -14,10 +14,10 @@ import IconButton from 'material-ui/IconButton'; import AddCircle from 'material-ui/svg-icons/content/add-circle'; import Delete from 'material-ui/svg-icons/action/delete'; -type Vertex = { +type Vertex = {| x: number, y: number, -}; +|}; type Props = {| vertices: Array, @@ -25,10 +25,40 @@ type Props = {| onChangeVertexY: (newValue: number, index: number) => void, onAdd: () => void, onRemove: (index: number) => void, - hasWarning: boolean, |}; export default class PolygonEditor extends React.Component { + _isPolygonConvex(vertices: Array) { + // Get edges + var edges = []; + var v1 = null; + var v2 = null; + for (var i = 0; i < vertices.length; i++) { + v1 = vertices[i]; + if (i + 1 >= vertices.length) v2 = vertices[0]; + else v2 = vertices[i + 1]; + edges.push({ x: v2.x - v1.x, y: v2.y - v1.y }); + } + // Check convexity + if (edges.length < 3) return false; + + const zProductIsPositive = + edges[0].x * edges[0 + 1].y - edges[0].y * edges[0 + 1].x > 0; + + for (i = 1; i < edges.length - 1; ++i) { + var zCrossProduct = + edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x; + if (zCrossProduct > 0 !== zProductIsPositive) return false; + } + + var lastZCrossProduct = + edges[edges.length - 1].x * edges[0].y - + edges[edges.length - 1].y * edges[0].x; + if (lastZCrossProduct > 0 !== zProductIsPositive) return false; + + return true; + } + render() { const { vertices, @@ -36,7 +66,6 @@ export default class PolygonEditor extends React.Component { onChangeVertexY, onAdd, onRemove, - hasWarning, } = this.props; return ( @@ -57,7 +86,7 @@ export default class PolygonEditor extends React.Component { {vertices.map((value, index) => { return ( - {hasWarning && } + {!this._isPolygonConvex(vertices) && } void, +|}) { + const { properties, propertyName, step, onUpdate } = props; + + return ( + + ); +} + +function BitProperty(props: {| + enabled: boolean, + propertyName: string, + pos: number, + spacing: boolean, + onUpdate: (enabled: boolean) => void, +|}) { + const { enabled, propertyName, pos, spacing, onUpdate } = props; + + return ( +
+ { + onUpdate(checked)} + /> + } + {spacing && ( +
+ )} +
+ ); +} + export default class Physics2Editor extends React.Component { resourcesLoader: typeof ResourcesLoader; @@ -40,7 +88,7 @@ export default class Physics2Editor extends React.Component { this.state = { image: '', - imageWidth: 9, + imageWidth: 0, imageHeight: 0, }; } @@ -52,116 +100,16 @@ export default class Physics2Editor extends React.Component { }); }; - _isPolygonConvex(properties: Object) { - const vertices = JSON.parse(properties.get('vertices').getValue()); - // Get edges - var edges = []; - var v1 = null; - var v2 = null; - for (var i = 0; i < vertices.length; i++) { - v1 = vertices[i]; - if (i + 1 >= vertices.length) v2 = vertices[0]; - else v2 = vertices[i + 1]; - edges.push({ x: v2.x - v1.x, y: v2.y - v1.y }); - } - // Check convexity - if (edges.length < 3) return false; - - const zProductIsPositive = - edges[0].x * edges[0 + 1].y - edges[0].y * edges[0 + 1].x > 0; - - for (i = 1; i < edges.length - 1; ++i) { - var zCrossProduct = - edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x; - if (zCrossProduct > 0 !== zProductIsPositive) return false; - } - - var lastZCrossProduct = - edges[edges.length - 1].x * edges[0].y - - edges[edges.length - 1].y * edges[0].x; - if (lastZCrossProduct > 0 !== zProductIsPositive) return false; - - return true; + _isBitEnabled(bitsValue: number, pos: number) { + return !!(bitsValue & (1 << pos)); } - _isBitEnabled(bitsValue: number, i: number) { - return !!(bitsValue & (1 << i)); - } - - _enableBit(bitsValue: number, i: number, enable: boolean) { - if (enable) bitsValue |= 1 << i; - else bitsValue &= ~(1 << i); + _enableBit(bitsValue: number, pos: number, enable: boolean) { + if (enable) bitsValue |= 1 << pos; + else bitsValue &= ~(1 << pos); return bitsValue; } - renderBitProperty( - properties: Object, - isLayer: boolean, - pos: number, - spacing: boolean - ) { - const bitValues = parseInt( - properties.get(isLayer ? 'layers' : 'masks').getValue(), - 10 - ); - - return ( -
- { - { - const newValue = this._enableBit(bitValues, pos, checked); - this.props.behavior.updateProperty( - isLayer ? 'layers' : 'masks', - newValue.toString(10), - this.props.project - ); - this.forceUpdate(); - }} - /> - } - {spacing && ( -
- )} -
- ); - } - - renderNumericProperty( - properties: Object, - name: string, - limit: boolean, - min: number, - step: number - ) { - return ( - { - this.props.behavior.updateProperty( - name, - newValue, - this.props.project - ); - this.forceUpdate(); - }} - type="number" - /> - ); - } - render() { const { behavior, project } = this.props; @@ -182,6 +130,8 @@ export default class Physics2Editor extends React.Component { const properties = behavior.getProperties(project); const bits = Array(16).fill(null); const shape = properties.get('shape').getValue(); + const layersValues = parseInt(properties.get('layers').getValue(), 10); + const masksValues = parseInt(properties.get('masks').getValue(), 10); return ( @@ -216,7 +166,7 @@ export default class Physics2Editor extends React.Component { -
+ { this.forceUpdate(); }} /> -
-
+ + { this.forceUpdate(); }} /> -
-
+ + { this.forceUpdate(); }} /> -
+
{ this.forceUpdate(); }} > - {[ - , - , - , - , - ]} + + + + @@ -357,53 +301,71 @@ export default class Physics2Editor extends React.Component { ]} )} - {this.renderNumericProperty(properties, 'shapeOffsetX', false, 0, 1)} - {this.renderNumericProperty(properties, 'shapeOffsetY', false, 0, 1)} + { + behavior.updateProperty('shapeOffsetX', newValue, project); + this.forceUpdate(); + }} + /> + { + this.props.behavior.updateProperty( + 'shapeOffsetY', + newValue, + this.props.project + ); + this.forceUpdate(); + }} + /> - + -
- - { - let vertices = JSON.parse( - properties.get('vertices').getValue() - ); - vertices[index].x = newX; - vertices[index].y = newY; - behavior.updateProperty( - 'vertices', - JSON.stringify(vertices), - project - ); - this.forceUpdate(); - }} - /> - -
+ + { + let vertices = JSON.parse( + properties.get('vertices').getValue() + ); + vertices[index].x = newX; + vertices[index].y = newY; + behavior.updateProperty( + 'vertices', + JSON.stringify(vertices), + project + ); + this.forceUpdate(); + }} + /> +
{ let vertices = JSON.parse( properties.get('vertices').getValue() ); + if (vertices.length >= 8) return; vertices.push({ x: 0, y: 0 }); behavior.updateProperty( 'vertices', @@ -473,7 +436,6 @@ export default class Physics2Editor extends React.Component { ); this.forceUpdate(); }} - hasWarning={!this._isPolygonConvex(properties)} /> )} @@ -491,59 +453,116 @@ export default class Physics2Editor extends React.Component { />
-
- {this.renderNumericProperty(properties, 'density', true, 0, 0.1)} -
-
- {this.renderNumericProperty( - properties, - 'gravityScale', - false, - 0, - 0.1 - )} -
+ + { + behavior.updateProperty( + 'density', + newValue > 0 ? newValue : 0, + project + ); + this.forceUpdate(); + }} + /> + + + { + behavior.updateProperty('gravityScale', newValue, project); + this.forceUpdate(); + }} + /> +
-
- {this.renderNumericProperty(properties, 'friction', true, 0, 0.1)} -
-
- {this.renderNumericProperty( - properties, - 'restitution', - true, - 0, - 0.1 - )} -
+ + { + behavior.updateProperty( + 'friction', + newValue > 0 ? newValue : 0, + project + ); + this.forceUpdate(); + }} + /> + + + { + behavior.updateProperty( + 'restitution', + newValue > 0 ? newValue : 0, + project + ); + this.forceUpdate(); + }} + /> +
-
- {this.renderNumericProperty( - properties, - 'linearDamping', - false, - 0, - 0.05 - )} -
-
- {this.renderNumericProperty( - properties, - 'angularDamping', - false, - 0, - 0.05 - )} -
+ + { + behavior.updateProperty('linearDamping', newValue, project); + this.forceUpdate(); + }} + /> + + + { + behavior.updateProperty('angularDamping', newValue, project); + this.forceUpdate(); + }} + /> +
{bits.map((value, index) => { - return this.renderBitProperty(properties, true, index, index === 7); + return ( + { + const newValue = this._enableBit( + layersValues, + index, + enabled + ); + this.props.behavior.updateProperty( + 'layers', + newValue.toString(10), + this.props.project + ); + this.forceUpdate(); + }} + key={`layer${index}`} + /> + ); })} @@ -551,11 +570,23 @@ export default class Physics2Editor extends React.Component { {properties.get('masks').getLabel()} {bits.map((value, index) => { - return this.renderBitProperty( - properties, - false, - index, - index === 7 + return ( + { + const newValue = this._enableBit(masksValues, index, enabled); + this.props.behavior.updateProperty( + 'masks', + newValue.toString(10), + this.props.project + ); + this.forceUpdate(); + }} + key={`mask${index}`} + /> ); })} From d86cefca94cb5182ee912ea92cb486bf35a83faf Mon Sep 17 00:00:00 2001 From: Lizard-13 Date: Thu, 3 Jan 2019 14:04:05 -0300 Subject: [PATCH 06/11] Add BehaviorsEditorService --- Extensions/Physics2Behavior/JsExtension.js | 6 --- .../BehaviorsEditor/BehaviorsEditorService.js | 20 +++++++++ .../Editors/BehaviorEditorProps.flow.js | 16 +++++++ .../Editors/BehaviorPropertiesEditor.js | 43 +++++++++++++++++++ .../Editors/Physics2Editor/PolygonEditor.js | 6 ++- .../Editors/Physics2Editor/index.js | 22 +++------- newIDE/app/src/BehaviorsEditor/index.js | 42 +++++------------- .../PropertiesEditor/PropertiesMapToSchema.js | 5 --- .../PropertiesRenderingService.js | 19 -------- newIDE/app/src/PropertiesEditor/index.js | 39 ----------------- 10 files changed, 99 insertions(+), 119 deletions(-) create mode 100644 newIDE/app/src/BehaviorsEditor/BehaviorsEditorService.js create mode 100644 newIDE/app/src/BehaviorsEditor/Editors/BehaviorEditorProps.flow.js create mode 100644 newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js delete mode 100644 newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js diff --git a/Extensions/Physics2Behavior/JsExtension.js b/Extensions/Physics2Behavior/JsExtension.js index b7af04927012..bf09107f4859 100644 --- a/Extensions/Physics2Behavior/JsExtension.js +++ b/Extensions/Physics2Behavior/JsExtension.js @@ -125,12 +125,6 @@ module.exports = { physics2Behavior.getProperties = function(behaviorContent) { var behaviorProperties = new gd.MapStringPropertyDescriptor(); - behaviorProperties.set( - 'dialog', - new gd.PropertyDescriptor(behaviorContent.type) - .setType('Dialog') - .addExtraInfo('physics2') - ); behaviorProperties.set( 'type', new gd.PropertyDescriptor(behaviorContent.type) diff --git a/newIDE/app/src/BehaviorsEditor/BehaviorsEditorService.js b/newIDE/app/src/BehaviorsEditor/BehaviorsEditorService.js new file mode 100644 index 000000000000..d677fcc83d81 --- /dev/null +++ b/newIDE/app/src/BehaviorsEditor/BehaviorsEditorService.js @@ -0,0 +1,20 @@ +// @flow +import BehaviorPropertiesEditor from './Editors/BehaviorPropertiesEditor'; +import Physics2Editor from './Editors/Physics2Editor'; + +/** + * A service returning editor components for each behavior type. + */ +export default { + getEditor(behaviorType: string) { + if (!this.components[behaviorType]) { + return BehaviorPropertiesEditor; // Default properties editor + } + return this.components[behaviorType].component; // Custom behavior editor + }, + components: { + 'Physics2::Physics2Behavior': { + component: Physics2Editor, + }, + }, +}; diff --git a/newIDE/app/src/BehaviorsEditor/Editors/BehaviorEditorProps.flow.js b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorEditorProps.flow.js new file mode 100644 index 000000000000..b37fc26a1ccc --- /dev/null +++ b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorEditorProps.flow.js @@ -0,0 +1,16 @@ +import { + type ResourceSource, + type ChooseResourceFunction, +} from '../../ResourcesList/ResourceSource.flow'; +import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow'; + +/** + * The props given to any behavior editor + */ +export type BehaviorEditorProps = {| + behavior: Object, + project: gdProject, + resourceSources: Array, + onChooseResource: ChooseResourceFunction, + resourceExternalEditors: Array, +|}; diff --git a/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js new file mode 100644 index 000000000000..594628f708ce --- /dev/null +++ b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js @@ -0,0 +1,43 @@ +// @flow +import * as React from 'react'; +import PropertiesEditor from '../../PropertiesEditor'; +import propertiesMapToSchema from '../../PropertiesEditor/PropertiesMapToSchema'; +import EmptyMessage from '../../UI/EmptyMessage'; +import { type BehaviorEditorProps } from './BehaviorEditorProps.flow'; + +type Props = BehaviorEditorProps; + +const styles = { + propertiesContainer: { + padding: 10, + }, +}; + +export default class BehaviorPropertiesEditor extends React.Component { + render() { + const { behavior, project } = this.props; + const properties = behavior.getProperties(project); + + const propertiesSchema = propertiesMapToSchema( + properties, + behavior => behavior.getProperties(project), + (behavior, name, value) => behavior.updateProperty(name, value, project) + ); + + return ( +
+ {propertiesSchema.length ? ( + + ) : ( + + There is nothing to configure for this behavior. You can still use + events to interact with the object and this behavior. + + )} +
+ ); + } +} diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js index 2bbff56aa27b..6c92da39e11b 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js @@ -14,7 +14,7 @@ import IconButton from 'material-ui/IconButton'; import AddCircle from 'material-ui/svg-icons/content/add-circle'; import Delete from 'material-ui/svg-icons/action/delete'; -type Vertex = {| +export type Vertex = {| x: number, y: number, |}; @@ -86,7 +86,9 @@ export default class PolygonEditor extends React.Component { {vertices.map((value, index) => { return ( - {!this._isPolygonConvex(vertices) && } + + {!this._isPolygonConvex(vertices) && } + , - onChooseResource: ChooseResourceFunction, - resourceExternalEditors: Array, -|}; +type Props = BehaviorEditorProps; type State = {| image: string, @@ -34,7 +24,7 @@ function NumericProperty(props: {| properties: gdMapStringPropertyDescriptor, propertyName: string, step: number, - onUpdate: (newValue: number) => void, + onUpdate: (newValue: string) => void, |}) { const { properties, propertyName, step, onUpdate } = props; @@ -461,7 +451,7 @@ export default class Physics2Editor extends React.Component { onUpdate={newValue => { behavior.updateProperty( 'density', - newValue > 0 ? newValue : 0, + parseFloat(newValue) > 0 ? newValue : '0', project ); this.forceUpdate(); @@ -489,7 +479,7 @@ export default class Physics2Editor extends React.Component { onUpdate={newValue => { behavior.updateProperty( 'friction', - newValue > 0 ? newValue : 0, + parseFloat(newValue) > 0 ? newValue : '0', project ); this.forceUpdate(); @@ -504,7 +494,7 @@ export default class Physics2Editor extends React.Component { onUpdate={newValue => { behavior.updateProperty( 'restitution', - newValue > 0 ? newValue : 0, + parseFloat(newValue) > 0 ? newValue : '0', project ); this.forceUpdate(); diff --git a/newIDE/app/src/BehaviorsEditor/index.js b/newIDE/app/src/BehaviorsEditor/index.js index aaefdc08e151..e05db6a3052f 100644 --- a/newIDE/app/src/BehaviorsEditor/index.js +++ b/newIDE/app/src/BehaviorsEditor/index.js @@ -6,11 +6,10 @@ import IconButton from 'material-ui/IconButton'; import EmptyMessage from '../UI/EmptyMessage'; import MiniToolbar from '../UI/MiniToolbar'; import HelpIcon from '../UI/HelpIcon'; -import PropertiesEditor from '../PropertiesEditor'; -import propertiesMapToSchema from '../PropertiesEditor/PropertiesMapToSchema'; import newNameGenerator from '../Utils/NewNameGenerator'; import NewBehaviorDialog from './NewBehaviorDialog'; import { getBehaviorHelpPagePath } from './BehaviorsHelpPagePaths'; +import BehaviorsEditorService from './BehaviorsEditorService'; const styles = { addBehaviorLine: { @@ -20,9 +19,6 @@ const styles = { addBehaviorText: { justifyContent: 'flex-end', }, - propertiesContainer: { - padding: 10, - }, behaviorTitle: { flex: 1, }, @@ -143,13 +139,8 @@ export default class BehaviorsEditor extends Component { {allBehaviorNames .map((behaviorName, index) => { const behavior = object.getBehavior(behaviorName); - - const properties = behavior.getProperties(project); - const propertiesSchema = propertiesMapToSchema( - properties, - behavior => behavior.getProperties(project), - (behavior, name, value) => - behavior.updateProperty(name, value, project) + const BehaviorComponent = BehaviorsEditorService.getEditor( + behavior.getTypeName() ); return ( @@ -177,26 +168,13 @@ export default class BehaviorsEditor extends Component { /> -
- {propertiesSchema.length ? ( - - ) : ( - - There is nothing to configure for this behavior. You can - still use events to interact with the object and this - behavior. - - )} -
+
); }) diff --git a/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js b/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js index 8cf13ec93141..0708e55b4e88 100644 --- a/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js +++ b/newIDE/app/src/PropertiesEditor/PropertiesMapToSchema.js @@ -1,7 +1,6 @@ // @flow import { mapFor } from '../Utils/MapFor'; import { type Schema, type Instance } from '.'; -import PropertiesRenderingService from './PropertiesRenderingService'; /** * Transform a MapStringPropertyDescriptor to a schema that can be used in PropertiesEditor. @@ -33,10 +32,6 @@ export default ( name, valueType, getChoices: valueType === 'choice' ? () => choices : undefined, - getDialog: - valueType === 'dialog' - ? () => PropertiesRenderingService.getDialogComponent(property) - : undefined, getValue: instance => { // Instance custom properties are always stored as string, cast them if necessary const rawValue = getProperties(instance) diff --git a/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js b/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js deleted file mode 100644 index 5bcaa9340aec..000000000000 --- a/newIDE/app/src/PropertiesEditor/PropertiesRenderingService.js +++ /dev/null @@ -1,19 +0,0 @@ -// @flow -import Physics2Editor from '../BehaviorsEditor/Editors/Physics2Editor'; - -const components = { - physics2: Physics2Editor, -}; - -export default { - components, - getDialogComponent: (property: Object) => { - const extraInfoArray = property.getExtraInfo().toJSArray(); - if (!extraInfoArray) return null; - - if (components.hasOwnProperty(extraInfoArray[0])) - return components[extraInfoArray[0]]; - - return null; - }, -}; diff --git a/newIDE/app/src/PropertiesEditor/index.js b/newIDE/app/src/PropertiesEditor/index.js index d9223f641595..0979c1514a6c 100644 --- a/newIDE/app/src/PropertiesEditor/index.js +++ b/newIDE/app/src/PropertiesEditor/index.js @@ -9,12 +9,6 @@ import MenuItem from 'material-ui/MenuItem'; import Edit from 'material-ui/svg-icons/image/edit'; import IconButton from 'material-ui/IconButton'; -import { - type ResourceSource, - type ChooseResourceFunction, -} from '../ResourcesList/ResourceSource.flow'; -import { type ResourceExternalEditor } from '../ResourcesList/ResourceExternalEditor.flow'; - export type Instance = Object; // This could be improved using generics. export type Instances = Array; export type Field = Object; @@ -25,10 +19,6 @@ type Props = {| instances: Instances, schema: Schema, mode?: 'column' | 'row', - project?: gdProject, - resourceSources?: Array, - onChooseResource?: ChooseResourceFunction, - resourceExternalEditors?: Array, |}; const styles = { @@ -235,38 +225,9 @@ export default class PropertiesEditor extends React.Component { ); }; - _renderDialog = (field: Field) => { - const EditorComponent = field.getDialog(); - - return ( - - ); - }; - render() { const { mode } = this.props; - for (var i = 0, len = this.props.schema.length; i < len; i++) { - if (this.props.schema[i].getDialog) { - return ( -
- {this._renderDialog(this.props.schema[i])} -
- ); - } - } - return (
Date: Fri, 4 Jan 2019 09:08:55 -0300 Subject: [PATCH 07/11] Avoid divs and Physics2Editor constructor --- .../Editors/BehaviorPropertiesEditor.js | 11 +++-------- .../Editors/Physics2Editor/index.js | 18 ++++++------------ 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js index 594628f708ce..459f7879fe32 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js @@ -3,16 +3,11 @@ import * as React from 'react'; import PropertiesEditor from '../../PropertiesEditor'; import propertiesMapToSchema from '../../PropertiesEditor/PropertiesMapToSchema'; import EmptyMessage from '../../UI/EmptyMessage'; +import { Column } from '../../UI/Grid'; import { type BehaviorEditorProps } from './BehaviorEditorProps.flow'; type Props = BehaviorEditorProps; -const styles = { - propertiesContainer: { - padding: 10, - }, -}; - export default class BehaviorPropertiesEditor extends React.Component { render() { const { behavior, project } = this.props; @@ -25,7 +20,7 @@ export default class BehaviorPropertiesEditor extends React.Component { ); return ( -
+ {propertiesSchema.length ? ( { events to interact with the object and this behavior. )} -
+ ); } } diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js index 81d844c340a1..c68fffccd5fb 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js @@ -69,19 +69,13 @@ function BitProperty(props: {| } export default class Physics2Editor extends React.Component { - resourcesLoader: typeof ResourcesLoader; + resourcesLoader = ResourcesLoader; - constructor(props: Props) { - super(props); - - this.resourcesLoader = ResourcesLoader; - - this.state = { - image: '', - imageWidth: 0, - imageHeight: 0, - }; - } + state = { + image: '', + imageWidth: 0, + imageHeight: 0, + }; _setImageSize = (width: number, height: number) => { this.setState({ From 76cbe1ce37c6c17028710a02710f7befad6a1ecf Mon Sep 17 00:00:00 2001 From: Lizard-13 Date: Fri, 4 Jan 2019 19:53:52 -0300 Subject: [PATCH 08/11] Fix warnings for mixing comparison operators --- .../BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js index 6c92da39e11b..c40eb5d0d3ff 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/PolygonEditor.js @@ -48,13 +48,15 @@ export default class PolygonEditor extends React.Component { for (i = 1; i < edges.length - 1; ++i) { var zCrossProduct = edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x; - if (zCrossProduct > 0 !== zProductIsPositive) return false; + var zCrossProductIsPositive = zCrossProduct > 0; + if (zCrossProductIsPositive !== zProductIsPositive) return false; } var lastZCrossProduct = edges[edges.length - 1].x * edges[0].y - edges[edges.length - 1].y * edges[0].x; - if (lastZCrossProduct > 0 !== zProductIsPositive) return false; + var lastZCrossProductIsPositive = lastZCrossProduct > 0; + if (lastZCrossProductIsPositive !== zProductIsPositive) return false; return true; } From 101157b5d68fda6c6dfc194d0d495c6e3a758663 Mon Sep 17 00:00:00 2001 From: Lizard-13 Date: Fri, 4 Jan 2019 20:48:35 -0300 Subject: [PATCH 09/11] Remove debug component and safe check --- .../Editors/Physics2Editor/index.js | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js index c68fffccd5fb..0fb53da58dff 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/Physics2Editor/index.js @@ -97,20 +97,6 @@ export default class Physics2Editor extends React.Component { render() { const { behavior, project } = this.props; - // Parsing error temporary workaround - if ( - !Array.isArray( - JSON.parse( - behavior - .getProperties() - .get('vertices') - .getValue() - ) - ) - ) { - behavior.updateProperty('vertices', '[]', project); - } - const properties = behavior.getProperties(project); const bits = Array(16).fill(null); const shape = properties.get('shape').getValue(); @@ -423,19 +409,6 @@ export default class Physics2Editor extends React.Component { /> )} - - { - behavior.updateProperty('vertices', newValue, project); - this.forceUpdate(); - }} - type="text" - /> - Date: Fri, 4 Jan 2019 21:06:09 -0300 Subject: [PATCH 10/11] Fix minor misspelling error --- Extensions/Physics2Behavior/JsExtension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Extensions/Physics2Behavior/JsExtension.js b/Extensions/Physics2Behavior/JsExtension.js index bf09107f4859..a2240f4c1026 100644 --- a/Extensions/Physics2Behavior/JsExtension.js +++ b/Extensions/Physics2Behavior/JsExtension.js @@ -718,7 +718,7 @@ module.exports = { t( 'Modify an object shape scale. It affects custom shape dimensions and shape offset, if custom dimensions are not set the body will be scaled automatically to the object size.' ), - t('Do to _PARAM2__PARAM3_ to the shape scale of _PARAM0_'), + t('Do _PARAM2__PARAM3_ to the shape scale of _PARAM0_'), t('Body settings'), 'res/physics24.png', 'res/physics16.png' From 2248e67cbd49b5da8dda2b77022dfa969f4920c1 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Sat, 5 Jan 2019 12:19:51 +0000 Subject: [PATCH 11/11] Run Prettier on BehaviorPropertiesEditor --- .../src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js index 459f7879fe32..2f858168a736 100644 --- a/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js +++ b/newIDE/app/src/BehaviorsEditor/Editors/BehaviorPropertiesEditor.js @@ -22,10 +22,7 @@ export default class BehaviorPropertiesEditor extends React.Component { return ( {propertiesSchema.length ? ( - + ) : ( There is nothing to configure for this behavior. You can still use