Skip to content

Commit

Permalink
Add button to open full editor for physics engine and regroup properties
Browse files Browse the repository at this point in the history
  • Loading branch information
4ian committed Sep 19, 2024
1 parent b65c5ec commit 07c5897
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 31 deletions.
10 changes: 10 additions & 0 deletions Core/GDCore/Extensions/Metadata/BehaviorMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,15 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
return *this;
}

BehaviorMetadata &SetOpenFullEditorLabel(const gd::String& label) {
openFullEditorLabel = label;
return *this;
}

const gd::String& GetOpenFullEditorLabel() const {
return openFullEditorLabel;
}

/**
* \brief Return the associated gd::Behavior, handling behavior contents.
*
Expand Down Expand Up @@ -384,6 +393,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
mutable std::vector<gd::String> requiredBehaviors;
bool isPrivate = false;
bool isHidden = false;
gd::String openFullEditorLabel;
QuickCustomization::Visibility quickCustomizationVisibility;

// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
Expand Down
96 changes: 74 additions & 22 deletions Extensions/Physics2Behavior/JsExtension.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,27 @@ module.exports = {
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.addExtraInfo('Static')
.addExtraInfo('Dynamic')
.addExtraInfo('Kinematic');
.addExtraInfo('Kinematic')
.setDescription(
_(
"A static object won't move (perfect for obstacles). Dynamic objects can move. Kinematic will move according to forces applied to it only (useful for characters or specific mechanisms)."
)
);
behaviorProperties
.getOrCreate('bullet')
.setValue(
behaviorContent.getChild('bullet').getBoolValue() ? 'true' : 'false'
)
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setType('Boolean')
.setLabel('Bullet');
.setLabel(_('Considered as a bullet'))
.setDescription(
_(
'Useful for fast moving objects which requires a more accurate collision detection.'
)
)
.setGroup(_('Physics body advanced settings'))
.setAdvanced(true);
behaviorProperties
.getOrCreate('fixedRotation')
.setValue(
Expand All @@ -203,15 +215,28 @@ module.exports = {
)
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setType('Boolean')
.setLabel('Fixed Rotation');
.setLabel('Fixed Rotation')
.setDescription(
_(
"If enabled, the object won't rotate and will stay at the same angle. Useful for characters for example."
)
)
.setGroup(_('Movement'));
behaviorProperties
.getOrCreate('canSleep')
.setValue(
behaviorContent.getChild('canSleep').getBoolValue() ? 'true' : 'false'
)
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setType('Boolean')
.setLabel('Can Sleep');
.setLabel(_('Can be put to sleep by the engine'))
.setDescription(
_(
"Allows the physics engine to stop computing interaction with the object when it's not touched. It's recommended to keep this on."
)
)
.setGroup(_('Physics body advanced settings'))
.setAdvanced(true);
behaviorProperties
.getOrCreate('shape')
.setValue(behaviorContent.getChild('shape').getStringValue())
Expand All @@ -233,7 +258,8 @@ module.exports = {
.setType('Number')
.setMeasurementUnit(gd.MeasurementUnit.getPixel())
.setLabel('Shape Dimension A')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.
behaviorProperties
.getOrCreate('shapeDimensionB')
.setValue(
Expand All @@ -245,7 +271,8 @@ module.exports = {
.setType('Number')
.setMeasurementUnit(gd.MeasurementUnit.getPixel())
.setLabel('Shape Dimension B')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.
behaviorProperties
.getOrCreate('shapeOffsetX')
.setValue(
Expand All @@ -254,7 +281,8 @@ module.exports = {
.setType('Number')
.setMeasurementUnit(gd.MeasurementUnit.getPixel())
.setLabel('Shape Offset X')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.
behaviorProperties
.getOrCreate('shapeOffsetY')
.setValue(
Expand All @@ -263,7 +291,8 @@ module.exports = {
.setType('Number')
.setMeasurementUnit(gd.MeasurementUnit.getPixel())
.setLabel('Shape Offset Y')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.
behaviorProperties
.getOrCreate('polygonOrigin')
.setValue(
Expand All @@ -276,7 +305,8 @@ module.exports = {
.addExtraInfo('Center')
.addExtraInfo('Origin')
.addExtraInfo('TopLeft')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.
behaviorProperties
.getOrCreate('vertices')
.setValue(
Expand All @@ -285,28 +315,44 @@ module.exports = {
: '[]'
)
.setLabel('Vertices')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.
behaviorProperties
.getOrCreate('density')
.setValue(
behaviorContent.getChild('density').getDoubleValue().toString(10)
)
.setType('Number')
.setLabel('Density');
.setLabel(_('Density'))
.setDescription(
_(
'Define the weight of the object, according to its size. The biggeer the density, the heavier the object.'
)
);
behaviorProperties
.getOrCreate('friction')
.setValue(
behaviorContent.getChild('friction').getDoubleValue().toString(10)
)
.setType('Number')
.setLabel('Friction');
.setLabel(_('Friction'))
.setDescription(
_(
'The friction applied when touching other objects. The higher the value, the more friction.'
)
);
behaviorProperties
.getOrCreate('restitution')
.setValue(
behaviorContent.getChild('restitution').getDoubleValue().toString(10)
)
.setType('Number')
.setLabel('Restitution');
.setLabel(_('Restitution'))
.setDescription(
_(
'The "bounciness" of the object. The higher the value, the more other objects will bounce against it.'
)
);
behaviorProperties
.getOrCreate('linearDamping')
.setValue(
Expand All @@ -316,7 +362,9 @@ module.exports = {
.toString(10)
)
.setType('Number')
.setLabel('Linear Damping');
.setLabel(_('Linear Damping'))
.setGroup(_('Movement'));

behaviorProperties
.getOrCreate('angularDamping')
.setValue(
Expand All @@ -326,28 +374,33 @@ module.exports = {
.toString(10)
)
.setType('Number')
.setLabel('Angular Damping')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setLabel(_('Angular Damping'))
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setGroup(_('Movement'));
behaviorProperties
.getOrCreate('gravityScale')
.setValue(
behaviorContent.getChild('gravityScale').getDoubleValue().toString(10)
)
.setType('Number')
.setLabel('Gravity Scale')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setGroup(_('Gravity'))
.setAdvanced(true);
behaviorProperties
.getOrCreate('layers')
.setValue(behaviorContent.getChild('layers').getIntValue().toString(10))
.setType('Number')
.setLabel('Layers')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.
behaviorProperties
.getOrCreate('masks')
.setValue(behaviorContent.getChild('masks').getIntValue().toString(10))
.setType('Number')
.setLabel('Masks')
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden);
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
.setHidden(true); // Hidden as required to be changed in the full editor.

return behaviorProperties;
};
Expand Down Expand Up @@ -474,9 +527,8 @@ module.exports = {
)
.setIncludeFile('Extensions/Physics2Behavior/physics2runtimebehavior.js')
.addIncludeFile('Extensions/Physics2Behavior/Box2D_v2.3.1_min.wasm.js')
.addRequiredFile(
'Extensions/Physics2Behavior/Box2D_v2.3.1_min.wasm.wasm'
);
.addRequiredFile('Extensions/Physics2Behavior/Box2D_v2.3.1_min.wasm.wasm')
.setOpenFullEditorLabel(_('Edit shape and avanced settings'));

// Global
aut
Expand Down
3 changes: 3 additions & 0 deletions GDevelop.js/Bindings/Bindings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -2029,6 +2029,9 @@ interface BehaviorMetadata {
QuickCustomization_Visibility GetQuickCustomizationVisibility();
[Ref] BehaviorMetadata SetQuickCustomizationVisibility(QuickCustomization_Visibility visibility);

[Ref] BehaviorMetadata SetOpenFullEditorLabel([Const] DOMString label);
[Const, Ref] DOMString GetOpenFullEditorLabel();

[Ref] Behavior Get();
BehaviorsSharedData GetSharedDataInstance();

Expand Down
2 changes: 2 additions & 0 deletions GDevelop.js/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,8 @@ export class BehaviorMetadata extends EmscriptenObject {
setHidden(): BehaviorMetadata;
getQuickCustomizationVisibility(): QuickCustomization_Visibility;
setQuickCustomizationVisibility(visibility: QuickCustomization_Visibility): BehaviorMetadata;
setOpenFullEditorLabel(label: string): BehaviorMetadata;
getOpenFullEditorLabel(): string;
get(): Behavior;
getSharedDataInstance(): BehaviorsSharedData;
getProperties(): MapStringPropertyDescriptor;
Expand Down
2 changes: 2 additions & 0 deletions GDevelop.js/types/gdbehaviormetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ declare class gdBehaviorMetadata {
setHidden(): gdBehaviorMetadata;
getQuickCustomizationVisibility(): QuickCustomization_Visibility;
setQuickCustomizationVisibility(visibility: QuickCustomization_Visibility): gdBehaviorMetadata;
setOpenFullEditorLabel(label: string): gdBehaviorMetadata;
getOpenFullEditorLabel(): string;
get(): gdBehavior;
getSharedDataInstance(): gdBehaviorsSharedData;
getProperties(): gdMapStringPropertyDescriptor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,74 @@ import ChevronArrowRight from '../../UI/CustomSvgIcons/ChevronArrowRight';
import Text from '../../UI/Text';
import { Line } from '../../UI/Grid';
import { useForceRecompute } from '../../Utils/UseForceUpdate';
import { type Schema, type ActionButton } from '../../CompactPropertiesEditor';
import ShareExternal from '../../UI/CustomSvgIcons/ShareExternal';

export const getSchemaWithOpenFullEditorButton = ({
schema,
fullEditorLabel,
behavior,
onOpenFullEditor,
}: {|
schema: Schema,
fullEditorLabel: ?string,
behavior: gdBehavior,
onOpenFullEditor: () => void,
|}): Schema => {
if (!fullEditorLabel) return schema;

const actionButton: ActionButton = {
label: fullEditorLabel,
disabled: 'onValuesDifferent',
nonFieldType: 'button',
showRightIcon: true,
getIcon: style => <ShareExternal style={style} />,
getValue: behavior => behavior.getName(),
onClick: behavior => onOpenFullEditor(),
};

let added = false;
schema.forEach(field => {
if (field.children && field.name === '') {
field.children.push(actionButton);
added = true;
}
});

if (!added) schema.push(actionButton);

return schema;
};

export const CompactBehaviorPropertiesEditor = ({
project,
behaviorMetadata,
behavior,
object,
onOpenFullEditor,
onBehaviorUpdated,
resourceManagementProps,
}: {|
project: gdProject,
behaviorMetadata: gdBehaviorMetadata,
behavior: gdBehavior,
object: gdObject,
onOpenFullEditor: () => void,
onBehaviorUpdated: () => void,
resourceManagementProps: ResourceManagementProps,
|}) => {
const [showAdvancedOptions, setShowAdvancedOptions] = React.useState(false);
const [schemaRecomputeTrigger, forceRecomputeSchema] = useForceRecompute();

const fullEditorLabel = behaviorMetadata.getOpenFullEditorLabel();

const basicPropertiesSchema = React.useMemo(
() => {
if (schemaRecomputeTrigger) {
// schemaRecomputeTrigger allows to invalidate the schema when required.
}

return propertiesMapToSchema(
const schema = propertiesMapToSchema(
behavior.getProperties(),
behavior => behavior.getProperties(),
(behavior, name, value) => {
Expand All @@ -43,8 +87,21 @@ export const CompactBehaviorPropertiesEditor = ({
object,
'Basic'
);

return getSchemaWithOpenFullEditorButton({
schema,
fullEditorLabel,
behavior,
onOpenFullEditor,
});
},
[behavior, object, schemaRecomputeTrigger]
[
behavior,
object,
schemaRecomputeTrigger,
fullEditorLabel,
onOpenFullEditor,
]
);

const advancedPropertiesSchema = React.useMemo(
Expand Down
Loading

0 comments on commit 07c5897

Please sign in to comment.