Add a drop-down menu action to extract selected instances as an external layout

This commit is contained in:
Davy Hélard
2024-05-13 12:01:57 +02:00
parent 92b9203ce8
commit 3e7b91fc0c
6 changed files with 49 additions and 1 deletions

View File

@@ -106,6 +106,8 @@ export type RenderEditorContainerProps = {|
// Object editing
openBehaviorEvents: (extensionName: string, behaviorName: string) => void,
onExtractAsExternalLayout: (name: string) => void,
|};
export type RenderEditorContainerPropsWithRef = {|

View File

@@ -213,6 +213,7 @@ export class ExternalLayoutEditorContainer extends React.Component<
isActive={isActive}
canInstallPrivateAsset={this.props.canInstallPrivateAsset}
openBehaviorEvents={this.props.openBehaviorEvents}
onExtractAsExternalLayout={this.props.onExtractAsExternalLayout}
/>
)}
{!layout && (

View File

@@ -108,6 +108,7 @@ export class SceneEditorContainer extends React.Component<RenderEditorContainerP
isActive={isActive}
hotReloadPreviewButtonProps={this.props.hotReloadPreviewButtonProps}
openBehaviorEvents={this.props.openBehaviorEvents}
onExtractAsExternalLayout={this.props.onExtractAsExternalLayout}
/>
);
}

View File

@@ -1880,6 +1880,10 @@ const MainFrame = (props: Props) => {
}
};
const onExtractAsExternalLayout = (name: string) => {
openExternalLayout(name);
};
const _onProjectItemModified = () => {
if (unsavedChanges) unsavedChanges.triggerUnsavedChanges();
forceUpdate();
@@ -3285,6 +3289,7 @@ const MainFrame = (props: Props) => {
cb(true);
},
openBehaviorEvents: openBehaviorEvents,
onExtractAsExternalLayout: onExtractAsExternalLayout,
})}
</ErrorBoundary>
</CommandsContextScopedProvider>

View File

@@ -1146,7 +1146,7 @@ const ProjectManager = React.forwardRef<Props, ProjectManagerInterface>(
return [
new PlaceHolderTreeViewItem(
externalLayoutEmptyPlaceholderId,
i18n._(t`Start by adding new a external layout.`)
i18n._(t`Start by adding a new external layout.`)
),
];
}

View File

@@ -70,6 +70,7 @@ import {
registerOnResourceExternallyChangedCallback,
unregisterOnResourceExternallyChangedCallback,
} from '../MainFrame/ResourcesWatcher';
import { unserializeFromJSObject } from '../Utils/Serializer';
const gd: libGDevelop = global.gd;
@@ -106,6 +107,7 @@ type Props = {|
unsavedChanges?: ?UnsavedChanges,
canInstallPrivateAsset: () => boolean,
openBehaviorEvents: (extensionName: string, behaviorName: string) => void,
onExtractAsExternalLayout: (name: string) => void,
// Preview:
hotReloadPreviewButtonProps: HotReloadPreviewButtonProps,
@@ -1321,6 +1323,11 @@ export default class SceneEditor extends React.Component<Props, State> {
},
},
{ type: 'separator' },
{
label: i18n._(t`Extract as an external layout`),
click: () => this.extractAsExternalLayout(i18n),
enabled: hasSelectedInstances,
},
{
label: i18n._(t`Show/Hide instance properties`),
click: () => this.toggleProperties(),
@@ -1551,6 +1558,38 @@ export default class SceneEditor extends React.Component<Props, State> {
this.forceUpdatePropertiesEditor();
};
extractAsExternalLayout = (i18n: I18nType) => {
const { project, layout, onExtractAsExternalLayout } = this.props;
const serializedSelection = this.instancesSelection
.getSelectedInstances()
.map(instance => serializeToJSObject(instance));
const newName = newNameGenerator(
i18n._(t`Untitled external layout`),
name => project.hasExternalLayoutNamed(name)
);
const newExternalLayout = project.insertNewExternalLayout(
newName,
project.getExternalLayoutsCount()
);
newExternalLayout.setAssociatedLayout(layout.getName());
for (const serializedInstance of serializedSelection) {
const instance = new gd.InitialInstance();
unserializeFromJSObject(instance, serializedInstance);
newExternalLayout
.getInitialInstances()
.insertInitialInstance(instance)
.resetPersistentUuid();
instance.delete();
}
this.deleteSelection();
onExtractAsExternalLayout(newName);
};
onSelectAllInstancesOfObjectInLayout = (objectName: string) => {
const { initialInstances } = this.props;
const instancesToSelect = getInstancesInLayoutForObject(