Add asset from asset store next to the selected item in the objects list (#6614)

- Also : hides variables list when multiple instances selected
This commit is contained in:
AlexandreS
2024-06-03 18:01:30 +02:00
committed by GitHub
parent ae6ac2068b
commit 4ed1889856
6 changed files with 109 additions and 50 deletions

View File

@@ -19,6 +19,7 @@ import {
import { type EventsFunctionsExtensionsState } from '../EventsFunctionsExtensionsLoader/EventsFunctionsExtensionsContext';
import { mapVector } from '../Utils/MapFor';
import { toNewGdMapStringString } from '../Utils/MapStringString';
import { getInsertionParentAndPositionFromSelection } from '../Utils/ObjectFolders';
const gd: libGDevelop = global.gd;
@@ -161,12 +162,14 @@ export type InstallAssetArgs = {|
asset: Asset,
project: gdProject,
objectsContainer: gdObjectsContainer,
targetObjectFolderOrObject?: ?gdObjectFolderOrObject,
|};
export const addAssetToProject = async ({
asset,
project,
objectsContainer,
targetObjectFolderOrObject,
}: InstallAssetArgs): Promise<InstallAssetOutput> => {
const objectNewNames = {};
const resourceNewNames = {};
@@ -182,12 +185,27 @@ export const addAssetToProject = async ({
const newName = newNameGenerator(originalName, name =>
objectsContainer.hasObjectNamed(name)
);
const object = objectsContainer.insertNewObject(
project,
type,
newName,
objectsContainer.getObjectsCount()
);
let object: gdObject;
if (targetObjectFolderOrObject) {
const { folder, position } = getInsertionParentAndPositionFromSelection(
targetObjectFolderOrObject
);
object = objectsContainer.insertNewObjectInFolder(
project,
type,
newName,
folder,
position
);
} else {
object = objectsContainer.insertNewObject(
project,
type,
newName,
objectsContainer.getObjectsCount()
);
}
objectNewNames[originalName] = newName;
unserializeFromJSObject(

View File

@@ -37,6 +37,7 @@ import PromisePool from '@supercharge/promise-pool';
import NewObjectFromScratch from './NewObjectFromScratch';
import { getAssetShortHeadersToDisplay } from './AssetsList';
import ErrorBoundary from '../UI/ErrorBoundary';
import type { ObjectFolderOrObjectWithContext } from '../ObjectsList/EnumerateObjectFolderOrObject';
const isDev = Window.isDev();
@@ -103,6 +104,7 @@ type Props = {|
onCreateNewObject: (type: string) => void,
onObjectsAddedFromAssets: (Array<gdObject>) => void,
canInstallPrivateAsset: () => boolean,
targetObjectFolderOrObjectWithContext?: ?ObjectFolderOrObjectWithContext,
|};
function NewObjectDialog({
@@ -114,6 +116,7 @@ function NewObjectDialog({
onCreateNewObject,
onObjectsAddedFromAssets,
canInstallPrivateAsset,
targetObjectFolderOrObjectWithContext,
}: Props) {
const { isMobile } = useResponsiveWindowSize();
const {
@@ -214,11 +217,21 @@ function NewObjectDialog({
asset,
project,
objectsContainer,
targetObjectFolderOrObject:
targetObjectFolderOrObjectWithContext &&
!targetObjectFolderOrObjectWithContext.global
? targetObjectFolderOrObjectWithContext.objectFolderOrObject
: null,
})
: await installPublicAsset({
asset,
project,
objectsContainer,
targetObjectFolderOrObject:
targetObjectFolderOrObjectWithContext &&
!targetObjectFolderOrObjectWithContext.global
? targetObjectFolderOrObjectWithContext.objectFolderOrObject
: null,
});
if (!installOutput) {
throw new Error('Unable to install private Asset.');
@@ -262,6 +275,7 @@ function NewObjectDialog({
canInstallPrivateAsset,
showAlert,
onObjectsAddedFromAssets,
targetObjectFolderOrObjectWithContext,
]
);

View File

@@ -114,6 +114,7 @@ const PrivateAssetsAuthorizationProvider = ({ children }: Props) => {
asset,
project,
objectsContainer,
targetObjectFolderOrObject,
}: InstallAssetArgs): Promise<?InstallAssetOutput> => {
if (!profile) {
throw new Error(
@@ -133,6 +134,7 @@ const PrivateAssetsAuthorizationProvider = ({ children }: Props) => {
asset: assetWithAuthorizedResourceUrls,
project,
objectsContainer,
targetObjectFolderOrObject,
});
};

View File

@@ -103,8 +103,14 @@ const CompactInstancePropertiesEditor = ({
[i18n, onGetInstanceSize, onEditObjectByName, layout, forceUpdate]
);
// TODO: multiple instances support.
const instance = instances[0];
/**
* TODO: multiple instances support for variables list. Expected behavior should be:
* - if instances of different objects, do not show
* - if instances of same object, show only variables in common (inherited variables
* obviously plus instance-wise variables with same name).
*/
const shouldDisplayVariablesList = instances.length === 1;
const { object, instanceSchema } = React.useMemo<{|
object?: gdObject,
@@ -166,42 +172,48 @@ const CompactInstancePropertiesEditor = ({
instances={instances}
onInstancesModified={onInstancesModified}
/>
<Spacer />
<Separator />
<Line alignItems="center" justifyContent="space-between">
<Text size="sub-title" noMargin>
<Trans>Instance Variables</Trans>
</Text>
<IconButton
size="small"
onClick={() => {
editInstanceVariables(instance);
}}
>
<ShareExternal style={styles.icon} />
</IconButton>
</Line>
</Column>
{object ? (
<VariablesList
projectScopedContainersAccessor={projectScopedContainersAccessor}
directlyStoreValueChangesWhileEditing
inheritedVariablesContainer={object.getVariables()}
variablesContainer={instance.getVariables()}
size="small"
onComputeAllVariableNames={() =>
object
? EventsRootVariablesFinder.findAllObjectVariables(
project.getCurrentPlatform(),
project,
layout,
object.getName()
)
: []
}
historyHandler={historyHandler}
toolbarIconStyle={styles.icon}
/>
{object && shouldDisplayVariablesList ? (
<>
<Column>
<Spacer />
<Separator />
<Line alignItems="center" justifyContent="space-between">
<Text size="sub-title" noMargin>
<Trans>Instance Variables</Trans>
</Text>
<IconButton
size="small"
onClick={() => {
editInstanceVariables(instance);
}}
>
<ShareExternal style={styles.icon} />
</IconButton>
</Line>
</Column>
<VariablesList
projectScopedContainersAccessor={
projectScopedContainersAccessor
}
directlyStoreValueChangesWhileEditing
inheritedVariablesContainer={object.getVariables()}
variablesContainer={instance.getVariables()}
size="small"
onComputeAllVariableNames={() =>
object
? EventsRootVariablesFinder.findAllObjectVariables(
project.getCurrentPlatform(),
project,
layout,
object.getName()
)
: []
}
historyHandler={historyHandler}
toolbarIconStyle={styles.icon}
/>
</>
) : null}
</Column>
</ScrollView>

View File

@@ -52,6 +52,7 @@ import { getHelpLink } from '../Utils/HelpLink';
import useAlertDialog from '../UI/Alert/useAlertDialog';
import { useResponsiveWindowSize } from '../UI/Responsive/ResponsiveWindowMeasurer';
import ErrorBoundary from '../UI/ErrorBoundary';
import { getInsertionParentAndPositionFromSelection } from '../Utils/ObjectFolders';
const gd: libGDevelop = global.gd;
const sceneObjectsRootFolderId = 'scene-objects';
@@ -318,23 +319,21 @@ const ObjectsList = React.forwardRef<Props, ObjectsListInterface>(
if (
newObjectDialogOpen &&
newObjectDialogOpen.from &&
// If a scene objectFolderOrObject is selected, insert new object next to or inside it.
!newObjectDialogOpen.from.global
) {
const selectedItem = newObjectDialogOpen.from.objectFolderOrObject;
const parentFolder = selectedItem.isFolder()
? selectedItem
: selectedItem.getParent();
const insertionIndex = selectedItem.isFolder()
? parentFolder.getChildrenCount()
: parentFolder.getChildPosition(selectedItem) + 1;
const {
folder: parentFolder,
position,
} = getInsertionParentAndPositionFromSelection(selectedItem);
// If a scene folder is selected, insert object in the folder.
object = objectsContainer.insertNewObjectInFolder(
project,
objectType,
name,
parentFolder,
insertionIndex
position
);
objectFolderOrObjectWithContext = {
objectFolderOrObject: parentFolder.getObjectChild(name),
@@ -1660,6 +1659,7 @@ const ObjectsList = React.forwardRef<Props, ObjectsListInterface>(
objectsContainer={objectsContainer}
resourceManagementProps={resourceManagementProps}
canInstallPrivateAsset={canInstallPrivateAsset}
targetObjectFolderOrObjectWithContext={newObjectDialogOpen.from}
/>
)}
</Background>

View File

@@ -0,0 +1,13 @@
// @flow
export const getInsertionParentAndPositionFromSelection = (
selectedObjectFolderOrObject: gdObjectFolderOrObject
) => {
const parentFolder = selectedObjectFolderOrObject.isFolder()
? selectedObjectFolderOrObject
: selectedObjectFolderOrObject.getParent();
const position = selectedObjectFolderOrObject.isFolder()
? parentFolder.getChildrenCount()
: parentFolder.getChildPosition(selectedObjectFolderOrObject) + 1;
return { folder: parentFolder, position };
};