Skip to content

Commit

Permalink
Allow to fold children object and add text for empty sections
Browse files Browse the repository at this point in the history
  • Loading branch information
4ian committed Sep 18, 2024
1 parent cc080cd commit 2680536
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 45 deletions.
25 changes: 24 additions & 1 deletion Core/GDCore/Project/CustomObjectConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <map>
#include <memory>
#include <unordered_set>
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/EventsBasedObject.h"
Expand Down Expand Up @@ -109,6 +110,27 @@ class CustomObjectConfiguration : public gd::ObjectConfiguration {
static const gd::CustomObjectConfiguration::EdgeAnchor
GetEdgeAnchorFromString(const gd::String &value);

/**
* Check if a child object properties must be displayed as folded in the editor.
* This is only useful when the object can override its children configuration (which
* is something being deprecated).
*/
bool IsChildObjectFolded(const gd::String& childName) const {
return unfoldedChildren.find(childName) == unfoldedChildren.end();
}

/**
* Set if a child object properties must be displayed as folded in the editor.
* This is only useful when the object can override its children configuration (which
* is something being deprecated).
*/
void SetChildObjectFolded(const gd::String& childName, bool folded) {
if (!folded)
unfoldedChildren.insert(childName);
else
unfoldedChildren.erase(childName);
}

protected:
void DoSerializeTo(SerializerElement& element) const override;
void DoUnserializeFrom(Project& project, const SerializerElement& element) override;
Expand All @@ -121,7 +143,8 @@ class CustomObjectConfiguration : public gd::ObjectConfiguration {
const Project* project; ///< The project is used to get the
///< EventBasedObject from the fullType.
gd::SerializerElement objectContent;

std::unordered_set<gd::String> unfoldedChildren;

bool isMarkedAsOverridingEventsBasedObjectChildrenConfiguration;
mutable std::map<gd::String, std::unique_ptr<gd::ObjectConfiguration>> childObjectConfigurations;

Expand Down
18 changes: 9 additions & 9 deletions Extensions/TextInput/JsExtension.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,21 +141,21 @@ module.exports = {
.setValue(objectContent.readOnly ? 'true' : 'false')
.setType('boolean')
.setLabel(_('Read only'))
.setGroup(_('Field appearance'));
.setGroup(_('Field'));

objectProperties
.getOrCreate('disabled')
.setValue(objectContent.disabled ? 'true' : 'false')
.setType('boolean')
.setLabel(_('Disabled'))
.setGroup(_('Field appearance'));
.setGroup(_('Field'));

objectProperties
.getOrCreate('textColor')
.setValue(objectContent.textColor || '0;0;0')
.setType('color')
.setLabel(_('Text color'))
.setGroup(_('Field appearance'));
.setGroup(_('Font'));

objectProperties
.getOrCreate('fillColor')
Expand All @@ -180,8 +180,8 @@ module.exports = {
.getOrCreate('borderColor')
.setValue(objectContent.borderColor || '0;0;0')
.setType('color')
.setLabel(_('Border color'))
.setGroup(_('Field appearance'));
.setLabel(_('Color'))
.setGroup(_('Border appearance'));

objectProperties
.getOrCreate('borderOpacity')
Expand All @@ -192,15 +192,15 @@ module.exports = {
).toString()
)
.setType('number')
.setLabel(_('Border opacity'))
.setGroup(_('Field appearance'));
.setLabel(_('Opacity'))
.setGroup(_('Border appearance'));

objectProperties
.getOrCreate('borderWidth')
.setValue((objectContent.borderWidth || 0).toString())
.setType('number')
.setLabel(_('Border width'))
.setGroup(_('Field appearance'));
.setLabel(_('Width'))
.setGroup(_('Border appearance'));

return objectProperties;
};
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 @@ -905,6 +905,9 @@ interface CustomObjectConfiguration {

[Ref] SpriteAnimationList GetAnimations();

boolean IsChildObjectFolded([Const] DOMString childName);
void SetChildObjectFolded([Const] DOMString childName, boolean folded);

CustomObjectConfiguration_EdgeAnchor STATIC_GetEdgeAnchorFromString([Const] DOMString value);
};
CustomObjectConfiguration implements ObjectConfiguration;
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 @@ -749,6 +749,8 @@ export class CustomObjectConfiguration extends ObjectConfiguration {
getInitialInstanceProperties(instance: InitialInstance): MapStringPropertyDescriptor;
updateInitialInstanceProperty(instance: InitialInstance, name: string, value: string): boolean;
getAnimations(): SpriteAnimationList;
isChildObjectFolded(childName: string): boolean;
setChildObjectFolded(childName: string, folded: boolean): void;
static getEdgeAnchorFromString(value: string): CustomObjectConfiguration_EdgeAnchor;
}

Expand Down
2 changes: 2 additions & 0 deletions GDevelop.js/types/gdcustomobjectconfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ declare class gdCustomObjectConfiguration extends gdObjectConfiguration {
getInitialInstanceProperties(instance: gdInitialInstance): gdMapStringPropertyDescriptor;
updateInitialInstanceProperty(instance: gdInitialInstance, name: string, value: string): boolean;
getAnimations(): gdSpriteAnimationList;
isChildObjectFolded(childName: string): boolean;
setChildObjectFolded(childName: string, folded: boolean): void;
static getEdgeAnchorFromString(value: string): CustomObjectConfiguration_EdgeAnchor;
delete(): void;
ptr: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ChevronArrowRight from '../../UI/CustomSvgIcons/ChevronArrowRight';
import { Trans } from '@lingui/macro';
import FlatButton from '../../UI/FlatButton';
import ChevronArrowTop from '../../UI/CustomSvgIcons/ChevronArrowTop';
import Text from '../../UI/Text';

const gd: libGDevelop = global.gd;

Expand Down Expand Up @@ -81,25 +82,34 @@ export const ChildObjectPropertiesEditor = ({
[childObjectConfigurationAsGd]
);
const hasObjectAdvancedProperties = objectAdvancedPropertiesSchema.length > 0;
const hasSomeObjectProperties =
objectBasicPropertiesSchema.length > 0 || hasObjectAdvancedProperties;

return (
<ColumnStackLayout noMargin noOverflowParent>
<CompactPropertiesEditor
project={project}
resourceManagementProps={resourceManagementProps}
unsavedChanges={unsavedChanges}
schema={objectBasicPropertiesSchema}
instances={[
{
object: childObject,
objectConfiguration: childObjectConfigurationAsGd,
},
]}
onInstancesModified={() => {
// TODO: undo/redo?
}}
onRefreshAllFields={onRefreshAllFields}
/>
{!hasSomeObjectProperties && (
<Text size="body2" align="center" color="secondary">
<Trans>This object has no properties.</Trans>
</Text>
)}
{hasSomeObjectProperties && (
<CompactPropertiesEditor
project={project}
resourceManagementProps={resourceManagementProps}
unsavedChanges={unsavedChanges}
schema={objectBasicPropertiesSchema}
instances={[
{
object: childObject,
objectConfiguration: childObjectConfigurationAsGd,
},
]}
onInstancesModified={() => {
// TODO: undo/redo?
}}
onRefreshAllFields={onRefreshAllFields}
/>
)}
{!showObjectAdvancedOptions && hasObjectAdvancedProperties && (
<FlatButton
fullWidth
Expand Down
70 changes: 51 additions & 19 deletions newIDE/app/src/ObjectEditor/CompactObjectPropertiesEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ export const CompactObjectPropertiesEditor = ({
onEditObject,
}: Props) => {
const forceUpdate = useForceUpdate();
const [showObjectAdvancedOptions, setShowObjectAdvancedOptions] = React.useState(false);
const [
showObjectAdvancedOptions,
setShowObjectAdvancedOptions,
] = React.useState(false);
const [schemaRecomputeTrigger, forceRecomputeSchema] = useForceRecompute();
const variablesListRef = React.useRef<?VariablesListInterface>(null);
const object = objects[0];
Expand Down Expand Up @@ -216,6 +219,8 @@ export const CompactObjectPropertiesEditor = ({
[objectConfigurationAsGd, schemaRecomputeTrigger]
);
const hasObjectAdvancedProperties = objectAdvancedPropertiesSchema.length > 0;
const hasSomeObjectProperties =
objectBasicPropertiesSchema.length > 0 || hasObjectAdvancedProperties;

// Behaviors:
const {
Expand Down Expand Up @@ -304,19 +309,26 @@ export const CompactObjectPropertiesEditor = ({
<ShareExternal style={styles.icon} />
</IconButton>
</LineStackLayout>
<CompactPropertiesEditor
project={project}
resourceManagementProps={resourceManagementProps}
unsavedChanges={unsavedChanges}
schema={objectBasicPropertiesSchema}
instances={[
{ object, objectConfiguration: objectConfigurationAsGd },
]}
onInstancesModified={() => {
// TODO: undo/redo?
}}
onRefreshAllFields={forceRecomputeSchema}
/>
{!hasSomeObjectProperties && (
<Text size="body2" align="center" color="secondary">
<Trans>This object has no properties.</Trans>
</Text>
)}
{hasSomeObjectProperties && (
<CompactPropertiesEditor
project={project}
resourceManagementProps={resourceManagementProps}
unsavedChanges={unsavedChanges}
schema={objectBasicPropertiesSchema}
instances={[
{ object, objectConfiguration: objectConfigurationAsGd },
]}
onInstancesModified={() => {
// TODO: undo/redo?
}}
onRefreshAllFields={forceRecomputeSchema}
/>
)}
{!showObjectAdvancedOptions && hasObjectAdvancedProperties && (
<FlatButton
fullWidth
Expand Down Expand Up @@ -361,6 +373,10 @@ export const CompactObjectPropertiesEditor = ({
const childObject = eventsBasedObject
.getObjects()
.getObjectAt(i);
const childObjectName = childObject.getName();
const isFolded = customObjectConfiguration.isChildObjectFolded(
childObjectName
);
return (
<CollapsibleSubPanel
key={i}
Expand All @@ -376,11 +392,17 @@ export const CompactObjectPropertiesEditor = ({
onRefreshAllFields={forceRecomputeSchema}
/>
)}
isFolded={false}
toggleFolded={() => {}}
isFolded={isFolded}
toggleFolded={() => {
customObjectConfiguration.setChildObjectFolded(
childObjectName,
!isFolded
);
forceUpdate();
}}
title={
<Text noMargin size="body">
{childObject.getName()}
{childObjectName}
</Text>
}
/>
Expand Down Expand Up @@ -409,6 +431,11 @@ export const CompactObjectPropertiesEditor = ({
</Line>
</Column>
<ColumnStackLayout>
{!allVisibleBehaviors.length && (
<Text size="body2" align="center" color="secondary">
<Trans>There are no behaviors on this object.</Trans>
</Text>
)}
{allVisibleBehaviors.map(behavior => {
const behaviorTypeName = behavior.getTypeName();
const behaviorMetadata = gd.MetadataProvider.getBehaviorMetadata(
Expand All @@ -430,7 +457,7 @@ export const CompactObjectPropertiesEditor = ({
resourceManagementProps={resourceManagementProps}
/>
)}
isFolded={!behavior.isFolded()}
isFolded={behavior.isFolded()}
toggleFolded={() => {
behavior.setFolded(!behavior.isFolded());
forceUpdate();
Expand Down Expand Up @@ -533,6 +560,11 @@ export const CompactObjectPropertiesEditor = ({
</Line>
</Column>
<ColumnStackLayout>
{effectsContainer.getEffectsCount() === 0 && (
<Text size="body2" align="center" color="secondary">
<Trans>There are no effects on this object.</Trans>
</Text>
)}
{mapFor(
0,
effectsContainer.getEffectsCount(),
Expand Down Expand Up @@ -574,7 +606,7 @@ export const CompactObjectPropertiesEditor = ({
/>
</ColumnStackLayout>
)}
isFolded={!effect.isFolded()}
isFolded={effect.isFolded()}
toggleFolded={() => {
effect.setFolded(!effect.isFolded());
forceUpdate();
Expand Down
4 changes: 4 additions & 0 deletions newIDE/app/src/Utils/Behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export const addBehaviorToObject = (
type,
name
);

// Show the beahvior properties in the editor by default, when just added.
object.getBehavior(name).setFolded(false);

return true;
};

Expand Down

0 comments on commit 2680536

Please sign in to comment.