Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions newIDE/app/src/BehaviorsEditor/Editors/AnchorBehaviorEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ import useForceUpdate from '../../Utils/UseForceUpdate';
import { ColumnStackLayout } from '../../UI/Layout';
import { Line } from '../../UI/Grid';
import Text from '../../UI/Text';
import {
getPropertyValue,
updateProperty,
} from '../../ObjectEditor/CompactObjectPropertiesEditor/CompactBehaviorPropertiesEditor';
import CompactToggleButtons, {
type CompactToggleButton,
} from '../../UI/CompactToggleButtons';
Expand Down Expand Up @@ -307,16 +303,20 @@ const AnchorBehaviorEditor = ({
const behavior = behaviors[0];
const forceUpdate = useForceUpdate();
const _getPropertyValue = React.useCallback(
(propertyName: string) => getPropertyValue(behavior, propertyName, null),
(propertyName: string) =>
behavior
.getProperties()
.get(propertyName)
.getValue(),
[behavior]
);
const _updateProperty = React.useCallback(
(propertyName: string, value: string) => {
updateProperty(project, behavior, propertyName, value, null);
behavior.updateProperty(propertyName, value);
forceUpdate();
onBehaviorUpdated();
},
[behavior, forceUpdate, onBehaviorUpdated, project]
[behavior, forceUpdate, onBehaviorUpdated]
);
const _onBehaviorUpdated = React.useCallback(
() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// @flow
import * as React from 'react';
import { type CompactInstanceBehaviorPropertiesEditorProps } from './CompactInstanceBehaviorPropertiesEditorProps.flow';
import {
CompactInstanceBehaviorPropertiesEditor,
getPropertyValue,
updateProperty,
} from './CompactInstanceBehaviorPropertiesEditor';
import useForceUpdate from '../../Utils/UseForceUpdate';
import { ColumnStackLayout } from '../../UI/Layout';
import {
HorizontalAnchorButtonGroup,
VerticalAnchorButtonGroup,
getBasicHorizontalAnchor,
getBasicVerticalAnchor,
} from '../../BehaviorsEditor/Editors/AnchorBehaviorEditor';

const CompactInstanceAnchorBehaviorEditor = ({
project,
object,
layersContainer,
behaviorMetadata,
instancesAndBehaviors,
onBehaviorUpdated,
resourceManagementProps,
}: CompactInstanceBehaviorPropertiesEditorProps): React.Node => {
const forceUpdate = useForceUpdate();
const _getPropertyValue = (propertyName: string) => {
let commonValue = null;
for (const { initialInstance, behavior } of instancesAndBehaviors) {
const value = getPropertyValue(behavior, propertyName, initialInstance);
if (commonValue === null) {
commonValue = value;
}
if (value !== commonValue) {
return null;
}
}
return commonValue;
};
const _updateProperty = (propertyName: string, value: string) => {
for (const { initialInstance, behavior } of instancesAndBehaviors) {
updateProperty(project, behavior, propertyName, value, initialInstance);
}
forceUpdate();
onBehaviorUpdated();
};
const _onBehaviorUpdated = React.useCallback(
() => {
forceUpdate();
onBehaviorUpdated();
},
[forceUpdate, onBehaviorUpdated]
);

const horizontalBasicAnchor = getBasicHorizontalAnchor(_getPropertyValue);
const verticalBasicAnchor = getBasicVerticalAnchor(_getPropertyValue);

return (
<ColumnStackLayout expand>
<HorizontalAnchorButtonGroup
basicAnchor={horizontalBasicAnchor}
expand
onUpdateProperty={_updateProperty}
/>
<VerticalAnchorButtonGroup
basicAnchor={verticalBasicAnchor}
expand
onUpdateProperty={_updateProperty}
/>
<CompactInstanceBehaviorPropertiesEditor
project={project}
object={object}
layersContainer={layersContainer}
behaviorMetadata={behaviorMetadata}
instancesAndBehaviors={instancesAndBehaviors}
onBehaviorUpdated={_onBehaviorUpdated}
resourceManagementProps={resourceManagementProps}
isAdvancedSectionInitiallyUncollapsed={
horizontalBasicAnchor === 'Advanced' ||
verticalBasicAnchor === 'Advanced' ||
_getPropertyValue('relativeToOriginalWindowSize') === 'false'
}
/>
</ColumnStackLayout>
);
};

export default CompactInstanceAnchorBehaviorEditor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// @flow
import * as React from 'react';
import { ColumnStackLayout } from '../../UI/Layout';
import { Trans } from '@lingui/macro';
import {
type Schema,
type ActionButton,
} from '../../PropertiesEditor/PropertiesEditorSchema';
import ShareExternal from '../../UI/CustomSvgIcons/ShareExternal';
import { CompactPropertiesEditorByVisibility } from '../../CompactPropertiesEditor/CompactPropertiesEditorByVisibility';
import propertiesMapToSchema from '../../PropertiesEditor/PropertiesMapToSchema';
import { useForceRecompute } from '../../Utils/UseForceUpdate';
import { type CompactInstanceBehaviorPropertiesEditorProps } from './CompactInstanceBehaviorPropertiesEditorProps.flow';

export const styles = {
icon: {
fontSize: 18,
},
};

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 getPropertyValue = (
behavior: gdBehavior,
propertyName: string,
initialInstance: gdInitialInstance
): string => {
const behaviorName = behavior.getName();
if (
initialInstance.hasBehaviorOverridingNamed(behaviorName) &&
initialInstance
.getBehaviorOverriding(behaviorName)
.hasPropertyValue(propertyName)
) {
const behaviorOverriding = initialInstance.getBehaviorOverriding(
behaviorName
);
return behaviorOverriding
.getProperties()
.get(propertyName)
.getValue();
}
return behavior
.getProperties()
.get(propertyName)
.getValue();
};

export const updateProperty = (
project: gdProject,
behavior: gdBehavior,
propertyName: string,
value: string,
initialInstance: gdInitialInstance
): void => {
const behaviorName = behavior.getName();
const behaviorOverriding = initialInstance.hasBehaviorOverridingNamed(
behaviorName
)
? initialInstance.getBehaviorOverriding(behaviorName)
: initialInstance.addNewBehaviorOverriding(
project,
behavior.getTypeName(),
behaviorName
);
const behaviorProperties = behavior.getProperties();
const inheritedValue = behaviorProperties.has(propertyName)
? behaviorProperties.get(propertyName).getValue()
: null;
if (inheritedValue === value) {
behaviorOverriding.removeProperty(propertyName);
} else {
behaviorOverriding.updateProperty(propertyName, value);
}
};

export const CompactInstanceBehaviorPropertiesEditor = ({
project,
behaviorMetadata,
object,
layersContainer,
instancesAndBehaviors,
onBehaviorUpdated,
resourceManagementProps,
}: CompactInstanceBehaviorPropertiesEditorProps): React.Node => {
const [schemaRecomputeTrigger, forceRecomputeSchema] = useForceRecompute();

const propertiesSchema: Schema = React.useMemo(
() => {
if (schemaRecomputeTrigger) {
// schemaRecomputeTrigger allows to invalidate the schema when required.
}
if (instancesAndBehaviors.length === 0) {
return [];
}
const behaviorProperties = instancesAndBehaviors[0].behavior.getProperties();
return propertiesMapToSchema({
properties: behaviorProperties,
defaultValueProperties: behaviorProperties,
getPropertyValue: (
{
behavior,
initialInstance,
}: { behavior: gdBehavior, initialInstance: gdInitialInstance },
propertyName
) => getPropertyValue(behavior, propertyName, initialInstance),
onUpdateProperty: (
{
behavior,
initialInstance,
}: { behavior: gdBehavior, initialInstance: gdInitialInstance },
propertyName,
value
) =>
updateProperty(
project,
behavior,
propertyName,
value,
initialInstance
),
object,
layersContainer,
visibility: 'All',
showcaseNonDefaultValues: true,
hideResourceProperties: true,
shouldDisabledFieldsWithMixedValues: false,
});
},
[
schemaRecomputeTrigger,
instancesAndBehaviors,
object,
layersContainer,
project,
]
);

return (
<ColumnStackLayout expand noMargin noOverflowParent>
<CompactPropertiesEditorByVisibility
project={project}
object={object}
schema={propertiesSchema}
instances={instancesAndBehaviors}
onInstancesModified={onBehaviorUpdated}
resourceManagementProps={resourceManagementProps}
placeholder={<Trans>Nothing to configure for this behavior.</Trans>}
customizeBasicSchema={null}
onRefreshAllFields={forceRecomputeSchema}
/>
</ColumnStackLayout>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// @flow
import { type ResourceManagementProps } from '../../ResourcesList/ResourceSource';

/**
* The props given to any behavior editor
*/
export type CompactInstanceBehaviorPropertiesEditorProps = {|
project: gdProject,
behaviorMetadata: gdBehaviorMetadata,
object: gdObject | null,
layersContainer: gdLayersContainer,
instancesAndBehaviors: Array<{
initialInstance: gdInitialInstance,
behavior: gdBehavior,
}>,
onBehaviorUpdated: () => void,
resourceManagementProps: ResourceManagementProps,
isAdvancedSectionInitiallyUncollapsed?: boolean,
|};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// @flow
import { CompactInstanceBehaviorPropertiesEditor } from './CompactInstanceBehaviorPropertiesEditor';
import { type CompactInstanceBehaviorPropertiesEditorProps } from './CompactInstanceBehaviorPropertiesEditorProps.flow';
import CompactInstanceAnchorBehaviorEditor from './CompactAnchorInstanceBehaviorEditor';

/**
* A service returning editor components for each behavior type.
*/
const CompactBehaviorsEditorService = {
getEditor(
behaviorType: string
): React.ComponentType<CompactInstanceBehaviorPropertiesEditorProps> {
// $FlowFixMe[object-this-reference]
if (!this.components[behaviorType]) {
return CompactInstanceBehaviorPropertiesEditor; // Default properties editor
}
// $FlowFixMe[object-this-reference]
return this.components[behaviorType].component; // Custom behavior editor
},
components: {
'AnchorBehavior::AnchorBehavior': {
component: CompactInstanceAnchorBehaviorEditor,
},
},
};

export default CompactBehaviorsEditorService;
Loading
Loading